1160814Ssimon/* crypto/ec/ec_asn1.c */ 2160814Ssimon/* 3160814Ssimon * Written by Nils Larsch for the OpenSSL project. 4160814Ssimon */ 5160814Ssimon/* ==================================================================== 6160814Ssimon * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. 7160814Ssimon * 8160814Ssimon * Redistribution and use in source and binary forms, with or without 9160814Ssimon * modification, are permitted provided that the following conditions 10160814Ssimon * are met: 11160814Ssimon * 12160814Ssimon * 1. Redistributions of source code must retain the above copyright 13160814Ssimon * notice, this list of conditions and the following disclaimer. 14160814Ssimon * 15160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 16160814Ssimon * notice, this list of conditions and the following disclaimer in 17160814Ssimon * the documentation and/or other materials provided with the 18160814Ssimon * distribution. 19160814Ssimon * 20160814Ssimon * 3. All advertising materials mentioning features or use of this 21160814Ssimon * software must display the following acknowledgment: 22160814Ssimon * "This product includes software developed by the OpenSSL Project 23160814Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24160814Ssimon * 25160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26160814Ssimon * endorse or promote products derived from this software without 27160814Ssimon * prior written permission. For written permission, please contact 28160814Ssimon * licensing@OpenSSL.org. 29160814Ssimon * 30160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 31160814Ssimon * nor may "OpenSSL" appear in their names without prior written 32160814Ssimon * permission of the OpenSSL Project. 33160814Ssimon * 34160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 35160814Ssimon * acknowledgment: 36160814Ssimon * "This product includes software developed by the OpenSSL Project 37160814Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38160814Ssimon * 39160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 51160814Ssimon * ==================================================================== 52160814Ssimon * 53160814Ssimon * This product includes cryptographic software written by Eric Young 54160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 55160814Ssimon * Hudson (tjh@cryptsoft.com). 56160814Ssimon * 57160814Ssimon */ 58160814Ssimon 59160814Ssimon#include <string.h> 60160814Ssimon#include "ec_lcl.h" 61160814Ssimon#include <openssl/err.h> 62160814Ssimon#include <openssl/asn1t.h> 63160814Ssimon#include <openssl/objects.h> 64160814Ssimon 65160814Ssimon 66160814Ssimonint EC_GROUP_get_basis_type(const EC_GROUP *group) 67160814Ssimon { 68160814Ssimon int i=0; 69160814Ssimon 70160814Ssimon if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 71160814Ssimon NID_X9_62_characteristic_two_field) 72160814Ssimon /* everything else is currently not supported */ 73160814Ssimon return 0; 74160814Ssimon 75160814Ssimon while (group->poly[i] != 0) 76160814Ssimon i++; 77160814Ssimon 78160814Ssimon if (i == 4) 79160814Ssimon return NID_X9_62_ppBasis; 80160814Ssimon else if (i == 2) 81160814Ssimon return NID_X9_62_tpBasis; 82160814Ssimon else 83160814Ssimon /* everything else is currently not supported */ 84160814Ssimon return 0; 85160814Ssimon } 86238405Sjkim#ifndef OPENSSL_NO_EC2M 87160814Ssimonint EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) 88160814Ssimon { 89160814Ssimon if (group == NULL) 90160814Ssimon return 0; 91160814Ssimon 92279264Sdelphij if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 93279264Sdelphij NID_X9_62_characteristic_two_field 94160814Ssimon || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0))) 95160814Ssimon { 96160814Ssimon ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 97160814Ssimon return 0; 98160814Ssimon } 99160814Ssimon 100160814Ssimon if (k) 101160814Ssimon *k = group->poly[1]; 102160814Ssimon 103160814Ssimon return 1; 104160814Ssimon } 105160814Ssimonint EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, 106160814Ssimon unsigned int *k2, unsigned int *k3) 107160814Ssimon { 108160814Ssimon if (group == NULL) 109160814Ssimon return 0; 110160814Ssimon 111279264Sdelphij if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 112279264Sdelphij NID_X9_62_characteristic_two_field 113160814Ssimon || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0))) 114160814Ssimon { 115160814Ssimon ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 116160814Ssimon return 0; 117160814Ssimon } 118160814Ssimon 119160814Ssimon if (k1) 120160814Ssimon *k1 = group->poly[3]; 121160814Ssimon if (k2) 122160814Ssimon *k2 = group->poly[2]; 123160814Ssimon if (k3) 124160814Ssimon *k3 = group->poly[1]; 125160814Ssimon 126160814Ssimon return 1; 127160814Ssimon } 128238405Sjkim#endif 129160814Ssimon 130160814Ssimon 131160814Ssimon/* some structures needed for the asn1 encoding */ 132160814Ssimontypedef struct x9_62_pentanomial_st { 133160814Ssimon long k1; 134160814Ssimon long k2; 135160814Ssimon long k3; 136160814Ssimon } X9_62_PENTANOMIAL; 137160814Ssimon 138160814Ssimontypedef struct x9_62_characteristic_two_st { 139160814Ssimon long m; 140160814Ssimon ASN1_OBJECT *type; 141160814Ssimon union { 142160814Ssimon char *ptr; 143160814Ssimon /* NID_X9_62_onBasis */ 144160814Ssimon ASN1_NULL *onBasis; 145160814Ssimon /* NID_X9_62_tpBasis */ 146160814Ssimon ASN1_INTEGER *tpBasis; 147160814Ssimon /* NID_X9_62_ppBasis */ 148160814Ssimon X9_62_PENTANOMIAL *ppBasis; 149160814Ssimon /* anything else */ 150160814Ssimon ASN1_TYPE *other; 151160814Ssimon } p; 152160814Ssimon } X9_62_CHARACTERISTIC_TWO; 153160814Ssimon 154160814Ssimontypedef struct x9_62_fieldid_st { 155160814Ssimon ASN1_OBJECT *fieldType; 156160814Ssimon union { 157160814Ssimon char *ptr; 158160814Ssimon /* NID_X9_62_prime_field */ 159160814Ssimon ASN1_INTEGER *prime; 160160814Ssimon /* NID_X9_62_characteristic_two_field */ 161160814Ssimon X9_62_CHARACTERISTIC_TWO *char_two; 162160814Ssimon /* anything else */ 163160814Ssimon ASN1_TYPE *other; 164160814Ssimon } p; 165160814Ssimon } X9_62_FIELDID; 166160814Ssimon 167160814Ssimontypedef struct x9_62_curve_st { 168160814Ssimon ASN1_OCTET_STRING *a; 169160814Ssimon ASN1_OCTET_STRING *b; 170160814Ssimon ASN1_BIT_STRING *seed; 171160814Ssimon } X9_62_CURVE; 172160814Ssimon 173160814Ssimontypedef struct ec_parameters_st { 174160814Ssimon long version; 175160814Ssimon X9_62_FIELDID *fieldID; 176160814Ssimon X9_62_CURVE *curve; 177160814Ssimon ASN1_OCTET_STRING *base; 178160814Ssimon ASN1_INTEGER *order; 179160814Ssimon ASN1_INTEGER *cofactor; 180160814Ssimon } ECPARAMETERS; 181160814Ssimon 182160814Ssimonstruct ecpk_parameters_st { 183160814Ssimon int type; 184160814Ssimon union { 185160814Ssimon ASN1_OBJECT *named_curve; 186160814Ssimon ECPARAMETERS *parameters; 187160814Ssimon ASN1_NULL *implicitlyCA; 188160814Ssimon } value; 189160814Ssimon }/* ECPKPARAMETERS */; 190160814Ssimon 191160814Ssimon/* SEC1 ECPrivateKey */ 192160814Ssimontypedef struct ec_privatekey_st { 193160814Ssimon long version; 194160814Ssimon ASN1_OCTET_STRING *privateKey; 195160814Ssimon ECPKPARAMETERS *parameters; 196160814Ssimon ASN1_BIT_STRING *publicKey; 197160814Ssimon } EC_PRIVATEKEY; 198160814Ssimon 199160814Ssimon/* the OpenSSL ASN.1 definitions */ 200160814SsimonASN1_SEQUENCE(X9_62_PENTANOMIAL) = { 201160814Ssimon ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG), 202160814Ssimon ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG), 203160814Ssimon ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG) 204160814Ssimon} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL) 205160814Ssimon 206160814SsimonDECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) 207160814SsimonIMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) 208160814Ssimon 209160814SsimonASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY); 210160814Ssimon 211160814SsimonASN1_ADB(X9_62_CHARACTERISTIC_TWO) = { 212160814Ssimon ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)), 213160814Ssimon ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)), 214160814Ssimon ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL)) 215160814Ssimon} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL); 216160814Ssimon 217160814SsimonASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = { 218160814Ssimon ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG), 219160814Ssimon ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT), 220160814Ssimon ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO) 221160814Ssimon} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO) 222160814Ssimon 223160814SsimonDECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) 224160814SsimonIMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) 225160814Ssimon 226160814SsimonASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY); 227160814Ssimon 228160814SsimonASN1_ADB(X9_62_FIELDID) = { 229160814Ssimon ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)), 230160814Ssimon ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO)) 231160814Ssimon} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL); 232160814Ssimon 233160814SsimonASN1_SEQUENCE(X9_62_FIELDID) = { 234160814Ssimon ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT), 235160814Ssimon ASN1_ADB_OBJECT(X9_62_FIELDID) 236160814Ssimon} ASN1_SEQUENCE_END(X9_62_FIELDID) 237160814Ssimon 238160814SsimonASN1_SEQUENCE(X9_62_CURVE) = { 239160814Ssimon ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING), 240160814Ssimon ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING), 241160814Ssimon ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) 242160814Ssimon} ASN1_SEQUENCE_END(X9_62_CURVE) 243160814Ssimon 244160814SsimonASN1_SEQUENCE(ECPARAMETERS) = { 245160814Ssimon ASN1_SIMPLE(ECPARAMETERS, version, LONG), 246160814Ssimon ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID), 247160814Ssimon ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE), 248160814Ssimon ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING), 249160814Ssimon ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER), 250160814Ssimon ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER) 251160814Ssimon} ASN1_SEQUENCE_END(ECPARAMETERS) 252160814Ssimon 253160814SsimonDECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) 254160814SsimonIMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) 255160814Ssimon 256160814SsimonASN1_CHOICE(ECPKPARAMETERS) = { 257160814Ssimon ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT), 258160814Ssimon ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS), 259160814Ssimon ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL) 260160814Ssimon} ASN1_CHOICE_END(ECPKPARAMETERS) 261160814Ssimon 262160814SsimonDECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS) 263160814SsimonDECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS) 264160814SsimonIMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS) 265160814Ssimon 266160814SsimonASN1_SEQUENCE(EC_PRIVATEKEY) = { 267160814Ssimon ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG), 268160814Ssimon ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), 269160814Ssimon ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), 270160814Ssimon ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1) 271160814Ssimon} ASN1_SEQUENCE_END(EC_PRIVATEKEY) 272160814Ssimon 273160814SsimonDECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) 274160814SsimonDECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY) 275160814SsimonIMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) 276160814Ssimon 277160814Ssimon/* some declarations of internal function */ 278160814Ssimon 279160814Ssimon/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ 280160814Ssimonstatic int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *); 281160814Ssimon/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ 282160814Ssimonstatic int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *); 283160814Ssimon/* ec_asn1_parameters2group() creates a EC_GROUP object from a 284160814Ssimon * ECPARAMETERS object */ 285160814Ssimonstatic EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); 286160814Ssimon/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a 287160814Ssimon * EC_GROUP object */ 288160814Ssimonstatic ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,ECPARAMETERS *); 289160814Ssimon/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a 290160814Ssimon * ECPKPARAMETERS object */ 291160814Ssimonstatic EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); 292160814Ssimon/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a 293160814Ssimon * EC_GROUP object */ 294160814Ssimonstatic ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, 295160814Ssimon ECPKPARAMETERS *); 296160814Ssimon 297160814Ssimon 298160814Ssimon/* the function definitions */ 299160814Ssimon 300160814Ssimonstatic int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) 301160814Ssimon { 302160814Ssimon int ok=0, nid; 303160814Ssimon BIGNUM *tmp = NULL; 304160814Ssimon 305160814Ssimon if (group == NULL || field == NULL) 306160814Ssimon return 0; 307160814Ssimon 308160814Ssimon /* clear the old values (if necessary) */ 309160814Ssimon if (field->fieldType != NULL) 310160814Ssimon ASN1_OBJECT_free(field->fieldType); 311160814Ssimon if (field->p.other != NULL) 312160814Ssimon ASN1_TYPE_free(field->p.other); 313160814Ssimon 314160814Ssimon nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); 315160814Ssimon /* set OID for the field */ 316160814Ssimon if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) 317160814Ssimon { 318160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); 319160814Ssimon goto err; 320160814Ssimon } 321160814Ssimon 322160814Ssimon if (nid == NID_X9_62_prime_field) 323160814Ssimon { 324160814Ssimon if ((tmp = BN_new()) == NULL) 325160814Ssimon { 326160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 327160814Ssimon goto err; 328160814Ssimon } 329160814Ssimon /* the parameters are specified by the prime number p */ 330160814Ssimon if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) 331160814Ssimon { 332160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); 333160814Ssimon goto err; 334160814Ssimon } 335160814Ssimon /* set the prime number */ 336160814Ssimon field->p.prime = BN_to_ASN1_INTEGER(tmp,NULL); 337160814Ssimon if (field->p.prime == NULL) 338160814Ssimon { 339160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); 340160814Ssimon goto err; 341160814Ssimon } 342160814Ssimon } 343160814Ssimon else /* nid == NID_X9_62_characteristic_two_field */ 344238405Sjkim#ifdef OPENSSL_NO_EC2M 345160814Ssimon { 346238405Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED); 347238405Sjkim goto err; 348238405Sjkim } 349238405Sjkim#else 350238405Sjkim { 351160814Ssimon int field_type; 352160814Ssimon X9_62_CHARACTERISTIC_TWO *char_two; 353160814Ssimon 354160814Ssimon field->p.char_two = X9_62_CHARACTERISTIC_TWO_new(); 355160814Ssimon char_two = field->p.char_two; 356160814Ssimon 357160814Ssimon if (char_two == NULL) 358160814Ssimon { 359160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 360160814Ssimon goto err; 361160814Ssimon } 362160814Ssimon 363160814Ssimon char_two->m = (long)EC_GROUP_get_degree(group); 364160814Ssimon 365160814Ssimon field_type = EC_GROUP_get_basis_type(group); 366160814Ssimon 367160814Ssimon if (field_type == 0) 368160814Ssimon { 369160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); 370160814Ssimon goto err; 371160814Ssimon } 372160814Ssimon /* set base type OID */ 373160814Ssimon if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) 374160814Ssimon { 375160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); 376160814Ssimon goto err; 377160814Ssimon } 378160814Ssimon 379160814Ssimon if (field_type == NID_X9_62_tpBasis) 380160814Ssimon { 381160814Ssimon unsigned int k; 382160814Ssimon 383160814Ssimon if (!EC_GROUP_get_trinomial_basis(group, &k)) 384160814Ssimon goto err; 385160814Ssimon 386160814Ssimon char_two->p.tpBasis = ASN1_INTEGER_new(); 387160814Ssimon if (!char_two->p.tpBasis) 388160814Ssimon { 389160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 390160814Ssimon goto err; 391160814Ssimon } 392160814Ssimon if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) 393160814Ssimon { 394160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, 395160814Ssimon ERR_R_ASN1_LIB); 396160814Ssimon goto err; 397160814Ssimon } 398160814Ssimon } 399160814Ssimon else if (field_type == NID_X9_62_ppBasis) 400160814Ssimon { 401160814Ssimon unsigned int k1, k2, k3; 402160814Ssimon 403160814Ssimon if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)) 404160814Ssimon goto err; 405160814Ssimon 406160814Ssimon char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); 407160814Ssimon if (!char_two->p.ppBasis) 408160814Ssimon { 409160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 410160814Ssimon goto err; 411160814Ssimon } 412160814Ssimon 413160814Ssimon /* set k? values */ 414160814Ssimon char_two->p.ppBasis->k1 = (long)k1; 415160814Ssimon char_two->p.ppBasis->k2 = (long)k2; 416160814Ssimon char_two->p.ppBasis->k3 = (long)k3; 417160814Ssimon } 418160814Ssimon else /* field_type == NID_X9_62_onBasis */ 419160814Ssimon { 420160814Ssimon /* for ONB the parameters are (asn1) NULL */ 421160814Ssimon char_two->p.onBasis = ASN1_NULL_new(); 422160814Ssimon if (!char_two->p.onBasis) 423160814Ssimon { 424160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 425160814Ssimon goto err; 426160814Ssimon } 427160814Ssimon } 428160814Ssimon } 429238405Sjkim#endif 430160814Ssimon 431160814Ssimon ok = 1; 432160814Ssimon 433160814Ssimonerr : if (tmp) 434160814Ssimon BN_free(tmp); 435160814Ssimon return(ok); 436160814Ssimon} 437160814Ssimon 438160814Ssimonstatic int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) 439160814Ssimon { 440160814Ssimon int ok=0, nid; 441160814Ssimon BIGNUM *tmp_1=NULL, *tmp_2=NULL; 442160814Ssimon unsigned char *buffer_1=NULL, *buffer_2=NULL, 443160814Ssimon *a_buf=NULL, *b_buf=NULL; 444160814Ssimon size_t len_1, len_2; 445160814Ssimon unsigned char char_zero = 0; 446160814Ssimon 447160814Ssimon if (!group || !curve || !curve->a || !curve->b) 448160814Ssimon return 0; 449160814Ssimon 450160814Ssimon if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) 451160814Ssimon { 452160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); 453160814Ssimon goto err; 454160814Ssimon } 455160814Ssimon 456160814Ssimon nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); 457160814Ssimon 458160814Ssimon /* get a and b */ 459160814Ssimon if (nid == NID_X9_62_prime_field) 460160814Ssimon { 461160814Ssimon if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) 462160814Ssimon { 463160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); 464160814Ssimon goto err; 465160814Ssimon } 466160814Ssimon } 467238405Sjkim#ifndef OPENSSL_NO_EC2M 468160814Ssimon else /* nid == NID_X9_62_characteristic_two_field */ 469160814Ssimon { 470160814Ssimon if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) 471160814Ssimon { 472160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); 473160814Ssimon goto err; 474160814Ssimon } 475160814Ssimon } 476238405Sjkim#endif 477160814Ssimon len_1 = (size_t)BN_num_bytes(tmp_1); 478160814Ssimon len_2 = (size_t)BN_num_bytes(tmp_2); 479160814Ssimon 480160814Ssimon if (len_1 == 0) 481160814Ssimon { 482160814Ssimon /* len_1 == 0 => a == 0 */ 483160814Ssimon a_buf = &char_zero; 484160814Ssimon len_1 = 1; 485160814Ssimon } 486160814Ssimon else 487160814Ssimon { 488160814Ssimon if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) 489160814Ssimon { 490160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2CURVE, 491160814Ssimon ERR_R_MALLOC_FAILURE); 492160814Ssimon goto err; 493160814Ssimon } 494160814Ssimon if ( (len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) 495160814Ssimon { 496160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); 497160814Ssimon goto err; 498160814Ssimon } 499160814Ssimon a_buf = buffer_1; 500160814Ssimon } 501160814Ssimon 502160814Ssimon if (len_2 == 0) 503160814Ssimon { 504160814Ssimon /* len_2 == 0 => b == 0 */ 505160814Ssimon b_buf = &char_zero; 506160814Ssimon len_2 = 1; 507160814Ssimon } 508160814Ssimon else 509160814Ssimon { 510160814Ssimon if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) 511160814Ssimon { 512160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2CURVE, 513160814Ssimon ERR_R_MALLOC_FAILURE); 514160814Ssimon goto err; 515160814Ssimon } 516160814Ssimon if ( (len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) 517160814Ssimon { 518160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); 519160814Ssimon goto err; 520160814Ssimon } 521160814Ssimon b_buf = buffer_2; 522160814Ssimon } 523160814Ssimon 524160814Ssimon /* set a and b */ 525160814Ssimon if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) || 526160814Ssimon !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) 527160814Ssimon { 528160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); 529160814Ssimon goto err; 530160814Ssimon } 531160814Ssimon 532160814Ssimon /* set the seed (optional) */ 533160814Ssimon if (group->seed) 534160814Ssimon { 535160814Ssimon if (!curve->seed) 536160814Ssimon if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) 537160814Ssimon { 538160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); 539160814Ssimon goto err; 540160814Ssimon } 541167612Ssimon curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); 542167612Ssimon curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; 543160814Ssimon if (!ASN1_BIT_STRING_set(curve->seed, group->seed, 544160814Ssimon (int)group->seed_len)) 545160814Ssimon { 546160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); 547160814Ssimon goto err; 548160814Ssimon } 549160814Ssimon } 550160814Ssimon else 551160814Ssimon { 552160814Ssimon if (curve->seed) 553160814Ssimon { 554160814Ssimon ASN1_BIT_STRING_free(curve->seed); 555160814Ssimon curve->seed = NULL; 556160814Ssimon } 557160814Ssimon } 558160814Ssimon 559160814Ssimon ok = 1; 560160814Ssimon 561160814Ssimonerr: if (buffer_1) 562160814Ssimon OPENSSL_free(buffer_1); 563160814Ssimon if (buffer_2) 564160814Ssimon OPENSSL_free(buffer_2); 565160814Ssimon if (tmp_1) 566160814Ssimon BN_free(tmp_1); 567160814Ssimon if (tmp_2) 568160814Ssimon BN_free(tmp_2); 569160814Ssimon return(ok); 570160814Ssimon } 571160814Ssimon 572160814Ssimonstatic ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, 573160814Ssimon ECPARAMETERS *param) 574160814Ssimon { 575160814Ssimon int ok=0; 576160814Ssimon size_t len=0; 577160814Ssimon ECPARAMETERS *ret=NULL; 578160814Ssimon BIGNUM *tmp=NULL; 579160814Ssimon unsigned char *buffer=NULL; 580160814Ssimon const EC_POINT *point=NULL; 581160814Ssimon point_conversion_form_t form; 582160814Ssimon 583160814Ssimon if ((tmp = BN_new()) == NULL) 584160814Ssimon { 585160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 586160814Ssimon goto err; 587160814Ssimon } 588160814Ssimon 589160814Ssimon if (param == NULL) 590160814Ssimon { 591160814Ssimon if ((ret = ECPARAMETERS_new()) == NULL) 592160814Ssimon { 593160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, 594160814Ssimon ERR_R_MALLOC_FAILURE); 595160814Ssimon goto err; 596160814Ssimon } 597160814Ssimon } 598160814Ssimon else 599160814Ssimon ret = param; 600160814Ssimon 601160814Ssimon /* set the version (always one) */ 602160814Ssimon ret->version = (long)0x1; 603160814Ssimon 604160814Ssimon /* set the fieldID */ 605160814Ssimon if (!ec_asn1_group2fieldid(group, ret->fieldID)) 606160814Ssimon { 607160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 608160814Ssimon goto err; 609160814Ssimon } 610160814Ssimon 611160814Ssimon /* set the curve */ 612160814Ssimon if (!ec_asn1_group2curve(group, ret->curve)) 613160814Ssimon { 614160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 615160814Ssimon goto err; 616160814Ssimon } 617160814Ssimon 618160814Ssimon /* set the base point */ 619160814Ssimon if ((point = EC_GROUP_get0_generator(group)) == NULL) 620160814Ssimon { 621160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR); 622160814Ssimon goto err; 623160814Ssimon } 624160814Ssimon 625160814Ssimon form = EC_GROUP_get_point_conversion_form(group); 626160814Ssimon 627160814Ssimon len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); 628160814Ssimon if (len == 0) 629160814Ssimon { 630160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 631160814Ssimon goto err; 632160814Ssimon } 633160814Ssimon if ((buffer = OPENSSL_malloc(len)) == NULL) 634160814Ssimon { 635160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 636160814Ssimon goto err; 637160814Ssimon } 638160814Ssimon if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) 639160814Ssimon { 640160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 641160814Ssimon goto err; 642160814Ssimon } 643160814Ssimon if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) 644160814Ssimon { 645160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 646160814Ssimon goto err; 647160814Ssimon } 648160814Ssimon if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) 649160814Ssimon { 650160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); 651160814Ssimon goto err; 652160814Ssimon } 653160814Ssimon 654160814Ssimon /* set the order */ 655160814Ssimon if (!EC_GROUP_get_order(group, tmp, NULL)) 656160814Ssimon { 657160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 658160814Ssimon goto err; 659160814Ssimon } 660160814Ssimon ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); 661160814Ssimon if (ret->order == NULL) 662160814Ssimon { 663160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); 664160814Ssimon goto err; 665160814Ssimon } 666160814Ssimon 667160814Ssimon /* set the cofactor (optional) */ 668160814Ssimon if (EC_GROUP_get_cofactor(group, tmp, NULL)) 669160814Ssimon { 670160814Ssimon ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); 671160814Ssimon if (ret->cofactor == NULL) 672160814Ssimon { 673160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); 674160814Ssimon goto err; 675160814Ssimon } 676160814Ssimon } 677160814Ssimon 678160814Ssimon ok = 1; 679160814Ssimon 680160814Ssimonerr : if(!ok) 681160814Ssimon { 682160814Ssimon if (ret && !param) 683160814Ssimon ECPARAMETERS_free(ret); 684160814Ssimon ret = NULL; 685160814Ssimon } 686160814Ssimon if (tmp) 687160814Ssimon BN_free(tmp); 688160814Ssimon if (buffer) 689160814Ssimon OPENSSL_free(buffer); 690160814Ssimon return(ret); 691160814Ssimon } 692160814Ssimon 693160814SsimonECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, 694160814Ssimon ECPKPARAMETERS *params) 695160814Ssimon { 696160814Ssimon int ok = 1, tmp; 697160814Ssimon ECPKPARAMETERS *ret = params; 698160814Ssimon 699160814Ssimon if (ret == NULL) 700160814Ssimon { 701160814Ssimon if ((ret = ECPKPARAMETERS_new()) == NULL) 702160814Ssimon { 703160814Ssimon ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, 704160814Ssimon ERR_R_MALLOC_FAILURE); 705160814Ssimon return NULL; 706160814Ssimon } 707160814Ssimon } 708160814Ssimon else 709160814Ssimon { 710160814Ssimon if (ret->type == 0 && ret->value.named_curve) 711160814Ssimon ASN1_OBJECT_free(ret->value.named_curve); 712160814Ssimon else if (ret->type == 1 && ret->value.parameters) 713160814Ssimon ECPARAMETERS_free(ret->value.parameters); 714160814Ssimon } 715160814Ssimon 716160814Ssimon if (EC_GROUP_get_asn1_flag(group)) 717160814Ssimon { 718160814Ssimon /* use the asn1 OID to describe the 719160814Ssimon * the elliptic curve parameters 720160814Ssimon */ 721160814Ssimon tmp = EC_GROUP_get_curve_name(group); 722160814Ssimon if (tmp) 723160814Ssimon { 724160814Ssimon ret->type = 0; 725160814Ssimon if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL) 726160814Ssimon ok = 0; 727160814Ssimon } 728160814Ssimon else 729160814Ssimon /* we don't kmow the nid => ERROR */ 730160814Ssimon ok = 0; 731160814Ssimon } 732160814Ssimon else 733160814Ssimon { 734160814Ssimon /* use the ECPARAMETERS structure */ 735160814Ssimon ret->type = 1; 736160814Ssimon if ((ret->value.parameters = ec_asn1_group2parameters( 737160814Ssimon group, NULL)) == NULL) 738160814Ssimon ok = 0; 739160814Ssimon } 740160814Ssimon 741160814Ssimon if (!ok) 742160814Ssimon { 743160814Ssimon ECPKPARAMETERS_free(ret); 744160814Ssimon return NULL; 745160814Ssimon } 746160814Ssimon return ret; 747160814Ssimon } 748160814Ssimon 749160814Ssimonstatic EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params) 750160814Ssimon { 751160814Ssimon int ok = 0, tmp; 752160814Ssimon EC_GROUP *ret = NULL; 753160814Ssimon BIGNUM *p = NULL, *a = NULL, *b = NULL; 754160814Ssimon EC_POINT *point=NULL; 755162911Ssimon long field_bits; 756160814Ssimon 757160814Ssimon if (!params->fieldID || !params->fieldID->fieldType || 758160814Ssimon !params->fieldID->p.ptr) 759160814Ssimon { 760160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 761160814Ssimon goto err; 762160814Ssimon } 763160814Ssimon 764160814Ssimon /* now extract the curve parameters a and b */ 765160814Ssimon if (!params->curve || !params->curve->a || 766160814Ssimon !params->curve->a->data || !params->curve->b || 767160814Ssimon !params->curve->b->data) 768160814Ssimon { 769160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 770160814Ssimon goto err; 771160814Ssimon } 772160814Ssimon a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); 773160814Ssimon if (a == NULL) 774160814Ssimon { 775160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); 776160814Ssimon goto err; 777160814Ssimon } 778160814Ssimon b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); 779160814Ssimon if (b == NULL) 780160814Ssimon { 781160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); 782160814Ssimon goto err; 783160814Ssimon } 784160814Ssimon 785160814Ssimon /* get the field parameters */ 786160814Ssimon tmp = OBJ_obj2nid(params->fieldID->fieldType); 787160814Ssimon if (tmp == NID_X9_62_characteristic_two_field) 788238405Sjkim#ifdef OPENSSL_NO_EC2M 789160814Ssimon { 790238405Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED); 791238405Sjkim goto err; 792238405Sjkim } 793238405Sjkim#else 794238405Sjkim { 795160814Ssimon X9_62_CHARACTERISTIC_TWO *char_two; 796160814Ssimon 797160814Ssimon char_two = params->fieldID->p.char_two; 798160814Ssimon 799162911Ssimon field_bits = char_two->m; 800162911Ssimon if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) 801162911Ssimon { 802162911Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); 803162911Ssimon goto err; 804162911Ssimon } 805162911Ssimon 806160814Ssimon if ((p = BN_new()) == NULL) 807160814Ssimon { 808160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); 809160814Ssimon goto err; 810160814Ssimon } 811160814Ssimon 812160814Ssimon /* get the base type */ 813160814Ssimon tmp = OBJ_obj2nid(char_two->type); 814160814Ssimon 815160814Ssimon if (tmp == NID_X9_62_tpBasis) 816160814Ssimon { 817160814Ssimon long tmp_long; 818160814Ssimon 819160814Ssimon if (!char_two->p.tpBasis) 820160814Ssimon { 821160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 822160814Ssimon goto err; 823160814Ssimon } 824160814Ssimon 825160814Ssimon tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis); 826162911Ssimon 827162911Ssimon if (!(char_two->m > tmp_long && tmp_long > 0)) 828162911Ssimon { 829162911Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS); 830162911Ssimon goto err; 831162911Ssimon } 832162911Ssimon 833160814Ssimon /* create the polynomial */ 834160814Ssimon if (!BN_set_bit(p, (int)char_two->m)) 835160814Ssimon goto err; 836160814Ssimon if (!BN_set_bit(p, (int)tmp_long)) 837160814Ssimon goto err; 838160814Ssimon if (!BN_set_bit(p, 0)) 839160814Ssimon goto err; 840160814Ssimon } 841160814Ssimon else if (tmp == NID_X9_62_ppBasis) 842160814Ssimon { 843160814Ssimon X9_62_PENTANOMIAL *penta; 844160814Ssimon 845160814Ssimon penta = char_two->p.ppBasis; 846160814Ssimon if (!penta) 847160814Ssimon { 848160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 849160814Ssimon goto err; 850160814Ssimon } 851162911Ssimon 852162911Ssimon if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0)) 853162911Ssimon { 854162911Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS); 855162911Ssimon goto err; 856162911Ssimon } 857162911Ssimon 858160814Ssimon /* create the polynomial */ 859160814Ssimon if (!BN_set_bit(p, (int)char_two->m)) goto err; 860160814Ssimon if (!BN_set_bit(p, (int)penta->k1)) goto err; 861160814Ssimon if (!BN_set_bit(p, (int)penta->k2)) goto err; 862160814Ssimon if (!BN_set_bit(p, (int)penta->k3)) goto err; 863160814Ssimon if (!BN_set_bit(p, 0)) goto err; 864160814Ssimon } 865160814Ssimon else if (tmp == NID_X9_62_onBasis) 866160814Ssimon { 867160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED); 868160814Ssimon goto err; 869160814Ssimon } 870160814Ssimon else /* error */ 871160814Ssimon { 872160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 873160814Ssimon goto err; 874160814Ssimon } 875160814Ssimon 876160814Ssimon /* create the EC_GROUP structure */ 877160814Ssimon ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL); 878160814Ssimon } 879238405Sjkim#endif 880160814Ssimon else if (tmp == NID_X9_62_prime_field) 881160814Ssimon { 882160814Ssimon /* we have a curve over a prime field */ 883160814Ssimon /* extract the prime number */ 884160814Ssimon if (!params->fieldID->p.prime) 885160814Ssimon { 886160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 887160814Ssimon goto err; 888160814Ssimon } 889160814Ssimon p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); 890160814Ssimon if (p == NULL) 891160814Ssimon { 892160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); 893160814Ssimon goto err; 894160814Ssimon } 895162911Ssimon 896162911Ssimon if (BN_is_negative(p) || BN_is_zero(p)) 897162911Ssimon { 898162911Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); 899162911Ssimon goto err; 900162911Ssimon } 901162911Ssimon 902162911Ssimon field_bits = BN_num_bits(p); 903162911Ssimon if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) 904162911Ssimon { 905162911Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); 906162911Ssimon goto err; 907162911Ssimon } 908162911Ssimon 909160814Ssimon /* create the EC_GROUP structure */ 910160814Ssimon ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); 911160814Ssimon } 912160814Ssimon else 913160814Ssimon { 914160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); 915160814Ssimon goto err; 916160814Ssimon } 917160814Ssimon 918160814Ssimon if (ret == NULL) 919160814Ssimon { 920160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); 921160814Ssimon goto err; 922160814Ssimon } 923160814Ssimon 924160814Ssimon /* extract seed (optional) */ 925160814Ssimon if (params->curve->seed != NULL) 926160814Ssimon { 927160814Ssimon if (ret->seed != NULL) 928160814Ssimon OPENSSL_free(ret->seed); 929160814Ssimon if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) 930160814Ssimon { 931160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 932160814Ssimon ERR_R_MALLOC_FAILURE); 933160814Ssimon goto err; 934160814Ssimon } 935160814Ssimon memcpy(ret->seed, params->curve->seed->data, 936160814Ssimon params->curve->seed->length); 937160814Ssimon ret->seed_len = params->curve->seed->length; 938160814Ssimon } 939160814Ssimon 940160814Ssimon if (!params->order || !params->base || !params->base->data) 941160814Ssimon { 942160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 943160814Ssimon goto err; 944160814Ssimon } 945160814Ssimon 946160814Ssimon if ((point = EC_POINT_new(ret)) == NULL) goto err; 947160814Ssimon 948160814Ssimon /* set the point conversion form */ 949160814Ssimon EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) 950160814Ssimon (params->base->data[0] & ~0x01)); 951160814Ssimon 952160814Ssimon /* extract the ec point */ 953160814Ssimon if (!EC_POINT_oct2point(ret, point, params->base->data, 954160814Ssimon params->base->length, NULL)) 955160814Ssimon { 956160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); 957160814Ssimon goto err; 958160814Ssimon } 959160814Ssimon 960160814Ssimon /* extract the order */ 961160814Ssimon if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) 962160814Ssimon { 963160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); 964160814Ssimon goto err; 965160814Ssimon } 966162911Ssimon if (BN_is_negative(a) || BN_is_zero(a)) 967162911Ssimon { 968162911Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); 969162911Ssimon goto err; 970162911Ssimon } 971162911Ssimon if (BN_num_bits(a) > (int)field_bits + 1) /* Hasse bound */ 972162911Ssimon { 973162911Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); 974162911Ssimon goto err; 975162911Ssimon } 976160814Ssimon 977160814Ssimon /* extract the cofactor (optional) */ 978160814Ssimon if (params->cofactor == NULL) 979160814Ssimon { 980160814Ssimon if (b) 981160814Ssimon { 982160814Ssimon BN_free(b); 983160814Ssimon b = NULL; 984160814Ssimon } 985160814Ssimon } 986160814Ssimon else 987160814Ssimon if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) 988160814Ssimon { 989160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); 990160814Ssimon goto err; 991160814Ssimon } 992160814Ssimon /* set the generator, order and cofactor (if present) */ 993160814Ssimon if (!EC_GROUP_set_generator(ret, point, a, b)) 994160814Ssimon { 995160814Ssimon ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); 996160814Ssimon goto err; 997160814Ssimon } 998160814Ssimon 999160814Ssimon ok = 1; 1000160814Ssimon 1001160814Ssimonerr: if (!ok) 1002160814Ssimon { 1003160814Ssimon if (ret) 1004160814Ssimon EC_GROUP_clear_free(ret); 1005160814Ssimon ret = NULL; 1006160814Ssimon } 1007160814Ssimon 1008160814Ssimon if (p) 1009160814Ssimon BN_free(p); 1010160814Ssimon if (a) 1011160814Ssimon BN_free(a); 1012160814Ssimon if (b) 1013160814Ssimon BN_free(b); 1014160814Ssimon if (point) 1015160814Ssimon EC_POINT_free(point); 1016160814Ssimon return(ret); 1017160814Ssimon} 1018160814Ssimon 1019160814SsimonEC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) 1020160814Ssimon { 1021160814Ssimon EC_GROUP *ret=NULL; 1022160814Ssimon int tmp=0; 1023160814Ssimon 1024160814Ssimon if (params == NULL) 1025160814Ssimon { 1026160814Ssimon ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 1027160814Ssimon EC_R_MISSING_PARAMETERS); 1028160814Ssimon return NULL; 1029160814Ssimon } 1030160814Ssimon 1031160814Ssimon if (params->type == 0) 1032160814Ssimon { /* the curve is given by an OID */ 1033160814Ssimon tmp = OBJ_obj2nid(params->value.named_curve); 1034160814Ssimon if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) 1035160814Ssimon { 1036160814Ssimon ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 1037160814Ssimon EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 1038160814Ssimon return NULL; 1039160814Ssimon } 1040160814Ssimon EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); 1041160814Ssimon } 1042160814Ssimon else if (params->type == 1) 1043160814Ssimon { /* the parameters are given by a ECPARAMETERS 1044160814Ssimon * structure */ 1045160814Ssimon ret = ec_asn1_parameters2group(params->value.parameters); 1046160814Ssimon if (!ret) 1047160814Ssimon { 1048160814Ssimon ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB); 1049160814Ssimon return NULL; 1050160814Ssimon } 1051160814Ssimon EC_GROUP_set_asn1_flag(ret, 0x0); 1052160814Ssimon } 1053160814Ssimon else if (params->type == 2) 1054160814Ssimon { /* implicitlyCA */ 1055160814Ssimon return NULL; 1056160814Ssimon } 1057160814Ssimon else 1058160814Ssimon { 1059160814Ssimon ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR); 1060160814Ssimon return NULL; 1061160814Ssimon } 1062160814Ssimon 1063160814Ssimon return ret; 1064160814Ssimon } 1065160814Ssimon 1066160814Ssimon/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */ 1067160814Ssimon 1068160814SsimonEC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) 1069160814Ssimon { 1070160814Ssimon EC_GROUP *group = NULL; 1071160814Ssimon ECPKPARAMETERS *params = NULL; 1072160814Ssimon 1073160814Ssimon if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) 1074160814Ssimon { 1075160814Ssimon ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE); 1076160814Ssimon ECPKPARAMETERS_free(params); 1077160814Ssimon return NULL; 1078160814Ssimon } 1079160814Ssimon 1080160814Ssimon if ((group = ec_asn1_pkparameters2group(params)) == NULL) 1081160814Ssimon { 1082160814Ssimon ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE); 1083238405Sjkim ECPKPARAMETERS_free(params); 1084160814Ssimon return NULL; 1085160814Ssimon } 1086160814Ssimon 1087160814Ssimon 1088160814Ssimon if (a && *a) 1089160814Ssimon EC_GROUP_clear_free(*a); 1090160814Ssimon if (a) 1091160814Ssimon *a = group; 1092160814Ssimon 1093160814Ssimon ECPKPARAMETERS_free(params); 1094160814Ssimon return(group); 1095160814Ssimon } 1096160814Ssimon 1097160814Ssimonint i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) 1098160814Ssimon { 1099160814Ssimon int ret=0; 1100160814Ssimon ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL); 1101160814Ssimon if (tmp == NULL) 1102160814Ssimon { 1103160814Ssimon ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE); 1104160814Ssimon return 0; 1105160814Ssimon } 1106160814Ssimon if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) 1107160814Ssimon { 1108160814Ssimon ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE); 1109160814Ssimon ECPKPARAMETERS_free(tmp); 1110160814Ssimon return 0; 1111160814Ssimon } 1112160814Ssimon ECPKPARAMETERS_free(tmp); 1113160814Ssimon return(ret); 1114160814Ssimon } 1115160814Ssimon 1116160814Ssimon/* some EC_KEY functions */ 1117160814Ssimon 1118160814SsimonEC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) 1119160814Ssimon { 1120160814Ssimon int ok=0; 1121160814Ssimon EC_KEY *ret=NULL; 1122160814Ssimon EC_PRIVATEKEY *priv_key=NULL; 1123160814Ssimon 1124160814Ssimon if ((priv_key = EC_PRIVATEKEY_new()) == NULL) 1125160814Ssimon { 1126160814Ssimon ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1127160814Ssimon return NULL; 1128160814Ssimon } 1129160814Ssimon 1130160814Ssimon if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL) 1131160814Ssimon { 1132160814Ssimon ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1133160814Ssimon EC_PRIVATEKEY_free(priv_key); 1134160814Ssimon return NULL; 1135160814Ssimon } 1136160814Ssimon 1137160814Ssimon if (a == NULL || *a == NULL) 1138160814Ssimon { 1139160814Ssimon if ((ret = EC_KEY_new()) == NULL) 1140160814Ssimon { 1141160814Ssimon ECerr(EC_F_D2I_ECPRIVATEKEY, 1142160814Ssimon ERR_R_MALLOC_FAILURE); 1143160814Ssimon goto err; 1144160814Ssimon } 1145160814Ssimon if (a) 1146160814Ssimon *a = ret; 1147160814Ssimon } 1148160814Ssimon else 1149160814Ssimon ret = *a; 1150160814Ssimon 1151160814Ssimon if (priv_key->parameters) 1152160814Ssimon { 1153160814Ssimon if (ret->group) 1154160814Ssimon EC_GROUP_clear_free(ret->group); 1155160814Ssimon ret->group = ec_asn1_pkparameters2group(priv_key->parameters); 1156160814Ssimon } 1157160814Ssimon 1158160814Ssimon if (ret->group == NULL) 1159160814Ssimon { 1160160814Ssimon ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1161160814Ssimon goto err; 1162160814Ssimon } 1163160814Ssimon 1164160814Ssimon ret->version = priv_key->version; 1165160814Ssimon 1166160814Ssimon if (priv_key->privateKey) 1167160814Ssimon { 1168160814Ssimon ret->priv_key = BN_bin2bn( 1169160814Ssimon M_ASN1_STRING_data(priv_key->privateKey), 1170160814Ssimon M_ASN1_STRING_length(priv_key->privateKey), 1171160814Ssimon ret->priv_key); 1172160814Ssimon if (ret->priv_key == NULL) 1173160814Ssimon { 1174160814Ssimon ECerr(EC_F_D2I_ECPRIVATEKEY, 1175160814Ssimon ERR_R_BN_LIB); 1176160814Ssimon goto err; 1177160814Ssimon } 1178160814Ssimon } 1179160814Ssimon else 1180160814Ssimon { 1181160814Ssimon ECerr(EC_F_D2I_ECPRIVATEKEY, 1182160814Ssimon EC_R_MISSING_PRIVATE_KEY); 1183160814Ssimon goto err; 1184160814Ssimon } 1185160814Ssimon 1186279264Sdelphij if (ret->pub_key) 1187279264Sdelphij EC_POINT_clear_free(ret->pub_key); 1188279264Sdelphij ret->pub_key = EC_POINT_new(ret->group); 1189279264Sdelphij if (ret->pub_key == NULL) 1190279264Sdelphij { 1191279264Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1192279264Sdelphij goto err; 1193279264Sdelphij } 1194279264Sdelphij 1195160814Ssimon if (priv_key->publicKey) 1196160814Ssimon { 1197160814Ssimon const unsigned char *pub_oct; 1198279264Sdelphij int pub_oct_len; 1199160814Ssimon 1200279264Sdelphij pub_oct = M_ASN1_STRING_data(priv_key->publicKey); 1201279264Sdelphij pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey); 1202279264Sdelphij /* The first byte - point conversion form - must be present. */ 1203279264Sdelphij if (pub_oct_len <= 0) 1204160814Ssimon { 1205279264Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); 1206160814Ssimon goto err; 1207160814Ssimon } 1208279264Sdelphij /* Save the point conversion form. */ 1209160814Ssimon ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01); 1210160814Ssimon if (!EC_POINT_oct2point(ret->group, ret->pub_key, 1211279264Sdelphij pub_oct, (size_t)(pub_oct_len), NULL)) 1212160814Ssimon { 1213160814Ssimon ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1214160814Ssimon goto err; 1215160814Ssimon } 1216160814Ssimon } 1217279264Sdelphij else 1218279264Sdelphij { 1219279264Sdelphij if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) 1220279264Sdelphij { 1221279264Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1222279264Sdelphij goto err; 1223279264Sdelphij } 1224279264Sdelphij /* Remember the original private-key-only encoding. */ 1225279264Sdelphij ret->enc_flag |= EC_PKEY_NO_PUBKEY; 1226279264Sdelphij } 1227160814Ssimon 1228160814Ssimon ok = 1; 1229160814Ssimonerr: 1230160814Ssimon if (!ok) 1231160814Ssimon { 1232160814Ssimon if (ret) 1233160814Ssimon EC_KEY_free(ret); 1234160814Ssimon ret = NULL; 1235160814Ssimon } 1236160814Ssimon 1237160814Ssimon if (priv_key) 1238160814Ssimon EC_PRIVATEKEY_free(priv_key); 1239160814Ssimon 1240160814Ssimon return(ret); 1241160814Ssimon } 1242160814Ssimon 1243160814Ssimonint i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) 1244160814Ssimon { 1245160814Ssimon int ret=0, ok=0; 1246160814Ssimon unsigned char *buffer=NULL; 1247160814Ssimon size_t buf_len=0, tmp_len; 1248160814Ssimon EC_PRIVATEKEY *priv_key=NULL; 1249160814Ssimon 1250279264Sdelphij if (a == NULL || a->group == NULL || a->priv_key == NULL || 1251279264Sdelphij (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) 1252160814Ssimon { 1253160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, 1254160814Ssimon ERR_R_PASSED_NULL_PARAMETER); 1255160814Ssimon goto err; 1256160814Ssimon } 1257160814Ssimon 1258160814Ssimon if ((priv_key = EC_PRIVATEKEY_new()) == NULL) 1259160814Ssimon { 1260160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, 1261160814Ssimon ERR_R_MALLOC_FAILURE); 1262160814Ssimon goto err; 1263160814Ssimon } 1264160814Ssimon 1265160814Ssimon priv_key->version = a->version; 1266160814Ssimon 1267160814Ssimon buf_len = (size_t)BN_num_bytes(a->priv_key); 1268160814Ssimon buffer = OPENSSL_malloc(buf_len); 1269160814Ssimon if (buffer == NULL) 1270160814Ssimon { 1271160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, 1272160814Ssimon ERR_R_MALLOC_FAILURE); 1273160814Ssimon goto err; 1274160814Ssimon } 1275160814Ssimon 1276160814Ssimon if (!BN_bn2bin(a->priv_key, buffer)) 1277160814Ssimon { 1278160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); 1279160814Ssimon goto err; 1280160814Ssimon } 1281160814Ssimon 1282160814Ssimon if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) 1283160814Ssimon { 1284160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); 1285160814Ssimon goto err; 1286160814Ssimon } 1287160814Ssimon 1288160814Ssimon if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) 1289160814Ssimon { 1290160814Ssimon if ((priv_key->parameters = ec_asn1_group2pkparameters( 1291160814Ssimon a->group, priv_key->parameters)) == NULL) 1292160814Ssimon { 1293160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); 1294160814Ssimon goto err; 1295160814Ssimon } 1296160814Ssimon } 1297160814Ssimon 1298160814Ssimon if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) 1299160814Ssimon { 1300160814Ssimon priv_key->publicKey = M_ASN1_BIT_STRING_new(); 1301160814Ssimon if (priv_key->publicKey == NULL) 1302160814Ssimon { 1303160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, 1304160814Ssimon ERR_R_MALLOC_FAILURE); 1305160814Ssimon goto err; 1306160814Ssimon } 1307160814Ssimon 1308160814Ssimon tmp_len = EC_POINT_point2oct(a->group, a->pub_key, 1309160814Ssimon a->conv_form, NULL, 0, NULL); 1310160814Ssimon 1311160814Ssimon if (tmp_len > buf_len) 1312160814Ssimon { 1313160814Ssimon unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len); 1314160814Ssimon if (!tmp_buffer) 1315160814Ssimon { 1316160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1317160814Ssimon goto err; 1318160814Ssimon } 1319160814Ssimon buffer = tmp_buffer; 1320160814Ssimon buf_len = tmp_len; 1321160814Ssimon } 1322160814Ssimon 1323160814Ssimon if (!EC_POINT_point2oct(a->group, a->pub_key, 1324160814Ssimon a->conv_form, buffer, buf_len, NULL)) 1325160814Ssimon { 1326160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); 1327160814Ssimon goto err; 1328160814Ssimon } 1329160814Ssimon 1330167612Ssimon priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); 1331167612Ssimon priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; 1332160814Ssimon if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, 1333160814Ssimon buf_len)) 1334160814Ssimon { 1335160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); 1336160814Ssimon goto err; 1337160814Ssimon } 1338160814Ssimon } 1339160814Ssimon 1340160814Ssimon if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) 1341160814Ssimon { 1342160814Ssimon ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); 1343160814Ssimon goto err; 1344160814Ssimon } 1345160814Ssimon ok=1; 1346160814Ssimonerr: 1347160814Ssimon if (buffer) 1348160814Ssimon OPENSSL_free(buffer); 1349160814Ssimon if (priv_key) 1350160814Ssimon EC_PRIVATEKEY_free(priv_key); 1351160814Ssimon return(ok?ret:0); 1352160814Ssimon } 1353160814Ssimon 1354160814Ssimonint i2d_ECParameters(EC_KEY *a, unsigned char **out) 1355160814Ssimon { 1356160814Ssimon if (a == NULL) 1357160814Ssimon { 1358160814Ssimon ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); 1359160814Ssimon return 0; 1360160814Ssimon } 1361160814Ssimon return i2d_ECPKParameters(a->group, out); 1362160814Ssimon } 1363160814Ssimon 1364160814SsimonEC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) 1365160814Ssimon { 1366160814Ssimon EC_KEY *ret; 1367160814Ssimon 1368160814Ssimon if (in == NULL || *in == NULL) 1369160814Ssimon { 1370160814Ssimon ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); 1371160814Ssimon return NULL; 1372160814Ssimon } 1373160814Ssimon 1374160814Ssimon if (a == NULL || *a == NULL) 1375160814Ssimon { 1376160814Ssimon if ((ret = EC_KEY_new()) == NULL) 1377160814Ssimon { 1378160814Ssimon ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE); 1379160814Ssimon return NULL; 1380160814Ssimon } 1381160814Ssimon if (a) 1382160814Ssimon *a = ret; 1383160814Ssimon } 1384160814Ssimon else 1385160814Ssimon ret = *a; 1386160814Ssimon 1387160814Ssimon if (!d2i_ECPKParameters(&ret->group, in, len)) 1388160814Ssimon { 1389160814Ssimon ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); 1390160814Ssimon return NULL; 1391160814Ssimon } 1392160814Ssimon 1393160814Ssimon return ret; 1394160814Ssimon } 1395160814Ssimon 1396160814SsimonEC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) 1397160814Ssimon { 1398160814Ssimon EC_KEY *ret=NULL; 1399160814Ssimon 1400160814Ssimon if (a == NULL || (*a) == NULL || (*a)->group == NULL) 1401160814Ssimon { 1402160814Ssimon /* sorry, but a EC_GROUP-structur is necessary 1403160814Ssimon * to set the public key */ 1404160814Ssimon ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); 1405160814Ssimon return 0; 1406160814Ssimon } 1407160814Ssimon ret = *a; 1408160814Ssimon if (ret->pub_key == NULL && 1409160814Ssimon (ret->pub_key = EC_POINT_new(ret->group)) == NULL) 1410160814Ssimon { 1411160814Ssimon ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); 1412160814Ssimon return 0; 1413160814Ssimon } 1414160814Ssimon if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) 1415160814Ssimon { 1416160814Ssimon ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB); 1417160814Ssimon return 0; 1418160814Ssimon } 1419160814Ssimon /* save the point conversion form */ 1420160814Ssimon ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01); 1421160814Ssimon *in += len; 1422160814Ssimon return ret; 1423160814Ssimon } 1424160814Ssimon 1425160814Ssimonint i2o_ECPublicKey(EC_KEY *a, unsigned char **out) 1426160814Ssimon { 1427160814Ssimon size_t buf_len=0; 1428160814Ssimon int new_buffer = 0; 1429160814Ssimon 1430160814Ssimon if (a == NULL) 1431160814Ssimon { 1432160814Ssimon ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); 1433160814Ssimon return 0; 1434160814Ssimon } 1435160814Ssimon 1436160814Ssimon buf_len = EC_POINT_point2oct(a->group, a->pub_key, 1437160814Ssimon a->conv_form, NULL, 0, NULL); 1438160814Ssimon 1439160814Ssimon if (out == NULL || buf_len == 0) 1440160814Ssimon /* out == NULL => just return the length of the octet string */ 1441160814Ssimon return buf_len; 1442160814Ssimon 1443160814Ssimon if (*out == NULL) 1444160814Ssimon { 1445160814Ssimon if ((*out = OPENSSL_malloc(buf_len)) == NULL) 1446160814Ssimon { 1447160814Ssimon ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); 1448160814Ssimon return 0; 1449160814Ssimon } 1450160814Ssimon new_buffer = 1; 1451160814Ssimon } 1452160814Ssimon if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, 1453160814Ssimon *out, buf_len, NULL)) 1454160814Ssimon { 1455160814Ssimon ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB); 1456279264Sdelphij if (new_buffer) 1457279264Sdelphij { 1458279264Sdelphij OPENSSL_free(*out); 1459279264Sdelphij *out = NULL; 1460279264Sdelphij } 1461160814Ssimon return 0; 1462160814Ssimon } 1463160814Ssimon if (!new_buffer) 1464160814Ssimon *out += buf_len; 1465160814Ssimon return buf_len; 1466160814Ssimon } 1467