]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_ameth.c
Fix coverity #305799
[openssl-gost/engine.git] / gost_ameth.c
1 /**********************************************************************
2  *                          gost_ameth.c                              *
3  *             Copyright (c) 2005-2006 Cryptocom LTD                  *
4  *         This file is distributed under the same license as OpenSSL *
5  *                                                                    *
6  *       Implementation of RFC 4490/4491 ASN1 method                  *
7  *       for OpenSSL                                                  *
8  *          Requires OpenSSL 0.9.9 for compilation                    *
9  **********************************************************************/
10 #include <string.h>
11 #include <openssl/crypto.h>
12 #include <openssl/err.h>
13 #include <openssl/engine.h>
14 #include <openssl/evp.h>
15 #include <openssl/asn1.h>
16 #ifndef OPENSSL_NO_CMS
17 # include <openssl/cms.h>
18 #endif
19 #include "gost_lcl.h"
20 #include "e_gost_err.h"
21
22 #define PK_WRAP_PARAM "LEGACY_PK_WRAP"
23
24 /*
25  * Pack bignum into byte buffer of given size, filling all leading bytes by
26  * zeros
27  */
28 int store_bignum(const BIGNUM *bn, unsigned char *buf, int len)
29 {
30     int bytes = BN_num_bytes(bn);
31
32     if (bytes > len)
33         return 0;
34     memset(buf, 0, len);
35     BN_bn2bin(bn, buf + len - bytes);
36     return 1;
37 }
38
39 static int pkey_bits_gost(const EVP_PKEY *pk)
40 {
41     if (!pk)
42         return -1;
43
44     switch (EVP_PKEY_base_id(pk)) {
45     case NID_id_GostR3410_2001:
46     case NID_id_GostR3410_2012_256:
47         return 256;
48     case NID_id_GostR3410_2012_512:
49         return 512;
50     }
51
52     return -1;
53 }
54
55 static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key)
56 {
57     ASN1_STRING *params = ASN1_STRING_new();
58     GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
59     int pkey_param_nid = NID_undef;
60     void *key_ptr = EVP_PKEY_get0((EVP_PKEY *)key);
61     int result = 0;
62
63     if (!params || !gkp) {
64         GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE);
65         goto err;
66     }
67     switch (EVP_PKEY_base_id(key)) {
68     case NID_id_GostR3410_2012_256:
69         pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(key_ptr));
70         switch (pkey_param_nid) {
71             case NID_id_GostR3410_2001_TestParamSet:
72             case NID_id_GostR3410_2001_CryptoPro_A_ParamSet:
73             case NID_id_GostR3410_2001_CryptoPro_B_ParamSet:
74             case NID_id_GostR3410_2001_CryptoPro_C_ParamSet:
75             case NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet:
76             case NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet:
77                 gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_2012_256);
78         }
79         break;
80     case NID_id_GostR3410_2012_512:
81         pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(key_ptr));
82         switch (pkey_param_nid) {
83             case NID_id_tc26_gost_3410_2012_512_paramSetTest:
84             case NID_id_tc26_gost_3410_2012_512_paramSetA:
85             case NID_id_tc26_gost_3410_2012_512_paramSetB:
86                 gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_2012_512);
87         }
88         break;
89     case NID_id_GostR3410_2001:
90         pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(key_ptr));
91         gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
92         break;
93     }
94
95     if (pkey_param_nid == NID_undef) {
96         GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, GOST_R_INVALID_PARAMSET);
97         goto err;
98     }
99
100     gkp->key_params = OBJ_nid2obj(pkey_param_nid);
101     /*
102      * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);
103      */
104     params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
105     if (params->length <= 0) {
106         GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE);
107         goto err;
108     }
109     params->type = V_ASN1_SEQUENCE;
110     result = 1;
111  err:
112     if (gkp)
113         GOST_KEY_PARAMS_free(gkp);
114     if (result == 0) {          /* if error */
115         if (params)
116             ASN1_STRING_free(params);
117         return NULL;
118     }
119     return params;
120 }
121
122 static int gost_decode_nid_params(EVP_PKEY *pkey, int pkey_nid, int param_nid)
123 {
124     void *key_ptr = EVP_PKEY_get0(pkey);
125
126     switch (pkey_nid) {
127     case NID_id_GostR3410_2012_256:
128     case NID_id_GostR3410_2012_512:
129     case NID_id_GostR3410_2001:
130         if (!key_ptr) {
131             key_ptr = EC_KEY_new();
132             if (!EVP_PKEY_assign(pkey, pkey_nid, key_ptr)) {
133                 EC_KEY_free(key_ptr);
134                 break;
135             }
136         }
137         return fill_GOST_EC_params(key_ptr, param_nid);
138     }
139
140     return 0;
141 }
142
143 /*
144  * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting
145  * NID and parameters
146  */
147 static int decode_gost_algor_params(EVP_PKEY *pkey,
148                                     const X509_ALGOR *palg)
149 {
150     const ASN1_OBJECT *palg_obj = NULL;
151     int ptype = V_ASN1_UNDEF;
152     int pkey_nid = NID_undef, param_nid = NID_undef;
153     ASN1_STRING *pval = NULL;
154     const unsigned char *p;
155     GOST_KEY_PARAMS *gkp = NULL;
156
157     if (!pkey || !palg)
158         return 0;
159     X509_ALGOR_get0(&palg_obj, &ptype, (const void **)&pval, palg);
160     if (ptype != V_ASN1_SEQUENCE) {
161         GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
162                 GOST_R_BAD_KEY_PARAMETERS_FORMAT);
163         return 0;
164     }
165     p = pval->data;
166     pkey_nid = OBJ_obj2nid(palg_obj);
167
168     gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length);
169     if (!gkp) {
170         GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
171                 GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
172         return 0;
173     }
174     param_nid = OBJ_obj2nid(gkp->key_params);
175     GOST_KEY_PARAMS_free(gkp);
176     if (!EVP_PKEY_set_type(pkey, pkey_nid)) {
177         GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR);
178         return 0;
179     }
180     return gost_decode_nid_params(pkey, pkey_nid, param_nid);
181 }
182
183 static int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv)
184 {
185     switch (EVP_PKEY_base_id(pkey)) {
186     case NID_id_GostR3410_2012_512:
187     case NID_id_GostR3410_2012_256:
188     case NID_id_GostR3410_2001:
189         {
190             EC_KEY *ec = EVP_PKEY_get0(pkey);
191             if (!ec) {
192                 ec = EC_KEY_new();
193                 EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec);
194             }
195             if (!EC_KEY_set_private_key(ec, priv))
196                 return 0;
197             if (!EVP_PKEY_missing_parameters(pkey))
198                 return gost_ec_compute_public(ec);
199             break;
200         }
201     default:
202         return 0;
203     }
204     return 1;
205 }
206
207 BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey)
208 {
209     switch (EVP_PKEY_base_id(pkey)) {
210     case NID_id_GostR3410_2012_512:
211     case NID_id_GostR3410_2012_256:
212     case NID_id_GostR3410_2001:
213         {
214             EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
215             if (ec)
216                 return (BIGNUM *)EC_KEY_get0_private_key(ec);
217             break;
218         }
219     }
220     return NULL;
221 }
222
223 /*
224  * GOST CMS processing functions
225  */
226 /* FIXME reaarange declarations */
227 static int pub_decode_gost_ec(EVP_PKEY *pk, const X509_PUBKEY *pub);
228
229 static int gost_cms_set_kari_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
230 {
231         int ret = 0;
232         X509_ALGOR *alg;
233         ASN1_OCTET_STRING *ukm;
234
235         /* Deal with originator */
236         X509_ALGOR *pubalg = NULL;
237         ASN1_BIT_STRING *pubkey = NULL;
238
239         EVP_PKEY *peer_key = NULL;
240         X509_PUBKEY *tmp   = NULL;
241
242         int nid;
243         unsigned char shared_key[64];
244         size_t shared_key_size = 64;
245         const EVP_CIPHER *cipher = NULL;
246
247         if (CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm) == 0)
248                 goto err;
249
250         if (CMS_RecipientInfo_kari_get0_orig_id(ri, &pubalg, &pubkey, NULL, NULL, NULL) == 0)
251                   goto err;
252
253         nid = OBJ_obj2nid(alg->algorithm);
254         if (alg->parameter->type != V_ASN1_SEQUENCE)
255                   goto err;
256
257         switch (nid) {
258                 case NID_kuznyechik_kexp15:
259                 case NID_magma_kexp15:
260                         cipher = EVP_get_cipherbynid(nid);
261                         break;
262         }
263
264         if (cipher == NULL) {
265                         GOSTerr(GOST_F_GOST_CMS_SET_KARI_SHARED_INFO, GOST_R_CIPHER_NOT_FOUND);
266                   goto err;
267   }
268
269         if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_SET_IV,
270                 ASN1_STRING_length(ukm), (void *)ASN1_STRING_get0_data(ukm)) <= 0)
271                         goto err;
272
273         if (pubkey != NULL && pubalg != NULL) {
274                 const ASN1_OBJECT *paobj = NULL;
275                 int ptype = 0;
276                 const void *param = NULL;
277
278                 peer_key = EVP_PKEY_new();
279                 tmp = X509_PUBKEY_new();
280
281                 if ((peer_key == NULL) || (tmp == NULL)) {
282                         GOSTerr(GOST_F_GOST_CMS_SET_KARI_SHARED_INFO, ERR_R_MALLOC_FAILURE);
283                         goto err;
284                 }
285
286                 X509_ALGOR_get0(&paobj, &ptype, &param, pubalg);
287
288                 if (X509_PUBKEY_set0_param(tmp, (ASN1_OBJECT *)paobj,
289                         ptype, (void *)param,
290                         (unsigned char *)ASN1_STRING_get0_data(pubkey),
291                         ASN1_STRING_length(pubkey) ) == 0) {
292                                 GOSTerr(GOST_F_GOST_CMS_SET_KARI_SHARED_INFO, GOST_R_PUBLIC_KEY_UNDEFINED);
293                                 goto err;
294                 }
295
296                 if (pub_decode_gost_ec(peer_key, tmp) <= 0) {
297                                 GOSTerr(GOST_F_GOST_CMS_SET_KARI_SHARED_INFO, GOST_R_ERROR_DECODING_PUBLIC_KEY);
298                                 goto err;
299                 }
300
301                 if (EVP_PKEY_derive_set_peer(pctx, peer_key) <= 0) {
302                                 GOSTerr(GOST_F_GOST_CMS_SET_KARI_SHARED_INFO, GOST_R_ERROR_SETTING_PEER_KEY);
303                                 goto err;
304                 }
305         }
306
307         if (EVP_PKEY_derive(pctx, shared_key, &shared_key_size) <= 0) {
308                 GOSTerr(GOST_F_GOST_CMS_SET_KARI_SHARED_INFO, GOST_R_ERROR_COMPUTING_SHARED_KEY);
309                 goto err;
310         }
311
312         EVP_CIPHER_CTX_set_flags(CMS_RecipientInfo_kari_get0_ctx(ri), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
313         if (EVP_DecryptInit_ex(CMS_RecipientInfo_kari_get0_ctx(ri), cipher, NULL,
314                 shared_key, ukm->data+24) == 0)
315                         goto err;
316
317         ret = 1;
318 err:
319         EVP_PKEY_free(peer_key);
320         if (ret == 0) {
321                 X509_PUBKEY_free(tmp);
322         }
323
324         return ret;
325 }
326
327 static int gost_cms_set_ktri_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
328 {
329         X509_ALGOR *alg;
330         struct gost_pmeth_data *gctx = EVP_PKEY_CTX_get_data(pctx);
331
332         CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg);
333
334         switch (OBJ_obj2nid(alg->algorithm)) {
335                 case NID_kuznyechik_kexp15:
336                         gctx->cipher_nid = NID_kuznyechik_ctr;
337                         break;
338
339                 case NID_magma_kexp15:
340                         gctx->cipher_nid = NID_magma_ctr;
341                         break;
342
343                 case NID_id_GostR3410_2001:
344                 case NID_id_GostR3410_2001DH:
345                 case NID_id_GostR3410_2012_256:
346                 case NID_id_GostR3410_2012_512:
347                         gctx->cipher_nid = NID_id_Gost28147_89;
348                         break;
349
350                 default:
351                         GOSTerr(GOST_F_GOST_CMS_SET_KTRI_SHARED_INFO, GOST_R_UNSUPPORTED_RECIPIENT_INFO);
352                         return 0;
353         }
354
355         return 1;
356 }
357
358 static int gost_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
359 {
360         switch(CMS_RecipientInfo_type(ri)) {
361                 case CMS_RECIPINFO_AGREE:
362                         return gost_cms_set_kari_shared_info(pctx, ri);
363                 break;
364                 case CMS_RECIPINFO_TRANS:
365                         return gost_cms_set_ktri_shared_info(pctx, ri);
366                 break;
367         }
368
369         GOSTerr(GOST_F_GOST_CMS_SET_SHARED_INFO, GOST_R_UNSUPPORTED_RECIPIENT_INFO);
370         return 0;
371 }
372
373 static ASN1_STRING *gost_encode_cms_params(int ka_nid)
374 {
375         ASN1_STRING *ret = NULL;
376         ASN1_STRING *params = ASN1_STRING_new();
377
378         /* It's a hack. We have only one OID here, so we can use
379          * GOST_KEY_PARAMS which is a sequence of 3 OIDs,
380          * the 1st one is mandatory and the rest are optional */
381         GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
382
383         if (params == NULL || gkp == NULL) {
384                   GOSTerr(GOST_F_GOST_ENCODE_CMS_PARAMS, ERR_R_MALLOC_FAILURE);
385                         goto end;
386         }
387
388         gkp->key_params = OBJ_nid2obj(ka_nid);
389         params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
390
391         if (params->length < 0) {
392                   GOSTerr(GOST_F_GOST_ENCODE_CMS_PARAMS, ERR_R_MALLOC_FAILURE);
393                         goto end;
394         }
395
396         params->type = V_ASN1_SEQUENCE;
397         ret = params;
398
399 end:
400         GOST_KEY_PARAMS_free(gkp);
401
402         if (ret == NULL)
403                 ASN1_STRING_free(params);
404
405         return ret;
406 }
407
408 /*
409  * Control function
410  */
411 static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
412 {
413     int nid = EVP_PKEY_base_id(pkey), md_nid = NID_undef;
414     X509_ALGOR *alg1 = NULL, *alg2 = NULL;
415
416     switch (nid) {
417     case NID_id_GostR3410_2012_512:
418         md_nid = NID_id_GostR3411_2012_512;
419         break;
420     case NID_id_GostR3410_2012_256:
421         md_nid = NID_id_GostR3411_2012_256;
422         break;
423     case NID_id_GostR3410_2001:
424     case NID_id_GostR3410_94:
425         md_nid = NID_id_GostR3411_94;
426         break;
427     default:
428         return -1;
429     }
430
431     switch (op) {
432     case ASN1_PKEY_CTRL_PKCS7_SIGN:
433         if (arg1 == 0) {
434             PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, NULL,
435                                         &alg1, &alg2);
436             X509_ALGOR_set0(alg1, OBJ_nid2obj(md_nid), V_ASN1_NULL, 0);
437             X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
438         }
439         return 1;
440 #ifndef OPENSSL_NO_CMS
441     case ASN1_PKEY_CTRL_CMS_SIGN:
442         if (arg1 == 0) {
443             CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, NULL, NULL,
444                                      &alg1, &alg2);
445             X509_ALGOR_set0(alg1, OBJ_nid2obj(md_nid), V_ASN1_NULL, 0);
446             X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
447         }
448         return 1;
449 #endif
450     case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
451         if (arg1 == 0) { /* Encryption */
452             ASN1_STRING *params = encode_gost_algor_params(pkey);
453             if (!params) {
454                 return -1;
455             }
456             PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg1);
457             X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_id(pkey)),
458                             V_ASN1_SEQUENCE, params);
459                                 }
460         return 1;
461 #ifndef OPENSSL_NO_CMS
462     case ASN1_PKEY_CTRL_CMS_ENVELOPE:
463         if (arg1 == 0) {
464           EVP_PKEY_CTX *pctx;
465           CMS_RecipientInfo *ri = arg2;
466
467           struct gost_pmeth_data *gctx = NULL;
468           ASN1_STRING *params = NULL;
469
470           pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
471           if (!pctx)
472             return 0;
473
474           gctx = EVP_PKEY_CTX_get_data(pctx);
475
476           switch (gctx->cipher_nid) {
477             case NID_magma_ctr:
478             case NID_kuznyechik_ctr:
479               {
480                 int ka_nid;
481
482                 nid = (gctx->cipher_nid == NID_magma_ctr) ? NID_magma_kexp15 :
483                   NID_kuznyechik_kexp15;
484
485                 ka_nid = (EVP_PKEY_base_id(pkey) == NID_id_GostR3410_2012_256) ?
486                   NID_id_tc26_agreement_gost_3410_2012_256 : NID_id_tc26_agreement_gost_3410_2012_512;
487
488                 params = gost_encode_cms_params(ka_nid);
489               }
490               break;
491             default:
492                 params = encode_gost_algor_params(pkey);
493               break;
494           }
495
496           if (params == NULL)
497               return -1;
498
499           CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL,
500               NULL, &alg1);
501           X509_ALGOR_set0(alg1, OBJ_nid2obj(nid), V_ASN1_SEQUENCE, params);
502         } else {
503           EVP_PKEY_CTX *pctx;
504           CMS_RecipientInfo *ri = arg2;
505           pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
506           if (!pctx)
507               return 0;
508           return gost_cms_set_shared_info(pctx, ri);
509         }
510         return 1;
511 #ifdef ASN1_PKEY_CTRL_CMS_RI_TYPE
512   case ASN1_PKEY_CTRL_CMS_RI_TYPE:
513         *(int *)arg2 = CMS_RECIPINFO_TRANS;
514         return 1;
515         case ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED:
516                         if (arg1 == CMS_RECIPINFO_AGREE || arg1 == CMS_RECIPINFO_TRANS) {
517           *(int *)arg2 = 1;
518                                   return 1;
519       }
520                         else
521                                   return 0;
522                         break;
523 #endif
524 #endif
525     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
526         *(int *)arg2 = md_nid;
527         return 2;
528     }
529
530     return -2;
531 }
532
533 /* --------------------- free functions * ------------------------------*/
534 static void pkey_free_gost_ec(EVP_PKEY *key)
535 {
536     EC_KEY_free((EC_KEY *)EVP_PKEY_get0(key));
537 }
538
539 /* ------------------ private key functions  -----------------------------*/
540
541 static BIGNUM *unmask_priv_key(EVP_PKEY *pk,
542                                const unsigned char *buf, int len, int num_masks)
543 {
544     BIGNUM *pknum_masked = NULL, *q = NULL;
545     const EC_KEY *key_ptr = (pk) ? EVP_PKEY_get0(pk) : NULL;
546     const EC_GROUP *group = (key_ptr) ? EC_KEY_get0_group(key_ptr) : NULL;
547
548     pknum_masked = BN_lebin2bn(buf, len, BN_secure_new());
549     if (!pknum_masked)
550         return NULL;
551
552     if (num_masks > 0) {
553         /*
554          * XXX Remove sign by gost94
555          */
556         const unsigned char *p = buf + num_masks * len;
557
558         q = BN_new();
559         if (!q || !group || EC_GROUP_get_order(group, q, NULL) <= 0) {
560             BN_free(pknum_masked);
561             pknum_masked = NULL;
562             goto end;
563         }
564
565         for (; p != buf; p -= len) {
566             BIGNUM *mask = BN_lebin2bn(p, len, BN_secure_new());
567             BN_CTX *ctx = BN_CTX_secure_new();
568
569             BN_mod_mul(pknum_masked, pknum_masked, mask, q, ctx);
570
571             BN_CTX_free(ctx);
572             BN_free(mask);
573         }
574     }
575
576  end:
577     if (q)
578         BN_free(q);
579     return pknum_masked;
580 }
581
582 static int priv_decode_gost(EVP_PKEY *pk,
583                             const PKCS8_PRIV_KEY_INFO *p8inf)
584 {
585     const unsigned char *pkey_buf = NULL, *p = NULL;
586     int priv_len = 0;
587     BIGNUM *pk_num = NULL;
588     int ret = 0;
589     const X509_ALGOR *palg = NULL;
590     const ASN1_OBJECT *palg_obj = NULL;
591     ASN1_INTEGER *priv_key = NULL;
592     int expected_key_len;
593
594     if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf))
595         return 0;
596     p = pkey_buf;
597     if (!decode_gost_algor_params(pk, palg)) {
598         return 0;
599     }
600
601     expected_key_len = pkey_bits_gost(pk) > 0 ? pkey_bits_gost(pk) / 8 : 0;
602     if (expected_key_len == 0) {
603         GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
604         return 0;
605     }
606
607     if (priv_len % expected_key_len == 0) {
608         /* Key is not wrapped but masked */
609         pk_num = unmask_priv_key(pk, pkey_buf, expected_key_len,
610                                  priv_len / expected_key_len - 1);
611     } else if (V_ASN1_OCTET_STRING == *p) {
612         /* New format - Little endian octet string */
613         ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len);
614         if (!s || ((s->length != 32) && (s->length != 64))) {
615             ASN1_STRING_free(s);
616             GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
617             return 0;
618         }
619         pk_num = BN_lebin2bn(s->data, s->length, BN_secure_new());
620         ASN1_STRING_free(s);
621     } else if (V_ASN1_INTEGER == *p) {
622         priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
623         if (!priv_key) {
624             GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
625             return 0;
626         }
627         pk_num = ASN1_INTEGER_to_BN(priv_key, BN_secure_new());
628         ASN1_INTEGER_free(priv_key);
629     } else if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == *p) {
630         MASKED_GOST_KEY *mgk = d2i_MASKED_GOST_KEY(NULL, &p, priv_len);
631
632         if (!mgk) {
633             GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
634             return 0;
635         }
636
637         priv_len = mgk->masked_priv_key->length;
638         if (priv_len % expected_key_len) {
639             MASKED_GOST_KEY_free(mgk);
640             GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
641             return 0;
642         }
643
644         pk_num = unmask_priv_key(pk, mgk->masked_priv_key->data,
645                                  expected_key_len,
646                                  priv_len / expected_key_len - 1);
647         MASKED_GOST_KEY_free(mgk);
648     } else {
649         GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
650         return 0;
651     }
652
653     if (pk_num == NULL) {
654         GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
655         return 0;
656     }
657
658     ret = gost_set_priv_key(pk, pk_num);
659     BN_free(pk_num);
660     return ret;
661 }
662
663 /* ----------------------------------------------------------------------*/
664 static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
665 {
666     ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
667     ASN1_STRING *params = NULL;
668     unsigned char *buf = NULL;
669     int key_len = pkey_bits_gost(pk), i = 0;
670     /* unmasked private key */
671     const char *pk_format = get_gost_engine_param(GOST_PARAM_PK_FORMAT);
672
673     key_len = (key_len < 0) ? 0 : key_len / 8;
674     if (key_len == 0 || !(buf = OPENSSL_secure_malloc(key_len))) {
675         return 0;
676     }
677
678     if (!store_bignum(gost_get0_priv_key(pk), buf, key_len)) {
679         OPENSSL_secure_free(buf);
680         return 0;
681     }
682
683     params = encode_gost_algor_params(pk);
684     if (!params) {
685         OPENSSL_secure_free(buf);
686         return 0;
687     }
688
689     /* Convert buf to Little-endian */
690     for (i = 0; i < key_len / 2; i++) {
691         unsigned char tmp = buf[i];
692         buf[i] = buf[key_len - 1 - i];
693         buf[key_len - 1 - i] = tmp;
694     }
695
696     if (pk_format != NULL && strcmp(pk_format, PK_WRAP_PARAM) == 0) {
697         ASN1_STRING *octet = ASN1_STRING_new();
698         int priv_len = 0;
699         unsigned char *priv_buf = NULL;
700         if (!octet || !ASN1_OCTET_STRING_set(octet, buf, key_len)) {
701             ASN1_STRING_free(octet);
702             ASN1_STRING_free(params);
703             OPENSSL_secure_free(buf);
704             return 0;
705         }
706         priv_len = i2d_ASN1_OCTET_STRING(octet, &priv_buf);
707         ASN1_STRING_free(octet);
708         OPENSSL_secure_free(buf);
709
710         return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params,
711                                priv_buf, priv_len);
712     }
713
714     return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params,
715                            buf, key_len);
716 }
717
718 /* --------- printing keys --------------------------------*/
719 static int print_gost_priv(BIO *out, const EVP_PKEY *pkey, int indent)
720 {
721     BIGNUM *key;
722
723     if (!BIO_indent(out, indent, 128))
724         return 0;
725     BIO_printf(out, "Private key: ");
726     key = gost_get0_priv_key(pkey);
727     if (!key)
728         BIO_printf(out, "<undefined>");
729     else
730         BN_print(out, key);
731     BIO_printf(out, "\n");
732
733     return 1;
734 }
735
736 static int print_gost_ec_pub(BIO *out, const EVP_PKEY *pkey, int indent)
737 {
738     BN_CTX *ctx;
739     BIGNUM *X, *Y;
740     const EC_POINT *pubkey;
741     const EC_GROUP *group;
742     EC_KEY *key = (EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey);
743     int ok = 0;
744
745     ctx = BN_CTX_new();
746     if (!ctx) {
747         GOSTerr(GOST_F_PRINT_GOST_EC_PUB, ERR_R_MALLOC_FAILURE);
748         return 0;
749     }
750
751     BN_CTX_start(ctx);
752     X = BN_CTX_get(ctx);
753     Y = BN_CTX_get(ctx);
754     pubkey = (key) ? EC_KEY_get0_public_key(key) : NULL;
755     group = (key) ? EC_KEY_get0_group(key) : NULL;
756     if (!pubkey || !group)
757         goto err;
758
759     if (!EC_POINT_get_affine_coordinates(group, pubkey, X, Y, ctx)) {
760         GOSTerr(GOST_F_PRINT_GOST_EC_PUB, ERR_R_EC_LIB);
761         goto err;
762     }
763     if (!BIO_indent(out, indent, 128))
764         goto err;
765     BIO_printf(out, "Public key:\n");
766     if (!BIO_indent(out, indent + 3, 128))
767         goto err;
768     BIO_printf(out, "X:");
769     BN_print(out, X);
770     BIO_printf(out, "\n");
771     if (!BIO_indent(out, indent + 3, 128))
772         goto err;
773     BIO_printf(out, "Y:");
774     BN_print(out, Y);
775     BIO_printf(out, "\n");
776     ok = 1;
777  err:
778     BN_CTX_end(ctx);
779     BN_CTX_free(ctx);
780
781     return ok;
782 }
783
784 static int print_gost_ec_param(BIO *out, const EVP_PKEY *pkey, int indent)
785 {
786     EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
787     const EC_GROUP *group = (ec) ? EC_KEY_get0_group(ec) : NULL;
788     int param_nid;
789
790     if (!group)
791         return 0;
792
793     param_nid = EC_GROUP_get_curve_name(group);
794     if (!BIO_indent(out, indent, 128))
795         return 0;
796     BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid));
797
798     return 1;
799 }
800
801 static int print_gost_ec(BIO *out, const EVP_PKEY *pkey, int indent,
802                          ASN1_PCTX *pctx, int type)
803 {
804     if (type == 2) {
805         if (print_gost_priv(out, pkey, indent) == 0)
806             return 0;
807     }
808     if (type >= 1) {
809         if (print_gost_ec_pub(out, pkey, indent) == 0)
810             return 0;
811     }
812
813     return print_gost_ec_param(out, pkey, indent);
814 }
815
816 static int param_print_gost_ec(BIO *out, const EVP_PKEY *pkey, int indent,
817                                ASN1_PCTX *pctx)
818 {
819     return print_gost_ec(out, pkey, indent, pctx, 0);
820 }
821
822 static int pub_print_gost_ec(BIO *out, const EVP_PKEY *pkey, int indent,
823                              ASN1_PCTX *pctx)
824 {
825     return print_gost_ec(out, pkey, indent, pctx, 1);
826 }
827
828 static int priv_print_gost_ec(BIO *out, const EVP_PKEY *pkey, int indent,
829                               ASN1_PCTX *pctx)
830 {
831     return print_gost_ec(out, pkey, indent, pctx, 2);
832 }
833
834 /* ---------------------------------------------------------------------*/
835 static int param_missing_gost_ec(const EVP_PKEY *pk)
836 {
837     const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
838     if (!ec)
839         return 1;
840     if (!EC_KEY_get0_group(ec))
841         return 1;
842     return 0;
843 }
844
845 static int param_copy_gost_ec(EVP_PKEY *to, const EVP_PKEY *from)
846 {
847     EC_KEY *eto = EVP_PKEY_get0(to);
848     const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from);
849     if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
850         GOSTerr(GOST_F_PARAM_COPY_GOST_EC, GOST_R_INCOMPATIBLE_ALGORITHMS);
851         return 0;
852     }
853     if (!efrom) {
854         GOSTerr(GOST_F_PARAM_COPY_GOST_EC, GOST_R_KEY_PARAMETERS_MISSING);
855         return 0;
856     }
857     if (!eto) {
858         eto = EC_KEY_new();
859         if (!eto) {
860             GOSTerr(GOST_F_PARAM_COPY_GOST_EC, ERR_R_MALLOC_FAILURE);
861             return 0;
862         }
863         if (!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) {
864             GOSTerr(GOST_F_PARAM_COPY_GOST_EC, ERR_R_INTERNAL_ERROR);
865             EC_KEY_free(eto);
866             return 0;
867         }
868     }
869     if (!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) {
870         GOSTerr(GOST_F_PARAM_COPY_GOST_EC, ERR_R_INTERNAL_ERROR);
871         return 0;
872     }
873     if (EC_KEY_get0_private_key(eto)) {
874         return gost_ec_compute_public(eto);
875     }
876     return 1;
877 }
878
879 static int param_cmp_gost_ec(const EVP_PKEY *a, const EVP_PKEY *b)
880 {
881     const EC_GROUP *group_a, *group_b;
882     EC_KEY *ec_a = EVP_PKEY_get0((EVP_PKEY *)a);
883     EC_KEY *ec_b = EVP_PKEY_get0((EVP_PKEY *)b);
884     if (!ec_a || !ec_b)
885         return 0;
886
887     group_a = EC_KEY_get0_group(ec_a);
888     group_b = EC_KEY_get0_group(ec_b);
889     if (!group_a || !group_b)
890         return 0;
891
892     if (EC_GROUP_get_curve_name(group_a) == EC_GROUP_get_curve_name(group_b)) {
893         return 1;
894     }
895     return 0;
896 }
897
898 /* ---------- Public key functions * --------------------------------------*/
899 static int pub_decode_gost_ec(EVP_PKEY *pk, const X509_PUBKEY *pub)
900 {
901     X509_ALGOR *palg = NULL;
902     const unsigned char *pubkey_buf = NULL;
903     unsigned char *databuf;
904     ASN1_OBJECT *palgobj = NULL;
905     int pub_len;
906     EC_POINT *pub_key;
907     BIGNUM *X, *Y;
908     ASN1_OCTET_STRING *octet = NULL;
909     size_t len;
910     const EC_GROUP *group;
911
912     if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub))
913         return 0;
914     EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL);
915     if (!decode_gost_algor_params(pk, palg))
916         return 0;
917     group = EC_KEY_get0_group(EVP_PKEY_get0(pk));
918     octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
919     if (!octet) {
920         GOSTerr(GOST_F_PUB_DECODE_GOST_EC, ERR_R_MALLOC_FAILURE);
921         return 0;
922     }
923     databuf = OPENSSL_malloc(octet->length);
924     if (databuf == NULL) {
925         GOSTerr(GOST_F_PUB_DECODE_GOST_EC, ERR_R_MALLOC_FAILURE);
926         ASN1_OCTET_STRING_free(octet);
927         return 0;
928     }
929
930     BUF_reverse(databuf, octet->data, octet->length);
931     len = octet->length / 2;
932     ASN1_OCTET_STRING_free(octet);
933
934     Y = BN_bin2bn(databuf, len, NULL);
935     X = BN_bin2bn(databuf + len, len, NULL);
936     OPENSSL_free(databuf);
937     pub_key = EC_POINT_new(group);
938     if (!EC_POINT_set_affine_coordinates(group, pub_key, X, Y, NULL)) {
939         GOSTerr(GOST_F_PUB_DECODE_GOST_EC, ERR_R_EC_LIB);
940         EC_POINT_free(pub_key);
941         BN_free(X);
942         BN_free(Y);
943         return 0;
944     }
945     BN_free(X);
946     BN_free(Y);
947     if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) {
948         GOSTerr(GOST_F_PUB_DECODE_GOST_EC, ERR_R_EC_LIB);
949         EC_POINT_free(pub_key);
950         return 0;
951     }
952     EC_POINT_free(pub_key);
953     return 1;
954
955 }
956
957 static int pub_encode_gost_ec(X509_PUBKEY *pub, const EVP_PKEY *pk)
958 {
959     ASN1_OBJECT *algobj;
960     ASN1_OCTET_STRING *octet = NULL;
961     void *pval;
962     unsigned char *buf = NULL, *databuf = NULL;
963     int data_len, ret = -1;
964     const EC_POINT *pub_key;
965     BIGNUM *X = NULL, *Y = NULL, *order;
966     const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
967     int ptype = V_ASN1_SEQUENCE;
968     ASN1_STRING *params;
969
970     algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
971
972     params = encode_gost_algor_params(pk);
973     pval = params;
974
975     order = BN_new();
976     if (order == NULL || EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL) == 0) {
977         GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE);
978         goto err;
979     }
980     EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL);
981     pub_key = EC_KEY_get0_public_key(ec);
982     if (!pub_key) {
983         GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, GOST_R_PUBLIC_KEY_UNDEFINED);
984         goto err;
985     }
986     X = BN_new();
987     Y = BN_new();
988     if (!X || !Y) {
989         GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE);
990         goto err;
991     }
992     if (!EC_POINT_get_affine_coordinates(EC_KEY_get0_group(ec),
993                                              pub_key, X, Y, NULL)) {
994         GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_INTERNAL_ERROR);
995         goto err;
996     }
997     data_len = 2 * BN_num_bytes(order);
998     databuf = OPENSSL_zalloc(data_len);
999     if (databuf == NULL) {
1000         GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE);
1001         goto err;
1002     }
1003
1004     store_bignum(X, databuf + data_len / 2, data_len / 2);
1005     store_bignum(Y, databuf, data_len / 2);
1006
1007     BUF_reverse(databuf, NULL, data_len);
1008
1009     octet = ASN1_OCTET_STRING_new();
1010     if (octet == NULL) {
1011         GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE);
1012         goto err;
1013     }
1014
1015     if (0 == ASN1_STRING_set(octet, databuf, data_len)) {
1016         GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE);
1017         goto err;
1018     }
1019
1020     ret = i2d_ASN1_OCTET_STRING(octet, &buf);
1021  err:
1022     ASN1_BIT_STRING_free(octet);
1023     if (X)
1024         BN_free(X);
1025     if (Y)
1026         BN_free(Y);
1027     if (order)
1028         BN_free(order);
1029     if (databuf)
1030         OPENSSL_free(databuf);
1031
1032     if (ret < 0)
1033         return 0;
1034     return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
1035 }
1036
1037 static int pub_cmp_gost_ec(const EVP_PKEY *a, const EVP_PKEY *b)
1038 {
1039     const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a);
1040     const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b);
1041     const EC_POINT *ka, *kb;
1042     if (!ea || !eb)
1043         return 0;
1044     ka = EC_KEY_get0_public_key(ea);
1045     kb = EC_KEY_get0_public_key(eb);
1046     if (!ka || !kb)
1047         return 0;
1048     return (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL));
1049 }
1050
1051 static int pkey_size_gost(const EVP_PKEY *pk)
1052 {
1053     if (!pk)
1054         return -1;
1055
1056     switch (EVP_PKEY_base_id(pk)) {
1057     case NID_id_GostR3410_94:
1058     case NID_id_GostR3410_2001:
1059     case NID_id_GostR3410_2012_256:
1060         return 64;
1061     case NID_id_GostR3410_2012_512:
1062         return 128;
1063     }
1064
1065     return -1;
1066 }
1067
1068 /* ---------------------- ASN1 METHOD for GOST MAC  -------------------*/
1069 static void mackey_free_gost(EVP_PKEY *pk)
1070 {
1071     OPENSSL_free(EVP_PKEY_get0(pk));
1072 }
1073
1074 static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
1075 {
1076     switch (op) {
1077     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
1078         if (arg2) {
1079             *(int *)arg2 = NID_id_Gost28147_89_MAC;
1080             return 2;
1081         }
1082     }
1083     return -2;
1084 }
1085
1086 static int mac_ctrl_gost_12(EVP_PKEY *pkey, int op, long arg1, void *arg2)
1087 {
1088     switch (op) {
1089     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
1090         if (arg2) {
1091             *(int *)arg2 = NID_gost_mac_12;
1092             return 2;
1093         }
1094     }
1095     return -2;
1096 }
1097
1098 static int mac_ctrl_magma(EVP_PKEY *pkey, int op, long arg1, void *arg2)
1099 {
1100     switch (op) {
1101     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
1102         if (arg2) {
1103             *(int *)arg2 = NID_magma_mac;
1104             return 2;
1105         }
1106     }
1107     return -2;
1108 }
1109
1110 static int mac_ctrl_grasshopper(EVP_PKEY *pkey, int op, long arg1, void *arg2)
1111 {
1112     switch (op) {
1113     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
1114         if (arg2) {
1115             *(int *)arg2 = NID_grasshopper_mac;
1116             return 2;
1117         }
1118     }
1119     return -2;
1120 }
1121
1122 static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
1123 {
1124     int nid =
1125         EC_GROUP_get_curve_name(EC_KEY_get0_group
1126                                 (EVP_PKEY_get0((EVP_PKEY *)pkey)));
1127     return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder);
1128 }
1129
1130 static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder,
1131                                  int derlen)
1132 {
1133     ASN1_OBJECT *obj = NULL;
1134     int nid;
1135     if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
1136         return 0;
1137     }
1138     nid = OBJ_obj2nid(obj);
1139     ASN1_OBJECT_free(obj);
1140
1141     return gost_decode_nid_params(pkey, NID_id_GostR3410_2001, nid);
1142 }
1143
1144 /* ----------------------------------------------------------------------*/
1145 int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth,
1146                         const char *pemstr, const char *info)
1147 {
1148     *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info);
1149     if (!*ameth)
1150         return 0;
1151     switch (nid) {
1152     case NID_id_GostR3410_2001:
1153         EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost_ec);
1154         EVP_PKEY_asn1_set_private(*ameth,
1155                                   priv_decode_gost, priv_encode_gost,
1156                                   priv_print_gost_ec);
1157
1158         EVP_PKEY_asn1_set_param(*ameth,
1159                                 gost2001_param_decode, gost2001_param_encode,
1160                                 param_missing_gost_ec, param_copy_gost_ec,
1161                                 param_cmp_gost_ec, param_print_gost_ec);
1162         EVP_PKEY_asn1_set_public(*ameth,
1163                                  pub_decode_gost_ec, pub_encode_gost_ec,
1164                                  pub_cmp_gost_ec, pub_print_gost_ec,
1165                                  pkey_size_gost, pkey_bits_gost);
1166
1167         EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost);
1168         EVP_PKEY_asn1_set_security_bits(*ameth, pkey_bits_gost);
1169         break;
1170     case NID_id_GostR3410_2012_256:
1171     case NID_id_GostR3410_2012_512:
1172         EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost_ec);
1173         EVP_PKEY_asn1_set_private(*ameth,
1174                                   priv_decode_gost, priv_encode_gost,
1175                                   priv_print_gost_ec);
1176
1177         EVP_PKEY_asn1_set_param(*ameth,
1178                                 NULL, NULL,
1179                                 param_missing_gost_ec, param_copy_gost_ec,
1180                                 param_cmp_gost_ec, NULL);
1181
1182         EVP_PKEY_asn1_set_public(*ameth,
1183                                  pub_decode_gost_ec, pub_encode_gost_ec,
1184                                  pub_cmp_gost_ec, pub_print_gost_ec,
1185                                  pkey_size_gost, pkey_bits_gost);
1186
1187         EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost);
1188         EVP_PKEY_asn1_set_security_bits(*ameth, pkey_bits_gost);
1189         break;
1190     case NID_id_Gost28147_89_MAC:
1191         EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
1192         EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost);
1193         break;
1194     case NID_gost_mac_12:
1195         EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
1196         EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost_12);
1197         break;
1198     case NID_magma_mac:
1199         EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
1200         EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_magma);
1201         break;
1202     case NID_grasshopper_mac:
1203         EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
1204         EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_grasshopper);
1205         break;
1206     }
1207     return 1;
1208 }