From c106a56a415bcef201bca8c1f1454ab6fe9bdb46 Mon Sep 17 00:00:00 2001 From: Hans Svensson Date: Mon, 4 Feb 2019 10:47:25 +0100 Subject: Add hash function BLAKE2 to crypto:hash/hmac Adds two hash functions blake2b and blake2s (64 bit hash and 32 bit hash respectively). These are modern and standard hash functions used in blockchains and encrypted communication protocols (e.g. Noise - http://www.noiseprotocol.org/). The hash functions are available in OpenSSL since version 1.1.1. Also add test cases and mention in documentation. --- lib/crypto/c_src/algorithms.c | 9 ++++- lib/crypto/c_src/atoms.c | 9 +++++ lib/crypto/c_src/atoms.h | 4 ++ lib/crypto/c_src/digest.c | 14 +++++++ lib/crypto/c_src/openssl_config.h | 6 +++ lib/crypto/doc/src/crypto.xml | 4 ++ lib/crypto/src/crypto.erl | 7 ++-- lib/crypto/test/crypto_SUITE.erl | 77 ++++++++++++++++++++++++++++++++++++++- 8 files changed, 124 insertions(+), 6 deletions(-) diff --git a/lib/crypto/c_src/algorithms.c b/lib/crypto/c_src/algorithms.c index 6318c8ad5a..a5bf248ea0 100644 --- a/lib/crypto/c_src/algorithms.c +++ b/lib/crypto/c_src/algorithms.c @@ -21,7 +21,7 @@ #include "algorithms.h" static unsigned int algo_hash_cnt, algo_hash_fips_cnt; -static ERL_NIF_TERM algo_hash[12]; /* increase when extending the list */ +static ERL_NIF_TERM algo_hash[14]; /* increase when extending the list */ static unsigned int algo_pubkey_cnt, algo_pubkey_fips_cnt; static ERL_NIF_TERM algo_pubkey[12]; /* increase when extending the list */ static unsigned int algo_cipher_cnt, algo_cipher_fips_cnt; @@ -62,6 +62,11 @@ void init_algorithms_types(ErlNifEnv* env) #ifdef HAVE_SHA3_512 algo_hash[algo_hash_cnt++] = enif_make_atom(env, "sha3_512"); #endif +#ifdef HAVE_BLAKE2 + algo_hash[algo_hash_cnt++] = enif_make_atom(env, "blake2b"); + algo_hash[algo_hash_cnt++] = enif_make_atom(env, "blake2s"); +#endif + // Non-validated algorithms follow algo_hash_fips_cnt = algo_hash_cnt; algo_hash[algo_hash_cnt++] = enif_make_atom(env, "md4"); @@ -136,7 +141,7 @@ void init_algorithms_types(ErlNifEnv* env) #if defined(HAVE_CHACHA20) algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"chacha20"); #endif - + // Validated algorithms first algo_mac_cnt = 0; algo_mac[algo_mac_cnt++] = enif_make_atom(env,"hmac"); diff --git a/lib/crypto/c_src/atoms.c b/lib/crypto/c_src/atoms.c index 3a028b9a67..5f19327197 100644 --- a/lib/crypto/c_src/atoms.c +++ b/lib/crypto/c_src/atoms.c @@ -110,6 +110,11 @@ ERL_NIF_TERM atom_sha3_512; ERL_NIF_TERM atom_md5; ERL_NIF_TERM atom_ripemd160; +#ifdef HAVE_BLAKE2 +ERL_NIF_TERM atom_blake2b; +ERL_NIF_TERM atom_blake2s; +#endif + #ifdef HAS_ENGINE_SUPPORT ERL_NIF_TERM atom_bad_engine_method; ERL_NIF_TERM atom_bad_engine_id; @@ -239,6 +244,10 @@ int init_atoms(ErlNifEnv *env, const ERL_NIF_TERM fips_mode, const ERL_NIF_TERM atom_sha3_512 = enif_make_atom(env,"sha3_512"); atom_md5 = enif_make_atom(env,"md5"); atom_ripemd160 = enif_make_atom(env,"ripemd160"); +#ifdef HAVE_BLAKE2 + atom_blake2b = enif_make_atom(env,"blake2b"); + atom_blake2s = enif_make_atom(env,"blake2s"); +#endif #ifdef HAS_ENGINE_SUPPORT atom_bad_engine_method = enif_make_atom(env,"bad_engine_method"); diff --git a/lib/crypto/c_src/atoms.h b/lib/crypto/c_src/atoms.h index 9ddf0131ac..32f5ec856c 100644 --- a/lib/crypto/c_src/atoms.h +++ b/lib/crypto/c_src/atoms.h @@ -113,6 +113,10 @@ extern ERL_NIF_TERM atom_sha3_384; extern ERL_NIF_TERM atom_sha3_512; extern ERL_NIF_TERM atom_md5; extern ERL_NIF_TERM atom_ripemd160; +#ifdef HAVE_BLAKE2 +extern ERL_NIF_TERM atom_blake2b; +extern ERL_NIF_TERM atom_blake2s; +#endif #ifdef HAS_ENGINE_SUPPORT extern ERL_NIF_TERM atom_bad_engine_method; diff --git a/lib/crypto/c_src/digest.c b/lib/crypto/c_src/digest.c index 00ba65bf54..fec286c000 100644 --- a/lib/crypto/c_src/digest.c +++ b/lib/crypto/c_src/digest.c @@ -82,6 +82,20 @@ static struct digest_type_t digest_types[] = {NULL} #endif }, + {{"blake2b"}, +#ifdef HAVE_BLAKE2 + {&EVP_blake2b512} +#else + {NULL} +#endif + }, + {{"blake2s"}, +#ifdef HAVE_BLAKE2 + {&EVP_blake2s256} +#else + {NULL} +#endif + }, {{NULL}, {NULL}} }; diff --git a/lib/crypto/c_src/openssl_config.h b/lib/crypto/c_src/openssl_config.h index c0ce1a59fe..16bc59a865 100644 --- a/lib/crypto/c_src/openssl_config.h +++ b/lib/crypto/c_src/openssl_config.h @@ -158,6 +158,12 @@ # define HAVE_SHA3_512 # endif +// BLAKE2: +#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,1,1) \ + && !defined(OPENSSL_NO_BLAKE2) +# define HAVE_BLAKE2 +#endif + #if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION(0,9,8,'o') \ && !defined(OPENSSL_NO_EC) \ && !defined(OPENSSL_NO_ECDH) \ diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 3306fe3d16..86fc3416f4 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -44,6 +44,10 @@ SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions [FIPS PUB 202] + BLAKE2 + + BLAKE2 — fast secure hashing + MD5 The MD5 Message Digest Algorithm [RFC 1321] diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 987bc3fe0f..de8cfac9a2 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -287,6 +287,7 @@ -type sha1() :: sha . -type sha2() :: sha224 | sha256 | sha384 | sha512 . -type sha3() :: sha3_224 | sha3_256 | sha3_384 | sha3_512 . +-type blake2() :: blake2b | blake2s . -type compatibility_only_hash() :: md5 | md4 . @@ -329,11 +330,11 @@ stop() -> | {macs, Macs} | {curves, Curves} | {rsa_opts, RSAopts}, - Hashs :: [sha1() | sha2() | sha3() | ripemd160 | compatibility_only_hash()], + Hashs :: [sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash()], Ciphers :: [stream_cipher() | block_cipher_with_iv() | block_cipher_without_iv() | aead_cipher() - ], + ], PKs :: [rsa | dss | ecdsa | dh | ecdh | ec_gf2m], Macs :: [hmac | cmac | poly1305], Curves :: [ec_named_curve() | edwards_curve_dh() | edwards_curve_ed()], @@ -367,7 +368,7 @@ enable_fips_mode(_) -> ?nif_stub. %%% %%%================================================================ --define(HASH_HASH_ALGORITHM, sha1() | sha2() | sha3() | ripemd160 | compatibility_only_hash() ). +-define(HASH_HASH_ALGORITHM, sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash() ). -spec hash(Type, Data) -> Digest when Type :: ?HASH_HASH_ALGORITHM, Data :: iodata(), diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 003e0c58b1..c4323de83f 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -56,6 +56,8 @@ groups() -> {group, sha3_256}, {group, sha3_384}, {group, sha3_512}, + {group, blake2b}, + {group, blake2s}, {group, rsa}, {group, dss}, {group, ecdsa}, @@ -137,6 +139,8 @@ groups() -> {sha3_256, [], [hash, hmac]}, {sha3_384, [], [hash, hmac]}, {sha3_512, [], [hash, hmac]}, + {blake2b, [], [hash, hmac]}, + {blake2s, [], [hash, hmac]}, {rsa, [], [sign_verify, public_encrypt, private_encrypt, @@ -587,7 +591,7 @@ use_all_elliptic_curves(_Config) -> {C,E} end} || Curve <- Curves -- [ed25519, ed448, x25519, x448, ipsec3, ipsec4], - Hash <- Hashs -- [md4, md5, ripemd160, sha3_224, sha3_256, sha3_384, sha3_512] + Hash <- Hashs -- [md4, md5, ripemd160, sha3_224, sha3_256, sha3_384, sha3_512, blake2b, blake2s] ], Fails = lists:filter(fun({_,true}) -> false; @@ -1438,6 +1442,12 @@ group_config(sha3_384 = Type, Config) -> group_config(sha3_512 = Type, Config) -> {Msgs,Digests} = sha3_test_vectors(Type), [{hash, {Type, Msgs, Digests}}, {hmac, hmac_sha3(Type)} | Config]; +group_config(blake2b = Type, Config) -> + {Msgs, Digests} = blake2_test_vectors(Type), + [{hash, {Type, Msgs, Digests}}, {hmac, blake2_hmac(Type)} | Config]; +group_config(blake2s = Type, Config) -> + {Msgs, Digests} = blake2_test_vectors(Type), + [{hash, {Type, Msgs, Digests}}, {hmac, blake2_hmac(Type)} | Config]; group_config(rsa, Config) -> Msg = rsa_plain(), Public = rsa_public(), @@ -1704,6 +1714,71 @@ rfc_1321_md5_digests() -> hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f"), hexstr2bin("57edf4a22be3c955ac49da2e2107b67a")]. + +%% BLAKE2 re-use SHA3 test vectors. +blake2_test_vectors(blake2b) -> + {sha3_msgs(), + [ <<186,128,165,63,152,28,77,13,106,39,151,182,159,18,246,233,76,33,47,20,104,90,196,183,75,18,187,111,219,255,162,209,125,135,197,57,42,171,121,45,194,82,213,222,69,51,204,149,24,211,138,168,219,241,146,90,185,35,134,237,212,0,153,35>> + , <<120,106,2,247,66,1,89,3,198,198,253,133,37,82,210,114,145,47,71,64,225,88,71,97,138,134,226,23,247,31,84,25,210,94,16,49,175,238,88,83,19,137,100,68,147,78,176,75,144,58,104,91,20,72,183,85,213,111,112,26,254,155,226,206>> + , <<114,133,255,62,139,215,104,214,155,230,43,59,241,135,101,163,37,145,127,169,116,74,194,245,130,162,8,80,188,43,17,65,237,27,62,69,40,89,90,204,144,119,43,223,45,55,220,138,71,19,11,68,243,58,2,232,115,14,90,216,225,102,232,136>> + , <<206,116,26,197,147,15,227,70,129,17,117,197,34,123,183,191,205,71,244,38,18,250,228,108,8,9,81,79,158,14,58,17,238,23,115,40,113,71,205,234,238,223,245,7,9,170,113,99,65,254,101,36,15,74,214,119,125,107,250,249,114,110,94,82>> + , <<152,251,62,251,114,6,253,25,235,246,155,111,49,44,247,182,78,59,148,219,225,161,113,7,145,57,117,167,147,241,119,225,208,119,96,157,127,186,54,60,187,160,13,5,247,170,78,79,168,113,93,100,40,16,76,10,117,100,59,15,243,253,62,175>> + ]}; +blake2_test_vectors(blake2s) -> + {sha3_msgs(), + [ <<80,140,94,140,50,124,20,226,225,167,43,163,78,235,69,47,55,69,139,32,158,214,58,41,77,153,155,76,134,103,89,130>> + , <<105,33,122,48,121,144,128,148,225,17,33,208,66,53,74,124,31,85,182,72,44,161,165,30,27,37,13,253,30,208,238,249>> + , <<111,77,245,17,106,111,51,46,218,177,217,225,14,232,125,246,85,123,234,182,37,157,118,99,243,188,213,114,44,19,241,137>> + , <<53,141,210,237,7,128,212,5,78,118,203,111,58,91,206,40,65,232,226,245,71,67,29,77,9,219,33,182,109,148,31,199>> + , <<190,192,192,230,205,229,182,122,203,115,184,31,121,166,122,64,121,174,28,96,218,201,210,102,26,241,142,159,139,80,223,165>> + ]}. + +blake2_hmac(Type) -> + {Ks, Ds, Hs} = lists:unzip3( + [ {hexstr2bin(K), hexstr2bin(D), H} + || {{K, D}, H} <- lists:zip(blake2_hmac_key_data(), blake2_hmac_hmac(Type)) ]), + {Type, Ks, Ds, Hs}. + +blake2_hmac_key_data() -> + [ {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b 0b0b0b0b", + "4869205468657265"} + , {"4a656665", + "7768617420646f2079612077616e7420 666f72206e6f7468696e673f"} + , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa", + "dddddddddddddddddddddddddddddddd dddddddddddddddddddddddddddddddd dddddddddddddddddddddddddddddddd dddd"} + , {"0102030405060708090a0b0c0d0e0f10 111213141516171819", + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcd"} + , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa", + "54657374205573696e67204c61726765 72205468616e20426c6f636b2d53697a 65204b6579202d2048617368204b6579 204669727374"} + , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa", + "54657374205573696e67204c61726765 72205468616e20426c6f636b2d53697a 65204b6579202d2048617368204b6579 204669727374"} + , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa", + "54686973206973206120746573742075 73696e672061206c6172676572207468 616e20626c6f636b2d73697a65206b65 7920616e642061206c61726765722074 68616e20626c6f636b2d73697a652064 6174612e20546865206b6579206e6565 647320746f2062652068617368656420 6265666f7265206265696e6720757365 642062792074686520484d414320616c 676f726974686d2e"} + , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa", + "54686973206973206120746573742075 73696e672061206c6172676572207468 616e20626c6f636b2d73697a65206b65 7920616e642061206c61726765722074 68616e20626c6f636b2d73697a652064 6174612e20546865206b6579206e6565 647320746f2062652068617368656420 6265666f7265206265696e6720757365 642062792074686520484d414320616c 676f726974686d2e"} + ]. + +blake2_hmac_hmac(blake2b) -> + [ <<53,138,106,24,73,36,137,79,195,75,238,86,128,238,223,87,216,74,55,187,56,131,47,40,142,59,39,220,99,169,140,200,201,30,118,218,71,107,80,139,198,178,212,8,162,72,133,116,82,144,110,74,32,180,140,107,75,85,210,223,15,225,221,36>> + , <<111,248,132,248,221,194,166,88,107,60,152,164,205,110,189,241,78,193,2,4,182,113,0,115,235,88,101,173,227,122,38,67,184,128,124,19,53,209,7,236,219,159,254,174,182,130,140,70,37,186,23,44,102,55,158,252,210,34,194,222,17,114,122,180>> + , <<244,59,198,44,122,153,53,60,59,44,96,232,239,36,251,189,66,233,84,120,102,220,156,91,228,237,198,244,167,212,188,10,198,32,194,198,0,52,208,64,240,219,175,134,249,233,205,120,145,160,149,89,94,237,85,226,169,150,33,95,12,21,192,24>> + , <<229,219,182,222,47,238,66,161,202,160,110,78,123,132,206,64,143,250,92,74,157,226,99,46,202,118,156,222,136,117,1,76,114,208,114,15,234,245,63,118,230,161,128,53,127,82,141,123,244,132,250,58,20,232,204,31,15,59,173,167,23,180,52,145>> + , <<165,75,41,67,178,162,2,39,212,28,164,108,9,69,175,9,188,31,174,251,47,73,137,76,35,174,188,85,127,183,156,72,137,220,167,68,8,220,134,80,134,102,122,237,238,74,49,133,197,58,73,200,11,129,76,76,88,19,234,12,139,56,168,248>> + , <<180,214,140,139,182,82,151,170,52,132,168,110,29,51,183,138,70,159,33,234,170,158,212,218,159,236,145,218,71,23,34,61,44,15,163,134,170,47,209,241,255,207,89,23,178,103,84,96,53,237,48,238,164,178,19,162,133,148,211,211,169,179,140,170>> + , <<171,52,121,128,166,75,94,130,93,209,14,125,50,253,67,160,26,142,109,234,38,122,185,173,125,145,53,36,82,102,24,146,83,17,175,188,176,196,149,25,203,235,221,112,149,64,168,215,37,251,145,26,194,174,233,178,163,170,67,215,150,18,51,147>> + , <<97,220,242,140,166,12,169,92,130,89,147,39,171,215,169,161,152,111,242,219,211,199,73,69,198,227,35,186,203,76,159,26,94,103,82,93,20,186,141,98,36,177,98,229,102,23,21,37,83,3,69,169,178,86,8,178,125,251,163,180,146,115,213,6>> + ]; +blake2_hmac_hmac(blake2s) -> + [ <<101,168,183,197,204,145,54,212,36,232,44,55,226,112,126,116,233,19,192,101,91,153,199,95,64,237,243,135,69,58,50,96>> + , <<144,182,40,30,47,48,56,201,5,106,240,180,167,231,99,202,230,254,93,158,180,56,106,14,201,82,55,137,12,16,79,240>> + , <<252,196,245,149,41,80,46,52,195,216,218,63,253,171,130,150,106,44,182,55,255,94,155,215,1,19,92,46,148,105,231,144>> + , <<70,68,52,220,190,206,9,93,69,106,29,98,214,236,86,248,152,230,37,163,158,92,82,189,249,77,175,17,27,173,131,170>> + , <<210,61,121,57,79,83,213,54,160,150,230,81,68,71,238,170,187,5,222,208,27,227,44,25,55,218,106,143,113,3,188,78>> + , <<92,76,83,46,110,69,89,83,133,78,21,16,149,38,110,224,127,213,88,129,190,223,139,57,8,217,95,13,190,54,159,234>> + , <<203,96,246,167,145,241,64,191,138,162,229,31,243,88,205,178,204,92,3,51,4,91,127,183,122,186,122,179,176,207,178,55>> + , <<190,53,233,217,99,171,215,108,1,184,171,181,22,36,240,209,16,96,16,92,213,22,16,58,114,241,117,214,211,189,30,202>> + ]. + %%% https://www.di-mgt.com.au/sha_testvectors.html sha3_msgs() -> ["abc", -- cgit v1.2.3 From 9aa84d39edef976250774811ac9a6e6895041c14 Mon Sep 17 00:00:00 2001 From: Hans Svensson Date: Tue, 5 Feb 2019 19:24:28 +0100 Subject: Add blake2 datatype to crypto.xml --- lib/crypto/doc/src/crypto.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 86fc3416f4..e0794a080e 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -239,6 +239,7 @@ + -- cgit v1.2.3