aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/src/crypto.erl
diff options
context:
space:
mode:
authorPetr Gotthard <[email protected]>2016-07-30 10:51:47 -0700
committerPetr Gotthard <[email protected]>2016-07-30 10:51:47 -0700
commit1cdaf0a6fd8dbbf08fe88dd148424df4da683f48 (patch)
treed4adc04cde9958587a25311c8259315e8ff326d2 /lib/crypto/src/crypto.erl
parent9c97ca598a1858d7b43799dee03a5c129b81220a (diff)
downloadotp-1cdaf0a6fd8dbbf08fe88dd148424df4da683f48.tar.gz
otp-1cdaf0a6fd8dbbf08fe88dd148424df4da683f48.tar.bz2
otp-1cdaf0a6fd8dbbf08fe88dd148424df4da683f48.zip
crypto:cmac calculating the Cipher-based Message Authentication Code
The ERL-82 issue requests a way to calculate a CMAC in Erlang. The AES128 CMAC is standartized in RFC 4493 and used e.g. for message authentication in the LoRaWAN networks. The CMAC is implemented by OpenSSL since v1.0.1, but as @IngelaAndin stated in response to the ERL-82, the current crypto implementation does not include functions that call those OpenSSL cryptolib functions. This commit introduces a new function `crypto:cmac` that calls the corresponding OpenSSL functions and calculates the CMAC. Only the cmac_nif is implemented. The incremental functions (init, update, final) are not provided because the current OpenSSL does not allow custom memory allocators like `enif_alloc_resource`. The Erlang user guide states that at least OpenSSL 0.9.8 is required, so I added few #ifdefs so the code is compatible with all versions. However, the OpenSSL pages say that the pre-1.0.1 versions (0.9.8 and 1.0.0) are no longer maintained. Even the 1.0.1 will be retired by Dec 2016. Hence I believe that adding a 1.0.1-only function like CMAC should be OK.
Diffstat (limited to 'lib/crypto/src/crypto.erl')
-rw-r--r--lib/crypto/src/crypto.erl14
1 files changed, 14 insertions, 0 deletions
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 025d57e9c5..ba824eb9cd 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -27,6 +27,7 @@
-export([sign/4, verify/5]).
-export([generate_key/2, generate_key/3, compute_key/4]).
-export([hmac/3, hmac/4, hmac_init/2, hmac_update/2, hmac_final/1, hmac_final_n/2]).
+-export([cmac/3, cmac/4]).
-export([exor/2, strong_rand_bytes/1, mod_pow/3]).
-export([rand_uniform/2]).
-export([block_encrypt/3, block_decrypt/3, block_encrypt/4, block_decrypt/4]).
@@ -271,6 +272,14 @@ hmac_final(Context) ->
hmac_final_n(Context, HashLen) ->
notsup_to_error(hmac_final_nif(Context, HashLen)).
+-spec cmac(_, iodata(), iodata()) -> binary().
+-spec cmac(_, iodata(), iodata(), integer()) -> binary().
+
+cmac(Type, Key, Data) ->
+ notsup_to_error(cmac_nif(Type, Key, Data)).
+cmac(Type, Key, Data, MacSize) ->
+ erlang:binary_part(cmac(Type, Key, Data), 0, MacSize).
+
%% Ecrypt/decrypt %%%
-spec block_encrypt(des_cbc | des_cfb |
@@ -782,6 +791,10 @@ hmac_update_nif(_Context, _Data) -> ?nif_stub.
hmac_final_nif(_Context) -> ?nif_stub.
hmac_final_nif(_Context, _MacSize) -> ?nif_stub.
+%% CMAC
+
+cmac_nif(_Type, _Key, _Data) -> ?nif_stub.
+
%%
%% MD5_MAC
%%
@@ -1460,6 +1473,7 @@ mod_exp_nif(_Base,_Exp,_Mod,_bin_hdr) -> ?nif_stub.
-define(FUNC_LIST, [hash, hash_init, hash_update, hash_final,
hmac, hmac_init, hmac_update, hmac_final, hmac_final_n,
+ cmac,
%% deprecated
md4, md4_init, md4_update, md4_final,
md5, md5_init, md5_update, md5_final,