summaryrefslogtreecommitdiffstats
path: root/providers/implementations/encode_decode
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-08-22 14:55:41 +1000
committerShane Lontis <shane.lontis@oracle.com>2020-08-22 14:55:41 +1000
commitc0f39ded68ba0929698a8773e63e9806ec9e5c74 (patch)
treedce39d009fceac112a1d320b5e072d94e22ca27d /providers/implementations/encode_decode
parenta02c715c183382aa3038fc4d7d463b17e62a24ff (diff)
Add Explicit EC parameter support to providers.
This was added for backward compatability. Added EC_GROUP_new_from_params() that supports explicit curve parameters. This fixes the 15-test_genec.t TODO. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/12604)
Diffstat (limited to 'providers/implementations/encode_decode')
-rw-r--r--providers/implementations/encode_decode/encoder_ec.c190
1 files changed, 165 insertions, 25 deletions
diff --git a/providers/implementations/encode_decode/encoder_ec.c b/providers/implementations/encode_decode/encoder_ec.c
index 8c256fe448..ee64e2f802 100644
--- a/providers/implementations/encode_decode/encoder_ec.c
+++ b/providers/implementations/encode_decode/encoder_ec.c
@@ -23,22 +23,134 @@ void ec_get_new_free_import(OSSL_FUNC_keymgmt_new_fn **ec_new,
*ec_import = ossl_prov_get_keymgmt_import(ec_keymgmt_functions);
}
-static int ossl_prov_print_ec_param(BIO *out, const EC_GROUP *group)
+static int ossl_prov_print_ec_param_explicit_curve(BIO *out,
+ const EC_GROUP *group,
+ BN_CTX *ctx)
{
- const char *curve_name;
- int curve_nid = EC_GROUP_get_curve_name(group);
+ const char *plabel = "Prime:";
+ BIGNUM *p = NULL, *a = NULL, *b = NULL;
- /* TODO(3.0): Explicit parameters are currently not supported */
- if (curve_nid == NID_undef)
+ p = BN_CTX_get(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ if (b == NULL
+ || !EC_GROUP_get_curve(group, p, a, b, ctx))
return 0;
- if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0)
+ if (EC_GROUP_get_field_type(group) == NID_X9_62_characteristic_two_field) {
+ int basis_type = EC_GROUP_get_basis_type(group);
+
+ /* print the 'short name' of the base type OID */
+ if (basis_type == NID_undef
+ || BIO_printf(out, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0)
+ return 0;
+ plabel = "Polynomial:";
+ }
+ return ossl_prov_print_labeled_bignum(out, plabel, p)
+ && ossl_prov_print_labeled_bignum(out, "A: ", a)
+ && ossl_prov_print_labeled_bignum(out, "B: ", b);
+}
+
+static int ossl_prov_print_ec_param_explicit_gen(BIO *out,
+ const EC_GROUP *group,
+ BN_CTX *ctx)
+{
+ const EC_POINT *point = NULL;
+ BIGNUM *gen = NULL;
+ const char *glabel = NULL;
+ point_conversion_form_t form;
+
+ form = EC_GROUP_get_point_conversion_form(group);
+ point = EC_GROUP_get0_generator(group);
+ gen = BN_CTX_get(ctx);
+
+ if (gen == NULL
+ || point == NULL
+ || EC_POINT_point2bn(group, point, form, gen, ctx) == NULL)
+ return 0;
+
+ if (gen != NULL) {
+ switch (form) {
+ case POINT_CONVERSION_COMPRESSED:
+ glabel = "Generator (compressed):";
+ break;
+ case POINT_CONVERSION_UNCOMPRESSED:
+ glabel = "Generator (uncompressed):";
+ break;
+ case POINT_CONVERSION_HYBRID:
+ glabel = "Generator (hybrid):";
+ break;
+ default:
+ return 0;
+ }
+ return ossl_prov_print_labeled_bignum(out, glabel, gen);
+ }
+ return 1;
+}
+
+/* Print explicit parameters */
+static int ossl_prov_print_ec_param_explicit(BIO *out, const EC_GROUP *group,
+ OPENSSL_CTX *libctx)
+{
+ int ret = 0, tmp_nid;
+ BN_CTX *ctx = NULL;
+ const BIGNUM *order = NULL, *cofactor = NULL;
+ const unsigned char *seed;
+ size_t seed_len = 0;
+
+ ctx = BN_CTX_new_ex(libctx);
+ if (ctx == NULL)
return 0;
+ BN_CTX_start(ctx);
+
+ tmp_nid = EC_GROUP_get_field_type(group);
+ order = EC_GROUP_get0_order(group);
+ if (order == NULL)
+ goto err;
+
+ seed = EC_GROUP_get0_seed(group);
+ if (seed != NULL)
+ seed_len = EC_GROUP_get_seed_len(group);
+ cofactor = EC_GROUP_get0_cofactor(group);
+
+ /* print the 'short name' of the field type */
+ if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0
+ || !ossl_prov_print_ec_param_explicit_curve(out, group, ctx)
+ || !ossl_prov_print_ec_param_explicit_gen(out, group, ctx)
+ || !ossl_prov_print_labeled_bignum(out, "Order: ", order)
+ || (cofactor != NULL
+ && !ossl_prov_print_labeled_bignum(out, "Cofactor: ", cofactor))
+ || (seed != NULL
+ && !ossl_prov_print_labeled_buf(out, "Seed:", seed, seed_len)))
+ goto err;
+ ret = 1;
+err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return ret;
+}
+
+static int ossl_prov_print_ec_param(BIO *out, const EC_GROUP *group,
+ OPENSSL_CTX *libctx)
+{
+ if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) {
+ const char *curve_name;
+ int curve_nid = EC_GROUP_get_curve_name(group);
- /* TODO(3.0): Only named curves are currently supported */
- curve_name = EC_curve_nid2nist(curve_nid);
- return (curve_name == NULL
- || BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0);
+ /* Explicit parameters */
+ if (curve_nid == NID_undef)
+ return 0;
+
+ if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0)
+ return 0;
+
+ /* TODO(3.0): Only named curves are currently supported */
+ curve_name = EC_curve_nid2nist(curve_nid);
+ return (curve_name == NULL
+ || BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0);
+ } else {
+ return ossl_prov_print_ec_param_explicit(out, group, libctx);
+ }
}
int ossl_prov_print_eckey(BIO *out, EC_KEY *eckey, enum ec_print_type type)
@@ -94,7 +206,7 @@ int ossl_prov_print_eckey(BIO *out, EC_KEY *eckey, enum ec_print_type type)
if (pub != NULL
&& !ossl_prov_print_labeled_buf(out, "pub:", pub, pub_len))
goto err;
- ret = ossl_prov_print_ec_param(out, group);
+ ret = ossl_prov_print_ec_param(out, group, ec_key_get_libctx(eckey));
err:
OPENSSL_clear_free(priv, priv_len);
OPENSSL_free(pub);
@@ -104,32 +216,60 @@ null_err:
goto err;
}
-int ossl_prov_prepare_ec_params(const void *eckey, int nid,
- void **pstr, int *pstrtype)
+static int ossl_prov_prepare_ec_explicit_params(const void *eckey,
+ void **pstr, int *pstrtype)
{
- int curve_nid;
- const EC_GROUP *group = EC_KEY_get0_group(eckey);
- ASN1_OBJECT *params;
+ ASN1_STRING *params = ASN1_STRING_new();
- if (group == NULL
- || ((curve_nid = EC_GROUP_get_curve_name(group)) == NID_undef)
- || ((params = OBJ_nid2obj(curve_nid)) == NULL)) {
- /* TODO(3.0): Explicit curves are not supported */
+ if (params == NULL) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
- if (OBJ_length(params) == 0) {
- /* Some curves might not have an associated OID */
- ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID);
- ASN1_OBJECT_free(params);
+ params->length = i2d_ECParameters(eckey, &params->data);
+ if (params->length <= 0) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+ ASN1_STRING_free(params);
return 0;
}
+ *pstrtype = V_ASN1_SEQUENCE;
*pstr = params;
- *pstrtype = V_ASN1_OBJECT;
return 1;
}
+int ossl_prov_prepare_ec_params(const void *eckey, int nid,
+ void **pstr, int *pstrtype)
+{
+ int curve_nid;
+ const EC_GROUP *group = EC_KEY_get0_group(eckey);
+ ASN1_OBJECT *params = NULL;
+
+ if (group == NULL)
+ return 0;
+ curve_nid = EC_GROUP_get_curve_name(group);
+ if (curve_nid != NID_undef) {
+ params = OBJ_nid2obj(curve_nid);
+ if (params == NULL)
+ return 0;
+ }
+
+ if (curve_nid != NID_undef
+ && (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE)) {
+ if (OBJ_length(params) == 0) {
+ /* Some curves might not have an associated OID */
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID);
+ ASN1_OBJECT_free(params);
+ return 0;
+ }
+ *pstr = params;
+ *pstrtype = V_ASN1_OBJECT;
+ return 1;
+ } else {
+ return ossl_prov_prepare_ec_explicit_params(eckey, pstr, pstrtype);
+ }
+}
+
int ossl_prov_ec_pub_to_der(const void *eckey, unsigned char **pder)
{
return i2o_ECPublicKey(eckey, pder);