[BACK]Return to cipher.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/cipher.c, Revision 1.26.2.3

1.1       deraadt     1: /*
1.17      deraadt     2:  * Author: Tatu Ylonen <ylo@cs.hut.fi>
                      3:  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                      4:  *                    All rights reserved
1.26      markus      5:  *
1.26.2.3! jason       6:  * As far as I am concerned, the code I have written for this software
        !             7:  * can be used freely for any purpose.  Any derived versions of this
        !             8:  * software must be clearly marked as such, and if the derived work is
        !             9:  * incompatible with the protocol description in the RFC file, it must be
        !            10:  * called by a name other than "ssh" or "Secure Shell".
        !            11:  *
        !            12:  *
        !            13:  * Copyright (c) 1999 Niels Provos.  All rights reserved.
        !            14:  * Copyright (c) 1999,2000 Markus Friedl.  All rights reserved.
1.26      markus     15:  *
1.26.2.3! jason      16:  * Redistribution and use in source and binary forms, with or without
        !            17:  * modification, are permitted provided that the following conditions
        !            18:  * are met:
        !            19:  * 1. Redistributions of source code must retain the above copyright
        !            20:  *    notice, this list of conditions and the following disclaimer.
        !            21:  * 2. Redistributions in binary form must reproduce the above copyright
        !            22:  *    notice, this list of conditions and the following disclaimer in the
        !            23:  *    documentation and/or other materials provided with the distribution.
        !            24:  *
        !            25:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            26:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            27:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            28:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            29:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            30:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            31:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            32:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            33:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            34:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.17      deraadt    35:  */
1.1       deraadt    36:
                     37: #include "includes.h"
1.26.2.3! jason      38: RCSID("$OpenBSD: cipher.c,v 1.37 2000/10/23 19:31:54 markus Exp $");
1.1       deraadt    39:
                     40: #include "ssh.h"
1.24      markus     41: #include "xmalloc.h"
1.8       deraadt    42:
1.25      markus     43: #include <openssl/md5.h>
1.1       deraadt    44:
1.26.2.3! jason      45:
        !            46: /* no encryption */
        !            47: void
        !            48: none_setkey(CipherContext *cc, const u_char *key, u_int keylen)
        !            49: {
        !            50: }
        !            51: void
        !            52: none_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
        !            53: {
        !            54: }
        !            55: void
        !            56: none_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
        !            57: {
        !            58:        memcpy(dest, src, len);
        !            59: }
        !            60:
        !            61: /* DES */
        !            62: void
        !            63: des_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen)
        !            64: {
        !            65:        static int dowarn = 1;
        !            66:        if (dowarn) {
        !            67:                error("Warning: use of DES is strongly discouraged "
        !            68:                    "due to cryptographic weaknesses");
        !            69:                dowarn = 0;
        !            70:        }
        !            71:        des_set_key((void *)key, cc->u.des.key);
        !            72: }
        !            73: void
        !            74: des_ssh1_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
        !            75: {
        !            76:        memset(cc->u.des.iv, 0, sizeof(cc->u.des.iv));
        !            77: }
        !            78: void
        !            79: des_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
        !            80: {
        !            81:        des_ncbc_encrypt(src, dest, len, cc->u.des.key, &cc->u.des.iv,
        !            82:            DES_ENCRYPT);
        !            83: }
        !            84: void
        !            85: des_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
        !            86: {
        !            87:        des_ncbc_encrypt(src, dest, len, cc->u.des.key, &cc->u.des.iv,
        !            88:            DES_DECRYPT);
        !            89: }
        !            90:
        !            91: /* 3DES */
        !            92: void
        !            93: des3_setkey(CipherContext *cc, const u_char *key, u_int keylen)
        !            94: {
        !            95:        des_set_key((void *) key, cc->u.des3.key1);
        !            96:        des_set_key((void *) (key+8), cc->u.des3.key2);
        !            97:        des_set_key((void *) (key+16), cc->u.des3.key3);
        !            98: }
        !            99: void
        !           100: des3_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
        !           101: {
        !           102:        memset(cc->u.des3.iv2, 0, sizeof(cc->u.des3.iv2));
        !           103:        memset(cc->u.des3.iv3, 0, sizeof(cc->u.des3.iv3));
        !           104:        if (iv == NULL)
        !           105:                return;
        !           106:        memcpy(cc->u.des3.iv3, (char *)iv, 8);
        !           107: }
        !           108: void
        !           109: des3_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
        !           110: {
        !           111:        des_ede3_cbc_encrypt(src, dest, len,
        !           112:            cc->u.des3.key1, cc->u.des3.key2, cc->u.des3.key3,
        !           113:            &cc->u.des3.iv3, DES_ENCRYPT);
        !           114: }
        !           115: void
        !           116: des3_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
        !           117: {
        !           118:        des_ede3_cbc_encrypt(src, dest, len,
        !           119:            cc->u.des3.key1, cc->u.des3.key2, cc->u.des3.key3,
        !           120:            &cc->u.des3.iv3, DES_DECRYPT);
        !           121: }
        !           122:
1.1       deraadt   123: /*
1.24      markus    124:  * This is used by SSH1:
                    125:  *
1.23      deraadt   126:  * What kind of triple DES are these 2 routines?
1.1       deraadt   127:  *
                    128:  * Why is there a redundant initialization vector?
                    129:  *
                    130:  * If only iv3 was used, then, this would till effect have been
                    131:  * outer-cbc. However, there is also a private iv1 == iv2 which
                    132:  * perhaps makes differential analysis easier. On the other hand, the
                    133:  * private iv1 probably makes the CRC-32 attack ineffective. This is a
                    134:  * result of that there is no longer any known iv1 to use when
                    135:  * choosing the X block.
                    136:  */
                    137: void
1.26.2.3! jason     138: des3_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen)
        !           139: {
        !           140:        des_set_key((void *) key, cc->u.des3.key1);
        !           141:        des_set_key((void *) (key+8), cc->u.des3.key2);
        !           142:        if (keylen <= 16)
        !           143:                des_set_key((void *) key, cc->u.des3.key3);
        !           144:        else
        !           145:                des_set_key((void *) (key+16), cc->u.des3.key3);
        !           146: }
        !           147: void
        !           148: des3_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src,
        !           149:     u_int len)
1.1       deraadt   150: {
1.16      markus    151:        des_cblock iv1;
1.26.2.3! jason     152:        des_cblock *iv2 = &cc->u.des3.iv2;
        !           153:        des_cblock *iv3 = &cc->u.des3.iv3;
1.1       deraadt   154:
1.16      markus    155:        memcpy(&iv1, iv2, 8);
1.1       deraadt   156:
1.26.2.3! jason     157:        des_cbc_encrypt(src, dest, len, cc->u.des3.key1, &iv1, DES_ENCRYPT);
1.16      markus    158:        memcpy(&iv1, dest + len - 8, 8);
1.1       deraadt   159:
1.26.2.3! jason     160:        des_cbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_DECRYPT);
1.16      markus    161:        memcpy(iv2, &iv1, 8);   /* Note how iv1 == iv2 on entry and exit. */
1.1       deraadt   162:
1.26.2.3! jason     163:        des_cbc_encrypt(dest, dest, len, cc->u.des3.key3, iv3, DES_ENCRYPT);
1.16      markus    164:        memcpy(iv3, dest + len - 8, 8);
1.1       deraadt   165: }
                    166: void
1.26.2.3! jason     167: des3_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src,
        !           168:     u_int len)
1.1       deraadt   169: {
1.16      markus    170:        des_cblock iv1;
1.26.2.3! jason     171:        des_cblock *iv2 = &cc->u.des3.iv2;
        !           172:        des_cblock *iv3 = &cc->u.des3.iv3;
1.1       deraadt   173:
1.16      markus    174:        memcpy(&iv1, iv2, 8);
1.1       deraadt   175:
1.26.2.3! jason     176:        des_cbc_encrypt(src, dest, len, cc->u.des3.key3, iv3, DES_DECRYPT);
1.16      markus    177:        memcpy(iv3, src + len - 8, 8);
1.1       deraadt   178:
1.26.2.3! jason     179:        des_cbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_ENCRYPT);
1.16      markus    180:        memcpy(iv2, dest + len - 8, 8);
1.1       deraadt   181:
1.26.2.3! jason     182:        des_cbc_encrypt(dest, dest, len, cc->u.des3.key1, &iv1, DES_DECRYPT);
1.16      markus    183:        /* memcpy(&iv1, iv2, 8); */
                    184:        /* Note how iv1 == iv2 on entry and exit. */
1.1       deraadt   185: }
                    186:
1.26.2.3! jason     187: /* Blowfish */
        !           188: void
        !           189: blowfish_setkey(CipherContext *cc, const u_char *key, u_int keylen)
        !           190: {
        !           191:        BF_set_key(&cc->u.bf.key, keylen, (unsigned char *)key);
        !           192: }
        !           193: void
        !           194: blowfish_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
        !           195: {
        !           196:        if (iv == NULL)
        !           197:                memset(cc->u.bf.iv, 0, 8);
        !           198:        else
        !           199:                memcpy(cc->u.bf.iv, (char *)iv, 8);
        !           200: }
        !           201: void
        !           202: blowfish_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src,
        !           203:      u_int len)
        !           204: {
        !           205:        BF_cbc_encrypt((void *)src, dest, len, &cc->u.bf.key, cc->u.bf.iv,
        !           206:            BF_ENCRYPT);
        !           207: }
        !           208: void
        !           209: blowfish_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src,
        !           210:      u_int len)
        !           211: {
        !           212:        BF_cbc_encrypt((void *)src, dest, len, &cc->u.bf.key, cc->u.bf.iv,
        !           213:            BF_DECRYPT);
        !           214: }
        !           215:
1.1       deraadt   216: /*
1.24      markus    217:  * SSH1 uses a variation on Blowfish, all bytes must be swapped before
1.1       deraadt   218:  * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
                    219:  */
1.16      markus    220: static void
1.26.2.3! jason     221: swap_bytes(const unsigned char *src, unsigned char *dst, int n)
1.1       deraadt   222: {
1.26.2.3! jason     223:        char c[4];
        !           224:
        !           225:        /* Process 4 bytes every lap. */
        !           226:        for (n = n / 4; n > 0; n--) {
        !           227:                c[3] = *src++;
        !           228:                c[2] = *src++;
        !           229:                c[1] = *src++;
        !           230:                c[0] = *src++;
        !           231:
        !           232:                *dst++ = c[0];
        !           233:                *dst++ = c[1];
        !           234:                *dst++ = c[2];
        !           235:                *dst++ = c[3];
1.16      markus    236:        }
1.1       deraadt   237: }
                    238:
1.26.2.3! jason     239: void
        !           240: blowfish_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src,
        !           241:     u_int len)
1.4       provos    242: {
1.26.2.3! jason     243:        swap_bytes(src, dest, len);
        !           244:        BF_cbc_encrypt((void *)dest, dest, len, &cc->u.bf.key, cc->u.bf.iv,
        !           245:            BF_ENCRYPT);
        !           246:        swap_bytes(dest, dest, len);
        !           247: }
        !           248: void
        !           249: blowfish_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src,
        !           250:     u_int len)
        !           251: {
        !           252:        swap_bytes(src, dest, len);
        !           253:        BF_cbc_encrypt((void *)dest, dest, len, &cc->u.bf.key, cc->u.bf.iv,
        !           254:            BF_DECRYPT);
        !           255:        swap_bytes(dest, dest, len);
        !           256: }
1.1       deraadt   257:
1.26.2.3! jason     258: /* alleged rc4 */
        !           259: void
        !           260: arcfour_setkey(CipherContext *cc, const u_char *key, u_int keylen)
        !           261: {
        !           262:        RC4_set_key(&cc->u.rc4, keylen, (u_char *)key);
        !           263: }
        !           264: void
        !           265: arcfour_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
        !           266: {
        !           267:        RC4(&cc->u.rc4, len, (u_char *)src, dest);
        !           268: }
1.1       deraadt   269:
1.26.2.3! jason     270: /* CAST */
        !           271: void
        !           272: cast_setkey(CipherContext *cc, const u_char *key, u_int keylen)
1.1       deraadt   273: {
1.26.2.3! jason     274:        CAST_set_key(&cc->u.cast.key, keylen, (unsigned char *) key);
1.22      markus    275: }
1.26.2.3! jason     276: void
        !           277: cast_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
1.22      markus    278: {
1.26.2.3! jason     279:        if (iv == NULL)
        !           280:                fatal("no IV for %s.", cc->cipher->name);
        !           281:        memcpy(cc->u.cast.iv, (char *)iv, 8);
1.1       deraadt   282: }
1.26.2.3! jason     283: void
        !           284: cast_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
        !           285: {
        !           286:        CAST_cbc_encrypt(src, dest, len, &cc->u.cast.key, cc->u.cast.iv,
        !           287:            CAST_ENCRYPT);
        !           288: }
        !           289: void
        !           290: cast_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
        !           291: {
        !           292:        CAST_cbc_encrypt(src, dest, len, &cc->u.cast.key, cc->u.cast.iv,
        !           293:            CAST_DECRYPT);
        !           294: }
        !           295:
        !           296: /* RIJNDAEL */
        !           297:
        !           298: #define RIJNDAEL_BLOCKSIZE 16
        !           299: void
        !           300: rijndael_setkey(CipherContext *cc, const u_char *key, u_int keylen)
        !           301: {
        !           302:        rijndael_set_key(&cc->u.rijndael.enc, (u4byte *)key, 8*keylen, 1);
        !           303:        rijndael_set_key(&cc->u.rijndael.dec, (u4byte *)key, 8*keylen, 0);
        !           304: }
        !           305: void
        !           306: rijndael_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
1.22      markus    307: {
1.26.2.3! jason     308:        if (iv == NULL)
        !           309:                fatal("no IV for %s.", cc->cipher->name);
        !           310:        memcpy((u_char *)cc->u.rijndael.iv, iv, RIJNDAEL_BLOCKSIZE);
1.22      markus    311: }
1.26.2.3! jason     312: void
        !           313: rijndael_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src,
        !           314:     u_int len)
        !           315: {
        !           316:        rijndael_ctx *ctx = &cc->u.rijndael.enc;
        !           317:        u4byte *iv = cc->u.rijndael.iv;
        !           318:        u4byte in[4];
        !           319:        u4byte *cprev, *cnow, *plain;
        !           320:        int i, blocks = len / RIJNDAEL_BLOCKSIZE;
        !           321:        if (len == 0)
        !           322:                return;
        !           323:        if (len % RIJNDAEL_BLOCKSIZE)
        !           324:                fatal("rijndael_cbc_encrypt: bad len %d", len);
        !           325:        cnow  = (u4byte*) dest;
        !           326:        plain = (u4byte*) src;
        !           327:        cprev = iv;
        !           328:        for(i = 0; i < blocks; i++, plain+=4, cnow+=4) {
        !           329:                in[0] = plain[0] ^ cprev[0];
        !           330:                in[1] = plain[1] ^ cprev[1];
        !           331:                in[2] = plain[2] ^ cprev[2];
        !           332:                in[3] = plain[3] ^ cprev[3];
        !           333:                rijndael_encrypt(ctx, in, cnow);
        !           334:                cprev = cnow;
        !           335:        }
        !           336:        memcpy(iv, cprev, RIJNDAEL_BLOCKSIZE);
        !           337: }
        !           338:
        !           339: void
        !           340: rijndael_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src,
        !           341:     u_int len)
        !           342: {
        !           343:        rijndael_ctx *ctx = &cc->u.rijndael.dec;
        !           344:        u4byte *iv = cc->u.rijndael.iv;
        !           345:        u4byte ivsaved[4];
        !           346:        u4byte *cnow =  (u4byte*) (src+len-RIJNDAEL_BLOCKSIZE);
        !           347:        u4byte *plain = (u4byte*) (dest+len-RIJNDAEL_BLOCKSIZE);
        !           348:        u4byte *ivp;
        !           349:        int i, blocks = len / RIJNDAEL_BLOCKSIZE;
        !           350:        if (len == 0)
        !           351:                return;
        !           352:        if (len % RIJNDAEL_BLOCKSIZE)
        !           353:                fatal("rijndael_cbc_decrypt: bad len %d", len);
        !           354:        memcpy(ivsaved, cnow, RIJNDAEL_BLOCKSIZE);
        !           355:        for(i = blocks; i > 0; i--, cnow-=4, plain-=4) {
        !           356:                rijndael_decrypt(ctx, cnow, plain);
        !           357:                ivp =  (i == 1) ? iv : cnow-4;
        !           358:                plain[0] ^= ivp[0];
        !           359:                plain[1] ^= ivp[1];
        !           360:                plain[2] ^= ivp[2];
        !           361:                plain[3] ^= ivp[3];
        !           362:        }
        !           363:        memcpy(iv, ivsaved, RIJNDAEL_BLOCKSIZE);
        !           364: }
        !           365:
        !           366: Cipher ciphers[] = {
        !           367:        { "none",
        !           368:                SSH_CIPHER_NONE, 8, 0,
        !           369:                none_setkey, none_setiv,
        !           370:                none_crypt, none_crypt },
        !           371:        { "des",
        !           372:                SSH_CIPHER_DES, 8, 8,
        !           373:                des_ssh1_setkey, des_ssh1_setiv,
        !           374:                des_ssh1_encrypt, des_ssh1_decrypt },
        !           375:        { "3des",
        !           376:                SSH_CIPHER_3DES, 8, 16,
        !           377:                des3_ssh1_setkey, des3_setiv,
        !           378:                des3_ssh1_encrypt, des3_ssh1_decrypt },
        !           379:        { "blowfish",
        !           380:                SSH_CIPHER_BLOWFISH, 8, 16,
        !           381:                blowfish_setkey, blowfish_setiv,
        !           382:                blowfish_ssh1_encrypt, blowfish_ssh1_decrypt },
        !           383:
        !           384:        { "3des-cbc",
        !           385:                SSH_CIPHER_SSH2, 8, 24,
        !           386:                des3_setkey, des3_setiv,
        !           387:                des3_cbc_encrypt, des3_cbc_decrypt },
        !           388:        { "blowfish-cbc",
        !           389:                SSH_CIPHER_SSH2, 8, 16,
        !           390:                blowfish_setkey, blowfish_setiv,
        !           391:                blowfish_cbc_encrypt, blowfish_cbc_decrypt },
        !           392:        { "cast128-cbc",
        !           393:                SSH_CIPHER_SSH2, 8, 16,
        !           394:                cast_setkey, cast_setiv,
        !           395:                cast_cbc_encrypt, cast_cbc_decrypt },
        !           396:        { "arcfour",
        !           397:                SSH_CIPHER_SSH2, 8, 16,
        !           398:                arcfour_setkey, none_setiv,
        !           399:                arcfour_crypt, arcfour_crypt },
        !           400:        { "aes128-cbc",
        !           401:                SSH_CIPHER_SSH2, 16, 16,
        !           402:                rijndael_setkey, rijndael_setiv,
        !           403:                rijndael_cbc_encrypt, rijndael_cbc_decrypt },
        !           404:        { "aes192-cbc",
        !           405:                SSH_CIPHER_SSH2, 16, 24,
        !           406:                rijndael_setkey, rijndael_setiv,
        !           407:                rijndael_cbc_encrypt, rijndael_cbc_decrypt },
        !           408:        { "aes256-cbc",
        !           409:                SSH_CIPHER_SSH2, 16, 32,
        !           410:                rijndael_setkey, rijndael_setiv,
        !           411:                rijndael_cbc_encrypt, rijndael_cbc_decrypt },
        !           412:        { "rijndael128-cbc",
        !           413:                SSH_CIPHER_SSH2, 16, 16,
        !           414:                rijndael_setkey, rijndael_setiv,
        !           415:                rijndael_cbc_encrypt, rijndael_cbc_decrypt },
        !           416:        { "rijndael192-cbc",
        !           417:                SSH_CIPHER_SSH2, 16, 24,
        !           418:                rijndael_setkey, rijndael_setiv,
        !           419:                rijndael_cbc_encrypt, rijndael_cbc_decrypt },
        !           420:        { "rijndael256-cbc",
        !           421:                SSH_CIPHER_SSH2, 16, 32,
        !           422:                rijndael_setkey, rijndael_setiv,
        !           423:                rijndael_cbc_encrypt, rijndael_cbc_decrypt },
        !           424:        { "rijndael-cbc@lysator.liu.se",
        !           425:                SSH_CIPHER_SSH2, 16, 32,
        !           426:                rijndael_setkey, rijndael_setiv,
        !           427:                rijndael_cbc_encrypt, rijndael_cbc_decrypt },
        !           428:         { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL, NULL, NULL, NULL }
        !           429: };
1.1       deraadt   430:
1.26.2.3! jason     431: /*--*/
1.1       deraadt   432:
1.26.2.3! jason     433: unsigned int
        !           434: cipher_mask_ssh1(int client)
1.1       deraadt   435: {
1.26.2.3! jason     436:        unsigned int mask = 0;
        !           437:        mask |= 1 << SSH_CIPHER_3DES;           /* Mandatory */
        !           438:        mask |= 1 << SSH_CIPHER_BLOWFISH;
        !           439:        if (client) {
        !           440:                mask |= 1 << SSH_CIPHER_DES;
        !           441:        }
        !           442:        return mask;
1.1       deraadt   443: }
                    444:
1.26.2.3! jason     445: Cipher *
        !           446: cipher_by_name(const char *name)
        !           447: {
        !           448:        Cipher *c;
        !           449:        for (c = ciphers; c->name != NULL; c++)
        !           450:                if (strcasecmp(c->name, name) == 0)
        !           451:                        return c;
        !           452:        return NULL;
        !           453: }
        !           454:
        !           455: Cipher *
        !           456: cipher_by_number(int id)
        !           457: {
        !           458:        Cipher *c;
        !           459:        for (c = ciphers; c->name != NULL; c++)
        !           460:                if (c->number == id)
        !           461:                        return c;
        !           462:        return NULL;
        !           463: }
1.24      markus    464:
                    465: #define        CIPHER_SEP      ","
                    466: int
                    467: ciphers_valid(const char *names)
                    468: {
1.26.2.3! jason     469:        Cipher *c;
1.26.2.2  jason     470:        char *ciphers, *cp;
1.24      markus    471:        char *p;
                    472:
1.26.2.1  jason     473:        if (names == NULL || strcmp(names, "") == 0)
1.24      markus    474:                return 0;
1.26.2.2  jason     475:        ciphers = cp = xstrdup(names);
1.26.2.3! jason     476:        for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
1.26.2.2  jason     477:             (p = strsep(&cp, CIPHER_SEP))) {
1.26.2.3! jason     478:                c = cipher_by_name(p);
        !           479:                if (c == NULL || c->number != SSH_CIPHER_SSH2) {
        !           480:                        debug("bad cipher %s [%s]", p, names);
1.24      markus    481:                        xfree(ciphers);
                    482:                        return 0;
1.26.2.3! jason     483:                } else {
        !           484:                        debug3("cipher ok: %s [%s]", p, names);
1.24      markus    485:                }
                    486:        }
1.26.2.3! jason     487:        debug3("ciphers ok: [%s]", names);
1.24      markus    488:        xfree(ciphers);
                    489:        return 1;
                    490: }
                    491:
1.18      markus    492: /*
                    493:  * Parses the name of the cipher.  Returns the number of the corresponding
                    494:  * cipher, or -1 on error.
                    495:  */
1.1       deraadt   496:
1.4       provos    497: int
                    498: cipher_number(const char *name)
1.1       deraadt   499: {
1.26.2.3! jason     500:        Cipher *c;
1.26.2.1  jason     501:        if (name == NULL)
                    502:                return -1;
1.26.2.3! jason     503:        c = cipher_by_name(name);
        !           504:        return (c==NULL) ? -1 : c->number;
1.1       deraadt   505: }
                    506:
1.26.2.3! jason     507: char *
        !           508: cipher_name(int id)
1.1       deraadt   509: {
1.26.2.3! jason     510:        Cipher *c = cipher_by_number(id);
        !           511:        return (c==NULL) ? "<unknown>" : c->name;
1.1       deraadt   512: }
                    513:
1.26      markus    514: void
1.26.2.3! jason     515: cipher_init(CipherContext *cc, Cipher *cipher,
        !           516:     const u_char *key, u_int keylen, const u_char *iv, u_int ivlen)
1.16      markus    517: {
1.26.2.3! jason     518:        if (keylen < cipher->key_len)
        !           519:                fatal("cipher_init: key length %d is insufficient for %s.",
        !           520:                    keylen, cipher->name);
        !           521:        if (iv != NULL && ivlen < cipher->block_size)
        !           522:                fatal("cipher_init: iv length %d is insufficient for %s.",
        !           523:                    ivlen, cipher->name);
        !           524:        cc->cipher = cipher;
        !           525:        cipher->setkey(cc, key, keylen);
        !           526:        cipher->setiv(cc, iv, ivlen);
1.1       deraadt   527: }
1.21      markus    528:
1.26      markus    529: void
1.26.2.3! jason     530: cipher_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
        !           531: {
        !           532:        if (len % cc->cipher->block_size)
        !           533:                fatal("cipher_encrypt: bad plaintext length %d", len);
        !           534:        cc->cipher->encrypt(cc, dest, src, len);
1.21      markus    535: }
                    536:
1.26      markus    537: void
1.26.2.3! jason     538: cipher_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
1.16      markus    539: {
1.26.2.3! jason     540:        if (len % cc->cipher->block_size)
        !           541:                fatal("cipher_decrypt: bad ciphertext length %d", len);
        !           542:        cc->cipher->decrypt(cc, dest, src, len);
1.16      markus    543: }
1.1       deraadt   544:
1.26.2.3! jason     545: /*
        !           546:  * Selects the cipher, and keys if by computing the MD5 checksum of the
        !           547:  * passphrase and using the resulting 16 bytes as the key.
        !           548:  */
1.1       deraadt   549:
1.26      markus    550: void
1.26.2.3! jason     551: cipher_set_key_string(CipherContext *cc, Cipher *cipher,
        !           552:     const char *passphrase)
1.16      markus    553: {
1.26.2.3! jason     554:        MD5_CTX md;
        !           555:        unsigned char digest[16];
        !           556:
        !           557:        MD5_Init(&md);
        !           558:        MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
        !           559:        MD5_Final(digest, &md);
1.16      markus    560:
1.26.2.3! jason     561:        cipher_init(cc, cipher, digest, 16, NULL, 0);
1.16      markus    562:
1.26.2.3! jason     563:        memset(digest, 0, sizeof(digest));
        !           564:        memset(&md, 0, sizeof(md));
1.1       deraadt   565: }