Support AES-Counter ciphers.
This commit is contained in:
parent
b78f854d8b
commit
ebbd7c879b
1
COPYING
1
COPYING
@ -1,6 +1,7 @@
|
|||||||
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||||
* Copyright (c) 2006-2007 The Written Word, Inc.
|
* Copyright (c) 2006-2007 The Written Word, Inc.
|
||||||
* Copyright (c) 2009 Daniel Stenberg
|
* Copyright (c) 2009 Daniel Stenberg
|
||||||
|
* Copyright (C) 2008, 2009 Simon Josefsson
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
|
4
NEWS
4
NEWS
@ -7,6 +7,10 @@ Version 1.2.2 (unreleased)
|
|||||||
<http://thread.gmane.org/gmane.network.ssh.libssh2.devel/2530>.
|
<http://thread.gmane.org/gmane.network.ssh.libssh2.devel/2530>.
|
||||||
By Simon Josefsson.
|
By Simon Josefsson.
|
||||||
|
|
||||||
|
o Support for the "aes128-ctr", "aes192-ctr", "aes256-ctr" ciphers
|
||||||
|
as per RFC 4344 for libgcrypt and OpenSSL. They are now the
|
||||||
|
preferred ciphers. By Simon Josefsson.
|
||||||
|
|
||||||
o Support for the "arcfour128" cipher as per RFC 4345 for libgcrypt
|
o Support for the "arcfour128" cipher as per RFC 4345 for libgcrypt
|
||||||
and OpenSSL. It is preferred over the normal "arcfour" cipher
|
and OpenSSL. It is preferred over the normal "arcfour" cipher
|
||||||
which is somewhat broken. By Simon Josefsson.
|
which is somewhat broken. By Simon Josefsson.
|
||||||
|
47
src/crypt.c
47
src/crypt.c
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2009 Simon Josefsson <simon@josefsson.org>
|
||||||
* Copyright (c) 2009 Simon Josefsson <simon@josefsson.org>
|
* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@ -115,6 +115,44 @@ crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LIBSSH2_AES_CTR
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
|
||||||
|
"aes128-ctr",
|
||||||
|
16, /* blocksize */
|
||||||
|
16, /* initial value length */
|
||||||
|
16, /* secret length -- 16*8 == 128bit */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_aes128ctr
|
||||||
|
};
|
||||||
|
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
|
||||||
|
"aes192-ctr",
|
||||||
|
16, /* blocksize */
|
||||||
|
16, /* initial value length */
|
||||||
|
24, /* secret length -- 24*8 == 192bit */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_aes192ctr
|
||||||
|
};
|
||||||
|
|
||||||
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
|
||||||
|
"aes256-ctr",
|
||||||
|
16, /* blocksize */
|
||||||
|
16, /* initial value length */
|
||||||
|
32, /* secret length -- 32*8 == 256bit */
|
||||||
|
0, /* flags */
|
||||||
|
&crypt_init,
|
||||||
|
&crypt_encrypt,
|
||||||
|
&crypt_dtor,
|
||||||
|
_libssh2_cipher_aes256ctr
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LIBSSH2_AES
|
#if LIBSSH2_AES
|
||||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
|
||||||
"aes128-cbc",
|
"aes128-cbc",
|
||||||
@ -258,6 +296,11 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
||||||
|
#if LIBSSH2_AES_CTR
|
||||||
|
&libssh2_crypt_method_aes128_ctr,
|
||||||
|
&libssh2_crypt_method_aes192_ctr,
|
||||||
|
&libssh2_crypt_method_aes256_ctr,
|
||||||
|
#endif /* LIBSSH2_AES */
|
||||||
#if LIBSSH2_AES
|
#if LIBSSH2_AES
|
||||||
&libssh2_crypt_method_aes256_cbc,
|
&libssh2_crypt_method_aes256_cbc,
|
||||||
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
|
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
|
||||||
|
@ -544,8 +544,11 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
|||||||
|
|
||||||
if (mode != GCRY_CIPHER_MODE_STREAM) {
|
if (mode != GCRY_CIPHER_MODE_STREAM) {
|
||||||
int blklen = gcry_cipher_get_algo_blklen(cipher);
|
int blklen = gcry_cipher_get_algo_blklen(cipher);
|
||||||
ret = gcry_cipher_setiv(*h, iv, blklen);
|
if (mode == GCRY_CIPHER_MODE_CTR)
|
||||||
if (ret) {
|
ret = gcry_cipher_setctr(*h, iv, blklen);
|
||||||
|
else
|
||||||
|
ret = gcry_cipher_setiv(*h, iv, blklen);
|
||||||
|
if (ret) {
|
||||||
gcry_cipher_close(*h);
|
gcry_cipher_close(*h);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#define LIBSSH2_HMAC_RIPEMD 1
|
#define LIBSSH2_HMAC_RIPEMD 1
|
||||||
|
|
||||||
#define LIBSSH2_AES 1
|
#define LIBSSH2_AES 1
|
||||||
|
#define LIBSSH2_AES_CTR 1
|
||||||
#define LIBSSH2_BLOWFISH 1
|
#define LIBSSH2_BLOWFISH 1
|
||||||
#define LIBSSH2_RC4 1
|
#define LIBSSH2_RC4 1
|
||||||
#define LIBSSH2_CAST 1
|
#define LIBSSH2_CAST 1
|
||||||
@ -160,7 +161,13 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
|||||||
#define _libssh2_gcry_cipher(c) (c >> 8)
|
#define _libssh2_gcry_cipher(c) (c >> 8)
|
||||||
#define _libssh2_gcry_mode(m) (m & 0xFF)
|
#define _libssh2_gcry_mode(m) (m & 0xFF)
|
||||||
|
|
||||||
#define _libssh2_cipher_aes256 \
|
#define _libssh2_cipher_aes256ctr \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR)
|
||||||
|
#define _libssh2_cipher_aes192ctr \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR)
|
||||||
|
#define _libssh2_cipher_aes128ctr \
|
||||||
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR)
|
||||||
|
#define _libssh2_cipher_aes256 \
|
||||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC)
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC)
|
||||||
#define _libssh2_cipher_aes192 \
|
#define _libssh2_cipher_aes192 \
|
||||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC)
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC)
|
||||||
|
106
src/openssl.c
106
src/openssl.c
@ -1,7 +1,9 @@
|
|||||||
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
/* Copyright (C) 2009 Simon Josefsson
|
||||||
* Author: Simon Josefsson
|
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||||
* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||||
*
|
*
|
||||||
|
* Author: Simon Josefsson
|
||||||
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
* with or without modification, are permitted provided
|
* with or without modification, are permitted provided
|
||||||
* that the following conditions are met:
|
* that the following conditions are met:
|
||||||
@ -197,6 +199,106 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
|||||||
return ret == 1 ? 0 : 1;
|
return ret == 1 ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <openssl/aes.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
AES_KEY key;
|
||||||
|
unsigned char ctr[AES_BLOCK_SIZE];
|
||||||
|
} aes_ctr_ctx;
|
||||||
|
|
||||||
|
static int
|
||||||
|
aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||||
|
const unsigned char *iv, int enc) /* init key */
|
||||||
|
{
|
||||||
|
aes_ctr_ctx *c = malloc(sizeof(*c));
|
||||||
|
if (c == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
AES_set_encrypt_key(key, 8 * ctx->key_len, &c->key);
|
||||||
|
memcpy(c->ctr, iv, AES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
EVP_CIPHER_CTX_set_app_data(ctx, c);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
|
const unsigned char *in,
|
||||||
|
unsigned int inl) /* encrypt/decrypt data */
|
||||||
|
{
|
||||||
|
aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx);
|
||||||
|
unsigned char b1[AES_BLOCK_SIZE];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (inl != 16) /* libssh2 only ever encrypt one block */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
To encrypt a packet P=P1||P2||...||Pn (where P1, P2, ..., Pn are each
|
||||||
|
blocks of length L), the encryptor first encrypts <X> with <cipher>
|
||||||
|
to obtain a block B1. The block B1 is then XORed with P1 to generate
|
||||||
|
the ciphertext block C1. The counter X is then incremented
|
||||||
|
*/
|
||||||
|
|
||||||
|
AES_encrypt(c->ctr, b1, &c->key);
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
*out++ = *in++ ^ b1[i];
|
||||||
|
|
||||||
|
i = 15;
|
||||||
|
while (c->ctr[i]++ == 0xFF) {
|
||||||
|
if (i == 0)
|
||||||
|
break;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) /* cleanup ctx */
|
||||||
|
{
|
||||||
|
free(EVP_CIPHER_CTX_get_app_data(ctx));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const EVP_CIPHER *
|
||||||
|
make_ctr_evp (size_t keylen)
|
||||||
|
{
|
||||||
|
static EVP_CIPHER aes_ctr_cipher;
|
||||||
|
|
||||||
|
memset(&aes_ctr_cipher, 0, sizeof(aes_ctr_cipher));
|
||||||
|
|
||||||
|
aes_ctr_cipher.block_size = 16;
|
||||||
|
aes_ctr_cipher.key_len = keylen;
|
||||||
|
aes_ctr_cipher.iv_len = 16;
|
||||||
|
aes_ctr_cipher.init = aes_ctr_init;
|
||||||
|
aes_ctr_cipher.do_cipher = aes_ctr_do_cipher;
|
||||||
|
aes_ctr_cipher.cleanup = aes_ctr_cleanup;
|
||||||
|
|
||||||
|
return &aes_ctr_cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EVP_CIPHER *
|
||||||
|
_libssh2_EVP_aes_128_ctr(void)
|
||||||
|
{
|
||||||
|
return make_ctr_evp (16);
|
||||||
|
}
|
||||||
|
|
||||||
|
const EVP_CIPHER *
|
||||||
|
_libssh2_EVP_aes_192_ctr(void)
|
||||||
|
{
|
||||||
|
return make_ctr_evp (24);
|
||||||
|
}
|
||||||
|
|
||||||
|
const EVP_CIPHER *
|
||||||
|
_libssh2_EVP_aes_256_ctr(void)
|
||||||
|
{
|
||||||
|
return make_ctr_evp (32);
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: Optionally call a passphrase callback specified by the
|
/* TODO: Optionally call a passphrase callback specified by the
|
||||||
* calling program
|
* calling program
|
||||||
*/
|
*/
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
/* Copyright (C) 2009 Simon Josefsson
|
||||||
|
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||||
|
*
|
||||||
* Author: Simon Josefsson
|
* Author: Simon Josefsson
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@ -71,6 +73,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)
|
#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)
|
||||||
|
# define LIBSSH2_AES_CTR 1
|
||||||
# define LIBSSH2_AES 1
|
# define LIBSSH2_AES 1
|
||||||
#else
|
#else
|
||||||
# define LIBSSH2_AES 0
|
# define LIBSSH2_AES 0
|
||||||
@ -194,6 +197,9 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
|||||||
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
|
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
|
||||||
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
|
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
|
||||||
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
|
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
|
||||||
|
#define _libssh2_cipher_aes128ctr _libssh2_EVP_aes_128_ctr
|
||||||
|
#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr
|
||||||
|
#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr
|
||||||
#define _libssh2_cipher_blowfish EVP_bf_cbc
|
#define _libssh2_cipher_blowfish EVP_bf_cbc
|
||||||
#define _libssh2_cipher_arcfour EVP_rc4
|
#define _libssh2_cipher_arcfour EVP_rc4
|
||||||
#define _libssh2_cipher_cast5 EVP_cast5_cbc
|
#define _libssh2_cipher_cast5 EVP_cast5_cbc
|
||||||
@ -223,3 +229,7 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
|||||||
#define _libssh2_bn_bytes(bn) BN_num_bytes(bn)
|
#define _libssh2_bn_bytes(bn) BN_num_bytes(bn)
|
||||||
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
|
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
|
||||||
#define _libssh2_bn_free(bn) BN_clear_free(bn)
|
#define _libssh2_bn_free(bn) BN_clear_free(bn)
|
||||||
|
|
||||||
|
const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void);
|
||||||
|
const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void);
|
||||||
|
const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user