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 13296341Sdelphij * 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) 66296341Sdelphij{ 67296341Sdelphij int i = 0; 68160814Ssimon 69296341Sdelphij if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 70296341Sdelphij NID_X9_62_characteristic_two_field) 71296341Sdelphij /* everything else is currently not supported */ 72296341Sdelphij return 0; 73160814Ssimon 74296341Sdelphij while (group->poly[i] != 0) 75296341Sdelphij i++; 76160814Ssimon 77296341Sdelphij if (i == 4) 78296341Sdelphij return NID_X9_62_ppBasis; 79296341Sdelphij else if (i == 2) 80296341Sdelphij return NID_X9_62_tpBasis; 81296341Sdelphij else 82296341Sdelphij /* everything else is currently not supported */ 83296341Sdelphij return 0; 84296341Sdelphij} 85296341Sdelphij 86238405Sjkim#ifndef OPENSSL_NO_EC2M 87160814Ssimonint EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) 88296341Sdelphij{ 89296341Sdelphij if (group == NULL) 90296341Sdelphij return 0; 91160814Ssimon 92296341Sdelphij if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 93296341Sdelphij NID_X9_62_characteristic_two_field 94296341Sdelphij || !((group->poly[0] != 0) && (group->poly[1] != 0) 95296341Sdelphij && (group->poly[2] == 0))) { 96296341Sdelphij ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, 97296341Sdelphij ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 98296341Sdelphij return 0; 99296341Sdelphij } 100160814Ssimon 101296341Sdelphij if (k) 102296341Sdelphij *k = group->poly[1]; 103160814Ssimon 104296341Sdelphij return 1; 105296341Sdelphij} 106296341Sdelphij 107160814Ssimonint EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, 108296341Sdelphij unsigned int *k2, unsigned int *k3) 109296341Sdelphij{ 110296341Sdelphij if (group == NULL) 111296341Sdelphij return 0; 112160814Ssimon 113296341Sdelphij if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 114296341Sdelphij NID_X9_62_characteristic_two_field 115296341Sdelphij || !((group->poly[0] != 0) && (group->poly[1] != 0) 116296341Sdelphij && (group->poly[2] != 0) && (group->poly[3] != 0) 117296341Sdelphij && (group->poly[4] == 0))) { 118296341Sdelphij ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, 119296341Sdelphij ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 120296341Sdelphij return 0; 121296341Sdelphij } 122160814Ssimon 123296341Sdelphij if (k1) 124296341Sdelphij *k1 = group->poly[3]; 125296341Sdelphij if (k2) 126296341Sdelphij *k2 = group->poly[2]; 127296341Sdelphij if (k3) 128296341Sdelphij *k3 = group->poly[1]; 129160814Ssimon 130296341Sdelphij return 1; 131296341Sdelphij} 132238405Sjkim#endif 133160814Ssimon 134160814Ssimon/* some structures needed for the asn1 encoding */ 135160814Ssimontypedef struct x9_62_pentanomial_st { 136296341Sdelphij long k1; 137296341Sdelphij long k2; 138296341Sdelphij long k3; 139296341Sdelphij} X9_62_PENTANOMIAL; 140160814Ssimon 141160814Ssimontypedef struct x9_62_characteristic_two_st { 142296341Sdelphij long m; 143296341Sdelphij ASN1_OBJECT *type; 144296341Sdelphij union { 145296341Sdelphij char *ptr; 146296341Sdelphij /* NID_X9_62_onBasis */ 147296341Sdelphij ASN1_NULL *onBasis; 148296341Sdelphij /* NID_X9_62_tpBasis */ 149296341Sdelphij ASN1_INTEGER *tpBasis; 150296341Sdelphij /* NID_X9_62_ppBasis */ 151296341Sdelphij X9_62_PENTANOMIAL *ppBasis; 152296341Sdelphij /* anything else */ 153296341Sdelphij ASN1_TYPE *other; 154296341Sdelphij } p; 155296341Sdelphij} X9_62_CHARACTERISTIC_TWO; 156160814Ssimon 157160814Ssimontypedef struct x9_62_fieldid_st { 158296341Sdelphij ASN1_OBJECT *fieldType; 159296341Sdelphij union { 160296341Sdelphij char *ptr; 161296341Sdelphij /* NID_X9_62_prime_field */ 162296341Sdelphij ASN1_INTEGER *prime; 163296341Sdelphij /* NID_X9_62_characteristic_two_field */ 164296341Sdelphij X9_62_CHARACTERISTIC_TWO *char_two; 165296341Sdelphij /* anything else */ 166296341Sdelphij ASN1_TYPE *other; 167296341Sdelphij } p; 168296341Sdelphij} X9_62_FIELDID; 169160814Ssimon 170160814Ssimontypedef struct x9_62_curve_st { 171296341Sdelphij ASN1_OCTET_STRING *a; 172296341Sdelphij ASN1_OCTET_STRING *b; 173296341Sdelphij ASN1_BIT_STRING *seed; 174296341Sdelphij} X9_62_CURVE; 175160814Ssimon 176160814Ssimontypedef struct ec_parameters_st { 177296341Sdelphij long version; 178296341Sdelphij X9_62_FIELDID *fieldID; 179296341Sdelphij X9_62_CURVE *curve; 180296341Sdelphij ASN1_OCTET_STRING *base; 181296341Sdelphij ASN1_INTEGER *order; 182296341Sdelphij ASN1_INTEGER *cofactor; 183296341Sdelphij} ECPARAMETERS; 184160814Ssimon 185160814Ssimonstruct ecpk_parameters_st { 186296341Sdelphij int type; 187296341Sdelphij union { 188296341Sdelphij ASN1_OBJECT *named_curve; 189296341Sdelphij ECPARAMETERS *parameters; 190296341Sdelphij ASN1_NULL *implicitlyCA; 191296341Sdelphij } value; 192296341Sdelphij} /* ECPKPARAMETERS */ ; 193160814Ssimon 194160814Ssimon/* SEC1 ECPrivateKey */ 195160814Ssimontypedef struct ec_privatekey_st { 196296341Sdelphij long version; 197296341Sdelphij ASN1_OCTET_STRING *privateKey; 198296341Sdelphij ECPKPARAMETERS *parameters; 199296341Sdelphij ASN1_BIT_STRING *publicKey; 200296341Sdelphij} EC_PRIVATEKEY; 201160814Ssimon 202160814Ssimon/* the OpenSSL ASN.1 definitions */ 203160814SsimonASN1_SEQUENCE(X9_62_PENTANOMIAL) = { 204296341Sdelphij ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG), 205296341Sdelphij ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG), 206296341Sdelphij 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) = { 215296341Sdelphij ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)), 216296341Sdelphij ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)), 217296341Sdelphij 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) = { 221296341Sdelphij ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG), 222296341Sdelphij ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT), 223296341Sdelphij 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) = { 232296341Sdelphij ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)), 233296341Sdelphij 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) = { 237296341Sdelphij ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT), 238296341Sdelphij ASN1_ADB_OBJECT(X9_62_FIELDID) 239160814Ssimon} ASN1_SEQUENCE_END(X9_62_FIELDID) 240160814Ssimon 241160814SsimonASN1_SEQUENCE(X9_62_CURVE) = { 242296341Sdelphij ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING), 243296341Sdelphij ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING), 244296341Sdelphij ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) 245160814Ssimon} ASN1_SEQUENCE_END(X9_62_CURVE) 246160814Ssimon 247160814SsimonASN1_SEQUENCE(ECPARAMETERS) = { 248296341Sdelphij ASN1_SIMPLE(ECPARAMETERS, version, LONG), 249296341Sdelphij ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID), 250296341Sdelphij ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE), 251296341Sdelphij ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING), 252296341Sdelphij ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER), 253296341Sdelphij 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) = { 260296341Sdelphij ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT), 261296341Sdelphij ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS), 262296341Sdelphij 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) = { 270296341Sdelphij ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG), 271296341Sdelphij ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), 272296341Sdelphij ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), 273296341Sdelphij 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 282296341Sdelphij/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ 283160814Ssimonstatic int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *); 284296341Sdelphij/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ 285160814Ssimonstatic int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *); 286296341Sdelphij/* 287296341Sdelphij * ec_asn1_parameters2group() creates a EC_GROUP object from a ECPARAMETERS 288296341Sdelphij * object 289296341Sdelphij */ 290296341Sdelphijstatic EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); 291296341Sdelphij/* 292296341Sdelphij * ec_asn1_group2parameters() creates a ECPARAMETERS object from a EC_GROUP 293296341Sdelphij * object 294296341Sdelphij */ 295296341Sdelphijstatic ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, 296296341Sdelphij ECPARAMETERS *); 297296341Sdelphij/* 298296341Sdelphij * ec_asn1_pkparameters2group() creates a EC_GROUP object from a 299296341Sdelphij * ECPKPARAMETERS object 300296341Sdelphij */ 301296341Sdelphijstatic EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); 302296341Sdelphij/* 303296341Sdelphij * ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a 304296341Sdelphij * EC_GROUP object 305296341Sdelphij */ 306296341Sdelphijstatic ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, 307296341Sdelphij ECPKPARAMETERS *); 308160814Ssimon 309160814Ssimon/* the function definitions */ 310160814Ssimon 311160814Ssimonstatic int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) 312296341Sdelphij{ 313296341Sdelphij int ok = 0, nid; 314296341Sdelphij BIGNUM *tmp = NULL; 315160814Ssimon 316296341Sdelphij if (group == NULL || field == NULL) 317296341Sdelphij return 0; 318160814Ssimon 319296341Sdelphij /* clear the old values (if necessary) */ 320296341Sdelphij if (field->fieldType != NULL) 321296341Sdelphij ASN1_OBJECT_free(field->fieldType); 322296341Sdelphij if (field->p.other != NULL) 323296341Sdelphij ASN1_TYPE_free(field->p.other); 324160814Ssimon 325296341Sdelphij nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); 326296341Sdelphij /* set OID for the field */ 327296341Sdelphij if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { 328296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); 329296341Sdelphij goto err; 330296341Sdelphij } 331296341Sdelphij 332296341Sdelphij if (nid == NID_X9_62_prime_field) { 333296341Sdelphij if ((tmp = BN_new()) == NULL) { 334296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 335296341Sdelphij goto err; 336296341Sdelphij } 337296341Sdelphij /* the parameters are specified by the prime number p */ 338296341Sdelphij if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) { 339296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); 340296341Sdelphij goto err; 341296341Sdelphij } 342296341Sdelphij /* set the prime number */ 343296341Sdelphij field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL); 344296341Sdelphij if (field->p.prime == NULL) { 345296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); 346296341Sdelphij goto err; 347296341Sdelphij } 348296341Sdelphij } else /* nid == NID_X9_62_characteristic_two_field */ 349238405Sjkim#ifdef OPENSSL_NO_EC2M 350296341Sdelphij { 351296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED); 352296341Sdelphij goto err; 353296341Sdelphij } 354238405Sjkim#else 355296341Sdelphij { 356296341Sdelphij int field_type; 357296341Sdelphij X9_62_CHARACTERISTIC_TWO *char_two; 358160814Ssimon 359296341Sdelphij field->p.char_two = X9_62_CHARACTERISTIC_TWO_new(); 360296341Sdelphij char_two = field->p.char_two; 361160814Ssimon 362296341Sdelphij if (char_two == NULL) { 363296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 364296341Sdelphij goto err; 365296341Sdelphij } 366160814Ssimon 367296341Sdelphij char_two->m = (long)EC_GROUP_get_degree(group); 368160814Ssimon 369296341Sdelphij field_type = EC_GROUP_get_basis_type(group); 370160814Ssimon 371296341Sdelphij if (field_type == 0) { 372296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); 373296341Sdelphij goto err; 374296341Sdelphij } 375296341Sdelphij /* set base type OID */ 376296341Sdelphij if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) { 377296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); 378296341Sdelphij goto err; 379296341Sdelphij } 380160814Ssimon 381296341Sdelphij if (field_type == NID_X9_62_tpBasis) { 382296341Sdelphij unsigned int k; 383160814Ssimon 384296341Sdelphij if (!EC_GROUP_get_trinomial_basis(group, &k)) 385296341Sdelphij goto err; 386160814Ssimon 387296341Sdelphij char_two->p.tpBasis = ASN1_INTEGER_new(); 388296341Sdelphij if (!char_two->p.tpBasis) { 389296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 390296341Sdelphij goto err; 391296341Sdelphij } 392296341Sdelphij if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) { 393296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); 394296341Sdelphij goto err; 395296341Sdelphij } 396296341Sdelphij } else if (field_type == NID_X9_62_ppBasis) { 397296341Sdelphij unsigned int k1, k2, k3; 398160814Ssimon 399296341Sdelphij if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)) 400296341Sdelphij goto err; 401160814Ssimon 402296341Sdelphij char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); 403296341Sdelphij if (!char_two->p.ppBasis) { 404296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 405296341Sdelphij goto err; 406296341Sdelphij } 407296341Sdelphij 408296341Sdelphij /* set k? values */ 409296341Sdelphij char_two->p.ppBasis->k1 = (long)k1; 410296341Sdelphij char_two->p.ppBasis->k2 = (long)k2; 411296341Sdelphij char_two->p.ppBasis->k3 = (long)k3; 412296341Sdelphij } else { /* field_type == NID_X9_62_onBasis */ 413296341Sdelphij 414296341Sdelphij /* for ONB the parameters are (asn1) NULL */ 415296341Sdelphij char_two->p.onBasis = ASN1_NULL_new(); 416296341Sdelphij if (!char_two->p.onBasis) { 417296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); 418296341Sdelphij goto err; 419296341Sdelphij } 420296341Sdelphij } 421296341Sdelphij } 422238405Sjkim#endif 423160814Ssimon 424296341Sdelphij ok = 1; 425160814Ssimon 426296341Sdelphij err:if (tmp) 427296341Sdelphij BN_free(tmp); 428296341Sdelphij return (ok); 429160814Ssimon} 430160814Ssimon 431160814Ssimonstatic int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) 432296341Sdelphij{ 433296341Sdelphij int ok = 0, nid; 434296341Sdelphij BIGNUM *tmp_1 = NULL, *tmp_2 = NULL; 435296341Sdelphij unsigned char *buffer_1 = NULL, *buffer_2 = NULL, 436296341Sdelphij *a_buf = NULL, *b_buf = NULL; 437296341Sdelphij size_t len_1, len_2; 438296341Sdelphij unsigned char char_zero = 0; 439160814Ssimon 440296341Sdelphij if (!group || !curve || !curve->a || !curve->b) 441296341Sdelphij return 0; 442160814Ssimon 443296341Sdelphij if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { 444296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); 445296341Sdelphij goto err; 446296341Sdelphij } 447160814Ssimon 448296341Sdelphij nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); 449160814Ssimon 450296341Sdelphij /* get a and b */ 451296341Sdelphij if (nid == NID_X9_62_prime_field) { 452296341Sdelphij if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) { 453296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); 454296341Sdelphij goto err; 455296341Sdelphij } 456296341Sdelphij } 457238405Sjkim#ifndef OPENSSL_NO_EC2M 458296341Sdelphij else { /* nid == NID_X9_62_characteristic_two_field */ 459296341Sdelphij 460296341Sdelphij if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) { 461296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); 462296341Sdelphij goto err; 463296341Sdelphij } 464296341Sdelphij } 465238405Sjkim#endif 466296341Sdelphij len_1 = (size_t)BN_num_bytes(tmp_1); 467296341Sdelphij len_2 = (size_t)BN_num_bytes(tmp_2); 468160814Ssimon 469296341Sdelphij if (len_1 == 0) { 470296341Sdelphij /* len_1 == 0 => a == 0 */ 471296341Sdelphij a_buf = &char_zero; 472296341Sdelphij len_1 = 1; 473296341Sdelphij } else { 474296341Sdelphij if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) { 475296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); 476296341Sdelphij goto err; 477296341Sdelphij } 478296341Sdelphij if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) { 479296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); 480296341Sdelphij goto err; 481296341Sdelphij } 482296341Sdelphij a_buf = buffer_1; 483296341Sdelphij } 484160814Ssimon 485296341Sdelphij if (len_2 == 0) { 486296341Sdelphij /* len_2 == 0 => b == 0 */ 487296341Sdelphij b_buf = &char_zero; 488296341Sdelphij len_2 = 1; 489296341Sdelphij } else { 490296341Sdelphij if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) { 491296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); 492296341Sdelphij goto err; 493296341Sdelphij } 494296341Sdelphij if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) { 495296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); 496296341Sdelphij goto err; 497296341Sdelphij } 498296341Sdelphij b_buf = buffer_2; 499296341Sdelphij } 500160814Ssimon 501296341Sdelphij /* set a and b */ 502296341Sdelphij if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) || 503296341Sdelphij !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) { 504296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); 505296341Sdelphij goto err; 506296341Sdelphij } 507160814Ssimon 508296341Sdelphij /* set the seed (optional) */ 509296341Sdelphij if (group->seed) { 510296341Sdelphij if (!curve->seed) 511296341Sdelphij if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { 512296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); 513296341Sdelphij goto err; 514296341Sdelphij } 515296341Sdelphij curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 516296341Sdelphij curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; 517296341Sdelphij if (!ASN1_BIT_STRING_set(curve->seed, group->seed, 518296341Sdelphij (int)group->seed_len)) { 519296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); 520296341Sdelphij goto err; 521296341Sdelphij } 522296341Sdelphij } else { 523296341Sdelphij if (curve->seed) { 524296341Sdelphij ASN1_BIT_STRING_free(curve->seed); 525296341Sdelphij curve->seed = NULL; 526296341Sdelphij } 527296341Sdelphij } 528160814Ssimon 529296341Sdelphij ok = 1; 530296341Sdelphij 531296341Sdelphij err:if (buffer_1) 532296341Sdelphij OPENSSL_free(buffer_1); 533296341Sdelphij if (buffer_2) 534296341Sdelphij OPENSSL_free(buffer_2); 535296341Sdelphij if (tmp_1) 536296341Sdelphij BN_free(tmp_1); 537296341Sdelphij if (tmp_2) 538296341Sdelphij BN_free(tmp_2); 539296341Sdelphij return (ok); 540296341Sdelphij} 541296341Sdelphij 542160814Ssimonstatic ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, 543160814Ssimon ECPARAMETERS *param) 544296341Sdelphij{ 545296341Sdelphij int ok = 0; 546296341Sdelphij size_t len = 0; 547296341Sdelphij ECPARAMETERS *ret = NULL; 548296341Sdelphij BIGNUM *tmp = NULL; 549296341Sdelphij unsigned char *buffer = NULL; 550296341Sdelphij const EC_POINT *point = NULL; 551296341Sdelphij point_conversion_form_t form; 552160814Ssimon 553296341Sdelphij if ((tmp = BN_new()) == NULL) { 554296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 555296341Sdelphij goto err; 556296341Sdelphij } 557160814Ssimon 558296341Sdelphij if (param == NULL) { 559296341Sdelphij if ((ret = ECPARAMETERS_new()) == NULL) { 560296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 561296341Sdelphij goto err; 562296341Sdelphij } 563296341Sdelphij } else 564296341Sdelphij ret = param; 565160814Ssimon 566296341Sdelphij /* set the version (always one) */ 567296341Sdelphij ret->version = (long)0x1; 568160814Ssimon 569296341Sdelphij /* set the fieldID */ 570296341Sdelphij if (!ec_asn1_group2fieldid(group, ret->fieldID)) { 571296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 572296341Sdelphij goto err; 573296341Sdelphij } 574160814Ssimon 575296341Sdelphij /* set the curve */ 576296341Sdelphij if (!ec_asn1_group2curve(group, ret->curve)) { 577296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 578296341Sdelphij goto err; 579296341Sdelphij } 580160814Ssimon 581296341Sdelphij /* set the base point */ 582296341Sdelphij if ((point = EC_GROUP_get0_generator(group)) == NULL) { 583296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR); 584296341Sdelphij goto err; 585296341Sdelphij } 586160814Ssimon 587296341Sdelphij form = EC_GROUP_get_point_conversion_form(group); 588160814Ssimon 589296341Sdelphij len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); 590296341Sdelphij if (len == 0) { 591296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 592296341Sdelphij goto err; 593296341Sdelphij } 594296341Sdelphij if ((buffer = OPENSSL_malloc(len)) == NULL) { 595296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 596296341Sdelphij goto err; 597296341Sdelphij } 598296341Sdelphij if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) { 599296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 600296341Sdelphij goto err; 601296341Sdelphij } 602296341Sdelphij if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { 603296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); 604296341Sdelphij goto err; 605296341Sdelphij } 606296341Sdelphij if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) { 607296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); 608296341Sdelphij goto err; 609296341Sdelphij } 610160814Ssimon 611296341Sdelphij /* set the order */ 612296341Sdelphij if (!EC_GROUP_get_order(group, tmp, NULL)) { 613296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); 614296341Sdelphij goto err; 615296341Sdelphij } 616296341Sdelphij ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); 617296341Sdelphij if (ret->order == NULL) { 618296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); 619296341Sdelphij goto err; 620296341Sdelphij } 621160814Ssimon 622296341Sdelphij /* set the cofactor (optional) */ 623296341Sdelphij if (EC_GROUP_get_cofactor(group, tmp, NULL)) { 624296341Sdelphij ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); 625296341Sdelphij if (ret->cofactor == NULL) { 626296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); 627296341Sdelphij goto err; 628296341Sdelphij } 629296341Sdelphij } 630160814Ssimon 631296341Sdelphij ok = 1; 632160814Ssimon 633296341Sdelphij err:if (!ok) { 634296341Sdelphij if (ret && !param) 635296341Sdelphij ECPARAMETERS_free(ret); 636296341Sdelphij ret = NULL; 637296341Sdelphij } 638296341Sdelphij if (tmp) 639296341Sdelphij BN_free(tmp); 640296341Sdelphij if (buffer) 641296341Sdelphij OPENSSL_free(buffer); 642296341Sdelphij return (ret); 643296341Sdelphij} 644160814Ssimon 645296341SdelphijECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, 646160814Ssimon ECPKPARAMETERS *params) 647296341Sdelphij{ 648296341Sdelphij int ok = 1, tmp; 649296341Sdelphij ECPKPARAMETERS *ret = params; 650160814Ssimon 651296341Sdelphij if (ret == NULL) { 652296341Sdelphij if ((ret = ECPKPARAMETERS_new()) == NULL) { 653296341Sdelphij ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, ERR_R_MALLOC_FAILURE); 654296341Sdelphij return NULL; 655296341Sdelphij } 656296341Sdelphij } else { 657296341Sdelphij if (ret->type == 0 && ret->value.named_curve) 658296341Sdelphij ASN1_OBJECT_free(ret->value.named_curve); 659296341Sdelphij else if (ret->type == 1 && ret->value.parameters) 660296341Sdelphij ECPARAMETERS_free(ret->value.parameters); 661296341Sdelphij } 662160814Ssimon 663296341Sdelphij if (EC_GROUP_get_asn1_flag(group)) { 664296341Sdelphij /* 665296341Sdelphij * use the asn1 OID to describe the the elliptic curve parameters 666296341Sdelphij */ 667296341Sdelphij tmp = EC_GROUP_get_curve_name(group); 668296341Sdelphij if (tmp) { 669296341Sdelphij ret->type = 0; 670296341Sdelphij if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL) 671296341Sdelphij ok = 0; 672296341Sdelphij } else 673296341Sdelphij /* we don't kmow the nid => ERROR */ 674296341Sdelphij ok = 0; 675296341Sdelphij } else { 676296341Sdelphij /* use the ECPARAMETERS structure */ 677296341Sdelphij ret->type = 1; 678296341Sdelphij if ((ret->value.parameters = 679296341Sdelphij ec_asn1_group2parameters(group, NULL)) == NULL) 680296341Sdelphij ok = 0; 681296341Sdelphij } 682160814Ssimon 683296341Sdelphij if (!ok) { 684296341Sdelphij ECPKPARAMETERS_free(ret); 685296341Sdelphij return NULL; 686296341Sdelphij } 687296341Sdelphij return ret; 688296341Sdelphij} 689160814Ssimon 690160814Ssimonstatic EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params) 691296341Sdelphij{ 692296341Sdelphij int ok = 0, tmp; 693296341Sdelphij EC_GROUP *ret = NULL; 694296341Sdelphij BIGNUM *p = NULL, *a = NULL, *b = NULL; 695296341Sdelphij EC_POINT *point = NULL; 696296341Sdelphij long field_bits; 697160814Ssimon 698296341Sdelphij if (!params->fieldID || !params->fieldID->fieldType || 699296341Sdelphij !params->fieldID->p.ptr) { 700296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 701296341Sdelphij goto err; 702296341Sdelphij } 703160814Ssimon 704296341Sdelphij /* now extract the curve parameters a and b */ 705296341Sdelphij if (!params->curve || !params->curve->a || 706296341Sdelphij !params->curve->a->data || !params->curve->b || 707296341Sdelphij !params->curve->b->data) { 708296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 709296341Sdelphij goto err; 710296341Sdelphij } 711296341Sdelphij a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); 712296341Sdelphij if (a == NULL) { 713296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); 714296341Sdelphij goto err; 715296341Sdelphij } 716296341Sdelphij b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); 717296341Sdelphij if (b == NULL) { 718296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); 719296341Sdelphij goto err; 720296341Sdelphij } 721160814Ssimon 722296341Sdelphij /* get the field parameters */ 723296341Sdelphij tmp = OBJ_obj2nid(params->fieldID->fieldType); 724296341Sdelphij if (tmp == NID_X9_62_characteristic_two_field) 725238405Sjkim#ifdef OPENSSL_NO_EC2M 726296341Sdelphij { 727296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED); 728296341Sdelphij goto err; 729296341Sdelphij } 730238405Sjkim#else 731296341Sdelphij { 732296341Sdelphij X9_62_CHARACTERISTIC_TWO *char_two; 733160814Ssimon 734296341Sdelphij char_two = params->fieldID->p.char_two; 735160814Ssimon 736296341Sdelphij field_bits = char_two->m; 737296341Sdelphij if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { 738296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); 739296341Sdelphij goto err; 740296341Sdelphij } 741162911Ssimon 742296341Sdelphij if ((p = BN_new()) == NULL) { 743296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); 744296341Sdelphij goto err; 745296341Sdelphij } 746160814Ssimon 747296341Sdelphij /* get the base type */ 748296341Sdelphij tmp = OBJ_obj2nid(char_two->type); 749160814Ssimon 750296341Sdelphij if (tmp == NID_X9_62_tpBasis) { 751296341Sdelphij long tmp_long; 752160814Ssimon 753296341Sdelphij if (!char_two->p.tpBasis) { 754296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 755296341Sdelphij goto err; 756296341Sdelphij } 757160814Ssimon 758296341Sdelphij tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis); 759162911Ssimon 760296341Sdelphij if (!(char_two->m > tmp_long && tmp_long > 0)) { 761296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 762296341Sdelphij EC_R_INVALID_TRINOMIAL_BASIS); 763296341Sdelphij goto err; 764296341Sdelphij } 765160814Ssimon 766296341Sdelphij /* create the polynomial */ 767296341Sdelphij if (!BN_set_bit(p, (int)char_two->m)) 768296341Sdelphij goto err; 769296341Sdelphij if (!BN_set_bit(p, (int)tmp_long)) 770296341Sdelphij goto err; 771296341Sdelphij if (!BN_set_bit(p, 0)) 772296341Sdelphij goto err; 773296341Sdelphij } else if (tmp == NID_X9_62_ppBasis) { 774296341Sdelphij X9_62_PENTANOMIAL *penta; 775162911Ssimon 776296341Sdelphij penta = char_two->p.ppBasis; 777296341Sdelphij if (!penta) { 778296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 779296341Sdelphij goto err; 780296341Sdelphij } 781160814Ssimon 782296341Sdelphij if (! 783296341Sdelphij (char_two->m > penta->k3 && penta->k3 > penta->k2 784296341Sdelphij && penta->k2 > penta->k1 && penta->k1 > 0)) { 785296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, 786296341Sdelphij EC_R_INVALID_PENTANOMIAL_BASIS); 787296341Sdelphij goto err; 788296341Sdelphij } 789296341Sdelphij 790296341Sdelphij /* create the polynomial */ 791296341Sdelphij if (!BN_set_bit(p, (int)char_two->m)) 792296341Sdelphij goto err; 793296341Sdelphij if (!BN_set_bit(p, (int)penta->k1)) 794296341Sdelphij goto err; 795296341Sdelphij if (!BN_set_bit(p, (int)penta->k2)) 796296341Sdelphij goto err; 797296341Sdelphij if (!BN_set_bit(p, (int)penta->k3)) 798296341Sdelphij goto err; 799296341Sdelphij if (!BN_set_bit(p, 0)) 800296341Sdelphij goto err; 801296341Sdelphij } else if (tmp == NID_X9_62_onBasis) { 802296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED); 803296341Sdelphij goto err; 804296341Sdelphij } else { /* error */ 805296341Sdelphij 806296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 807296341Sdelphij goto err; 808296341Sdelphij } 809296341Sdelphij 810296341Sdelphij /* create the EC_GROUP structure */ 811296341Sdelphij ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL); 812296341Sdelphij } 813238405Sjkim#endif 814296341Sdelphij else if (tmp == NID_X9_62_prime_field) { 815296341Sdelphij /* we have a curve over a prime field */ 816296341Sdelphij /* extract the prime number */ 817296341Sdelphij if (!params->fieldID->p.prime) { 818296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 819296341Sdelphij goto err; 820296341Sdelphij } 821296341Sdelphij p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); 822296341Sdelphij if (p == NULL) { 823296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); 824296341Sdelphij goto err; 825296341Sdelphij } 826162911Ssimon 827296341Sdelphij if (BN_is_negative(p) || BN_is_zero(p)) { 828296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); 829296341Sdelphij goto err; 830296341Sdelphij } 831162911Ssimon 832296341Sdelphij field_bits = BN_num_bits(p); 833296341Sdelphij if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { 834296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); 835296341Sdelphij goto err; 836296341Sdelphij } 837162911Ssimon 838296341Sdelphij /* create the EC_GROUP structure */ 839296341Sdelphij ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); 840296341Sdelphij } else { 841296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); 842296341Sdelphij goto err; 843296341Sdelphij } 844160814Ssimon 845296341Sdelphij if (ret == NULL) { 846296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); 847296341Sdelphij goto err; 848296341Sdelphij } 849160814Ssimon 850296341Sdelphij /* extract seed (optional) */ 851296341Sdelphij if (params->curve->seed != NULL) { 852296341Sdelphij if (ret->seed != NULL) 853296341Sdelphij OPENSSL_free(ret->seed); 854296341Sdelphij if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) { 855296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); 856296341Sdelphij goto err; 857296341Sdelphij } 858296341Sdelphij memcpy(ret->seed, params->curve->seed->data, 859296341Sdelphij params->curve->seed->length); 860296341Sdelphij ret->seed_len = params->curve->seed->length; 861296341Sdelphij } 862160814Ssimon 863296341Sdelphij if (!params->order || !params->base || !params->base->data) { 864296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); 865296341Sdelphij goto err; 866296341Sdelphij } 867160814Ssimon 868296341Sdelphij if ((point = EC_POINT_new(ret)) == NULL) 869296341Sdelphij goto err; 870160814Ssimon 871296341Sdelphij /* set the point conversion form */ 872296341Sdelphij EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) 873296341Sdelphij (params->base->data[0] & ~0x01)); 874160814Ssimon 875296341Sdelphij /* extract the ec point */ 876296341Sdelphij if (!EC_POINT_oct2point(ret, point, params->base->data, 877296341Sdelphij params->base->length, NULL)) { 878296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); 879296341Sdelphij goto err; 880296341Sdelphij } 881160814Ssimon 882296341Sdelphij /* extract the order */ 883296341Sdelphij if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) { 884296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); 885296341Sdelphij goto err; 886296341Sdelphij } 887296341Sdelphij if (BN_is_negative(a) || BN_is_zero(a)) { 888296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); 889296341Sdelphij goto err; 890296341Sdelphij } 891296341Sdelphij if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */ 892296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); 893296341Sdelphij goto err; 894296341Sdelphij } 895160814Ssimon 896296341Sdelphij /* extract the cofactor (optional) */ 897296341Sdelphij if (params->cofactor == NULL) { 898296341Sdelphij if (b) { 899296341Sdelphij BN_free(b); 900296341Sdelphij b = NULL; 901296341Sdelphij } 902296341Sdelphij } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) { 903296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); 904296341Sdelphij goto err; 905296341Sdelphij } 906296341Sdelphij /* set the generator, order and cofactor (if present) */ 907296341Sdelphij if (!EC_GROUP_set_generator(ret, point, a, b)) { 908296341Sdelphij ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); 909296341Sdelphij goto err; 910296341Sdelphij } 911160814Ssimon 912296341Sdelphij ok = 1; 913160814Ssimon 914296341Sdelphij err:if (!ok) { 915296341Sdelphij if (ret) 916296341Sdelphij EC_GROUP_clear_free(ret); 917296341Sdelphij ret = NULL; 918296341Sdelphij } 919296341Sdelphij 920296341Sdelphij if (p) 921296341Sdelphij BN_free(p); 922296341Sdelphij if (a) 923296341Sdelphij BN_free(a); 924296341Sdelphij if (b) 925296341Sdelphij BN_free(b); 926296341Sdelphij if (point) 927296341Sdelphij EC_POINT_free(point); 928296341Sdelphij return (ret); 929160814Ssimon} 930160814Ssimon 931160814SsimonEC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) 932296341Sdelphij{ 933296341Sdelphij EC_GROUP *ret = NULL; 934296341Sdelphij int tmp = 0; 935160814Ssimon 936296341Sdelphij if (params == NULL) { 937296341Sdelphij ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_MISSING_PARAMETERS); 938296341Sdelphij return NULL; 939296341Sdelphij } 940160814Ssimon 941296341Sdelphij if (params->type == 0) { /* the curve is given by an OID */ 942296341Sdelphij tmp = OBJ_obj2nid(params->value.named_curve); 943296341Sdelphij if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { 944296341Sdelphij ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, 945296341Sdelphij EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 946296341Sdelphij return NULL; 947296341Sdelphij } 948296341Sdelphij EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); 949296341Sdelphij } else if (params->type == 1) { /* the parameters are given by a 950296341Sdelphij * ECPARAMETERS structure */ 951296341Sdelphij ret = ec_asn1_parameters2group(params->value.parameters); 952296341Sdelphij if (!ret) { 953296341Sdelphij ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB); 954296341Sdelphij return NULL; 955296341Sdelphij } 956296341Sdelphij EC_GROUP_set_asn1_flag(ret, 0x0); 957296341Sdelphij } else if (params->type == 2) { /* implicitlyCA */ 958296341Sdelphij return NULL; 959296341Sdelphij } else { 960296341Sdelphij ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR); 961296341Sdelphij return NULL; 962296341Sdelphij } 963160814Ssimon 964296341Sdelphij return ret; 965296341Sdelphij} 966160814Ssimon 967160814Ssimon/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */ 968160814Ssimon 969160814SsimonEC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) 970296341Sdelphij{ 971296341Sdelphij EC_GROUP *group = NULL; 972296341Sdelphij ECPKPARAMETERS *params = NULL; 973160814Ssimon 974296341Sdelphij if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) { 975296341Sdelphij ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE); 976296341Sdelphij ECPKPARAMETERS_free(params); 977296341Sdelphij return NULL; 978296341Sdelphij } 979160814Ssimon 980296341Sdelphij if ((group = ec_asn1_pkparameters2group(params)) == NULL) { 981296341Sdelphij ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE); 982296341Sdelphij ECPKPARAMETERS_free(params); 983296341Sdelphij return NULL; 984296341Sdelphij } 985160814Ssimon 986296341Sdelphij if (a && *a) 987296341Sdelphij EC_GROUP_clear_free(*a); 988296341Sdelphij if (a) 989296341Sdelphij *a = group; 990160814Ssimon 991296341Sdelphij ECPKPARAMETERS_free(params); 992296341Sdelphij return (group); 993296341Sdelphij} 994296341Sdelphij 995160814Ssimonint i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) 996296341Sdelphij{ 997296341Sdelphij int ret = 0; 998296341Sdelphij ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL); 999296341Sdelphij if (tmp == NULL) { 1000296341Sdelphij ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE); 1001296341Sdelphij return 0; 1002296341Sdelphij } 1003296341Sdelphij if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) { 1004296341Sdelphij ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE); 1005296341Sdelphij ECPKPARAMETERS_free(tmp); 1006296341Sdelphij return 0; 1007296341Sdelphij } 1008296341Sdelphij ECPKPARAMETERS_free(tmp); 1009296341Sdelphij return (ret); 1010296341Sdelphij} 1011160814Ssimon 1012160814Ssimon/* some EC_KEY functions */ 1013160814Ssimon 1014160814SsimonEC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) 1015296341Sdelphij{ 1016296341Sdelphij int ok = 0; 1017296341Sdelphij EC_KEY *ret = NULL; 1018296341Sdelphij EC_PRIVATEKEY *priv_key = NULL; 1019160814Ssimon 1020296341Sdelphij if ((priv_key = d2i_EC_PRIVATEKEY(NULL, in, len)) == NULL) { 1021296341Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1022296341Sdelphij return NULL; 1023296341Sdelphij } 1024160814Ssimon 1025296341Sdelphij if (a == NULL || *a == NULL) { 1026296341Sdelphij if ((ret = EC_KEY_new()) == NULL) { 1027296341Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1028296341Sdelphij goto err; 1029296341Sdelphij } 1030296341Sdelphij } else 1031296341Sdelphij ret = *a; 1032160814Ssimon 1033296341Sdelphij if (priv_key->parameters) { 1034296341Sdelphij if (ret->group) 1035296341Sdelphij EC_GROUP_clear_free(ret->group); 1036296341Sdelphij ret->group = ec_asn1_pkparameters2group(priv_key->parameters); 1037296341Sdelphij } 1038160814Ssimon 1039296341Sdelphij if (ret->group == NULL) { 1040296341Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1041296341Sdelphij goto err; 1042296341Sdelphij } 1043160814Ssimon 1044296341Sdelphij ret->version = priv_key->version; 1045160814Ssimon 1046296341Sdelphij if (priv_key->privateKey) { 1047296341Sdelphij ret->priv_key = BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey), 1048296341Sdelphij M_ASN1_STRING_length(priv_key->privateKey), 1049296341Sdelphij ret->priv_key); 1050296341Sdelphij if (ret->priv_key == NULL) { 1051296341Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB); 1052296341Sdelphij goto err; 1053296341Sdelphij } 1054296341Sdelphij } else { 1055296341Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY); 1056296341Sdelphij goto err; 1057296341Sdelphij } 1058160814Ssimon 1059296341Sdelphij if (ret->pub_key) 1060296341Sdelphij EC_POINT_clear_free(ret->pub_key); 1061296341Sdelphij ret->pub_key = EC_POINT_new(ret->group); 1062296341Sdelphij if (ret->pub_key == NULL) { 1063296341Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1064296341Sdelphij goto err; 1065296341Sdelphij } 1066160814Ssimon 1067296341Sdelphij if (priv_key->publicKey) { 1068296341Sdelphij const unsigned char *pub_oct; 1069296341Sdelphij int pub_oct_len; 1070273399Sdelphij 1071296341Sdelphij pub_oct = M_ASN1_STRING_data(priv_key->publicKey); 1072296341Sdelphij pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey); 1073296341Sdelphij /* 1074296341Sdelphij * The first byte - point conversion form - must be present. 1075296341Sdelphij */ 1076296341Sdelphij if (pub_oct_len <= 0) { 1077296341Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); 1078296341Sdelphij goto err; 1079296341Sdelphij } 1080296341Sdelphij /* Save the point conversion form. */ 1081296341Sdelphij ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01); 1082296341Sdelphij if (!EC_POINT_oct2point(ret->group, ret->pub_key, 1083296341Sdelphij pub_oct, (size_t)(pub_oct_len), NULL)) { 1084296341Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1085296341Sdelphij goto err; 1086296341Sdelphij } 1087296341Sdelphij } else { 1088296341Sdelphij if (!EC_POINT_mul 1089296341Sdelphij (ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) { 1090296341Sdelphij ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); 1091296341Sdelphij goto err; 1092296341Sdelphij } 1093296341Sdelphij /* Remember the original private-key-only encoding. */ 1094296341Sdelphij ret->enc_flag |= EC_PKEY_NO_PUBKEY; 1095296341Sdelphij } 1096160814Ssimon 1097296341Sdelphij if (a) 1098296341Sdelphij *a = ret; 1099296341Sdelphij ok = 1; 1100296341Sdelphij err: 1101296341Sdelphij if (!ok) { 1102296341Sdelphij if (ret && (a == NULL || *a != ret)) 1103296341Sdelphij EC_KEY_free(ret); 1104296341Sdelphij ret = NULL; 1105296341Sdelphij } 1106160814Ssimon 1107296341Sdelphij if (priv_key) 1108296341Sdelphij EC_PRIVATEKEY_free(priv_key); 1109160814Ssimon 1110296341Sdelphij return (ret); 1111296341Sdelphij} 1112160814Ssimon 1113296341Sdelphijint i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) 1114296341Sdelphij{ 1115296341Sdelphij int ret = 0, ok = 0; 1116296341Sdelphij unsigned char *buffer = NULL; 1117296341Sdelphij size_t buf_len = 0, tmp_len, bn_len; 1118296341Sdelphij EC_PRIVATEKEY *priv_key = NULL; 1119160814Ssimon 1120296341Sdelphij if (a == NULL || a->group == NULL || a->priv_key == NULL || 1121296341Sdelphij (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { 1122296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); 1123296341Sdelphij goto err; 1124296341Sdelphij } 1125160814Ssimon 1126296341Sdelphij if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { 1127296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1128296341Sdelphij goto err; 1129296341Sdelphij } 1130160814Ssimon 1131296341Sdelphij priv_key->version = a->version; 1132160814Ssimon 1133296341Sdelphij bn_len = (size_t)BN_num_bytes(a->priv_key); 1134160814Ssimon 1135296341Sdelphij /* Octetstring may need leading zeros if BN is to short */ 1136160814Ssimon 1137296341Sdelphij buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8; 1138160814Ssimon 1139296341Sdelphij if (bn_len > buf_len) { 1140296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); 1141296341Sdelphij goto err; 1142296341Sdelphij } 1143160814Ssimon 1144296341Sdelphij buffer = OPENSSL_malloc(buf_len); 1145296341Sdelphij if (buffer == NULL) { 1146296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1147296341Sdelphij goto err; 1148296341Sdelphij } 1149160814Ssimon 1150296341Sdelphij if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) { 1151296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); 1152296341Sdelphij goto err; 1153296341Sdelphij } 1154160814Ssimon 1155296341Sdelphij if (buf_len - bn_len > 0) { 1156296341Sdelphij memset(buffer, 0, buf_len - bn_len); 1157296341Sdelphij } 1158160814Ssimon 1159296341Sdelphij if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) { 1160296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); 1161296341Sdelphij goto err; 1162296341Sdelphij } 1163160814Ssimon 1164296341Sdelphij if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) { 1165296341Sdelphij if ((priv_key->parameters = 1166296341Sdelphij ec_asn1_group2pkparameters(a->group, 1167296341Sdelphij priv_key->parameters)) == NULL) { 1168296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); 1169296341Sdelphij goto err; 1170296341Sdelphij } 1171296341Sdelphij } 1172160814Ssimon 1173296341Sdelphij if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) { 1174296341Sdelphij priv_key->publicKey = M_ASN1_BIT_STRING_new(); 1175296341Sdelphij if (priv_key->publicKey == NULL) { 1176296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1177296341Sdelphij goto err; 1178296341Sdelphij } 1179160814Ssimon 1180296341Sdelphij tmp_len = EC_POINT_point2oct(a->group, a->pub_key, 1181296341Sdelphij a->conv_form, NULL, 0, NULL); 1182296341Sdelphij 1183296341Sdelphij if (tmp_len > buf_len) { 1184296341Sdelphij unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len); 1185296341Sdelphij if (!tmp_buffer) { 1186296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); 1187296341Sdelphij goto err; 1188296341Sdelphij } 1189296341Sdelphij buffer = tmp_buffer; 1190296341Sdelphij buf_len = tmp_len; 1191296341Sdelphij } 1192296341Sdelphij 1193296341Sdelphij if (!EC_POINT_point2oct(a->group, a->pub_key, 1194296341Sdelphij a->conv_form, buffer, buf_len, NULL)) { 1195296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); 1196296341Sdelphij goto err; 1197296341Sdelphij } 1198296341Sdelphij 1199296341Sdelphij priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 1200296341Sdelphij priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; 1201296341Sdelphij if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) { 1202296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); 1203296341Sdelphij goto err; 1204296341Sdelphij } 1205296341Sdelphij } 1206296341Sdelphij 1207296341Sdelphij if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) { 1208296341Sdelphij ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); 1209296341Sdelphij goto err; 1210296341Sdelphij } 1211296341Sdelphij ok = 1; 1212296341Sdelphij err: 1213296341Sdelphij if (buffer) 1214296341Sdelphij OPENSSL_free(buffer); 1215296341Sdelphij if (priv_key) 1216296341Sdelphij EC_PRIVATEKEY_free(priv_key); 1217296341Sdelphij return (ok ? ret : 0); 1218296341Sdelphij} 1219296341Sdelphij 1220160814Ssimonint i2d_ECParameters(EC_KEY *a, unsigned char **out) 1221296341Sdelphij{ 1222296341Sdelphij if (a == NULL) { 1223296341Sdelphij ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); 1224296341Sdelphij return 0; 1225296341Sdelphij } 1226296341Sdelphij return i2d_ECPKParameters(a->group, out); 1227296341Sdelphij} 1228160814Ssimon 1229160814SsimonEC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) 1230296341Sdelphij{ 1231296341Sdelphij EC_KEY *ret; 1232160814Ssimon 1233296341Sdelphij if (in == NULL || *in == NULL) { 1234296341Sdelphij ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); 1235296341Sdelphij return NULL; 1236296341Sdelphij } 1237160814Ssimon 1238296341Sdelphij if (a == NULL || *a == NULL) { 1239296341Sdelphij if ((ret = EC_KEY_new()) == NULL) { 1240296341Sdelphij ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE); 1241296341Sdelphij return NULL; 1242296341Sdelphij } 1243296341Sdelphij } else 1244296341Sdelphij ret = *a; 1245160814Ssimon 1246296341Sdelphij if (!d2i_ECPKParameters(&ret->group, in, len)) { 1247296341Sdelphij ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); 1248296341Sdelphij if (a == NULL || *a != ret) 1249296341Sdelphij EC_KEY_free(ret); 1250296341Sdelphij return NULL; 1251296341Sdelphij } 1252160814Ssimon 1253296341Sdelphij if (a) 1254296341Sdelphij *a = ret; 1255160814Ssimon 1256296341Sdelphij return ret; 1257296341Sdelphij} 1258296341Sdelphij 1259160814SsimonEC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) 1260296341Sdelphij{ 1261296341Sdelphij EC_KEY *ret = NULL; 1262160814Ssimon 1263296341Sdelphij if (a == NULL || (*a) == NULL || (*a)->group == NULL) { 1264296341Sdelphij /* 1265296341Sdelphij * sorry, but a EC_GROUP-structur is necessary to set the public key 1266296341Sdelphij */ 1267296341Sdelphij ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); 1268296341Sdelphij return 0; 1269296341Sdelphij } 1270296341Sdelphij ret = *a; 1271296341Sdelphij if (ret->pub_key == NULL && 1272296341Sdelphij (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { 1273296341Sdelphij ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); 1274296341Sdelphij return 0; 1275296341Sdelphij } 1276296341Sdelphij if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) { 1277296341Sdelphij ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB); 1278296341Sdelphij return 0; 1279296341Sdelphij } 1280296341Sdelphij /* save the point conversion form */ 1281296341Sdelphij ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01); 1282296341Sdelphij *in += len; 1283296341Sdelphij return ret; 1284296341Sdelphij} 1285160814Ssimon 1286160814Ssimonint i2o_ECPublicKey(EC_KEY *a, unsigned char **out) 1287296341Sdelphij{ 1288296341Sdelphij size_t buf_len = 0; 1289296341Sdelphij int new_buffer = 0; 1290160814Ssimon 1291296341Sdelphij if (a == NULL) { 1292296341Sdelphij ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); 1293296341Sdelphij return 0; 1294296341Sdelphij } 1295160814Ssimon 1296296341Sdelphij buf_len = EC_POINT_point2oct(a->group, a->pub_key, 1297296341Sdelphij a->conv_form, NULL, 0, NULL); 1298160814Ssimon 1299296341Sdelphij if (out == NULL || buf_len == 0) 1300296341Sdelphij /* out == NULL => just return the length of the octet string */ 1301296341Sdelphij return buf_len; 1302160814Ssimon 1303296341Sdelphij if (*out == NULL) { 1304296341Sdelphij if ((*out = OPENSSL_malloc(buf_len)) == NULL) { 1305296341Sdelphij ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); 1306296341Sdelphij return 0; 1307296341Sdelphij } 1308296341Sdelphij new_buffer = 1; 1309296341Sdelphij } 1310296341Sdelphij if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, 1311296341Sdelphij *out, buf_len, NULL)) { 1312296341Sdelphij ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB); 1313296341Sdelphij if (new_buffer) { 1314296341Sdelphij OPENSSL_free(*out); 1315296341Sdelphij *out = NULL; 1316296341Sdelphij } 1317296341Sdelphij return 0; 1318296341Sdelphij } 1319296341Sdelphij if (!new_buffer) 1320296341Sdelphij *out += buf_len; 1321296341Sdelphij return buf_len; 1322296341Sdelphij} 1323