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 13280304Sjkim * 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 65160814Ssimonint EC_GROUP_get_basis_type(const EC_GROUP *group) 66280304Sjkim{ 67280304Sjkim int i = 0; 68160814Ssimon 69280304Sjkim if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 70280304Sjkim NID_X9_62_characteristic_two_field) 71280304Sjkim /* everything else is currently not supported */ 72280304Sjkim return 0; 73160814Ssimon 74280304Sjkim while (group->poly[i] != 0) 75280304Sjkim i++; 76160814Ssimon 77280304Sjkim if (i == 4) 78280304Sjkim return NID_X9_62_ppBasis; 79280304Sjkim else if (i == 2) 80280304Sjkim return NID_X9_62_tpBasis; 81280304Sjkim else 82280304Sjkim /* everything else is currently not supported */ 83280304Sjkim return 0; 84280304Sjkim} 85280304Sjkim 86238405Sjkim#ifndef OPENSSL_NO_EC2M 87160814Ssimonint EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) 88280304Sjkim{ 89280304Sjkim if (group == NULL) 90280304Sjkim return 0; 91160814Ssimon 92280304Sjkim if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 93280304Sjkim NID_X9_62_characteristic_two_field 94280304Sjkim || !((group->poly[0] != 0) && (group->poly[1] != 0) 95280304Sjkim && (group->poly[2] == 0))) { 96280304Sjkim ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, 97280304Sjkim ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 98280304Sjkim return 0; 99280304Sjkim } 100160814Ssimon 101280304Sjkim if (k) 102280304Sjkim *k = group->poly[1]; 103160814Ssimon 104280304Sjkim return 1; 105280304Sjkim} 106280304Sjkim 107160814Ssimonint EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, 108280304Sjkim unsigned int *k2, unsigned int *k3) 109280304Sjkim{ 110280304Sjkim if (group == NULL) 111280304Sjkim return 0; 112160814Ssimon 113280304Sjkim if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 114280304Sjkim NID_X9_62_characteristic_two_field 115280304Sjkim || !((group->poly[0] != 0) && (group->poly[1] != 0) 116280304Sjkim && (group->poly[2] != 0) && (group->poly[3] != 0) 117280304Sjkim && (group->poly[4] == 0))) { 118280304Sjkim ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, 119280304Sjkim ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 120280304Sjkim return 0; 121280304Sjkim } 122160814Ssimon 123280304Sjkim if (k1) 124280304Sjkim *k1 = group->poly[3]; 125280304Sjkim if (k2) 126280304Sjkim *k2 = group->poly[2]; 127280304Sjkim if (k3) 128280304Sjkim *k3 = group->poly[1]; 129160814Ssimon 130280304Sjkim return 1; 131280304Sjkim} 132238405Sjkim#endif 133160814Ssimon 134160814Ssimon/* some structures needed for the asn1 encoding */ 135160814Ssimontypedef struct x9_62_pentanomial_st { 136280304Sjkim long k1; 137280304Sjkim long k2; 138280304Sjkim long k3; 139280304Sjkim} X9_62_PENTANOMIAL; 140160814Ssimon 141160814Ssimontypedef struct x9_62_characteristic_two_st { 142280304Sjkim long m; 143280304Sjkim ASN1_OBJECT *type; 144280304Sjkim union { 145280304Sjkim char *ptr; 146280304Sjkim /* NID_X9_62_onBasis */ 147280304Sjkim ASN1_NULL *onBasis; 148280304Sjkim /* NID_X9_62_tpBasis */ 149280304Sjkim ASN1_INTEGER *tpBasis; 150280304Sjkim /* NID_X9_62_ppBasis */ 151280304Sjkim X9_62_PENTANOMIAL *ppBasis; 152280304Sjkim /* anything else */ 153280304Sjkim ASN1_TYPE *other; 154280304Sjkim } p; 155280304Sjkim} X9_62_CHARACTERISTIC_TWO; 156160814Ssimon 157160814Ssimontypedef struct x9_62_fieldid_st { 158280304Sjkim ASN1_OBJECT *fieldType; 159280304Sjkim union { 160280304Sjkim char *ptr; 161280304Sjkim /* NID_X9_62_prime_field */ 162280304Sjkim ASN1_INTEGER *prime; 163280304Sjkim /* NID_X9_62_characteristic_two_field */ 164280304Sjkim X9_62_CHARACTERISTIC_TWO *char_two; 165280304Sjkim /* anything else */ 166280304Sjkim ASN1_TYPE *other; 167280304Sjkim } p; 168280304Sjkim} X9_62_FIELDID; 169160814Ssimon 170160814Ssimontypedef struct x9_62_curve_st { 171280304Sjkim ASN1_OCTET_STRING *a; 172280304Sjkim ASN1_OCTET_STRING *b; 173280304Sjkim ASN1_BIT_STRING *seed; 174280304Sjkim} X9_62_CURVE; 175160814Ssimon 176160814Ssimontypedef struct ec_parameters_st { 177280304Sjkim long version; 178280304Sjkim X9_62_FIELDID *fieldID; 179280304Sjkim X9_62_CURVE *curve; 180280304Sjkim ASN1_OCTET_STRING *base; 181280304Sjkim ASN1_INTEGER *order; 182280304Sjkim ASN1_INTEGER *cofactor; 183280304Sjkim} ECPARAMETERS; 184160814Ssimon 185160814Ssimonstruct ecpk_parameters_st { 186280304Sjkim int type; 187280304Sjkim union { 188280304Sjkim ASN1_OBJECT *named_curve; 189280304Sjkim ECPARAMETERS *parameters; 190280304Sjkim ASN1_NULL *implicitlyCA; 191280304Sjkim } value; 192280304Sjkim} /* ECPKPARAMETERS */ ; 193160814Ssimon 194160814Ssimon/* SEC1 ECPrivateKey */ 195160814Ssimontypedef struct ec_privatekey_st { 196280304Sjkim long version; 197280304Sjkim ASN1_OCTET_STRING *privateKey; 198280304Sjkim ECPKPARAMETERS *parameters; 199280304Sjkim ASN1_BIT_STRING *publicKey; 200280304Sjkim} EC_PRIVATEKEY; 201160814Ssimon 202160814Ssimon/* the OpenSSL ASN.1 definitions */ 203160814SsimonASN1_SEQUENCE(X9_62_PENTANOMIAL) = { 204280304Sjkim ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG), 205280304Sjkim ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG), 206280304Sjkim ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG) 207160814Ssimon} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL) 208160814Ssimon 209160814SsimonDECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) 210160814SsimonIMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) 211160814Ssimon 212160814SsimonASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY); 213160814Ssimon 214160814SsimonASN1_ADB(X9_62_CHARACTERISTIC_TWO) = { 215280304Sjkim ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)), 216280304Sjkim ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)), 217280304Sjkim ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL)) 218160814Ssimon} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL); 219160814Ssimon 220160814SsimonASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = { 221280304Sjkim ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG), 222280304Sjkim ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT), 223280304Sjkim ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO) 224160814Ssimon} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO) 225160814Ssimon 226160814SsimonDECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) 227160814SsimonIMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) 228160814Ssimon 229160814SsimonASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY); 230160814Ssimon 231160814SsimonASN1_ADB(X9_62_FIELDID) = { 232280304Sjkim ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)), 233280304Sjkim ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO)) 234160814Ssimon} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL); 235160814Ssimon 236160814SsimonASN1_SEQUENCE(X9_62_FIELDID) = { 237280304Sjkim ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT), 238280304Sjkim ASN1_ADB_OBJECT(X9_62_FIELDID) 239160814Ssimon} ASN1_SEQUENCE_END(X9_62_FIELDID) 240160814Ssimon 241160814SsimonASN1_SEQUENCE(X9_62_CURVE) = { 242280304Sjkim ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING), 243280304Sjkim ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING), 244280304Sjkim ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) 245160814Ssimon} ASN1_SEQUENCE_END(X9_62_CURVE) 246160814Ssimon 247160814SsimonASN1_SEQUENCE(ECPARAMETERS) = { 248280304Sjkim ASN1_SIMPLE(ECPARAMETERS, version, LONG), 249280304Sjkim ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID), 250280304Sjkim ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE), 251280304Sjkim ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING), 252280304Sjkim ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER), 253280304Sjkim ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER) 254160814Ssimon} ASN1_SEQUENCE_END(ECPARAMETERS) 255160814Ssimon 256160814SsimonDECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) 257160814SsimonIMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) 258160814Ssimon 259160814SsimonASN1_CHOICE(ECPKPARAMETERS) = { 260280304Sjkim ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT), 261280304Sjkim ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS), 262280304Sjkim ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL) 263160814Ssimon} ASN1_CHOICE_END(ECPKPARAMETERS) 264160814Ssimon 265160814SsimonDECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS) 266160814SsimonDECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS) 267160814SsimonIMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS) 268160814Ssimon 269160814SsimonASN1_SEQUENCE(EC_PRIVATEKEY) = { 270280304Sjkim ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG), 271280304Sjkim ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), 272280304Sjkim ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), 273280304Sjkim ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1) 274160814Ssimon} ASN1_SEQUENCE_END(EC_PRIVATEKEY) 275160814Ssimon 276160814SsimonDECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) 277160814SsimonDECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY) 278160814SsimonIMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) 279160814Ssimon 280160814Ssimon/* some declarations of internal function */ 281160814Ssimon 282280304Sjkim/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ 283160814Ssimonstatic int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *); 284280304Sjkim/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ 285160814Ssimonstatic int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *); 286280304Sjkim/* 287280304Sjkim * ec_asn1_parameters2group() creates a EC_GROUP object from a ECPARAMETERS 288280304Sjkim * object 289280304Sjkim */ 290280304Sjkimstatic EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); 291280304Sjkim/* 292280304Sjkim * ec_asn1_group2parameters() creates a ECPARAMETERS object from a EC_GROUP 293280304Sjkim * object 294280304Sjkim */ 295280304Sjkimstatic ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, 296280304Sjkim ECPARAMETERS *); 297280304Sjkim/* 298280304Sjkim * ec_asn1_pkparameters2group() creates a EC_GROUP object from a 299280304Sjkim * ECPKPARAMETERS object 300280304Sjkim */ 301280304Sjkimstatic EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); 302280304Sjkim/* 303280304Sjkim * ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a 304280304Sjkim * EC_GROUP object 305280304Sjkim */ 306280304Sjkimstatic ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, 307280304Sjkim ECPKPARAMETERS *); 308160814Ssimon 309160814Ssimon/* the function definitions */ 310160814Ssimon 311160814Ssimonstatic int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) 312280304Sjkim{ 313280304Sjkim int ok = 0, nid; 314280304Sjkim BIGNUM *tmp = NULL; 315160814Ssimon 316280304Sjkim if (group == NULL || field == NULL) 317280304Sjkim return 0; 318160814Ssimon 319280304Sjkim /* clear the old values (if necessary) */ 320280304Sjkim if (field->fieldType != NULL) 321280304Sjkim ASN1_OBJECT_free(field->fieldType); 322280304Sjkim if (field->p.other != NULL) 323280304Sjkim ASN1_TYPE_free(field->p.other); 324160814Ssimon 325280304Sjkim nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); 326280304Sjkim /* set OID for the field */ 327280304Sjkim if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { 328280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); 329280304Sjkim goto err; 330280304Sjkim } 331280304Sjkim 332280304Sjkim if (nid == NID_X9_62_prime_field) { 333280304Sjkim if ((tmp = BN_new()) == NULL) { 334280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 335280304Sjkim goto err; 336280304Sjkim } 337280304Sjkim /* the parameters are specified by the prime number p */ 338280304Sjkim if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) { 339280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); 340280304Sjkim goto err; 341280304Sjkim } 342280304Sjkim /* set the prime number */ 343280304Sjkim field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL); 344280304Sjkim if (field->p.prime == NULL) { 345280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); 346280304Sjkim goto err; 347280304Sjkim } 348280304Sjkim } else /* nid == NID_X9_62_characteristic_two_field */ 349238405Sjkim#ifdef OPENSSL_NO_EC2M 350280304Sjkim { 351280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED); 352280304Sjkim goto err; 353280304Sjkim } 354238405Sjkim#else 355280304Sjkim { 356280304Sjkim int field_type; 357280304Sjkim X9_62_CHARACTERISTIC_TWO *char_two; 358160814Ssimon 359280304Sjkim field->p.char_two = X9_62_CHARACTERISTIC_TWO_new(); 360280304Sjkim char_two = field->p.char_two; 361160814Ssimon 362280304Sjkim if (char_two == NULL) { 363280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 364280304Sjkim goto err; 365280304Sjkim } 366160814Ssimon 367280304Sjkim char_two->m = (long)EC_GROUP_get_degree(group); 368160814Ssimon 369280304Sjkim field_type = EC_GROUP_get_basis_type(group); 370160814Ssimon 371280304Sjkim if (field_type == 0) { 372280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); 373280304Sjkim goto err; 374280304Sjkim } 375280304Sjkim /* set base type OID */ 376280304Sjkim if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) { 377280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); 378280304Sjkim goto err; 379280304Sjkim } 380160814Ssimon 381280304Sjkim if (field_type == NID_X9_62_tpBasis) { 382280304Sjkim unsigned int k; 383160814Ssimon 384280304Sjkim if (!EC_GROUP_get_trinomial_basis(group, &k)) 385280304Sjkim goto err; 386160814Ssimon 387280304Sjkim char_two->p.tpBasis = ASN1_INTEGER_new(); 388280304Sjkim if (!char_two->p.tpBasis) { 389280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 390280304Sjkim goto err; 391280304Sjkim } 392280304Sjkim if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) { 393280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); 394280304Sjkim goto err; 395280304Sjkim } 396280304Sjkim } else if (field_type == NID_X9_62_ppBasis) { 397280304Sjkim unsigned int k1, k2, k3; 398160814Ssimon 399280304Sjkim if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)) 400280304Sjkim goto err; 401160814Ssimon 402280304Sjkim char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); 403280304Sjkim if (!char_two->p.ppBasis) { 404280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 405280304Sjkim goto err; 406280304Sjkim } 407280304Sjkim 408280304Sjkim /* set k? values */ 409280304Sjkim char_two->p.ppBasis->k1 = (long)k1; 410280304Sjkim char_two->p.ppBasis->k2 = (long)k2; 411280304Sjkim char_two->p.ppBasis->k3 = (long)k3; 412280304Sjkim } else { /* field_type == NID_X9_62_onBasis */ 413280304Sjkim 414280304Sjkim /* for ONB the parameters are (asn1) NULL */ 415280304Sjkim char_two->p.onBasis = ASN1_NULL_new(); 416280304Sjkim if (!char_two->p.onBasis) { 417280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 418280304Sjkim goto err; 419280304Sjkim } 420280304Sjkim } 421280304Sjkim } 422238405Sjkim#endif 423160814Ssimon 424280304Sjkim ok = 1; 425160814Ssimon 426280304Sjkim err:if (tmp) 427280304Sjkim BN_free(tmp); 428280304Sjkim return (ok); 429160814Ssimon} 430160814Ssimon 431160814Ssimonstatic int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) 432280304Sjkim{ 433280304Sjkim int ok = 0, nid; 434280304Sjkim BIGNUM *tmp_1 = NULL, *tmp_2 = NULL; 435280304Sjkim unsigned char *buffer_1 = NULL, *buffer_2 = NULL, 436280304Sjkim *a_buf = NULL, *b_buf = NULL; 437280304Sjkim size_t len_1, len_2; 438280304Sjkim unsigned char char_zero = 0; 439160814Ssimon 440280304Sjkim if (!group || !curve || !curve->a || !curve->b) 441280304Sjkim return 0; 442160814Ssimon 443280304Sjkim if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { 444280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); 445280304Sjkim goto err; 446280304Sjkim } 447160814Ssimon 448280304Sjkim nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); 449160814Ssimon 450280304Sjkim /* get a and b */ 451280304Sjkim if (nid == NID_X9_62_prime_field) { 452280304Sjkim if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) { 453280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); 454280304Sjkim goto err; 455280304Sjkim } 456280304Sjkim } 457238405Sjkim#ifndef OPENSSL_NO_EC2M 458280304Sjkim else { /* nid == NID_X9_62_characteristic_two_field */ 459280304Sjkim 460280304Sjkim if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) { 461280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); 462280304Sjkim goto err; 463280304Sjkim } 464280304Sjkim } 465238405Sjkim#endif 466280304Sjkim len_1 = (size_t)BN_num_bytes(tmp_1); 467280304Sjkim len_2 = (size_t)BN_num_bytes(tmp_2); 468160814Ssimon 469280304Sjkim if (len_1 == 0) { 470280304Sjkim /* len_1 == 0 => a == 0 */ 471280304Sjkim a_buf = &char_zero; 472280304Sjkim len_1 = 1; 473280304Sjkim } else { 474280304Sjkim if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) { 475280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); 476280304Sjkim goto err; 477280304Sjkim } 478280304Sjkim if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) { 479280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); 480280304Sjkim goto err; 481280304Sjkim } 482280304Sjkim a_buf = buffer_1; 483280304Sjkim } 484160814Ssimon 485280304Sjkim if (len_2 == 0) { 486280304Sjkim /* len_2 == 0 => b == 0 */ 487280304Sjkim b_buf = &char_zero; 488280304Sjkim len_2 = 1; 489280304Sjkim } else { 490280304Sjkim if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) { 491280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); 492280304Sjkim goto err; 493280304Sjkim } 494280304Sjkim if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) { 495280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); 496280304Sjkim goto err; 497280304Sjkim } 498280304Sjkim b_buf = buffer_2; 499280304Sjkim } 500160814Ssimon 501280304Sjkim /* set a and b */ 502280304Sjkim if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) || 503280304Sjkim !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) { 504280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); 505280304Sjkim goto err; 506280304Sjkim } 507160814Ssimon 508280304Sjkim /* set the seed (optional) */ 509280304Sjkim if (group->seed) { 510280304Sjkim if (!curve->seed) 511280304Sjkim if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { 512280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); 513280304Sjkim goto err; 514280304Sjkim } 515280304Sjkim curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 516280304Sjkim curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; 517280304Sjkim if (!ASN1_BIT_STRING_set(curve->seed, group->seed, 518280304Sjkim (int)group->seed_len)) { 519280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); 520280304Sjkim goto err; 521280304Sjkim } 522280304Sjkim } else { 523280304Sjkim if (curve->seed) { 524280304Sjkim ASN1_BIT_STRING_free(curve->seed); 525280304Sjkim curve->seed = NULL; 526280304Sjkim } 527280304Sjkim } 528160814Ssimon 529280304Sjkim ok = 1; 530280304Sjkim 531280304Sjkim err:if (buffer_1) 532280304Sjkim OPENSSL_free(buffer_1); 533280304Sjkim if (buffer_2) 534280304Sjkim OPENSSL_free(buffer_2); 535280304Sjkim if (tmp_1) 536280304Sjkim BN_free(tmp_1); 537280304Sjkim if (tmp_2) 538280304Sjkim BN_free(tmp_2); 539280304Sjkim return (ok); 540280304Sjkim} 541280304Sjkim 542160814Ssimonstatic ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, 543160814Ssimon ECPARAMETERS *param) 544280304Sjkim{ 545280304Sjkim int ok = 0; 546280304Sjkim size_t len = 0; 547280304Sjkim ECPARAMETERS *ret = NULL; 548280304Sjkim BIGNUM *tmp = NULL; 549280304Sjkim unsigned char *buffer = NULL; 550280304Sjkim const EC_POINT *point = NULL; 551280304Sjkim point_conversion_form_t form; 552160814Ssimon 553280304Sjkim if ((tmp = BN_new()) == NULL) { 554280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 555280304Sjkim goto err; 556280304Sjkim } 557160814Ssimon 558280304Sjkim if (param == NULL) { 559280304Sjkim if ((ret = ECPARAMETERS_new()) == NULL) { 560280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 561280304Sjkim goto err; 562280304Sjkim } 563280304Sjkim } else 564280304Sjkim ret = param; 565160814Ssimon 566280304Sjkim /* set the version (always one) */ 567280304Sjkim ret->version = (long)0x1; 568160814Ssimon 569280304Sjkim /* set the fieldID */ 570280304Sjkim if (!ec_asn1_group2fieldid(group, ret->fieldID)) { 571280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 572280304Sjkim goto err; 573280304Sjkim } 574160814Ssimon 575280304Sjkim /* set the curve */ 576280304Sjkim if (!ec_asn1_group2curve(group, ret->curve)) { 577280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 578280304Sjkim goto err; 579280304Sjkim } 580160814Ssimon 581280304Sjkim /* set the base point */ 582280304Sjkim if ((point = EC_GROUP_get0_generator(group)) == NULL) { 583280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR); 584280304Sjkim goto err; 585280304Sjkim } 586160814Ssimon 587280304Sjkim form = EC_GROUP_get_point_conversion_form(group); 588160814Ssimon 589280304Sjkim len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); 590280304Sjkim if (len == 0) { 591280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 592280304Sjkim goto err; 593280304Sjkim } 594280304Sjkim if ((buffer = OPENSSL_malloc(len)) == NULL) { 595280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 596280304Sjkim goto err; 597280304Sjkim } 598280304Sjkim if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) { 599280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 600280304Sjkim goto err; 601280304Sjkim } 602280304Sjkim if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { 603280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 604280304Sjkim goto err; 605280304Sjkim } 606280304Sjkim if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) { 607280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); 608280304Sjkim goto err; 609280304Sjkim } 610160814Ssimon 611280304Sjkim /* set the order */ 612280304Sjkim if (!EC_GROUP_get_order(group, tmp, NULL)) { 613280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 614280304Sjkim goto err; 615280304Sjkim } 616280304Sjkim ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); 617280304Sjkim if (ret->order == NULL) { 618280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); 619280304Sjkim goto err; 620280304Sjkim } 621160814Ssimon 622280304Sjkim /* set the cofactor (optional) */ 623280304Sjkim if (EC_GROUP_get_cofactor(group, tmp, NULL)) { 624280304Sjkim ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); 625280304Sjkim if (ret->cofactor == NULL) { 626280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); 627280304Sjkim goto err; 628280304Sjkim } 629280304Sjkim } 630160814Ssimon 631280304Sjkim ok = 1; 632160814Ssimon 633280304Sjkim err:if (!ok) { 634280304Sjkim if (ret && !param) 635280304Sjkim ECPARAMETERS_free(ret); 636280304Sjkim ret = NULL; 637280304Sjkim } 638280304Sjkim if (tmp) 639280304Sjkim BN_free(tmp); 640280304Sjkim if (buffer) 641280304Sjkim OPENSSL_free(buffer); 642280304Sjkim return (ret); 643280304Sjkim} 644160814Ssimon 645280304SjkimECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, 646160814Ssimon ECPKPARAMETERS *params) 647280304Sjkim{ 648280304Sjkim int ok = 1, tmp; 649280304Sjkim ECPKPARAMETERS *ret = params; 650160814Ssimon 651280304Sjkim if (ret == NULL) { 652280304Sjkim if ((ret = ECPKPARAMETERS_new()) == NULL) { 653280304Sjkim ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, ERR_R_MALLOC_FAILURE); 654280304Sjkim return NULL; 655280304Sjkim } 656280304Sjkim } else { 657280304Sjkim if (ret->type == 0 && ret->value.named_curve) 658280304Sjkim ASN1_OBJECT_free(ret->value.named_curve); 659280304Sjkim else if (ret->type == 1 && ret->value.parameters) 660280304Sjkim ECPARAMETERS_free(ret->value.parameters); 661280304Sjkim } 662160814Ssimon 663280304Sjkim if (EC_GROUP_get_asn1_flag(group)) { 664280304Sjkim /* 665280304Sjkim * use the asn1 OID to describe the the elliptic curve parameters 666280304Sjkim */ 667280304Sjkim tmp = EC_GROUP_get_curve_name(group); 668280304Sjkim if (tmp) { 669280304Sjkim ret->type = 0; 670280304Sjkim if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL) 671280304Sjkim ok = 0; 672280304Sjkim } else 673280304Sjkim /* we don't kmow the nid => ERROR */ 674280304Sjkim ok = 0; 675280304Sjkim } else { 676280304Sjkim /* use the ECPARAMETERS structure */ 677280304Sjkim ret->type = 1; 678280304Sjkim if ((ret->value.parameters = 679280304Sjkim ec_asn1_group2parameters(group, NULL)) == NULL) 680280304Sjkim ok = 0; 681280304Sjkim } 682160814Ssimon 683280304Sjkim if (!ok) { 684280304Sjkim ECPKPARAMETERS_free(ret); 685280304Sjkim return NULL; 686280304Sjkim } 687280304Sjkim return ret; 688280304Sjkim} 689160814Ssimon 690160814Ssimonstatic EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params) 691280304Sjkim{ 692280304Sjkim int ok = 0, tmp; 693280304Sjkim EC_GROUP *ret = NULL; 694280304Sjkim BIGNUM *p = NULL, *a = NULL, *b = NULL; 695280304Sjkim EC_POINT *point = NULL; 696280304Sjkim long field_bits; 697160814Ssimon 698280304Sjkim if (!params->fieldID || !params->fieldID->fieldType || 699280304Sjkim !params->fieldID->p.ptr) { 700280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 701280304Sjkim goto err; 702280304Sjkim } 703160814Ssimon 704280304Sjkim /* now extract the curve parameters a and b */ 705280304Sjkim if (!params->curve || !params->curve->a || 706280304Sjkim !params->curve->a->data || !params->curve->b || 707280304Sjkim !params->curve->b->data) { 708280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 709280304Sjkim goto err; 710280304Sjkim } 711280304Sjkim a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); 712280304Sjkim if (a == NULL) { 713280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); 714280304Sjkim goto err; 715280304Sjkim } 716280304Sjkim b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); 717280304Sjkim if (b == NULL) { 718280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); 719280304Sjkim goto err; 720280304Sjkim } 721160814Ssimon 722280304Sjkim /* get the field parameters */ 723280304Sjkim tmp = OBJ_obj2nid(params->fieldID->fieldType); 724280304Sjkim if (tmp == NID_X9_62_characteristic_two_field) 725238405Sjkim#ifdef OPENSSL_NO_EC2M 726280304Sjkim { 727280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED); 728280304Sjkim goto err; 729280304Sjkim } 730238405Sjkim#else 731280304Sjkim { 732280304Sjkim X9_62_CHARACTERISTIC_TWO *char_two; 733160814Ssimon 734280304Sjkim char_two = params->fieldID->p.char_two; 735160814Ssimon 736280304Sjkim field_bits = char_two->m; 737280304Sjkim if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { 738280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); 739280304Sjkim goto err; 740280304Sjkim } 741162911Ssimon 742280304Sjkim if ((p = BN_new()) == NULL) { 743280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); 744280304Sjkim goto err; 745280304Sjkim } 746160814Ssimon 747280304Sjkim /* get the base type */ 748280304Sjkim tmp = OBJ_obj2nid(char_two->type); 749160814Ssimon 750280304Sjkim if (tmp == NID_X9_62_tpBasis) { 751280304Sjkim long tmp_long; 752160814Ssimon 753280304Sjkim if (!char_two->p.tpBasis) { 754280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 755280304Sjkim goto err; 756280304Sjkim } 757160814Ssimon 758280304Sjkim tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis); 759162911Ssimon 760280304Sjkim if (!(char_two->m > tmp_long && tmp_long > 0)) { 761280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 762280304Sjkim EC_R_INVALID_TRINOMIAL_BASIS); 763280304Sjkim goto err; 764280304Sjkim } 765160814Ssimon 766280304Sjkim /* create the polynomial */ 767280304Sjkim if (!BN_set_bit(p, (int)char_two->m)) 768280304Sjkim goto err; 769280304Sjkim if (!BN_set_bit(p, (int)tmp_long)) 770280304Sjkim goto err; 771280304Sjkim if (!BN_set_bit(p, 0)) 772280304Sjkim goto err; 773280304Sjkim } else if (tmp == NID_X9_62_ppBasis) { 774280304Sjkim X9_62_PENTANOMIAL *penta; 775162911Ssimon 776280304Sjkim penta = char_two->p.ppBasis; 777280304Sjkim if (!penta) { 778280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 779280304Sjkim goto err; 780280304Sjkim } 781160814Ssimon 782280304Sjkim if (! 783280304Sjkim (char_two->m > penta->k3 && penta->k3 > penta->k2 784280304Sjkim && penta->k2 > penta->k1 && penta->k1 > 0)) { 785280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 786280304Sjkim EC_R_INVALID_PENTANOMIAL_BASIS); 787280304Sjkim goto err; 788280304Sjkim } 789280304Sjkim 790280304Sjkim /* create the polynomial */ 791280304Sjkim if (!BN_set_bit(p, (int)char_two->m)) 792280304Sjkim goto err; 793280304Sjkim if (!BN_set_bit(p, (int)penta->k1)) 794280304Sjkim goto err; 795280304Sjkim if (!BN_set_bit(p, (int)penta->k2)) 796280304Sjkim goto err; 797280304Sjkim if (!BN_set_bit(p, (int)penta->k3)) 798280304Sjkim goto err; 799280304Sjkim if (!BN_set_bit(p, 0)) 800280304Sjkim goto err; 801280304Sjkim } else if (tmp == NID_X9_62_onBasis) { 802280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED); 803280304Sjkim goto err; 804280304Sjkim } else { /* error */ 805280304Sjkim 806280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 807280304Sjkim goto err; 808280304Sjkim } 809280304Sjkim 810280304Sjkim /* create the EC_GROUP structure */ 811280304Sjkim ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL); 812280304Sjkim } 813238405Sjkim#endif 814280304Sjkim else if (tmp == NID_X9_62_prime_field) { 815280304Sjkim /* we have a curve over a prime field */ 816280304Sjkim /* extract the prime number */ 817280304Sjkim if (!params->fieldID->p.prime) { 818280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 819280304Sjkim goto err; 820280304Sjkim } 821280304Sjkim p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); 822280304Sjkim if (p == NULL) { 823280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); 824280304Sjkim goto err; 825280304Sjkim } 826162911Ssimon 827280304Sjkim if (BN_is_negative(p) || BN_is_zero(p)) { 828280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); 829280304Sjkim goto err; 830280304Sjkim } 831162911Ssimon 832280304Sjkim field_bits = BN_num_bits(p); 833280304Sjkim if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { 834280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); 835280304Sjkim goto err; 836280304Sjkim } 837162911Ssimon 838280304Sjkim /* create the EC_GROUP structure */ 839280304Sjkim ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); 840280304Sjkim } else { 841280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); 842280304Sjkim goto err; 843280304Sjkim } 844160814Ssimon 845280304Sjkim if (ret == NULL) { 846280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); 847280304Sjkim goto err; 848280304Sjkim } 849160814Ssimon 850280304Sjkim /* extract seed (optional) */ 851280304Sjkim if (params->curve->seed != NULL) { 852280304Sjkim if (ret->seed != NULL) 853280304Sjkim OPENSSL_free(ret->seed); 854280304Sjkim if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) { 855280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); 856280304Sjkim goto err; 857280304Sjkim } 858280304Sjkim memcpy(ret->seed, params->curve->seed->data, 859280304Sjkim params->curve->seed->length); 860280304Sjkim ret->seed_len = params->curve->seed->length; 861280304Sjkim } 862160814Ssimon 863280304Sjkim if (!params->order || !params->base || !params->base->data) { 864280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 865280304Sjkim goto err; 866280304Sjkim } 867160814Ssimon 868280304Sjkim if ((point = EC_POINT_new(ret)) == NULL) 869280304Sjkim goto err; 870160814Ssimon 871280304Sjkim /* set the point conversion form */ 872280304Sjkim EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) 873280304Sjkim (params->base->data[0] & ~0x01)); 874160814Ssimon 875280304Sjkim /* extract the ec point */ 876280304Sjkim if (!EC_POINT_oct2point(ret, point, params->base->data, 877280304Sjkim params->base->length, NULL)) { 878280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); 879280304Sjkim goto err; 880280304Sjkim } 881160814Ssimon 882280304Sjkim /* extract the order */ 883280304Sjkim if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) { 884280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); 885280304Sjkim goto err; 886280304Sjkim } 887280304Sjkim if (BN_is_negative(a) || BN_is_zero(a)) { 888280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); 889280304Sjkim goto err; 890280304Sjkim } 891280304Sjkim if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */ 892280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); 893280304Sjkim goto err; 894280304Sjkim } 895160814Ssimon 896280304Sjkim /* extract the cofactor (optional) */ 897280304Sjkim if (params->cofactor == NULL) { 898280304Sjkim if (b) { 899280304Sjkim BN_free(b); 900280304Sjkim b = NULL; 901280304Sjkim } 902280304Sjkim } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) { 903280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); 904280304Sjkim goto err; 905280304Sjkim } 906280304Sjkim /* set the generator, order and cofactor (if present) */ 907280304Sjkim if (!EC_GROUP_set_generator(ret, point, a, b)) { 908280304Sjkim ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); 909280304Sjkim goto err; 910280304Sjkim } 911160814Ssimon 912280304Sjkim ok = 1; 913160814Ssimon 914280304Sjkim err:if (!ok) { 915280304Sjkim if (ret) 916280304Sjkim EC_GROUP_clear_free(ret); 917280304Sjkim ret = NULL; 918280304Sjkim } 919280304Sjkim 920280304Sjkim if (p) 921280304Sjkim BN_free(p); 922280304Sjkim if (a) 923280304Sjkim BN_free(a); 924280304Sjkim if (b) 925280304Sjkim BN_free(b); 926280304Sjkim if (point) 927280304Sjkim EC_POINT_free(point); 928280304Sjkim return (ret); 929160814Ssimon} 930160814Ssimon 931160814SsimonEC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) 932280304Sjkim{ 933280304Sjkim EC_GROUP *ret = NULL; 934280304Sjkim int tmp = 0; 935160814Ssimon 936280304Sjkim if (params == NULL) { 937280304Sjkim ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_MISSING_PARAMETERS); 938280304Sjkim return NULL; 939280304Sjkim } 940160814Ssimon 941280304Sjkim if (params->type == 0) { /* the curve is given by an OID */ 942280304Sjkim tmp = OBJ_obj2nid(params->value.named_curve); 943280304Sjkim if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { 944280304Sjkim ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 945280304Sjkim EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 946280304Sjkim return NULL; 947280304Sjkim } 948280304Sjkim EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); 949280304Sjkim } else if (params->type == 1) { /* the parameters are given by a 950280304Sjkim * ECPARAMETERS structure */ 951280304Sjkim ret = ec_asn1_parameters2group(params->value.parameters); 952280304Sjkim if (!ret) { 953280304Sjkim ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB); 954280304Sjkim return NULL; 955280304Sjkim } 956280304Sjkim EC_GROUP_set_asn1_flag(ret, 0x0); 957280304Sjkim } else if (params->type == 2) { /* implicitlyCA */ 958280304Sjkim return NULL; 959280304Sjkim } else { 960280304Sjkim ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR); 961280304Sjkim return NULL; 962280304Sjkim } 963160814Ssimon 964280304Sjkim return ret; 965280304Sjkim} 966160814Ssimon 967160814Ssimon/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */ 968160814Ssimon 969160814SsimonEC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) 970280304Sjkim{ 971280304Sjkim EC_GROUP *group = NULL; 972280304Sjkim ECPKPARAMETERS *params = NULL; 973291721Sjkim const unsigned char *p = *in; 974160814Ssimon 975291721Sjkim if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) { 976280304Sjkim ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE); 977280304Sjkim ECPKPARAMETERS_free(params); 978280304Sjkim return NULL; 979280304Sjkim } 980160814Ssimon 981280304Sjkim if ((group = ec_asn1_pkparameters2group(params)) == NULL) { 982280304Sjkim ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE); 983280304Sjkim ECPKPARAMETERS_free(params); 984280304Sjkim return NULL; 985280304Sjkim } 986160814Ssimon 987280304Sjkim if (a && *a) 988280304Sjkim EC_GROUP_clear_free(*a); 989280304Sjkim if (a) 990280304Sjkim *a = group; 991160814Ssimon 992280304Sjkim ECPKPARAMETERS_free(params); 993291721Sjkim *in = p; 994280304Sjkim return (group); 995280304Sjkim} 996280304Sjkim 997160814Ssimonint i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) 998280304Sjkim{ 999280304Sjkim int ret = 0; 1000280304Sjkim ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL); 1001280304Sjkim if (tmp == NULL) { 1002280304Sjkim ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE); 1003280304Sjkim return 0; 1004280304Sjkim } 1005280304Sjkim if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) { 1006280304Sjkim ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE); 1007280304Sjkim ECPKPARAMETERS_free(tmp); 1008280304Sjkim return 0; 1009280304Sjkim } 1010280304Sjkim ECPKPARAMETERS_free(tmp); 1011280304Sjkim return (ret); 1012280304Sjkim} 1013160814Ssimon 1014160814Ssimon/* some EC_KEY functions */ 1015160814Ssimon 1016160814SsimonEC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) 1017280304Sjkim{ 1018280304Sjkim int ok = 0; 1019280304Sjkim EC_KEY *ret = NULL; 1020280304Sjkim EC_PRIVATEKEY *priv_key = NULL; 1021291721Sjkim const unsigned char *p = *in; 1022160814Ssimon 1023291721Sjkim if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) { 1024280304Sjkim ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1025280304Sjkim return NULL; 1026280304Sjkim } 1027160814Ssimon 1028280304Sjkim if (a == NULL || *a == NULL) { 1029280304Sjkim if ((ret = EC_KEY_new()) == NULL) { 1030280304Sjkim ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1031280304Sjkim goto err; 1032280304Sjkim } 1033280304Sjkim } else 1034280304Sjkim ret = *a; 1035160814Ssimon 1036280304Sjkim if (priv_key->parameters) { 1037280304Sjkim if (ret->group) 1038280304Sjkim EC_GROUP_clear_free(ret->group); 1039280304Sjkim ret->group = ec_asn1_pkparameters2group(priv_key->parameters); 1040280304Sjkim } 1041160814Ssimon 1042280304Sjkim if (ret->group == NULL) { 1043280304Sjkim ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1044280304Sjkim goto err; 1045280304Sjkim } 1046160814Ssimon 1047280304Sjkim ret->version = priv_key->version; 1048160814Ssimon 1049280304Sjkim if (priv_key->privateKey) { 1050280304Sjkim ret->priv_key = BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey), 1051280304Sjkim M_ASN1_STRING_length(priv_key->privateKey), 1052280304Sjkim ret->priv_key); 1053280304Sjkim if (ret->priv_key == NULL) { 1054280304Sjkim ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB); 1055280304Sjkim goto err; 1056280304Sjkim } 1057280304Sjkim } else { 1058280304Sjkim ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY); 1059280304Sjkim goto err; 1060280304Sjkim } 1061160814Ssimon 1062280304Sjkim if (ret->pub_key) 1063280304Sjkim EC_POINT_clear_free(ret->pub_key); 1064280304Sjkim ret->pub_key = EC_POINT_new(ret->group); 1065280304Sjkim if (ret->pub_key == NULL) { 1066280304Sjkim ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1067280304Sjkim goto err; 1068280304Sjkim } 1069160814Ssimon 1070280304Sjkim if (priv_key->publicKey) { 1071280304Sjkim const unsigned char *pub_oct; 1072280304Sjkim int pub_oct_len; 1073273149Sjkim 1074280304Sjkim pub_oct = M_ASN1_STRING_data(priv_key->publicKey); 1075280304Sjkim pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey); 1076280304Sjkim /* 1077280304Sjkim * The first byte - point conversion form - must be present. 1078280304Sjkim */ 1079280304Sjkim if (pub_oct_len <= 0) { 1080280304Sjkim ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); 1081280304Sjkim goto err; 1082280304Sjkim } 1083280304Sjkim /* Save the point conversion form. */ 1084280304Sjkim ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01); 1085280304Sjkim if (!EC_POINT_oct2point(ret->group, ret->pub_key, 1086280304Sjkim pub_oct, (size_t)(pub_oct_len), NULL)) { 1087280304Sjkim ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1088280304Sjkim goto err; 1089280304Sjkim } 1090280304Sjkim } else { 1091280304Sjkim if (!EC_POINT_mul 1092280304Sjkim (ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) { 1093280304Sjkim ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1094280304Sjkim goto err; 1095280304Sjkim } 1096280304Sjkim /* Remember the original private-key-only encoding. */ 1097280304Sjkim ret->enc_flag |= EC_PKEY_NO_PUBKEY; 1098280304Sjkim } 1099160814Ssimon 1100280304Sjkim if (a) 1101280304Sjkim *a = ret; 1102291721Sjkim *in = p; 1103280304Sjkim ok = 1; 1104280304Sjkim err: 1105280304Sjkim if (!ok) { 1106280304Sjkim if (ret && (a == NULL || *a != ret)) 1107280304Sjkim EC_KEY_free(ret); 1108280304Sjkim ret = NULL; 1109280304Sjkim } 1110160814Ssimon 1111280304Sjkim if (priv_key) 1112280304Sjkim EC_PRIVATEKEY_free(priv_key); 1113160814Ssimon 1114280304Sjkim return (ret); 1115280304Sjkim} 1116160814Ssimon 1117280304Sjkimint i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) 1118280304Sjkim{ 1119280304Sjkim int ret = 0, ok = 0; 1120280304Sjkim unsigned char *buffer = NULL; 1121284285Sjkim size_t buf_len = 0, tmp_len, bn_len; 1122280304Sjkim EC_PRIVATEKEY *priv_key = NULL; 1123160814Ssimon 1124280304Sjkim if (a == NULL || a->group == NULL || a->priv_key == NULL || 1125280304Sjkim (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { 1126280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 1127280304Sjkim goto err; 1128280304Sjkim } 1129160814Ssimon 1130280304Sjkim if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { 1131280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1132280304Sjkim goto err; 1133280304Sjkim } 1134160814Ssimon 1135280304Sjkim priv_key->version = a->version; 1136160814Ssimon 1137284285Sjkim bn_len = (size_t)BN_num_bytes(a->priv_key); 1138284285Sjkim 1139284285Sjkim /* Octetstring may need leading zeros if BN is to short */ 1140284285Sjkim 1141284285Sjkim buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8; 1142284285Sjkim 1143284285Sjkim if (bn_len > buf_len) { 1144284285Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); 1145284285Sjkim goto err; 1146284285Sjkim } 1147284285Sjkim 1148280304Sjkim buffer = OPENSSL_malloc(buf_len); 1149280304Sjkim if (buffer == NULL) { 1150280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1151280304Sjkim goto err; 1152280304Sjkim } 1153160814Ssimon 1154284285Sjkim if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) { 1155280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); 1156280304Sjkim goto err; 1157280304Sjkim } 1158160814Ssimon 1159284285Sjkim if (buf_len - bn_len > 0) { 1160284285Sjkim memset(buffer, 0, buf_len - bn_len); 1161284285Sjkim } 1162284285Sjkim 1163280304Sjkim if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) { 1164280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); 1165280304Sjkim goto err; 1166280304Sjkim } 1167160814Ssimon 1168280304Sjkim if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) { 1169280304Sjkim if ((priv_key->parameters = 1170280304Sjkim ec_asn1_group2pkparameters(a->group, 1171280304Sjkim priv_key->parameters)) == NULL) { 1172280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); 1173280304Sjkim goto err; 1174280304Sjkim } 1175280304Sjkim } 1176160814Ssimon 1177280304Sjkim if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) { 1178280304Sjkim priv_key->publicKey = M_ASN1_BIT_STRING_new(); 1179280304Sjkim if (priv_key->publicKey == NULL) { 1180280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1181280304Sjkim goto err; 1182280304Sjkim } 1183160814Ssimon 1184280304Sjkim tmp_len = EC_POINT_point2oct(a->group, a->pub_key, 1185280304Sjkim a->conv_form, NULL, 0, NULL); 1186160814Ssimon 1187280304Sjkim if (tmp_len > buf_len) { 1188280304Sjkim unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len); 1189280304Sjkim if (!tmp_buffer) { 1190280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1191280304Sjkim goto err; 1192280304Sjkim } 1193280304Sjkim buffer = tmp_buffer; 1194280304Sjkim buf_len = tmp_len; 1195280304Sjkim } 1196160814Ssimon 1197280304Sjkim if (!EC_POINT_point2oct(a->group, a->pub_key, 1198280304Sjkim a->conv_form, buffer, buf_len, NULL)) { 1199280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); 1200280304Sjkim goto err; 1201280304Sjkim } 1202160814Ssimon 1203280304Sjkim priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 1204280304Sjkim priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; 1205280304Sjkim if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) { 1206280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); 1207280304Sjkim goto err; 1208280304Sjkim } 1209280304Sjkim } 1210160814Ssimon 1211280304Sjkim if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) { 1212280304Sjkim ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); 1213280304Sjkim goto err; 1214280304Sjkim } 1215280304Sjkim ok = 1; 1216280304Sjkim err: 1217280304Sjkim if (buffer) 1218280304Sjkim OPENSSL_free(buffer); 1219280304Sjkim if (priv_key) 1220280304Sjkim EC_PRIVATEKEY_free(priv_key); 1221280304Sjkim return (ok ? ret : 0); 1222280304Sjkim} 1223160814Ssimon 1224160814Ssimonint i2d_ECParameters(EC_KEY *a, unsigned char **out) 1225280304Sjkim{ 1226280304Sjkim if (a == NULL) { 1227280304Sjkim ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); 1228280304Sjkim return 0; 1229280304Sjkim } 1230280304Sjkim return i2d_ECPKParameters(a->group, out); 1231280304Sjkim} 1232160814Ssimon 1233160814SsimonEC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) 1234280304Sjkim{ 1235280304Sjkim EC_KEY *ret; 1236160814Ssimon 1237280304Sjkim if (in == NULL || *in == NULL) { 1238280304Sjkim ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); 1239280304Sjkim return NULL; 1240280304Sjkim } 1241160814Ssimon 1242280304Sjkim if (a == NULL || *a == NULL) { 1243280304Sjkim if ((ret = EC_KEY_new()) == NULL) { 1244280304Sjkim ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE); 1245280304Sjkim return NULL; 1246280304Sjkim } 1247280304Sjkim } else 1248280304Sjkim ret = *a; 1249160814Ssimon 1250280304Sjkim if (!d2i_ECPKParameters(&ret->group, in, len)) { 1251280304Sjkim ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); 1252280304Sjkim if (a == NULL || *a != ret) 1253280304Sjkim EC_KEY_free(ret); 1254280304Sjkim return NULL; 1255280304Sjkim } 1256160814Ssimon 1257280304Sjkim if (a) 1258280304Sjkim *a = ret; 1259160814Ssimon 1260280304Sjkim return ret; 1261280304Sjkim} 1262280304Sjkim 1263160814SsimonEC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) 1264280304Sjkim{ 1265280304Sjkim EC_KEY *ret = NULL; 1266160814Ssimon 1267280304Sjkim if (a == NULL || (*a) == NULL || (*a)->group == NULL) { 1268280304Sjkim /* 1269280304Sjkim * sorry, but a EC_GROUP-structur is necessary to set the public key 1270280304Sjkim */ 1271280304Sjkim ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); 1272280304Sjkim return 0; 1273280304Sjkim } 1274280304Sjkim ret = *a; 1275280304Sjkim if (ret->pub_key == NULL && 1276280304Sjkim (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { 1277280304Sjkim ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); 1278280304Sjkim return 0; 1279280304Sjkim } 1280280304Sjkim if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) { 1281280304Sjkim ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB); 1282280304Sjkim return 0; 1283280304Sjkim } 1284280304Sjkim /* save the point conversion form */ 1285280304Sjkim ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01); 1286280304Sjkim *in += len; 1287280304Sjkim return ret; 1288280304Sjkim} 1289160814Ssimon 1290160814Ssimonint i2o_ECPublicKey(EC_KEY *a, unsigned char **out) 1291280304Sjkim{ 1292280304Sjkim size_t buf_len = 0; 1293280304Sjkim int new_buffer = 0; 1294160814Ssimon 1295280304Sjkim if (a == NULL) { 1296280304Sjkim ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); 1297280304Sjkim return 0; 1298280304Sjkim } 1299160814Ssimon 1300280304Sjkim buf_len = EC_POINT_point2oct(a->group, a->pub_key, 1301280304Sjkim a->conv_form, NULL, 0, NULL); 1302160814Ssimon 1303280304Sjkim if (out == NULL || buf_len == 0) 1304280304Sjkim /* out == NULL => just return the length of the octet string */ 1305280304Sjkim return buf_len; 1306160814Ssimon 1307280304Sjkim if (*out == NULL) { 1308280304Sjkim if ((*out = OPENSSL_malloc(buf_len)) == NULL) { 1309280304Sjkim ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); 1310280304Sjkim return 0; 1311280304Sjkim } 1312280304Sjkim new_buffer = 1; 1313280304Sjkim } 1314280304Sjkim if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, 1315280304Sjkim *out, buf_len, NULL)) { 1316280304Sjkim ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB); 1317280304Sjkim if (new_buffer) { 1318280304Sjkim OPENSSL_free(*out); 1319280304Sjkim *out = NULL; 1320280304Sjkim } 1321280304Sjkim return 0; 1322280304Sjkim } 1323280304Sjkim if (!new_buffer) 1324280304Sjkim *out += buf_len; 1325280304Sjkim return buf_len; 1326280304Sjkim} 1327