summaryrefslogtreecommitdiff
path: root/cipher.c
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2002-03-22 01:39:44 +0000
committerBen Lindstrom <mouring@eviladmin.org>2002-03-22 01:39:44 +0000
commit212facacdeae1b5c004860500b03ee33dc5a2240 (patch)
treed0d490cf069962084b64ab811a05c7814681cabd /cipher.c
parentb481e1323e305a0de4934b3341b4f0d5fe759cea (diff)
- markus@cvs.openbsd.org 2002/03/18 17:13:15
[cipher.c cipher.h] export/import cipher states; needed by ssh-privsep
Diffstat (limited to 'cipher.c')
-rw-r--r--cipher.c175
1 files changed, 174 insertions, 1 deletions
diff --git a/cipher.c b/cipher.c
index 9e8f42f5e..7a9c9c491 100644
--- a/cipher.c
+++ b/cipher.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: cipher.c,v 1.52 2002/02/18 13:05:32 markus Exp $"); 38RCSID("$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}
91u_int
92cipher_get_number(Cipher *c)
93{
94 return (c->number);
95}
91 96
92u_int 97u_int
93cipher_mask_ssh1(int client) 98cipher_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
518int
519cipher_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
531void
532cipher_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
579void
580cipher_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
630int
631cipher_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
659void
660cipher_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];