From a77aaf91b9695d704607bf7c09b0ec515d457871 Mon Sep 17 00:00:00 2001 From: Alex Wilson Date: Thu, 9 Oct 2014 21:39:29 +1000 Subject: crypto: use EVP for AES-CBC This enables the use of hardware acceleration for AES crypto on newer Intel CPUs (AES-NI), among other platforms. Cherry-pick from 425a34001fdd --- lib/crypto/c_src/crypto.c | 55 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 42fb172953..b4fd37b5eb 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -2058,11 +2058,12 @@ done: static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Key, IVec, Data, IsEncrypt) */ ErlNifBinary key_bin, ivec_bin, data_bin; - AES_KEY aes_key; unsigned char ivec[16]; - int i; + int enc, i = 0, outlen = 0; + EVP_CIPHER_CTX *ctx = NULL; + const EVP_CIPHER *cipher = NULL; unsigned char* ret_ptr; - ERL_NIF_TERM ret; + ERL_NIF_TERM ret; if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin) || (key_bin.size != 16 && key_bin.size != 32) @@ -2074,20 +2075,44 @@ static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a return enif_make_badarg(env); } - if (argv[3] == atom_true) { - i = AES_ENCRYPT; - AES_set_encrypt_key(key_bin.data, key_bin.size*8, &aes_key); - } - else { - i = AES_DECRYPT; - AES_set_decrypt_key(key_bin.data, key_bin.size*8, &aes_key); - } + if (argv[3] == atom_true) + enc = 1; + else + enc = 0; + + if (!(ctx = EVP_CIPHER_CTX_new())) + return enif_make_badarg(env); + + if (key_bin.size == 16) + cipher = EVP_aes_128_cbc(); + else if (key_bin.size == 32) + cipher = EVP_aes_256_cbc(); + + memcpy(ivec, ivec_bin.data, 16); /* writeable copy */ + + /* openssl docs say we need to leave at least 3 blocks available + at the end of the buffer for EVP calls. let's be safe */ + ret_ptr = enif_make_new_binary(env, data_bin.size + 16*3, &ret); + + if (EVP_CipherInit_ex(ctx, cipher, NULL, key_bin.data, ivec, enc) != 1) + return enif_make_badarg(env); + + /* disable padding, we only handle whole blocks */ + EVP_CIPHER_CTX_set_padding(ctx, 0); + + if (EVP_CipherUpdate(ctx, ret_ptr, &i, data_bin.data, data_bin.size) != 1) + return enif_make_badarg(env); + outlen += i; + if (EVP_CipherFinal_ex(ctx, ret_ptr + outlen, &i) != 1) + return enif_make_badarg(env); + outlen += i; + + EVP_CIPHER_CTX_free(ctx); - ret_ptr = enif_make_new_binary(env, data_bin.size, &ret); - memcpy(ivec, ivec_bin.data, 16); /* writable copy */ - AES_cbc_encrypt(data_bin.data, ret_ptr, data_bin.size, &aes_key, ivec, i); CONSUME_REDS(env,data_bin); - return ret; + + /* the garbage collector is going to love this */ + return enif_make_sub_binary(env, ret, 0, outlen); } static ERL_NIF_TERM do_exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -- cgit v1.2.3 From 8055ad8a5b6ce0c1e9c1c9c7eafccef179415bb3 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 9 Apr 2015 18:25:09 +0200 Subject: crypto: Fix undefined symbol EVP_CIPHER_CTX_new Use a stack allocated context and EVP_CIPHER_CTX_init/cleanup instead of dynamic EVP_CIPHER_CTX_new/free that does not exist in older 0.9.8 versions. Cherry-pick from b23f1ff1f79 --- lib/crypto/c_src/crypto.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index b4fd37b5eb..f9ded34670 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -2060,7 +2060,7 @@ static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a ErlNifBinary key_bin, ivec_bin, data_bin; unsigned char ivec[16]; int enc, i = 0, outlen = 0; - EVP_CIPHER_CTX *ctx = NULL; + EVP_CIPHER_CTX ctx; const EVP_CIPHER *cipher = NULL; unsigned char* ret_ptr; ERL_NIF_TERM ret; @@ -2080,8 +2080,7 @@ static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a else enc = 0; - if (!(ctx = EVP_CIPHER_CTX_new())) - return enif_make_badarg(env); + EVP_CIPHER_CTX_init(&ctx); if (key_bin.size == 16) cipher = EVP_aes_128_cbc(); @@ -2094,20 +2093,20 @@ static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a at the end of the buffer for EVP calls. let's be safe */ ret_ptr = enif_make_new_binary(env, data_bin.size + 16*3, &ret); - if (EVP_CipherInit_ex(ctx, cipher, NULL, key_bin.data, ivec, enc) != 1) + if (EVP_CipherInit_ex(&ctx, cipher, NULL, key_bin.data, ivec, enc) != 1) return enif_make_badarg(env); /* disable padding, we only handle whole blocks */ - EVP_CIPHER_CTX_set_padding(ctx, 0); + EVP_CIPHER_CTX_set_padding(&ctx, 0); - if (EVP_CipherUpdate(ctx, ret_ptr, &i, data_bin.data, data_bin.size) != 1) + if (EVP_CipherUpdate(&ctx, ret_ptr, &i, data_bin.data, data_bin.size) != 1) return enif_make_badarg(env); outlen += i; - if (EVP_CipherFinal_ex(ctx, ret_ptr + outlen, &i) != 1) + if (EVP_CipherFinal_ex(&ctx, ret_ptr + outlen, &i) != 1) return enif_make_badarg(env); outlen += i; - EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_CTX_cleanup(&ctx); CONSUME_REDS(env,data_bin); -- cgit v1.2.3 From e7f96c4bc2d38feaab718bd61bcfb3ddc956dd25 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 26 Feb 2016 18:07:18 +0100 Subject: Prepare release --- lib/crypto/doc/src/notes.xml | 19 +++++++++++++++++++ lib/crypto/vsn.mk | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index 7408907ebd..e82965a117 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -30,6 +30,25 @@

This document describes the changes made to the Crypto application.

+
Crypto 3.2.0.1 + +
Improvements and New Features + + +

+ Use EVP interface for AES-CBC encryption. This enables + OpenSSL 1.0.1 the use of hardware acceleration on newer + Intel CPUs (AES-NI), among other platforms.

+

+ This is a backport from OTP 18.0 to R16B03.

+

+ Own Id: OTP-13384

+
+
+
+ +
+
Crypto 3.2
Fixed Bugs and Malfunctions diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index 98c071cf87..d49e833f89 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 3.2 +CRYPTO_VSN = 3.2.0.1 -- cgit v1.2.3