1 /* $NetBSD: cipher.c,v 1.9 2016/12/25 00:07:47 christos Exp $ */ 2 /* $OpenBSD: cipher.c,v 1.102 2016/08/03 05:41:57 djm Exp $ */ 3 4 /* 5 * Author: Tatu Ylonen <ylo@cs.hut.fi> 6 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * All rights reserved 8 * 9 * As far as I am concerned, the code I have written for this software 10 * can be used freely for any purpose. Any derived versions of this 11 * software must be clearly marked as such, and if the derived work is 12 * incompatible with the protocol description in the RFC file, it must be 13 * called by a name other than "ssh" or "Secure Shell". 14 * 15 * 16 * Copyright (c) 1999 Niels Provos. All rights reserved. 17 * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved. 18 * 19 * Redistribution and use in source and binary forms, with or without 20 * modification, are permitted provided that the following conditions 21 * are met: 22 * 1. Redistributions of source code must retain the above copyright 23 * notice, this list of conditions and the following disclaimer. 24 * 2. Redistributions in binary form must reproduce the above copyright 25 * notice, this list of conditions and the following disclaimer in the 26 * documentation and/or other materials provided with the distribution. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 29 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 31 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 33 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 #include "includes.h" 41 __RCSID("$NetBSD: cipher.c,v 1.9 2016/12/25 00:07:47 christos Exp $"); 42 #include <sys/types.h> 43 44 #include <string.h> 45 #include <stdarg.h> 46 #include <stdio.h> 47 48 #include "cipher.h" 49 #include "misc.h" 50 #include "sshbuf.h" 51 #include "ssherr.h" 52 #include "digest.h" 53 54 #ifdef WITH_SSH1 55 extern const EVP_CIPHER *evp_ssh1_bf(void); 56 extern const EVP_CIPHER *evp_ssh1_3des(void); 57 extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); 58 #endif 59 60 struct sshcipher_ctx { 61 int plaintext; 62 int encrypt; 63 EVP_CIPHER_CTX *evp; 64 struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ 65 struct aesctr_ctx ac_ctx; /* XXX union with evp? */ 66 const struct sshcipher *cipher; 67 }; 68 69 struct sshcipher { 70 const char *name; 71 int number; /* for ssh1 only */ 72 u_int block_size; 73 u_int key_len; 74 u_int iv_len; /* defaults to block_size */ 75 u_int auth_len; 76 u_int discard_len; 77 u_int flags; 78 #define CFLAG_CBC (1<<0) 79 #define CFLAG_CHACHAPOLY (1<<1) 80 #define CFLAG_AESCTR (1<<2) 81 #define CFLAG_NONE (1<<3) 82 #ifdef WITH_OPENSSL 83 const EVP_CIPHER *(*evptype)(void); 84 #else 85 void *ignored; 86 #endif 87 }; 88 89 static const struct sshcipher ciphers[] = { 90 #ifdef WITH_SSH1 91 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, 92 { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, 93 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, 94 #endif 95 #ifdef WITH_OPENSSL 96 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, 97 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, 98 { "blowfish-cbc", 99 SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, 100 { "cast128-cbc", 101 SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc }, 102 { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 }, 103 { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 }, 104 { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 }, 105 { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, 106 { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, 107 { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, 108 { "rijndael-cbc@lysator.liu.se", 109 SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, 110 #ifdef AES_CTR_MT 111 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, evp_aes_ctr_mt }, 112 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, evp_aes_ctr_mt }, 113 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, evp_aes_ctr_mt }, 114 #else 115 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, 116 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, 117 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, 118 #endif 119 { "aes128-gcm@openssh.com", 120 SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, 121 { "aes256-gcm@openssh.com", 122 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, 123 #else 124 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, 125 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, 126 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL }, 127 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL }, 128 #endif 129 { "chacha20-poly1305@openssh.com", 130 SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, 131 132 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } 133 }; 134 135 /*--*/ 136 137 /* Returns a comma-separated list of supported ciphers. */ 138 char * 139 cipher_alg_list(char sep, int auth_only) 140 { 141 char *tmp, *ret = NULL; 142 size_t nlen, rlen = 0; 143 const struct sshcipher *c; 144 145 for (c = ciphers; c->name != NULL; c++) { 146 if (c->number != SSH_CIPHER_SSH2) 147 continue; 148 if (auth_only && c->auth_len == 0) 149 continue; 150 if (ret != NULL) 151 ret[rlen++] = sep; 152 nlen = strlen(c->name); 153 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { 154 free(ret); 155 return NULL; 156 } 157 ret = tmp; 158 memcpy(ret + rlen, c->name, nlen + 1); 159 rlen += nlen; 160 } 161 return ret; 162 } 163 164 u_int 165 cipher_blocksize(const struct sshcipher *c) 166 { 167 return (c->block_size); 168 } 169 170 u_int 171 cipher_keylen(const struct sshcipher *c) 172 { 173 return (c->key_len); 174 } 175 176 u_int 177 cipher_seclen(const struct sshcipher *c) 178 { 179 if (strcmp("3des-cbc", c->name) == 0) 180 return 14; 181 return cipher_keylen(c); 182 } 183 184 u_int 185 cipher_authlen(const struct sshcipher *c) 186 { 187 return (c->auth_len); 188 } 189 190 u_int 191 cipher_ivlen(const struct sshcipher *c) 192 { 193 /* 194 * Default is cipher block size, except for chacha20+poly1305 that 195 * needs no IV. XXX make iv_len == -1 default? 196 */ 197 return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ? 198 c->iv_len : c->block_size; 199 } 200 201 u_int 202 cipher_get_number(const struct sshcipher *c) 203 { 204 return (c->number); 205 } 206 207 u_int 208 cipher_is_cbc(const struct sshcipher *c) 209 { 210 return (c->flags & CFLAG_CBC) != 0; 211 } 212 213 u_int 214 cipher_ctx_is_plaintext(struct sshcipher_ctx *cc) 215 { 216 return cc->plaintext; 217 } 218 219 u_int 220 cipher_ctx_get_number(struct sshcipher_ctx *cc) 221 { 222 return cc->cipher->number; 223 } 224 225 u_int 226 cipher_mask_ssh1(int client) 227 { 228 u_int mask = 0; 229 mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ 230 mask |= 1 << SSH_CIPHER_BLOWFISH; 231 if (client) { 232 mask |= 1 << SSH_CIPHER_DES; 233 } 234 return mask; 235 } 236 237 const struct sshcipher * 238 cipher_by_name(const char *name) 239 { 240 const struct sshcipher *c; 241 for (c = ciphers; c->name != NULL; c++) 242 if (strcmp(c->name, name) == 0) 243 return c; 244 return NULL; 245 } 246 247 const struct sshcipher * 248 cipher_by_number(int id) 249 { 250 const struct sshcipher *c; 251 for (c = ciphers; c->name != NULL; c++) 252 if (c->number == id) 253 return c; 254 return NULL; 255 } 256 257 #define CIPHER_SEP "," 258 int 259 ciphers_valid(const char *names) 260 { 261 const struct sshcipher *c; 262 char *cipher_list, *cp; 263 char *p; 264 265 if (names == NULL || strcmp(names, "") == 0) 266 return 0; 267 if ((cipher_list = cp = strdup(names)) == NULL) 268 return 0; 269 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; 270 (p = strsep(&cp, CIPHER_SEP))) { 271 c = cipher_by_name(p); 272 if (c == NULL || (c->number != SSH_CIPHER_SSH2 && 273 c->number != SSH_CIPHER_NONE)) { 274 free(cipher_list); 275 return 0; 276 } 277 } 278 free(cipher_list); 279 return 1; 280 } 281 282 /* 283 * Parses the name of the cipher. Returns the number of the corresponding 284 * cipher, or -1 on error. 285 */ 286 287 int 288 cipher_number(const char *name) 289 { 290 const struct sshcipher *c; 291 if (name == NULL) 292 return -1; 293 for (c = ciphers; c->name != NULL; c++) 294 if (strcasecmp(c->name, name) == 0) 295 return c->number; 296 return -1; 297 } 298 299 const char * 300 cipher_name(int id) 301 { 302 const struct sshcipher *c = cipher_by_number(id); 303 return (c==NULL) ? "<unknown>" : c->name; 304 } 305 306 const char * 307 cipher_warning_message(const struct sshcipher_ctx *cc) 308 { 309 if (cc == NULL || cc->cipher == NULL) 310 return NULL; 311 if (cc->cipher->number == SSH_CIPHER_DES) 312 return "use of DES is strongly discouraged due to " 313 "cryptographic weaknesses"; 314 return NULL; 315 } 316 317 int 318 cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, 319 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, 320 int do_encrypt) 321 { 322 struct sshcipher_ctx *cc = NULL; 323 int ret = SSH_ERR_INTERNAL_ERROR; 324 #ifdef WITH_OPENSSL 325 const EVP_CIPHER *type; 326 int klen; 327 u_char *junk, *discard; 328 #endif 329 330 *ccp = NULL; 331 if ((cc = calloc(sizeof(*cc), 1)) == NULL) 332 return SSH_ERR_ALLOC_FAIL; 333 334 if (cipher->number == SSH_CIPHER_DES) { 335 if (keylen > 8) 336 keylen = 8; 337 } 338 339 cc->plaintext = (cipher->number == SSH_CIPHER_NONE); 340 cc->encrypt = do_encrypt; 341 342 if (keylen < cipher->key_len || 343 (iv != NULL && ivlen < cipher_ivlen(cipher))) { 344 ret = SSH_ERR_INVALID_ARGUMENT; 345 goto out; 346 } 347 348 cc->cipher = cipher; 349 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 350 ret = chachapoly_init(&cc->cp_ctx, key, keylen); 351 goto out; 352 } 353 #ifndef WITH_OPENSSL 354 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 355 aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); 356 aesctr_ivsetup(&cc->ac_ctx, iv); 357 ret = 0; 358 goto out; 359 } 360 if ((cc->cipher->flags & CFLAG_NONE) != 0) { 361 ret = 0; 362 goto out; 363 } 364 ret = SSH_ERR_INVALID_ARGUMENT; 365 goto out; 366 #else /* WITH_OPENSSL */ 367 type = (*cipher->evptype)(); 368 if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) { 369 ret = SSH_ERR_ALLOC_FAIL; 370 goto out; 371 } 372 if (EVP_CipherInit(cc->evp, type, NULL, (const u_char *)iv, 373 (do_encrypt == CIPHER_ENCRYPT)) == 0) { 374 ret = SSH_ERR_LIBCRYPTO_ERROR; 375 goto out; 376 } 377 if (cipher_authlen(cipher) && 378 !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, 379 -1, __UNCONST(iv))) { 380 ret = SSH_ERR_LIBCRYPTO_ERROR; 381 goto out; 382 } 383 klen = EVP_CIPHER_CTX_key_length(cc->evp); 384 if (klen > 0 && keylen != (u_int)klen) { 385 if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) { 386 ret = SSH_ERR_LIBCRYPTO_ERROR; 387 goto out; 388 } 389 } 390 if (EVP_CipherInit(cc->evp, NULL, __UNCONST(key), NULL, -1) == 0) { 391 ret = SSH_ERR_LIBCRYPTO_ERROR; 392 goto out; 393 } 394 395 if (cipher->discard_len > 0) { 396 if ((junk = malloc(cipher->discard_len)) == NULL || 397 (discard = malloc(cipher->discard_len)) == NULL) { 398 free(junk); 399 ret = SSH_ERR_ALLOC_FAIL; 400 goto out; 401 } 402 ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len); 403 explicit_bzero(discard, cipher->discard_len); 404 free(junk); 405 free(discard); 406 if (ret != 1) { 407 ret = SSH_ERR_LIBCRYPTO_ERROR; 408 goto out; 409 } 410 } 411 ret = 0; 412 #endif /* WITH_OPENSSL */ 413 out: 414 if (ret == 0) { 415 /* success */ 416 *ccp = cc; 417 } else { 418 if (cc != NULL) { 419 #ifdef WITH_OPENSSL 420 if (cc->evp != NULL) 421 EVP_CIPHER_CTX_free(cc->evp); 422 #endif /* WITH_OPENSSL */ 423 explicit_bzero(cc, sizeof(*cc)); 424 free(cc); 425 } 426 } 427 return ret; 428 } 429 430 /* 431 * cipher_crypt() operates as following: 432 * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'. 433 * Theses bytes are treated as additional authenticated data for 434 * authenticated encryption modes. 435 * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. 436 * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. 437 * This tag is written on encryption and verified on decryption. 438 * Both 'aadlen' and 'authlen' can be set to 0. 439 */ 440 int 441 cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, 442 const u_char *src, u_int len, u_int aadlen, u_int authlen) 443 { 444 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 445 return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, 446 len, aadlen, authlen, cc->encrypt); 447 } 448 #ifndef WITH_OPENSSL 449 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 450 if (aadlen) 451 memcpy(dest, src, aadlen); 452 aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen, 453 dest + aadlen, len); 454 return 0; 455 } 456 if ((cc->cipher->flags & CFLAG_NONE) != 0) { 457 memcpy(dest, src, aadlen + len); 458 return 0; 459 } 460 return SSH_ERR_INVALID_ARGUMENT; 461 #else 462 if (authlen) { 463 u_char lastiv[1]; 464 465 if (authlen != cipher_authlen(cc->cipher)) 466 return SSH_ERR_INVALID_ARGUMENT; 467 /* increment IV */ 468 if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, 469 1, lastiv)) 470 return SSH_ERR_LIBCRYPTO_ERROR; 471 /* set tag on decyption */ 472 if (!cc->encrypt && 473 !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, 474 authlen, __UNCONST(src + aadlen + len))) 475 return SSH_ERR_LIBCRYPTO_ERROR; 476 } 477 if (aadlen) { 478 if (authlen && 479 EVP_Cipher(cc->evp, NULL, (const u_char *)src, aadlen) < 0) 480 return SSH_ERR_LIBCRYPTO_ERROR; 481 memcpy(dest, src, aadlen); 482 } 483 if (len % cc->cipher->block_size) 484 return SSH_ERR_INVALID_ARGUMENT; 485 if (EVP_Cipher(cc->evp, dest + aadlen, (const u_char *)src + aadlen, 486 len) < 0) 487 return SSH_ERR_LIBCRYPTO_ERROR; 488 if (authlen) { 489 /* compute tag (on encrypt) or verify tag (on decrypt) */ 490 if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0) 491 return cc->encrypt ? 492 SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; 493 if (cc->encrypt && 494 !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, 495 authlen, dest + aadlen + len)) 496 return SSH_ERR_LIBCRYPTO_ERROR; 497 } 498 return 0; 499 #endif 500 } 501 502 /* Extract the packet length, including any decryption necessary beforehand */ 503 int 504 cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, 505 const u_char *cp, u_int len) 506 { 507 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 508 return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, 509 cp, len); 510 if (len < 4) 511 return SSH_ERR_MESSAGE_INCOMPLETE; 512 *plenp = get_u32(cp); 513 return 0; 514 } 515 516 void 517 cipher_free(struct sshcipher_ctx *cc) 518 { 519 if (cc == NULL) 520 return; 521 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 522 explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); 523 else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) 524 explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); 525 #ifdef WITH_OPENSSL 526 if (cc->evp != NULL) { 527 EVP_CIPHER_CTX_free(cc->evp); 528 cc->evp = NULL; 529 } 530 #endif 531 explicit_bzero(cc, sizeof(*cc)); 532 free(cc); 533 } 534 535 /* 536 * Selects the cipher, and keys if by computing the MD5 checksum of the 537 * passphrase and using the resulting 16 bytes as the key. 538 */ 539 int 540 cipher_set_key_string(struct sshcipher_ctx **ccp, 541 const struct sshcipher *cipher, const char *passphrase, int do_encrypt) 542 { 543 u_char digest[16]; 544 int r = SSH_ERR_INTERNAL_ERROR; 545 546 if ((r = ssh_digest_memory(SSH_DIGEST_MD5, 547 passphrase, strlen(passphrase), 548 digest, sizeof(digest))) != 0) 549 goto out; 550 551 r = cipher_init(ccp, cipher, digest, 16, NULL, 0, do_encrypt); 552 out: 553 explicit_bzero(digest, sizeof(digest)); 554 return r; 555 } 556 557 /* 558 * Exports an IV from the sshcipher_ctx required to export the key 559 * state back from the unprivileged child to the privileged parent 560 * process. 561 */ 562 int 563 cipher_get_keyiv_len(const struct sshcipher_ctx *cc) 564 { 565 const struct sshcipher *c = cc->cipher; 566 int ivlen = 0; 567 568 if (c->number == SSH_CIPHER_3DES) 569 ivlen = 24; 570 else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 571 ivlen = 0; 572 else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) 573 ivlen = sizeof(cc->ac_ctx.ctr); 574 #ifdef WITH_OPENSSL 575 else 576 ivlen = EVP_CIPHER_CTX_iv_length(cc->evp); 577 #endif /* WITH_OPENSSL */ 578 return (ivlen); 579 } 580 581 int 582 cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) 583 { 584 const struct sshcipher *c = cc->cipher; 585 #ifdef WITH_OPENSSL 586 int evplen; 587 #endif 588 589 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 590 if (len != 0) 591 return SSH_ERR_INVALID_ARGUMENT; 592 return 0; 593 } 594 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 595 if (len != sizeof(cc->ac_ctx.ctr)) 596 return SSH_ERR_INVALID_ARGUMENT; 597 memcpy(iv, cc->ac_ctx.ctr, len); 598 return 0; 599 } 600 if ((cc->cipher->flags & CFLAG_NONE) != 0) 601 return 0; 602 603 switch (c->number) { 604 #ifdef WITH_OPENSSL 605 case SSH_CIPHER_NONE: 606 case SSH_CIPHER_SSH2: 607 case SSH_CIPHER_DES: 608 case SSH_CIPHER_BLOWFISH: 609 evplen = EVP_CIPHER_CTX_iv_length(cc->evp); 610 if (evplen == 0) 611 return 0; 612 else if (evplen < 0) 613 return SSH_ERR_LIBCRYPTO_ERROR; 614 if ((u_int)evplen != len) 615 return SSH_ERR_INVALID_ARGUMENT; 616 if (cipher_authlen(c)) { 617 if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, 618 len, iv)) 619 return SSH_ERR_LIBCRYPTO_ERROR; 620 } else 621 memcpy(iv, cc->evp->iv, len); 622 break; 623 #endif 624 #ifdef WITH_SSH1 625 case SSH_CIPHER_3DES: 626 return ssh1_3des_iv(cc->evp, 0, iv, 24); 627 #endif 628 default: 629 return SSH_ERR_INVALID_ARGUMENT; 630 } 631 return 0; 632 } 633 634 int 635 cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) 636 { 637 const struct sshcipher *c = cc->cipher; 638 #ifdef WITH_OPENSSL 639 int evplen = 0; 640 #endif 641 642 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 643 return 0; 644 if ((cc->cipher->flags & CFLAG_NONE) != 0) 645 return 0; 646 647 switch (c->number) { 648 #ifdef WITH_OPENSSL 649 case SSH_CIPHER_NONE: 650 case SSH_CIPHER_SSH2: 651 case SSH_CIPHER_DES: 652 case SSH_CIPHER_BLOWFISH: 653 evplen = EVP_CIPHER_CTX_iv_length(cc->evp); 654 if (evplen <= 0) 655 return SSH_ERR_LIBCRYPTO_ERROR; 656 if (cipher_authlen(c)) { 657 /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ 658 if (!EVP_CIPHER_CTX_ctrl(cc->evp, 659 EVP_CTRL_GCM_SET_IV_FIXED, -1, __UNCONST(iv))) 660 return SSH_ERR_LIBCRYPTO_ERROR; 661 } else 662 memcpy(cc->evp->iv, iv, evplen); 663 break; 664 #endif 665 #ifdef WITH_SSH1 666 case SSH_CIPHER_3DES: 667 return ssh1_3des_iv(cc->evp, 1, __UNCONST(iv), 24); 668 #endif 669 default: 670 return SSH_ERR_INVALID_ARGUMENT; 671 } 672 return 0; 673 } 674 675 #ifdef WITH_OPENSSL 676 #define EVP_X_STATE(evp) (evp)->cipher_data 677 #define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size 678 #endif 679 680 int 681 cipher_get_keycontext(const struct sshcipher_ctx *cc, u_char *dat) 682 { 683 #ifdef WITH_OPENSSL 684 const struct sshcipher *c = cc->cipher; 685 int plen = 0; 686 687 if (c->evptype == EVP_rc4) { 688 plen = EVP_X_STATE_LEN(cc->evp); 689 if (dat == NULL) 690 return (plen); 691 memcpy(dat, EVP_X_STATE(cc->evp), plen); 692 } 693 return (plen); 694 #else 695 return 0; 696 #endif 697 } 698 699 void 700 cipher_set_keycontext(struct sshcipher_ctx *cc, const u_char *dat) 701 { 702 #ifdef WITH_OPENSSL 703 const struct sshcipher *c = cc->cipher; 704 int plen; 705 706 if (c->evptype == EVP_rc4) { 707 plen = EVP_X_STATE_LEN(cc->evp); 708 memcpy(EVP_X_STATE(cc->evp), dat, plen); 709 } 710 #endif 711 } 712