diff options
Diffstat (limited to 'lib/crypto')
-rw-r--r-- | lib/crypto/c_src/crypto.c | 59 | ||||
-rw-r--r-- | lib/crypto/doc/src/notes.xml | 35 | ||||
-rw-r--r-- | lib/crypto/test/crypto_SUITE.erl | 23 | ||||
-rw-r--r-- | lib/crypto/vsn.mk | 2 |
4 files changed, 95 insertions, 24 deletions
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index c28ff8136c..f9ded34670 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; + 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,43 @@ 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; + + EVP_CIPHER_CTX_init(&ctx); + + 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_cleanup(&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[]) @@ -2658,8 +2682,9 @@ static ERL_NIF_TERM srp_user_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_ <premaster secret> = (B - (k * g^x)) ^ (a + (u * x)) % N */ BIGNUM *bn_exponent = NULL, *bn_a = NULL; - BIGNUM *bn_u, *bn_multiplier, *bn_exp2, *bn_base, - *bn_prime, *bn_generator, *bn_B, *bn_result; + BIGNUM *bn_u = NULL, *bn_multiplier = NULL, *bn_exp2, + *bn_base, *bn_prime = NULL, *bn_generator = NULL, + *bn_B = NULL, *bn_result; BN_CTX *bn_ctx; unsigned char* ptr; unsigned dlen; diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index 97558ef0e7..e82965a117 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -30,6 +30,41 @@ </header> <p>This document describes the changes made to the Crypto application.</p> +<section><title>Crypto 3.2.0.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + 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.</p> + <p> + This is a backport from OTP 18.0 to R16B03.</p> + <p> + Own Id: OTP-13384</p> + </item> + </list> + </section> + +</section> + +<section><title>Crypto 3.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix uninitialized pointers in crypto (Thanks to Anthony + Ramine)</p> + <p> + Own Id: OTP-11510</p> + </item> + </list> + </section> + +</section> + <section><title>Crypto 3.1</title> <section><title>Improvements and New Features</title> diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 58aaa78d28..ddc9607e29 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -143,7 +143,8 @@ app(Config) when is_list(Config) -> hash() -> [{doc, "Test all different hash functions"}]. hash(Config) when is_list(Config) -> - {Type, Msgs, Digests} = proplists:get_value(hash, Config), + {Type, MsgsLE, Digests} = proplists:get_value(hash, Config), + Msgs = lazy_eval(MsgsLE), [LongMsg | _] = lists:reverse(Msgs), Inc = iolistify(LongMsg), [IncrDigest | _] = lists:reverse(Digests), @@ -154,7 +155,8 @@ hash(Config) when is_list(Config) -> hmac() -> [{doc, "Test all different hmac functions"}]. hmac(Config) when is_list(Config) -> - {Type, Keys, Data, Expected} = proplists:get_value(hmac, Config), + {Type, Keys, DataLE, Expected} = proplists:get_value(hmac, Config), + Data = lazy_eval(DataLE), hmac(Type, Keys, Data, Expected), hmac(Type, lists:map(fun iolistify/1, Keys), lists:map(fun iolistify/1, Data), Expected), hmac_increment(Type). @@ -171,7 +173,8 @@ block(Config) when is_list(Config) -> stream() -> [{doc, "Test stream ciphers"}]. stream(Config) when is_list(Config) -> - Streams = proplists:get_value(stream, Config), + Streams = lazy_eval(proplists:get_value(stream, Config)), + lists:foreach(fun stream_cipher/1, Streams), lists:foreach(fun stream_cipher/1, stream_iolistify(Streams)), lists:foreach(fun stream_cipher_incment/1, stream_iolistify(Streams)). @@ -795,7 +798,15 @@ rfc_4634_sha512_digests() -> hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA17299AEADB6889018501D289E4900F7E4331B99DEC4B5433AC7D329EEB6DD26545E96E55B874BE909")]. long_msg() -> - lists:duplicate(1000000, $a). + fun() -> lists:duplicate(1000000, $a) end. + +%% Building huge terms (like long_msg/0) in init_per_group seems to cause +%% test_server crash with 'no_answer_from_tc_supervisor' sometimes on some +%% machines. Therefore lazy evaluation when test case has started. +lazy_eval(F) when is_function(F) -> F(); +lazy_eval(Lst) when is_list(Lst) -> lists:map(fun lazy_eval/1, Lst); +lazy_eval(Tpl) when is_tuple(Tpl) -> list_to_tuple(lists:map(fun lazy_eval/1, tuple_to_list(Tpl))); +lazy_eval(Term) -> Term. long_sha_digest() -> hexstr2bin("34aa973c" "d4c4daa4" "f61eeb2b" "dbad2731" "6534016f"). @@ -1245,7 +1256,7 @@ blowfish_ofb64() -> rc4() -> [{rc4, <<"apaapa">>, <<"Yo baby yo">>}, {rc4, <<"apaapa">>, list_to_binary(lists:seq(0, 255))}, - {rc4, <<"apaapa">>, lists:duplicate(1000000, $a)} + {rc4, <<"apaapa">>, long_msg()} ]. aes_ctr() -> @@ -1293,7 +1304,7 @@ aes_ctr() -> {aes_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), - lists:duplicate(1000000, $a)} + long_msg()} ]. rsa_plain() -> diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index 3bd2f9b4bf..d49e833f89 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 3.1 +CRYPTO_VSN = 3.2.0.1 |