summaryrefslogtreecommitdiff
path: root/cipher.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-01-09 16:12:19 +1100
committerDamien Miller <djm@mindrot.org>2013-01-09 16:12:19 +1100
commit1d75abfe23cadf8cdba0bd2cfd54f3bc1ca80dc5 (patch)
treeb717aa08dcc3c018d6fdae575017b3cb5fd92767 /cipher.c
parentaa7ad3039c671c157bb99217d60674dad8154a22 (diff)
- markus@cvs.openbsd.org 2013/01/08 18:49:04
[PROTOCOL authfile.c cipher.c cipher.h kex.c kex.h monitor_wrap.c] [myproposal.h packet.c ssh_config.5 sshd_config.5] support AES-GCM as defined in RFC 5647 (but with simpler KEX handling) ok and feedback djm@
Diffstat (limited to 'cipher.c')
-rw-r--r--cipher.c105
1 files changed, 81 insertions, 24 deletions
diff --git a/cipher.c b/cipher.c
index aae69c347..cad8a2f36 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.c,v 1.84 2012/12/12 16:46:10 naddy Exp $ */ 1/* $OpenBSD: cipher.c,v 1.85 2013/01/08 18:49:04 markus 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
@@ -71,29 +71,38 @@ struct Cipher {
71 u_int cbc_mode; 71 u_int cbc_mode;
72 const EVP_CIPHER *(*evptype)(void); 72 const EVP_CIPHER *(*evptype)(void);
73} ciphers[] = { 73} ciphers[] = {
74 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null }, 74 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL }
75 { "des", SSH_CIPHER_DES, 8, 8, 0, 1, EVP_des_cbc }, 75
76 { "3des", SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des }, 76 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
77 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 1, evp_ssh1_bf }, 77 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
78 78 { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
79 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc }, 79 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
80 { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_bf_cbc }, 80
81 { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_cast5_cbc }, 81 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
82 { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, EVP_rc4 }, 82 { "blowfish-cbc",
83 { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, 0, EVP_rc4 }, 83 SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
84 { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, 0, EVP_rc4 }, 84 { "cast128-cbc",
85 { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc }, 85 SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc },
86 { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc }, 86 { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 },
87 { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, 87 { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 },
88 { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 },
89 { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc },
90 { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc },
91 { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
88 { "rijndael-cbc@lysator.liu.se", 92 { "rijndael-cbc@lysator.liu.se",
89 SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, 93 SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
90 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, EVP_aes_128_ctr }, 94 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr },
91 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, EVP_aes_192_ctr }, 95 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr },
92 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, EVP_aes_256_ctr }, 96 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr },
97 { "aes128-gcm@openssh.com",
98 SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },
99 { "aes256-gcm@openssh.com",
100 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
93#ifdef USE_CIPHER_ACSS 101#ifdef USE_CIPHER_ACSS
94 { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss }, 102 { "acss@openssh.org",
103 SSH_CIPHER_SSH2, 16, 5, 0, 0, 0, 0, EVP_acss },
95#endif 104#endif
96 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } 105 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
97}; 106};
98 107
99/*--*/ 108/*--*/
@@ -111,6 +120,18 @@ cipher_keylen(const Cipher *c)
111} 120}
112 121
113u_int 122u_int
123cipher_authlen(const Cipher *c)
124{
125 return (c->auth_len);
126}
127
128u_int
129cipher_ivlen(const Cipher *c)
130{
131 return (c->iv_len ? c->iv_len : c->block_size);
132}
133
134u_int
114cipher_get_number(const Cipher *c) 135cipher_get_number(const Cipher *c)
115{ 136{
116 return (c->number); 137 return (c->number);
@@ -229,11 +250,12 @@ cipher_init(CipherContext *cc, Cipher *cipher,
229 keylen = 8; 250 keylen = 8;
230 } 251 }
231 cc->plaintext = (cipher->number == SSH_CIPHER_NONE); 252 cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
253 cc->encrypt = do_encrypt;
232 254
233 if (keylen < cipher->key_len) 255 if (keylen < cipher->key_len)
234 fatal("cipher_init: key length %d is insufficient for %s.", 256 fatal("cipher_init: key length %d is insufficient for %s.",
235 keylen, cipher->name); 257 keylen, cipher->name);
236 if (iv != NULL && ivlen < cipher->block_size) 258 if (iv != NULL && ivlen < cipher_ivlen(cipher))
237 fatal("cipher_init: iv length %d is insufficient for %s.", 259 fatal("cipher_init: iv length %d is insufficient for %s.",
238 ivlen, cipher->name); 260 ivlen, cipher->name);
239 cc->cipher = cipher; 261 cc->cipher = cipher;
@@ -254,6 +276,11 @@ cipher_init(CipherContext *cc, Cipher *cipher,
254 (do_encrypt == CIPHER_ENCRYPT)) == 0) 276 (do_encrypt == CIPHER_ENCRYPT)) == 0)
255 fatal("cipher_init: EVP_CipherInit failed for %s", 277 fatal("cipher_init: EVP_CipherInit failed for %s",
256 cipher->name); 278 cipher->name);
279 if (cipher_authlen(cipher) &&
280 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
281 -1, (u_char *)iv))
282 fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s",
283 cipher->name);
257 klen = EVP_CIPHER_CTX_key_length(&cc->evp); 284 klen = EVP_CIPHER_CTX_key_length(&cc->evp);
258 if (klen > 0 && keylen != (u_int)klen) { 285 if (klen > 0 && keylen != (u_int)klen) {
259 debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); 286 debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
@@ -284,19 +311,49 @@ cipher_init(CipherContext *cc, Cipher *cipher,
284 * Theses bytes are treated as additional authenticated data for 311 * Theses bytes are treated as additional authenticated data for
285 * authenticated encryption modes. 312 * authenticated encryption modes.
286 * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. 313 * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.
314 * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
315 * This tag is written on encryption and verified on decryption.
287 * Both 'aadlen' and 'authlen' can be set to 0. 316 * Both 'aadlen' and 'authlen' can be set to 0.
288 */ 317 */
289void 318void
290cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, 319cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src,
291 u_int len, u_int aadlen) 320 u_int len, u_int aadlen, u_int authlen)
292{ 321{
293 if (aadlen) 322 if (authlen) {
323 u_char lastiv[1];
324
325 if (authlen != cipher_authlen(cc->cipher))
326 fatal("%s: authlen mismatch %d", __func__, authlen);
327 /* increment IV */
328 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
329 1, lastiv))
330 fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__);
331 /* set tag on decyption */
332 if (!cc->encrypt &&
333 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG,
334 authlen, (u_char *)src + aadlen + len))
335 fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__);
336 }
337 if (aadlen) {
338 if (authlen &&
339 EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0)
340 fatal("%s: EVP_Cipher(aad) failed", __func__);
294 memcpy(dest, src, aadlen); 341 memcpy(dest, src, aadlen);
342 }
295 if (len % cc->cipher->block_size) 343 if (len % cc->cipher->block_size)
296 fatal("%s: bad plaintext length %d", __func__, len); 344 fatal("%s: bad plaintext length %d", __func__, len);
297 if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, 345 if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen,
298 len) < 0) 346 len) < 0)
299 fatal("%s: EVP_Cipher failed", __func__); 347 fatal("%s: EVP_Cipher failed", __func__);
348 if (authlen) {
349 /* compute tag (on encrypt) or verify tag (on decrypt) */
350 if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0)
351 fatal("%s: EVP_Cipher(finish) failed", __func__);
352 if (cc->encrypt &&
353 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG,
354 authlen, dest + aadlen + len))
355 fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__);
356 }
300} 357}
301 358
302void 359void