diff options
author | Ben Lindstrom <mouring@eviladmin.org> | 2002-03-22 01:39:44 +0000 |
---|---|---|
committer | Ben Lindstrom <mouring@eviladmin.org> | 2002-03-22 01:39:44 +0000 |
commit | 212facacdeae1b5c004860500b03ee33dc5a2240 (patch) | |
tree | d0d490cf069962084b64ab811a05c7814681cabd | |
parent | b481e1323e305a0de4934b3341b4f0d5fe759cea (diff) |
- markus@cvs.openbsd.org 2002/03/18 17:13:15
[cipher.c cipher.h]
export/import cipher states; needed by ssh-privsep
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | cipher.c | 175 | ||||
-rw-r--r-- | cipher.h | 9 |
3 files changed, 186 insertions, 3 deletions
@@ -44,6 +44,9 @@ | |||
44 | - provos@cvs.openbsd.org 2002/03/18 03:41:08 | 44 | - provos@cvs.openbsd.org 2002/03/18 03:41:08 |
45 | [auth.c session.c] | 45 | [auth.c session.c] |
46 | move auth_approval into getpwnamallow with help from millert@ | 46 | move auth_approval into getpwnamallow with help from millert@ |
47 | - markus@cvs.openbsd.org 2002/03/18 17:13:15 | ||
48 | [cipher.c cipher.h] | ||
49 | export/import cipher states; needed by ssh-privsep | ||
47 | 50 | ||
48 | 20020317 | 51 | 20020317 |
49 | - (tim) [configure.ac] Assume path given with --with-pid-dir=PATH is wanted, | 52 | - (tim) [configure.ac] Assume path given with --with-pid-dir=PATH is wanted, |
@@ -7890,4 +7893,4 @@ | |||
7890 | - Wrote replacements for strlcpy and mkdtemp | 7893 | - Wrote replacements for strlcpy and mkdtemp |
7891 | - Released 1.0pre1 | 7894 | - Released 1.0pre1 |
7892 | 7895 | ||
7893 | $Id: ChangeLog,v 1.1937 2002/03/22 01:35:47 mouring Exp $ | 7896 | $Id: ChangeLog,v 1.1938 2002/03/22 01:39:44 mouring Exp $ |
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "includes.h" | 37 | #include "includes.h" |
38 | RCSID("$OpenBSD: cipher.c,v 1.52 2002/02/18 13:05:32 markus Exp $"); | 38 | RCSID("$OpenBSD: cipher.c,v 1.53 2002/03/18 17:13:15 markus Exp $"); |
39 | 39 | ||
40 | #include "xmalloc.h" | 40 | #include "xmalloc.h" |
41 | #include "log.h" | 41 | #include "log.h" |
@@ -88,6 +88,11 @@ cipher_keylen(Cipher *c) | |||
88 | { | 88 | { |
89 | return (c->key_len); | 89 | return (c->key_len); |
90 | } | 90 | } |
91 | u_int | ||
92 | cipher_get_number(Cipher *c) | ||
93 | { | ||
94 | return (c->number); | ||
95 | } | ||
91 | 96 | ||
92 | u_int | 97 | u_int |
93 | cipher_mask_ssh1(int client) | 98 | cipher_mask_ssh1(int client) |
@@ -502,6 +507,174 @@ ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, | |||
502 | for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE, | 507 | for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE, |
503 | plain-=RIJNDAEL_BLOCKSIZE) { | 508 | plain-=RIJNDAEL_BLOCKSIZE) { |
504 | rijndael_decrypt(&c->r_ctx, cnow, plain); | 509 | rijndael_decrypt(&c->r_ctx, cnow, plain); |
510 | } | ||
511 | |||
512 | /* | ||
513 | * Exports an IV from the CipherContext required to export the key | ||
514 | * state back from the unprivileged child to the privileged parent | ||
515 | * process. | ||
516 | */ | ||
517 | |||
518 | int | ||
519 | cipher_get_keyiv_len(CipherContext *cc) | ||
520 | { | ||
521 | Cipher *c = cc->cipher; | ||
522 | int ivlen; | ||
523 | |||
524 | if (c->number == SSH_CIPHER_3DES) | ||
525 | ivlen = 24; | ||
526 | else | ||
527 | ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); | ||
528 | return (ivlen); | ||
529 | } | ||
530 | |||
531 | void | ||
532 | cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) | ||
533 | { | ||
534 | Cipher *c = cc->cipher; | ||
535 | u_char *civ = NULL; | ||
536 | int evplen; | ||
537 | |||
538 | switch (c->number) { | ||
539 | case SSH_CIPHER_SSH2: | ||
540 | case SSH_CIPHER_DES: | ||
541 | case SSH_CIPHER_BLOWFISH: | ||
542 | evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); | ||
543 | if (evplen == 0) | ||
544 | return; | ||
545 | if (evplen != len) | ||
546 | fatal("%s: wrong iv length %d != %d", __FUNCTION__, | ||
547 | evplen, len); | ||
548 | |||
549 | if (strncmp(c->name, "aes", 3) == 0) { | ||
550 | struct ssh_rijndael_ctx *aesc; | ||
551 | |||
552 | aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp); | ||
553 | if (aesc == NULL) | ||
554 | fatal("%s: no rijndael context", __FUNCTION__); | ||
555 | civ = aesc->r_iv; | ||
556 | } else { | ||
557 | civ = cc->evp.iv; | ||
558 | } | ||
559 | break; | ||
560 | case SSH_CIPHER_3DES: { | ||
561 | struct ssh1_3des_ctx *desc; | ||
562 | if (len != 24) | ||
563 | fatal("%s: bad 3des iv length: %d", __FUNCTION__, len); | ||
564 | desc = EVP_CIPHER_CTX_get_app_data(&cc->evp); | ||
565 | if (desc == NULL) | ||
566 | fatal("%s: no 3des context", __FUNCTION__); | ||
567 | debug3("%s: Copying 3DES IV", __FUNCTION__); | ||
568 | memcpy(iv, desc->k1.iv, 8); | ||
569 | memcpy(iv + 8, desc->k2.iv, 8); | ||
570 | memcpy(iv + 16, desc->k3.iv, 8); | ||
571 | return; | ||
572 | } | ||
573 | default: | ||
574 | fatal("%s: bad cipher %d", __FUNCTION__, c->number); | ||
575 | } | ||
576 | memcpy(iv, civ, len); | ||
577 | } | ||
578 | |||
579 | void | ||
580 | cipher_set_keyiv(CipherContext *cc, u_char *iv) | ||
581 | { | ||
582 | Cipher *c = cc->cipher; | ||
583 | u_char *div = NULL; | ||
584 | int evplen = 0; | ||
585 | |||
586 | switch (c->number) { | ||
587 | case SSH_CIPHER_SSH2: | ||
588 | case SSH_CIPHER_DES: | ||
589 | case SSH_CIPHER_BLOWFISH: | ||
590 | evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); | ||
591 | if (evplen == 0) | ||
592 | return; | ||
593 | |||
594 | if (strncmp(c->name, "aes", 3) == 0) { | ||
595 | struct ssh_rijndael_ctx *aesc; | ||
596 | |||
597 | aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp); | ||
598 | if (aesc == NULL) | ||
599 | fatal("%s: no rijndael context", __FUNCTION__); | ||
600 | div = aesc->r_iv; | ||
601 | }else { | ||
602 | div = cc->evp.iv; | ||
603 | } | ||
604 | break; | ||
605 | case SSH_CIPHER_3DES: { | ||
606 | struct ssh1_3des_ctx *desc; | ||
607 | desc = EVP_CIPHER_CTX_get_app_data(&cc->evp); | ||
608 | if (desc == NULL) | ||
609 | fatal("%s: no 3des context", __FUNCTION__); | ||
610 | debug3("%s: Installed 3DES IV", __FUNCTION__); | ||
611 | memcpy(desc->k1.iv, iv, 8); | ||
612 | memcpy(desc->k2.iv, iv + 8, 8); | ||
613 | memcpy(desc->k3.iv, iv + 16, 8); | ||
614 | return; | ||
615 | } | ||
616 | default: | ||
617 | fatal("%s: bad cipher %d", __FUNCTION__, c->number); | ||
618 | } | ||
619 | memcpy(div, iv, evplen); | ||
620 | } | ||
621 | |||
622 | #if OPENSSL_VERSION_NUMBER < 0x00907000L | ||
623 | #define EVP_X_STATE(evp) &(evp).c | ||
624 | #define EVP_X_STATE_LEN(evp) sizeof((evp).c) | ||
625 | #else | ||
626 | #define EVP_X_STATE(evp) (evp).cipher_data | ||
627 | #define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size | ||
628 | #endif | ||
629 | |||
630 | int | ||
631 | cipher_get_keycontext(CipherContext *cc, u_char *dat) | ||
632 | { | ||
633 | Cipher *c = cc->cipher; | ||
634 | int plen; | ||
635 | |||
636 | if (c->number == SSH_CIPHER_3DES) { | ||
637 | struct ssh1_3des_ctx *desc; | ||
638 | desc = EVP_CIPHER_CTX_get_app_data(&cc->evp); | ||
639 | if (desc == NULL) | ||
640 | fatal("%s: no 3des context", __FUNCTION__); | ||
641 | plen = EVP_X_STATE_LEN(desc->k1); | ||
642 | if (dat == NULL) | ||
643 | return (3*plen); | ||
644 | memcpy(dat, EVP_X_STATE(desc->k1), plen); | ||
645 | memcpy(dat + plen, EVP_X_STATE(desc->k2), plen); | ||
646 | memcpy(dat + 2*plen, EVP_X_STATE(desc->k3), plen); | ||
647 | return (3*plen); | ||
648 | } | ||
649 | |||
650 | /* Generic EVP */ | ||
651 | plen = EVP_X_STATE_LEN(cc->evp); | ||
652 | if (dat == NULL) | ||
653 | return (plen); | ||
654 | |||
655 | memcpy(dat, EVP_X_STATE(cc->evp), plen); | ||
656 | return (plen); | ||
657 | } | ||
658 | |||
659 | void | ||
660 | cipher_set_keycontext(CipherContext *cc, u_char *dat) | ||
661 | { | ||
662 | Cipher *c = cc->cipher; | ||
663 | int plen; | ||
664 | |||
665 | if (c->number == SSH_CIPHER_3DES) { | ||
666 | struct ssh1_3des_ctx *desc; | ||
667 | desc = EVP_CIPHER_CTX_get_app_data(&cc->evp); | ||
668 | if (desc == NULL) | ||
669 | fatal("%s: no 3des context", __FUNCTION__); | ||
670 | plen = EVP_X_STATE_LEN(desc->k1); | ||
671 | memcpy(EVP_X_STATE(desc->k1), dat, plen); | ||
672 | memcpy(EVP_X_STATE(desc->k2), dat + plen, plen); | ||
673 | memcpy(EVP_X_STATE(desc->k3), dat + 2*plen, plen); | ||
674 | } else { | ||
675 | plen = EVP_X_STATE_LEN(cc->evp); | ||
676 | memcpy(EVP_X_STATE(cc->evp), dat, plen); | ||
677 | } | ||
505 | ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE; | 678 | ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE; |
506 | for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++) | 679 | for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++) |
507 | plain[j] ^= ivp[j]; | 680 | plain[j] ^= ivp[j]; |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher.h,v 1.32 2002/03/04 17:27:39 stevesk Exp $ */ | 1 | /* $OpenBSD: cipher.h,v 1.33 2002/03/18 17:13:15 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -81,4 +81,11 @@ void cipher_cleanup(CipherContext *); | |||
81 | void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); | 81 | void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); |
82 | u_int cipher_blocksize(Cipher *); | 82 | u_int cipher_blocksize(Cipher *); |
83 | u_int cipher_keylen(Cipher *); | 83 | u_int cipher_keylen(Cipher *); |
84 | |||
85 | u_int cipher_get_number(Cipher *); | ||
86 | void cipher_get_keyiv(CipherContext *, u_char *, u_int); | ||
87 | void cipher_set_keyiv(CipherContext *, u_char *); | ||
88 | int cipher_get_keyiv_len(CipherContext *); | ||
89 | int cipher_get_keycontext(CipherContext *, u_char *); | ||
90 | void cipher_set_keycontext(CipherContext *, u_char *); | ||
84 | #endif /* CIPHER_H */ | 91 | #endif /* CIPHER_H */ |