Extract SHA384/SHA512/SHA512_256 from bcm Change-Id: I62027a3a9c3aa338721f42b045b9e028d307ab23 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/70967 Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/build.json b/build.json index e682971..f1e6173 100644 --- a/build.json +++ b/build.json
@@ -305,6 +305,7 @@ "crypto/rsa_extra/rsa_print.c", "crypto/sha/sha1.c", "crypto/sha/sha256.c", + "crypto/sha/sha512.c", "crypto/siphash/siphash.c", "crypto/slhdsa/fors.c", "crypto/slhdsa/merkle.c",
diff --git a/crypto/fipsmodule/bcm_interface.h b/crypto/fipsmodule/bcm_interface.h index 222a9db..ba084f5 100644 --- a/crypto/fipsmodule/bcm_interface.h +++ b/crypto/fipsmodule/bcm_interface.h
@@ -137,7 +137,7 @@ // BCM_sha224_update adds |len| bytes from |data| to |sha|. bcm_infallible BCM_sha224_update(SHA256_CTX *sha, const void *data, size_t len); -// BCM_sha224_Final adds the final padding to |sha| and writes the resulting +// BCM_sha224_final adds the final padding to |sha| and writes the resulting // digest to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of // space. It aborts on programmer error. bcm_infallible BCM_sha224_final(uint8_t out[BCM_SHA224_DIGEST_LENGTH], @@ -175,6 +175,68 @@ size_t num_blocks); +// SHA-384. + +// BCM_SHA384_DIGEST_LENGTH is the length of a SHA-384 digest. +#define BCM_SHA384_DIGEST_LENGTH 48 + +// BCM_sha384_init initialises |sha|. +bcm_infallible BCM_sha384_init(SHA512_CTX *sha); + +// BCM_sha384_update adds |len| bytes from |data| to |sha|. +bcm_infallible BCM_sha384_update(SHA512_CTX *sha, const void *data, size_t len); + +// BCM_sha384_final adds the final padding to |sha| and writes the resulting +// digest to |out|, which must have at least |BCM_sha384_DIGEST_LENGTH| bytes of +// space. It may abort on programmer error. +bcm_infallible BCM_sha384_final(uint8_t out[BCM_SHA384_DIGEST_LENGTH], + SHA512_CTX *sha); + + +// SHA-512. + +// BCM_SHA512_DIGEST_LENGTH is the length of a SHA-512 digest. +#define BCM_SHA512_DIGEST_LENGTH 64 + +// BCM_sha512_init initialises |sha|. +bcm_infallible BCM_sha512_init(SHA512_CTX *sha); + +// BCM_sha512_update adds |len| bytes from |data| to |sha|. +bcm_infallible BCM_sha512_update(SHA512_CTX *sha, const void *data, size_t len); + +// BCM_sha512_final adds the final padding to |sha| and writes the resulting +// digest to |out|, which must have at least |BCM_sha512_DIGEST_LENGTH| bytes of +// space. +bcm_infallible BCM_sha512_final(uint8_t out[BCM_SHA512_DIGEST_LENGTH], + SHA512_CTX *sha); + +// BCM_sha512_transform is a low-level function that performs a single, SHA-512 +// block transformation using the state from |sha| and |BCM_sha512_CBLOCK| bytes +// from |block|. +bcm_infallible BCM_sha512_transform(SHA512_CTX *sha, + const uint8_t block[BCM_SHA512_CBLOCK]); + + +// SHA-512-256 +// +// See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6 + +#define BCM_SHA512_256_DIGEST_LENGTH 32 + +// BCM_sha512_256_init initialises |sha|. +bcm_infallible BCM_sha512_256_init(SHA512_CTX *sha); + +// BCM_sha512_256_update adds |len| bytes from |data| to |sha|. +bcm_infallible BCM_sha512_256_update(SHA512_CTX *sha, const void *data, + size_t len); + +// BCM_sha512_256_final adds the final padding to |sha| and writes the resulting +// digest to |out|, which must have at least |BCM_sha512_256_DIGEST_LENGTH| +// bytes of space. It may abort on programmer error. +bcm_infallible BCM_sha512_256_final(uint8_t out[BCM_SHA512_256_DIGEST_LENGTH], + SHA512_CTX *sha); + + #if defined(__cplusplus) } // extern C #endif
diff --git a/crypto/fipsmodule/digest/digests.c.inc b/crypto/fipsmodule/digest/digests.c.inc index 216af52..9ead2c6 100644 --- a/crypto/fipsmodule/digest/digests.c.inc +++ b/crypto/fipsmodule/digest/digests.c.inc
@@ -60,7 +60,6 @@ #include <string.h> #include <openssl/nid.h> -#include <openssl/sha.h> #include "internal.h" #include "../delocate.h" @@ -146,20 +145,20 @@ static void sha384_init(EVP_MD_CTX *ctx) { - CHECK(SHA384_Init(ctx->md_data)); + BCM_sha384_init(ctx->md_data); } static void sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) { - CHECK(SHA384_Update(ctx->md_data, data, count)); + BCM_sha384_update(ctx->md_data, data, count); } static void sha384_final(EVP_MD_CTX *ctx, uint8_t *md) { - CHECK(SHA384_Final(md, ctx->md_data)); + BCM_sha384_final(md, ctx->md_data); } DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) { out->type = NID_sha384; - out->md_size = SHA384_DIGEST_LENGTH; + out->md_size = BCM_SHA384_DIGEST_LENGTH; out->flags = 0; out->init = sha384_init; out->update = sha384_update; @@ -170,20 +169,20 @@ static void sha512_init(EVP_MD_CTX *ctx) { - CHECK(SHA512_Init(ctx->md_data)); + BCM_sha512_init(ctx->md_data); } static void sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) { - CHECK(SHA512_Update(ctx->md_data, data, count)); + BCM_sha512_update(ctx->md_data, data, count); } static void sha512_final(EVP_MD_CTX *ctx, uint8_t *md) { - CHECK(SHA512_Final(md, ctx->md_data)); + BCM_sha512_final(md, ctx->md_data); } DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512) { out->type = NID_sha512; - out->md_size = SHA512_DIGEST_LENGTH; + out->md_size = BCM_SHA512_DIGEST_LENGTH; out->flags = 0; out->init = sha512_init; out->update = sha512_update; @@ -194,20 +193,20 @@ static void sha512_256_init(EVP_MD_CTX *ctx) { - CHECK(SHA512_256_Init(ctx->md_data)); + BCM_sha512_256_init(ctx->md_data); } static void sha512_256_update(EVP_MD_CTX *ctx, const void *data, size_t count) { - CHECK(SHA512_256_Update(ctx->md_data, data, count)); + BCM_sha512_256_update(ctx->md_data, data, count); } static void sha512_256_final(EVP_MD_CTX *ctx, uint8_t *md) { - CHECK(SHA512_256_Final(md, ctx->md_data)); + BCM_sha512_256_final(md, ctx->md_data); } DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512_256) { out->type = NID_sha512_256; - out->md_size = SHA512_256_DIGEST_LENGTH; + out->md_size = BCM_SHA512_256_DIGEST_LENGTH; out->flags = 0; out->init = sha512_256_init; out->update = sha512_256_update;
diff --git a/crypto/fipsmodule/ecdh/ecdh.c.inc b/crypto/fipsmodule/ecdh/ecdh.c.inc index d16c3c1..86ba258 100644 --- a/crypto/fipsmodule/ecdh/ecdh.c.inc +++ b/crypto/fipsmodule/ecdh/ecdh.c.inc
@@ -72,7 +72,6 @@ #include <openssl/ec_key.h> #include <openssl/err.h> #include <openssl/mem.h> -#include <openssl/sha.h> #include "../../internal.h" #include "../ec/internal.h" @@ -106,24 +105,27 @@ FIPS_service_indicator_lock_state(); SHA256_CTX ctx; + SHA512_CTX ctx_512; switch (out_len) { case SHA224_DIGEST_LENGTH: BCM_sha224_init(&ctx); BCM_sha224_update(&ctx, buf, buflen); BCM_sha224_final(out, &ctx); - OPENSSL_cleanse(&ctx, sizeof(ctx)); break; case SHA256_DIGEST_LENGTH: BCM_sha256_init(&ctx); BCM_sha256_update(&ctx, buf, buflen); BCM_sha256_final(out, &ctx); - OPENSSL_cleanse(&ctx, sizeof(ctx)); break; case SHA384_DIGEST_LENGTH: - SHA384(buf, buflen, out); + BCM_sha384_init(&ctx_512); + BCM_sha384_update(&ctx_512, buf, buflen); + BCM_sha384_final(out, &ctx_512); break; case SHA512_DIGEST_LENGTH: - SHA512(buf, buflen, out); + BCM_sha512_init(&ctx_512); + BCM_sha512_update(&ctx_512, buf, buflen); + BCM_sha512_final(out, &ctx_512); break; default: OPENSSL_PUT_ERROR(ECDH, ECDH_R_UNKNOWN_DIGEST_LENGTH);
diff --git a/crypto/fipsmodule/ecdsa/ecdsa.c.inc b/crypto/fipsmodule/ecdsa/ecdsa.c.inc index cba8972..f5508a1 100644 --- a/crypto/fipsmodule/ecdsa/ecdsa.c.inc +++ b/crypto/fipsmodule/ecdsa/ecdsa.c.inc
@@ -58,7 +58,6 @@ #include <openssl/bn.h> #include <openssl/err.h> #include <openssl/mem.h> -#include <openssl/sha.h> #include "../../internal.h" #include "../bn/internal.h" @@ -268,17 +267,17 @@ // Pass a SHA512 hash of the private key and digest as additional data // into the RBG. This is a hardening measure against entropy failure. - static_assert(SHA512_DIGEST_LENGTH >= 32, + static_assert(BCM_SHA512_DIGEST_LENGTH >= 32, "additional_data is too large for SHA-512"); FIPS_service_indicator_lock_state(); SHA512_CTX sha; - uint8_t additional_data[SHA512_DIGEST_LENGTH]; - SHA512_Init(&sha); - SHA512_Update(&sha, priv_key->words, order->width * sizeof(BN_ULONG)); - SHA512_Update(&sha, digest, digest_len); - SHA512_Final(additional_data, &sha); + uint8_t additional_data[BCM_SHA512_DIGEST_LENGTH]; + BCM_sha512_init(&sha); + BCM_sha512_update(&sha, priv_key->words, order->width * sizeof(BN_ULONG)); + BCM_sha512_update(&sha, digest, digest_len); + BCM_sha512_final(additional_data, &sha); // Cap iterations so callers who supply invalid values as custom groups do not // infinite loop. This does not impact valid parameters (e.g. those covered by
diff --git a/crypto/fipsmodule/rsa/padding.c.inc b/crypto/fipsmodule/rsa/padding.c.inc index e4c1c1c..2deceb3 100644 --- a/crypto/fipsmodule/rsa/padding.c.inc +++ b/crypto/fipsmodule/rsa/padding.c.inc
@@ -63,7 +63,6 @@ #include <openssl/digest.h> #include <openssl/err.h> #include <openssl/mem.h> -#include <openssl/sha.h> #include "internal.h" #include "../service_indicator/internal.h"
diff --git a/crypto/fipsmodule/rsa/rsa.c.inc b/crypto/fipsmodule/rsa/rsa.c.inc index 8cb6c5d..5f38005 100644 --- a/crypto/fipsmodule/rsa/rsa.c.inc +++ b/crypto/fipsmodule/rsa/rsa.c.inc
@@ -68,7 +68,6 @@ #include <openssl/md5.h> #include <openssl/mem.h> #include <openssl/nid.h> -#include <openssl/sha.h> #include <openssl/thread.h> #include "../bn/internal.h" @@ -501,14 +500,14 @@ }, { NID_sha384, - SHA384_DIGEST_LENGTH, + BCM_SHA384_DIGEST_LENGTH, 19, {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}, }, { NID_sha512, - SHA512_DIGEST_LENGTH, + BCM_SHA512_DIGEST_LENGTH, 19, {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
diff --git a/crypto/fipsmodule/sha/sha512.c.inc b/crypto/fipsmodule/sha/sha512.c.inc index f9f7be8..65a5265 100644 --- a/crypto/fipsmodule/sha/sha512.c.inc +++ b/crypto/fipsmodule/sha/sha512.c.inc
@@ -54,13 +54,12 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -#include <openssl/sha.h> - #include <string.h> #include <openssl/mem.h> #include "../../internal.h" +#include "../bcm_interface.h" #include "../service_indicator/internal.h" #include "internal.h" @@ -71,9 +70,9 @@ // this writing, so there is no need for a common collector/padding // implementation yet. -static int sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha); +static void sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha); -int SHA384_Init(SHA512_CTX *sha) { +bcm_infallible BCM_sha384_init(SHA512_CTX *sha) { sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8); sha->h[1] = UINT64_C(0x629a292a367cd507); sha->h[2] = UINT64_C(0x9159015a3070dd17); @@ -86,12 +85,12 @@ sha->Nl = 0; sha->Nh = 0; sha->num = 0; - sha->md_len = SHA384_DIGEST_LENGTH; - return 1; + sha->md_len = BCM_SHA384_DIGEST_LENGTH; + return bcm_infallible_approved; } -int SHA512_Init(SHA512_CTX *sha) { +bcm_infallible BCM_sha512_init(SHA512_CTX *sha) { sha->h[0] = UINT64_C(0x6a09e667f3bcc908); sha->h[1] = UINT64_C(0xbb67ae8584caa73b); sha->h[2] = UINT64_C(0x3c6ef372fe94f82b); @@ -104,11 +103,11 @@ sha->Nl = 0; sha->Nh = 0; sha->num = 0; - sha->md_len = SHA512_DIGEST_LENGTH; - return 1; + sha->md_len = BCM_SHA512_DIGEST_LENGTH; + return bcm_infallible_approved; } -int SHA512_256_Init(SHA512_CTX *sha) { +bcm_infallible BCM_sha512_256_init(SHA512_CTX *sha) { sha->h[0] = UINT64_C(0x22312194fc2bf72c); sha->h[1] = UINT64_C(0x9f555fa3c84c64c2); sha->h[2] = UINT64_C(0x2393b86b6f53b151); @@ -121,38 +120,8 @@ sha->Nl = 0; sha->Nh = 0; sha->num = 0; - sha->md_len = SHA512_256_DIGEST_LENGTH; - return 1; -} - -uint8_t *SHA384(const uint8_t *data, size_t len, - uint8_t out[SHA384_DIGEST_LENGTH]) { - SHA512_CTX ctx; - SHA384_Init(&ctx); - SHA384_Update(&ctx, data, len); - SHA384_Final(out, &ctx); - OPENSSL_cleanse(&ctx, sizeof(ctx)); - return out; -} - -uint8_t *SHA512(const uint8_t *data, size_t len, - uint8_t out[SHA512_DIGEST_LENGTH]) { - SHA512_CTX ctx; - SHA512_Init(&ctx); - SHA512_Update(&ctx, data, len); - SHA512_Final(out, &ctx); - OPENSSL_cleanse(&ctx, sizeof(ctx)); - return out; -} - -uint8_t *SHA512_256(const uint8_t *data, size_t len, - uint8_t out[SHA512_256_DIGEST_LENGTH]) { - SHA512_CTX ctx; - SHA512_256_Init(&ctx); - SHA512_256_Update(&ctx, data, len); - SHA512_256_Final(out, &ctx); - OPENSSL_cleanse(&ctx, sizeof(ctx)); - return out; + sha->md_len = BCM_SHA512_256_DIGEST_LENGTH; + return bcm_infallible_approved; } #if !defined(SHA512_ASM) @@ -161,39 +130,48 @@ #endif -int SHA384_Final(uint8_t out[SHA384_DIGEST_LENGTH], SHA512_CTX *sha) { - // This function must be paired with |SHA384_Init|, which sets |sha->md_len| - // to |SHA384_DIGEST_LENGTH|. - assert(sha->md_len == SHA384_DIGEST_LENGTH); - return sha512_final_impl(out, SHA384_DIGEST_LENGTH, sha); +bcm_infallible BCM_sha384_final(uint8_t out[BCM_SHA384_DIGEST_LENGTH], + SHA512_CTX *sha) { + // This function must be paired with |BCM_sha384_init|, which sets + // |sha->md_len| to |BCM_SHA384_DIGEST_LENGTH|. + assert(sha->md_len == BCM_SHA384_DIGEST_LENGTH); + sha512_final_impl(out, BCM_SHA384_DIGEST_LENGTH, sha); + return bcm_infallible_approved; } -int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len) { - return SHA512_Update(sha, data, len); +bcm_infallible BCM_sha384_update(SHA512_CTX *sha, const void *data, + size_t len) { + return BCM_sha512_update(sha, data, len); } -int SHA512_256_Update(SHA512_CTX *sha, const void *data, size_t len) { - return SHA512_Update(sha, data, len); +bcm_infallible BCM_sha512_256_update(SHA512_CTX *sha, const void *data, + size_t len) { + return BCM_sha512_update(sha, data, len); } -int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH], SHA512_CTX *sha) { - // This function must be paired with |SHA512_256_Init|, which sets - // |sha->md_len| to |SHA512_256_DIGEST_LENGTH|. - assert(sha->md_len == SHA512_256_DIGEST_LENGTH); - return sha512_final_impl(out, SHA512_256_DIGEST_LENGTH, sha); +bcm_infallible BCM_sha512_256_final(uint8_t out[BCM_SHA512_256_DIGEST_LENGTH], + SHA512_CTX *sha) { + // This function must be paired with |BCM_sha512_256_init|, which sets + // |sha->md_len| to |BCM_SHA512_256_DIGEST_LENGTH|. + assert(sha->md_len == BCM_SHA512_256_DIGEST_LENGTH); + sha512_final_impl(out, BCM_SHA512_256_DIGEST_LENGTH, sha); + return bcm_infallible_approved; } -void SHA512_Transform(SHA512_CTX *c, const uint8_t block[SHA512_CBLOCK]) { +bcm_infallible BCM_sha512_transform(SHA512_CTX *c, + const uint8_t block[SHA512_CBLOCK]) { sha512_block_data_order(c->h, block, 1); + return bcm_infallible_approved; } -int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) { +bcm_infallible BCM_sha512_update(SHA512_CTX *c, const void *in_data, + size_t len) { uint64_t l; uint8_t *p = c->p; const uint8_t *data = in_data; if (len == 0) { - return 1; + return bcm_infallible_approved; } l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff); @@ -232,19 +210,21 @@ c->num = (int)len; } - return 1; + return bcm_infallible_approved; } -int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], SHA512_CTX *sha) { - // Ideally we would assert |sha->md_len| is |SHA512_DIGEST_LENGTH| to match - // the size hint, but calling code often pairs |SHA384_Init| with - // |SHA512_Final| and expects |sha->md_len| to carry the size over. +bcm_infallible BCM_sha512_final(uint8_t out[BCM_SHA512_DIGEST_LENGTH], + SHA512_CTX *sha) { + // Ideally we would assert |sha->md_len| is |BCM_SHA512_DIGEST_LENGTH| to + // match the size hint, but calling code often pairs |BCM_sha384_init| with + // |BCM_sha512_final| and expects |sha->md_len| to carry the size over. // // TODO(davidben): Add an assert and fix code to match them up. - return sha512_final_impl(out, sha->md_len, sha); + sha512_final_impl(out, sha->md_len, sha); + return bcm_infallible_approved; } -static int sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha) { +static void sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha) { uint8_t *p = sha->p; size_t n = sha->num; @@ -262,12 +242,6 @@ sha512_block_data_order(sha->h, p, 1); - if (out == NULL) { - // TODO(davidben): This NULL check is absent in other low-level hash 'final' - // functions and is one of the few places one can fail. - return 0; - } - assert(md_len % 8 == 0); const size_t out_words = md_len / 8; for (size_t i = 0; i < out_words; i++) { @@ -276,7 +250,6 @@ } FIPS_service_indicator_update_state(); - return 1; } #if !defined(SHA512_ASM) @@ -423,7 +396,6 @@ int i; while (num--) { - a = state[0]; b = state[1]; c = state[2];
diff --git a/crypto/sha/sha512.c b/crypto/sha/sha512.c new file mode 100644 index 0000000..507320d --- /dev/null +++ b/crypto/sha/sha512.c
@@ -0,0 +1,104 @@ +/* Copyright (c) 2024, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <openssl/sha.h> + +#include <openssl/mem.h> + +#include "../fipsmodule/bcm_interface.h" + + +int SHA384_Init(SHA512_CTX *sha) { + BCM_sha384_init(sha); + return 1; +} + +int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len) { + BCM_sha384_update(sha, data, len); + return 1; +} + +int SHA384_Final(uint8_t out[SHA384_DIGEST_LENGTH], SHA512_CTX *sha) { + BCM_sha384_final(out, sha); + return 1; +} + +uint8_t *SHA384(const uint8_t *data, size_t len, + uint8_t out[SHA384_DIGEST_LENGTH]) { + SHA512_CTX ctx; + BCM_sha384_init(&ctx); + BCM_sha384_update(&ctx, data, len); + BCM_sha384_final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +int SHA512_256_Init(SHA512_CTX *sha) { + BCM_sha512_256_init(sha); + return 1; +} + +int SHA512_256_Update(SHA512_CTX *sha, const void *data, size_t len) { + BCM_sha512_256_update(sha, data, len); + return 1; +} + +int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH], SHA512_CTX *sha) { + BCM_sha512_256_final(out, sha); + return 1; +} + +uint8_t *SHA512_256(const uint8_t *data, size_t len, + uint8_t out[SHA512_256_DIGEST_LENGTH]) { + SHA512_CTX ctx; + BCM_sha512_256_init(&ctx); + BCM_sha512_256_update(&ctx, data, len); + BCM_sha512_256_final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +int SHA512_Init(SHA512_CTX *sha) { + BCM_sha512_init(sha); + return 1; +} + +int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len) { + BCM_sha512_update(sha, data, len); + return 1; +} + +int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], SHA512_CTX *sha) { + // Historically this function retured failure if passed NULL, even + // though other final functions do not. + if (out == NULL) { + return 0; + } + BCM_sha512_final(out, sha); + return 1; +} + +uint8_t *SHA512(const uint8_t *data, size_t len, + uint8_t out[SHA512_DIGEST_LENGTH]) { + SHA512_CTX ctx; + BCM_sha512_init(&ctx); + BCM_sha512_update(&ctx, data, len); + BCM_sha512_final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +void SHA512_Transform(SHA512_CTX *sha, const uint8_t block[SHA512_CBLOCK]) { + BCM_sha512_transform(sha, block); +}
diff --git a/gen/sources.bzl b/gen/sources.bzl index 1eef089..1ca1a8b 100644 --- a/gen/sources.bzl +++ b/gen/sources.bzl
@@ -400,6 +400,7 @@ "crypto/rsa_extra/rsa_print.c", "crypto/sha/sha1.c", "crypto/sha/sha256.c", + "crypto/sha/sha512.c", "crypto/siphash/siphash.c", "crypto/slhdsa/fors.c", "crypto/slhdsa/merkle.c",
diff --git a/gen/sources.cmake b/gen/sources.cmake index 9335959..94b6195 100644 --- a/gen/sources.cmake +++ b/gen/sources.cmake
@@ -414,6 +414,7 @@ crypto/rsa_extra/rsa_print.c crypto/sha/sha1.c crypto/sha/sha256.c + crypto/sha/sha512.c crypto/siphash/siphash.c crypto/slhdsa/fors.c crypto/slhdsa/merkle.c
diff --git a/gen/sources.gni b/gen/sources.gni index 36b50c8..131de07 100644 --- a/gen/sources.gni +++ b/gen/sources.gni
@@ -400,6 +400,7 @@ "crypto/rsa_extra/rsa_print.c", "crypto/sha/sha1.c", "crypto/sha/sha256.c", + "crypto/sha/sha512.c", "crypto/siphash/siphash.c", "crypto/slhdsa/fors.c", "crypto/slhdsa/merkle.c",
diff --git a/gen/sources.json b/gen/sources.json index 9587ab2..f5879cd 100644 --- a/gen/sources.json +++ b/gen/sources.json
@@ -384,6 +384,7 @@ "crypto/rsa_extra/rsa_print.c", "crypto/sha/sha1.c", "crypto/sha/sha256.c", + "crypto/sha/sha512.c", "crypto/siphash/siphash.c", "crypto/slhdsa/fors.c", "crypto/slhdsa/merkle.c",
diff --git a/include/openssl/bcm_public.h b/include/openssl/bcm_public.h index 9bb0dbb..ac594ea 100644 --- a/include/openssl/bcm_public.h +++ b/include/openssl/bcm_public.h
@@ -64,6 +64,16 @@ unsigned num, md_len; }; +// BCM_SHA512_CBLOCK is the block size of SHA-512. +#define BCM_SHA512_CBLOCK 128 + +struct sha512_state_st { + uint64_t h[8]; + uint64_t Nl, Nh; + uint8_t p[BCM_SHA512_CBLOCK]; + unsigned num, md_len; +}; + #if defined(__cplusplus) } // extern C
diff --git a/include/openssl/sha.h b/include/openssl/sha.h index bfaeb78..d70f33c 100644 --- a/include/openssl/sha.h +++ b/include/openssl/sha.h
@@ -240,14 +240,6 @@ OPENSSL_EXPORT void SHA512_Transform(SHA512_CTX *sha, const uint8_t block[SHA512_CBLOCK]); -struct sha512_state_st { - uint64_t h[8]; - uint64_t Nl, Nh; - uint8_t p[128]; - unsigned num, md_len; -}; - - // SHA-512-256 // // See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6