mldsa: convert to C++
No semantic changes, just getting it building as C++.
Change-Id: Ie2bedd0ca25a7b58e4c44b5b5be0645d29dc154a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/71767
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2308d57..4f3b196 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -506,6 +506,12 @@
if(FIPS_DELOCATE)
add_library(bcm_c_generated_asm STATIC ${BCM_SOURCES})
+ if(NOT MSVC)
+ # The C++ code in libcrypto shouldn't depend on libstdc++. This requires
+ # -fno-exceptions otherwise use of std::unique_ptr emits a call to
+ # std::terminate.
+ target_compile_options(bcm_c_generated_asm PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti>)
+ endif()
add_dependencies(bcm_c_generated_asm boringssl_prefix_symbols)
target_include_directories(bcm_c_generated_asm PRIVATE ${PROJECT_SOURCE_DIR}/include)
set_target_properties(bcm_c_generated_asm PROPERTIES COMPILE_OPTIONS "-S")
@@ -556,6 +562,12 @@
endif()
add_library(bcm_library STATIC ${BCM_SOURCES} ${BCM_SOURCES_ASM_USED})
+ if(NOT MSVC)
+ # The C++ code in libcrypto shouldn't depend on libstdc++. This requires
+ # -fno-exceptions otherwise use of std::unique_ptr emits a call to
+ # std::terminate.
+ target_compile_options(bcm_library PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti>)
+ endif()
add_dependencies(bcm_library boringssl_prefix_symbols)
target_include_directories(bcm_library PRIVATE ${PROJECT_SOURCE_DIR}/include)
@@ -568,12 +580,24 @@
set(CRYPTO_FIPS_OBJECTS bcm.o)
else()
add_library(fipsmodule OBJECT ${BCM_SOURCES} ${BCM_SOURCES_ASM_USED})
+ if(NOT MSVC)
+ # The C++ code in libcrypto shouldn't depend on libstdc++. This requires
+ # -fno-exceptions otherwise use of std::unique_ptr emits a call to
+ # std::terminate.
+ target_compile_options(fipsmodule PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti>)
+ endif()
add_dependencies(fipsmodule boringssl_prefix_symbols)
target_include_directories(fipsmodule PRIVATE ${PROJECT_SOURCE_DIR}/include)
set(CRYPTO_FIPS_OBJECTS $<TARGET_OBJECTS:fipsmodule>)
endif()
add_library(crypto ${CRYPTO_SOURCES} ${CRYPTO_FIPS_OBJECTS} ${CRYPTO_SOURCES_ASM_USED})
+if(NOT MSVC)
+ # The C++ code in libcrypto shouldn't depend on libstdc++. This requires
+ # -fno-exceptions otherwise use of std::unique_ptr emits a call to
+ # std::terminate.
+ target_compile_options(crypto PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti>)
+endif()
target_include_directories(crypto PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
diff --git a/build.json b/build.json
index 5f32890..2b39997 100644
--- a/build.json
+++ b/build.json
@@ -266,7 +266,7 @@
"crypto/md4/md4.c",
"crypto/md5/md5.c",
"crypto/mem.c",
- "crypto/mldsa/mldsa.c",
+ "crypto/mldsa/mldsa.cc",
"crypto/mlkem/mlkem.cc",
"crypto/obj/obj.c",
"crypto/obj/obj_xref.c",
diff --git a/crypto/mldsa/mldsa.c b/crypto/mldsa/mldsa.cc
similarity index 97%
rename from crypto/mldsa/mldsa.c
rename to crypto/mldsa/mldsa.cc
index 0a75864..a5ada3d 100644
--- a/crypto/mldsa/mldsa.c
+++ b/crypto/mldsa/mldsa.cc
@@ -1280,14 +1280,17 @@
seed);
}
+template <typename T>
+struct DeleterFree {
+ void operator()(T *ptr) { OPENSSL_free(ptr); }
+};
+
// FIPS 204, Algorithm 6 (`ML-DSA.KeyGen_internal`). Returns 1 on success and 0
// on failure.
int MLDSA65_generate_key_external_entropy(
uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES],
struct MLDSA65_private_key *out_private_key,
const uint8_t entropy[MLDSA_SEED_BYTES]) {
- int ret = 0;
-
// Intermediate values, allocated on the heap to allow use when there is a
// limited amount of stack.
struct values_st {
@@ -1296,9 +1299,10 @@
vectorl s1_ntt;
vectork t;
};
- struct values_st *values = OPENSSL_malloc(sizeof(*values));
+ std::unique_ptr<values_st, DeleterFree<values_st>> values(
+ reinterpret_cast<struct values_st *>(OPENSSL_malloc(sizeof(values_st))));
if (values == NULL) {
- goto err;
+ return 0;
}
struct private_key *priv = private_key_from_external(out_private_key);
@@ -1337,7 +1341,7 @@
CBB cbb;
CBB_init_fixed(&cbb, out_encoded_public_key, MLDSA65_PUBLIC_KEY_BYTES);
if (!mldsa_marshal_public_key(&cbb, &values->pub)) {
- goto err;
+ return 0;
}
assert(CBB_len(&cbb) == MLDSA65_PUBLIC_KEY_BYTES);
@@ -1345,16 +1349,11 @@
out_encoded_public_key, MLDSA65_PUBLIC_KEY_BYTES,
boringssl_shake256);
- ret = 1;
-err:
- OPENSSL_free(values);
- return ret;
+ return 1;
}
int MLDSA65_public_from_private(struct MLDSA65_public_key *out_public_key,
const struct MLDSA65_private_key *private_key) {
- int ret = 0;
-
// Intermediate values, allocated on the heap to allow use when there is a
// limited amount of stack.
struct values_st {
@@ -1363,9 +1362,10 @@
vectork t;
vectork t0;
};
- struct values_st *values = OPENSSL_malloc(sizeof(*values));
+ std::unique_ptr<values_st, DeleterFree<values_st>> values(
+ reinterpret_cast<struct values_st *>(OPENSSL_malloc(sizeof(values_st))));
if (values == NULL) {
- goto err;
+ return 0;
}
const struct private_key *priv = private_key_from_external(private_key);
@@ -1385,11 +1385,7 @@
vectork_add(&values->t, &values->t, &priv->s2);
vectork_power2_round(&pub->t1, &values->t0, &values->t);
-
- ret = 1;
-err:
- OPENSSL_free(values);
- return ret;
+ return 1;
}
// FIPS 204, Algorithm 7 (`ML-DSA.Sign_internal`). Returns 1 on success and 0 on
@@ -1400,7 +1396,6 @@
size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len,
const uint8_t *context, size_t context_len,
const uint8_t randomizer[MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
- int ret = 0;
const struct private_key *priv = private_key_from_external(private_key);
uint8_t mu[MU_BYTES];
@@ -1435,9 +1430,10 @@
vectorl cs1;
vectork cs2;
};
- struct values_st *values = OPENSSL_malloc(sizeof(*values));
+ std::unique_ptr<values_st, DeleterFree<values_st>> values(
+ reinterpret_cast<struct values_st *>(OPENSSL_malloc(sizeof(values_st))));
if (values == NULL) {
- goto err;
+ return 0;
}
OPENSSL_memcpy(&values->s1_ntt, &priv->s1, sizeof(values->s1_ntt));
vectorl_ntt(&values->s1_ntt);
@@ -1526,17 +1522,12 @@
CBB cbb;
CBB_init_fixed(&cbb, out_encoded_signature, MLDSA65_SIGNATURE_BYTES);
if (!mldsa_marshal_signature(&cbb, &values->sign)) {
- goto err;
+ return 0;
}
BSSL_CHECK(CBB_len(&cbb) == MLDSA65_SIGNATURE_BYTES);
- ret = 1;
- break;
+ return 1;
}
-
-err:
- OPENSSL_free(values);
- return ret;
}
// mldsa signature in randomized mode, filling the random bytes with
@@ -1552,7 +1543,7 @@
uint8_t randomizer[MLDSA_SIGNATURE_RANDOMIZER_BYTES];
RAND_bytes(randomizer, sizeof(randomizer));
- const uint8_t context_prefix[2] = {0, context_len};
+ const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context_len)};
return MLDSA65_sign_internal(out_encoded_signature, private_key, msg, msg_len,
context_prefix, sizeof(context_prefix), context,
context_len, randomizer);
@@ -1567,7 +1558,7 @@
return 0;
}
- const uint8_t context_prefix[2] = {0, context_len};
+ const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context_len)};
return MLDSA65_verify_internal(public_key, signature, msg, msg_len,
context_prefix, sizeof(context_prefix),
context, context_len);
@@ -1579,8 +1570,6 @@
const uint8_t encoded_signature[MLDSA65_SIGNATURE_BYTES],
const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix,
size_t context_prefix_len, const uint8_t *context, size_t context_len) {
- int ret = 0;
-
// Intermediate values, allocated on the heap to allow use when there is a
// limited amount of stack.
struct values_st {
@@ -1590,9 +1579,10 @@
vectork az_ntt;
vectork ct1_ntt;
};
- struct values_st *values = OPENSSL_malloc(sizeof(*values));
+ std::unique_ptr<values_st, DeleterFree<values_st>> values(
+ reinterpret_cast<struct values_st *>(OPENSSL_malloc(sizeof(values_st))));
if (values == NULL) {
- goto err;
+ return 0;
}
const struct public_key *pub = public_key_from_external(public_key);
@@ -1600,7 +1590,7 @@
CBS cbs;
CBS_init(&cbs, encoded_signature, MLDSA65_SIGNATURE_BYTES);
if (!mldsa_parse_signature(&values->sign, &cbs)) {
- goto err;
+ return 0;
}
matrix_expand(&values->a_ntt, pub->rho);
@@ -1645,14 +1635,8 @@
BORINGSSL_keccak_squeeze(&keccak_ctx, c_tilde, 2 * LAMBDA_BYTES);
uint32_t z_max = vectorl_max(&values->sign.z);
- if (z_max < kGamma1 - BETA &&
- OPENSSL_memcmp(c_tilde, values->sign.c_tilde, 2 * LAMBDA_BYTES) == 0) {
- ret = 1;
- }
-
-err:
- OPENSSL_free(values);
- return ret;
+ return z_max < kGamma1 - BETA &&
+ OPENSSL_memcmp(c_tilde, values->sign.c_tilde, 2 * LAMBDA_BYTES) == 0;
}
/* Serialization of keys. */
diff --git a/gen/sources.bzl b/gen/sources.bzl
index 79f2831..fbf52c1 100644
--- a/gen/sources.bzl
+++ b/gen/sources.bzl
@@ -361,7 +361,7 @@
"crypto/md4/md4.c",
"crypto/md5/md5.c",
"crypto/mem.c",
- "crypto/mldsa/mldsa.c",
+ "crypto/mldsa/mldsa.cc",
"crypto/mlkem/mlkem.cc",
"crypto/obj/obj.c",
"crypto/obj/obj_xref.c",
diff --git a/gen/sources.cmake b/gen/sources.cmake
index 2a20d22..429f6dc 100644
--- a/gen/sources.cmake
+++ b/gen/sources.cmake
@@ -375,7 +375,7 @@
crypto/md4/md4.c
crypto/md5/md5.c
crypto/mem.c
- crypto/mldsa/mldsa.c
+ crypto/mldsa/mldsa.cc
crypto/mlkem/mlkem.cc
crypto/obj/obj.c
crypto/obj/obj_xref.c
diff --git a/gen/sources.gni b/gen/sources.gni
index b019af8..0c49a46 100644
--- a/gen/sources.gni
+++ b/gen/sources.gni
@@ -361,7 +361,7 @@
"crypto/md4/md4.c",
"crypto/md5/md5.c",
"crypto/mem.c",
- "crypto/mldsa/mldsa.c",
+ "crypto/mldsa/mldsa.cc",
"crypto/mlkem/mlkem.cc",
"crypto/obj/obj.c",
"crypto/obj/obj_xref.c",
diff --git a/gen/sources.json b/gen/sources.json
index 6a236ef..18145d1 100644
--- a/gen/sources.json
+++ b/gen/sources.json
@@ -345,7 +345,7 @@
"crypto/md4/md4.c",
"crypto/md5/md5.c",
"crypto/mem.c",
- "crypto/mldsa/mldsa.c",
+ "crypto/mldsa/mldsa.cc",
"crypto/mlkem/mlkem.cc",
"crypto/obj/obj.c",
"crypto/obj/obj_xref.c",