Skip to content

Commit 0499de5

Browse files
ifranzkit8m
authored andcommitted
s390x: Add hardware acceleration for HMAC
The CPACF instruction KMAC provides support for accelerating the HMAC algorithm on newer machines for HMAC with SHA-224, SHA-256, SHA-384, and SHA-512. Preliminary measurements showed performance improvements of up to a factor of 2, dependent on the message size, whether chunking is used and the size of the chunks. Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com> Reviewed-by: Paul Dale <ppzgs1@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #25161)
1 parent 518b53b commit 0499de5

File tree

5 files changed

+392
-4
lines changed

5 files changed

+392
-4
lines changed

crypto/hmac/build.info

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,22 @@ LIBS=../../libcrypto
22

33
$COMMON=hmac.c
44

5-
SOURCE[../../libcrypto]=$COMMON
6-
SOURCE[../../providers/libfips.a]=$COMMON
5+
IF[{- !$disabled{asm} -}]
6+
IF[{- ($target{perlasm_scheme} // '') ne '31' -}]
7+
$HMACASM_s390x=hmac_s390x.c
8+
$HMACDEF_s390x=OPENSSL_HMAC_S390X
9+
ENDIF
10+
11+
# Now that we have defined all the arch specific variables, use the
12+
# appropriate ones, and define the appropriate macros
13+
IF[$HMACASM_{- $target{asm_arch} -}]
14+
$HMACASM=$HMACASM_{- $target{asm_arch} -}
15+
$HMACDEF=$HMACDEF_{- $target{asm_arch} -}
16+
ENDIF
17+
ENDIF
18+
19+
DEFINE[../../libcrypto]=$HMACDEF
20+
DEFINE[../../providers/libfips.a]=$HMACDEF
21+
22+
SOURCE[../../libcrypto]=$COMMON $HMACASM
23+
SOURCE[../../providers/libfips.a]=$COMMON $HMACASM

crypto/hmac/hmac.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
2+
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
33
*
44
* Licensed under the Apache License 2.0 (the "License"). You may not use
55
* this file except in compliance with the License. You can obtain a copy
@@ -49,6 +49,12 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
4949
if ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0)
5050
return 0;
5151

52+
#ifdef OPENSSL_HMAC_S390X
53+
rv = s390x_HMAC_init(ctx, key, len, impl);
54+
if (rv >= 1)
55+
return rv;
56+
#endif
57+
5258
if (key != NULL) {
5359
reset = 1;
5460

@@ -111,6 +117,12 @@ int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
111117
{
112118
if (!ctx->md)
113119
return 0;
120+
121+
#ifdef OPENSSL_HMAC_S390X
122+
if (ctx->plat.s390x.fc)
123+
return s390x_HMAC_update(ctx, data, len);
124+
#endif
125+
114126
return EVP_DigestUpdate(ctx->md_ctx, data, len);
115127
}
116128

@@ -122,6 +134,11 @@ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
122134
if (!ctx->md)
123135
goto err;
124136

137+
#ifdef OPENSSL_HMAC_S390X
138+
if (ctx->plat.s390x.fc)
139+
return s390x_HMAC_final(ctx, md, len);
140+
#endif
141+
125142
if (!EVP_DigestFinal_ex(ctx->md_ctx, buf, &i))
126143
goto err;
127144
if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->o_ctx))
@@ -161,6 +178,10 @@ static void hmac_ctx_cleanup(HMAC_CTX *ctx)
161178
EVP_MD_CTX_reset(ctx->o_ctx);
162179
EVP_MD_CTX_reset(ctx->md_ctx);
163180
ctx->md = NULL;
181+
182+
#ifdef OPENSSL_HMAC_S390X
183+
s390x_HMAC_CTX_cleanup(ctx);
184+
#endif
164185
}
165186

166187
void HMAC_CTX_free(HMAC_CTX *ctx)
@@ -212,6 +233,12 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
212233
if (!EVP_MD_CTX_copy_ex(dctx->md_ctx, sctx->md_ctx))
213234
goto err;
214235
dctx->md = sctx->md;
236+
237+
#ifdef OPENSSL_HMAC_S390X
238+
if (s390x_HMAC_CTX_copy(dctx, sctx) == 0)
239+
goto err;
240+
#endif
241+
215242
return 1;
216243
err:
217244
hmac_ctx_cleanup(dctx);

crypto/hmac/hmac_local.h

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
2+
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
33
*
44
* Licensed under the Apache License 2.0 (the "License"). You may not use
55
* this file except in compliance with the License. You can obtain a copy
@@ -10,6 +10,10 @@
1010
#ifndef OSSL_CRYPTO_HMAC_LOCAL_H
1111
# define OSSL_CRYPTO_HMAC_LOCAL_H
1212

13+
# include "internal/common.h"
14+
# include "internal/numbers.h"
15+
# include "openssl/sha.h"
16+
1317
/* The current largest case is for SHA3-224 */
1418
#define HMAC_MAX_MD_CBLOCK_SIZE 144
1519

@@ -18,6 +22,45 @@ struct hmac_ctx_st {
1822
EVP_MD_CTX *md_ctx;
1923
EVP_MD_CTX *i_ctx;
2024
EVP_MD_CTX *o_ctx;
25+
26+
/* Platform specific data */
27+
union {
28+
int dummy;
29+
# ifdef OPENSSL_HMAC_S390X
30+
struct {
31+
unsigned int fc; /* 0 if not supported by kmac instruction */
32+
int blk_size;
33+
int ikp;
34+
int iimp;
35+
unsigned char *buf;
36+
size_t size; /* must be multiple of digest block size */
37+
size_t num;
38+
union {
39+
OSSL_UNION_ALIGN;
40+
struct {
41+
uint32_t h[8];
42+
uint64_t imbl;
43+
unsigned char key[64];
44+
} hmac_224_256;
45+
struct {
46+
uint64_t h[8];
47+
uint128_t imbl;
48+
unsigned char key[128];
49+
} hmac_384_512;
50+
} param;
51+
} s390x;
52+
# endif /* OPENSSL_HMAC_S390X */
53+
} plat;
2154
};
2255

56+
# ifdef OPENSSL_HMAC_S390X
57+
# define HMAC_S390X_BUF_NUM_BLOCKS 64
58+
59+
int s390x_HMAC_init(HMAC_CTX *ctx, const void *key, int key_len, ENGINE *impl);
60+
int s390x_HMAC_update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
61+
int s390x_HMAC_final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
62+
int s390x_HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
63+
int s390x_HMAC_CTX_cleanup(HMAC_CTX *ctx);
64+
# endif /* OPENSSL_HMAC_S390X */
65+
2366
#endif

0 commit comments

Comments
 (0)