1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * ECDSA low level APIs are deprecated for public use, but still ok for 12e1051a39Sopenharmony_ci * internal use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <string.h> 17e1051a39Sopenharmony_ci#include "ec_local.h" 18e1051a39Sopenharmony_ci#include <openssl/err.h> 19e1051a39Sopenharmony_ci#include <openssl/asn1t.h> 20e1051a39Sopenharmony_ci#include <openssl/objects.h> 21e1051a39Sopenharmony_ci#include "internal/nelem.h" 22e1051a39Sopenharmony_ci#include "crypto/asn1_dsa.h" 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ci/* some structures needed for the asn1 encoding */ 27e1051a39Sopenharmony_citypedef struct x9_62_pentanomial_st { 28e1051a39Sopenharmony_ci int32_t k1; 29e1051a39Sopenharmony_ci int32_t k2; 30e1051a39Sopenharmony_ci int32_t k3; 31e1051a39Sopenharmony_ci} X9_62_PENTANOMIAL; 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_citypedef struct x9_62_characteristic_two_st { 34e1051a39Sopenharmony_ci int32_t m; 35e1051a39Sopenharmony_ci ASN1_OBJECT *type; 36e1051a39Sopenharmony_ci union { 37e1051a39Sopenharmony_ci char *ptr; 38e1051a39Sopenharmony_ci /* NID_X9_62_onBasis */ 39e1051a39Sopenharmony_ci ASN1_NULL *onBasis; 40e1051a39Sopenharmony_ci /* NID_X9_62_tpBasis */ 41e1051a39Sopenharmony_ci ASN1_INTEGER *tpBasis; 42e1051a39Sopenharmony_ci /* NID_X9_62_ppBasis */ 43e1051a39Sopenharmony_ci X9_62_PENTANOMIAL *ppBasis; 44e1051a39Sopenharmony_ci /* anything else */ 45e1051a39Sopenharmony_ci ASN1_TYPE *other; 46e1051a39Sopenharmony_ci } p; 47e1051a39Sopenharmony_ci} X9_62_CHARACTERISTIC_TWO; 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_citypedef struct x9_62_fieldid_st { 50e1051a39Sopenharmony_ci ASN1_OBJECT *fieldType; 51e1051a39Sopenharmony_ci union { 52e1051a39Sopenharmony_ci char *ptr; 53e1051a39Sopenharmony_ci /* NID_X9_62_prime_field */ 54e1051a39Sopenharmony_ci ASN1_INTEGER *prime; 55e1051a39Sopenharmony_ci /* NID_X9_62_characteristic_two_field */ 56e1051a39Sopenharmony_ci X9_62_CHARACTERISTIC_TWO *char_two; 57e1051a39Sopenharmony_ci /* anything else */ 58e1051a39Sopenharmony_ci ASN1_TYPE *other; 59e1051a39Sopenharmony_ci } p; 60e1051a39Sopenharmony_ci} X9_62_FIELDID; 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_citypedef struct x9_62_curve_st { 63e1051a39Sopenharmony_ci ASN1_OCTET_STRING *a; 64e1051a39Sopenharmony_ci ASN1_OCTET_STRING *b; 65e1051a39Sopenharmony_ci ASN1_BIT_STRING *seed; 66e1051a39Sopenharmony_ci} X9_62_CURVE; 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_cistruct ec_parameters_st { 69e1051a39Sopenharmony_ci int32_t version; 70e1051a39Sopenharmony_ci X9_62_FIELDID *fieldID; 71e1051a39Sopenharmony_ci X9_62_CURVE *curve; 72e1051a39Sopenharmony_ci ASN1_OCTET_STRING *base; 73e1051a39Sopenharmony_ci ASN1_INTEGER *order; 74e1051a39Sopenharmony_ci ASN1_INTEGER *cofactor; 75e1051a39Sopenharmony_ci} /* ECPARAMETERS */ ; 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_citypedef enum { 78e1051a39Sopenharmony_ci ECPKPARAMETERS_TYPE_NAMED = 0, 79e1051a39Sopenharmony_ci ECPKPARAMETERS_TYPE_EXPLICIT, 80e1051a39Sopenharmony_ci ECPKPARAMETERS_TYPE_IMPLICIT 81e1051a39Sopenharmony_ci} ecpk_parameters_type_t; 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_cistruct ecpk_parameters_st { 84e1051a39Sopenharmony_ci int type; 85e1051a39Sopenharmony_ci union { 86e1051a39Sopenharmony_ci ASN1_OBJECT *named_curve; 87e1051a39Sopenharmony_ci ECPARAMETERS *parameters; 88e1051a39Sopenharmony_ci ASN1_NULL *implicitlyCA; 89e1051a39Sopenharmony_ci } value; 90e1051a39Sopenharmony_ci} /* ECPKPARAMETERS */ ; 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_ci/* SEC1 ECPrivateKey */ 93e1051a39Sopenharmony_citypedef struct ec_privatekey_st { 94e1051a39Sopenharmony_ci int32_t version; 95e1051a39Sopenharmony_ci ASN1_OCTET_STRING *privateKey; 96e1051a39Sopenharmony_ci ECPKPARAMETERS *parameters; 97e1051a39Sopenharmony_ci ASN1_BIT_STRING *publicKey; 98e1051a39Sopenharmony_ci} EC_PRIVATEKEY; 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_ci/* the OpenSSL ASN.1 definitions */ 101e1051a39Sopenharmony_ciASN1_SEQUENCE(X9_62_PENTANOMIAL) = { 102e1051a39Sopenharmony_ci ASN1_EMBED(X9_62_PENTANOMIAL, k1, INT32), 103e1051a39Sopenharmony_ci ASN1_EMBED(X9_62_PENTANOMIAL, k2, INT32), 104e1051a39Sopenharmony_ci ASN1_EMBED(X9_62_PENTANOMIAL, k3, INT32) 105e1051a39Sopenharmony_ci} static_ASN1_SEQUENCE_END(X9_62_PENTANOMIAL) 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_ciDECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) 108e1051a39Sopenharmony_ciIMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) 109e1051a39Sopenharmony_ci 110e1051a39Sopenharmony_ciASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY); 111e1051a39Sopenharmony_ci 112e1051a39Sopenharmony_ciASN1_ADB(X9_62_CHARACTERISTIC_TWO) = { 113e1051a39Sopenharmony_ci ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)), 114e1051a39Sopenharmony_ci ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)), 115e1051a39Sopenharmony_ci ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL)) 116e1051a39Sopenharmony_ci} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL); 117e1051a39Sopenharmony_ci 118e1051a39Sopenharmony_ciASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = { 119e1051a39Sopenharmony_ci ASN1_EMBED(X9_62_CHARACTERISTIC_TWO, m, INT32), 120e1051a39Sopenharmony_ci ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT), 121e1051a39Sopenharmony_ci ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO) 122e1051a39Sopenharmony_ci} static_ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO) 123e1051a39Sopenharmony_ci 124e1051a39Sopenharmony_ciDECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) 125e1051a39Sopenharmony_ciIMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ciASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY); 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ciASN1_ADB(X9_62_FIELDID) = { 130e1051a39Sopenharmony_ci ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)), 131e1051a39Sopenharmony_ci ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO)) 132e1051a39Sopenharmony_ci} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL); 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ciASN1_SEQUENCE(X9_62_FIELDID) = { 135e1051a39Sopenharmony_ci ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT), 136e1051a39Sopenharmony_ci ASN1_ADB_OBJECT(X9_62_FIELDID) 137e1051a39Sopenharmony_ci} static_ASN1_SEQUENCE_END(X9_62_FIELDID) 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_ciASN1_SEQUENCE(X9_62_CURVE) = { 140e1051a39Sopenharmony_ci ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING), 141e1051a39Sopenharmony_ci ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING), 142e1051a39Sopenharmony_ci ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) 143e1051a39Sopenharmony_ci} static_ASN1_SEQUENCE_END(X9_62_CURVE) 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ciASN1_SEQUENCE(ECPARAMETERS) = { 146e1051a39Sopenharmony_ci ASN1_EMBED(ECPARAMETERS, version, INT32), 147e1051a39Sopenharmony_ci ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID), 148e1051a39Sopenharmony_ci ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE), 149e1051a39Sopenharmony_ci ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING), 150e1051a39Sopenharmony_ci ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER), 151e1051a39Sopenharmony_ci ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER) 152e1051a39Sopenharmony_ci} ASN1_SEQUENCE_END(ECPARAMETERS) 153e1051a39Sopenharmony_ci 154e1051a39Sopenharmony_ciDECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) 155e1051a39Sopenharmony_ciIMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) 156e1051a39Sopenharmony_ci 157e1051a39Sopenharmony_ciASN1_CHOICE(ECPKPARAMETERS) = { 158e1051a39Sopenharmony_ci ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT), 159e1051a39Sopenharmony_ci ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS), 160e1051a39Sopenharmony_ci ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL) 161e1051a39Sopenharmony_ci} ASN1_CHOICE_END(ECPKPARAMETERS) 162e1051a39Sopenharmony_ci 163e1051a39Sopenharmony_ciDECLARE_ASN1_FUNCTIONS(ECPKPARAMETERS) 164e1051a39Sopenharmony_ciDECLARE_ASN1_ENCODE_FUNCTIONS_name(ECPKPARAMETERS, ECPKPARAMETERS) 165e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(ECPKPARAMETERS) 166e1051a39Sopenharmony_ci 167e1051a39Sopenharmony_ciASN1_SEQUENCE(EC_PRIVATEKEY) = { 168e1051a39Sopenharmony_ci ASN1_EMBED(EC_PRIVATEKEY, version, INT32), 169e1051a39Sopenharmony_ci ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), 170e1051a39Sopenharmony_ci ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), 171e1051a39Sopenharmony_ci ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1) 172e1051a39Sopenharmony_ci} static_ASN1_SEQUENCE_END(EC_PRIVATEKEY) 173e1051a39Sopenharmony_ci 174e1051a39Sopenharmony_ciDECLARE_ASN1_FUNCTIONS(EC_PRIVATEKEY) 175e1051a39Sopenharmony_ciDECLARE_ASN1_ENCODE_FUNCTIONS_name(EC_PRIVATEKEY, EC_PRIVATEKEY) 176e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(EC_PRIVATEKEY) 177e1051a39Sopenharmony_ci 178e1051a39Sopenharmony_ci/* some declarations of internal function */ 179e1051a39Sopenharmony_ci 180e1051a39Sopenharmony_ci/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ 181e1051a39Sopenharmony_cistatic int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *); 182e1051a39Sopenharmony_ci/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ 183e1051a39Sopenharmony_cistatic int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *); 184e1051a39Sopenharmony_ci 185e1051a39Sopenharmony_ci/* the function definitions */ 186e1051a39Sopenharmony_ci 187e1051a39Sopenharmony_cistatic int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) 188e1051a39Sopenharmony_ci{ 189e1051a39Sopenharmony_ci int ok = 0, nid; 190e1051a39Sopenharmony_ci BIGNUM *tmp = NULL; 191e1051a39Sopenharmony_ci 192e1051a39Sopenharmony_ci if (group == NULL || field == NULL) 193e1051a39Sopenharmony_ci return 0; 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci /* clear the old values (if necessary) */ 196e1051a39Sopenharmony_ci ASN1_OBJECT_free(field->fieldType); 197e1051a39Sopenharmony_ci ASN1_TYPE_free(field->p.other); 198e1051a39Sopenharmony_ci 199e1051a39Sopenharmony_ci nid = EC_GROUP_get_field_type(group); 200e1051a39Sopenharmony_ci /* set OID for the field */ 201e1051a39Sopenharmony_ci if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { 202e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_OBJ_LIB); 203e1051a39Sopenharmony_ci goto err; 204e1051a39Sopenharmony_ci } 205e1051a39Sopenharmony_ci 206e1051a39Sopenharmony_ci if (nid == NID_X9_62_prime_field) { 207e1051a39Sopenharmony_ci if ((tmp = BN_new()) == NULL) { 208e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 209e1051a39Sopenharmony_ci goto err; 210e1051a39Sopenharmony_ci } 211e1051a39Sopenharmony_ci /* the parameters are specified by the prime number p */ 212e1051a39Sopenharmony_ci if (!EC_GROUP_get_curve(group, tmp, NULL, NULL, NULL)) { 213e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 214e1051a39Sopenharmony_ci goto err; 215e1051a39Sopenharmony_ci } 216e1051a39Sopenharmony_ci /* set the prime number */ 217e1051a39Sopenharmony_ci field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL); 218e1051a39Sopenharmony_ci if (field->p.prime == NULL) { 219e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); 220e1051a39Sopenharmony_ci goto err; 221e1051a39Sopenharmony_ci } 222e1051a39Sopenharmony_ci } else if (nid == NID_X9_62_characteristic_two_field) 223e1051a39Sopenharmony_ci#ifdef OPENSSL_NO_EC2M 224e1051a39Sopenharmony_ci { 225e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); 226e1051a39Sopenharmony_ci goto err; 227e1051a39Sopenharmony_ci } 228e1051a39Sopenharmony_ci#else 229e1051a39Sopenharmony_ci { 230e1051a39Sopenharmony_ci int field_type; 231e1051a39Sopenharmony_ci X9_62_CHARACTERISTIC_TWO *char_two; 232e1051a39Sopenharmony_ci 233e1051a39Sopenharmony_ci field->p.char_two = X9_62_CHARACTERISTIC_TWO_new(); 234e1051a39Sopenharmony_ci char_two = field->p.char_two; 235e1051a39Sopenharmony_ci 236e1051a39Sopenharmony_ci if (char_two == NULL) { 237e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 238e1051a39Sopenharmony_ci goto err; 239e1051a39Sopenharmony_ci } 240e1051a39Sopenharmony_ci 241e1051a39Sopenharmony_ci char_two->m = (long)EC_GROUP_get_degree(group); 242e1051a39Sopenharmony_ci 243e1051a39Sopenharmony_ci field_type = EC_GROUP_get_basis_type(group); 244e1051a39Sopenharmony_ci 245e1051a39Sopenharmony_ci if (field_type == 0) { 246e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 247e1051a39Sopenharmony_ci goto err; 248e1051a39Sopenharmony_ci } 249e1051a39Sopenharmony_ci /* set base type OID */ 250e1051a39Sopenharmony_ci if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) { 251e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_OBJ_LIB); 252e1051a39Sopenharmony_ci goto err; 253e1051a39Sopenharmony_ci } 254e1051a39Sopenharmony_ci 255e1051a39Sopenharmony_ci if (field_type == NID_X9_62_tpBasis) { 256e1051a39Sopenharmony_ci unsigned int k; 257e1051a39Sopenharmony_ci 258e1051a39Sopenharmony_ci if (!EC_GROUP_get_trinomial_basis(group, &k)) 259e1051a39Sopenharmony_ci goto err; 260e1051a39Sopenharmony_ci 261e1051a39Sopenharmony_ci char_two->p.tpBasis = ASN1_INTEGER_new(); 262e1051a39Sopenharmony_ci if (char_two->p.tpBasis == NULL) { 263e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 264e1051a39Sopenharmony_ci goto err; 265e1051a39Sopenharmony_ci } 266e1051a39Sopenharmony_ci if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) { 267e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); 268e1051a39Sopenharmony_ci goto err; 269e1051a39Sopenharmony_ci } 270e1051a39Sopenharmony_ci } else if (field_type == NID_X9_62_ppBasis) { 271e1051a39Sopenharmony_ci unsigned int k1, k2, k3; 272e1051a39Sopenharmony_ci 273e1051a39Sopenharmony_ci if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)) 274e1051a39Sopenharmony_ci goto err; 275e1051a39Sopenharmony_ci 276e1051a39Sopenharmony_ci char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); 277e1051a39Sopenharmony_ci if (char_two->p.ppBasis == NULL) { 278e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 279e1051a39Sopenharmony_ci goto err; 280e1051a39Sopenharmony_ci } 281e1051a39Sopenharmony_ci 282e1051a39Sopenharmony_ci /* set k? values */ 283e1051a39Sopenharmony_ci char_two->p.ppBasis->k1 = (long)k1; 284e1051a39Sopenharmony_ci char_two->p.ppBasis->k2 = (long)k2; 285e1051a39Sopenharmony_ci char_two->p.ppBasis->k3 = (long)k3; 286e1051a39Sopenharmony_ci } else { /* field_type == NID_X9_62_onBasis */ 287e1051a39Sopenharmony_ci 288e1051a39Sopenharmony_ci /* for ONB the parameters are (asn1) NULL */ 289e1051a39Sopenharmony_ci char_two->p.onBasis = ASN1_NULL_new(); 290e1051a39Sopenharmony_ci if (char_two->p.onBasis == NULL) { 291e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 292e1051a39Sopenharmony_ci goto err; 293e1051a39Sopenharmony_ci } 294e1051a39Sopenharmony_ci } 295e1051a39Sopenharmony_ci } 296e1051a39Sopenharmony_ci#endif 297e1051a39Sopenharmony_ci else { 298e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD); 299e1051a39Sopenharmony_ci goto err; 300e1051a39Sopenharmony_ci } 301e1051a39Sopenharmony_ci 302e1051a39Sopenharmony_ci ok = 1; 303e1051a39Sopenharmony_ci 304e1051a39Sopenharmony_ci err: 305e1051a39Sopenharmony_ci BN_free(tmp); 306e1051a39Sopenharmony_ci return ok; 307e1051a39Sopenharmony_ci} 308e1051a39Sopenharmony_ci 309e1051a39Sopenharmony_cistatic int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) 310e1051a39Sopenharmony_ci{ 311e1051a39Sopenharmony_ci int ok = 0; 312e1051a39Sopenharmony_ci BIGNUM *tmp_1 = NULL, *tmp_2 = NULL; 313e1051a39Sopenharmony_ci unsigned char *a_buf = NULL, *b_buf = NULL; 314e1051a39Sopenharmony_ci size_t len; 315e1051a39Sopenharmony_ci 316e1051a39Sopenharmony_ci if (!group || !curve || !curve->a || !curve->b) 317e1051a39Sopenharmony_ci return 0; 318e1051a39Sopenharmony_ci 319e1051a39Sopenharmony_ci if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { 320e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 321e1051a39Sopenharmony_ci goto err; 322e1051a39Sopenharmony_ci } 323e1051a39Sopenharmony_ci 324e1051a39Sopenharmony_ci /* get a and b */ 325e1051a39Sopenharmony_ci if (!EC_GROUP_get_curve(group, NULL, tmp_1, tmp_2, NULL)) { 326e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 327e1051a39Sopenharmony_ci goto err; 328e1051a39Sopenharmony_ci } 329e1051a39Sopenharmony_ci 330e1051a39Sopenharmony_ci /* 331e1051a39Sopenharmony_ci * Per SEC 1, the curve coefficients must be padded up to size. See C.2's 332e1051a39Sopenharmony_ci * definition of Curve, C.1's definition of FieldElement, and 2.3.5's 333e1051a39Sopenharmony_ci * definition of how to encode the field elements. 334e1051a39Sopenharmony_ci */ 335e1051a39Sopenharmony_ci len = ((size_t)EC_GROUP_get_degree(group) + 7) / 8; 336e1051a39Sopenharmony_ci if ((a_buf = OPENSSL_malloc(len)) == NULL 337e1051a39Sopenharmony_ci || (b_buf = OPENSSL_malloc(len)) == NULL) { 338e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 339e1051a39Sopenharmony_ci goto err; 340e1051a39Sopenharmony_ci } 341e1051a39Sopenharmony_ci if (BN_bn2binpad(tmp_1, a_buf, len) < 0 342e1051a39Sopenharmony_ci || BN_bn2binpad(tmp_2, b_buf, len) < 0) { 343e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 344e1051a39Sopenharmony_ci goto err; 345e1051a39Sopenharmony_ci } 346e1051a39Sopenharmony_ci 347e1051a39Sopenharmony_ci /* set a and b */ 348e1051a39Sopenharmony_ci if (!ASN1_OCTET_STRING_set(curve->a, a_buf, len) 349e1051a39Sopenharmony_ci || !ASN1_OCTET_STRING_set(curve->b, b_buf, len)) { 350e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); 351e1051a39Sopenharmony_ci goto err; 352e1051a39Sopenharmony_ci } 353e1051a39Sopenharmony_ci 354e1051a39Sopenharmony_ci /* set the seed (optional) */ 355e1051a39Sopenharmony_ci if (group->seed) { 356e1051a39Sopenharmony_ci if (!curve->seed) 357e1051a39Sopenharmony_ci if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { 358e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 359e1051a39Sopenharmony_ci goto err; 360e1051a39Sopenharmony_ci } 361e1051a39Sopenharmony_ci curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 362e1051a39Sopenharmony_ci curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; 363e1051a39Sopenharmony_ci if (!ASN1_BIT_STRING_set(curve->seed, group->seed, 364e1051a39Sopenharmony_ci (int)group->seed_len)) { 365e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); 366e1051a39Sopenharmony_ci goto err; 367e1051a39Sopenharmony_ci } 368e1051a39Sopenharmony_ci } else { 369e1051a39Sopenharmony_ci ASN1_BIT_STRING_free(curve->seed); 370e1051a39Sopenharmony_ci curve->seed = NULL; 371e1051a39Sopenharmony_ci } 372e1051a39Sopenharmony_ci 373e1051a39Sopenharmony_ci ok = 1; 374e1051a39Sopenharmony_ci 375e1051a39Sopenharmony_ci err: 376e1051a39Sopenharmony_ci OPENSSL_free(a_buf); 377e1051a39Sopenharmony_ci OPENSSL_free(b_buf); 378e1051a39Sopenharmony_ci BN_free(tmp_1); 379e1051a39Sopenharmony_ci BN_free(tmp_2); 380e1051a39Sopenharmony_ci return ok; 381e1051a39Sopenharmony_ci} 382e1051a39Sopenharmony_ci 383e1051a39Sopenharmony_ciECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, 384e1051a39Sopenharmony_ci ECPARAMETERS *params) 385e1051a39Sopenharmony_ci{ 386e1051a39Sopenharmony_ci size_t len = 0; 387e1051a39Sopenharmony_ci ECPARAMETERS *ret = NULL; 388e1051a39Sopenharmony_ci const BIGNUM *tmp; 389e1051a39Sopenharmony_ci unsigned char *buffer = NULL; 390e1051a39Sopenharmony_ci const EC_POINT *point = NULL; 391e1051a39Sopenharmony_ci point_conversion_form_t form; 392e1051a39Sopenharmony_ci ASN1_INTEGER *orig; 393e1051a39Sopenharmony_ci 394e1051a39Sopenharmony_ci if (params == NULL) { 395e1051a39Sopenharmony_ci if ((ret = ECPARAMETERS_new()) == NULL) { 396e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 397e1051a39Sopenharmony_ci goto err; 398e1051a39Sopenharmony_ci } 399e1051a39Sopenharmony_ci } else 400e1051a39Sopenharmony_ci ret = params; 401e1051a39Sopenharmony_ci 402e1051a39Sopenharmony_ci /* set the version (always one) */ 403e1051a39Sopenharmony_ci ret->version = (long)0x1; 404e1051a39Sopenharmony_ci 405e1051a39Sopenharmony_ci /* set the fieldID */ 406e1051a39Sopenharmony_ci if (!ec_asn1_group2fieldid(group, ret->fieldID)) { 407e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 408e1051a39Sopenharmony_ci goto err; 409e1051a39Sopenharmony_ci } 410e1051a39Sopenharmony_ci 411e1051a39Sopenharmony_ci /* set the curve */ 412e1051a39Sopenharmony_ci if (!ec_asn1_group2curve(group, ret->curve)) { 413e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 414e1051a39Sopenharmony_ci goto err; 415e1051a39Sopenharmony_ci } 416e1051a39Sopenharmony_ci 417e1051a39Sopenharmony_ci /* set the base point */ 418e1051a39Sopenharmony_ci if ((point = EC_GROUP_get0_generator(group)) == NULL) { 419e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR); 420e1051a39Sopenharmony_ci goto err; 421e1051a39Sopenharmony_ci } 422e1051a39Sopenharmony_ci 423e1051a39Sopenharmony_ci form = EC_GROUP_get_point_conversion_form(group); 424e1051a39Sopenharmony_ci 425e1051a39Sopenharmony_ci len = EC_POINT_point2buf(group, point, form, &buffer, NULL); 426e1051a39Sopenharmony_ci if (len == 0) { 427e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 428e1051a39Sopenharmony_ci goto err; 429e1051a39Sopenharmony_ci } 430e1051a39Sopenharmony_ci if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { 431e1051a39Sopenharmony_ci OPENSSL_free(buffer); 432e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 433e1051a39Sopenharmony_ci goto err; 434e1051a39Sopenharmony_ci } 435e1051a39Sopenharmony_ci ASN1_STRING_set0(ret->base, buffer, len); 436e1051a39Sopenharmony_ci 437e1051a39Sopenharmony_ci /* set the order */ 438e1051a39Sopenharmony_ci tmp = EC_GROUP_get0_order(group); 439e1051a39Sopenharmony_ci if (tmp == NULL) { 440e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 441e1051a39Sopenharmony_ci goto err; 442e1051a39Sopenharmony_ci } 443e1051a39Sopenharmony_ci ret->order = BN_to_ASN1_INTEGER(tmp, orig = ret->order); 444e1051a39Sopenharmony_ci if (ret->order == NULL) { 445e1051a39Sopenharmony_ci ret->order = orig; 446e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); 447e1051a39Sopenharmony_ci goto err; 448e1051a39Sopenharmony_ci } 449e1051a39Sopenharmony_ci 450e1051a39Sopenharmony_ci /* set the cofactor (optional) */ 451e1051a39Sopenharmony_ci tmp = EC_GROUP_get0_cofactor(group); 452e1051a39Sopenharmony_ci if (tmp != NULL) { 453e1051a39Sopenharmony_ci ret->cofactor = BN_to_ASN1_INTEGER(tmp, orig = ret->cofactor); 454e1051a39Sopenharmony_ci if (ret->cofactor == NULL) { 455e1051a39Sopenharmony_ci ret->cofactor = orig; 456e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); 457e1051a39Sopenharmony_ci goto err; 458e1051a39Sopenharmony_ci } 459e1051a39Sopenharmony_ci } 460e1051a39Sopenharmony_ci 461e1051a39Sopenharmony_ci return ret; 462e1051a39Sopenharmony_ci 463e1051a39Sopenharmony_ci err: 464e1051a39Sopenharmony_ci if (params == NULL) 465e1051a39Sopenharmony_ci ECPARAMETERS_free(ret); 466e1051a39Sopenharmony_ci return NULL; 467e1051a39Sopenharmony_ci} 468e1051a39Sopenharmony_ci 469e1051a39Sopenharmony_ciECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, 470e1051a39Sopenharmony_ci ECPKPARAMETERS *params) 471e1051a39Sopenharmony_ci{ 472e1051a39Sopenharmony_ci int ok = 1, tmp; 473e1051a39Sopenharmony_ci ECPKPARAMETERS *ret = params; 474e1051a39Sopenharmony_ci 475e1051a39Sopenharmony_ci if (ret == NULL) { 476e1051a39Sopenharmony_ci if ((ret = ECPKPARAMETERS_new()) == NULL) { 477e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 478e1051a39Sopenharmony_ci return NULL; 479e1051a39Sopenharmony_ci } 480e1051a39Sopenharmony_ci } else { 481e1051a39Sopenharmony_ci if (ret->type == ECPKPARAMETERS_TYPE_NAMED) 482e1051a39Sopenharmony_ci ASN1_OBJECT_free(ret->value.named_curve); 483e1051a39Sopenharmony_ci else if (ret->type == ECPKPARAMETERS_TYPE_EXPLICIT 484e1051a39Sopenharmony_ci && ret->value.parameters != NULL) 485e1051a39Sopenharmony_ci ECPARAMETERS_free(ret->value.parameters); 486e1051a39Sopenharmony_ci } 487e1051a39Sopenharmony_ci 488e1051a39Sopenharmony_ci if (EC_GROUP_get_asn1_flag(group) == OPENSSL_EC_NAMED_CURVE) { 489e1051a39Sopenharmony_ci /* 490e1051a39Sopenharmony_ci * use the asn1 OID to describe the elliptic curve parameters 491e1051a39Sopenharmony_ci */ 492e1051a39Sopenharmony_ci tmp = EC_GROUP_get_curve_name(group); 493e1051a39Sopenharmony_ci if (tmp) { 494e1051a39Sopenharmony_ci ASN1_OBJECT *asn1obj = OBJ_nid2obj(tmp); 495e1051a39Sopenharmony_ci 496e1051a39Sopenharmony_ci if (asn1obj == NULL || OBJ_length(asn1obj) == 0) { 497e1051a39Sopenharmony_ci ASN1_OBJECT_free(asn1obj); 498e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_MISSING_OID); 499e1051a39Sopenharmony_ci ok = 0; 500e1051a39Sopenharmony_ci } else { 501e1051a39Sopenharmony_ci ret->type = ECPKPARAMETERS_TYPE_NAMED; 502e1051a39Sopenharmony_ci ret->value.named_curve = asn1obj; 503e1051a39Sopenharmony_ci } 504e1051a39Sopenharmony_ci } else 505e1051a39Sopenharmony_ci /* we don't know the nid => ERROR */ 506e1051a39Sopenharmony_ci ok = 0; 507e1051a39Sopenharmony_ci } else { 508e1051a39Sopenharmony_ci /* use the ECPARAMETERS structure */ 509e1051a39Sopenharmony_ci ret->type = ECPKPARAMETERS_TYPE_EXPLICIT; 510e1051a39Sopenharmony_ci if ((ret->value.parameters = 511e1051a39Sopenharmony_ci EC_GROUP_get_ecparameters(group, NULL)) == NULL) 512e1051a39Sopenharmony_ci ok = 0; 513e1051a39Sopenharmony_ci } 514e1051a39Sopenharmony_ci 515e1051a39Sopenharmony_ci if (!ok) { 516e1051a39Sopenharmony_ci ECPKPARAMETERS_free(ret); 517e1051a39Sopenharmony_ci return NULL; 518e1051a39Sopenharmony_ci } 519e1051a39Sopenharmony_ci return ret; 520e1051a39Sopenharmony_ci} 521e1051a39Sopenharmony_ci 522e1051a39Sopenharmony_ciEC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) 523e1051a39Sopenharmony_ci{ 524e1051a39Sopenharmony_ci int ok = 0, tmp; 525e1051a39Sopenharmony_ci EC_GROUP *ret = NULL, *dup = NULL; 526e1051a39Sopenharmony_ci BIGNUM *p = NULL, *a = NULL, *b = NULL; 527e1051a39Sopenharmony_ci EC_POINT *point = NULL; 528e1051a39Sopenharmony_ci long field_bits; 529e1051a39Sopenharmony_ci int curve_name = NID_undef; 530e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 531e1051a39Sopenharmony_ci 532e1051a39Sopenharmony_ci if (params->fieldID == NULL 533e1051a39Sopenharmony_ci || params->fieldID->fieldType == NULL 534e1051a39Sopenharmony_ci || params->fieldID->p.ptr == NULL) { 535e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); 536e1051a39Sopenharmony_ci goto err; 537e1051a39Sopenharmony_ci } 538e1051a39Sopenharmony_ci 539e1051a39Sopenharmony_ci /* 540e1051a39Sopenharmony_ci * Now extract the curve parameters a and b. Note that, although SEC 1 541e1051a39Sopenharmony_ci * specifies the length of their encodings, historical versions of OpenSSL 542e1051a39Sopenharmony_ci * encoded them incorrectly, so we must accept any length for backwards 543e1051a39Sopenharmony_ci * compatibility. 544e1051a39Sopenharmony_ci */ 545e1051a39Sopenharmony_ci if (params->curve == NULL 546e1051a39Sopenharmony_ci || params->curve->a == NULL || params->curve->a->data == NULL 547e1051a39Sopenharmony_ci || params->curve->b == NULL || params->curve->b->data == NULL) { 548e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); 549e1051a39Sopenharmony_ci goto err; 550e1051a39Sopenharmony_ci } 551e1051a39Sopenharmony_ci a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); 552e1051a39Sopenharmony_ci if (a == NULL) { 553e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 554e1051a39Sopenharmony_ci goto err; 555e1051a39Sopenharmony_ci } 556e1051a39Sopenharmony_ci b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); 557e1051a39Sopenharmony_ci if (b == NULL) { 558e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 559e1051a39Sopenharmony_ci goto err; 560e1051a39Sopenharmony_ci } 561e1051a39Sopenharmony_ci 562e1051a39Sopenharmony_ci /* get the field parameters */ 563e1051a39Sopenharmony_ci tmp = OBJ_obj2nid(params->fieldID->fieldType); 564e1051a39Sopenharmony_ci if (tmp == NID_X9_62_characteristic_two_field) 565e1051a39Sopenharmony_ci#ifdef OPENSSL_NO_EC2M 566e1051a39Sopenharmony_ci { 567e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); 568e1051a39Sopenharmony_ci goto err; 569e1051a39Sopenharmony_ci } 570e1051a39Sopenharmony_ci#else 571e1051a39Sopenharmony_ci { 572e1051a39Sopenharmony_ci X9_62_CHARACTERISTIC_TWO *char_two; 573e1051a39Sopenharmony_ci 574e1051a39Sopenharmony_ci char_two = params->fieldID->p.char_two; 575e1051a39Sopenharmony_ci 576e1051a39Sopenharmony_ci field_bits = char_two->m; 577e1051a39Sopenharmony_ci if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { 578e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE); 579e1051a39Sopenharmony_ci goto err; 580e1051a39Sopenharmony_ci } 581e1051a39Sopenharmony_ci 582e1051a39Sopenharmony_ci if ((p = BN_new()) == NULL) { 583e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 584e1051a39Sopenharmony_ci goto err; 585e1051a39Sopenharmony_ci } 586e1051a39Sopenharmony_ci 587e1051a39Sopenharmony_ci /* get the base type */ 588e1051a39Sopenharmony_ci tmp = OBJ_obj2nid(char_two->type); 589e1051a39Sopenharmony_ci 590e1051a39Sopenharmony_ci if (tmp == NID_X9_62_tpBasis) { 591e1051a39Sopenharmony_ci long tmp_long; 592e1051a39Sopenharmony_ci 593e1051a39Sopenharmony_ci if (!char_two->p.tpBasis) { 594e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); 595e1051a39Sopenharmony_ci goto err; 596e1051a39Sopenharmony_ci } 597e1051a39Sopenharmony_ci 598e1051a39Sopenharmony_ci tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis); 599e1051a39Sopenharmony_ci 600e1051a39Sopenharmony_ci if (!(char_two->m > tmp_long && tmp_long > 0)) { 601e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_TRINOMIAL_BASIS); 602e1051a39Sopenharmony_ci goto err; 603e1051a39Sopenharmony_ci } 604e1051a39Sopenharmony_ci 605e1051a39Sopenharmony_ci /* create the polynomial */ 606e1051a39Sopenharmony_ci if (!BN_set_bit(p, (int)char_two->m)) 607e1051a39Sopenharmony_ci goto err; 608e1051a39Sopenharmony_ci if (!BN_set_bit(p, (int)tmp_long)) 609e1051a39Sopenharmony_ci goto err; 610e1051a39Sopenharmony_ci if (!BN_set_bit(p, 0)) 611e1051a39Sopenharmony_ci goto err; 612e1051a39Sopenharmony_ci } else if (tmp == NID_X9_62_ppBasis) { 613e1051a39Sopenharmony_ci X9_62_PENTANOMIAL *penta; 614e1051a39Sopenharmony_ci 615e1051a39Sopenharmony_ci penta = char_two->p.ppBasis; 616e1051a39Sopenharmony_ci if (penta == NULL) { 617e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); 618e1051a39Sopenharmony_ci goto err; 619e1051a39Sopenharmony_ci } 620e1051a39Sopenharmony_ci 621e1051a39Sopenharmony_ci if (! 622e1051a39Sopenharmony_ci (char_two->m > penta->k3 && penta->k3 > penta->k2 623e1051a39Sopenharmony_ci && penta->k2 > penta->k1 && penta->k1 > 0)) { 624e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_PENTANOMIAL_BASIS); 625e1051a39Sopenharmony_ci goto err; 626e1051a39Sopenharmony_ci } 627e1051a39Sopenharmony_ci 628e1051a39Sopenharmony_ci /* create the polynomial */ 629e1051a39Sopenharmony_ci if (!BN_set_bit(p, (int)char_two->m)) 630e1051a39Sopenharmony_ci goto err; 631e1051a39Sopenharmony_ci if (!BN_set_bit(p, (int)penta->k1)) 632e1051a39Sopenharmony_ci goto err; 633e1051a39Sopenharmony_ci if (!BN_set_bit(p, (int)penta->k2)) 634e1051a39Sopenharmony_ci goto err; 635e1051a39Sopenharmony_ci if (!BN_set_bit(p, (int)penta->k3)) 636e1051a39Sopenharmony_ci goto err; 637e1051a39Sopenharmony_ci if (!BN_set_bit(p, 0)) 638e1051a39Sopenharmony_ci goto err; 639e1051a39Sopenharmony_ci } else if (tmp == NID_X9_62_onBasis) { 640e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_NOT_IMPLEMENTED); 641e1051a39Sopenharmony_ci goto err; 642e1051a39Sopenharmony_ci } else { /* error */ 643e1051a39Sopenharmony_ci 644e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); 645e1051a39Sopenharmony_ci goto err; 646e1051a39Sopenharmony_ci } 647e1051a39Sopenharmony_ci 648e1051a39Sopenharmony_ci /* create the EC_GROUP structure */ 649e1051a39Sopenharmony_ci ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL); 650e1051a39Sopenharmony_ci } 651e1051a39Sopenharmony_ci#endif 652e1051a39Sopenharmony_ci else if (tmp == NID_X9_62_prime_field) { 653e1051a39Sopenharmony_ci /* we have a curve over a prime field */ 654e1051a39Sopenharmony_ci /* extract the prime number */ 655e1051a39Sopenharmony_ci if (params->fieldID->p.prime == NULL) { 656e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); 657e1051a39Sopenharmony_ci goto err; 658e1051a39Sopenharmony_ci } 659e1051a39Sopenharmony_ci p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); 660e1051a39Sopenharmony_ci if (p == NULL) { 661e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); 662e1051a39Sopenharmony_ci goto err; 663e1051a39Sopenharmony_ci } 664e1051a39Sopenharmony_ci 665e1051a39Sopenharmony_ci if (BN_is_negative(p) || BN_is_zero(p)) { 666e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); 667e1051a39Sopenharmony_ci goto err; 668e1051a39Sopenharmony_ci } 669e1051a39Sopenharmony_ci 670e1051a39Sopenharmony_ci field_bits = BN_num_bits(p); 671e1051a39Sopenharmony_ci if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { 672e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE); 673e1051a39Sopenharmony_ci goto err; 674e1051a39Sopenharmony_ci } 675e1051a39Sopenharmony_ci 676e1051a39Sopenharmony_ci /* create the EC_GROUP structure */ 677e1051a39Sopenharmony_ci ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); 678e1051a39Sopenharmony_ci } else { 679e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); 680e1051a39Sopenharmony_ci goto err; 681e1051a39Sopenharmony_ci } 682e1051a39Sopenharmony_ci 683e1051a39Sopenharmony_ci if (ret == NULL) { 684e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 685e1051a39Sopenharmony_ci goto err; 686e1051a39Sopenharmony_ci } 687e1051a39Sopenharmony_ci 688e1051a39Sopenharmony_ci /* extract seed (optional) */ 689e1051a39Sopenharmony_ci if (params->curve->seed != NULL) { 690e1051a39Sopenharmony_ci /* 691e1051a39Sopenharmony_ci * This happens for instance with 692e1051a39Sopenharmony_ci * fuzz/corpora/asn1/65cf44e85614c62f10cf3b7a7184c26293a19e4a 693e1051a39Sopenharmony_ci * and causes the OPENSSL_malloc below to choke on the 694e1051a39Sopenharmony_ci * zero length allocation request. 695e1051a39Sopenharmony_ci */ 696e1051a39Sopenharmony_ci if (params->curve->seed->length == 0) { 697e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); 698e1051a39Sopenharmony_ci goto err; 699e1051a39Sopenharmony_ci } 700e1051a39Sopenharmony_ci OPENSSL_free(ret->seed); 701e1051a39Sopenharmony_ci if ((ret->seed = OPENSSL_malloc(params->curve->seed->length)) == NULL) { 702e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 703e1051a39Sopenharmony_ci goto err; 704e1051a39Sopenharmony_ci } 705e1051a39Sopenharmony_ci memcpy(ret->seed, params->curve->seed->data, 706e1051a39Sopenharmony_ci params->curve->seed->length); 707e1051a39Sopenharmony_ci ret->seed_len = params->curve->seed->length; 708e1051a39Sopenharmony_ci } 709e1051a39Sopenharmony_ci 710e1051a39Sopenharmony_ci if (params->order == NULL 711e1051a39Sopenharmony_ci || params->base == NULL 712e1051a39Sopenharmony_ci || params->base->data == NULL 713e1051a39Sopenharmony_ci || params->base->length == 0) { 714e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); 715e1051a39Sopenharmony_ci goto err; 716e1051a39Sopenharmony_ci } 717e1051a39Sopenharmony_ci 718e1051a39Sopenharmony_ci if ((point = EC_POINT_new(ret)) == NULL) 719e1051a39Sopenharmony_ci goto err; 720e1051a39Sopenharmony_ci 721e1051a39Sopenharmony_ci /* set the point conversion form */ 722e1051a39Sopenharmony_ci EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) 723e1051a39Sopenharmony_ci (params->base->data[0] & ~0x01)); 724e1051a39Sopenharmony_ci 725e1051a39Sopenharmony_ci /* extract the ec point */ 726e1051a39Sopenharmony_ci if (!EC_POINT_oct2point(ret, point, params->base->data, 727e1051a39Sopenharmony_ci params->base->length, NULL)) { 728e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 729e1051a39Sopenharmony_ci goto err; 730e1051a39Sopenharmony_ci } 731e1051a39Sopenharmony_ci 732e1051a39Sopenharmony_ci /* extract the order */ 733e1051a39Sopenharmony_ci if (ASN1_INTEGER_to_BN(params->order, a) == NULL) { 734e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); 735e1051a39Sopenharmony_ci goto err; 736e1051a39Sopenharmony_ci } 737e1051a39Sopenharmony_ci if (BN_is_negative(a) || BN_is_zero(a)) { 738e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); 739e1051a39Sopenharmony_ci goto err; 740e1051a39Sopenharmony_ci } 741e1051a39Sopenharmony_ci if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */ 742e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); 743e1051a39Sopenharmony_ci goto err; 744e1051a39Sopenharmony_ci } 745e1051a39Sopenharmony_ci 746e1051a39Sopenharmony_ci /* extract the cofactor (optional) */ 747e1051a39Sopenharmony_ci if (params->cofactor == NULL) { 748e1051a39Sopenharmony_ci BN_free(b); 749e1051a39Sopenharmony_ci b = NULL; 750e1051a39Sopenharmony_ci } else if (ASN1_INTEGER_to_BN(params->cofactor, b) == NULL) { 751e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); 752e1051a39Sopenharmony_ci goto err; 753e1051a39Sopenharmony_ci } 754e1051a39Sopenharmony_ci /* set the generator, order and cofactor (if present) */ 755e1051a39Sopenharmony_ci if (!EC_GROUP_set_generator(ret, point, a, b)) { 756e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 757e1051a39Sopenharmony_ci goto err; 758e1051a39Sopenharmony_ci } 759e1051a39Sopenharmony_ci 760e1051a39Sopenharmony_ci /* 761e1051a39Sopenharmony_ci * Check if the explicit parameters group just created matches one of the 762e1051a39Sopenharmony_ci * built-in curves. 763e1051a39Sopenharmony_ci * 764e1051a39Sopenharmony_ci * We create a copy of the group just built, so that we can remove optional 765e1051a39Sopenharmony_ci * fields for the lookup: we do this to avoid the possibility that one of 766e1051a39Sopenharmony_ci * the optional parameters is used to force the library into using a less 767e1051a39Sopenharmony_ci * performant and less secure EC_METHOD instead of the specialized one. 768e1051a39Sopenharmony_ci * In any case, `seed` is not really used in any computation, while a 769e1051a39Sopenharmony_ci * cofactor different from the one in the built-in table is just 770e1051a39Sopenharmony_ci * mathematically wrong anyway and should not be used. 771e1051a39Sopenharmony_ci */ 772e1051a39Sopenharmony_ci if ((ctx = BN_CTX_new()) == NULL) { 773e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 774e1051a39Sopenharmony_ci goto err; 775e1051a39Sopenharmony_ci } 776e1051a39Sopenharmony_ci if ((dup = EC_GROUP_dup(ret)) == NULL 777e1051a39Sopenharmony_ci || EC_GROUP_set_seed(dup, NULL, 0) != 1 778e1051a39Sopenharmony_ci || !EC_GROUP_set_generator(dup, point, a, NULL)) { 779e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 780e1051a39Sopenharmony_ci goto err; 781e1051a39Sopenharmony_ci } 782e1051a39Sopenharmony_ci if ((curve_name = ossl_ec_curve_nid_from_params(dup, ctx)) != NID_undef) { 783e1051a39Sopenharmony_ci /* 784e1051a39Sopenharmony_ci * The input explicit parameters successfully matched one of the 785e1051a39Sopenharmony_ci * built-in curves: often for built-in curves we have specialized 786e1051a39Sopenharmony_ci * methods with better performance and hardening. 787e1051a39Sopenharmony_ci * 788e1051a39Sopenharmony_ci * In this case we replace the `EC_GROUP` created through explicit 789e1051a39Sopenharmony_ci * parameters with one created from a named group. 790e1051a39Sopenharmony_ci */ 791e1051a39Sopenharmony_ci EC_GROUP *named_group = NULL; 792e1051a39Sopenharmony_ci 793e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 794e1051a39Sopenharmony_ci /* 795e1051a39Sopenharmony_ci * NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for 796e1051a39Sopenharmony_ci * the same curve, we prefer the SECP nid when matching explicit 797e1051a39Sopenharmony_ci * parameters as that is associated with a specialized EC_METHOD. 798e1051a39Sopenharmony_ci */ 799e1051a39Sopenharmony_ci if (curve_name == NID_wap_wsg_idm_ecid_wtls12) 800e1051a39Sopenharmony_ci curve_name = NID_secp224r1; 801e1051a39Sopenharmony_ci#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */ 802e1051a39Sopenharmony_ci 803e1051a39Sopenharmony_ci if ((named_group = EC_GROUP_new_by_curve_name(curve_name)) == NULL) { 804e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 805e1051a39Sopenharmony_ci goto err; 806e1051a39Sopenharmony_ci } 807e1051a39Sopenharmony_ci EC_GROUP_free(ret); 808e1051a39Sopenharmony_ci ret = named_group; 809e1051a39Sopenharmony_ci 810e1051a39Sopenharmony_ci /* 811e1051a39Sopenharmony_ci * Set the flag so that EC_GROUPs created from explicit parameters are 812e1051a39Sopenharmony_ci * serialized using explicit parameters by default. 813e1051a39Sopenharmony_ci */ 814e1051a39Sopenharmony_ci EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE); 815e1051a39Sopenharmony_ci 816e1051a39Sopenharmony_ci /* 817e1051a39Sopenharmony_ci * If the input params do not contain the optional seed field we make 818e1051a39Sopenharmony_ci * sure it is not added to the returned group. 819e1051a39Sopenharmony_ci * 820e1051a39Sopenharmony_ci * The seed field is not really used inside libcrypto anyway, and 821e1051a39Sopenharmony_ci * adding it to parsed explicit parameter keys would alter their DER 822e1051a39Sopenharmony_ci * encoding output (because of the extra field) which could impact 823e1051a39Sopenharmony_ci * applications fingerprinting keys by their DER encoding. 824e1051a39Sopenharmony_ci */ 825e1051a39Sopenharmony_ci if (params->curve->seed == NULL) { 826e1051a39Sopenharmony_ci if (EC_GROUP_set_seed(ret, NULL, 0) != 1) 827e1051a39Sopenharmony_ci goto err; 828e1051a39Sopenharmony_ci } 829e1051a39Sopenharmony_ci } 830e1051a39Sopenharmony_ci 831e1051a39Sopenharmony_ci ok = 1; 832e1051a39Sopenharmony_ci 833e1051a39Sopenharmony_ci err: 834e1051a39Sopenharmony_ci if (!ok) { 835e1051a39Sopenharmony_ci EC_GROUP_free(ret); 836e1051a39Sopenharmony_ci ret = NULL; 837e1051a39Sopenharmony_ci } 838e1051a39Sopenharmony_ci EC_GROUP_free(dup); 839e1051a39Sopenharmony_ci 840e1051a39Sopenharmony_ci BN_free(p); 841e1051a39Sopenharmony_ci BN_free(a); 842e1051a39Sopenharmony_ci BN_free(b); 843e1051a39Sopenharmony_ci EC_POINT_free(point); 844e1051a39Sopenharmony_ci 845e1051a39Sopenharmony_ci BN_CTX_free(ctx); 846e1051a39Sopenharmony_ci 847e1051a39Sopenharmony_ci return ret; 848e1051a39Sopenharmony_ci} 849e1051a39Sopenharmony_ci 850e1051a39Sopenharmony_ciEC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params) 851e1051a39Sopenharmony_ci{ 852e1051a39Sopenharmony_ci EC_GROUP *ret = NULL; 853e1051a39Sopenharmony_ci int tmp = 0; 854e1051a39Sopenharmony_ci 855e1051a39Sopenharmony_ci if (params == NULL) { 856e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS); 857e1051a39Sopenharmony_ci return NULL; 858e1051a39Sopenharmony_ci } 859e1051a39Sopenharmony_ci 860e1051a39Sopenharmony_ci if (params->type == ECPKPARAMETERS_TYPE_NAMED) { 861e1051a39Sopenharmony_ci /* the curve is given by an OID */ 862e1051a39Sopenharmony_ci tmp = OBJ_obj2nid(params->value.named_curve); 863e1051a39Sopenharmony_ci if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { 864e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 865e1051a39Sopenharmony_ci return NULL; 866e1051a39Sopenharmony_ci } 867e1051a39Sopenharmony_ci EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); 868e1051a39Sopenharmony_ci } else if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT) { 869e1051a39Sopenharmony_ci /* the parameters are given by an ECPARAMETERS structure */ 870e1051a39Sopenharmony_ci ret = EC_GROUP_new_from_ecparameters(params->value.parameters); 871e1051a39Sopenharmony_ci if (!ret) { 872e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 873e1051a39Sopenharmony_ci return NULL; 874e1051a39Sopenharmony_ci } 875e1051a39Sopenharmony_ci EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE); 876e1051a39Sopenharmony_ci } else if (params->type == ECPKPARAMETERS_TYPE_IMPLICIT) { 877e1051a39Sopenharmony_ci /* implicit parameters inherited from CA - unsupported */ 878e1051a39Sopenharmony_ci return NULL; 879e1051a39Sopenharmony_ci } else { 880e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); 881e1051a39Sopenharmony_ci return NULL; 882e1051a39Sopenharmony_ci } 883e1051a39Sopenharmony_ci 884e1051a39Sopenharmony_ci return ret; 885e1051a39Sopenharmony_ci} 886e1051a39Sopenharmony_ci 887e1051a39Sopenharmony_ci/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */ 888e1051a39Sopenharmony_ci 889e1051a39Sopenharmony_ciEC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) 890e1051a39Sopenharmony_ci{ 891e1051a39Sopenharmony_ci EC_GROUP *group = NULL; 892e1051a39Sopenharmony_ci ECPKPARAMETERS *params = NULL; 893e1051a39Sopenharmony_ci const unsigned char *p = *in; 894e1051a39Sopenharmony_ci 895e1051a39Sopenharmony_ci if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) { 896e1051a39Sopenharmony_ci ECPKPARAMETERS_free(params); 897e1051a39Sopenharmony_ci return NULL; 898e1051a39Sopenharmony_ci } 899e1051a39Sopenharmony_ci 900e1051a39Sopenharmony_ci if ((group = EC_GROUP_new_from_ecpkparameters(params)) == NULL) { 901e1051a39Sopenharmony_ci ECPKPARAMETERS_free(params); 902e1051a39Sopenharmony_ci return NULL; 903e1051a39Sopenharmony_ci } 904e1051a39Sopenharmony_ci 905e1051a39Sopenharmony_ci if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT) 906e1051a39Sopenharmony_ci group->decoded_from_explicit_params = 1; 907e1051a39Sopenharmony_ci 908e1051a39Sopenharmony_ci if (a) { 909e1051a39Sopenharmony_ci EC_GROUP_free(*a); 910e1051a39Sopenharmony_ci *a = group; 911e1051a39Sopenharmony_ci } 912e1051a39Sopenharmony_ci 913e1051a39Sopenharmony_ci ECPKPARAMETERS_free(params); 914e1051a39Sopenharmony_ci *in = p; 915e1051a39Sopenharmony_ci return group; 916e1051a39Sopenharmony_ci} 917e1051a39Sopenharmony_ci 918e1051a39Sopenharmony_ciint i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) 919e1051a39Sopenharmony_ci{ 920e1051a39Sopenharmony_ci int ret = 0; 921e1051a39Sopenharmony_ci ECPKPARAMETERS *tmp = EC_GROUP_get_ecpkparameters(a, NULL); 922e1051a39Sopenharmony_ci if (tmp == NULL) { 923e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_GROUP2PKPARAMETERS_FAILURE); 924e1051a39Sopenharmony_ci return 0; 925e1051a39Sopenharmony_ci } 926e1051a39Sopenharmony_ci if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) { 927e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_I2D_ECPKPARAMETERS_FAILURE); 928e1051a39Sopenharmony_ci ECPKPARAMETERS_free(tmp); 929e1051a39Sopenharmony_ci return 0; 930e1051a39Sopenharmony_ci } 931e1051a39Sopenharmony_ci ECPKPARAMETERS_free(tmp); 932e1051a39Sopenharmony_ci return ret; 933e1051a39Sopenharmony_ci} 934e1051a39Sopenharmony_ci 935e1051a39Sopenharmony_ci/* some EC_KEY functions */ 936e1051a39Sopenharmony_ci 937e1051a39Sopenharmony_ciEC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) 938e1051a39Sopenharmony_ci{ 939e1051a39Sopenharmony_ci EC_KEY *ret = NULL; 940e1051a39Sopenharmony_ci EC_PRIVATEKEY *priv_key = NULL; 941e1051a39Sopenharmony_ci const unsigned char *p = *in; 942e1051a39Sopenharmony_ci 943e1051a39Sopenharmony_ci if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) 944e1051a39Sopenharmony_ci return NULL; 945e1051a39Sopenharmony_ci 946e1051a39Sopenharmony_ci if (a == NULL || *a == NULL) { 947e1051a39Sopenharmony_ci if ((ret = EC_KEY_new()) == NULL) { 948e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 949e1051a39Sopenharmony_ci goto err; 950e1051a39Sopenharmony_ci } 951e1051a39Sopenharmony_ci } else 952e1051a39Sopenharmony_ci ret = *a; 953e1051a39Sopenharmony_ci 954e1051a39Sopenharmony_ci if (priv_key->parameters) { 955e1051a39Sopenharmony_ci EC_GROUP_free(ret->group); 956e1051a39Sopenharmony_ci ret->group = EC_GROUP_new_from_ecpkparameters(priv_key->parameters); 957e1051a39Sopenharmony_ci if (ret->group != NULL 958e1051a39Sopenharmony_ci && priv_key->parameters->type == ECPKPARAMETERS_TYPE_EXPLICIT) 959e1051a39Sopenharmony_ci ret->group->decoded_from_explicit_params = 1; 960e1051a39Sopenharmony_ci } 961e1051a39Sopenharmony_ci 962e1051a39Sopenharmony_ci if (ret->group == NULL) { 963e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 964e1051a39Sopenharmony_ci goto err; 965e1051a39Sopenharmony_ci } 966e1051a39Sopenharmony_ci 967e1051a39Sopenharmony_ci ret->version = priv_key->version; 968e1051a39Sopenharmony_ci 969e1051a39Sopenharmony_ci if (priv_key->privateKey) { 970e1051a39Sopenharmony_ci ASN1_OCTET_STRING *pkey = priv_key->privateKey; 971e1051a39Sopenharmony_ci if (EC_KEY_oct2priv(ret, ASN1_STRING_get0_data(pkey), 972e1051a39Sopenharmony_ci ASN1_STRING_length(pkey)) == 0) 973e1051a39Sopenharmony_ci goto err; 974e1051a39Sopenharmony_ci } else { 975e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY); 976e1051a39Sopenharmony_ci goto err; 977e1051a39Sopenharmony_ci } 978e1051a39Sopenharmony_ci 979e1051a39Sopenharmony_ci if (EC_GROUP_get_curve_name(ret->group) == NID_sm2) 980e1051a39Sopenharmony_ci EC_KEY_set_flags(ret, EC_FLAG_SM2_RANGE); 981e1051a39Sopenharmony_ci 982e1051a39Sopenharmony_ci EC_POINT_clear_free(ret->pub_key); 983e1051a39Sopenharmony_ci ret->pub_key = EC_POINT_new(ret->group); 984e1051a39Sopenharmony_ci if (ret->pub_key == NULL) { 985e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 986e1051a39Sopenharmony_ci goto err; 987e1051a39Sopenharmony_ci } 988e1051a39Sopenharmony_ci 989e1051a39Sopenharmony_ci if (priv_key->publicKey) { 990e1051a39Sopenharmony_ci const unsigned char *pub_oct; 991e1051a39Sopenharmony_ci int pub_oct_len; 992e1051a39Sopenharmony_ci 993e1051a39Sopenharmony_ci pub_oct = ASN1_STRING_get0_data(priv_key->publicKey); 994e1051a39Sopenharmony_ci pub_oct_len = ASN1_STRING_length(priv_key->publicKey); 995e1051a39Sopenharmony_ci if (!EC_KEY_oct2key(ret, pub_oct, pub_oct_len, NULL)) { 996e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 997e1051a39Sopenharmony_ci goto err; 998e1051a39Sopenharmony_ci } 999e1051a39Sopenharmony_ci } else { 1000e1051a39Sopenharmony_ci if (ret->group->meth->keygenpub == NULL 1001e1051a39Sopenharmony_ci || ret->group->meth->keygenpub(ret) == 0) 1002e1051a39Sopenharmony_ci goto err; 1003e1051a39Sopenharmony_ci /* Remember the original private-key-only encoding. */ 1004e1051a39Sopenharmony_ci ret->enc_flag |= EC_PKEY_NO_PUBKEY; 1005e1051a39Sopenharmony_ci } 1006e1051a39Sopenharmony_ci 1007e1051a39Sopenharmony_ci if (a) 1008e1051a39Sopenharmony_ci *a = ret; 1009e1051a39Sopenharmony_ci EC_PRIVATEKEY_free(priv_key); 1010e1051a39Sopenharmony_ci *in = p; 1011e1051a39Sopenharmony_ci ret->dirty_cnt++; 1012e1051a39Sopenharmony_ci return ret; 1013e1051a39Sopenharmony_ci 1014e1051a39Sopenharmony_ci err: 1015e1051a39Sopenharmony_ci if (a == NULL || *a != ret) 1016e1051a39Sopenharmony_ci EC_KEY_free(ret); 1017e1051a39Sopenharmony_ci EC_PRIVATEKEY_free(priv_key); 1018e1051a39Sopenharmony_ci return NULL; 1019e1051a39Sopenharmony_ci} 1020e1051a39Sopenharmony_ci 1021e1051a39Sopenharmony_ciint i2d_ECPrivateKey(const EC_KEY *a, unsigned char **out) 1022e1051a39Sopenharmony_ci{ 1023e1051a39Sopenharmony_ci int ret = 0, ok = 0; 1024e1051a39Sopenharmony_ci unsigned char *priv= NULL, *pub= NULL; 1025e1051a39Sopenharmony_ci size_t privlen = 0, publen = 0; 1026e1051a39Sopenharmony_ci 1027e1051a39Sopenharmony_ci EC_PRIVATEKEY *priv_key = NULL; 1028e1051a39Sopenharmony_ci 1029e1051a39Sopenharmony_ci if (a == NULL || a->group == NULL || 1030e1051a39Sopenharmony_ci (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { 1031e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 1032e1051a39Sopenharmony_ci goto err; 1033e1051a39Sopenharmony_ci } 1034e1051a39Sopenharmony_ci 1035e1051a39Sopenharmony_ci if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { 1036e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 1037e1051a39Sopenharmony_ci goto err; 1038e1051a39Sopenharmony_ci } 1039e1051a39Sopenharmony_ci 1040e1051a39Sopenharmony_ci priv_key->version = a->version; 1041e1051a39Sopenharmony_ci 1042e1051a39Sopenharmony_ci privlen = EC_KEY_priv2buf(a, &priv); 1043e1051a39Sopenharmony_ci 1044e1051a39Sopenharmony_ci if (privlen == 0) { 1045e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 1046e1051a39Sopenharmony_ci goto err; 1047e1051a39Sopenharmony_ci } 1048e1051a39Sopenharmony_ci 1049e1051a39Sopenharmony_ci ASN1_STRING_set0(priv_key->privateKey, priv, privlen); 1050e1051a39Sopenharmony_ci priv = NULL; 1051e1051a39Sopenharmony_ci 1052e1051a39Sopenharmony_ci if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) { 1053e1051a39Sopenharmony_ci if ((priv_key->parameters = 1054e1051a39Sopenharmony_ci EC_GROUP_get_ecpkparameters(a->group, 1055e1051a39Sopenharmony_ci priv_key->parameters)) == NULL) { 1056e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 1057e1051a39Sopenharmony_ci goto err; 1058e1051a39Sopenharmony_ci } 1059e1051a39Sopenharmony_ci } 1060e1051a39Sopenharmony_ci 1061e1051a39Sopenharmony_ci if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) { 1062e1051a39Sopenharmony_ci priv_key->publicKey = ASN1_BIT_STRING_new(); 1063e1051a39Sopenharmony_ci if (priv_key->publicKey == NULL) { 1064e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 1065e1051a39Sopenharmony_ci goto err; 1066e1051a39Sopenharmony_ci } 1067e1051a39Sopenharmony_ci 1068e1051a39Sopenharmony_ci publen = EC_KEY_key2buf(a, a->conv_form, &pub, NULL); 1069e1051a39Sopenharmony_ci 1070e1051a39Sopenharmony_ci if (publen == 0) { 1071e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 1072e1051a39Sopenharmony_ci goto err; 1073e1051a39Sopenharmony_ci } 1074e1051a39Sopenharmony_ci 1075e1051a39Sopenharmony_ci priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 1076e1051a39Sopenharmony_ci priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; 1077e1051a39Sopenharmony_ci ASN1_STRING_set0(priv_key->publicKey, pub, publen); 1078e1051a39Sopenharmony_ci pub = NULL; 1079e1051a39Sopenharmony_ci } 1080e1051a39Sopenharmony_ci 1081e1051a39Sopenharmony_ci if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) { 1082e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 1083e1051a39Sopenharmony_ci goto err; 1084e1051a39Sopenharmony_ci } 1085e1051a39Sopenharmony_ci ok = 1; 1086e1051a39Sopenharmony_ci err: 1087e1051a39Sopenharmony_ci OPENSSL_clear_free(priv, privlen); 1088e1051a39Sopenharmony_ci OPENSSL_free(pub); 1089e1051a39Sopenharmony_ci EC_PRIVATEKEY_free(priv_key); 1090e1051a39Sopenharmony_ci return (ok ? ret : 0); 1091e1051a39Sopenharmony_ci} 1092e1051a39Sopenharmony_ci 1093e1051a39Sopenharmony_ciint i2d_ECParameters(const EC_KEY *a, unsigned char **out) 1094e1051a39Sopenharmony_ci{ 1095e1051a39Sopenharmony_ci if (a == NULL) { 1096e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 1097e1051a39Sopenharmony_ci return 0; 1098e1051a39Sopenharmony_ci } 1099e1051a39Sopenharmony_ci return i2d_ECPKParameters(a->group, out); 1100e1051a39Sopenharmony_ci} 1101e1051a39Sopenharmony_ci 1102e1051a39Sopenharmony_ciEC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) 1103e1051a39Sopenharmony_ci{ 1104e1051a39Sopenharmony_ci EC_KEY *ret; 1105e1051a39Sopenharmony_ci 1106e1051a39Sopenharmony_ci if (in == NULL || *in == NULL) { 1107e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 1108e1051a39Sopenharmony_ci return NULL; 1109e1051a39Sopenharmony_ci } 1110e1051a39Sopenharmony_ci 1111e1051a39Sopenharmony_ci if (a == NULL || *a == NULL) { 1112e1051a39Sopenharmony_ci if ((ret = EC_KEY_new()) == NULL) { 1113e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 1114e1051a39Sopenharmony_ci return NULL; 1115e1051a39Sopenharmony_ci } 1116e1051a39Sopenharmony_ci } else 1117e1051a39Sopenharmony_ci ret = *a; 1118e1051a39Sopenharmony_ci 1119e1051a39Sopenharmony_ci if (!d2i_ECPKParameters(&ret->group, in, len)) { 1120e1051a39Sopenharmony_ci if (a == NULL || *a != ret) 1121e1051a39Sopenharmony_ci EC_KEY_free(ret); 1122e1051a39Sopenharmony_ci else 1123e1051a39Sopenharmony_ci ret->dirty_cnt++; 1124e1051a39Sopenharmony_ci return NULL; 1125e1051a39Sopenharmony_ci } 1126e1051a39Sopenharmony_ci 1127e1051a39Sopenharmony_ci if (EC_GROUP_get_curve_name(ret->group) == NID_sm2) 1128e1051a39Sopenharmony_ci EC_KEY_set_flags(ret, EC_FLAG_SM2_RANGE); 1129e1051a39Sopenharmony_ci 1130e1051a39Sopenharmony_ci ret->dirty_cnt++; 1131e1051a39Sopenharmony_ci 1132e1051a39Sopenharmony_ci if (a) 1133e1051a39Sopenharmony_ci *a = ret; 1134e1051a39Sopenharmony_ci 1135e1051a39Sopenharmony_ci return ret; 1136e1051a39Sopenharmony_ci} 1137e1051a39Sopenharmony_ci 1138e1051a39Sopenharmony_ciEC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) 1139e1051a39Sopenharmony_ci{ 1140e1051a39Sopenharmony_ci EC_KEY *ret = NULL; 1141e1051a39Sopenharmony_ci 1142e1051a39Sopenharmony_ci if (a == NULL || (*a) == NULL || (*a)->group == NULL) { 1143e1051a39Sopenharmony_ci /* 1144e1051a39Sopenharmony_ci * sorry, but a EC_GROUP-structure is necessary to set the public key 1145e1051a39Sopenharmony_ci */ 1146e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 1147e1051a39Sopenharmony_ci return 0; 1148e1051a39Sopenharmony_ci } 1149e1051a39Sopenharmony_ci ret = *a; 1150e1051a39Sopenharmony_ci /* EC_KEY_opt2key updates dirty_cnt */ 1151e1051a39Sopenharmony_ci if (!EC_KEY_oct2key(ret, *in, len, NULL)) { 1152e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 1153e1051a39Sopenharmony_ci return 0; 1154e1051a39Sopenharmony_ci } 1155e1051a39Sopenharmony_ci *in += len; 1156e1051a39Sopenharmony_ci return ret; 1157e1051a39Sopenharmony_ci} 1158e1051a39Sopenharmony_ci 1159e1051a39Sopenharmony_ciint i2o_ECPublicKey(const EC_KEY *a, unsigned char **out) 1160e1051a39Sopenharmony_ci{ 1161e1051a39Sopenharmony_ci size_t buf_len = 0; 1162e1051a39Sopenharmony_ci int new_buffer = 0; 1163e1051a39Sopenharmony_ci 1164e1051a39Sopenharmony_ci if (a == NULL || a->pub_key == NULL) { 1165e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 1166e1051a39Sopenharmony_ci return 0; 1167e1051a39Sopenharmony_ci } 1168e1051a39Sopenharmony_ci 1169e1051a39Sopenharmony_ci buf_len = EC_POINT_point2oct(a->group, a->pub_key, 1170e1051a39Sopenharmony_ci a->conv_form, NULL, 0, NULL); 1171e1051a39Sopenharmony_ci 1172e1051a39Sopenharmony_ci if (out == NULL || buf_len == 0) 1173e1051a39Sopenharmony_ci /* out == NULL => just return the length of the octet string */ 1174e1051a39Sopenharmony_ci return buf_len; 1175e1051a39Sopenharmony_ci 1176e1051a39Sopenharmony_ci if (*out == NULL) { 1177e1051a39Sopenharmony_ci if ((*out = OPENSSL_malloc(buf_len)) == NULL) { 1178e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 1179e1051a39Sopenharmony_ci return 0; 1180e1051a39Sopenharmony_ci } 1181e1051a39Sopenharmony_ci new_buffer = 1; 1182e1051a39Sopenharmony_ci } 1183e1051a39Sopenharmony_ci if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, 1184e1051a39Sopenharmony_ci *out, buf_len, NULL)) { 1185e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 1186e1051a39Sopenharmony_ci if (new_buffer) { 1187e1051a39Sopenharmony_ci OPENSSL_free(*out); 1188e1051a39Sopenharmony_ci *out = NULL; 1189e1051a39Sopenharmony_ci } 1190e1051a39Sopenharmony_ci return 0; 1191e1051a39Sopenharmony_ci } 1192e1051a39Sopenharmony_ci if (!new_buffer) 1193e1051a39Sopenharmony_ci *out += buf_len; 1194e1051a39Sopenharmony_ci return buf_len; 1195e1051a39Sopenharmony_ci} 1196e1051a39Sopenharmony_ci 1197e1051a39Sopenharmony_ciDECLARE_ASN1_FUNCTIONS(ECDSA_SIG) 1198e1051a39Sopenharmony_ciDECLARE_ASN1_ENCODE_FUNCTIONS_name(ECDSA_SIG, ECDSA_SIG) 1199e1051a39Sopenharmony_ci 1200e1051a39Sopenharmony_ci#endif /* FIPS_MODULE */ 1201e1051a39Sopenharmony_ci 1202e1051a39Sopenharmony_ciECDSA_SIG *ECDSA_SIG_new(void) 1203e1051a39Sopenharmony_ci{ 1204e1051a39Sopenharmony_ci ECDSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); 1205e1051a39Sopenharmony_ci if (sig == NULL) 1206e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 1207e1051a39Sopenharmony_ci return sig; 1208e1051a39Sopenharmony_ci} 1209e1051a39Sopenharmony_ci 1210e1051a39Sopenharmony_civoid ECDSA_SIG_free(ECDSA_SIG *sig) 1211e1051a39Sopenharmony_ci{ 1212e1051a39Sopenharmony_ci if (sig == NULL) 1213e1051a39Sopenharmony_ci return; 1214e1051a39Sopenharmony_ci BN_clear_free(sig->r); 1215e1051a39Sopenharmony_ci BN_clear_free(sig->s); 1216e1051a39Sopenharmony_ci OPENSSL_free(sig); 1217e1051a39Sopenharmony_ci} 1218e1051a39Sopenharmony_ci 1219e1051a39Sopenharmony_ciECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **psig, const unsigned char **ppin, long len) 1220e1051a39Sopenharmony_ci{ 1221e1051a39Sopenharmony_ci ECDSA_SIG *sig; 1222e1051a39Sopenharmony_ci 1223e1051a39Sopenharmony_ci if (len < 0) 1224e1051a39Sopenharmony_ci return NULL; 1225e1051a39Sopenharmony_ci if (psig != NULL && *psig != NULL) { 1226e1051a39Sopenharmony_ci sig = *psig; 1227e1051a39Sopenharmony_ci } else { 1228e1051a39Sopenharmony_ci sig = ECDSA_SIG_new(); 1229e1051a39Sopenharmony_ci if (sig == NULL) 1230e1051a39Sopenharmony_ci return NULL; 1231e1051a39Sopenharmony_ci } 1232e1051a39Sopenharmony_ci if (sig->r == NULL) 1233e1051a39Sopenharmony_ci sig->r = BN_new(); 1234e1051a39Sopenharmony_ci if (sig->s == NULL) 1235e1051a39Sopenharmony_ci sig->s = BN_new(); 1236e1051a39Sopenharmony_ci if (sig->r == NULL || sig->s == NULL 1237e1051a39Sopenharmony_ci || ossl_decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { 1238e1051a39Sopenharmony_ci if (psig == NULL || *psig == NULL) 1239e1051a39Sopenharmony_ci ECDSA_SIG_free(sig); 1240e1051a39Sopenharmony_ci return NULL; 1241e1051a39Sopenharmony_ci } 1242e1051a39Sopenharmony_ci if (psig != NULL && *psig == NULL) 1243e1051a39Sopenharmony_ci *psig = sig; 1244e1051a39Sopenharmony_ci return sig; 1245e1051a39Sopenharmony_ci} 1246e1051a39Sopenharmony_ci 1247e1051a39Sopenharmony_ciint i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **ppout) 1248e1051a39Sopenharmony_ci{ 1249e1051a39Sopenharmony_ci BUF_MEM *buf = NULL; 1250e1051a39Sopenharmony_ci size_t encoded_len; 1251e1051a39Sopenharmony_ci WPACKET pkt; 1252e1051a39Sopenharmony_ci 1253e1051a39Sopenharmony_ci if (ppout == NULL) { 1254e1051a39Sopenharmony_ci if (!WPACKET_init_null(&pkt, 0)) 1255e1051a39Sopenharmony_ci return -1; 1256e1051a39Sopenharmony_ci } else if (*ppout == NULL) { 1257e1051a39Sopenharmony_ci if ((buf = BUF_MEM_new()) == NULL 1258e1051a39Sopenharmony_ci || !WPACKET_init_len(&pkt, buf, 0)) { 1259e1051a39Sopenharmony_ci BUF_MEM_free(buf); 1260e1051a39Sopenharmony_ci return -1; 1261e1051a39Sopenharmony_ci } 1262e1051a39Sopenharmony_ci } else { 1263e1051a39Sopenharmony_ci if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0)) 1264e1051a39Sopenharmony_ci return -1; 1265e1051a39Sopenharmony_ci } 1266e1051a39Sopenharmony_ci 1267e1051a39Sopenharmony_ci if (!ossl_encode_der_dsa_sig(&pkt, sig->r, sig->s) 1268e1051a39Sopenharmony_ci || !WPACKET_get_total_written(&pkt, &encoded_len) 1269e1051a39Sopenharmony_ci || !WPACKET_finish(&pkt)) { 1270e1051a39Sopenharmony_ci BUF_MEM_free(buf); 1271e1051a39Sopenharmony_ci WPACKET_cleanup(&pkt); 1272e1051a39Sopenharmony_ci return -1; 1273e1051a39Sopenharmony_ci } 1274e1051a39Sopenharmony_ci 1275e1051a39Sopenharmony_ci if (ppout != NULL) { 1276e1051a39Sopenharmony_ci if (*ppout == NULL) { 1277e1051a39Sopenharmony_ci *ppout = (unsigned char *)buf->data; 1278e1051a39Sopenharmony_ci buf->data = NULL; 1279e1051a39Sopenharmony_ci BUF_MEM_free(buf); 1280e1051a39Sopenharmony_ci } else { 1281e1051a39Sopenharmony_ci *ppout += encoded_len; 1282e1051a39Sopenharmony_ci } 1283e1051a39Sopenharmony_ci } 1284e1051a39Sopenharmony_ci 1285e1051a39Sopenharmony_ci return (int)encoded_len; 1286e1051a39Sopenharmony_ci} 1287e1051a39Sopenharmony_ci 1288e1051a39Sopenharmony_civoid ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) 1289e1051a39Sopenharmony_ci{ 1290e1051a39Sopenharmony_ci if (pr != NULL) 1291e1051a39Sopenharmony_ci *pr = sig->r; 1292e1051a39Sopenharmony_ci if (ps != NULL) 1293e1051a39Sopenharmony_ci *ps = sig->s; 1294e1051a39Sopenharmony_ci} 1295e1051a39Sopenharmony_ci 1296e1051a39Sopenharmony_ciconst BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig) 1297e1051a39Sopenharmony_ci{ 1298e1051a39Sopenharmony_ci return sig->r; 1299e1051a39Sopenharmony_ci} 1300e1051a39Sopenharmony_ci 1301e1051a39Sopenharmony_ciconst BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig) 1302e1051a39Sopenharmony_ci{ 1303e1051a39Sopenharmony_ci return sig->s; 1304e1051a39Sopenharmony_ci} 1305e1051a39Sopenharmony_ci 1306e1051a39Sopenharmony_ciint ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) 1307e1051a39Sopenharmony_ci{ 1308e1051a39Sopenharmony_ci if (r == NULL || s == NULL) 1309e1051a39Sopenharmony_ci return 0; 1310e1051a39Sopenharmony_ci BN_clear_free(sig->r); 1311e1051a39Sopenharmony_ci BN_clear_free(sig->s); 1312e1051a39Sopenharmony_ci sig->r = r; 1313e1051a39Sopenharmony_ci sig->s = s; 1314e1051a39Sopenharmony_ci return 1; 1315e1051a39Sopenharmony_ci} 1316e1051a39Sopenharmony_ci 1317e1051a39Sopenharmony_ciint ECDSA_size(const EC_KEY *ec) 1318e1051a39Sopenharmony_ci{ 1319e1051a39Sopenharmony_ci int ret; 1320e1051a39Sopenharmony_ci ECDSA_SIG sig; 1321e1051a39Sopenharmony_ci const EC_GROUP *group; 1322e1051a39Sopenharmony_ci const BIGNUM *bn; 1323e1051a39Sopenharmony_ci 1324e1051a39Sopenharmony_ci if (ec == NULL) 1325e1051a39Sopenharmony_ci return 0; 1326e1051a39Sopenharmony_ci group = EC_KEY_get0_group(ec); 1327e1051a39Sopenharmony_ci if (group == NULL) 1328e1051a39Sopenharmony_ci return 0; 1329e1051a39Sopenharmony_ci 1330e1051a39Sopenharmony_ci bn = EC_GROUP_get0_order(group); 1331e1051a39Sopenharmony_ci if (bn == NULL) 1332e1051a39Sopenharmony_ci return 0; 1333e1051a39Sopenharmony_ci 1334e1051a39Sopenharmony_ci sig.r = sig.s = (BIGNUM *)bn; 1335e1051a39Sopenharmony_ci ret = i2d_ECDSA_SIG(&sig, NULL); 1336e1051a39Sopenharmony_ci 1337e1051a39Sopenharmony_ci if (ret < 0) 1338e1051a39Sopenharmony_ci ret = 0; 1339e1051a39Sopenharmony_ci return ret; 1340e1051a39Sopenharmony_ci} 1341