summaryrefslogtreecommitdiff
path: root/cipher.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-04-30 23:15:04 +0000
committerDamien Miller <djm@mindrot.org>2017-05-01 10:04:58 +1000
commitcdccebdf85204bf7542b7fcc1aa2ea3f36661833 (patch)
treefd07acdcdebd7da5dc027e58261a446a807466ba /cipher.c
parent97f4d3083b036ce3e68d6346a6140a22123d5864 (diff)
upstream commit
remove SSHv1 ciphers; ok markus@ Upstream-ID: e5ebc5e540d7f23a8c1266db1839794d4d177890
Diffstat (limited to 'cipher.c')
-rw-r--r--cipher.c237
1 files changed, 75 insertions, 162 deletions
diff --git a/cipher.c b/cipher.c
index 2df2b84bc..622e745d0 100644
--- a/cipher.c
+++ b/cipher.c
@@ -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
64struct sshcipher { 64struct 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
84static const struct sshcipher ciphers[] = { 84static 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
193u_int 190u_int
194cipher_get_number(const struct sshcipher *c)
195{
196 return (c->number);
197}
198
199u_int
200cipher_is_cbc(const struct sshcipher *c) 191cipher_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
211u_int
212cipher_ctx_get_number(struct sshcipher_ctx *cc)
213{
214 return cc->cipher->number;
215}
216
217u_int
218cipher_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
229const struct sshcipher * 202const struct sshcipher *
230cipher_by_name(const char *name) 203cipher_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
239const struct sshcipher *
240cipher_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 ","
250int 213int
251ciphers_valid(const char *names) 214ciphers_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
278int
279cipher_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
290char *
291cipher_name(int id)
292{
293 const struct sshcipher *c = cipher_by_number(id);
294 return (c==NULL) ? "<unknown>" : c->name;
295}
296
297const char * 236const char *
298cipher_warning_message(const struct sshcipher_ctx *cc) 237cipher_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
554cipher_get_keyiv_len(const struct sshcipher_ctx *cc) 486cipher_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
572int 501int
@@ -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