update main-with-bazel from master branch

This commit is contained in:
BoringSSL Robot
2024-12-19 00:10:17 +00:00
27 changed files with 794 additions and 659 deletions
+11 -11
View File
@@ -83,6 +83,11 @@ fips_fragments = [
"src/crypto/fipsmodule/sha/sha1.cc.inc",
"src/crypto/fipsmodule/sha/sha256.cc.inc",
"src/crypto/fipsmodule/sha/sha512.cc.inc",
"src/crypto/fipsmodule/slhdsa/fors.cc.inc",
"src/crypto/fipsmodule/slhdsa/merkle.cc.inc",
"src/crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
"src/crypto/fipsmodule/slhdsa/thash.cc.inc",
"src/crypto/fipsmodule/slhdsa/wots.cc.inc",
"src/crypto/fipsmodule/tls/kdf.cc.inc",
]
@@ -258,6 +263,12 @@ crypto_internal_headers = [
"src/crypto/fipsmodule/rsa/internal.h",
"src/crypto/fipsmodule/service_indicator/internal.h",
"src/crypto/fipsmodule/sha/internal.h",
"src/crypto/fipsmodule/slhdsa/address.h",
"src/crypto/fipsmodule/slhdsa/fors.h",
"src/crypto/fipsmodule/slhdsa/merkle.h",
"src/crypto/fipsmodule/slhdsa/params.h",
"src/crypto/fipsmodule/slhdsa/thash.h",
"src/crypto/fipsmodule/slhdsa/wots.h",
"src/crypto/fipsmodule/tls/internal.h",
"src/crypto/hrss/internal.h",
"src/crypto/internal.h",
@@ -272,13 +283,6 @@ crypto_internal_headers = [
"src/crypto/rand_extra/getrandom_fillin.h",
"src/crypto/rand_extra/sysrand_internal.h",
"src/crypto/rsa_extra/internal.h",
"src/crypto/slhdsa/address.h",
"src/crypto/slhdsa/fors.h",
"src/crypto/slhdsa/internal.h",
"src/crypto/slhdsa/merkle.h",
"src/crypto/slhdsa/params.h",
"src/crypto/slhdsa/thash.h",
"src/crypto/slhdsa/wots.h",
"src/crypto/trust_token/internal.h",
"src/crypto/x509/ext_dat.h",
"src/crypto/x509/internal.h",
@@ -449,11 +453,7 @@ crypto_sources = [
"src/crypto/sha/sha256.cc",
"src/crypto/sha/sha512.cc",
"src/crypto/siphash/siphash.cc",
"src/crypto/slhdsa/fors.cc",
"src/crypto/slhdsa/merkle.cc",
"src/crypto/slhdsa/slhdsa.cc",
"src/crypto/slhdsa/thash.cc",
"src/crypto/slhdsa/wots.cc",
"src/crypto/stack/stack.cc",
"src/crypto/thread.cc",
"src/crypto/thread_none.cc",
+6 -7
View File
@@ -37,6 +37,12 @@ test_support_sources = [
"src/crypto/fipsmodule/rsa/internal.h",
"src/crypto/fipsmodule/service_indicator/internal.h",
"src/crypto/fipsmodule/sha/internal.h",
"src/crypto/fipsmodule/slhdsa/address.h",
"src/crypto/fipsmodule/slhdsa/fors.h",
"src/crypto/fipsmodule/slhdsa/merkle.h",
"src/crypto/fipsmodule/slhdsa/params.h",
"src/crypto/fipsmodule/slhdsa/thash.h",
"src/crypto/fipsmodule/slhdsa/wots.h",
"src/crypto/fipsmodule/tls/internal.h",
"src/crypto/hrss/internal.h",
"src/crypto/internal.h",
@@ -51,13 +57,6 @@ test_support_sources = [
"src/crypto/rand_extra/getrandom_fillin.h",
"src/crypto/rand_extra/sysrand_internal.h",
"src/crypto/rsa_extra/internal.h",
"src/crypto/slhdsa/address.h",
"src/crypto/slhdsa/fors.h",
"src/crypto/slhdsa/internal.h",
"src/crypto/slhdsa/merkle.h",
"src/crypto/slhdsa/params.h",
"src/crypto/slhdsa/thash.h",
"src/crypto/slhdsa/wots.h",
"src/crypto/test/abi_test.cc",
"src/crypto/test/abi_test.h",
"src/crypto/test/file_test.cc",
-4
View File
@@ -420,11 +420,7 @@ add_library(
src/crypto/sha/sha256.cc
src/crypto/sha/sha512.cc
src/crypto/siphash/siphash.cc
src/crypto/slhdsa/fors.cc
src/crypto/slhdsa/merkle.cc
src/crypto/slhdsa/slhdsa.cc
src/crypto/slhdsa/thash.cc
src/crypto/slhdsa/wots.cc
src/crypto/stack/stack.cc
src/crypto/thread.cc
src/crypto/thread_none.cc
+11 -11
View File
@@ -160,11 +160,7 @@
"src/crypto/sha/sha256.cc",
"src/crypto/sha/sha512.cc",
"src/crypto/siphash/siphash.cc",
"src/crypto/slhdsa/fors.cc",
"src/crypto/slhdsa/merkle.cc",
"src/crypto/slhdsa/slhdsa.cc",
"src/crypto/slhdsa/thash.cc",
"src/crypto/slhdsa/wots.cc",
"src/crypto/stack/stack.cc",
"src/crypto/thread.cc",
"src/crypto/thread_none.cc",
@@ -502,6 +498,12 @@
"src/crypto/fipsmodule/rsa/internal.h",
"src/crypto/fipsmodule/service_indicator/internal.h",
"src/crypto/fipsmodule/sha/internal.h",
"src/crypto/fipsmodule/slhdsa/address.h",
"src/crypto/fipsmodule/slhdsa/fors.h",
"src/crypto/fipsmodule/slhdsa/merkle.h",
"src/crypto/fipsmodule/slhdsa/params.h",
"src/crypto/fipsmodule/slhdsa/thash.h",
"src/crypto/fipsmodule/slhdsa/wots.h",
"src/crypto/fipsmodule/tls/internal.h",
"src/crypto/hrss/internal.h",
"src/crypto/internal.h",
@@ -516,13 +518,6 @@
"src/crypto/rand_extra/getrandom_fillin.h",
"src/crypto/rand_extra/sysrand_internal.h",
"src/crypto/rsa_extra/internal.h",
"src/crypto/slhdsa/address.h",
"src/crypto/slhdsa/fors.h",
"src/crypto/slhdsa/internal.h",
"src/crypto/slhdsa/merkle.h",
"src/crypto/slhdsa/params.h",
"src/crypto/slhdsa/thash.h",
"src/crypto/slhdsa/wots.h",
"src/crypto/trust_token/internal.h",
"src/crypto/x509/ext_dat.h",
"src/crypto/x509/internal.h",
@@ -976,6 +971,11 @@
"src/crypto/fipsmodule/sha/sha1.cc.inc",
"src/crypto/fipsmodule/sha/sha256.cc.inc",
"src/crypto/fipsmodule/sha/sha512.cc.inc",
"src/crypto/fipsmodule/slhdsa/fors.cc.inc",
"src/crypto/fipsmodule/slhdsa/merkle.cc.inc",
"src/crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
"src/crypto/fipsmodule/slhdsa/thash.cc.inc",
"src/crypto/fipsmodule/slhdsa/wots.cc.inc",
"src/crypto/fipsmodule/tls/kdf.cc.inc"
],
"fuzz": [
+12 -12
View File
@@ -90,6 +90,11 @@
"crypto/fipsmodule/sha/sha1.cc.inc",
"crypto/fipsmodule/sha/sha256.cc.inc",
"crypto/fipsmodule/sha/sha512.cc.inc",
"crypto/fipsmodule/slhdsa/fors.cc.inc",
"crypto/fipsmodule/slhdsa/merkle.cc.inc",
"crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
"crypto/fipsmodule/slhdsa/thash.cc.inc",
"crypto/fipsmodule/slhdsa/wots.cc.inc",
"crypto/fipsmodule/tls/kdf.cc.inc"
],
"asm": [
@@ -305,15 +310,11 @@
"crypto/rsa_extra/rsa_crypt.cc",
"crypto/rsa_extra/rsa_extra.cc",
"crypto/rsa_extra/rsa_print.cc",
"crypto/slhdsa/slhdsa.cc",
"crypto/sha/sha1.cc",
"crypto/sha/sha256.cc",
"crypto/sha/sha512.cc",
"crypto/siphash/siphash.cc",
"crypto/slhdsa/fors.cc",
"crypto/slhdsa/merkle.cc",
"crypto/slhdsa/slhdsa.cc",
"crypto/slhdsa/thash.cc",
"crypto/slhdsa/wots.cc",
"crypto/stack/stack.cc",
"crypto/thread.cc",
"crypto/thread_none.cc",
@@ -518,6 +519,12 @@
"crypto/fipsmodule/rsa/internal.h",
"crypto/fipsmodule/service_indicator/internal.h",
"crypto/fipsmodule/sha/internal.h",
"crypto/fipsmodule/slhdsa/address.h",
"crypto/fipsmodule/slhdsa/fors.h",
"crypto/fipsmodule/slhdsa/merkle.h",
"crypto/fipsmodule/slhdsa/params.h",
"crypto/fipsmodule/slhdsa/thash.h",
"crypto/fipsmodule/slhdsa/wots.h",
"crypto/fipsmodule/tls/internal.h",
"crypto/hrss/internal.h",
"crypto/bcm_support.h",
@@ -533,13 +540,6 @@
"crypto/rand_extra/getrandom_fillin.h",
"crypto/rand_extra/sysrand_internal.h",
"crypto/rsa_extra/internal.h",
"crypto/slhdsa/address.h",
"crypto/slhdsa/fors.h",
"crypto/slhdsa/internal.h",
"crypto/slhdsa/merkle.h",
"crypto/slhdsa/params.h",
"crypto/slhdsa/thash.h",
"crypto/slhdsa/wots.h",
"crypto/trust_token/internal.h",
"crypto/x509/ext_dat.h",
"crypto/x509/internal.h",
+5
View File
@@ -108,6 +108,11 @@
#include "sha/sha1.cc.inc"
#include "sha/sha256.cc.inc"
#include "sha/sha512.cc.inc"
#include "slhdsa/fors.cc.inc"
#include "slhdsa/merkle.cc.inc"
#include "slhdsa/slhdsa.cc.inc"
#include "slhdsa/thash.cc.inc"
#include "slhdsa/wots.cc.inc"
#include "tls/kdf.cc.inc"
+85
View File
@@ -637,6 +637,91 @@ OPENSSL_EXPORT bcm_status BCM_mlkem1024_marshal_private_key(
CBB *out, const struct BCM_mlkem1024_private_key *private_key);
// SLH-DSA
// Output length of the hash function.
#define BCM_SLHDSA_SHA2_128S_N 16
// The number of bytes at the beginning of M', the augmented message, before the
// context.
#define BCM_SLHDSA_M_PRIME_HEADER_LEN 2
// SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES is the number of bytes in an
// SLH-DSA-SHA2-128s public key.
#define BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES 32
// BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES is the number of bytes in an
// SLH-DSA-SHA2-128s private key.
#define BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES 64
// BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES is the number of bytes in an
// SLH-DSA-SHA2-128s signature.
#define BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES 7856
// 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 bcm_infallible BCM_slhdsa_sha2_128s_generate_key_from_seed(
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
uint8_t out_secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N]);
// BCM_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 bcm_infallible BCM_slhdsa_sha2_128s_sign_internal(
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
const uint8_t secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
const uint8_t header[BCM_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[BCM_SLHDSA_SHA2_128S_N]);
// BCM_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 bcm_status BCM_slhdsa_sha2_128s_verify_internal(
const uint8_t *signature, size_t signature_len,
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
size_t context_len, const uint8_t *msg, size_t msg_len);
OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_generate_key(
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]);
OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_public_from_private(
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]);
OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_sign(
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
const uint8_t *msg, size_t msg_len, const uint8_t *context,
size_t context_len);
OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_verify(
const uint8_t *signature, size_t signature_len,
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
const uint8_t *msg, size_t msg_len, const uint8_t *context,
size_t context_len);
OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_prehash_sign(
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
const uint8_t *context, size_t context_len);
OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_prehash_verify(
const uint8_t *signature, size_t signature_len,
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
const uint8_t *context, size_t context_len);
#if defined(__cplusplus)
} // extern C
#endif
@@ -12,12 +12,12 @@
* 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
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_ADDRESS_H
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_ADDRESS_H
#include <openssl/mem.h>
#include "../internal.h"
#include "../../internal.h"
#if defined(__cplusplus)
extern "C" {
@@ -116,4 +116,4 @@ inline uint32_t slhdsa_get_tree_index(uint8_t addr[32]) {
} // extern C
#endif
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_ADDRESS_H
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_ADDRESS_H
@@ -17,7 +17,7 @@
#include <assert.h>
#include <string.h>
#include "../internal.h"
#include "../../internal.h"
#include "./address.h"
#include "./fors.h"
#include "./params.h"
@@ -40,9 +40,9 @@ static void fors_base_b(
}
// 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],
void slhdsa_fors_sk_gen(uint8_t fors_sk[BCM_SLHDSA_SHA2_128S_N], uint32_t idx,
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
uint8_t addr[32]) {
uint8_t sk_addr[32];
OPENSSL_memcpy(sk_addr, addr, sizeof(sk_addr));
@@ -54,27 +54,27 @@ void slhdsa_fors_sk_gen(uint8_t fors_sk[SLHDSA_SHA2_128S_N], uint32_t idx,
}
// 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],
void slhdsa_fors_treehash(uint8_t root_node[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_seed[BCM_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],
const uint8_t pk_seed[BCM_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];
uint8_t sk[BCM_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];
uint8_t nodes[2 * BCM_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,
slhdsa_fors_treehash(nodes + BCM_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);
@@ -85,8 +85,8 @@ void slhdsa_fors_treehash(uint8_t root_node[SLHDSA_SHA2_128S_N],
// 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],
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
uint8_t addr[32]) {
uint16_t indices[SLHDSA_SHA2_128S_FORS_TREES];
@@ -97,14 +97,14 @@ void slhdsa_fors_sign(uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES],
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),
fors_sig + i * BCM_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 *
fors_sig + BCM_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);
@@ -114,13 +114,13 @@ void slhdsa_fors_sign(uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES],
// Implements Algorithm 17: fors_pkFromSig function (page 32)
void slhdsa_fors_pk_from_sig(
uint8_t fors_pk[SLHDSA_SHA2_128S_N],
uint8_t fors_pk[BCM_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]) {
const uint8_t pk_seed[BCM_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];
uint8_t tmp[2 * BCM_SLHDSA_SHA2_128S_N];
uint8_t roots[SLHDSA_SHA2_128S_FORS_TREES * BCM_SLHDSA_SHA2_128S_N];
// Derive FORS indices compatible with the NIST changes.
fors_base_b(indices, message);
@@ -128,11 +128,11 @@ void slhdsa_fors_pk_from_sig(
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);
fors_sig + i * BCM_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];
fors_sig + i * BCM_SLHDSA_SHA2_128S_N * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1) +
BCM_SLHDSA_SHA2_128S_N;
uint8_t nodes[2 * BCM_SLHDSA_SHA2_128S_N];
slhdsa_set_tree_height(addr, 0);
slhdsa_set_tree_index(
@@ -146,19 +146,19 @@ void slhdsa_fors_pk_from_sig(
// 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);
OPENSSL_memcpy(tmp, nodes, BCM_SLHDSA_SHA2_128S_N);
OPENSSL_memcpy(tmp + BCM_SLHDSA_SHA2_128S_N, auth + j * BCM_SLHDSA_SHA2_128S_N,
BCM_SLHDSA_SHA2_128S_N);
slhdsa_thash_h(nodes + BCM_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(tmp, auth + j * BCM_SLHDSA_SHA2_128S_N, BCM_SLHDSA_SHA2_128S_N);
OPENSSL_memcpy(tmp + BCM_SLHDSA_SHA2_128S_N, nodes, BCM_SLHDSA_SHA2_128S_N);
slhdsa_thash_h(nodes + BCM_SLHDSA_SHA2_128S_N, tmp, pk_seed, addr);
}
OPENSSL_memcpy(nodes, nodes + SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N);
OPENSSL_memcpy(nodes, nodes + BCM_SLHDSA_SHA2_128S_N, BCM_SLHDSA_SHA2_128S_N);
}
OPENSSL_memcpy(roots + i * SLHDSA_SHA2_128S_N, nodes, SLHDSA_SHA2_128S_N);
OPENSSL_memcpy(roots + i * BCM_SLHDSA_SHA2_128S_N, nodes, BCM_SLHDSA_SHA2_128S_N);
}
uint8_t forspk_addr[32];
@@ -12,8 +12,8 @@
* 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
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_FORS_H
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_FORS_H
#include "./params.h"
@@ -23,36 +23,36 @@ extern "C" {
// 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],
void slhdsa_fors_sk_gen(uint8_t fors_sk[BCM_SLHDSA_SHA2_128S_N], uint32_t idx,
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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],
void slhdsa_fors_treehash(uint8_t root_node[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_seed[BCM_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],
const uint8_t pk_seed[BCM_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],
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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],
uint8_t fors_pk[BCM_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]);
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N], uint8_t addr[32]);
#if defined(__cplusplus)
} // extern C
#endif
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_FORS_H
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_FORS_H
@@ -16,7 +16,7 @@
#include <string.h>
#include "../internal.h"
#include "../../internal.h"
#include "./address.h"
#include "./merkle.h"
#include "./params.h"
@@ -25,11 +25,11 @@
// 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],
void slhdsa_treehash(uint8_t out_pk[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_seed[BCM_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],
const uint8_t pk_seed[BCM_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)));
@@ -40,9 +40,9 @@ void slhdsa_treehash(uint8_t out_pk[SLHDSA_SHA2_128S_N],
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];
uint8_t nodes[2 * BCM_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,
slhdsa_treehash(nodes + BCM_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);
@@ -53,14 +53,14 @@ void slhdsa_treehash(uint8_t out_pk[SLHDSA_SHA2_128S_N],
// 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],
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N], unsigned int idx,
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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,
slhdsa_treehash(sig + SLHDSA_SHA2_128S_WOTS_BYTES + j * BCM_SLHDSA_SHA2_128S_N,
sk_seed, k, j, pk_seed, addr);
}
@@ -72,52 +72,52 @@ void slhdsa_xmss_sign(uint8_t sig[SLHDSA_SHA2_128S_XMSS_BYTES],
// Implements Algorithm 11: xmss_pkFromSig function (page 25)
void slhdsa_xmss_pk_from_sig(
uint8_t root[SLHDSA_SHA2_128S_N],
uint8_t root[BCM_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]) {
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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];
uint8_t node[2 * BCM_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];
uint8_t tmp[2 * BCM_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);
OPENSSL_memcpy(tmp, node, BCM_SLHDSA_SHA2_128S_N);
OPENSSL_memcpy(tmp + BCM_SLHDSA_SHA2_128S_N, auth + k * BCM_SLHDSA_SHA2_128S_N,
BCM_SLHDSA_SHA2_128S_N);
slhdsa_thash_h(node + BCM_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(tmp, auth + k * BCM_SLHDSA_SHA2_128S_N, BCM_SLHDSA_SHA2_128S_N);
OPENSSL_memcpy(tmp + BCM_SLHDSA_SHA2_128S_N, node, BCM_SLHDSA_SHA2_128S_N);
slhdsa_thash_h(node + BCM_SLHDSA_SHA2_128S_N, tmp, pk_seed, addr);
}
OPENSSL_memcpy(node, node + SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N);
OPENSSL_memcpy(node, node + BCM_SLHDSA_SHA2_128S_N, BCM_SLHDSA_SHA2_128S_N);
}
OPENSSL_memcpy(root, node, SLHDSA_SHA2_128S_N);
OPENSSL_memcpy(root, node, BCM_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]) {
const uint8_t message[BCM_SLHDSA_SHA2_128S_N], uint64_t idx_tree,
uint32_t idx_leaf, const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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];
uint8_t root[BCM_SLHDSA_SHA2_128S_N];
slhdsa_xmss_pk_from_sig(root, sig, idx_leaf, message, pk_seed, addr);
sig += SLHDSA_SHA2_128S_XMSS_BYTES;
@@ -139,13 +139,13 @@ void slhdsa_ht_sign(
// 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]) {
const uint8_t message[BCM_SLHDSA_SHA2_128S_N], uint64_t idx_tree,
uint32_t idx_leaf, const uint8_t pk_root[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N]) {
uint8_t addr[32] = {0};
slhdsa_set_tree_addr(addr, idx_tree);
uint8_t node[SLHDSA_SHA2_128S_N];
uint8_t node[BCM_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) {
@@ -157,5 +157,5 @@ int slhdsa_ht_verify(
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;
return memcmp(node, pk_root, BCM_SLHDSA_SHA2_128S_N) == 0;
}
@@ -12,8 +12,8 @@
* 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
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_MERKLE_H
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_MERKLE_H
#include <openssl/base.h>
@@ -27,44 +27,44 @@ extern "C" {
// 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],
void slhdsa_treehash(uint8_t out_pk[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_seed[BCM_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],
const uint8_t pk_seed[BCM_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],
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N], unsigned int idx,
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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],
uint8_t root[BCM_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]);
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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]);
const uint8_t message[BCM_SLHDSA_SHA2_128S_N], uint64_t idx_tree,
uint32_t idx_leaf, const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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]);
const uint8_t message[BCM_SLHDSA_SHA2_128S_N], uint64_t idx_tree,
uint32_t idx_leaf, const uint8_t pk_root[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N]);
#if defined(__cplusplus)
} // extern C
#endif
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_MERKLE_H
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_MERKLE_H
@@ -12,18 +12,16 @@
* 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
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_PARAMS_H
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_PARAMS_H
#include <openssl/base.h>
#include "../bcm_interface.h"
#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.
@@ -37,10 +35,7 @@ extern "C" {
// 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
BCM_SLHDSA_SHA2_128S_N)
// Winternitz parameter and derived values
#define SLHDSA_SHA2_128S_WOTS_W 16
@@ -49,12 +44,12 @@ extern "C" {
#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)
(BCM_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))
(BCM_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)
@@ -80,4 +75,4 @@ extern "C" {
} // extern C
#endif
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_PARAMS_H
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_PARAMS_H
+319
View File
@@ -0,0 +1,319 @@
/* Copyright 2014 The BoringSSL Authors
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/base.h>
#include <string.h>
#include <openssl/bytestring.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
#include "../../internal.h"
#include "../bcm_interface.h"
#include "address.h"
#include "fors.h"
#include "merkle.h"
#include "params.h"
#include "thash.h"
// The OBJECT IDENTIFIER header is also included in these values, per the spec.
static const uint8_t kSHA384OID[] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x02, 0x02};
#define MAX_OID_LENGTH 11
#define MAX_CONTEXT_LENGTH 255
bcm_infallible BCM_slhdsa_sha2_128s_generate_key_from_seed(
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
uint8_t out_secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N]) {
// Initialize SK.seed || SK.prf || PK.seed from seed.
OPENSSL_memcpy(out_secret_key, seed, 3 * BCM_SLHDSA_SHA2_128S_N);
// Initialize PK.seed from seed.
OPENSSL_memcpy(out_public_key, seed + 2 * BCM_SLHDSA_SHA2_128S_N,
BCM_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 + BCM_SLHDSA_SHA2_128S_N, out_secret_key, 0,
SLHDSA_SHA2_128S_TREE_HEIGHT, out_public_key, addr);
OPENSSL_memcpy(out_secret_key + 3 * BCM_SLHDSA_SHA2_128S_N,
out_public_key + BCM_SLHDSA_SHA2_128S_N,
BCM_SLHDSA_SHA2_128S_N);
return bcm_infallible::approved;
}
bcm_infallible BCM_slhdsa_sha2_128s_generate_key(
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) {
uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N];
RAND_bytes(seed, 3 * BCM_SLHDSA_SHA2_128S_N);
BCM_slhdsa_sha2_128s_generate_key_from_seed(out_public_key, out_private_key,
seed);
return bcm_infallible::approved;
}
bcm_infallible BCM_slhdsa_sha2_128s_public_from_private(
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) {
OPENSSL_memcpy(out_public_key, private_key + 2 * BCM_SLHDSA_SHA2_128S_N,
BCM_SLHDSA_SHA2_128S_N * 2);
return bcm_infallible::approved;
}
// 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)
bcm_infallible BCM_slhdsa_sha2_128s_sign_internal(
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
const uint8_t secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
const uint8_t header[BCM_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[BCM_SLHDSA_SHA2_128S_N]) {
const uint8_t *sk_seed = secret_key;
const uint8_t *sk_prf = secret_key + BCM_SLHDSA_SHA2_128S_N;
const uint8_t *pk_seed = secret_key + 2 * BCM_SLHDSA_SHA2_128S_N;
const uint8_t *pk_root = secret_key + 3 * BCM_SLHDSA_SHA2_128S_N;
// Derive randomizer R and copy it to signature
uint8_t R[BCM_SLHDSA_SHA2_128S_N];
slhdsa_thash_prfmsg(R, sk_prf, entropy, header, context, context_len, msg,
msg_len);
OPENSSL_memcpy(out_signature, R, BCM_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 + BCM_SLHDSA_SHA2_128S_N, fors_digest, sk_seed,
pk_seed, addr);
uint8_t pk_fors[BCM_SLHDSA_SHA2_128S_N];
slhdsa_fors_pk_from_sig(pk_fors, out_signature + BCM_SLHDSA_SHA2_128S_N,
fors_digest, pk_seed, addr);
slhdsa_ht_sign(
out_signature + BCM_SLHDSA_SHA2_128S_N + SLHDSA_SHA2_128S_FORS_BYTES,
pk_fors, idx_tree, idx_leaf, sk_seed, pk_seed);
return bcm_infallible::approved;
}
bcm_status BCM_slhdsa_sha2_128s_sign(
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
const uint8_t private_key[BCM_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 > MAX_CONTEXT_LENGTH) {
return bcm_status::failure;
}
// 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[BCM_SLHDSA_SHA2_128S_N];
RAND_bytes(entropy, sizeof(entropy));
BCM_slhdsa_sha2_128s_sign_internal(out_signature, private_key, M_prime_header,
context, context_len, msg, msg_len,
entropy);
return bcm_status::approved;
}
static int slhdsa_get_context_and_oid(uint8_t *out_context_and_oid,
size_t *out_context_and_oid_len,
size_t max_out_context_and_oid,
const uint8_t *context,
size_t context_len, int hash_nid,
size_t hashed_msg_len) {
const uint8_t *oid;
size_t oid_len;
size_t expected_hash_len;
switch (hash_nid) {
// The SLH-DSA spec only lists SHA-256 and SHA-512. This function supports
// SHA-384, which is non-standard.
case NID_sha384:
oid = kSHA384OID;
oid_len = sizeof(kSHA384OID);
static_assert(sizeof(kSHA384OID) <= MAX_OID_LENGTH, "");
expected_hash_len = 48;
break;
// If adding a hash function with a larger `oid_len`, update the size of
// `context_and_oid` in the callers.
default:
return 0;
}
if (hashed_msg_len != expected_hash_len) {
return 0;
}
*out_context_and_oid_len = context_len + oid_len;
if (*out_context_and_oid_len > max_out_context_and_oid) {
return 0;
}
OPENSSL_memcpy(out_context_and_oid, context, context_len);
OPENSSL_memcpy(out_context_and_oid + context_len, oid, oid_len);
return 1;
}
bcm_status BCM_slhdsa_sha2_128s_prehash_sign(
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
const uint8_t *context, size_t context_len) {
if (context_len > MAX_CONTEXT_LENGTH) {
return bcm_status::failure;
}
uint8_t M_prime_header[2];
M_prime_header[0] = 1; // domain separator for prehashed signing
M_prime_header[1] = (uint8_t)context_len;
uint8_t context_and_oid[MAX_CONTEXT_LENGTH + MAX_OID_LENGTH];
size_t context_and_oid_len;
if (!slhdsa_get_context_and_oid(context_and_oid, &context_and_oid_len,
sizeof(context_and_oid), context, context_len,
hash_nid, hashed_msg_len)) {
return bcm_status::failure;
}
uint8_t entropy[BCM_SLHDSA_SHA2_128S_N];
RAND_bytes(entropy, sizeof(entropy));
BCM_slhdsa_sha2_128s_sign_internal(out_signature, private_key, M_prime_header,
context_and_oid, context_and_oid_len,
hashed_msg, hashed_msg_len, entropy);
return bcm_status::approved;
}
// Implements Algorithm 24: slh_verify function (Section 10.3, page 41)
bcm_status BCM_slhdsa_sha2_128s_verify(
const uint8_t *signature, size_t signature_len,
const uint8_t public_key[BCM_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 > MAX_CONTEXT_LENGTH) {
return bcm_status::failure;
}
// 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 BCM_slhdsa_sha2_128s_verify_internal(
signature, signature_len, public_key, M_prime_header, context,
context_len, msg, msg_len);
}
bcm_status BCM_slhdsa_sha2_128s_prehash_verify(
const uint8_t *signature, size_t signature_len,
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
const uint8_t *context, size_t context_len) {
if (context_len > MAX_CONTEXT_LENGTH) {
return bcm_status::failure;
}
uint8_t M_prime_header[2];
M_prime_header[0] = 1; // domain separator for prehashed verification
M_prime_header[1] = (uint8_t)context_len;
uint8_t context_and_oid[MAX_CONTEXT_LENGTH + MAX_OID_LENGTH];
size_t context_and_oid_len;
if (!slhdsa_get_context_and_oid(context_and_oid, &context_and_oid_len,
sizeof(context_and_oid), context, context_len,
hash_nid, hashed_msg_len)) {
return bcm_status::failure;
}
return BCM_slhdsa_sha2_128s_verify_internal(
signature, signature_len, public_key, M_prime_header, context_and_oid,
context_and_oid_len, hashed_msg, hashed_msg_len);
}
bcm_status BCM_slhdsa_sha2_128s_verify_internal(
const uint8_t *signature, size_t signature_len,
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
size_t context_len, const uint8_t *msg, size_t msg_len) {
if (signature_len != BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES) {
return bcm_status::failure;
}
const uint8_t *pk_seed = public_key;
const uint8_t *pk_root = public_key + BCM_SLHDSA_SHA2_128S_N;
const uint8_t *r = signature;
const uint8_t *sig_fors = signature + BCM_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[BCM_SLHDSA_SHA2_128S_N];
slhdsa_fors_pk_from_sig(pk_fors, sig_fors, fors_digest, pk_seed, addr);
if (!slhdsa_ht_verify(sig_ht, pk_fors, idx_tree, idx_leaf, pk_root,
pk_seed)) {
return bcm_status::failure;
}
return bcm_status::approved;
}
@@ -19,108 +19,108 @@
#include <openssl/sha.h>
#include "../internal.h"
#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],
static void slhdsa_thash(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t *input, size_t input_blocks,
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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);
static const uint8_t kZeros[64 - BCM_SLHDSA_SHA2_128S_N] = {0};
SHA256_Update(&sha256, pk_seed, BCM_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);
SHA256_Update(&sha256, input, input_blocks * BCM_SLHDSA_SHA2_128S_N);
uint8_t hash[32];
SHA256_Final(hash, &sha256);
OPENSSL_memcpy(output, hash, SLHDSA_SHA2_128S_N);
OPENSSL_memcpy(output, hash, BCM_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],
void slhdsa_thash_prfmsg(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_prf[BCM_SLHDSA_SHA2_128S_N],
const uint8_t entropy[BCM_SLHDSA_SHA2_128S_N],
const uint8_t header[BCM_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,
static_assert(BCM_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++) {
OPENSSL_memcpy(hmac_key, sk_prf, BCM_SLHDSA_SHA2_128S_N);
for (size_t i = 0; i < BCM_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);
OPENSSL_memset(hmac_key + BCM_SLHDSA_SHA2_128S_N, 0x36,
sizeof(hmac_key) - BCM_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);
SHA256_Update(&sha_ctx, entropy, BCM_SLHDSA_SHA2_128S_N);
if (header) {
SHA256_Update(&sha_ctx, header, SLHDSA_M_PRIME_HEADER_LEN);
SHA256_Update(&sha_ctx, header, BCM_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++) {
for (size_t i = 0; i < BCM_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);
OPENSSL_memset(hmac_key + BCM_SLHDSA_SHA2_128S_N, 0x5c,
sizeof(hmac_key) - BCM_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);
// Truncate to BCM_SLHDSA_SHA2_128S_N bytes
OPENSSL_memcpy(output, hash, BCM_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 r[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_root[BCM_SLHDSA_SHA2_128S_N],
const uint8_t header[BCM_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);
uint8_t input_buffer[2 * BCM_SLHDSA_SHA2_128S_N + 32 + 4] = {0};
OPENSSL_memcpy(input_buffer, r, BCM_SLHDSA_SHA2_128S_N);
OPENSSL_memcpy(input_buffer + BCM_SLHDSA_SHA2_128S_N, pk_seed,
BCM_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);
SHA256_Update(&sha_ctx, r, BCM_SLHDSA_SHA2_128S_N);
SHA256_Update(&sha_ctx, pk_seed, BCM_SLHDSA_SHA2_128S_N);
SHA256_Update(&sha_ctx, pk_root, BCM_SLHDSA_SHA2_128S_N);
if (header) {
SHA256_Update(&sha_ctx, header, SLHDSA_M_PRIME_HEADER_LEN);
SHA256_Update(&sha_ctx, header, BCM_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);
SHA256_Final(input_buffer + 2 * BCM_SLHDSA_SHA2_128S_N, &sha_ctx);
// MGF1-SHA-256
uint8_t hash[32];
@@ -131,34 +131,34 @@ void slhdsa_thash_hmsg(uint8_t output[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],
void slhdsa_thash_prf(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_seed[BCM_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],
void slhdsa_thash_tl(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t input[SLHDSA_SHA2_128S_WOTS_BYTES],
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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],
void slhdsa_thash_h(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t input[2 * BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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],
void slhdsa_thash_f(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t input[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
uint8_t addr[32]) {
slhdsa_thash(output, input, 1, pk_seed, addr);
}
@@ -166,8 +166,8 @@ void slhdsa_thash_f(uint8_t output[SLHDSA_SHA2_128S_N],
// 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]) {
uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t input[SLHDSA_SHA2_128S_FORS_TREES * BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N], uint8_t addr[32]) {
slhdsa_thash(output, input, SLHDSA_SHA2_128S_FORS_TREES, pk_seed, addr);
}
@@ -12,8 +12,8 @@
* 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
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_THASH_H
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_THASH_H
#include "./params.h"
@@ -25,61 +25,61 @@ extern "C" {
// 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],
void slhdsa_thash_prfmsg(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_prf[BCM_SLHDSA_SHA2_128S_N],
const uint8_t opt_rand[BCM_SLHDSA_SHA2_128S_N],
const uint8_t header[BCM_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 r[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_root[BCM_SLHDSA_SHA2_128S_N],
const uint8_t header[BCM_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],
void slhdsa_thash_prf(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_seed[BCM_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],
void slhdsa_thash_tl(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t input[SLHDSA_SHA2_128S_WOTS_BYTES],
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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],
void slhdsa_thash_h(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t input[2 * BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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],
void slhdsa_thash_f(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t input[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_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]);
uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t input[SLHDSA_SHA2_128S_FORS_TREES * BCM_SLHDSA_SHA2_128S_N],
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N], uint8_t addr[32]);
#if defined(__cplusplus)
} // extern C
#endif
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_THASH_H
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_THASH_H
@@ -18,7 +18,7 @@
#include <stdint.h>
#include <string.h>
#include "../internal.h"
#include "../../internal.h"
#include "./address.h"
#include "./params.h"
#include "./thash.h"
@@ -26,14 +26,14 @@
// 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],
static void chain(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
const uint8_t input[BCM_SLHDSA_SHA2_128S_N], uint32_t start,
uint32_t steps, const uint8_t pub_seed[BCM_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);
OPENSSL_memcpy(output, input, BCM_SLHDSA_SHA2_128S_N);
for (size_t i = start; i < (start + steps) && i < SLHDSA_SHA2_128S_WOTS_W;
++i) {
@@ -42,13 +42,13 @@ static void chain(uint8_t output[SLHDSA_SHA2_128S_N],
}
}
static void slhdsa_wots_do_chain(uint8_t out[SLHDSA_SHA2_128S_N],
static void slhdsa_wots_do_chain(uint8_t out[BCM_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],
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
uint32_t chain_index) {
uint8_t tmp_sk[SLHDSA_SHA2_128S_N];
uint8_t tmp_sk[BCM_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);
@@ -56,9 +56,9 @@ static void slhdsa_wots_do_chain(uint8_t out[SLHDSA_SHA2_128S_N],
}
// 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],
void slhdsa_wots_pk_gen(uint8_t pk[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pub_seed[BCM_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));
@@ -68,7 +68,7 @@ void slhdsa_wots_pk_gen(uint8_t pk[SLHDSA_SHA2_128S_N],
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_wots_do_chain(tmp + i * BCM_SLHDSA_SHA2_128S_N, sk_addr, addr,
SLHDSA_SHA2_128S_WOTS_W - 1, sk_seed, pub_seed, i);
}
@@ -80,14 +80,14 @@ void slhdsa_wots_pk_gen(uint8_t pk[SLHDSA_SHA2_128S_N],
// 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],
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
uint8_t addr[32]) {
// Compute checksum
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == SLHDSA_SHA2_128S_N * 2, "");
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == BCM_SLHDSA_SHA2_128S_N * 2, "");
uint16_t csum = 0;
for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) {
for (size_t i = 0; i < BCM_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);
}
@@ -99,23 +99,23 @@ void slhdsa_wots_sign(uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES],
slhdsa_copy_keypair_addr(sk_addr, addr);
uint32_t chain_index = 0;
for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) {
for (size_t i = 0; i < BCM_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;
sig += BCM_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;
sig += BCM_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;
sig += BCM_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;
sig += BCM_SLHDSA_SHA2_128S_N;
slhdsa_wots_do_chain(sig, sk_addr, addr, csum & 15, sk_seed, pub_seed,
chain_index++);
}
@@ -123,23 +123,23 @@ void slhdsa_wots_sign(uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES],
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) {
const uint8_t pub_seed[BCM_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,
chain(out + chain_index * BCM_SLHDSA_SHA2_128S_N,
in + chain_index * BCM_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],
void slhdsa_wots_pk_from_sig(uint8_t pk[BCM_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],
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
uint8_t addr[32]) {
// Compute checksum
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == SLHDSA_SHA2_128S_N * 2, "");
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == BCM_SLHDSA_SHA2_128S_N * 2, "");
uint16_t csum = 0;
for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) {
for (size_t i = 0; i < BCM_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);
}
@@ -149,8 +149,8 @@ void slhdsa_wots_pk_from_sig(uint8_t pk[SLHDSA_SHA2_128S_N],
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) {
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == BCM_SLHDSA_SHA2_128S_N * 2, "");
for (size_t i = 0; i < BCM_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,
@@ -12,8 +12,8 @@
* 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
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_WOTS_H
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_WOTS_H
#include "./params.h"
@@ -23,23 +23,23 @@ extern "C" {
// 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],
void slhdsa_wots_pk_gen(uint8_t pk[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pub_seed[BCM_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],
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pub_seed[BCM_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],
void slhdsa_wots_pk_from_sig(uint8_t pk[BCM_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],
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
uint8_t addr[32]);
@@ -47,4 +47,4 @@ void slhdsa_wots_pk_from_sig(uint8_t pk[SLHDSA_SHA2_128S_N],
} // extern C
#endif
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_WOTS_H
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_WOTS_H
+14 -4
View File
@@ -135,7 +135,7 @@ static const uint16_t kModRoots[128] = {
// reduce_once reduces 0 <= x < 2*kPrime, mod kPrime.
static uint16_t reduce_once(uint16_t x) {
assert(x < 2 * kPrime);
declassify_assert(x < 2 * kPrime);
const uint16_t subtracted = x - kPrime;
uint16_t mask = 0u - (subtracted >> 15);
// Although this is a constant-time select, we omit a value barrier here.
@@ -153,7 +153,7 @@ static uint16_t reduce_once(uint16_t x) {
// constant time reduce x mod kPrime using Barrett reduction. x must be less
// than kPrime + 2×kPrime².
static uint16_t reduce(uint32_t x) {
assert(x < kPrime + 2u * kPrime * kPrime);
declassify_assert(x < kPrime + 2u * kPrime * kPrime);
uint64_t product = (uint64_t)x * kBarrettMultiplier;
uint32_t quotient = (uint32_t)(product >> kBarrettShift);
uint32_t remainder = x - quotient * kPrime;
@@ -480,7 +480,9 @@ static int scalar_decode(scalar *out, const uint8_t *in, int bits) {
element_bits_done += chunk_bits;
}
if (element >= kPrime) {
// An element is only out of range in the case of invalid input, in which
// case it is okay to leak the comparison.
if (constant_time_declassify_int(element >= kPrime)) {
return 0;
}
out->c[i] = element;
@@ -528,7 +530,7 @@ static uint16_t compress(uint16_t x, int bits) {
// 0 <= remainder <= kHalfPrime round to 0
// kHalfPrime < remainder <= kPrime + kHalfPrime round to 1
// kPrime + kHalfPrime < remainder < 2 * kPrime round to 2
assert(remainder < 2u * kPrime);
declassify_assert(remainder < 2u * kPrime);
quotient += 1 & constant_time_lt_w(kHalfPrime, remainder);
quotient += 1 & constant_time_lt_w(kPrime + kHalfPrime, remainder);
return quotient & ((1 << bits) - 1);
@@ -617,6 +619,7 @@ void KYBER_generate_key(uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES],
struct KYBER_private_key *out_private_key) {
uint8_t entropy[KYBER_GENERATE_KEY_ENTROPY];
RAND_bytes(entropy, sizeof(entropy));
CONSTTIME_SECRET(entropy, sizeof(entropy));
KYBER_generate_key_external_entropy(out_encoded_public_key, out_private_key,
entropy);
}
@@ -645,6 +648,8 @@ void KYBER_generate_key_external_entropy(
hash_g(hashed, entropy, 32);
const uint8_t *const rho = hashed;
const uint8_t *const sigma = hashed + 32;
// rho is public.
CONSTTIME_DECLASSIFY(rho, 32);
OPENSSL_memcpy(priv->pub.rho, hashed, sizeof(priv->pub.rho));
matrix_expand(&priv->pub.m, rho);
uint8_t counter = 0;
@@ -655,6 +660,8 @@ void KYBER_generate_key_external_entropy(
vector_ntt(&error);
matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s);
vector_add(&priv->pub.t, &error);
// t is part of the public key and thus is public.
CONSTTIME_DECLASSIFY(&priv->pub.t, sizeof(priv->pub.t));
CBB cbb;
CBB_init_fixed(&cbb, out_encoded_public_key, KYBER_PUBLIC_KEY_BYTES);
@@ -716,6 +723,7 @@ void KYBER_encap(uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES],
const struct KYBER_public_key *public_key) {
uint8_t entropy[KYBER_ENCAP_ENTROPY];
RAND_bytes(entropy, KYBER_ENCAP_ENTROPY);
CONSTTIME_SECRET(entropy, KYBER_ENCAP_ENTROPY);
KYBER_encap_external_entropy(out_ciphertext, out_shared_secret, public_key,
entropy);
}
@@ -739,6 +747,8 @@ void KYBER_encap_external_entropy(
uint8_t prekey_and_randomness[64];
hash_g(prekey_and_randomness, input, sizeof(input));
encrypt_cpa(out_ciphertext, pub, entropy, prekey_and_randomness + 32);
// The ciphertext is public.
CONSTTIME_DECLASSIFY(out_ciphertext, KYBER_CIPHERTEXT_BYTES);
hash_h(prekey_and_randomness + 32, out_ciphertext, KYBER_CIPHERTEXT_BYTES);
kdf(out_shared_secret, KYBER_SHARED_SECRET_BYTES, prekey_and_randomness,
sizeof(prekey_and_randomness));
+20 -10
View File
@@ -95,17 +95,20 @@ TEST(KyberTest, Basic) {
sizeof(first_two_bytes));
CBS_init(&cbs, encoded_private_key.data(), encoded_private_key.size());
ASSERT_TRUE(KYBER_parse_private_key(priv2.get(), &cbs));
EXPECT_EQ(Bytes(encoded_private_key),
Bytes(Marshal(KYBER_marshal_private_key, priv2.get())));
EXPECT_EQ(
Bytes(Declassified(encoded_private_key)),
Bytes(Declassified((Marshal(KYBER_marshal_private_key, priv2.get())))));
uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES];
uint8_t shared_secret1[KYBER_SHARED_SECRET_BYTES];
uint8_t shared_secret2[KYBER_SHARED_SECRET_BYTES];
KYBER_encap(ciphertext, shared_secret1, pub.get());
KYBER_decap(shared_secret2, ciphertext, priv.get());
EXPECT_EQ(Bytes(shared_secret1), Bytes(shared_secret2));
EXPECT_EQ(Bytes(Declassified(shared_secret1)),
Bytes(Declassified(shared_secret2)));
KYBER_decap(shared_secret2, ciphertext, priv2.get());
EXPECT_EQ(Bytes(shared_secret1), Bytes(shared_secret2));
EXPECT_EQ(Bytes(Declassified(shared_secret1)),
Bytes(Declassified(shared_secret2)));
}
static void KyberFileTest(FileTest *t) {
@@ -134,6 +137,7 @@ static void KyberFileTest(FileTest *t) {
// The test vectors provide a CTR-DRBG seed which is used to generate the
// input entropy.
ASSERT_EQ(seed.size(), size_t{CTR_DRBG_ENTROPY_LEN});
CONSTTIME_SECRET(seed.data(), seed.size());
{
bssl::UniquePtr<CTR_DRBG_STATE> state(
CTR_DRBG_new(seed.data(), nullptr, 0));
@@ -146,8 +150,10 @@ static void KyberFileTest(FileTest *t) {
KYBER_ENCAP_ENTROPY, nullptr, 0));
}
EXPECT_EQ(Bytes(gen_key_entropy), Bytes(given_generate_entropy));
EXPECT_EQ(Bytes(encap_entropy), Bytes(given_encap_entropy_pre_hash));
EXPECT_EQ(Bytes(Declassified(gen_key_entropy)),
Bytes(given_generate_entropy));
EXPECT_EQ(Bytes(Declassified(encap_entropy)),
Bytes(given_encap_entropy_pre_hash));
BORINGSSL_keccak(encap_entropy, sizeof(encap_entropy), encap_entropy,
sizeof(encap_entropy), boringssl_sha3_256);
@@ -165,11 +171,14 @@ static void KyberFileTest(FileTest *t) {
encap_entropy);
KYBER_decap(decapsulated_key, ciphertext, &priv);
EXPECT_EQ(Bytes(encapsulated_key), Bytes(decapsulated_key));
EXPECT_EQ(Bytes(private_key_expected), Bytes(encoded_private_key));
EXPECT_EQ(Bytes(Declassified(encapsulated_key)),
Bytes(Declassified(decapsulated_key)));
EXPECT_EQ(Bytes(private_key_expected),
Bytes(Declassified(encoded_private_key)));
EXPECT_EQ(Bytes(public_key_expected), Bytes(encoded_public_key));
EXPECT_EQ(Bytes(ciphertext_expected), Bytes(ciphertext));
EXPECT_EQ(Bytes(shared_secret_expected), Bytes(encapsulated_key));
EXPECT_EQ(Bytes(shared_secret_expected),
Bytes(Declassified(encapsulated_key)));
uint8_t corrupted_ciphertext[KYBER_CIPHERTEXT_BYTES];
OPENSSL_memcpy(corrupted_ciphertext, ciphertext, KYBER_CIPHERTEXT_BYTES);
@@ -179,7 +188,8 @@ static void KyberFileTest(FileTest *t) {
// It would be nice to have actual test vectors for the failure case, but the
// NIST submission currently does not include those, so we are just testing
// for inequality.
EXPECT_NE(Bytes(encapsulated_key), Bytes(corrupted_decapsulated_key));
EXPECT_NE(Bytes(Declassified(encapsulated_key)),
Bytes(Declassified(corrupted_decapsulated_key)));
}
TEST(KyberTest, TestVectors) {
-63
View File
@@ -1,63 +0,0 @@
/* Copyright 2024 The BoringSSL Authors
*
* 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 <openssl/slhdsa.h>
#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
+31 -251
View File
@@ -14,122 +14,31 @@
#include <openssl/slhdsa.h>
#include <string.h>
#include <openssl/bytestring.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
#include "../internal.h"
#include "address.h"
#include "fors.h"
#include "internal.h"
#include "merkle.h"
#include "params.h"
#include "thash.h"
#include "../fipsmodule/bcm_interface.h"
// The OBJECT IDENTIFIER header is also included in these values, per the spec.
static const uint8_t kSHA384OID[] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x02, 0x02};
#define MAX_OID_LENGTH 11
#define MAX_CONTEXT_LENGTH 255
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);
}
static_assert(SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES ==
BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES,
"");
static_assert(SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES ==
BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES,
"");
static_assert(SLHDSA_SHA2_128S_SIGNATURE_BYTES ==
BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES,
"");
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);
BCM_slhdsa_sha2_128s_generate_key(out_public_key, out_private_key);
}
OPENSSL_EXPORT void SLHDSA_SHA2_128S_public_from_private(
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);
BCM_slhdsa_sha2_128s_public_from_private(out_public_key, private_key);
}
int SLHDSA_SHA2_128S_sign(
@@ -137,107 +46,31 @@ int SLHDSA_SHA2_128S_sign(
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 > MAX_CONTEXT_LENGTH) {
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;
return bcm_success(BCM_slhdsa_sha2_128s_sign(out_signature, private_key, msg,
msg_len, context, context_len));
}
static int slhdsa_get_nonstandard_context_and_oid(
uint8_t *out_context_and_oid, size_t *out_context_and_oid_len,
size_t max_out_context_and_oid, const uint8_t *context, size_t context_len,
int hash_nid, size_t hashed_msg_len) {
const uint8_t *oid;
size_t oid_len;
size_t expected_hash_len;
switch (hash_nid) {
// The SLH-DSA spec only lists SHA-256 and SHA-512. This function supports
// SHA-384, which is non-standard.
case NID_sha384:
oid = kSHA384OID;
oid_len = sizeof(kSHA384OID);
static_assert(sizeof(kSHA384OID) <= MAX_OID_LENGTH, "");
expected_hash_len = 48;
break;
// If adding a hash function with a larger `oid_len`, update the size of
// `context_and_oid` in the callers.
default:
return 0;
}
if (hashed_msg_len != expected_hash_len) {
return 0;
}
*out_context_and_oid_len = context_len + oid_len;
if (*out_context_and_oid_len > max_out_context_and_oid) {
return 0;
}
OPENSSL_memcpy(out_context_and_oid, context, context_len);
OPENSSL_memcpy(out_context_and_oid + context_len, oid, oid_len);
return 1;
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) {
return bcm_success(BCM_slhdsa_sha2_128s_verify(signature, signature_len,
public_key, msg, msg_len,
context, context_len));
}
int SLHDSA_SHA2_128S_prehash_warning_nonstandard_sign(
uint8_t out_signature[SLHDSA_SHA2_128S_SIGNATURE_BYTES],
const uint8_t private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
const uint8_t *context, size_t context_len) {
if (context_len > MAX_CONTEXT_LENGTH) {
if (hash_nid != NID_sha384) {
return 0;
}
uint8_t M_prime_header[2];
M_prime_header[0] = 1; // domain separator for prehashed signing
M_prime_header[1] = (uint8_t)context_len;
uint8_t context_and_oid[MAX_CONTEXT_LENGTH + MAX_OID_LENGTH];
size_t context_and_oid_len;
if (!slhdsa_get_nonstandard_context_and_oid(
context_and_oid, &context_and_oid_len, sizeof(context_and_oid),
context, context_len, hash_nid, hashed_msg_len)) {
return 0;
}
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_and_oid, context_and_oid_len,
hashed_msg, hashed_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 > MAX_CONTEXT_LENGTH) {
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);
return bcm_success(BCM_slhdsa_sha2_128s_prehash_sign(
out_signature, private_key, hashed_msg, hashed_msg_len, hash_nid, context,
context_len));
}
int SLHDSA_SHA2_128S_prehash_warning_nonstandard_verify(
@@ -245,63 +78,10 @@ int SLHDSA_SHA2_128S_prehash_warning_nonstandard_verify(
const uint8_t public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
const uint8_t *context, size_t context_len) {
if (context_len > MAX_CONTEXT_LENGTH) {
if (hash_nid != NID_sha384) {
return 0;
}
uint8_t M_prime_header[2];
M_prime_header[0] = 1; // domain separator for prehashed verification
M_prime_header[1] = (uint8_t)context_len;
uint8_t context_and_oid[MAX_CONTEXT_LENGTH + MAX_OID_LENGTH];
size_t context_and_oid_len;
if (!slhdsa_get_nonstandard_context_and_oid(
context_and_oid, &context_and_oid_len, sizeof(context_and_oid),
context, context_len, hash_nid, hashed_msg_len)) {
return 0;
}
return SLHDSA_SHA2_128S_verify_internal(
signature, signature_len, public_key, M_prime_header, context_and_oid,
context_and_oid_len, hashed_msg, hashed_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);
return bcm_success(BCM_slhdsa_sha2_128s_prehash_verify(
signature, signature_len, public_key, hashed_msg, hashed_msg_len,
hash_nid, context, context_len));
}
+10 -11
View File
@@ -22,15 +22,14 @@
#include <openssl/obj.h>
#include <openssl/slhdsa.h>
#include "../fipsmodule/slhdsa/params.h"
#include "../test/file_test.h"
#include "../test/test_util.h"
#include "internal.h"
#include "params.h"
namespace {
TEST(SLHDSATest, KeyGeneration) {
const uint8_t seed[3 * SLHDSA_SHA2_128S_N] = {0};
const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N] = {0};
const uint8_t expected_pub[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x6b, 0xd7, 0xe8, 0xe1, 0x98,
@@ -47,7 +46,7 @@ TEST(SLHDSATest, KeyGeneration) {
uint8_t pub[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES];
uint8_t priv[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES];
SLHDSA_SHA2_128S_generate_key_from_seed(pub, priv, seed);
BCM_slhdsa_sha2_128s_generate_key_from_seed(pub, priv, seed);
EXPECT_EQ(Bytes(pub), Bytes(expected_pub));
EXPECT_EQ(Bytes(priv), Bytes(expected_priv));
@@ -132,7 +131,7 @@ static void NISTKeyGenerationFileTest(FileTest *t) {
uint8_t pub[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES];
uint8_t priv[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES];
SLHDSA_SHA2_128S_generate_key_from_seed(pub, priv, seed.data());
BCM_slhdsa_sha2_128s_generate_key_from_seed(pub, priv, seed.data());
EXPECT_EQ(Bytes(pub), Bytes(expected_pub));
EXPECT_EQ(Bytes(priv), Bytes(expected_priv));
@@ -148,13 +147,13 @@ static void NISTSignatureGenerationFileTest(FileTest *t) {
ASSERT_EQ(priv.size(),
static_cast<size_t>(SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES));
ASSERT_TRUE(t->GetBytes(&entropy, "entropy"));
ASSERT_EQ(entropy.size(), static_cast<size_t>(SLHDSA_SHA2_128S_N));
ASSERT_EQ(entropy.size(), static_cast<size_t>(BCM_SLHDSA_SHA2_128S_N));
ASSERT_TRUE(t->GetBytes(&msg, "msg"));
ASSERT_TRUE(t->GetBytes(&expected_sig, "sig"));
uint8_t sig[SLHDSA_SHA2_128S_SIGNATURE_BYTES];
SLHDSA_SHA2_128S_sign_internal(sig, priv.data(), nullptr, nullptr, 0,
msg.data(), msg.size(), entropy.data());
BCM_slhdsa_sha2_128s_sign_internal(sig, priv.data(), nullptr, nullptr, 0,
msg.data(), msg.size(), entropy.data());
EXPECT_EQ(Bytes(sig), Bytes(expected_sig));
}
@@ -173,9 +172,9 @@ static void NISTSignatureVerificationFileTest(FileTest *t) {
ASSERT_TRUE(t->GetBytes(&sig, "sig"));
ASSERT_TRUE(t->GetAttribute(&valid, "valid"));
int ok = SLHDSA_SHA2_128S_verify_internal(sig.data(), sig.size(), pub.data(),
nullptr, nullptr, 0, msg.data(),
msg.size());
int ok = bcm_success(BCM_slhdsa_sha2_128s_verify_internal(
sig.data(), sig.size(), pub.data(), nullptr, nullptr, 0, msg.data(),
msg.size()));
EXPECT_EQ(ok, valid == "true");
}
+11 -11
View File
@@ -93,6 +93,11 @@ bcm_internal_headers = [
"crypto/fipsmodule/sha/sha1.cc.inc",
"crypto/fipsmodule/sha/sha256.cc.inc",
"crypto/fipsmodule/sha/sha512.cc.inc",
"crypto/fipsmodule/slhdsa/fors.cc.inc",
"crypto/fipsmodule/slhdsa/merkle.cc.inc",
"crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
"crypto/fipsmodule/slhdsa/thash.cc.inc",
"crypto/fipsmodule/slhdsa/wots.cc.inc",
"crypto/fipsmodule/tls/kdf.cc.inc",
]
@@ -406,11 +411,7 @@ crypto_sources = [
"crypto/sha/sha256.cc",
"crypto/sha/sha512.cc",
"crypto/siphash/siphash.cc",
"crypto/slhdsa/fors.cc",
"crypto/slhdsa/merkle.cc",
"crypto/slhdsa/slhdsa.cc",
"crypto/slhdsa/thash.cc",
"crypto/slhdsa/wots.cc",
"crypto/stack/stack.cc",
"crypto/thread.cc",
"crypto/thread_none.cc",
@@ -619,6 +620,12 @@ crypto_internal_headers = [
"crypto/fipsmodule/rsa/internal.h",
"crypto/fipsmodule/service_indicator/internal.h",
"crypto/fipsmodule/sha/internal.h",
"crypto/fipsmodule/slhdsa/address.h",
"crypto/fipsmodule/slhdsa/fors.h",
"crypto/fipsmodule/slhdsa/merkle.h",
"crypto/fipsmodule/slhdsa/params.h",
"crypto/fipsmodule/slhdsa/thash.h",
"crypto/fipsmodule/slhdsa/wots.h",
"crypto/fipsmodule/tls/internal.h",
"crypto/hrss/internal.h",
"crypto/internal.h",
@@ -633,13 +640,6 @@ crypto_internal_headers = [
"crypto/rand_extra/getrandom_fillin.h",
"crypto/rand_extra/sysrand_internal.h",
"crypto/rsa_extra/internal.h",
"crypto/slhdsa/address.h",
"crypto/slhdsa/fors.h",
"crypto/slhdsa/internal.h",
"crypto/slhdsa/merkle.h",
"crypto/slhdsa/params.h",
"crypto/slhdsa/thash.h",
"crypto/slhdsa/wots.h",
"crypto/trust_token/internal.h",
"crypto/x509/ext_dat.h",
"crypto/x509/internal.h",
+11 -11
View File
@@ -97,6 +97,11 @@ set(
crypto/fipsmodule/sha/sha1.cc.inc
crypto/fipsmodule/sha/sha256.cc.inc
crypto/fipsmodule/sha/sha512.cc.inc
crypto/fipsmodule/slhdsa/fors.cc.inc
crypto/fipsmodule/slhdsa/merkle.cc.inc
crypto/fipsmodule/slhdsa/slhdsa.cc.inc
crypto/fipsmodule/slhdsa/thash.cc.inc
crypto/fipsmodule/slhdsa/wots.cc.inc
crypto/fipsmodule/tls/kdf.cc.inc
)
@@ -420,11 +425,7 @@ set(
crypto/sha/sha256.cc
crypto/sha/sha512.cc
crypto/siphash/siphash.cc
crypto/slhdsa/fors.cc
crypto/slhdsa/merkle.cc
crypto/slhdsa/slhdsa.cc
crypto/slhdsa/thash.cc
crypto/slhdsa/wots.cc
crypto/stack/stack.cc
crypto/thread.cc
crypto/thread_none.cc
@@ -637,6 +638,12 @@ set(
crypto/fipsmodule/rsa/internal.h
crypto/fipsmodule/service_indicator/internal.h
crypto/fipsmodule/sha/internal.h
crypto/fipsmodule/slhdsa/address.h
crypto/fipsmodule/slhdsa/fors.h
crypto/fipsmodule/slhdsa/merkle.h
crypto/fipsmodule/slhdsa/params.h
crypto/fipsmodule/slhdsa/thash.h
crypto/fipsmodule/slhdsa/wots.h
crypto/fipsmodule/tls/internal.h
crypto/hrss/internal.h
crypto/internal.h
@@ -651,13 +658,6 @@ set(
crypto/rand_extra/getrandom_fillin.h
crypto/rand_extra/sysrand_internal.h
crypto/rsa_extra/internal.h
crypto/slhdsa/address.h
crypto/slhdsa/fors.h
crypto/slhdsa/internal.h
crypto/slhdsa/merkle.h
crypto/slhdsa/params.h
crypto/slhdsa/thash.h
crypto/slhdsa/wots.h
crypto/trust_token/internal.h
crypto/x509/ext_dat.h
crypto/x509/internal.h
+11 -11
View File
@@ -93,6 +93,11 @@ bcm_internal_headers = [
"crypto/fipsmodule/sha/sha1.cc.inc",
"crypto/fipsmodule/sha/sha256.cc.inc",
"crypto/fipsmodule/sha/sha512.cc.inc",
"crypto/fipsmodule/slhdsa/fors.cc.inc",
"crypto/fipsmodule/slhdsa/merkle.cc.inc",
"crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
"crypto/fipsmodule/slhdsa/thash.cc.inc",
"crypto/fipsmodule/slhdsa/wots.cc.inc",
"crypto/fipsmodule/tls/kdf.cc.inc",
]
@@ -406,11 +411,7 @@ crypto_sources = [
"crypto/sha/sha256.cc",
"crypto/sha/sha512.cc",
"crypto/siphash/siphash.cc",
"crypto/slhdsa/fors.cc",
"crypto/slhdsa/merkle.cc",
"crypto/slhdsa/slhdsa.cc",
"crypto/slhdsa/thash.cc",
"crypto/slhdsa/wots.cc",
"crypto/stack/stack.cc",
"crypto/thread.cc",
"crypto/thread_none.cc",
@@ -619,6 +620,12 @@ crypto_internal_headers = [
"crypto/fipsmodule/rsa/internal.h",
"crypto/fipsmodule/service_indicator/internal.h",
"crypto/fipsmodule/sha/internal.h",
"crypto/fipsmodule/slhdsa/address.h",
"crypto/fipsmodule/slhdsa/fors.h",
"crypto/fipsmodule/slhdsa/merkle.h",
"crypto/fipsmodule/slhdsa/params.h",
"crypto/fipsmodule/slhdsa/thash.h",
"crypto/fipsmodule/slhdsa/wots.h",
"crypto/fipsmodule/tls/internal.h",
"crypto/hrss/internal.h",
"crypto/internal.h",
@@ -633,13 +640,6 @@ crypto_internal_headers = [
"crypto/rand_extra/getrandom_fillin.h",
"crypto/rand_extra/sysrand_internal.h",
"crypto/rsa_extra/internal.h",
"crypto/slhdsa/address.h",
"crypto/slhdsa/fors.h",
"crypto/slhdsa/internal.h",
"crypto/slhdsa/merkle.h",
"crypto/slhdsa/params.h",
"crypto/slhdsa/thash.h",
"crypto/slhdsa/wots.h",
"crypto/trust_token/internal.h",
"crypto/x509/ext_dat.h",
"crypto/x509/internal.h",
+11 -11
View File
@@ -78,6 +78,11 @@
"crypto/fipsmodule/sha/sha1.cc.inc",
"crypto/fipsmodule/sha/sha256.cc.inc",
"crypto/fipsmodule/sha/sha512.cc.inc",
"crypto/fipsmodule/slhdsa/fors.cc.inc",
"crypto/fipsmodule/slhdsa/merkle.cc.inc",
"crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
"crypto/fipsmodule/slhdsa/thash.cc.inc",
"crypto/fipsmodule/slhdsa/wots.cc.inc",
"crypto/fipsmodule/tls/kdf.cc.inc"
],
"asm": [
@@ -390,11 +395,7 @@
"crypto/sha/sha256.cc",
"crypto/sha/sha512.cc",
"crypto/siphash/siphash.cc",
"crypto/slhdsa/fors.cc",
"crypto/slhdsa/merkle.cc",
"crypto/slhdsa/slhdsa.cc",
"crypto/slhdsa/thash.cc",
"crypto/slhdsa/wots.cc",
"crypto/stack/stack.cc",
"crypto/thread.cc",
"crypto/thread_none.cc",
@@ -601,6 +602,12 @@
"crypto/fipsmodule/rsa/internal.h",
"crypto/fipsmodule/service_indicator/internal.h",
"crypto/fipsmodule/sha/internal.h",
"crypto/fipsmodule/slhdsa/address.h",
"crypto/fipsmodule/slhdsa/fors.h",
"crypto/fipsmodule/slhdsa/merkle.h",
"crypto/fipsmodule/slhdsa/params.h",
"crypto/fipsmodule/slhdsa/thash.h",
"crypto/fipsmodule/slhdsa/wots.h",
"crypto/fipsmodule/tls/internal.h",
"crypto/hrss/internal.h",
"crypto/internal.h",
@@ -615,13 +622,6 @@
"crypto/rand_extra/getrandom_fillin.h",
"crypto/rand_extra/sysrand_internal.h",
"crypto/rsa_extra/internal.h",
"crypto/slhdsa/address.h",
"crypto/slhdsa/fors.h",
"crypto/slhdsa/internal.h",
"crypto/slhdsa/merkle.h",
"crypto/slhdsa/params.h",
"crypto/slhdsa/thash.h",
"crypto/slhdsa/wots.h",
"crypto/trust_token/internal.h",
"crypto/x509/ext_dat.h",
"crypto/x509/internal.h",