cipher.c revision 137019
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. 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 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. 35 */ 36 37#include "includes.h" 38RCSID("$OpenBSD: cipher.c,v 1.71 2004/07/28 09:40:29 markus Exp $"); 39 40#include "xmalloc.h" 41#include "log.h" 42#include "cipher.h" 43 44#include <openssl/md5.h> 45 46#if OPENSSL_VERSION_NUMBER < 0x00906000L 47#define SSH_OLD_EVP 48#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data) 49#endif 50 51#if OPENSSL_VERSION_NUMBER < 0x00907000L 52extern const EVP_CIPHER *evp_rijndael(void); 53extern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); 54#endif 55 56#if !defined(EVP_CTRL_SET_ACSS_MODE) 57# if (OPENSSL_VERSION_NUMBER >= 0x00907000L) 58extern const EVP_CIPHER *evp_acss(void); 59# define EVP_acss evp_acss 60# define EVP_CTRL_SET_ACSS_MODE xxx /* used below */ 61# else 62# define EVP_acss NULL /* Don't try to support ACSS on older OpenSSL */ 63# endif /* (OPENSSL_VERSION_NUMBER >= 0x00906000L) */ 64#endif /* !defined(EVP_CTRL_SET_ACSS_MODE) */ 65 66extern const EVP_CIPHER *evp_ssh1_bf(void); 67extern const EVP_CIPHER *evp_ssh1_3des(void); 68extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); 69extern const EVP_CIPHER *evp_aes_128_ctr(void); 70extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); 71 72struct Cipher { 73 char *name; 74 int number; /* for ssh1 only */ 75 u_int block_size; 76 u_int key_len; 77 const EVP_CIPHER *(*evptype)(void); 78} ciphers[] = { 79 { "none", SSH_CIPHER_NONE, 8, 0, EVP_enc_null }, 80 { "des", SSH_CIPHER_DES, 8, 8, EVP_des_cbc }, 81 { "3des", SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des }, 82 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf }, 83 84 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc }, 85 { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc }, 86 { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc }, 87 { "arcfour", SSH_CIPHER_SSH2, 8, 16, EVP_rc4 }, 88#if OPENSSL_VERSION_NUMBER < 0x00907000L 89 { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, evp_rijndael }, 90 { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, evp_rijndael }, 91 { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, evp_rijndael }, 92 { "rijndael-cbc@lysator.liu.se", 93 SSH_CIPHER_SSH2, 16, 32, evp_rijndael }, 94#else 95 { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, EVP_aes_128_cbc }, 96 { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, EVP_aes_192_cbc }, 97 { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc }, 98 { "rijndael-cbc@lysator.liu.se", 99 SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc }, 100#endif 101#if OPENSSL_VERSION_NUMBER >= 0x00905000L 102 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr }, 103 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr }, 104 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr }, 105#endif 106#if defined(EVP_CTRL_SET_ACSS_MODE) 107 { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, EVP_acss }, 108#endif 109 { NULL, SSH_CIPHER_INVALID, 0, 0, NULL } 110}; 111 112/*--*/ 113 114u_int 115cipher_blocksize(const Cipher *c) 116{ 117 return (c->block_size); 118} 119 120u_int 121cipher_keylen(const Cipher *c) 122{ 123 return (c->key_len); 124} 125 126u_int 127cipher_get_number(const Cipher *c) 128{ 129 return (c->number); 130} 131 132u_int 133cipher_mask_ssh1(int client) 134{ 135 u_int mask = 0; 136 mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ 137 mask |= 1 << SSH_CIPHER_BLOWFISH; 138 if (client) { 139 mask |= 1 << SSH_CIPHER_DES; 140 } 141 return mask; 142} 143 144Cipher * 145cipher_by_name(const char *name) 146{ 147 Cipher *c; 148 for (c = ciphers; c->name != NULL; c++) 149 if (strcasecmp(c->name, name) == 0) 150 return c; 151 return NULL; 152} 153 154Cipher * 155cipher_by_number(int id) 156{ 157 Cipher *c; 158 for (c = ciphers; c->name != NULL; c++) 159 if (c->number == id) 160 return c; 161 return NULL; 162} 163 164#define CIPHER_SEP "," 165int 166ciphers_valid(const char *names) 167{ 168 Cipher *c; 169 char *cipher_list, *cp; 170 char *p; 171 172 if (names == NULL || strcmp(names, "") == 0) 173 return 0; 174 cipher_list = cp = xstrdup(names); 175 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; 176 (p = strsep(&cp, CIPHER_SEP))) { 177 c = cipher_by_name(p); 178 if (c == NULL || c->number != SSH_CIPHER_SSH2) { 179 debug("bad cipher %s [%s]", p, names); 180 xfree(cipher_list); 181 return 0; 182 } else { 183 debug3("cipher ok: %s [%s]", p, names); 184 } 185 } 186 debug3("ciphers ok: [%s]", names); 187 xfree(cipher_list); 188 return 1; 189} 190 191/* 192 * Parses the name of the cipher. Returns the number of the corresponding 193 * cipher, or -1 on error. 194 */ 195 196int 197cipher_number(const char *name) 198{ 199 Cipher *c; 200 if (name == NULL) 201 return -1; 202 c = cipher_by_name(name); 203 return (c==NULL) ? -1 : c->number; 204} 205 206char * 207cipher_name(int id) 208{ 209 Cipher *c = cipher_by_number(id); 210 return (c==NULL) ? "<unknown>" : c->name; 211} 212 213void 214cipher_init(CipherContext *cc, Cipher *cipher, 215 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, 216 int do_encrypt) 217{ 218 static int dowarn = 1; 219#ifdef SSH_OLD_EVP 220 EVP_CIPHER *type; 221#else 222 const EVP_CIPHER *type; 223#endif 224 int klen; 225 226 if (cipher->number == SSH_CIPHER_DES) { 227 if (dowarn) { 228 error("Warning: use of DES is strongly discouraged " 229 "due to cryptographic weaknesses"); 230 dowarn = 0; 231 } 232 if (keylen > 8) 233 keylen = 8; 234 } 235 cc->plaintext = (cipher->number == SSH_CIPHER_NONE); 236 237 if (keylen < cipher->key_len) 238 fatal("cipher_init: key length %d is insufficient for %s.", 239 keylen, cipher->name); 240 if (iv != NULL && ivlen < cipher->block_size) 241 fatal("cipher_init: iv length %d is insufficient for %s.", 242 ivlen, cipher->name); 243 cc->cipher = cipher; 244 245 type = (*cipher->evptype)(); 246 247 EVP_CIPHER_CTX_init(&cc->evp); 248#ifdef SSH_OLD_EVP 249 if (type->key_len > 0 && type->key_len != keylen) { 250 debug("cipher_init: set keylen (%d -> %d)", 251 type->key_len, keylen); 252 type->key_len = keylen; 253 } 254 EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv, 255 (do_encrypt == CIPHER_ENCRYPT)); 256#else 257 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, 258 (do_encrypt == CIPHER_ENCRYPT)) == 0) 259 fatal("cipher_init: EVP_CipherInit failed for %s", 260 cipher->name); 261 klen = EVP_CIPHER_CTX_key_length(&cc->evp); 262 if (klen > 0 && keylen != klen) { 263 debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); 264 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) 265 fatal("cipher_init: set keylen failed (%d -> %d)", 266 klen, keylen); 267 } 268 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) 269 fatal("cipher_init: EVP_CipherInit: set key failed for %s", 270 cipher->name); 271#endif 272} 273 274void 275cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) 276{ 277 if (len % cc->cipher->block_size) 278 fatal("cipher_encrypt: bad plaintext length %d", len); 279#ifdef SSH_OLD_EVP 280 EVP_Cipher(&cc->evp, dest, (u_char *)src, len); 281#else 282 if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0) 283 fatal("evp_crypt: EVP_Cipher failed"); 284#endif 285} 286 287void 288cipher_cleanup(CipherContext *cc) 289{ 290#ifdef SSH_OLD_EVP 291 EVP_CIPHER_CTX_cleanup(&cc->evp); 292#else 293 if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) 294 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); 295#endif 296} 297 298/* 299 * Selects the cipher, and keys if by computing the MD5 checksum of the 300 * passphrase and using the resulting 16 bytes as the key. 301 */ 302 303void 304cipher_set_key_string(CipherContext *cc, Cipher *cipher, 305 const char *passphrase, int do_encrypt) 306{ 307 MD5_CTX md; 308 u_char digest[16]; 309 310 MD5_Init(&md); 311 MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); 312 MD5_Final(digest, &md); 313 314 cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); 315 316 memset(digest, 0, sizeof(digest)); 317 memset(&md, 0, sizeof(md)); 318} 319 320/* 321 * Exports an IV from the CipherContext required to export the key 322 * state back from the unprivileged child to the privileged parent 323 * process. 324 */ 325 326int 327cipher_get_keyiv_len(const CipherContext *cc) 328{ 329 Cipher *c = cc->cipher; 330 int ivlen; 331 332 if (c->number == SSH_CIPHER_3DES) 333 ivlen = 24; 334 else 335 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); 336 return (ivlen); 337} 338 339void 340cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) 341{ 342 Cipher *c = cc->cipher; 343 int evplen; 344 345 switch (c->number) { 346 case SSH_CIPHER_SSH2: 347 case SSH_CIPHER_DES: 348 case SSH_CIPHER_BLOWFISH: 349 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 350 if (evplen == 0) 351 return; 352 if (evplen != len) 353 fatal("%s: wrong iv length %d != %d", __func__, 354 evplen, len); 355#if OPENSSL_VERSION_NUMBER < 0x00907000L 356 if (c->evptype == evp_rijndael) 357 ssh_rijndael_iv(&cc->evp, 0, iv, len); 358 else 359#endif 360 if (c->evptype == evp_aes_128_ctr) 361 ssh_aes_ctr_iv(&cc->evp, 0, iv, len); 362 else 363 memcpy(iv, cc->evp.iv, len); 364 break; 365 case SSH_CIPHER_3DES: 366 ssh1_3des_iv(&cc->evp, 0, iv, 24); 367 break; 368 default: 369 fatal("%s: bad cipher %d", __func__, c->number); 370 } 371} 372 373void 374cipher_set_keyiv(CipherContext *cc, u_char *iv) 375{ 376 Cipher *c = cc->cipher; 377 int evplen = 0; 378 379 switch (c->number) { 380 case SSH_CIPHER_SSH2: 381 case SSH_CIPHER_DES: 382 case SSH_CIPHER_BLOWFISH: 383 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 384 if (evplen == 0) 385 return; 386#if OPENSSL_VERSION_NUMBER < 0x00907000L 387 if (c->evptype == evp_rijndael) 388 ssh_rijndael_iv(&cc->evp, 1, iv, evplen); 389 else 390#endif 391 if (c->evptype == evp_aes_128_ctr) 392 ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); 393 else 394 memcpy(cc->evp.iv, iv, evplen); 395 break; 396 case SSH_CIPHER_3DES: 397 ssh1_3des_iv(&cc->evp, 1, iv, 24); 398 break; 399 default: 400 fatal("%s: bad cipher %d", __func__, c->number); 401 } 402} 403 404#if OPENSSL_VERSION_NUMBER < 0x00907000L 405#define EVP_X_STATE(evp) &(evp).c 406#define EVP_X_STATE_LEN(evp) sizeof((evp).c) 407#else 408#define EVP_X_STATE(evp) (evp).cipher_data 409#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size 410#endif 411 412int 413cipher_get_keycontext(const CipherContext *cc, u_char *dat) 414{ 415 Cipher *c = cc->cipher; 416 int plen = 0; 417 418 if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { 419 plen = EVP_X_STATE_LEN(cc->evp); 420 if (dat == NULL) 421 return (plen); 422 memcpy(dat, EVP_X_STATE(cc->evp), plen); 423 } 424 return (plen); 425} 426 427void 428cipher_set_keycontext(CipherContext *cc, u_char *dat) 429{ 430 Cipher *c = cc->cipher; 431 int plen; 432 433 if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { 434 plen = EVP_X_STATE_LEN(cc->evp); 435 memcpy(EVP_X_STATE(cc->evp), dat, plen); 436 } 437} 438