summaryrefslogtreecommitdiff
path: root/cipher.c
diff options
context:
space:
mode:
Diffstat (limited to 'cipher.c')
-rw-r--r--cipher.c407
1 files changed, 242 insertions, 165 deletions
diff --git a/cipher.c b/cipher.c
index 53d9b4fb7..638ca2d97 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.c,v 1.97 2014/02/07 06:55:54 djm Exp $ */ 1/* $OpenBSD: cipher.c,v 1.99 2014/06/24 01:13:21 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
@@ -43,21 +43,21 @@
43#include <stdarg.h> 43#include <stdarg.h>
44#include <stdio.h> 44#include <stdio.h>
45 45
46#include "xmalloc.h"
47#include "log.h"
48#include "misc.h"
49#include "cipher.h" 46#include "cipher.h"
50#include "buffer.h" 47#include "misc.h"
48#include "sshbuf.h"
49#include "ssherr.h"
51#include "digest.h" 50#include "digest.h"
52 51
53/* compatibility with old or broken OpenSSL versions */
54#include "openbsd-compat/openssl-compat.h" 52#include "openbsd-compat/openssl-compat.h"
55 53
54#ifdef WITH_SSH1
56extern const EVP_CIPHER *evp_ssh1_bf(void); 55extern const EVP_CIPHER *evp_ssh1_bf(void);
57extern const EVP_CIPHER *evp_ssh1_3des(void); 56extern const EVP_CIPHER *evp_ssh1_3des(void);
58extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); 57extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
58#endif
59 59
60struct Cipher { 60struct sshcipher {
61 char *name; 61 char *name;
62 int number; /* for ssh1 only */ 62 int number; /* for ssh1 only */
63 u_int block_size; 63 u_int block_size;
@@ -68,15 +68,23 @@ struct Cipher {
68 u_int flags; 68 u_int flags;
69#define CFLAG_CBC (1<<0) 69#define CFLAG_CBC (1<<0)
70#define CFLAG_CHACHAPOLY (1<<1) 70#define CFLAG_CHACHAPOLY (1<<1)
71#define CFLAG_AESCTR (1<<2)
72#define CFLAG_NONE (1<<3)
73#ifdef WITH_OPENSSL
71 const EVP_CIPHER *(*evptype)(void); 74 const EVP_CIPHER *(*evptype)(void);
75#else
76 void *ignored;
77#endif
72}; 78};
73 79
74static const struct Cipher ciphers[] = { 80static const struct sshcipher ciphers[] = {
75 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, 81#ifdef WITH_SSH1
76 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, 82 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
77 { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, 83 { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
78 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, 84 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
79 85#endif /* WITH_SSH1 */
86#ifdef WITH_OPENSSL
87 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
80 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, 88 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
81 { "blowfish-cbc", 89 { "blowfish-cbc",
82 SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, 90 SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
@@ -93,26 +101,33 @@ static const struct Cipher ciphers[] = {
93 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, 101 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr },
94 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, 102 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr },
95 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, 103 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr },
96#ifdef OPENSSL_HAVE_EVPGCM 104# ifdef OPENSSL_HAVE_EVPGCM
97 { "aes128-gcm@openssh.com", 105 { "aes128-gcm@openssh.com",
98 SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, 106 SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },
99 { "aes256-gcm@openssh.com", 107 { "aes256-gcm@openssh.com",
100 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, 108 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
101#endif 109# endif /* OPENSSL_HAVE_EVPGCM */
110#else /* WITH_OPENSSL */
111 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL },
112 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL },
113 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL },
114 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL },
115#endif /* WITH_OPENSSL */
102 { "chacha20-poly1305@openssh.com", 116 { "chacha20-poly1305@openssh.com",
103 SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, 117 SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },
118
104 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } 119 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
105}; 120};
106 121
107/*--*/ 122/*--*/
108 123
109/* Returns a list of supported ciphers separated by the specified char. */ 124/* Returns a comma-separated list of supported ciphers. */
110char * 125char *
111cipher_alg_list(char sep, int auth_only) 126cipher_alg_list(char sep, int auth_only)
112{ 127{
113 char *ret = NULL; 128 char *tmp, *ret = NULL;
114 size_t nlen, rlen = 0; 129 size_t nlen, rlen = 0;
115 const Cipher *c; 130 const struct sshcipher *c;
116 131
117 for (c = ciphers; c->name != NULL; c++) { 132 for (c = ciphers; c->name != NULL; c++) {
118 if (c->number != SSH_CIPHER_SSH2) 133 if (c->number != SSH_CIPHER_SSH2)
@@ -122,7 +137,11 @@ cipher_alg_list(char sep, int auth_only)
122 if (ret != NULL) 137 if (ret != NULL)
123 ret[rlen++] = sep; 138 ret[rlen++] = sep;
124 nlen = strlen(c->name); 139 nlen = strlen(c->name);
125 ret = xrealloc(ret, 1, rlen + nlen + 2); 140 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
141 free(ret);
142 return NULL;
143 }
144 ret = tmp;
126 memcpy(ret + rlen, c->name, nlen + 1); 145 memcpy(ret + rlen, c->name, nlen + 1);
127 rlen += nlen; 146 rlen += nlen;
128 } 147 }
@@ -130,19 +149,19 @@ cipher_alg_list(char sep, int auth_only)
130} 149}
131 150
132u_int 151u_int
133cipher_blocksize(const Cipher *c) 152cipher_blocksize(const struct sshcipher *c)
134{ 153{
135 return (c->block_size); 154 return (c->block_size);
136} 155}
137 156
138u_int 157u_int
139cipher_keylen(const Cipher *c) 158cipher_keylen(const struct sshcipher *c)
140{ 159{
141 return (c->key_len); 160 return (c->key_len);
142} 161}
143 162
144u_int 163u_int
145cipher_seclen(const Cipher *c) 164cipher_seclen(const struct sshcipher *c)
146{ 165{
147 if (strcmp("3des-cbc", c->name) == 0) 166 if (strcmp("3des-cbc", c->name) == 0)
148 return 14; 167 return 14;
@@ -150,13 +169,13 @@ cipher_seclen(const Cipher *c)
150} 169}
151 170
152u_int 171u_int
153cipher_authlen(const Cipher *c) 172cipher_authlen(const struct sshcipher *c)
154{ 173{
155 return (c->auth_len); 174 return (c->auth_len);
156} 175}
157 176
158u_int 177u_int
159cipher_ivlen(const Cipher *c) 178cipher_ivlen(const struct sshcipher *c)
160{ 179{
161 /* 180 /*
162 * Default is cipher block size, except for chacha20+poly1305 that 181 * Default is cipher block size, except for chacha20+poly1305 that
@@ -167,13 +186,13 @@ cipher_ivlen(const Cipher *c)
167} 186}
168 187
169u_int 188u_int
170cipher_get_number(const Cipher *c) 189cipher_get_number(const struct sshcipher *c)
171{ 190{
172 return (c->number); 191 return (c->number);
173} 192}
174 193
175u_int 194u_int
176cipher_is_cbc(const Cipher *c) 195cipher_is_cbc(const struct sshcipher *c)
177{ 196{
178 return (c->flags & CFLAG_CBC) != 0; 197 return (c->flags & CFLAG_CBC) != 0;
179} 198}
@@ -190,20 +209,20 @@ cipher_mask_ssh1(int client)
190 return mask; 209 return mask;
191} 210}
192 211
193const Cipher * 212const struct sshcipher *
194cipher_by_name(const char *name) 213cipher_by_name(const char *name)
195{ 214{
196 const Cipher *c; 215 const struct sshcipher *c;
197 for (c = ciphers; c->name != NULL; c++) 216 for (c = ciphers; c->name != NULL; c++)
198 if (strcmp(c->name, name) == 0) 217 if (strcmp(c->name, name) == 0)
199 return c; 218 return c;
200 return NULL; 219 return NULL;
201} 220}
202 221
203const Cipher * 222const struct sshcipher *
204cipher_by_number(int id) 223cipher_by_number(int id)
205{ 224{
206 const Cipher *c; 225 const struct sshcipher *c;
207 for (c = ciphers; c->name != NULL; c++) 226 for (c = ciphers; c->name != NULL; c++)
208 if (c->number == id) 227 if (c->number == id)
209 return c; 228 return c;
@@ -214,23 +233,22 @@ cipher_by_number(int id)
214int 233int
215ciphers_valid(const char *names) 234ciphers_valid(const char *names)
216{ 235{
217 const Cipher *c; 236 const struct sshcipher *c;
218 char *cipher_list, *cp; 237 char *cipher_list, *cp;
219 char *p; 238 char *p;
220 239
221 if (names == NULL || strcmp(names, "") == 0) 240 if (names == NULL || strcmp(names, "") == 0)
222 return 0; 241 return 0;
223 cipher_list = cp = xstrdup(names); 242 if ((cipher_list = cp = strdup(names)) == NULL)
243 return 0;
224 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; 244 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
225 (p = strsep(&cp, CIPHER_SEP))) { 245 (p = strsep(&cp, CIPHER_SEP))) {
226 c = cipher_by_name(p); 246 c = cipher_by_name(p);
227 if (c == NULL || c->number != SSH_CIPHER_SSH2) { 247 if (c == NULL || c->number != SSH_CIPHER_SSH2) {
228 debug("bad cipher %s [%s]", p, names);
229 free(cipher_list); 248 free(cipher_list);
230 return 0; 249 return 0;
231 } 250 }
232 } 251 }
233 debug3("ciphers ok: [%s]", names);
234 free(cipher_list); 252 free(cipher_list);
235 return 1; 253 return 1;
236} 254}
@@ -243,7 +261,7 @@ ciphers_valid(const char *names)
243int 261int
244cipher_number(const char *name) 262cipher_number(const char *name)
245{ 263{
246 const Cipher *c; 264 const struct sshcipher *c;
247 if (name == NULL) 265 if (name == NULL)
248 return -1; 266 return -1;
249 for (c = ciphers; c->name != NULL; c++) 267 for (c = ciphers; c->name != NULL; c++)
@@ -255,90 +273,104 @@ cipher_number(const char *name)
255char * 273char *
256cipher_name(int id) 274cipher_name(int id)
257{ 275{
258 const Cipher *c = cipher_by_number(id); 276 const struct sshcipher *c = cipher_by_number(id);
259 return (c==NULL) ? "<unknown>" : c->name; 277 return (c==NULL) ? "<unknown>" : c->name;
260} 278}
261 279
262void 280const char *
263cipher_init(CipherContext *cc, const Cipher *cipher, 281cipher_warning_message(const struct sshcipher_ctx *cc)
282{
283 if (cc == NULL || cc->cipher == NULL)
284 return NULL;
285 if (cc->cipher->number == SSH_CIPHER_DES)
286 return "use of DES is strongly discouraged due to "
287 "cryptographic weaknesses";
288 return NULL;
289}
290
291int
292cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
264 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, 293 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
265 int do_encrypt) 294 int do_encrypt)
266{ 295{
267 static int dowarn = 1; 296#ifdef WITH_OPENSSL
268#ifdef SSH_OLD_EVP 297 int ret = SSH_ERR_INTERNAL_ERROR;
269 EVP_CIPHER *type;
270#else
271 const EVP_CIPHER *type; 298 const EVP_CIPHER *type;
272 int klen; 299 int klen;
273#endif
274 u_char *junk, *discard; 300 u_char *junk, *discard;
275 301
276 if (cipher->number == SSH_CIPHER_DES) { 302 if (cipher->number == SSH_CIPHER_DES) {
277 if (dowarn) {
278 error("Warning: use of DES is strongly discouraged "
279 "due to cryptographic weaknesses");
280 dowarn = 0;
281 }
282 if (keylen > 8) 303 if (keylen > 8)
283 keylen = 8; 304 keylen = 8;
284 } 305 }
306#endif
285 cc->plaintext = (cipher->number == SSH_CIPHER_NONE); 307 cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
286 cc->encrypt = do_encrypt; 308 cc->encrypt = do_encrypt;
287 309
288 if (keylen < cipher->key_len) 310 if (keylen < cipher->key_len ||
289 fatal("cipher_init: key length %d is insufficient for %s.", 311 (iv != NULL && ivlen < cipher_ivlen(cipher)))
290 keylen, cipher->name); 312 return SSH_ERR_INVALID_ARGUMENT;
291 if (iv != NULL && ivlen < cipher_ivlen(cipher))
292 fatal("cipher_init: iv length %d is insufficient for %s.",
293 ivlen, cipher->name);
294 cc->cipher = cipher;
295 313
314 cc->cipher = cipher;
296 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 315 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
297 chachapoly_init(&cc->cp_ctx, key, keylen); 316 return chachapoly_init(&cc->cp_ctx, key, keylen);
298 return;
299 } 317 }
300 type = (*cipher->evptype)(); 318#ifndef WITH_OPENSSL
301 EVP_CIPHER_CTX_init(&cc->evp); 319 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
302#ifdef SSH_OLD_EVP 320 aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
303 if (type->key_len > 0 && type->key_len != keylen) { 321 aesctr_ivsetup(&cc->ac_ctx, iv);
304 debug("cipher_init: set keylen (%d -> %d)", 322 return 0;
305 type->key_len, keylen);
306 type->key_len = keylen;
307 } 323 }
308 EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv, 324 if ((cc->cipher->flags & CFLAG_NONE) != 0)
309 (do_encrypt == CIPHER_ENCRYPT)); 325 return 0;
326 return SSH_ERR_INVALID_ARGUMENT;
310#else 327#else
328 type = (*cipher->evptype)();
329 EVP_CIPHER_CTX_init(&cc->evp);
311 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, 330 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
312 (do_encrypt == CIPHER_ENCRYPT)) == 0) 331 (do_encrypt == CIPHER_ENCRYPT)) == 0) {
313 fatal("cipher_init: EVP_CipherInit failed for %s", 332 ret = SSH_ERR_LIBCRYPTO_ERROR;
314 cipher->name); 333 goto bad;
334 }
315 if (cipher_authlen(cipher) && 335 if (cipher_authlen(cipher) &&
316 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, 336 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
317 -1, (u_char *)iv)) 337 -1, (u_char *)iv)) {
318 fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s", 338 ret = SSH_ERR_LIBCRYPTO_ERROR;
319 cipher->name); 339 goto bad;
340 }
320 klen = EVP_CIPHER_CTX_key_length(&cc->evp); 341 klen = EVP_CIPHER_CTX_key_length(&cc->evp);
321 if (klen > 0 && keylen != (u_int)klen) { 342 if (klen > 0 && keylen != (u_int)klen) {
322 debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); 343 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) {
323 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) 344 ret = SSH_ERR_LIBCRYPTO_ERROR;
324 fatal("cipher_init: set keylen failed (%d -> %d)", 345 goto bad;
325 klen, keylen); 346 }
347 }
348 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
349 ret = SSH_ERR_LIBCRYPTO_ERROR;
350 goto bad;
326 } 351 }
327 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
328 fatal("cipher_init: EVP_CipherInit: set key failed for %s",
329 cipher->name);
330#endif
331 352
332 if (cipher->discard_len > 0) { 353 if (cipher->discard_len > 0) {
333 junk = xmalloc(cipher->discard_len); 354 if ((junk = malloc(cipher->discard_len)) == NULL ||
334 discard = xmalloc(cipher->discard_len); 355 (discard = malloc(cipher->discard_len)) == NULL) {
335 if (EVP_Cipher(&cc->evp, discard, junk, 356 if (junk != NULL)
336 cipher->discard_len) == 0) 357 free(junk);
337 fatal("evp_crypt: EVP_Cipher failed during discard"); 358 ret = SSH_ERR_ALLOC_FAIL;
359 goto bad;
360 }
361 ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len);
338 explicit_bzero(discard, cipher->discard_len); 362 explicit_bzero(discard, cipher->discard_len);
339 free(junk); 363 free(junk);
340 free(discard); 364 free(discard);
365 if (ret != 1) {
366 ret = SSH_ERR_LIBCRYPTO_ERROR;
367 bad:
368 EVP_CIPHER_CTX_cleanup(&cc->evp);
369 return ret;
370 }
341 } 371 }
372#endif
373 return 0;
342} 374}
343 375
344/* 376/*
@@ -350,204 +382,244 @@ cipher_init(CipherContext *cc, const Cipher *cipher,
350 * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. 382 * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
351 * This tag is written on encryption and verified on decryption. 383 * This tag is written on encryption and verified on decryption.
352 * Both 'aadlen' and 'authlen' can be set to 0. 384 * Both 'aadlen' and 'authlen' can be set to 0.
353 * cipher_crypt() returns 0 on success and -1 if the decryption integrity
354 * check fails.
355 */ 385 */
356int 386int
357cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, 387cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
358 u_int len, u_int aadlen, u_int authlen) 388 const u_char *src, u_int len, u_int aadlen, u_int authlen)
359{ 389{
360 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 390 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
361 return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, 391 return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src,
362 aadlen, authlen, cc->encrypt); 392 len, aadlen, authlen, cc->encrypt);
393 }
394#ifndef WITH_OPENSSL
395 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
396 if (aadlen)
397 memcpy(dest, src, aadlen);
398 aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen,
399 dest + aadlen, len);
400 return 0;
401 }
402 if ((cc->cipher->flags & CFLAG_NONE) != 0) {
403 memcpy(dest, src, aadlen + len);
404 return 0;
405 }
406 return SSH_ERR_INVALID_ARGUMENT;
407#else
363 if (authlen) { 408 if (authlen) {
364 u_char lastiv[1]; 409 u_char lastiv[1];
365 410
366 if (authlen != cipher_authlen(cc->cipher)) 411 if (authlen != cipher_authlen(cc->cipher))
367 fatal("%s: authlen mismatch %d", __func__, authlen); 412 return SSH_ERR_INVALID_ARGUMENT;
368 /* increment IV */ 413 /* increment IV */
369 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, 414 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
370 1, lastiv)) 415 1, lastiv))
371 fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__); 416 return SSH_ERR_LIBCRYPTO_ERROR;
372 /* set tag on decyption */ 417 /* set tag on decyption */
373 if (!cc->encrypt && 418 if (!cc->encrypt &&
374 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, 419 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG,
375 authlen, (u_char *)src + aadlen + len)) 420 authlen, (u_char *)src + aadlen + len))
376 fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__); 421 return SSH_ERR_LIBCRYPTO_ERROR;
377 } 422 }
378 if (aadlen) { 423 if (aadlen) {
379 if (authlen && 424 if (authlen &&
380 EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) 425 EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0)
381 fatal("%s: EVP_Cipher(aad) failed", __func__); 426 return SSH_ERR_LIBCRYPTO_ERROR;
382 memcpy(dest, src, aadlen); 427 memcpy(dest, src, aadlen);
383 } 428 }
384 if (len % cc->cipher->block_size) 429 if (len % cc->cipher->block_size)
385 fatal("%s: bad plaintext length %d", __func__, len); 430 return SSH_ERR_INVALID_ARGUMENT;
386 if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, 431 if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen,
387 len) < 0) 432 len) < 0)
388 fatal("%s: EVP_Cipher failed", __func__); 433 return SSH_ERR_LIBCRYPTO_ERROR;
389 if (authlen) { 434 if (authlen) {
390 /* compute tag (on encrypt) or verify tag (on decrypt) */ 435 /* compute tag (on encrypt) or verify tag (on decrypt) */
391 if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) { 436 if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0)
392 if (cc->encrypt) 437 return cc->encrypt ?
393 fatal("%s: EVP_Cipher(final) failed", __func__); 438 SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID;
394 else
395 return -1;
396 }
397 if (cc->encrypt && 439 if (cc->encrypt &&
398 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, 440 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG,
399 authlen, dest + aadlen + len)) 441 authlen, dest + aadlen + len))
400 fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); 442 return SSH_ERR_LIBCRYPTO_ERROR;
401 } 443 }
402 return 0; 444 return 0;
445#endif
403} 446}
404 447
405/* Extract the packet length, including any decryption necessary beforehand */ 448/* Extract the packet length, including any decryption necessary beforehand */
406int 449int
407cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr, 450cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr,
408 const u_char *cp, u_int len) 451 const u_char *cp, u_int len)
409{ 452{
410 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 453 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
411 return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, 454 return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,
412 cp, len); 455 cp, len);
413 if (len < 4) 456 if (len < 4)
414 return -1; 457 return SSH_ERR_MESSAGE_INCOMPLETE;
415 *plenp = get_u32(cp); 458 *plenp = get_u32(cp);
416 return 0; 459 return 0;
417} 460}
418 461
419void 462int
420cipher_cleanup(CipherContext *cc) 463cipher_cleanup(struct sshcipher_ctx *cc)
421{ 464{
465 if (cc == NULL || cc->cipher == NULL)
466 return 0;
422 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 467 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
423 explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); 468 explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
469 else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
470 explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
471#ifdef WITH_OPENSSL
424 else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) 472 else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
425 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); 473 return SSH_ERR_LIBCRYPTO_ERROR;
474#endif
475 return 0;
426} 476}
427 477
428/* 478/*
429 * Selects the cipher, and keys if by computing the MD5 checksum of the 479 * Selects the cipher, and keys if by computing the MD5 checksum of the
430 * passphrase and using the resulting 16 bytes as the key. 480 * passphrase and using the resulting 16 bytes as the key.
431 */ 481 */
432 482int
433void 483cipher_set_key_string(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
434cipher_set_key_string(CipherContext *cc, const Cipher *cipher,
435 const char *passphrase, int do_encrypt) 484 const char *passphrase, int do_encrypt)
436{ 485{
437 u_char digest[16]; 486 u_char digest[16];
487 int r = SSH_ERR_INTERNAL_ERROR;
438 488
439 if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase), 489 if ((r = ssh_digest_memory(SSH_DIGEST_MD5,
440 digest, sizeof(digest)) < 0) 490 passphrase, strlen(passphrase),
441 fatal("%s: md5 failed", __func__); 491 digest, sizeof(digest))) != 0)
442 492 goto out;
443 cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
444 493
494 r = cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
495 out:
445 explicit_bzero(digest, sizeof(digest)); 496 explicit_bzero(digest, sizeof(digest));
497 return r;
446} 498}
447 499
448/* 500/*
449 * Exports an IV from the CipherContext required to export the key 501 * Exports an IV from the sshcipher_ctx required to export the key
450 * state back from the unprivileged child to the privileged parent 502 * state back from the unprivileged child to the privileged parent
451 * process. 503 * process.
452 */ 504 */
453
454int 505int
455cipher_get_keyiv_len(const CipherContext *cc) 506cipher_get_keyiv_len(const struct sshcipher_ctx *cc)
456{ 507{
457 const Cipher *c = cc->cipher; 508 const struct sshcipher *c = cc->cipher;
458 int ivlen; 509 int ivlen = 0;
459 510
460 if (c->number == SSH_CIPHER_3DES) 511 if (c->number == SSH_CIPHER_3DES)
461 ivlen = 24; 512 ivlen = 24;
462 else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 513 else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
463 ivlen = 0; 514 ivlen = 0;
515#ifdef WITH_OPENSSL
464 else 516 else
465 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); 517 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
518#endif /* WITH_OPENSSL */
466 return (ivlen); 519 return (ivlen);
467} 520}
468 521
469void 522int
470cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) 523cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
471{ 524{
472 const Cipher *c = cc->cipher; 525 const struct sshcipher *c = cc->cipher;
473 int evplen; 526#ifdef WITH_OPENSSL
527 int evplen;
528#endif
474 529
475 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 530 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
476 if (len != 0) 531 if (len != 0)
477 fatal("%s: wrong iv length %d != %d", __func__, len, 0); 532 return SSH_ERR_INVALID_ARGUMENT;
478 return; 533 return 0;
479 } 534 }
535 if ((cc->cipher->flags & CFLAG_NONE) != 0)
536 return 0;
480 537
481 switch (c->number) { 538 switch (c->number) {
539#ifdef WITH_OPENSSL
482 case SSH_CIPHER_SSH2: 540 case SSH_CIPHER_SSH2:
483 case SSH_CIPHER_DES: 541 case SSH_CIPHER_DES:
484 case SSH_CIPHER_BLOWFISH: 542 case SSH_CIPHER_BLOWFISH:
485 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 543 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
486 if (evplen <= 0) 544 if (evplen == 0)
487 return; 545 return 0;
546 else if (evplen < 0)
547 return SSH_ERR_LIBCRYPTO_ERROR;
488 if ((u_int)evplen != len) 548 if ((u_int)evplen != len)
489 fatal("%s: wrong iv length %d != %d", __func__, 549 return SSH_ERR_INVALID_ARGUMENT;
490 evplen, len);
491#ifdef USE_BUILTIN_RIJNDAEL
492 if (c->evptype == evp_rijndael)
493 ssh_rijndael_iv(&cc->evp, 0, iv, len);
494 else
495#endif
496#ifndef OPENSSL_HAVE_EVPCTR 550#ifndef OPENSSL_HAVE_EVPCTR
497 if (c->evptype == evp_aes_128_ctr) 551 if (c->evptype == evp_aes_128_ctr)
498 ssh_aes_ctr_iv(&cc->evp, 0, iv, len); 552 ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
499 else 553 else
500#endif 554#endif
501 memcpy(iv, cc->evp.iv, len); 555 if (cipher_authlen(c)) {
556 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
557 len, iv))
558 return SSH_ERR_LIBCRYPTO_ERROR;
559 } else
560 memcpy(iv, cc->evp.iv, len);
502 break; 561 break;
562#endif
563#ifdef WITH_SSH1
503 case SSH_CIPHER_3DES: 564 case SSH_CIPHER_3DES:
504 ssh1_3des_iv(&cc->evp, 0, iv, 24); 565 return ssh1_3des_iv(&cc->evp, 0, iv, 24);
505 break; 566#endif
506 default: 567 default:
507 fatal("%s: bad cipher %d", __func__, c->number); 568 return SSH_ERR_INVALID_ARGUMENT;
508 } 569 }
570 return 0;
509} 571}
510 572
511void 573int
512cipher_set_keyiv(CipherContext *cc, u_char *iv) 574cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
513{ 575{
514 const Cipher *c = cc->cipher; 576 const struct sshcipher *c = cc->cipher;
515 int evplen = 0; 577#ifdef WITH_OPENSSL
578 int evplen = 0;
579#endif
516 580
517 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 581 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
518 return; 582 return 0;
583 if ((cc->cipher->flags & CFLAG_NONE) != 0)
584 return 0;
519 585
520 switch (c->number) { 586 switch (c->number) {
587#ifdef WITH_OPENSSL
521 case SSH_CIPHER_SSH2: 588 case SSH_CIPHER_SSH2:
522 case SSH_CIPHER_DES: 589 case SSH_CIPHER_DES:
523 case SSH_CIPHER_BLOWFISH: 590 case SSH_CIPHER_BLOWFISH:
524 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 591 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
525 if (evplen == 0) 592 if (evplen <= 0)
526 return; 593 return SSH_ERR_LIBCRYPTO_ERROR;
527#ifdef USE_BUILTIN_RIJNDAEL 594 if (cipher_authlen(c)) {
528 if (c->evptype == evp_rijndael) 595 /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */
529 ssh_rijndael_iv(&cc->evp, 1, iv, evplen); 596 if (!EVP_CIPHER_CTX_ctrl(&cc->evp,
530 else 597 EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
531#endif 598 return SSH_ERR_LIBCRYPTO_ERROR;
532#ifndef OPENSSL_HAVE_EVPCTR 599 } else
533 if (c->evptype == evp_aes_128_ctr) 600 memcpy(cc->evp.iv, iv, evplen);
534 ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
535 else
536#endif
537 memcpy(cc->evp.iv, iv, evplen);
538 break; 601 break;
602#endif
603#ifdef WITH_SSH1
539 case SSH_CIPHER_3DES: 604 case SSH_CIPHER_3DES:
540 ssh1_3des_iv(&cc->evp, 1, iv, 24); 605 return ssh1_3des_iv(&cc->evp, 1, (u_char *)iv, 24);
541 break; 606#endif
542 default: 607 default:
543 fatal("%s: bad cipher %d", __func__, c->number); 608 return SSH_ERR_INVALID_ARGUMENT;
544 } 609 }
610 return 0;
545} 611}
546 612
613#ifdef WITH_OPENSSL
614#define EVP_X_STATE(evp) (evp).cipher_data
615#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size
616#endif
617
547int 618int
548cipher_get_keycontext(const CipherContext *cc, u_char *dat) 619cipher_get_keycontext(const struct sshcipher_ctx *cc, u_char *dat)
549{ 620{
550 const Cipher *c = cc->cipher; 621#ifdef WITH_OPENSSL
622 const struct sshcipher *c = cc->cipher;
551 int plen = 0; 623 int plen = 0;
552 624
553 if (c->evptype == EVP_rc4) { 625 if (c->evptype == EVP_rc4) {
@@ -557,16 +629,21 @@ cipher_get_keycontext(const CipherContext *cc, u_char *dat)
557 memcpy(dat, EVP_X_STATE(cc->evp), plen); 629 memcpy(dat, EVP_X_STATE(cc->evp), plen);
558 } 630 }
559 return (plen); 631 return (plen);
632#else
633 return 0;
634#endif
560} 635}
561 636
562void 637void
563cipher_set_keycontext(CipherContext *cc, u_char *dat) 638cipher_set_keycontext(struct sshcipher_ctx *cc, const u_char *dat)
564{ 639{
565 const Cipher *c = cc->cipher; 640#ifdef WITH_OPENSSL
641 const struct sshcipher *c = cc->cipher;
566 int plen; 642 int plen;
567 643
568 if (c->evptype == EVP_rc4) { 644 if (c->evptype == EVP_rc4) {
569 plen = EVP_X_STATE_LEN(cc->evp); 645 plen = EVP_X_STATE_LEN(cc->evp);
570 memcpy(EVP_X_STATE(cc->evp), dat, plen); 646 memcpy(EVP_X_STATE(cc->evp), dat, plen);
571 } 647 }
648#endif
572} 649}