diff options
Diffstat (limited to 'usr.bin/ssh')
-rw-r--r-- | usr.bin/ssh/cipher-ctr.c | 149 | ||||
-rw-r--r-- | usr.bin/ssh/cipher.c | 13 | ||||
-rw-r--r-- | usr.bin/ssh/lib/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/ssh/myproposal.h | 5 |
4 files changed, 166 insertions, 5 deletions
diff --git a/usr.bin/ssh/cipher-ctr.c b/usr.bin/ssh/cipher-ctr.c new file mode 100644 index 00000000000..8d548c708d4 --- /dev/null +++ b/usr.bin/ssh/cipher-ctr.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2003 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "includes.h" +RCSID("$OpenBSD: cipher-ctr.c,v 1.1 2003/05/17 04:27:52 markus Exp $"); + +#include <openssl/evp.h> + +#include "log.h" +#include "xmalloc.h" + +#if OPENSSL_VERSION_NUMBER < 0x00907000L +#include "rijndael.h" +#define AES_KEY rijndael_ctx +#define AES_BLOCK_SIZE 16 +#define AES_encrypt(a, b, c) rijndael_encrypt(c, a, b) +#define AES_set_encrypt_key(a, b, c) rijndael_set_key(c, (char *)a, b, 1) +#else +#include <openssl/aes.h> +#endif + +const EVP_CIPHER *evp_aes_128_ctr(void); +void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); + +struct ssh_aes_ctr_ctx +{ + AES_KEY aes_ctx; + u_char aes_counter[AES_BLOCK_SIZE]; +}; + +/* + * increment counter 'ctr', + * the counter is of size 'len' bytes and stored in network-byte-order. + * (LSB at ctr[len-1], MSB at ctr[0]) + */ +static void +ssh_ctr_inc(u_char *ctr, u_int len) +{ + int i; + + for (i = len - 1; i >= 0; i--) + if (++ctr[i]) /* continue on overflow */ + return; +} + +static int +ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, + u_int len) +{ + struct ssh_aes_ctr_ctx *c; + u_int n = 0; + u_char buf[AES_BLOCK_SIZE]; + + if (len == 0) + return (1); + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) + return (0); + + while ((len--) > 0) { + if (n == 0) { + AES_encrypt(c->aes_counter, buf, &c->aes_ctx); + ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); + } + *(dest++) = *(src++) ^ buf[n]; + n = (n + 1) % AES_BLOCK_SIZE; + } + return (1); +} + +static int +ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, + int enc) +{ + struct ssh_aes_ctr_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { + c = xmalloc(sizeof(*c)); + EVP_CIPHER_CTX_set_app_data(ctx, c); + } + if (key != NULL) + AES_set_encrypt_key(key, ctx->key_len * 8, &c->aes_ctx); + if (iv != NULL) + memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); + return (1); +} + +static int +ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) +{ + struct ssh_aes_ctr_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { + memset(c, 0, sizeof(*c)); + xfree(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); + } + return (1); +} + +void +ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len) +{ + struct ssh_aes_ctr_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) + fatal("ssh_aes_ctr_iv: no context"); + if (doset) + memcpy(c->aes_counter, iv, len); + else + memcpy(iv, c->aes_counter, len); +} + +const EVP_CIPHER * +evp_aes_128_ctr(void) +{ + static EVP_CIPHER aes_ctr; + + memset(&aes_ctr, 0, sizeof(EVP_CIPHER)); + aes_ctr.nid = NID_undef; + aes_ctr.block_size = AES_BLOCK_SIZE; + aes_ctr.iv_len = AES_BLOCK_SIZE; + aes_ctr.key_len = 16; + aes_ctr.init = ssh_aes_ctr_init; + aes_ctr.cleanup = ssh_aes_ctr_cleanup; + aes_ctr.do_cipher = ssh_aes_ctr; + aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; + return (&aes_ctr); +} diff --git a/usr.bin/ssh/cipher.c b/usr.bin/ssh/cipher.c index 196812bb200..efdfa391314 100644 --- a/usr.bin/ssh/cipher.c +++ b/usr.bin/ssh/cipher.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: cipher.c,v 1.64 2003/05/15 03:08:29 markus Exp $"); +RCSID("$OpenBSD: cipher.c,v 1.65 2003/05/17 04:27:52 markus Exp $"); #include "xmalloc.h" #include "log.h" @@ -50,6 +50,8 @@ extern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); 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); +extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); struct Cipher { char *name; @@ -80,6 +82,9 @@ struct Cipher { { "rijndael-cbc@lysator.liu.se", SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc }, #endif + { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr }, + { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr }, + { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr }, { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL } }; @@ -310,6 +315,9 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) ssh_rijndael_iv(&cc->evp, 0, iv, len); else #endif + if (c->evptype == evp_aes_128_ctr) + ssh_aes_ctr_iv(&cc->evp, 0, iv, len); + else memcpy(iv, cc->evp.iv, len); break; case SSH_CIPHER_3DES: @@ -338,6 +346,9 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) ssh_rijndael_iv(&cc->evp, 1, iv, evplen); else #endif + if (c->evptype == evp_aes_128_ctr) + ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); + else memcpy(cc->evp.iv, iv, evplen); break; case SSH_CIPHER_3DES: diff --git a/usr.bin/ssh/lib/Makefile b/usr.bin/ssh/lib/Makefile index f10d07f770e..6ba4cb0900c 100644 --- a/usr.bin/ssh/lib/Makefile +++ b/usr.bin/ssh/lib/Makefile @@ -1,10 +1,10 @@ -# $OpenBSD: Makefile,v 1.42 2003/05/15 03:08:29 markus Exp $ +# $OpenBSD: Makefile,v 1.43 2003/05/17 04:27:52 markus Exp $ .PATH: ${.CURDIR}/.. LIB= ssh SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \ - cipher.c cipher-3des1.c cipher-aes.c cipher-bf1.c \ + cipher.c cipher-3des1.c cipher-aes.c cipher-bf1.c cipher-ctr.c \ compat.c compress.c crc32.c deattack.c fatal.c \ hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \ rsa.c tildexpand.c ttymodes.c xmalloc.c atomicio.c \ diff --git a/usr.bin/ssh/myproposal.h b/usr.bin/ssh/myproposal.h index 62f5cfb655e..8b431d9d277 100644 --- a/usr.bin/ssh/myproposal.h +++ b/usr.bin/ssh/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.14 2002/04/03 09:26:11 markus Exp $ */ +/* $OpenBSD: myproposal.h,v 1.15 2003/05/17 04:27:52 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -27,7 +27,8 @@ #define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss" #define KEX_DEFAULT_ENCRYPT \ "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \ - "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" + "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \ + "aes128-ctr,aes192-ctr,aes256-ctr" #define KEX_DEFAULT_MAC \ "hmac-md5,hmac-sha1,hmac-ripemd160," \ "hmac-ripemd160@openssh.com," \ |