diff options
Diffstat (limited to 'cipher.c')
-rw-r--r-- | cipher.c | 299 |
1 files changed, 70 insertions, 229 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher.c,v 1.102 2016/08/03 05:41:57 djm Exp $ */ | 1 | /* $OpenBSD: cipher.c,v 1.107 2017/05/07 23:12:57 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 |
@@ -51,11 +51,6 @@ | |||
51 | 51 | ||
52 | #include "openbsd-compat/openssl-compat.h" | 52 | #include "openbsd-compat/openssl-compat.h" |
53 | 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 | 54 | ||
60 | struct sshcipher_ctx { | 55 | struct sshcipher_ctx { |
61 | int plaintext; | 56 | int plaintext; |
@@ -68,17 +63,16 @@ struct sshcipher_ctx { | |||
68 | 63 | ||
69 | struct sshcipher { | 64 | struct sshcipher { |
70 | char *name; | 65 | char *name; |
71 | int number; /* for ssh1 only */ | ||
72 | u_int block_size; | 66 | u_int block_size; |
73 | u_int key_len; | 67 | u_int key_len; |
74 | u_int iv_len; /* defaults to block_size */ | 68 | u_int iv_len; /* defaults to block_size */ |
75 | u_int auth_len; | 69 | u_int auth_len; |
76 | u_int discard_len; | ||
77 | u_int flags; | 70 | u_int flags; |
78 | #define CFLAG_CBC (1<<0) | 71 | #define CFLAG_CBC (1<<0) |
79 | #define CFLAG_CHACHAPOLY (1<<1) | 72 | #define CFLAG_CHACHAPOLY (1<<1) |
80 | #define CFLAG_AESCTR (1<<2) | 73 | #define CFLAG_AESCTR (1<<2) |
81 | #define CFLAG_NONE (1<<3) | 74 | #define CFLAG_NONE (1<<3) |
75 | #define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */ | ||
82 | #ifdef WITH_OPENSSL | 76 | #ifdef WITH_OPENSSL |
83 | const EVP_CIPHER *(*evptype)(void); | 77 | const EVP_CIPHER *(*evptype)(void); |
84 | #else | 78 | #else |
@@ -87,53 +81,32 @@ struct sshcipher { | |||
87 | }; | 81 | }; |
88 | 82 | ||
89 | static const struct sshcipher ciphers[] = { | 83 | 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 | # ifndef OPENSSL_NO_BF | ||
94 | { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, | ||
95 | # endif /* OPENSSL_NO_BF */ | ||
96 | #endif /* WITH_SSH1 */ | ||
97 | #ifdef WITH_OPENSSL | 84 | #ifdef WITH_OPENSSL |
98 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, | 85 | { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, |
99 | { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, | 86 | { "aes128-cbc", 16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc }, |
100 | # ifndef OPENSSL_NO_BF | 87 | { "aes192-cbc", 16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc }, |
101 | { "blowfish-cbc", | 88 | { "aes256-cbc", 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc }, |
102 | SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, | ||
103 | # endif /* OPENSSL_NO_BF */ | ||
104 | # ifndef OPENSSL_NO_CAST | ||
105 | { "cast128-cbc", | ||
106 | SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc }, | ||
107 | # endif /* OPENSSL_NO_CAST */ | ||
108 | # ifndef OPENSSL_NO_RC4 | ||
109 | { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 }, | ||
110 | { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 }, | ||
111 | { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 }, | ||
112 | # endif /* OPENSSL_NO_RC4 */ | ||
113 | { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, | ||
114 | { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, | ||
115 | { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, | ||
116 | { "rijndael-cbc@lysator.liu.se", | 89 | { "rijndael-cbc@lysator.liu.se", |
117 | SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, | 90 | 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc }, |
118 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, | 91 | { "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr }, |
119 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, | 92 | { "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr }, |
120 | { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, | 93 | { "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr }, |
121 | # ifdef OPENSSL_HAVE_EVPGCM | 94 | # ifdef OPENSSL_HAVE_EVPGCM |
122 | { "aes128-gcm@openssh.com", | 95 | { "aes128-gcm@openssh.com", |
123 | SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, | 96 | 16, 16, 12, 16, 0, EVP_aes_128_gcm }, |
124 | { "aes256-gcm@openssh.com", | 97 | { "aes256-gcm@openssh.com", |
125 | SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, | 98 | 16, 32, 12, 16, 0, EVP_aes_256_gcm }, |
126 | # endif /* OPENSSL_HAVE_EVPGCM */ | 99 | # endif /* OPENSSL_HAVE_EVPGCM */ |
127 | #else /* WITH_OPENSSL */ | 100 | #else |
128 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, | 101 | { "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL }, |
129 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, | 102 | { "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL }, |
130 | { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL }, | 103 | { "aes256-ctr", 16, 32, 0, 0, CFLAG_AESCTR, NULL }, |
131 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL }, | 104 | #endif |
132 | #endif /* WITH_OPENSSL */ | ||
133 | { "chacha20-poly1305@openssh.com", | 105 | { "chacha20-poly1305@openssh.com", |
134 | SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, | 106 | 8, 64, 0, 16, CFLAG_CHACHAPOLY, NULL }, |
107 | { "none", 8, 0, 0, 0, CFLAG_NONE, NULL }, | ||
135 | 108 | ||
136 | { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } | 109 | { NULL, 0, 0, 0, 0, 0, NULL } |
137 | }; | 110 | }; |
138 | 111 | ||
139 | /*--*/ | 112 | /*--*/ |
@@ -147,7 +120,7 @@ cipher_alg_list(char sep, int auth_only) | |||
147 | const struct sshcipher *c; | 120 | const struct sshcipher *c; |
148 | 121 | ||
149 | for (c = ciphers; c->name != NULL; c++) { | 122 | for (c = ciphers; c->name != NULL; c++) { |
150 | if (c->number != SSH_CIPHER_SSH2) | 123 | if ((c->flags & CFLAG_INTERNAL) != 0) |
151 | continue; | 124 | continue; |
152 | if (auth_only && c->auth_len == 0) | 125 | if (auth_only && c->auth_len == 0) |
153 | continue; | 126 | continue; |
@@ -203,12 +176,6 @@ cipher_ivlen(const struct sshcipher *c) | |||
203 | } | 176 | } |
204 | 177 | ||
205 | u_int | 178 | u_int |
206 | cipher_get_number(const struct sshcipher *c) | ||
207 | { | ||
208 | return (c->number); | ||
209 | } | ||
210 | |||
211 | u_int | ||
212 | cipher_is_cbc(const struct sshcipher *c) | 179 | cipher_is_cbc(const struct sshcipher *c) |
213 | { | 180 | { |
214 | return (c->flags & CFLAG_CBC) != 0; | 181 | return (c->flags & CFLAG_CBC) != 0; |
@@ -220,24 +187,6 @@ cipher_ctx_is_plaintext(struct sshcipher_ctx *cc) | |||
220 | return cc->plaintext; | 187 | return cc->plaintext; |
221 | } | 188 | } |
222 | 189 | ||
223 | u_int | ||
224 | cipher_ctx_get_number(struct sshcipher_ctx *cc) | ||
225 | { | ||
226 | return cc->cipher->number; | ||
227 | } | ||
228 | |||
229 | u_int | ||
230 | cipher_mask_ssh1(int client) | ||
231 | { | ||
232 | u_int mask = 0; | ||
233 | mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ | ||
234 | mask |= 1 << SSH_CIPHER_BLOWFISH; | ||
235 | if (client) { | ||
236 | mask |= 1 << SSH_CIPHER_DES; | ||
237 | } | ||
238 | return mask; | ||
239 | } | ||
240 | |||
241 | const struct sshcipher * | 190 | const struct sshcipher * |
242 | cipher_by_name(const char *name) | 191 | cipher_by_name(const char *name) |
243 | { | 192 | { |
@@ -248,16 +197,6 @@ cipher_by_name(const char *name) | |||
248 | return NULL; | 197 | return NULL; |
249 | } | 198 | } |
250 | 199 | ||
251 | const struct sshcipher * | ||
252 | cipher_by_number(int id) | ||
253 | { | ||
254 | const struct sshcipher *c; | ||
255 | for (c = ciphers; c->name != NULL; c++) | ||
256 | if (c->number == id) | ||
257 | return c; | ||
258 | return NULL; | ||
259 | } | ||
260 | |||
261 | #define CIPHER_SEP "," | 200 | #define CIPHER_SEP "," |
262 | int | 201 | int |
263 | ciphers_valid(const char *names) | 202 | ciphers_valid(const char *names) |
@@ -273,7 +212,7 @@ ciphers_valid(const char *names) | |||
273 | for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; | 212 | for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; |
274 | (p = strsep(&cp, CIPHER_SEP))) { | 213 | (p = strsep(&cp, CIPHER_SEP))) { |
275 | c = cipher_by_name(p); | 214 | c = cipher_by_name(p); |
276 | if (c == NULL || c->number != SSH_CIPHER_SSH2) { | 215 | if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) { |
277 | free(cipher_list); | 216 | free(cipher_list); |
278 | return 0; | 217 | return 0; |
279 | } | 218 | } |
@@ -282,38 +221,12 @@ ciphers_valid(const char *names) | |||
282 | return 1; | 221 | return 1; |
283 | } | 222 | } |
284 | 223 | ||
285 | /* | ||
286 | * Parses the name of the cipher. Returns the number of the corresponding | ||
287 | * cipher, or -1 on error. | ||
288 | */ | ||
289 | |||
290 | int | ||
291 | cipher_number(const char *name) | ||
292 | { | ||
293 | const struct sshcipher *c; | ||
294 | if (name == NULL) | ||
295 | return -1; | ||
296 | for (c = ciphers; c->name != NULL; c++) | ||
297 | if (strcasecmp(c->name, name) == 0) | ||
298 | return c->number; | ||
299 | return -1; | ||
300 | } | ||
301 | |||
302 | char * | ||
303 | cipher_name(int id) | ||
304 | { | ||
305 | const struct sshcipher *c = cipher_by_number(id); | ||
306 | return (c==NULL) ? "<unknown>" : c->name; | ||
307 | } | ||
308 | |||
309 | const char * | 224 | const char * |
310 | cipher_warning_message(const struct sshcipher_ctx *cc) | 225 | cipher_warning_message(const struct sshcipher_ctx *cc) |
311 | { | 226 | { |
312 | if (cc == NULL || cc->cipher == NULL) | 227 | if (cc == NULL || cc->cipher == NULL) |
313 | return NULL; | 228 | return NULL; |
314 | if (cc->cipher->number == SSH_CIPHER_DES) | 229 | /* XXX repurpose for CBC warning */ |
315 | return "use of DES is strongly discouraged due to " | ||
316 | "cryptographic weaknesses"; | ||
317 | return NULL; | 230 | return NULL; |
318 | } | 231 | } |
319 | 232 | ||
@@ -327,19 +240,13 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, | |||
327 | #ifdef WITH_OPENSSL | 240 | #ifdef WITH_OPENSSL |
328 | const EVP_CIPHER *type; | 241 | const EVP_CIPHER *type; |
329 | int klen; | 242 | int klen; |
330 | u_char *junk, *discard; | ||
331 | #endif | 243 | #endif |
332 | 244 | ||
333 | *ccp = NULL; | 245 | *ccp = NULL; |
334 | if ((cc = calloc(sizeof(*cc), 1)) == NULL) | 246 | if ((cc = calloc(sizeof(*cc), 1)) == NULL) |
335 | return SSH_ERR_ALLOC_FAIL; | 247 | return SSH_ERR_ALLOC_FAIL; |
336 | 248 | ||
337 | if (cipher->number == SSH_CIPHER_DES) { | 249 | cc->plaintext = (cipher->flags & CFLAG_NONE) != 0; |
338 | if (keylen > 8) | ||
339 | keylen = 8; | ||
340 | } | ||
341 | |||
342 | cc->plaintext = (cipher->number == SSH_CIPHER_NONE); | ||
343 | cc->encrypt = do_encrypt; | 250 | cc->encrypt = do_encrypt; |
344 | 251 | ||
345 | if (keylen < cipher->key_len || | 252 | if (keylen < cipher->key_len || |
@@ -353,6 +260,10 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, | |||
353 | ret = chachapoly_init(&cc->cp_ctx, key, keylen); | 260 | ret = chachapoly_init(&cc->cp_ctx, key, keylen); |
354 | goto out; | 261 | goto out; |
355 | } | 262 | } |
263 | if ((cc->cipher->flags & CFLAG_NONE) != 0) { | ||
264 | ret = 0; | ||
265 | goto out; | ||
266 | } | ||
356 | #ifndef WITH_OPENSSL | 267 | #ifndef WITH_OPENSSL |
357 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { | 268 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { |
358 | aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); | 269 | aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); |
@@ -360,10 +271,6 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, | |||
360 | ret = 0; | 271 | ret = 0; |
361 | goto out; | 272 | goto out; |
362 | } | 273 | } |
363 | if ((cc->cipher->flags & CFLAG_NONE) != 0) { | ||
364 | ret = 0; | ||
365 | goto out; | ||
366 | } | ||
367 | ret = SSH_ERR_INVALID_ARGUMENT; | 274 | ret = SSH_ERR_INVALID_ARGUMENT; |
368 | goto out; | 275 | goto out; |
369 | #else /* WITH_OPENSSL */ | 276 | #else /* WITH_OPENSSL */ |
@@ -394,23 +301,6 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, | |||
394 | ret = SSH_ERR_LIBCRYPTO_ERROR; | 301 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
395 | goto out; | 302 | goto out; |
396 | } | 303 | } |
397 | |||
398 | if (cipher->discard_len > 0) { | ||
399 | if ((junk = malloc(cipher->discard_len)) == NULL || | ||
400 | (discard = malloc(cipher->discard_len)) == NULL) { | ||
401 | free(junk); | ||
402 | ret = SSH_ERR_ALLOC_FAIL; | ||
403 | goto out; | ||
404 | } | ||
405 | ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len); | ||
406 | explicit_bzero(discard, cipher->discard_len); | ||
407 | free(junk); | ||
408 | free(discard); | ||
409 | if (ret != 1) { | ||
410 | ret = SSH_ERR_LIBCRYPTO_ERROR; | ||
411 | goto out; | ||
412 | } | ||
413 | } | ||
414 | ret = 0; | 304 | ret = 0; |
415 | #endif /* WITH_OPENSSL */ | 305 | #endif /* WITH_OPENSSL */ |
416 | out: | 306 | out: |
@@ -448,6 +338,10 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, | |||
448 | return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, | 338 | return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, |
449 | len, aadlen, authlen, cc->encrypt); | 339 | len, aadlen, authlen, cc->encrypt); |
450 | } | 340 | } |
341 | if ((cc->cipher->flags & CFLAG_NONE) != 0) { | ||
342 | memcpy(dest, src, aadlen + len); | ||
343 | return 0; | ||
344 | } | ||
451 | #ifndef WITH_OPENSSL | 345 | #ifndef WITH_OPENSSL |
452 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { | 346 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { |
453 | if (aadlen) | 347 | if (aadlen) |
@@ -456,10 +350,6 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, | |||
456 | dest + aadlen, len); | 350 | dest + aadlen, len); |
457 | return 0; | 351 | return 0; |
458 | } | 352 | } |
459 | if ((cc->cipher->flags & CFLAG_NONE) != 0) { | ||
460 | memcpy(dest, src, aadlen + len); | ||
461 | return 0; | ||
462 | } | ||
463 | return SSH_ERR_INVALID_ARGUMENT; | 353 | return SSH_ERR_INVALID_ARGUMENT; |
464 | #else | 354 | #else |
465 | if (authlen) { | 355 | if (authlen) { |
@@ -536,28 +426,6 @@ cipher_free(struct sshcipher_ctx *cc) | |||
536 | } | 426 | } |
537 | 427 | ||
538 | /* | 428 | /* |
539 | * Selects the cipher, and keys if by computing the MD5 checksum of the | ||
540 | * passphrase and using the resulting 16 bytes as the key. | ||
541 | */ | ||
542 | int | ||
543 | cipher_set_key_string(struct sshcipher_ctx **ccp, | ||
544 | const struct sshcipher *cipher, const char *passphrase, int do_encrypt) | ||
545 | { | ||
546 | u_char digest[16]; | ||
547 | int r = SSH_ERR_INTERNAL_ERROR; | ||
548 | |||
549 | if ((r = ssh_digest_memory(SSH_DIGEST_MD5, | ||
550 | passphrase, strlen(passphrase), | ||
551 | digest, sizeof(digest))) != 0) | ||
552 | goto out; | ||
553 | |||
554 | r = cipher_init(ccp, cipher, digest, 16, NULL, 0, do_encrypt); | ||
555 | out: | ||
556 | explicit_bzero(digest, sizeof(digest)); | ||
557 | return r; | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * Exports an IV from the sshcipher_ctx required to export the key | 429 | * Exports an IV from the sshcipher_ctx required to export the key |
562 | * state back from the unprivileged child to the privileged parent | 430 | * state back from the unprivileged child to the privileged parent |
563 | * process. | 431 | * process. |
@@ -566,19 +434,16 @@ int | |||
566 | cipher_get_keyiv_len(const struct sshcipher_ctx *cc) | 434 | cipher_get_keyiv_len(const struct sshcipher_ctx *cc) |
567 | { | 435 | { |
568 | const struct sshcipher *c = cc->cipher; | 436 | const struct sshcipher *c = cc->cipher; |
569 | int ivlen = 0; | ||
570 | 437 | ||
571 | if (c->number == SSH_CIPHER_3DES) | 438 | if ((c->flags & CFLAG_CHACHAPOLY) != 0) |
572 | ivlen = 24; | 439 | return 0; |
573 | else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 440 | else if ((c->flags & CFLAG_AESCTR) != 0) |
574 | ivlen = 0; | 441 | return sizeof(cc->ac_ctx.ctr); |
575 | else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) | ||
576 | ivlen = sizeof(cc->ac_ctx.ctr); | ||
577 | #ifdef WITH_OPENSSL | 442 | #ifdef WITH_OPENSSL |
578 | else | 443 | return EVP_CIPHER_CTX_iv_length(cc->evp); |
579 | ivlen = EVP_CIPHER_CTX_iv_length(cc->evp); | 444 | #else |
580 | #endif /* WITH_OPENSSL */ | 445 | return 0; |
581 | return (ivlen); | 446 | #endif |
582 | } | 447 | } |
583 | 448 | ||
584 | int | 449 | int |
@@ -603,38 +468,26 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) | |||
603 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | 468 | if ((cc->cipher->flags & CFLAG_NONE) != 0) |
604 | return 0; | 469 | return 0; |
605 | 470 | ||
606 | switch (c->number) { | ||
607 | #ifdef WITH_OPENSSL | 471 | #ifdef WITH_OPENSSL |
608 | case SSH_CIPHER_SSH2: | 472 | evplen = EVP_CIPHER_CTX_iv_length(cc->evp); |
609 | case SSH_CIPHER_DES: | 473 | if (evplen == 0) |
610 | case SSH_CIPHER_BLOWFISH: | 474 | return 0; |
611 | evplen = EVP_CIPHER_CTX_iv_length(cc->evp); | 475 | else if (evplen < 0) |
612 | if (evplen == 0) | 476 | return SSH_ERR_LIBCRYPTO_ERROR; |
613 | return 0; | 477 | if ((u_int)evplen != len) |
614 | else if (evplen < 0) | 478 | return SSH_ERR_INVALID_ARGUMENT; |
615 | return SSH_ERR_LIBCRYPTO_ERROR; | ||
616 | if ((u_int)evplen != len) | ||
617 | return SSH_ERR_INVALID_ARGUMENT; | ||
618 | #ifndef OPENSSL_HAVE_EVPCTR | 479 | #ifndef OPENSSL_HAVE_EVPCTR |
619 | if (c->evptype == evp_aes_128_ctr) | 480 | if (c->evptype == evp_aes_128_ctr) |
620 | ssh_aes_ctr_iv(cc->evp, 0, iv, len); | 481 | ssh_aes_ctr_iv(cc->evp, 0, iv, len); |
621 | else | 482 | else |
622 | #endif | ||
623 | if (cipher_authlen(c)) { | ||
624 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, | ||
625 | len, iv)) | ||
626 | return SSH_ERR_LIBCRYPTO_ERROR; | ||
627 | } else | ||
628 | memcpy(iv, cc->evp->iv, len); | ||
629 | break; | ||
630 | #endif | 483 | #endif |
631 | #ifdef WITH_SSH1 | 484 | if (cipher_authlen(c)) { |
632 | case SSH_CIPHER_3DES: | 485 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, |
633 | return ssh1_3des_iv(cc->evp, 0, iv, 24); | 486 | len, iv)) |
487 | return SSH_ERR_LIBCRYPTO_ERROR; | ||
488 | } else | ||
489 | memcpy(iv, cc->evp->iv, len); | ||
634 | #endif | 490 | #endif |
635 | default: | ||
636 | return SSH_ERR_INVALID_ARGUMENT; | ||
637 | } | ||
638 | return 0; | 491 | return 0; |
639 | } | 492 | } |
640 | 493 | ||
@@ -651,36 +504,24 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) | |||
651 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | 504 | if ((cc->cipher->flags & CFLAG_NONE) != 0) |
652 | return 0; | 505 | return 0; |
653 | 506 | ||
654 | switch (c->number) { | ||
655 | #ifdef WITH_OPENSSL | 507 | #ifdef WITH_OPENSSL |
656 | case SSH_CIPHER_SSH2: | 508 | evplen = EVP_CIPHER_CTX_iv_length(cc->evp); |
657 | case SSH_CIPHER_DES: | 509 | if (evplen <= 0) |
658 | case SSH_CIPHER_BLOWFISH: | 510 | return SSH_ERR_LIBCRYPTO_ERROR; |
659 | evplen = EVP_CIPHER_CTX_iv_length(cc->evp); | ||
660 | if (evplen <= 0) | ||
661 | return SSH_ERR_LIBCRYPTO_ERROR; | ||
662 | #ifndef OPENSSL_HAVE_EVPCTR | 511 | #ifndef OPENSSL_HAVE_EVPCTR |
663 | /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */ | 512 | /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */ |
664 | if (c->evptype == evp_aes_128_ctr) | 513 | if (c->evptype == evp_aes_128_ctr) |
665 | ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen); | 514 | ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen); |
666 | else | 515 | else |
667 | #endif | ||
668 | if (cipher_authlen(c)) { | ||
669 | /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ | ||
670 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, | ||
671 | EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) | ||
672 | return SSH_ERR_LIBCRYPTO_ERROR; | ||
673 | } else | ||
674 | memcpy(cc->evp->iv, iv, evplen); | ||
675 | break; | ||
676 | #endif | 516 | #endif |
677 | #ifdef WITH_SSH1 | 517 | if (cipher_authlen(c)) { |
678 | case SSH_CIPHER_3DES: | 518 | /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ |
679 | return ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24); | 519 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, |
520 | EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) | ||
521 | return SSH_ERR_LIBCRYPTO_ERROR; | ||
522 | } else | ||
523 | memcpy(cc->evp->iv, iv, evplen); | ||
680 | #endif | 524 | #endif |
681 | default: | ||
682 | return SSH_ERR_INVALID_ARGUMENT; | ||
683 | } | ||
684 | return 0; | 525 | return 0; |
685 | } | 526 | } |
686 | 527 | ||