From 25cd2b2fb71fd6197b32c18d1f416a80f3b76f67 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Tue, 16 Mar 2021 17:04:01 +0100 Subject: [PATCH] Add Blake2b and Blake2s hash support for crypto backend. We support most recent crypto algorithms, so this is only addition of the Blake hash family. Kernel and gcrypt crypto backend supports all variants, OpenSSL only Blake2b-512 and Blake2s-256. There is no useable support for NSS and Nettle yet. Crypto backend supports kernel notation e.g. "blake2b-512" that is translated to the library backend names. --- lib/crypto_backend/crypto_gcrypt.c | 30 +++++++++++++++++++- lib/crypto_backend/crypto_kernel.c | 8 ++++++ lib/crypto_backend/crypto_openssl.c | 38 ++++++++++++++++++++++--- tests/crypto-vectors.c | 44 ++++++++++++++++++++++++++++- 4 files changed, 114 insertions(+), 6 deletions(-) diff --git a/lib/crypto_backend/crypto_gcrypt.c b/lib/crypto_backend/crypto_gcrypt.c index 0388bacf..1f6fd35a 100644 --- a/lib/crypto_backend/crypto_gcrypt.c +++ b/lib/crypto_backend/crypto_gcrypt.c @@ -51,6 +51,11 @@ struct crypt_cipher { } u; }; +struct hash_alg { + const char *name; + const char *gcrypt_name; +}; + /* * Test for wrong Whirlpool variant, * Ref: https://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html @@ -150,10 +155,24 @@ uint32_t crypt_backend_flags(void) static const char *crypt_hash_compat_name(const char *name, unsigned int *flags) { const char *hash_name = name; + int i; + static struct hash_alg hash_algs[] = { + { "blake2b-160", "blake2b_160" }, + { "blake2b-256", "blake2b_256" }, + { "blake2b-384", "blake2b_384" }, + { "blake2b-512", "blake2b_512" }, + { "blake2s-128", "blake2s_128" }, + { "blake2s-160", "blake2s_160" }, + { "blake2s-224", "blake2s_224" }, + { "blake2s-256", "blake2s_256" }, + { NULL, NULL, }}; + + if (!name) + return NULL; /* "whirlpool_gcryptbug" is out shortcut to flawed whirlpool * in libgcrypt < 1.6.0 */ - if (name && !strcasecmp(name, "whirlpool_gcryptbug")) { + if (!strcasecmp(name, "whirlpool_gcryptbug")) { #if GCRYPT_VERSION_NUMBER >= 0x010601 if (flags) *flags |= GCRY_MD_FLAG_BUGEMU1; @@ -161,6 +180,15 @@ static const char *crypt_hash_compat_name(const char *name, unsigned int *flags) hash_name = "whirlpool"; } + i = 0; + while (hash_algs[i].name) { + if (!strcasecmp(name, hash_algs[i].name)) { + hash_name = hash_algs[i].gcrypt_name; + break; + } + i++; + } + return hash_name; } diff --git a/lib/crypto_backend/crypto_kernel.c b/lib/crypto_backend/crypto_kernel.c index e304e38f..18c9a3ef 100644 --- a/lib/crypto_backend/crypto_kernel.c +++ b/lib/crypto_backend/crypto_kernel.c @@ -61,6 +61,14 @@ static struct hash_alg hash_algs[] = { { "stribog256","streebog256", 32, 64 }, { "stribog512","streebog512", 64, 64 }, { "sm3", "sm3", 32, 64 }, + { "blake2b-160","blake2b-160",20, 128 }, + { "blake2b-256","blake2b-256",32, 128 }, + { "blake2b-384","blake2b-384",48, 128 }, + { "blake2b-512","blake2b-512",64, 128 }, + { "blake2s-128","blake2s-128",16, 64 }, + { "blake2s-160","blake2s-160",20, 64 }, + { "blake2s-224","blake2s-224",28, 64 }, + { "blake2s-256","blake2s-256",32, 64 }, { NULL, NULL, 0, 0 } }; diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c index 3b75cfe5..b453583b 100644 --- a/lib/crypto_backend/crypto_openssl.c +++ b/lib/crypto_backend/crypto_openssl.c @@ -63,6 +63,11 @@ struct crypt_cipher { } u; }; +struct hash_alg { + const char *name; + const char *openssl_name; +}; + /* * Compatible wrappers for OpenSSL < 1.1.0 and LibreSSL < 2.7.0 */ @@ -147,11 +152,36 @@ const char *crypt_backend_version(void) return openssl_backend_version(); } +static const char *crypt_hash_compat_name(const char *name) +{ + const char *hash_name = name; + int i; + static struct hash_alg hash_algs[] = { + { "blake2b-512", "blake2b512" }, + { "blake2s-256", "blake2s256" }, + { NULL, NULL, }}; + + if (!name) + return NULL; + + i = 0; + while (hash_algs[i].name) { + if (!strcasecmp(name, hash_algs[i].name)) { + hash_name = hash_algs[i].openssl_name; + break; + } + i++; + } + + return hash_name; +} + /* HASH */ int crypt_hash_size(const char *name) { - const EVP_MD *hash_id = EVP_get_digestbyname(name); + const EVP_MD *hash_id; + hash_id = EVP_get_digestbyname(crypt_hash_compat_name(name)); if (!hash_id) return -EINVAL; @@ -172,7 +202,7 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name) return -ENOMEM; } - h->hash_id = EVP_get_digestbyname(name); + h->hash_id = EVP_get_digestbyname(crypt_hash_compat_name(name)); if (!h->hash_id) { EVP_MD_CTX_free(h->md); free(h); @@ -257,7 +287,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, return -ENOMEM; } - h->hash_id = EVP_get_digestbyname(name); + h->hash_id = EVP_get_digestbyname(crypt_hash_compat_name(name)); if (!h->hash_id) { HMAC_CTX_free(h->md); free(h); @@ -334,7 +364,7 @@ int crypt_pbkdf(const char *kdf, const char *hash, return -EINVAL; if (!strcmp(kdf, "pbkdf2")) { - hash_id = EVP_get_digestbyname(hash); + hash_id = EVP_get_digestbyname(crypt_hash_compat_name(hash)); if (!hash_id) return -EINVAL; diff --git a/tests/crypto-vectors.c b/tests/crypto-vectors.c index 9a51c842..bc7b80a4 100644 --- a/tests/crypto-vectors.c +++ b/tests/crypto-vectors.c @@ -251,7 +251,7 @@ struct hash_test_vector { const char *name; unsigned int length; const char *out; - } out[6]; + } out[8]; }; static struct hash_test_vector hash_test_vectors[] = { @@ -270,6 +270,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\xc5\x30\x23\x21\x30\xd4\x07\xf8\x9a\xfe\xe0\x96\x49\x97\xf7\xa7" "\x3e\x83\xbe\x69\x8b\x28\x8f\xeb\xcf\x88\xe3\xe0\x3c\x4f\x07\x57" "\xea\x89\x64\xe5\x9b\x63\xd9\x37\x08\xb1\x38\xcc\x42\xa6\x6e\xb3" }, + { "blake2b-512",64,"\x78\x6a\x02\xf7\x42\x01\x59\x03\xc6\xc6\xfd\x85\x25\x52\xd2\x72" + "\x91\x2f\x47\x40\xe1\x58\x47\x61\x8a\x86\xe2\x17\xf7\x1f\x54\x19" + "\xd2\x5e\x10\x31\xaf\xee\x58\x53\x13\x89\x64\x44\x93\x4e\xb0\x4b" + "\x90\x3a\x68\x5b\x14\x48\xb7\x55\xd5\x6f\x70\x1a\xfe\x9b\xe2\xce" }, + { "blake2s-256",32,"\x69\x21\x7a\x30\x79\x90\x80\x94\xe1\x11\x21\xd0\x42\x35\x4a\x7c" + "\x1f\x55\xb6\x48\x2c\xa1\xa5\x1e\x1b\x25\x0d\xfd\x1e\xd0\xee\xf9" }, }},{ "a", 1, { { "crc32", 4, "\xe8\xb7\xbe\x43" }, @@ -285,6 +291,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\xf0\xdf\xf5\x94\x13\x14\x5e\x69\x73\xc4\x50\x01\xd0\x08\x7b\x42" "\xd1\x1b\xc6\x45\x41\x3a\xef\xf6\x3a\x42\x39\x1a\x39\x14\x5a\x59" "\x1a\x92\x20\x0d\x56\x01\x95\xe5\x3b\x47\x85\x84\xfd\xae\x23\x1a" }, + { "blake2b-512",64,"\x33\x3f\xcb\x4e\xe1\xaa\x7c\x11\x53\x55\xec\x66\xce\xac\x91\x7c" + "\x8b\xfd\x81\x5b\xf7\x58\x7d\x32\x5a\xec\x18\x64\xed\xd2\x4e\x34" + "\xd5\xab\xe2\xc6\xb1\xb5\xee\x3f\xac\xe6\x2f\xed\x78\xdb\xef\x80" + "\x2f\x2a\x85\xcb\x91\xd4\x55\xa8\xf5\x24\x9d\x33\x08\x53\xcb\x3c" }, + { "blake2s-256",32,"\x4a\x0d\x12\x98\x73\x40\x30\x37\xc2\xcd\x9b\x90\x48\x20\x36\x87" + "\xf6\x23\x3f\xb6\x73\x89\x56\xe0\x34\x9b\xd4\x32\x0f\xec\x3e\x90" }, }},{ "abc", 3, { { "crc32", 4, "\x35\x24\x41\xc2" }, @@ -300,6 +312,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\xf3\x04\x3e\x3a\x73\x1b\xce\x72\x1a\xe1\xb3\x03\xd9\x7e\x6d\x4c" "\x71\x81\xee\xbd\xb6\xc5\x7e\x27\x7d\x0e\x34\x95\x71\x14\xcb\xd6" "\xc7\x97\xfc\x9d\x95\xd8\xb5\x82\xd2\x25\x29\x20\x76\xd4\xee\xf5" }, + { "blake2b-512",64,"\xba\x80\xa5\x3f\x98\x1c\x4d\x0d\x6a\x27\x97\xb6\x9f\x12\xf6\xe9" + "\x4c\x21\x2f\x14\x68\x5a\xc4\xb7\x4b\x12\xbb\x6f\xdb\xff\xa2\xd1" + "\x7d\x87\xc5\x39\x2a\xab\x79\x2d\xc2\x52\xd5\xde\x45\x33\xcc\x95" + "\x18\xd3\x8a\xa8\xdb\xf1\x92\x5a\xb9\x23\x86\xed\xd4\x00\x99\x23" }, + { "blake2s-256",32,"\x50\x8c\x5e\x8c\x32\x7c\x14\xe2\xe1\xa7\x2b\xa3\x4e\xeb\x45\x2f" + "\x37\x45\x8b\x20\x9e\xd6\x3a\x29\x4d\x99\x9b\x4c\x86\x67\x59\x82" }, }},{ "abcdefghijklmnopqrstuvwxyz", 26, { { "crc32", 4, "\x4c\x27\x50\xbd" }, @@ -315,6 +333,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\x8d\x38\x63\x1e\xad\x42\x38\xf5\x44\x2e\xe1\x3b\x80\x54\xe4\x1b" "\x08\xbf\x2a\x92\x51\xc3\x0b\x6a\x0b\x8a\xae\x86\x17\x7a\xb4\xa6" "\xf6\x8f\x67\x3e\x72\x07\x86\x5d\x5d\x98\x19\xa3\xdb\xa4\xeb\x3b" }, + { "blake2b-512",64,"\xc6\x8e\xde\x14\x3e\x41\x6e\xb7\xb4\xaa\xae\x0d\x8e\x48\xe5\x5d" + "\xd5\x29\xea\xfe\xd1\x0b\x1d\xf1\xa6\x14\x16\x95\x3a\x2b\x0a\x56" + "\x66\xc7\x61\xe7\xd4\x12\xe6\x70\x9e\x31\xff\xe2\x21\xb7\xa7\xa7" + "\x39\x08\xcb\x95\xa4\xd1\x20\xb8\xb0\x90\xa8\x7d\x1f\xbe\xdb\x4c" }, + { "blake2s-256",32,"\xbd\xf8\x8e\xb1\xf8\x6a\x0c\xdf\x0e\x84\x0b\xa8\x8f\xa1\x18\x50" + "\x83\x69\xdf\x18\x6c\x73\x55\xb4\xb1\x6c\xf7\x9f\xa2\x71\x0a\x12" }, }},{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62, { { "crc32", 4, "\x1f\xc2\xe6\xd2" }, @@ -330,6 +354,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\x1d\xd7\xc2\x8c\xde\xc0\x66\xcc\x6a\xf4\x2e\x40\xf8\x2f\x3a\x1e" "\x08\xeb\xa2\x66\x29\x12\x9d\x8f\xb7\xcb\x57\x21\x1b\x92\x81\xa6" "\x55\x17\xcc\x87\x9d\x7b\x96\x21\x42\xc6\x5f\x5a\x7a\xf0\x14\x67" }, + { "blake2b-512",64,"\x99\x96\x48\x02\xe5\xc2\x5e\x70\x37\x22\x90\x5d\x3f\xb8\x00\x46" + "\xb6\xbc\xa6\x98\xca\x9e\x2c\xc7\xe4\x9b\x4f\xe1\xfa\x08\x7c\x2e" + "\xdf\x03\x12\xdf\xbb\x27\x5c\xf2\x50\xa1\xe5\x42\xfd\x5d\xc2\xed" + "\xd3\x13\xf9\xc4\x91\x12\x7c\x2e\x8c\x0c\x9b\x24\x16\x8e\x2d\x50" }, + { "blake2s-256",32,"\xc7\x54\x39\xea\x17\xe1\xde\x6f\xa4\x51\x0c\x33\x5d\xc3\xd3\xf3" + "\x43\xe6\xf9\xe1\xce\x27\x73\xe2\x5b\x41\x74\xf1\xdf\x8b\x11\x9b" }, }},{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, { { "crc32", 4, "\x17\x1a\x3f\x5f" }, @@ -345,6 +375,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\x02\x7f\x61\x36\x6a\x14\x07\x26\x2d\xc2\xa6\xa3\x45\xd9\xe2\x40" "\xc0\x17\xc1\x83\x3d\xb1\xe6\xdb\x6a\x46\xbd\x44\x4b\x0c\x69\x52" "\x0c\x85\x6e\x7c\x6e\x9c\x36\x6d\x15\x0a\x7d\xa3\xae\xb1\x60\xd1" }, + { "blake2b-512",64,"\x72\x85\xff\x3e\x8b\xd7\x68\xd6\x9b\xe6\x2b\x3b\xf1\x87\x65\xa3" + "\x25\x91\x7f\xa9\x74\x4a\xc2\xf5\x82\xa2\x08\x50\xbc\x2b\x11\x41" + "\xed\x1b\x3e\x45\x28\x59\x5a\xcc\x90\x77\x2b\xdf\x2d\x37\xdc\x8a" + "\x47\x13\x0b\x44\xf3\x3a\x02\xe8\x73\x0e\x5a\xd8\xe1\x66\xe8\x88" }, + { "blake2s-256",32,"\x6f\x4d\xf5\x11\x6a\x6f\x33\x2e\xda\xb1\xd9\xe1\x0e\xe8\x7d\xf6" + "\x55\x7b\xea\xb6\x25\x9d\x76\x63\xf3\xbc\xd5\x72\x2c\x13\xf1\x89" }, }},{ "message digest", 14, { { "crc32", 4, "\x20\x15\x9d\x7f" }, @@ -360,6 +396,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\x83\x8d\x00\x03\x22\x30\xf5\x3c\xe1\xf5\x70\x0c\x0f\xfb\x4d\x3b" "\x84\x21\x55\x76\x59\xef\x55\xc1\x06\xb4\xb5\x2a\xc5\xa4\xaa\xa6" "\x92\xed\x92\x00\x52\x83\x8f\x33\x62\xe8\x6d\xbd\x37\xa8\x90\x3e" }, + { "blake2b-512",64,"\x3c\x26\xce\x48\x7b\x1c\x0f\x06\x23\x63\xaf\xa3\xc6\x75\xeb\xdb" + "\xf5\xf4\xef\x9b\xdc\x02\x2c\xfb\xef\x91\xe3\x11\x1c\xdc\x28\x38" + "\x40\xd8\x33\x1f\xc3\x0a\x8a\x09\x06\xcf\xf4\xbc\xdb\xcd\x23\x0c" + "\x61\xaa\xec\x60\xfd\xfa\xd4\x57\xed\x96\xb7\x09\xa3\x82\x35\x9a" }, + { "blake2s-256",32,"\xfa\x10\xab\x77\x5a\xcf\x89\xb7\xd3\xc8\xa6\xe8\x23\xd5\x86\xf6" + "\xb6\x7b\xdb\xac\x4c\xe2\x07\xfe\x14\x5b\x7d\x3a\xc2\x5c\xd2\x8c" }, }}}; /*