diff options
Diffstat (limited to 'cipher.c')
-rw-r--r-- | cipher.c | 147 |
1 files changed, 106 insertions, 41 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher.c,v 1.82 2009/01/26 09:58:15 markus Exp $ */ | 1 | /* $OpenBSD: cipher.c,v 1.87 2013/01/26 06:11:05 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 |
@@ -54,41 +54,46 @@ | |||
54 | extern const EVP_CIPHER *evp_ssh1_bf(void); | 54 | extern const EVP_CIPHER *evp_ssh1_bf(void); |
55 | extern const EVP_CIPHER *evp_ssh1_3des(void); | 55 | extern const EVP_CIPHER *evp_ssh1_3des(void); |
56 | extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); | 56 | extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); |
57 | extern const EVP_CIPHER *evp_aes_128_ctr(void); | ||
58 | extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); | ||
59 | 57 | ||
60 | struct Cipher { | 58 | struct Cipher { |
61 | char *name; | 59 | char *name; |
62 | int number; /* for ssh1 only */ | 60 | int number; /* for ssh1 only */ |
63 | u_int block_size; | 61 | u_int block_size; |
64 | u_int key_len; | 62 | u_int key_len; |
63 | u_int iv_len; /* defaults to block_size */ | ||
64 | u_int auth_len; | ||
65 | u_int discard_len; | 65 | u_int discard_len; |
66 | u_int cbc_mode; | 66 | u_int cbc_mode; |
67 | const EVP_CIPHER *(*evptype)(void); | 67 | const EVP_CIPHER *(*evptype)(void); |
68 | } ciphers[] = { | 68 | } ciphers[] = { |
69 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null }, | 69 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, |
70 | { "des", SSH_CIPHER_DES, 8, 8, 0, 1, EVP_des_cbc }, | 70 | { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, |
71 | { "3des", SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des }, | 71 | { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, |
72 | { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 1, evp_ssh1_bf }, | 72 | { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, |
73 | 73 | ||
74 | { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc }, | 74 | { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, |
75 | { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_bf_cbc }, | 75 | { "blowfish-cbc", |
76 | { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_cast5_cbc }, | 76 | SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, |
77 | { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, EVP_rc4 }, | 77 | { "cast128-cbc", |
78 | { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, 0, EVP_rc4 }, | 78 | SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc }, |
79 | { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, 0, EVP_rc4 }, | 79 | { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 }, |
80 | { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc }, | 80 | { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 }, |
81 | { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc }, | 81 | { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 }, |
82 | { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, | 82 | { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, |
83 | { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, | ||
84 | { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, | ||
83 | { "rijndael-cbc@lysator.liu.se", | 85 | { "rijndael-cbc@lysator.liu.se", |
84 | SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, | 86 | SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, |
85 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr }, | 87 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, |
86 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr }, | 88 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, |
87 | { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr }, | 89 | { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, |
88 | #ifdef USE_CIPHER_ACSS | 90 | #ifdef OPENSSL_HAVE_EVPGCM |
89 | { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss }, | 91 | { "aes128-gcm@openssh.com", |
92 | SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, | ||
93 | { "aes256-gcm@openssh.com", | ||
94 | SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, | ||
90 | #endif | 95 | #endif |
91 | { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } | 96 | { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } |
92 | }; | 97 | }; |
93 | 98 | ||
94 | /*--*/ | 99 | /*--*/ |
@@ -106,6 +111,18 @@ cipher_keylen(const Cipher *c) | |||
106 | } | 111 | } |
107 | 112 | ||
108 | u_int | 113 | u_int |
114 | cipher_authlen(const Cipher *c) | ||
115 | { | ||
116 | return (c->auth_len); | ||
117 | } | ||
118 | |||
119 | u_int | ||
120 | cipher_ivlen(const Cipher *c) | ||
121 | { | ||
122 | return (c->iv_len ? c->iv_len : c->block_size); | ||
123 | } | ||
124 | |||
125 | u_int | ||
109 | cipher_get_number(const Cipher *c) | 126 | cipher_get_number(const Cipher *c) |
110 | { | 127 | { |
111 | return (c->number); | 128 | return (c->number); |
@@ -224,11 +241,12 @@ cipher_init(CipherContext *cc, Cipher *cipher, | |||
224 | keylen = 8; | 241 | keylen = 8; |
225 | } | 242 | } |
226 | cc->plaintext = (cipher->number == SSH_CIPHER_NONE); | 243 | cc->plaintext = (cipher->number == SSH_CIPHER_NONE); |
244 | cc->encrypt = do_encrypt; | ||
227 | 245 | ||
228 | if (keylen < cipher->key_len) | 246 | if (keylen < cipher->key_len) |
229 | fatal("cipher_init: key length %d is insufficient for %s.", | 247 | fatal("cipher_init: key length %d is insufficient for %s.", |
230 | keylen, cipher->name); | 248 | keylen, cipher->name); |
231 | if (iv != NULL && ivlen < cipher->block_size) | 249 | if (iv != NULL && ivlen < cipher_ivlen(cipher)) |
232 | fatal("cipher_init: iv length %d is insufficient for %s.", | 250 | fatal("cipher_init: iv length %d is insufficient for %s.", |
233 | ivlen, cipher->name); | 251 | ivlen, cipher->name); |
234 | cc->cipher = cipher; | 252 | cc->cipher = cipher; |
@@ -249,6 +267,11 @@ cipher_init(CipherContext *cc, Cipher *cipher, | |||
249 | (do_encrypt == CIPHER_ENCRYPT)) == 0) | 267 | (do_encrypt == CIPHER_ENCRYPT)) == 0) |
250 | fatal("cipher_init: EVP_CipherInit failed for %s", | 268 | fatal("cipher_init: EVP_CipherInit failed for %s", |
251 | cipher->name); | 269 | cipher->name); |
270 | if (cipher_authlen(cipher) && | ||
271 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, | ||
272 | -1, (u_char *)iv)) | ||
273 | fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s", | ||
274 | cipher->name); | ||
252 | klen = EVP_CIPHER_CTX_key_length(&cc->evp); | 275 | klen = EVP_CIPHER_CTX_key_length(&cc->evp); |
253 | if (klen > 0 && keylen != (u_int)klen) { | 276 | if (klen > 0 && keylen != (u_int)klen) { |
254 | debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); | 277 | debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); |
@@ -273,13 +296,59 @@ cipher_init(CipherContext *cc, Cipher *cipher, | |||
273 | } | 296 | } |
274 | } | 297 | } |
275 | 298 | ||
299 | /* | ||
300 | * cipher_crypt() operates as following: | ||
301 | * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'. | ||
302 | * Theses bytes are treated as additional authenticated data for | ||
303 | * authenticated encryption modes. | ||
304 | * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. | ||
305 | * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. | ||
306 | * This tag is written on encryption and verified on decryption. | ||
307 | * Both 'aadlen' and 'authlen' can be set to 0. | ||
308 | */ | ||
276 | void | 309 | void |
277 | cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) | 310 | cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, |
311 | u_int len, u_int aadlen, u_int authlen) | ||
278 | { | 312 | { |
313 | if (authlen) { | ||
314 | u_char lastiv[1]; | ||
315 | |||
316 | if (authlen != cipher_authlen(cc->cipher)) | ||
317 | fatal("%s: authlen mismatch %d", __func__, authlen); | ||
318 | /* increment IV */ | ||
319 | if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, | ||
320 | 1, lastiv)) | ||
321 | fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__); | ||
322 | /* set tag on decyption */ | ||
323 | if (!cc->encrypt && | ||
324 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, | ||
325 | authlen, (u_char *)src + aadlen + len)) | ||
326 | fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__); | ||
327 | } | ||
328 | if (aadlen) { | ||
329 | if (authlen && | ||
330 | EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) | ||
331 | fatal("%s: EVP_Cipher(aad) failed", __func__); | ||
332 | memcpy(dest, src, aadlen); | ||
333 | } | ||
279 | if (len % cc->cipher->block_size) | 334 | if (len % cc->cipher->block_size) |
280 | fatal("cipher_encrypt: bad plaintext length %d", len); | 335 | fatal("%s: bad plaintext length %d", __func__, len); |
281 | if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0) | 336 | if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, |
282 | fatal("evp_crypt: EVP_Cipher failed"); | 337 | len) < 0) |
338 | fatal("%s: EVP_Cipher failed", __func__); | ||
339 | if (authlen) { | ||
340 | /* compute tag (on encrypt) or verify tag (on decrypt) */ | ||
341 | if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) { | ||
342 | if (cc->encrypt) | ||
343 | fatal("%s: EVP_Cipher(final) failed", __func__); | ||
344 | else | ||
345 | fatal("Decryption integrity check failed"); | ||
346 | } | ||
347 | if (cc->encrypt && | ||
348 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, | ||
349 | authlen, dest + aadlen + len)) | ||
350 | fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); | ||
351 | } | ||
283 | } | 352 | } |
284 | 353 | ||
285 | void | 354 | void |
@@ -351,10 +420,12 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) | |||
351 | ssh_rijndael_iv(&cc->evp, 0, iv, len); | 420 | ssh_rijndael_iv(&cc->evp, 0, iv, len); |
352 | else | 421 | else |
353 | #endif | 422 | #endif |
423 | #ifndef OPENSSL_HAVE_EVPCTR | ||
354 | if (c->evptype == evp_aes_128_ctr) | 424 | if (c->evptype == evp_aes_128_ctr) |
355 | ssh_aes_ctr_iv(&cc->evp, 0, iv, len); | 425 | ssh_aes_ctr_iv(&cc->evp, 0, iv, len); |
356 | else | 426 | else |
357 | memcpy(iv, cc->evp.iv, len); | 427 | #endif |
428 | memcpy(iv, cc->evp.iv, len); | ||
358 | break; | 429 | break; |
359 | case SSH_CIPHER_3DES: | 430 | case SSH_CIPHER_3DES: |
360 | ssh1_3des_iv(&cc->evp, 0, iv, 24); | 431 | ssh1_3des_iv(&cc->evp, 0, iv, 24); |
@@ -382,10 +453,12 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) | |||
382 | ssh_rijndael_iv(&cc->evp, 1, iv, evplen); | 453 | ssh_rijndael_iv(&cc->evp, 1, iv, evplen); |
383 | else | 454 | else |
384 | #endif | 455 | #endif |
456 | #ifndef OPENSSL_HAVE_EVPCTR | ||
385 | if (c->evptype == evp_aes_128_ctr) | 457 | if (c->evptype == evp_aes_128_ctr) |
386 | ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); | 458 | ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); |
387 | else | 459 | else |
388 | memcpy(cc->evp.iv, iv, evplen); | 460 | #endif |
461 | memcpy(cc->evp.iv, iv, evplen); | ||
389 | break; | 462 | break; |
390 | case SSH_CIPHER_3DES: | 463 | case SSH_CIPHER_3DES: |
391 | ssh1_3des_iv(&cc->evp, 1, iv, 24); | 464 | ssh1_3des_iv(&cc->evp, 1, iv, 24); |
@@ -395,21 +468,13 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) | |||
395 | } | 468 | } |
396 | } | 469 | } |
397 | 470 | ||
398 | #if OPENSSL_VERSION_NUMBER < 0x00907000L | ||
399 | #define EVP_X_STATE(evp) &(evp).c | ||
400 | #define EVP_X_STATE_LEN(evp) sizeof((evp).c) | ||
401 | #else | ||
402 | #define EVP_X_STATE(evp) (evp).cipher_data | ||
403 | #define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size | ||
404 | #endif | ||
405 | |||
406 | int | 471 | int |
407 | cipher_get_keycontext(const CipherContext *cc, u_char *dat) | 472 | cipher_get_keycontext(const CipherContext *cc, u_char *dat) |
408 | { | 473 | { |
409 | Cipher *c = cc->cipher; | 474 | Cipher *c = cc->cipher; |
410 | int plen = 0; | 475 | int plen = 0; |
411 | 476 | ||
412 | if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { | 477 | if (c->evptype == EVP_rc4) { |
413 | plen = EVP_X_STATE_LEN(cc->evp); | 478 | plen = EVP_X_STATE_LEN(cc->evp); |
414 | if (dat == NULL) | 479 | if (dat == NULL) |
415 | return (plen); | 480 | return (plen); |
@@ -424,7 +489,7 @@ cipher_set_keycontext(CipherContext *cc, u_char *dat) | |||
424 | Cipher *c = cc->cipher; | 489 | Cipher *c = cc->cipher; |
425 | int plen; | 490 | int plen; |
426 | 491 | ||
427 | if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { | 492 | if (c->evptype == EVP_rc4) { |
428 | plen = EVP_X_STATE_LEN(cc->evp); | 493 | plen = EVP_X_STATE_LEN(cc->evp); |
429 | memcpy(EVP_X_STATE(cc->evp), dat, plen); | 494 | memcpy(EVP_X_STATE(cc->evp), dat, plen); |
430 | } | 495 | } |