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 17280304Sjkim# include <openssl/cms.h> 18238384Sjkim#endif 19238384Sjkim#include "gost_params.h" 20238384Sjkim#include "gost_lcl.h" 21238384Sjkim#include "e_gost_err.h" 22238384Sjkim 23280304Sjkimint gost94_nid_by_params(DSA *p) 24280304Sjkim{ 25280304Sjkim R3410_params *gost_params; 26280304Sjkim BIGNUM *q = BN_new(); 27280304Sjkim for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) { 28280304Sjkim BN_dec2bn(&q, gost_params->q); 29280304Sjkim if (!BN_cmp(q, p->q)) { 30280304Sjkim BN_free(q); 31280304Sjkim return gost_params->nid; 32280304Sjkim } 33280304Sjkim } 34280304Sjkim BN_free(q); 35280304Sjkim return NID_undef; 36280304Sjkim} 37238384Sjkim 38280304Sjkimstatic ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) 39280304Sjkim{ 40280304Sjkim ASN1_STRING *params = ASN1_STRING_new(); 41280304Sjkim GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); 42280304Sjkim int pkey_param_nid = NID_undef; 43238384Sjkim 44280304Sjkim if (!params || !gkp) { 45280304Sjkim GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); 46280304Sjkim ASN1_STRING_free(params); 47280304Sjkim params = NULL; 48280304Sjkim goto err; 49280304Sjkim } 50280304Sjkim switch (EVP_PKEY_base_id(key)) { 51280304Sjkim case NID_id_GostR3410_2001: 52280304Sjkim pkey_param_nid = 53280304Sjkim EC_GROUP_get_curve_name(EC_KEY_get0_group 54280304Sjkim (EVP_PKEY_get0((EVP_PKEY *)key))); 55280304Sjkim break; 56280304Sjkim case NID_id_GostR3410_94: 57280304Sjkim pkey_param_nid = 58280304Sjkim (int)gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); 59280304Sjkim if (pkey_param_nid == NID_undef) { 60280304Sjkim GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, 61280304Sjkim GOST_R_INVALID_GOST94_PARMSET); 62280304Sjkim ASN1_STRING_free(params); 63280304Sjkim params = NULL; 64280304Sjkim goto err; 65280304Sjkim } 66280304Sjkim break; 67280304Sjkim } 68280304Sjkim gkp->key_params = OBJ_nid2obj(pkey_param_nid); 69280304Sjkim gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); 70280304Sjkim /* 71280304Sjkim * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); 72280304Sjkim */ 73280304Sjkim params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); 74280304Sjkim if (params->length <= 0) { 75280304Sjkim GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); 76280304Sjkim ASN1_STRING_free(params); 77280304Sjkim params = NULL; 78280304Sjkim goto err; 79280304Sjkim } 80280304Sjkim params->type = V_ASN1_SEQUENCE; 81280304Sjkim err: 82280304Sjkim GOST_KEY_PARAMS_free(gkp); 83280304Sjkim return params; 84280304Sjkim} 85238384Sjkim 86280304Sjkim/* 87280304Sjkim * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting 88280304Sjkim * NID and parameters 89238384Sjkim */ 90280304Sjkimstatic int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) 91280304Sjkim{ 92280304Sjkim ASN1_OBJECT *palg_obj = NULL; 93280304Sjkim int ptype = V_ASN1_UNDEF; 94280304Sjkim int pkey_nid = NID_undef, param_nid = NID_undef; 95280304Sjkim void *_pval; 96280304Sjkim ASN1_STRING *pval = NULL; 97280304Sjkim const unsigned char *p; 98280304Sjkim GOST_KEY_PARAMS *gkp = NULL; 99238384Sjkim 100280304Sjkim X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); 101280304Sjkim pval = _pval; 102280304Sjkim if (ptype != V_ASN1_SEQUENCE) { 103280304Sjkim GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 104280304Sjkim GOST_R_BAD_KEY_PARAMETERS_FORMAT); 105280304Sjkim return 0; 106280304Sjkim } 107280304Sjkim p = pval->data; 108280304Sjkim pkey_nid = OBJ_obj2nid(palg_obj); 109238384Sjkim 110280304Sjkim gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length); 111280304Sjkim if (!gkp) { 112280304Sjkim GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, 113280304Sjkim GOST_R_BAD_PKEY_PARAMETERS_FORMAT); 114280304Sjkim return 0; 115280304Sjkim } 116280304Sjkim param_nid = OBJ_obj2nid(gkp->key_params); 117280304Sjkim GOST_KEY_PARAMS_free(gkp); 118284285Sjkim if(!EVP_PKEY_set_type(pkey, pkey_nid)) { 119284285Sjkim GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR); 120284285Sjkim return 0; 121284285Sjkim } 122280304Sjkim switch (pkey_nid) { 123280304Sjkim case NID_id_GostR3410_94: 124280304Sjkim { 125280304Sjkim DSA *dsa = EVP_PKEY_get0(pkey); 126280304Sjkim if (!dsa) { 127280304Sjkim dsa = DSA_new(); 128280304Sjkim if (!EVP_PKEY_assign(pkey, pkey_nid, dsa)) 129280304Sjkim return 0; 130280304Sjkim } 131280304Sjkim if (!fill_GOST94_params(dsa, param_nid)) 132280304Sjkim return 0; 133280304Sjkim break; 134280304Sjkim } 135280304Sjkim case NID_id_GostR3410_2001: 136280304Sjkim { 137280304Sjkim EC_KEY *ec = EVP_PKEY_get0(pkey); 138280304Sjkim if (!ec) { 139280304Sjkim ec = EC_KEY_new(); 140280304Sjkim if (!EVP_PKEY_assign(pkey, pkey_nid, ec)) 141280304Sjkim return 0; 142280304Sjkim } 143280304Sjkim if (!fill_GOST2001_params(ec, param_nid)) 144280304Sjkim return 0; 145280304Sjkim } 146280304Sjkim } 147238384Sjkim 148280304Sjkim return 1; 149280304Sjkim} 150238384Sjkim 151280304Sjkimstatic int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv) 152280304Sjkim{ 153280304Sjkim switch (EVP_PKEY_base_id(pkey)) { 154280304Sjkim case NID_id_GostR3410_94: 155280304Sjkim { 156280304Sjkim DSA *dsa = EVP_PKEY_get0(pkey); 157280304Sjkim if (!dsa) { 158280304Sjkim dsa = DSA_new(); 159280304Sjkim EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa); 160280304Sjkim } 161280304Sjkim dsa->priv_key = BN_dup(priv); 162280304Sjkim if (!EVP_PKEY_missing_parameters(pkey)) 163280304Sjkim gost94_compute_public(dsa); 164280304Sjkim break; 165280304Sjkim } 166280304Sjkim case NID_id_GostR3410_2001: 167280304Sjkim { 168280304Sjkim EC_KEY *ec = EVP_PKEY_get0(pkey); 169280304Sjkim if (!ec) { 170280304Sjkim ec = EC_KEY_new(); 171280304Sjkim EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec); 172280304Sjkim } 173280304Sjkim if (!EC_KEY_set_private_key(ec, priv)) 174280304Sjkim return 0; 175280304Sjkim if (!EVP_PKEY_missing_parameters(pkey)) 176280304Sjkim gost2001_compute_public(ec); 177280304Sjkim break; 178280304Sjkim } 179280304Sjkim } 180280304Sjkim return 1; 181280304Sjkim} 182238384Sjkim 183280304SjkimBIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey) 184280304Sjkim{ 185280304Sjkim switch (EVP_PKEY_base_id(pkey)) { 186280304Sjkim case NID_id_GostR3410_94: 187280304Sjkim { 188280304Sjkim DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); 189280304Sjkim if (!dsa) { 190280304Sjkim return NULL; 191280304Sjkim } 192280304Sjkim if (!dsa->priv_key) 193280304Sjkim return NULL; 194280304Sjkim return dsa->priv_key; 195280304Sjkim break; 196280304Sjkim } 197280304Sjkim case NID_id_GostR3410_2001: 198280304Sjkim { 199280304Sjkim EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); 200280304Sjkim const BIGNUM *priv; 201280304Sjkim if (!ec) { 202280304Sjkim return NULL; 203280304Sjkim } 204280304Sjkim if (!(priv = EC_KEY_get0_private_key(ec))) 205280304Sjkim return NULL; 206280304Sjkim return (BIGNUM *)priv; 207280304Sjkim break; 208280304Sjkim } 209280304Sjkim } 210280304Sjkim return NULL; 211280304Sjkim} 212280304Sjkim 213280304Sjkimstatic int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 214280304Sjkim{ 215280304Sjkim switch (op) { 216280304Sjkim case ASN1_PKEY_CTRL_PKCS7_SIGN: 217280304Sjkim if (arg1 == 0) { 218280304Sjkim X509_ALGOR *alg1 = NULL, *alg2 = NULL; 219280304Sjkim int nid = EVP_PKEY_base_id(pkey); 220280304Sjkim PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, 221280304Sjkim NULL, &alg1, &alg2); 222280304Sjkim X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 223280304Sjkim V_ASN1_NULL, 0); 224280304Sjkim if (nid == NID_undef) { 225280304Sjkim return (-1); 226280304Sjkim } 227280304Sjkim X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 228280304Sjkim } 229280304Sjkim return 1; 230238384Sjkim#ifndef OPENSSL_NO_CMS 231280304Sjkim case ASN1_PKEY_CTRL_CMS_SIGN: 232280304Sjkim if (arg1 == 0) { 233280304Sjkim X509_ALGOR *alg1 = NULL, *alg2 = NULL; 234280304Sjkim int nid = EVP_PKEY_base_id(pkey); 235280304Sjkim CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, 236280304Sjkim NULL, NULL, &alg1, &alg2); 237280304Sjkim X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), 238280304Sjkim V_ASN1_NULL, 0); 239280304Sjkim if (nid == NID_undef) { 240280304Sjkim return (-1); 241280304Sjkim } 242280304Sjkim X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); 243280304Sjkim } 244280304Sjkim return 1; 245238384Sjkim#endif 246280304Sjkim case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: 247280304Sjkim if (arg1 == 0) { 248280304Sjkim X509_ALGOR *alg; 249280304Sjkim ASN1_STRING *params = encode_gost_algor_params(pkey); 250280304Sjkim if (!params) { 251280304Sjkim return -1; 252280304Sjkim } 253280304Sjkim PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg); 254280304Sjkim X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), 255280304Sjkim V_ASN1_SEQUENCE, params); 256280304Sjkim } 257280304Sjkim return 1; 258238384Sjkim#ifndef OPENSSL_NO_CMS 259280304Sjkim case ASN1_PKEY_CTRL_CMS_ENVELOPE: 260280304Sjkim if (arg1 == 0) { 261280304Sjkim X509_ALGOR *alg = NULL; 262280304Sjkim ASN1_STRING *params = encode_gost_algor_params(pkey); 263280304Sjkim if (!params) { 264280304Sjkim return -1; 265280304Sjkim } 266280304Sjkim CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, 267280304Sjkim NULL, &alg); 268280304Sjkim X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, 269280304Sjkim params); 270280304Sjkim } 271280304Sjkim return 1; 272238384Sjkim#endif 273280304Sjkim case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 274280304Sjkim *(int *)arg2 = NID_id_GostR3411_94; 275280304Sjkim return 2; 276280304Sjkim } 277238384Sjkim 278280304Sjkim return -2; 279280304Sjkim} 280238384Sjkim 281280304Sjkim/* --------------------- free functions * ------------------------------*/ 282280304Sjkimstatic void pkey_free_gost94(EVP_PKEY *key) 283280304Sjkim{ 284280304Sjkim if (key->pkey.dsa) { 285280304Sjkim DSA_free(key->pkey.dsa); 286280304Sjkim } 287280304Sjkim} 288280304Sjkim 289280304Sjkimstatic void pkey_free_gost01(EVP_PKEY *key) 290280304Sjkim{ 291280304Sjkim if (key->pkey.ec) { 292280304Sjkim EC_KEY_free(key->pkey.ec); 293280304Sjkim } 294280304Sjkim} 295280304Sjkim 296238384Sjkim/* ------------------ private key functions -----------------------------*/ 297280304Sjkimstatic int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) 298280304Sjkim{ 299280304Sjkim const unsigned char *pkey_buf = NULL, *p = NULL; 300280304Sjkim int priv_len = 0; 301280304Sjkim BIGNUM *pk_num = NULL; 302280304Sjkim int ret = 0; 303280304Sjkim X509_ALGOR *palg = NULL; 304280304Sjkim ASN1_OBJECT *palg_obj = NULL; 305280304Sjkim ASN1_INTEGER *priv_key = NULL; 306238384Sjkim 307280304Sjkim if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf)) 308280304Sjkim return 0; 309280304Sjkim p = pkey_buf; 310280304Sjkim if (!decode_gost_algor_params(pk, palg)) { 311280304Sjkim return 0; 312280304Sjkim } 313280304Sjkim if (V_ASN1_OCTET_STRING == *p) { 314280304Sjkim /* New format - Little endian octet string */ 315280304Sjkim unsigned char rev_buf[32]; 316280304Sjkim int i; 317280304Sjkim ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); 318280304Sjkim if (!s || s->length != 32) { 319280304Sjkim GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); 320280304Sjkim return 0; 321280304Sjkim } 322280304Sjkim for (i = 0; i < 32; i++) { 323280304Sjkim rev_buf[31 - i] = s->data[i]; 324280304Sjkim } 325280304Sjkim ASN1_STRING_free(s); 326280304Sjkim pk_num = getbnfrombuf(rev_buf, 32); 327280304Sjkim } else { 328280304Sjkim priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); 329280304Sjkim if (!priv_key) 330280304Sjkim return 0; 331280304Sjkim ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); 332280304Sjkim ASN1_INTEGER_free(priv_key); 333280304Sjkim if (!ret) { 334280304Sjkim GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); 335280304Sjkim return 0; 336280304Sjkim } 337280304Sjkim } 338238384Sjkim 339280304Sjkim ret = gost_set_priv_key(pk, pk_num); 340280304Sjkim BN_free(pk_num); 341280304Sjkim return ret; 342280304Sjkim} 343238384Sjkim 344238384Sjkim/* ----------------------------------------------------------------------*/ 345238384Sjkimstatic int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) 346280304Sjkim{ 347280304Sjkim ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 348280304Sjkim ASN1_STRING *params = encode_gost_algor_params(pk); 349280304Sjkim unsigned char *priv_buf = NULL; 350280304Sjkim int priv_len; 351238384Sjkim 352280304Sjkim ASN1_INTEGER *asn1key = NULL; 353280304Sjkim if (!params) { 354280304Sjkim return 0; 355280304Sjkim } 356280304Sjkim asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL); 357280304Sjkim priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); 358280304Sjkim ASN1_INTEGER_free(asn1key); 359280304Sjkim return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, 360280304Sjkim priv_buf, priv_len); 361280304Sjkim} 362280304Sjkim 363238384Sjkim/* --------- printing keys --------------------------------*/ 364238384Sjkimstatic int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, 365280304Sjkim ASN1_PCTX *pctx, int type) 366280304Sjkim{ 367280304Sjkim int param_nid = NID_undef; 368238384Sjkim 369280304Sjkim if (type == 2) { 370280304Sjkim BIGNUM *key; 371238384Sjkim 372280304Sjkim if (!BIO_indent(out, indent, 128)) 373280304Sjkim return 0; 374280304Sjkim BIO_printf(out, "Private key: "); 375280304Sjkim key = gost_get0_priv_key(pkey); 376280304Sjkim if (!key) 377280304Sjkim BIO_printf(out, "<undefined>"); 378280304Sjkim else 379280304Sjkim BN_print(out, key); 380280304Sjkim BIO_printf(out, "\n"); 381280304Sjkim } 382280304Sjkim if (type >= 1) { 383280304Sjkim BIGNUM *pubkey; 384238384Sjkim 385280304Sjkim pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; 386280304Sjkim BIO_indent(out, indent, 128); 387280304Sjkim BIO_printf(out, "Public key: "); 388280304Sjkim BN_print(out, pubkey); 389280304Sjkim BIO_printf(out, "\n"); 390280304Sjkim } 391280304Sjkim 392280304Sjkim param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 393280304Sjkim BIO_indent(out, indent, 128); 394280304Sjkim BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 395280304Sjkim return 1; 396238384Sjkim} 397238384Sjkim 398238384Sjkimstatic int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 399280304Sjkim ASN1_PCTX *pctx) 400280304Sjkim{ 401280304Sjkim return print_gost_94(out, pkey, indent, pctx, 0); 402280304Sjkim} 403238384Sjkim 404238384Sjkimstatic int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 405280304Sjkim ASN1_PCTX *pctx) 406280304Sjkim{ 407280304Sjkim return print_gost_94(out, pkey, indent, pctx, 1); 408280304Sjkim} 409238384Sjkim 410280304Sjkimstatic int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, 411280304Sjkim ASN1_PCTX *pctx) 412280304Sjkim{ 413280304Sjkim return print_gost_94(out, pkey, indent, pctx, 2); 414280304Sjkim} 415280304Sjkim 416238384Sjkimstatic int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, 417280304Sjkim ASN1_PCTX *pctx, int type) 418280304Sjkim{ 419280304Sjkim int param_nid = NID_undef; 420280304Sjkim if (type == 2) { 421280304Sjkim BIGNUM *key; 422238384Sjkim 423280304Sjkim if (!BIO_indent(out, indent, 128)) 424280304Sjkim return 0; 425280304Sjkim BIO_printf(out, "Private key: "); 426280304Sjkim key = gost_get0_priv_key(pkey); 427280304Sjkim if (!key) 428280304Sjkim BIO_printf(out, "<undefined)"); 429280304Sjkim else 430280304Sjkim BN_print(out, key); 431280304Sjkim BIO_printf(out, "\n"); 432280304Sjkim } 433280304Sjkim if (type >= 1) { 434280304Sjkim BN_CTX *ctx = BN_CTX_new(); 435280304Sjkim BIGNUM *X, *Y; 436280304Sjkim const EC_POINT *pubkey; 437280304Sjkim const EC_GROUP *group; 438238384Sjkim 439280304Sjkim if (!ctx) { 440280304Sjkim GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE); 441280304Sjkim return 0; 442280304Sjkim } 443280304Sjkim BN_CTX_start(ctx); 444280304Sjkim X = BN_CTX_get(ctx); 445280304Sjkim Y = BN_CTX_get(ctx); 446280304Sjkim pubkey = 447280304Sjkim EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 448280304Sjkim group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); 449280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { 450280304Sjkim GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB); 451280304Sjkim BN_CTX_free(ctx); 452280304Sjkim return 0; 453280304Sjkim } 454280304Sjkim if (!BIO_indent(out, indent, 128)) 455280304Sjkim return 0; 456280304Sjkim BIO_printf(out, "Public key:\n"); 457280304Sjkim if (!BIO_indent(out, indent + 3, 128)) 458280304Sjkim return 0; 459280304Sjkim BIO_printf(out, "X:"); 460280304Sjkim BN_print(out, X); 461280304Sjkim BIO_printf(out, "\n"); 462280304Sjkim BIO_indent(out, indent + 3, 128); 463280304Sjkim BIO_printf(out, "Y:"); 464280304Sjkim BN_print(out, Y); 465280304Sjkim BIO_printf(out, "\n"); 466280304Sjkim BN_CTX_end(ctx); 467280304Sjkim BN_CTX_free(ctx); 468280304Sjkim } 469238384Sjkim 470280304Sjkim param_nid = 471280304Sjkim EC_GROUP_get_curve_name(EC_KEY_get0_group 472280304Sjkim (EVP_PKEY_get0((EVP_PKEY *)pkey))); 473280304Sjkim if (!BIO_indent(out, indent, 128)) 474280304Sjkim return 0; 475280304Sjkim BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); 476280304Sjkim return 1; 477238384Sjkim} 478280304Sjkim 479238384Sjkimstatic int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 480280304Sjkim ASN1_PCTX *pctx) 481280304Sjkim{ 482280304Sjkim return print_gost_01(out, pkey, indent, pctx, 0); 483280304Sjkim} 484280304Sjkim 485238384Sjkimstatic int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 486280304Sjkim ASN1_PCTX *pctx) 487280304Sjkim{ 488280304Sjkim return print_gost_01(out, pkey, indent, pctx, 1); 489280304Sjkim} 490280304Sjkim 491280304Sjkimstatic int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, 492280304Sjkim ASN1_PCTX *pctx) 493280304Sjkim{ 494280304Sjkim return print_gost_01(out, pkey, indent, pctx, 2); 495280304Sjkim} 496280304Sjkim 497238384Sjkim/* ---------------------------------------------------------------------*/ 498280304Sjkimstatic int param_missing_gost94(const EVP_PKEY *pk) 499280304Sjkim{ 500280304Sjkim const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 501280304Sjkim if (!dsa) 502280304Sjkim return 1; 503280304Sjkim if (!dsa->q) 504280304Sjkim return 1; 505280304Sjkim return 0; 506280304Sjkim} 507238384Sjkim 508280304Sjkimstatic int param_missing_gost01(const EVP_PKEY *pk) 509280304Sjkim{ 510280304Sjkim const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 511280304Sjkim if (!ec) 512280304Sjkim return 1; 513280304Sjkim if (!EC_KEY_get0_group(ec)) 514280304Sjkim return 1; 515280304Sjkim return 0; 516280304Sjkim} 517238384Sjkim 518280304Sjkimstatic int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) 519280304Sjkim{ 520280304Sjkim const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from); 521280304Sjkim DSA *dto = EVP_PKEY_get0(to); 522280304Sjkim if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 523280304Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS); 524280304Sjkim return 0; 525280304Sjkim } 526280304Sjkim if (!dfrom) { 527280304Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING); 528280304Sjkim return 0; 529280304Sjkim } 530280304Sjkim if (!dto) { 531280304Sjkim dto = DSA_new(); 532280304Sjkim EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto); 533280304Sjkim } 534280304Sjkim#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x); 535280304Sjkim COPYBIGNUM(dto, dfrom, p) 536280304Sjkim COPYBIGNUM(dto, dfrom, q) 537280304Sjkim COPYBIGNUM(dto, dfrom, g) 538238384Sjkim 539280304Sjkim if (dto->priv_key) 540280304Sjkim gost94_compute_public(dto); 541280304Sjkim return 1; 542280304Sjkim} 543238384Sjkim 544280304Sjkimstatic int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 545280304Sjkim{ 546280304Sjkim EC_KEY *eto = EVP_PKEY_get0(to); 547280304Sjkim const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); 548280304Sjkim if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { 549280304Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS); 550280304Sjkim return 0; 551280304Sjkim } 552280304Sjkim if (!efrom) { 553280304Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); 554280304Sjkim return 0; 555280304Sjkim } 556280304Sjkim if (!eto) { 557280304Sjkim eto = EC_KEY_new(); 558284285Sjkim if(!eto) { 559284285Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE); 560284285Sjkim return 0; 561284285Sjkim } 562284285Sjkim if(!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) { 563284285Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); 564284285Sjkim return 0; 565284285Sjkim } 566280304Sjkim } 567284285Sjkim if(!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) { 568284285Sjkim GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); 569284285Sjkim return 0; 570284285Sjkim } 571280304Sjkim if (EC_KEY_get0_private_key(eto)) { 572280304Sjkim gost2001_compute_public(eto); 573280304Sjkim } 574280304Sjkim return 1; 575280304Sjkim} 576238384Sjkim 577280304Sjkimstatic int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 578280304Sjkim{ 579280304Sjkim const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 580280304Sjkim const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 581280304Sjkim if (!BN_cmp(da->q, db->q)) 582280304Sjkim return 1; 583280304Sjkim return 0; 584280304Sjkim} 585238384Sjkim 586280304Sjkimstatic int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 587280304Sjkim{ 588280304Sjkim if (EC_GROUP_get_curve_name 589280304Sjkim (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) == 590280304Sjkim EC_GROUP_get_curve_name(EC_KEY_get0_group 591280304Sjkim (EVP_PKEY_get0((EVP_PKEY *)b)))) { 592280304Sjkim return 1; 593280304Sjkim } 594280304Sjkim return 0; 595238384Sjkim 596280304Sjkim} 597280304Sjkim 598238384Sjkim/* ---------- Public key functions * --------------------------------------*/ 599238384Sjkimstatic int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) 600280304Sjkim{ 601280304Sjkim X509_ALGOR *palg = NULL; 602280304Sjkim const unsigned char *pubkey_buf = NULL; 603280304Sjkim unsigned char *databuf; 604280304Sjkim ASN1_OBJECT *palgobj = NULL; 605280304Sjkim int pub_len, i, j; 606280304Sjkim DSA *dsa; 607280304Sjkim ASN1_OCTET_STRING *octet = NULL; 608238384Sjkim 609280304Sjkim if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) 610280304Sjkim return 0; 611280304Sjkim EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); 612280304Sjkim if (!decode_gost_algor_params(pk, palg)) 613280304Sjkim return 0; 614280304Sjkim octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 615280304Sjkim if (!octet) { 616280304Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); 617280304Sjkim return 0; 618280304Sjkim } 619280304Sjkim databuf = OPENSSL_malloc(octet->length); 620280304Sjkim for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { 621280304Sjkim databuf[j] = octet->data[i]; 622280304Sjkim } 623280304Sjkim dsa = EVP_PKEY_get0(pk); 624280304Sjkim dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL); 625280304Sjkim ASN1_OCTET_STRING_free(octet); 626280304Sjkim OPENSSL_free(databuf); 627280304Sjkim return 1; 628238384Sjkim 629280304Sjkim} 630238384Sjkim 631280304Sjkimstatic int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk) 632280304Sjkim{ 633280304Sjkim ASN1_OBJECT *algobj = NULL; 634280304Sjkim ASN1_OCTET_STRING *octet = NULL; 635280304Sjkim void *pval = NULL; 636280304Sjkim unsigned char *buf = NULL, *databuf, *sptr; 637280304Sjkim int i, j, data_len, ret = 0; 638238384Sjkim 639280304Sjkim int ptype = V_ASN1_UNDEF; 640280304Sjkim DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); 641280304Sjkim algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 642280304Sjkim if (pk->save_parameters) { 643280304Sjkim ASN1_STRING *params = encode_gost_algor_params(pk); 644280304Sjkim pval = params; 645280304Sjkim ptype = V_ASN1_SEQUENCE; 646280304Sjkim } 647280304Sjkim data_len = BN_num_bytes(dsa->pub_key); 648280304Sjkim databuf = OPENSSL_malloc(data_len); 649280304Sjkim BN_bn2bin(dsa->pub_key, databuf); 650280304Sjkim octet = ASN1_OCTET_STRING_new(); 651280304Sjkim ASN1_STRING_set(octet, NULL, data_len); 652280304Sjkim sptr = ASN1_STRING_data(octet); 653280304Sjkim for (i = 0, j = data_len - 1; i < data_len; i++, j--) { 654280304Sjkim sptr[i] = databuf[j]; 655280304Sjkim } 656280304Sjkim OPENSSL_free(databuf); 657280304Sjkim ret = i2d_ASN1_OCTET_STRING(octet, &buf); 658280304Sjkim ASN1_BIT_STRING_free(octet); 659280304Sjkim if (ret < 0) 660280304Sjkim return 0; 661280304Sjkim return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 662280304Sjkim} 663238384Sjkim 664280304Sjkimstatic int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) 665280304Sjkim{ 666280304Sjkim X509_ALGOR *palg = NULL; 667280304Sjkim const unsigned char *pubkey_buf = NULL; 668280304Sjkim unsigned char *databuf; 669280304Sjkim ASN1_OBJECT *palgobj = NULL; 670280304Sjkim int pub_len, i, j; 671280304Sjkim EC_POINT *pub_key; 672280304Sjkim BIGNUM *X, *Y; 673280304Sjkim ASN1_OCTET_STRING *octet = NULL; 674280304Sjkim int len; 675280304Sjkim const EC_GROUP *group; 676238384Sjkim 677280304Sjkim if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) 678280304Sjkim return 0; 679280304Sjkim EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); 680280304Sjkim if (!decode_gost_algor_params(pk, palg)) 681280304Sjkim return 0; 682280304Sjkim group = EC_KEY_get0_group(EVP_PKEY_get0(pk)); 683280304Sjkim octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); 684280304Sjkim if (!octet) { 685280304Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); 686280304Sjkim return 0; 687280304Sjkim } 688280304Sjkim databuf = OPENSSL_malloc(octet->length); 689280304Sjkim for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { 690280304Sjkim databuf[j] = octet->data[i]; 691280304Sjkim } 692280304Sjkim len = octet->length / 2; 693280304Sjkim ASN1_OCTET_STRING_free(octet); 694238384Sjkim 695280304Sjkim Y = getbnfrombuf(databuf, len); 696280304Sjkim X = getbnfrombuf(databuf + len, len); 697280304Sjkim OPENSSL_free(databuf); 698280304Sjkim pub_key = EC_POINT_new(group); 699280304Sjkim if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) { 700280304Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 701280304Sjkim EC_POINT_free(pub_key); 702280304Sjkim BN_free(X); 703280304Sjkim BN_free(Y); 704280304Sjkim return 0; 705280304Sjkim } 706280304Sjkim BN_free(X); 707280304Sjkim BN_free(Y); 708280304Sjkim if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) { 709280304Sjkim GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); 710280304Sjkim EC_POINT_free(pub_key); 711280304Sjkim return 0; 712280304Sjkim } 713280304Sjkim EC_POINT_free(pub_key); 714280304Sjkim return 1; 715238384Sjkim 716280304Sjkim} 717238384Sjkim 718280304Sjkimstatic int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) 719280304Sjkim{ 720280304Sjkim ASN1_OBJECT *algobj = NULL; 721280304Sjkim ASN1_OCTET_STRING *octet = NULL; 722280304Sjkim void *pval = NULL; 723280304Sjkim unsigned char *buf = NULL, *databuf, *sptr; 724280304Sjkim int i, j, data_len, ret = 0; 725280304Sjkim const EC_POINT *pub_key; 726280304Sjkim BIGNUM *X, *Y, *order; 727280304Sjkim const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); 728280304Sjkim int ptype = V_ASN1_UNDEF; 729238384Sjkim 730280304Sjkim algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); 731280304Sjkim if (pk->save_parameters) { 732280304Sjkim ASN1_STRING *params = encode_gost_algor_params(pk); 733280304Sjkim pval = params; 734280304Sjkim ptype = V_ASN1_SEQUENCE; 735280304Sjkim } 736280304Sjkim order = BN_new(); 737280304Sjkim EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL); 738280304Sjkim pub_key = EC_KEY_get0_public_key(ec); 739280304Sjkim if (!pub_key) { 740280304Sjkim GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); 741280304Sjkim return 0; 742280304Sjkim } 743280304Sjkim X = BN_new(); 744280304Sjkim Y = BN_new(); 745284285Sjkim if(!X || !Y) { 746284285Sjkim GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); 747284285Sjkim if(X) BN_free(X); 748284285Sjkim if(Y) BN_free(Y); 749284285Sjkim BN_free(order); 750284285Sjkim return 0; 751284285Sjkim } 752284285Sjkim if(!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), 753284285Sjkim pub_key, X, Y, NULL)) { 754284285Sjkim GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); 755284285Sjkim BN_free(X); 756284285Sjkim BN_free(Y); 757284285Sjkim BN_free(order); 758284285Sjkim return 0; 759284285Sjkim } 760280304Sjkim data_len = 2 * BN_num_bytes(order); 761280304Sjkim BN_free(order); 762280304Sjkim databuf = OPENSSL_malloc(data_len); 763280304Sjkim memset(databuf, 0, data_len); 764280304Sjkim 765280304Sjkim store_bignum(X, databuf + data_len / 2, data_len / 2); 766280304Sjkim store_bignum(Y, databuf, data_len / 2); 767280304Sjkim 768280304Sjkim BN_free(X); 769280304Sjkim BN_free(Y); 770280304Sjkim octet = ASN1_OCTET_STRING_new(); 771280304Sjkim ASN1_STRING_set(octet, NULL, data_len); 772280304Sjkim sptr = ASN1_STRING_data(octet); 773280304Sjkim for (i = 0, j = data_len - 1; i < data_len; i++, j--) { 774280304Sjkim sptr[i] = databuf[j]; 775280304Sjkim } 776238384Sjkim OPENSSL_free(databuf); 777280304Sjkim ret = i2d_ASN1_OCTET_STRING(octet, &buf); 778280304Sjkim ASN1_BIT_STRING_free(octet); 779280304Sjkim if (ret < 0) 780280304Sjkim return 0; 781280304Sjkim return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); 782280304Sjkim} 783238384Sjkim 784238384Sjkimstatic int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 785280304Sjkim{ 786280304Sjkim const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); 787280304Sjkim const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); 788280304Sjkim if (da && db && da->pub_key && db->pub_key 789280304Sjkim && !BN_cmp(da->pub_key, db->pub_key)) { 790280304Sjkim return 1; 791280304Sjkim } 792280304Sjkim return 0; 793280304Sjkim} 794238384Sjkim 795280304Sjkimstatic int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 796280304Sjkim{ 797280304Sjkim const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a); 798280304Sjkim const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b); 799280304Sjkim const EC_POINT *ka, *kb; 800280304Sjkim int ret = 0; 801280304Sjkim if (!ea || !eb) 802280304Sjkim return 0; 803280304Sjkim ka = EC_KEY_get0_public_key(ea); 804280304Sjkim kb = EC_KEY_get0_public_key(eb); 805280304Sjkim if (!ka || !kb) 806280304Sjkim return 0; 807280304Sjkim ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL)); 808280304Sjkim return ret; 809280304Sjkim} 810238384Sjkim 811238384Sjkimstatic int pkey_size_gost(const EVP_PKEY *pk) 812280304Sjkim{ 813280304Sjkim return 64; 814280304Sjkim} 815238384Sjkim 816238384Sjkimstatic int pkey_bits_gost(const EVP_PKEY *pk) 817238384Sjkim{ 818280304Sjkim return 256; 819280304Sjkim} 820238384Sjkim 821280304Sjkim/* ---------------------- ASN1 METHOD for GOST MAC -------------------*/ 822280304Sjkimstatic void mackey_free_gost(EVP_PKEY *pk) 823238384Sjkim{ 824280304Sjkim if (pk->pkey.ptr) { 825280304Sjkim OPENSSL_free(pk->pkey.ptr); 826280304Sjkim } 827238384Sjkim} 828280304Sjkim 829280304Sjkimstatic int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) 830238384Sjkim{ 831280304Sjkim switch (op) { 832280304Sjkim case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 833280304Sjkim *(int *)arg2 = NID_id_Gost28147_89_MAC; 834280304Sjkim return 2; 835280304Sjkim } 836280304Sjkim return -2; 837238384Sjkim} 838238384Sjkim 839280304Sjkimstatic int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 840238384Sjkim{ 841280304Sjkim int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); 842280304Sjkim return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); 843280304Sjkim} 844238384Sjkim 845280304Sjkimstatic int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 846280304Sjkim{ 847280304Sjkim int nid = 848280304Sjkim EC_GROUP_get_curve_name(EC_KEY_get0_group 849280304Sjkim (EVP_PKEY_get0((EVP_PKEY *)pkey))); 850280304Sjkim return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); 851280304Sjkim} 852238384Sjkim 853280304Sjkimstatic int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, 854280304Sjkim int derlen) 855280304Sjkim{ 856280304Sjkim ASN1_OBJECT *obj = NULL; 857280304Sjkim DSA *dsa = EVP_PKEY_get0(pkey); 858280304Sjkim int nid; 859280304Sjkim if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 860280304Sjkim return 0; 861280304Sjkim } 862280304Sjkim nid = OBJ_obj2nid(obj); 863280304Sjkim ASN1_OBJECT_free(obj); 864280304Sjkim if (!dsa) { 865280304Sjkim dsa = DSA_new(); 866280304Sjkim if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa)) 867280304Sjkim return 0; 868280304Sjkim } 869280304Sjkim if (!fill_GOST94_params(dsa, nid)) 870280304Sjkim return 0; 871280304Sjkim return 1; 872280304Sjkim} 873238384Sjkim 874280304Sjkimstatic int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, 875280304Sjkim int derlen) 876280304Sjkim{ 877280304Sjkim ASN1_OBJECT *obj = NULL; 878280304Sjkim int nid; 879280304Sjkim EC_KEY *ec = EVP_PKEY_get0(pkey); 880280304Sjkim if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { 881280304Sjkim return 0; 882280304Sjkim } 883280304Sjkim nid = OBJ_obj2nid(obj); 884280304Sjkim ASN1_OBJECT_free(obj); 885280304Sjkim if (!ec) { 886280304Sjkim ec = EC_KEY_new(); 887280304Sjkim if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) 888280304Sjkim return 0; 889280304Sjkim } 890280304Sjkim if (!fill_GOST2001_params(ec, nid)) 891280304Sjkim return 0; 892280304Sjkim return 1; 893280304Sjkim} 894238384Sjkim 895280304Sjkim/* ----------------------------------------------------------------------*/ 896280304Sjkimint register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, 897280304Sjkim const char *pemstr, const char *info) 898280304Sjkim{ 899280304Sjkim *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info); 900280304Sjkim if (!*ameth) 901280304Sjkim return 0; 902280304Sjkim switch (nid) { 903280304Sjkim case NID_id_GostR3410_94: 904280304Sjkim EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94); 905280304Sjkim EVP_PKEY_asn1_set_private(*ameth, 906280304Sjkim priv_decode_gost, priv_encode_gost, 907280304Sjkim priv_print_gost94); 908238384Sjkim 909280304Sjkim EVP_PKEY_asn1_set_param(*ameth, 910280304Sjkim gost94_param_decode, gost94_param_encode, 911280304Sjkim param_missing_gost94, param_copy_gost94, 912280304Sjkim param_cmp_gost94, param_print_gost94); 913280304Sjkim EVP_PKEY_asn1_set_public(*ameth, 914280304Sjkim pub_decode_gost94, pub_encode_gost94, 915280304Sjkim pub_cmp_gost94, pub_print_gost94, 916280304Sjkim pkey_size_gost, pkey_bits_gost); 917238384Sjkim 918280304Sjkim EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); 919280304Sjkim break; 920280304Sjkim case NID_id_GostR3410_2001: 921280304Sjkim EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01); 922280304Sjkim EVP_PKEY_asn1_set_private(*ameth, 923280304Sjkim priv_decode_gost, priv_encode_gost, 924280304Sjkim priv_print_gost01); 925238384Sjkim 926280304Sjkim EVP_PKEY_asn1_set_param(*ameth, 927280304Sjkim gost2001_param_decode, gost2001_param_encode, 928280304Sjkim param_missing_gost01, param_copy_gost01, 929280304Sjkim param_cmp_gost01, param_print_gost01); 930280304Sjkim EVP_PKEY_asn1_set_public(*ameth, 931280304Sjkim pub_decode_gost01, pub_encode_gost01, 932280304Sjkim pub_cmp_gost01, pub_print_gost01, 933280304Sjkim pkey_size_gost, pkey_bits_gost); 934238384Sjkim 935280304Sjkim EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); 936280304Sjkim break; 937280304Sjkim case NID_id_Gost28147_89_MAC: 938280304Sjkim EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); 939280304Sjkim EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost); 940280304Sjkim break; 941280304Sjkim } 942280304Sjkim return 1; 943280304Sjkim} 944