]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
New function EC_GROUP_to_params to convert an EC_GROUP to an array of OSSL_PARAM.
authorOliver Mihatsch <oliver.mihatsch@virtual-solution.com>
Thu, 2 Feb 2023 11:15:14 +0000 (12:15 +0100)
committerTodd Short <todd.short@me.com>
Wed, 8 Feb 2023 15:27:07 +0000 (10:27 -0500)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Todd Short <todd.short@me.com>
(Merged from https://github.com/openssl/openssl/pull/20205)

CHANGES.md
crypto/ec/ec_lib.c
doc/man3/EC_GROUP_new.pod
include/openssl/ec.h
test/ectest.c
util/libcrypto.num

index 1f76a23d2f684fe603b87361ff1c9420835b1434..77a053a425a5d7bd4428ca01cbfc9c8bb0ecd2e1 100644 (file)
@@ -25,6 +25,11 @@ OpenSSL 3.2
 
 ### Changes between 3.1 and 3.2 [xx XXX xxxx]
 
+ * Added EC_GROUP_to_params which creates an OSSL_PARAM array
+   from a given EC_GROUP.
+
+   *Oliver Mihatsch*
+
  * Added support for Hybrid Public Key Encryption (HPKE) as defined
    in RFC9180. HPKE is required for TLS Encrypted ClientHello (ECH),
    Message Layer Security (MLS) and other IETF specifications.
index 2e7139cbdda387bb01137417e0ffd85fe60bb142..9e262b427d3a947b55e5c2233776c9e23c2feb29 100644 (file)
@@ -19,6 +19,7 @@
 #include <openssl/core_names.h>
 #include <openssl/err.h>
 #include <openssl/opensslv.h>
+#include <openssl/param_build.h>
 #include "crypto/ec.h"
 #include "internal/nelem.h"
 #include "ec_local.h"
@@ -1748,3 +1749,38 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
     return group;
 #endif /* FIPS_MODULE */
 }
+
+OSSL_PARAM *EC_GROUP_to_params(const EC_GROUP *group, OSSL_LIB_CTX *libctx,
+                               const char *propq, BN_CTX *bnctx)
+{
+    OSSL_PARAM_BLD *tmpl = NULL;
+    BN_CTX *new_bnctx = NULL;
+    unsigned char *gen_buf = NULL;
+    OSSL_PARAM *params = NULL;
+
+    if (group == NULL)
+        goto err;
+
+    tmpl = OSSL_PARAM_BLD_new();
+    if (tmpl == NULL)
+        goto err;
+
+    if (bnctx == NULL)
+        bnctx = new_bnctx = BN_CTX_new_ex(libctx);
+    if (bnctx == NULL)
+        goto err;
+    BN_CTX_start(bnctx);
+
+    if (!ossl_ec_group_todata(
+            group, tmpl, NULL, libctx, propq, bnctx, &gen_buf))
+        goto err;
+
+    params = OSSL_PARAM_BLD_to_param(tmpl);
+
+ err:
+    OSSL_PARAM_BLD_free(tmpl);
+    OPENSSL_free(gen_buf);
+    BN_CTX_end(bnctx);
+    BN_CTX_free(new_bnctx);
+    return params;
+}
index b6d67b6176422272ad69af21fa04da65f1963840..d7f8d001c263a6441120076962c010e75f2bd339 100644 (file)
@@ -5,6 +5,7 @@
 EC_GROUP_get_ecparameters,
 EC_GROUP_get_ecpkparameters,
 EC_GROUP_new_from_params,
+EC_GROUP_to_params,
 EC_GROUP_new_from_ecparameters,
 EC_GROUP_new_from_ecpkparameters,
 EC_GROUP_new,
@@ -30,6 +31,8 @@ Functions for creating and destroying EC_GROUP objects
 
  EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
                                     OSSL_LIB_CTX *libctx, const char *propq);
+ OSSL_PARAM *EC_GROUP_to_params(const EC_GROUP *group, OSSL_LIB_CTX *libctx,
+                                const char *propq, BN_CTX *bnctx);
  EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params);
  EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params);
  void EC_GROUP_free(EC_GROUP *group);
@@ -107,6 +110,16 @@ The values for I<ctx> and I<propq> may be NULL.
 The I<params> that can be used are described in
 L<B<EVP_PKEY-EC>(7)|EVP_PKEY-EC(7)/Common EC parameters>.
 
+EC_GROUP_to_params creates an OSSL_PARAM array with the corresponding parameters
+describing the given EC_GROUP. The resulting parameters may contain parameters
+describing a named or explicit curve depending on the EC_GROUP.
+The library context I<libctx> (see L<OSSL_LIB_CTX(3)>) and property query string
+I<propq> are used to fetch algorithms from providers.
+I<bnctx> is an optional preallocated BN_CTX (to save the overhead of allocating
+and freeing the structure in a loop).
+The values for I<libctx>, I<propq> and I<bnctx> may be NULL.
+The caller is responsible for freeing the OSSL_PARAM pointer returned.
+
 EC_GROUP_new_from_ecparameters() will create a group from the
 specified I<params> and
 EC_GROUP_new_from_ecpkparameters() will create a group from the specific PK
index be9fb2f08923e645bd78df94604b3ad389ac40ae..3089dfccd4d80ded5dad918fbada0643b8019469 100644 (file)
@@ -460,6 +460,22 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
 EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
                                    OSSL_LIB_CTX *libctx, const char *propq);
 
+/**
+ * Creates an OSSL_PARAM array with the parameters describing the given
+ * EC_GROUP.
+ * The resulting parameters may contain an explicit or a named curve depending
+ * on the EC_GROUP.
+ *  \param  group  pointer to the EC_GROUP object
+ *  \param  libctx The associated library context or NULL for the default
+ *                 context
+ *  \param  propq  A property query string
+ *  \param  bnctx  BN_CTX object (optional)
+ *  \return newly created OSSL_PARAM array with the parameters
+ *          describing the given EC_GROUP or NULL if an error occurred
+ */
+OSSL_PARAM *EC_GROUP_to_params(const EC_GROUP *group, OSSL_LIB_CTX *libctx,
+                               const char *propq, BN_CTX *bnctx);
+
 /**
  * Creates a EC_GROUP object with a curve specified by a NID
  *  \param  libctx The associated library context or NULL for the default
index c0337e1c9531a2276180404c763154882ee1a864..f93fd768114f0a02e24d04d32aea08c611ea2bc4 100644 (file)
@@ -2054,6 +2054,118 @@ err:
     return r;
 }
 
+/*
+ * This test validates converting an EC_GROUP to an OSSL_PARAM array
+ * using EC_GROUP_to_params(). A named and an explicit curve are tested.
+ */
+static int ossl_parameter_test(void)
+{
+    EC_GROUP *group_nmd = NULL, *group_nmd2 = NULL, *group_nmd3 = NULL;
+    EC_GROUP *group_exp = NULL, *group_exp2 = NULL;
+    OSSL_PARAM *params_nmd = NULL, *params_nmd2 = NULL;
+    OSSL_PARAM *params_exp = NULL, *params_exp2 = NULL;
+    unsigned char *buf = NULL, *buf2 = NULL;
+    BN_CTX *bn_ctx = NULL;
+    OSSL_PARAM_BLD *bld = NULL;
+    BIGNUM *p, *a, *b;
+    const EC_POINT *group_gen = NULL;
+    size_t bsize;
+    int r = 0;
+
+    if (!TEST_ptr(bn_ctx = BN_CTX_new()))
+        goto err;
+
+    /* test named curve */
+    if (!TEST_ptr(group_nmd = EC_GROUP_new_by_curve_name(NID_secp384r1))
+        /* test with null BN_CTX */
+        || !TEST_ptr(params_nmd = EC_GROUP_to_params(
+                group_nmd, NULL, NULL, NULL))
+        || !TEST_ptr(group_nmd2 = EC_GROUP_new_from_params(
+                params_nmd, NULL, NULL))
+        || !TEST_int_eq(EC_GROUP_cmp(group_nmd, group_nmd2, NULL), 0)
+        /* test with BN_CTX set */
+        || !TEST_ptr(params_nmd2 = EC_GROUP_to_params(
+                group_nmd, NULL, NULL, bn_ctx))
+        || !TEST_ptr(group_nmd3 = EC_GROUP_new_from_params(
+                params_nmd2, NULL, NULL))
+        || !TEST_int_eq(EC_GROUP_cmp(group_nmd, group_nmd3, NULL), 0))
+        goto err;
+
+    /* test explicit curve */
+    if (!TEST_ptr(bld = OSSL_PARAM_BLD_new()))
+        goto err;
+
+    BN_CTX_start(bn_ctx);
+    p = BN_CTX_get(bn_ctx);
+    a = BN_CTX_get(bn_ctx);
+    b = BN_CTX_get(bn_ctx);
+
+    if (!TEST_true(EC_GROUP_get_curve(group_nmd, p, a, b, bn_ctx))
+        || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(
+                bld, OSSL_PKEY_PARAM_EC_FIELD_TYPE, SN_X9_62_prime_field, 0))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, p))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b)))
+        goto err;
+
+    if (EC_GROUP_get0_seed(group_nmd) != NULL) {
+        if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(
+                bld, OSSL_PKEY_PARAM_EC_SEED, EC_GROUP_get0_seed(group_nmd),
+                EC_GROUP_get_seed_len(group_nmd))))
+            goto err;
+    }
+    if (EC_GROUP_get0_cofactor(group_nmd) != NULL) {
+        if (!TEST_true(OSSL_PARAM_BLD_push_BN(
+                bld, OSSL_PKEY_PARAM_EC_COFACTOR,
+                EC_GROUP_get0_cofactor(group_nmd))))
+            goto err;
+    }
+
+    if (!TEST_ptr(group_gen = EC_GROUP_get0_generator(group_nmd))
+        || !TEST_size_t_gt(bsize = EC_POINT_point2oct(
+                group_nmd, EC_GROUP_get0_generator(group_nmd),
+                POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx), 0)
+        || !TEST_ptr(buf2 = OPENSSL_malloc(bsize))
+        || !TEST_size_t_eq(EC_POINT_point2oct(
+                group_nmd, EC_GROUP_get0_generator(group_nmd),
+                POINT_CONVERSION_UNCOMPRESSED, buf2, bsize, bn_ctx), bsize)
+        || !TEST_true(OSSL_PARAM_BLD_push_octet_string(
+                bld, OSSL_PKEY_PARAM_EC_GENERATOR, buf2, bsize))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(
+                bld, OSSL_PKEY_PARAM_EC_ORDER, EC_GROUP_get0_order(group_nmd))))
+        goto err;
+
+    if (!TEST_ptr(params_exp = OSSL_PARAM_BLD_to_param(bld))
+        || !TEST_ptr(group_exp =
+                EC_GROUP_new_from_params(params_exp, NULL, NULL))
+        || !TEST_ptr(params_exp2 =
+                EC_GROUP_to_params(group_exp, NULL, NULL, NULL))
+        || !TEST_ptr(group_exp2 =
+                EC_GROUP_new_from_params(params_exp2, NULL, NULL))
+        || !TEST_int_eq(EC_GROUP_cmp(group_exp, group_exp2, NULL), 0))
+        goto err;
+
+    r = 1;
+
+err:
+    EC_GROUP_free(group_nmd);
+    EC_GROUP_free(group_nmd2);
+    EC_GROUP_free(group_nmd3);
+    OSSL_PARAM_free(params_nmd);
+    OSSL_PARAM_free(params_nmd2);
+    OPENSSL_free(buf);
+
+    EC_GROUP_free(group_exp);
+    EC_GROUP_free(group_exp2);
+    BN_CTX_end(bn_ctx);
+    BN_CTX_free(bn_ctx);
+    OPENSSL_free(buf2);
+    OSSL_PARAM_BLD_free(bld);
+    OSSL_PARAM_free(params_exp);
+    OSSL_PARAM_free(params_exp2);
+    return r;
+}
+
 /*-
  * random 256-bit explicit parameters curve, cofactor absent
  * order:    0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
@@ -3015,6 +3127,7 @@ int setup_tests(void)
         return 0;
 
     ADD_TEST(parameter_test);
+    ADD_TEST(ossl_parameter_test);
     ADD_TEST(cofactor_range_test);
     ADD_ALL_TESTS(cardinality_test, crv_len);
     ADD_TEST(prime_field_tests);
index 2487861a18bcf62f33c4d15043e5c1f619305f9a..78fd4813ee45b72eadd903756e59a9ecd058d409 100644 (file)
@@ -5512,3 +5512,4 @@ BIO_get_wpoll_descriptor                ? 3_2_0   EXIST::FUNCTION:
 ASN1_item_unpack_ex                     ?      3_2_0   EXIST::FUNCTION:
 PKCS12_SAFEBAG_get1_cert_ex             ?      3_2_0   EXIST::FUNCTION:
 PKCS12_SAFEBAG_get1_crl_ex              ?      3_2_0   EXIST::FUNCTION:
+EC_GROUP_to_params                      ?      3_2_0   EXIST::FUNCTION:EC