cipher.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. /* $OpenBSD: cipher.c,v 1.117 2020/04/03 04:27:03 djm 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. #include "includes.h"
  38. #include <sys/types.h>
  39. #include <string.h>
  40. #include <stdarg.h>
  41. #include <stdio.h>
  42. #include "cipher.h"
  43. #include "misc.h"
  44. #include "sshbuf.h"
  45. #include "ssherr.h"
  46. #include "digest.h"
  47. #include "log.h"
  48. #include "openbsd-compat/openssl-compat.h"
  49. #ifndef WITH_OPENSSL
  50. #define EVP_CIPHER_CTX void
  51. #endif
  52. /* for multi-threaded aes-ctr cipher */
  53. extern const EVP_CIPHER *evp_aes_ctr_mt(void);
  54. struct sshcipher_ctx {
  55. int plaintext;
  56. int encrypt;
  57. EVP_CIPHER_CTX *evp;
  58. struct chachapoly_ctx *cp_ctx;
  59. struct aesctr_ctx ac_ctx; /* XXX union with evp? */
  60. const struct sshcipher *cipher;
  61. };
  62. //struct sshcipher {
  63. // char *name;
  64. // u_int block_size;
  65. // u_int key_len;
  66. // u_int iv_len; /* defaults to block_size */
  67. // u_int auth_len;
  68. // u_int flags;
  69. //#define CFLAG_CBC (1<<0)
  70. //#define CFLAG_CHACHAPOLY (1<<1)
  71. //#define CFLAG_AESCTR (1<<2)
  72. //#define CFLAG_NONE (1<<3)
  73. //#define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */
  74. //#ifdef WITH_OPENSSL
  75. // const EVP_CIPHER *(*evptype)(void);
  76. //#else
  77. // void *ignored;
  78. //#endif
  79. //};
  80. static struct sshcipher ciphers[] = {
  81. #ifdef WITH_OPENSSL
  82. #ifndef OPENSSL_NO_DES
  83. { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc },
  84. #endif
  85. { "aes128-cbc", 16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc },
  86. { "aes192-cbc", 16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc },
  87. { "aes256-cbc", 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
  88. { "rijndael-cbc@lysator.liu.se",
  89. 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
  90. { "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr },
  91. { "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr },
  92. { "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr },
  93. # ifdef OPENSSL_HAVE_EVPGCM
  94. { "aes128-gcm@openssh.com",
  95. 16, 16, 12, 16, 0, EVP_aes_128_gcm },
  96. { "aes256-gcm@openssh.com",
  97. 16, 32, 12, 16, 0, EVP_aes_256_gcm },
  98. # endif /* OPENSSL_HAVE_EVPGCM */
  99. #else
  100. { "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL },
  101. { "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL },
  102. { "aes256-ctr", 16, 32, 0, 0, CFLAG_AESCTR, NULL },
  103. #endif
  104. { "chacha20-poly1305@openssh.com",
  105. 8, 64, 0, 16, CFLAG_CHACHAPOLY, NULL },
  106. { "none", 8, 0, 0, 0, CFLAG_NONE, NULL },
  107. { NULL, 0, 0, 0, 0, 0, NULL }
  108. };
  109. /*--*/
  110. /* Returns a comma-separated list of supported ciphers. */
  111. char *
  112. cipher_alg_list(char sep, int auth_only)
  113. {
  114. char *tmp, *ret = NULL;
  115. size_t nlen, rlen = 0;
  116. const struct sshcipher *c;
  117. for (c = ciphers; c->name != NULL; c++) {
  118. if ((c->flags & CFLAG_INTERNAL) != 0)
  119. continue;
  120. if (auth_only && c->auth_len == 0)
  121. continue;
  122. if (ret != NULL)
  123. ret[rlen++] = sep;
  124. nlen = strlen(c->name);
  125. if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
  126. free(ret);
  127. return NULL;
  128. }
  129. ret = tmp;
  130. memcpy(ret + rlen, c->name, nlen + 1);
  131. rlen += nlen;
  132. }
  133. return ret;
  134. }
  135. const char *
  136. compression_alg_list(int compression)
  137. {
  138. #ifdef WITH_ZLIB
  139. return compression ? "zlib@openssh.com,zlib,none" :
  140. "none,zlib@openssh.com,zlib";
  141. #else
  142. return "none";
  143. #endif
  144. }
  145. /* used to get the cipher name so when force rekeying to handle the
  146. * single to multithreaded ctr cipher swap we only rekey when appropriate
  147. */
  148. const char *
  149. cipher_ctx_name(const struct sshcipher_ctx *cc)
  150. {
  151. return cc->cipher->name;
  152. }
  153. /* in order to get around sandbox and forking issues with a threaded cipher
  154. * we set the initial pre-auth aes-ctr cipher to the default OpenSSH cipher
  155. * post auth we set them to the new evp as defined by cipher-ctr-mt
  156. */
  157. #ifdef WITH_OPENSSL
  158. void
  159. cipher_reset_multithreaded(void)
  160. {
  161. cipher_by_name("aes128-ctr")->evptype = evp_aes_ctr_mt;
  162. cipher_by_name("aes192-ctr")->evptype = evp_aes_ctr_mt;
  163. cipher_by_name("aes256-ctr")->evptype = evp_aes_ctr_mt;
  164. }
  165. #endif
  166. u_int
  167. cipher_blocksize(const struct sshcipher *c)
  168. {
  169. return (c->block_size);
  170. }
  171. u_int
  172. cipher_keylen(const struct sshcipher *c)
  173. {
  174. return (c->key_len);
  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. u_int
  184. cipher_authlen(const struct sshcipher *c)
  185. {
  186. return (c->auth_len);
  187. }
  188. u_int
  189. cipher_ivlen(const struct sshcipher *c)
  190. {
  191. /*
  192. * Default is cipher block size, except for chacha20+poly1305 that
  193. * needs no IV. XXX make iv_len == -1 default?
  194. */
  195. return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ?
  196. c->iv_len : c->block_size;
  197. }
  198. u_int
  199. cipher_is_cbc(const struct sshcipher *c)
  200. {
  201. return (c->flags & CFLAG_CBC) != 0;
  202. }
  203. u_int
  204. cipher_ctx_is_plaintext(struct sshcipher_ctx *cc)
  205. {
  206. return cc->plaintext;
  207. }
  208. struct sshcipher *
  209. cipher_by_name(const char *name)
  210. {
  211. struct sshcipher *c;
  212. for (c = ciphers; c->name != NULL; c++)
  213. if (strcmp(c->name, name) == 0)
  214. return c;
  215. return NULL;
  216. }
  217. #define CIPHER_SEP ","
  218. int
  219. ciphers_valid(const char *names)
  220. {
  221. const struct sshcipher *c;
  222. char *cipher_list, *cp;
  223. char *p;
  224. if (names == NULL || strcmp(names, "") == 0)
  225. return 0;
  226. if ((cipher_list = cp = strdup(names)) == NULL)
  227. return 0;
  228. for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
  229. (p = strsep(&cp, CIPHER_SEP))) {
  230. c = cipher_by_name(p);
  231. if (c == NULL || ((c->flags & CFLAG_INTERNAL) != 0 &&
  232. (c->flags & CFLAG_NONE) != 0)) {
  233. free(cipher_list);
  234. return 0;
  235. }
  236. }
  237. free(cipher_list);
  238. return 1;
  239. }
  240. const char *
  241. cipher_warning_message(const struct sshcipher_ctx *cc)
  242. {
  243. if (cc == NULL || cc->cipher == NULL)
  244. return NULL;
  245. /* XXX repurpose for CBC warning */
  246. return NULL;
  247. }
  248. int
  249. cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
  250. const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
  251. int do_encrypt)
  252. {
  253. struct sshcipher_ctx *cc = NULL;
  254. int ret = SSH_ERR_INTERNAL_ERROR;
  255. #ifdef WITH_OPENSSL
  256. const EVP_CIPHER *type;
  257. int klen;
  258. #endif
  259. *ccp = NULL;
  260. if ((cc = calloc(sizeof(*cc), 1)) == NULL)
  261. return SSH_ERR_ALLOC_FAIL;
  262. cc->plaintext = (cipher->flags & CFLAG_NONE) != 0;
  263. cc->encrypt = do_encrypt;
  264. if (keylen < cipher->key_len ||
  265. (iv != NULL && ivlen < cipher_ivlen(cipher))) {
  266. ret = SSH_ERR_INVALID_ARGUMENT;
  267. goto out;
  268. }
  269. cc->cipher = cipher;
  270. if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
  271. cc->cp_ctx = chachapoly_new(key, keylen);
  272. ret = cc->cp_ctx != NULL ? 0 : SSH_ERR_INVALID_ARGUMENT;
  273. goto out;
  274. }
  275. if ((cc->cipher->flags & CFLAG_NONE) != 0) {
  276. ret = 0;
  277. goto out;
  278. }
  279. #ifndef WITH_OPENSSL
  280. if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
  281. aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
  282. aesctr_ivsetup(&cc->ac_ctx, iv);
  283. ret = 0;
  284. goto out;
  285. }
  286. ret = SSH_ERR_INVALID_ARGUMENT;
  287. goto out;
  288. #else /* WITH_OPENSSL */
  289. type = (*cipher->evptype)();
  290. if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) {
  291. ret = SSH_ERR_ALLOC_FAIL;
  292. goto out;
  293. }
  294. if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv,
  295. (do_encrypt == CIPHER_ENCRYPT)) == 0) {
  296. debug("(EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0");
  297. ret = SSH_ERR_LIBCRYPTO_ERROR;
  298. goto out;
  299. }
  300. if (cipher_authlen(cipher) &&
  301. !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
  302. -1, (u_char *)iv)) {
  303. debug("(cipher_authlen(cipher) && !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv))");
  304. ret = SSH_ERR_LIBCRYPTO_ERROR;
  305. goto out;
  306. }
  307. klen = EVP_CIPHER_CTX_key_length(cc->evp);
  308. if (klen > 0 && keylen != (u_int)klen) {
  309. if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) {
  310. debug("(klen > 0 && keylen != (u_int)klen) ... (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0)");
  311. ret = SSH_ERR_LIBCRYPTO_ERROR;
  312. goto out;
  313. }
  314. }
  315. if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
  316. debug ("EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0)");
  317. ret = SSH_ERR_LIBCRYPTO_ERROR;
  318. goto out;
  319. }
  320. ret = 0;
  321. #endif /* WITH_OPENSSL */
  322. out:
  323. if (ret == 0) {
  324. /* success */
  325. *ccp = cc;
  326. } else {
  327. if (cc != NULL) {
  328. #ifdef WITH_OPENSSL
  329. EVP_CIPHER_CTX_free(cc->evp);
  330. #endif /* WITH_OPENSSL */
  331. freezero(cc, sizeof(*cc));
  332. }
  333. }
  334. return ret;
  335. }
  336. /*
  337. * cipher_crypt() operates as following:
  338. * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.
  339. * These bytes are treated as additional authenticated data for
  340. * authenticated encryption modes.
  341. * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.
  342. * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
  343. * This tag is written on encryption and verified on decryption.
  344. * Both 'aadlen' and 'authlen' can be set to 0.
  345. */
  346. int
  347. cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
  348. const u_char *src, u_int len, u_int aadlen, u_int authlen)
  349. {
  350. if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
  351. return chachapoly_crypt(cc->cp_ctx, seqnr, dest, src,
  352. len, aadlen, authlen, cc->encrypt);
  353. }
  354. if ((cc->cipher->flags & CFLAG_NONE) != 0) {
  355. memcpy(dest, src, aadlen + len);
  356. return 0;
  357. }
  358. #ifndef WITH_OPENSSL
  359. if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
  360. if (aadlen)
  361. memcpy(dest, src, aadlen);
  362. aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen,
  363. dest + aadlen, len);
  364. return 0;
  365. }
  366. return SSH_ERR_INVALID_ARGUMENT;
  367. #else
  368. if (authlen) {
  369. u_char lastiv[1];
  370. if (authlen != cipher_authlen(cc->cipher))
  371. return SSH_ERR_INVALID_ARGUMENT;
  372. /* increment IV */
  373. if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
  374. 1, lastiv)) {
  375. debug("(!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, 1, lastiv))");
  376. return SSH_ERR_LIBCRYPTO_ERROR;
  377. }
  378. /* set tag on decyption */
  379. if (!cc->encrypt &&
  380. !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG,
  381. authlen, (u_char *)src + aadlen + len)) {
  382. debug("!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, authlen, (u_char *)src + aadlen + len))");
  383. return SSH_ERR_LIBCRYPTO_ERROR;
  384. }
  385. }
  386. if (aadlen) {
  387. if (authlen &&
  388. EVP_Cipher(cc->evp, NULL, (u_char *)src, aadlen) < 0)
  389. return SSH_ERR_LIBCRYPTO_ERROR;
  390. memcpy(dest, src, aadlen);
  391. }
  392. if (len % cc->cipher->block_size)
  393. return SSH_ERR_INVALID_ARGUMENT;
  394. if (EVP_Cipher(cc->evp, dest + aadlen, (u_char *)src + aadlen,
  395. len) < 0)
  396. return SSH_ERR_LIBCRYPTO_ERROR;
  397. if (authlen) {
  398. /* compute tag (on encrypt) or verify tag (on decrypt) */
  399. if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0)
  400. return cc->encrypt ?
  401. SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID;
  402. if (cc->encrypt &&
  403. !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG,
  404. authlen, dest + aadlen + len))
  405. return SSH_ERR_LIBCRYPTO_ERROR;
  406. }
  407. return 0;
  408. #endif
  409. }
  410. /* Extract the packet length, including any decryption necessary beforehand */
  411. int
  412. cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr,
  413. const u_char *cp, u_int len)
  414. {
  415. if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
  416. return chachapoly_get_length(cc->cp_ctx, plenp, seqnr,
  417. cp, len);
  418. if (len < 4)
  419. return SSH_ERR_MESSAGE_INCOMPLETE;
  420. *plenp = PEEK_U32(cp);
  421. return 0;
  422. }
  423. void
  424. cipher_free(struct sshcipher_ctx *cc)
  425. {
  426. if (cc == NULL || cc->cipher == NULL)
  427. return;
  428. if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
  429. chachapoly_free(cc->cp_ctx);
  430. cc->cp_ctx = NULL;
  431. } else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
  432. explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
  433. #ifdef WITH_OPENSSL
  434. EVP_CIPHER_CTX_free(cc->evp);
  435. cc->evp = NULL;
  436. #endif
  437. freezero(cc, sizeof(*cc));
  438. }
  439. /*
  440. * Exports an IV from the sshcipher_ctx required to export the key
  441. * state back from the unprivileged child to the privileged parent
  442. * process.
  443. */
  444. int
  445. cipher_get_keyiv_len(const struct sshcipher_ctx *cc)
  446. {
  447. const struct sshcipher *c = cc->cipher;
  448. if ((c->flags & CFLAG_CHACHAPOLY) != 0)
  449. return 0;
  450. else if ((c->flags & CFLAG_AESCTR) != 0)
  451. return sizeof(cc->ac_ctx.ctr);
  452. #ifdef WITH_OPENSSL
  453. return EVP_CIPHER_CTX_iv_length(cc->evp);
  454. #else
  455. return 0;
  456. #endif
  457. }
  458. int
  459. cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, size_t len)
  460. {
  461. #ifdef WITH_OPENSSL
  462. const struct sshcipher *c = cc->cipher;
  463. int evplen;
  464. #endif
  465. if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
  466. if (len != 0)
  467. return SSH_ERR_INVALID_ARGUMENT;
  468. return 0;
  469. }
  470. if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
  471. if (len != sizeof(cc->ac_ctx.ctr))
  472. return SSH_ERR_INVALID_ARGUMENT;
  473. memcpy(iv, cc->ac_ctx.ctr, len);
  474. return 0;
  475. }
  476. if ((cc->cipher->flags & CFLAG_NONE) != 0)
  477. return 0;
  478. #ifdef WITH_OPENSSL
  479. evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
  480. if (evplen == 0)
  481. return 0;
  482. else if (evplen < 0)
  483. return SSH_ERR_LIBCRYPTO_ERROR;
  484. if ((size_t)evplen != len)
  485. return SSH_ERR_INVALID_ARGUMENT;
  486. #ifndef OPENSSL_HAVE_EVPCTR
  487. if (c->evptype == evp_aes_128_ctr)
  488. ssh_aes_ctr_iv(cc->evp, 0, iv, len);
  489. else
  490. #endif
  491. if (cipher_authlen(c)) {
  492. if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
  493. len, iv))
  494. return SSH_ERR_LIBCRYPTO_ERROR;
  495. } else if (!EVP_CIPHER_CTX_get_iv(cc->evp, iv, len))
  496. return SSH_ERR_LIBCRYPTO_ERROR;
  497. #endif
  498. return 0;
  499. }
  500. int
  501. cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv, size_t len)
  502. {
  503. #ifdef WITH_OPENSSL
  504. const struct sshcipher *c = cc->cipher;
  505. int evplen = 0;
  506. #endif
  507. if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
  508. return 0;
  509. if ((cc->cipher->flags & CFLAG_NONE) != 0)
  510. return 0;
  511. #ifdef WITH_OPENSSL
  512. evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
  513. if (evplen <= 0)
  514. return SSH_ERR_LIBCRYPTO_ERROR;
  515. if ((size_t)evplen != len)
  516. return SSH_ERR_INVALID_ARGUMENT;
  517. #ifndef OPENSSL_HAVE_EVPCTR
  518. /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */
  519. if (c->evptype == evp_aes_128_ctr)
  520. ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen);
  521. else
  522. #endif
  523. if (cipher_authlen(c)) {
  524. /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */
  525. if (!EVP_CIPHER_CTX_ctrl(cc->evp,
  526. EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
  527. return SSH_ERR_LIBCRYPTO_ERROR;
  528. } else if (!EVP_CIPHER_CTX_set_iv(cc->evp, iv, evplen))
  529. return SSH_ERR_LIBCRYPTO_ERROR;
  530. #endif
  531. return 0;
  532. }