2150 lines
79 KiB
Diff
2150 lines
79 KiB
Diff
diff --git a/cmd/lib/secutil.c b/cmd/lib/secutil.c
|
|
--- a/cmd/lib/secutil.c
|
|
+++ b/cmd/lib/secutil.c
|
|
@@ -4212,17 +4212,21 @@ static const struct SSLNamedGroupString
|
|
{ NAME_AND_LEN("FF3072"), ssl_grp_ffdhe_3072 },
|
|
{ NAME_AND_LEN("FF4096"), ssl_grp_ffdhe_4096 },
|
|
{ NAME_AND_LEN("FF6144"), ssl_grp_ffdhe_6144 },
|
|
{ NAME_AND_LEN("FF8192"), ssl_grp_ffdhe_8192 },
|
|
#ifndef NSS_DISABLE_KYBER
|
|
{ NAME_AND_LEN("xyber76800"), ssl_grp_kem_xyber768d00 },
|
|
#endif
|
|
+ { NAME_AND_LEN("x25519mlkem768"), ssl_grp_kem_mlkem768x25519 },
|
|
{ NAME_AND_LEN("mlkem768x25519"), ssl_grp_kem_mlkem768x25519 },
|
|
+ { NAME_AND_LEN("secp256r1mlkem768"), ssl_grp_kem_secp256r1mlkem768 },
|
|
{ NAME_AND_LEN("mlkem768secp256r1"), ssl_grp_kem_secp256r1mlkem768 },
|
|
+ { NAME_AND_LEN("secp384r1mlkem1024"), ssl_grp_kem_secp384r1mlkem1024 },
|
|
+ { NAME_AND_LEN("mlkem1024secp384r1"), ssl_grp_kem_secp384r1mlkem1024},
|
|
};
|
|
|
|
static const size_t sslNamedGroupStringLen=PR_ARRAY_SIZE(sslNamedGroupStringArray);
|
|
|
|
static SSLNamedGroup
|
|
groupNameToNamedGroup(char *name)
|
|
{
|
|
int len = PL_strlen(name);
|
|
@@ -4231,21 +4235,16 @@ groupNameToNamedGroup(char *name)
|
|
for (i=0; i < sslNamedGroupStringLen; i++) {
|
|
const struct SSLNamedGroupString *ngs = &sslNamedGroupStringArray[i];
|
|
if (len == ngs->len) {
|
|
if (!strncmp(name, ngs->name, len)) {
|
|
return ngs->grp;
|
|
}
|
|
}
|
|
}
|
|
- if (PL_strlen(name) == 14) {
|
|
- if (!strncmp(name, "mlkem768x25519", 14)) {
|
|
- return ssl_grp_kem_mlkem768x25519;
|
|
- }
|
|
- }
|
|
|
|
return ssl_grp_none;
|
|
}
|
|
|
|
static SECStatus
|
|
countItems(const char *arg, unsigned int *numItems)
|
|
{
|
|
char *str = PORT_Strdup(arg);
|
|
diff --git a/cmd/selfserv/selfserv.c b/cmd/selfserv/selfserv.c
|
|
--- a/cmd/selfserv/selfserv.c
|
|
+++ b/cmd/selfserv/selfserv.c
|
|
@@ -226,17 +226,17 @@ PrintParameterUsage()
|
|
"-Q enables ALPN for HTTP/1.1 [RFC7301]\n"
|
|
"-I comma separated list of enabled groups for TLS key exchange.\n"
|
|
" The following values are valid:\n"
|
|
" P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192,\n"
|
|
" "
|
|
#ifndef NSS_DISABLE_KYBER
|
|
"xyber768d00, "
|
|
#endif
|
|
- "mlkem768x25519, mlkem768secp256r1\n"
|
|
+ "x25519mlkem768, secp256r1mlkem768, secp384r1mlkem1024\n"
|
|
"-J comma separated list of enabled signature schemes in preference order.\n"
|
|
" The following values are valid:\n"
|
|
" rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n"
|
|
" ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n"
|
|
" ecdsa_secp521r1_sha512,\n"
|
|
" rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n"
|
|
" rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n"
|
|
"-Z enable 0-RTT (for TLS 1.3; also use -u)\n"
|
|
diff --git a/cmd/tstclnt/tstclnt.c b/cmd/tstclnt/tstclnt.c
|
|
--- a/cmd/tstclnt/tstclnt.c
|
|
+++ b/cmd/tstclnt/tstclnt.c
|
|
@@ -309,17 +309,17 @@ PrintParameterUsage()
|
|
fprintf(stderr, "%-20s Disconnect and reconnect up to N times total\n", "-L");
|
|
fprintf(stderr, "%-20s Comma separated list of enabled groups for TLS key exchange.\n"
|
|
"%-20s The following values are valid:\n"
|
|
"%-20s P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n"
|
|
"%-20s "
|
|
#ifndef NSS_DISABLE_KYBER
|
|
"xyber768d00, "
|
|
#endif
|
|
- "mlkem768x25519, mlkem768secp256r1\n",
|
|
+ "x25519mlkem768, secp256r1mlkem768, secp384r1mlkem1024\n",
|
|
"-I", "", "", "");
|
|
fprintf(stderr, "%-20s Comma separated list of signature schemes in preference order.\n"
|
|
"%-20s The following values are valid:\n"
|
|
"%-20s rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n"
|
|
"%-20s ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n"
|
|
"%-20s ecdsa_secp521r1_sha512,\n"
|
|
"%-20s rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n"
|
|
"%-20s rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n"
|
|
diff --git a/gtests/pk11_gtest/pk11_keygen.cc b/gtests/pk11_gtest/pk11_keygen.cc
|
|
--- a/gtests/pk11_gtest/pk11_keygen.cc
|
|
+++ b/gtests/pk11_gtest/pk11_keygen.cc
|
|
@@ -162,15 +162,20 @@ std::unique_ptr<ParamHolder> Pkcs11KeyPa
|
|
return std::unique_ptr<ParamHolder>(
|
|
new KyberParamHolder(CKP_NSS_KYBER_768_ROUND3));
|
|
|
|
case CKM_NSS_ML_KEM_KEY_PAIR_GEN:
|
|
std::cerr << "Generate ML-KEM768 pair" << std::endl;
|
|
return std::unique_ptr<ParamHolder>(
|
|
new KyberParamHolder(CKP_NSS_ML_KEM_768));
|
|
|
|
+ case CKM_ML_KEM_KEY_PAIR_GEN:
|
|
+ std::cerr << "Generate ML-KEM1024 pair" << std::endl;
|
|
+ return std::unique_ptr<ParamHolder>(
|
|
+ new KyberParamHolder(CKP_ML_KEM_1024));
|
|
+
|
|
default:
|
|
- ADD_FAILURE() << "unknown OID " << mech_;
|
|
+ ADD_FAILURE() << "unknown Mechanism " << mech_;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
} // namespace nss_test
|
|
diff --git a/gtests/pk11_gtest/pk11_kem_unittest.cc b/gtests/pk11_gtest/pk11_kem_unittest.cc
|
|
--- a/gtests/pk11_gtest/pk11_kem_unittest.cc
|
|
+++ b/gtests/pk11_gtest/pk11_kem_unittest.cc
|
|
@@ -69,41 +69,50 @@ class Pkcs11KEMTest
|
|
}
|
|
|
|
CK_MECHANISM_TYPE keyGenMech() {
|
|
switch (GetParam()) {
|
|
case CKP_NSS_KYBER_768_ROUND3:
|
|
return CKM_NSS_KYBER_KEY_PAIR_GEN;
|
|
case CKP_NSS_ML_KEM_768:
|
|
return CKM_NSS_ML_KEM_KEY_PAIR_GEN;
|
|
+ case CKP_ML_KEM_768:
|
|
+ case CKP_ML_KEM_1024:
|
|
+ return CKM_ML_KEM_KEY_PAIR_GEN;
|
|
default:
|
|
EXPECT_TRUE(false);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
CK_MECHANISM_TYPE encapsMech() {
|
|
switch (GetParam()) {
|
|
case CKP_NSS_KYBER_768_ROUND3:
|
|
return CKM_NSS_KYBER;
|
|
case CKP_NSS_ML_KEM_768:
|
|
return CKM_NSS_ML_KEM;
|
|
+ case CKP_ML_KEM_768:
|
|
+ case CKP_ML_KEM_1024:
|
|
+ return CKM_ML_KEM;
|
|
default:
|
|
EXPECT_TRUE(false);
|
|
return 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
TEST_P(Pkcs11KEMTest, KemConsistencyTest) {
|
|
Pkcs11KeyPairGenerator generator(keyGenMech());
|
|
ScopedSECKEYPrivateKey priv;
|
|
ScopedSECKEYPublicKey pub;
|
|
generator.GenerateKey(&priv, &pub, false);
|
|
|
|
+ ASSERT_NE(nullptr, pub);
|
|
+ ASSERT_NE(nullptr, priv);
|
|
+
|
|
// Copy the public key to simulate receiving the key as an octet string
|
|
ScopedSECKEYPublicKey pubCopy(SECKEY_CopyPublicKey(pub.get()));
|
|
ASSERT_NE(nullptr, pubCopy);
|
|
|
|
ScopedPK11SlotInfo slot(PK11_GetBestSlot(encapsMech(), nullptr));
|
|
ASSERT_NE(nullptr, slot);
|
|
|
|
ASSERT_NE((unsigned int)CK_INVALID_HANDLE,
|
|
@@ -139,11 +148,13 @@ TEST_P(Pkcs11KEMTest, KemConsistencyTest
|
|
EXPECT_EQ(0, SECITEM_CompareItem(item1, item2));
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(Pkcs11KEMTest, Pkcs11KEMTest,
|
|
::testing::Values(
|
|
#ifndef NSS_DISABLE_KYBER
|
|
CKP_NSS_KYBER_768_ROUND3,
|
|
#endif
|
|
+ CKP_ML_KEM_768,
|
|
+ CKP_ML_KEM_1024,
|
|
CKP_NSS_ML_KEM_768));
|
|
|
|
} // namespace nss_test
|
|
diff --git a/gtests/ssl_gtest/tls_agent.cc b/gtests/ssl_gtest/tls_agent.cc
|
|
--- a/gtests/ssl_gtest/tls_agent.cc
|
|
+++ b/gtests/ssl_gtest/tls_agent.cc
|
|
@@ -521,53 +521,57 @@ void TlsAgent::DisableAllCiphers() {
|
|
const std::vector<SSLNamedGroup> kAllDHEGroups = {
|
|
ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
|
|
ssl_grp_ec_secp521r1, ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072,
|
|
ssl_grp_ffdhe_4096, ssl_grp_ffdhe_6144, ssl_grp_ffdhe_8192,
|
|
#ifndef NSS_DISABLE_KYBER
|
|
ssl_grp_kem_xyber768d00,
|
|
#endif
|
|
ssl_grp_kem_mlkem768x25519, ssl_grp_kem_secp256r1mlkem768,
|
|
+ ssl_grp_kem_secp384r1mlkem1024,
|
|
};
|
|
|
|
const std::vector<SSLNamedGroup> kNonPQDHEGroups = {
|
|
ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
|
|
ssl_grp_ec_secp521r1, ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072,
|
|
ssl_grp_ffdhe_4096, ssl_grp_ffdhe_6144, ssl_grp_ffdhe_8192,
|
|
};
|
|
|
|
const std::vector<SSLNamedGroup> kECDHEGroups = {
|
|
ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
|
|
ssl_grp_ec_secp521r1,
|
|
#ifndef NSS_DISABLE_KYBER
|
|
ssl_grp_kem_xyber768d00,
|
|
#endif
|
|
- ssl_grp_kem_mlkem768x25519, ssl_grp_kem_secp256r1mlkem768
|
|
+ ssl_grp_kem_mlkem768x25519, ssl_grp_kem_secp256r1mlkem768,
|
|
+ ssl_grp_kem_secp384r1mlkem1024,
|
|
};
|
|
|
|
const std::vector<SSLNamedGroup> kFFDHEGroups = {
|
|
ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072, ssl_grp_ffdhe_4096,
|
|
ssl_grp_ffdhe_6144, ssl_grp_ffdhe_8192};
|
|
|
|
// Defined because the big DHE groups are ridiculously slow.
|
|
const std::vector<SSLNamedGroup> kFasterDHEGroups = {
|
|
ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
|
|
ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072,
|
|
#ifndef NSS_DISABLE_KYBER
|
|
ssl_grp_kem_xyber768d00,
|
|
#endif
|
|
ssl_grp_kem_mlkem768x25519, ssl_grp_kem_secp256r1mlkem768,
|
|
+ ssl_grp_kem_secp384r1mlkem1024,
|
|
};
|
|
|
|
const std::vector<SSLNamedGroup> kEcdhHybridGroups = {
|
|
#ifndef NSS_DISABLE_KYBER
|
|
ssl_grp_kem_xyber768d00,
|
|
#endif
|
|
ssl_grp_kem_mlkem768x25519,
|
|
ssl_grp_kem_secp256r1mlkem768,
|
|
+ ssl_grp_kem_secp384r1mlkem1024,
|
|
};
|
|
|
|
void TlsAgent::EnableCiphersByKeyExchange(SSLKEAType kea) {
|
|
EXPECT_TRUE(EnsureTlsSetup());
|
|
|
|
for (size_t i = 0; i < SSL_NumImplementedCiphers; ++i) {
|
|
SSLCipherSuiteInfo csinfo;
|
|
|
|
@@ -735,16 +739,19 @@ void TlsAgent::CheckKEA(SSLKEAType kea,
|
|
#endif
|
|
case ssl_grp_kem_mlkem768x25519:
|
|
kea_size = 255;
|
|
break;
|
|
case ssl_grp_ec_secp256r1:
|
|
case ssl_grp_kem_secp256r1mlkem768:
|
|
kea_size = 256;
|
|
break;
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
+ kea_size = 384;
|
|
+ break;
|
|
case ssl_grp_ec_secp384r1:
|
|
kea_size = 384;
|
|
break;
|
|
case ssl_grp_ffdhe_2048:
|
|
kea_size = 2048;
|
|
break;
|
|
case ssl_grp_ffdhe_3072:
|
|
kea_size = 3072;
|
|
diff --git a/gtests/ssl_gtest/tls_mlkem_unittest.cc b/gtests/ssl_gtest/tls_mlkem_unittest.cc
|
|
--- a/gtests/ssl_gtest/tls_mlkem_unittest.cc
|
|
+++ b/gtests/ssl_gtest/tls_mlkem_unittest.cc
|
|
@@ -35,16 +35,25 @@ TEST_P(TlsKeyExchangeTest13, Mlkem768Sec
|
|
EnsureKeyShareSetup();
|
|
ConfigNamedGroups({ssl_grp_kem_secp256r1mlkem768});
|
|
|
|
Connect();
|
|
CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_secp256r1mlkem768,
|
|
ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
|
|
}
|
|
|
|
+TEST_P(TlsKeyExchangeTest13, Mlkem1024Secp384r1Supported) {
|
|
+ EnsureKeyShareSetup();
|
|
+ ConfigNamedGroups({ssl_grp_kem_secp384r1mlkem1024});
|
|
+
|
|
+ Connect();
|
|
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_secp384r1mlkem1024,
|
|
+ ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
|
|
+}
|
|
+
|
|
TEST_P(TlsKeyExchangeTest, Tls12ClientMlkem768StartNotSupported) {
|
|
EnsureKeyShareSetup();
|
|
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
|
SSL_LIBRARY_VERSION_TLS_1_2);
|
|
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
|
SSL_LIBRARY_VERSION_TLS_1_3);
|
|
client_->DisableAllCiphers();
|
|
client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
|
|
@@ -53,16 +62,17 @@ TEST_P(TlsKeyExchangeTest, Tls12ClientMl
|
|
client_->ssl_fd(),
|
|
kECDHEGroups.size() + kEcdhHybridGroups.size()));
|
|
|
|
Connect();
|
|
std::vector<SSLNamedGroup> groups = GetGroupDetails(groups_capture_);
|
|
for (auto group : groups) {
|
|
EXPECT_NE(group, ssl_grp_kem_mlkem768x25519);
|
|
EXPECT_NE(group, ssl_grp_kem_secp256r1mlkem768);
|
|
+ EXPECT_NE(group, ssl_grp_kem_secp384r1mlkem1024);
|
|
}
|
|
}
|
|
|
|
TEST_P(TlsKeyExchangeTest13, Tls12ServerMlkem768x25519NotSupported) {
|
|
EnsureKeyShareSetup();
|
|
|
|
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
|
SSL_LIBRARY_VERSION_TLS_1_3);
|
|
@@ -127,43 +137,63 @@ TEST_P(TlsKeyExchangeTest13, Mlkem768x25
|
|
|
|
Connect();
|
|
CheckKEXDetails({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_secp256r1},
|
|
{ssl_grp_kem_mlkem768x25519}, ssl_grp_ec_secp256r1);
|
|
}
|
|
|
|
TEST_P(TlsKeyExchangeTest13, Mlkem768Secp256r1ClientDisabledByPolicy) {
|
|
EnsureKeyShareSetup();
|
|
- client_->SetPolicy(SEC_OID_SECP256R1MLKEM768, 0, NSS_USE_ALG_IN_SSL_KX);
|
|
+ client_->SetPolicy(SEC_OID_SECP256R1MLKEM768, 0, NSS_USE_ALG_IN_SSL_KX);
|
|
ConfigNamedGroups({ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1});
|
|
|
|
Connect();
|
|
CheckKEXDetails({ssl_grp_ec_secp256r1}, {ssl_grp_ec_secp256r1});
|
|
}
|
|
|
|
TEST_P(TlsKeyExchangeTest13, Mlkem768Secp256r1ServerDisabledByPolicy) {
|
|
EnsureKeyShareSetup();
|
|
- server_->SetPolicy(SEC_OID_SECP256R1MLKEM768, 0, NSS_USE_ALG_IN_SSL_KX);
|
|
+ server_->SetPolicy(SEC_OID_SECP256R1MLKEM768, 0, NSS_USE_ALG_IN_SSL_KX);
|
|
ConfigNamedGroups({ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1});
|
|
|
|
Connect();
|
|
CheckKEXDetails({ssl_grp_kem_secp256r1mlkem768, ssl_grp_ec_secp256r1},
|
|
{ssl_grp_kem_secp256r1mlkem768}, ssl_grp_ec_secp256r1);
|
|
}
|
|
|
|
+TEST_P(TlsKeyExchangeTest13, Secp384r1Mlkem1024ClientDisabledByPolicy) {
|
|
+ EnsureKeyShareSetup();
|
|
+ client_->SetPolicy(SEC_OID_SECP384R1MLKEM1024, 0, NSS_USE_ALG_IN_SSL_KX);
|
|
+ ConfigNamedGroups({ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp256r1});
|
|
+
|
|
+ Connect();
|
|
+ CheckKEXDetails({ssl_grp_ec_secp256r1}, {ssl_grp_ec_secp256r1});
|
|
+}
|
|
+
|
|
+TEST_P(TlsKeyExchangeTest13, Secp384r1Mlkem1024ServerDisabledByPolicy) {
|
|
+ EnsureKeyShareSetup();
|
|
+ server_->SetPolicy(SEC_OID_SECP384R1MLKEM1024, 0, NSS_USE_ALG_IN_SSL_KX);
|
|
+ ConfigNamedGroups({ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp256r1});
|
|
+
|
|
+ Connect();
|
|
+ CheckKEXDetails({ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp256r1},
|
|
+ {ssl_grp_kem_secp384r1mlkem1024}, ssl_grp_ec_secp256r1);
|
|
+}
|
|
+
|
|
static void CheckECDHShareReuse(
|
|
const std::shared_ptr<TlsExtensionCapture>& capture) {
|
|
EXPECT_TRUE(capture->captured());
|
|
const DataBuffer& ext = capture->extension();
|
|
- DataBuffer hybrid_share[4];
|
|
- DataBuffer ecdh_share[4];
|
|
- int hybrid_offset[4];
|
|
- SSLNamedGroup hybrid_ec_type[4];
|
|
- SSLNamedGroup ec_type[4];
|
|
- int ecdh_index[4];
|
|
+ const int max_count=4;
|
|
+ DataBuffer hybrid_share[max_count];
|
|
+ DataBuffer ecdh_share[max_count];
|
|
+ int hybrid_offset[max_count];
|
|
+ SSLNamedGroup hybrid_ec_type[max_count];
|
|
+ SSLNamedGroup ec_type[max_count];
|
|
+ int ecdh_index[max_count];
|
|
int nextHybrid = 0;
|
|
int nextECDH = 0;
|
|
|
|
size_t offset = 0;
|
|
uint32_t ext_len;
|
|
ext.Read(0, 2, &ext_len);
|
|
EXPECT_EQ(ext.len() - 2, ext_len);
|
|
offset += 2;
|
|
@@ -180,30 +210,40 @@ static void CheckECDHShareReuse(
|
|
hybrid_ec_type[nextHybrid] = ssl_grp_ec_curve25519;
|
|
nextHybrid++;
|
|
break;
|
|
case ssl_grp_kem_secp256r1mlkem768:
|
|
hybrid_share[nextHybrid] = DataBuffer(ext.data() + offset + 2 + 2, named_group_len);
|
|
hybrid_offset[nextHybrid] = 0;
|
|
hybrid_ec_type[nextHybrid] = ssl_grp_ec_secp256r1;
|
|
nextHybrid++;
|
|
+ break;
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
+ hybrid_share[nextHybrid] = DataBuffer(ext.data() + offset + 2 + 2, named_group_len);
|
|
+ hybrid_offset[nextHybrid] = 0;
|
|
+ hybrid_ec_type[nextHybrid] = ssl_grp_ec_secp384r1;
|
|
+ nextHybrid++;
|
|
+ break;
|
|
case ssl_grp_ec_curve25519:
|
|
case ssl_grp_ec_secp256r1:
|
|
+ case ssl_grp_ec_secp384r1:
|
|
ecdh_share[nextECDH] = DataBuffer(ext.data() + offset + 2 + 2, named_group_len);
|
|
ec_type[nextECDH] = (SSLNamedGroup) named_group;
|
|
nextECDH++;
|
|
}
|
|
offset += 2 + 2 + named_group_len;
|
|
ext.Read(offset, 2, &named_group);
|
|
ext.Read(offset + 2, 2, &named_group_len);
|
|
}
|
|
EXPECT_EQ(offset, ext.len());
|
|
|
|
ASSERT_TRUE(nextECDH > 0);
|
|
ASSERT_TRUE(nextHybrid > 0);
|
|
+ ASSERT_TRUE(nextECDH <= max_count);
|
|
+ ASSERT_TRUE(nextHybrid <= max_count);
|
|
/* setup the hybrid ecdh indeces */
|
|
for (int i=0; i < nextHybrid; i++) {
|
|
ecdh_index[i] = -1;
|
|
for (int j=0; j < nextECDH; j++) {
|
|
if (hybrid_ec_type[i] == ec_type[j]) {
|
|
ecdh_index[i] = j;
|
|
break;
|
|
}
|
|
@@ -265,16 +305,40 @@ TEST_P(TlsKeyExchangeTest13, Mlkem768Sec
|
|
|
|
Connect();
|
|
|
|
CheckKEXDetails({ssl_grp_ec_secp256r1, ssl_grp_kem_secp256r1mlkem768},
|
|
{ssl_grp_ec_secp256r1, ssl_grp_kem_secp256r1mlkem768});
|
|
CheckECDHShareReuse(shares_capture_);
|
|
}
|
|
|
|
+TEST_P(TlsKeyExchangeTest13, Secp384r1Mlkem1024ShareReuseFirst) {
|
|
+ EnsureKeyShareSetup();
|
|
+ ConfigNamedGroups({ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp384r1});
|
|
+ EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
|
|
+
|
|
+ Connect();
|
|
+
|
|
+ CheckKEXDetails({ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp384r1},
|
|
+ {ssl_grp_kem_secp384r1mlkem1024, ssl_grp_ec_secp384r1});
|
|
+ CheckECDHShareReuse(shares_capture_);
|
|
+}
|
|
+
|
|
+TEST_P(TlsKeyExchangeTest13, Secp384r1Mlkem1024ShareReuseSecond) {
|
|
+ EnsureKeyShareSetup();
|
|
+ ConfigNamedGroups({ssl_grp_ec_secp384r1, ssl_grp_kem_secp384r1mlkem1024});
|
|
+ EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
|
|
+
|
|
+ Connect();
|
|
+
|
|
+ CheckKEXDetails({ssl_grp_ec_secp384r1, ssl_grp_kem_secp384r1mlkem1024},
|
|
+ {ssl_grp_ec_secp384r1, ssl_grp_kem_secp384r1mlkem1024});
|
|
+ CheckECDHShareReuse(shares_capture_);
|
|
+}
|
|
+
|
|
class Mlkem768x25519ShareDamager : public TlsExtensionFilter {
|
|
public:
|
|
typedef enum {
|
|
downgrade,
|
|
extend,
|
|
truncate,
|
|
zero_ecdh,
|
|
modify_ecdh,
|
|
diff --git a/lib/freebl/Makefile b/lib/freebl/Makefile
|
|
--- a/lib/freebl/Makefile
|
|
+++ b/lib/freebl/Makefile
|
|
@@ -594,17 +594,22 @@ ifndef NSS_DISABLE_CHACHAPOLY
|
|
EXTRA_SRCS += Hacl_Poly1305_128.c Hacl_Chacha20_Vec128.c Hacl_Chacha20Poly1305_128.c
|
|
DEFINES += -DHACL_CAN_COMPILE_VEC128
|
|
endif
|
|
endif # x86_64
|
|
|
|
VERIFIED_SRCS += Hacl_Poly1305_32.c Hacl_Chacha20.c Hacl_Chacha20Poly1305_32.c
|
|
endif # NSS_DISABLE_CHACHAPOLY
|
|
|
|
+ifndef NSS_DISABLE_KYBER
|
|
+KYBER_PQCRYSTALS = kyber-pqcrystals-ref.c
|
|
+endif
|
|
+
|
|
VERIFIED_SRCS += Hacl_Hash_SHA3.c Hacl_P256.c Hacl_P384.c Hacl_P521.c libcrux_mlkem768_portable.c libcrux_mlkem_portable.c libcrux_core.c
|
|
+VERIFIED_SRCS += libcrux_mlkem1024_portable.c
|
|
VERIFIED_SRCS += Hacl_Ed25519.c
|
|
VERIFIED_SRCS += Hacl_Curve25519_51.c
|
|
|
|
# Bug 1918767 / Bug 1918711 - by setting KRML_MUSTINLINE=inline here, we
|
|
# avoid it being defined to `inline __forceinline` (for msvc) or `inline
|
|
# __attribute__((always_inline))` (for gcc/clang) in
|
|
# verified/karamel/include/krml/internal/target.h. These other
|
|
# configurations can cause excessive stack usage.
|
|
diff --git a/lib/freebl/freebl_base.gypi b/lib/freebl/freebl_base.gypi
|
|
--- a/lib/freebl/freebl_base.gypi
|
|
+++ b/lib/freebl/freebl_base.gypi
|
|
@@ -27,17 +27,16 @@
|
|
'ecl/ecp_secp521r1.c',
|
|
'fipsfreebl.c',
|
|
'blinit.c',
|
|
'freeblver.c',
|
|
'gcm.c',
|
|
'hmacct.c',
|
|
'jpake.c',
|
|
'kyber.c',
|
|
- 'kyber-pqcrystals-ref.c',
|
|
'ldvector.c',
|
|
'md2.c',
|
|
'md5.c',
|
|
'mpi/mp_gf2m.c',
|
|
'mpi/mpcpucache.c',
|
|
'mpi/mpi.c',
|
|
'mpi/mplogic.c',
|
|
'mpi/mpmontg.c',
|
|
@@ -228,13 +227,25 @@
|
|
'MP_IS_LITTLE_ENDIAN',
|
|
'MPI_AMD64',
|
|
'MP_ASSEMBLY_MULTIPLY',
|
|
'NSS_USE_COMBA',
|
|
],
|
|
}],
|
|
],
|
|
}],
|
|
+ [ 'no_kyber_support==0', {
|
|
+ 'sources': [
|
|
+ 'kyber-pqcrystals-ref.c',
|
|
+ ],
|
|
+ }]
|
|
+ [ 'ml_kem_1024_support==1', {
|
|
+ 'sources': [
|
|
+ 'verified/libcrux_mlkem1024_portable.c',
|
|
+ ],
|
|
+ }]
|
|
+
|
|
+
|
|
],
|
|
'ldflags': [
|
|
'-Wl,-Bsymbolic'
|
|
],
|
|
}
|
|
diff --git a/lib/freebl/kyber.c b/lib/freebl/kyber.c
|
|
--- a/lib/freebl/kyber.c
|
|
+++ b/lib/freebl/kyber.c
|
|
@@ -12,126 +12,168 @@
|
|
#include "secerr.h"
|
|
#include "secitem.h"
|
|
|
|
#include "kyber-pqcrystals-ref.h"
|
|
#include "kyber.h"
|
|
#include "verified/internal/libcrux_core.h"
|
|
#include "verified/libcrux_mlkem768_portable.h"
|
|
#include "verified/libcrux_mlkem768.h"
|
|
+#include "verified/libcrux_mlkem1024_portable.h"
|
|
+#include "verified/libcrux_mlkem1024.h"
|
|
|
|
/* Consistency check between kyber-pqcrystals-ref.h and kyber.h */
|
|
PR_STATIC_ASSERT(KYBER768_PUBLIC_KEY_BYTES == pqcrystals_kyber768_PUBLICKEYBYTES);
|
|
PR_STATIC_ASSERT(KYBER768_PRIVATE_KEY_BYTES == pqcrystals_kyber768_SECRETKEYBYTES);
|
|
PR_STATIC_ASSERT(KYBER768_CIPHERTEXT_BYTES == pqcrystals_kyber768_CIPHERTEXTBYTES);
|
|
PR_STATIC_ASSERT(KYBER_SHARED_SECRET_BYTES == pqcrystals_kyber768_BYTES);
|
|
PR_STATIC_ASSERT(KYBER_KEYPAIR_COIN_BYTES == pqcrystals_kyber768_KEYPAIRCOINBYTES);
|
|
PR_STATIC_ASSERT(KYBER_ENC_COIN_BYTES == pqcrystals_kyber768_ENCCOINBYTES);
|
|
|
|
/* Consistency check between libcrux_mlkem768_portable.h and kyber.h */
|
|
PR_STATIC_ASSERT(KYBER768_PUBLIC_KEY_BYTES == LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768);
|
|
PR_STATIC_ASSERT(KYBER768_PRIVATE_KEY_BYTES == LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768);
|
|
PR_STATIC_ASSERT(KYBER768_CIPHERTEXT_BYTES == LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768);
|
|
PR_STATIC_ASSERT(KYBER_SHARED_SECRET_BYTES == LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE);
|
|
+
|
|
+/* Consistency check between libcrux_mlkem1024_portable.h and kyber.h */
|
|
+PR_STATIC_ASSERT(MLKEM1024_PUBLIC_KEY_BYTES == LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024);
|
|
+PR_STATIC_ASSERT(MLKEM1024_PRIVATE_KEY_BYTES == LIBCRUX_ML_KEM_MLKEM1024_SECRET_KEY_SIZE_1024);
|
|
+PR_STATIC_ASSERT(MLKEM1024_CIPHERTEXT_BYTES == LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024);
|
|
+
|
|
PR_STATIC_ASSERT(KYBER_KEYPAIR_COIN_BYTES == 64);
|
|
PR_STATIC_ASSERT(KYBER_ENC_COIN_BYTES == 32);
|
|
|
|
static bool
|
|
valid_params(KyberParams params)
|
|
{
|
|
switch (params) {
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3:
|
|
case params_kyber768_round3_test_mode:
|
|
+#endif
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static bool
|
|
valid_pubkey(KyberParams params, const SECItem *pubkey)
|
|
{
|
|
switch (params) {
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3:
|
|
case params_kyber768_round3_test_mode:
|
|
+#endif
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
return pubkey && pubkey->len == KYBER768_PUBLIC_KEY_BYTES;
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
+ return pubkey && pubkey->len ==MLKEM1024_PUBLIC_KEY_BYTES;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static bool
|
|
valid_privkey(KyberParams params, const SECItem *privkey)
|
|
{
|
|
switch (params) {
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3:
|
|
case params_kyber768_round3_test_mode:
|
|
+#endif
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
return privkey && privkey->len == KYBER768_PRIVATE_KEY_BYTES;
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
+ return privkey && privkey->len == MLKEM1024_PRIVATE_KEY_BYTES;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static bool
|
|
valid_ciphertext(KyberParams params, const SECItem *ciphertext)
|
|
{
|
|
switch (params) {
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3:
|
|
case params_kyber768_round3_test_mode:
|
|
+#endif
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
return ciphertext && ciphertext->len == KYBER768_CIPHERTEXT_BYTES;
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
+ return ciphertext && ciphertext->len == MLKEM1024_CIPHERTEXT_BYTES;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static bool
|
|
valid_secret(KyberParams params, const SECItem *secret)
|
|
{
|
|
switch (params) {
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3:
|
|
case params_kyber768_round3_test_mode:
|
|
+#endif
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
return secret && secret->len == KYBER_SHARED_SECRET_BYTES;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static bool
|
|
valid_keypair_seed(KyberParams params, const SECItem *seed)
|
|
{
|
|
switch (params) {
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3:
|
|
case params_kyber768_round3_test_mode:
|
|
+#endif
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
return !seed || seed->len == KYBER_KEYPAIR_COIN_BYTES;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static bool
|
|
valid_enc_seed(KyberParams params, const SECItem *seed)
|
|
{
|
|
switch (params) {
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3:
|
|
+#endif
|
|
case params_ml_kem768:
|
|
+ case params_ml_kem1024:
|
|
return !seed;
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3_test_mode:
|
|
+#endif
|
|
case params_ml_kem768_test_mode:
|
|
+ case params_ml_kem1024_test_mode:
|
|
+ return !seed;
|
|
return !seed || seed->len == KYBER_SHARED_SECRET_BYTES;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
SECStatus
|
|
Kyber_NewKey(KyberParams params, const SECItem *keypair_seed, SECItem *privkey, SECItem *pubkey)
|
|
@@ -153,22 +195,28 @@ Kyber_NewKey(KyberParams params, const S
|
|
} else {
|
|
if (RNG_GenerateGlobalRandomBytes(randbuf, sizeof randbuf) != SECSuccess) {
|
|
PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
|
return SECFailure;
|
|
}
|
|
coins = randbuf;
|
|
}
|
|
NSS_CLASSIFY(coins, KYBER_KEYPAIR_COIN_BYTES);
|
|
- if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
|
|
- pqcrystals_kyber768_ref_keypair_derand(pubkey->data, privkey->data, coins);
|
|
- } else if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
|
|
+ if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
|
|
libcrux_ml_kem_mlkem768_MlKem768KeyPair keys = libcrux_ml_kem_mlkem768_portable_generate_key_pair(coins);
|
|
memcpy(pubkey->data, keys.pk.value, KYBER768_PUBLIC_KEY_BYTES);
|
|
memcpy(privkey->data, keys.sk.value, KYBER768_PRIVATE_KEY_BYTES);
|
|
+ } else if (params == params_ml_kem1024 || params == params_ml_kem1024_test_mode) {
|
|
+ libcrux_ml_kem_mlkem1024_MlKem1024KeyPair keys = libcrux_ml_kem_mlkem1024_portable_generate_key_pair(coins);
|
|
+ memcpy(pubkey->data, keys.pk.value, MLKEM1024_PUBLIC_KEY_BYTES);
|
|
+ memcpy(privkey->data, keys.sk.value, MLKEM1024_PRIVATE_KEY_BYTES);
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
+ } else if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
|
|
+ pqcrystals_kyber768_ref_keypair_derand(pubkey->data, privkey->data, coins);
|
|
+#endif
|
|
} else {
|
|
/* unreachable */
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
return SECFailure;
|
|
}
|
|
NSS_DECLASSIFY(pubkey->data, pubkey->len);
|
|
return SECSuccess;
|
|
}
|
|
@@ -193,31 +241,48 @@ Kyber_Encapsulate(KyberParams params, co
|
|
} else {
|
|
if (RNG_GenerateGlobalRandomBytes(randbuf, sizeof randbuf) != SECSuccess) {
|
|
PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
|
return SECFailure;
|
|
}
|
|
coins = randbuf;
|
|
}
|
|
NSS_CLASSIFY(coins, KYBER_ENC_COIN_BYTES);
|
|
- if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
|
|
- pqcrystals_kyber768_ref_enc_derand(ciphertext->data, secret->data, pubkey->data, coins);
|
|
- } else if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
|
|
+ if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
|
|
+ /* shouldn't this just use the typedef im libcrux_mlkem768.h? */
|
|
libcrux_ml_kem_types_MlKemPublicKey_15 pk_value;
|
|
memcpy(pk_value.value, pubkey->data, KYBER768_PUBLIC_KEY_BYTES);
|
|
|
|
bool valid_pk = libcrux_ml_kem_mlkem768_portable_validate_public_key(&pk_value);
|
|
if (!valid_pk) {
|
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
return SECFailure;
|
|
}
|
|
|
|
tuple_3c encap = libcrux_ml_kem_mlkem768_portable_encapsulate(&pk_value, coins);
|
|
memcpy(ciphertext->data, encap.fst.value, KYBER768_CIPHERTEXT_BYTES);
|
|
memcpy(secret->data, encap.snd, KYBER_SHARED_SECRET_BYTES);
|
|
+ } else if (params == params_ml_kem1024 || params == params_ml_kem1024_test_mode) {
|
|
+ /* shouldn't this just use the typedef im libcrux_mlkem1024.h? */
|
|
+ libcrux_ml_kem_types_MlKemPublicKey_1f pk_value;
|
|
+ memcpy(pk_value.value, pubkey->data, MLKEM1024_PUBLIC_KEY_BYTES);
|
|
+
|
|
+ bool valid_pk = libcrux_ml_kem_mlkem1024_portable_validate_public_key(&pk_value);
|
|
+ if (!valid_pk) {
|
|
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
+ return SECFailure;
|
|
+ }
|
|
+
|
|
+ tuple_21 encap = libcrux_ml_kem_mlkem1024_portable_encapsulate(&pk_value, coins);
|
|
+ memcpy(ciphertext->data, encap.fst.value, MLKEM1024_CIPHERTEXT_BYTES);
|
|
+ memcpy(secret->data, encap.snd, KYBER_SHARED_SECRET_BYTES);
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
+ } else if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
|
|
+ pqcrystals_kyber768_ref_enc_derand(ciphertext->data, secret->data, pubkey->data, coins);
|
|
+#endif
|
|
} else {
|
|
/* unreachable */
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
return SECFailure;
|
|
}
|
|
|
|
return SECSuccess;
|
|
}
|
|
@@ -230,32 +295,48 @@ Kyber_Decapsulate(KyberParams params, co
|
|
return SECFailure;
|
|
}
|
|
|
|
if (!(valid_privkey(params, privkey) && valid_ciphertext(params, ciphertext) && valid_secret(params, secret))) {
|
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
return SECFailure;
|
|
}
|
|
|
|
- if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
|
|
- pqcrystals_kyber768_ref_dec(secret->data, ciphertext->data, privkey->data);
|
|
- } else if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
|
|
+ if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
|
|
libcrux_ml_kem_types_MlKemPrivateKey_55 private_key;
|
|
memcpy(private_key.value, privkey->data, KYBER768_PRIVATE_KEY_BYTES);
|
|
|
|
libcrux_ml_kem_mlkem768_MlKem768Ciphertext cipher_text;
|
|
memcpy(cipher_text.value, ciphertext->data, KYBER768_CIPHERTEXT_BYTES);
|
|
|
|
bool valid = libcrux_ml_kem_mlkem768_portable_validate_private_key(&private_key, &cipher_text);
|
|
if (!valid) {
|
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
return SECFailure;
|
|
}
|
|
|
|
libcrux_ml_kem_mlkem768_portable_decapsulate(&private_key, &cipher_text, secret->data);
|
|
+ } else if (params == params_ml_kem1024 || params == params_ml_kem1024_test_mode) {
|
|
+ libcrux_ml_kem_types_MlKemPrivateKey_95 private_key;
|
|
+ memcpy(private_key.value, privkey->data, MLKEM1024_PRIVATE_KEY_BYTES);
|
|
+
|
|
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext cipher_text;
|
|
+ memcpy(cipher_text.value, ciphertext->data, MLKEM1024_CIPHERTEXT_BYTES);
|
|
+
|
|
+ bool valid = libcrux_ml_kem_mlkem1024_portable_validate_private_key(&private_key, &cipher_text);
|
|
+ if (!valid) {
|
|
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
+ return SECFailure;
|
|
+ }
|
|
+
|
|
+ libcrux_ml_kem_mlkem1024_portable_decapsulate(&private_key, &cipher_text, secret->data);
|
|
+#ifndef NSS_DISABLE_KYBER
|
|
+ } else if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
|
|
+ pqcrystals_kyber768_ref_dec(secret->data, ciphertext->data, privkey->data);
|
|
+#endif
|
|
} else {
|
|
// unreachable
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
return SECFailure;
|
|
}
|
|
|
|
return SECSuccess;
|
|
}
|
|
diff --git a/lib/freebl/manifest.mn b/lib/freebl/manifest.mn
|
|
--- a/lib/freebl/manifest.mn
|
|
+++ b/lib/freebl/manifest.mn
|
|
@@ -152,17 +152,17 @@ CSRCS = \
|
|
rsa.c \
|
|
rsa_blind.c \
|
|
rsapkcs.c \
|
|
shvfy.c \
|
|
tlsprfalg.c \
|
|
jpake.c \
|
|
secmpi.c \
|
|
kyber.c \
|
|
- kyber-pqcrystals-ref.c \
|
|
+ $(KYBER_PQCRYSTALS) \
|
|
$(MPI_SRCS) \
|
|
$(MPCPU_SRCS) \
|
|
$(ECL_SRCS) \
|
|
$(VERIFIED_SRCS) \
|
|
$(STUBS_SRCS) \
|
|
$(LOWHASH_SRCS) \
|
|
$(EXTRA_SRCS) \
|
|
$(NULL)
|
|
diff --git a/lib/freebl/verified/libcrux_mlkem1024.h b/lib/freebl/verified/libcrux_mlkem1024.h
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/lib/freebl/verified/libcrux_mlkem1024.h
|
|
@@ -0,0 +1,94 @@
|
|
+/*
|
|
+ * SPDX-FileCopyrightText: 2024 Cryspen Sarl <info@cryspen.com>
|
|
+ *
|
|
+ * SPDX-License-Identifier: MIT or Apache-2.0
|
|
+ *
|
|
+ * This code was generated with the following revisions:
|
|
+ * Charon: b351338f6a84c7a1afc27433eb0ffdc668b3581d
|
|
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
|
|
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
|
|
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
|
|
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
|
|
+ */
|
|
+
|
|
+#ifndef __libcrux_mlkem1024_H
|
|
+#define __libcrux_mlkem1024_H
|
|
+
|
|
+#if defined(__cplusplus)
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+#include "eurydice_glue.h"
|
|
+#include "libcrux_core.h"
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_VECTOR_U_COMPRESSION_FACTOR_1024 ((size_t)11U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_C1_BLOCK_SIZE_1024 \
|
|
+ (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \
|
|
+ LIBCRUX_ML_KEM_MLKEM1024_VECTOR_U_COMPRESSION_FACTOR_1024 / (size_t)8U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 ((size_t)4U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_C1_SIZE_1024 \
|
|
+ (LIBCRUX_ML_KEM_MLKEM1024_C1_BLOCK_SIZE_1024 * \
|
|
+ LIBCRUX_ML_KEM_MLKEM1024_RANK_1024)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_VECTOR_V_COMPRESSION_FACTOR_1024 ((size_t)5U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_C2_SIZE_1024 \
|
|
+ (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \
|
|
+ LIBCRUX_ML_KEM_MLKEM1024_VECTOR_V_COMPRESSION_FACTOR_1024 / (size_t)8U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024 \
|
|
+ (LIBCRUX_ML_KEM_MLKEM1024_C1_SIZE_1024 + \
|
|
+ LIBCRUX_ML_KEM_MLKEM1024_C2_SIZE_1024)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_T_AS_NTT_ENCODED_SIZE_1024 \
|
|
+ (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * \
|
|
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \
|
|
+ LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024 \
|
|
+ (LIBCRUX_ML_KEM_MLKEM1024_T_AS_NTT_ENCODED_SIZE_1024 + (size_t)32U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_SECRET_KEY_SIZE_1024 \
|
|
+ (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * \
|
|
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \
|
|
+ LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_ETA1 ((size_t)2U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_ETA1_RANDOMNESS_SIZE \
|
|
+ (LIBCRUX_ML_KEM_MLKEM1024_ETA1 * (size_t)64U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_ETA2 ((size_t)2U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_ETA2_RANDOMNESS_SIZE \
|
|
+ (LIBCRUX_ML_KEM_MLKEM1024_ETA2 * (size_t)64U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_IMPLICIT_REJECTION_HASH_INPUT_SIZE \
|
|
+ (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \
|
|
+ LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024)
|
|
+
|
|
+typedef libcrux_ml_kem_types_MlKemPrivateKey_95
|
|
+ libcrux_ml_kem_mlkem1024_MlKem1024PrivateKey;
|
|
+
|
|
+typedef libcrux_ml_kem_types_MlKemPublicKey_1f
|
|
+ libcrux_ml_kem_mlkem1024_MlKem1024PublicKey;
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_RANKED_BYTES_PER_RING_ELEMENT_1024 \
|
|
+ (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * \
|
|
+ LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U)
|
|
+
|
|
+#define LIBCRUX_ML_KEM_MLKEM1024_SECRET_KEY_SIZE_1024 \
|
|
+ (LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_SECRET_KEY_SIZE_1024 + \
|
|
+ LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024 + \
|
|
+ LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \
|
|
+ LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)
|
|
+
|
|
+#if defined(__cplusplus)
|
|
+}
|
|
+#endif
|
|
+
|
|
+#define __libcrux_mlkem1024_H_DEFINED
|
|
+#endif
|
|
diff --git a/lib/freebl/verified/libcrux_mlkem1024_portable.c b/lib/freebl/verified/libcrux_mlkem1024_portable.c
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/lib/freebl/verified/libcrux_mlkem1024_portable.c
|
|
@@ -0,0 +1,192 @@
|
|
+/*
|
|
+ * SPDX-FileCopyrightText: 2024 Cryspen Sarl <info@cryspen.com>
|
|
+ *
|
|
+ * SPDX-License-Identifier: MIT or Apache-2.0
|
|
+ *
|
|
+ * This code was generated with the following revisions:
|
|
+ * Charon: b351338f6a84c7a1afc27433eb0ffdc668b3581d
|
|
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
|
|
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
|
|
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
|
|
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
|
|
+ */
|
|
+
|
|
+#include "libcrux_mlkem1024_portable.h"
|
|
+
|
|
+#include "internal/libcrux_mlkem_portable.h"
|
|
+
|
|
+/**
|
|
+ Portable decapsulate
|
|
+*/
|
|
+/**
|
|
+A monomorphic instance of
|
|
+libcrux_ml_kem.ind_cca.instantiations.portable.decapsulate with const generics
|
|
+- K= 4
|
|
+- SECRET_KEY_SIZE= 3168
|
|
+- CPA_SECRET_KEY_SIZE= 1536
|
|
+- PUBLIC_KEY_SIZE= 1568
|
|
+- CIPHERTEXT_SIZE= 1568
|
|
+- T_AS_NTT_ENCODED_SIZE= 1536
|
|
+- C1_SIZE= 1408
|
|
+- C2_SIZE= 160
|
|
+- VECTOR_U_COMPRESSION_FACTOR= 11
|
|
+- VECTOR_V_COMPRESSION_FACTOR= 5
|
|
+- C1_BLOCK_SIZE= 352
|
|
+- ETA1= 2
|
|
+- ETA1_RANDOMNESS_SIZE= 128
|
|
+- ETA2= 2
|
|
+- ETA2_RANDOMNESS_SIZE= 128
|
|
+- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1600
|
|
+*/
|
|
+static void decapsulate_671(
|
|
+ libcrux_ml_kem_types_MlKemPrivateKey_95 *private_key,
|
|
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext,
|
|
+ uint8_t ret[32U]) {
|
|
+ libcrux_ml_kem_ind_cca_decapsulate_1f1(private_key, ciphertext, ret);
|
|
+}
|
|
+
|
|
+/**
|
|
+ Decapsulate ML-KEM 1024
|
|
+
|
|
+ Generates an [`MlKemSharedSecret`].
|
|
+ The input is a reference to an [`MlKem1024PrivateKey`] and an
|
|
+ [`MlKem1024Ciphertext`].
|
|
+*/
|
|
+void libcrux_ml_kem_mlkem1024_portable_decapsulate(
|
|
+ libcrux_ml_kem_types_MlKemPrivateKey_95 *private_key,
|
|
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext,
|
|
+ uint8_t ret[32U]) {
|
|
+ decapsulate_671(private_key, ciphertext, ret);
|
|
+}
|
|
+
|
|
+/**
|
|
+A monomorphic instance of
|
|
+libcrux_ml_kem.ind_cca.instantiations.portable.encapsulate with const generics
|
|
+- K= 4
|
|
+- CIPHERTEXT_SIZE= 1568
|
|
+- PUBLIC_KEY_SIZE= 1568
|
|
+- T_AS_NTT_ENCODED_SIZE= 1536
|
|
+- C1_SIZE= 1408
|
|
+- C2_SIZE= 160
|
|
+- VECTOR_U_COMPRESSION_FACTOR= 11
|
|
+- VECTOR_V_COMPRESSION_FACTOR= 5
|
|
+- VECTOR_U_BLOCK_LEN= 352
|
|
+- ETA1= 2
|
|
+- ETA1_RANDOMNESS_SIZE= 128
|
|
+- ETA2= 2
|
|
+- ETA2_RANDOMNESS_SIZE= 128
|
|
+*/
|
|
+static tuple_21 encapsulate_021(
|
|
+ libcrux_ml_kem_types_MlKemPublicKey_1f *public_key,
|
|
+ uint8_t randomness[32U]) {
|
|
+ libcrux_ml_kem_types_MlKemPublicKey_1f *uu____0 = public_key;
|
|
+ /* Passing arrays by value in Rust generates a copy in C */
|
|
+ uint8_t copy_of_randomness[32U];
|
|
+ memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t));
|
|
+ return libcrux_ml_kem_ind_cca_encapsulate_eb1(uu____0, copy_of_randomness);
|
|
+}
|
|
+
|
|
+/**
|
|
+ Encapsulate ML-KEM 1024
|
|
+
|
|
+ Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple.
|
|
+ The input is a reference to an [`MlKem1024PublicKey`] and
|
|
+ [`SHARED_SECRET_SIZE`] bytes of `randomness`.
|
|
+*/
|
|
+tuple_21 libcrux_ml_kem_mlkem1024_portable_encapsulate(
|
|
+ libcrux_ml_kem_types_MlKemPublicKey_1f *public_key,
|
|
+ uint8_t randomness[32U]) {
|
|
+ libcrux_ml_kem_types_MlKemPublicKey_1f *uu____0 = public_key;
|
|
+ /* Passing arrays by value in Rust generates a copy in C */
|
|
+ uint8_t copy_of_randomness[32U];
|
|
+ memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t));
|
|
+ return encapsulate_021(uu____0, copy_of_randomness);
|
|
+}
|
|
+
|
|
+/**
|
|
+ Portable generate key pair.
|
|
+*/
|
|
+/**
|
|
+A monomorphic instance of
|
|
+libcrux_ml_kem.ind_cca.instantiations.portable.generate_keypair with const
|
|
+generics
|
|
+- K= 4
|
|
+- CPA_PRIVATE_KEY_SIZE= 1536
|
|
+- PRIVATE_KEY_SIZE= 3168
|
|
+- PUBLIC_KEY_SIZE= 1568
|
|
+- BYTES_PER_RING_ELEMENT= 1536
|
|
+- ETA1= 2
|
|
+- ETA1_RANDOMNESS_SIZE= 128
|
|
+*/
|
|
+static libcrux_ml_kem_mlkem1024_MlKem1024KeyPair generate_keypair_871(
|
|
+ uint8_t randomness[64U]) {
|
|
+ /* Passing arrays by value in Rust generates a copy in C */
|
|
+ uint8_t copy_of_randomness[64U];
|
|
+ memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t));
|
|
+ return libcrux_ml_kem_ind_cca_generate_keypair_f61(copy_of_randomness);
|
|
+}
|
|
+
|
|
+/**
|
|
+ Generate ML-KEM 1024 Key Pair
|
|
+*/
|
|
+libcrux_ml_kem_mlkem1024_MlKem1024KeyPair
|
|
+libcrux_ml_kem_mlkem1024_portable_generate_key_pair(uint8_t randomness[64U]) {
|
|
+ /* Passing arrays by value in Rust generates a copy in C */
|
|
+ uint8_t copy_of_randomness[64U];
|
|
+ memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t));
|
|
+ return generate_keypair_871(copy_of_randomness);
|
|
+}
|
|
+
|
|
+/**
|
|
+ Portable private key validation
|
|
+*/
|
|
+/**
|
|
+A monomorphic instance of
|
|
+libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key with const
|
|
+generics
|
|
+- K= 4
|
|
+- SECRET_KEY_SIZE= 3168
|
|
+- CIPHERTEXT_SIZE= 1568
|
|
+*/
|
|
+static KRML_MUSTINLINE bool validate_private_key_e81(
|
|
+ libcrux_ml_kem_types_MlKemPrivateKey_95 *private_key,
|
|
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext) {
|
|
+ return libcrux_ml_kem_ind_cca_validate_private_key_dc(private_key,
|
|
+ ciphertext);
|
|
+}
|
|
+
|
|
+/**
|
|
+ Validate a private key.
|
|
+
|
|
+ Returns `true` if valid, and `false` otherwise.
|
|
+*/
|
|
+bool libcrux_ml_kem_mlkem1024_portable_validate_private_key(
|
|
+ libcrux_ml_kem_types_MlKemPrivateKey_95 *private_key,
|
|
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext) {
|
|
+ return validate_private_key_e81(private_key, ciphertext);
|
|
+}
|
|
+
|
|
+/**
|
|
+ Portable public key validation
|
|
+*/
|
|
+/**
|
|
+A monomorphic instance of
|
|
+libcrux_ml_kem.ind_cca.instantiations.portable.validate_public_key with const
|
|
+generics
|
|
+- K= 4
|
|
+- RANKED_BYTES_PER_RING_ELEMENT= 1536
|
|
+- PUBLIC_KEY_SIZE= 1568
|
|
+*/
|
|
+static KRML_MUSTINLINE bool validate_public_key_7d1(uint8_t *public_key) {
|
|
+ return libcrux_ml_kem_ind_cca_validate_public_key_b71(public_key);
|
|
+}
|
|
+
|
|
+/**
|
|
+ Validate a public key.
|
|
+
|
|
+ Returns `true` if valid, and `false` otherwise.
|
|
+*/
|
|
+bool libcrux_ml_kem_mlkem1024_portable_validate_public_key(
|
|
+ libcrux_ml_kem_types_MlKemPublicKey_1f *public_key) {
|
|
+ return validate_public_key_7d1(public_key->value);
|
|
+}
|
|
diff --git a/lib/freebl/verified/libcrux_mlkem1024_portable.h b/lib/freebl/verified/libcrux_mlkem1024_portable.h
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/lib/freebl/verified/libcrux_mlkem1024_portable.h
|
|
@@ -0,0 +1,74 @@
|
|
+/*
|
|
+ * SPDX-FileCopyrightText: 2024 Cryspen Sarl <info@cryspen.com>
|
|
+ *
|
|
+ * SPDX-License-Identifier: MIT or Apache-2.0
|
|
+ *
|
|
+ * This code was generated with the following revisions:
|
|
+ * Charon: b351338f6a84c7a1afc27433eb0ffdc668b3581d
|
|
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
|
|
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
|
|
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
|
|
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
|
|
+ */
|
|
+
|
|
+#ifndef __libcrux_mlkem1024_portable_H
|
|
+#define __libcrux_mlkem1024_portable_H
|
|
+
|
|
+#if defined(__cplusplus)
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+#include "eurydice_glue.h"
|
|
+#include "libcrux_core.h"
|
|
+
|
|
+/**
|
|
+ Decapsulate ML-KEM 1024
|
|
+
|
|
+ Generates an [`MlKemSharedSecret`].
|
|
+ The input is a reference to an [`MlKem1024PrivateKey`] and an
|
|
+ [`MlKem1024Ciphertext`].
|
|
+*/
|
|
+void libcrux_ml_kem_mlkem1024_portable_decapsulate(
|
|
+ libcrux_ml_kem_types_MlKemPrivateKey_95 *private_key,
|
|
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]);
|
|
+
|
|
+/**
|
|
+ Encapsulate ML-KEM 1024
|
|
+
|
|
+ Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple.
|
|
+ The input is a reference to an [`MlKem1024PublicKey`] and
|
|
+ [`SHARED_SECRET_SIZE`] bytes of `randomness`.
|
|
+*/
|
|
+tuple_21 libcrux_ml_kem_mlkem1024_portable_encapsulate(
|
|
+ libcrux_ml_kem_types_MlKemPublicKey_1f *public_key,
|
|
+ uint8_t randomness[32U]);
|
|
+
|
|
+/**
|
|
+ Generate ML-KEM 1024 Key Pair
|
|
+*/
|
|
+libcrux_ml_kem_mlkem1024_MlKem1024KeyPair
|
|
+libcrux_ml_kem_mlkem1024_portable_generate_key_pair(uint8_t randomness[64U]);
|
|
+
|
|
+/**
|
|
+ Validate a private key.
|
|
+
|
|
+ Returns `true` if valid, and `false` otherwise.
|
|
+*/
|
|
+bool libcrux_ml_kem_mlkem1024_portable_validate_private_key(
|
|
+ libcrux_ml_kem_types_MlKemPrivateKey_95 *private_key,
|
|
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext);
|
|
+
|
|
+/**
|
|
+ Validate a public key.
|
|
+
|
|
+ Returns `true` if valid, and `false` otherwise.
|
|
+*/
|
|
+bool libcrux_ml_kem_mlkem1024_portable_validate_public_key(
|
|
+ libcrux_ml_kem_types_MlKemPublicKey_1f *public_key);
|
|
+
|
|
+#if defined(__cplusplus)
|
|
+}
|
|
+#endif
|
|
+
|
|
+#define __libcrux_mlkem1024_portable_H_DEFINED
|
|
+#endif
|
|
diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
|
|
--- a/lib/pk11wrap/pk11akey.c
|
|
+++ b/lib/pk11wrap/pk11akey.c
|
|
@@ -259,16 +259,21 @@ PK11_ImportPublicKey(PK11SlotInfo *slot,
|
|
kemParams = CKP_NSS_KYBER_768_ROUND3;
|
|
break;
|
|
#endif
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
keyType = CKK_ML_KEM;
|
|
kemParams = CKP_ML_KEM_768;
|
|
break;
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
+ keyType = CKK_ML_KEM;
|
|
+ kemParams = CKP_ML_KEM_1024;
|
|
+ break;
|
|
default:
|
|
kemParams = CKP_INVALID_ID;
|
|
break;
|
|
}
|
|
/*fprintf(stderr, "PK11_ImportPublic KEY_TYPE=0x%08lx, kem_params=0x%08lxd\n",
|
|
keyType, kemParams); */
|
|
|
|
PK11_SETATTRS(attrs, CKA_PARAMETER_SET,
|
|
@@ -908,16 +913,19 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot
|
|
case CKP_NSS_KYBER_768_ROUND3:
|
|
pubKey->u.kyber.params = params_kyber768_round3;
|
|
break;
|
|
#endif
|
|
case CKP_NSS_ML_KEM_768:
|
|
case CKP_ML_KEM_768:
|
|
pubKey->u.kyber.params = params_ml_kem768;
|
|
break;
|
|
+ case CKP_ML_KEM_1024:
|
|
+ pubKey->u.kyber.params = params_ml_kem1024;
|
|
+ break;
|
|
default:
|
|
pubKey->u.kyber.params = params_kyber_invalid;
|
|
break;
|
|
}
|
|
crv = pk11_Attr2SecItem(arena, value, &pubKey->u.kyber.publicValue);
|
|
break;
|
|
case fortezzaKey:
|
|
case nullKey:
|
|
diff --git a/lib/pk11wrap/pk11pars.c b/lib/pk11wrap/pk11pars.c
|
|
--- a/lib/pk11wrap/pk11pars.c
|
|
+++ b/lib/pk11wrap/pk11pars.c
|
|
@@ -244,17 +244,32 @@ static const oidValDef curveOptList[] =
|
|
{ CIPHER_NAME("SECP521R1"), SEC_OID_SECG_EC_SECP521R1,
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
{ CIPHER_NAME("CURVE25519"), SEC_OID_CURVE25519,
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
{ CIPHER_NAME("XYBER768D00"), SEC_OID_XYBER768D00,
|
|
NSS_USE_ALG_IN_SSL_KX },
|
|
{ CIPHER_NAME("MLKEM768X25519"), SEC_OID_MLKEM768X25519,
|
|
NSS_USE_ALG_IN_SSL_KX },
|
|
- { CIPHER_NAME("MLKEM768SECP256R1"), SEC_OID_SECP256R1MLKEM768,
|
|
+ { CIPHER_NAME("SECP256R1MLKEM768"), SEC_OID_SECP256R1MLKEM768,
|
|
+ NSS_USE_ALG_IN_SSL_KX },
|
|
+ { CIPHER_NAME("MLKEM1024SECP384R1"), SEC_OID_SECP384R1MLKEM1024,
|
|
+ NSS_USE_ALG_IN_SSL_KX },
|
|
+ { CIPHER_NAME("X25519MLKEM768"), SEC_OID_MLKEM768X25519,
|
|
+ NSS_USE_ALG_IN_SSL_KX },
|
|
+ { CIPHER_NAME("SECP256R1MLKEM768"), SEC_OID_SECP256R1MLKEM768,
|
|
+ NSS_USE_ALG_IN_SSL_KX },
|
|
+ { CIPHER_NAME("SECP384R1MLKEM1024"), SEC_OID_SECP384R1MLKEM1024,
|
|
+ NSS_USE_ALG_IN_SSL_KX },
|
|
+ /* aliases for old names */
|
|
+ { CIPHER_NAME("MLKEM768X25519"), SEC_OID_MLKEM768X25519,
|
|
+ NSS_USE_ALG_IN_SSL_KX },
|
|
+ { CIPHER_NAME("SECP256R1MLKEM768"), SEC_OID_SECP256R1MLKEM768,
|
|
+ NSS_USE_ALG_IN_SSL_KX },
|
|
+ { CIPHER_NAME("MLKEM1024SECP384R1"), SEC_OID_SECP384R1MLKEM1024,
|
|
NSS_USE_ALG_IN_SSL_KX },
|
|
/* ANSI X9.62 named elliptic curves (characteristic two field) */
|
|
{ CIPHER_NAME("C2PNB163V1"), SEC_OID_ANSIX962_EC_C2PNB163V1,
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
{ CIPHER_NAME("C2PNB163V2"), SEC_OID_ANSIX962_EC_C2PNB163V2,
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
{ CIPHER_NAME("C2PNB163V3"), SEC_OID_ANSIX962_EC_C2PNB163V3,
|
|
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
|
diff --git a/lib/pk11wrap/pk11skey.c b/lib/pk11wrap/pk11skey.c
|
|
--- a/lib/pk11wrap/pk11skey.c
|
|
+++ b/lib/pk11wrap/pk11skey.c
|
|
@@ -3083,16 +3083,19 @@ static CK_ULONG
|
|
pk11_KyberCiphertextLength(SECKEYKyberPublicKey *pubKey)
|
|
{
|
|
switch (pubKey->params) {
|
|
case params_kyber768_round3:
|
|
case params_kyber768_round3_test_mode:
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
return KYBER768_CIPHERTEXT_BYTES;
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
+ return MLKEM1024_CIPHERTEXT_BYTES;
|
|
default:
|
|
// unreachable
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static CK_ULONG
|
|
pk11_KEMCiphertextLength(SECKEYPublicKey *pubKey)
|
|
diff --git a/lib/pk11wrap/secmodti.h b/lib/pk11wrap/secmodti.h
|
|
--- a/lib/pk11wrap/secmodti.h
|
|
+++ b/lib/pk11wrap/secmodti.h
|
|
@@ -201,12 +201,13 @@ struct PK11GenericObjectStr {
|
|
|
|
/* This mask includes all CK_FLAGs with an equivalent CKA_ attribute. */
|
|
#define CKF_KEY_OPERATION_FLAGS 0x000e7b00UL
|
|
|
|
/*
|
|
* private header file, so we can set real names for oids that aren't upstream
|
|
* yet, so we applications don't try to use them and get hosed when they change
|
|
*/
|
|
-#define SEC_OID_SECP256R1MLKEM768 SEC_OID_PRIVATE_1
|
|
-#define SEC_OID_MLKEM1024SECP256R1 SEC_OID_PRIVATE_2
|
|
+#define SEC_OID_X25519MLKEM768 SEC_OID_MLKEM768X25519
|
|
+#define SEC_OID_SECP256R1MLKEM768 SEC_OID_PRIVATE_1
|
|
+#define SEC_OID_SECP384R1MLKEM1024 SEC_OID_PRIVATE_2
|
|
|
|
#endif /* _SECMODTI_H_ */
|
|
diff --git a/lib/softoken/kem.c b/lib/softoken/kem.c
|
|
--- a/lib/softoken/kem.c
|
|
+++ b/lib/softoken/kem.c
|
|
@@ -7,77 +7,90 @@
|
|
#include "pkcs11i.h"
|
|
#include "pkcs11n.h"
|
|
#include "secerr.h"
|
|
#include "secitem.h"
|
|
#include "secport.h"
|
|
#include "softoken.h"
|
|
|
|
/* change to the largest KEM Secret Bytes value supported */
|
|
-#define MAX_SHARED_SECRET_BYTES KYBER_SHARED_SECRET_BYTES
|
|
+/* currenly only mlkem is supported */
|
|
+#define MAX_KEM_SHARED_SECRET_BYTES KYBER_SHARED_SECRET_BYTES
|
|
|
|
KyberParams
|
|
sftk_kyber_PK11ParamToInternal(CK_ML_KEM_PARAMETER_SET_TYPE pk11ParamSet)
|
|
{
|
|
switch (pk11ParamSet) {
|
|
#ifndef NSS_DISABLE_KYBER
|
|
case CKP_NSS_KYBER_768_ROUND3:
|
|
return params_kyber768_round3;
|
|
#endif
|
|
case CKP_NSS_ML_KEM_768:
|
|
case CKP_ML_KEM_768:
|
|
return params_ml_kem768;
|
|
+ case CKP_ML_KEM_1024:
|
|
+ return params_ml_kem1024;
|
|
default:
|
|
return params_kyber_invalid;
|
|
}
|
|
}
|
|
|
|
SECItem *
|
|
sftk_kyber_AllocPubKeyItem(KyberParams params, SECItem *pubkey)
|
|
{
|
|
switch (params) {
|
|
#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3:
|
|
case params_kyber768_round3_test_mode:
|
|
#endif
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
return SECITEM_AllocItem(NULL, pubkey, KYBER768_PUBLIC_KEY_BYTES);
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
+ return SECITEM_AllocItem(NULL, pubkey, MLKEM1024_PUBLIC_KEY_BYTES);
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
SECItem *
|
|
sftk_kyber_AllocPrivKeyItem(KyberParams params, SECItem *privkey)
|
|
{
|
|
switch (params) {
|
|
#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3:
|
|
case params_kyber768_round3_test_mode:
|
|
#endif
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
return SECITEM_AllocItem(NULL, privkey, KYBER768_PRIVATE_KEY_BYTES);
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
+ return SECITEM_AllocItem(NULL, privkey, MLKEM1024_PRIVATE_KEY_BYTES);
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
SECItem *
|
|
sftk_kyber_AllocCiphertextItem(KyberParams params, SECItem *ciphertext)
|
|
{
|
|
switch (params) {
|
|
#ifndef NSS_DISABLE_KYBER
|
|
case params_kyber768_round3:
|
|
case params_kyber768_round3_test_mode:
|
|
#endif
|
|
case params_ml_kem768:
|
|
case params_ml_kem768_test_mode:
|
|
return SECITEM_AllocItem(NULL, ciphertext, KYBER768_CIPHERTEXT_BYTES);
|
|
+ case params_ml_kem1024:
|
|
+ case params_ml_kem1024_test_mode:
|
|
+ return SECITEM_AllocItem(NULL, ciphertext, MLKEM1024_CIPHERTEXT_BYTES);
|
|
+
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
static PRBool
|
|
sftk_kem_ValidateMechanism(CK_MECHANISM_PTR pMechanism)
|
|
{
|
|
@@ -147,16 +160,18 @@ sftk_kem_CiphertextLen(CK_MECHANISM_PTR
|
|
case CKM_ML_KEM:
|
|
switch (paramSet) {
|
|
#ifndef NSS_DISABLE_KYBER
|
|
case CKP_NSS_KYBER_768_ROUND3:
|
|
#endif
|
|
case CKP_NSS_ML_KEM_768:
|
|
case CKP_ML_KEM_768:
|
|
return KYBER768_CIPHERTEXT_BYTES;
|
|
+ case CKP_ML_KEM_1024:
|
|
+ return MLKEM1024_CIPHERTEXT_BYTES;
|
|
default:
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -245,17 +260,17 @@ NSC_EncapsulateKey(CK_SESSION_HANDLE hSe
|
|
goto cleanup;
|
|
}
|
|
|
|
SECItem ciphertext = { siBuffer, pCiphertext, ciphertextLen };
|
|
SECItem pubKey = { siBuffer, encapsulationKey->attrib.pValue, encapsulationKey->attrib.ulValueLen };
|
|
|
|
/* The length of secretBuf can be increased if we ever support other KEMs
|
|
* by changing the define at the top of this file */
|
|
- uint8_t secretBuf[MAX_SHARED_SECRET_BYTES] = { 0 };
|
|
+ uint8_t secretBuf[MAX_KEM_SHARED_SECRET_BYTES] = { 0 };
|
|
SECItem secret = { siBuffer, secretBuf, sizeof secretBuf };
|
|
|
|
key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_ENCAPSULATE,
|
|
key, 0);
|
|
key->source = SFTK_SOURCE_KEA;
|
|
switch (pMechanism->mechanism) {
|
|
#ifndef NSS_DISABLE_KYBER
|
|
case CKM_NSS_KYBER:
|
|
@@ -394,17 +409,17 @@ NSC_DecapsulateKey(CK_SESSION_HANDLE hSe
|
|
}
|
|
|
|
SECItem privKey = { siBuffer, decapsulationKey->attrib.pValue,
|
|
decapsulationKey->attrib.ulValueLen };
|
|
SECItem ciphertext = { siBuffer, pCiphertext, ulCiphertextLen };
|
|
|
|
/* The length of secretBuf can be increased if we ever support other KEMs
|
|
* by changing the define at the top of this file */
|
|
- uint8_t secretBuf[MAX_SHARED_SECRET_BYTES] = { 0 };
|
|
+ uint8_t secretBuf[MAX_KEM_SHARED_SECRET_BYTES] = { 0 };
|
|
SECItem secret = { siBuffer, secretBuf, sizeof secretBuf };
|
|
key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DECAPSULATE,
|
|
key, 0);
|
|
key->source = SFTK_SOURCE_KEA;
|
|
|
|
switch (pMechanism->mechanism) {
|
|
#ifndef NSS_DISABLE_KYBER
|
|
case CKM_NSS_KYBER:
|
|
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
|
|
--- a/lib/softoken/pkcs11c.c
|
|
+++ b/lib/softoken/pkcs11c.c
|
|
@@ -5532,17 +5532,17 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
|
|
CK_KEY_TYPE genType = CKO_SECRET_KEY;
|
|
CK_ATTRIBUTE template = { CKA_KEY_TYPE, NULL, 0 };
|
|
|
|
template.pValue = &genType;
|
|
template.ulValueLen = sizeof(genType);
|
|
crv = CKR_OK;
|
|
switch (keyType) {
|
|
case CKK_ML_KEM:
|
|
- cipher_text_length = KYBER_SHARED_SECRET_BYTES;
|
|
+ cipher_text_length = MAX_ML_KEM_CIPHER_LENGTH;
|
|
mech.mechanism = CKM_ML_KEM;
|
|
break;
|
|
case CKK_RSA:
|
|
if (!isEncryptable) {
|
|
/* already handled the pairwise test, no need to
|
|
* do it again */
|
|
goto kem_done;
|
|
}
|
|
diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
|
|
--- a/lib/ssl/sslimpl.h
|
|
+++ b/lib/ssl/sslimpl.h
|
|
@@ -128,19 +128,19 @@ typedef enum { SSLAppOpRead = 0,
|
|
#define DTLS_RETRANSMIT_MAX_MS 10000
|
|
/* Time to wait in FINISHED state for retransmissions. */
|
|
#define DTLS_RETRANSMIT_FINISHED_MS 30000
|
|
|
|
/* default number of entries in namedGroupPreferences */
|
|
#ifndef NSS_DISABLE_KYBER
|
|
/* this define is checked against the namedGroup table
|
|
* and compile time asserts kick in if it doesn't match */
|
|
-#define SSL_NAMED_GROUP_COUNT 34
|
|
+#define SSL_NAMED_GROUP_COUNT 35
|
|
#else
|
|
-#define SSL_NAMED_GROUP_COUNT 33
|
|
+#define SSL_NAMED_GROUP_COUNT 34
|
|
#endif
|
|
|
|
/* The maximum DH and RSA bit-length supported. */
|
|
#define SSL_MAX_DH_KEY_BITS 8192
|
|
#define SSL_MAX_RSA_KEY_BITS 8192
|
|
|
|
/* Types and names of elliptic curves used in TLS */
|
|
typedef enum {
|
|
diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
|
|
--- a/lib/ssl/sslsock.c
|
|
+++ b/lib/ssl/sslsock.c
|
|
@@ -156,25 +156,26 @@ static const PRUint16 srtpCiphers[] = {
|
|
}
|
|
#define FFGROUP(size) \
|
|
{ \
|
|
ssl_grp_ffdhe_##size, size, ssl_kea_dh, \
|
|
SEC_OID_TLS_FFDHE_##size, PR_TRUE \
|
|
}
|
|
#define HYGROUP(kem, ec, size, kem_oid, ec_oid, assumeSupported) \
|
|
{ \
|
|
- ssl_grp_kem_##kem##ec, size, ssl_kea_ecdh_hybrid, \
|
|
- SEC_OID_##kem_oid##ec_oid, assumeSupported \
|
|
+ ssl_grp_kem_##ec##kem, size, ssl_kea_ecdh_hybrid, \
|
|
+ SEC_OID_##ec_oid##kem_oid, assumeSupported \
|
|
}
|
|
|
|
const sslNamedGroupDef ssl_named_groups[] = {
|
|
/* Note that 256 for 25519 and hybrid is a lie, but we only use it for
|
|
* checking bit security and expect 256 bits there (not 255). */
|
|
HYGROUP(mlkem768, x25519, 256, MLKEM768, X25519, PR_TRUE),
|
|
HYGROUP(mlkem768, secp256r1, 256, MLKEM768, SECP256R1, PR_TRUE),
|
|
+ HYGROUP(mlkem1024, secp384r1, 384, MLKEM1024, SECP384R1, PR_TRUE),
|
|
{ ssl_grp_ec_curve25519, 256, ssl_kea_ecdh, SEC_OID_CURVE25519, PR_TRUE },
|
|
ECGROUP(secp256r1, 256, SECP256R1, PR_TRUE),
|
|
ECGROUP(secp384r1, 384, SECP384R1, PR_TRUE),
|
|
ECGROUP(secp521r1, 521, SECP521R1, PR_TRUE),
|
|
#ifndef NSS_DISABLE_KYBER
|
|
{ ssl_grp_kem_xyber768d00, 256, ssl_kea_ecdh_hybrid, SEC_OID_XYBER768D00, PR_TRUE },
|
|
#endif
|
|
FFGROUP(2048),
|
|
@@ -204,16 +205,17 @@ const sslNamedGroupDef ssl_named_groups[
|
|
ECGROUP(sect409r1, 409, SECT409R1, PR_FALSE),
|
|
ECGROUP(sect571k1, 571, SECT571K1, PR_FALSE),
|
|
ECGROUP(sect571r1, 571, SECT571R1, PR_FALSE),
|
|
};
|
|
PR_STATIC_ASSERT(SSL_NAMED_GROUP_COUNT == PR_ARRAY_SIZE(ssl_named_groups));
|
|
|
|
#undef ECGROUP
|
|
#undef FFGROUP
|
|
+#undef HYGROUP
|
|
|
|
/* forward declarations. */
|
|
static sslSocket *ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant variant);
|
|
static SECStatus ssl_MakeLocks(sslSocket *ss);
|
|
static PRStatus ssl_SetDefaultsFromEnvironmentCallOnce(void);
|
|
static void ssl_SetDefaultsFromEnvironment(void);
|
|
static PRStatus ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,
|
|
PRDescIdentity id);
|
|
diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h
|
|
--- a/lib/ssl/sslt.h
|
|
+++ b/lib/ssl/sslt.h
|
|
@@ -255,25 +255,29 @@ typedef enum {
|
|
ssl_grp_ec_secp384r1 = 24,
|
|
ssl_grp_ec_secp521r1 = 25,
|
|
ssl_grp_ec_curve25519 = 29, /* RFC4492 */
|
|
ssl_grp_ffdhe_2048 = 256, /* RFC7919 */
|
|
ssl_grp_ffdhe_3072 = 257,
|
|
ssl_grp_ffdhe_4096 = 258,
|
|
ssl_grp_ffdhe_6144 = 259,
|
|
ssl_grp_ffdhe_8192 = 260,
|
|
- ssl_grp_kem_mlkem768x25519 = 4588,
|
|
- ssl_grp_kem_secp256r1mlkem768 = 4587,
|
|
+ ssl_grp_kem_x25519mlkem768 = 4588,
|
|
+ ssl_grp_kem_secp256r1mlkem768 = 4587,
|
|
+ ssl_grp_kem_secp384r1mlkem1024 = 4589,
|
|
#ifndef NSS_DISABLE_KYBER
|
|
ssl_grp_kem_xyber768d00 = 25497, /* draft-tls-westerbaan-xyber768d00-02 */
|
|
#endif
|
|
ssl_grp_none = 65537, /* special value */
|
|
ssl_grp_ffdhe_custom = 65538 /* special value */
|
|
} SSLNamedGroup;
|
|
|
|
+/* alias old names */
|
|
+#define ssl_grp_kem_mlkem768x25519 ssl_grp_kem_x25519mlkem768
|
|
+#define ssl_grp_kem_mlkem768secp256r1 ssl_grp_kem_secp256r1mlkem768
|
|
typedef struct SSLExtraServerCertDataStr {
|
|
/* When this struct is passed to SSL_ConfigServerCert, and authType is set
|
|
* to a value other than ssl_auth_null, this limits the use of the key to
|
|
* the type defined; otherwise, the certificate is configured for all
|
|
* compatible types. */
|
|
SSLAuthType authType;
|
|
/* The remainder of the certificate chain. */
|
|
const CERTCertificateList* certChain;
|
|
diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c
|
|
--- a/lib/ssl/tls13con.c
|
|
+++ b/lib/ssl/tls13con.c
|
|
@@ -385,19 +385,23 @@ tls13_CreateKEMKeyPair(sslSocket *ss, co
|
|
#ifndef NSS_DISABLE_KYBER
|
|
case ssl_grp_kem_xyber768d00:
|
|
mechanism = CKM_NSS_KYBER_KEY_PAIR_GEN;
|
|
paramSet = CKP_NSS_KYBER_768_ROUND3;
|
|
break;
|
|
#endif
|
|
case ssl_grp_kem_mlkem768x25519:
|
|
case ssl_grp_kem_secp256r1mlkem768:
|
|
- mechanism = CKM_NSS_ML_KEM_KEY_PAIR_GEN;
|
|
+ mechanism = CKM_ML_KEM_KEY_PAIR_GEN;
|
|
paramSet = CKP_ML_KEM_768;
|
|
break;
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
+ mechanism = CKM_ML_KEM_KEY_PAIR_GEN;
|
|
+ paramSet = CKP_ML_KEM_1024;
|
|
+ break;
|
|
default:
|
|
PORT_Assert(0);
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
return SECFailure;
|
|
}
|
|
|
|
PK11SlotInfo *slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg);
|
|
if (!slot) {
|
|
@@ -494,16 +498,20 @@ tls13_FindHybridKeyPair(sslSocket *ss, c
|
|
{
|
|
sslEphemeralKeyPair *hybridPair = NULL;
|
|
switch (groupDef->name) {
|
|
case ssl_grp_ec_secp256r1:
|
|
/* future, this may be a loop to check multiple named groups */
|
|
hybridPair = ssl_LookupEphemeralKeyPair(ss,
|
|
ssl_LookupNamedGroup(ssl_grp_kem_secp256r1mlkem768));
|
|
break;
|
|
+ case ssl_grp_ec_secp384r1:
|
|
+ hybridPair = ssl_LookupEphemeralKeyPair(ss,
|
|
+ ssl_LookupNamedGroup(ssl_grp_kem_secp384r1mlkem1024));
|
|
+ break;
|
|
case ssl_grp_ec_curve25519:
|
|
#ifndef NSS_DISABLE_KYBER
|
|
/* a loop to check multiple named groups */
|
|
SSLNamedGroup gnames[] = { ssl_grp_kem_xyber768d00,
|
|
ssl_grp_kem_mlkem768x25519 };
|
|
for (int i=0; i < PR_ARRAY_SIZE(gnames); i++) {
|
|
hybridPair = ssl_LookupEphemeralKeyPair(ss,
|
|
ssl_LookupNamedGroup(gnames[i]));
|
|
@@ -563,16 +571,19 @@ tls13_CreateKeyShare(sslSocket *ss, cons
|
|
|
|
PORT_Assert(groupDef);
|
|
switch (groupDef->keaType) {
|
|
case ssl_kea_ecdh_hybrid:
|
|
switch (groupDef->name) {
|
|
case ssl_grp_kem_secp256r1mlkem768:
|
|
dhGroup = ssl_LookupNamedGroup(ssl_grp_ec_secp256r1);
|
|
break;
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
+ dhGroup = ssl_LookupNamedGroup(ssl_grp_ec_secp384r1);
|
|
+ break;
|
|
#ifndef NSS_DISABLE_KYBER
|
|
case ssl_grp_kem_xyber768d00:
|
|
#endif
|
|
case ssl_grp_kem_mlkem768x25519:
|
|
dhGroup = ssl_LookupNamedGroup(ssl_grp_ec_curve25519);
|
|
break;
|
|
default:
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
@@ -832,16 +843,19 @@ tls13_ImportKEMKeyShare(SECKEYPublicKey
|
|
break;
|
|
#endif
|
|
case ssl_grp_kem_mlkem768x25519:
|
|
expected_len = X25519_PUBLIC_KEY_BYTES + KYBER768_PUBLIC_KEY_BYTES;
|
|
break;
|
|
case ssl_grp_kem_secp256r1mlkem768:
|
|
expected_len = SECP256_PUBLIC_KEY_BYTES + KYBER768_PUBLIC_KEY_BYTES;
|
|
break;
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
+ expected_len = SECP384_PUBLIC_KEY_BYTES + MLKEM1024_PUBLIC_KEY_BYTES;
|
|
+ break;
|
|
default:
|
|
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
|
|
return SECFailure;
|
|
}
|
|
|
|
if (entry->key_exchange.len != expected_len) {
|
|
PORT_SetError(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE);
|
|
return SECFailure;
|
|
@@ -866,16 +880,23 @@ tls13_ImportKEMKeyShare(SECKEYPublicKey
|
|
break;
|
|
case ssl_grp_kem_secp256r1mlkem768:
|
|
peerKey->keyType = kyberKey;
|
|
peerKey->u.kyber.params = params_ml_kem768;
|
|
/* key_exchange.data is `secp256 || mlkem768` */
|
|
pk.data = entry->key_exchange.data + SECP256_PUBLIC_KEY_BYTES;
|
|
pk.len = KYBER768_PUBLIC_KEY_BYTES;
|
|
break;
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
+ peerKey->keyType = kyberKey;
|
|
+ peerKey->u.kyber.params = params_ml_kem1024;
|
|
+ /* key_exchange.data is `secp384 || mlkem1024` */
|
|
+ pk.data = entry->key_exchange.data + SECP384_PUBLIC_KEY_BYTES;
|
|
+ pk.len = MLKEM1024_PUBLIC_KEY_BYTES;
|
|
+ break;
|
|
default:
|
|
PORT_Assert(0);
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
return SECFailure;
|
|
}
|
|
|
|
rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.kyber.publicValue, &pk);
|
|
if (rv != SECSuccess) {
|
|
@@ -914,16 +935,24 @@ tls13_HandleKEMCiphertext(sslSocket *ss,
|
|
case ssl_grp_kem_secp256r1mlkem768:
|
|
if (entry->key_exchange.len != SECP256_PUBLIC_KEY_BYTES + KYBER768_CIPHERTEXT_BYTES) {
|
|
ssl_MapLowLevelError(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE);
|
|
return SECFailure;
|
|
}
|
|
ct.data = entry->key_exchange.data + SECP256_PUBLIC_KEY_BYTES;
|
|
ct.len = KYBER768_CIPHERTEXT_BYTES;
|
|
break;
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
+ if (entry->key_exchange.len != SECP384_PUBLIC_KEY_BYTES + MLKEM1024_CIPHERTEXT_BYTES) {
|
|
+ ssl_MapLowLevelError(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE);
|
|
+ return SECFailure;
|
|
+ }
|
|
+ ct.data = entry->key_exchange.data + SECP384_PUBLIC_KEY_BYTES;
|
|
+ ct.len = MLKEM1024_CIPHERTEXT_BYTES;
|
|
+ break;
|
|
default:
|
|
PORT_Assert(0);
|
|
ssl_MapLowLevelError(SEC_ERROR_LIBRARY_FAILURE);
|
|
return SECFailure;
|
|
}
|
|
|
|
rv = PK11_Decapsulate(keyPair->privKey, &ct, CKM_HKDF_DERIVE, PK11_ATTR_SESSION,
|
|
CKF_DERIVE, outKey);
|
|
@@ -1039,16 +1068,24 @@ tls13_HandleKeyShare(sslSocket *ss,
|
|
case ssl_grp_kem_secp256r1mlkem768:
|
|
dhLen = SECP256_PUBLIC_KEY_BYTES;
|
|
/* secp256 share is at the beginning */
|
|
ec_data = entry->key_exchange.len < dhLen
|
|
? NULL
|
|
: entry->key_exchange.data;
|
|
dhGroup = ssl_LookupNamedGroup(ssl_grp_ec_secp256r1);
|
|
break;
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
+ dhLen = SECP384_PUBLIC_KEY_BYTES;
|
|
+ /* secp256 share is at the beginning */
|
|
+ ec_data = entry->key_exchange.len < dhLen
|
|
+ ? NULL
|
|
+ : entry->key_exchange.data;
|
|
+ dhGroup = ssl_LookupNamedGroup(ssl_grp_ec_secp384r1);
|
|
+ break;
|
|
default:
|
|
ec_data = NULL;
|
|
break;
|
|
}
|
|
if (!ec_data) {
|
|
PORT_SetError(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE);
|
|
goto loser;
|
|
}
|
|
@@ -2927,16 +2964,17 @@ tls13_HandleClientKeyShare(sslSocket *ss
|
|
case ssl_grp_kem_xyber768d00:
|
|
ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(dheSecret, kemSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
|
|
break;
|
|
#endif
|
|
case ssl_grp_kem_mlkem768x25519:
|
|
ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(kemSecret, dheSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
|
|
break;
|
|
case ssl_grp_kem_secp256r1mlkem768:
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(dheSecret, kemSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
|
|
break;
|
|
default:
|
|
PORT_Assert(0);
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
ss->ssl3.hs.dheSecret = NULL;
|
|
break;
|
|
}
|
|
@@ -3791,16 +3829,17 @@ tls13_HandleServerKeyShare(sslSocket *ss
|
|
case ssl_grp_kem_xyber768d00:
|
|
ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(dheSecret, kemSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
|
|
break;
|
|
#endif
|
|
case ssl_grp_kem_mlkem768x25519:
|
|
ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(kemSecret, dheSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
|
|
break;
|
|
case ssl_grp_kem_secp256r1mlkem768:
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(dheSecret, kemSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
|
|
break;
|
|
default:
|
|
PORT_Assert(0);
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
ss->ssl3.hs.dheSecret = NULL;
|
|
break;
|
|
}
|
|
diff --git a/lib/ssl/tls13exthandle.c b/lib/ssl/tls13exthandle.c
|
|
--- a/lib/ssl/tls13exthandle.c
|
|
+++ b/lib/ssl/tls13exthandle.c
|
|
@@ -80,70 +80,47 @@ tls13_SizeOfKeyShareEntry(const sslEphem
|
|
|
|
if (keyPair->kemKeys) {
|
|
PORT_Assert(!keyPair->kemCt);
|
|
PORT_Assert(
|
|
#ifndef NSS_DISABLE_KYBER
|
|
keyPair->group->name == ssl_grp_kem_xyber768d00 ||
|
|
#endif
|
|
keyPair->group->name == ssl_grp_kem_mlkem768x25519 ||
|
|
- keyPair->group->name == ssl_grp_kem_secp256r1mlkem768);
|
|
+ keyPair->group->name == ssl_grp_kem_secp256r1mlkem768 ||
|
|
+ keyPair->group->name == ssl_grp_kem_secp384r1mlkem1024);
|
|
pubKey = keyPair->kemKeys->pubKey;
|
|
size += pubKey->u.kyber.publicValue.len;
|
|
}
|
|
if (keyPair->kemCt) {
|
|
PORT_Assert(!keyPair->kemKeys);
|
|
PORT_Assert(
|
|
#ifndef NSS_DISABLE_KYBER
|
|
keyPair->group->name == ssl_grp_kem_xyber768d00 ||
|
|
#endif
|
|
keyPair->group->name == ssl_grp_kem_mlkem768x25519 ||
|
|
- keyPair->group->name == ssl_grp_kem_secp256r1mlkem768);
|
|
+ keyPair->group->name == ssl_grp_kem_secp256r1mlkem768 ||
|
|
+ keyPair->group->name == ssl_grp_kem_secp384r1mlkem1024);
|
|
size += keyPair->kemCt->len;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
+static SECStatus
|
|
+tls13_WriteECCFirstMLKEMKeyExchangeInfo(sslBuffer *buf, sslEphemeralKeyPair *keyPair)
|
|
+ {
|
|
+ PORT_Assert(keyPair->group->name == ssl_grp_kem_secp256r1mlkem768 ||
|
|
#ifndef NSS_DISABLE_KYBER
|
|
-static SECStatus
|
|
-tls13_WriteXyber768D00KeyExchangeInfo(sslBuffer *buf, sslEphemeralKeyPair *keyPair)
|
|
-{
|
|
- PORT_Assert(keyPair->group->name == ssl_grp_kem_xyber768d00);
|
|
+ keyPair->group->name == ssl_grp_kem_xyber768d00 ||
|
|
+#endif
|
|
+ keyPair->group->name == ssl_grp_kem_secp384r1mlkem1024);
|
|
PORT_Assert(keyPair->keys->pubKey->keyType == ecKey);
|
|
|
|
- // Encode the X25519 share first, then the Kyber768 key or ciphertext.
|
|
- SECStatus rv;
|
|
- rv = sslBuffer_Append(buf, keyPair->keys->pubKey->u.ec.publicValue.data,
|
|
- keyPair->keys->pubKey->u.ec.publicValue.len);
|
|
- if (rv != SECSuccess) {
|
|
- return rv;
|
|
- }
|
|
-
|
|
- if (keyPair->kemKeys) {
|
|
- PORT_Assert(!keyPair->kemCt);
|
|
- rv = sslBuffer_Append(buf, keyPair->kemKeys->pubKey->u.kyber.publicValue.data, keyPair->kemKeys->pubKey->u.kyber.publicValue.len);
|
|
- } else if (keyPair->kemCt) {
|
|
- rv = sslBuffer_Append(buf, keyPair->kemCt->data, keyPair->kemCt->len);
|
|
- } else {
|
|
- PORT_Assert(0);
|
|
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
- rv = SECFailure;
|
|
- }
|
|
- return rv;
|
|
-}
|
|
-#endif
|
|
-
|
|
-static SECStatus
|
|
-tls13_WriteMLKEM768Secp256r1KeyExchangeInfo(sslBuffer *buf, sslEphemeralKeyPair *keyPair)
|
|
- {
|
|
- PORT_Assert(keyPair->group->name == ssl_grp_kem_secp256r1mlkem768);
|
|
- PORT_Assert(keyPair->keys->pubKey->keyType == ecKey);
|
|
-
|
|
- // Encode the p256 key first, then the Kyber768 key or ciphertext.
|
|
+ // Encode the ECC key first, then the ML-KEM key or ciphertext.
|
|
SECStatus rv;
|
|
rv = sslBuffer_Append(buf, keyPair->keys->pubKey->u.ec.publicValue.data,
|
|
keyPair->keys->pubKey->u.ec.publicValue.len);
|
|
if (rv != SECSuccess) {
|
|
return rv;
|
|
}
|
|
|
|
if (keyPair->kemKeys) {
|
|
@@ -155,22 +132,22 @@ tls13_WriteMLKEM768Secp256r1KeyExchangeI
|
|
PORT_Assert(0);
|
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
|
rv = SECFailure;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
static SECStatus
|
|
-tls13_WriteMLKEM768X25519KeyExchangeInfo(sslBuffer *buf, sslEphemeralKeyPair *keyPair)
|
|
+tls13_WriteMLKEMFirstKeyExchangeInfo(sslBuffer *buf, sslEphemeralKeyPair *keyPair)
|
|
{
|
|
PORT_Assert(keyPair->group->name == ssl_grp_kem_mlkem768x25519);
|
|
PORT_Assert(keyPair->keys->pubKey->keyType == ecKey);
|
|
|
|
- // Encode the ML-KEM-768 key or ciphertext first, then the X25519 share.
|
|
+ // Encode the ML-KEM key or ciphertext first, then the ecc share.
|
|
SECStatus rv;
|
|
if (keyPair->kemKeys) {
|
|
PORT_Assert(!keyPair->kemCt);
|
|
rv = sslBuffer_Append(buf, keyPair->kemKeys->pubKey->u.kyber.publicValue.data, keyPair->kemKeys->pubKey->u.kyber.publicValue.len);
|
|
} else if (keyPair->kemCt) {
|
|
rv = sslBuffer_Append(buf, keyPair->kemCt->data, keyPair->kemCt->len);
|
|
} else {
|
|
PORT_Assert(0);
|
|
@@ -223,26 +200,24 @@ tls13_EncodeKeyShareEntry(sslBuffer *buf
|
|
rv = sslBuffer_AppendNumber(buf, size - 4, 2);
|
|
if (rv != SECSuccess) {
|
|
return rv;
|
|
}
|
|
|
|
switch (keyPair->group->name) {
|
|
#ifndef NSS_DISABLE_KYBER
|
|
case ssl_grp_kem_xyber768d00:
|
|
- rv = tls13_WriteXyber768D00KeyExchangeInfo(buf, keyPair);
|
|
+#endif
|
|
+ case ssl_grp_kem_secp256r1mlkem768:
|
|
+ case ssl_grp_kem_secp384r1mlkem1024:
|
|
+ rv = tls13_WriteECCFirstMLKEMKeyExchangeInfo(buf, keyPair);
|
|
break;
|
|
-#endif
|
|
case ssl_grp_kem_mlkem768x25519:
|
|
- rv = tls13_WriteMLKEM768X25519KeyExchangeInfo(buf, keyPair);
|
|
+ rv = tls13_WriteMLKEMFirstKeyExchangeInfo(buf, keyPair);
|
|
break;
|
|
- case ssl_grp_kem_secp256r1mlkem768:
|
|
- rv = tls13_WriteMLKEM768Secp256r1KeyExchangeInfo(buf, keyPair);
|
|
- break;
|
|
-
|
|
default:
|
|
rv = tls13_WriteKeyExchangeInfo(buf, keyPair);
|
|
break;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
SECStatus
|
|
diff --git a/lib/util/eccutil.h b/lib/util/eccutil.h
|
|
--- a/lib/util/eccutil.h
|
|
+++ b/lib/util/eccutil.h
|
|
@@ -2,16 +2,17 @@
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef _FREEBL_H_
|
|
#define _FREEBL_H_
|
|
|
|
#define X25519_PUBLIC_KEY_BYTES 32U
|
|
#define SECP256_PUBLIC_KEY_BYTES 65U
|
|
+#define SECP384_PUBLIC_KEY_BYTES 97U
|
|
|
|
/* deprecated */
|
|
typedef enum {
|
|
ECPoint_Uncompressed,
|
|
ECPoint_XOnly,
|
|
ECPoint_Undefined
|
|
} ECPointEncoding;
|
|
|
|
diff --git a/lib/util/kyber.h b/lib/util/kyber.h
|
|
--- a/lib/util/kyber.h
|
|
+++ b/lib/util/kyber.h
|
|
@@ -4,20 +4,28 @@
|
|
|
|
#ifndef KYBER_UTIL_H
|
|
#define KYBER_UTIL_H
|
|
|
|
#define KYBER768_PUBLIC_KEY_BYTES 1184U
|
|
#define KYBER768_PRIVATE_KEY_BYTES 2400U
|
|
#define KYBER768_CIPHERTEXT_BYTES 1088U
|
|
|
|
+#define MLKEM1024_PUBLIC_KEY_BYTES 1568U
|
|
+#define MLKEM1024_PRIVATE_KEY_BYTES 3168U
|
|
+#define MLKEM1024_CIPHERTEXT_BYTES 1568U
|
|
+
|
|
#define KYBER_SHARED_SECRET_BYTES 32U
|
|
#define KYBER_KEYPAIR_COIN_BYTES 64U
|
|
#define KYBER_ENC_COIN_BYTES 32U
|
|
|
|
+#define MAX_ML_KEM_CIPHER_LENGTH MLKEM1024_CIPHERTEXT_BYTES
|
|
+#define MAX_ML_KEM_PRIVATE_KEY_LENGTH MLKEM1024_PRIVATE_KEY_BYTES
|
|
+#define MAX_ML_KEM_PUBLIC_KEY_LENGTH MLKEM1024_PUBLIC_KEY_BYTES
|
|
+
|
|
typedef enum {
|
|
params_kyber_invalid,
|
|
|
|
/*
|
|
* The Kyber768 parameters specified in version 3.02 of the NIST submission
|
|
* https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf
|
|
*/
|
|
params_kyber768_round3,
|
|
@@ -34,11 +42,24 @@ typedef enum {
|
|
*/
|
|
params_ml_kem768,
|
|
|
|
/*
|
|
* Identical to params_ml_kem768 except that this parameter set allows
|
|
* the use of a seed in `Kyber_Encapsulate` for testing.
|
|
*/
|
|
params_ml_kem768_test_mode,
|
|
+
|
|
+ /*
|
|
+ * The ML-KEM parameters specified in FIPS 203.
|
|
+ * https://csrc.nist.gov/pubs/fips/203/final
|
|
+ */
|
|
+ params_ml_kem1024,
|
|
+
|
|
+ /*
|
|
+ * Identical to params_ml_kem1024 except that this parameter set allows
|
|
+ * the use of a seed in `Kyber_Encapsulate` for testing.
|
|
+ */
|
|
+ params_ml_kem1024_test_mode,
|
|
+
|
|
} KyberParams;
|
|
|
|
#endif /* KYBER_UTIL_H */
|
|
diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh
|
|
--- a/tests/ssl/ssl.sh
|
|
+++ b/tests/ssl/ssl.sh
|
|
@@ -119,19 +119,19 @@ ssl_init()
|
|
|
|
# List of cipher suites to test, including ECC cipher suites.
|
|
CIPHER_SUITES="-c ${EC_SUITES}${NON_EC_SUITES}"
|
|
TLS13_CIPHER_SUITES="-c ${TLS13_SUITES}${EC_SUITES}${NON_EC_SUITES}"
|
|
|
|
# FIPS specific options for both clients and servers
|
|
FIPS_OPTIONS=""
|
|
# in fips mode, turn off curve25519 until it's NIST approved
|
|
- ALL_GROUPS="P256,P384,P521,x25519,FF2048,FF3072,FF4096,FF6144,FF8192,mlkem768secp256r1,mlkem768x25519"
|
|
+ ALL_GROUPS="P256,P384,P521,x25519,FF2048,FF3072,FF4096,FF6144,FF8192,secp256r1mlkem768,secp384r1mlkem1024, mlkem768x25519"
|
|
NON_PQ_GROUPS="P256,P384,P521,x25519,FF2048,FF3072,FF4096,FF6144,FF8192"
|
|
- FIPS_GROUPS="P256,P384,P521,FF2048,FF3072,FF4096,FF6144,FF8192,mlkem768secp256r1,mlkem768x25519"
|
|
+ FIPS_GROUPS="P256,P384,P521,FF2048,FF3072,FF4096,FF6144,FF8192,secp256r1mlkem768,secp384r1mlkem1024,mlkem768x25519"
|
|
|
|
# in non-fips mode, tstclnt may run without the db password in some
|
|
# cases, but in fips mode it's always needed
|
|
CLIENT_PW=""
|
|
CLIENT_PW_FIPS="-w nss"
|
|
CLIENT_PW_NORMAL=""
|
|
|
|
if [ "${OS_ARCH}" != "WINNT" ]; then
|
|
@@ -372,19 +372,21 @@ ssl_cov()
|
|
if [ "$VMAX" = "ssl3" -a "$VMIN" = "tls1.1" ]; then
|
|
kill_selfserv
|
|
start_selfserv $CIPHER_SUITES
|
|
VMIN="ssl3"
|
|
fi
|
|
|
|
TLS_GROUPS=${CLIENT_GROUPS}
|
|
if [ "$ectype" = "MLKEM256" ]; then
|
|
- TLS_GROUPS="mlkem768secp256r1"
|
|
+ TLS_GROUPS="secp256r1mlkem768"
|
|
elif [ "$ectype" = "MLKEM219" ]; then
|
|
- TLS_GROUPS="mlkem768x25519"
|
|
+ TLS_GROUPS="x25519mlkem768"
|
|
+ elif [ "$ectype" = "MLKEM384" ]; then
|
|
+ TLS_GROUPS="secp384r1mlkem1024"
|
|
fi
|
|
echo "TLS_GROUPS=${TLS_GROUPS}"
|
|
|
|
echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I \"${TLS_GROUPS}\" -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
|
|
echo " -f -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE}"
|
|
|
|
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
|
|
${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I "${TLS_GROUPS}" -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
|
|
diff --git a/tests/ssl/sslcov.txt b/tests/ssl/sslcov.txt
|
|
--- a/tests/ssl/sslcov.txt
|
|
+++ b/tests/ssl/sslcov.txt
|
|
@@ -148,14 +148,17 @@
|
|
# Test against server with RSA-PSS server certificate
|
|
#
|
|
ECC TLS12 :C02F TLS12_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - RSA-PSS
|
|
ECC TLS12 :C030 TLS12_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - RSA-PSS
|
|
# test TLS 1.3
|
|
ECC TLS13 :1301 TLS13_ECDHE_WITH_AES_128_GCM_SHA256
|
|
ECC TLS13 :1302 TLS13_ECDHE_WITH_AES_256_GCM_SHA384
|
|
ECC TLS13 :1303 TLS13_ECDHE_WITH_CHACHA20_POLY1305_SHA256
|
|
-MLKEM256 TLS13 :1301 TLS13_MLKEMP256_WITH_AES_128_GCM_SHA256
|
|
-MLKEM256 TLS13 :1302 TLS13_MLKEMP256_WITH_AES_256_GCM_SHA384
|
|
-MLKEM256 TLS13 :1303 TLS13_MLKEMP256_WITH_CHACHA20_POLY1305_SHA256
|
|
-MLKEM219 TLS13 :1301 TLS13_MLKEMX25519_WITH_AES_128_GCM_SHA256
|
|
-MLKEM219 TLS13 :1302 TLS13_MLKEMX25519_WITH_AES_256_GCM_SHA384
|
|
-MLKEM219 TLS13 :1303 TLS13_MLKEMX25519_WITH_CHACHA20_POLY1305_SHA256
|
|
+MLKEM384 TLS13 :1301 TLS13_MLKEM1024P384_WITH_AES_128_GCM_SHA256
|
|
+MLKEM384 TLS13 :1302 TLS13_MLKEM1024P384_WITH_AES_256_GCM_SHA384
|
|
+MLKEM384 TLS13 :1303 TLS13_MLKEM1024P384_WITH_CHACHA20_POLY1305_SHA256
|
|
+MLKEM256 TLS13 :1301 TLS13_MLKEM768P256_WITH_AES_128_GCM_SHA256
|
|
+MLKEM256 TLS13 :1302 TLS13_MLKEM768P256_WITH_AES_256_GCM_SHA384
|
|
+MLKEM256 TLS13 :1303 TLS13_MLKEM768P256_WITH_CHACHA20_POLY1305_SHA256
|
|
+MLKEM219 TLS13 :1301 TLS13_MLKEM768X25519_WITH_AES_128_GCM_SHA256
|
|
+MLKEM219 TLS13 :1302 TLS13_MLKEM768X25519_WITH_AES_256_GCM_SHA384
|
|
+MLKEM219 TLS13 :1303 TLS13_MLKEM768X25519_WITH_CHACHA20_POLY1305_SHA256
|