diff --git a/Package.swift b/Package.swift index 3d8b3ef7..e4823ca3 100644 --- a/Package.swift +++ b/Package.swift @@ -20,7 +20,7 @@ // Sources/CCryptoBoringSSL directory. The source repository is at // https://boringssl.googlesource.com/boringssl. // -// BoringSSL Commit: 6a2ccdcc2ed1d37a43a2183658d2ae61fd5ce208 +// BoringSSL Commit: 76968bb3d53982560bcf08bcd0ba3e1865fe15cd import PackageDescription diff --git a/Sources/CCryptoBoringSSL/CMakeLists.txt b/Sources/CCryptoBoringSSL/CMakeLists.txt index 07be1e7a..3eea1dfa 100644 --- a/Sources/CCryptoBoringSSL/CMakeLists.txt +++ b/Sources/CCryptoBoringSSL/CMakeLists.txt @@ -165,9 +165,17 @@ add_library(CCryptoBoringSSL STATIC "crypto/refcount.c" "crypto/rsa_extra/rsa_asn1.c" "crypto/rsa_extra/rsa_crypt.c" + "crypto/rsa_extra/rsa_extra.c" "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" + "crypto/slhdsa/slhdsa.c" + "crypto/slhdsa/thash.c" + "crypto/slhdsa/wots.c" "crypto/spx/spx.c" "crypto/spx/spx_address.c" "crypto/spx/spx_fors.c" diff --git a/Sources/CCryptoBoringSSL/crypto/bcm_support.h b/Sources/CCryptoBoringSSL/crypto/bcm_support.h index 9556c17f..fe5d712a 100644 --- a/Sources/CCryptoBoringSSL/crypto/bcm_support.h +++ b/Sources/CCryptoBoringSSL/crypto/bcm_support.h @@ -17,6 +17,8 @@ #include +#include + // Provided by libcrypto, called from BCM #if defined(__cplusplus) @@ -105,6 +107,10 @@ OPENSSL_EXPORT uint64_t CRYPTO_get_fork_generation(void); OPENSSL_EXPORT void CRYPTO_fork_detect_force_madv_wipeonfork_for_testing( int on); +// CRYPTO_get_stderr returns stderr. This function exists to avoid BCM needing +// a data dependency on libc. +FILE *CRYPTO_get_stderr(void); + #if defined(__cplusplus) } // extern C diff --git a/Sources/CCryptoBoringSSL/crypto/cipher_extra/e_tls.c b/Sources/CCryptoBoringSSL/crypto/cipher_extra/e_tls.c index 035f45ad..5dc66a9d 100644 --- a/Sources/CCryptoBoringSSL/crypto/cipher_extra/e_tls.c +++ b/Sources/CCryptoBoringSSL/crypto/cipher_extra/e_tls.c @@ -442,6 +442,7 @@ static int aead_tls_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; const size_t iv_len = EVP_CIPHER_CTX_iv_length(&tls_ctx->cipher_ctx); if (iv_len <= 1) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/crypto.c b/Sources/CCryptoBoringSSL/crypto/crypto.c index 9a4f440e..2a86d115 100644 --- a/Sources/CCryptoBoringSSL/crypto/crypto.c +++ b/Sources/CCryptoBoringSSL/crypto/crypto.c @@ -15,6 +15,7 @@ #include #include +#include #include "fipsmodule/rand/internal.h" #include "bcm_support.h" @@ -186,3 +187,5 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { } void OPENSSL_cleanup(void) {} + +FILE *CRYPTO_get_stderr(void) { return stderr; } diff --git a/Sources/CCryptoBoringSSL/crypto/dsa/internal.h b/Sources/CCryptoBoringSSL/crypto/dsa/internal.h index 44a40934..eb537d6f 100644 --- a/Sources/CCryptoBoringSSL/crypto/dsa/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/dsa/internal.h @@ -42,8 +42,6 @@ struct dsa_st { CRYPTO_EX_DATA ex_data; }; -#define OPENSSL_DSA_MAX_MODULUS_BITS 10000 - // dsa_check_key performs cheap self-checks on |dsa|, and ensures it is within // DoS bounds. It returns one on success and zero on error. int dsa_check_key(const DSA *dsa); diff --git a/Sources/CCryptoBoringSSL/crypto/ec_extra/ec_asn1.c b/Sources/CCryptoBoringSSL/crypto/ec_extra/ec_asn1.c index 7f3aa6c0..2e6da166 100644 --- a/Sources/CCryptoBoringSSL/crypto/ec_extra/ec_asn1.c +++ b/Sources/CCryptoBoringSSL/crypto/ec_extra/ec_asn1.c @@ -478,6 +478,41 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) { return CBB_finish_i2d(&cbb, outp); } +EC_GROUP *d2i_ECPKParameters(EC_GROUP **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EC_GROUP *ret = EC_KEY_parse_parameters(&cbs); + if (ret == NULL) { + return NULL; + } + + if (out != NULL) { + EC_GROUP_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) { + if (group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + CBB cbb; + if (!CBB_init(&cbb, 0) || // + !EC_KEY_marshal_curve_name(&cbb, group)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) { if (len < 0) { return NULL; diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.c b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.c index 7cc13342..6f297b49 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.c +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.c @@ -29,6 +29,7 @@ #include #include "bcm_interface.h" +#include "../bcm_support.h" #include "../internal.h" // TODO(crbug.com/362530616): When delocate is removed, build these files as @@ -136,7 +137,7 @@ static void assert_within(const void *start, const void *symbol, } fprintf( - stderr, + CRYPTO_get_stderr(), "FIPS module doesn't span expected symbol. Expected %p <= %p < %p\n", start, symbol, end); BORINGSSL_FIPS_abort(); @@ -194,7 +195,7 @@ int BORINGSSL_integrity_test(void) { assert_within(start, RSA_sign, end); assert_within(start, BCM_rand_bytes, end); assert_within(start, EC_GROUP_cmp, end); - assert_within(start, SHA256_Update, end); + assert_within(start, BCM_sha256_update, end); assert_within(start, ecdsa_verify_fixed, end); assert_within(start, EVP_AEAD_CTX_seal, end); @@ -224,7 +225,7 @@ int BORINGSSL_integrity_test(void) { HMAC_CTX_init(&hmac_ctx); if (!HMAC_Init_ex(&hmac_ctx, kHMACKey, sizeof(kHMACKey), kHashFunction, NULL /* no ENGINE */)) { - fprintf(stderr, "HMAC_Init_ex failed.\n"); + fprintf(CRYPTO_get_stderr(), "HMAC_Init_ex failed.\n"); return 0; } @@ -244,7 +245,7 @@ int BORINGSSL_integrity_test(void) { if (!HMAC_Final(&hmac_ctx, result, &result_len) || result_len != sizeof(result)) { - fprintf(stderr, "HMAC failed.\n"); + fprintf(CRYPTO_get_stderr(), "HMAC failed.\n"); return 0; } HMAC_CTX_cleanse(&hmac_ctx); // FIPS 140-3, AS05.10. diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h index b5461595..e087a8a2 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h @@ -98,7 +98,8 @@ bcm_infallible BCM_sha1_init(SHA_CTX *sha); // BCM_SHA1_transform is a low-level function that performs a single, SHA-1 // block transformation using the state from |sha| and |SHA_CBLOCK| bytes from // |block|. -bcm_infallible BCM_sha1_transform(SHA_CTX *c, const uint8_t data[BCM_SHA_CBLOCK]); +bcm_infallible BCM_sha1_transform(SHA_CTX *c, + const uint8_t data[BCM_SHA_CBLOCK]); // BCM_sha1_update adds |len| bytes from |data| to |sha|. bcm_infallible BCM_sha1_update(SHA_CTX *c, const void *data, size_t len); @@ -125,6 +126,117 @@ bcm_infallible BCM_fips_186_2_prf(uint8_t *out, size_t out_len, const uint8_t xkey[BCM_SHA_DIGEST_LENGTH]); +// SHA-224 + +// SHA224_DIGEST_LENGTH is the length of a SHA-224 digest. +#define BCM_SHA224_DIGEST_LENGTH 28 + +// BCM_sha224_unit initialises |sha|. +bcm_infallible BCM_sha224_init(SHA256_CTX *sha); + +// 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 +// 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], + SHA256_CTX *sha); + + +// SHA-256 + +// BCM_SHA256_DIGEST_LENGTH is the length of a SHA-256 digest. +#define BCM_SHA256_DIGEST_LENGTH 32 + +// BCM_sha256_init initialises |sha|. +bcm_infallible BCM_sha256_init(SHA256_CTX *sha); + +// BCM_sha256_update adds |len| bytes from |data| to |sha|. +bcm_infallible BCM_sha256_update(SHA256_CTX *sha, const void *data, size_t len); + +// BCM_sha256_final adds the final padding to |sha| and writes the resulting +// digest to |out|, which must have at least |BCM_SHA256_DIGEST_LENGTH| bytes of +// space. It aborts on programmer error. +bcm_infallible BCM_sha256_final(uint8_t out[BCM_SHA256_DIGEST_LENGTH], + SHA256_CTX *sha); + +// BCM_sha256_transform is a low-level function that performs a single, SHA-256 +// block transformation using the state from |sha| and |BCM_SHA256_CBLOCK| bytes +// from |block|. +bcm_infallible BCM_sha256_transform(SHA256_CTX *sha, + const uint8_t block[BCM_SHA256_CBLOCK]); + +// BCM_sha256_transform_blocks is a low-level function that takes |num_blocks| * +// |BCM_SHA256_CBLOCK| bytes of data and performs SHA-256 transforms on it to +// update |state|. +bcm_infallible BCM_sha256_transform_blocks(uint32_t state[8], + const uint8_t *data, + 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/Sources/CCryptoBoringSSL/crypto/fipsmodule/cipher/aead.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/cipher/aead.c.inc index a33916cf..4897970d 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/cipher/aead.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/cipher/aead.c.inc @@ -262,6 +262,7 @@ const EVP_AEAD *EVP_AEAD_CTX_aead(const EVP_AEAD_CTX *ctx) { return ctx->aead; } int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, size_t *out_len) { if (ctx->aead->get_iv == NULL) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/internal.h index 86daa21e..aa7ab771 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/internal.h @@ -26,8 +26,6 @@ extern "C" { #endif -#define OPENSSL_DH_MAX_MODULUS_BITS 10000 - struct dh_st { BIGNUM *p; BIGNUM *g; diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.c.inc index 817f454d..8287d5e8 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.c.inc @@ -60,7 +60,6 @@ #include #include -#include #include "internal.h" #include "../delocate.h" @@ -98,20 +97,20 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha1) { static void sha224_init(EVP_MD_CTX *ctx) { - CHECK(SHA224_Init(ctx->md_data)); + BCM_sha224_init(ctx->md_data); } static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) { - CHECK(SHA224_Update(ctx->md_data, data, count)); + BCM_sha224_update(ctx->md_data, data, count); } static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) { - CHECK(SHA224_Final(md, ctx->md_data)); + BCM_sha224_final(md, ctx->md_data); } DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) { out->type = NID_sha224; - out->md_size = SHA224_DIGEST_LENGTH; + out->md_size = BCM_SHA224_DIGEST_LENGTH; out->flags = 0; out->init = sha224_init; out->update = sha224_update; @@ -122,20 +121,20 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) { static void sha256_init(EVP_MD_CTX *ctx) { - CHECK(SHA256_Init(ctx->md_data)); + BCM_sha256_init(ctx->md_data); } static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) { - CHECK(SHA256_Update(ctx->md_data, data, count)); + BCM_sha256_update(ctx->md_data, data, count); } static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) { - CHECK(SHA256_Final(md, ctx->md_data)); + BCM_sha256_final(md, ctx->md_data); } DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha256) { out->type = NID_sha256; - out->md_size = SHA256_DIGEST_LENGTH; + out->md_size = BCM_SHA256_DIGEST_LENGTH; out->flags = 0; out->init = sha256_init; out->update = sha256_update; @@ -146,20 +145,20 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha256) { 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 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) { 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 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512) { 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/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec_key.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec_key.c.inc index 249588fb..047e154c 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec_key.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec_key.c.inc @@ -75,7 +75,6 @@ #include #include #include -#include #include #include "internal.h" @@ -346,7 +345,7 @@ int EC_KEY_check_fips(const EC_KEY *key) { } if (key->priv_key) { - uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + uint8_t digest[BCM_SHA256_DIGEST_LENGTH] = {0}; uint8_t sig[ECDSA_MAX_FIXED_LEN]; size_t sig_len; if (!ecdsa_sign_fixed(digest, sizeof(digest), sig, &sig_len, sizeof(sig), diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ecdh/ecdh.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ecdh/ecdh.c.inc index 323aebef..711065d1 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ecdh/ecdh.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ecdh/ecdh.c.inc @@ -72,7 +72,6 @@ #include #include #include -#include #include "../../internal.h" #include "../ec/internal.h" @@ -105,18 +104,28 @@ int ECDH_compute_key_fips(uint8_t *out, size_t out_len, const EC_POINT *pub_key, } FIPS_service_indicator_lock_state(); + SHA256_CTX ctx; + SHA512_CTX ctx_512; switch (out_len) { case SHA224_DIGEST_LENGTH: - SHA224(buf, buflen, out); + BCM_sha224_init(&ctx); + BCM_sha224_update(&ctx, buf, buflen); + BCM_sha224_final(out, &ctx); break; case SHA256_DIGEST_LENGTH: - SHA256(buf, buflen, out); + BCM_sha256_init(&ctx); + BCM_sha256_update(&ctx, buf, buflen); + BCM_sha256_final(out, &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/Sources/CCryptoBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c.inc index 5065f2a8..928fc56a 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ecdsa/ecdsa.c.inc @@ -58,7 +58,6 @@ #include #include #include -#include #include "../../internal.h" #include "../bn/internal.h" @@ -268,17 +267,17 @@ int ecdsa_sign_fixed(const uint8_t *digest, size_t digest_len, uint8_t *sig, // 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/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.c.inc index 38ed6857..ea223b02 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.c.inc @@ -275,7 +275,7 @@ static void rand_get_seed(struct rand_thread_state *state, // rate of failure is small enough not to be a problem in practice. if (CRYPTO_memcmp(state->last_block, entropy, sizeof(state->last_block)) == 0) { - fprintf(stderr, "CRNGT failed.\n"); + fprintf(CRYPTO_get_stderr(), "CRNGT failed.\n"); BORINGSSL_FIPS_abort(); } @@ -283,7 +283,7 @@ static void rand_get_seed(struct rand_thread_state *state, for (size_t i = CRNGT_BLOCK_SIZE; i < entropy_len; i += CRNGT_BLOCK_SIZE) { if (CRYPTO_memcmp(entropy + i - CRNGT_BLOCK_SIZE, entropy + i, CRNGT_BLOCK_SIZE) == 0) { - fprintf(stderr, "CRNGT failed.\n"); + fprintf(CRYPTO_get_stderr(), "CRNGT failed.\n"); BORINGSSL_FIPS_abort(); } } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.c.inc index 1ac8b31b..1db38910 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.c.inc @@ -63,7 +63,6 @@ #include #include #include -#include #include "internal.h" #include "../service_indicator/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.c.inc index eea8988b..8cd87d1c 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.c.inc @@ -68,7 +68,6 @@ #include #include #include -#include #include #include "../bn/internal.h" @@ -487,28 +486,28 @@ static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = { }, { NID_sha224, - SHA224_DIGEST_LENGTH, + BCM_SHA224_DIGEST_LENGTH, 19, {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c}, }, { NID_sha256, - SHA256_DIGEST_LENGTH, + BCM_SHA256_DIGEST_LENGTH, 19, {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}, }, { 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/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c.inc index c13d979f..a2f04998 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.c.inc @@ -79,10 +79,8 @@ int rsa_check_public_key(const RSA *rsa) { return 0; } - // TODO(davidben): 16384-bit RSA is huge. Can we bring this down to a limit of - // 8192-bit? unsigned n_bits = BN_num_bits(rsa->n); - if (n_bits > 16 * 1024) { + if (n_bits > OPENSSL_RSA_MAX_MODULUS_BITS) { OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.c.inc index 8b63d0b8..9e7fd53f 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.c.inc @@ -32,6 +32,7 @@ #include #include +#include "../../bcm_support.h" #include "../../internal.h" #include "../delocate.h" #include "../dh/internal.h" @@ -53,21 +54,22 @@ int BORINGSSL_self_test(void) { #else -static void hexdump(const uint8_t *in, size_t len) { +static void hexdump(FILE *out, const uint8_t *in, size_t len) { for (size_t i = 0; i < len; i++) { - fprintf(stderr, "%02x", in[i]); + fprintf(out, "%02x", in[i]); } } static int check_test(const void *expected, const void *actual, size_t expected_len, const char *name) { if (OPENSSL_memcmp(actual, expected, expected_len) != 0) { - fprintf(stderr, "%s failed.\nExpected: ", name); - hexdump(expected, expected_len); - fprintf(stderr, "\nCalculated: "); - hexdump(actual, expected_len); - fprintf(stderr, "\n"); - fflush(stderr); + FILE *err = CRYPTO_get_stderr(); + fprintf(err, "%s failed.\nExpected: ", name); + hexdump(err, expected, expected_len); + fprintf(err, "\nCalculated: "); + hexdump(err, actual, expected_len); + fprintf(err, "\n"); + fflush(err); return 0; } return 1; @@ -294,7 +296,7 @@ static int boringssl_self_test_rsa(void) { RSA *const rsa_key = self_test_rsa_key(); if (rsa_key == NULL) { - fprintf(stderr, "RSA key construction failed\n"); + fprintf(CRYPTO_get_stderr(), "RSA key construction failed\n"); goto err; } // Disable blinding for the power-on tests because it's not needed and @@ -338,7 +340,7 @@ static int boringssl_self_test_rsa(void) { output, &sig_len, rsa_key) || !check_test(kRSASignSignature, output, sizeof(kRSASignSignature), "RSA-sign KAT")) { - fprintf(stderr, "RSA signing test failed.\n"); + fprintf(CRYPTO_get_stderr(), "RSA signing test failed.\n"); goto err; } @@ -376,7 +378,7 @@ static int boringssl_self_test_rsa(void) { if (!rsa_verify_no_self_test(NID_sha256, kRSAVerifyDigest, sizeof(kRSAVerifyDigest), kRSAVerifySignature, sizeof(kRSAVerifySignature), rsa_key)) { - fprintf(stderr, "RSA-verify KAT failed.\n"); + fprintf(CRYPTO_get_stderr(), "RSA-verify KAT failed.\n"); goto err; } @@ -397,7 +399,7 @@ static int boringssl_self_test_ecc(void) { ec_key = self_test_ecdsa_key(); if (ec_key == NULL) { - fprintf(stderr, "ECDSA KeyGen failed\n"); + fprintf(CRYPTO_get_stderr(), "ECDSA KeyGen failed\n"); goto err; } @@ -429,7 +431,7 @@ static int boringssl_self_test_ecc(void) { sizeof(ecdsa_k)) || !check_test(kECDSASignSig, ecdsa_sign_output, sizeof(ecdsa_sign_output), "ECDSA-sign signature")) { - fprintf(stderr, "ECDSA-sign KAT failed.\n"); + fprintf(CRYPTO_get_stderr(), "ECDSA-sign KAT failed.\n"); goto err; } @@ -450,7 +452,7 @@ static int boringssl_self_test_ecc(void) { if (!ecdsa_verify_fixed_no_self_test( kECDSAVerifyDigest, sizeof(kECDSAVerifyDigest), kECDSAVerifySig, sizeof(kECDSAVerifySig), ec_key)) { - fprintf(stderr, "ECDSA-verify KAT failed.\n"); + fprintf(CRYPTO_get_stderr(), "ECDSA-verify KAT failed.\n"); goto err; } @@ -496,7 +498,7 @@ static int boringssl_self_test_ecc(void) { z_comp_result, sizeof(z_comp_result), NULL) || !check_test(kP256PointResult, z_comp_result, sizeof(z_comp_result), "Z Computation Result")) { - fprintf(stderr, "Z-computation KAT failed.\n"); + fprintf(CRYPTO_get_stderr(), "Z-computation KAT failed.\n"); goto err; } @@ -575,7 +577,7 @@ static int boringssl_self_test_ffdh(void) { dh_compute_key_padded_no_self_test(dh_out, ffdhe2048_value, dh) != sizeof(dh_out) || !check_test(kDHOutput, dh_out, sizeof(dh_out), "FFC DH")) { - fprintf(stderr, "FFDH failed.\n"); + fprintf(CRYPTO_get_stderr(), "FFDH failed.\n"); goto err; } @@ -723,7 +725,7 @@ static int boringssl_self_test_fast(void) { }; memcpy(aes_iv, kAESIV, sizeof(kAESIV)); if (AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { - fprintf(stderr, "AES_set_encrypt_key failed.\n"); + fprintf(CRYPTO_get_stderr(), "AES_set_encrypt_key failed.\n"); goto err; } AES_cbc_encrypt(kAESCBCEncPlaintext, output, sizeof(kAESCBCEncPlaintext), @@ -746,7 +748,7 @@ static int boringssl_self_test_fast(void) { }; memcpy(aes_iv, kAESIV, sizeof(kAESIV)); if (AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { - fprintf(stderr, "AES_set_decrypt_key failed.\n"); + fprintf(CRYPTO_get_stderr(), "AES_set_decrypt_key failed.\n"); goto err; } AES_cbc_encrypt(kAESCBCDecCiphertext, output, sizeof(kAESCBCDecCiphertext), @@ -761,7 +763,7 @@ static int boringssl_self_test_fast(void) { OPENSSL_memset(nonce, 0, sizeof(nonce)); if (!EVP_AEAD_CTX_init(&aead_ctx, EVP_aead_aes_128_gcm(), kAESKey, sizeof(kAESKey), 0, NULL)) { - fprintf(stderr, "EVP_AEAD_CTX_init for AES-128-GCM failed.\n"); + fprintf(CRYPTO_get_stderr(), "EVP_AEAD_CTX_init for AES-128-GCM failed.\n"); goto err; } @@ -783,7 +785,7 @@ static int boringssl_self_test_fast(void) { 0) || !check_test(kAESGCMCiphertext, output, sizeof(kAESGCMCiphertext), "AES-GCM-encrypt KAT")) { - fprintf(stderr, "EVP_AEAD_CTX_seal for AES-128-GCM failed.\n"); + fprintf(CRYPTO_get_stderr(), "EVP_AEAD_CTX_seal for AES-128-GCM failed.\n"); goto err; } @@ -806,7 +808,7 @@ static int boringssl_self_test_fast(void) { NULL, 0) || !check_test(kAESGCMDecPlaintext, output, sizeof(kAESGCMDecPlaintext), "AES-GCM-decrypt KAT")) { - fprintf(stderr, + fprintf(CRYPTO_get_stderr(), "AES-GCM-decrypt KAT failed because EVP_AEAD_CTX_open failed.\n"); goto err; } @@ -875,7 +877,7 @@ static int boringssl_self_test_fast(void) { sizeof(kDRBGAD)) || !check_test(kDRBGReseedOutput, output, sizeof(kDRBGReseedOutput), "DRBG-reseed KAT")) { - fprintf(stderr, "CTR-DRBG failed.\n"); + fprintf(CRYPTO_get_stderr(), "CTR-DRBG failed.\n"); goto err; } CTR_DRBG_clear(&drbg); @@ -914,7 +916,7 @@ static int boringssl_self_test_fast(void) { kTLSSeed2, sizeof(kTLSSeed2)) || !check_test(kTLS10Output, tls10_output, sizeof(kTLS10Output), "TLS10-KDF KAT")) { - fprintf(stderr, "TLS KDF failed.\n"); + fprintf(CRYPTO_get_stderr(), "TLS KDF failed.\n"); goto err; } @@ -935,7 +937,7 @@ static int boringssl_self_test_fast(void) { kTLSSeed2, sizeof(kTLSSeed2)) || !check_test(kTLS12Output, tls12_output, sizeof(kTLS12Output), "TLS12-KDF KAT")) { - fprintf(stderr, "TLS KDF failed.\n"); + fprintf(CRYPTO_get_stderr(), "TLS KDF failed.\n"); goto err; } @@ -975,7 +977,7 @@ static int boringssl_self_test_fast(void) { !check_test(kTLS13ExpandLabelOutput, tls13_expand_label_output, sizeof(kTLS13ExpandLabelOutput), "CRYPTO_tls13_hkdf_expand_label")) { - fprintf(stderr, "TLS13-KDF failed.\n"); + fprintf(CRYPTO_get_stderr(), "TLS13-KDF failed.\n"); goto err; } @@ -1005,7 +1007,7 @@ static int boringssl_self_test_fast(void) { sizeof(kHKDFSecret), kHKDFSalt, sizeof(kHKDFSalt), kHKDFInfo, sizeof(kHKDFInfo)) || !check_test(kHKDFOutput, hkdf_output, sizeof(kHKDFOutput), "HKDF")) { - fprintf(stderr, "HKDF failed.\n"); + fprintf(CRYPTO_get_stderr(), "HKDF failed.\n"); goto err; } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha256.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha256.c.inc index 25bf3c11..68af74ed 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha256.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha256.c.inc @@ -54,19 +54,18 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -#include - #include #include #include "../../internal.h" +#include "../bcm_interface.h" #include "../digest/md32_common.h" #include "../service_indicator/internal.h" #include "internal.h" -int SHA224_Init(SHA256_CTX *sha) { +bcm_infallible BCM_sha224_init(SHA256_CTX *sha) { OPENSSL_memset(sha, 0, sizeof(SHA256_CTX)); sha->h[0] = 0xc1059ed8UL; sha->h[1] = 0x367cd507UL; @@ -76,11 +75,11 @@ int SHA224_Init(SHA256_CTX *sha) { sha->h[5] = 0x68581511UL; sha->h[6] = 0x64f98fa7UL; sha->h[7] = 0xbefa4fa4UL; - sha->md_len = SHA224_DIGEST_LENGTH; - return 1; + sha->md_len = BCM_SHA224_DIGEST_LENGTH; + return bcm_infallible_approved; } -int SHA256_Init(SHA256_CTX *sha) { +bcm_infallible BCM_sha256_init(SHA256_CTX *sha) { OPENSSL_memset(sha, 0, sizeof(SHA256_CTX)); sha->h[0] = 0x6a09e667UL; sha->h[1] = 0xbb67ae85UL; @@ -90,28 +89,8 @@ int SHA256_Init(SHA256_CTX *sha) { sha->h[5] = 0x9b05688cUL; sha->h[6] = 0x1f83d9abUL; sha->h[7] = 0x5be0cd19UL; - sha->md_len = SHA256_DIGEST_LENGTH; - return 1; -} - -uint8_t *SHA224(const uint8_t *data, size_t len, - uint8_t out[SHA224_DIGEST_LENGTH]) { - SHA256_CTX ctx; - SHA224_Init(&ctx); - SHA224_Update(&ctx, data, len); - SHA224_Final(out, &ctx); - OPENSSL_cleanse(&ctx, sizeof(ctx)); - return out; -} - -uint8_t *SHA256(const uint8_t *data, size_t len, - uint8_t out[SHA256_DIGEST_LENGTH]) { - SHA256_CTX ctx; - SHA256_Init(&ctx); - SHA256_Update(&ctx, data, len); - SHA256_Final(out, &ctx); - OPENSSL_cleanse(&ctx, sizeof(ctx)); - return out; + sha->md_len = BCM_SHA256_DIGEST_LENGTH; + return bcm_infallible_approved; } #if !defined(SHA256_ASM) @@ -119,31 +98,28 @@ static void sha256_block_data_order(uint32_t state[8], const uint8_t *in, size_t num); #endif -void SHA256_Transform(SHA256_CTX *c, const uint8_t data[SHA256_CBLOCK]) { +bcm_infallible BCM_sha256_transform(SHA256_CTX *c, + const uint8_t data[BCM_SHA256_CBLOCK]) { sha256_block_data_order(c->h, data, 1); + return bcm_infallible_approved; } -int SHA256_Update(SHA256_CTX *c, const void *data, size_t len) { - crypto_md32_update(&sha256_block_data_order, c->h, c->data, SHA256_CBLOCK, +bcm_infallible BCM_sha256_update(SHA256_CTX *c, const void *data, size_t len) { + crypto_md32_update(&sha256_block_data_order, c->h, c->data, BCM_SHA256_CBLOCK, &c->num, &c->Nh, &c->Nl, data, len); - return 1; + return bcm_infallible_approved; } -int SHA224_Update(SHA256_CTX *ctx, const void *data, size_t len) { - return SHA256_Update(ctx, data, len); +bcm_infallible BCM_sha224_update(SHA256_CTX *ctx, const void *data, + size_t len) { + return BCM_sha256_update(ctx, data, len); } -static int sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) { - crypto_md32_final(&sha256_block_data_order, c->h, c->data, SHA256_CBLOCK, +static void sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) { + crypto_md32_final(&sha256_block_data_order, c->h, c->data, BCM_SHA256_CBLOCK, &c->num, c->Nh, c->Nl, /*is_big_endian=*/1); - // TODO(davidben): This overflow check one of the few places a low-level hash - // 'final' function can fail. SHA-512 does not have a corresponding check. - // These functions already misbehave if the caller arbitrarily mutates |c|, so - // can we assume one of |SHA256_Init| or |SHA224_Init| was used? - if (md_len > SHA256_DIGEST_LENGTH) { - return 0; - } + BSSL_CHECK(md_len <= BCM_SHA256_DIGEST_LENGTH); assert(md_len % 4 == 0); const size_t out_words = md_len / 4; @@ -153,23 +129,26 @@ static int sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) { } FIPS_service_indicator_update_state(); - return 1; } -int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], SHA256_CTX *c) { - // Ideally we would assert |sha->md_len| is |SHA256_DIGEST_LENGTH| to match - // the size hint, but calling code often pairs |SHA224_Init| with +bcm_infallible BCM_sha256_final(uint8_t out[BCM_SHA256_DIGEST_LENGTH], + SHA256_CTX *c) { + // Ideally we would assert |sha->md_len| is |BCM_SHA256_DIGEST_LENGTH| to + // match the size hint, but calling code often pairs |SHA224_Init| with // |SHA256_Final| and expects |sha->md_len| to carry the size over. // // TODO(davidben): Add an assert and fix code to match them up. - return sha256_final_impl(out, c->md_len, c); + sha256_final_impl(out, c->md_len, c); + return bcm_infallible_approved; } -int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], SHA256_CTX *ctx) { +bcm_infallible BCM_sha224_final(uint8_t out[BCM_SHA224_DIGEST_LENGTH], + SHA256_CTX *ctx) { // This function must be paired with |SHA224_Init|, which sets |ctx->md_len| - // to |SHA224_DIGEST_LENGTH|. - assert(ctx->md_len == SHA224_DIGEST_LENGTH); - return sha256_final_impl(out, SHA224_DIGEST_LENGTH, ctx); + // to |BCM_SHA224_DIGEST_LENGTH|. + assert(ctx->md_len == BCM_SHA224_DIGEST_LENGTH); + sha256_final_impl(out, BCM_SHA224_DIGEST_LENGTH, ctx); + return bcm_infallible_approved; } #if !defined(SHA256_ASM) @@ -344,9 +323,11 @@ static void sha256_block_data_order(uint32_t state[8], const uint8_t *data, #endif // !defined(SHA256_ASM) -void SHA256_TransformBlocks(uint32_t state[8], const uint8_t *data, - size_t num_blocks) { +bcm_infallible BCM_sha256_transform_blocks(uint32_t state[8], + const uint8_t *data, + size_t num_blocks) { sha256_block_data_order(state, data, num_blocks); + return bcm_infallible_approved; } #undef Sigma0 diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.c.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.c.inc index ea73199d..59708ede 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.c.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.c.inc @@ -54,13 +54,12 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -#include - #include #include #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 @@ int SHA384_Init(SHA512_CTX *sha) { 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 @@ int SHA512_Init(SHA512_CTX *sha) { 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 @@ int SHA512_256_Init(SHA512_CTX *sha) { 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 @@ static void sha512_block_data_order(uint64_t state[8], const uint8_t *in, #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 @@ int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) { 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 @@ static int sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha) { 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 @@ static int sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha) { } FIPS_service_indicator_update_state(); - return 1; } #if !defined(SHA512_ASM) @@ -423,7 +396,6 @@ static void sha512_block_data_order_nohw(uint64_t state[8], const uint8_t *in, int i; while (num--) { - a = state[0]; b = state[1]; c = state[2]; diff --git a/Sources/CCryptoBoringSSL/crypto/internal.h b/Sources/CCryptoBoringSSL/crypto/internal.h index a742ef6b..a24dedaa 100644 --- a/Sources/CCryptoBoringSSL/crypto/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/internal.h @@ -1093,6 +1093,17 @@ static inline void *OPENSSL_memset(void *dst, int c, size_t n) { // endianness. They use |memcpy|, and so avoid alignment or strict aliasing // requirements on the input and output pointers. +static inline uint16_t CRYPTO_load_u16_be(const void *in) { + uint16_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return CRYPTO_bswap2(v); +} + +static inline void CRYPTO_store_u16_be(void *out, uint16_t v) { + v = CRYPTO_bswap2(v); + OPENSSL_memcpy(out, &v, sizeof(v)); +} + static inline uint32_t CRYPTO_load_u32_le(const void *in) { uint32_t v; OPENSSL_memcpy(&v, in, sizeof(v)); diff --git a/Sources/CCryptoBoringSSL/crypto/rsa_extra/rsa_extra.c b/Sources/CCryptoBoringSSL/crypto/rsa_extra/rsa_extra.c new file mode 100644 index 00000000..1558c7ea --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/rsa_extra/rsa_extra.c @@ -0,0 +1,17 @@ +/* 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 + +void RSA_blinding_off(RSA *rsa) {} diff --git a/Sources/CCryptoBoringSSL/crypto/sha/sha256.c b/Sources/CCryptoBoringSSL/crypto/sha/sha256.c new file mode 100644 index 00000000..90838110 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/sha/sha256.c @@ -0,0 +1,87 @@ +/* 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 + +#include + +#include "../fipsmodule/bcm_interface.h" + + +int SHA224_Init(SHA256_CTX *sha) { + BCM_sha224_init(sha); + return 1; +} + +int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len) { + BCM_sha224_update(sha, data, len); + return 1; +} + +int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], SHA256_CTX *sha) { + BCM_sha224_final(out, sha); + return 1; +} + +uint8_t *SHA224(const uint8_t *data, size_t len, + uint8_t out[SHA224_DIGEST_LENGTH]) { + SHA256_CTX ctx; + BCM_sha224_init(&ctx); + BCM_sha224_update(&ctx, data, len); + BCM_sha224_final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +int SHA256_Init(SHA256_CTX *sha) { + BCM_sha256_init(sha); + return 1; +} + +int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len) { + BCM_sha256_update(sha, data, len); + return 1; +} + +int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], SHA256_CTX *sha) { + // TODO(bbe): This overflow check one of the few places a low-level hash + // 'final' function can fail. SHA-512 does not have a corresponding check. + // The BCM function is infallible and will abort if this is done incorrectly. + // we should verify nothing crashes with this removed and eliminate the 0 + // return. + if (sha->md_len > SHA256_DIGEST_LENGTH) { + return 0; + } + BCM_sha256_final(out, sha); + return 1; +} + +uint8_t *SHA256(const uint8_t *data, size_t len, + uint8_t out[SHA256_DIGEST_LENGTH]) { + SHA256_CTX ctx; + BCM_sha256_init(&ctx); + BCM_sha256_update(&ctx, data, len); + BCM_sha256_final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +void SHA256_Transform(SHA256_CTX *sha, const uint8_t block[SHA256_CBLOCK]) { + BCM_sha256_transform(sha, block); +} + +void SHA256_TransformBlocks(uint32_t state[8], const uint8_t *data, + size_t num_blocks) { + BCM_sha256_transform_blocks(state, data, num_blocks); +} diff --git a/Sources/CCryptoBoringSSL/crypto/sha/sha512.c b/Sources/CCryptoBoringSSL/crypto/sha/sha512.c new file mode 100644 index 00000000..a80aa47e --- /dev/null +++ b/Sources/CCryptoBoringSSL/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 + +#include + +#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/Sources/CCryptoBoringSSL/crypto/slhdsa/address.h b/Sources/CCryptoBoringSSL/crypto/slhdsa/address.h new file mode 100644 index 00000000..7d21e8be --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/address.h @@ -0,0 +1,123 @@ +/* Copyright (c) 2024, Google LLC + * + * 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. */ + +#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_ADDRESS_H +#define OPENSSL_HEADER_CRYPTO_SLHDSA_ADDRESS_H + +#include + +#include "../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Offsets of various fields in the address structure for SLH-DSA-SHA2-128s. + +// The byte used to specify the Merkle tree layer. +#define SLHDSA_SHA2_128S_OFFSET_LAYER 0 + +// The start of the 8 byte field used to specify the tree. +#define SLHDSA_SHA2_128S_OFFSET_TREE 1 + +// The byte used to specify the hash type (reason). +#define SLHDSA_SHA2_128S_OFFSET_TYPE 9 + +// The high byte used to specify the key pair (which one-time signature). +#define SLHDSA_SHA2_128S_OFFSET_KP_ADDR2 12 + +// The low byte used to specific the key pair. +#define SLHDSA_SHA2_128S_OFFSET_KP_ADDR1 13 + +// The byte used to specify the chain address (which Winternitz chain). +#define SLHDSA_SHA2_128S_OFFSET_CHAIN_ADDR 17 + +// The byte used to specify the hash address (where in the Winternitz chain). +#define SLHDSA_SHA2_128S_OFFSET_HASH_ADDR 21 + +// The byte used to specify the height of this node in the FORS or Merkle tree. +#define SLHDSA_SHA2_128S_OFFSET_TREE_HGT 17 + +// The start of the 4 byte field used to specify the node in the FORS or Merkle +// tree. +#define SLHDSA_SHA2_128S_OFFSET_TREE_INDEX 18 + + +OPENSSL_INLINE void slhdsa_set_chain_addr(uint8_t addr[32], uint32_t chain) { + addr[SLHDSA_SHA2_128S_OFFSET_CHAIN_ADDR] = (uint8_t)chain; +} + +OPENSSL_INLINE void slhdsa_set_hash_addr(uint8_t addr[32], uint32_t hash) { + addr[SLHDSA_SHA2_128S_OFFSET_HASH_ADDR] = (uint8_t)hash; +} + +OPENSSL_INLINE void slhdsa_set_keypair_addr(uint8_t addr[32], + uint32_t keypair) { + addr[SLHDSA_SHA2_128S_OFFSET_KP_ADDR2] = (uint8_t)(keypair >> 8); + addr[SLHDSA_SHA2_128S_OFFSET_KP_ADDR1] = (uint8_t)keypair; +} + +OPENSSL_INLINE void slhdsa_copy_keypair_addr(uint8_t out[32], + const uint8_t in[32]) { + OPENSSL_memcpy(out, in, SLHDSA_SHA2_128S_OFFSET_TREE + 8); + out[SLHDSA_SHA2_128S_OFFSET_KP_ADDR2] = in[SLHDSA_SHA2_128S_OFFSET_KP_ADDR2]; + out[SLHDSA_SHA2_128S_OFFSET_KP_ADDR1] = in[SLHDSA_SHA2_128S_OFFSET_KP_ADDR1]; +} + +OPENSSL_INLINE void slhdsa_set_layer_addr(uint8_t addr[32], uint32_t layer) { + addr[SLHDSA_SHA2_128S_OFFSET_LAYER] = (uint8_t)layer; +} + +OPENSSL_INLINE void slhdsa_set_tree_addr(uint8_t addr[32], uint64_t tree) { + CRYPTO_store_u64_be(&addr[SLHDSA_SHA2_128S_OFFSET_TREE], tree); +} + +#define SLHDSA_SHA2_128S_ADDR_TYPE_WOTS 0 +#define SLHDSA_SHA2_128S_ADDR_TYPE_WOTSPK 1 +#define SLHDSA_SHA2_128S_ADDR_TYPE_HASHTREE 2 +#define SLHDSA_SHA2_128S_ADDR_TYPE_FORSTREE 3 +#define SLHDSA_SHA2_128S_ADDR_TYPE_FORSPK 4 +#define SLHDSA_SHA2_128S_ADDR_TYPE_WOTSPRF 5 +#define SLHDSA_SHA2_128S_ADDR_TYPE_FORSPRF 6 + +OPENSSL_INLINE void slhdsa_set_type(uint8_t addr[32], uint32_t type) { + // FIPS 205 relies on this setting parts of the address to 0, so we do it + // here to avoid confusion. + // + // The behavior here is only correct for the SHA-2 instantiations. + OPENSSL_memset(addr + 10, 0, 12); + addr[SLHDSA_SHA2_128S_OFFSET_TYPE] = (uint8_t)type; +} + +OPENSSL_INLINE void slhdsa_set_tree_height(uint8_t addr[32], + uint32_t tree_height) { + addr[SLHDSA_SHA2_128S_OFFSET_TREE_HGT] = (uint8_t)tree_height; +} + +OPENSSL_INLINE void slhdsa_set_tree_index(uint8_t addr[32], + uint32_t tree_index) { + CRYPTO_store_u32_be(&addr[SLHDSA_SHA2_128S_OFFSET_TREE_INDEX], tree_index); +} + +OPENSSL_INLINE uint32_t slhdsa_get_tree_index(uint8_t addr[32]) { + return CRYPTO_load_u32_be(addr + SLHDSA_SHA2_128S_OFFSET_TREE_INDEX); +} + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_ADDRESS_H diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/fors.c b/Sources/CCryptoBoringSSL/crypto/slhdsa/fors.c new file mode 100644 index 00000000..b8eed896 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/fors.c @@ -0,0 +1,169 @@ +/* Copyright (c) 2024, Google LLC + * + * 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 + +#include +#include + +#include "../internal.h" +#include "./address.h" +#include "./fors.h" +#include "./params.h" +#include "./thash.h" + +// Compute the base 2^12 representation of `message` (algorithm 4, page 16). +static void fors_base_b( + uint16_t indices[SLHDSA_SHA2_128S_FORS_TREES], + const uint8_t message[SLHDSA_SHA2_128S_FORS_MSG_BYTES]) { + static_assert(SLHDSA_SHA2_128S_FORS_HEIGHT == 12, ""); + static_assert((SLHDSA_SHA2_128S_FORS_TREES & 1) == 0, ""); + + const uint8_t *msg = message; + for (size_t i = 0; i < SLHDSA_SHA2_128S_FORS_TREES; i += 2) { + uint32_t val = ((uint32_t)msg[0] << 16) | ((uint32_t)msg[1] << 8) | msg[2]; + indices[i] = (val >> 12) & 0xFFF; + indices[i + 1] = val & 0xFFF; + msg += 3; + } +} + +// Implements Algorithm 14: fors_skGen function (page 29) +void slhdsa_fors_sk_gen(uint8_t fors_sk[SLHDSA_SHA2_128S_N], uint32_t idx, + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + uint8_t sk_addr[32]; + OPENSSL_memcpy(sk_addr, addr, sizeof(sk_addr)); + + slhdsa_set_type(sk_addr, SLHDSA_SHA2_128S_ADDR_TYPE_FORSPRF); + slhdsa_copy_keypair_addr(sk_addr, addr); + slhdsa_set_tree_index(sk_addr, idx); + slhdsa_thash_prf(fors_sk, pk_seed, sk_seed, sk_addr); +} + +// Implements Algorithm 15: fors_node function (page 30) +void slhdsa_fors_treehash(uint8_t root_node[SLHDSA_SHA2_128S_N], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + uint32_t i /*target node index*/, + uint32_t z /*target node height*/, + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + BSSL_CHECK(z <= SLHDSA_SHA2_128S_FORS_HEIGHT); + BSSL_CHECK(i < (uint32_t)(SLHDSA_SHA2_128S_FORS_TREES * + (1 << (SLHDSA_SHA2_128S_FORS_HEIGHT - z)))); + + if (z == 0) { + uint8_t sk[SLHDSA_SHA2_128S_N]; + slhdsa_set_tree_height(addr, 0); + slhdsa_set_tree_index(addr, i); + slhdsa_fors_sk_gen(sk, i, sk_seed, pk_seed, addr); + slhdsa_thash_f(root_node, sk, pk_seed, addr); + } else { + // Stores left node and right node. + uint8_t nodes[2 * SLHDSA_SHA2_128S_N]; + slhdsa_fors_treehash(nodes, sk_seed, 2 * i, z - 1, pk_seed, addr); + slhdsa_fors_treehash(nodes + SLHDSA_SHA2_128S_N, sk_seed, 2 * i + 1, z - 1, + pk_seed, addr); + slhdsa_set_tree_height(addr, z); + slhdsa_set_tree_index(addr, i); + slhdsa_thash_h(root_node, nodes, pk_seed, addr); + } +} + +// Implements Algorithm 16: fors_sign function (page 31) +void slhdsa_fors_sign(uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES], + const uint8_t message[SLHDSA_SHA2_128S_FORS_MSG_BYTES], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + uint16_t indices[SLHDSA_SHA2_128S_FORS_TREES]; + + // Derive FORS indices compatible with the NIST changes. + fors_base_b(indices, message); + + for (size_t i = 0; i < SLHDSA_SHA2_128S_FORS_TREES; ++i) { + slhdsa_set_tree_height(addr, 0); + // Write the FORS secret key element to the correct position. + slhdsa_fors_sk_gen( + fors_sig + i * SLHDSA_SHA2_128S_N * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1), + i * (1 << SLHDSA_SHA2_128S_FORS_HEIGHT) + indices[i], sk_seed, pk_seed, + addr); + for (size_t j = 0; j < SLHDSA_SHA2_128S_FORS_HEIGHT; ++j) { + size_t s = (indices[i] / (1 << j)) ^ 1; + // Write the FORS auth path element to the correct position. + slhdsa_fors_treehash( + fors_sig + SLHDSA_SHA2_128S_N * + (i * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1) + j + 1), + sk_seed, i * (1ULL << (SLHDSA_SHA2_128S_FORS_HEIGHT - j)) + s, j, + pk_seed, addr); + } + } +} + +// Implements Algorithm 17: fors_pkFromSig function (page 32) +void slhdsa_fors_pk_from_sig( + uint8_t fors_pk[SLHDSA_SHA2_128S_N], + const uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES], + const uint8_t message[SLHDSA_SHA2_128S_FORS_MSG_BYTES], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]) { + uint16_t indices[SLHDSA_SHA2_128S_FORS_TREES]; + uint8_t tmp[2 * SLHDSA_SHA2_128S_N]; + uint8_t roots[SLHDSA_SHA2_128S_FORS_TREES * SLHDSA_SHA2_128S_N]; + + // Derive FORS indices compatible with the NIST changes. + fors_base_b(indices, message); + + for (size_t i = 0; i < SLHDSA_SHA2_128S_FORS_TREES; ++i) { + // Pointer to current sk and authentication path + const uint8_t *sk = + fors_sig + i * SLHDSA_SHA2_128S_N * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1); + const uint8_t *auth = + fors_sig + i * SLHDSA_SHA2_128S_N * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1) + + SLHDSA_SHA2_128S_N; + uint8_t nodes[2 * SLHDSA_SHA2_128S_N]; + + slhdsa_set_tree_height(addr, 0); + slhdsa_set_tree_index( + addr, (i * (1 << SLHDSA_SHA2_128S_FORS_HEIGHT)) + indices[i]); + + slhdsa_thash_f(nodes, sk, pk_seed, addr); + + for (size_t j = 0; j < SLHDSA_SHA2_128S_FORS_HEIGHT; ++j) { + slhdsa_set_tree_height(addr, j + 1); + + // Even node + if (((indices[i] / (1 << j)) % 2) == 0) { + slhdsa_set_tree_index(addr, slhdsa_get_tree_index(addr) / 2); + OPENSSL_memcpy(tmp, nodes, SLHDSA_SHA2_128S_N); + OPENSSL_memcpy(tmp + SLHDSA_SHA2_128S_N, auth + j * SLHDSA_SHA2_128S_N, + SLHDSA_SHA2_128S_N); + slhdsa_thash_h(nodes + SLHDSA_SHA2_128S_N, tmp, pk_seed, addr); + } else { + slhdsa_set_tree_index(addr, (slhdsa_get_tree_index(addr) - 1) / 2); + OPENSSL_memcpy(tmp, auth + j * SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N); + OPENSSL_memcpy(tmp + SLHDSA_SHA2_128S_N, nodes, SLHDSA_SHA2_128S_N); + slhdsa_thash_h(nodes + SLHDSA_SHA2_128S_N, tmp, pk_seed, addr); + } + OPENSSL_memcpy(nodes, nodes + SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N); + } + OPENSSL_memcpy(roots + i * SLHDSA_SHA2_128S_N, nodes, SLHDSA_SHA2_128S_N); + } + + uint8_t forspk_addr[32]; + OPENSSL_memcpy(forspk_addr, addr, sizeof(forspk_addr)); + slhdsa_set_type(forspk_addr, SLHDSA_SHA2_128S_ADDR_TYPE_FORSPK); + slhdsa_copy_keypair_addr(forspk_addr, addr); + slhdsa_thash_tk(fors_pk, roots, pk_seed, forspk_addr); +} diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/fors.h b/Sources/CCryptoBoringSSL/crypto/slhdsa/fors.h new file mode 100644 index 00000000..194a126a --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/fors.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2024, Google LLC + * + * 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. */ + +#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_FORS_H +#define OPENSSL_HEADER_CRYPTO_SLHDSA_FORS_H + +#include "./params.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Implements Algorithm 14: fors_skGen function (page 29) +void slhdsa_fors_sk_gen(uint8_t fors_sk[SLHDSA_SHA2_128S_N], uint32_t idx, + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements Algorithm 15: fors_node function (page 30) +void slhdsa_fors_treehash(uint8_t root_node[SLHDSA_SHA2_128S_N], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + uint32_t i /*target node index*/, + uint32_t z /*target node height*/, + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements Algorithm 16: fors_sign function (page 31) +void slhdsa_fors_sign(uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES], + const uint8_t message[SLHDSA_SHA2_128S_FORS_MSG_BYTES], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements Algorithm 17: fors_pkFromSig function (page 32) +void slhdsa_fors_pk_from_sig( + uint8_t fors_pk[SLHDSA_SHA2_128S_N], + const uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES], + const uint8_t message[SLHDSA_SHA2_128S_FORS_MSG_BYTES], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_FORS_H diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/internal.h b/Sources/CCryptoBoringSSL/crypto/slhdsa/internal.h new file mode 100644 index 00000000..6412853c --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/internal.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2024, Google LLC + * + * 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. */ + +#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_SLHDSA_INTERNAL_H + +#include + +#include "params.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// SLHDSA_SHA2_128S_generate_key_from_seed generates an SLH-DSA-SHA2-128s key +// pair from a 48-byte seed and writes the result to |out_public_key| and +// |out_secret_key|. +OPENSSL_EXPORT void SLHDSA_SHA2_128S_generate_key_from_seed( + uint8_t out_public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + uint8_t out_secret_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], + const uint8_t seed[3 * SLHDSA_SHA2_128S_N]); + +// SLHDSA_SHA2_128S_sign_internal acts like |SLHDSA_SHA2_128S_sign| but +// accepts an explicit entropy input, which can be PK.seed (bytes 32..48 of +// the private key) to generate deterministic signatures. It also takes the +// input message in three parts so that the "internal" version of the signing +// function, from section 9.2, can be implemented. The |header| argument may be +// NULL to omit it. +OPENSSL_EXPORT void SLHDSA_SHA2_128S_sign_internal( + uint8_t out_signature[SLHDSA_SHA2_128S_SIGNATURE_BYTES], + const uint8_t secret_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], + const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context, + size_t context_len, const uint8_t *msg, size_t msg_len, + const uint8_t entropy[SLHDSA_SHA2_128S_N]); + +// SLHDSA_SHA2_128S_verify_internal acts like |SLHDSA_SHA2_128S_verify| but +// takes the input message in three parts so that the "internal" version of the +// verification function, from section 9.3, can be implemented. The |header| +// argument may be NULL to omit it. +OPENSSL_EXPORT int SLHDSA_SHA2_128S_verify_internal( + const uint8_t *signature, size_t signature_len, + const uint8_t public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context, + size_t context_len, const uint8_t *msg, size_t msg_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_INTERNAL_H diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/merkle.c b/Sources/CCryptoBoringSSL/crypto/slhdsa/merkle.c new file mode 100644 index 00000000..9df00e55 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/merkle.c @@ -0,0 +1,161 @@ +/* Copyright (c) 2024, Google LLC + * + * 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 + +#include + +#include "../internal.h" +#include "./address.h" +#include "./merkle.h" +#include "./params.h" +#include "./thash.h" +#include "./wots.h" + + +// Implements Algorithm 9: xmss_node function (page 23) +void slhdsa_treehash(uint8_t out_pk[SLHDSA_SHA2_128S_N], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + uint32_t i /*target node index*/, + uint32_t z /*target node height*/, + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + BSSL_CHECK(z <= SLHDSA_SHA2_128S_TREE_HEIGHT); + BSSL_CHECK(i < (uint32_t)(1 << (SLHDSA_SHA2_128S_TREE_HEIGHT - z))); + + if (z == 0) { + slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_WOTS); + slhdsa_set_keypair_addr(addr, i); + slhdsa_wots_pk_gen(out_pk, sk_seed, pk_seed, addr); + } else { + // Stores left node and right node. + uint8_t nodes[2 * SLHDSA_SHA2_128S_N]; + slhdsa_treehash(nodes, sk_seed, 2 * i, z - 1, pk_seed, addr); + slhdsa_treehash(nodes + SLHDSA_SHA2_128S_N, sk_seed, 2 * i + 1, z - 1, + pk_seed, addr); + slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_HASHTREE); + slhdsa_set_tree_height(addr, z); + slhdsa_set_tree_index(addr, i); + slhdsa_thash_h(out_pk, nodes, pk_seed, addr); + } +} + +// Implements Algorithm 10: xmss_sign function (page 24) +void slhdsa_xmss_sign(uint8_t sig[SLHDSA_SHA2_128S_XMSS_BYTES], + const uint8_t msg[SLHDSA_SHA2_128S_N], unsigned int idx, + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + // Build authentication path + for (size_t j = 0; j < SLHDSA_SHA2_128S_TREE_HEIGHT; ++j) { + unsigned int k = (idx >> j) ^ 1; + slhdsa_treehash(sig + SLHDSA_SHA2_128S_WOTS_BYTES + j * SLHDSA_SHA2_128S_N, + sk_seed, k, j, pk_seed, addr); + } + + // Compute WOTS+ signature + slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_WOTS); + slhdsa_set_keypair_addr(addr, idx); + slhdsa_wots_sign(sig, msg, sk_seed, pk_seed, addr); +} + +// Implements Algorithm 11: xmss_pkFromSig function (page 25) +void slhdsa_xmss_pk_from_sig( + uint8_t root[SLHDSA_SHA2_128S_N], + const uint8_t xmss_sig[SLHDSA_SHA2_128S_XMSS_BYTES], unsigned int idx, + const uint8_t msg[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]) { + // Stores node[0] and node[1] from Algorithm 11 + slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_WOTS); + slhdsa_set_keypair_addr(addr, idx); + uint8_t node[2 * SLHDSA_SHA2_128S_N]; + slhdsa_wots_pk_from_sig(node, xmss_sig, msg, pk_seed, addr); + + slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_HASHTREE); + slhdsa_set_tree_index(addr, idx); + + uint8_t tmp[2 * SLHDSA_SHA2_128S_N]; + const uint8_t *const auth = xmss_sig + SLHDSA_SHA2_128S_WOTS_BYTES; + for (size_t k = 0; k < SLHDSA_SHA2_128S_TREE_HEIGHT; ++k) { + slhdsa_set_tree_height(addr, k + 1); + if (((idx >> k) & 1) == 0) { + slhdsa_set_tree_index(addr, slhdsa_get_tree_index(addr) >> 1); + OPENSSL_memcpy(tmp, node, SLHDSA_SHA2_128S_N); + OPENSSL_memcpy(tmp + SLHDSA_SHA2_128S_N, auth + k * SLHDSA_SHA2_128S_N, + SLHDSA_SHA2_128S_N); + slhdsa_thash_h(node + SLHDSA_SHA2_128S_N, tmp, pk_seed, addr); + } else { + slhdsa_set_tree_index(addr, (slhdsa_get_tree_index(addr) - 1) >> 1); + OPENSSL_memcpy(tmp, auth + k * SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N); + OPENSSL_memcpy(tmp + SLHDSA_SHA2_128S_N, node, SLHDSA_SHA2_128S_N); + slhdsa_thash_h(node + SLHDSA_SHA2_128S_N, tmp, pk_seed, addr); + } + OPENSSL_memcpy(node, node + SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N); + } + OPENSSL_memcpy(root, node, SLHDSA_SHA2_128S_N); +} + +// Implements Algorithm 12: ht_sign function (page 27) +void slhdsa_ht_sign( + uint8_t sig[SLHDSA_SHA2_128S_XMSS_BYTES * SLHDSA_SHA2_128S_D], + const uint8_t message[SLHDSA_SHA2_128S_N], uint64_t idx_tree, + uint32_t idx_leaf, const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N]) { + uint8_t addr[32] = {0}; + slhdsa_set_tree_addr(addr, idx_tree); + + // Layer 0 + slhdsa_xmss_sign(sig, message, idx_leaf, sk_seed, pk_seed, addr); + uint8_t root[SLHDSA_SHA2_128S_N]; + slhdsa_xmss_pk_from_sig(root, sig, idx_leaf, message, pk_seed, addr); + sig += SLHDSA_SHA2_128S_XMSS_BYTES; + + // All other layers + for (size_t j = 1; j < SLHDSA_SHA2_128S_D; ++j) { + idx_leaf = idx_tree % (1 << SLHDSA_SHA2_128S_TREE_HEIGHT); + idx_tree = idx_tree >> SLHDSA_SHA2_128S_TREE_HEIGHT; + slhdsa_set_layer_addr(addr, j); + slhdsa_set_tree_addr(addr, idx_tree); + slhdsa_xmss_sign(sig, root, idx_leaf, sk_seed, pk_seed, addr); + if (j < (SLHDSA_SHA2_128S_D - 1)) { + slhdsa_xmss_pk_from_sig(root, sig, idx_leaf, root, pk_seed, addr); + } + + sig += SLHDSA_SHA2_128S_XMSS_BYTES; + } +} + +// Implements Algorithm 13: ht_verify function (page 28) +int slhdsa_ht_verify( + const uint8_t sig[SLHDSA_SHA2_128S_D * SLHDSA_SHA2_128S_XMSS_BYTES], + const uint8_t message[SLHDSA_SHA2_128S_N], uint64_t idx_tree, + uint32_t idx_leaf, const uint8_t pk_root[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N]) { + uint8_t addr[32] = {0}; + slhdsa_set_tree_addr(addr, idx_tree); + + uint8_t node[SLHDSA_SHA2_128S_N]; + slhdsa_xmss_pk_from_sig(node, sig, idx_leaf, message, pk_seed, addr); + + for (size_t j = 1; j < SLHDSA_SHA2_128S_D; ++j) { + idx_leaf = idx_tree % (1 << SLHDSA_SHA2_128S_TREE_HEIGHT); + idx_tree = idx_tree >> SLHDSA_SHA2_128S_TREE_HEIGHT; + slhdsa_set_layer_addr(addr, j); + slhdsa_set_tree_addr(addr, idx_tree); + + slhdsa_xmss_pk_from_sig(node, sig + j * SLHDSA_SHA2_128S_XMSS_BYTES, + idx_leaf, node, pk_seed, addr); + } + return memcmp(node, pk_root, SLHDSA_SHA2_128S_N) == 0; +} diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/merkle.h b/Sources/CCryptoBoringSSL/crypto/slhdsa/merkle.h new file mode 100644 index 00000000..b23c2e63 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/merkle.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2024, Google LLC + * + * 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. */ + +#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_MERKLE_H +#define OPENSSL_HEADER_CRYPTO_SLHDSA_MERKLE_H + +#include + +#include + +#include "./params.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Implements Algorithm 9: xmss_node function (page 23) +void slhdsa_treehash(uint8_t out_pk[SLHDSA_SHA2_128S_N], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + uint32_t i /*target node index*/, + uint32_t z /*target node height*/, + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements Algorithm 10: xmss_sign function (page 24) +void slhdsa_xmss_sign(uint8_t sig[SLHDSA_SHA2_128S_XMSS_BYTES], + const uint8_t msg[SLHDSA_SHA2_128S_N], unsigned int idx, + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements Algorithm 11: xmss_pkFromSig function (page 25) +void slhdsa_xmss_pk_from_sig( + uint8_t root[SLHDSA_SHA2_128S_N], + const uint8_t xmss_sig[SLHDSA_SHA2_128S_XMSS_BYTES], unsigned int idx, + const uint8_t msg[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]); + +// Implements Algorithm 12: ht_sign function (page 27) +void slhdsa_ht_sign( + uint8_t sig[SLHDSA_SHA2_128S_D * SLHDSA_SHA2_128S_XMSS_BYTES], + const uint8_t message[SLHDSA_SHA2_128S_N], uint64_t idx_tree, + uint32_t idx_leaf, const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N]); + +// Implements Algorithm 13: ht_verify function (page 28) +int slhdsa_ht_verify( + const uint8_t sig[SLHDSA_SHA2_128S_D * SLHDSA_SHA2_128S_XMSS_BYTES], + const uint8_t message[SLHDSA_SHA2_128S_N], uint64_t idx_tree, + uint32_t idx_leaf, const uint8_t pk_root[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_MERKLE_H diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/params.h b/Sources/CCryptoBoringSSL/crypto/slhdsa/params.h new file mode 100644 index 00000000..d0812962 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/params.h @@ -0,0 +1,83 @@ +/* Copyright (c) 2024, Google LLC + * + * 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. */ + +#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_PARAMS_H +#define OPENSSL_HEADER_CRYPTO_SLHDSA_PARAMS_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Output length of the hash function. +#define SLHDSA_SHA2_128S_N 16 +// Total height of the tree structure. +#define SLHDSA_SHA2_128S_FULL_HEIGHT 63 +// Number of subtree layers. +#define SLHDSA_SHA2_128S_D 7 +// Height of the trees on each layer +#define SLHDSA_SHA2_128S_TREE_HEIGHT 9 +// Height of each individual FORS tree. +#define SLHDSA_SHA2_128S_FORS_HEIGHT 12 +// Total number of FORS tree used. +#define SLHDSA_SHA2_128S_FORS_TREES 14 +// Size of a FORS signature +#define SLHDSA_SHA2_128S_FORS_BYTES \ + ((SLHDSA_SHA2_128S_FORS_HEIGHT + 1) * SLHDSA_SHA2_128S_FORS_TREES * \ + SLHDSA_SHA2_128S_N) +// The number of bytes at the beginning of M', the augmented message, before the +// context. +#define SLHDSA_M_PRIME_HEADER_LEN 2 + +// Winternitz parameter and derived values +#define SLHDSA_SHA2_128S_WOTS_W 16 +#define SLHDSA_SHA2_128S_WOTS_LOG_W 4 +#define SLHDSA_SHA2_128S_WOTS_LEN1 32 +#define SLHDSA_SHA2_128S_WOTS_LEN2 3 +#define SLHDSA_SHA2_128S_WOTS_LEN 35 +#define SLHDSA_SHA2_128S_WOTS_BYTES \ + (SLHDSA_SHA2_128S_N * SLHDSA_SHA2_128S_WOTS_LEN) + +// XMSS sizes +#define SLHDSA_SHA2_128S_XMSS_BYTES \ + (SLHDSA_SHA2_128S_WOTS_BYTES + \ + (SLHDSA_SHA2_128S_N * SLHDSA_SHA2_128S_TREE_HEIGHT)) + +// Size of the message digest (NOTE: This is only correct for the SHA-256 params +// here) +#define SLHDSA_SHA2_128S_DIGEST_SIZE \ + (((SLHDSA_SHA2_128S_FORS_TREES * SLHDSA_SHA2_128S_FORS_HEIGHT) / 8) + \ + (((SLHDSA_SHA2_128S_FULL_HEIGHT - SLHDSA_SHA2_128S_TREE_HEIGHT) / 8) + 1) + \ + (SLHDSA_SHA2_128S_TREE_HEIGHT / 8) + 1) + +// Compressed address size when using SHA-256 +#define SLHDSA_SHA2_128S_SHA256_ADDR_BYTES 22 + +// Size of the FORS message hash +#define SLHDSA_SHA2_128S_FORS_MSG_BYTES \ + ((SLHDSA_SHA2_128S_FORS_HEIGHT * SLHDSA_SHA2_128S_FORS_TREES + 7) / 8) +#define SLHDSA_SHA2_128S_TREE_BITS \ + (SLHDSA_SHA2_128S_TREE_HEIGHT * (SLHDSA_SHA2_128S_D - 1)) +#define SLHDSA_SHA2_128S_TREE_BYTES ((SLHDSA_SHA2_128S_TREE_BITS + 7) / 8) +#define SLHDSA_SHA2_128S_LEAF_BITS SLHDSA_SHA2_128S_TREE_HEIGHT +#define SLHDSA_SHA2_128S_LEAF_BYTES ((SLHDSA_SHA2_128S_LEAF_BITS + 7) / 8) + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_PARAMS_H diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/slhdsa.c b/Sources/CCryptoBoringSSL/crypto/slhdsa/slhdsa.c new file mode 100644 index 00000000..4a076cfd --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/slhdsa.c @@ -0,0 +1,206 @@ +/* Copyright (c) 2024, Google LLC + * + * 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 + +#include + +#include + +#include "../internal.h" +#include "address.h" +#include "fors.h" +#include "internal.h" +#include "merkle.h" +#include "params.h" +#include "thash.h" + + +void SLHDSA_SHA2_128S_generate_key_from_seed( + uint8_t out_public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + uint8_t out_secret_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], + const uint8_t seed[3 * SLHDSA_SHA2_128S_N]) { + // Initialize SK.seed || SK.prf || PK.seed from seed. + OPENSSL_memcpy(out_secret_key, seed, 3 * SLHDSA_SHA2_128S_N); + + // Initialize PK.seed from seed. + OPENSSL_memcpy(out_public_key, seed + 2 * SLHDSA_SHA2_128S_N, + SLHDSA_SHA2_128S_N); + + uint8_t addr[32] = {0}; + slhdsa_set_layer_addr(addr, SLHDSA_SHA2_128S_D - 1); + + // Set PK.root + slhdsa_treehash(out_public_key + SLHDSA_SHA2_128S_N, out_secret_key, 0, + SLHDSA_SHA2_128S_TREE_HEIGHT, out_public_key, addr); + OPENSSL_memcpy(out_secret_key + 3 * SLHDSA_SHA2_128S_N, + out_public_key + SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N); +} + +void SLHDSA_SHA2_128S_generate_key( + uint8_t out_public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + uint8_t out_private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) { + uint8_t seed[3 * SLHDSA_SHA2_128S_N]; + RAND_bytes(seed, 3 * SLHDSA_SHA2_128S_N); + SLHDSA_SHA2_128S_generate_key_from_seed(out_public_key, out_private_key, + seed); +} + +OPENSSL_EXPORT void SLHDSA_SHA2_128S_public_from_private( + uint8_t out_public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + const uint8_t private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) { + OPENSSL_memcpy(out_public_key, private_key + 2 * SLHDSA_SHA2_128S_N, + SLHDSA_SHA2_128S_N * 2); +} + +// Note that this overreads by a byte. This is fine in the context that it's +// used. +static uint64_t load_tree_index(const uint8_t in[8]) { + static_assert(SLHDSA_SHA2_128S_TREE_BYTES == 7, + "This code needs to be updated"); + uint64_t index = CRYPTO_load_u64_be(in); + index >>= 8; + index &= (~(uint64_t)0) >> (64 - SLHDSA_SHA2_128S_TREE_BITS); + return index; +} + +// Implements Algorithm 22: slh_sign function (Section 10.2.1, page 39) +void SLHDSA_SHA2_128S_sign_internal( + uint8_t out_signature[SLHDSA_SHA2_128S_SIGNATURE_BYTES], + const uint8_t secret_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], + const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context, + size_t context_len, const uint8_t *msg, size_t msg_len, + const uint8_t entropy[SLHDSA_SHA2_128S_N]) { + const uint8_t *sk_seed = secret_key; + const uint8_t *sk_prf = secret_key + SLHDSA_SHA2_128S_N; + const uint8_t *pk_seed = secret_key + 2 * SLHDSA_SHA2_128S_N; + const uint8_t *pk_root = secret_key + 3 * SLHDSA_SHA2_128S_N; + + // Derive randomizer R and copy it to signature + uint8_t R[SLHDSA_SHA2_128S_N]; + slhdsa_thash_prfmsg(R, sk_prf, entropy, header, context, context_len, msg, + msg_len); + OPENSSL_memcpy(out_signature, R, SLHDSA_SHA2_128S_N); + + // Compute message digest + uint8_t digest[SLHDSA_SHA2_128S_DIGEST_SIZE]; + slhdsa_thash_hmsg(digest, R, pk_seed, pk_root, header, context, context_len, + msg, msg_len); + + uint8_t fors_digest[SLHDSA_SHA2_128S_FORS_MSG_BYTES]; + OPENSSL_memcpy(fors_digest, digest, SLHDSA_SHA2_128S_FORS_MSG_BYTES); + + const uint64_t idx_tree = + load_tree_index(digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES); + uint32_t idx_leaf = CRYPTO_load_u16_be( + digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES + SLHDSA_SHA2_128S_TREE_BYTES); + idx_leaf &= (~(uint32_t)0) >> (32 - SLHDSA_SHA2_128S_LEAF_BITS); + + uint8_t addr[32] = {0}; + slhdsa_set_tree_addr(addr, idx_tree); + slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_FORSTREE); + slhdsa_set_keypair_addr(addr, idx_leaf); + + slhdsa_fors_sign(out_signature + SLHDSA_SHA2_128S_N, fors_digest, sk_seed, + pk_seed, addr); + + uint8_t pk_fors[SLHDSA_SHA2_128S_N]; + slhdsa_fors_pk_from_sig(pk_fors, out_signature + SLHDSA_SHA2_128S_N, + fors_digest, pk_seed, addr); + + slhdsa_ht_sign( + out_signature + SLHDSA_SHA2_128S_N + SLHDSA_SHA2_128S_FORS_BYTES, pk_fors, + idx_tree, idx_leaf, sk_seed, pk_seed); +} + +int SLHDSA_SHA2_128S_sign( + uint8_t out_signature[SLHDSA_SHA2_128S_SIGNATURE_BYTES], + const uint8_t private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], + const uint8_t *msg, size_t msg_len, const uint8_t *context, + size_t context_len) { + if (context_len > 255) { + return 0; + } + + // Construct header for M' as specified in Algorithm 22 + uint8_t M_prime_header[2]; + M_prime_header[0] = 0; // domain separator for pure signing + M_prime_header[1] = (uint8_t)context_len; + + uint8_t entropy[SLHDSA_SHA2_128S_N]; + RAND_bytes(entropy, sizeof(entropy)); + SLHDSA_SHA2_128S_sign_internal(out_signature, private_key, M_prime_header, + context, context_len, msg, msg_len, entropy); + return 1; +} + +// Implements Algorithm 24: slh_verify function (Section 10.3, page 41) +int SLHDSA_SHA2_128S_verify( + const uint8_t *signature, size_t signature_len, + const uint8_t public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + const uint8_t *msg, size_t msg_len, const uint8_t *context, + size_t context_len) { + if (context_len > 255) { + return 0; + } + + // Construct header for M' as specified in Algorithm 24 + uint8_t M_prime_header[2]; + M_prime_header[0] = 0; // domain separator for pure verification + M_prime_header[1] = (uint8_t)context_len; + + return SLHDSA_SHA2_128S_verify_internal(signature, signature_len, public_key, + M_prime_header, context, context_len, + msg, msg_len); +} + +int SLHDSA_SHA2_128S_verify_internal( + const uint8_t *signature, size_t signature_len, + const uint8_t public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context, + size_t context_len, const uint8_t *msg, size_t msg_len) { + if (signature_len != SLHDSA_SHA2_128S_SIGNATURE_BYTES) { + return 0; + } + const uint8_t *pk_seed = public_key; + const uint8_t *pk_root = public_key + SLHDSA_SHA2_128S_N; + + const uint8_t *r = signature; + const uint8_t *sig_fors = signature + SLHDSA_SHA2_128S_N; + const uint8_t *sig_ht = sig_fors + SLHDSA_SHA2_128S_FORS_BYTES; + + uint8_t digest[SLHDSA_SHA2_128S_DIGEST_SIZE]; + slhdsa_thash_hmsg(digest, r, pk_seed, pk_root, header, context, context_len, + msg, msg_len); + + uint8_t fors_digest[SLHDSA_SHA2_128S_FORS_MSG_BYTES]; + OPENSSL_memcpy(fors_digest, digest, SLHDSA_SHA2_128S_FORS_MSG_BYTES); + + const uint64_t idx_tree = + load_tree_index(digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES); + uint32_t idx_leaf = CRYPTO_load_u16_be( + digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES + SLHDSA_SHA2_128S_TREE_BYTES); + idx_leaf &= (~(uint32_t)0) >> (32 - SLHDSA_SHA2_128S_LEAF_BITS); + + uint8_t addr[32] = {0}; + slhdsa_set_tree_addr(addr, idx_tree); + slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_FORSTREE); + slhdsa_set_keypair_addr(addr, idx_leaf); + + uint8_t pk_fors[SLHDSA_SHA2_128S_N]; + slhdsa_fors_pk_from_sig(pk_fors, sig_fors, fors_digest, pk_seed, addr); + + return slhdsa_ht_verify(sig_ht, pk_fors, idx_tree, idx_leaf, pk_root, + pk_seed); +} diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/thash.c b/Sources/CCryptoBoringSSL/crypto/slhdsa/thash.c new file mode 100644 index 00000000..88c33392 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/thash.c @@ -0,0 +1,173 @@ +/* Copyright (c) 2024, Google LLC + * + * 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 + +#include +#include + +#include + +#include "../internal.h" +#include "./params.h" +#include "./thash.h" + + +// Internal thash function used by F, H, and T_l (Section 11.2, pages 44-46) +static void slhdsa_thash(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t *input, size_t input_blocks, + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + SHA256_CTX sha256; + SHA256_Init(&sha256); + + // Process pubseed with padding to full block. + static const uint8_t kZeros[64 - SLHDSA_SHA2_128S_N] = {0}; + SHA256_Update(&sha256, pk_seed, SLHDSA_SHA2_128S_N); + SHA256_Update(&sha256, kZeros, sizeof(kZeros)); + SHA256_Update(&sha256, addr, SLHDSA_SHA2_128S_SHA256_ADDR_BYTES); + SHA256_Update(&sha256, input, input_blocks * SLHDSA_SHA2_128S_N); + + uint8_t hash[32]; + SHA256_Final(hash, &sha256); + OPENSSL_memcpy(output, hash, SLHDSA_SHA2_128S_N); +} + +// Implements PRF_msg function (Section 4.1, page 11 and Section 11.2, pages +// 44-46) +void slhdsa_thash_prfmsg(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t sk_prf[SLHDSA_SHA2_128S_N], + const uint8_t entropy[SLHDSA_SHA2_128S_N], + const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], + const uint8_t *ctx, size_t ctx_len, const uint8_t *msg, + size_t msg_len) { + // Compute HMAC-SHA256(sk_prf, entropy || header || ctx || msg). We inline + // HMAC to avoid an allocation. + uint8_t hmac_key[SHA256_CBLOCK]; + static_assert(SLHDSA_SHA2_128S_N <= SHA256_CBLOCK, + "HMAC key is larger than block size"); + OPENSSL_memcpy(hmac_key, sk_prf, SLHDSA_SHA2_128S_N); + for (size_t i = 0; i < SLHDSA_SHA2_128S_N; i++) { + hmac_key[i] ^= 0x36; + } + OPENSSL_memset(hmac_key + SLHDSA_SHA2_128S_N, 0x36, + sizeof(hmac_key) - SLHDSA_SHA2_128S_N); + + SHA256_CTX sha_ctx; + SHA256_Init(&sha_ctx); + SHA256_Update(&sha_ctx, hmac_key, sizeof(hmac_key)); + SHA256_Update(&sha_ctx, entropy, SLHDSA_SHA2_128S_N); + if (header) { + SHA256_Update(&sha_ctx, header, SLHDSA_M_PRIME_HEADER_LEN); + } + SHA256_Update(&sha_ctx, ctx, ctx_len); + SHA256_Update(&sha_ctx, msg, msg_len); + uint8_t hash[SHA256_DIGEST_LENGTH]; + SHA256_Final(hash, &sha_ctx); + + for (size_t i = 0; i < SLHDSA_SHA2_128S_N; i++) { + hmac_key[i] ^= 0x36 ^ 0x5c; + } + OPENSSL_memset(hmac_key + SLHDSA_SHA2_128S_N, 0x5c, + sizeof(hmac_key) - SLHDSA_SHA2_128S_N); + + SHA256_Init(&sha_ctx); + SHA256_Update(&sha_ctx, hmac_key, sizeof(hmac_key)); + SHA256_Update(&sha_ctx, hash, sizeof(hash)); + SHA256_Final(hash, &sha_ctx); + + // Truncate to SLHDSA_SHA2_128S_N bytes + OPENSSL_memcpy(output, hash, SLHDSA_SHA2_128S_N); +} + +// Implements H_msg function (Section 4.1, page 11 and Section 11.2, pages +// 44-46) +void slhdsa_thash_hmsg(uint8_t output[SLHDSA_SHA2_128S_DIGEST_SIZE], + const uint8_t r[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pk_root[SLHDSA_SHA2_128S_N], + const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], + const uint8_t *ctx, size_t ctx_len, const uint8_t *msg, + size_t msg_len) { + // MGF1-SHA-256(R || PK.seed || SHA-256(R || PK.seed || PK.root || header || + // ctx || M), m) input_buffer stores R || PK_SEED || SHA256(..) || 4-byte + // index + uint8_t input_buffer[2 * SLHDSA_SHA2_128S_N + 32 + 4] = {0}; + OPENSSL_memcpy(input_buffer, r, SLHDSA_SHA2_128S_N); + OPENSSL_memcpy(input_buffer + SLHDSA_SHA2_128S_N, pk_seed, + SLHDSA_SHA2_128S_N); + + // Inner hash + SHA256_CTX sha_ctx; + SHA256_Init(&sha_ctx); + SHA256_Update(&sha_ctx, r, SLHDSA_SHA2_128S_N); + SHA256_Update(&sha_ctx, pk_seed, SLHDSA_SHA2_128S_N); + SHA256_Update(&sha_ctx, pk_root, SLHDSA_SHA2_128S_N); + if (header) { + SHA256_Update(&sha_ctx, header, SLHDSA_M_PRIME_HEADER_LEN); + } + SHA256_Update(&sha_ctx, ctx, ctx_len); + SHA256_Update(&sha_ctx, msg, msg_len); + // Write directly into the input buffer + SHA256_Final(input_buffer + 2 * SLHDSA_SHA2_128S_N, &sha_ctx); + + // MGF1-SHA-256 + uint8_t hash[32]; + static_assert(SLHDSA_SHA2_128S_DIGEST_SIZE < sizeof(hash), + "More MGF1 iterations required"); + SHA256(input_buffer, sizeof(input_buffer), hash); + OPENSSL_memcpy(output, hash, SLHDSA_SHA2_128S_DIGEST_SIZE); +} + +// Implements PRF function (Section 4.1, page 11 and Section 11.2, pages 44-46) +void slhdsa_thash_prf(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + slhdsa_thash(output, sk_seed, 1, pk_seed, addr); +} + +// Implements T_l function for WOTS+ public key compression (Section 4.1, page +// 11 and Section 11.2, pages 44-46) +void slhdsa_thash_tl(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t input[SLHDSA_SHA2_128S_WOTS_BYTES], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + slhdsa_thash(output, input, SLHDSA_SHA2_128S_WOTS_LEN, pk_seed, addr); +} + +// Implements H function (Section 4.1, page 11 and Section 11.2, pages 44-46) +void slhdsa_thash_h(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t input[2 * SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + slhdsa_thash(output, input, 2, pk_seed, addr); +} + +// Implements F function (Section 4.1, page 11 and Section 11.2, pages 44-46) +void slhdsa_thash_f(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t input[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + slhdsa_thash(output, input, 1, pk_seed, addr); +} + +// Implements T_k function for FORS public key compression (Section 4.1, page 11 +// and Section 11.2, pages 44-46) +void slhdsa_thash_tk( + uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t input[SLHDSA_SHA2_128S_FORS_TREES * SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]) { + slhdsa_thash(output, input, SLHDSA_SHA2_128S_FORS_TREES, pk_seed, addr); +} diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/thash.h b/Sources/CCryptoBoringSSL/crypto/slhdsa/thash.h new file mode 100644 index 00000000..19d9cd39 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/thash.h @@ -0,0 +1,85 @@ +/* Copyright (c) 2024, Google LLC + * + * 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. */ + +#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_THASH_H +#define OPENSSL_HEADER_CRYPTO_SLHDSA_THASH_H + +#include "./params.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Implements PRF_msg: a pseudo-random function that is used to generate the +// randomizer r for the randomized hashing of the message to be signed. +// (Section 4.1, page 11) +void slhdsa_thash_prfmsg(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t sk_prf[SLHDSA_SHA2_128S_N], + const uint8_t opt_rand[SLHDSA_SHA2_128S_N], + const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], + const uint8_t *ctx, size_t ctx_len, const uint8_t *msg, + size_t msg_len); + +// Implements H_msg: a hash function used to generate the digest of the message +// to be signed. (Section 4.1, page 11) +void slhdsa_thash_hmsg(uint8_t output[SLHDSA_SHA2_128S_DIGEST_SIZE], + const uint8_t r[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pk_root[SLHDSA_SHA2_128S_N], + const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], + const uint8_t *ctx, size_t ctx_len, const uint8_t *msg, + size_t msg_len); + +// Implements PRF: a pseudo-random function that is used to generate the secret +// values in WOTS+ and FORS private keys. (Section 4.1, page 11) +void slhdsa_thash_prf(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements T_l: a hash function that maps an l*n-byte message to an n-byte +// message. Used for WOTS+ public key compression. (Section 4.1, page 11) +void slhdsa_thash_tl(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t input[SLHDSA_SHA2_128S_WOTS_BYTES], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements H: a hash function that takes a 2*n-byte message as input and +// produces an n-byte output. (Section 4.1, page 11) +void slhdsa_thash_h(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t input[2 * SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements F: a hash function that takes an n-byte message as input and +// produces an n-byte output. (Section 4.1, page 11) +void slhdsa_thash_f(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t input[SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements T_k: a hash function that maps a k*n-byte message to an n-byte +// message. Used for FORS public key compression. (Section 4.1, page 11) +void slhdsa_thash_tk( + uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t input[SLHDSA_SHA2_128S_FORS_TREES * SLHDSA_SHA2_128S_N], + const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_THASH_H diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/wots.c b/Sources/CCryptoBoringSSL/crypto/slhdsa/wots.c new file mode 100644 index 00000000..e9ca1185 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/wots.c @@ -0,0 +1,171 @@ +/* Copyright (c) 2024, Google LLC + * + * 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 + +#include +#include +#include + +#include "../internal.h" +#include "./address.h" +#include "./params.h" +#include "./thash.h" +#include "./wots.h" + + +// Implements Algorithm 5: chain function, page 18 +static void chain(uint8_t output[SLHDSA_SHA2_128S_N], + const uint8_t input[SLHDSA_SHA2_128S_N], uint32_t start, + uint32_t steps, const uint8_t pub_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + assert(start < SLHDSA_SHA2_128S_WOTS_W); + assert(steps < SLHDSA_SHA2_128S_WOTS_W); + + OPENSSL_memcpy(output, input, SLHDSA_SHA2_128S_N); + + for (size_t i = start; i < (start + steps) && i < SLHDSA_SHA2_128S_WOTS_W; + ++i) { + slhdsa_set_hash_addr(addr, i); + slhdsa_thash_f(output, output, pub_seed, addr); + } +} + +static void slhdsa_wots_do_chain(uint8_t out[SLHDSA_SHA2_128S_N], + uint8_t sk_addr[32], uint8_t addr[32], + uint8_t value, + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pub_seed[SLHDSA_SHA2_128S_N], + uint32_t chain_index) { + uint8_t tmp_sk[SLHDSA_SHA2_128S_N]; + slhdsa_set_chain_addr(sk_addr, chain_index); + slhdsa_thash_prf(tmp_sk, pub_seed, sk_seed, sk_addr); + slhdsa_set_chain_addr(addr, chain_index); + chain(out, tmp_sk, 0, value, pub_seed, addr); +} + +// Implements Algorithm 6: wots_pkGen function, page 18 +void slhdsa_wots_pk_gen(uint8_t pk[SLHDSA_SHA2_128S_N], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pub_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + uint8_t wots_pk_addr[32], sk_addr[32]; + OPENSSL_memcpy(wots_pk_addr, addr, sizeof(wots_pk_addr)); + OPENSSL_memcpy(sk_addr, addr, sizeof(sk_addr)); + slhdsa_set_type(sk_addr, SLHDSA_SHA2_128S_ADDR_TYPE_WOTSPRF); + slhdsa_copy_keypair_addr(sk_addr, addr); + + uint8_t tmp[SLHDSA_SHA2_128S_WOTS_BYTES]; + for (size_t i = 0; i < SLHDSA_SHA2_128S_WOTS_LEN; ++i) { + slhdsa_wots_do_chain(tmp + i * SLHDSA_SHA2_128S_N, sk_addr, addr, + SLHDSA_SHA2_128S_WOTS_W - 1, sk_seed, pub_seed, i); + } + + // Compress pk + slhdsa_set_type(wots_pk_addr, SLHDSA_SHA2_128S_ADDR_TYPE_WOTSPK); + slhdsa_copy_keypair_addr(wots_pk_addr, addr); + slhdsa_thash_tl(pk, tmp, pub_seed, wots_pk_addr); +} + +// Implements Algorithm 7: wots_sign function, page 20 +void slhdsa_wots_sign(uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES], + const uint8_t msg[SLHDSA_SHA2_128S_N], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pub_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + // Compute checksum + static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == SLHDSA_SHA2_128S_N * 2, ""); + uint16_t csum = 0; + for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) { + csum += SLHDSA_SHA2_128S_WOTS_W - 1 - (msg[i] >> 4); + csum += SLHDSA_SHA2_128S_WOTS_W - 1 - (msg[i] & 15); + } + + // Compute chains + uint8_t sk_addr[32]; + OPENSSL_memcpy(sk_addr, addr, sizeof(sk_addr)); + slhdsa_set_type(sk_addr, SLHDSA_SHA2_128S_ADDR_TYPE_WOTSPRF); + slhdsa_copy_keypair_addr(sk_addr, addr); + + uint32_t chain_index = 0; + for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) { + slhdsa_wots_do_chain(sig, sk_addr, addr, msg[i] >> 4, sk_seed, pub_seed, + chain_index++); + sig += SLHDSA_SHA2_128S_N; + + slhdsa_wots_do_chain(sig, sk_addr, addr, msg[i] & 15, sk_seed, pub_seed, + chain_index++); + sig += SLHDSA_SHA2_128S_N; + } + + // Include the SLHDSA_SHA2_128S_WOTS_LEN2 checksum values. + slhdsa_wots_do_chain(sig, sk_addr, addr, (csum >> 8) & 15, sk_seed, pub_seed, + chain_index++); + sig += SLHDSA_SHA2_128S_N; + slhdsa_wots_do_chain(sig, sk_addr, addr, (csum >> 4) & 15, sk_seed, pub_seed, + chain_index++); + sig += SLHDSA_SHA2_128S_N; + slhdsa_wots_do_chain(sig, sk_addr, addr, csum & 15, sk_seed, pub_seed, + chain_index++); +} + +static void slhdsa_wots_pk_from_sig_do_chain( + uint8_t out[SLHDSA_SHA2_128S_WOTS_BYTES], uint8_t addr[32], + const uint8_t in[SLHDSA_SHA2_128S_WOTS_BYTES], uint8_t value, + const uint8_t pub_seed[SLHDSA_SHA2_128S_N], uint32_t chain_index) { + slhdsa_set_chain_addr(addr, chain_index); + chain(out + chain_index * SLHDSA_SHA2_128S_N, + in + chain_index * SLHDSA_SHA2_128S_N, value, + SLHDSA_SHA2_128S_WOTS_W - 1 - value, pub_seed, addr); +} + +// Implements Algorithm 8: wots_pkFromSig function, page 21 +void slhdsa_wots_pk_from_sig(uint8_t pk[SLHDSA_SHA2_128S_N], + const uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES], + const uint8_t msg[SLHDSA_SHA2_128S_N], + const uint8_t pub_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]) { + // Compute checksum + static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == SLHDSA_SHA2_128S_N * 2, ""); + uint16_t csum = 0; + for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) { + csum += SLHDSA_SHA2_128S_WOTS_W - 1 - (msg[i] >> 4); + csum += SLHDSA_SHA2_128S_WOTS_W - 1 - (msg[i] & 15); + } + + uint8_t tmp[SLHDSA_SHA2_128S_WOTS_BYTES]; + uint8_t wots_pk_addr[32]; + OPENSSL_memcpy(wots_pk_addr, addr, sizeof(wots_pk_addr)); + + uint32_t chain_index = 0; + static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == SLHDSA_SHA2_128S_N * 2, ""); + for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) { + slhdsa_wots_pk_from_sig_do_chain(tmp, addr, sig, msg[i] >> 4, pub_seed, + chain_index++); + slhdsa_wots_pk_from_sig_do_chain(tmp, addr, sig, msg[i] & 15, pub_seed, + chain_index++); + } + + slhdsa_wots_pk_from_sig_do_chain(tmp, addr, sig, csum >> 8, pub_seed, + chain_index++); + slhdsa_wots_pk_from_sig_do_chain(tmp, addr, sig, (csum >> 4) & 15, pub_seed, + chain_index++); + slhdsa_wots_pk_from_sig_do_chain(tmp, addr, sig, csum & 15, pub_seed, + chain_index++); + + // Compress pk + slhdsa_set_type(wots_pk_addr, SLHDSA_SHA2_128S_ADDR_TYPE_WOTSPK); + slhdsa_copy_keypair_addr(wots_pk_addr, addr); + slhdsa_thash_tl(pk, tmp, pub_seed, wots_pk_addr); +} diff --git a/Sources/CCryptoBoringSSL/crypto/slhdsa/wots.h b/Sources/CCryptoBoringSSL/crypto/slhdsa/wots.h new file mode 100644 index 00000000..8b3ca2de --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/slhdsa/wots.h @@ -0,0 +1,50 @@ +/* Copyright (c) 2024, Google LLC + * + * 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. */ + +#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_WOTS_H +#define OPENSSL_HEADER_CRYPTO_SLHDSA_WOTS_H + +#include "./params.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Implements Algorithm 6: wots_pkGen function, page 18 +void slhdsa_wots_pk_gen(uint8_t pk[SLHDSA_SHA2_128S_N], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pub_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements Algorithm 7: wots_sign function, page 20 +void slhdsa_wots_sign(uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES], + const uint8_t msg[SLHDSA_SHA2_128S_N], + const uint8_t sk_seed[SLHDSA_SHA2_128S_N], + const uint8_t pub_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + +// Implements Algorithm 8: wots_pkFromSig function, page 21 +void slhdsa_wots_pk_from_sig(uint8_t pk[SLHDSA_SHA2_128S_N], + const uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES], + const uint8_t msg[SLHDSA_SHA2_128S_N], + const uint8_t pub_seed[SLHDSA_SHA2_128S_N], + uint8_t addr[32]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_WOTS_H diff --git a/Sources/CCryptoBoringSSL/hash.txt b/Sources/CCryptoBoringSSL/hash.txt index 64113321..b0324a31 100644 --- a/Sources/CCryptoBoringSSL/hash.txt +++ b/Sources/CCryptoBoringSSL/hash.txt @@ -1 +1 @@ -This directory is derived from BoringSSL cloned from https://boringssl.googlesource.com/boringssl at revision 6a2ccdcc2ed1d37a43a2183658d2ae61fd5ce208 +This directory is derived from BoringSSL cloned from https://boringssl.googlesource.com/boringssl at revision 76968bb3d53982560bcf08bcd0ba3e1865fe15cd diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h index 1a02695d..a3732230 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h @@ -52,12 +52,6 @@ #ifndef OPENSSL_HEADER_BASE_H #define OPENSSL_HEADER_BASE_H -#if defined(_WIN32) && !(defined(_M_IX86) || defined(__i386__)) -#define OPENSSL_NO_ASM -#endif -#if defined(__APPLE__) && defined(__i386__) -#define OPENSSL_NO_ASM -#endif #define BORINGSSL_PREFIX CCryptoBoringSSL diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h index 89c45765..8abc6862 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h @@ -53,6 +53,27 @@ struct sha_state_st { unsigned num; }; +// SHA256_CBLOCK is the block size of SHA-256. +#define BCM_SHA256_CBLOCK 64 + +// SHA256_CTX +struct sha256_state_st { + uint32_t h[8]; + uint32_t Nl, Nh; + uint8_t data[BCM_SHA256_CBLOCK]; + 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/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h index 7ec8370c..e31d964b 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h @@ -218,6 +218,24 @@ #define BCM_sha1_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha1_init) #define BCM_sha1_transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha1_transform) #define BCM_sha1_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha1_update) +#define BCM_sha224_final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha224_final) +#define BCM_sha224_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha224_init) +#define BCM_sha224_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha224_update) +#define BCM_sha256_final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha256_final) +#define BCM_sha256_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha256_init) +#define BCM_sha256_transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha256_transform) +#define BCM_sha256_transform_blocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha256_transform_blocks) +#define BCM_sha256_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha256_update) +#define BCM_sha384_final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha384_final) +#define BCM_sha384_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha384_init) +#define BCM_sha384_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha384_update) +#define BCM_sha512_256_final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha512_256_final) +#define BCM_sha512_256_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha512_256_init) +#define BCM_sha512_256_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha512_256_update) +#define BCM_sha512_final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha512_final) +#define BCM_sha512_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha512_init) +#define BCM_sha512_transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha512_transform) +#define BCM_sha512_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_sha512_update) #define BIO_append_filename BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_append_filename) #define BIO_callback_ctrl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_callback_ctrl) #define BIO_clear_flags BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BIO_clear_flags) @@ -632,6 +650,7 @@ #define CRYPTO_get_fork_generation BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_fork_generation) #define CRYPTO_get_lock_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_lock_name) #define CRYPTO_get_locking_callback BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_locking_callback) +#define CRYPTO_get_stderr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_stderr) #define CRYPTO_get_thread_local BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_thread_local) #define CRYPTO_ghash_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_ghash_init) #define CRYPTO_has_asm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_has_asm) @@ -1673,6 +1692,7 @@ #define RSA_PSS_PARAMS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_PSS_PARAMS_new) #define RSA_add_pkcs1_prefix BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_add_pkcs1_prefix) #define RSA_bits BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_bits) +#define RSA_blinding_off BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_blinding_off) #define RSA_blinding_on BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_blinding_on) #define RSA_check_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_check_fips) #define RSA_check_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_check_key) @@ -1769,6 +1789,13 @@ #define SHA512_Transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_Transform) #define SHA512_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_Update) #define SIPHASH_24 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SIPHASH_24) +#define SLHDSA_SHA2_128S_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_generate_key) +#define SLHDSA_SHA2_128S_generate_key_from_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_generate_key_from_seed) +#define SLHDSA_SHA2_128S_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_public_from_private) +#define SLHDSA_SHA2_128S_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_sign) +#define SLHDSA_SHA2_128S_sign_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_sign_internal) +#define SLHDSA_SHA2_128S_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_verify) +#define SLHDSA_SHA2_128S_verify_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_verify_internal) #define SPAKE2_CTX_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SPAKE2_CTX_free) #define SPAKE2_CTX_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SPAKE2_CTX_new) #define SPAKE2_generate_msg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SPAKE2_generate_msg) @@ -2461,6 +2488,7 @@ #define d2i_DSA_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSA_SIG) #define d2i_DSAparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_DSAparams) #define d2i_ECDSA_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ECDSA_SIG) +#define d2i_ECPKParameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ECPKParameters) #define d2i_ECParameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ECParameters) #define d2i_ECPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ECPrivateKey) #define d2i_ECPrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ECPrivateKey_bio) @@ -2729,6 +2757,7 @@ #define i2d_DSA_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSA_SIG) #define i2d_DSAparams BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_DSAparams) #define i2d_ECDSA_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ECDSA_SIG) +#define i2d_ECPKParameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ECPKParameters) #define i2d_ECParameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ECParameters) #define i2d_ECPrivateKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ECPrivateKey) #define i2d_ECPrivateKey_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_ECPrivateKey_bio) @@ -2894,6 +2923,25 @@ #define sk_pop_free_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_pop_free_ex) #define sk_push BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_push) #define sk_value BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sk_value) +#define slhdsa_fors_pk_from_sig BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_fors_pk_from_sig) +#define slhdsa_fors_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_fors_sign) +#define slhdsa_fors_sk_gen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_fors_sk_gen) +#define slhdsa_fors_treehash BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_fors_treehash) +#define slhdsa_ht_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_ht_sign) +#define slhdsa_ht_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_ht_verify) +#define slhdsa_thash_f BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_thash_f) +#define slhdsa_thash_h BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_thash_h) +#define slhdsa_thash_hmsg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_thash_hmsg) +#define slhdsa_thash_prf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_thash_prf) +#define slhdsa_thash_prfmsg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_thash_prfmsg) +#define slhdsa_thash_tk BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_thash_tk) +#define slhdsa_thash_tl BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_thash_tl) +#define slhdsa_treehash BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_treehash) +#define slhdsa_wots_pk_from_sig BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_wots_pk_from_sig) +#define slhdsa_wots_pk_gen BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_wots_pk_gen) +#define slhdsa_wots_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_wots_sign) +#define slhdsa_xmss_pk_from_sig BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_xmss_pk_from_sig) +#define slhdsa_xmss_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, slhdsa_xmss_sign) #define spx_base_b BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, spx_base_b) #define spx_copy_keypair_addr BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, spx_copy_keypair_addr) #define spx_fors_pk_from_sig BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, spx_fors_pk_from_sig) diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h index 2d0fad13..4767eab2 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h @@ -223,6 +223,24 @@ #define _BCM_sha1_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha1_init) #define _BCM_sha1_transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha1_transform) #define _BCM_sha1_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha1_update) +#define _BCM_sha224_final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha224_final) +#define _BCM_sha224_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha224_init) +#define _BCM_sha224_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha224_update) +#define _BCM_sha256_final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha256_final) +#define _BCM_sha256_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha256_init) +#define _BCM_sha256_transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha256_transform) +#define _BCM_sha256_transform_blocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha256_transform_blocks) +#define _BCM_sha256_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha256_update) +#define _BCM_sha384_final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha384_final) +#define _BCM_sha384_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha384_init) +#define _BCM_sha384_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha384_update) +#define _BCM_sha512_256_final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha512_256_final) +#define _BCM_sha512_256_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha512_256_init) +#define _BCM_sha512_256_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha512_256_update) +#define _BCM_sha512_final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha512_final) +#define _BCM_sha512_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha512_init) +#define _BCM_sha512_transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha512_transform) +#define _BCM_sha512_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_sha512_update) #define _BIO_append_filename BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_append_filename) #define _BIO_callback_ctrl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_callback_ctrl) #define _BIO_clear_flags BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BIO_clear_flags) @@ -637,6 +655,7 @@ #define _CRYPTO_get_fork_generation BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_fork_generation) #define _CRYPTO_get_lock_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_lock_name) #define _CRYPTO_get_locking_callback BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_locking_callback) +#define _CRYPTO_get_stderr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_stderr) #define _CRYPTO_get_thread_local BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_thread_local) #define _CRYPTO_ghash_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_ghash_init) #define _CRYPTO_has_asm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_has_asm) @@ -1678,6 +1697,7 @@ #define _RSA_PSS_PARAMS_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_PSS_PARAMS_new) #define _RSA_add_pkcs1_prefix BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_add_pkcs1_prefix) #define _RSA_bits BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_bits) +#define _RSA_blinding_off BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_blinding_off) #define _RSA_blinding_on BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_blinding_on) #define _RSA_check_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_check_fips) #define _RSA_check_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_check_key) @@ -1774,6 +1794,13 @@ #define _SHA512_Transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_Transform) #define _SHA512_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_Update) #define _SIPHASH_24 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SIPHASH_24) +#define _SLHDSA_SHA2_128S_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_generate_key) +#define _SLHDSA_SHA2_128S_generate_key_from_seed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_generate_key_from_seed) +#define _SLHDSA_SHA2_128S_public_from_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_public_from_private) +#define _SLHDSA_SHA2_128S_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_sign) +#define _SLHDSA_SHA2_128S_sign_internal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_sign_internal) +#define _SLHDSA_SHA2_128S_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_verify) +#define _SLHDSA_SHA2_128S_verify_internal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SLHDSA_SHA2_128S_verify_internal) #define _SPAKE2_CTX_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SPAKE2_CTX_free) #define _SPAKE2_CTX_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SPAKE2_CTX_new) #define _SPAKE2_generate_msg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SPAKE2_generate_msg) @@ -2466,6 +2493,7 @@ #define _d2i_DSA_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSA_SIG) #define _d2i_DSAparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_DSAparams) #define _d2i_ECDSA_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ECDSA_SIG) +#define _d2i_ECPKParameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ECPKParameters) #define _d2i_ECParameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ECParameters) #define _d2i_ECPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ECPrivateKey) #define _d2i_ECPrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ECPrivateKey_bio) @@ -2734,6 +2762,7 @@ #define _i2d_DSA_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSA_SIG) #define _i2d_DSAparams BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_DSAparams) #define _i2d_ECDSA_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ECDSA_SIG) +#define _i2d_ECPKParameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ECPKParameters) #define _i2d_ECParameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ECParameters) #define _i2d_ECPrivateKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ECPrivateKey) #define _i2d_ECPrivateKey_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_ECPrivateKey_bio) @@ -2899,6 +2928,25 @@ #define _sk_pop_free_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_pop_free_ex) #define _sk_push BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_push) #define _sk_value BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sk_value) +#define _slhdsa_fors_pk_from_sig BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_fors_pk_from_sig) +#define _slhdsa_fors_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_fors_sign) +#define _slhdsa_fors_sk_gen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_fors_sk_gen) +#define _slhdsa_fors_treehash BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_fors_treehash) +#define _slhdsa_ht_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_ht_sign) +#define _slhdsa_ht_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_ht_verify) +#define _slhdsa_thash_f BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_thash_f) +#define _slhdsa_thash_h BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_thash_h) +#define _slhdsa_thash_hmsg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_thash_hmsg) +#define _slhdsa_thash_prf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_thash_prf) +#define _slhdsa_thash_prfmsg BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_thash_prfmsg) +#define _slhdsa_thash_tk BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_thash_tk) +#define _slhdsa_thash_tl BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_thash_tl) +#define _slhdsa_treehash BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_treehash) +#define _slhdsa_wots_pk_from_sig BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_wots_pk_from_sig) +#define _slhdsa_wots_pk_gen BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_wots_pk_gen) +#define _slhdsa_wots_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_wots_sign) +#define _slhdsa_xmss_pk_from_sig BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_xmss_pk_from_sig) +#define _slhdsa_xmss_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, slhdsa_xmss_sign) #define _spx_base_b BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, spx_base_b) #define _spx_copy_keypair_addr BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, spx_copy_keypair_addr) #define _spx_fors_pk_from_sig BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, spx_fors_pk_from_sig) diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h index f3cb46f0..4c441a0d 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h @@ -145,6 +145,8 @@ OPENSSL_EXPORT int ENGINE_register_all_complete(void); // OPENSSL_load_builtin_modules does nothing. OPENSSL_EXPORT void OPENSSL_load_builtin_modules(void); +// OPENSSL_INIT_* are options in OpenSSL to configure the library. In BoringSSL, +// they do nothing. #define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS 0 #define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0 #define OPENSSL_INIT_ADD_ALL_CIPHERS 0 @@ -154,6 +156,15 @@ OPENSSL_EXPORT void OPENSSL_load_builtin_modules(void); #define OPENSSL_INIT_LOAD_CONFIG 0 #define OPENSSL_INIT_NO_LOAD_CONFIG 0 #define OPENSSL_INIT_NO_ATEXIT 0 +#define OPENSSL_INIT_ATFORK 0 +#define OPENSSL_INIT_ENGINE_RDRAND 0 +#define OPENSSL_INIT_ENGINE_DYNAMIC 0 +#define OPENSSL_INIT_ENGINE_OPENSSL 0 +#define OPENSSL_INIT_ENGINE_CRYPTODEV 0 +#define OPENSSL_INIT_ENGINE_CAPI 0 +#define OPENSSL_INIT_ENGINE_PADLOCK 0 +#define OPENSSL_INIT_ENGINE_AFALG 0 +#define OPENSSL_INIT_ENGINE_ALL_BUILTIN 0 // OPENSSL_init_crypto returns one. OPENSSL_EXPORT int OPENSSL_init_crypto(uint64_t opts, diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h index f7399260..c626bc9c 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h @@ -96,6 +96,10 @@ OPENSSL_EXPORT int DH_up_ref(DH *dh); // Properties. +// OPENSSL_DH_MAX_MODULUS_BITS is the maximum supported Diffie-Hellman group +// modulus, in bits. +#define OPENSSL_DH_MAX_MODULUS_BITS 10000 + // DH_bits returns the size of |dh|'s group modulus, in bits. OPENSSL_EXPORT unsigned DH_bits(const DH *dh); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h index a16f934b..6339a782 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h @@ -99,6 +99,10 @@ OPENSSL_EXPORT int DSA_up_ref(DSA *dsa); // Properties. +// OPENSSL_DSA_MAX_MODULUS_BITS is the maximum supported DSA group modulus, in +// bits. +#define OPENSSL_DSA_MAX_MODULUS_BITS 10000 + // DSA_bits returns the size of |dsa|'s group modulus, in bits. OPENSSL_EXPORT unsigned DSA_bits(const DSA *dsa); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h index 94ba5a4d..ec4f8105 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h @@ -351,8 +351,24 @@ OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp, // Use |EC_KEY_marshal_private_key| instead. OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp); +// d2i_ECPKParameters parses a DER-encoded ECParameters structure (RFC 5480) +// from |len| bytes at |*inp|, as described in |d2i_SAMPLE|. For legacy reasons, +// it recognizes the specifiedCurve form, but only for curves that are already +// supported as named curves. +// +// Use |EC_KEY_parse_parameters| or |EC_KEY_parse_curve_name| instead. +OPENSSL_EXPORT EC_GROUP *d2i_ECPKParameters(EC_GROUP **out, const uint8_t **inp, + long len); + +// i2d_ECPKParameters marshals |group| as a DER-encoded ECParameters structure +// (RFC 5480), as described in |i2d_SAMPLE|. +// +// Use |EC_KEY_marshal_curve_name| instead. +OPENSSL_EXPORT int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp); + // d2i_ECParameters parses a DER-encoded ECParameters structure (RFC 5480) from -// |len| bytes at |*inp|, as described in |d2i_SAMPLE|. +// |len| bytes at |*inp|, as described in |d2i_SAMPLE|. It returns the result as +// an |EC_KEY| with parameters, but no key, configured. // // Use |EC_KEY_parse_parameters| or |EC_KEY_parse_curve_name| instead. OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h index a846bb76..5497a3a7 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h @@ -111,6 +111,11 @@ OPENSSL_EXPORT int RSA_up_ref(RSA *rsa); // Properties. +// OPENSSL_RSA_MAX_MODULUS_BITS is the maximum supported RSA modulus, in bits. +// +// TODO(davidben): Reduce this to 8192. +#define OPENSSL_RSA_MAX_MODULUS_BITS 16384 + // RSA_bits returns the size of |rsa|, in bits. OPENSSL_EXPORT unsigned RSA_bits(const RSA *rsa); @@ -670,11 +675,8 @@ OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *rsa, int idx); #define RSA_FLAG_OPAQUE 1 // RSA_FLAG_NO_BLINDING disables blinding of private operations, which is a -// dangerous thing to do. It is deprecated and should not be used. It will -// be ignored whenever possible. -// -// This flag must be used if a key without the public exponent |e| is used for -// private key operations; avoid using such keys whenever possible. +// dangerous thing to do. This flag is set internally as part of self-tests but +// is otherwise impossible to set externally. #define RSA_FLAG_NO_BLINDING 8 // RSA_FLAG_EXT_PKEY is deprecated and ignored. @@ -712,6 +714,9 @@ OPENSSL_EXPORT int RSA_test_flags(const RSA *rsa, int flags); // RSA_blinding_on returns one. OPENSSL_EXPORT int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +// RSA_blinding_off does nothing. +OPENSSL_EXPORT void RSA_blinding_off(RSA *rsa); + // RSA_generate_key behaves like |RSA_generate_key_ex|, which is what you // should use instead. It returns NULL on error, or a newly-allocated |RSA| on // success. This function is provided for compatibility only. The |callback| diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h index dff93f36..7a683e38 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h @@ -130,7 +130,7 @@ OPENSSL_EXPORT int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len); // 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 -// returns one on success and zero on programmer error. +// returns 1. OPENSSL_EXPORT int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], SHA256_CTX *sha); @@ -181,14 +181,6 @@ OPENSSL_EXPORT void SHA256_TransformBlocks(uint32_t state[8], const uint8_t *data, size_t num_blocks); -struct sha256_state_st { - uint32_t h[8]; - uint32_t Nl, Nh; - uint8_t data[SHA256_CBLOCK]; - unsigned num, md_len; -}; - - // SHA-384. // SHA384_CBLOCK is the block size of SHA-384. @@ -248,14 +240,6 @@ OPENSSL_EXPORT uint8_t *SHA512(const uint8_t *data, size_t len, 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 diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_slhdsa.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_slhdsa.h new file mode 100644 index 00000000..4c1d2237 --- /dev/null +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_slhdsa.h @@ -0,0 +1,79 @@ +/* Copyright (c) 2024, Google LLC + * + * 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. */ + +#ifndef OPENSSL_HEADER_SLHDSA_H +#define OPENSSL_HEADER_SLHDSA_H + +#include "CCryptoBoringSSL_base.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES is the number of bytes in an +// SLH-DSA-SHA2-128s public key. +#define SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES 32 + +// SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES is the number of bytes in an +// SLH-DSA-SHA2-128s private key. +#define SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES 64 + +// SLHDSA_SHA2_128S_SIGNATURE_BYTES is the number of bytes in an +// SLH-DSA-SHA2-128s signature. +#define SLHDSA_SHA2_128S_SIGNATURE_BYTES 7856 + +// SLHDSA_SHA2_128S_generate_key generates a SLH-DSA-SHA2-128s key pair and +// writes the result to |out_public_key| and |out_private_key|. +OPENSSL_EXPORT void SLHDSA_SHA2_128S_generate_key( + uint8_t out_public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + uint8_t out_private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]); + +// SLHDSA_SHA2_128S_public_from_private writes the public key corresponding to +// |private_key| to |out_public_key|. +OPENSSL_EXPORT void SLHDSA_SHA2_128S_public_from_private( + uint8_t out_public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + const uint8_t private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]); + +// SLHDSA_SHA2_128S_sign slowly generates a SLH-DSA-SHA2-128s signature of |msg| +// using |private_key| and writes it to |out_signature|. The |context| argument +// is also signed over and can be used to include implicit contextual +// information that isn't included in |msg|. The same value of |context| must be +// presented to |SLHDSA_SHA2_128S_verify| in order for the generated signature +// to be considered valid. |context| and |context_len| may be |NULL| and 0 to +// use an empty context (this is common). It returns 1 on success and 0 if +// |context_len| is larger than 255. +OPENSSL_EXPORT int SLHDSA_SHA2_128S_sign( + uint8_t out_signature[SLHDSA_SHA2_128S_SIGNATURE_BYTES], + const uint8_t private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], + const uint8_t *msg, size_t msg_len, const uint8_t *context, + size_t context_len); + +// SLHDSA_SHA2_128S_verify verifies that |signature| is a valid +// SLH-DSA-SHA2-128s signature of |msg| by |public_key|. The value of |context| +// must equal the value that was passed to |SLHDSA_SHA2_128S_sign| when the +// signature was generated. It returns 1 if the signature is valid and 0 +// otherwise. +OPENSSL_EXPORT int SLHDSA_SHA2_128S_verify( + const uint8_t *signature, size_t signature_len, + const uint8_t public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + const uint8_t *msg, size_t msg_len, const uint8_t *context, + size_t context_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_SLHDSA_H diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_span.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_span.h index 90ee7bb1..af6f0504 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_span.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_span.h @@ -234,6 +234,11 @@ constexpr auto MakeSpan(C &c) -> decltype(MakeSpan(c.data(), c.size())) { return MakeSpan(c.data(), c.size()); } +template +constexpr Span MakeSpan(T (&array)[N]) { + return Span(array, N); +} + template constexpr Span MakeConstSpan(T *ptr, size_t size) { return Span(ptr, size); diff --git a/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc b/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc index 517fba6f..e1ebe170 100644 --- a/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc +++ b/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc @@ -215,6 +215,24 @@ %xdefine _BCM_sha1_init _ %+ BORINGSSL_PREFIX %+ _BCM_sha1_init %xdefine _BCM_sha1_transform _ %+ BORINGSSL_PREFIX %+ _BCM_sha1_transform %xdefine _BCM_sha1_update _ %+ BORINGSSL_PREFIX %+ _BCM_sha1_update +%xdefine _BCM_sha224_final _ %+ BORINGSSL_PREFIX %+ _BCM_sha224_final +%xdefine _BCM_sha224_init _ %+ BORINGSSL_PREFIX %+ _BCM_sha224_init +%xdefine _BCM_sha224_update _ %+ BORINGSSL_PREFIX %+ _BCM_sha224_update +%xdefine _BCM_sha256_final _ %+ BORINGSSL_PREFIX %+ _BCM_sha256_final +%xdefine _BCM_sha256_init _ %+ BORINGSSL_PREFIX %+ _BCM_sha256_init +%xdefine _BCM_sha256_transform _ %+ BORINGSSL_PREFIX %+ _BCM_sha256_transform +%xdefine _BCM_sha256_transform_blocks _ %+ BORINGSSL_PREFIX %+ _BCM_sha256_transform_blocks +%xdefine _BCM_sha256_update _ %+ BORINGSSL_PREFIX %+ _BCM_sha256_update +%xdefine _BCM_sha384_final _ %+ BORINGSSL_PREFIX %+ _BCM_sha384_final +%xdefine _BCM_sha384_init _ %+ BORINGSSL_PREFIX %+ _BCM_sha384_init +%xdefine _BCM_sha384_update _ %+ BORINGSSL_PREFIX %+ _BCM_sha384_update +%xdefine _BCM_sha512_256_final _ %+ BORINGSSL_PREFIX %+ _BCM_sha512_256_final +%xdefine _BCM_sha512_256_init _ %+ BORINGSSL_PREFIX %+ _BCM_sha512_256_init +%xdefine _BCM_sha512_256_update _ %+ BORINGSSL_PREFIX %+ _BCM_sha512_256_update +%xdefine _BCM_sha512_final _ %+ BORINGSSL_PREFIX %+ _BCM_sha512_final +%xdefine _BCM_sha512_init _ %+ BORINGSSL_PREFIX %+ _BCM_sha512_init +%xdefine _BCM_sha512_transform _ %+ BORINGSSL_PREFIX %+ _BCM_sha512_transform +%xdefine _BCM_sha512_update _ %+ BORINGSSL_PREFIX %+ _BCM_sha512_update %xdefine _BIO_append_filename _ %+ BORINGSSL_PREFIX %+ _BIO_append_filename %xdefine _BIO_callback_ctrl _ %+ BORINGSSL_PREFIX %+ _BIO_callback_ctrl %xdefine _BIO_clear_flags _ %+ BORINGSSL_PREFIX %+ _BIO_clear_flags @@ -629,6 +647,7 @@ %xdefine _CRYPTO_get_fork_generation _ %+ BORINGSSL_PREFIX %+ _CRYPTO_get_fork_generation %xdefine _CRYPTO_get_lock_name _ %+ BORINGSSL_PREFIX %+ _CRYPTO_get_lock_name %xdefine _CRYPTO_get_locking_callback _ %+ BORINGSSL_PREFIX %+ _CRYPTO_get_locking_callback +%xdefine _CRYPTO_get_stderr _ %+ BORINGSSL_PREFIX %+ _CRYPTO_get_stderr %xdefine _CRYPTO_get_thread_local _ %+ BORINGSSL_PREFIX %+ _CRYPTO_get_thread_local %xdefine _CRYPTO_ghash_init _ %+ BORINGSSL_PREFIX %+ _CRYPTO_ghash_init %xdefine _CRYPTO_has_asm _ %+ BORINGSSL_PREFIX %+ _CRYPTO_has_asm @@ -1670,6 +1689,7 @@ %xdefine _RSA_PSS_PARAMS_new _ %+ BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_new %xdefine _RSA_add_pkcs1_prefix _ %+ BORINGSSL_PREFIX %+ _RSA_add_pkcs1_prefix %xdefine _RSA_bits _ %+ BORINGSSL_PREFIX %+ _RSA_bits +%xdefine _RSA_blinding_off _ %+ BORINGSSL_PREFIX %+ _RSA_blinding_off %xdefine _RSA_blinding_on _ %+ BORINGSSL_PREFIX %+ _RSA_blinding_on %xdefine _RSA_check_fips _ %+ BORINGSSL_PREFIX %+ _RSA_check_fips %xdefine _RSA_check_key _ %+ BORINGSSL_PREFIX %+ _RSA_check_key @@ -1766,6 +1786,13 @@ %xdefine _SHA512_Transform _ %+ BORINGSSL_PREFIX %+ _SHA512_Transform %xdefine _SHA512_Update _ %+ BORINGSSL_PREFIX %+ _SHA512_Update %xdefine _SIPHASH_24 _ %+ BORINGSSL_PREFIX %+ _SIPHASH_24 +%xdefine _SLHDSA_SHA2_128S_generate_key _ %+ BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_generate_key +%xdefine _SLHDSA_SHA2_128S_generate_key_from_seed _ %+ BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_generate_key_from_seed +%xdefine _SLHDSA_SHA2_128S_public_from_private _ %+ BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_public_from_private +%xdefine _SLHDSA_SHA2_128S_sign _ %+ BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_sign +%xdefine _SLHDSA_SHA2_128S_sign_internal _ %+ BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_sign_internal +%xdefine _SLHDSA_SHA2_128S_verify _ %+ BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_verify +%xdefine _SLHDSA_SHA2_128S_verify_internal _ %+ BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_verify_internal %xdefine _SPAKE2_CTX_free _ %+ BORINGSSL_PREFIX %+ _SPAKE2_CTX_free %xdefine _SPAKE2_CTX_new _ %+ BORINGSSL_PREFIX %+ _SPAKE2_CTX_new %xdefine _SPAKE2_generate_msg _ %+ BORINGSSL_PREFIX %+ _SPAKE2_generate_msg @@ -2458,6 +2485,7 @@ %xdefine _d2i_DSA_SIG _ %+ BORINGSSL_PREFIX %+ _d2i_DSA_SIG %xdefine _d2i_DSAparams _ %+ BORINGSSL_PREFIX %+ _d2i_DSAparams %xdefine _d2i_ECDSA_SIG _ %+ BORINGSSL_PREFIX %+ _d2i_ECDSA_SIG +%xdefine _d2i_ECPKParameters _ %+ BORINGSSL_PREFIX %+ _d2i_ECPKParameters %xdefine _d2i_ECParameters _ %+ BORINGSSL_PREFIX %+ _d2i_ECParameters %xdefine _d2i_ECPrivateKey _ %+ BORINGSSL_PREFIX %+ _d2i_ECPrivateKey %xdefine _d2i_ECPrivateKey_bio _ %+ BORINGSSL_PREFIX %+ _d2i_ECPrivateKey_bio @@ -2726,6 +2754,7 @@ %xdefine _i2d_DSA_SIG _ %+ BORINGSSL_PREFIX %+ _i2d_DSA_SIG %xdefine _i2d_DSAparams _ %+ BORINGSSL_PREFIX %+ _i2d_DSAparams %xdefine _i2d_ECDSA_SIG _ %+ BORINGSSL_PREFIX %+ _i2d_ECDSA_SIG +%xdefine _i2d_ECPKParameters _ %+ BORINGSSL_PREFIX %+ _i2d_ECPKParameters %xdefine _i2d_ECParameters _ %+ BORINGSSL_PREFIX %+ _i2d_ECParameters %xdefine _i2d_ECPrivateKey _ %+ BORINGSSL_PREFIX %+ _i2d_ECPrivateKey %xdefine _i2d_ECPrivateKey_bio _ %+ BORINGSSL_PREFIX %+ _i2d_ECPrivateKey_bio @@ -2891,6 +2920,25 @@ %xdefine _sk_pop_free_ex _ %+ BORINGSSL_PREFIX %+ _sk_pop_free_ex %xdefine _sk_push _ %+ BORINGSSL_PREFIX %+ _sk_push %xdefine _sk_value _ %+ BORINGSSL_PREFIX %+ _sk_value +%xdefine _slhdsa_fors_pk_from_sig _ %+ BORINGSSL_PREFIX %+ _slhdsa_fors_pk_from_sig +%xdefine _slhdsa_fors_sign _ %+ BORINGSSL_PREFIX %+ _slhdsa_fors_sign +%xdefine _slhdsa_fors_sk_gen _ %+ BORINGSSL_PREFIX %+ _slhdsa_fors_sk_gen +%xdefine _slhdsa_fors_treehash _ %+ BORINGSSL_PREFIX %+ _slhdsa_fors_treehash +%xdefine _slhdsa_ht_sign _ %+ BORINGSSL_PREFIX %+ _slhdsa_ht_sign +%xdefine _slhdsa_ht_verify _ %+ BORINGSSL_PREFIX %+ _slhdsa_ht_verify +%xdefine _slhdsa_thash_f _ %+ BORINGSSL_PREFIX %+ _slhdsa_thash_f +%xdefine _slhdsa_thash_h _ %+ BORINGSSL_PREFIX %+ _slhdsa_thash_h +%xdefine _slhdsa_thash_hmsg _ %+ BORINGSSL_PREFIX %+ _slhdsa_thash_hmsg +%xdefine _slhdsa_thash_prf _ %+ BORINGSSL_PREFIX %+ _slhdsa_thash_prf +%xdefine _slhdsa_thash_prfmsg _ %+ BORINGSSL_PREFIX %+ _slhdsa_thash_prfmsg +%xdefine _slhdsa_thash_tk _ %+ BORINGSSL_PREFIX %+ _slhdsa_thash_tk +%xdefine _slhdsa_thash_tl _ %+ BORINGSSL_PREFIX %+ _slhdsa_thash_tl +%xdefine _slhdsa_treehash _ %+ BORINGSSL_PREFIX %+ _slhdsa_treehash +%xdefine _slhdsa_wots_pk_from_sig _ %+ BORINGSSL_PREFIX %+ _slhdsa_wots_pk_from_sig +%xdefine _slhdsa_wots_pk_gen _ %+ BORINGSSL_PREFIX %+ _slhdsa_wots_pk_gen +%xdefine _slhdsa_wots_sign _ %+ BORINGSSL_PREFIX %+ _slhdsa_wots_sign +%xdefine _slhdsa_xmss_pk_from_sig _ %+ BORINGSSL_PREFIX %+ _slhdsa_xmss_pk_from_sig +%xdefine _slhdsa_xmss_sign _ %+ BORINGSSL_PREFIX %+ _slhdsa_xmss_sign %xdefine _spx_base_b _ %+ BORINGSSL_PREFIX %+ _spx_base_b %xdefine _spx_copy_keypair_addr _ %+ BORINGSSL_PREFIX %+ _spx_copy_keypair_addr %xdefine _spx_fors_pk_from_sig _ %+ BORINGSSL_PREFIX %+ _spx_fors_pk_from_sig @@ -3204,6 +3252,24 @@ %xdefine BCM_sha1_init BORINGSSL_PREFIX %+ _BCM_sha1_init %xdefine BCM_sha1_transform BORINGSSL_PREFIX %+ _BCM_sha1_transform %xdefine BCM_sha1_update BORINGSSL_PREFIX %+ _BCM_sha1_update +%xdefine BCM_sha224_final BORINGSSL_PREFIX %+ _BCM_sha224_final +%xdefine BCM_sha224_init BORINGSSL_PREFIX %+ _BCM_sha224_init +%xdefine BCM_sha224_update BORINGSSL_PREFIX %+ _BCM_sha224_update +%xdefine BCM_sha256_final BORINGSSL_PREFIX %+ _BCM_sha256_final +%xdefine BCM_sha256_init BORINGSSL_PREFIX %+ _BCM_sha256_init +%xdefine BCM_sha256_transform BORINGSSL_PREFIX %+ _BCM_sha256_transform +%xdefine BCM_sha256_transform_blocks BORINGSSL_PREFIX %+ _BCM_sha256_transform_blocks +%xdefine BCM_sha256_update BORINGSSL_PREFIX %+ _BCM_sha256_update +%xdefine BCM_sha384_final BORINGSSL_PREFIX %+ _BCM_sha384_final +%xdefine BCM_sha384_init BORINGSSL_PREFIX %+ _BCM_sha384_init +%xdefine BCM_sha384_update BORINGSSL_PREFIX %+ _BCM_sha384_update +%xdefine BCM_sha512_256_final BORINGSSL_PREFIX %+ _BCM_sha512_256_final +%xdefine BCM_sha512_256_init BORINGSSL_PREFIX %+ _BCM_sha512_256_init +%xdefine BCM_sha512_256_update BORINGSSL_PREFIX %+ _BCM_sha512_256_update +%xdefine BCM_sha512_final BORINGSSL_PREFIX %+ _BCM_sha512_final +%xdefine BCM_sha512_init BORINGSSL_PREFIX %+ _BCM_sha512_init +%xdefine BCM_sha512_transform BORINGSSL_PREFIX %+ _BCM_sha512_transform +%xdefine BCM_sha512_update BORINGSSL_PREFIX %+ _BCM_sha512_update %xdefine BIO_append_filename BORINGSSL_PREFIX %+ _BIO_append_filename %xdefine BIO_callback_ctrl BORINGSSL_PREFIX %+ _BIO_callback_ctrl %xdefine BIO_clear_flags BORINGSSL_PREFIX %+ _BIO_clear_flags @@ -3618,6 +3684,7 @@ %xdefine CRYPTO_get_fork_generation BORINGSSL_PREFIX %+ _CRYPTO_get_fork_generation %xdefine CRYPTO_get_lock_name BORINGSSL_PREFIX %+ _CRYPTO_get_lock_name %xdefine CRYPTO_get_locking_callback BORINGSSL_PREFIX %+ _CRYPTO_get_locking_callback +%xdefine CRYPTO_get_stderr BORINGSSL_PREFIX %+ _CRYPTO_get_stderr %xdefine CRYPTO_get_thread_local BORINGSSL_PREFIX %+ _CRYPTO_get_thread_local %xdefine CRYPTO_ghash_init BORINGSSL_PREFIX %+ _CRYPTO_ghash_init %xdefine CRYPTO_has_asm BORINGSSL_PREFIX %+ _CRYPTO_has_asm @@ -4659,6 +4726,7 @@ %xdefine RSA_PSS_PARAMS_new BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_new %xdefine RSA_add_pkcs1_prefix BORINGSSL_PREFIX %+ _RSA_add_pkcs1_prefix %xdefine RSA_bits BORINGSSL_PREFIX %+ _RSA_bits +%xdefine RSA_blinding_off BORINGSSL_PREFIX %+ _RSA_blinding_off %xdefine RSA_blinding_on BORINGSSL_PREFIX %+ _RSA_blinding_on %xdefine RSA_check_fips BORINGSSL_PREFIX %+ _RSA_check_fips %xdefine RSA_check_key BORINGSSL_PREFIX %+ _RSA_check_key @@ -4755,6 +4823,13 @@ %xdefine SHA512_Transform BORINGSSL_PREFIX %+ _SHA512_Transform %xdefine SHA512_Update BORINGSSL_PREFIX %+ _SHA512_Update %xdefine SIPHASH_24 BORINGSSL_PREFIX %+ _SIPHASH_24 +%xdefine SLHDSA_SHA2_128S_generate_key BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_generate_key +%xdefine SLHDSA_SHA2_128S_generate_key_from_seed BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_generate_key_from_seed +%xdefine SLHDSA_SHA2_128S_public_from_private BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_public_from_private +%xdefine SLHDSA_SHA2_128S_sign BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_sign +%xdefine SLHDSA_SHA2_128S_sign_internal BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_sign_internal +%xdefine SLHDSA_SHA2_128S_verify BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_verify +%xdefine SLHDSA_SHA2_128S_verify_internal BORINGSSL_PREFIX %+ _SLHDSA_SHA2_128S_verify_internal %xdefine SPAKE2_CTX_free BORINGSSL_PREFIX %+ _SPAKE2_CTX_free %xdefine SPAKE2_CTX_new BORINGSSL_PREFIX %+ _SPAKE2_CTX_new %xdefine SPAKE2_generate_msg BORINGSSL_PREFIX %+ _SPAKE2_generate_msg @@ -5447,6 +5522,7 @@ %xdefine d2i_DSA_SIG BORINGSSL_PREFIX %+ _d2i_DSA_SIG %xdefine d2i_DSAparams BORINGSSL_PREFIX %+ _d2i_DSAparams %xdefine d2i_ECDSA_SIG BORINGSSL_PREFIX %+ _d2i_ECDSA_SIG +%xdefine d2i_ECPKParameters BORINGSSL_PREFIX %+ _d2i_ECPKParameters %xdefine d2i_ECParameters BORINGSSL_PREFIX %+ _d2i_ECParameters %xdefine d2i_ECPrivateKey BORINGSSL_PREFIX %+ _d2i_ECPrivateKey %xdefine d2i_ECPrivateKey_bio BORINGSSL_PREFIX %+ _d2i_ECPrivateKey_bio @@ -5715,6 +5791,7 @@ %xdefine i2d_DSA_SIG BORINGSSL_PREFIX %+ _i2d_DSA_SIG %xdefine i2d_DSAparams BORINGSSL_PREFIX %+ _i2d_DSAparams %xdefine i2d_ECDSA_SIG BORINGSSL_PREFIX %+ _i2d_ECDSA_SIG +%xdefine i2d_ECPKParameters BORINGSSL_PREFIX %+ _i2d_ECPKParameters %xdefine i2d_ECParameters BORINGSSL_PREFIX %+ _i2d_ECParameters %xdefine i2d_ECPrivateKey BORINGSSL_PREFIX %+ _i2d_ECPrivateKey %xdefine i2d_ECPrivateKey_bio BORINGSSL_PREFIX %+ _i2d_ECPrivateKey_bio @@ -5880,6 +5957,25 @@ %xdefine sk_pop_free_ex BORINGSSL_PREFIX %+ _sk_pop_free_ex %xdefine sk_push BORINGSSL_PREFIX %+ _sk_push %xdefine sk_value BORINGSSL_PREFIX %+ _sk_value +%xdefine slhdsa_fors_pk_from_sig BORINGSSL_PREFIX %+ _slhdsa_fors_pk_from_sig +%xdefine slhdsa_fors_sign BORINGSSL_PREFIX %+ _slhdsa_fors_sign +%xdefine slhdsa_fors_sk_gen BORINGSSL_PREFIX %+ _slhdsa_fors_sk_gen +%xdefine slhdsa_fors_treehash BORINGSSL_PREFIX %+ _slhdsa_fors_treehash +%xdefine slhdsa_ht_sign BORINGSSL_PREFIX %+ _slhdsa_ht_sign +%xdefine slhdsa_ht_verify BORINGSSL_PREFIX %+ _slhdsa_ht_verify +%xdefine slhdsa_thash_f BORINGSSL_PREFIX %+ _slhdsa_thash_f +%xdefine slhdsa_thash_h BORINGSSL_PREFIX %+ _slhdsa_thash_h +%xdefine slhdsa_thash_hmsg BORINGSSL_PREFIX %+ _slhdsa_thash_hmsg +%xdefine slhdsa_thash_prf BORINGSSL_PREFIX %+ _slhdsa_thash_prf +%xdefine slhdsa_thash_prfmsg BORINGSSL_PREFIX %+ _slhdsa_thash_prfmsg +%xdefine slhdsa_thash_tk BORINGSSL_PREFIX %+ _slhdsa_thash_tk +%xdefine slhdsa_thash_tl BORINGSSL_PREFIX %+ _slhdsa_thash_tl +%xdefine slhdsa_treehash BORINGSSL_PREFIX %+ _slhdsa_treehash +%xdefine slhdsa_wots_pk_from_sig BORINGSSL_PREFIX %+ _slhdsa_wots_pk_from_sig +%xdefine slhdsa_wots_pk_gen BORINGSSL_PREFIX %+ _slhdsa_wots_pk_gen +%xdefine slhdsa_wots_sign BORINGSSL_PREFIX %+ _slhdsa_wots_sign +%xdefine slhdsa_xmss_pk_from_sig BORINGSSL_PREFIX %+ _slhdsa_xmss_pk_from_sig +%xdefine slhdsa_xmss_sign BORINGSSL_PREFIX %+ _slhdsa_xmss_sign %xdefine spx_base_b BORINGSSL_PREFIX %+ _spx_base_b %xdefine spx_copy_keypair_addr BORINGSSL_PREFIX %+ _spx_copy_keypair_addr %xdefine spx_fors_pk_from_sig BORINGSSL_PREFIX %+ _spx_fors_pk_from_sig diff --git a/scripts/vendor-boringssl.sh b/scripts/vendor-boringssl.sh index 12bccce3..e4987039 100755 --- a/scripts/vendor-boringssl.sh +++ b/scripts/vendor-boringssl.sh @@ -101,9 +101,9 @@ function mangle_symbols { ) # Now cross compile for our targets. - docker run -t -i --rm --privileged -v$(pwd):/src -w/src --platform linux/arm64 swift:5.8-jammy \ + docker run -t -i --rm --privileged -v$(pwd):/src -w/src --platform linux/arm64 swift:5.9-jammy \ swift build --product CCryptoBoringSSL - docker run -t -i --rm --privileged -v$(pwd):/src -w/src --platform linux/amd64 swift:5.8-jammy \ + docker run -t -i --rm --privileged -v$(pwd):/src -w/src --platform linux/amd64 swift:5.9-jammy \ swift build --product CCryptoBoringSSL # Now we need to generate symbol mangles for Linux. We can do this in @@ -241,14 +241,6 @@ echo "REMOVING libssl" mangle_symbols -# Removing ASM on 32 bit Apple platforms -echo "REMOVING assembly on 32-bit Apple platforms" -gsed -i "/#define OPENSSL_HEADER_BASE_H/a#if defined(__APPLE__) && defined(__i386__)\n#define OPENSSL_NO_ASM\n#endif" "$DSTROOT/include/openssl/base.h" - -# Remove assembly on non-x86 Windows -echo "REMOVING assembly on non-x86 Windows" -gsed -i "/#define OPENSSL_HEADER_BASE_H/a#if defined(_WIN32) && !(defined(_M_IX86) || defined(__i386__))\n#define OPENSSL_NO_ASM\n#endif" "$DSTROOT/include/openssl/base.h" - echo "RENAMING header files" ( # We need to rearrange a coouple of things here, the end state will be: