]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Expose and report EC curve field degrees
authorViktor Dukhovni <openssl-users@dukhovni.org>
Sat, 3 Jan 2026 06:36:40 +0000 (17:36 +1100)
committerAlexandr Nedvedicky <sashan@openssl.org>
Thu, 15 Jan 2026 16:10:12 +0000 (17:10 +0100)
Expose the EC field degree as a gettable parameter for both provided
and legacy EC keys.  In the latter case, drop a spurious assertion,
since even in debug builds an application may try to get an unknown
parameter, and this should return an error rather than abort.

In the EC `TEXT` encoding format, instead of reporting the bit count of
the group order, report the field degree (which matches the size number
in the curve's name when present) and also the symmetric-equivalent
security-bits (adjusted down the the standard numbers (80, 112, 128,
192, 256).

Along the way, add a missing getter method for the EC_GROUP security
bits.

Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
MergeDate: Thu Jan 15 16:10:26 2026
(Merged from https://github.com/openssl/openssl/pull/29539)

13 files changed:
crypto/ec/ec_ameth.c
crypto/ec/ec_lib.c
crypto/evp/ctrl_params_translate.c
doc/man3/EC_GROUP_copy.pod
doc/man7/EVP_PKEY-EC.pod
include/openssl/ec.h
providers/implementations/encode_decode/encode_key2text.c
providers/implementations/keymgmt/ec_kmgmt.c
test/ectest.c
test/recipes/30-test_evp_pkey_provided/EC.priv.txt
test/recipes/30-test_evp_pkey_provided/EC.pub.txt
util/libcrypto.num
util/perl/OpenSSL/paramnames.pm

index 541d9936e553b73909c3ccc91e37f8cd46edbf28..f25f5d80d6600cb66cf785eb5058a0e60e9a4c81 100644 (file)
@@ -214,19 +214,7 @@ static int ec_bits(const EVP_PKEY *pkey)
 
 static int ec_security_bits(const EVP_PKEY *pkey)
 {
-    int ecbits = ec_bits(pkey);
-
-    if (ecbits >= 512)
-        return 256;
-    if (ecbits >= 384)
-        return 192;
-    if (ecbits >= 256)
-        return 128;
-    if (ecbits >= 224)
-        return 112;
-    if (ecbits >= 160)
-        return 80;
-    return ecbits / 2;
+    return EC_GROUP_security_bits(EC_KEY_get0_group(pkey->pkey.ec));
 }
 
 static int ec_missing_parameters(const EVP_PKEY *pkey)
index 13dcd29b115cb7cfb969716d0e04a5f93463c43f..b041ecd0f722544a819220548b4fe3a07147909a 100644 (file)
@@ -465,10 +465,36 @@ int EC_GROUP_order_bits(const EC_GROUP *group)
     return group->meth->group_order_bits(group);
 }
 
+int EC_GROUP_security_bits(const EC_GROUP *group)
+{
+    int ecbits = group->meth->group_order_bits(group);
+
+    /*
+     * The following estimates are based on the values published in Table 2 of
+     * "NIST Special Publication 800-57 Part 1 Revision 4" at
+     * http://dx.doi.org/10.6028/NIST.SP.800-57pt1r4 .
+     *
+     * Note that the above reference explicitly categorizes algorithms in a
+     * discrete set of values {80, 112, 128, 192, 256}, and that it is relevant
+     * only for NIST approved Elliptic Curves, while OpenSSL applies the same
+     * logic also to other curves.
+     */
+    if (ecbits >= 512)
+        return 256;
+    if (ecbits >= 384)
+        return 192;
+    if (ecbits >= 256)
+        return 128;
+    if (ecbits >= 224)
+        return 112;
+    if (ecbits >= 160)
+        return 80;
+    return ecbits / 2;
+}
+
 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
     BN_CTX *ctx)
 {
-
     if (group->cofactor == NULL)
         return 0;
     if (!BN_copy(cofactor, group->cofactor))
index 5371e21fc4cb410267f15f76e713776b3cd4bb18..0ab5ce1257418dcb58d47f85f08e51142be3c7d0 100644 (file)
@@ -1833,6 +1833,36 @@ static int get_ec_decoded_from_explicit_params(enum state state,
     return get_payload_int(state, translation, ctx, val);
 }
 
+static int get_ec_field_degree(enum state state,
+    const struct translation_st *translation,
+    struct translation_ctx_st *ctx)
+{
+#ifndef OPENSSL_NO_EC
+    const EC_KEY *key;
+    const EC_GROUP *group;
+#endif
+    EVP_PKEY *pkey = ctx->p2;
+    int val = 0;
+
+    switch (EVP_PKEY_base_id(pkey)) {
+#ifndef OPENSSL_NO_EC
+    case EVP_PKEY_EC:
+        if ((key = EVP_PKEY_get0_EC_KEY(pkey)) == NULL
+            || (group = EC_KEY_get0_group(key)) == NULL) {
+            ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY);
+            return 0;
+        }
+        val = EC_GROUP_get_degree(group);
+        break;
+#endif
+    default:
+        ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE);
+        return 0;
+    }
+
+    return get_payload_int(state, translation, ctx, val);
+}
+
 static int get_rsa_payload_n(enum state state,
     const struct translation_st *translation,
     struct translation_ctx_st *ctx)
@@ -2568,6 +2598,9 @@ static const struct translation_st evp_pkey_translations[] = {
     { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
         OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, OSSL_PARAM_INTEGER,
         get_ec_decoded_from_explicit_params },
+    { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
+        OSSL_PKEY_PARAM_EC_FIELD_DEGREE, OSSL_PARAM_INTEGER,
+        get_ec_field_degree },
 };
 
 static const struct translation_st *
@@ -2935,7 +2968,7 @@ static int evp_pkey_setget_params_to_ctrl(const EVP_PKEY *pkey,
          * on fixup_args to do the whole work.  Also, we currently only
          * support getting.
          */
-        if (!ossl_assert(translation != NULL)
+        if (translation == NULL
             || !ossl_assert(translation->action_type == OSSL_ACTION_GET)
             || !ossl_assert(translation->fixup_args != NULL)) {
             return -2;
index e525fad0bf6b332260bf241c46e15f01b4eec2fd..da2fa498387cb065ec505e8daf02885b77334941 100644 (file)
@@ -2,18 +2,17 @@
 
 =head1 NAME
 
-EC_GROUP_get0_order, EC_GROUP_order_bits, EC_GROUP_get0_cofactor,
-EC_GROUP_copy, EC_GROUP_dup, EC_GROUP_method_of, EC_GROUP_set_generator,
-EC_GROUP_get0_generator, EC_GROUP_get_order, EC_GROUP_get_cofactor,
-EC_GROUP_set_curve_name, EC_GROUP_get_curve_name, EC_GROUP_set_asn1_flag,
-EC_GROUP_get_asn1_flag, EC_GROUP_set_point_conversion_form,
-EC_GROUP_get_point_conversion_form, EC_GROUP_get0_seed,
-EC_GROUP_get_seed_len, EC_GROUP_set_seed, EC_GROUP_get_degree,
-EC_GROUP_check, EC_GROUP_check_named_curve,
-EC_GROUP_check_discriminant, EC_GROUP_cmp,
-EC_GROUP_get_basis_type, EC_GROUP_get_trinomial_basis,
-EC_GROUP_get_pentanomial_basis, EC_GROUP_get0_field,
-EC_GROUP_get_field_type
+EC_GROUP_get0_order, EC_GROUP_order_bits, EC_GROUP_security_bits,
+EC_GROUP_get0_cofactor, EC_GROUP_copy, EC_GROUP_dup, EC_GROUP_method_of,
+EC_GROUP_set_generator, EC_GROUP_get0_generator, EC_GROUP_get_order,
+EC_GROUP_get_cofactor, EC_GROUP_set_curve_name, EC_GROUP_get_curve_name,
+EC_GROUP_set_asn1_flag, EC_GROUP_get_asn1_flag,
+EC_GROUP_set_point_conversion_form, EC_GROUP_get_point_conversion_form,
+EC_GROUP_get0_seed, EC_GROUP_get_seed_len, EC_GROUP_set_seed,
+EC_GROUP_get_degree, EC_GROUP_check, EC_GROUP_check_named_curve,
+EC_GROUP_check_discriminant, EC_GROUP_cmp, EC_GROUP_get_basis_type,
+EC_GROUP_get_trinomial_basis, EC_GROUP_get_pentanomial_basis,
+EC_GROUP_get0_field, EC_GROUP_get_field_type
 - Functions for manipulating EC_GROUP objects
 
 =head1 SYNOPSIS
@@ -30,6 +29,7 @@ EC_GROUP_get_field_type
  int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
  const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group);
  int EC_GROUP_order_bits(const EC_GROUP *group);
+ int EC_GROUP_security_bits(const EC_GROUP *group);
  int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
  const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group);
  const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group);
@@ -223,6 +223,8 @@ EC_GROUP_check_named_curve() returns the nid of the matching named curve, otherw
 
 EC_GROUP_get0_order() returns an internal pointer to the group order.
 EC_GROUP_order_bits() returns the number of bits in the group order.
+EC_GROUP_security_bits() returns the symmetric-equivalent security bit count of the group,
+rounding down to the standard sizes (80, 112, 128, 192, 256) when the value is at least 80.
 EC_GROUP_get0_cofactor() returns an internal pointer to the group cofactor.
 EC_GROUP_get0_field() returns an internal pointer to the group field. For curves over GF(p), this is the modulus; for curves
 over GF(2^m), this is the irreducible polynomial defining the field.
@@ -250,6 +252,8 @@ EC_GROUP_method_of() was deprecated in OpenSSL 3.0.
 EC_GROUP_get0_field(), EC_GROUP_check_named_curve() and EC_GROUP_get_field_type() were added in OpenSSL 3.0.
 EC_GROUP_get0_order(), EC_GROUP_order_bits() and EC_GROUP_get0_cofactor() were added in OpenSSL 1.1.0.
 
+EC_GROUP_security_bits() was added in OpenSSL 4.0.
+
 =head1 COPYRIGHT
 
 Copyright 2013-2023 The OpenSSL Project Authors. All Rights Reserved.
index 25177aa2dae8e1946634c592f0e53cef906210c0..5822e21088bb233bba941c7b02c3f0eb8ae62237 100644 (file)
@@ -161,6 +161,15 @@ The following Gettable types are also available for the built-in EC algorithm:
 
 =over 4
 
+=item "field-degree" (B<OSSL_PKEY_PARAM_EC_FIELD_DEGREE>) <integer>
+
+This is the bit length of the curve's field coefficients.
+It coincides with the B<OSSL_PKEY_PARAM_EC_CHAR2_M> parameter for binary
+fields, and is otherwise (for prime fields) equal to the bit length of the
+field's characteristic.
+For most curves (e.g. C<secp160r1>) this number is embedded in the curve's
+name.
+
 =item "basis-type" (B<OSSL_PKEY_PARAM_EC_CHAR2_TYPE>) <UTF8 string>
 
 Supports the values "tpBasis" for a trinomial or "ppBasis" for a pentanomial.
@@ -194,7 +203,8 @@ OpenSSL FIPS provider's EC algorithm:
 
 =item "key-check" (B<OSSL_PKEY_PARAM_FIPS_KEY_CHECK>) <integer>
 
-See L<provider-keymgmt(7)/Common Information Parameters> for further information.
+See L<provider-keymgmt(7)/Common Information Parameters> for descriptions
+of additional parameters generally available across all algorithms.
 
 =back
 
@@ -300,6 +310,10 @@ L<provider-keymgmt(7)>,
 L<EVP_SIGNATURE-ECDSA(7)>,
 L<EVP_KEYEXCH-ECDH(7)>
 
+=head1 HISTORY
+
+The B<OSSL_PKEY_PARAM_EC_FIELD_DEGREE> parameter was added in OpenSSL 4.0.
+
 =head1 COPYRIGHT
 
 Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
index 4ea2c363214b83e627088c6143c90c1b08221773..3d8b681d711e0e413b4b4a6373340de5a6eb3f05 100644 (file)
@@ -253,6 +253,14 @@ const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group);
  */
 int EC_GROUP_order_bits(const EC_GROUP *group);
 
+/** Gets the symmetric-equivalent security bit size an EC_GROUP.
+ * This is rounded down to one of the standard sizes, (80, 112,
+ * 128, 192, 256) or reported as-is when smaller than 80.
+ *  \param  group  EC_GROUP object
+ *  \return symmetric-equivalent security bits.
+ */
+int EC_GROUP_security_bits(const EC_GROUP *group);
+
 /** Gets the cofactor of a EC_GROUP
  *  \param  group     EC_GROUP object
  *  \param  cofactor  BIGNUM to which the cofactor is copied
index 026929275c3a5b212b738f43a9e9e2b3273a6fd7..e87532a75da302f9edad15baa30d4acadf6e5faa 100644 (file)
@@ -362,8 +362,9 @@ static int ec_to_text(BIO *out, const void *key, int selection)
     }
 
     if (type_label != NULL
-        && BIO_printf(out, "%s: (%d bit)\n", type_label,
-               EC_GROUP_order_bits(group))
+        && BIO_printf(out, "%s: (%d bit field, %d bit security level)\n",
+               type_label, EC_GROUP_get_degree(group),
+               EC_GROUP_security_bits(group))
             <= 0)
         goto err;
     if (priv != NULL
index cc3cf75cd8082f02ae8d0912a2df94417bd85281..b54f69df511099b7752530d6ab5a150c2a2e66ef 100644 (file)
@@ -647,43 +647,12 @@ static int common_get_params(void *key, OSSL_PARAM params[], int sm2)
     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
         && !OSSL_PARAM_set_int(p, EC_GROUP_order_bits(ecg)))
         goto err;
-    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL) {
-        int ecbits, sec_bits;
-
-        ecbits = EC_GROUP_order_bits(ecg);
-
-        /*
-         * The following estimates are based on the values published
-         * in Table 2 of "NIST Special Publication 800-57 Part 1 Revision 4"
-         * at http://dx.doi.org/10.6028/NIST.SP.800-57pt1r4 .
-         *
-         * Note that the above reference explicitly categorizes algorithms in a
-         * discrete set of values {80, 112, 128, 192, 256}, and that it is
-         * relevant only for NIST approved Elliptic Curves, while OpenSSL
-         * applies the same logic also to other curves.
-         *
-         * Classifications produced by other standardazing bodies might differ,
-         * so the results provided for "bits of security" by this provider are
-         * to be considered merely indicative, and it is the users'
-         * responsibility to compare these values against the normative
-         * references that may be relevant for their intent and purposes.
-         */
-        if (ecbits >= 512)
-            sec_bits = 256;
-        else if (ecbits >= 384)
-            sec_bits = 192;
-        else if (ecbits >= 256)
-            sec_bits = 128;
-        else if (ecbits >= 224)
-            sec_bits = 112;
-        else if (ecbits >= 160)
-            sec_bits = 80;
-        else
-            sec_bits = ecbits / 2;
-
-        if (!OSSL_PARAM_set_int(p, sec_bits))
-            goto err;
-    }
+    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_FIELD_DEGREE)) != NULL
+        && !OSSL_PARAM_set_int(p, EC_GROUP_get_degree(ecg)))
+        goto err;
+    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
+        && !OSSL_PARAM_set_int(p, EC_GROUP_security_bits(ecg)))
+        goto err;
     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_CATEGORY)) != NULL)
         if (!OSSL_PARAM_set_int(p, 0))
             goto err;
@@ -768,6 +737,7 @@ static int ec_get_params(void *key, OSSL_PARAM params[])
 
 static const OSSL_PARAM ec_known_gettable_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
+    OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_FIELD_DEGREE, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_CATEGORY, NULL),
@@ -844,6 +814,7 @@ static int sm2_get_params(void *key, OSSL_PARAM params[])
 
 static const OSSL_PARAM sm2_known_gettable_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
+    OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_FIELD_DEGREE, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
     OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),
index 9b1c911b5bfa07ba006bf8bffb42bf1f8e4e1c95..9fca45bad450d07d6ebf59195d29fcbfb729ffb2 100644 (file)
@@ -306,6 +306,7 @@ static int prime_field_tests(void)
                                  "3168947d59dcc912042351377ac5fb32"))
         || !TEST_BN_eq(y, z)
         || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
+        || !TEST_int_eq(EC_GROUP_security_bits(group), 80)
         || !group_order_tests(group)
 
         /* Curve P-192 (FIPS PUB 186-2, App. 6) */
@@ -343,6 +344,7 @@ static int prime_field_tests(void)
         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
             ctx))
         || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
+        || !TEST_int_eq(EC_GROUP_security_bits(group), 80)
         || !group_order_tests(group)
 
         /* Curve P-224 (FIPS PUB 186-2, App. 6) */
@@ -380,6 +382,7 @@ static int prime_field_tests(void)
         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
             ctx))
         || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
+        || !TEST_int_eq(EC_GROUP_security_bits(group), 112)
         || !group_order_tests(group)
 
         /* Curve P-256 (FIPS PUB 186-2, App. 6) */
@@ -418,6 +421,7 @@ static int prime_field_tests(void)
         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
             ctx))
         || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
+        || !TEST_int_eq(EC_GROUP_security_bits(group), 128)
         || !group_order_tests(group)
 
         /* Curve P-384 (FIPS PUB 186-2, App. 6) */
@@ -462,6 +466,7 @@ static int prime_field_tests(void)
         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
             ctx))
         || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
+        || !TEST_int_eq(EC_GROUP_security_bits(group), 192)
         || !group_order_tests(group)
 
         /* Curve P-521 (FIPS PUB 186-2, App. 6) */
@@ -516,6 +521,7 @@ static int prime_field_tests(void)
         || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
             ctx))
         || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
+        || !TEST_int_eq(EC_GROUP_security_bits(group), 256)
         || !group_order_tests(group)
 
         /* more tests using the last curve */
@@ -612,6 +618,7 @@ static struct c2_curve_test {
     const char *order;
     const char *cof;
     int degree;
+    int security;
 } char2_curve_tests[] = {
     /* Curve K-163 (FIPS PUB 186-2, App. 6) */
     {
@@ -621,7 +628,7 @@ static struct c2_curve_test {
         "1",
         "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
         "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
-        1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163 },
+        1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163, 80 },
     /* Curve B-163 (FIPS PUB 186-2, App. 6) */
     {
         "NIST curve B-163",
@@ -630,7 +637,7 @@ static struct c2_curve_test {
         "020A601907B8C953CA1481EB10512F78744A3205FD",
         "03F0EBA16286A2D57EA0991168D4994637E8343E36",
         "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
-        1, "040000000000000000000292FE77E70C12A4234C33", "2", 163 },
+        1, "040000000000000000000292FE77E70C12A4234C33", "2", 163, 80 },
     /* Curve K-233 (FIPS PUB 186-2, App. 6) */
     {
         "NIST curve K-233",
@@ -641,7 +648,7 @@ static struct c2_curve_test {
         "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
         0,
         "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
-        "4", 233 },
+        "4", 233, 112 },
     /* Curve B-233 (FIPS PUB 186-2, App. 6) */
     {
         "NIST curve B-233",
@@ -652,7 +659,7 @@ static struct c2_curve_test {
         "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
         1,
         "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
-        "2", 233 },
+        "2", 233, 112 },
     /* Curve K-283 (FIPS PUB 186-2, App. 6) */
     {
         "NIST curve K-283",
@@ -667,7 +674,7 @@ static struct c2_curve_test {
         0,
         "01FFFFFF"
         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
-        "4", 283 },
+        "4", 283, 128 },
     /* Curve B-283 (FIPS PUB 186-2, App. 6) */
     {
         "NIST curve B-283",
@@ -684,7 +691,7 @@ static struct c2_curve_test {
         1,
         "03FFFFFF"
         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
-        "2", 283 },
+        "2", 283, 128 },
     /* Curve K-409 (FIPS PUB 186-2, App. 6) */
     {
         "NIST curve K-409",
@@ -699,7 +706,7 @@ static struct c2_curve_test {
         1,
         "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
         "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
-        "4", 409 },
+        "4", 409, 192 },
     /* Curve B-409 (FIPS PUB 186-2, App. 6) */
     {
         "NIST curve B-409",
@@ -716,7 +723,7 @@ static struct c2_curve_test {
         1,
         "0100000000000000000000000000000000000000"
         "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
-        "2", 409 },
+        "2", 409, 192 },
     /* Curve K-571 (FIPS PUB 186-2, App. 6) */
     {
         "NIST curve K-571",
@@ -735,7 +742,7 @@ static struct c2_curve_test {
         "0200000000000000"
         "00000000000000000000000000000000000000000000000000000000131850E1"
         "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
-        "4", 571 },
+        "4", 571, 256 },
     /* Curve B-571 (FIPS PUB 186-2, App. 6) */
     {
         "NIST curve B-571",
@@ -758,7 +765,7 @@ static struct c2_curve_test {
         "03FFFFFFFFFFFFFF"
         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
         "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
-        "2", 571 }
+        "2", 571, 256 }
 };
 
 static int char2_curve_test(int n)
@@ -836,6 +843,7 @@ static int char2_curve_test(int n)
 #endif
 
     if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
+        || !TEST_int_eq(EC_GROUP_security_bits(group), test->security)
         || !group_order_tests(group))
         goto err;
 
@@ -1183,6 +1191,7 @@ static int group_field_test(void)
 struct nistp_test_params {
     const int nid;
     int degree;
+    int security;
     /*
      * Qx, Qy and D are taken from
      * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
@@ -1196,6 +1205,7 @@ static const struct nistp_test_params nistp_tests_params[] = {
         /* P-224 */
         NID_secp224r1,
         224,
+        112,
         /* p */
         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
         /* a */
@@ -1219,6 +1229,7 @@ static const struct nistp_test_params nistp_tests_params[] = {
         /* P-256 */
         NID_X9_62_prime256v1,
         256,
+        128,
         /* p */
         "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
         /* a */
@@ -1242,6 +1253,7 @@ static const struct nistp_test_params nistp_tests_params[] = {
         /* P-521 */
         NID_secp521r1,
         521,
+        256,
         /* p */
         "1ff"
         "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
@@ -1330,7 +1342,8 @@ static int nistp_single_test(int idx)
         || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
         || !TEST_true(BN_hex2bn(&order, test->order))
         || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
-        || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
+        || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree)
+        || !TEST_int_eq(EC_GROUP_security_bits(NISTP), test->security))
         goto err;
 
     TEST_note("NIST test vectors ... ");
@@ -3003,6 +3016,11 @@ static int do_test_custom_explicit_fromdata(EC_GROUP *group, BN_CTX *ctx,
             goto err;
     }
 
+    if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam,
+            OSSL_PKEY_PARAM_EC_FIELD_DEGREE, &i_out))
+        || !TEST_int_eq(EC_GROUP_get_degree(group), i_out))
+        goto err;
+
     if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) {
         /* No extra fields should be set for a prime field */
         if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam,
@@ -3493,7 +3511,7 @@ static int ec_d2i_publickey_test(void)
     const unsigned char *pk_enc = pubkey_enc;
     EVP_PKEY *gen_key = NULL, *decoded_key = NULL;
     EVP_PKEY_CTX *pctx = NULL;
-    int pklen, ret = 0;
+    int pklen, i_out = 0, ret = 0;
     OSSL_PARAM params[2];
 
     if (!TEST_ptr(gen_key = EVP_EC_gen("P-256")))
@@ -3516,8 +3534,15 @@ static int ec_d2i_publickey_test(void)
                          &pk_enc, pklen)))
         goto err;
 
-    if (!TEST_true(EVP_PKEY_eq(gen_key, decoded_key)))
+    if (!TEST_true(EVP_PKEY_eq(gen_key, decoded_key))
+        || !TEST_true(EVP_PKEY_get_int_param(gen_key,
+            OSSL_PKEY_PARAM_EC_FIELD_DEGREE, &i_out))
+        || !TEST_int_eq(i_out, 256)
+        || !TEST_true(EVP_PKEY_get_int_param(decoded_key,
+            OSSL_PKEY_PARAM_EC_FIELD_DEGREE, &i_out))
+        || !TEST_int_eq(i_out, 256))
         goto err;
+
     ret = 1;
 
 err:
index 9df64554011e1ea7ae83769a4000b696586c7d06..84ca80606222c019462b673bfeaceac9c631f3f2 100644 (file)
@@ -1,4 +1,4 @@
-Private-Key: (256 bit)
+Private-Key: (256 bit field, 128 bit security level)
 priv:
     33:d0:43:83:a9:89:56:03:d2:d7:fe:6b:01:6f:e4:59:
     cc:0d:9a:24:6c:86:1b:2e:dc:4b:4d:35:43:e1:1b:ad
index c72473f72b8b645949a87e077f076ede668ca8dc..d8dec75adceb5ce162cbd43441ff0bdd1632e93c 100644 (file)
@@ -1,4 +1,4 @@
-Public-Key: (256 bit)
+Public-Key: (256 bit field, 128 bit security level)
 pub:
     04:1b:93:67:55:1c:55:9f:63:d1:22:a4:d8:d1:0a:60:
     6d:02:a5:77:57:c8:a3:47:73:3a:6a:08:28:39:bd:c9:
index c01447b1775b78840ca768fe14d330d30a25e1eb..81cda111b7845d189c5fbf36216863d3a0773145 100644 (file)
@@ -617,6 +617,7 @@ EC_GROUP_get_mont_data                  ?   4_0_0   EXIST::FUNCTION:EC
 EC_GROUP_get_order                      ?      4_0_0   EXIST::FUNCTION:EC
 EC_GROUP_get0_order                     ?      4_0_0   EXIST::FUNCTION:EC
 EC_GROUP_order_bits                     ?      4_0_0   EXIST::FUNCTION:EC
+EC_GROUP_security_bits                  ?      4_0_0   EXIST::FUNCTION:EC
 EC_GROUP_get_cofactor                   ?      4_0_0   EXIST::FUNCTION:EC
 EC_GROUP_get0_cofactor                  ?      4_0_0   EXIST::FUNCTION:EC
 EC_GROUP_set_curve_name                 ?      4_0_0   EXIST::FUNCTION:EC
index 3a8cb6f1b10d798885db55469e7ab1b35ce5eacf..8473aa2b07501165f7726a0123dcb9a8aaeff419 100644 (file)
@@ -348,6 +348,7 @@ my %params = (
 
 # Elliptic Curve Explicit Domain Parameters
     'OSSL_PKEY_PARAM_EC_FIELD_TYPE' =>                   "field-type",
+    'OSSL_PKEY_PARAM_EC_FIELD_DEGREE' =>                 "field-degree",
     'OSSL_PKEY_PARAM_EC_P' =>                            "p",
     'OSSL_PKEY_PARAM_EC_A' =>                            "a",
     'OSSL_PKEY_PARAM_EC_B' =>                            "b",