From 1d83b520b491c303fd3df752cef4d740257cf2b3 Mon Sep 17 00:00:00 2001 From: Lars Nordin Date: Sun, 27 Jun 2010 22:23:50 +0200 Subject: [PATCH] openssl: make use of the EVP interface Make use of the EVP interface for the AES-funktion. Using this method supports the use of different ENGINES in OpenSSL for the AES function (and the direct call to the AES_encrypt should not be used according to openssl.org) --- src/openssl.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/openssl.c b/src/openssl.c index 92e63a6..6abcdda 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -204,10 +204,12 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, #if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR) #include +#include typedef struct { AES_KEY key; + EVP_CIPHER_CTX *aes_ctx; unsigned char ctr[AES_BLOCK_SIZE]; } aes_ctr_ctx; @@ -216,12 +218,35 @@ 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)); + const EVP_CIPHER *aes_cipher; (void) enc; if (c == NULL) return 0; - AES_set_encrypt_key(key, 8 * ctx->key_len, &c->key); + switch (ctx->key_len) { + case 16: + aes_cipher = EVP_aes_128_ecb(); + break; + case 24: + aes_cipher = EVP_aes_192_ecb(); + break; + case 32: + aes_cipher = EVP_aes_256_ecb(); + break; + default: + return 0; + } + c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX)); + if (c->aes_ctx == NULL) + return 0; + + if (EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) { + return 0; + } + + EVP_CIPHER_CTX_set_padding(c->aes_ctx, 0); + memcpy(c->ctr, iv, AES_BLOCK_SIZE); EVP_CIPHER_CTX_set_app_data(ctx, c); @@ -236,11 +261,16 @@ aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx); unsigned char b1[AES_BLOCK_SIZE]; - size_t i; + size_t i = 0; + int outlen = 0; if (inl != 16) /* libssh2 only ever encrypt one block */ return 0; + if (c == NULL) { + return 0; + } + /* To encrypt a packet P=P1||P2||...||Pn (where P1, P2, ..., Pn are each blocks of length L), the encryptor first encrypts with @@ -248,7 +278,9 @@ aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, the ciphertext block C1. The counter X is then incremented */ - AES_encrypt(c->ctr, b1, &c->key); + if (EVP_EncryptUpdate(c->aes_ctx, b1, &outlen, c->ctr, AES_BLOCK_SIZE) != 1) { + return 0; + } for (i = 0; i < 16; i++) *out++ = *in++ ^ b1[i]; @@ -266,7 +298,18 @@ aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) /* cleanup ctx */ { - free(EVP_CIPHER_CTX_get_app_data(ctx)); + aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx); + + if (c == NULL) { + return 1; + } + + if (c->aes_ctx != NULL) { + free(c->aes_ctx); + } + + free(c); + return 1; }