Skip to content

Commit

Permalink
hmac: use EVP_PKEY_new_raw_private_key() if available
Browse files Browse the repository at this point in the history
Current OpenSSL 3.0.x release has a regression with zero-length MAC
keys. While this issue should be fixed in a future release of OpenSSL,
we can use EVP_PKEY_new_raw_private_key() in place of the problematic
EVP_PKEY_new_mac_key() to avoid the issue. OpenSSL 3.0's man page
recommends using it regardless:

> EVP_PKEY_new_mac_key() works in the same way as
> EVP_PKEY_new_raw_private_key().  New applications should use
> EVP_PKEY_new_raw_private_key() instead.

Fixes #369 (comment)
  • Loading branch information
rhenium committed Sep 2, 2022
1 parent d52549a commit 4293f18
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 0 deletions.
1 change: 1 addition & 0 deletions ext/openssl/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ def find_openssl_library

# added in 1.1.1
have_func("EVP_PKEY_check")
have_func("EVP_PKEY_new_raw_private_key")

# added in 3.0.0
have_func("SSL_set0_tmp_dh_pkey")
Expand Down
8 changes: 8 additions & 0 deletions ext/openssl/ossl_hmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,19 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)

GetHMAC(self, ctx);
StringValue(key);
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
(unsigned char *)RSTRING_PTR(key),
RSTRING_LENINT(key));
if (!pkey)
ossl_raise(eHMACError, "EVP_PKEY_new_raw_private_key");
#else
pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
(unsigned char *)RSTRING_PTR(key),
RSTRING_LENINT(key));
if (!pkey)
ossl_raise(eHMACError, "EVP_PKEY_new_mac_key");
#endif
if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest),
NULL, pkey) != 1) {
EVP_PKEY_free(pkey);
Expand Down
8 changes: 8 additions & 0 deletions test/openssl/test_hmac.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ def test_singleton_methods
b64digest = OpenSSL::HMAC.base64digest("MD5", key, "Hi There")
assert_equal "kpRyejY4uxwT9I74FYv8nQ==", b64digest
end

def test_zero_length_key
# Empty string as the key
hexdigest = OpenSSL::HMAC.hexdigest("SHA256", "\0"*32, "test")
assert_equal "43b0cef99265f9e34c10ea9d3501926d27b39f57c6d674561d8ba236e7a819fb", hexdigest
hexdigest = OpenSSL::HMAC.hexdigest("SHA256", "", "test")
assert_equal "43b0cef99265f9e34c10ea9d3501926d27b39f57c6d674561d8ba236e7a819fb", hexdigest
end
end

end

0 comments on commit 4293f18

Please sign in to comment.