summaryrefslogtreecommitdiff
path: root/cipher.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2016-08-03 05:41:57 +0000
committerDarren Tucker <dtucker@zip.com.au>2016-08-09 09:06:52 +1000
commit4706c1d8c15cd5565b59512853c2da9bd4ca26c9 (patch)
tree81ff9de3bdf3627b382bb4b808cf0e0612f4424f /cipher.c
parente600348a7afd6325cc5cd783cb424065cbc20434 (diff)
upstream commit
small refactor of cipher.c: make ciphercontext opaque to callers feedback and ok markus@ Upstream-ID: 094849f8be68c3bdad2c0f3dee551ecf7be87f6f
Diffstat (limited to 'cipher.c')
-rw-r--r--cipher.c165
1 files changed, 109 insertions, 56 deletions
diff --git a/cipher.c b/cipher.c
index 031bda9ec..747b59bf0 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.c,v 1.101 2015/12/10 17:08:40 mmcc Exp $ */ 1/* $OpenBSD: cipher.c,v 1.102 2016/08/03 05:41:57 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -57,6 +57,15 @@ extern const EVP_CIPHER *evp_ssh1_3des(void);
57extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); 57extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
58#endif 58#endif
59 59
60struct sshcipher_ctx {
61 int plaintext;
62 int encrypt;
63 EVP_CIPHER_CTX *evp;
64 struct chachapoly_ctx cp_ctx; /* XXX union with evp? */
65 struct aesctr_ctx ac_ctx; /* XXX union with evp? */
66 const struct sshcipher *cipher;
67};
68
60struct sshcipher { 69struct sshcipher {
61 char *name; 70 char *name;
62 int number; /* for ssh1 only */ 71 int number; /* for ssh1 only */
@@ -206,6 +215,18 @@ cipher_is_cbc(const struct sshcipher *c)
206} 215}
207 216
208u_int 217u_int
218cipher_ctx_is_plaintext(struct sshcipher_ctx *cc)
219{
220 return cc->plaintext;
221}
222
223u_int
224cipher_ctx_get_number(struct sshcipher_ctx *cc)
225{
226 return cc->cipher->number;
227}
228
229u_int
209cipher_mask_ssh1(int client) 230cipher_mask_ssh1(int client)
210{ 231{
211 u_int mask = 0; 232 u_int mask = 0;
@@ -297,65 +318,81 @@ cipher_warning_message(const struct sshcipher_ctx *cc)
297} 318}
298 319
299int 320int
300cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher, 321cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
301 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, 322 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
302 int do_encrypt) 323 int do_encrypt)
303{ 324{
304#ifdef WITH_OPENSSL 325 struct sshcipher_ctx *cc = NULL;
305 int ret = SSH_ERR_INTERNAL_ERROR; 326 int ret = SSH_ERR_INTERNAL_ERROR;
327#ifdef WITH_OPENSSL
306 const EVP_CIPHER *type; 328 const EVP_CIPHER *type;
307 int klen; 329 int klen;
308 u_char *junk, *discard; 330 u_char *junk, *discard;
331#endif
332
333 *ccp = NULL;
334 if ((cc = calloc(sizeof(*cc), 1)) == NULL)
335 return SSH_ERR_ALLOC_FAIL;
309 336
310 if (cipher->number == SSH_CIPHER_DES) { 337 if (cipher->number == SSH_CIPHER_DES) {
311 if (keylen > 8) 338 if (keylen > 8)
312 keylen = 8; 339 keylen = 8;
313 } 340 }
314#endif 341
315 cc->plaintext = (cipher->number == SSH_CIPHER_NONE); 342 cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
316 cc->encrypt = do_encrypt; 343 cc->encrypt = do_encrypt;
317 344
318 if (keylen < cipher->key_len || 345 if (keylen < cipher->key_len ||
319 (iv != NULL && ivlen < cipher_ivlen(cipher))) 346 (iv != NULL && ivlen < cipher_ivlen(cipher))) {
320 return SSH_ERR_INVALID_ARGUMENT; 347 ret = SSH_ERR_INVALID_ARGUMENT;
348 goto out;
349 }
321 350
322 cc->cipher = cipher; 351 cc->cipher = cipher;
323 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 352 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
324 return chachapoly_init(&cc->cp_ctx, key, keylen); 353 ret = chachapoly_init(&cc->cp_ctx, key, keylen);
354 goto out;
325 } 355 }
326#ifndef WITH_OPENSSL 356#ifndef WITH_OPENSSL
327 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 357 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
328 aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); 358 aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
329 aesctr_ivsetup(&cc->ac_ctx, iv); 359 aesctr_ivsetup(&cc->ac_ctx, iv);
330 return 0; 360 ret = 0;
361 goto out;
331 } 362 }
332 if ((cc->cipher->flags & CFLAG_NONE) != 0) 363 if ((cc->cipher->flags & CFLAG_NONE) != 0) {
333 return 0; 364 ret = 0;
334 return SSH_ERR_INVALID_ARGUMENT; 365 goto out;
335#else 366 }
367 ret = SSH_ERR_INVALID_ARGUMENT;
368 goto out;
369#else /* WITH_OPENSSL */
336 type = (*cipher->evptype)(); 370 type = (*cipher->evptype)();
337 EVP_CIPHER_CTX_init(&cc->evp); 371 if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) {
338 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, 372 ret = SSH_ERR_ALLOC_FAIL;
373 goto out;
374 }
375 if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv,
339 (do_encrypt == CIPHER_ENCRYPT)) == 0) { 376 (do_encrypt == CIPHER_ENCRYPT)) == 0) {
340 ret = SSH_ERR_LIBCRYPTO_ERROR; 377 ret = SSH_ERR_LIBCRYPTO_ERROR;
341 goto bad; 378 goto out;
342 } 379 }
343 if (cipher_authlen(cipher) && 380 if (cipher_authlen(cipher) &&
344 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, 381 !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
345 -1, (u_char *)iv)) { 382 -1, (u_char *)iv)) {
346 ret = SSH_ERR_LIBCRYPTO_ERROR; 383 ret = SSH_ERR_LIBCRYPTO_ERROR;
347 goto bad; 384 goto out;
348 } 385 }
349 klen = EVP_CIPHER_CTX_key_length(&cc->evp); 386 klen = EVP_CIPHER_CTX_key_length(cc->evp);
350 if (klen > 0 && keylen != (u_int)klen) { 387 if (klen > 0 && keylen != (u_int)klen) {
351 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) { 388 if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) {
352 ret = SSH_ERR_LIBCRYPTO_ERROR; 389 ret = SSH_ERR_LIBCRYPTO_ERROR;
353 goto bad; 390 goto out;
354 } 391 }
355 } 392 }
356 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { 393 if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
357 ret = SSH_ERR_LIBCRYPTO_ERROR; 394 ret = SSH_ERR_LIBCRYPTO_ERROR;
358 goto bad; 395 goto out;
359 } 396 }
360 397
361 if (cipher->discard_len > 0) { 398 if (cipher->discard_len > 0) {
@@ -363,21 +400,34 @@ cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
363 (discard = malloc(cipher->discard_len)) == NULL) { 400 (discard = malloc(cipher->discard_len)) == NULL) {
364 free(junk); 401 free(junk);
365 ret = SSH_ERR_ALLOC_FAIL; 402 ret = SSH_ERR_ALLOC_FAIL;
366 goto bad; 403 goto out;
367 } 404 }
368 ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len); 405 ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len);
369 explicit_bzero(discard, cipher->discard_len); 406 explicit_bzero(discard, cipher->discard_len);
370 free(junk); 407 free(junk);
371 free(discard); 408 free(discard);
372 if (ret != 1) { 409 if (ret != 1) {
373 ret = SSH_ERR_LIBCRYPTO_ERROR; 410 ret = SSH_ERR_LIBCRYPTO_ERROR;
374 bad: 411 goto out;
375 EVP_CIPHER_CTX_cleanup(&cc->evp);
376 return ret;
377 } 412 }
378 } 413 }
379#endif 414 ret = 0;
380 return 0; 415#endif /* WITH_OPENSSL */
416 out:
417 if (ret == 0) {
418 /* success */
419 *ccp = cc;
420 } else {
421 if (cc != NULL) {
422#ifdef WITH_OPENSSL
423 if (cc->evp != NULL)
424 EVP_CIPHER_CTX_free(cc->evp);
425#endif /* WITH_OPENSSL */
426 explicit_bzero(cc, sizeof(*cc));
427 free(cc);
428 }
429 }
430 return ret;
381} 431}
382 432
383/* 433/*
@@ -418,33 +468,33 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
418 if (authlen != cipher_authlen(cc->cipher)) 468 if (authlen != cipher_authlen(cc->cipher))
419 return SSH_ERR_INVALID_ARGUMENT; 469 return SSH_ERR_INVALID_ARGUMENT;
420 /* increment IV */ 470 /* increment IV */
421 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, 471 if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
422 1, lastiv)) 472 1, lastiv))
423 return SSH_ERR_LIBCRYPTO_ERROR; 473 return SSH_ERR_LIBCRYPTO_ERROR;
424 /* set tag on decyption */ 474 /* set tag on decyption */
425 if (!cc->encrypt && 475 if (!cc->encrypt &&
426 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, 476 !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG,
427 authlen, (u_char *)src + aadlen + len)) 477 authlen, (u_char *)src + aadlen + len))
428 return SSH_ERR_LIBCRYPTO_ERROR; 478 return SSH_ERR_LIBCRYPTO_ERROR;
429 } 479 }
430 if (aadlen) { 480 if (aadlen) {
431 if (authlen && 481 if (authlen &&
432 EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) 482 EVP_Cipher(cc->evp, NULL, (u_char *)src, aadlen) < 0)
433 return SSH_ERR_LIBCRYPTO_ERROR; 483 return SSH_ERR_LIBCRYPTO_ERROR;
434 memcpy(dest, src, aadlen); 484 memcpy(dest, src, aadlen);
435 } 485 }
436 if (len % cc->cipher->block_size) 486 if (len % cc->cipher->block_size)
437 return SSH_ERR_INVALID_ARGUMENT; 487 return SSH_ERR_INVALID_ARGUMENT;
438 if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, 488 if (EVP_Cipher(cc->evp, dest + aadlen, (u_char *)src + aadlen,
439 len) < 0) 489 len) < 0)
440 return SSH_ERR_LIBCRYPTO_ERROR; 490 return SSH_ERR_LIBCRYPTO_ERROR;
441 if (authlen) { 491 if (authlen) {
442 /* compute tag (on encrypt) or verify tag (on decrypt) */ 492 /* compute tag (on encrypt) or verify tag (on decrypt) */
443 if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) 493 if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0)
444 return cc->encrypt ? 494 return cc->encrypt ?
445 SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; 495 SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID;
446 if (cc->encrypt && 496 if (cc->encrypt &&
447 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, 497 !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG,
448 authlen, dest + aadlen + len)) 498 authlen, dest + aadlen + len))
449 return SSH_ERR_LIBCRYPTO_ERROR; 499 return SSH_ERR_LIBCRYPTO_ERROR;
450 } 500 }
@@ -466,20 +516,23 @@ cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr,
466 return 0; 516 return 0;
467} 517}
468 518
469int 519void
470cipher_cleanup(struct sshcipher_ctx *cc) 520cipher_free(struct sshcipher_ctx *cc)
471{ 521{
472 if (cc == NULL || cc->cipher == NULL) 522 if (cc == NULL)
473 return 0; 523 return;
474 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 524 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
475 explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); 525 explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
476 else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) 526 else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
477 explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); 527 explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
478#ifdef WITH_OPENSSL 528#ifdef WITH_OPENSSL
479 else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) 529 if (cc->evp != NULL) {
480 return SSH_ERR_LIBCRYPTO_ERROR; 530 EVP_CIPHER_CTX_free(cc->evp);
531 cc->evp = NULL;
532 }
481#endif 533#endif
482 return 0; 534 explicit_bzero(cc, sizeof(*cc));
535 free(cc);
483} 536}
484 537
485/* 538/*
@@ -487,8 +540,8 @@ cipher_cleanup(struct sshcipher_ctx *cc)
487 * passphrase and using the resulting 16 bytes as the key. 540 * passphrase and using the resulting 16 bytes as the key.
488 */ 541 */
489int 542int
490cipher_set_key_string(struct sshcipher_ctx *cc, const struct sshcipher *cipher, 543cipher_set_key_string(struct sshcipher_ctx **ccp,
491 const char *passphrase, int do_encrypt) 544 const struct sshcipher *cipher, const char *passphrase, int do_encrypt)
492{ 545{
493 u_char digest[16]; 546 u_char digest[16];
494 int r = SSH_ERR_INTERNAL_ERROR; 547 int r = SSH_ERR_INTERNAL_ERROR;
@@ -498,7 +551,7 @@ cipher_set_key_string(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
498 digest, sizeof(digest))) != 0) 551 digest, sizeof(digest))) != 0)
499 goto out; 552 goto out;
500 553
501 r = cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); 554 r = cipher_init(ccp, cipher, digest, 16, NULL, 0, do_encrypt);
502 out: 555 out:
503 explicit_bzero(digest, sizeof(digest)); 556 explicit_bzero(digest, sizeof(digest));
504 return r; 557 return r;
@@ -523,7 +576,7 @@ cipher_get_keyiv_len(const struct sshcipher_ctx *cc)
523 ivlen = sizeof(cc->ac_ctx.ctr); 576 ivlen = sizeof(cc->ac_ctx.ctr);
524#ifdef WITH_OPENSSL 577#ifdef WITH_OPENSSL
525 else 578 else
526 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); 579 ivlen = EVP_CIPHER_CTX_iv_length(cc->evp);
527#endif /* WITH_OPENSSL */ 580#endif /* WITH_OPENSSL */
528 return (ivlen); 581 return (ivlen);
529} 582}
@@ -555,7 +608,7 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
555 case SSH_CIPHER_SSH2: 608 case SSH_CIPHER_SSH2:
556 case SSH_CIPHER_DES: 609 case SSH_CIPHER_DES:
557 case SSH_CIPHER_BLOWFISH: 610 case SSH_CIPHER_BLOWFISH:
558 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 611 evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
559 if (evplen == 0) 612 if (evplen == 0)
560 return 0; 613 return 0;
561 else if (evplen < 0) 614 else if (evplen < 0)
@@ -568,16 +621,16 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
568 else 621 else
569#endif 622#endif
570 if (cipher_authlen(c)) { 623 if (cipher_authlen(c)) {
571 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, 624 if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
572 len, iv)) 625 len, iv))
573 return SSH_ERR_LIBCRYPTO_ERROR; 626 return SSH_ERR_LIBCRYPTO_ERROR;
574 } else 627 } else
575 memcpy(iv, cc->evp.iv, len); 628 memcpy(iv, cc->evp->iv, len);
576 break; 629 break;
577#endif 630#endif
578#ifdef WITH_SSH1 631#ifdef WITH_SSH1
579 case SSH_CIPHER_3DES: 632 case SSH_CIPHER_3DES:
580 return ssh1_3des_iv(&cc->evp, 0, iv, 24); 633 return ssh1_3des_iv(cc->evp, 0, iv, 24);
581#endif 634#endif
582 default: 635 default:
583 return SSH_ERR_INVALID_ARGUMENT; 636 return SSH_ERR_INVALID_ARGUMENT;
@@ -603,21 +656,21 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
603 case SSH_CIPHER_SSH2: 656 case SSH_CIPHER_SSH2:
604 case SSH_CIPHER_DES: 657 case SSH_CIPHER_DES:
605 case SSH_CIPHER_BLOWFISH: 658 case SSH_CIPHER_BLOWFISH:
606 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 659 evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
607 if (evplen <= 0) 660 if (evplen <= 0)
608 return SSH_ERR_LIBCRYPTO_ERROR; 661 return SSH_ERR_LIBCRYPTO_ERROR;
609 if (cipher_authlen(c)) { 662 if (cipher_authlen(c)) {
610 /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ 663 /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */
611 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, 664 if (!EVP_CIPHER_CTX_ctrl(cc->evp,
612 EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) 665 EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
613 return SSH_ERR_LIBCRYPTO_ERROR; 666 return SSH_ERR_LIBCRYPTO_ERROR;
614 } else 667 } else
615 memcpy(cc->evp.iv, iv, evplen); 668 memcpy(cc->evp->iv, iv, evplen);
616 break; 669 break;
617#endif 670#endif
618#ifdef WITH_SSH1 671#ifdef WITH_SSH1
619 case SSH_CIPHER_3DES: 672 case SSH_CIPHER_3DES:
620 return ssh1_3des_iv(&cc->evp, 1, (u_char *)iv, 24); 673 return ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24);
621#endif 674#endif
622 default: 675 default:
623 return SSH_ERR_INVALID_ARGUMENT; 676 return SSH_ERR_INVALID_ARGUMENT;
@@ -626,8 +679,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
626} 679}
627 680
628#ifdef WITH_OPENSSL 681#ifdef WITH_OPENSSL
629#define EVP_X_STATE(evp) (evp).cipher_data 682#define EVP_X_STATE(evp) (evp)->cipher_data
630#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size 683#define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size
631#endif 684#endif
632 685
633int 686int