1 /* Written by Nils Larsch for the OpenSSL project. */ 2 /* ==================================================================== 3 * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * licensing (at) OpenSSL.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This product includes cryptographic software written by Eric Young 51 * (eay (at) cryptsoft.com). This product includes software written by Tim 52 * Hudson (tjh (at) cryptsoft.com). */ 53 54 #include <openssl/ec.h> 55 56 #include <openssl/asn1.h> 57 #include <openssl/asn1t.h> 58 #include <openssl/bn.h> 59 #include <openssl/err.h> 60 #include <openssl/mem.h> 61 #include <openssl/obj.h> 62 63 #include "internal.h" 64 65 66 typedef struct x9_62_fieldid_st { 67 ASN1_OBJECT *fieldType; 68 union { 69 char *ptr; 70 /* NID_X9_62_prime_field */ 71 ASN1_INTEGER *prime; 72 /* anything else */ 73 ASN1_TYPE *other; 74 } p; 75 } X9_62_FIELDID; 76 77 ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY); 78 79 ASN1_ADB(X9_62_FIELDID) = { 80 ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)), 81 } ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL); 82 83 ASN1_SEQUENCE(X9_62_FIELDID) = { 84 ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT), 85 ASN1_ADB_OBJECT(X9_62_FIELDID) 86 } ASN1_SEQUENCE_END(X9_62_FIELDID); 87 88 typedef struct x9_62_curve_st { 89 ASN1_OCTET_STRING *a; 90 ASN1_OCTET_STRING *b; 91 ASN1_BIT_STRING *seed; 92 } X9_62_CURVE; 93 94 ASN1_SEQUENCE(X9_62_CURVE) = { 95 ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING), 96 ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING), 97 ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) 98 } ASN1_SEQUENCE_END(X9_62_CURVE); 99 100 typedef struct ec_parameters_st { 101 long version; 102 X9_62_FIELDID *fieldID; 103 X9_62_CURVE *curve; 104 ASN1_OCTET_STRING *base; 105 ASN1_INTEGER *order; 106 ASN1_INTEGER *cofactor; 107 } ECPARAMETERS; 108 109 ASN1_SEQUENCE(ECPARAMETERS) = { 110 ASN1_SIMPLE(ECPARAMETERS, version, LONG), 111 ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID), 112 ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE), 113 ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING), 114 ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER), 115 ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER) 116 } ASN1_SEQUENCE_END(ECPARAMETERS); 117 118 DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS); 119 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS); 120 121 typedef struct ecpk_parameters_st { 122 int type; 123 union { 124 ASN1_OBJECT *named_curve; 125 ECPARAMETERS *parameters; 126 } value; 127 } ECPKPARAMETERS; 128 129 /* SEC1 ECPrivateKey */ 130 typedef struct ec_privatekey_st { 131 long version; 132 ASN1_OCTET_STRING *privateKey; 133 ECPKPARAMETERS *parameters; 134 ASN1_BIT_STRING *publicKey; 135 } EC_PRIVATEKEY; 136 137 ASN1_CHOICE(ECPKPARAMETERS) = { 138 ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT), 139 ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS), 140 } ASN1_CHOICE_END(ECPKPARAMETERS); 141 142 DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS); 143 DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS); 144 IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS); 145 146 ASN1_SEQUENCE(EC_PRIVATEKEY) = { 147 ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG), 148 ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), 149 ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), 150 ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1), 151 } ASN1_SEQUENCE_END(EC_PRIVATEKEY); 152 153 DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY); 154 DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY); 155 IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY); 156 157 158 ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, 159 ECPKPARAMETERS *params) { 160 int ok = 0, nid; 161 ECPKPARAMETERS *ret = params; 162 163 if (ret == NULL) { 164 ret = ECPKPARAMETERS_new(); 165 if (ret == NULL) { 166 OPENSSL_PUT_ERROR(EC, ec_asn1_group2pkparameters, ERR_R_MALLOC_FAILURE); 167 return NULL; 168 } 169 } else { 170 if (ret->value.named_curve) { 171 ASN1_OBJECT_free(ret->value.named_curve); 172 } 173 } 174 175 /* use the ASN.1 OID to describe the the elliptic curve parameters. */ 176 nid = EC_GROUP_get_curve_name(group); 177 if (nid) { 178 ret->type = 0; 179 ret->value.named_curve = (ASN1_OBJECT*) OBJ_nid2obj(nid); 180 ok = ret->value.named_curve != NULL; 181 } 182 183 if (!ok) { 184 ECPKPARAMETERS_free(ret); 185 return NULL; 186 } 187 188 return ret; 189 } 190 191 EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) { 192 EC_GROUP *ret = NULL; 193 int nid = NID_undef; 194 195 if (params == NULL) { 196 OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_MISSING_PARAMETERS); 197 return NULL; 198 } 199 200 if (params->type == 0) { 201 nid = OBJ_obj2nid(params->value.named_curve); 202 } else if (params->type == 1) { 203 /* We don't support arbitary curves so we attempt to recognise it from the 204 * group order. */ 205 const ECPARAMETERS *ecparams = params->value.parameters; 206 unsigned i; 207 const struct built_in_curve *curve; 208 209 for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) { 210 curve = &OPENSSL_built_in_curves[i]; 211 const unsigned param_len = curve->data->param_len; 212 if (ecparams->order->length == param_len && 213 memcmp(ecparams->order->data, &curve->data->data[param_len * 5], 214 param_len) == 0) { 215 nid = curve->nid; 216 break; 217 } 218 } 219 } 220 221 if (nid == NID_undef) { 222 OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_NON_NAMED_CURVE); 223 return NULL; 224 } 225 226 ret = EC_GROUP_new_by_curve_name(nid); 227 if (ret == NULL) { 228 OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, 229 EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); 230 return NULL; 231 } 232 233 return ret; 234 } 235 236 static EC_GROUP *d2i_ECPKParameters(EC_GROUP **groupp, const uint8_t **inp, 237 long len) { 238 EC_GROUP *group = NULL; 239 ECPKPARAMETERS *params = NULL; 240 241 params = d2i_ECPKPARAMETERS(NULL, inp, len); 242 if (params == NULL) { 243 OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_D2I_ECPKPARAMETERS_FAILURE); 244 ECPKPARAMETERS_free(params); 245 return NULL; 246 } 247 248 group = ec_asn1_pkparameters2group(params); 249 if (group == NULL) { 250 OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_PKPARAMETERS2GROUP_FAILURE); 251 ECPKPARAMETERS_free(params); 252 return NULL; 253 } 254 255 if (groupp && *groupp) { 256 EC_GROUP_free(*groupp); 257 } 258 if (groupp) { 259 *groupp = group; 260 } 261 262 ECPKPARAMETERS_free(params); 263 return group; 264 } 265 266 static int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) { 267 int ret = 0; 268 ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(group, NULL); 269 if (tmp == NULL) { 270 OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_GROUP2PKPARAMETERS_FAILURE); 271 return 0; 272 } 273 ret = i2d_ECPKPARAMETERS(tmp, outp); 274 if (ret == 0) { 275 OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_I2D_ECPKPARAMETERS_FAILURE); 276 ECPKPARAMETERS_free(tmp); 277 return 0; 278 } 279 ECPKPARAMETERS_free(tmp); 280 return ret; 281 } 282 283 EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) { 284 int ok = 0; 285 EC_KEY *ret = NULL; 286 EC_PRIVATEKEY *priv_key = NULL; 287 288 priv_key = EC_PRIVATEKEY_new(); 289 if (priv_key == NULL) { 290 OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_MALLOC_FAILURE); 291 return NULL; 292 } 293 294 priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len); 295 if (priv_key == NULL) { 296 OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB); 297 EC_PRIVATEKEY_free(priv_key); 298 return NULL; 299 } 300 301 if (a == NULL || *a == NULL) { 302 ret = EC_KEY_new(); 303 if (ret == NULL) { 304 OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_MALLOC_FAILURE); 305 goto err; 306 } 307 if (a) { 308 *a = ret; 309 } 310 } else { 311 ret = *a; 312 } 313 314 if (priv_key->parameters) { 315 if (ret->group) { 316 EC_GROUP_free(ret->group); 317 } 318 ret->group = ec_asn1_pkparameters2group(priv_key->parameters); 319 } 320 321 if (ret->group == NULL) { 322 OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB); 323 goto err; 324 } 325 326 ret->version = priv_key->version; 327 328 if (priv_key->privateKey) { 329 ret->priv_key = 330 BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey), 331 M_ASN1_STRING_length(priv_key->privateKey), ret->priv_key); 332 if (ret->priv_key == NULL) { 333 OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_BN_LIB); 334 goto err; 335 } 336 } else { 337 OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, EC_R_MISSING_PRIVATE_KEY); 338 goto err; 339 } 340 341 /* TODO(fork): loading the public key is silly. Why not calculate it? */ 342 if (priv_key->publicKey) { 343 const uint8_t *pub_oct; 344 size_t pub_oct_len; 345 346 if (ret->pub_key) { 347 EC_POINT_free(ret->pub_key); 348 } 349 ret->pub_key = EC_POINT_new(ret->group); 350 if (ret->pub_key == NULL) { 351 OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB); 352 goto err; 353 } 354 pub_oct = M_ASN1_STRING_data(priv_key->publicKey); 355 pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey); 356 /* save the point conversion form */ 357 ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01); 358 if (!EC_POINT_oct2point(ret->group, ret->pub_key, pub_oct, pub_oct_len, 359 NULL)) { 360 OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB); 361 goto err; 362 } 363 } 364 365 ok = 1; 366 367 err: 368 if (!ok) { 369 if (ret) { 370 EC_KEY_free(ret); 371 } 372 ret = NULL; 373 } 374 375 if (priv_key) { 376 EC_PRIVATEKEY_free(priv_key); 377 } 378 379 return ret; 380 } 381 382 int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) { 383 int ret = 0, ok = 0; 384 uint8_t *buffer = NULL; 385 size_t buf_len = 0, tmp_len; 386 EC_PRIVATEKEY *priv_key = NULL; 387 388 if (key == NULL || key->group == NULL || key->priv_key == NULL) { 389 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_PASSED_NULL_PARAMETER); 390 goto err; 391 } 392 393 priv_key = EC_PRIVATEKEY_new(); 394 if (priv_key == NULL) { 395 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE); 396 goto err; 397 } 398 399 priv_key->version = key->version; 400 401 buf_len = BN_num_bytes(key->priv_key); 402 buffer = OPENSSL_malloc(buf_len); 403 if (buffer == NULL) { 404 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE); 405 goto err; 406 } 407 408 if (!BN_bn2bin(key->priv_key, buffer)) { 409 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_BN_LIB); 410 goto err; 411 } 412 413 if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) { 414 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB); 415 goto err; 416 } 417 418 /* TODO(fork): replace this flexibility with key sensible default? */ 419 if (!(key->enc_flag & EC_PKEY_NO_PARAMETERS)) { 420 if ((priv_key->parameters = ec_asn1_group2pkparameters( 421 key->group, priv_key->parameters)) == NULL) { 422 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB); 423 goto err; 424 } 425 } 426 427 /* TODO(fork): replace this flexibility with key sensible default? */ 428 if (!(key->enc_flag & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) { 429 priv_key->publicKey = M_ASN1_BIT_STRING_new(); 430 if (priv_key->publicKey == NULL) { 431 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE); 432 goto err; 433 } 434 435 tmp_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL, 436 0, NULL); 437 438 if (tmp_len > buf_len) { 439 uint8_t *tmp_buffer = OPENSSL_realloc(buffer, tmp_len); 440 if (!tmp_buffer) { 441 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE); 442 goto err; 443 } 444 buffer = tmp_buffer; 445 buf_len = tmp_len; 446 } 447 448 if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, buffer, 449 buf_len, NULL)) { 450 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB); 451 goto err; 452 } 453 454 priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 455 priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; 456 if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) { 457 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB); 458 goto err; 459 } 460 } 461 462 ret = i2d_EC_PRIVATEKEY(priv_key, outp); 463 if (ret == 0) { 464 OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB); 465 goto err; 466 } 467 ok = 1; 468 469 err: 470 if (buffer) { 471 OPENSSL_free(buffer); 472 } 473 if (priv_key) { 474 EC_PRIVATEKEY_free(priv_key); 475 } 476 return (ok ? ret : 0); 477 } 478 479 int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) { 480 if (key == NULL) { 481 OPENSSL_PUT_ERROR(EC, i2d_ECParameters, ERR_R_PASSED_NULL_PARAMETER); 482 return 0; 483 } 484 return i2d_ECPKParameters(key->group, outp); 485 } 486 487 EC_KEY *d2i_ECParameters(EC_KEY **key, const uint8_t **inp, long len) { 488 EC_KEY *ret; 489 490 if (inp == NULL || *inp == NULL) { 491 OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_PASSED_NULL_PARAMETER); 492 return NULL; 493 } 494 495 if (key == NULL || *key == NULL) { 496 ret = EC_KEY_new(); 497 if (ret == NULL) { 498 OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_MALLOC_FAILURE); 499 return NULL; 500 } 501 if (key) { 502 *key = ret; 503 } 504 } else { 505 ret = *key; 506 } 507 508 if (!d2i_ECPKParameters(&ret->group, inp, len)) { 509 OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_EC_LIB); 510 return NULL; 511 } 512 513 return ret; 514 } 515 516 EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) { 517 EC_KEY *ret = NULL; 518 519 if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) { 520 OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER); 521 return 0; 522 } 523 ret = *keyp; 524 if (ret->pub_key == NULL && 525 (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { 526 OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_MALLOC_FAILURE); 527 return 0; 528 } 529 if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) { 530 OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_EC_LIB); 531 return 0; 532 } 533 /* save the point conversion form */ 534 ret->conv_form = (point_conversion_form_t)(*inp[0] & ~0x01); 535 *inp += len; 536 return ret; 537 } 538 539 int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) { 540 size_t buf_len = 0; 541 int new_buffer = 0; 542 543 if (key == NULL) { 544 OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER); 545 return 0; 546 } 547 548 buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL, 549 0, NULL); 550 551 if (outp == NULL || buf_len == 0) { 552 /* out == NULL => just return the length of the octet string */ 553 return buf_len; 554 } 555 556 if (*outp == NULL) { 557 *outp = OPENSSL_malloc(buf_len); 558 if (*outp == NULL) { 559 OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_MALLOC_FAILURE); 560 return 0; 561 } 562 new_buffer = 1; 563 } 564 if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp, 565 buf_len, NULL)) { 566 OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_EC_LIB); 567 if (new_buffer) { 568 OPENSSL_free(*outp); 569 *outp = NULL; 570 } 571 return 0; 572 } 573 574 if (!new_buffer) { 575 *outp += buf_len; 576 } 577 return buf_len; 578 } 579