diff options
author | Erlang/OTP <[email protected]> | 2017-03-31 12:58:35 +0200 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2017-03-31 12:58:35 +0200 |
commit | b209cea8bd69aa71aef919e794988d3367f36891 (patch) | |
tree | f0be11376b8e97e4552a1d46790e9aa58ded24d3 /lib/crypto/c_src/crypto.c | |
parent | e29f48616d61b9ef53d79280d5a5f46bd9765d9a (diff) | |
parent | 25b8f8119f5b64b5c07cb5ed4978f7df64d4799f (diff) | |
download | otp-b209cea8bd69aa71aef919e794988d3367f36891.tar.gz otp-b209cea8bd69aa71aef919e794988d3367f36891.tar.bz2 otp-b209cea8bd69aa71aef919e794988d3367f36891.zip |
Merge branch 'kellymclaughlin/crypto/aes_cfb_128/PR-1393/OTP-14313' into maint-19
* kellymclaughlin/crypto/aes_cfb_128/PR-1393/OTP-14313:
Fix bug with AES CFB 128
Demonstrate the bug with AES CFB 128 encryption
Diffstat (limited to 'lib/crypto/c_src/crypto.c')
-rw-r--r-- | lib/crypto/c_src/crypto.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 2c8fb445dd..d4264335b6 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -231,6 +231,7 @@ static ERL_NIF_TERM hmac_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM static ERL_NIF_TERM hmac_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM block_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM aes_cfb_8_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM aes_cfb_128_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM aes_ctr_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); @@ -301,6 +302,7 @@ static ErlNifFunc nif_funcs[] = { {"hmac_final_nif", 2, hmac_final_nif}, {"block_crypt_nif", 5, block_crypt_nif}, {"block_crypt_nif", 4, block_crypt_nif}, + {"aes_cfb_128_crypt_nif", 4, aes_cfb_128_crypt_nif}, {"aes_ige_crypt_nif", 4, aes_ige_crypt_nif}, {"aes_ctr_encrypt", 3, aes_ctr_encrypt}, @@ -1403,13 +1405,20 @@ static ERL_NIF_TERM block_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM return enif_raise_exception(env, atom_notsup); } - if ((argv[0] == atom_aes_cfb8 || argv[0] == atom_aes_cfb128) + if (argv[0] == atom_aes_cfb8 && (key.size == 24 || key.size == 32)) { /* Why do EVP_CIPHER_CTX_set_key_length() fail on these key sizes? * Fall back on low level API */ return aes_cfb_8_crypt(env, argc-1, argv+1); } + else if (argv[0] == atom_aes_cfb128 + && (key.size == 24 || key.size == 32)) { + /* Why do EVP_CIPHER_CTX_set_key_length() fail on these key sizes? + * Fall back on low level API + */ + return aes_cfb_128_crypt_nif(env, argc-1, argv+1); + } ivec_size = EVP_CIPHER_iv_length(cipher); @@ -1483,6 +1492,31 @@ static ERL_NIF_TERM aes_cfb_8_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM return ret; } +static ERL_NIF_TERM aes_cfb_128_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, IVec, Data, IsEncrypt) */ + ErlNifBinary key, ivec, text; + AES_KEY aes_key; + unsigned char ivec_clone[16]; /* writable copy */ + int new_ivlen = 0; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) + || !(key.size == 16 || key.size == 24 || key.size == 32) + || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16 + || !enif_inspect_iolist_as_binary(env, argv[2], &text)) { + return enif_make_badarg(env); + } + + memcpy(ivec_clone, ivec.data, 16); + AES_set_encrypt_key(key.data, key.size * 8, &aes_key); + AES_cfb128_encrypt((unsigned char *) text.data, + enif_make_new_binary(env, text.size, &ret), + text.size, &aes_key, ivec_clone, &new_ivlen, + (argv[3] != atom_true)); + CONSUME_REDS(env,text); + return ret; +} + static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Key, IVec, Data, IsEncrypt) */ #ifdef HAVE_AES_IGE |