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