diff options
author | Yuki Ito <[email protected]> | 2016-03-25 17:55:17 +0900 |
---|---|---|
committer | Yuki Ito <[email protected]> | 2016-03-26 12:01:36 +0900 |
commit | f4f588683dce36c4470171cb6af74763778498ff (patch) | |
tree | 461c7d681d8b7d5d4045552c1dbfce989cd95b83 /lib | |
parent | ab418313123e98d5de15e2e71ac169afdad8d3f8 (diff) | |
download | otp-f4f588683dce36c4470171cb6af74763778498ff.tar.gz otp-f4f588683dce36c4470171cb6af74763778498ff.tar.bz2 otp-f4f588683dce36c4470171cb6af74763778498ff.zip |
crypto: Enable AES-GCM tag length to change
This commit enables AES-GCM encryption/decryption to change its tag
length between 1 to 16 bytes.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/crypto/c_src/crypto.c | 14 | ||||
-rw-r--r-- | lib/crypto/doc/src/crypto.xml | 2 | ||||
-rw-r--r-- | lib/crypto/src/crypto.erl | 7 |
3 files changed, 16 insertions, 7 deletions
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index d1f620d892..e77bbe184b 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -314,7 +314,7 @@ static ErlNifFunc nif_funcs[] = { {"rand_seed_nif", 1, rand_seed_nif}, - {"aes_gcm_encrypt", 4, aes_gcm_encrypt}, + {"aes_gcm_encrypt", 5, aes_gcm_encrypt}, {"aes_gcm_decrypt", 5, aes_gcm_decrypt}, {"chacha20_poly1305_encrypt", 4, chacha20_poly1305_encrypt}, @@ -1629,6 +1629,7 @@ static ERL_NIF_TERM aes_gcm_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM EVP_CIPHER_CTX ctx; const EVP_CIPHER *cipher = NULL; ErlNifBinary key, iv, aad, in; + unsigned int tag_len; unsigned char *outp, *tagp; ERL_NIF_TERM out, out_tag; int len; @@ -1637,7 +1638,8 @@ static ERL_NIF_TERM aes_gcm_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM || (key.size != 16 && key.size != 24 && key.size != 32) || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0 || !enif_inspect_iolist_as_binary(env, argv[2], &aad) - || !enif_inspect_iolist_as_binary(env, argv[3], &in)) { + || !enif_inspect_iolist_as_binary(env, argv[3], &in) + || !enif_get_uint(env, argv[4], &tag_len) || tag_len < 1 || tag_len > 16) { return enif_make_badarg(env); } @@ -1669,9 +1671,9 @@ static ERL_NIF_TERM aes_gcm_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM if (EVP_EncryptFinal_ex(&ctx, outp+len, &len) != 1) goto out_err; - tagp = enif_make_new_binary(env, EVP_GCM_TLS_TAG_LEN, &out_tag); + tagp = enif_make_new_binary(env, tag_len, &out_tag); - if (EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, EVP_GCM_TLS_TAG_LEN, tagp) != 1) + if (EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, tag_len, tagp) != 1) goto out_err; EVP_CIPHER_CTX_cleanup(&ctx); @@ -1704,7 +1706,7 @@ static ERL_NIF_TERM aes_gcm_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0 || !enif_inspect_iolist_as_binary(env, argv[2], &aad) || !enif_inspect_iolist_as_binary(env, argv[3], &in) - || !enif_inspect_iolist_as_binary(env, argv[4], &tag) || tag.size != EVP_GCM_TLS_TAG_LEN) { + || !enif_inspect_iolist_as_binary(env, argv[4], &tag)) { return enif_make_badarg(env); } @@ -1730,7 +1732,7 @@ static ERL_NIF_TERM aes_gcm_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM if (EVP_DecryptUpdate(&ctx, outp, &len, in.data, in.size) != 1) goto out_err; - if (EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag.data) != 1) + if (EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, tag.size, tag.data) != 1) goto out_err; if (EVP_DecryptFinal_ex(&ctx, outp+len, &len) != 1) goto out_err; diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index d3e827b3e6..9cb9587964 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -203,6 +203,7 @@ <func> <name>block_encrypt(Type, Key, Ivec, PlainText) -> CipherText</name> <name>block_encrypt(AeadType, Key, Ivec, {AAD, PlainText}) -> {CipherText, CipherTag}</name> + <name>block_encrypt(aes_gcm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag}</name> <fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary> <type> <v>Type = block_cipher() </v> @@ -210,6 +211,7 @@ <v>Key = block_key() </v> <v>PlainText = iodata() </v> <v>AAD = IVec = CipherText = CipherTag = binary()</v> + <v>TagLength = 1..16</v> </type> <desc> <p>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher. diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 3e24ff2b0a..a9dbca3caf 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -302,6 +302,8 @@ block_encrypt(aes_ige256, Key, Ivec, Data) -> aes_ige_crypt_nif(Key, Ivec, Data, true); block_encrypt(aes_gcm, Key, Ivec, {AAD, Data}) -> aes_gcm_encrypt(Key, Ivec, AAD, Data); +block_encrypt(aes_gcm, Key, Ivec, {AAD, Data, TagLength}) -> + aes_gcm_encrypt(Key, Ivec, AAD, Data, TagLength); block_encrypt(chacha20_poly1305, Key, Ivec, {AAD, Data}) -> chacha20_poly1305_encrypt(Key, Ivec, AAD, Data). @@ -917,7 +919,10 @@ aes_cfb_128_decrypt(Key, IVec, Data) -> %% %% AES - in Galois/Counter Mode (GCM) %% -aes_gcm_encrypt(_Key, _Ivec, _AAD, _In) -> ?nif_stub. +%% The default tag length is EVP_GCM_TLS_TAG_LEN(16), +aes_gcm_encrypt(Key, Ivec, AAD, In) -> + aes_gcm_encrypt(Key, Ivec, AAD, In, 16). +aes_gcm_encrypt(_Key, _Ivec, _AAD, _In, _TagLength) -> ?nif_stub. aes_gcm_decrypt(_Key, _Ivec, _AAD, _In, _Tag) -> ?nif_stub. %% |