cipher.c (76262) | cipher.c (92559) |
---|---|
1/* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * 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. | 1/* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * 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. | 14 * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved. |
15 * 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 --- 7 unchanged lines hidden (view full) --- 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. 35 */ 36 37#include "includes.h" | 15 * 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 --- 7 unchanged lines hidden (view full) --- 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. 35 */ 36 37#include "includes.h" |
38RCSID("$OpenBSD: cipher.c,v 1.43 2001/02/04 15:32:23 stevesk Exp $"); 39RCSID("$FreeBSD: head/crypto/openssh/cipher.c 76262 2001-05-04 04:14:23Z green $"); | 38RCSID("$OpenBSD: cipher.c,v 1.52 2002/02/18 13:05:32 markus Exp $"); 39RCSID("$FreeBSD: head/crypto/openssh/cipher.c 92559 2002-03-18 10:09:43Z des $"); |
40 41#include "xmalloc.h" 42#include "log.h" 43#include "cipher.h" 44 45#include <openssl/md5.h> | 40 41#include "xmalloc.h" 42#include "log.h" 43#include "cipher.h" 44 45#include <openssl/md5.h> |
46#include "rijndael.h" |
|
46 | 47 |
48static EVP_CIPHER *evp_ssh1_3des(void); 49static EVP_CIPHER *evp_ssh1_bf(void); 50static EVP_CIPHER *evp_rijndael(void); |
|
47 | 51 |
48/* no encryption */ 49void 50none_setkey(CipherContext *cc, const u_char *key, u_int keylen) 51{ 52} 53void 54none_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) 55{ 56} 57void 58none_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) 59{ 60 memcpy(dest, src, len); 61} | 52struct Cipher { 53 char *name; 54 int number; /* for ssh1 only */ 55 u_int block_size; 56 u_int key_len; 57 EVP_CIPHER *(*evptype)(void); 58} ciphers[] = { 59 { "none", SSH_CIPHER_NONE, 8, 0, EVP_enc_null }, 60 { "des", SSH_CIPHER_DES, 8, 8, EVP_des_cbc }, 61 { "3des", SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des }, 62 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf }, |
62 | 63 |
63/* DES */ 64void 65des_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen) 66{ 67 static int dowarn = 1; 68 if (dowarn) { 69 error("Warning: use of DES is strongly discouraged " 70 "due to cryptographic weaknesses"); 71 dowarn = 0; 72 } 73 des_set_key((void *)key, cc->u.des.key); 74} 75void 76des_ssh1_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) 77{ 78 memset(cc->u.des.iv, 0, sizeof(cc->u.des.iv)); 79} 80void 81des_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) 82{ 83 des_ncbc_encrypt(src, dest, len, cc->u.des.key, &cc->u.des.iv, 84 DES_ENCRYPT); 85} 86void 87des_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) 88{ 89 des_ncbc_encrypt(src, dest, len, cc->u.des.key, &cc->u.des.iv, 90 DES_DECRYPT); 91} | 64 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc }, 65 { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc }, 66 { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc }, 67 { "arcfour", SSH_CIPHER_SSH2, 8, 16, EVP_rc4 }, 68 { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, evp_rijndael }, 69 { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, evp_rijndael }, 70 { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, evp_rijndael }, |
92 | 71 |
93/* 3DES */ 94void 95des3_setkey(CipherContext *cc, const u_char *key, u_int keylen) 96{ 97 des_set_key((void *) key, cc->u.des3.key1); 98 des_set_key((void *) (key+8), cc->u.des3.key2); 99 des_set_key((void *) (key+16), cc->u.des3.key3); 100} 101void 102des3_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) 103{ 104 memset(cc->u.des3.iv2, 0, sizeof(cc->u.des3.iv2)); 105 memset(cc->u.des3.iv3, 0, sizeof(cc->u.des3.iv3)); 106 if (iv == NULL) 107 return; 108 memcpy(cc->u.des3.iv3, (char *)iv, 8); 109} 110void 111des3_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) 112{ 113 des_ede3_cbc_encrypt(src, dest, len, 114 cc->u.des3.key1, cc->u.des3.key2, cc->u.des3.key3, 115 &cc->u.des3.iv3, DES_ENCRYPT); 116} 117void 118des3_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) 119{ 120 des_ede3_cbc_encrypt(src, dest, len, 121 cc->u.des3.key1, cc->u.des3.key2, cc->u.des3.key3, 122 &cc->u.des3.iv3, DES_DECRYPT); 123} | 72 { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL } 73}; |
124 | 74 |
125/* 126 * This is used by SSH1: 127 * 128 * What kind of triple DES are these 2 routines? 129 * 130 * Why is there a redundant initialization vector? 131 * 132 * If only iv3 was used, then, this would till effect have been 133 * outer-cbc. However, there is also a private iv1 == iv2 which 134 * perhaps makes differential analysis easier. On the other hand, the 135 * private iv1 probably makes the CRC-32 attack ineffective. This is a 136 * result of that there is no longer any known iv1 to use when 137 * choosing the X block. 138 */ 139void 140des3_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen) 141{ 142 des_set_key((void *) key, cc->u.des3.key1); 143 des_set_key((void *) (key+8), cc->u.des3.key2); 144 if (keylen <= 16) 145 des_set_key((void *) key, cc->u.des3.key3); 146 else 147 des_set_key((void *) (key+16), cc->u.des3.key3); 148} 149void 150des3_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, 151 u_int len) 152{ 153 des_cblock iv1; 154 des_cblock *iv2 = &cc->u.des3.iv2; 155 des_cblock *iv3 = &cc->u.des3.iv3; | 75/*--*/ |
156 | 76 |
157 memcpy(&iv1, iv2, 8); 158 159 des_ncbc_encrypt(src, dest, len, cc->u.des3.key1, &iv1, DES_ENCRYPT); 160 des_ncbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_DECRYPT); 161 des_ncbc_encrypt(dest, dest, len, cc->u.des3.key3, iv3, DES_ENCRYPT); 162} 163void 164des3_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, 165 u_int len) | 77u_int 78cipher_blocksize(Cipher *c) |
166{ | 79{ |
167 des_cblock iv1; 168 des_cblock *iv2 = &cc->u.des3.iv2; 169 des_cblock *iv3 = &cc->u.des3.iv3; 170 171 memcpy(&iv1, iv2, 8); 172 173 des_ncbc_encrypt(src, dest, len, cc->u.des3.key3, iv3, DES_DECRYPT); 174 des_ncbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_ENCRYPT); 175 des_ncbc_encrypt(dest, dest, len, cc->u.des3.key1, &iv1, DES_DECRYPT); | 80 return (c->block_size); |
176} | 81} |
177 178/* Blowfish */ 179void 180blowfish_setkey(CipherContext *cc, const u_char *key, u_int keylen) | 82u_int 83cipher_keylen(Cipher *c) |
181{ | 84{ |
182 BF_set_key(&cc->u.bf.key, keylen, (u_char *)key); | 85 return (c->key_len); |
183} | 86} |
184void 185blowfish_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) 186{ 187 if (iv == NULL) 188 memset(cc->u.bf.iv, 0, 8); 189 else 190 memcpy(cc->u.bf.iv, (char *)iv, 8); 191} 192void 193blowfish_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, 194 u_int len) 195{ 196 BF_cbc_encrypt((void *)src, dest, len, &cc->u.bf.key, cc->u.bf.iv, 197 BF_ENCRYPT); 198} 199void 200blowfish_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, 201 u_int len) 202{ 203 BF_cbc_encrypt((void *)src, dest, len, &cc->u.bf.key, cc->u.bf.iv, 204 BF_DECRYPT); 205} | |
206 | 87 |
207/* 208 * SSH1 uses a variation on Blowfish, all bytes must be swapped before 209 * and after encryption/decryption. Thus the swap_bytes stuff (yuk). 210 */ 211static void 212swap_bytes(const u_char *src, u_char *dst, int n) 213{ 214 char c[4]; 215 216 /* Process 4 bytes every lap. */ 217 for (n = n / 4; n > 0; n--) { 218 c[3] = *src++; 219 c[2] = *src++; 220 c[1] = *src++; 221 c[0] = *src++; 222 223 *dst++ = c[0]; 224 *dst++ = c[1]; 225 *dst++ = c[2]; 226 *dst++ = c[3]; 227 } 228} 229 230void 231blowfish_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, 232 u_int len) 233{ 234 swap_bytes(src, dest, len); 235 BF_cbc_encrypt((void *)dest, dest, len, &cc->u.bf.key, cc->u.bf.iv, 236 BF_ENCRYPT); 237 swap_bytes(dest, dest, len); 238} 239void 240blowfish_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, 241 u_int len) 242{ 243 swap_bytes(src, dest, len); 244 BF_cbc_encrypt((void *)dest, dest, len, &cc->u.bf.key, cc->u.bf.iv, 245 BF_DECRYPT); 246 swap_bytes(dest, dest, len); 247} 248 249/* alleged rc4 */ 250void 251arcfour_setkey(CipherContext *cc, const u_char *key, u_int keylen) 252{ 253 RC4_set_key(&cc->u.rc4, keylen, (u_char *)key); 254} 255void 256arcfour_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) 257{ 258 RC4(&cc->u.rc4, len, (u_char *)src, dest); 259} 260 261/* CAST */ 262void 263cast_setkey(CipherContext *cc, const u_char *key, u_int keylen) 264{ 265 CAST_set_key(&cc->u.cast.key, keylen, (u_char *) key); 266} 267void 268cast_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) 269{ 270 if (iv == NULL) 271 fatal("no IV for %s.", cc->cipher->name); 272 memcpy(cc->u.cast.iv, (char *)iv, 8); 273} 274void 275cast_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) 276{ 277 CAST_cbc_encrypt(src, dest, len, &cc->u.cast.key, cc->u.cast.iv, 278 CAST_ENCRYPT); 279} 280void 281cast_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) 282{ 283 CAST_cbc_encrypt(src, dest, len, &cc->u.cast.key, cc->u.cast.iv, 284 CAST_DECRYPT); 285} 286 287/* RIJNDAEL */ 288 289#define RIJNDAEL_BLOCKSIZE 16 290void 291rijndael_setkey(CipherContext *cc, const u_char *key, u_int keylen) 292{ 293 rijndael_set_key(&cc->u.rijndael.enc, (u4byte *)key, 8*keylen, 1); 294 rijndael_set_key(&cc->u.rijndael.dec, (u4byte *)key, 8*keylen, 0); 295} 296void 297rijndael_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) 298{ 299 if (iv == NULL) 300 fatal("no IV for %s.", cc->cipher->name); 301 memcpy((u_char *)cc->u.rijndael.iv, iv, RIJNDAEL_BLOCKSIZE); 302} 303void 304rijndael_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, 305 u_int len) 306{ 307 rijndael_ctx *ctx = &cc->u.rijndael.enc; 308 u4byte *iv = cc->u.rijndael.iv; 309 u4byte in[4]; 310 u4byte *cprev, *cnow, *plain; 311 int i, blocks = len / RIJNDAEL_BLOCKSIZE; 312 if (len == 0) 313 return; 314 if (len % RIJNDAEL_BLOCKSIZE) 315 fatal("rijndael_cbc_encrypt: bad len %d", len); 316 cnow = (u4byte*) dest; 317 plain = (u4byte*) src; 318 cprev = iv; 319 for(i = 0; i < blocks; i++, plain+=4, cnow+=4) { 320 in[0] = plain[0] ^ cprev[0]; 321 in[1] = plain[1] ^ cprev[1]; 322 in[2] = plain[2] ^ cprev[2]; 323 in[3] = plain[3] ^ cprev[3]; 324 rijndael_encrypt(ctx, in, cnow); 325 cprev = cnow; 326 } 327 memcpy(iv, cprev, RIJNDAEL_BLOCKSIZE); 328} 329 330void 331rijndael_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, 332 u_int len) 333{ 334 rijndael_ctx *ctx = &cc->u.rijndael.dec; 335 u4byte *iv = cc->u.rijndael.iv; 336 u4byte ivsaved[4]; 337 u4byte *cnow = (u4byte*) (src+len-RIJNDAEL_BLOCKSIZE); 338 u4byte *plain = (u4byte*) (dest+len-RIJNDAEL_BLOCKSIZE); 339 u4byte *ivp; 340 int i, blocks = len / RIJNDAEL_BLOCKSIZE; 341 if (len == 0) 342 return; 343 if (len % RIJNDAEL_BLOCKSIZE) 344 fatal("rijndael_cbc_decrypt: bad len %d", len); 345 memcpy(ivsaved, cnow, RIJNDAEL_BLOCKSIZE); 346 for(i = blocks; i > 0; i--, cnow-=4, plain-=4) { 347 rijndael_decrypt(ctx, cnow, plain); 348 ivp = (i == 1) ? iv : cnow-4; 349 plain[0] ^= ivp[0]; 350 plain[1] ^= ivp[1]; 351 plain[2] ^= ivp[2]; 352 plain[3] ^= ivp[3]; 353 } 354 memcpy(iv, ivsaved, RIJNDAEL_BLOCKSIZE); 355} 356 357Cipher ciphers[] = { 358 { "none", 359 SSH_CIPHER_NONE, 8, 0, 360 none_setkey, none_setiv, 361 none_crypt, none_crypt }, 362 { "des", 363 SSH_CIPHER_DES, 8, 8, 364 des_ssh1_setkey, des_ssh1_setiv, 365 des_ssh1_encrypt, des_ssh1_decrypt }, 366 { "3des", 367 SSH_CIPHER_3DES, 8, 16, 368 des3_ssh1_setkey, des3_setiv, 369 des3_ssh1_encrypt, des3_ssh1_decrypt }, 370 { "blowfish", 371 SSH_CIPHER_BLOWFISH, 8, 16, 372 blowfish_setkey, blowfish_setiv, 373 blowfish_ssh1_encrypt, blowfish_ssh1_decrypt }, 374 375 { "3des-cbc", 376 SSH_CIPHER_SSH2, 8, 24, 377 des3_setkey, des3_setiv, 378 des3_cbc_encrypt, des3_cbc_decrypt }, 379 { "blowfish-cbc", 380 SSH_CIPHER_SSH2, 8, 16, 381 blowfish_setkey, blowfish_setiv, 382 blowfish_cbc_encrypt, blowfish_cbc_decrypt }, 383 { "cast128-cbc", 384 SSH_CIPHER_SSH2, 8, 16, 385 cast_setkey, cast_setiv, 386 cast_cbc_encrypt, cast_cbc_decrypt }, 387 { "arcfour", 388 SSH_CIPHER_SSH2, 8, 16, 389 arcfour_setkey, none_setiv, 390 arcfour_crypt, arcfour_crypt }, 391 { "aes128-cbc", 392 SSH_CIPHER_SSH2, 16, 16, 393 rijndael_setkey, rijndael_setiv, 394 rijndael_cbc_encrypt, rijndael_cbc_decrypt }, 395 { "aes192-cbc", 396 SSH_CIPHER_SSH2, 16, 24, 397 rijndael_setkey, rijndael_setiv, 398 rijndael_cbc_encrypt, rijndael_cbc_decrypt }, 399 { "aes256-cbc", 400 SSH_CIPHER_SSH2, 16, 32, 401 rijndael_setkey, rijndael_setiv, 402 rijndael_cbc_encrypt, rijndael_cbc_decrypt }, 403 { "rijndael128-cbc", 404 SSH_CIPHER_SSH2, 16, 16, 405 rijndael_setkey, rijndael_setiv, 406 rijndael_cbc_encrypt, rijndael_cbc_decrypt }, 407 { "rijndael192-cbc", 408 SSH_CIPHER_SSH2, 16, 24, 409 rijndael_setkey, rijndael_setiv, 410 rijndael_cbc_encrypt, rijndael_cbc_decrypt }, 411 { "rijndael256-cbc", 412 SSH_CIPHER_SSH2, 16, 32, 413 rijndael_setkey, rijndael_setiv, 414 rijndael_cbc_encrypt, rijndael_cbc_decrypt }, 415 { "rijndael-cbc@lysator.liu.se", 416 SSH_CIPHER_SSH2, 16, 32, 417 rijndael_setkey, rijndael_setiv, 418 rijndael_cbc_encrypt, rijndael_cbc_decrypt }, 419 { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL, NULL, NULL, NULL } 420}; 421 422/*--*/ 423 | |
424u_int 425cipher_mask_ssh1(int client) 426{ 427 u_int mask = 0; | 88u_int 89cipher_mask_ssh1(int client) 90{ 91 u_int mask = 0; |
428 mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ | 92 mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ |
429 mask |= 1 << SSH_CIPHER_BLOWFISH; 430 if (client) { 431 mask |= 1 << SSH_CIPHER_DES; 432 } 433 return mask; 434} 435 436Cipher * --- 23 unchanged lines hidden (view full) --- 460 Cipher *c; 461 char *ciphers, *cp; 462 char *p; 463 464 if (names == NULL || strcmp(names, "") == 0) 465 return 0; 466 ciphers = cp = xstrdup(names); 467 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; | 93 mask |= 1 << SSH_CIPHER_BLOWFISH; 94 if (client) { 95 mask |= 1 << SSH_CIPHER_DES; 96 } 97 return mask; 98} 99 100Cipher * --- 23 unchanged lines hidden (view full) --- 124 Cipher *c; 125 char *ciphers, *cp; 126 char *p; 127 128 if (names == NULL || strcmp(names, "") == 0) 129 return 0; 130 ciphers = cp = xstrdup(names); 131 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; |
468 (p = strsep(&cp, CIPHER_SEP))) { | 132 (p = strsep(&cp, CIPHER_SEP))) { |
469 c = cipher_by_name(p); 470 if (c == NULL || c->number != SSH_CIPHER_SSH2) { 471 debug("bad cipher %s [%s]", p, names); 472 xfree(ciphers); 473 return 0; 474 } else { 475 debug3("cipher ok: %s [%s]", p, names); 476 } --- 22 unchanged lines hidden (view full) --- 499cipher_name(int id) 500{ 501 Cipher *c = cipher_by_number(id); 502 return (c==NULL) ? "<unknown>" : c->name; 503} 504 505void 506cipher_init(CipherContext *cc, Cipher *cipher, | 133 c = cipher_by_name(p); 134 if (c == NULL || c->number != SSH_CIPHER_SSH2) { 135 debug("bad cipher %s [%s]", p, names); 136 xfree(ciphers); 137 return 0; 138 } else { 139 debug3("cipher ok: %s [%s]", p, names); 140 } --- 22 unchanged lines hidden (view full) --- 163cipher_name(int id) 164{ 165 Cipher *c = cipher_by_number(id); 166 return (c==NULL) ? "<unknown>" : c->name; 167} 168 169void 170cipher_init(CipherContext *cc, Cipher *cipher, |
507 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen) | 171 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, 172 int encrypt) |
508{ | 173{ |
174 static int dowarn = 1; 175 const EVP_CIPHER *type; 176 int klen; 177 178 if (cipher->number == SSH_CIPHER_DES) { 179 if (dowarn) { 180 error("Warning: use of DES is strongly discouraged " 181 "due to cryptographic weaknesses"); 182 dowarn = 0; 183 } 184 if (keylen > 8) 185 keylen = 8; 186 } 187 cc->plaintext = (cipher->number == SSH_CIPHER_NONE); 188 |
|
509 if (keylen < cipher->key_len) 510 fatal("cipher_init: key length %d is insufficient for %s.", 511 keylen, cipher->name); 512 if (iv != NULL && ivlen < cipher->block_size) 513 fatal("cipher_init: iv length %d is insufficient for %s.", 514 ivlen, cipher->name); 515 cc->cipher = cipher; | 189 if (keylen < cipher->key_len) 190 fatal("cipher_init: key length %d is insufficient for %s.", 191 keylen, cipher->name); 192 if (iv != NULL && ivlen < cipher->block_size) 193 fatal("cipher_init: iv length %d is insufficient for %s.", 194 ivlen, cipher->name); 195 cc->cipher = cipher; |
516 cipher->setkey(cc, key, keylen); 517 cipher->setiv(cc, iv, ivlen); | 196 197 type = (*cipher->evptype)(); 198 199 EVP_CIPHER_CTX_init(&cc->evp); 200 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, 201 (encrypt == CIPHER_ENCRYPT)) == 0) 202 fatal("cipher_init: EVP_CipherInit failed for %s", 203 cipher->name); 204 klen = EVP_CIPHER_CTX_key_length(&cc->evp); 205 if (klen > 0 && keylen != klen) { 206 debug("cipher_init: set keylen (%d -> %d)", klen, keylen); 207 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) 208 fatal("cipher_init: set keylen failed (%d -> %d)", 209 klen, keylen); 210 } 211 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) 212 fatal("cipher_init: EVP_CipherInit: set key failed for %s", 213 cipher->name); |
518} 519 520void | 214} 215 216void |
521cipher_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) | 217cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) |
522{ 523 if (len % cc->cipher->block_size) 524 fatal("cipher_encrypt: bad plaintext length %d", len); | 218{ 219 if (len % cc->cipher->block_size) 220 fatal("cipher_encrypt: bad plaintext length %d", len); |
525 cc->cipher->encrypt(cc, dest, src, len); | 221 if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0) 222 fatal("evp_crypt: EVP_Cipher failed"); |
526} 527 528void | 223} 224 225void |
529cipher_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) | 226cipher_cleanup(CipherContext *cc) |
530{ | 227{ |
531 if (len % cc->cipher->block_size) 532 fatal("cipher_decrypt: bad ciphertext length %d", len); 533 cc->cipher->decrypt(cc, dest, src, len); | 228 if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) 229 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); |
534} 535 536/* 537 * Selects the cipher, and keys if by computing the MD5 checksum of the 538 * passphrase and using the resulting 16 bytes as the key. 539 */ 540 541void 542cipher_set_key_string(CipherContext *cc, Cipher *cipher, | 230} 231 232/* 233 * Selects the cipher, and keys if by computing the MD5 checksum of the 234 * passphrase and using the resulting 16 bytes as the key. 235 */ 236 237void 238cipher_set_key_string(CipherContext *cc, Cipher *cipher, |
543 const char *passphrase) | 239 const char *passphrase, int encrypt) |
544{ 545 MD5_CTX md; 546 u_char digest[16]; 547 548 MD5_Init(&md); 549 MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); 550 MD5_Final(digest, &md); 551 | 240{ 241 MD5_CTX md; 242 u_char digest[16]; 243 244 MD5_Init(&md); 245 MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); 246 MD5_Final(digest, &md); 247 |
552 cipher_init(cc, cipher, digest, 16, NULL, 0); | 248 cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt); |
553 554 memset(digest, 0, sizeof(digest)); 555 memset(&md, 0, sizeof(md)); 556} | 249 250 memset(digest, 0, sizeof(digest)); 251 memset(&md, 0, sizeof(md)); 252} |
253 254/* Implementations for other non-EVP ciphers */ 255 256/* 257 * This is used by SSH1: 258 * 259 * What kind of triple DES are these 2 routines? 260 * 261 * Why is there a redundant initialization vector? 262 * 263 * If only iv3 was used, then, this would till effect have been 264 * outer-cbc. However, there is also a private iv1 == iv2 which 265 * perhaps makes differential analysis easier. On the other hand, the 266 * private iv1 probably makes the CRC-32 attack ineffective. This is a 267 * result of that there is no longer any known iv1 to use when 268 * choosing the X block. 269 */ 270struct ssh1_3des_ctx 271{ 272 EVP_CIPHER_CTX k1, k2, k3; 273}; 274static int 275ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, 276 int enc) 277{ 278 struct ssh1_3des_ctx *c; 279 u_char *k1, *k2, *k3; 280 281 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { 282 c = xmalloc(sizeof(*c)); 283 EVP_CIPHER_CTX_set_app_data(ctx, c); 284 } 285 if (key == NULL) 286 return (1); 287 if (enc == -1) 288 enc = ctx->encrypt; 289 k1 = k2 = k3 = (u_char *) key; 290 k2 += 8; 291 if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { 292 if (enc) 293 k3 += 16; 294 else 295 k1 += 16; 296 } 297 EVP_CIPHER_CTX_init(&c->k1); 298 EVP_CIPHER_CTX_init(&c->k2); 299 EVP_CIPHER_CTX_init(&c->k3); 300 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || 301 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || 302 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { 303 memset(c, 0, sizeof(*c)); 304 xfree(c); 305 EVP_CIPHER_CTX_set_app_data(ctx, NULL); 306 return (0); 307 } 308 return (1); 309} 310static int 311ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len) 312{ 313 struct ssh1_3des_ctx *c; 314 315 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { 316 error("ssh1_3des_cbc: no context"); 317 return (0); 318 } 319 if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || 320 EVP_Cipher(&c->k2, dest, dest, len) == 0 || 321 EVP_Cipher(&c->k3, dest, dest, len) == 0) 322 return (0); 323 return (1); 324} 325static int 326ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) 327{ 328 struct ssh1_3des_ctx *c; 329 330 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { 331 memset(c, 0, sizeof(*c)); 332 xfree(c); 333 EVP_CIPHER_CTX_set_app_data(ctx, NULL); 334 } 335 return (1); 336} 337static EVP_CIPHER * 338evp_ssh1_3des(void) 339{ 340 static EVP_CIPHER ssh1_3des; 341 342 memset(&ssh1_3des, 0, sizeof(EVP_CIPHER)); 343 ssh1_3des.nid = NID_undef; 344 ssh1_3des.block_size = 8; 345 ssh1_3des.iv_len = 0; 346 ssh1_3des.key_len = 16; 347 ssh1_3des.init = ssh1_3des_init; 348 ssh1_3des.cleanup = ssh1_3des_cleanup; 349 ssh1_3des.do_cipher = ssh1_3des_cbc; 350 ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; 351 return (&ssh1_3des); 352} 353 354/* 355 * SSH1 uses a variation on Blowfish, all bytes must be swapped before 356 * and after encryption/decryption. Thus the swap_bytes stuff (yuk). 357 */ 358static void 359swap_bytes(const u_char *src, u_char *dst, int n) 360{ 361 u_char c[4]; 362 363 /* Process 4 bytes every lap. */ 364 for (n = n / 4; n > 0; n--) { 365 c[3] = *src++; 366 c[2] = *src++; 367 c[1] = *src++; 368 c[0] = *src++; 369 370 *dst++ = c[0]; 371 *dst++ = c[1]; 372 *dst++ = c[2]; 373 *dst++ = c[3]; 374 } 375} 376static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL; 377static int 378bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len) 379{ 380 int ret; 381 382 swap_bytes(in, out, len); 383 ret = (*orig_bf)(ctx, out, out, len); 384 swap_bytes(out, out, len); 385 return (ret); 386} 387static EVP_CIPHER * 388evp_ssh1_bf(void) 389{ 390 static EVP_CIPHER ssh1_bf; 391 392 memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER)); 393 orig_bf = ssh1_bf.do_cipher; 394 ssh1_bf.nid = NID_undef; 395 ssh1_bf.do_cipher = bf_ssh1_cipher; 396 ssh1_bf.key_len = 32; 397 return (&ssh1_bf); 398} 399 400/* RIJNDAEL */ 401#define RIJNDAEL_BLOCKSIZE 16 402struct ssh_rijndael_ctx 403{ 404 rijndael_ctx r_ctx; 405 u_char r_iv[RIJNDAEL_BLOCKSIZE]; 406}; 407 408static int 409ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, 410 int enc) 411{ 412 struct ssh_rijndael_ctx *c; 413 414 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { 415 c = xmalloc(sizeof(*c)); 416 EVP_CIPHER_CTX_set_app_data(ctx, c); 417 } 418 if (key != NULL) { 419 if (enc == -1) 420 enc = ctx->encrypt; 421 rijndael_set_key(&c->r_ctx, (u_char *)key, 422 8*EVP_CIPHER_CTX_key_length(ctx), enc); 423 } 424 if (iv != NULL) 425 memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE); 426 return (1); 427} 428static int 429ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, 430 u_int len) 431{ 432 struct ssh_rijndael_ctx *c; 433 u_char buf[RIJNDAEL_BLOCKSIZE]; 434 u_char *cprev, *cnow, *plain, *ivp; 435 int i, j, blocks = len / RIJNDAEL_BLOCKSIZE; 436 437 if (len == 0) 438 return (1); 439 if (len % RIJNDAEL_BLOCKSIZE) 440 fatal("ssh_rijndael_cbc: bad len %d", len); 441 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { 442 error("ssh_rijndael_cbc: no context"); 443 return (0); 444 } 445 if (ctx->encrypt) { 446 cnow = dest; 447 plain = (u_char *)src; 448 cprev = c->r_iv; 449 for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE, 450 cnow+=RIJNDAEL_BLOCKSIZE) { 451 for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++) 452 buf[j] = plain[j] ^ cprev[j]; 453 rijndael_encrypt(&c->r_ctx, buf, cnow); 454 cprev = cnow; 455 } 456 memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE); 457 } else { 458 cnow = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE); 459 plain = dest+len-RIJNDAEL_BLOCKSIZE; 460 461 memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE); 462 for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE, 463 plain-=RIJNDAEL_BLOCKSIZE) { 464 rijndael_decrypt(&c->r_ctx, cnow, plain); 465 ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE; 466 for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++) 467 plain[j] ^= ivp[j]; 468 } 469 memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE); 470 } 471 return (1); 472} 473static int 474ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx) 475{ 476 struct ssh_rijndael_ctx *c; 477 478 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { 479 memset(c, 0, sizeof(*c)); 480 xfree(c); 481 EVP_CIPHER_CTX_set_app_data(ctx, NULL); 482 } 483 return (1); 484} 485static EVP_CIPHER * 486evp_rijndael(void) 487{ 488 static EVP_CIPHER rijndal_cbc; 489 490 memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER)); 491 rijndal_cbc.nid = NID_undef; 492 rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE; 493 rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE; 494 rijndal_cbc.key_len = 16; 495 rijndal_cbc.init = ssh_rijndael_init; 496 rijndal_cbc.cleanup = ssh_rijndael_cleanup; 497 rijndal_cbc.do_cipher = ssh_rijndael_cbc; 498 rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | 499 EVP_CIPH_ALWAYS_CALL_INIT; 500 return (&rijndal_cbc); 501} |
|