]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
fips: mark EdDSA as approved in FIPS mode
authorpohsingwu <pohsingwu@synology.com>
Sat, 16 Nov 2024 18:01:37 +0000 (02:01 +0800)
committerpohsingwu <pohsingwu@synology.com>
Sat, 16 Nov 2024 19:19:15 +0000 (03:19 +0800)
FIPS 186-5 approves EdDSA.

Signed-off-by: Po-Hsing Wu <pohsingwu@synology.com>
lib/crypto-selftests-pk.c
lib/fips.c
lib/nettle/pk.c
tests/fips-test.c
tests/privkey-keygen.c

index 294d2b3e80b66b22ef417f94109a436a9b5c35bb..9d6aca4b490a83841e178d0072de7d1c161429d8 100644 (file)
@@ -224,6 +224,35 @@ static const char gost12_512_privkey[] =
        "hsQ3JCCy4xnd5jWT\n"
        "-----END PRIVATE KEY-----\n";
 
+/* ed25519 private key and signature */
+static const char eddsa_ed25519_privkey[] =
+       "-----BEGIN PRIVATE KEY-----\n"
+       "MC4CAQAwBQYDK2VwBCIEIH4WeqmZGZQlSY/8H85ZZimVd26h6I68gFNyBvyh3Vcy\n"
+       "-----END PRIVATE KEY-----\n";
+
+static const char eddsa_ed25519_sig[] =
+       "\xd1\xcb\x06\x1e\x22\xf2\xec\x56\xa6\xe6\xb3\x89\xb6\x1c\xcf\x13"
+       "\x95\x53\x3d\x12\x27\xea\x32\xfd\x5b\xe6\x5f\x24\xc9\xd0\xa9\x21"
+       "\x36\x63\x06\x20\xe4\xaf\xb1\x36\xc5\x21\x5c\xaa\xdc\x89\x62\xfa"
+       "\xc6\x4c\xea\x42\xd7\xd8\x39\x81\x46\x9f\x41\x09\x10\x94\x9f\x07";
+
+/* ed448 private key and signature */
+static const char eddsa_ed448_privkey[] =
+       "-----BEGIN PRIVATE KEY-----\n"
+       "MEcCAQAwBQYDK2VxBDsEOcUwM3PlIVddDpjHbTANVDGN82jtXJNMbq1oy5u5iJTe\n"
+       "dXGSbQ0e1N/7o1wIO+fKUR1G/CbcXu+XFQ==\n"
+       "-----END PRIVATE KEY-----\n";
+
+static const char eddsa_ed448_sig[] =
+       "\xe3\x13\x89\xef\x7d\x63\x93\xcf\x15\xfb\xe4\x98\x9d\x24\xec\x56"
+       "\xbe\xfc\xcd\xfd\xad\x54\xb3\x8b\xfb\x96\x1b\x08\xbe\xbe\xf0\xc4"
+       "\xff\x67\xf9\x3d\x57\x4a\x2e\x8c\x9c\x39\x83\x5b\x22\xab\x91\x1e"
+       "\x71\x23\x79\xba\x30\xaa\x6d\xbe\x80\xf7\xef\x59\xa5\x3b\xe3\xdf"
+       "\xba\x59\x29\xfe\xe2\xc5\xd2\xb4\xe4\xb5\x94\x2f\x2b\xad\xd9\x20"
+       "\xdc\x25\x75\xbb\xed\xc4\xdb\x72\x22\x6d\x79\x42\x27\xb3\xd9\x8c"
+       "\x80\x68\xd8\x75\x0c\x1c\x6a\xd7\x28\x01\x03\x29\xd0\x7e\x04\x65"
+       "\x2a\x00";
+
 static int test_rsa_enc(gnutls_pk_algorithm_t pk, unsigned bits,
                        gnutls_digest_algorithm_t dig)
 {
@@ -505,7 +534,8 @@ static int test_known_sig(gnutls_pk_algorithm_t pk, unsigned bits,
        unsigned vflags = 0;
 
        if (pk == GNUTLS_PK_EC || pk == GNUTLS_PK_GOST_01 ||
-           pk == GNUTLS_PK_GOST_12_256 || pk == GNUTLS_PK_GOST_12_512) {
+           pk == GNUTLS_PK_GOST_12_256 || pk == GNUTLS_PK_GOST_12_512 ||
+           pk == GNUTLS_PK_EDDSA_ED25519 || pk == GNUTLS_PK_EDDSA_ED448) {
                snprintf(param_name, sizeof(param_name), "%s",
                         gnutls_ecc_curve_get_name(GNUTLS_BITS_TO_CURVE(bits)));
                if (dig == GNUTLS_DIG_GOSTR_94)
@@ -1144,6 +1174,26 @@ int gnutls_pk_self_test(unsigned flags, gnutls_pk_algorithm_t pk)
                if (!(flags & GNUTLS_SELF_TEST_FLAG_ALL))
                        return 0;
 #endif
+               FALLTHROUGH;
+       case GNUTLS_PK_EDDSA_ED25519:
+               PK_KNOWN_TEST(GNUTLS_PK_EDDSA_ED25519,
+                             GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_ED25519),
+                             GNUTLS_DIG_SHA512, eddsa_ed25519_privkey,
+                             eddsa_ed25519_sig, 0);
+
+               if (!(flags & GNUTLS_SELF_TEST_FLAG_ALL))
+                       return 0;
+
+               FALLTHROUGH;
+       case GNUTLS_PK_EDDSA_ED448:
+               PK_KNOWN_TEST(GNUTLS_PK_EDDSA_ED448,
+                             GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_ED448),
+                             GNUTLS_DIG_SHAKE_256, eddsa_ed448_privkey,
+                             eddsa_ed448_sig, 0);
+
+               if (!(flags & GNUTLS_SELF_TEST_FLAG_ALL))
+                       return 0;
+
                break;
        default:
                return gnutls_assert_val(GNUTLS_E_NO_SELF_TEST);
index dc86a4435486214985838f230324e645653964b2..5e2c59638bca39857eed66e18edc3b9eb7ef19ce 100644 (file)
@@ -639,6 +639,16 @@ int _gnutls_fips_perform_self_checks2(void)
                return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
        }
 
+       ret = gnutls_pk_self_test(0, GNUTLS_PK_EDDSA_ED25519);
+       if (ret < 0) {
+               return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+       }
+
+       ret = gnutls_pk_self_test(0, GNUTLS_PK_EDDSA_ED448);
+       if (ret < 0) {
+               return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+       }
+
        ret = gnutls_pk_self_test(0, GNUTLS_PK_DH);
        if (ret < 0) {
                return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
index 00fa706b8dd0c245020cb58c59fbce5b3f9dd2ae..343c7bc4431271777879ce01bbf9150469603ce1 100644 (file)
@@ -1475,9 +1475,6 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
        case GNUTLS_PK_EDDSA_ED448: {
                const gnutls_ecc_curve_entry_st *e;
 
-               /* EdDSA is not approved yet */
-               not_approved = true;
-
                if (unlikely(get_eddsa_curve(algo) != pk_params->curve)) {
                        ret = gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
                        goto cleanup;
@@ -1955,9 +1952,6 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
        case GNUTLS_PK_EDDSA_ED448: {
                const gnutls_ecc_curve_entry_st *e;
 
-               /* EdDSA is not approved yet */
-               not_approved = true;
-
                if (unlikely(get_eddsa_curve(algo) != pk_params->curve)) {
                        ret = gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
                        goto cleanup;
@@ -3453,9 +3447,6 @@ wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo,
        case GNUTLS_PK_EDDSA_ED448: {
                unsigned size = gnutls_ecc_curve_get_size(level);
 
-               /* EdDSA is not approved yet */
-               not_approved = true;
-
                if (params->pkflags & GNUTLS_PK_FLAG_PROVABLE) {
                        ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                        goto cleanup;
index 4051d798ef5bb01184de64ba08ba6e13d673d6ba..3af4df7190ee66f003d8ead3bf34086298ced1a1 100644 (file)
@@ -761,6 +761,33 @@ void doit(void)
        gnutls_pubkey_deinit(pubkey);
        gnutls_privkey_deinit(privkey);
 
+       /* Import ED25519 key; not a security function */
+       FIPS_PUSH_CONTEXT();
+       import_keypair(&privkey, &pubkey, "ed25519.pem");
+       FIPS_POP_CONTEXT(INITIAL);
+
+       /* Create a signature with ED25519; approved */
+       FIPS_PUSH_CONTEXT();
+       ret = gnutls_privkey_sign_data2(privkey, GNUTLS_SIGN_EDDSA_ED25519, 0,
+                                       &data, &signature);
+       if (ret < 0) {
+               fail("gnutls_privkey_sign_data2 failed\n");
+       }
+       FIPS_POP_CONTEXT(APPROVED);
+
+       /* Verify a signature with ED25519; approved */
+       FIPS_PUSH_CONTEXT();
+       ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_EDDSA_ED25519, 0,
+                                        &data, &signature);
+       if (ret < 0) {
+               fail("gnutls_pubkey_verify_data2 failed\n");
+       }
+       FIPS_POP_CONTEXT(APPROVED);
+       gnutls_free(signature.data);
+
+       gnutls_pubkey_deinit(pubkey);
+       gnutls_privkey_deinit(privkey);
+
        /* Test RND functions */
        FIPS_PUSH_CONTEXT();
        ret = gnutls_rnd(GNUTLS_RND_RANDOM, key16, sizeof(key16));
index 1eea0a473cd182ad38ec3d0f83498f81a3be7cdf..2af60e27ca5f237e6ff5ebca5ac0c1414199ef42 100644 (file)
@@ -111,6 +111,8 @@ static bool is_approved_pk_algo(gnutls_pk_algorithm_t algo)
        case GNUTLS_PK_RSA_PSS:
        case GNUTLS_PK_RSA_OAEP:
        case GNUTLS_PK_EC:
+       case GNUTLS_PK_EDDSA_ED25519:
+       case GNUTLS_PK_EDDSA_ED448:
                return true;
        default:
                return false;