summaryrefslogtreecommitdiff
path: root/cipher.c
diff options
context:
space:
mode:
Diffstat (limited to 'cipher.c')
-rw-r--r--cipher.c81
1 files changed, 69 insertions, 12 deletions
diff --git a/cipher.c b/cipher.c
index a2cbe2bea..2476e6539 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.c,v 1.89 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: cipher.c,v 1.94 2014/01/25 10:12:50 dtucker 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
@@ -43,9 +43,11 @@
43 43
44#include <string.h> 44#include <string.h>
45#include <stdarg.h> 45#include <stdarg.h>
46#include <stdio.h>
46 47
47#include "xmalloc.h" 48#include "xmalloc.h"
48#include "log.h" 49#include "log.h"
50#include "misc.h"
49#include "cipher.h" 51#include "cipher.h"
50 52
51/* compatibility with old or broken OpenSSL versions */ 53/* compatibility with old or broken OpenSSL versions */
@@ -63,7 +65,9 @@ struct Cipher {
63 u_int iv_len; /* defaults to block_size */ 65 u_int iv_len; /* defaults to block_size */
64 u_int auth_len; 66 u_int auth_len;
65 u_int discard_len; 67 u_int discard_len;
66 u_int cbc_mode; 68 u_int flags;
69#define CFLAG_CBC (1<<0)
70#define CFLAG_CHACHAPOLY (1<<1)
67 const EVP_CIPHER *(*evptype)(void); 71 const EVP_CIPHER *(*evptype)(void);
68}; 72};
69 73
@@ -95,14 +99,16 @@ static const struct Cipher ciphers[] = {
95 { "aes256-gcm@openssh.com", 99 { "aes256-gcm@openssh.com",
96 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, 100 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
97#endif 101#endif
102 { "chacha20-poly1305@openssh.com",
103 SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },
98 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } 104 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
99}; 105};
100 106
101/*--*/ 107/*--*/
102 108
103/* Returns a comma-separated list of supported ciphers. */ 109/* Returns a list of supported ciphers separated by the specified char. */
104char * 110char *
105cipher_alg_list(void) 111cipher_alg_list(char sep, int auth_only)
106{ 112{
107 char *ret = NULL; 113 char *ret = NULL;
108 size_t nlen, rlen = 0; 114 size_t nlen, rlen = 0;
@@ -111,8 +117,10 @@ cipher_alg_list(void)
111 for (c = ciphers; c->name != NULL; c++) { 117 for (c = ciphers; c->name != NULL; c++) {
112 if (c->number != SSH_CIPHER_SSH2) 118 if (c->number != SSH_CIPHER_SSH2)
113 continue; 119 continue;
120 if (auth_only && c->auth_len == 0)
121 continue;
114 if (ret != NULL) 122 if (ret != NULL)
115 ret[rlen++] = '\n'; 123 ret[rlen++] = sep;
116 nlen = strlen(c->name); 124 nlen = strlen(c->name);
117 ret = xrealloc(ret, 1, rlen + nlen + 2); 125 ret = xrealloc(ret, 1, rlen + nlen + 2);
118 memcpy(ret + rlen, c->name, nlen + 1); 126 memcpy(ret + rlen, c->name, nlen + 1);
@@ -134,6 +142,14 @@ cipher_keylen(const Cipher *c)
134} 142}
135 143
136u_int 144u_int
145cipher_seclen(const Cipher *c)
146{
147 if (strcmp("3des-cbc", c->name) == 0)
148 return 14;
149 return cipher_keylen(c);
150}
151
152u_int
137cipher_authlen(const Cipher *c) 153cipher_authlen(const Cipher *c)
138{ 154{
139 return (c->auth_len); 155 return (c->auth_len);
@@ -142,7 +158,12 @@ cipher_authlen(const Cipher *c)
142u_int 158u_int
143cipher_ivlen(const Cipher *c) 159cipher_ivlen(const Cipher *c)
144{ 160{
145 return (c->iv_len ? c->iv_len : c->block_size); 161 /*
162 * Default is cipher block size, except for chacha20+poly1305 that
163 * needs no IV. XXX make iv_len == -1 default?
164 */
165 return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ?
166 c->iv_len : c->block_size;
146} 167}
147 168
148u_int 169u_int
@@ -154,7 +175,7 @@ cipher_get_number(const Cipher *c)
154u_int 175u_int
155cipher_is_cbc(const Cipher *c) 176cipher_is_cbc(const Cipher *c)
156{ 177{
157 return (c->cbc_mode); 178 return (c->flags & CFLAG_CBC) != 0;
158} 179}
159 180
160u_int 181u_int
@@ -274,8 +295,11 @@ cipher_init(CipherContext *cc, const Cipher *cipher,
274 ivlen, cipher->name); 295 ivlen, cipher->name);
275 cc->cipher = cipher; 296 cc->cipher = cipher;
276 297
298 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
299 chachapoly_init(&cc->cp_ctx, key, keylen);
300 return;
301 }
277 type = (*cipher->evptype)(); 302 type = (*cipher->evptype)();
278
279 EVP_CIPHER_CTX_init(&cc->evp); 303 EVP_CIPHER_CTX_init(&cc->evp);
280#ifdef SSH_OLD_EVP 304#ifdef SSH_OLD_EVP
281 if (type->key_len > 0 && type->key_len != keylen) { 305 if (type->key_len > 0 && type->key_len != keylen) {
@@ -328,11 +352,16 @@ cipher_init(CipherContext *cc, const Cipher *cipher,
328 * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. 352 * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
329 * This tag is written on encryption and verified on decryption. 353 * This tag is written on encryption and verified on decryption.
330 * Both 'aadlen' and 'authlen' can be set to 0. 354 * Both 'aadlen' and 'authlen' can be set to 0.
355 * cipher_crypt() returns 0 on success and -1 if the decryption integrity
356 * check fails.
331 */ 357 */
332void 358int
333cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, 359cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src,
334 u_int len, u_int aadlen, u_int authlen) 360 u_int len, u_int aadlen, u_int authlen)
335{ 361{
362 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
363 return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len,
364 aadlen, authlen, cc->encrypt);
336 if (authlen) { 365 if (authlen) {
337 u_char lastiv[1]; 366 u_char lastiv[1];
338 367
@@ -365,19 +394,36 @@ cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src,
365 if (cc->encrypt) 394 if (cc->encrypt)
366 fatal("%s: EVP_Cipher(final) failed", __func__); 395 fatal("%s: EVP_Cipher(final) failed", __func__);
367 else 396 else
368 fatal("Decryption integrity check failed"); 397 return -1;
369 } 398 }
370 if (cc->encrypt && 399 if (cc->encrypt &&
371 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, 400 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG,
372 authlen, dest + aadlen + len)) 401 authlen, dest + aadlen + len))
373 fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); 402 fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__);
374 } 403 }
404 return 0;
405}
406
407/* Extract the packet length, including any decryption necessary beforehand */
408int
409cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr,
410 const u_char *cp, u_int len)
411{
412 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
413 return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,
414 cp, len);
415 if (len < 4)
416 return -1;
417 *plenp = get_u32(cp);
418 return 0;
375} 419}
376 420
377void 421void
378cipher_cleanup(CipherContext *cc) 422cipher_cleanup(CipherContext *cc)
379{ 423{
380 if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) 424 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
425 memset(&cc->cp_ctx, 0, sizeof(cc->cp_ctx));
426 else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
381 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); 427 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
382} 428}
383 429
@@ -417,6 +463,8 @@ cipher_get_keyiv_len(const CipherContext *cc)
417 463
418 if (c->number == SSH_CIPHER_3DES) 464 if (c->number == SSH_CIPHER_3DES)
419 ivlen = 24; 465 ivlen = 24;
466 else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
467 ivlen = 0;
420 else 468 else
421 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); 469 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
422 return (ivlen); 470 return (ivlen);
@@ -428,6 +476,12 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
428 const Cipher *c = cc->cipher; 476 const Cipher *c = cc->cipher;
429 int evplen; 477 int evplen;
430 478
479 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
480 if (len != 0)
481 fatal("%s: wrong iv length %d != %d", __func__, len, 0);
482 return;
483 }
484
431 switch (c->number) { 485 switch (c->number) {
432 case SSH_CIPHER_SSH2: 486 case SSH_CIPHER_SSH2:
433 case SSH_CIPHER_DES: 487 case SSH_CIPHER_DES:
@@ -464,6 +518,9 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv)
464 const Cipher *c = cc->cipher; 518 const Cipher *c = cc->cipher;
465 int evplen = 0; 519 int evplen = 0;
466 520
521 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
522 return;
523
467 switch (c->number) { 524 switch (c->number) {
468 case SSH_CIPHER_SSH2: 525 case SSH_CIPHER_SSH2:
469 case SSH_CIPHER_DES: 526 case SSH_CIPHER_DES: