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" }, }}}; /*