diff options
author | djm@openbsd.org <djm@openbsd.org> | 2017-04-30 23:15:04 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-05-01 10:04:58 +1000 |
commit | cdccebdf85204bf7542b7fcc1aa2ea3f36661833 (patch) | |
tree | fd07acdcdebd7da5dc027e58261a446a807466ba /cipher.c | |
parent | 97f4d3083b036ce3e68d6346a6140a22123d5864 (diff) |
upstream commit
remove SSHv1 ciphers; ok markus@
Upstream-ID: e5ebc5e540d7f23a8c1266db1839794d4d177890
Diffstat (limited to 'cipher.c')
-rw-r--r-- | cipher.c | 237 |
1 files changed, 75 insertions, 162 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher.c,v 1.103 2017/04/30 23:10:43 djm Exp $ */ | 1 | /* $OpenBSD: cipher.c,v 1.104 2017/04/30 23:15:04 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -63,7 +63,6 @@ struct sshcipher_ctx { | |||
63 | 63 | ||
64 | struct sshcipher { | 64 | struct sshcipher { |
65 | char *name; | 65 | char *name; |
66 | int number; /* for ssh1 only */ | ||
67 | u_int block_size; | 66 | u_int block_size; |
68 | u_int key_len; | 67 | u_int key_len; |
69 | u_int iv_len; /* defaults to block_size */ | 68 | u_int iv_len; /* defaults to block_size */ |
@@ -74,6 +73,7 @@ struct sshcipher { | |||
74 | #define CFLAG_CHACHAPOLY (1<<1) | 73 | #define CFLAG_CHACHAPOLY (1<<1) |
75 | #define CFLAG_AESCTR (1<<2) | 74 | #define CFLAG_AESCTR (1<<2) |
76 | #define CFLAG_NONE (1<<3) | 75 | #define CFLAG_NONE (1<<3) |
76 | #define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */ | ||
77 | #ifdef WITH_OPENSSL | 77 | #ifdef WITH_OPENSSL |
78 | const EVP_CIPHER *(*evptype)(void); | 78 | const EVP_CIPHER *(*evptype)(void); |
79 | #else | 79 | #else |
@@ -83,45 +83,42 @@ struct sshcipher { | |||
83 | 83 | ||
84 | static const struct sshcipher ciphers[] = { | 84 | static const struct sshcipher ciphers[] = { |
85 | #ifdef WITH_OPENSSL | 85 | #ifdef WITH_OPENSSL |
86 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, | 86 | { "3des-cbc", 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, |
87 | { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, | ||
88 | # ifndef OPENSSL_NO_BF | 87 | # ifndef OPENSSL_NO_BF |
89 | { "blowfish-cbc", | 88 | { "blowfish-cbc", 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, |
90 | SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, | ||
91 | # endif /* OPENSSL_NO_BF */ | 89 | # endif /* OPENSSL_NO_BF */ |
92 | # ifndef OPENSSL_NO_CAST | 90 | # ifndef OPENSSL_NO_CAST |
93 | { "cast128-cbc", | 91 | { "cast128-cbc", 8, 16, 0, 0, 0, 1, EVP_cast5_cbc }, |
94 | SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc }, | ||
95 | # endif /* OPENSSL_NO_CAST */ | 92 | # endif /* OPENSSL_NO_CAST */ |
96 | # ifndef OPENSSL_NO_RC4 | 93 | # ifndef OPENSSL_NO_RC4 |
97 | { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 }, | 94 | { "arcfour", 8, 16, 0, 0, 0, 0, EVP_rc4 }, |
98 | { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 }, | 95 | { "arcfour128", 8, 16, 0, 0, 1536, 0, EVP_rc4 }, |
99 | { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 }, | 96 | { "arcfour256", 8, 32, 0, 0, 1536, 0, EVP_rc4 }, |
100 | # endif /* OPENSSL_NO_RC4 */ | 97 | # endif /* OPENSSL_NO_RC4 */ |
101 | { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, | 98 | { "aes128-cbc", 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, |
102 | { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, | 99 | { "aes192-cbc", 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, |
103 | { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, | 100 | { "aes256-cbc", 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, |
104 | { "rijndael-cbc@lysator.liu.se", | 101 | { "rijndael-cbc@lysator.liu.se", |
105 | SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, | 102 | 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, |
106 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, | 103 | { "aes128-ctr", 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, |
107 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, | 104 | { "aes192-ctr", 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, |
108 | { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, | 105 | { "aes256-ctr", 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, |
109 | # ifdef OPENSSL_HAVE_EVPGCM | 106 | # ifdef OPENSSL_HAVE_EVPGCM |
110 | { "aes128-gcm@openssh.com", | 107 | { "aes128-gcm@openssh.com", |
111 | SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, | 108 | 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, |
112 | { "aes256-gcm@openssh.com", | 109 | { "aes256-gcm@openssh.com", |
113 | SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, | 110 | 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, |
114 | # endif /* OPENSSL_HAVE_EVPGCM */ | 111 | # endif /* OPENSSL_HAVE_EVPGCM */ |
115 | #else /* WITH_OPENSSL */ | 112 | #else |
116 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, | 113 | { "aes128-ctr", 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, |
117 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, | 114 | { "aes192-ctr", 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, |
118 | { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL }, | 115 | { "aes256-ctr", 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL }, |
119 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL }, | 116 | #endif |
120 | #endif /* WITH_OPENSSL */ | ||
121 | { "chacha20-poly1305@openssh.com", | 117 | { "chacha20-poly1305@openssh.com", |
122 | SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, | 118 | 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, |
119 | { "none", 8, 0, 0, 0, 0, CFLAG_NONE, NULL }, | ||
123 | 120 | ||
124 | { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } | 121 | { NULL, 0, 0, 0, 0, 0, 0, NULL } |
125 | }; | 122 | }; |
126 | 123 | ||
127 | /*--*/ | 124 | /*--*/ |
@@ -135,7 +132,7 @@ cipher_alg_list(char sep, int auth_only) | |||
135 | const struct sshcipher *c; | 132 | const struct sshcipher *c; |
136 | 133 | ||
137 | for (c = ciphers; c->name != NULL; c++) { | 134 | for (c = ciphers; c->name != NULL; c++) { |
138 | if (c->number != SSH_CIPHER_SSH2) | 135 | if ((c->flags & CFLAG_INTERNAL) != 0) |
139 | continue; | 136 | continue; |
140 | if (auth_only && c->auth_len == 0) | 137 | if (auth_only && c->auth_len == 0) |
141 | continue; | 138 | continue; |
@@ -191,12 +188,6 @@ cipher_ivlen(const struct sshcipher *c) | |||
191 | } | 188 | } |
192 | 189 | ||
193 | u_int | 190 | u_int |
194 | cipher_get_number(const struct sshcipher *c) | ||
195 | { | ||
196 | return (c->number); | ||
197 | } | ||
198 | |||
199 | u_int | ||
200 | cipher_is_cbc(const struct sshcipher *c) | 191 | cipher_is_cbc(const struct sshcipher *c) |
201 | { | 192 | { |
202 | return (c->flags & CFLAG_CBC) != 0; | 193 | return (c->flags & CFLAG_CBC) != 0; |
@@ -208,24 +199,6 @@ cipher_ctx_is_plaintext(struct sshcipher_ctx *cc) | |||
208 | return cc->plaintext; | 199 | return cc->plaintext; |
209 | } | 200 | } |
210 | 201 | ||
211 | u_int | ||
212 | cipher_ctx_get_number(struct sshcipher_ctx *cc) | ||
213 | { | ||
214 | return cc->cipher->number; | ||
215 | } | ||
216 | |||
217 | u_int | ||
218 | cipher_mask_ssh1(int client) | ||
219 | { | ||
220 | u_int mask = 0; | ||
221 | mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ | ||
222 | mask |= 1 << SSH_CIPHER_BLOWFISH; | ||
223 | if (client) { | ||
224 | mask |= 1 << SSH_CIPHER_DES; | ||
225 | } | ||
226 | return mask; | ||
227 | } | ||
228 | |||
229 | const struct sshcipher * | 202 | const struct sshcipher * |
230 | cipher_by_name(const char *name) | 203 | cipher_by_name(const char *name) |
231 | { | 204 | { |
@@ -236,16 +209,6 @@ cipher_by_name(const char *name) | |||
236 | return NULL; | 209 | return NULL; |
237 | } | 210 | } |
238 | 211 | ||
239 | const struct sshcipher * | ||
240 | cipher_by_number(int id) | ||
241 | { | ||
242 | const struct sshcipher *c; | ||
243 | for (c = ciphers; c->name != NULL; c++) | ||
244 | if (c->number == id) | ||
245 | return c; | ||
246 | return NULL; | ||
247 | } | ||
248 | |||
249 | #define CIPHER_SEP "," | 212 | #define CIPHER_SEP "," |
250 | int | 213 | int |
251 | ciphers_valid(const char *names) | 214 | ciphers_valid(const char *names) |
@@ -261,7 +224,7 @@ ciphers_valid(const char *names) | |||
261 | for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; | 224 | for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; |
262 | (p = strsep(&cp, CIPHER_SEP))) { | 225 | (p = strsep(&cp, CIPHER_SEP))) { |
263 | c = cipher_by_name(p); | 226 | c = cipher_by_name(p); |
264 | if (c == NULL || c->number != SSH_CIPHER_SSH2) { | 227 | if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) { |
265 | free(cipher_list); | 228 | free(cipher_list); |
266 | return 0; | 229 | return 0; |
267 | } | 230 | } |
@@ -270,38 +233,12 @@ ciphers_valid(const char *names) | |||
270 | return 1; | 233 | return 1; |
271 | } | 234 | } |
272 | 235 | ||
273 | /* | ||
274 | * Parses the name of the cipher. Returns the number of the corresponding | ||
275 | * cipher, or -1 on error. | ||
276 | */ | ||
277 | |||
278 | int | ||
279 | cipher_number(const char *name) | ||
280 | { | ||
281 | const struct sshcipher *c; | ||
282 | if (name == NULL) | ||
283 | return -1; | ||
284 | for (c = ciphers; c->name != NULL; c++) | ||
285 | if (strcasecmp(c->name, name) == 0) | ||
286 | return c->number; | ||
287 | return -1; | ||
288 | } | ||
289 | |||
290 | char * | ||
291 | cipher_name(int id) | ||
292 | { | ||
293 | const struct sshcipher *c = cipher_by_number(id); | ||
294 | return (c==NULL) ? "<unknown>" : c->name; | ||
295 | } | ||
296 | |||
297 | const char * | 236 | const char * |
298 | cipher_warning_message(const struct sshcipher_ctx *cc) | 237 | cipher_warning_message(const struct sshcipher_ctx *cc) |
299 | { | 238 | { |
300 | if (cc == NULL || cc->cipher == NULL) | 239 | if (cc == NULL || cc->cipher == NULL) |
301 | return NULL; | 240 | return NULL; |
302 | if (cc->cipher->number == SSH_CIPHER_DES) | 241 | /* XXX repurpose for CBC warning */ |
303 | return "use of DES is strongly discouraged due to " | ||
304 | "cryptographic weaknesses"; | ||
305 | return NULL; | 242 | return NULL; |
306 | } | 243 | } |
307 | 244 | ||
@@ -322,12 +259,7 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, | |||
322 | if ((cc = calloc(sizeof(*cc), 1)) == NULL) | 259 | if ((cc = calloc(sizeof(*cc), 1)) == NULL) |
323 | return SSH_ERR_ALLOC_FAIL; | 260 | return SSH_ERR_ALLOC_FAIL; |
324 | 261 | ||
325 | if (cipher->number == SSH_CIPHER_DES) { | 262 | cc->plaintext = 0; /* XXX */ |
326 | if (keylen > 8) | ||
327 | keylen = 8; | ||
328 | } | ||
329 | |||
330 | cc->plaintext = (cipher->number == SSH_CIPHER_NONE); | ||
331 | cc->encrypt = do_encrypt; | 263 | cc->encrypt = do_encrypt; |
332 | 264 | ||
333 | if (keylen < cipher->key_len || | 265 | if (keylen < cipher->key_len || |
@@ -341,6 +273,10 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, | |||
341 | ret = chachapoly_init(&cc->cp_ctx, key, keylen); | 273 | ret = chachapoly_init(&cc->cp_ctx, key, keylen); |
342 | goto out; | 274 | goto out; |
343 | } | 275 | } |
276 | if ((cc->cipher->flags & CFLAG_NONE) != 0) { | ||
277 | ret = 0; | ||
278 | goto out; | ||
279 | } | ||
344 | #ifndef WITH_OPENSSL | 280 | #ifndef WITH_OPENSSL |
345 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { | 281 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { |
346 | aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); | 282 | aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); |
@@ -348,10 +284,6 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, | |||
348 | ret = 0; | 284 | ret = 0; |
349 | goto out; | 285 | goto out; |
350 | } | 286 | } |
351 | if ((cc->cipher->flags & CFLAG_NONE) != 0) { | ||
352 | ret = 0; | ||
353 | goto out; | ||
354 | } | ||
355 | ret = SSH_ERR_INVALID_ARGUMENT; | 287 | ret = SSH_ERR_INVALID_ARGUMENT; |
356 | goto out; | 288 | goto out; |
357 | #else /* WITH_OPENSSL */ | 289 | #else /* WITH_OPENSSL */ |
@@ -436,6 +368,10 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, | |||
436 | return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, | 368 | return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, |
437 | len, aadlen, authlen, cc->encrypt); | 369 | len, aadlen, authlen, cc->encrypt); |
438 | } | 370 | } |
371 | if ((cc->cipher->flags & CFLAG_NONE) != 0) { | ||
372 | memcpy(dest, src, aadlen + len); | ||
373 | return 0; | ||
374 | } | ||
439 | #ifndef WITH_OPENSSL | 375 | #ifndef WITH_OPENSSL |
440 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { | 376 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { |
441 | if (aadlen) | 377 | if (aadlen) |
@@ -444,10 +380,6 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, | |||
444 | dest + aadlen, len); | 380 | dest + aadlen, len); |
445 | return 0; | 381 | return 0; |
446 | } | 382 | } |
447 | if ((cc->cipher->flags & CFLAG_NONE) != 0) { | ||
448 | memcpy(dest, src, aadlen + len); | ||
449 | return 0; | ||
450 | } | ||
451 | return SSH_ERR_INVALID_ARGUMENT; | 383 | return SSH_ERR_INVALID_ARGUMENT; |
452 | #else | 384 | #else |
453 | if (authlen) { | 385 | if (authlen) { |
@@ -554,19 +486,16 @@ int | |||
554 | cipher_get_keyiv_len(const struct sshcipher_ctx *cc) | 486 | cipher_get_keyiv_len(const struct sshcipher_ctx *cc) |
555 | { | 487 | { |
556 | const struct sshcipher *c = cc->cipher; | 488 | const struct sshcipher *c = cc->cipher; |
557 | int ivlen = 0; | ||
558 | 489 | ||
559 | if (c->number == SSH_CIPHER_3DES) | 490 | if ((c->flags & CFLAG_CHACHAPOLY) != 0) |
560 | ivlen = 24; | 491 | return 0; |
561 | else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 492 | else if ((c->flags & CFLAG_AESCTR) != 0) |
562 | ivlen = 0; | 493 | return sizeof(cc->ac_ctx.ctr); |
563 | else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) | ||
564 | ivlen = sizeof(cc->ac_ctx.ctr); | ||
565 | #ifdef WITH_OPENSSL | 494 | #ifdef WITH_OPENSSL |
566 | else | 495 | return EVP_CIPHER_CTX_iv_length(cc->evp); |
567 | ivlen = EVP_CIPHER_CTX_iv_length(cc->evp); | 496 | #else |
568 | #endif /* WITH_OPENSSL */ | 497 | return 0; |
569 | return (ivlen); | 498 | #endif |
570 | } | 499 | } |
571 | 500 | ||
572 | int | 501 | int |
@@ -591,34 +520,26 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) | |||
591 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | 520 | if ((cc->cipher->flags & CFLAG_NONE) != 0) |
592 | return 0; | 521 | return 0; |
593 | 522 | ||
594 | switch (c->number) { | ||
595 | #ifdef WITH_OPENSSL | 523 | #ifdef WITH_OPENSSL |
596 | case SSH_CIPHER_SSH2: | 524 | evplen = EVP_CIPHER_CTX_iv_length(cc->evp); |
597 | case SSH_CIPHER_DES: | 525 | if (evplen == 0) |
598 | case SSH_CIPHER_BLOWFISH: | 526 | return 0; |
599 | evplen = EVP_CIPHER_CTX_iv_length(cc->evp); | 527 | else if (evplen < 0) |
600 | if (evplen == 0) | 528 | return SSH_ERR_LIBCRYPTO_ERROR; |
601 | return 0; | 529 | if ((u_int)evplen != len) |
602 | else if (evplen < 0) | 530 | return SSH_ERR_INVALID_ARGUMENT; |
603 | return SSH_ERR_LIBCRYPTO_ERROR; | ||
604 | if ((u_int)evplen != len) | ||
605 | return SSH_ERR_INVALID_ARGUMENT; | ||
606 | #ifndef OPENSSL_HAVE_EVPCTR | 531 | #ifndef OPENSSL_HAVE_EVPCTR |
607 | if (c->evptype == evp_aes_128_ctr) | 532 | if (c->evptype == evp_aes_128_ctr) |
608 | ssh_aes_ctr_iv(cc->evp, 0, iv, len); | 533 | ssh_aes_ctr_iv(cc->evp, 0, iv, len); |
609 | else | 534 | else |
610 | #endif | 535 | #endif |
611 | if (cipher_authlen(c)) { | 536 | if (cipher_authlen(c)) { |
612 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, | 537 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, |
613 | len, iv)) | 538 | len, iv)) |
614 | return SSH_ERR_LIBCRYPTO_ERROR; | 539 | return SSH_ERR_LIBCRYPTO_ERROR; |
615 | } else | 540 | } else |
616 | memcpy(iv, cc->evp->iv, len); | 541 | memcpy(iv, cc->evp->iv, len); |
617 | break; | ||
618 | #endif | 542 | #endif |
619 | default: | ||
620 | return SSH_ERR_INVALID_ARGUMENT; | ||
621 | } | ||
622 | return 0; | 543 | return 0; |
623 | } | 544 | } |
624 | 545 | ||
@@ -635,32 +556,24 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) | |||
635 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | 556 | if ((cc->cipher->flags & CFLAG_NONE) != 0) |
636 | return 0; | 557 | return 0; |
637 | 558 | ||
638 | switch (c->number) { | ||
639 | #ifdef WITH_OPENSSL | 559 | #ifdef WITH_OPENSSL |
640 | case SSH_CIPHER_SSH2: | 560 | evplen = EVP_CIPHER_CTX_iv_length(cc->evp); |
641 | case SSH_CIPHER_DES: | 561 | if (evplen <= 0) |
642 | case SSH_CIPHER_BLOWFISH: | 562 | return SSH_ERR_LIBCRYPTO_ERROR; |
643 | evplen = EVP_CIPHER_CTX_iv_length(cc->evp); | ||
644 | if (evplen <= 0) | ||
645 | return SSH_ERR_LIBCRYPTO_ERROR; | ||
646 | #ifndef OPENSSL_HAVE_EVPCTR | 563 | #ifndef OPENSSL_HAVE_EVPCTR |
647 | /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */ | 564 | /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */ |
648 | if (c->evptype == evp_aes_128_ctr) | 565 | if (c->evptype == evp_aes_128_ctr) |
649 | ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen); | 566 | ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen); |
650 | else | 567 | else |
651 | #endif | 568 | #endif |
652 | if (cipher_authlen(c)) { | 569 | if (cipher_authlen(c)) { |
653 | /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ | 570 | /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ |
654 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, | 571 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, |
655 | EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) | 572 | EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) |
656 | return SSH_ERR_LIBCRYPTO_ERROR; | 573 | return SSH_ERR_LIBCRYPTO_ERROR; |
657 | } else | 574 | } else |
658 | memcpy(cc->evp->iv, iv, evplen); | 575 | memcpy(cc->evp->iv, iv, evplen); |
659 | break; | ||
660 | #endif | 576 | #endif |
661 | default: | ||
662 | return SSH_ERR_INVALID_ARGUMENT; | ||
663 | } | ||
664 | return 0; | 577 | return 0; |
665 | } | 578 | } |
666 | 579 | ||