parent
5bb6bc10e7
commit
c9d6d3b84e
@ -0,0 +1,26 @@
|
|||||||
|
diff --git a/gtests/ssl_gtest/tls_subcerts_unittest.cc b/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
||||||
|
--- a/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
||||||
|
+++ b/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
||||||
|
@@ -15,13 +15,22 @@
|
||||||
|
#include "gtest_utils.h"
|
||||||
|
#include "tls_agent.h"
|
||||||
|
#include "tls_connect.h"
|
||||||
|
+#define LTO
|
||||||
|
|
||||||
|
namespace nss_test {
|
||||||
|
|
||||||
|
+#ifndef LTO
|
||||||
|
+// sigh this construction breaks LTO
|
||||||
|
const std::string kEcdsaDelegatorId = TlsAgent::kDelegatorEcdsa256;
|
||||||
|
const std::string kRsaeDelegatorId = TlsAgent::kDelegatorRsae2048;
|
||||||
|
const std::string kPssDelegatorId = TlsAgent::kDelegatorRsaPss2048;
|
||||||
|
const std::string kDCId = TlsAgent::kServerEcdsa256;
|
||||||
|
+#else
|
||||||
|
+#define kEcdsaDelegatorId TlsAgent::kDelegatorEcdsa256
|
||||||
|
+#define kRsaeDelegatorId TlsAgent::kDelegatorRsae2048
|
||||||
|
+#define kPssDelegatorId TlsAgent::kDelegatorRsaPss2048
|
||||||
|
+#define kDCId TlsAgent::kServerEcdsa256
|
||||||
|
+#endif
|
||||||
|
const SSLSignatureScheme kDCScheme = ssl_sig_ecdsa_secp256r1_sha256;
|
||||||
|
const PRUint32 kDCValidFor = 60 * 60 * 24 * 7 /* 1 week (seconds) */;
|
||||||
|
|
@ -0,0 +1,90 @@
|
|||||||
|
diff -up ./lib/freebl/fipsfreebl.c.dh_test ./lib/freebl/fipsfreebl.c
|
||||||
|
--- ./lib/freebl/fipsfreebl.c.dh_test 2024-01-18 08:34:45.936944401 -0800
|
||||||
|
+++ ./lib/freebl/fipsfreebl.c 2024-01-18 09:20:57.555980326 -0800
|
||||||
|
@@ -1816,38 +1816,39 @@ freebl_fips_DH_PowerUpSelfTest(void)
|
||||||
|
{
|
||||||
|
/* DH Known P (2048-bits) */
|
||||||
|
static const PRUint8 dh_known_P[] = {
|
||||||
|
- 0xc2, 0x79, 0xbb, 0x76, 0x32, 0x0d, 0x43, 0xfd,
|
||||||
|
- 0x1b, 0x8c, 0xa2, 0x3c, 0x00, 0xdd, 0x6d, 0xef,
|
||||||
|
- 0xf8, 0x1a, 0xd9, 0xc1, 0xa2, 0xf5, 0x73, 0x2b,
|
||||||
|
- 0xdb, 0x1a, 0x3e, 0x84, 0x90, 0xeb, 0xe7, 0x8e,
|
||||||
|
- 0x5f, 0x5c, 0x6b, 0xb6, 0x61, 0x89, 0xd1, 0x03,
|
||||||
|
- 0xb0, 0x5f, 0x91, 0xe4, 0xd2, 0x82, 0x90, 0xfc,
|
||||||
|
- 0x3c, 0x49, 0x69, 0x59, 0xc1, 0x51, 0x6a, 0x85,
|
||||||
|
- 0x71, 0xe7, 0x5d, 0x72, 0x5a, 0x45, 0xad, 0x01,
|
||||||
|
- 0x6f, 0x82, 0xae, 0xec, 0x91, 0x08, 0x2e, 0x7c,
|
||||||
|
- 0x64, 0x93, 0x46, 0x1c, 0x68, 0xef, 0xc2, 0x03,
|
||||||
|
- 0x28, 0x1d, 0x75, 0x3a, 0xeb, 0x9c, 0x46, 0xf0,
|
||||||
|
- 0xc9, 0xdb, 0x99, 0x95, 0x13, 0x66, 0x4d, 0xd5,
|
||||||
|
- 0x1a, 0x78, 0x92, 0x51, 0x89, 0x72, 0x28, 0x7f,
|
||||||
|
- 0x20, 0x70, 0x41, 0x49, 0xa2, 0x86, 0xe9, 0xf9,
|
||||||
|
- 0x78, 0x5f, 0x8d, 0x2e, 0x5d, 0xfa, 0xdb, 0x57,
|
||||||
|
- 0xd4, 0x71, 0xdf, 0x66, 0xe3, 0x9e, 0x88, 0x70,
|
||||||
|
- 0xa4, 0x21, 0x44, 0x6a, 0xc7, 0xae, 0x30, 0x2c,
|
||||||
|
- 0x9c, 0x1f, 0x91, 0x57, 0xc8, 0x24, 0x34, 0x2d,
|
||||||
|
- 0x7a, 0x4a, 0x43, 0xc2, 0x5f, 0xab, 0x64, 0x2e,
|
||||||
|
- 0xaa, 0x28, 0x32, 0x95, 0x42, 0x7b, 0xa0, 0xcc,
|
||||||
|
- 0xdf, 0xfd, 0x22, 0xc8, 0x56, 0x84, 0xc1, 0x62,
|
||||||
|
- 0x15, 0xb2, 0x77, 0x86, 0x81, 0xfc, 0xa5, 0x12,
|
||||||
|
- 0x3c, 0xca, 0x28, 0x17, 0x8f, 0x03, 0x16, 0x6e,
|
||||||
|
- 0xb8, 0x24, 0xfa, 0x1b, 0x15, 0x02, 0xfd, 0x8b,
|
||||||
|
- 0xb6, 0x0a, 0x1a, 0xf7, 0x47, 0x41, 0xc5, 0x2b,
|
||||||
|
- 0x37, 0x3e, 0xa1, 0xbf, 0x68, 0xda, 0x1c, 0x55,
|
||||||
|
- 0x44, 0xc3, 0xee, 0xa1, 0x63, 0x07, 0x11, 0x3b,
|
||||||
|
- 0x5f, 0x00, 0x84, 0xb4, 0xc4, 0xe4, 0xa7, 0x97,
|
||||||
|
- 0x29, 0xf8, 0xce, 0xab, 0xfc, 0x27, 0x3e, 0x34,
|
||||||
|
- 0xe4, 0xc7, 0x81, 0x52, 0x32, 0x0e, 0x27, 0x3c,
|
||||||
|
- 0xa6, 0x70, 0x3f, 0x4a, 0x54, 0xda, 0xdd, 0x60,
|
||||||
|
- 0x26, 0xb3, 0x6e, 0x45, 0x26, 0x19, 0x41, 0x6f
|
||||||
|
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
+ 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
|
||||||
|
+ 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
|
||||||
|
+ 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
|
||||||
|
+ 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
|
||||||
|
+ 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
|
||||||
|
+ 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
|
||||||
|
+ 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
|
||||||
|
+ 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
|
||||||
|
+ 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
|
||||||
|
+ 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
|
||||||
|
+ 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
|
||||||
|
+ 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
|
||||||
|
+ 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
|
||||||
|
+ 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
|
||||||
|
+ 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
|
||||||
|
+ 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
|
||||||
|
+ 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
|
||||||
|
+ 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
|
||||||
|
+ 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
|
||||||
|
+ 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
|
||||||
|
+ 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
|
||||||
|
+ 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
|
||||||
|
+ 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
|
||||||
|
+ 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
|
||||||
|
+ 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
|
||||||
|
+ 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
|
||||||
|
+ 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
|
||||||
|
+ 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
|
||||||
|
+ 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
|
||||||
|
+ 0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97,
|
||||||
|
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||||
|
+
|
||||||
|
};
|
||||||
|
|
||||||
|
static const PRUint8 dh_known_Y_1[] = {
|
||||||
|
@@ -1893,10 +1894,10 @@ freebl_fips_DH_PowerUpSelfTest(void)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const PRUint8 dh_known_hash_result[] = {
|
||||||
|
- 0x93, 0xa2, 0x89, 0x1c, 0x8a, 0xc3, 0x70, 0xbf,
|
||||||
|
- 0xa7, 0xdf, 0xb6, 0xd7, 0x82, 0xfb, 0x87, 0x81,
|
||||||
|
- 0x09, 0x47, 0xf3, 0x9f, 0x5a, 0xbf, 0x4f, 0x3f,
|
||||||
|
- 0x8e, 0x5e, 0x06, 0xca, 0x30, 0xa7, 0xaf, 0x10
|
||||||
|
+ 0x40, 0xe3, 0x7a, 0x34, 0x83, 0x2d, 0x94, 0x57,
|
||||||
|
+ 0x99, 0x3d, 0x66, 0xec, 0x54, 0xdf, 0x82, 0x4a,
|
||||||
|
+ 0x37, 0x0d, 0xf9, 0x01, 0xb3, 0xbc, 0x54, 0xe5,
|
||||||
|
+ 0x5e, 0x63, 0xd3, 0x46, 0x4e, 0xa3, 0xe2, 0x8a
|
||||||
|
};
|
||||||
|
|
||||||
|
/* DH variables. */
|
@ -0,0 +1,194 @@
|
|||||||
|
diff -up ./cmd/pk11ectest/pk11ectest.c.ecc_wrap ./cmd/pk11ectest/pk11ectest.c
|
||||||
|
--- ./cmd/pk11ectest/pk11ectest.c.ecc_wrap 2023-06-04 01:42:53.000000000 -0700
|
||||||
|
+++ ./cmd/pk11ectest/pk11ectest.c 2024-01-23 14:07:29.421036328 -0800
|
||||||
|
@@ -10,6 +10,32 @@
|
||||||
|
#include "pk11pub.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
+typedef struct KeyLengthEntryStr {
|
||||||
|
+ SECOidTag tag;
|
||||||
|
+ unsigned int len;
|
||||||
|
+ PRBool encoded;
|
||||||
|
+} KeyLengthEntry;
|
||||||
|
+
|
||||||
|
+const KeyLengthEntry keyLengthTable[] = {
|
||||||
|
+ { SEC_OID_SECG_EC_SECP256R1, 65, PR_TRUE },
|
||||||
|
+ { SEC_OID_SECG_EC_SECP384R1, 97, PR_TRUE },
|
||||||
|
+ { SEC_OID_SECG_EC_SECP521R1, 133, PR_TRUE },
|
||||||
|
+ { SEC_OID_CURVE25519, 32, PR_FALSE }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+const KeyLengthEntry *
|
||||||
|
+getKeyLengthEntry(SECOidTag tag)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < PR_ARRAY_SIZE(keyLengthTable); i++) {
|
||||||
|
+ if (keyLengthTable[i].tag == tag) {
|
||||||
|
+ return &keyLengthTable[i];
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
printBuf(const SECItem *item)
|
||||||
|
{
|
||||||
|
@@ -53,6 +79,10 @@ ectest_curve_pkcs11(SECOidTag oid)
|
||||||
|
CK_MECHANISM_TYPE target = CKM_TLS12_MASTER_KEY_DERIVE_DH;
|
||||||
|
PK11SymKey *symKey = NULL;
|
||||||
|
SECStatus rv = SECFailure;
|
||||||
|
+ const KeyLengthEntry *keyLengthEntry;
|
||||||
|
+ SECItem point = { siBuffer, NULL, 0 };
|
||||||
|
+ SECItem value = { siBuffer, NULL, 0 };
|
||||||
|
+ PLArenaPool *arena = NULL;
|
||||||
|
|
||||||
|
oidData = SECOID_FindOIDByTag(oid);
|
||||||
|
if (oidData == NULL) {
|
||||||
|
@@ -79,8 +109,63 @@ ectest_curve_pkcs11(SECOidTag oid)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
PrintKey(symKey);
|
||||||
|
- rv = SECSuccess;
|
||||||
|
|
||||||
|
+ keyLengthEntry = getKeyLengthEntry(oid);
|
||||||
|
+ /* this shouldn't happen unless new curves are added without adding them
|
||||||
|
+ * to the keyLengthTable */
|
||||||
|
+ PR_ASSERT(keyLengthEntry);
|
||||||
|
+
|
||||||
|
+ /* make sure we are returning CKA_EC_POINT according to the PKCS #11 standard.
|
||||||
|
+ * NSS itself can tolerate non-standard CKA_EC_POINT, so this is the only place
|
||||||
|
+ * our test will detect incorrect behavior */
|
||||||
|
+ rv = PK11_ReadRawAttribute(PK11_TypePubKey, pubKey, CKA_EC_POINT, &point);
|
||||||
|
+ if (rv == SECFailure) {
|
||||||
|
+ printf(" >>> Couldn't get CKA_EC_POINT from the ec pubKey.\n");
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ rv = SECFailure;
|
||||||
|
+ if (keyLengthEntry->encoded) {
|
||||||
|
+ if (point.len == keyLengthEntry->len) {
|
||||||
|
+ printf(" >>> Expected encoded CKA_EC_POINT and got a decoded value.\n");
|
||||||
|
+ printBuf(&point);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
|
+ if (arena == NULL) {
|
||||||
|
+ printf(" >>> arena alloc failed.\n");
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rv = SEC_QuickDERDecodeItem(arena, &value, SEC_ASN1_GET(SEC_OctetStringTemplate),
|
||||||
|
+ &point);
|
||||||
|
+ if (rv != SECSuccess) {
|
||||||
|
+ printf(" >>> invalid endoded CKA_EC_POINT.\n");
|
||||||
|
+ printBuf(&point);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ rv = SECFailure;
|
||||||
|
+ if (value.len != keyLengthEntry->len) {
|
||||||
|
+ printf(" >>> invalid decoded CKA_EC_POINT len (%d) expected %d.\n",
|
||||||
|
+ value.len, keyLengthEntry->len);
|
||||||
|
+ printBuf(&value);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ if (value.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
|
||||||
|
+ printf(" >>> invalid CKA_EC_POINT format (%02x) expected %02x.\n",
|
||||||
|
+ value.data[0], EC_POINT_FORM_UNCOMPRESSED);
|
||||||
|
+ printBuf(&value);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ if (point.len != keyLengthEntry->len) {
|
||||||
|
+ printf(" >>> invalid CKA_EC_POINT len (%d) expected %d.\n",
|
||||||
|
+ point.len, keyLengthEntry->len);
|
||||||
|
+ printBuf(&point);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rv = SECSuccess;
|
||||||
|
cleanup:
|
||||||
|
if (privKey) {
|
||||||
|
SECKEY_DestroyPrivateKey(privKey);
|
||||||
|
@@ -91,7 +176,11 @@ cleanup:
|
||||||
|
if (symKey) {
|
||||||
|
PK11_FreeSymKey(symKey);
|
||||||
|
}
|
||||||
|
+ if (arena) {
|
||||||
|
+ PORT_FreeArena(arena, PR_TRUE);
|
||||||
|
+ }
|
||||||
|
SECITEM_FreeItem(&pk_11_ecParams, PR_FALSE);
|
||||||
|
+ SECITEM_FreeItem(&point, PR_FALSE);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
diff -up ./lib/freebl/blapit.h.ecc_wrap ./lib/freebl/blapit.h
|
||||||
|
--- ./lib/freebl/blapit.h.ecc_wrap 2023-06-04 01:42:53.000000000 -0700
|
||||||
|
+++ ./lib/freebl/blapit.h 2024-01-23 14:07:29.421036328 -0800
|
||||||
|
@@ -375,7 +375,9 @@ typedef struct DHPrivateKeyStr DHPrivate
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum { ec_params_explicit,
|
||||||
|
- ec_params_named
|
||||||
|
+ ec_params_named,
|
||||||
|
+ ec_params_edwards_named,
|
||||||
|
+ ec_params_montgomery_named,
|
||||||
|
} ECParamsType;
|
||||||
|
|
||||||
|
typedef enum { ec_field_GFp = 1,
|
||||||
|
diff -up ./lib/freebl/ecdecode.c.ecc_wrap ./lib/freebl/ecdecode.c
|
||||||
|
--- ./lib/freebl/ecdecode.c.ecc_wrap 2024-01-23 14:07:14.533870602 -0800
|
||||||
|
+++ ./lib/freebl/ecdecode.c 2024-01-23 14:07:29.422036340 -0800
|
||||||
|
@@ -176,6 +176,7 @@ EC_FillParams(PLArenaPool *arena, const
|
||||||
|
|
||||||
|
case SEC_OID_CURVE25519:
|
||||||
|
/* Populate params for Curve25519 */
|
||||||
|
+ params->type = ec_params_montgomery_named;
|
||||||
|
CHECK_SEC_OK(gf_populate_params_bytes(ECCurve25519,
|
||||||
|
ec_field_plain,
|
||||||
|
params));
|
||||||
|
diff -up ./lib/softoken/pkcs11c.c.ecc_wrap ./lib/softoken/pkcs11c.c
|
||||||
|
--- ./lib/softoken/pkcs11c.c.ecc_wrap 2024-01-23 14:07:14.520870457 -0800
|
||||||
|
+++ ./lib/softoken/pkcs11c.c 2024-01-23 14:08:38.198801966 -0800
|
||||||
|
@@ -5164,7 +5164,7 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
|
||||||
|
}
|
||||||
|
/* make sure it has the same encoding */
|
||||||
|
if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") ||
|
||||||
|
- lowPrivKey->u.ec.ecParams.fieldID.type == ec_field_plain) {
|
||||||
|
+ lowPrivKey->u.ec.ecParams.type != ec_params_named) {
|
||||||
|
lowPubValue = SECITEM_DupItem(&ecPriv->publicValue);
|
||||||
|
} else {
|
||||||
|
lowPubValue = SEC_ASN1EncodeItem(NULL, NULL, &ecPriv->publicValue,
|
||||||
|
@@ -5694,7 +5694,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") ||
|
||||||
|
- ecParams->fieldID.type == ec_field_plain) {
|
||||||
|
+ ecParams->type != ec_params_named) {
|
||||||
|
PORT_FreeArena(ecParams->arena, PR_TRUE);
|
||||||
|
crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
|
||||||
|
sftk_item_expand(&ecPriv->publicValue));
|
||||||
|
diff -up ./lib/softoken/pkcs11.c.ecc_wrap ./lib/softoken/pkcs11.c
|
||||||
|
--- ./lib/softoken/pkcs11.c.ecc_wrap 2024-01-23 14:07:14.505870290 -0800
|
||||||
|
+++ ./lib/softoken/pkcs11.c 2024-01-23 14:07:29.423036351 -0800
|
||||||
|
@@ -1897,8 +1897,8 @@ sftk_GetPubKey(SFTKObject *object, CK_KE
|
||||||
|
/* Handle the non-DER encoded case.
|
||||||
|
* Some curves are always pressumed to be non-DER.
|
||||||
|
*/
|
||||||
|
- if (pubKey->u.ec.publicValue.len == keyLen &&
|
||||||
|
- (pubKey->u.ec.ecParams.fieldID.type == ec_field_plain ||
|
||||||
|
+ if (pubKey->u.ec.ecParams.type != ec_params_named ||
|
||||||
|
+ (pubKey->u.ec.publicValue.len == keyLen &&
|
||||||
|
pubKey->u.ec.publicValue.data[0] == EC_POINT_FORM_UNCOMPRESSED)) {
|
||||||
|
break; /* key was not DER encoded, no need to unwrap */
|
||||||
|
}
|
||||||
|
@@ -1918,8 +1918,7 @@ sftk_GetPubKey(SFTKObject *object, CK_KE
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* we don't handle compressed points except in the case of ECCurve25519 */
|
||||||
|
- if ((pubKey->u.ec.ecParams.fieldID.type != ec_field_plain) &&
|
||||||
|
- (publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED)) {
|
||||||
|
+ if (publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
|
||||||
|
crv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||||
|
break;
|
||||||
|
}
|
@ -0,0 +1,176 @@
|
|||||||
|
diff -up ./lib/softoken/pkcs11c.c.fips_2 ./lib/softoken/pkcs11c.c
|
||||||
|
--- ./lib/softoken/pkcs11c.c.fips_2 2024-01-19 09:21:19.632889660 -0800
|
||||||
|
+++ ./lib/softoken/pkcs11c.c 2024-01-19 09:22:18.541471306 -0800
|
||||||
|
@@ -7090,7 +7090,7 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
|
||||||
|
mech.ulParameterLen = sizeof(*params);
|
||||||
|
key->isFIPS = sftk_operationIsFIPS(saltKey->slot, &mech,
|
||||||
|
CKA_DERIVE, saltKey,
|
||||||
|
- keySize);
|
||||||
|
+ keySize*PR_BITS_PER_BYTE);
|
||||||
|
}
|
||||||
|
saltKeySource = saltKey->source;
|
||||||
|
saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE);
|
||||||
|
@@ -7404,7 +7404,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE, sourceKey,
|
||||||
|
- keySize);
|
||||||
|
+ keySize*PR_BITS_PER_BYTE);
|
||||||
|
|
||||||
|
switch (mechanism) {
|
||||||
|
/* get a public key from a private key. nsslowkey_ConvertToPublickey()
|
||||||
|
diff -up ./lib/softoken/pkcs11u.c.fips_2 ./lib/softoken/pkcs11u.c
|
||||||
|
--- ./lib/softoken/pkcs11u.c.fips_2 2024-01-19 09:21:19.633889670 -0800
|
||||||
|
+++ ./lib/softoken/pkcs11u.c 2024-01-19 09:28:00.082843565 -0800
|
||||||
|
@@ -2393,20 +2393,43 @@ sftk_getKeyLength(SFTKObject *source)
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
-sftk_CheckFIPSHash(CK_MECHANISM_TYPE hash)
|
||||||
|
+sftk_checkFIPSHash(CK_MECHANISM_TYPE hash, PRBool allowSmall, PRBool allowCMAC)
|
||||||
|
{
|
||||||
|
switch (hash) {
|
||||||
|
+ case CKM_AES_CMAC:
|
||||||
|
+ return allowCMAC;
|
||||||
|
+ case CKM_SHA_1:
|
||||||
|
+ case CKM_SHA_1_HMAC:
|
||||||
|
+ case CKM_SHA224:
|
||||||
|
+ case CKM_SHA224_HMAC:
|
||||||
|
+ return allowSmall;
|
||||||
|
case CKM_SHA256:
|
||||||
|
- case CKG_MGF1_SHA256:
|
||||||
|
+ case CKM_SHA256_HMAC:
|
||||||
|
case CKM_SHA384:
|
||||||
|
- case CKG_MGF1_SHA384:
|
||||||
|
+ case CKM_SHA384_HMAC:
|
||||||
|
case CKM_SHA512:
|
||||||
|
- case CKG_MGF1_SHA512:
|
||||||
|
+ case CKM_SHA512_HMAC:
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+PRBool
|
||||||
|
+sftk_checkKeyLength(CK_ULONG keyLength, CK_ULONG min,
|
||||||
|
+ CK_ULONG max, CK_ULONG step)
|
||||||
|
+{
|
||||||
|
+ if (keyLength > max) {
|
||||||
|
+ return PR_FALSE;
|
||||||
|
+ }
|
||||||
|
+ if (keyLength < min ) {
|
||||||
|
+ return PR_FALSE;
|
||||||
|
+ }
|
||||||
|
+ if (((keyLength - min) % step) != 0) {
|
||||||
|
+ return PR_FALSE;
|
||||||
|
+ }
|
||||||
|
+ return PR_TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* handle specialized FIPS semantics that are too complicated to
|
||||||
|
* handle with just a table. NOTE: this means any additional semantics
|
||||||
|
@@ -2416,6 +2439,8 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
|
||||||
|
SFTKFIPSAlgorithmList *mechInfo, SFTKObject *source,
|
||||||
|
CK_ULONG keyLength, CK_ULONG targetKeyLength)
|
||||||
|
{
|
||||||
|
+ PRBool allowSmall = PR_FALSE;
|
||||||
|
+ PRBool allowCMAC = PR_FALSE;
|
||||||
|
switch (mechInfo->special) {
|
||||||
|
case SFTKFIPSDH: {
|
||||||
|
SECItem dhPrime;
|
||||||
|
@@ -2482,7 +2507,11 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
|
||||||
|
if (pss->sLen > hashObj->length) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
- return sftk_CheckFIPSHash(pss->hashAlg);
|
||||||
|
+ /* Our code makes sure pss->hashAlg matches the explicit
|
||||||
|
+ * hash in the mechanism, and only mechanisms with approved
|
||||||
|
+ * hashes are included, so no need to check pss->hashAlg
|
||||||
|
+ * here */
|
||||||
|
+ return PR_TRUE;
|
||||||
|
}
|
||||||
|
case SFTKFIPSPBKDF2: {
|
||||||
|
/* PBKDF2 must have the following addition restrictions
|
||||||
|
@@ -2508,12 +2537,28 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
/* check the hash mechanisms to make sure they themselves are FIPS */
|
||||||
|
+ case SFTKFIPSChkHashSp800:
|
||||||
|
+ allowCMAC = PR_TRUE;
|
||||||
|
case SFTKFIPSChkHash:
|
||||||
|
+ allowSmall = PR_TRUE;
|
||||||
|
+ case SFTKFIPSChkHashTls:
|
||||||
|
if (mech->ulParameterLen < mechInfo->offset +sizeof(CK_ULONG)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
- return sftk_CheckFIPSHash(*(CK_ULONG *)(((char *)mech->pParameter)
|
||||||
|
- + mechInfo->offset));
|
||||||
|
+ return sftk_checkFIPSHash(*(CK_ULONG *)(((char *)mech->pParameter)
|
||||||
|
+ + mechInfo->offset), allowSmall, allowCMAC);
|
||||||
|
+ case SFTKFIPSTlsKeyCheck:
|
||||||
|
+ if (mech->mechanism != CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) {
|
||||||
|
+ /* unless the mechnism has a built-in hash, check the hash */
|
||||||
|
+ if (mech->ulParameterLen < mechInfo->offset +sizeof(CK_ULONG)) {
|
||||||
|
+ return PR_FALSE;
|
||||||
|
+ }
|
||||||
|
+ if (!sftk_checkFIPSHash(*(CK_ULONG *)(((char *)mech->pParameter)
|
||||||
|
+ + mechInfo->offset), PR_FALSE, PR_FALSE)) {
|
||||||
|
+ return PR_FALSE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return sftk_checkKeyLength(targetKeyLength, 112, 512, 1);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -2558,13 +2603,11 @@ sftk_operationIsFIPS(SFTKSlot *slot, CK_
|
||||||
|
* approved algorithm in the approved mode with an approved key */
|
||||||
|
if ((mech->mechanism == mechs->type) &&
|
||||||
|
(opFlags == (mechs->info.flags & opFlags)) &&
|
||||||
|
- (keyLength <= mechs->info.ulMaxKeySize) &&
|
||||||
|
- (keyLength >= mechs->info.ulMinKeySize) &&
|
||||||
|
- (((keyLength - mechs->info.ulMinKeySize) % mechs->step) == 0) &&
|
||||||
|
- ((targetKeyLength == 0) ||
|
||||||
|
- ((targetKeyLength <= mechs->info.ulMaxKeySize) &&
|
||||||
|
- (targetKeyLength >= mechs->info.ulMinKeySize) &&
|
||||||
|
- ((targetKeyLength - mechs->info.ulMinKeySize) % mechs->step) == 0)) &&
|
||||||
|
+ sftk_checkKeyLength(keyLength, mechs->info.ulMinKeySize,
|
||||||
|
+ mechs->info.ulMaxKeySize, mechs->step) &&
|
||||||
|
+ ((targetKeyLength == 0) || (mechs->special == SFTKFIPSTlsKeyCheck)
|
||||||
|
+ || sftk_checkKeyLength(targetKeyLength, mechs->info.ulMinKeySize,
|
||||||
|
+ mechs->info.ulMaxKeySize, mechs->step)) &&
|
||||||
|
((mechs->special == SFTKFIPSNone) ||
|
||||||
|
sftk_handleSpecial(slot, mech, mechs, source, keyLength, targetKeyLength))) {
|
||||||
|
return PR_TRUE;
|
||||||
|
diff -up ./lib/softoken/sftkmessage.c.fips_2 ./lib/softoken/sftkmessage.c
|
||||||
|
--- ./lib/softoken/sftkmessage.c.fips_2 2024-01-19 09:21:19.634889680 -0800
|
||||||
|
+++ ./lib/softoken/sftkmessage.c 2024-01-19 09:22:18.541471306 -0800
|
||||||
|
@@ -157,16 +157,25 @@ sftk_CryptMessage(CK_SESSION_HANDLE hSes
|
||||||
|
} else {
|
||||||
|
CK_GCM_MESSAGE_PARAMS *p = (CK_GCM_MESSAGE_PARAMS *)pParameter;
|
||||||
|
switch (p->ivGenerator) {
|
||||||
|
+ default:
|
||||||
|
case CKG_NO_GENERATE:
|
||||||
|
context->isFIPS = PR_FALSE;
|
||||||
|
break;
|
||||||
|
case CKG_GENERATE_RANDOM:
|
||||||
|
- if ((p->ulIvLen < 12) || (p->ulIvFixedBits != 0)) {
|
||||||
|
+ if ((p->ulIvLen < 96/PR_BITS_PER_BYTE) ||
|
||||||
|
+ (p->ulIvFixedBits != 0)) {
|
||||||
|
context->isFIPS = PR_FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
- default:
|
||||||
|
- if ((p->ulIvLen < 12) || (p->ulIvFixedBits < 32)) {
|
||||||
|
+ case CKG_GENERATE_COUNTER_XOR:
|
||||||
|
+ if ((p->ulIvLen != 96/PR_BITS_PER_BYTE) ||
|
||||||
|
+ (p->ulIvFixedBits != 32)) {
|
||||||
|
+ context->isFIPS = PR_FALSE;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case CKG_GENERATE_COUNTER:
|
||||||
|
+ if ((p->ulIvFixedBits < 32) ||
|
||||||
|
+ ((p->ulIvLen*PR_BITS_PER_BYTE - p->ulIvFixedBits) < 32)) {
|
||||||
|
context->isFIPS = PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,644 @@
|
|||||||
|
diff -up ./automation/taskcluster/scripts/run_hacl.sh.p384 ./automation/taskcluster/scripts/run_hacl.sh
|
||||||
|
--- ./automation/taskcluster/scripts/run_hacl.sh.p384 2023-06-04 01:42:53.000000000 -0700
|
||||||
|
+++ ./automation/taskcluster/scripts/run_hacl.sh 2024-01-09 11:49:58.650418434 -0800
|
||||||
|
@@ -40,5 +40,14 @@ files=($(find ~/nss/lib/freebl/verified/
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
file_name=$(basename "$f")
|
||||||
|
hacl_file=($(find ~/hacl-star/dist/mozilla/ ~/hacl-star/dist/karamel/ -type f -name $file_name -not -path "*/hacl-star/dist/mozilla/internal/*"))
|
||||||
|
+ # TODO(Bug 1854438): Remove P384 exception.
|
||||||
|
+ # TODO(Bug 1854439): Remove P521 exception.
|
||||||
|
+ if [ $file_name == "Hacl_P384.c" \
|
||||||
|
+ -o $file_name == "Hacl_P384.h" \
|
||||||
|
+ -o $file_name == "Hacl_P521.c" \
|
||||||
|
+ -o $file_name == "Hacl_P521.h" ]
|
||||||
|
+ then
|
||||||
|
+ continue;
|
||||||
|
+ fi
|
||||||
|
diff $hacl_file $f
|
||||||
|
done
|
||||||
|
diff -up ./lib/freebl/ec.c.p384 ./lib/freebl/ec.c
|
||||||
|
--- ./lib/freebl/ec.c.p384 2024-01-09 11:49:14.118980084 -0800
|
||||||
|
+++ ./lib/freebl/ec.c 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
@@ -15,15 +15,62 @@
|
||||||
|
#include "mplogic.h"
|
||||||
|
#include "ec.h"
|
||||||
|
#include "ecl.h"
|
||||||
|
+#include "verified/Hacl_P384.h"
|
||||||
|
+#include "verified/Hacl_P521.h"
|
||||||
|
|
||||||
|
#define EC_DOUBLECHECK PR_FALSE
|
||||||
|
|
||||||
|
+SECStatus
|
||||||
|
+ec_secp384r1_scalar_validate(const SECItem *scalar)
|
||||||
|
+{
|
||||||
|
+ if (!scalar || !scalar->data) {
|
||||||
|
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
|
+ return SECFailure;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (scalar->len != 48) {
|
||||||
|
+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||||
|
+ return SECFailure;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bool b = Hacl_P384_validate_private_key(scalar->data);
|
||||||
|
+
|
||||||
|
+ if (!b) {
|
||||||
|
+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||||
|
+ return SECFailure;
|
||||||
|
+ }
|
||||||
|
+ return SECSuccess;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+SECStatus
|
||||||
|
+ec_secp521r1_scalar_validate(const SECItem *scalar)
|
||||||
|
+{
|
||||||
|
+ if (!scalar || !scalar->data) {
|
||||||
|
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
|
+ return SECFailure;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (scalar->len != 66) {
|
||||||
|
+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||||
|
+ return SECFailure;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bool b = Hacl_P521_validate_private_key(scalar->data);
|
||||||
|
+
|
||||||
|
+ if (!b) {
|
||||||
|
+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||||
|
+ return SECFailure;
|
||||||
|
+ }
|
||||||
|
+ return SECSuccess;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static const ECMethod kMethods[] = {
|
||||||
|
{ ECCurve25519,
|
||||||
|
ec_Curve25519_pt_mul,
|
||||||
|
ec_Curve25519_pt_validate,
|
||||||
|
ec_Curve25519_scalar_validate,
|
||||||
|
- NULL, NULL },
|
||||||
|
+ NULL,
|
||||||
|
+ NULL },
|
||||||
|
{
|
||||||
|
ECCurve_NIST_P256,
|
||||||
|
ec_secp256r1_pt_mul,
|
||||||
|
@@ -352,8 +415,7 @@ EC_NewKeyFromSeed(ECParams *ecParams, EC
|
||||||
|
SECStatus
|
||||||
|
ec_GenerateRandomPrivateKey(ECParams *ecParams, SECItem *privKey)
|
||||||
|
{
|
||||||
|
- SECStatus rv = SECSuccess;
|
||||||
|
- mp_err err;
|
||||||
|
+ SECStatus rv = SECFailure;
|
||||||
|
|
||||||
|
unsigned int len = EC_GetScalarSize(ecParams);
|
||||||
|
|
||||||
|
@@ -362,82 +424,43 @@ ec_GenerateRandomPrivateKey(ECParams *ec
|
||||||
|
return SECFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* For known curves, use rejection sampling A.4.2 */
|
||||||
|
- if (ecParams->fieldID.type == ec_field_plain) {
|
||||||
|
- const ECMethod *method = ec_get_method_from_name(ecParams->name);
|
||||||
|
- rv = SECFailure;
|
||||||
|
- if (method == NULL || method->scalar_validate == NULL) {
|
||||||
|
- /* unknown curve */
|
||||||
|
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
|
- goto done;
|
||||||
|
- }
|
||||||
|
- int count = 100;
|
||||||
|
- while (rv != SECSuccess && count >= 0) {
|
||||||
|
- rv = RNG_GenerateGlobalRandomBytes(privKey->data, len);
|
||||||
|
- if (rv != SECSuccess) {
|
||||||
|
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
||||||
|
- goto done;
|
||||||
|
- }
|
||||||
|
- rv = method->scalar_validate(privKey);
|
||||||
|
- count--;
|
||||||
|
- }
|
||||||
|
- if (rv != SECSuccess) {
|
||||||
|
- PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||||
|
- }
|
||||||
|
- goto done;
|
||||||
|
+ const ECMethod *method = ec_get_method_from_name(ecParams->name);
|
||||||
|
+ if (method == NULL || method->scalar_validate == NULL) {
|
||||||
|
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
|
||||||
|
+ return SECFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* For unknown curves, use algotithm A.4.1 */
|
||||||
|
-
|
||||||
|
- unsigned char *order = ecParams->order.data;
|
||||||
|
- mp_int privKeyVal, order_1, one;
|
||||||
|
- unsigned char *privKeyBytes = NULL;
|
||||||
|
-
|
||||||
|
- MP_DIGITS(&privKeyVal) = 0;
|
||||||
|
- MP_DIGITS(&order_1) = 0;
|
||||||
|
- MP_DIGITS(&one) = 0;
|
||||||
|
- CHECK_MPI_OK(mp_init(&privKeyVal));
|
||||||
|
- CHECK_MPI_OK(mp_init(&order_1));
|
||||||
|
- CHECK_MPI_OK(mp_init(&one));
|
||||||
|
-
|
||||||
|
- /* Generates 2*len random bytes using the global random bit generator
|
||||||
|
- * (which implements Algorithm 1 of FIPS 186-2 Change Notice 1) then
|
||||||
|
- * reduces modulo the group order.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- if ((privKeyBytes = PORT_Alloc(2 * len)) == NULL) {
|
||||||
|
- PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||||
|
- rv = SECFailure;
|
||||||
|
- goto cleanup;
|
||||||
|
+ uint8_t leading_coeff_mask;
|
||||||
|
+ switch (ecParams->name) {
|
||||||
|
+ case ECCurve25519:
|
||||||
|
+ case ECCurve_NIST_P256:
|
||||||
|
+ case ECCurve_NIST_P384:
|
||||||
|
+ leading_coeff_mask = 0xff;
|
||||||
|
+ break;
|
||||||
|
+ case ECCurve_NIST_P521:
|
||||||
|
+ leading_coeff_mask = 0x01;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
|
||||||
|
+ return SECFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
- CHECK_SEC_OK(RNG_GenerateGlobalRandomBytes(privKeyBytes, 2 * len));
|
||||||
|
- CHECK_MPI_OK(mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2 * len));
|
||||||
|
- CHECK_MPI_OK(mp_read_unsigned_octets(&order_1, order, len));
|
||||||
|
- CHECK_MPI_OK(mp_set_int(&one, 1));
|
||||||
|
- CHECK_MPI_OK(mp_sub(&order_1, &one, &order_1));
|
||||||
|
- CHECK_MPI_OK(mp_mod(&privKeyVal, &order_1, &privKeyVal));
|
||||||
|
- CHECK_MPI_OK(mp_add(&privKeyVal, &one, &privKeyVal));
|
||||||
|
- CHECK_MPI_OK(mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len));
|
||||||
|
- memcpy(privKey->data, privKeyBytes, len);
|
||||||
|
+ /* The rejection sampling method from FIPS 186-5 A.4.2 */
|
||||||
|
+ int count = 100;
|
||||||
|
+ do {
|
||||||
|
+ rv = RNG_GenerateGlobalRandomBytes(privKey->data, len);
|
||||||
|
+ if (rv != SECSuccess) {
|
||||||
|
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
||||||
|
+ return SECFailure;
|
||||||
|
+ }
|
||||||
|
+ privKey->data[0] &= leading_coeff_mask;
|
||||||
|
+ rv = method->scalar_validate(privKey);
|
||||||
|
+ } while (rv != SECSuccess && --count > 0);
|
||||||
|
|
||||||
|
-cleanup:
|
||||||
|
- mp_clear(&privKeyVal);
|
||||||
|
- mp_clear(&order_1);
|
||||||
|
- mp_clear(&one);
|
||||||
|
- if (privKeyBytes) {
|
||||||
|
- PORT_ZFree(privKeyBytes, 2 * len);
|
||||||
|
- }
|
||||||
|
- if (err < MP_OKAY) {
|
||||||
|
- MP_TO_SEC_ERROR(err);
|
||||||
|
- rv = SECFailure;
|
||||||
|
+ if (rv != SECSuccess) { // implies count == 0
|
||||||
|
+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
-done:
|
||||||
|
- if (rv != SECSuccess && privKey->data) {
|
||||||
|
- SECITEM_ZfreeItem(privKey, PR_FALSE);
|
||||||
|
- return rv;
|
||||||
|
- }
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -up ./lib/freebl/ecl/ecl.h.p384 ./lib/freebl/ecl/ecl.h
|
||||||
|
--- ./lib/freebl/ecl/ecl.h.p384 2024-01-09 11:49:14.118980084 -0800
|
||||||
|
+++ ./lib/freebl/ecl/ecl.h 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
@@ -57,4 +57,8 @@ SECStatus ec_secp256r1_sign_digest(ECPri
|
||||||
|
SECStatus ec_secp256r1_verify_digest(ECPublicKey *key, const SECItem *signature,
|
||||||
|
const SECItem *digest);
|
||||||
|
|
||||||
|
+SECStatus ec_secp384r1_scalar_validate(const SECItem *scalar);
|
||||||
|
+
|
||||||
|
+SECStatus ec_secp521r1_scalar_validate(const SECItem *scalar);
|
||||||
|
+
|
||||||
|
#endif /* __ecl_h_ */
|
||||||
|
diff -up ./lib/freebl/freebl_base.gypi.p384 ./lib/freebl/freebl_base.gypi
|
||||||
|
--- ./lib/freebl/freebl_base.gypi.p384 2024-01-09 11:49:14.118980084 -0800
|
||||||
|
+++ ./lib/freebl/freebl_base.gypi 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
@@ -38,6 +38,8 @@
|
||||||
|
'ecl/ecp_secp384r1.c',
|
||||||
|
'ecl/ecp_secp521r1.c',
|
||||||
|
'verified/Hacl_P256.c',
|
||||||
|
+ 'verified/Hacl_P384.c',
|
||||||
|
+ 'verified/Hacl_P521.c',
|
||||||
|
'fipsfreebl.c',
|
||||||
|
'blinit.c',
|
||||||
|
'freeblver.c',
|
||||||
|
diff -up ./lib/freebl/Makefile.p384 ./lib/freebl/Makefile
|
||||||
|
--- ./lib/freebl/Makefile.p384 2024-01-09 11:49:58.650418434 -0800
|
||||||
|
+++ ./lib/freebl/Makefile 2024-01-09 11:51:20.500224176 -0800
|
||||||
|
@@ -612,7 +612,7 @@ ifndef NSS_DISABLE_CHACHAPOLY
|
||||||
|
VERIFIED_SRCS += Hacl_Poly1305_32.c Hacl_Chacha20.c Hacl_Chacha20Poly1305_32.c
|
||||||
|
endif # NSS_DISABLE_CHACHAPOLY
|
||||||
|
|
||||||
|
-VERIFIED_SRCS += Hacl_P256.c
|
||||||
|
+VERIFIED_SRCS += Hacl_P256.c Hacl_P384.c Hacl_P521.c
|
||||||
|
|
||||||
|
ifeq (,$(filter-out x86_64 aarch64,$(CPU_ARCH)))
|
||||||
|
# All 64-bit architectures get the 64 bit version.
|
||||||
|
diff -up ./lib/freebl/verified/Hacl_P384.c.p384 ./lib/freebl/verified/Hacl_P384.c
|
||||||
|
--- ./lib/freebl/verified/Hacl_P384.c.p384 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
+++ ./lib/freebl/verified/Hacl_P384.c 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
@@ -0,0 +1,126 @@
|
||||||
|
+/* MIT License
|
||||||
|
+ *
|
||||||
|
+ * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation
|
||||||
|
+ * Copyright (c) 2022-2023 HACL* Contributors
|
||||||
|
+ *
|
||||||
|
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
+ * of this software and associated documentation files (the "Software"), to deal
|
||||||
|
+ * in the Software without restriction, including without limitation the rights
|
||||||
|
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
+ * copies of the Software, and to permit persons to whom the Software is
|
||||||
|
+ * furnished to do so, subject to the following conditions:
|
||||||
|
+ *
|
||||||
|
+ * The above copyright notice and this permission notice shall be included in all
|
||||||
|
+ * copies or substantial portions of the Software.
|
||||||
|
+ *
|
||||||
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
+ * SOFTWARE.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "Hacl_P384.h"
|
||||||
|
+
|
||||||
|
+#include "internal/Hacl_Krmllib.h"
|
||||||
|
+#include "internal/Hacl_Bignum_Base.h"
|
||||||
|
+
|
||||||
|
+static inline uint64_t
|
||||||
|
+bn_is_eq_mask(uint64_t *x, uint64_t *y)
|
||||||
|
+{
|
||||||
|
+ uint64_t mask = (uint64_t)0xFFFFFFFFFFFFFFFFU;
|
||||||
|
+ KRML_MAYBE_FOR6(i,
|
||||||
|
+ (uint32_t)0U,
|
||||||
|
+ (uint32_t)6U,
|
||||||
|
+ (uint32_t)1U,
|
||||||
|
+ uint64_t uu____0 = FStar_UInt64_eq_mask(x[i], y[i]);
|
||||||
|
+ mask = uu____0 & mask;);
|
||||||
|
+ uint64_t mask1 = mask;
|
||||||
|
+ return mask1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline uint64_t
|
||||||
|
+bn_sub(uint64_t *a, uint64_t *b, uint64_t *c)
|
||||||
|
+{
|
||||||
|
+ uint64_t c1 = (uint64_t)0U;
|
||||||
|
+ {
|
||||||
|
+ uint64_t t1 = b[(uint32_t)4U * (uint32_t)0U];
|
||||||
|
+ uint64_t t20 = c[(uint32_t)4U * (uint32_t)0U];
|
||||||
|
+ uint64_t *res_i0 = a + (uint32_t)4U * (uint32_t)0U;
|
||||||
|
+ c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t1, t20, res_i0);
|
||||||
|
+ uint64_t t10 = b[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
|
||||||
|
+ uint64_t t21 = c[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
|
||||||
|
+ uint64_t *res_i1 = a + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
|
||||||
|
+ c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t10, t21, res_i1);
|
||||||
|
+ uint64_t t11 = b[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
|
||||||
|
+ uint64_t t22 = c[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
|
||||||
|
+ uint64_t *res_i2 = a + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
|
||||||
|
+ c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t11, t22, res_i2);
|
||||||
|
+ uint64_t t12 = b[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
|
||||||
|
+ uint64_t t2 = c[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
|
||||||
|
+ uint64_t *res_i = a + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
|
||||||
|
+ c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t12, t2, res_i);
|
||||||
|
+ }
|
||||||
|
+ KRML_MAYBE_FOR2(i,
|
||||||
|
+ (uint32_t)4U,
|
||||||
|
+ (uint32_t)6U,
|
||||||
|
+ (uint32_t)1U,
|
||||||
|
+ uint64_t t1 = b[i];
|
||||||
|
+ uint64_t t2 = c[i];
|
||||||
|
+ uint64_t *res_i = a + i;
|
||||||
|
+ c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t1, t2, res_i););
|
||||||
|
+ uint64_t c10 = c1;
|
||||||
|
+ return c10;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void
|
||||||
|
+bn_from_bytes_be(uint64_t *a, uint8_t *b)
|
||||||
|
+{
|
||||||
|
+ KRML_MAYBE_FOR6(i,
|
||||||
|
+ (uint32_t)0U,
|
||||||
|
+ (uint32_t)6U,
|
||||||
|
+ (uint32_t)1U,
|
||||||
|
+ uint64_t *os = a;
|
||||||
|
+ uint64_t u = load64_be(b + ((uint32_t)6U - i - (uint32_t)1U) * (uint32_t)8U);
|
||||||
|
+ uint64_t x = u;
|
||||||
|
+ os[i] = x;);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void
|
||||||
|
+p384_make_order(uint64_t *n)
|
||||||
|
+{
|
||||||
|
+ n[0U] = (uint64_t)0xecec196accc52973U;
|
||||||
|
+ n[1U] = (uint64_t)0x581a0db248b0a77aU;
|
||||||
|
+ n[2U] = (uint64_t)0xc7634d81f4372ddfU;
|
||||||
|
+ n[3U] = (uint64_t)0xffffffffffffffffU;
|
||||||
|
+ n[4U] = (uint64_t)0xffffffffffffffffU;
|
||||||
|
+ n[5U] = (uint64_t)0xffffffffffffffffU;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+Private key validation.
|
||||||
|
+
|
||||||
|
+ The function returns `true` if a private key is valid and `false` otherwise.
|
||||||
|
+
|
||||||
|
+ The argument `private_key` points to 48 bytes of valid memory, i.e., uint8_t[48].
|
||||||
|
+
|
||||||
|
+ The private key is valid:
|
||||||
|
+ • 0 < `private_key` < the order of the curve
|
||||||
|
+*/
|
||||||
|
+bool
|
||||||
|
+Hacl_P384_validate_private_key(uint8_t *private_key)
|
||||||
|
+{
|
||||||
|
+ uint64_t bn_sk[6U] = { 0U };
|
||||||
|
+ bn_from_bytes_be(bn_sk, private_key);
|
||||||
|
+ uint64_t tmp[6U] = { 0U };
|
||||||
|
+ p384_make_order(tmp);
|
||||||
|
+ uint64_t c = bn_sub(tmp, bn_sk, tmp);
|
||||||
|
+ uint64_t is_lt_order = (uint64_t)0U - c;
|
||||||
|
+ uint64_t bn_zero[6U] = { 0U };
|
||||||
|
+ uint64_t res = bn_is_eq_mask(bn_sk, bn_zero);
|
||||||
|
+ uint64_t is_eq_zero = res;
|
||||||
|
+ uint64_t res0 = is_lt_order & ~is_eq_zero;
|
||||||
|
+ return res0 == (uint64_t)0xFFFFFFFFFFFFFFFFU;
|
||||||
|
+}
|
||||||
|
diff -up ./lib/freebl/verified/Hacl_P384.h.p384 ./lib/freebl/verified/Hacl_P384.h
|
||||||
|
--- ./lib/freebl/verified/Hacl_P384.h.p384 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
+++ ./lib/freebl/verified/Hacl_P384.h 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
@@ -0,0 +1,68 @@
|
||||||
|
+/* MIT License
|
||||||
|
+ *
|
||||||
|
+ * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation
|
||||||
|
+ * Copyright (c) 2022-2023 HACL* Contributors
|
||||||
|
+ *
|
||||||
|
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
+ * of this software and associated documentation files (the "Software"), to deal
|
||||||
|
+ * in the Software without restriction, including without limitation the rights
|
||||||
|
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
+ * copies of the Software, and to permit persons to whom the Software is
|
||||||
|
+ * furnished to do so, subject to the following conditions:
|
||||||
|
+ *
|
||||||
|
+ * The above copyright notice and this permission notice shall be included in all
|
||||||
|
+ * copies or substantial portions of the Software.
|
||||||
|
+ *
|
||||||
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
+ * SOFTWARE.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef __Hacl_P384_H
|
||||||
|
+#define __Hacl_P384_H
|
||||||
|
+
|
||||||
|
+#if defined(__cplusplus)
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#include <string.h>
|
||||||
|
+#include "krml/internal/types.h"
|
||||||
|
+#include "krml/lowstar_endianness.h"
|
||||||
|
+
|
||||||
|
+#include "lib_intrinsics.h"
|
||||||
|
+
|
||||||
|
+/*******************************************************************************
|
||||||
|
+
|
||||||
|
+ Verified C library for ECDSA and ECDH functions over the P-384 NIST curve.
|
||||||
|
+
|
||||||
|
+ This module implements signing and verification, key validation, conversions
|
||||||
|
+ between various point representations, and ECDH key agreement.
|
||||||
|
+
|
||||||
|
+*******************************************************************************/
|
||||||
|
+
|
||||||
|
+/******************/
|
||||||
|
+/* Key validation */
|
||||||
|
+/******************/
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+Private key validation.
|
||||||
|
+
|
||||||
|
+ The function returns `true` if a private key is valid and `false` otherwise.
|
||||||
|
+
|
||||||
|
+ The argument `private_key` points to 32 bytes of valid memory, i.e., uint8_t[32].
|
||||||
|
+
|
||||||
|
+ The private key is valid:
|
||||||
|
+ • 0 < `private_key` < the order of the curve
|
||||||
|
+*/
|
||||||
|
+bool Hacl_P384_validate_private_key(uint8_t *private_key);
|
||||||
|
+
|
||||||
|
+#if defined(__cplusplus)
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define __Hacl_P384_H_DEFINED
|
||||||
|
+#endif
|
||||||
|
diff -up ./lib/freebl/verified/Hacl_P521.c.p384 ./lib/freebl/verified/Hacl_P521.c
|
||||||
|
--- ./lib/freebl/verified/Hacl_P521.c.p384 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
+++ ./lib/freebl/verified/Hacl_P521.c 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
@@ -0,0 +1,131 @@
|
||||||
|
+/* MIT License
|
||||||
|
+ *
|
||||||
|
+ * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation
|
||||||
|
+ * Copyright (c) 2022-2023 HACL* Contributors
|
||||||
|
+ *
|
||||||
|
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
+ * of this software and associated documentation files (the "Software"), to deal
|
||||||
|
+ * in the Software without restriction, including without limitation the rights
|
||||||
|
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
+ * copies of the Software, and to permit persons to whom the Software is
|
||||||
|
+ * furnished to do so, subject to the following conditions:
|
||||||
|
+ *
|
||||||
|
+ * The above copyright notice and this permission notice shall be included in all
|
||||||
|
+ * copies or substantial portions of the Software.
|
||||||
|
+ *
|
||||||
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
+ * SOFTWARE.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "Hacl_P521.h"
|
||||||
|
+
|
||||||
|
+#include "internal/Hacl_Krmllib.h"
|
||||||
|
+#include "internal/Hacl_Bignum_Base.h"
|
||||||
|
+
|
||||||
|
+static inline uint64_t
|
||||||
|
+bn_is_eq_mask(uint64_t *x, uint64_t *y)
|
||||||
|
+{
|
||||||
|
+ uint64_t mask = (uint64_t)0xFFFFFFFFFFFFFFFFU;
|
||||||
|
+ KRML_MAYBE_FOR9(i,
|
||||||
|
+ (uint32_t)0U,
|
||||||
|
+ (uint32_t)9U,
|
||||||
|
+ (uint32_t)1U,
|
||||||
|
+ uint64_t uu____0 = FStar_UInt64_eq_mask(x[i], y[i]);
|
||||||
|
+ mask = uu____0 & mask;);
|
||||||
|
+ uint64_t mask1 = mask;
|
||||||
|
+ return mask1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline uint64_t
|
||||||
|
+bn_sub(uint64_t *a, uint64_t *b, uint64_t *c)
|
||||||
|
+{
|
||||||
|
+ uint64_t c1 = (uint64_t)0U;
|
||||||
|
+ KRML_MAYBE_FOR2(i,
|
||||||
|
+ (uint32_t)0U,
|
||||||
|
+ (uint32_t)2U,
|
||||||
|
+ (uint32_t)1U,
|
||||||
|
+ uint64_t t1 = b[(uint32_t)4U * i];
|
||||||
|
+ uint64_t t20 = c[(uint32_t)4U * i];
|
||||||
|
+ uint64_t *res_i0 = a + (uint32_t)4U * i;
|
||||||
|
+ c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t1, t20, res_i0);
|
||||||
|
+ uint64_t t10 = b[(uint32_t)4U * i + (uint32_t)1U];
|
||||||
|
+ uint64_t t21 = c[(uint32_t)4U * i + (uint32_t)1U];
|
||||||
|
+ uint64_t *res_i1 = a + (uint32_t)4U * i + (uint32_t)1U;
|
||||||
|
+ c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t10, t21, res_i1);
|
||||||
|
+ uint64_t t11 = b[(uint32_t)4U * i + (uint32_t)2U];
|
||||||
|
+ uint64_t t22 = c[(uint32_t)4U * i + (uint32_t)2U];
|
||||||
|
+ uint64_t *res_i2 = a + (uint32_t)4U * i + (uint32_t)2U;
|
||||||
|
+ c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t11, t22, res_i2);
|
||||||
|
+ uint64_t t12 = b[(uint32_t)4U * i + (uint32_t)3U];
|
||||||
|
+ uint64_t t2 = c[(uint32_t)4U * i + (uint32_t)3U];
|
||||||
|
+ uint64_t *res_i = a + (uint32_t)4U * i + (uint32_t)3U;
|
||||||
|
+ c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t12, t2, res_i););
|
||||||
|
+ {
|
||||||
|
+ uint64_t t1 = b[8U];
|
||||||
|
+ uint64_t t2 = c[8U];
|
||||||
|
+ uint64_t *res_i = a + (uint32_t)8U;
|
||||||
|
+ c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t1, t2, res_i);
|
||||||
|
+ }
|
||||||
|
+ uint64_t c10 = c1;
|
||||||
|
+ return c10;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void
|
||||||
|
+bn_from_bytes_be(uint64_t *a, uint8_t *b)
|
||||||
|
+{
|
||||||
|
+ uint8_t tmp[72U] = { 0U };
|
||||||
|
+ memcpy(tmp + (uint32_t)6U, b, (uint32_t)66U * sizeof(uint8_t));
|
||||||
|
+ KRML_MAYBE_FOR9(i,
|
||||||
|
+ (uint32_t)0U,
|
||||||
|
+ (uint32_t)9U,
|
||||||
|
+ (uint32_t)1U,
|
||||||
|
+ uint64_t *os = a;
|
||||||
|
+ uint64_t u = load64_be(tmp + ((uint32_t)9U - i - (uint32_t)1U) * (uint32_t)8U);
|
||||||
|
+ uint64_t x = u;
|
||||||
|
+ os[i] = x;);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void
|
||||||
|
+p521_make_order(uint64_t *n)
|
||||||
|
+{
|
||||||
|
+ n[0U] = (uint64_t)0xbb6fb71e91386409U;
|
||||||
|
+ n[1U] = (uint64_t)0x3bb5c9b8899c47aeU;
|
||||||
|
+ n[2U] = (uint64_t)0x7fcc0148f709a5d0U;
|
||||||
|
+ n[3U] = (uint64_t)0x51868783bf2f966bU;
|
||||||
|
+ n[4U] = (uint64_t)0xfffffffffffffffaU;
|
||||||
|
+ n[5U] = (uint64_t)0xffffffffffffffffU;
|
||||||
|
+ n[6U] = (uint64_t)0xffffffffffffffffU;
|
||||||
|
+ n[7U] = (uint64_t)0xffffffffffffffffU;
|
||||||
|
+ n[8U] = (uint64_t)0x1ffU;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+Private key validation.
|
||||||
|
+
|
||||||
|
+ The function returns `true` if a private key is valid and `false` otherwise.
|
||||||
|
+
|
||||||
|
+ The argument `private_key` points to 66 bytes of valid memory, i.e., uint8_t[66].
|
||||||
|
+
|
||||||
|
+ The private key is valid:
|
||||||
|
+ • 0 < `private_key` < the order of the curve
|
||||||
|
+*/
|
||||||
|
+bool
|
||||||
|
+Hacl_P521_validate_private_key(uint8_t *private_key)
|
||||||
|
+{
|
||||||
|
+ uint64_t bn_sk[9U] = { 0U };
|
||||||
|
+ bn_from_bytes_be(bn_sk, private_key);
|
||||||
|
+ uint64_t tmp[9U] = { 0U };
|
||||||
|
+ p521_make_order(tmp);
|
||||||
|
+ uint64_t c = bn_sub(tmp, bn_sk, tmp);
|
||||||
|
+ uint64_t is_lt_order = (uint64_t)0U - c;
|
||||||
|
+ uint64_t bn_zero[9U] = { 0U };
|
||||||
|
+ uint64_t res = bn_is_eq_mask(bn_sk, bn_zero);
|
||||||
|
+ uint64_t is_eq_zero = res;
|
||||||
|
+ uint64_t res0 = is_lt_order & ~is_eq_zero;
|
||||||
|
+ return res0 == (uint64_t)0xFFFFFFFFFFFFFFFFU;
|
||||||
|
+}
|
||||||
|
diff -up ./lib/freebl/verified/Hacl_P521.h.p384 ./lib/freebl/verified/Hacl_P521.h
|
||||||
|
--- ./lib/freebl/verified/Hacl_P521.h.p384 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
+++ ./lib/freebl/verified/Hacl_P521.h 2024-01-09 11:49:58.651418444 -0800
|
||||||
|
@@ -0,0 +1,59 @@
|
||||||
|
+/* MIT License
|
||||||
|
+ *
|
||||||
|
+ * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation
|
||||||
|
+ * Copyright (c) 2022-2023 HACL* Contributors
|
||||||
|
+ *
|
||||||
|
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
+ * of this software and associated documentation files (the "Software"), to deal
|
||||||
|
+ * in the Software without restriction, including without limitation the rights
|
||||||
|
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
+ * copies of the Software, and to permit persons to whom the Software is
|
||||||
|
+ * furnished to do so, subject to the following conditions:
|
||||||
|
+ *
|
||||||
|
+ * The above copyright notice and this permission notice shall be included in all
|
||||||
|
+ * copies or substantial portions of the Software.
|
||||||
|
+ *
|
||||||
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
+ * SOFTWARE.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef __Hacl_P521_H
|
||||||
|
+#define __Hacl_P521_H
|
||||||
|
+
|
||||||
|
+#if defined(__cplusplus)
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#include <string.h>
|
||||||
|
+#include "krml/internal/types.h"
|
||||||
|
+#include "krml/lowstar_endianness.h"
|
||||||
|
+
|
||||||
|
+#include "lib_intrinsics.h"
|
||||||
|
+
|
||||||
|
+/******************/
|
||||||
|
+/* Key validation */
|
||||||
|
+/******************/
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+Private key validation.
|
||||||
|
+
|
||||||
|
+ The function returns `true` if a private key is valid and `false` otherwise.
|
||||||
|
+
|
||||||
|
+ The argument `private_key` points to 66 bytes of valid memory, i.e., uint8_t[66].
|
||||||
|
+
|
||||||
|
+ The private key is valid:
|
||||||
|
+ • 0 < `private_key` < the order of the curve
|
||||||
|
+*/
|
||||||
|
+bool Hacl_P521_validate_private_key(uint8_t *private_key);
|
||||||
|
+
|
||||||
|
+#if defined(__cplusplus)
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define __Hacl_P521_H_DEFINED
|
||||||
|
+#endif
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue