From af43a7ac2d77c57112b48f34c7a72be2adb761bc Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 12 Dec 2012 10:46:31 +1100 Subject: - markus@cvs.openbsd.org 2012/12/11 22:31:18 [PROTOCOL authfile.c cipher.c cipher.h kex.h mac.c myproposal.h] [packet.c ssh_config.5 sshd_config.5] add encrypt-then-mac (EtM) modes to openssh by defining new mac algorithms that change the packet format and compute the MAC over the encrypted message (including the packet size) instead of the plaintext data; these EtM modes are considered more secure and used by default. feedback and ok djm@ --- cipher.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'cipher.c') diff --git a/cipher.c b/cipher.c index bb5c0ac3a..2116b55b1 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.82 2009/01/26 09:58:15 markus Exp $ */ +/* $OpenBSD: cipher.c,v 1.83 2012/12/11 22:31:18 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -273,13 +273,25 @@ cipher_init(CipherContext *cc, Cipher *cipher, } } +/* + * cipher_crypt() operates as following: + * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'. + * Theses bytes are treated as additional authenticated data for + * authenticated encryption modes. + * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. + * Both 'aadlen' and 'authlen' can be set to 0. + */ void -cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, + u_int len, u_int aadlen) { + if (aadlen) + memcpy(dest, src, aadlen); if (len % cc->cipher->block_size) - fatal("cipher_encrypt: bad plaintext length %d", len); - if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0) - fatal("evp_crypt: EVP_Cipher failed"); + fatal("%s: bad plaintext length %d", __func__, len); + if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, + len) < 0) + fatal("%s: EVP_Cipher failed", __func__); } void -- cgit v1.2.3 From 25a02b0c95e01bc331267a1db0f62d3cbd7a0897 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 13 Dec 2012 08:18:56 +1100 Subject: - (djm) [configure.ac cipher-ctr.c] Adapt EVP AES CTR change to retain our compat code for older OpenSSL --- ChangeLog | 6 ++++++ cipher-ctr.c | 3 +++ cipher.c | 22 +++++++++++++++------- configure.ac | 25 +++++++++++++++++++++++-- 4 files changed, 47 insertions(+), 9 deletions(-) (limited to 'cipher.c') diff --git a/ChangeLog b/ChangeLog index f44c4f1ca..2c6da413f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,12 @@ reset incoming_packet buffer for each new packet in EtM-case, too; this happens if packets are parsed only parially (e.g. ignore messages sent when su/sudo turn off echo); noted by sthen/millert + - naddy@cvs.openbsd.org 2012/12/12 16:46:10 + [cipher.c] + use OpenSSL's EVP_aes_{128,192,256}_ctr() API and remove our hand-rolled + counter mode code; ok djm@ + - (djm) [configure.ac cipher-ctr.c] Adapt EVP AES CTR change to retain our + compat code for older OpenSSL 20121212 - (djm) OpenBSD CVS Sync diff --git a/cipher-ctr.c b/cipher-ctr.c index 04975b4b6..f053abe2e 100644 --- a/cipher-ctr.c +++ b/cipher-ctr.c @@ -16,6 +16,7 @@ */ #include "includes.h" +#ifndef OPENSSL_HAVE_EVPCTR #include #include @@ -144,3 +145,5 @@ evp_aes_128_ctr(void) #endif return (&aes_ctr); } + +#endif /* OPENSSL_HAVE_EVPCTR */ diff --git a/cipher.c b/cipher.c index 2116b55b1..d15c226ae 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.83 2012/12/11 22:31:18 markus Exp $ */ +/* $OpenBSD: cipher.c,v 1.84 2012/12/12 16:46:10 naddy Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -54,8 +54,12 @@ extern const EVP_CIPHER *evp_ssh1_bf(void); extern const EVP_CIPHER *evp_ssh1_3des(void); extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); -extern const EVP_CIPHER *evp_aes_128_ctr(void); +#ifndef OPENSSL_HAVE_EVPCTR +#define EVP_aes_128_ctr evp_aes_128_ctr +#define EVP_aes_192_ctr evp_aes_128_ctr +#define EVP_aes_256_ctr evp_aes_128_ctr extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); +#endif struct Cipher { char *name; @@ -82,9 +86,9 @@ struct Cipher { { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, { "rijndael-cbc@lysator.liu.se", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, - { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr }, - { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr }, - { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr }, + { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, EVP_aes_128_ctr }, + { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, EVP_aes_192_ctr }, + { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, EVP_aes_256_ctr }, #ifdef USE_CIPHER_ACSS { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss }, #endif @@ -363,10 +367,12 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) ssh_rijndael_iv(&cc->evp, 0, iv, len); else #endif +#ifndef OPENSSL_HAVE_EVPCTR if (c->evptype == evp_aes_128_ctr) ssh_aes_ctr_iv(&cc->evp, 0, iv, len); else - memcpy(iv, cc->evp.iv, len); +#endif + memcpy(iv, cc->evp.iv, len); break; case SSH_CIPHER_3DES: ssh1_3des_iv(&cc->evp, 0, iv, 24); @@ -394,10 +400,12 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) ssh_rijndael_iv(&cc->evp, 1, iv, evplen); else #endif +#ifndef OPENSSL_HAVE_EVPCTR if (c->evptype == evp_aes_128_ctr) ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); else - memcpy(cc->evp.iv, iv, evplen); +#endif + memcpy(cc->evp.iv, iv, evplen); break; case SSH_CIPHER_3DES: ssh1_3des_iv(&cc->evp, 1, iv, 24); diff --git a/configure.ac b/configure.ac index 8b32e40c9..64c231b7e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.498 2012/12/03 01:35:55 djm Exp $ +# $Id: configure.ac,v 1.499 2012/12/12 21:18:56 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) -AC_REVISION($Revision: 1.498 $) +AC_REVISION($Revision: 1.499 $) AC_CONFIG_SRCDIR([ssh.c]) AC_LANG([C]) @@ -2299,6 +2299,27 @@ AC_LINK_IFELSE( ] ) +# Check for OpenSSL with EVP_aes_*ctr +AC_MSG_CHECKING([whether OpenSSL has AES CTR via EVP]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +#include +#include + ]], [[ + exit(EVP_aes_128_ctr() == NULL || + EVP_aes_192_cbc() == NULL || + EVP_aes_256_cbc() == NULL); + ]])], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([OPENSSL_HAVE_EVPCTR], [1], + [libcrypto has EVP AES CTR]) + ], + [ + AC_MSG_RESULT([no]) + ] +) + AC_MSG_CHECKING([if EVP_DigestUpdate returns an int]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ -- cgit v1.2.3 From 13cbff1e009c2a1f786e5d84bf78099c70949bf0 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 13 Dec 2012 08:25:07 +1100 Subject: - (djm) [cipher.c] Fix missing prototype for compat code --- ChangeLog | 1 + cipher.c | 1 + 2 files changed, 2 insertions(+) (limited to 'cipher.c') diff --git a/ChangeLog b/ChangeLog index 2c6da413f..16a6489e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ counter mode code; ok djm@ - (djm) [configure.ac cipher-ctr.c] Adapt EVP AES CTR change to retain our compat code for older OpenSSL + - (djm) [cipher.c] Fix missing prototype for compat code 20121212 - (djm) OpenBSD CVS Sync diff --git a/cipher.c b/cipher.c index d15c226ae..aae69c347 100644 --- a/cipher.c +++ b/cipher.c @@ -58,6 +58,7 @@ extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); #define EVP_aes_128_ctr evp_aes_128_ctr #define EVP_aes_192_ctr evp_aes_128_ctr #define EVP_aes_256_ctr evp_aes_128_ctr +extern const EVP_CIPHER *evp_aes_128_ctr(void); extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); #endif -- cgit v1.2.3 From 1d75abfe23cadf8cdba0bd2cfd54f3bc1ca80dc5 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 9 Jan 2013 16:12:19 +1100 Subject: - 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@ --- ChangeLog | 5 +++ PROTOCOL | 14 +++++++- authfile.c | 6 ++-- cipher.c | 105 ++++++++++++++++++++++++++++++++++++++++++++------------- cipher.h | 8 +++-- kex.c | 16 ++++++--- kex.h | 3 +- monitor_wrap.c | 39 ++++++++++----------- myproposal.h | 3 +- packet.c | 45 ++++++++++++++----------- ssh_config.5 | 7 ++-- sshd_config.5 | 7 ++-- 12 files changed, 179 insertions(+), 79 deletions(-) (limited to 'cipher.c') diff --git a/ChangeLog b/ChangeLog index 0f62953c7..b5812cc7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,11 @@ sftp-server.8: add argument name to -d sftp-server.c: add -d to usage() ok djm + - 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@ 20121217 - (dtucker) [Makefile.in] Add some scaffolding so that the new regress diff --git a/PROTOCOL b/PROTOCOL index eb5d0889c..48b3a4400 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -79,6 +79,18 @@ contains: byte[n1] payload; n1 = packet_length - padding_length - 1 byte[n2] random padding; n2 = padding_length +1.6 transport: AES-GCM + +OpenSSH supports the AES-GCM algorithm as specified in RFC 5647. +Because of problems with the specification of the key exchange +the behaviour of OpenSSH differs from the RFC as follows: + +AES-GCM is only negotiated as the cipher algorithms +"aes128-gcm@openssh.com" or "aes256-gcm@openssh.com" and never as +an MAC algorithm. Additionally, if AES-GCM is selected as the cipher +the exchanged MAC algorithms are ignored and there doesn't have to be +a matching MAC. + 2. Connection protocol changes 2.1. connection: Channel write close extension "eow@openssh.com" @@ -319,4 +331,4 @@ link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message. This extension is advertised in the SSH_FXP_VERSION hello with version "1". -$OpenBSD: PROTOCOL,v 1.19 2013/01/03 12:49:01 djm Exp $ +$OpenBSD: PROTOCOL,v 1.20 2013/01/08 18:49:04 markus Exp $ diff --git a/authfile.c b/authfile.c index d9ee4ca65..3544d170b 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.94 2012/12/11 22:31:18 markus Exp $ */ +/* $OpenBSD: authfile.c,v 1.95 2013/01/08 18:49:04 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -150,7 +150,7 @@ key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase, cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_ENCRYPT); cipher_crypt(&ciphercontext, cp, - buffer_ptr(&buffer), buffer_len(&buffer), 0); + buffer_ptr(&buffer), buffer_len(&buffer), 0, 0); cipher_cleanup(&ciphercontext); memset(&ciphercontext, 0, sizeof(ciphercontext)); @@ -474,7 +474,7 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_DECRYPT); cipher_crypt(&ciphercontext, cp, - buffer_ptr(©), buffer_len(©), 0); + buffer_ptr(©), buffer_len(©), 0, 0); cipher_cleanup(&ciphercontext); memset(&ciphercontext, 0, sizeof(ciphercontext)); buffer_free(©); diff --git a/cipher.c b/cipher.c index aae69c347..cad8a2f36 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.84 2012/12/12 16:46:10 naddy Exp $ */ +/* $OpenBSD: cipher.c,v 1.85 2013/01/08 18:49:04 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -71,29 +71,38 @@ struct Cipher { u_int cbc_mode; const EVP_CIPHER *(*evptype)(void); } ciphers[] = { - { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null }, - { "des", SSH_CIPHER_DES, 8, 8, 0, 1, EVP_des_cbc }, - { "3des", SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des }, - { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 1, evp_ssh1_bf }, - - { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc }, - { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_bf_cbc }, - { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_cast5_cbc }, - { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, EVP_rc4 }, - { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, 0, EVP_rc4 }, - { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, 0, EVP_rc4 }, - { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc }, - { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc }, - { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, + { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } + + { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, + { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, + { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, + { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, + + { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, + { "blowfish-cbc", + SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, + { "cast128-cbc", + SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc }, + { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 }, + { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 }, + { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 }, + { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, + { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, + { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, { "rijndael-cbc@lysator.liu.se", - SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, - { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, EVP_aes_128_ctr }, - { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, EVP_aes_192_ctr }, - { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, EVP_aes_256_ctr }, + SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, + { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, + { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, + { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, + { "aes128-gcm@openssh.com", + SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, + { "aes256-gcm@openssh.com", + SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, #ifdef USE_CIPHER_ACSS - { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss }, + { "acss@openssh.org", + SSH_CIPHER_SSH2, 16, 5, 0, 0, 0, 0, EVP_acss }, #endif - { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } + { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } }; /*--*/ @@ -110,6 +119,18 @@ cipher_keylen(const Cipher *c) return (c->key_len); } +u_int +cipher_authlen(const Cipher *c) +{ + return (c->auth_len); +} + +u_int +cipher_ivlen(const Cipher *c) +{ + return (c->iv_len ? c->iv_len : c->block_size); +} + u_int cipher_get_number(const Cipher *c) { @@ -229,11 +250,12 @@ cipher_init(CipherContext *cc, Cipher *cipher, keylen = 8; } cc->plaintext = (cipher->number == SSH_CIPHER_NONE); + cc->encrypt = do_encrypt; if (keylen < cipher->key_len) fatal("cipher_init: key length %d is insufficient for %s.", keylen, cipher->name); - if (iv != NULL && ivlen < cipher->block_size) + if (iv != NULL && ivlen < cipher_ivlen(cipher)) fatal("cipher_init: iv length %d is insufficient for %s.", ivlen, cipher->name); cc->cipher = cipher; @@ -254,6 +276,11 @@ cipher_init(CipherContext *cc, Cipher *cipher, (do_encrypt == CIPHER_ENCRYPT)) == 0) fatal("cipher_init: EVP_CipherInit failed for %s", cipher->name); + if (cipher_authlen(cipher) && + !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, + -1, (u_char *)iv)) + fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s", + cipher->name); klen = EVP_CIPHER_CTX_key_length(&cc->evp); if (klen > 0 && keylen != (u_int)klen) { debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); @@ -284,19 +311,49 @@ cipher_init(CipherContext *cc, Cipher *cipher, * Theses bytes are treated as additional authenticated data for * authenticated encryption modes. * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. + * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. + * This tag is written on encryption and verified on decryption. * Both 'aadlen' and 'authlen' can be set to 0. */ void cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, - u_int len, u_int aadlen) + u_int len, u_int aadlen, u_int authlen) { - if (aadlen) + if (authlen) { + u_char lastiv[1]; + + if (authlen != cipher_authlen(cc->cipher)) + fatal("%s: authlen mismatch %d", __func__, authlen); + /* increment IV */ + if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, + 1, lastiv)) + fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__); + /* set tag on decyption */ + if (!cc->encrypt && + !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, + authlen, (u_char *)src + aadlen + len)) + fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__); + } + if (aadlen) { + if (authlen && + EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) + fatal("%s: EVP_Cipher(aad) failed", __func__); memcpy(dest, src, aadlen); + } if (len % cc->cipher->block_size) fatal("%s: bad plaintext length %d", __func__, len); if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, len) < 0) fatal("%s: EVP_Cipher failed", __func__); + if (authlen) { + /* compute tag (on encrypt) or verify tag (on decrypt) */ + if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) + fatal("%s: EVP_Cipher(finish) failed", __func__); + if (cc->encrypt && + !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, + authlen, dest + aadlen + len)) + fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); + } } void diff --git a/cipher.h b/cipher.h index 78972fea5..8cb57c3e5 100644 --- a/cipher.h +++ b/cipher.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.h,v 1.38 2012/12/11 22:31:18 markus Exp $ */ +/* $OpenBSD: cipher.h,v 1.39 2013/01/08 18:49:04 markus Exp $ */ /* * Author: Tatu Ylonen @@ -64,6 +64,7 @@ typedef struct CipherContext CipherContext; struct Cipher; struct CipherContext { int plaintext; + int encrypt; EVP_CIPHER_CTX evp; Cipher *cipher; }; @@ -76,11 +77,14 @@ char *cipher_name(int); int ciphers_valid(const char *); void cipher_init(CipherContext *, Cipher *, const u_char *, u_int, const u_char *, u_int, int); -void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int, u_int); +void cipher_crypt(CipherContext *, u_char *, const u_char *, + u_int, u_int, u_int); void cipher_cleanup(CipherContext *); void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); u_int cipher_blocksize(const Cipher *); u_int cipher_keylen(const Cipher *); +u_int cipher_authlen(const Cipher *); +u_int cipher_ivlen(const Cipher *); u_int cipher_is_cbc(const Cipher *); u_int cipher_get_number(const Cipher *); diff --git a/kex.c b/kex.c index f77b3c925..57a79dd9e 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.87 2012/08/17 01:22:56 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.88 2013/01/08 18:49:04 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -304,6 +304,7 @@ choose_enc(Enc *enc, char *client, char *server) enc->name = name; enc->enabled = 0; enc->iv = NULL; + enc->iv_len = cipher_ivlen(enc->cipher); enc->key = NULL; enc->key_len = cipher_keylen(enc->cipher); enc->block_size = cipher_blocksize(enc->cipher); @@ -415,7 +416,7 @@ kex_choose_conf(Kex *kex) char **my, **peer; char **cprop, **sprop; int nenc, nmac, ncomp; - u_int mode, ctos, need; + u_int mode, ctos, need, authlen; int first_kex_follows, type; my = kex_buf2prop(&kex->my, NULL); @@ -448,13 +449,16 @@ kex_choose_conf(Kex *kex) nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; - choose_enc (&newkeys->enc, cprop[nenc], sprop[nenc]); - choose_mac (&newkeys->mac, cprop[nmac], sprop[nmac]); + choose_enc(&newkeys->enc, cprop[nenc], sprop[nenc]); + /* ignore mac for authenticated encryption */ + authlen = cipher_authlen(newkeys->enc.cipher); + if (authlen == 0) + choose_mac(&newkeys->mac, cprop[nmac], sprop[nmac]); choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]); debug("kex: %s %s %s %s", ctos ? "client->server" : "server->client", newkeys->enc.name, - newkeys->mac.name, + authlen == 0 ? newkeys->mac.name : "", newkeys->comp.name); } choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); @@ -467,6 +471,8 @@ kex_choose_conf(Kex *kex) need = newkeys->enc.key_len; if (need < newkeys->enc.block_size) need = newkeys->enc.block_size; + if (need < newkeys->enc.iv_len) + need = newkeys->enc.iv_len; if (need < newkeys->mac.key_len) need = newkeys->mac.key_len; } diff --git a/kex.h b/kex.h index 03b984cc8..46731fa45 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.53 2012/12/11 22:31:18 markus Exp $ */ +/* $OpenBSD: kex.h,v 1.54 2013/01/08 18:49:04 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -89,6 +89,7 @@ struct Enc { Cipher *cipher; int enabled; u_int key_len; + u_int iv_len; u_int block_size; u_char *key; u_char *iv; diff --git a/monitor_wrap.c b/monitor_wrap.c index c22d0a2a6..ea654a73f 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.74 2012/10/01 13:59:51 naddy Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.75 2013/01/08 18:49:04 markus Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -491,25 +491,24 @@ mm_newkeys_from_blob(u_char *blob, int blen) enc->enabled = buffer_get_int(&b); enc->block_size = buffer_get_int(&b); enc->key = buffer_get_string(&b, &enc->key_len); - enc->iv = buffer_get_string(&b, &len); - if (len != enc->block_size) - fatal("%s: bad ivlen: expected %u != %u", __func__, - enc->block_size, len); + enc->iv = buffer_get_string(&b, &enc->iv_len); if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher) fatal("%s: bad cipher name %s or pointer %p", __func__, enc->name, enc->cipher); /* Mac structure */ - mac->name = buffer_get_string(&b, NULL); - if (mac->name == NULL || mac_setup(mac, mac->name) == -1) - fatal("%s: can not setup mac %s", __func__, mac->name); - mac->enabled = buffer_get_int(&b); - mac->key = buffer_get_string(&b, &len); - if (len > mac->key_len) - fatal("%s: bad mac key length: %u > %d", __func__, len, - mac->key_len); - mac->key_len = len; + if (cipher_authlen(enc->cipher) == 0) { + mac->name = buffer_get_string(&b, NULL); + if (mac->name == NULL || mac_setup(mac, mac->name) == -1) + fatal("%s: can not setup mac %s", __func__, mac->name); + mac->enabled = buffer_get_int(&b); + mac->key = buffer_get_string(&b, &len); + if (len > mac->key_len) + fatal("%s: bad mac key length: %u > %d", __func__, len, + mac->key_len); + mac->key_len = len; + } /* Comp structure */ comp->type = buffer_get_int(&b); @@ -551,13 +550,15 @@ mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp) buffer_put_int(&b, enc->enabled); buffer_put_int(&b, enc->block_size); buffer_put_string(&b, enc->key, enc->key_len); - packet_get_keyiv(mode, enc->iv, enc->block_size); - buffer_put_string(&b, enc->iv, enc->block_size); + packet_get_keyiv(mode, enc->iv, enc->iv_len); + buffer_put_string(&b, enc->iv, enc->iv_len); /* Mac structure */ - buffer_put_cstring(&b, mac->name); - buffer_put_int(&b, mac->enabled); - buffer_put_string(&b, mac->key, mac->key_len); + if (cipher_authlen(enc->cipher) == 0) { + buffer_put_cstring(&b, mac->name); + buffer_put_int(&b, mac->enabled); + buffer_put_string(&b, mac->key, mac->key_len); + } /* Comp structure */ buffer_put_int(&b, comp->type); diff --git a/myproposal.h b/myproposal.h index d98f4b051..99d093461 100644 --- a/myproposal.h +++ b/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.31 2012/12/11 22:31:18 markus Exp $ */ +/* $OpenBSD: myproposal.h,v 1.32 2013/01/08 18:49:04 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -73,6 +73,7 @@ #define KEX_DEFAULT_ENCRYPT \ "aes128-ctr,aes192-ctr,aes256-ctr," \ "arcfour256,arcfour128," \ + "aes128-gcm@openssh.com,aes256-gcm@openssh.com," \ "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \ "aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se" #ifdef HAVE_EVP_SHA256 diff --git a/packet.c b/packet.c index fe379aa49..ae7b04cd8 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.179 2012/12/12 16:45:52 markus Exp $ */ +/* $OpenBSD: packet.c,v 1.180 2013/01/08 18:49:04 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -709,7 +709,7 @@ packet_send1(void) buffer_len(&active_state->outgoing_packet)); cipher_crypt(&active_state->send_context, cp, buffer_ptr(&active_state->outgoing_packet), - buffer_len(&active_state->outgoing_packet), 0); + buffer_len(&active_state->outgoing_packet), 0, 0); #ifdef PACKET_DEBUG fprintf(stderr, "encrypted: "); @@ -757,7 +757,7 @@ set_newkeys(int mode) mac = &active_state->newkeys[mode]->mac; comp = &active_state->newkeys[mode]->comp; mac_clear(mac); - memset(enc->iv, 0, enc->block_size); + memset(enc->iv, 0, enc->iv_len); memset(enc->key, 0, enc->key_len); memset(mac->key, 0, mac->key_len); xfree(enc->name); @@ -774,11 +774,11 @@ set_newkeys(int mode) enc = &active_state->newkeys[mode]->enc; mac = &active_state->newkeys[mode]->mac; comp = &active_state->newkeys[mode]->comp; - if (mac_init(mac) == 0) + if (cipher_authlen(enc->cipher) == 0 && mac_init(mac) == 0) mac->enabled = 1; DBG(debug("cipher_init_context: %d", mode)); cipher_init(cc, enc->cipher, enc->key, enc->key_len, - enc->iv, enc->block_size, crypt_type); + enc->iv, enc->iv_len, crypt_type); /* Deleting the keys does not gain extra security */ /* memset(enc->iv, 0, enc->block_size); memset(enc->key, 0, enc->key_len); @@ -846,7 +846,7 @@ packet_send2_wrapped(void) { u_char type, *cp, *macbuf = NULL; u_char padlen, pad = 0; - u_int i, len, aadlen = 0; + u_int i, len, authlen = 0, aadlen = 0; u_int32_t rnd = 0; Enc *enc = NULL; Mac *mac = NULL; @@ -857,9 +857,12 @@ packet_send2_wrapped(void) enc = &active_state->newkeys[MODE_OUT]->enc; mac = &active_state->newkeys[MODE_OUT]->mac; comp = &active_state->newkeys[MODE_OUT]->comp; + /* disable mac for authenticated encryption */ + if ((authlen = cipher_authlen(enc->cipher)) != 0) + mac = NULL; } block_size = enc ? enc->block_size : 8; - aadlen = mac && mac->enabled && mac->etm ? 4 : 0; + aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; cp = buffer_ptr(&active_state->outgoing_packet); type = cp[5]; @@ -936,10 +939,10 @@ packet_send2_wrapped(void) DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr)); } /* encrypt packet and append to output buffer. */ - cp = buffer_append_space(&active_state->output, len); + cp = buffer_append_space(&active_state->output, len + authlen); cipher_crypt(&active_state->send_context, cp, buffer_ptr(&active_state->outgoing_packet), - len - aadlen, aadlen); + len - aadlen, aadlen, authlen); /* append unencrypted MAC */ if (mac && mac->enabled) { if (mac->etm) { @@ -1199,7 +1202,7 @@ packet_read_poll1(void) buffer_clear(&active_state->incoming_packet); cp = buffer_append_space(&active_state->incoming_packet, padded_len); cipher_crypt(&active_state->receive_context, cp, - buffer_ptr(&active_state->input), padded_len, 0); + buffer_ptr(&active_state->input), padded_len, 0, 0); buffer_consume(&active_state->input, padded_len); @@ -1248,7 +1251,7 @@ packet_read_poll2(u_int32_t *seqnr_p) { u_int padlen, need; u_char *macbuf = NULL, *cp, type; - u_int maclen, aadlen = 0, block_size; + u_int maclen, authlen = 0, aadlen = 0, block_size; Enc *enc = NULL; Mac *mac = NULL; Comp *comp = NULL; @@ -1260,10 +1263,13 @@ packet_read_poll2(u_int32_t *seqnr_p) enc = &active_state->newkeys[MODE_IN]->enc; mac = &active_state->newkeys[MODE_IN]->mac; comp = &active_state->newkeys[MODE_IN]->comp; + /* disable mac for authenticated encryption */ + if ((authlen = cipher_authlen(enc->cipher)) != 0) + mac = NULL; } maclen = mac && mac->enabled ? mac->mac_len : 0; block_size = enc ? enc->block_size : 8; - aadlen = mac && mac->enabled && mac->etm ? 4 : 0; + aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; if (aadlen && active_state->packlen == 0) { if (buffer_len(&active_state->input) < 4) @@ -1290,7 +1296,7 @@ packet_read_poll2(u_int32_t *seqnr_p) cp = buffer_append_space(&active_state->incoming_packet, block_size); cipher_crypt(&active_state->receive_context, cp, - buffer_ptr(&active_state->input), block_size, 0); + buffer_ptr(&active_state->input), block_size, 0, 0); cp = buffer_ptr(&active_state->incoming_packet); active_state->packlen = get_u32(cp); if (active_state->packlen < 1 + 4 || @@ -1316,8 +1322,8 @@ packet_read_poll2(u_int32_t *seqnr_p) */ need = 4 + active_state->packlen - block_size; } - DBG(debug("partial packet: block %d, need %d, maclen %d, aadlen %d", - block_size, need, maclen, aadlen)); + DBG(debug("partial packet: block %d, need %d, maclen %d, authlen %d," + " aadlen %d", block_size, need, maclen, authlen, aadlen)); if (need % block_size != 0) { logit("padding error: need %d block %d mod %d", need, block_size, need % block_size); @@ -1329,10 +1335,11 @@ packet_read_poll2(u_int32_t *seqnr_p) * check if the entire packet has been received and * decrypt into incoming_packet: * 'aadlen' bytes are unencrypted, but authenticated. - * 'need' bytes are encrypted, followed by + * 'need' bytes are encrypted, followed by either + * 'authlen' bytes of authentication tag or * 'maclen' bytes of message authentication code. */ - if (buffer_len(&active_state->input) < aadlen + need + maclen) + if (buffer_len(&active_state->input) < aadlen + need + authlen + maclen) return SSH_MSG_NONE; #ifdef PACKET_DEBUG fprintf(stderr, "read_poll enc/full: "); @@ -1344,8 +1351,8 @@ packet_read_poll2(u_int32_t *seqnr_p) buffer_ptr(&active_state->input), aadlen + need); cp = buffer_append_space(&active_state->incoming_packet, aadlen + need); cipher_crypt(&active_state->receive_context, cp, - buffer_ptr(&active_state->input), need, aadlen); - buffer_consume(&active_state->input, aadlen + need); + buffer_ptr(&active_state->input), need, aadlen, authlen); + buffer_consume(&active_state->input, aadlen + need + authlen); /* * compute MAC over seqnr and packet, * increment sequence number for incoming packet diff --git a/ssh_config.5 b/ssh_config.5 index ee466d800..269529c00 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.160 2012/12/11 22:31:18 markus Exp $ -.Dd $Mdocdate: December 11 2012 $ +.\" $OpenBSD: ssh_config.5,v 1.161 2013/01/08 18:49:04 markus Exp $ +.Dd $Mdocdate: January 8 2013 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -204,6 +204,8 @@ The supported ciphers are .Dq aes128-ctr , .Dq aes192-ctr , .Dq aes256-ctr , +.Dq aes128-gcm@openssh.com , +.Dq aes256-gcm@openssh.com , .Dq arcfour128 , .Dq arcfour256 , .Dq arcfour , @@ -213,6 +215,7 @@ and The default is: .Bd -literal -offset 3n aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, +aes128-gcm@openssh.com,aes256-gcm@openssh.com, aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, aes256-cbc,arcfour .Ed diff --git a/sshd_config.5 b/sshd_config.5 index 0f4aa639d..e7bb0b55f 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.152 2012/12/11 22:31:18 markus Exp $ -.Dd $Mdocdate: December 11 2012 $ +.\" $OpenBSD: sshd_config.5,v 1.153 2013/01/08 18:49:04 markus Exp $ +.Dd $Mdocdate: January 8 2013 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -336,6 +336,8 @@ The supported ciphers are .Dq aes128-ctr , .Dq aes192-ctr , .Dq aes256-ctr , +.Dq aes128-gcm@openssh.com , +.Dq aes256-gcm@openssh.com , .Dq arcfour128 , .Dq arcfour256 , .Dq arcfour , @@ -345,6 +347,7 @@ and The default is: .Bd -literal -offset 3n aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, +aes128-gcm@openssh.com,aes256-gcm@openssh.com, aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, aes256-cbc,arcfour .Ed -- cgit v1.2.3 From d522c68872689e2e80d9667da1c9a18d04b001cd Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 9 Jan 2013 16:42:47 +1100 Subject: - (djm) [cipher.c configure.ac openbsd-compat/openssl-compat.h] Fix merge botch, automatically detect AES-GCM in OpenSSL, move a little cipher compat code to openssl-compat.h --- ChangeLog | 3 +++ cipher.c | 21 ++++----------------- configure.ac | 24 ++++++++++++++++++++++-- openbsd-compat/openssl-compat.h | 26 +++++++++++++++++++++++++- 4 files changed, 54 insertions(+), 20 deletions(-) (limited to 'cipher.c') diff --git a/ChangeLog b/ChangeLog index b5812cc7d..868158cfc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,6 +37,9 @@ [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@ + - (djm) [cipher.c configure.ac openbsd-compat/openssl-compat.h] + Fix merge botch, automatically detect AES-GCM in OpenSSL, move a little + cipher compat code to openssl-compat.h 20121217 - (dtucker) [Makefile.in] Add some scaffolding so that the new regress diff --git a/cipher.c b/cipher.c index cad8a2f36..e137f359b 100644 --- a/cipher.c +++ b/cipher.c @@ -54,25 +54,18 @@ extern const EVP_CIPHER *evp_ssh1_bf(void); extern const EVP_CIPHER *evp_ssh1_3des(void); extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); -#ifndef OPENSSL_HAVE_EVPCTR -#define EVP_aes_128_ctr evp_aes_128_ctr -#define EVP_aes_192_ctr evp_aes_128_ctr -#define EVP_aes_256_ctr evp_aes_128_ctr -extern const EVP_CIPHER *evp_aes_128_ctr(void); -extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); -#endif struct Cipher { char *name; int number; /* for ssh1 only */ u_int block_size; u_int key_len; + u_int iv_len; /* defaults to block_size */ + u_int auth_len; u_int discard_len; u_int cbc_mode; const EVP_CIPHER *(*evptype)(void); } ciphers[] = { - { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } - { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, @@ -94,10 +87,12 @@ struct Cipher { { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, +#ifdef OPENSSL_HAVE_EVPGCM { "aes128-gcm@openssh.com", SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, { "aes256-gcm@openssh.com", SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, +#endif #ifdef USE_CIPHER_ACSS { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, 0, 0, 0, EVP_acss }, @@ -473,14 +468,6 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) } } -#if OPENSSL_VERSION_NUMBER < 0x00907000L -#define EVP_X_STATE(evp) &(evp).c -#define EVP_X_STATE_LEN(evp) sizeof((evp).c) -#else -#define EVP_X_STATE(evp) (evp).cipher_data -#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size -#endif - int cipher_get_keycontext(const CipherContext *cc, u_char *dat) { diff --git a/configure.ac b/configure.ac index 64c231b7e..36761233c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.499 2012/12/12 21:18:56 djm Exp $ +# $Id: configure.ac,v 1.500 2013/01/09 05:42:47 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) -AC_REVISION($Revision: 1.499 $) +AC_REVISION($Revision: 1.500 $) AC_CONFIG_SRCDIR([ssh.c]) AC_LANG([C]) @@ -2320,6 +2320,26 @@ AC_LINK_IFELSE( ] ) +# Check for OpenSSL with EVP_aes_*gcm +AC_MSG_CHECKING([whether OpenSSL has AES GCM via EVP]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +#include +#include + ]], [[ + exit(EVP_aes_128_gcm() == NULL || + EVP_aes_256_gcm() == NULL); + ]])], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([OPENSSL_HAVE_EVPGCM], [1], + [libcrypto has EVP AES GCM]) + ], + [ + AC_MSG_RESULT([no]) + ] +) + AC_MSG_CHECKING([if EVP_DigestUpdate returns an int]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index a151eff38..28da3be2d 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -1,4 +1,4 @@ -/* $Id: openssl-compat.h,v 1.20 2012/01/17 03:03:39 dtucker Exp $ */ +/* $Id: openssl-compat.h,v 1.21 2013/01/09 05:42:49 djm Exp $ */ /* * Copyright (c) 2005 Darren Tucker @@ -63,6 +63,30 @@ extern const EVP_CIPHER *evp_rijndael(void); extern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); #endif +#ifndef OPENSSL_HAVE_EVPCTR +#define EVP_aes_128_ctr evp_aes_128_ctr +#define EVP_aes_192_ctr evp_aes_128_ctr +#define EVP_aes_256_ctr evp_aes_128_ctr +extern const EVP_CIPHER *evp_aes_128_ctr(void); +extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); +#endif + +/* Avoid some #ifdef. Code that uses these is unreachable without GCM */ +#if !defined(OPENSSL_HAVE_EVPGCM) && !defined(EVP_CTRL_GCM_SET_IV_FIXED) +# define EVP_CTRL_GCM_SET_IV_FIXED -1 +# define EVP_CTRL_GCM_IV_GEN -1 +# define EVP_CTRL_GCM_SET_TAG -1 +# define EVP_CTRL_GCM_GET_TAG -1 +#endif + +#if OPENSSL_VERSION_NUMBER < 0x00907000L +#define EVP_X_STATE(evp) &(evp).c +#define EVP_X_STATE_LEN(evp) sizeof((evp).c) +#else +#define EVP_X_STATE(evp) (evp).cipher_data +#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size +#endif + #if !defined(EVP_CTRL_SET_ACSS_MODE) # if (OPENSSL_VERSION_NUMBER >= 0x00907000L) # define USE_CIPHER_ACSS 1 -- cgit v1.2.3 From c20eb8b8eac8b6cb1f86199e16dc7d13902a760b Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 12 Jan 2013 22:41:26 +1100 Subject: - djm@cvs.openbsd.org 2013/01/12 11:22:04 [cipher.c] improve error message for integrity failure in AES-GCM modes; ok markus@ --- ChangeLog | 6 ++++++ cipher.c | 10 +++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'cipher.c') diff --git a/ChangeLog b/ChangeLog index 37f114b5b..3be438c75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20130112 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2013/01/12 11:22:04 + [cipher.c] + improve error message for integrity failure in AES-GCM modes; ok markus@ + 20130109 - (djm) OpenBSD CVS Sync - dtucker@cvs.openbsd.org 2012/12/14 05:26:43 diff --git a/cipher.c b/cipher.c index e137f359b..2d307e160 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.85 2013/01/08 18:49:04 markus Exp $ */ +/* $OpenBSD: cipher.c,v 1.86 2013/01/12 11:22:04 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -342,8 +342,12 @@ cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, fatal("%s: EVP_Cipher failed", __func__); if (authlen) { /* compute tag (on encrypt) or verify tag (on decrypt) */ - if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) - fatal("%s: EVP_Cipher(finish) failed", __func__); + if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) { + if (cc->encrypt) + fatal("%s: EVP_Cipher(final) failed", __func__); + else + fatal("Decryption integrity check failed"); + } if (cc->encrypt && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, authlen, dest + aadlen + len)) -- cgit v1.2.3 From f0a8ded824a0149940a8c95755da05a9ce5d7f35 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 12 Feb 2013 11:00:34 +1100 Subject: - djm@cvs.openbsd.org 2013/01/26 06:11:05 [Makefile.in acss.c acss.h cipher-acss.c cipher.c] [openbsd-compat/openssl-compat.h] remove ACSS, now that it is gone from libcrypto too --- ChangeLog | 4 + Makefile.in | 6 +- acss.c | 267 ---------------------------------------- acss.h | 47 ------- cipher-acss.c | 86 ------------- cipher.c | 10 +- openbsd-compat/openssl-compat.h | 12 +- 7 files changed, 11 insertions(+), 421 deletions(-) delete mode 100644 acss.c delete mode 100644 acss.h delete mode 100644 cipher-acss.c (limited to 'cipher.c') diff --git a/ChangeLog b/ChangeLog index 428a93ddb..25fb4b680 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,10 @@ redo last commit without the vi-vomit that snuck in: skip serial lookup when cert's serial number is zero (now with 100% better comment) + - djm@cvs.openbsd.org 2013/01/26 06:11:05 + [Makefile.in acss.c acss.h cipher-acss.c cipher.c] + [openbsd-compat/openssl-compat.h] + remove ACSS, now that it is gone from libcrypto too 20130211 - (djm) [configure.ac openbsd-compat/openssl-compat.h] Repair build on old diff --git a/Makefile.in b/Makefile.in index 74eeab574..ec3e1f417 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.330 2013/01/18 00:44:04 djm Exp $ +# $Id: Makefile.in,v 1.331 2013/02/12 00:00:34 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -61,8 +61,8 @@ MANFMT=@MANFMT@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) -LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \ +LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ + canohost.o channels.o cipher.o cipher-aes.o \ cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \ log.o match.o md-sha256.o moduli.o nchan.o packet.o \ diff --git a/acss.c b/acss.c deleted file mode 100644 index 86e2c01a8..000000000 --- a/acss.c +++ /dev/null @@ -1,267 +0,0 @@ -/* $Id: acss.c,v 1.4 2006/07/24 04:51:01 djm Exp $ */ -/* - * Copyright (c) 2004 The OpenBSD project - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#include - -#include - -#if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00906000L) - -#include "acss.h" - -/* decryption sbox */ -static unsigned char sboxdec[] = { - 0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76, - 0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b, - 0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96, - 0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b, - 0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12, - 0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f, - 0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90, - 0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91, - 0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74, - 0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75, - 0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94, - 0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95, - 0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10, - 0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11, - 0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92, - 0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f, - 0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16, - 0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b, - 0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6, - 0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb, - 0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72, - 0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f, - 0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0, - 0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1, - 0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14, - 0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15, - 0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4, - 0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5, - 0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70, - 0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71, - 0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2, - 0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff -}; - -/* encryption sbox */ -static unsigned char sboxenc[] = { - 0x33, 0x3b, 0x73, 0x15, 0x53, 0x5b, 0x13, 0x75, - 0x3d, 0x35, 0x7d, 0x1b, 0x5d, 0x55, 0x1d, 0x7b, - 0x67, 0x6f, 0x27, 0x81, 0xc7, 0xcf, 0x87, 0x21, - 0x69, 0x61, 0x29, 0x8f, 0xc9, 0xc1, 0x89, 0x2f, - 0xe3, 0xeb, 0xa3, 0x05, 0x43, 0x4b, 0x03, 0xa5, - 0xed, 0xe5, 0xad, 0x0b, 0x4d, 0x45, 0x0d, 0xab, - 0xea, 0xe2, 0xaa, 0x00, 0x4a, 0x42, 0x0a, 0xa0, - 0xe8, 0xe0, 0xa8, 0x02, 0x48, 0x40, 0x08, 0xa2, - 0x3e, 0x36, 0x7e, 0x14, 0x5e, 0x56, 0x1e, 0x74, - 0x3c, 0x34, 0x7c, 0x16, 0x5c, 0x54, 0x1c, 0x76, - 0x6a, 0x62, 0x2a, 0x80, 0xca, 0xc2, 0x8a, 0x20, - 0x68, 0x60, 0x28, 0x82, 0xc8, 0xc0, 0x88, 0x22, - 0xee, 0xe6, 0xae, 0x04, 0x4e, 0x46, 0x0e, 0xa4, - 0xec, 0xe4, 0xac, 0x06, 0x4c, 0x44, 0x0c, 0xa6, - 0xe7, 0xef, 0xa7, 0x01, 0x47, 0x4f, 0x07, 0xa1, - 0xe9, 0xe1, 0xa9, 0x0f, 0x49, 0x41, 0x09, 0xaf, - 0x63, 0x6b, 0x23, 0x85, 0xc3, 0xcb, 0x83, 0x25, - 0x6d, 0x65, 0x2d, 0x8b, 0xcd, 0xc5, 0x8d, 0x2b, - 0x37, 0x3f, 0x77, 0x11, 0x57, 0x5f, 0x17, 0x71, - 0x39, 0x31, 0x79, 0x1f, 0x59, 0x51, 0x19, 0x7f, - 0xb3, 0xbb, 0xf3, 0x95, 0xd3, 0xdb, 0x93, 0xf5, - 0xbd, 0xb5, 0xfd, 0x9b, 0xdd, 0xd5, 0x9d, 0xfb, - 0xba, 0xb2, 0xfa, 0x90, 0xda, 0xd2, 0x9a, 0xf0, - 0xb8, 0xb0, 0xf8, 0x92, 0xd8, 0xd0, 0x98, 0xf2, - 0x6e, 0x66, 0x2e, 0x84, 0xce, 0xc6, 0x8e, 0x24, - 0x6c, 0x64, 0x2c, 0x86, 0xcc, 0xc4, 0x8c, 0x26, - 0x3a, 0x32, 0x7a, 0x10, 0x5a, 0x52, 0x1a, 0x70, - 0x38, 0x30, 0x78, 0x12, 0x58, 0x50, 0x18, 0x72, - 0xbe, 0xb6, 0xfe, 0x94, 0xde, 0xd6, 0x9e, 0xf4, - 0xbc, 0xb4, 0xfc, 0x96, 0xdc, 0xd4, 0x9c, 0xf6, - 0xb7, 0xbf, 0xf7, 0x91, 0xd7, 0xdf, 0x97, 0xf1, - 0xb9, 0xb1, 0xf9, 0x9f, 0xd9, 0xd1, 0x99, 0xff -}; - -static unsigned char reverse[] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff -}; - -/* - * Two linear feedback shift registers are used: - * - * lfsr17: polynomial of degree 17, primitive modulo 2 (listed in Schneier) - * x^15 + x + 1 - * lfsr25: polynomial of degree 25, not know if primitive modulo 2 - * x^13 + x^5 + x^4 + x^1 + 1 - * - * Output bits are discarded, instead the feedback bits are added to produce - * the cipher stream. Depending on the mode, feedback bytes may be inverted - * bit-wise before addition. - * - * The lfsrs are seeded with bytes from the raw key: - * - * lfsr17: byte 0[0:7] at bit 9 - * byte 1[0:7] at bit 0 - * - * lfsr25: byte 2[0:4] at bit 16 - * byte 2[5:7] at bit 22 - * byte 3[0:7] at bit 8 - * byte 4[0:7] at bit 0 - * - * To prevent 0 cycles, 1's are inject at bit 8 in lfrs17 and bit 21 in - * lfsr25. - * - */ - -int -acss(ACSS_KEY *key, unsigned long len, const unsigned char *in, - unsigned char *out) -{ - unsigned long i; - unsigned long lfsr17tmp, lfsr25tmp, lfsrsumtmp; - - lfsrsumtmp = lfsr17tmp = lfsr25tmp = 0; - - /* keystream is sum of lfsrs */ - for (i = 0; i < len; i++) { - lfsr17tmp = key->lfsr17 ^ (key->lfsr17 >> 14); - key->lfsr17 = (key->lfsr17 >> 8) - ^ (lfsr17tmp << 9) - ^ (lfsr17tmp << 12) - ^ (lfsr17tmp << 15); - key->lfsr17 &= 0x1ffff; /* 17 bit LFSR */ - - lfsr25tmp = key->lfsr25 - ^ (key->lfsr25 >> 3) - ^ (key->lfsr25 >> 4) - ^ (key->lfsr25 >> 12); - key->lfsr25 = (key->lfsr25 >> 8) ^ (lfsr25tmp << 17); - key->lfsr25 &= 0x1ffffff; /* 25 bit LFSR */ - - lfsrsumtmp = key->lfsrsum; - - /* addition */ - switch (key->mode) { - case ACSS_AUTHENTICATE: - case ACSS_DATA: - key->lfsrsum = 0xff & ~(key->lfsr17 >> 9); - key->lfsrsum += key->lfsr25 >> 17; - break; - case ACSS_SESSIONKEY: - key->lfsrsum = key->lfsr17 >> 9; - key->lfsrsum += key->lfsr25 >> 17; - break; - case ACSS_TITLEKEY: - key->lfsrsum = key->lfsr17 >> 9; - key->lfsrsum += 0xff & ~(key->lfsr25 >> 17); - break; - default: - return 1; - } - key->lfsrsum += (lfsrsumtmp >> 8); - - if (key->encrypt) { - out[i] = sboxenc[(in[i] ^ key->lfsrsum) & 0xff]; - } else { - out[i] = (sboxdec[in[i]] ^ key->lfsrsum) & 0xff; - } - } - - return 0; -} - -static void -acss_seed(ACSS_KEY *key) -{ - int i; - - /* if available, mangle with subkey */ - if (key->subkey_avilable) { - for (i = 0; i < ACSS_KEYSIZE; i++) - key->seed[i] = reverse[key->data[i] ^ key->subkey[i]]; - } else { - for (i = 0; i < ACSS_KEYSIZE; i++) - key->seed[i] = reverse[key->data[i]]; - } - - /* seed lfsrs */ - key->lfsr17 = key->seed[1] - | (key->seed[0] << 9) - | (1 << 8); /* inject 1 at bit 9 */ - key->lfsr25 = key->seed[4] - | (key->seed[3] << 8) - | ((key->seed[2] & 0x1f) << 16) - | ((key->seed[2] & 0xe0) << 17) - | (1 << 21); /* inject 1 at bit 22 */ - - key->lfsrsum = 0; -} - -void -acss_setkey(ACSS_KEY *key, const unsigned char *data, int enc, int mode) -{ - memcpy(key->data, data, sizeof(key->data)); - memset(key->subkey, 0, sizeof(key->subkey)); - - if (enc != -1) - key->encrypt = enc; - key->mode = mode; - key->subkey_avilable = 0; - - acss_seed(key); -} - -void -acss_setsubkey(ACSS_KEY *key, const unsigned char *subkey) -{ - memcpy(key->subkey, subkey, sizeof(key->subkey)); - key->subkey_avilable = 1; - acss_seed(key); -} -#endif diff --git a/acss.h b/acss.h deleted file mode 100644 index 91b489542..000000000 --- a/acss.h +++ /dev/null @@ -1,47 +0,0 @@ -/* $Id: acss.h,v 1.2 2004/02/06 04:22:43 dtucker Exp $ */ -/* - * Copyright (c) 2004 The OpenBSD project - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _ACSS_H_ -#define _ACSS_H_ - -/* 40bit key */ -#define ACSS_KEYSIZE 5 - -/* modes of acss */ -#define ACSS_AUTHENTICATE 0 -#define ACSS_SESSIONKEY 1 -#define ACSS_TITLEKEY 2 -#define ACSS_DATA 3 - -typedef struct acss_key_st { - unsigned int lfsr17; /* current state of lfsrs */ - unsigned int lfsr25; - unsigned int lfsrsum; - unsigned char seed[ACSS_KEYSIZE]; - unsigned char data[ACSS_KEYSIZE]; - unsigned char subkey[ACSS_KEYSIZE]; - int encrypt; /* XXX make these bit flags? */ - int mode; - int seeded; - int subkey_avilable; -} ACSS_KEY; - -void acss_setkey(ACSS_KEY *, const unsigned char *, int, int); -void acss_setsubkey(ACSS_KEY *, const unsigned char *); -int acss(ACSS_KEY *, unsigned long, const unsigned char *, unsigned char *); - -#endif /* ifndef _ACSS_H_ */ diff --git a/cipher-acss.c b/cipher-acss.c deleted file mode 100644 index e755f92b9..000000000 --- a/cipher-acss.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2004 The OpenBSD project - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#include - -#include - -#if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) - -#include "acss.h" -#include "openbsd-compat/openssl-compat.h" - -#define data(ctx) ((EVP_ACSS_KEY *)(ctx)->cipher_data) - -typedef struct { - ACSS_KEY ks; -} EVP_ACSS_KEY; - -#define EVP_CTRL_SET_ACSS_MODE 0xff06 -#define EVP_CTRL_SET_ACSS_SUBKEY 0xff07 - -static int -acss_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - acss_setkey(&data(ctx)->ks,key,enc,ACSS_DATA); - return 1; -} - -static int -acss_ciph(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, - LIBCRYPTO_EVP_INL_TYPE inl) -{ - acss(&data(ctx)->ks,inl,in,out); - return 1; -} - -static int -acss_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) -{ - switch(type) { - case EVP_CTRL_SET_ACSS_MODE: - data(ctx)->ks.mode = arg; - return 1; - case EVP_CTRL_SET_ACSS_SUBKEY: - acss_setsubkey(&data(ctx)->ks,(unsigned char *)ptr); - return 1; - default: - return -1; - } -} - -const EVP_CIPHER * -evp_acss(void) -{ - static EVP_CIPHER acss_cipher; - - memset(&acss_cipher, 0, sizeof(EVP_CIPHER)); - - acss_cipher.nid = NID_undef; - acss_cipher.block_size = 1; - acss_cipher.key_len = 5; - acss_cipher.init = acss_init_key; - acss_cipher.do_cipher = acss_ciph; - acss_cipher.ctx_size = sizeof(EVP_ACSS_KEY); - acss_cipher.ctrl = acss_ctrl; - - return (&acss_cipher); -} -#endif - diff --git a/cipher.c b/cipher.c index 2d307e160..9ca1d0065 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.86 2013/01/12 11:22:04 djm Exp $ */ +/* $OpenBSD: cipher.c,v 1.87 2013/01/26 06:11:05 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -92,10 +92,6 @@ struct Cipher { SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, { "aes256-gcm@openssh.com", SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, -#endif -#ifdef USE_CIPHER_ACSS - { "acss@openssh.org", - SSH_CIPHER_SSH2, 16, 5, 0, 0, 0, 0, EVP_acss }, #endif { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } }; @@ -478,7 +474,7 @@ cipher_get_keycontext(const CipherContext *cc, u_char *dat) Cipher *c = cc->cipher; int plen = 0; - if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { + if (c->evptype == EVP_rc4) { plen = EVP_X_STATE_LEN(cc->evp); if (dat == NULL) return (plen); @@ -493,7 +489,7 @@ cipher_set_keycontext(CipherContext *cc, u_char *dat) Cipher *c = cc->cipher; int plen; - if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { + if (c->evptype == EVP_rc4) { plen = EVP_X_STATE_LEN(cc->evp); memcpy(EVP_X_STATE(cc->evp), dat, plen); } diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 6c4d68def..e7439b4e7 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -1,4 +1,4 @@ -/* $Id: openssl-compat.h,v 1.23 2013/02/10 23:39:15 djm Exp $ */ +/* $Id: openssl-compat.h,v 1.24 2013/02/12 00:00:40 djm Exp $ */ /* * Copyright (c) 2005 Darren Tucker @@ -96,16 +96,6 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t); #define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size #endif -#if !defined(EVP_CTRL_SET_ACSS_MODE) -# if (OPENSSL_VERSION_NUMBER >= 0x00907000L) -# define USE_CIPHER_ACSS 1 -extern const EVP_CIPHER *evp_acss(void); -# define EVP_acss evp_acss -# else -# define EVP_acss NULL -# endif -#endif - /* OpenSSL 0.9.8e returns cipher key len not context key len */ #if (OPENSSL_VERSION_NUMBER == 0x0090805fL) # define EVP_CIPHER_CTX_key_length(c) ((c)->key_len) -- cgit v1.2.3