gost_ameth.c revision 280304
1/********************************************************************** 2 * gost_ameth.c * 3 * Copyright (c) 2005-2006 Cryptocom LTD * 4 * This file is distributed under the same license as OpenSSL * 5 * * 6 * Implementation of RFC 4490/4491 ASN1 method * 7 * for OpenSSL * 8 * Requires OpenSSL 0.9.9 for compilation * 9 **********************************************************************/ 10#include <string.h> 11#include <openssl/crypto.h> 12#include <openssl/err.h> 13#include <openssl/engine.h> 14#include <openssl/evp.h> 15#include <openssl/asn1.h> 16#ifndef OPENSSL_NO_CMS 17# include <openssl/cms.h> 18#endif 19#include "gost_params.h" 20#include "gost_lcl.h" 21#include "e_gost_err.h" 22 23int gost94_nid_by_params(DSA *p) 24{ 25 R3410_params *gost_params; 26 BIGNUM *q = BN_new(); 27 for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) { 28 BN_dec2bn(&q, gost_params->q); 29 if (!BN_cmp(q, p->q)) { 30 BN_free(q); 31 return gost_params->nid; 32 } 33 } 34 BN_free(q); 35 return NID_undef; 36} 37 38static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) 39{ 40 ASN1_STRING *params = ASN1_STRING_new(); 41 GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); 42 int pkey_param_nid = NID_undef; 43 44 if (!params || !gkp) { 45 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); 46 ASN1_STRING_free(params); 47 params = NULL; 48 goto err; 49 } 50 switch (EVP_PKEY_base_id(key)) { 51 case NID_id_GostR3410_2001: 52 pkey_param_nid = 53 EC_GROUP_get_curve_name(EC_KEY_get0_group 54 (EVP_PKEY_get0((EVP_PKEY *)key))); 55 break; 56 case NID_id_GostR3410_94: 57 pkey_param_nid = 58 (int)gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); 59 if (pkey_param_nid == NID_undef) { 60 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, 61 GOST_R_INVALID_GOST94_PARMSET); 62 ASN1_STRING_free(params); 63 params = NULL; 64 goto err; 65 } 66 break; 67 } 68 gkp->key_params = OBJ_nid2obj(pkey_param_nid); 69 gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); 70 /* 71 * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); 72 */ 73 params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); 74 if (params->length <= 0) { 75 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); 76 ASN1_STRING_free(params); 77 params = NULL; 78 goto err; 79 } 80 params->type = V_ASN1_SEQUENCE; 81 err: 82 GOST_KEY_PARAMS_free(gkp); 83 return params; 84} 85 86/* 87 * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting 88 * NID and parameters 89 */ 90static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) 91{ 92 ASN1_OBJECT *palg_obj = NULL; 93 int ptype = V_ASN1_UNDEF; 94 int pkey_nid = NID_undef, param_nid = NID_undef; 95 void *_pval; 96 ASN1_STRING *pval = NULL; 97 const unsigned char *p; 98 GOST_KEY_PARAMS *gkp = NULL; 99 100 X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); 101 pval = _pval; 102 if (ptype != V_ASN1_SEQUENCE) { 103 GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 104 GOST_R_BAD_KEY_PARAMETERS_FORMAT); 105 return 0; 106 } 107 p = pval->data; 108 pkey_nid = OBJ_obj2nid(palg_obj); 109 110 gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length); 111 if (!gkp) { 112 GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 113 GOST_R_BAD_PKEY_PARAMETERS_FORMAT); 114 return 0; 115 } 116 param_nid = OBJ_obj2nid(gkp->key_params); 117 GOST_KEY_PARAMS_free(gkp); 118 EVP_PKEY_set_type(pkey, pkey_nid); 119 switch (pkey_nid) { 120 case NID_id_GostR3410_94: 121 { 122 DSA *dsa = EVP_PKEY_get0(pkey); 123 if (!dsa) { 124 dsa = DSA_new(); 125 if (!EVP_PKEY_assign(pkey, pkey_nid, dsa)) 126 return 0; 127 } 128 if (!fill_GOST94_params(dsa, param_nid)) 129 return 0; 130 break; 131 } 132 case NID_id_GostR3410_2001: 133 { 134 EC_KEY *ec = EVP_PKEY_get0(pkey); 135 if (!ec) { 136 ec = EC_KEY_new(); 137 if (!EVP_PKEY_assign(pkey, pkey_nid, ec)) 138 return 0; 139 } 140 if (!fill_GOST2001_params(ec, param_nid)) 141 return 0; 142 } 143 } 144 145 return 1; 146} 147 148static int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv) 149{ 150 switch (EVP_PKEY_base_id(pkey)) { 151 case NID_id_GostR3410_94: 152 { 153 DSA *dsa = EVP_PKEY_get0(pkey); 154 if (!dsa) { 155 dsa = DSA_new(); 156 EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa); 157 } 158 dsa->priv_key = BN_dup(priv); 159 if (!EVP_PKEY_missing_parameters(pkey)) 160 gost94_compute_public(dsa); 161 break; 162 } 163 case NID_id_GostR3410_2001: 164 { 165 EC_KEY *ec = EVP_PKEY_get0(pkey); 166 if (!ec) { 167 ec = EC_KEY_new(); 168 EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec); 169 } 170 if (!EC_KEY_set_private_key(ec, priv)) 171 return 0; 172 if (!EVP_PKEY_missing_parameters(pkey)) 173 gost2001_compute_public(ec); 174 break; 175 } 176 } 177 return 1; 178} 179 180BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey) 181{ 182 switch (EVP_PKEY_base_id(pkey)) { 183 case NID_id_GostR3410_94: 184 { 185 DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); 186 if (!dsa) { 187 return NULL; 188 } 189 if (!dsa->priv_key) 190 return NULL; 191 return dsa->priv_key; 192 break; 193 } 194 case NID_id_GostR3410_2001: 195 { 196 EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); 197 const BIGNUM *priv; 198 if (!ec) { 199 return NULL; 200 } 201 if (!(priv = EC_KEY_get0_private_key(ec))) 202 return NULL; 203 return (BIGNUM *)priv; 204 break; 205 } 206 } 207 return NULL; 208} 209 210static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 211{ 212 switch (op) { 213 case ASN1_PKEY_CTRL_PKCS7_SIGN: 214 if (arg1 == 0) { 215 X509_ALGOR *alg1 = NULL, *alg2 = NULL; 216 int nid = EVP_PKEY_base_id(pkey); 217 PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, 218 NULL, &alg1, &alg2); 219 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 220 V_ASN1_NULL, 0); 221 if (nid == NID_undef) { 222 return (-1); 223 } 224 X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 225 } 226 return 1; 227#ifndef OPENSSL_NO_CMS 228 case ASN1_PKEY_CTRL_CMS_SIGN: 229 if (arg1 == 0) { 230 X509_ALGOR *alg1 = NULL, *alg2 = NULL; 231 int nid = EVP_PKEY_base_id(pkey); 232 CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, 233 NULL, NULL, &alg1, &alg2); 234 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 235 V_ASN1_NULL, 0); 236 if (nid == NID_undef) { 237 return (-1); 238 } 239 X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 240 } 241 return 1; 242#endif 243 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: 244 if (arg1 == 0) { 245 X509_ALGOR *alg; 246 ASN1_STRING *params = encode_gost_algor_params(pkey); 247 if (!params) { 248 return -1; 249 } 250 PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg); 251 X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), 252 V_ASN1_SEQUENCE, params); 253 } 254 return 1; 255#ifndef OPENSSL_NO_CMS 256 case ASN1_PKEY_CTRL_CMS_ENVELOPE: 257 if (arg1 == 0) { 258 X509_ALGOR *alg = NULL; 259 ASN1_STRING *params = encode_gost_algor_params(pkey); 260 if (!params) { 261 return -1; 262 } 263 CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, 264 NULL, &alg); 265 X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, 266 params); 267 } 268 return 1; 269#endif 270 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 271 *(int *)arg2 = NID_id_GostR3411_94; 272 return 2; 273 } 274 275 return -2; 276} 277 278/* --------------------- free functions * ------------------------------*/ 279static void pkey_free_gost94(EVP_PKEY *key) 280{ 281 if (key->pkey.dsa) { 282 DSA_free(key->pkey.dsa); 283 } 284} 285 286static void pkey_free_gost01(EVP_PKEY *key) 287{ 288 if (key->pkey.ec) { 289 EC_KEY_free(key->pkey.ec); 290 } 291} 292 293/* ------------------ private key functions -----------------------------*/ 294static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) 295{ 296 const unsigned char *pkey_buf = NULL, *p = NULL; 297 int priv_len = 0; 298 BIGNUM *pk_num = NULL; 299 int ret = 0; 300 X509_ALGOR *palg = NULL; 301 ASN1_OBJECT *palg_obj = NULL; 302 ASN1_INTEGER *priv_key = NULL; 303 304 if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf)) 305 return 0; 306 p = pkey_buf; 307 if (!decode_gost_algor_params(pk, palg)) { 308 return 0; 309 } 310 if (V_ASN1_OCTET_STRING == *p) { 311 /* New format - Little endian octet string */ 312 unsigned char rev_buf[32]; 313 int i; 314 ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); 315 if (!s || s->length != 32) { 316 GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); 317 return 0; 318 } 319 for (i = 0; i < 32; i++) { 320 rev_buf[31 - i] = s->data[i]; 321 } 322 ASN1_STRING_free(s); 323 pk_num = getbnfrombuf(rev_buf, 32); 324 } else { 325 priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); 326 if (!priv_key) 327 return 0; 328 ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); 329 ASN1_INTEGER_free(priv_key); 330 if (!ret) { 331 GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); 332 return 0; 333 } 334 } 335 336 ret = gost_set_priv_key(pk, pk_num); 337 BN_free(pk_num); 338 return ret; 339} 340 341/* ----------------------------------------------------------------------*/ 342static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) 343{ 344 ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 345 ASN1_STRING *params = encode_gost_algor_params(pk); 346 unsigned char *priv_buf = NULL; 347 int priv_len; 348 349 ASN1_INTEGER *asn1key = NULL; 350 if (!params) { 351 return 0; 352 } 353 asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL); 354 priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); 355 ASN1_INTEGER_free(asn1key); 356 return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, 357 priv_buf, priv_len); 358} 359 360/* --------- printing keys --------------------------------*/ 361static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, 362 ASN1_PCTX *pctx, int type) 363{ 364 int param_nid = NID_undef; 365 366 if (type == 2) { 367 BIGNUM *key; 368 369 if (!BIO_indent(out, indent, 128)) 370 return 0; 371 BIO_printf(out, "Private key: "); 372 key = gost_get0_priv_key(pkey); 373 if (!key) 374 BIO_printf(out, "<undefined>"); 375 else 376 BN_print(out, key); 377 BIO_printf(out, "\n"); 378 } 379 if (type >= 1) { 380 BIGNUM *pubkey; 381 382 pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; 383 BIO_indent(out, indent, 128); 384 BIO_printf(out, "Public key: "); 385 BN_print(out, pubkey); 386 BIO_printf(out, "\n"); 387 } 388 389 param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 390 BIO_indent(out, indent, 128); 391 BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 392 return 1; 393} 394 395static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 396 ASN1_PCTX *pctx) 397{ 398 return print_gost_94(out, pkey, indent, pctx, 0); 399} 400 401static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 402 ASN1_PCTX *pctx) 403{ 404 return print_gost_94(out, pkey, indent, pctx, 1); 405} 406 407static int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 408 ASN1_PCTX *pctx) 409{ 410 return print_gost_94(out, pkey, indent, pctx, 2); 411} 412 413static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, 414 ASN1_PCTX *pctx, int type) 415{ 416 int param_nid = NID_undef; 417 if (type == 2) { 418 BIGNUM *key; 419 420 if (!BIO_indent(out, indent, 128)) 421 return 0; 422 BIO_printf(out, "Private key: "); 423 key = gost_get0_priv_key(pkey); 424 if (!key) 425 BIO_printf(out, "<undefined)"); 426 else 427 BN_print(out, key); 428 BIO_printf(out, "\n"); 429 } 430 if (type >= 1) { 431 BN_CTX *ctx = BN_CTX_new(); 432 BIGNUM *X, *Y; 433 const EC_POINT *pubkey; 434 const EC_GROUP *group; 435 436 if (!ctx) { 437 GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE); 438 return 0; 439 } 440 BN_CTX_start(ctx); 441 X = BN_CTX_get(ctx); 442 Y = BN_CTX_get(ctx); 443 pubkey = 444 EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 445 group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 446 if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { 447 GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB); 448 BN_CTX_free(ctx); 449 return 0; 450 } 451 if (!BIO_indent(out, indent, 128)) 452 return 0; 453 BIO_printf(out, "Public key:\n"); 454 if (!BIO_indent(out, indent + 3, 128)) 455 return 0; 456 BIO_printf(out, "X:"); 457 BN_print(out, X); 458 BIO_printf(out, "\n"); 459 BIO_indent(out, indent + 3, 128); 460 BIO_printf(out, "Y:"); 461 BN_print(out, Y); 462 BIO_printf(out, "\n"); 463 BN_CTX_end(ctx); 464 BN_CTX_free(ctx); 465 } 466 467 param_nid = 468 EC_GROUP_get_curve_name(EC_KEY_get0_group 469 (EVP_PKEY_get0((EVP_PKEY *)pkey))); 470 if (!BIO_indent(out, indent, 128)) 471 return 0; 472 BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 473 return 1; 474} 475 476static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 477 ASN1_PCTX *pctx) 478{ 479 return print_gost_01(out, pkey, indent, pctx, 0); 480} 481 482static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 483 ASN1_PCTX *pctx) 484{ 485 return print_gost_01(out, pkey, indent, pctx, 1); 486} 487 488static int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 489 ASN1_PCTX *pctx) 490{ 491 return print_gost_01(out, pkey, indent, pctx, 2); 492} 493 494/* ---------------------------------------------------------------------*/ 495static int param_missing_gost94(const EVP_PKEY *pk) 496{ 497 const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 498 if (!dsa) 499 return 1; 500 if (!dsa->q) 501 return 1; 502 return 0; 503} 504 505static int param_missing_gost01(const EVP_PKEY *pk) 506{ 507 const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 508 if (!ec) 509 return 1; 510 if (!EC_KEY_get0_group(ec)) 511 return 1; 512 return 0; 513} 514 515static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) 516{ 517 const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from); 518 DSA *dto = EVP_PKEY_get0(to); 519 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 520 GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS); 521 return 0; 522 } 523 if (!dfrom) { 524 GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING); 525 return 0; 526 } 527 if (!dto) { 528 dto = DSA_new(); 529 EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto); 530 } 531#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x); 532 COPYBIGNUM(dto, dfrom, p) 533 COPYBIGNUM(dto, dfrom, q) 534 COPYBIGNUM(dto, dfrom, g) 535 536 if (dto->priv_key) 537 gost94_compute_public(dto); 538 return 1; 539} 540 541static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 542{ 543 EC_KEY *eto = EVP_PKEY_get0(to); 544 const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); 545 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 546 GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS); 547 return 0; 548 } 549 if (!efrom) { 550 GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); 551 return 0; 552 } 553 if (!eto) { 554 eto = EC_KEY_new(); 555 EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto); 556 } 557 EC_KEY_set_group(eto, EC_KEY_get0_group(efrom)); 558 if (EC_KEY_get0_private_key(eto)) { 559 gost2001_compute_public(eto); 560 } 561 return 1; 562} 563 564static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 565{ 566 const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 567 const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 568 if (!BN_cmp(da->q, db->q)) 569 return 1; 570 return 0; 571} 572 573static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 574{ 575 if (EC_GROUP_get_curve_name 576 (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) == 577 EC_GROUP_get_curve_name(EC_KEY_get0_group 578 (EVP_PKEY_get0((EVP_PKEY *)b)))) { 579 return 1; 580 } 581 return 0; 582 583} 584 585/* ---------- Public key functions * --------------------------------------*/ 586static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) 587{ 588 X509_ALGOR *palg = NULL; 589 const unsigned char *pubkey_buf = NULL; 590 unsigned char *databuf; 591 ASN1_OBJECT *palgobj = NULL; 592 int pub_len, i, j; 593 DSA *dsa; 594 ASN1_OCTET_STRING *octet = NULL; 595 596 if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) 597 return 0; 598 EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); 599 if (!decode_gost_algor_params(pk, palg)) 600 return 0; 601 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 602 if (!octet) { 603 GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); 604 return 0; 605 } 606 databuf = OPENSSL_malloc(octet->length); 607 for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { 608 databuf[j] = octet->data[i]; 609 } 610 dsa = EVP_PKEY_get0(pk); 611 dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL); 612 ASN1_OCTET_STRING_free(octet); 613 OPENSSL_free(databuf); 614 return 1; 615 616} 617 618static int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk) 619{ 620 ASN1_OBJECT *algobj = NULL; 621 ASN1_OCTET_STRING *octet = NULL; 622 void *pval = NULL; 623 unsigned char *buf = NULL, *databuf, *sptr; 624 int i, j, data_len, ret = 0; 625 626 int ptype = V_ASN1_UNDEF; 627 DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 628 algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 629 if (pk->save_parameters) { 630 ASN1_STRING *params = encode_gost_algor_params(pk); 631 pval = params; 632 ptype = V_ASN1_SEQUENCE; 633 } 634 data_len = BN_num_bytes(dsa->pub_key); 635 databuf = OPENSSL_malloc(data_len); 636 BN_bn2bin(dsa->pub_key, databuf); 637 octet = ASN1_OCTET_STRING_new(); 638 ASN1_STRING_set(octet, NULL, data_len); 639 sptr = ASN1_STRING_data(octet); 640 for (i = 0, j = data_len - 1; i < data_len; i++, j--) { 641 sptr[i] = databuf[j]; 642 } 643 OPENSSL_free(databuf); 644 ret = i2d_ASN1_OCTET_STRING(octet, &buf); 645 ASN1_BIT_STRING_free(octet); 646 if (ret < 0) 647 return 0; 648 return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 649} 650 651static int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) 652{ 653 X509_ALGOR *palg = NULL; 654 const unsigned char *pubkey_buf = NULL; 655 unsigned char *databuf; 656 ASN1_OBJECT *palgobj = NULL; 657 int pub_len, i, j; 658 EC_POINT *pub_key; 659 BIGNUM *X, *Y; 660 ASN1_OCTET_STRING *octet = NULL; 661 int len; 662 const EC_GROUP *group; 663 664 if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) 665 return 0; 666 EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); 667 if (!decode_gost_algor_params(pk, palg)) 668 return 0; 669 group = EC_KEY_get0_group(EVP_PKEY_get0(pk)); 670 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 671 if (!octet) { 672 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); 673 return 0; 674 } 675 databuf = OPENSSL_malloc(octet->length); 676 for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { 677 databuf[j] = octet->data[i]; 678 } 679 len = octet->length / 2; 680 ASN1_OCTET_STRING_free(octet); 681 682 Y = getbnfrombuf(databuf, len); 683 X = getbnfrombuf(databuf + len, len); 684 OPENSSL_free(databuf); 685 pub_key = EC_POINT_new(group); 686 if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) { 687 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 688 EC_POINT_free(pub_key); 689 BN_free(X); 690 BN_free(Y); 691 return 0; 692 } 693 BN_free(X); 694 BN_free(Y); 695 if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) { 696 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 697 EC_POINT_free(pub_key); 698 return 0; 699 } 700 EC_POINT_free(pub_key); 701 return 1; 702 703} 704 705static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) 706{ 707 ASN1_OBJECT *algobj = NULL; 708 ASN1_OCTET_STRING *octet = NULL; 709 void *pval = NULL; 710 unsigned char *buf = NULL, *databuf, *sptr; 711 int i, j, data_len, ret = 0; 712 const EC_POINT *pub_key; 713 BIGNUM *X, *Y, *order; 714 const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 715 int ptype = V_ASN1_UNDEF; 716 717 algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 718 if (pk->save_parameters) { 719 ASN1_STRING *params = encode_gost_algor_params(pk); 720 pval = params; 721 ptype = V_ASN1_SEQUENCE; 722 } 723 order = BN_new(); 724 EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL); 725 pub_key = EC_KEY_get0_public_key(ec); 726 if (!pub_key) { 727 GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); 728 return 0; 729 } 730 X = BN_new(); 731 Y = BN_new(); 732 EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), 733 pub_key, X, Y, NULL); 734 data_len = 2 * BN_num_bytes(order); 735 BN_free(order); 736 databuf = OPENSSL_malloc(data_len); 737 memset(databuf, 0, data_len); 738 739 store_bignum(X, databuf + data_len / 2, data_len / 2); 740 store_bignum(Y, databuf, data_len / 2); 741 742 BN_free(X); 743 BN_free(Y); 744 octet = ASN1_OCTET_STRING_new(); 745 ASN1_STRING_set(octet, NULL, data_len); 746 sptr = ASN1_STRING_data(octet); 747 for (i = 0, j = data_len - 1; i < data_len; i++, j--) { 748 sptr[i] = databuf[j]; 749 } 750 OPENSSL_free(databuf); 751 ret = i2d_ASN1_OCTET_STRING(octet, &buf); 752 ASN1_BIT_STRING_free(octet); 753 if (ret < 0) 754 return 0; 755 return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 756} 757 758static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 759{ 760 const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 761 const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 762 if (da && db && da->pub_key && db->pub_key 763 && !BN_cmp(da->pub_key, db->pub_key)) { 764 return 1; 765 } 766 return 0; 767} 768 769static int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 770{ 771 const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a); 772 const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b); 773 const EC_POINT *ka, *kb; 774 int ret = 0; 775 if (!ea || !eb) 776 return 0; 777 ka = EC_KEY_get0_public_key(ea); 778 kb = EC_KEY_get0_public_key(eb); 779 if (!ka || !kb) 780 return 0; 781 ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL)); 782 return ret; 783} 784 785static int pkey_size_gost(const EVP_PKEY *pk) 786{ 787 return 64; 788} 789 790static int pkey_bits_gost(const EVP_PKEY *pk) 791{ 792 return 256; 793} 794 795/* ---------------------- ASN1 METHOD for GOST MAC -------------------*/ 796static void mackey_free_gost(EVP_PKEY *pk) 797{ 798 if (pk->pkey.ptr) { 799 OPENSSL_free(pk->pkey.ptr); 800 } 801} 802 803static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 804{ 805 switch (op) { 806 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 807 *(int *)arg2 = NID_id_Gost28147_89_MAC; 808 return 2; 809 } 810 return -2; 811} 812 813static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 814{ 815 int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 816 return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); 817} 818 819static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 820{ 821 int nid = 822 EC_GROUP_get_curve_name(EC_KEY_get0_group 823 (EVP_PKEY_get0((EVP_PKEY *)pkey))); 824 return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); 825} 826 827static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, 828 int derlen) 829{ 830 ASN1_OBJECT *obj = NULL; 831 DSA *dsa = EVP_PKEY_get0(pkey); 832 int nid; 833 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 834 return 0; 835 } 836 nid = OBJ_obj2nid(obj); 837 ASN1_OBJECT_free(obj); 838 if (!dsa) { 839 dsa = DSA_new(); 840 if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa)) 841 return 0; 842 } 843 if (!fill_GOST94_params(dsa, nid)) 844 return 0; 845 return 1; 846} 847 848static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, 849 int derlen) 850{ 851 ASN1_OBJECT *obj = NULL; 852 int nid; 853 EC_KEY *ec = EVP_PKEY_get0(pkey); 854 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 855 return 0; 856 } 857 nid = OBJ_obj2nid(obj); 858 ASN1_OBJECT_free(obj); 859 if (!ec) { 860 ec = EC_KEY_new(); 861 if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) 862 return 0; 863 } 864 if (!fill_GOST2001_params(ec, nid)) 865 return 0; 866 return 1; 867} 868 869/* ----------------------------------------------------------------------*/ 870int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, 871 const char *pemstr, const char *info) 872{ 873 *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info); 874 if (!*ameth) 875 return 0; 876 switch (nid) { 877 case NID_id_GostR3410_94: 878 EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94); 879 EVP_PKEY_asn1_set_private(*ameth, 880 priv_decode_gost, priv_encode_gost, 881 priv_print_gost94); 882 883 EVP_PKEY_asn1_set_param(*ameth, 884 gost94_param_decode, gost94_param_encode, 885 param_missing_gost94, param_copy_gost94, 886 param_cmp_gost94, param_print_gost94); 887 EVP_PKEY_asn1_set_public(*ameth, 888 pub_decode_gost94, pub_encode_gost94, 889 pub_cmp_gost94, pub_print_gost94, 890 pkey_size_gost, pkey_bits_gost); 891 892 EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); 893 break; 894 case NID_id_GostR3410_2001: 895 EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01); 896 EVP_PKEY_asn1_set_private(*ameth, 897 priv_decode_gost, priv_encode_gost, 898 priv_print_gost01); 899 900 EVP_PKEY_asn1_set_param(*ameth, 901 gost2001_param_decode, gost2001_param_encode, 902 param_missing_gost01, param_copy_gost01, 903 param_cmp_gost01, param_print_gost01); 904 EVP_PKEY_asn1_set_public(*ameth, 905 pub_decode_gost01, pub_encode_gost01, 906 pub_cmp_gost01, pub_print_gost01, 907 pkey_size_gost, pkey_bits_gost); 908 909 EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); 910 break; 911 case NID_id_Gost28147_89_MAC: 912 EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); 913 EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost); 914 break; 915 } 916 return 1; 917} 918