Skip to content

Commit 80f986b

Browse files
Implement HMAC over SHA3 truncated variants (#2484)
This PR implements HMAC over truncated SHA3 variants as specified in [NIST SP 800-224](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-224.ipd.pdf#section.3). We do so without externalizing any SHA3/keccak internals, including its context struct. This is done intentionally, as OpenSSL [has not yet externalized its SHA3/keccak context struct](https://github.com/openssl/openssl/blob/be7467f5a0aa098531597b95a71be6d7c2a463c7/include/internal/sha3.h#L40) and we want to leave the door open to future interoperability. To work around this in `hmac.h`'s `md_ctx_union`, we hard-code the context struct size and add a compile-time assertion that it does not grow larger than the hard-coded value. SHA3 is unique in supported HMAC digests in that, due to differences between its sponge construction and others' Merkle-Dåmgard constructions, it does not support pre-computed keys. To accommodate this difference, we refactor the relevant code generation macros and relevant unit tests. The HMAC-SHA3 feature gap was discovered in a somewhat roundabout way. While preparing a [pull request](python/cpython#135402) to add AWS-LC to upstream CPython's CI, I discovered that CPython's `./configure` script's compile probe failed to detect `libcrypto` support for linking `hashlib`. The compile probe [referenced](https://github.com/python/cpython/blob/59963e866a1bb8128a50cd53d1b13eeab03df06e/configure#L30869) `NID_blake2b512`, which AWS-LC does not support. The consequence of this was that CPython used its HACL implementations for `hashlib` instead of linking AWS-LC. This did not affect our `ssl` integration, as AWS-LC always uses its own hash functions for TLS.
1 parent e6f0499 commit 80f986b

File tree

17 files changed

+5308
-65
lines changed

17 files changed

+5308
-65
lines changed

crypto/fipsmodule/hmac/hmac.c

Lines changed: 70 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@ struct hmac_methods_st {
9696
static int AWS_LC_TRAMPOLINE_##HASH_NAME##_Update(void *, const void *, \
9797
size_t); \
9898
static int AWS_LC_TRAMPOLINE_##HASH_NAME##_Final(uint8_t *, void *); \
99-
static int AWS_LC_TRAMPOLINE_##HASH_NAME##_Init_from_state( \
100-
void *, const uint8_t *, uint64_t); \
101-
static int AWS_LC_TRAMPOLINE_##HASH_NAME##_get_state(void *, uint8_t *, \
102-
uint64_t *); \
10399
static int AWS_LC_TRAMPOLINE_##HASH_NAME##_Init(void *ctx) { \
104100
return HASH_NAME##_Init((HASH_CTX *)ctx); \
105101
} \
@@ -110,6 +106,18 @@ struct hmac_methods_st {
110106
static int AWS_LC_TRAMPOLINE_##HASH_NAME##_Final(uint8_t *out, void *ctx) { \
111107
return HASH_NAME##_Final(out, (HASH_CTX *)ctx); \
112108
} \
109+
OPENSSL_STATIC_ASSERT(HASH_CBLOCK % 8 == 0, \
110+
HASH_NAME##_has_blocksize_not_divisible_by_eight_t) \
111+
OPENSSL_STATIC_ASSERT(HASH_CBLOCK <= EVP_MAX_MD_BLOCK_SIZE, \
112+
HASH_NAME##_has_overlarge_blocksize_t) \
113+
OPENSSL_STATIC_ASSERT(sizeof(HASH_CTX) <= sizeof(union md_ctx_union), \
114+
HASH_NAME##_has_overlarge_context_t)
115+
116+
// For merkle-damgard constructions, we also define functions for importing and
117+
// exporting hash state for precomputed keys. These are not applicable to
118+
// Keccak/SHA3.
119+
#define MD_TRAMPOLINES_EXPLICIT_PRECOMPUTED(HASH_NAME, HASH_CTX, HASH_CBLOCK) \
120+
MD_TRAMPOLINES_EXPLICIT(HASH_NAME, HASH_CTX, HASH_CBLOCK); \
113121
static int AWS_LC_TRAMPOLINE_##HASH_NAME##_Init_from_state( \
114122
void *ctx, const uint8_t *h, uint64_t n) { \
115123
return HASH_NAME##_Init_from_state((HASH_CTX *)ctx, h, n); \
@@ -118,62 +126,75 @@ struct hmac_methods_st {
118126
void *ctx, uint8_t *out_h, uint64_t *out_n) { \
119127
return HASH_NAME##_get_state((HASH_CTX *)ctx, out_h, out_n); \
120128
} \
121-
OPENSSL_STATIC_ASSERT(HASH_CBLOCK % 8 == 0, \
122-
HASH_NAME##_has_blocksize_not_divisible_by_eight_t) \
123-
OPENSSL_STATIC_ASSERT(HASH_CBLOCK <= EVP_MAX_MD_BLOCK_SIZE, \
124-
HASH_NAME##_has_overlarge_blocksize_t) \
125129
OPENSSL_STATIC_ASSERT(HMAC_##HASH_NAME##_PRECOMPUTED_KEY_SIZE == \
126130
2 * HASH_NAME##_CHAINING_LENGTH, \
127131
HASH_NAME##_has_incorrect_precomputed_key_size) \
128132
OPENSSL_STATIC_ASSERT(HMAC_##HASH_NAME##_PRECOMPUTED_KEY_SIZE <= \
129133
HMAC_MAX_PRECOMPUTED_KEY_SIZE, \
130134
HASH_NAME##_has_too_large_precomputed_key_size) \
131-
OPENSSL_STATIC_ASSERT(sizeof(HASH_CTX) <= sizeof(union md_ctx_union), \
132-
HASH_NAME##_has_overlarge_context_t)
133135

134136
// The maximum number of HMAC implementations
135-
#define HMAC_METHOD_MAX 8
136-
137-
MD_TRAMPOLINES_EXPLICIT(MD5, MD5_CTX, MD5_CBLOCK)
138-
MD_TRAMPOLINES_EXPLICIT(SHA1, SHA_CTX, SHA_CBLOCK)
139-
MD_TRAMPOLINES_EXPLICIT(SHA224, SHA256_CTX, SHA256_CBLOCK)
140-
MD_TRAMPOLINES_EXPLICIT(SHA256, SHA256_CTX, SHA256_CBLOCK)
141-
MD_TRAMPOLINES_EXPLICIT(SHA384, SHA512_CTX, SHA512_CBLOCK)
142-
MD_TRAMPOLINES_EXPLICIT(SHA512, SHA512_CTX, SHA512_CBLOCK)
143-
MD_TRAMPOLINES_EXPLICIT(SHA512_224, SHA512_CTX, SHA512_CBLOCK)
144-
MD_TRAMPOLINES_EXPLICIT(SHA512_256, SHA512_CTX, SHA512_CBLOCK)
137+
#define HMAC_METHOD_MAX 12
138+
139+
MD_TRAMPOLINES_EXPLICIT_PRECOMPUTED(MD5, MD5_CTX, MD5_CBLOCK)
140+
MD_TRAMPOLINES_EXPLICIT_PRECOMPUTED(SHA1, SHA_CTX, SHA_CBLOCK)
141+
MD_TRAMPOLINES_EXPLICIT_PRECOMPUTED(SHA224, SHA256_CTX, SHA256_CBLOCK)
142+
MD_TRAMPOLINES_EXPLICIT_PRECOMPUTED(SHA256, SHA256_CTX, SHA256_CBLOCK)
143+
MD_TRAMPOLINES_EXPLICIT_PRECOMPUTED(SHA384, SHA512_CTX, SHA512_CBLOCK)
144+
MD_TRAMPOLINES_EXPLICIT_PRECOMPUTED(SHA512, SHA512_CTX, SHA512_CBLOCK)
145+
MD_TRAMPOLINES_EXPLICIT_PRECOMPUTED(SHA512_224, SHA512_CTX, SHA512_CBLOCK)
146+
MD_TRAMPOLINES_EXPLICIT_PRECOMPUTED(SHA512_256, SHA512_CTX, SHA512_CBLOCK)
147+
MD_TRAMPOLINES_EXPLICIT(SHA3_224, KECCAK1600_CTX, SHA3_224_CBLOCK)
148+
MD_TRAMPOLINES_EXPLICIT(SHA3_256, KECCAK1600_CTX, SHA3_256_CBLOCK)
149+
MD_TRAMPOLINES_EXPLICIT(SHA3_384, KECCAK1600_CTX, SHA3_384_CBLOCK)
150+
MD_TRAMPOLINES_EXPLICIT(SHA3_512, KECCAK1600_CTX, SHA3_512_CBLOCK)
145151

146152
struct hmac_method_array_st {
147153
HmacMethods methods[HMAC_METHOD_MAX];
148154
};
149155

156+
// This macro does not set any values for precomputed keys for portable state,
157+
// and as such is suitable for use with Keccak/SHA3.
150158
#define DEFINE_IN_PLACE_METHODS(EVP_MD, HASH_NAME) { \
151159
out->methods[idx].evp_md = EVP_MD; \
152-
out->methods[idx].chaining_length = HASH_NAME##_CHAINING_LENGTH; \
153160
out->methods[idx].init = AWS_LC_TRAMPOLINE_##HASH_NAME##_Init; \
154161
out->methods[idx].update = AWS_LC_TRAMPOLINE_##HASH_NAME##_Update; \
155162
out->methods[idx].finalize = AWS_LC_TRAMPOLINE_##HASH_NAME##_Final; \
156-
out->methods[idx].init_from_state = \
157-
AWS_LC_TRAMPOLINE_##HASH_NAME##_Init_from_state; \
158-
out->methods[idx].get_state = AWS_LC_TRAMPOLINE_##HASH_NAME##_get_state; \
163+
out->methods[idx].chaining_length = 0UL; \
164+
out->methods[idx].init_from_state = NULL; \
165+
out->methods[idx].get_state = NULL; \
159166
idx++; \
160167
assert(idx <= HMAC_METHOD_MAX); \
161168
}
162169

170+
// Use |idx-1| because DEFINE_IN_PLACE_METHODS has already incremented it.
171+
#define DEFINE_IN_PLACE_METHODS_PRECOMPUTED(EVP_MD, HASH_NAME) { \
172+
DEFINE_IN_PLACE_METHODS(EVP_MD, HASH_NAME); \
173+
assert(idx-1 >= 0); \
174+
out->methods[idx-1].chaining_length = HASH_NAME##_CHAINING_LENGTH; \
175+
out->methods[idx-1].init_from_state = \
176+
AWS_LC_TRAMPOLINE_##HASH_NAME##_Init_from_state; \
177+
out->methods[idx-1].get_state = \
178+
AWS_LC_TRAMPOLINE_##HASH_NAME##_get_state; \
179+
}
180+
163181
DEFINE_LOCAL_DATA(struct hmac_method_array_st, AWSLC_hmac_in_place_methods) {
164182
OPENSSL_memset((void*) out->methods, 0, sizeof(out->methods));
165183
int idx = 0;
166184
// Since we search these linearly it helps (just a bit) to put the most common ones first.
167185
// This isn't based on hard metrics and will not make a significant different on performance.
168-
// FIXME: all hashes but SHA256 have been disabled to check first SHA256
169-
DEFINE_IN_PLACE_METHODS(EVP_sha256(), SHA256);
170-
DEFINE_IN_PLACE_METHODS(EVP_sha1(), SHA1);
171-
DEFINE_IN_PLACE_METHODS(EVP_sha384(), SHA384);
172-
DEFINE_IN_PLACE_METHODS(EVP_sha512(), SHA512);
173-
DEFINE_IN_PLACE_METHODS(EVP_md5(), MD5);
174-
DEFINE_IN_PLACE_METHODS(EVP_sha224(), SHA224);
175-
DEFINE_IN_PLACE_METHODS(EVP_sha512_224(), SHA512_224);
176-
DEFINE_IN_PLACE_METHODS(EVP_sha512_256(), SHA512_256);
186+
DEFINE_IN_PLACE_METHODS_PRECOMPUTED(EVP_sha256(), SHA256);
187+
DEFINE_IN_PLACE_METHODS_PRECOMPUTED(EVP_sha1(), SHA1);
188+
DEFINE_IN_PLACE_METHODS_PRECOMPUTED(EVP_sha384(), SHA384);
189+
DEFINE_IN_PLACE_METHODS_PRECOMPUTED(EVP_sha512(), SHA512);
190+
DEFINE_IN_PLACE_METHODS_PRECOMPUTED(EVP_md5(), MD5);
191+
DEFINE_IN_PLACE_METHODS_PRECOMPUTED(EVP_sha224(), SHA224);
192+
DEFINE_IN_PLACE_METHODS_PRECOMPUTED(EVP_sha512_224(), SHA512_224);
193+
DEFINE_IN_PLACE_METHODS_PRECOMPUTED(EVP_sha512_256(), SHA512_256);
194+
DEFINE_IN_PLACE_METHODS(EVP_sha3_224(), SHA3_224);
195+
DEFINE_IN_PLACE_METHODS(EVP_sha3_256(), SHA3_256);
196+
DEFINE_IN_PLACE_METHODS(EVP_sha3_384(), SHA3_384);
197+
DEFINE_IN_PLACE_METHODS(EVP_sha3_512(), SHA3_512);
177198
}
178199

179200
static const HmacMethods *GetInPlaceMethods(const EVP_MD *evp_md) {
@@ -494,6 +515,11 @@ void HMAC_CTX_reset(HMAC_CTX *ctx) {
494515
}
495516

496517
int HMAC_set_precomputed_key_export(HMAC_CTX *ctx) {
518+
GUARD_PTR(ctx);
519+
if (ctx->methods != NULL && ctx->methods->get_state == NULL) {
520+
OPENSSL_PUT_ERROR(HMAC, HMAC_R_PRECOMPUTED_KEY_NOT_SUPPORTED_FOR_DIGEST);
521+
return 0;
522+
}
497523
if (HMAC_STATE_INIT_NO_DATA != ctx->state &&
498524
HMAC_STATE_PRECOMPUTED_KEY_EXPORT_READY != ctx->state) {
499525
// HMAC_set_precomputed_key_export can only be called after Hmac_Init_*
@@ -505,6 +531,13 @@ int HMAC_set_precomputed_key_export(HMAC_CTX *ctx) {
505531
}
506532

507533
int HMAC_get_precomputed_key(HMAC_CTX *ctx, uint8_t *out, size_t *out_len) {
534+
GUARD_PTR(ctx);
535+
GUARD_PTR(ctx->methods);
536+
if (ctx->methods->get_state == NULL) {
537+
OPENSSL_PUT_ERROR(HMAC, HMAC_R_PRECOMPUTED_KEY_NOT_SUPPORTED_FOR_DIGEST);
538+
return 0;
539+
}
540+
508541
if (HMAC_STATE_PRECOMPUTED_KEY_EXPORT_READY != ctx->state) {
509542
OPENSSL_PUT_ERROR(EVP, HMAC_R_SET_PRECOMPUTED_KEY_EXPORT_NOT_CALLED);
510543
return 0;
@@ -583,6 +616,10 @@ int HMAC_Init_from_precomputed_key(HMAC_CTX *ctx,
583616
}
584617

585618
const HmacMethods *methods = ctx->methods;
619+
if (ctx->methods->init_from_state == NULL) {
620+
OPENSSL_PUT_ERROR(HMAC, HMAC_R_PRECOMPUTED_KEY_NOT_SUPPORTED_FOR_DIGEST);
621+
return 0;
622+
}
586623

587624
const size_t chaining_length = methods->chaining_length;
588625
const size_t block_size = EVP_MD_block_size(methods->evp_md);

crypto/fipsmodule/service_indicator/service_indicator.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,10 @@ void HMAC_verify_service_indicator(const EVP_MD *evp_md) {
414414
case NID_sha512:
415415
case NID_sha512_224:
416416
case NID_sha512_256:
417+
case NID_sha3_224:
418+
case NID_sha3_256:
419+
case NID_sha3_384:
420+
case NID_sha3_512:
417421
FIPS_service_indicator_update_state();
418422
break;
419423
default:

crypto/fipsmodule/sha/internal.h

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
#include <openssl/base.h>
1919

20+
#include <openssl/hmac.h>
21+
2022
#include "../../internal.h"
2123
#include "../cpucap/internal.h"
2224

@@ -43,18 +45,22 @@ extern "C" {
4345
#define KECCAK1600_WIDTH 1600
4446

4547
#define SHA3_224_CAPACITY_BYTES 56
48+
#define SHA3_224_CBLOCK SHA3_BLOCKSIZE(SHA3_224_DIGEST_BITLENGTH)
4649
#define SHA3_224_DIGEST_BITLENGTH 224
4750
#define SHA3_224_DIGEST_LENGTH 28
4851

4952
#define SHA3_256_CAPACITY_BYTES 64
53+
#define SHA3_256_CBLOCK SHA3_BLOCKSIZE(SHA3_256_DIGEST_BITLENGTH)
5054
#define SHA3_256_DIGEST_BITLENGTH 256
5155
#define SHA3_256_DIGEST_LENGTH 32
5256

5357
#define SHA3_384_CAPACITY_BYTES 96
58+
#define SHA3_384_CBLOCK SHA3_BLOCKSIZE(SHA3_384_DIGEST_BITLENGTH)
5459
#define SHA3_384_DIGEST_BITLENGTH 384
5560
#define SHA3_384_DIGEST_LENGTH 48
5661

5762
#define SHA3_512_CAPACITY_BYTES 128
63+
#define SHA3_512_CBLOCK SHA3_BLOCKSIZE(SHA3_512_DIGEST_BITLENGTH)
5864
#define SHA3_512_DIGEST_BITLENGTH 512
5965
#define SHA3_512_DIGEST_LENGTH 64
6066

@@ -81,11 +87,11 @@ extern "C" {
8187
// so that |SHAKE_Squeeze| cannot be called anymore.
8288
#define KECCAK1600_STATE_FINAL 2
8389

84-
typedef struct keccak_st KECCAK1600_CTX;
90+
typedef struct keccak_ctx_st KECCAK1600_CTX;
8591

8692
// The data buffer should have at least the maximum number of
8793
// block size bytes to fit any SHA3/SHAKE block length.
88-
struct keccak_st {
94+
struct keccak_ctx_st {
8995
uint64_t A[KECCAK1600_ROWS][KECCAK1600_ROWS];
9096
size_t block_size; // cached ctx->digest->block_size
9197
size_t md_size; // output length, variable in XOF (SHAKE)
@@ -95,6 +101,15 @@ struct keccak_st {
95101
uint8_t state; // denotes the keccak phase (absorb, squeeze, final)
96102
};
97103

104+
// To avoid externalizing KECCAK1600_CTX, we hard-code the context size in
105+
// hmac.h's |md_ctx_union| and use a compile time check here to make sure
106+
// |KECCAK1600_CTX|'s size never exceeds that of |md_ctx_union|. This means
107+
// that whenever a new field is added to |keccak_ctx_st| we must also update
108+
// the hard-coded size of |sha3| in hmac.h's |md_ctx_union| with the new
109+
// value given by |sizeof(keccaak_ctx_st)|.
110+
OPENSSL_STATIC_ASSERT(sizeof(KECCAK1600_CTX) <= sizeof(union md_ctx_union),
111+
hmac_md_ctx_union_sha3_size_needs_update)
112+
98113
// KECCAK1600 x4 batched context structure
99114
typedef KECCAK1600_CTX KECCAK1600_CTX_x4[4];
100115

@@ -445,6 +460,46 @@ int SHA3_Update(KECCAK1600_CTX *ctx, const void *data, size_t len);
445460
// When call-discipline is maintained, this function never fails.
446461
int SHA3_Final(uint8_t *md, KECCAK1600_CTX *ctx);
447462

463+
// SHA3_224_Init initialises |sha| and returns 1.
464+
int SHA3_224_Init(KECCAK1600_CTX *sha);
465+
466+
// SHA3_224_Update adds |len| bytes from |data| to |sha| and returns 1.
467+
int SHA3_224_Update(KECCAK1600_CTX *sha, const void *data, size_t len);
468+
469+
// SHA3_224_Final adds the final padding to |sha| and writes the resulting
470+
// digest to |out|. It returns one on success and zero on programmer error.
471+
int SHA3_224_Final(uint8_t out[SHA3_224_DIGEST_LENGTH], KECCAK1600_CTX *sha);
472+
473+
// SHA3_256_Init initialises |sha| and returns 1.
474+
int SHA3_256_Init(KECCAK1600_CTX *sha);
475+
476+
// SHA3_256_Update adds |len| bytes from |data| to |sha| and returns 1.
477+
int SHA3_256_Update(KECCAK1600_CTX *sha, const void *data, size_t len);
478+
479+
// SHA3_256_Final adds the final padding to |sha| and writes the resulting
480+
// digest to |out|. It returns one on success and zero on programmer error.
481+
int SHA3_256_Final(uint8_t out[SHA3_256_DIGEST_LENGTH], KECCAK1600_CTX *sha);
482+
483+
// SHA3_384_Init initialises |sha| and returns 1.
484+
int SHA3_384_Init(KECCAK1600_CTX *sha);
485+
486+
// SHA3_384_Update adds |len| bytes from |data| to |sha| and returns 1.
487+
int SHA3_384_Update(KECCAK1600_CTX *sha, const void *data, size_t len);
488+
489+
// SHA3_384_Final adds the final padding to |sha| and writes the resulting
490+
// digest to |out|. It returns one on success and zero on programmer error.
491+
int SHA3_384_Final(uint8_t out[SHA3_384_DIGEST_LENGTH], KECCAK1600_CTX *sha);
492+
493+
// SHA3_512_Init initialises |sha| and returns 1.
494+
int SHA3_512_Init(KECCAK1600_CTX *sha);
495+
496+
// SHA3_512_Update adds |len| bytes from |data| to |sha| and returns 1.
497+
int SHA3_512_Update(KECCAK1600_CTX *sha, const void *data, size_t len);
498+
499+
// SHA3_512_Final adds the final padding to |sha| and writes the resulting
500+
// digest to |out|. It returns one on success and zero on programmer error.
501+
int SHA3_512_Final(uint8_t out[SHA3_512_DIGEST_LENGTH], KECCAK1600_CTX *sha);
502+
448503
/*
449504
* SHAKE APIs implement SHAKE functionalities on top of FIPS202 API layer
450505
*

crypto/fipsmodule/sha/sha3.c

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,67 @@ int SHA3_Final(uint8_t *md, KECCAK1600_CTX *ctx) {
270270

271271
Keccak1600_Squeeze(ctx->A, md, ctx->md_size, ctx->block_size, ctx->state);
272272
ctx->state = KECCAK1600_STATE_FINAL;
273-
273+
274274
FIPS_service_indicator_update_state();
275275
return 1;
276276
}
277277

278+
int SHA3_224_Init(KECCAK1600_CTX *ctx) {
279+
return SHA3_Init(ctx, SHA3_224_DIGEST_BITLENGTH);
280+
}
281+
282+
int SHA3_224_Update(KECCAK1600_CTX *ctx, const void *data,
283+
size_t len) {
284+
return SHA3_Update(ctx, data, len);
285+
}
286+
287+
int SHA3_224_Final(uint8_t out[SHA3_224_DIGEST_LENGTH],
288+
KECCAK1600_CTX *ctx) {
289+
return SHA3_Final(&out[0], ctx);
290+
}
291+
292+
int SHA3_256_Init(KECCAK1600_CTX *ctx) {
293+
return SHA3_Init(ctx, SHA3_256_DIGEST_BITLENGTH);
294+
}
295+
296+
int SHA3_256_Update(KECCAK1600_CTX *ctx, const void *data,
297+
size_t len) {
298+
return SHA3_Update(ctx, data, len);
299+
}
300+
301+
int SHA3_256_Final(uint8_t out[SHA3_256_DIGEST_LENGTH],
302+
KECCAK1600_CTX *ctx) {
303+
return SHA3_Final(&out[0], ctx);
304+
}
305+
306+
int SHA3_384_Init(KECCAK1600_CTX *ctx) {
307+
return SHA3_Init(ctx, SHA3_384_DIGEST_BITLENGTH);
308+
}
309+
310+
int SHA3_384_Update(KECCAK1600_CTX *ctx, const void *data,
311+
size_t len) {
312+
return SHA3_Update(ctx, data, len);
313+
}
314+
315+
int SHA3_384_Final(uint8_t out[SHA3_384_DIGEST_LENGTH],
316+
KECCAK1600_CTX *ctx) {
317+
return SHA3_Final(&out[0], ctx);
318+
}
319+
320+
int SHA3_512_Init(KECCAK1600_CTX *ctx) {
321+
return SHA3_Init(ctx, SHA3_512_DIGEST_BITLENGTH);
322+
}
323+
324+
int SHA3_512_Update(KECCAK1600_CTX *ctx, const void *data,
325+
size_t len) {
326+
return SHA3_Update(ctx, data, len);
327+
}
328+
329+
int SHA3_512_Final(uint8_t out[SHA3_512_DIGEST_LENGTH],
330+
KECCAK1600_CTX *ctx) {
331+
return SHA3_Final(&out[0], ctx);
332+
}
333+
278334
/*
279335
* SHAKE APIs implement SHAKE functionalities on top of FIPS202 API layer
280336
*/

0 commit comments

Comments
 (0)