When running on the s390x platform HMAC_Init_ex() calls s390x_HMAC_init()
to optionally allow hardware acceleration of the HMAC operation. In case
the hardware acceleration is not available, s390x_HMAC_init() returns -1
to indicate that. In this case the software path is continued.
The problem is that rv was set to -1 by s390x_HMAC_init() and stays at
this until the end of the function. In case the software path detects an
error it goes to the 'err' label which just returns rv as is, and thus
HMAC_Init_ex() now returns -1 instead of 0 (rv was initialized to 0 at
declaration).
The wrong return value might then be propagated through all layers, i.e.
to EVP_MAC_init() which also returns -1 in this case. However, EVP_MAC_init()
is defined as returning 1 on success, or 0 on error, i.e. a boolean kind of
return value.
Typically, callers will do something like 'if (!EVP_MAC_init(s....))' to
check for errors. A return value of -1 is non-zero, and thus it is treated
as successful return.
Fix this by setting rv back to 0 when s390x_HMAC_init() returned -1.
Fixes: 0499de5adda2 "s390x: Add hardware acceleration for HMAC"
Resolves: https://github.com/openssl/openssl/issues/31706
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Milan Broz <mbroz@openssl.org>
MergeDate: Tue Jun 30 20:49:52 2026
(Merged from https://github.com/openssl/openssl/pull/31723)
return 0;
#ifdef OPENSSL_HMAC_S390X
- rv = s390x_HMAC_init(ctx, key, len);
- if (rv != -1)
- return rv;
+ {
+ int ret = s390x_HMAC_init(ctx, key, len);
+ if (ret != -1) /* -1 means SW fallback */
+ return ret;
+ }
#endif
if (key != NULL) {