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 17238384Sjkim#include <openssl/cms.h> 18238384Sjkim#endif 19238384Sjkim#include "gost_params.h" 20238384Sjkim#include "gost_lcl.h" 21238384Sjkim#include "e_gost_err.h" 22238384Sjkim 23238384Sjkimint gost94_nid_by_params(DSA *p) 24238384Sjkim { 25238384Sjkim R3410_params *gost_params; 26238384Sjkim BIGNUM *q=BN_new(); 27238384Sjkim for (gost_params = R3410_paramset;gost_params->q!=NULL; gost_params++) 28238384Sjkim { 29238384Sjkim BN_dec2bn(&q,gost_params->q); 30238384Sjkim if (!BN_cmp(q,p->q)) 31238384Sjkim { 32238384Sjkim BN_free(q); 33238384Sjkim return gost_params->nid; 34238384Sjkim } 35238384Sjkim } 36238384Sjkim BN_free(q); 37238384Sjkim return NID_undef; 38238384Sjkim } 39238384Sjkim 40238384Sjkimstatic ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) 41238384Sjkim { 42238384Sjkim ASN1_STRING *params = ASN1_STRING_new(); 43238384Sjkim GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); 44238384Sjkim int pkey_param_nid = NID_undef; 45238384Sjkim 46238384Sjkim if (!params || !gkp) 47238384Sjkim { 48238384Sjkim GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, 49238384Sjkim ERR_R_MALLOC_FAILURE); 50238384Sjkim ASN1_STRING_free(params); 51238384Sjkim params = NULL; 52238384Sjkim goto err; 53238384Sjkim } 54238384Sjkim switch (EVP_PKEY_base_id(key)) 55238384Sjkim { 56238384Sjkim case NID_id_GostR3410_2001: 57238384Sjkim pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)key))); 58238384Sjkim break; 59238384Sjkim case NID_id_GostR3410_94: 60238384Sjkim pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); 61238384Sjkim if (pkey_param_nid == NID_undef) 62238384Sjkim { 63238384Sjkim GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, 64238384Sjkim GOST_R_INVALID_GOST94_PARMSET); 65238384Sjkim ASN1_STRING_free(params); 66238384Sjkim params=NULL; 67238384Sjkim goto err; 68238384Sjkim } 69238384Sjkim break; 70238384Sjkim } 71238384Sjkim gkp->key_params = OBJ_nid2obj(pkey_param_nid); 72238384Sjkim gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); 73238384Sjkim /*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);*/ 74238384Sjkim params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); 75238384Sjkim if (params->length <=0 ) 76238384Sjkim { 77238384Sjkim GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, 78238384Sjkim ERR_R_MALLOC_FAILURE); 79238384Sjkim ASN1_STRING_free(params); 80238384Sjkim params = NULL; 81238384Sjkim goto err; 82238384Sjkim } 83238384Sjkim params ->type = V_ASN1_SEQUENCE; 84238384Sjkim err: 85238384Sjkim GOST_KEY_PARAMS_free(gkp); 86238384Sjkim return params; 87238384Sjkim } 88238384Sjkim 89238384Sjkim/* Parses GOST algorithm parameters from X509_ALGOR and 90238384Sjkim * modifies pkey setting NID and parameters 91238384Sjkim */ 92238384Sjkimstatic int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) 93238384Sjkim { 94238384Sjkim ASN1_OBJECT *palg_obj =NULL; 95238384Sjkim int ptype = V_ASN1_UNDEF; 96238384Sjkim int pkey_nid = NID_undef,param_nid = NID_undef; 97238384Sjkim void *_pval; 98238384Sjkim ASN1_STRING *pval = NULL; 99238384Sjkim const unsigned char *p; 100238384Sjkim GOST_KEY_PARAMS *gkp = NULL; 101238384Sjkim 102238384Sjkim X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); 103238384Sjkim pval = _pval; 104238384Sjkim if (ptype != V_ASN1_SEQUENCE) 105238384Sjkim { 106238384Sjkim GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 107238384Sjkim GOST_R_BAD_KEY_PARAMETERS_FORMAT); 108238384Sjkim return 0; 109238384Sjkim } 110238384Sjkim p=pval->data; 111238384Sjkim pkey_nid = OBJ_obj2nid(palg_obj); 112238384Sjkim 113238384Sjkim gkp = d2i_GOST_KEY_PARAMS(NULL,&p,pval->length); 114238384Sjkim if (!gkp) 115238384Sjkim { 116238384Sjkim GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 117238384Sjkim GOST_R_BAD_PKEY_PARAMETERS_FORMAT); 118238384Sjkim return 0; 119238384Sjkim } 120238384Sjkim param_nid = OBJ_obj2nid(gkp->key_params); 121238384Sjkim GOST_KEY_PARAMS_free(gkp); 122238384Sjkim EVP_PKEY_set_type(pkey,pkey_nid); 123238384Sjkim switch (pkey_nid) 124238384Sjkim { 125238384Sjkim case NID_id_GostR3410_94: 126238384Sjkim { 127238384Sjkim DSA *dsa= EVP_PKEY_get0(pkey); 128238384Sjkim if (!dsa) 129238384Sjkim { 130238384Sjkim dsa = DSA_new(); 131238384Sjkim if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0; 132238384Sjkim } 133238384Sjkim if (!fill_GOST94_params(dsa,param_nid)) return 0; 134238384Sjkim break; 135238384Sjkim } 136238384Sjkim case NID_id_GostR3410_2001: 137238384Sjkim { 138238384Sjkim EC_KEY *ec = EVP_PKEY_get0(pkey); 139238384Sjkim if (!ec) 140238384Sjkim { 141238384Sjkim ec = EC_KEY_new(); 142238384Sjkim if (!EVP_PKEY_assign(pkey,pkey_nid,ec)) return 0; 143238384Sjkim } 144238384Sjkim if (!fill_GOST2001_params(ec,param_nid)) return 0; 145238384Sjkim } 146238384Sjkim } 147238384Sjkim 148238384Sjkim return 1; 149238384Sjkim } 150238384Sjkim 151238384Sjkimstatic int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) 152238384Sjkim { 153238384Sjkim switch (EVP_PKEY_base_id(pkey)) 154238384Sjkim { 155238384Sjkim case NID_id_GostR3410_94: 156238384Sjkim { 157238384Sjkim DSA *dsa = EVP_PKEY_get0(pkey); 158238384Sjkim if (!dsa) 159238384Sjkim { 160238384Sjkim dsa = DSA_new(); 161238384Sjkim EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa); 162238384Sjkim } 163238384Sjkim dsa->priv_key = BN_dup(priv); 164238384Sjkim if (!EVP_PKEY_missing_parameters(pkey)) 165238384Sjkim gost94_compute_public(dsa); 166238384Sjkim break; 167238384Sjkim } 168238384Sjkim case NID_id_GostR3410_2001: 169238384Sjkim { 170238384Sjkim EC_KEY *ec = EVP_PKEY_get0(pkey); 171238384Sjkim if (!ec) 172238384Sjkim { 173238384Sjkim ec = EC_KEY_new(); 174238384Sjkim EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec); 175238384Sjkim } 176238384Sjkim if (!EC_KEY_set_private_key(ec,priv)) return 0; 177238384Sjkim if (!EVP_PKEY_missing_parameters(pkey)) 178238384Sjkim gost2001_compute_public(ec); 179238384Sjkim break; 180238384Sjkim } 181238384Sjkim } 182238384Sjkim return 1; 183238384Sjkim } 184238384SjkimBIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) 185238384Sjkim { 186238384Sjkim switch (EVP_PKEY_base_id(pkey)) 187238384Sjkim { 188238384Sjkim case NID_id_GostR3410_94: 189238384Sjkim { 190238384Sjkim DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); 191238384Sjkim if (!dsa) 192238384Sjkim { 193238384Sjkim return NULL; 194238384Sjkim } 195238384Sjkim if (!dsa->priv_key) return NULL; 196238384Sjkim return dsa->priv_key; 197238384Sjkim break; 198238384Sjkim } 199238384Sjkim case NID_id_GostR3410_2001: 200238384Sjkim { 201238384Sjkim EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); 202238384Sjkim const BIGNUM* priv; 203238384Sjkim if (!ec) 204238384Sjkim { 205238384Sjkim return NULL; 206238384Sjkim } 207238384Sjkim if (!(priv=EC_KEY_get0_private_key(ec))) return NULL; 208238384Sjkim return (BIGNUM *)priv; 209238384Sjkim break; 210238384Sjkim } 211238384Sjkim } 212238384Sjkim return NULL; 213238384Sjkim } 214238384Sjkim 215238384Sjkimstatic int pkey_ctrl_gost(EVP_PKEY *pkey, int op, 216238384Sjkim long arg1, void *arg2) 217238384Sjkim { 218238384Sjkim switch (op) 219238384Sjkim { 220238384Sjkim case ASN1_PKEY_CTRL_PKCS7_SIGN: 221238384Sjkim if (arg1 == 0) 222238384Sjkim { 223238384Sjkim X509_ALGOR *alg1 = NULL, *alg2 = NULL; 224238384Sjkim int nid = EVP_PKEY_base_id(pkey); 225238384Sjkim PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO*)arg2, 226238384Sjkim NULL, &alg1, &alg2); 227238384Sjkim X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 228238384Sjkim V_ASN1_NULL, 0); 229238384Sjkim if (nid == NID_undef) 230238384Sjkim { 231238384Sjkim return (-1); 232238384Sjkim } 233238384Sjkim X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 234238384Sjkim } 235238384Sjkim return 1; 236238384Sjkim#ifndef OPENSSL_NO_CMS 237238384Sjkim case ASN1_PKEY_CTRL_CMS_SIGN: 238238384Sjkim if (arg1 == 0) 239238384Sjkim { 240238384Sjkim X509_ALGOR *alg1 = NULL, *alg2 = NULL; 241238384Sjkim int nid = EVP_PKEY_base_id(pkey); 242238384Sjkim CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, 243238384Sjkim NULL, NULL, &alg1, &alg2); 244238384Sjkim X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 245238384Sjkim V_ASN1_NULL, 0); 246238384Sjkim if (nid == NID_undef) 247238384Sjkim { 248238384Sjkim return (-1); 249238384Sjkim } 250238384Sjkim X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 251238384Sjkim } 252238384Sjkim return 1; 253238384Sjkim#endif 254238384Sjkim case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: 255238384Sjkim if (arg1 == 0) 256238384Sjkim { 257238384Sjkim X509_ALGOR *alg; 258238384Sjkim ASN1_STRING * params = encode_gost_algor_params(pkey); 259238384Sjkim if (!params) 260238384Sjkim { 261238384Sjkim return -1; 262238384Sjkim } 263238384Sjkim PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO*)arg2, &alg); 264238384Sjkim X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), 265238384Sjkim V_ASN1_SEQUENCE, params); 266238384Sjkim } 267238384Sjkim return 1; 268238384Sjkim#ifndef OPENSSL_NO_CMS 269238384Sjkim case ASN1_PKEY_CTRL_CMS_ENVELOPE: 270238384Sjkim if (arg1 == 0) 271238384Sjkim { 272279264Sdelphij X509_ALGOR *alg = NULL; 273238384Sjkim ASN1_STRING * params = encode_gost_algor_params(pkey); 274238384Sjkim if (!params) 275238384Sjkim { 276238384Sjkim return -1; 277238384Sjkim } 278238384Sjkim CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, NULL, &alg); 279238384Sjkim X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), 280238384Sjkim V_ASN1_SEQUENCE, params); 281238384Sjkim } 282238384Sjkim return 1; 283238384Sjkim#endif 284238384Sjkim case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 285238384Sjkim *(int *)arg2 = NID_id_GostR3411_94; 286238384Sjkim return 2; 287238384Sjkim } 288238384Sjkim 289238384Sjkim return -2; 290238384Sjkim } 291238384Sjkim/*----------------------- free functions * ------------------------------*/ 292238384Sjkimstatic void pkey_free_gost94(EVP_PKEY *key) 293238384Sjkim { 294238384Sjkim if (key->pkey.dsa) 295238384Sjkim { 296238384Sjkim DSA_free(key->pkey.dsa); 297238384Sjkim } 298238384Sjkim } 299238384Sjkim 300238384Sjkimstatic void pkey_free_gost01(EVP_PKEY *key) 301238384Sjkim { 302238384Sjkim if (key->pkey.ec) 303238384Sjkim { 304238384Sjkim EC_KEY_free(key->pkey.ec); 305238384Sjkim } 306238384Sjkim } 307238384Sjkim 308238384Sjkim/* ------------------ private key functions -----------------------------*/ 309238384Sjkimstatic int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) 310238384Sjkim { 311238384Sjkim const unsigned char *pkey_buf = NULL,*p=NULL; 312238384Sjkim int priv_len = 0; 313238384Sjkim BIGNUM *pk_num=NULL; 314238384Sjkim int ret =0; 315238384Sjkim X509_ALGOR *palg =NULL; 316238384Sjkim ASN1_OBJECT *palg_obj = NULL; 317238384Sjkim ASN1_INTEGER *priv_key=NULL; 318238384Sjkim 319238384Sjkim if (!PKCS8_pkey_get0(&palg_obj,&pkey_buf,&priv_len,&palg,p8inf)) 320238384Sjkim return 0; 321238384Sjkim p = pkey_buf; 322238384Sjkim if (!decode_gost_algor_params(pk,palg)) 323238384Sjkim { 324238384Sjkim return 0; 325238384Sjkim } 326238384Sjkim if (V_ASN1_OCTET_STRING == *p) 327238384Sjkim { 328238384Sjkim /* New format - Little endian octet string */ 329238384Sjkim unsigned char rev_buf[32]; 330238384Sjkim int i; 331238384Sjkim ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL,&p,priv_len); 332238384Sjkim if (!s||s->length !=32) 333238384Sjkim { 334238384Sjkim GOSTerr(GOST_F_PRIV_DECODE_GOST, 335238384Sjkim EVP_R_DECODE_ERROR); 336238384Sjkim return 0; 337238384Sjkim } 338238384Sjkim for (i=0;i<32;i++) 339238384Sjkim { 340238384Sjkim rev_buf[31-i]=s->data[i]; 341238384Sjkim } 342238384Sjkim ASN1_STRING_free(s); 343238384Sjkim pk_num = getbnfrombuf(rev_buf,32); 344238384Sjkim } 345238384Sjkim else 346238384Sjkim { 347238384Sjkim priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len); 348238384Sjkim if (!priv_key) return 0; 349238384Sjkim ret= ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL))!=NULL) ; 350238384Sjkim ASN1_INTEGER_free(priv_key); 351238384Sjkim if (!ret) 352238384Sjkim { 353238384Sjkim GOSTerr(GOST_F_PRIV_DECODE_GOST, 354238384Sjkim EVP_R_DECODE_ERROR); 355238384Sjkim return 0; 356238384Sjkim } 357238384Sjkim } 358238384Sjkim 359238384Sjkim ret= gost_set_priv_key(pk,pk_num); 360238384Sjkim BN_free(pk_num); 361238384Sjkim return ret; 362238384Sjkim } 363238384Sjkim 364238384Sjkim/* ----------------------------------------------------------------------*/ 365238384Sjkimstatic int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) 366238384Sjkim { 367238384Sjkim ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 368238384Sjkim ASN1_STRING *params = encode_gost_algor_params(pk); 369238384Sjkim unsigned char *priv_buf = NULL; 370238384Sjkim int priv_len; 371238384Sjkim 372238384Sjkim ASN1_INTEGER *asn1key=NULL; 373238384Sjkim if (!params) 374238384Sjkim { 375238384Sjkim return 0; 376238384Sjkim } 377238384Sjkim asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk),NULL); 378238384Sjkim priv_len = i2d_ASN1_INTEGER(asn1key,&priv_buf); 379238384Sjkim ASN1_INTEGER_free(asn1key); 380238384Sjkim return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params, 381238384Sjkim priv_buf,priv_len); 382238384Sjkim } 383238384Sjkim/* --------- printing keys --------------------------------*/ 384238384Sjkimstatic int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, 385238384Sjkim ASN1_PCTX *pctx, int type) 386238384Sjkim { 387238384Sjkim int param_nid = NID_undef; 388238384Sjkim 389238384Sjkim if (type == 2) 390238384Sjkim { 391238384Sjkim BIGNUM *key; 392238384Sjkim 393238384Sjkim if (!BIO_indent(out,indent,128)) return 0; 394238384Sjkim BIO_printf(out,"Private key: "); 395238384Sjkim key = gost_get0_priv_key(pkey); 396238384Sjkim if (!key) 397238384Sjkim BIO_printf(out,"<undefined>"); 398238384Sjkim else 399238384Sjkim BN_print(out,key); 400238384Sjkim BIO_printf(out,"\n"); 401238384Sjkim } 402238384Sjkim if (type >= 1) 403238384Sjkim { 404238384Sjkim BIGNUM *pubkey; 405238384Sjkim 406238384Sjkim pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; 407238384Sjkim BIO_indent(out,indent,128); 408238384Sjkim BIO_printf(out,"Public key: "); 409238384Sjkim BN_print(out,pubkey); 410238384Sjkim BIO_printf(out,"\n"); 411238384Sjkim } 412238384Sjkim 413238384Sjkim param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 414238384Sjkim BIO_indent(out,indent,128); 415238384Sjkim BIO_printf(out, "Parameter set: %s\n",OBJ_nid2ln(param_nid)); 416238384Sjkim return 1; 417238384Sjkim} 418238384Sjkim 419238384Sjkimstatic int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 420238384Sjkim ASN1_PCTX *pctx) 421238384Sjkim { 422238384Sjkim return print_gost_94(out, pkey, indent, pctx,0); 423238384Sjkim } 424238384Sjkim 425238384Sjkimstatic int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 426238384Sjkim ASN1_PCTX *pctx) 427238384Sjkim { 428238384Sjkim return print_gost_94(out,pkey, indent, pctx,1); 429238384Sjkim } 430238384Sjkimstatic int priv_print_gost94(BIO *out,const EVP_PKEY *pkey, int indent, 431238384Sjkim ASN1_PCTX *pctx) 432238384Sjkim { 433238384Sjkim return print_gost_94(out,pkey,indent,pctx,2); 434238384Sjkim } 435238384Sjkim 436238384Sjkimstatic int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, 437238384Sjkim ASN1_PCTX *pctx, int type) 438238384Sjkim { 439238384Sjkim int param_nid = NID_undef; 440238384Sjkim if (type == 2) 441238384Sjkim { 442238384Sjkim BIGNUM *key; 443238384Sjkim 444238384Sjkim if (!BIO_indent(out,indent,128)) return 0; 445238384Sjkim BIO_printf(out,"Private key: "); 446238384Sjkim key = gost_get0_priv_key(pkey); 447238384Sjkim if (!key) 448238384Sjkim BIO_printf(out,"<undefined)"); 449238384Sjkim else 450238384Sjkim BN_print(out,key); 451238384Sjkim BIO_printf(out,"\n"); 452238384Sjkim } 453238384Sjkim if (type >= 1) 454238384Sjkim { 455238384Sjkim BN_CTX *ctx = BN_CTX_new(); 456238384Sjkim BIGNUM *X,*Y; 457238384Sjkim const EC_POINT *pubkey; 458238384Sjkim const EC_GROUP *group; 459238384Sjkim 460238384Sjkim if (!ctx) 461238384Sjkim { 462238384Sjkim GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_MALLOC_FAILURE); 463238384Sjkim return 0; 464238384Sjkim } 465238384Sjkim BN_CTX_start(ctx); 466238384Sjkim X = BN_CTX_get(ctx); 467238384Sjkim Y = BN_CTX_get(ctx); 468238384Sjkim pubkey = EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 469238384Sjkim group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 470238384Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group,pubkey,X,Y,ctx)) 471238384Sjkim { 472238384Sjkim GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_EC_LIB); 473238384Sjkim BN_CTX_free(ctx); 474238384Sjkim return 0; 475238384Sjkim } 476238384Sjkim if (!BIO_indent(out,indent,128)) return 0; 477238384Sjkim BIO_printf(out,"Public key:\n"); 478238384Sjkim if (!BIO_indent(out,indent+3,128)) return 0; 479238384Sjkim BIO_printf(out,"X:"); 480238384Sjkim BN_print(out,X); 481238384Sjkim BIO_printf(out,"\n"); 482238384Sjkim BIO_indent(out,indent+3,128); 483238384Sjkim BIO_printf(out,"Y:"); 484238384Sjkim BN_print(out,Y); 485238384Sjkim BIO_printf(out,"\n"); 486238384Sjkim BN_CTX_end(ctx); 487238384Sjkim BN_CTX_free(ctx); 488238384Sjkim } 489238384Sjkim 490238384Sjkim param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey))); 491238384Sjkim if (!BIO_indent(out,indent,128)) return 0; 492238384Sjkim BIO_printf(out,"Parameter set: %s\n",OBJ_nid2ln(param_nid)); 493238384Sjkim return 1; 494238384Sjkim} 495238384Sjkimstatic int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 496238384Sjkim ASN1_PCTX *pctx) 497238384Sjkim { 498238384Sjkim return print_gost_01(out,pkey,indent,pctx,0); 499238384Sjkim } 500238384Sjkimstatic int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 501238384Sjkim ASN1_PCTX *pctx) 502238384Sjkim { 503238384Sjkim return print_gost_01(out,pkey, indent, pctx,1); 504238384Sjkim } 505238384Sjkimstatic int priv_print_gost01(BIO *out,const EVP_PKEY *pkey, int indent, 506238384Sjkim ASN1_PCTX *pctx) 507238384Sjkim { 508238384Sjkim return print_gost_01(out,pkey,indent,pctx,2); 509238384Sjkim } 510238384Sjkim/* ---------------------------------------------------------------------*/ 511238384Sjkimstatic int param_missing_gost94(const EVP_PKEY *pk) 512238384Sjkim { 513238384Sjkim const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 514238384Sjkim if (!dsa) return 1; 515238384Sjkim if (!dsa->q) return 1; 516238384Sjkim return 0; 517238384Sjkim } 518238384Sjkim 519238384Sjkimstatic int param_missing_gost01(const EVP_PKEY *pk) 520238384Sjkim { 521238384Sjkim const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 522238384Sjkim if (!ec) return 1; 523238384Sjkim if (!EC_KEY_get0_group(ec)) return 1; 524238384Sjkim return 0; 525238384Sjkim } 526238384Sjkim 527238384Sjkimstatic int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) 528238384Sjkim { 529238384Sjkim const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from); 530238384Sjkim DSA *dto = EVP_PKEY_get0(to); 531238384Sjkim if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) 532238384Sjkim { 533238384Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST94, 534238384Sjkim GOST_R_INCOMPATIBLE_ALGORITHMS); 535238384Sjkim return 0; 536238384Sjkim } 537238384Sjkim if (!dfrom) 538238384Sjkim { 539238384Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST94, 540238384Sjkim GOST_R_KEY_PARAMETERS_MISSING); 541238384Sjkim return 0; 542238384Sjkim } 543238384Sjkim if (!dto) 544238384Sjkim { 545238384Sjkim dto = DSA_new(); 546238384Sjkim EVP_PKEY_assign(to,EVP_PKEY_base_id(from),dto); 547238384Sjkim } 548238384Sjkim#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x); 549238384Sjkim COPYBIGNUM(dto,dfrom,p) 550238384Sjkim COPYBIGNUM(dto,dfrom,q) 551238384Sjkim COPYBIGNUM(dto,dfrom,g) 552238384Sjkim 553238384Sjkim if (dto->priv_key) 554238384Sjkim gost94_compute_public(dto); 555238384Sjkim return 1; 556238384Sjkim } 557238384Sjkimstatic int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 558238384Sjkim { 559238384Sjkim EC_KEY *eto = EVP_PKEY_get0(to); 560238384Sjkim const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); 561238384Sjkim if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) 562238384Sjkim { 563238384Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, 564238384Sjkim GOST_R_INCOMPATIBLE_ALGORITHMS); 565238384Sjkim return 0; 566238384Sjkim } 567238384Sjkim if (!efrom) 568238384Sjkim { 569238384Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, 570238384Sjkim GOST_R_KEY_PARAMETERS_MISSING); 571238384Sjkim return 0; 572238384Sjkim } 573238384Sjkim if (!eto) 574238384Sjkim { 575238384Sjkim eto = EC_KEY_new(); 576238384Sjkim EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto); 577238384Sjkim } 578238384Sjkim EC_KEY_set_group(eto,EC_KEY_get0_group(efrom)); 579238384Sjkim if (EC_KEY_get0_private_key(eto)) 580238384Sjkim { 581238384Sjkim gost2001_compute_public(eto); 582238384Sjkim } 583238384Sjkim return 1; 584238384Sjkim } 585238384Sjkim 586238384Sjkimstatic int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 587238384Sjkim { 588238384Sjkim const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 589238384Sjkim const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 590238384Sjkim if (!BN_cmp(da->q,db->q)) return 1; 591238384Sjkim return 0; 592238384Sjkim } 593238384Sjkim 594238384Sjkimstatic int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 595238384Sjkim { 596238384Sjkim if (EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a)))== 597238384Sjkim EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)b)))) 598238384Sjkim { 599238384Sjkim return 1; 600238384Sjkim } 601238384Sjkim return 0; 602238384Sjkim 603238384Sjkim } 604238384Sjkim 605238384Sjkim/* ---------- Public key functions * --------------------------------------*/ 606238384Sjkimstatic int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) 607238384Sjkim { 608238384Sjkim X509_ALGOR *palg = NULL; 609238384Sjkim const unsigned char *pubkey_buf = NULL; 610238384Sjkim unsigned char *databuf; 611238384Sjkim ASN1_OBJECT *palgobj = NULL; 612238384Sjkim int pub_len,i,j; 613238384Sjkim DSA *dsa; 614238384Sjkim ASN1_OCTET_STRING *octet= NULL; 615238384Sjkim 616238384Sjkim if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len, 617238384Sjkim &palg, pub)) return 0; 618238384Sjkim EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL); 619238384Sjkim if (!decode_gost_algor_params(pk,palg)) return 0; 620238384Sjkim octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len); 621238384Sjkim if (!octet) 622238384Sjkim { 623238384Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST94,ERR_R_MALLOC_FAILURE); 624238384Sjkim return 0; 625238384Sjkim } 626238384Sjkim databuf = OPENSSL_malloc(octet->length); 627238384Sjkim for (i=0,j=octet->length-1;i<octet->length;i++,j--) 628238384Sjkim { 629238384Sjkim databuf[j]=octet->data[i]; 630238384Sjkim } 631238384Sjkim dsa = EVP_PKEY_get0(pk); 632238384Sjkim dsa->pub_key=BN_bin2bn(databuf,octet->length,NULL); 633238384Sjkim ASN1_OCTET_STRING_free(octet); 634238384Sjkim OPENSSL_free(databuf); 635238384Sjkim return 1; 636238384Sjkim 637238384Sjkim } 638238384Sjkim 639238384Sjkimstatic int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk) 640238384Sjkim { 641238384Sjkim ASN1_OBJECT *algobj = NULL; 642238384Sjkim ASN1_OCTET_STRING *octet = NULL; 643238384Sjkim void *pval = NULL; 644238384Sjkim unsigned char *buf=NULL,*databuf,*sptr; 645238384Sjkim int i,j,data_len,ret=0; 646238384Sjkim 647238384Sjkim int ptype = V_ASN1_UNDEF; 648238384Sjkim DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 649238384Sjkim algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 650238384Sjkim if (pk->save_parameters) 651238384Sjkim { 652238384Sjkim ASN1_STRING *params = encode_gost_algor_params(pk); 653238384Sjkim pval = params; 654238384Sjkim ptype = V_ASN1_SEQUENCE; 655238384Sjkim } 656238384Sjkim data_len = BN_num_bytes(dsa->pub_key); 657238384Sjkim databuf = OPENSSL_malloc(data_len); 658238384Sjkim BN_bn2bin(dsa->pub_key,databuf); 659238384Sjkim octet = ASN1_OCTET_STRING_new(); 660238384Sjkim ASN1_STRING_set(octet,NULL,data_len); 661238384Sjkim sptr = ASN1_STRING_data(octet); 662238384Sjkim for (i=0,j=data_len-1; i< data_len;i++,j--) 663238384Sjkim { 664238384Sjkim sptr[i]=databuf[j]; 665238384Sjkim } 666238384Sjkim OPENSSL_free(databuf); 667238384Sjkim ret = i2d_ASN1_OCTET_STRING(octet,&buf); 668238384Sjkim ASN1_BIT_STRING_free(octet); 669238384Sjkim if (ret <0) return 0; 670238384Sjkim return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret); 671238384Sjkim } 672238384Sjkim 673238384Sjkimstatic int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub) 674238384Sjkim { 675238384Sjkim X509_ALGOR *palg = NULL; 676238384Sjkim const unsigned char *pubkey_buf = NULL; 677238384Sjkim unsigned char *databuf; 678238384Sjkim ASN1_OBJECT *palgobj = NULL; 679238384Sjkim int pub_len,i,j; 680238384Sjkim EC_POINT *pub_key; 681238384Sjkim BIGNUM *X,*Y; 682238384Sjkim ASN1_OCTET_STRING *octet= NULL; 683238384Sjkim int len; 684238384Sjkim const EC_GROUP *group; 685238384Sjkim 686238384Sjkim if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len, 687238384Sjkim &palg, pub)) return 0; 688238384Sjkim EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL); 689238384Sjkim if (!decode_gost_algor_params(pk,palg)) return 0; 690238384Sjkim group = EC_KEY_get0_group(EVP_PKEY_get0(pk)); 691238384Sjkim octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len); 692238384Sjkim if (!octet) 693238384Sjkim { 694238384Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST01,ERR_R_MALLOC_FAILURE); 695238384Sjkim return 0; 696238384Sjkim } 697238384Sjkim databuf = OPENSSL_malloc(octet->length); 698238384Sjkim for (i=0,j=octet->length-1;i<octet->length;i++,j--) 699238384Sjkim { 700238384Sjkim databuf[j]=octet->data[i]; 701238384Sjkim } 702238384Sjkim len=octet->length/2; 703238384Sjkim ASN1_OCTET_STRING_free(octet); 704238384Sjkim 705238384Sjkim Y= getbnfrombuf(databuf,len); 706238384Sjkim X= getbnfrombuf(databuf+len,len); 707238384Sjkim OPENSSL_free(databuf); 708238384Sjkim pub_key = EC_POINT_new(group); 709238384Sjkim if (!EC_POINT_set_affine_coordinates_GFp(group 710238384Sjkim ,pub_key,X,Y,NULL)) 711238384Sjkim { 712238384Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST01, 713238384Sjkim ERR_R_EC_LIB); 714238384Sjkim EC_POINT_free(pub_key); 715238384Sjkim BN_free(X); 716238384Sjkim BN_free(Y); 717238384Sjkim return 0; 718238384Sjkim } 719238384Sjkim BN_free(X); 720238384Sjkim BN_free(Y); 721238384Sjkim if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk),pub_key)) 722238384Sjkim { 723238384Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST01, 724238384Sjkim ERR_R_EC_LIB); 725238384Sjkim EC_POINT_free(pub_key); 726238384Sjkim return 0; 727238384Sjkim } 728238384Sjkim EC_POINT_free(pub_key); 729238384Sjkim return 1; 730238384Sjkim 731238384Sjkim } 732238384Sjkim 733238384Sjkimstatic int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk) 734238384Sjkim { 735238384Sjkim ASN1_OBJECT *algobj = NULL; 736238384Sjkim ASN1_OCTET_STRING *octet = NULL; 737238384Sjkim void *pval = NULL; 738238384Sjkim unsigned char *buf=NULL,*databuf,*sptr; 739238384Sjkim int i,j,data_len,ret=0; 740238384Sjkim const EC_POINT *pub_key; 741238384Sjkim BIGNUM *X,*Y,*order; 742238384Sjkim const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 743238384Sjkim int ptype = V_ASN1_UNDEF; 744238384Sjkim 745238384Sjkim algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 746238384Sjkim if (pk->save_parameters) 747238384Sjkim { 748238384Sjkim ASN1_STRING *params = encode_gost_algor_params(pk); 749238384Sjkim pval = params; 750238384Sjkim ptype = V_ASN1_SEQUENCE; 751238384Sjkim } 752238384Sjkim order = BN_new(); 753238384Sjkim EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL); 754238384Sjkim pub_key=EC_KEY_get0_public_key(ec); 755238384Sjkim if (!pub_key) 756238384Sjkim { 757238384Sjkim GOSTerr(GOST_F_PUB_ENCODE_GOST01, 758238384Sjkim GOST_R_PUBLIC_KEY_UNDEFINED); 759238384Sjkim return 0; 760238384Sjkim } 761238384Sjkim X=BN_new(); 762238384Sjkim Y=BN_new(); 763238384Sjkim EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), 764238384Sjkim pub_key,X,Y,NULL); 765238384Sjkim data_len = 2*BN_num_bytes(order); 766238384Sjkim BN_free(order); 767238384Sjkim databuf = OPENSSL_malloc(data_len); 768238384Sjkim memset(databuf,0,data_len); 769238384Sjkim 770238384Sjkim store_bignum(X,databuf+data_len/2,data_len/2); 771238384Sjkim store_bignum(Y,databuf,data_len/2); 772238384Sjkim 773238384Sjkim BN_free(X); 774238384Sjkim BN_free(Y); 775238384Sjkim octet = ASN1_OCTET_STRING_new(); 776238384Sjkim ASN1_STRING_set(octet,NULL,data_len); 777238384Sjkim sptr=ASN1_STRING_data(octet); 778238384Sjkim for (i=0,j=data_len-1;i<data_len;i++,j--) 779238384Sjkim { 780238384Sjkim sptr[i]=databuf[j]; 781238384Sjkim } 782238384Sjkim OPENSSL_free(databuf); 783238384Sjkim ret = i2d_ASN1_OCTET_STRING(octet,&buf); 784238384Sjkim ASN1_BIT_STRING_free(octet); 785238384Sjkim if (ret <0) return 0; 786238384Sjkim return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret); 787238384Sjkim } 788238384Sjkim 789238384Sjkimstatic int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 790238384Sjkim { 791238384Sjkim const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 792238384Sjkim const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 793238384Sjkim if (da && db && da->pub_key && db->pub_key 794238384Sjkim && !BN_cmp(da->pub_key,db->pub_key)) 795238384Sjkim { 796238384Sjkim return 1; 797238384Sjkim } 798238384Sjkim return 0; 799238384Sjkim } 800238384Sjkim 801238384Sjkimstatic int pub_cmp_gost01(const EVP_PKEY *a,const EVP_PKEY *b) 802238384Sjkim { 803238384Sjkim const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a); 804238384Sjkim const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b); 805238384Sjkim const EC_POINT *ka,*kb; 806238384Sjkim int ret=0; 807238384Sjkim if (!ea || !eb) return 0; 808238384Sjkim ka = EC_KEY_get0_public_key(ea); 809238384Sjkim kb = EC_KEY_get0_public_key(eb); 810238384Sjkim if (!ka || !kb) return 0; 811238384Sjkim ret = (0==EC_POINT_cmp(EC_KEY_get0_group(ea),ka,kb,NULL)) ; 812238384Sjkim return ret; 813238384Sjkim } 814238384Sjkim 815238384Sjkim 816238384Sjkim 817238384Sjkim 818238384Sjkimstatic int pkey_size_gost(const EVP_PKEY *pk) 819238384Sjkim { 820238384Sjkim return 64; 821238384Sjkim } 822238384Sjkim 823238384Sjkimstatic int pkey_bits_gost(const EVP_PKEY *pk) 824238384Sjkim { 825238384Sjkim return 256; 826238384Sjkim } 827238384Sjkim/*------------------------ ASN1 METHOD for GOST MAC -------------------*/ 828238384Sjkimstatic void mackey_free_gost(EVP_PKEY *pk) 829238384Sjkim { 830238384Sjkim if (pk->pkey.ptr) { 831238384Sjkim OPENSSL_free(pk->pkey.ptr); 832238384Sjkim } 833238384Sjkim } 834238384Sjkimstatic int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 835238384Sjkim{ 836238384Sjkim switch (op) 837238384Sjkim { 838238384Sjkim case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 839238384Sjkim *(int *)arg2 = NID_id_Gost28147_89_MAC; 840238384Sjkim return 2; 841238384Sjkim } 842238384Sjkim return -2; 843238384Sjkim} 844238384Sjkim 845238384Sjkimstatic int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 846238384Sjkim{ 847238384Sjkim int nid=gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 848238384Sjkim return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder); 849238384Sjkim} 850238384Sjkimstatic int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 851238384Sjkim{ 852238384Sjkim int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey))); 853238384Sjkim return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder); 854238384Sjkim} 855238384Sjkim 856238384Sjkimstatic int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) 857238384Sjkim{ 858238384Sjkim ASN1_OBJECT *obj=NULL; 859238384Sjkim DSA *dsa = EVP_PKEY_get0(pkey); 860238384Sjkim int nid; 861238384Sjkim if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) { 862238384Sjkim return 0; 863238384Sjkim } 864238384Sjkim nid = OBJ_obj2nid(obj); 865238384Sjkim ASN1_OBJECT_free(obj); 866238384Sjkim if (!dsa) 867238384Sjkim { 868238384Sjkim dsa=DSA_new(); 869238384Sjkim if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa)) return 0; 870238384Sjkim } 871238384Sjkim if (!fill_GOST94_params(dsa,nid)) return 0; 872238384Sjkim return 1; 873238384Sjkim} 874238384Sjkim 875238384Sjkimstatic int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { 876238384Sjkim ASN1_OBJECT *obj=NULL; 877238384Sjkim int nid; 878238384Sjkim EC_KEY *ec = EVP_PKEY_get0(pkey); 879238384Sjkim if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) { 880238384Sjkim return 0; 881238384Sjkim } 882238384Sjkim nid = OBJ_obj2nid(obj); 883238384Sjkim ASN1_OBJECT_free(obj); 884238384Sjkim if (!ec) 885238384Sjkim { 886238384Sjkim ec = EC_KEY_new(); 887238384Sjkim if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec)) return 0; 888238384Sjkim } 889238384Sjkim if (!fill_GOST2001_params(ec, nid)) return 0; 890238384Sjkim return 1; 891238384Sjkim} 892238384Sjkim 893238384Sjkim 894238384Sjkim 895238384Sjkim 896238384Sjkim 897238384Sjkim/* ----------------------------------------------------------------------*/ 898238384Sjkimint register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info) 899238384Sjkim { 900238384Sjkim *ameth = EVP_PKEY_asn1_new(nid, 901238384Sjkim ASN1_PKEY_SIGPARAM_NULL, pemstr, info); 902238384Sjkim if (!*ameth) return 0; 903238384Sjkim switch (nid) 904238384Sjkim { 905238384Sjkim case NID_id_GostR3410_94: 906238384Sjkim EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94); 907238384Sjkim EVP_PKEY_asn1_set_private (*ameth, 908238384Sjkim priv_decode_gost, priv_encode_gost, 909238384Sjkim priv_print_gost94); 910238384Sjkim 911238384Sjkim EVP_PKEY_asn1_set_param (*ameth, 912238384Sjkim gost94_param_decode, gost94_param_encode, 913238384Sjkim param_missing_gost94, param_copy_gost94, 914238384Sjkim param_cmp_gost94,param_print_gost94 ); 915238384Sjkim EVP_PKEY_asn1_set_public (*ameth, 916238384Sjkim pub_decode_gost94, pub_encode_gost94, 917238384Sjkim pub_cmp_gost94, pub_print_gost94, 918238384Sjkim pkey_size_gost, pkey_bits_gost); 919238384Sjkim 920238384Sjkim EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost); 921238384Sjkim break; 922238384Sjkim case NID_id_GostR3410_2001: 923238384Sjkim EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost01); 924238384Sjkim EVP_PKEY_asn1_set_private (*ameth, 925238384Sjkim priv_decode_gost, priv_encode_gost, 926238384Sjkim priv_print_gost01); 927238384Sjkim 928238384Sjkim EVP_PKEY_asn1_set_param (*ameth, 929238384Sjkim gost2001_param_decode, gost2001_param_encode, 930238384Sjkim param_missing_gost01, param_copy_gost01, 931238384Sjkim param_cmp_gost01, param_print_gost01); 932238384Sjkim EVP_PKEY_asn1_set_public (*ameth, 933238384Sjkim pub_decode_gost01, pub_encode_gost01, 934238384Sjkim pub_cmp_gost01, pub_print_gost01, 935238384Sjkim pkey_size_gost, pkey_bits_gost); 936238384Sjkim 937238384Sjkim EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost); 938238384Sjkim break; 939238384Sjkim case NID_id_Gost28147_89_MAC: 940238384Sjkim EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); 941238384Sjkim EVP_PKEY_asn1_set_ctrl(*ameth,mac_ctrl_gost); 942238384Sjkim break; 943238384Sjkim } 944238384Sjkim return 1; 945238384Sjkim } 946