1238384Sjkim/********************************************************************** 2238384Sjkim * gost_ameth.c * 3238384Sjkim * Copyright (c) 2005-2006 Cryptocom LTD * 4238384Sjkim * This file is distributed under the same license as OpenSSL * 5238384Sjkim * * 6238384Sjkim * Implementation of RFC 4490/4491 ASN1 method * 7238384Sjkim * for OpenSSL * 8238384Sjkim * Requires OpenSSL 0.9.9 for compilation * 9238384Sjkim **********************************************************************/ 10238384Sjkim#include <string.h> 11238384Sjkim#include <openssl/crypto.h> 12238384Sjkim#include <openssl/err.h> 13238384Sjkim#include <openssl/engine.h> 14238384Sjkim#include <openssl/evp.h> 15238384Sjkim#include <openssl/asn1.h> 16238384Sjkim#ifndef OPENSSL_NO_CMS 17280297Sjkim# include <openssl/cms.h> 18238384Sjkim#endif 19238384Sjkim#include "gost_params.h" 20238384Sjkim#include "gost_lcl.h" 21238384Sjkim#include "e_gost_err.h" 22238384Sjkim 23280297Sjkimint gost94_nid_by_params(DSA *p) 24280297Sjkim{ 25280297Sjkim R3410_params *gost_params; 26280297Sjkim BIGNUM *q = BN_new(); 27280297Sjkim for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) { 28280297Sjkim BN_dec2bn(&q, gost_params->q); 29280297Sjkim if (!BN_cmp(q, p->q)) { 30280297Sjkim BN_free(q); 31280297Sjkim return gost_params->nid; 32280297Sjkim } 33280297Sjkim } 34280297Sjkim BN_free(q); 35280297Sjkim return NID_undef; 36280297Sjkim} 37238384Sjkim 38280297Sjkimstatic ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) 39280297Sjkim{ 40280297Sjkim ASN1_STRING *params = ASN1_STRING_new(); 41280297Sjkim GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); 42280297Sjkim int pkey_param_nid = NID_undef; 43238384Sjkim 44280297Sjkim if (!params || !gkp) { 45280297Sjkim GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); 46280297Sjkim ASN1_STRING_free(params); 47280297Sjkim params = NULL; 48280297Sjkim goto err; 49280297Sjkim } 50280297Sjkim switch (EVP_PKEY_base_id(key)) { 51280297Sjkim case NID_id_GostR3410_2001: 52280297Sjkim pkey_param_nid = 53280297Sjkim EC_GROUP_get_curve_name(EC_KEY_get0_group 54280297Sjkim (EVP_PKEY_get0((EVP_PKEY *)key))); 55280297Sjkim break; 56280297Sjkim case NID_id_GostR3410_94: 57280297Sjkim pkey_param_nid = 58280297Sjkim (int)gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); 59280297Sjkim if (pkey_param_nid == NID_undef) { 60280297Sjkim GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, 61280297Sjkim GOST_R_INVALID_GOST94_PARMSET); 62280297Sjkim ASN1_STRING_free(params); 63280297Sjkim params = NULL; 64280297Sjkim goto err; 65280297Sjkim } 66280297Sjkim break; 67280297Sjkim } 68280297Sjkim gkp->key_params = OBJ_nid2obj(pkey_param_nid); 69280297Sjkim gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); 70280297Sjkim /* 71280297Sjkim * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); 72280297Sjkim */ 73280297Sjkim params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); 74280297Sjkim if (params->length <= 0) { 75280297Sjkim GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); 76280297Sjkim ASN1_STRING_free(params); 77280297Sjkim params = NULL; 78280297Sjkim goto err; 79280297Sjkim } 80280297Sjkim params->type = V_ASN1_SEQUENCE; 81280297Sjkim err: 82280297Sjkim GOST_KEY_PARAMS_free(gkp); 83280297Sjkim return params; 84280297Sjkim} 85238384Sjkim 86280297Sjkim/* 87280297Sjkim * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting 88280297Sjkim * NID and parameters 89238384Sjkim */ 90280297Sjkimstatic int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) 91280297Sjkim{ 92280297Sjkim ASN1_OBJECT *palg_obj = NULL; 93280297Sjkim int ptype = V_ASN1_UNDEF; 94280297Sjkim int pkey_nid = NID_undef, param_nid = NID_undef; 95280297Sjkim void *_pval; 96280297Sjkim ASN1_STRING *pval = NULL; 97280297Sjkim const unsigned char *p; 98280297Sjkim GOST_KEY_PARAMS *gkp = NULL; 99238384Sjkim 100280297Sjkim X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); 101280297Sjkim pval = _pval; 102280297Sjkim if (ptype != V_ASN1_SEQUENCE) { 103280297Sjkim GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 104280297Sjkim GOST_R_BAD_KEY_PARAMETERS_FORMAT); 105280297Sjkim return 0; 106280297Sjkim } 107280297Sjkim p = pval->data; 108280297Sjkim pkey_nid = OBJ_obj2nid(palg_obj); 109238384Sjkim 110280297Sjkim gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length); 111280297Sjkim if (!gkp) { 112280297Sjkim GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 113280297Sjkim GOST_R_BAD_PKEY_PARAMETERS_FORMAT); 114280297Sjkim return 0; 115280297Sjkim } 116280297Sjkim param_nid = OBJ_obj2nid(gkp->key_params); 117280297Sjkim GOST_KEY_PARAMS_free(gkp); 118284283Sjkim if(!EVP_PKEY_set_type(pkey, pkey_nid)) { 119284283Sjkim GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR); 120284283Sjkim return 0; 121284283Sjkim } 122280297Sjkim switch (pkey_nid) { 123280297Sjkim case NID_id_GostR3410_94: 124280297Sjkim { 125280297Sjkim DSA *dsa = EVP_PKEY_get0(pkey); 126280297Sjkim if (!dsa) { 127280297Sjkim dsa = DSA_new(); 128280297Sjkim if (!EVP_PKEY_assign(pkey, pkey_nid, dsa)) 129280297Sjkim return 0; 130280297Sjkim } 131280297Sjkim if (!fill_GOST94_params(dsa, param_nid)) 132280297Sjkim return 0; 133280297Sjkim break; 134280297Sjkim } 135280297Sjkim case NID_id_GostR3410_2001: 136280297Sjkim { 137280297Sjkim EC_KEY *ec = EVP_PKEY_get0(pkey); 138280297Sjkim if (!ec) { 139280297Sjkim ec = EC_KEY_new(); 140280297Sjkim if (!EVP_PKEY_assign(pkey, pkey_nid, ec)) 141280297Sjkim return 0; 142280297Sjkim } 143280297Sjkim if (!fill_GOST2001_params(ec, param_nid)) 144280297Sjkim return 0; 145280297Sjkim } 146280297Sjkim } 147238384Sjkim 148280297Sjkim return 1; 149280297Sjkim} 150238384Sjkim 151280297Sjkimstatic int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv) 152280297Sjkim{ 153280297Sjkim switch (EVP_PKEY_base_id(pkey)) { 154280297Sjkim case NID_id_GostR3410_94: 155280297Sjkim { 156280297Sjkim DSA *dsa = EVP_PKEY_get0(pkey); 157280297Sjkim if (!dsa) { 158280297Sjkim dsa = DSA_new(); 159280297Sjkim EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa); 160280297Sjkim } 161280297Sjkim dsa->priv_key = BN_dup(priv); 162280297Sjkim if (!EVP_PKEY_missing_parameters(pkey)) 163280297Sjkim gost94_compute_public(dsa); 164280297Sjkim break; 165280297Sjkim } 166280297Sjkim case NID_id_GostR3410_2001: 167280297Sjkim { 168280297Sjkim EC_KEY *ec = EVP_PKEY_get0(pkey); 169280297Sjkim if (!ec) { 170280297Sjkim ec = EC_KEY_new(); 171280297Sjkim EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec); 172280297Sjkim } 173280297Sjkim if (!EC_KEY_set_private_key(ec, priv)) 174280297Sjkim return 0; 175280297Sjkim if (!EVP_PKEY_missing_parameters(pkey)) 176280297Sjkim gost2001_compute_public(ec); 177280297Sjkim break; 178280297Sjkim } 179280297Sjkim } 180280297Sjkim return 1; 181280297Sjkim} 182238384Sjkim 183280297SjkimBIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey) 184280297Sjkim{ 185280297Sjkim switch (EVP_PKEY_base_id(pkey)) { 186280297Sjkim case NID_id_GostR3410_94: 187280297Sjkim { 188280297Sjkim DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); 189280297Sjkim if (!dsa) { 190280297Sjkim return NULL; 191280297Sjkim } 192280297Sjkim if (!dsa->priv_key) 193280297Sjkim return NULL; 194280297Sjkim return dsa->priv_key; 195280297Sjkim break; 196280297Sjkim } 197280297Sjkim case NID_id_GostR3410_2001: 198280297Sjkim { 199280297Sjkim EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); 200280297Sjkim const BIGNUM *priv; 201280297Sjkim if (!ec) { 202280297Sjkim return NULL; 203280297Sjkim } 204280297Sjkim if (!(priv = EC_KEY_get0_private_key(ec))) 205280297Sjkim return NULL; 206280297Sjkim return (BIGNUM *)priv; 207280297Sjkim break; 208280297Sjkim } 209280297Sjkim } 210280297Sjkim return NULL; 211280297Sjkim} 212280297Sjkim 213280297Sjkimstatic int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 214280297Sjkim{ 215280297Sjkim switch (op) { 216280297Sjkim case ASN1_PKEY_CTRL_PKCS7_SIGN: 217280297Sjkim if (arg1 == 0) { 218280297Sjkim X509_ALGOR *alg1 = NULL, *alg2 = NULL; 219280297Sjkim int nid = EVP_PKEY_base_id(pkey); 220280297Sjkim PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, 221280297Sjkim NULL, &alg1, &alg2); 222280297Sjkim X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 223280297Sjkim V_ASN1_NULL, 0); 224280297Sjkim if (nid == NID_undef) { 225280297Sjkim return (-1); 226280297Sjkim } 227280297Sjkim X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 228280297Sjkim } 229280297Sjkim return 1; 230238384Sjkim#ifndef OPENSSL_NO_CMS 231280297Sjkim case ASN1_PKEY_CTRL_CMS_SIGN: 232280297Sjkim if (arg1 == 0) { 233280297Sjkim X509_ALGOR *alg1 = NULL, *alg2 = NULL; 234280297Sjkim int nid = EVP_PKEY_base_id(pkey); 235280297Sjkim CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, 236280297Sjkim NULL, NULL, &alg1, &alg2); 237280297Sjkim X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 238280297Sjkim V_ASN1_NULL, 0); 239280297Sjkim if (nid == NID_undef) { 240280297Sjkim return (-1); 241280297Sjkim } 242280297Sjkim X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 243280297Sjkim } 244280297Sjkim return 1; 245238384Sjkim#endif 246280297Sjkim case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: 247280297Sjkim if (arg1 == 0) { 248280297Sjkim X509_ALGOR *alg; 249280297Sjkim ASN1_STRING *params = encode_gost_algor_params(pkey); 250280297Sjkim if (!params) { 251280297Sjkim return -1; 252280297Sjkim } 253280297Sjkim PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg); 254280297Sjkim X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), 255280297Sjkim V_ASN1_SEQUENCE, params); 256280297Sjkim } 257280297Sjkim return 1; 258238384Sjkim#ifndef OPENSSL_NO_CMS 259280297Sjkim case ASN1_PKEY_CTRL_CMS_ENVELOPE: 260280297Sjkim if (arg1 == 0) { 261280297Sjkim X509_ALGOR *alg = NULL; 262280297Sjkim ASN1_STRING *params = encode_gost_algor_params(pkey); 263280297Sjkim if (!params) { 264280297Sjkim return -1; 265280297Sjkim } 266280297Sjkim CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, 267280297Sjkim NULL, &alg); 268280297Sjkim X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, 269280297Sjkim params); 270280297Sjkim } 271280297Sjkim return 1; 272238384Sjkim#endif 273280297Sjkim case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 274280297Sjkim *(int *)arg2 = NID_id_GostR3411_94; 275280297Sjkim return 2; 276280297Sjkim } 277238384Sjkim 278280297Sjkim return -2; 279280297Sjkim} 280238384Sjkim 281280297Sjkim/* --------------------- free functions * ------------------------------*/ 282280297Sjkimstatic void pkey_free_gost94(EVP_PKEY *key) 283280297Sjkim{ 284280297Sjkim if (key->pkey.dsa) { 285280297Sjkim DSA_free(key->pkey.dsa); 286280297Sjkim } 287280297Sjkim} 288280297Sjkim 289280297Sjkimstatic void pkey_free_gost01(EVP_PKEY *key) 290280297Sjkim{ 291280297Sjkim if (key->pkey.ec) { 292280297Sjkim EC_KEY_free(key->pkey.ec); 293280297Sjkim } 294280297Sjkim} 295280297Sjkim 296238384Sjkim/* ------------------ private key functions -----------------------------*/ 297280297Sjkimstatic int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) 298280297Sjkim{ 299280297Sjkim const unsigned char *pkey_buf = NULL, *p = NULL; 300280297Sjkim int priv_len = 0; 301280297Sjkim BIGNUM *pk_num = NULL; 302280297Sjkim int ret = 0; 303280297Sjkim X509_ALGOR *palg = NULL; 304280297Sjkim ASN1_OBJECT *palg_obj = NULL; 305280297Sjkim ASN1_INTEGER *priv_key = NULL; 306238384Sjkim 307280297Sjkim if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf)) 308280297Sjkim return 0; 309280297Sjkim p = pkey_buf; 310280297Sjkim if (!decode_gost_algor_params(pk, palg)) { 311280297Sjkim return 0; 312280297Sjkim } 313280297Sjkim if (V_ASN1_OCTET_STRING == *p) { 314280297Sjkim /* New format - Little endian octet string */ 315280297Sjkim unsigned char rev_buf[32]; 316280297Sjkim int i; 317280297Sjkim ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); 318280297Sjkim if (!s || s->length != 32) { 319280297Sjkim GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); 320280297Sjkim return 0; 321280297Sjkim } 322280297Sjkim for (i = 0; i < 32; i++) { 323280297Sjkim rev_buf[31 - i] = s->data[i]; 324280297Sjkim } 325280297Sjkim ASN1_STRING_free(s); 326280297Sjkim pk_num = getbnfrombuf(rev_buf, 32); 327280297Sjkim } else { 328280297Sjkim priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); 329280297Sjkim if (!priv_key) 330280297Sjkim return 0; 331280297Sjkim ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); 332280297Sjkim ASN1_INTEGER_free(priv_key); 333280297Sjkim if (!ret) { 334280297Sjkim GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); 335280297Sjkim return 0; 336280297Sjkim } 337280297Sjkim } 338238384Sjkim 339280297Sjkim ret = gost_set_priv_key(pk, pk_num); 340280297Sjkim BN_free(pk_num); 341280297Sjkim return ret; 342280297Sjkim} 343238384Sjkim 344238384Sjkim/* ----------------------------------------------------------------------*/ 345238384Sjkimstatic int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) 346280297Sjkim{ 347280297Sjkim ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 348280297Sjkim ASN1_STRING *params = encode_gost_algor_params(pk); 349280297Sjkim unsigned char *priv_buf = NULL; 350280297Sjkim int priv_len; 351238384Sjkim 352280297Sjkim ASN1_INTEGER *asn1key = NULL; 353280297Sjkim if (!params) { 354280297Sjkim return 0; 355280297Sjkim } 356280297Sjkim asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL); 357280297Sjkim priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); 358280297Sjkim ASN1_INTEGER_free(asn1key); 359280297Sjkim return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, 360280297Sjkim priv_buf, priv_len); 361280297Sjkim} 362280297Sjkim 363238384Sjkim/* --------- printing keys --------------------------------*/ 364238384Sjkimstatic int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, 365280297Sjkim ASN1_PCTX *pctx, int type) 366280297Sjkim{ 367280297Sjkim int param_nid = NID_undef; 368238384Sjkim 369280297Sjkim if (type == 2) { 370280297Sjkim BIGNUM *key; 371238384Sjkim 372280297Sjkim if (!BIO_indent(out, indent, 128)) 373280297Sjkim return 0; 374280297Sjkim BIO_printf(out, "Private key: "); 375280297Sjkim key = gost_get0_priv_key(pkey); 376280297Sjkim if (!key) 377280297Sjkim BIO_printf(out, "<undefined>"); 378280297Sjkim else 379280297Sjkim BN_print(out, key); 380280297Sjkim BIO_printf(out, "\n"); 381280297Sjkim } 382280297Sjkim if (type >= 1) { 383280297Sjkim BIGNUM *pubkey; 384238384Sjkim 385280297Sjkim pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; 386280297Sjkim BIO_indent(out, indent, 128); 387280297Sjkim BIO_printf(out, "Public key: "); 388280297Sjkim BN_print(out, pubkey); 389280297Sjkim BIO_printf(out, "\n"); 390280297Sjkim } 391280297Sjkim 392280297Sjkim param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 393280297Sjkim BIO_indent(out, indent, 128); 394280297Sjkim BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 395280297Sjkim return 1; 396238384Sjkim} 397238384Sjkim 398238384Sjkimstatic int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 399280297Sjkim ASN1_PCTX *pctx) 400280297Sjkim{ 401280297Sjkim return print_gost_94(out, pkey, indent, pctx, 0); 402280297Sjkim} 403238384Sjkim 404238384Sjkimstatic int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 405280297Sjkim ASN1_PCTX *pctx) 406280297Sjkim{ 407280297Sjkim return print_gost_94(out, pkey, indent, pctx, 1); 408280297Sjkim} 409238384Sjkim 410280297Sjkimstatic int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 411280297Sjkim ASN1_PCTX *pctx) 412280297Sjkim{ 413280297Sjkim return print_gost_94(out, pkey, indent, pctx, 2); 414280297Sjkim} 415280297Sjkim 416238384Sjkimstatic int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, 417280297Sjkim ASN1_PCTX *pctx, int type) 418280297Sjkim{ 419280297Sjkim int param_nid = NID_undef; 420280297Sjkim if (type == 2) { 421280297Sjkim BIGNUM *key; 422238384Sjkim 423280297Sjkim if (!BIO_indent(out, indent, 128)) 424280297Sjkim return 0; 425280297Sjkim BIO_printf(out, "Private key: "); 426280297Sjkim key = gost_get0_priv_key(pkey); 427280297Sjkim if (!key) 428280297Sjkim BIO_printf(out, "<undefined)"); 429280297Sjkim else 430280297Sjkim BN_print(out, key); 431280297Sjkim BIO_printf(out, "\n"); 432280297Sjkim } 433280297Sjkim if (type >= 1) { 434280297Sjkim BN_CTX *ctx = BN_CTX_new(); 435280297Sjkim BIGNUM *X, *Y; 436280297Sjkim const EC_POINT *pubkey; 437280297Sjkim const EC_GROUP *group; 438238384Sjkim 439280297Sjkim if (!ctx) { 440280297Sjkim GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE); 441280297Sjkim return 0; 442280297Sjkim } 443280297Sjkim BN_CTX_start(ctx); 444280297Sjkim X = BN_CTX_get(ctx); 445280297Sjkim Y = BN_CTX_get(ctx); 446280297Sjkim pubkey = 447280297Sjkim EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 448280297Sjkim group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 449280297Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { 450280297Sjkim GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB); 451280297Sjkim BN_CTX_free(ctx); 452280297Sjkim return 0; 453280297Sjkim } 454280297Sjkim if (!BIO_indent(out, indent, 128)) 455280297Sjkim return 0; 456280297Sjkim BIO_printf(out, "Public key:\n"); 457280297Sjkim if (!BIO_indent(out, indent + 3, 128)) 458280297Sjkim return 0; 459280297Sjkim BIO_printf(out, "X:"); 460280297Sjkim BN_print(out, X); 461280297Sjkim BIO_printf(out, "\n"); 462280297Sjkim BIO_indent(out, indent + 3, 128); 463280297Sjkim BIO_printf(out, "Y:"); 464280297Sjkim BN_print(out, Y); 465280297Sjkim BIO_printf(out, "\n"); 466280297Sjkim BN_CTX_end(ctx); 467280297Sjkim BN_CTX_free(ctx); 468280297Sjkim } 469238384Sjkim 470280297Sjkim param_nid = 471280297Sjkim EC_GROUP_get_curve_name(EC_KEY_get0_group 472280297Sjkim (EVP_PKEY_get0((EVP_PKEY *)pkey))); 473280297Sjkim if (!BIO_indent(out, indent, 128)) 474280297Sjkim return 0; 475280297Sjkim BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 476280297Sjkim return 1; 477238384Sjkim} 478280297Sjkim 479238384Sjkimstatic int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 480280297Sjkim ASN1_PCTX *pctx) 481280297Sjkim{ 482280297Sjkim return print_gost_01(out, pkey, indent, pctx, 0); 483280297Sjkim} 484280297Sjkim 485238384Sjkimstatic int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 486280297Sjkim ASN1_PCTX *pctx) 487280297Sjkim{ 488280297Sjkim return print_gost_01(out, pkey, indent, pctx, 1); 489280297Sjkim} 490280297Sjkim 491280297Sjkimstatic int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 492280297Sjkim ASN1_PCTX *pctx) 493280297Sjkim{ 494280297Sjkim return print_gost_01(out, pkey, indent, pctx, 2); 495280297Sjkim} 496280297Sjkim 497238384Sjkim/* ---------------------------------------------------------------------*/ 498280297Sjkimstatic int param_missing_gost94(const EVP_PKEY *pk) 499280297Sjkim{ 500280297Sjkim const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 501280297Sjkim if (!dsa) 502280297Sjkim return 1; 503280297Sjkim if (!dsa->q) 504280297Sjkim return 1; 505280297Sjkim return 0; 506280297Sjkim} 507238384Sjkim 508280297Sjkimstatic int param_missing_gost01(const EVP_PKEY *pk) 509280297Sjkim{ 510280297Sjkim const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 511280297Sjkim if (!ec) 512280297Sjkim return 1; 513280297Sjkim if (!EC_KEY_get0_group(ec)) 514280297Sjkim return 1; 515280297Sjkim return 0; 516280297Sjkim} 517238384Sjkim 518280297Sjkimstatic int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) 519280297Sjkim{ 520280297Sjkim const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from); 521280297Sjkim DSA *dto = EVP_PKEY_get0(to); 522280297Sjkim if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 523280297Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS); 524280297Sjkim return 0; 525280297Sjkim } 526280297Sjkim if (!dfrom) { 527280297Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING); 528280297Sjkim return 0; 529280297Sjkim } 530280297Sjkim if (!dto) { 531280297Sjkim dto = DSA_new(); 532280297Sjkim EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto); 533280297Sjkim } 534280297Sjkim#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x); 535280297Sjkim COPYBIGNUM(dto, dfrom, p) 536280297Sjkim COPYBIGNUM(dto, dfrom, q) 537280297Sjkim COPYBIGNUM(dto, dfrom, g) 538238384Sjkim 539280297Sjkim if (dto->priv_key) 540280297Sjkim gost94_compute_public(dto); 541280297Sjkim return 1; 542280297Sjkim} 543238384Sjkim 544280297Sjkimstatic int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 545280297Sjkim{ 546280297Sjkim EC_KEY *eto = EVP_PKEY_get0(to); 547280297Sjkim const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); 548280297Sjkim if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 549280297Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS); 550280297Sjkim return 0; 551280297Sjkim } 552280297Sjkim if (!efrom) { 553280297Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); 554280297Sjkim return 0; 555280297Sjkim } 556280297Sjkim if (!eto) { 557280297Sjkim eto = EC_KEY_new(); 558284283Sjkim if(!eto) { 559284283Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE); 560284283Sjkim return 0; 561284283Sjkim } 562284283Sjkim if(!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) { 563284283Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); 564284283Sjkim return 0; 565284283Sjkim } 566280297Sjkim } 567284283Sjkim if(!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) { 568284283Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); 569284283Sjkim return 0; 570284283Sjkim } 571280297Sjkim if (EC_KEY_get0_private_key(eto)) { 572280297Sjkim gost2001_compute_public(eto); 573280297Sjkim } 574280297Sjkim return 1; 575280297Sjkim} 576238384Sjkim 577280297Sjkimstatic int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 578280297Sjkim{ 579280297Sjkim const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 580280297Sjkim const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 581280297Sjkim if (!BN_cmp(da->q, db->q)) 582280297Sjkim return 1; 583280297Sjkim return 0; 584280297Sjkim} 585238384Sjkim 586280297Sjkimstatic int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 587280297Sjkim{ 588280297Sjkim if (EC_GROUP_get_curve_name 589280297Sjkim (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) == 590280297Sjkim EC_GROUP_get_curve_name(EC_KEY_get0_group 591280297Sjkim (EVP_PKEY_get0((EVP_PKEY *)b)))) { 592280297Sjkim return 1; 593280297Sjkim } 594280297Sjkim return 0; 595238384Sjkim 596280297Sjkim} 597280297Sjkim 598238384Sjkim/* ---------- Public key functions * --------------------------------------*/ 599238384Sjkimstatic int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) 600280297Sjkim{ 601280297Sjkim X509_ALGOR *palg = NULL; 602280297Sjkim const unsigned char *pubkey_buf = NULL; 603280297Sjkim unsigned char *databuf; 604280297Sjkim ASN1_OBJECT *palgobj = NULL; 605280297Sjkim int pub_len, i, j; 606280297Sjkim DSA *dsa; 607280297Sjkim ASN1_OCTET_STRING *octet = NULL; 608238384Sjkim 609280297Sjkim if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) 610280297Sjkim return 0; 611280297Sjkim EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); 612280297Sjkim if (!decode_gost_algor_params(pk, palg)) 613280297Sjkim return 0; 614280297Sjkim octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 615280297Sjkim if (!octet) { 616280297Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); 617280297Sjkim return 0; 618280297Sjkim } 619280297Sjkim databuf = OPENSSL_malloc(octet->length); 620306195Sjkim if (databuf == NULL) { 621306195Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); 622306195Sjkim return 0; 623306195Sjkim } 624280297Sjkim for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { 625280297Sjkim databuf[j] = octet->data[i]; 626280297Sjkim } 627280297Sjkim dsa = EVP_PKEY_get0(pk); 628280297Sjkim dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL); 629280297Sjkim ASN1_OCTET_STRING_free(octet); 630280297Sjkim OPENSSL_free(databuf); 631280297Sjkim return 1; 632238384Sjkim 633280297Sjkim} 634238384Sjkim 635280297Sjkimstatic int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk) 636280297Sjkim{ 637280297Sjkim ASN1_OBJECT *algobj = NULL; 638280297Sjkim ASN1_OCTET_STRING *octet = NULL; 639280297Sjkim void *pval = NULL; 640280297Sjkim unsigned char *buf = NULL, *databuf, *sptr; 641280297Sjkim int i, j, data_len, ret = 0; 642238384Sjkim 643280297Sjkim int ptype = V_ASN1_UNDEF; 644280297Sjkim DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 645280297Sjkim algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 646280297Sjkim if (pk->save_parameters) { 647280297Sjkim ASN1_STRING *params = encode_gost_algor_params(pk); 648280297Sjkim pval = params; 649280297Sjkim ptype = V_ASN1_SEQUENCE; 650280297Sjkim } 651280297Sjkim data_len = BN_num_bytes(dsa->pub_key); 652280297Sjkim databuf = OPENSSL_malloc(data_len); 653306195Sjkim if (databuf == NULL) 654306195Sjkim return 0; 655280297Sjkim BN_bn2bin(dsa->pub_key, databuf); 656280297Sjkim octet = ASN1_OCTET_STRING_new(); 657280297Sjkim ASN1_STRING_set(octet, NULL, data_len); 658280297Sjkim sptr = ASN1_STRING_data(octet); 659280297Sjkim for (i = 0, j = data_len - 1; i < data_len; i++, j--) { 660280297Sjkim sptr[i] = databuf[j]; 661280297Sjkim } 662280297Sjkim OPENSSL_free(databuf); 663280297Sjkim ret = i2d_ASN1_OCTET_STRING(octet, &buf); 664280297Sjkim ASN1_BIT_STRING_free(octet); 665280297Sjkim if (ret < 0) 666280297Sjkim return 0; 667280297Sjkim return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 668280297Sjkim} 669238384Sjkim 670280297Sjkimstatic int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) 671280297Sjkim{ 672280297Sjkim X509_ALGOR *palg = NULL; 673280297Sjkim const unsigned char *pubkey_buf = NULL; 674280297Sjkim unsigned char *databuf; 675280297Sjkim ASN1_OBJECT *palgobj = NULL; 676280297Sjkim int pub_len, i, j; 677280297Sjkim EC_POINT *pub_key; 678280297Sjkim BIGNUM *X, *Y; 679280297Sjkim ASN1_OCTET_STRING *octet = NULL; 680280297Sjkim int len; 681280297Sjkim const EC_GROUP *group; 682238384Sjkim 683280297Sjkim if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) 684280297Sjkim return 0; 685280297Sjkim EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); 686280297Sjkim if (!decode_gost_algor_params(pk, palg)) 687280297Sjkim return 0; 688280297Sjkim group = EC_KEY_get0_group(EVP_PKEY_get0(pk)); 689280297Sjkim octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 690280297Sjkim if (!octet) { 691280297Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); 692280297Sjkim return 0; 693280297Sjkim } 694280297Sjkim databuf = OPENSSL_malloc(octet->length); 695306195Sjkim if (databuf == NULL) { 696306195Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); 697306195Sjkim return 0; 698306195Sjkim } 699280297Sjkim for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { 700280297Sjkim databuf[j] = octet->data[i]; 701280297Sjkim } 702280297Sjkim len = octet->length / 2; 703280297Sjkim ASN1_OCTET_STRING_free(octet); 704238384Sjkim 705280297Sjkim Y = getbnfrombuf(databuf, len); 706280297Sjkim X = getbnfrombuf(databuf + len, len); 707280297Sjkim OPENSSL_free(databuf); 708280297Sjkim pub_key = EC_POINT_new(group); 709280297Sjkim if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) { 710280297Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 711280297Sjkim EC_POINT_free(pub_key); 712280297Sjkim BN_free(X); 713280297Sjkim BN_free(Y); 714280297Sjkim return 0; 715280297Sjkim } 716280297Sjkim BN_free(X); 717280297Sjkim BN_free(Y); 718280297Sjkim if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) { 719280297Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 720280297Sjkim EC_POINT_free(pub_key); 721280297Sjkim return 0; 722280297Sjkim } 723280297Sjkim EC_POINT_free(pub_key); 724280297Sjkim return 1; 725238384Sjkim 726280297Sjkim} 727238384Sjkim 728280297Sjkimstatic int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) 729280297Sjkim{ 730280297Sjkim ASN1_OBJECT *algobj = NULL; 731280297Sjkim ASN1_OCTET_STRING *octet = NULL; 732280297Sjkim void *pval = NULL; 733280297Sjkim unsigned char *buf = NULL, *databuf, *sptr; 734280297Sjkim int i, j, data_len, ret = 0; 735280297Sjkim const EC_POINT *pub_key; 736280297Sjkim BIGNUM *X, *Y, *order; 737280297Sjkim const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 738280297Sjkim int ptype = V_ASN1_UNDEF; 739238384Sjkim 740280297Sjkim algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 741280297Sjkim if (pk->save_parameters) { 742280297Sjkim ASN1_STRING *params = encode_gost_algor_params(pk); 743280297Sjkim pval = params; 744280297Sjkim ptype = V_ASN1_SEQUENCE; 745280297Sjkim } 746280297Sjkim order = BN_new(); 747280297Sjkim EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL); 748280297Sjkim pub_key = EC_KEY_get0_public_key(ec); 749280297Sjkim if (!pub_key) { 750280297Sjkim GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); 751280297Sjkim return 0; 752280297Sjkim } 753280297Sjkim X = BN_new(); 754280297Sjkim Y = BN_new(); 755284283Sjkim if(!X || !Y) { 756284283Sjkim GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); 757284283Sjkim if(X) BN_free(X); 758284283Sjkim if(Y) BN_free(Y); 759284283Sjkim BN_free(order); 760284283Sjkim return 0; 761284283Sjkim } 762284283Sjkim if(!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), 763284283Sjkim pub_key, X, Y, NULL)) { 764284283Sjkim GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); 765284283Sjkim BN_free(X); 766284283Sjkim BN_free(Y); 767284283Sjkim BN_free(order); 768284283Sjkim return 0; 769284283Sjkim } 770280297Sjkim data_len = 2 * BN_num_bytes(order); 771280297Sjkim BN_free(order); 772280297Sjkim databuf = OPENSSL_malloc(data_len); 773306195Sjkim if (databuf == NULL) { 774306195Sjkim GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); 775306195Sjkim return 0; 776306195Sjkim } 777280297Sjkim memset(databuf, 0, data_len); 778280297Sjkim 779280297Sjkim store_bignum(X, databuf + data_len / 2, data_len / 2); 780280297Sjkim store_bignum(Y, databuf, data_len / 2); 781280297Sjkim 782280297Sjkim BN_free(X); 783280297Sjkim BN_free(Y); 784280297Sjkim octet = ASN1_OCTET_STRING_new(); 785280297Sjkim ASN1_STRING_set(octet, NULL, data_len); 786280297Sjkim sptr = ASN1_STRING_data(octet); 787280297Sjkim for (i = 0, j = data_len - 1; i < data_len; i++, j--) { 788280297Sjkim sptr[i] = databuf[j]; 789280297Sjkim } 790238384Sjkim OPENSSL_free(databuf); 791280297Sjkim ret = i2d_ASN1_OCTET_STRING(octet, &buf); 792280297Sjkim ASN1_BIT_STRING_free(octet); 793280297Sjkim if (ret < 0) 794280297Sjkim return 0; 795280297Sjkim return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 796280297Sjkim} 797238384Sjkim 798238384Sjkimstatic int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 799280297Sjkim{ 800280297Sjkim const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 801280297Sjkim const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 802280297Sjkim if (da && db && da->pub_key && db->pub_key 803280297Sjkim && !BN_cmp(da->pub_key, db->pub_key)) { 804280297Sjkim return 1; 805280297Sjkim } 806280297Sjkim return 0; 807280297Sjkim} 808238384Sjkim 809280297Sjkimstatic int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 810280297Sjkim{ 811280297Sjkim const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a); 812280297Sjkim const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b); 813280297Sjkim const EC_POINT *ka, *kb; 814280297Sjkim int ret = 0; 815280297Sjkim if (!ea || !eb) 816280297Sjkim return 0; 817280297Sjkim ka = EC_KEY_get0_public_key(ea); 818280297Sjkim kb = EC_KEY_get0_public_key(eb); 819280297Sjkim if (!ka || !kb) 820280297Sjkim return 0; 821280297Sjkim ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL)); 822280297Sjkim return ret; 823280297Sjkim} 824238384Sjkim 825238384Sjkimstatic int pkey_size_gost(const EVP_PKEY *pk) 826280297Sjkim{ 827280297Sjkim return 64; 828280297Sjkim} 829238384Sjkim 830238384Sjkimstatic int pkey_bits_gost(const EVP_PKEY *pk) 831238384Sjkim{ 832280297Sjkim return 256; 833280297Sjkim} 834238384Sjkim 835280297Sjkim/* ---------------------- ASN1 METHOD for GOST MAC -------------------*/ 836280297Sjkimstatic void mackey_free_gost(EVP_PKEY *pk) 837238384Sjkim{ 838280297Sjkim if (pk->pkey.ptr) { 839280297Sjkim OPENSSL_free(pk->pkey.ptr); 840280297Sjkim } 841238384Sjkim} 842280297Sjkim 843280297Sjkimstatic int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 844238384Sjkim{ 845280297Sjkim switch (op) { 846280297Sjkim case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 847280297Sjkim *(int *)arg2 = NID_id_Gost28147_89_MAC; 848280297Sjkim return 2; 849280297Sjkim } 850280297Sjkim return -2; 851238384Sjkim} 852238384Sjkim 853280297Sjkimstatic int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 854238384Sjkim{ 855280297Sjkim int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 856280297Sjkim return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); 857280297Sjkim} 858238384Sjkim 859280297Sjkimstatic int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 860280297Sjkim{ 861280297Sjkim int nid = 862280297Sjkim EC_GROUP_get_curve_name(EC_KEY_get0_group 863280297Sjkim (EVP_PKEY_get0((EVP_PKEY *)pkey))); 864280297Sjkim return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); 865280297Sjkim} 866238384Sjkim 867280297Sjkimstatic int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, 868280297Sjkim int derlen) 869280297Sjkim{ 870280297Sjkim ASN1_OBJECT *obj = NULL; 871280297Sjkim DSA *dsa = EVP_PKEY_get0(pkey); 872280297Sjkim int nid; 873280297Sjkim if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 874280297Sjkim return 0; 875280297Sjkim } 876280297Sjkim nid = OBJ_obj2nid(obj); 877280297Sjkim ASN1_OBJECT_free(obj); 878280297Sjkim if (!dsa) { 879280297Sjkim dsa = DSA_new(); 880280297Sjkim if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa)) 881280297Sjkim return 0; 882280297Sjkim } 883280297Sjkim if (!fill_GOST94_params(dsa, nid)) 884280297Sjkim return 0; 885280297Sjkim return 1; 886280297Sjkim} 887238384Sjkim 888280297Sjkimstatic int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, 889280297Sjkim int derlen) 890280297Sjkim{ 891280297Sjkim ASN1_OBJECT *obj = NULL; 892280297Sjkim int nid; 893280297Sjkim EC_KEY *ec = EVP_PKEY_get0(pkey); 894280297Sjkim if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 895280297Sjkim return 0; 896280297Sjkim } 897280297Sjkim nid = OBJ_obj2nid(obj); 898280297Sjkim ASN1_OBJECT_free(obj); 899280297Sjkim if (!ec) { 900280297Sjkim ec = EC_KEY_new(); 901280297Sjkim if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) 902280297Sjkim return 0; 903280297Sjkim } 904280297Sjkim if (!fill_GOST2001_params(ec, nid)) 905280297Sjkim return 0; 906280297Sjkim return 1; 907280297Sjkim} 908238384Sjkim 909280297Sjkim/* ----------------------------------------------------------------------*/ 910280297Sjkimint register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, 911280297Sjkim const char *pemstr, const char *info) 912280297Sjkim{ 913280297Sjkim *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info); 914280297Sjkim if (!*ameth) 915280297Sjkim return 0; 916280297Sjkim switch (nid) { 917280297Sjkim case NID_id_GostR3410_94: 918280297Sjkim EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94); 919280297Sjkim EVP_PKEY_asn1_set_private(*ameth, 920280297Sjkim priv_decode_gost, priv_encode_gost, 921280297Sjkim priv_print_gost94); 922238384Sjkim 923280297Sjkim EVP_PKEY_asn1_set_param(*ameth, 924280297Sjkim gost94_param_decode, gost94_param_encode, 925280297Sjkim param_missing_gost94, param_copy_gost94, 926280297Sjkim param_cmp_gost94, param_print_gost94); 927280297Sjkim EVP_PKEY_asn1_set_public(*ameth, 928280297Sjkim pub_decode_gost94, pub_encode_gost94, 929280297Sjkim pub_cmp_gost94, pub_print_gost94, 930280297Sjkim pkey_size_gost, pkey_bits_gost); 931238384Sjkim 932280297Sjkim EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); 933280297Sjkim break; 934280297Sjkim case NID_id_GostR3410_2001: 935280297Sjkim EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01); 936280297Sjkim EVP_PKEY_asn1_set_private(*ameth, 937280297Sjkim priv_decode_gost, priv_encode_gost, 938280297Sjkim priv_print_gost01); 939238384Sjkim 940280297Sjkim EVP_PKEY_asn1_set_param(*ameth, 941280297Sjkim gost2001_param_decode, gost2001_param_encode, 942280297Sjkim param_missing_gost01, param_copy_gost01, 943280297Sjkim param_cmp_gost01, param_print_gost01); 944280297Sjkim EVP_PKEY_asn1_set_public(*ameth, 945280297Sjkim pub_decode_gost01, pub_encode_gost01, 946280297Sjkim pub_cmp_gost01, pub_print_gost01, 947280297Sjkim pkey_size_gost, pkey_bits_gost); 948238384Sjkim 949280297Sjkim EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); 950280297Sjkim break; 951280297Sjkim case NID_id_Gost28147_89_MAC: 952280297Sjkim EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); 953280297Sjkim EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost); 954280297Sjkim break; 955280297Sjkim } 956280297Sjkim return 1; 957280297Sjkim} 958