Commit 1d75abfe authored by Damien Miller's avatar Damien Miller

- 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@
parent aa7ad303
......@@ -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
......
......@@ -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 $
/* $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 <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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(&copy), buffer_len(&copy), 0);
buffer_ptr(&copy), buffer_len(&copy), 0, 0);
cipher_cleanup(&ciphercontext);
memset(&ciphercontext, 0, sizeof(ciphercontext));
buffer_free(&copy);
......
/* $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 <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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
......
/* $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 <ylo@cs.hut.fi>
......@@ -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 *);
......
/* $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 : "<implicit>",
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;
}
......
/* $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;
......
/* $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 <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
......@@ -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);
......
/* $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
......
/* $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 <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment