]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_pmeth.c
Free memory
[openssl-gost/engine.git] / gost_pmeth.c
1 /**********************************************************************
2  *                          gost_pmeth.c                              *
3  *             Copyright (c) 2005-2013 Cryptocom LTD                  *
4  *         This file is distributed under the same license as OpenSSL *
5  *                                                                    *
6  *   Implementation of RFC 4357 (GOST R 34.10) Publick key method     *
7  *       for OpenSSL                                                  *
8  *          Requires OpenSSL 1.0.0+ for compilation                   *
9  **********************************************************************/
10 #include <openssl/evp.h>
11 #include <openssl/objects.h>
12 #include <openssl/ec.h>
13 #include <openssl/err.h>
14 #include <openssl/x509v3.h>     /* For string_to_hex */
15 #include <openssl/opensslv.h>   /* For OPENSSL_VERSION_MAJOR */
16 #include <stdlib.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include "gost_lcl.h"
20 #include "e_gost_err.h"
21
22 #define ossl3_const
23 #ifdef OPENSSL_VERSION_MAJOR
24 #undef ossl3_const
25 #define ossl3_const const
26 #endif
27
28 /* -----init, cleanup, copy - uniform for all algs  --------------*/
29 /* Allocates new gost_pmeth_data structure and assigns it as data */
30 static int pkey_gost_init(EVP_PKEY_CTX *ctx)
31 {
32     struct gost_pmeth_data *data;
33     EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
34
35     data = OPENSSL_malloc(sizeof(*data));
36     if (!data)
37         return 0;
38     memset(data, 0, sizeof(*data));
39     if (pkey && EVP_PKEY_get0(pkey)) {
40         switch (EVP_PKEY_base_id(pkey)) {
41         case NID_id_GostR3410_2001:
42         case NID_id_GostR3410_2012_256:
43         case NID_id_GostR3410_2012_512:
44             {
45                 const EC_GROUP *group =
46                     EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey));
47                 if (group != NULL) {
48                     data->sign_param_nid = EC_GROUP_get_curve_name(group);
49                     break;
50                 }
51                 /* else */
52             }
53         default:
54             OPENSSL_free(data);
55             return 0;
56         }
57     }
58     EVP_PKEY_CTX_set_data(ctx, data);
59     return 1;
60 }
61
62 /* Copies contents of gost_pmeth_data structure */
63 static int pkey_gost_copy(EVP_PKEY_CTX *dst, ossl3_const EVP_PKEY_CTX *src)
64 {
65     struct gost_pmeth_data *dst_data, *src_data;
66     if (!pkey_gost_init(dst)) {
67         return 0;
68     }
69     src_data = EVP_PKEY_CTX_get_data(src);
70     dst_data = EVP_PKEY_CTX_get_data(dst);
71     if (!src_data || !dst_data)
72         return 0;
73
74     *dst_data = *src_data;
75     if (src_data->shared_ukm) {
76         dst_data->shared_ukm = NULL;
77     }
78     return 1;
79 }
80
81 /* Frees up gost_pmeth_data structure */
82 static void pkey_gost_cleanup(EVP_PKEY_CTX *ctx)
83 {
84     struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
85     if (!data)
86         return;
87     OPENSSL_free(data->shared_ukm);
88     OPENSSL_free(data);
89 }
90
91 /* --------------------- control functions  ------------------------------*/
92 static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
93 {
94     struct gost_pmeth_data *pctx =
95         (struct gost_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
96     if (pctx == NULL)
97         return 0;
98
99     switch (type) {
100     case EVP_PKEY_CTRL_MD:
101         {
102             EVP_PKEY *key = EVP_PKEY_CTX_get0_pkey(ctx);
103             int pkey_nid = (key == NULL) ? NID_undef : EVP_PKEY_base_id(key);
104
105             OPENSSL_assert(p2 != NULL);
106
107             switch (EVP_MD_type((const EVP_MD *)p2)) {
108             case NID_id_GostR3411_94:
109                 if (pkey_nid == NID_id_GostR3410_2001
110                     || pkey_nid == NID_id_GostR3410_94) {
111                     pctx->md = (EVP_MD *)p2;
112                     return 1;
113                 }
114                 break;
115
116             case NID_id_GostR3411_2012_256:
117                 if (pkey_nid == NID_id_GostR3410_2012_256) {
118                     pctx->md = (EVP_MD *)p2;
119                     return 1;
120                 }
121                 break;
122
123             case NID_id_GostR3411_2012_512:
124                 if (pkey_nid == NID_id_GostR3410_2012_512) {
125                     pctx->md = (EVP_MD *)p2;
126                     return 1;
127                 }
128                 break;
129             }
130
131             GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
132             return 0;
133         }
134
135     case EVP_PKEY_CTRL_GET_MD:
136         *(const EVP_MD **)p2 = pctx->md;
137         return 1;
138
139     case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
140     case EVP_PKEY_CTRL_PKCS7_DECRYPT:
141     case EVP_PKEY_CTRL_PKCS7_SIGN:
142     case EVP_PKEY_CTRL_DIGESTINIT:
143 #ifndef OPENSSL_NO_CMS
144     case EVP_PKEY_CTRL_CMS_ENCRYPT:
145     case EVP_PKEY_CTRL_CMS_DECRYPT:
146     case EVP_PKEY_CTRL_CMS_SIGN:
147 #endif
148         return 1;
149
150     case EVP_PKEY_CTRL_GOST_PARAMSET:
151         pctx->sign_param_nid = (int)p1;
152         return 1;
153     case EVP_PKEY_CTRL_SET_IV:
154         OPENSSL_assert(p2 != NULL);
155         pctx->shared_ukm = OPENSSL_malloc((int)p1);
156         if (pctx->shared_ukm == NULL) {
157             GOSTerr(GOST_F_PKEY_GOST_CTRL, ERR_R_MALLOC_FAILURE);
158             return 0;
159         }
160         memcpy(pctx->shared_ukm, p2, (int)p1);
161         pctx->shared_ukm_size = p1;
162         return 1;
163     case EVP_PKEY_CTRL_CIPHER:
164         pctx->cipher_nid = p1;
165         return 1;
166     case EVP_PKEY_CTRL_PEER_KEY:
167         if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */
168             return 1;
169         if (p1 == 2)            /* TLS: peer key used? */
170             return pctx->peer_key_used;
171         if (p1 == 3)            /* TLS: peer key used! */
172             return (pctx->peer_key_used = 1);
173         break;
174     }
175
176     GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_CTRL_CALL_FAILED);
177     return -2;
178 }
179
180 static int pkey_gost_ec_ctrl_str_common(EVP_PKEY_CTX *ctx,
181                                      const char *type, const char *value)
182 {
183   if (0 == strcmp(type, ukm_ctrl_string)) {
184     unsigned char ukm_buf[32], *tmp = NULL;
185     long len = 0;
186     tmp = OPENSSL_hexstr2buf(value, &len);
187     if (tmp == NULL)
188       return 0;
189
190     if (len > 32) {
191       OPENSSL_free(tmp);
192       GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_COMMON, GOST_R_CTRL_CALL_FAILED);
193       return 0;
194     }
195     memcpy(ukm_buf, tmp, len);
196     OPENSSL_free(tmp);
197
198     return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_SET_IV, len, ukm_buf);
199   }
200   return -2;
201 }
202
203 static int pkey_gost_ec_ctrl_str_256(EVP_PKEY_CTX *ctx,
204                                      const char *type, const char *value)
205 {
206     if (strcmp(type, param_ctrl_string) == 0) {
207         int param_nid = 0;
208
209         if (!value) {
210             return 0;
211         }
212         if (strlen(value) == 1) {
213             switch (toupper((unsigned char)value[0])) {
214             case 'A':
215                 param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
216                 break;
217             case 'B':
218                 param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
219                 break;
220             case 'C':
221                 param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
222                 break;
223             case '0':
224                 param_nid = NID_id_GostR3410_2001_TestParamSet;
225                 break;
226             default:
227                 return 0;
228             }
229         } else if ((strlen(value) == 2)
230                    && (toupper((unsigned char)value[0]) == 'X')) {
231             switch (toupper((unsigned char)value[1])) {
232             case 'A':
233                 param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
234                 break;
235             case 'B':
236                 param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
237                 break;
238             default:
239                 return 0;
240             }
241     } else if ((strlen(value) == 3)
242         && (toupper((unsigned char)value[0]) == 'T')
243         && (toupper((unsigned char)value[1]) == 'C')) {
244             switch (toupper((unsigned char)value[2])) {
245             case 'A':
246                 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetA;
247                 break;
248             case 'B':
249                 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetB;
250                 break;
251             case 'C':
252                 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetC;
253                 break;
254             case 'D':
255                 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetD;
256                 break;
257             default:
258                 return 0;
259             }
260         } else {
261             R3410_ec_params *p = R3410_2001_paramset;
262             param_nid = OBJ_txt2nid(value);
263             if (param_nid == NID_undef) {
264                 return 0;
265             }
266             for (; p->nid != NID_undef; p++) {
267                 if (p->nid == param_nid)
268                     break;
269             }
270             if (p->nid == NID_undef) {
271                 GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_256,
272                         GOST_R_INVALID_PARAMSET);
273                 return 0;
274             }
275         }
276
277         return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
278                               param_nid, NULL);
279     }
280
281     return pkey_gost_ec_ctrl_str_common(ctx, type, value);
282 }
283
284 static int pkey_gost_ec_ctrl_str_512(EVP_PKEY_CTX *ctx,
285                                      const char *type, const char *value)
286 {
287     int param_nid = NID_undef;
288
289     if (strcmp(type, param_ctrl_string))
290       return pkey_gost_ec_ctrl_str_common(ctx, type, value);
291
292     if (!value)
293         return 0;
294
295     if (strlen(value) == 1) {
296         switch (toupper((unsigned char)value[0])) {
297         case 'A':
298             param_nid = NID_id_tc26_gost_3410_2012_512_paramSetA;
299             break;
300
301         case 'B':
302             param_nid = NID_id_tc26_gost_3410_2012_512_paramSetB;
303             break;
304
305         case 'C':
306             param_nid = NID_id_tc26_gost_3410_2012_512_paramSetC;
307             break;
308
309         default:
310             return 0;
311         }
312     } else {
313         R3410_ec_params *p = R3410_2012_512_paramset;
314         param_nid = OBJ_txt2nid(value);
315         if (param_nid == NID_undef)
316             return 0;
317
318         while (p->nid != NID_undef && p->nid != param_nid)
319             p++;
320
321         if (p->nid == NID_undef) {
322             GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_512,
323                     GOST_R_INVALID_PARAMSET);
324             return 0;
325         }
326     }
327
328     return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, param_nid, NULL);
329 }
330
331 /* --------------------- key generation  --------------------------------*/
332
333 static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx)
334 {
335     return 1;
336 }
337
338 static int pkey_gost2001_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
339 {
340     struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
341     EC_KEY *ec = NULL;
342
343     if (!data || data->sign_param_nid == NID_undef) {
344         GOSTerr(GOST_F_PKEY_GOST2001_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
345         return 0;
346     }
347
348     ec = EC_KEY_new();
349     if (!fill_GOST_EC_params(ec, data->sign_param_nid)
350         || !EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) {
351         EC_KEY_free(ec);
352         return 0;
353     }
354     return 1;
355 }
356
357 static int pkey_gost2012_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
358 {
359     struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
360     EC_KEY *ec;
361     int result = 0;
362
363     if (!data || data->sign_param_nid == NID_undef) {
364         GOSTerr(GOST_F_PKEY_GOST2012_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
365         return 0;
366     }
367
368     ec = EC_KEY_new();
369     if (!fill_GOST_EC_params(ec, data->sign_param_nid)) {
370         EC_KEY_free(ec);
371         return 0;
372     }
373
374     switch (data->sign_param_nid) {
375     case NID_id_tc26_gost_3410_2012_512_paramSetA:
376     case NID_id_tc26_gost_3410_2012_512_paramSetB:
377     case NID_id_tc26_gost_3410_2012_512_paramSetC:
378     case NID_id_tc26_gost_3410_2012_512_paramSetTest:
379         result =
380             (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_512, ec)) ? 1 : 0;
381         break;
382
383     case NID_id_GostR3410_2001_CryptoPro_A_ParamSet:
384     case NID_id_GostR3410_2001_CryptoPro_B_ParamSet:
385     case NID_id_GostR3410_2001_CryptoPro_C_ParamSet:
386     case NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet:
387     case NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet:
388     case NID_id_GostR3410_2001_TestParamSet:
389     case NID_id_tc26_gost_3410_2012_256_paramSetA:
390     case NID_id_tc26_gost_3410_2012_256_paramSetB:
391     case NID_id_tc26_gost_3410_2012_256_paramSetC:
392     case NID_id_tc26_gost_3410_2012_256_paramSetD:
393         result =
394             (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_256, ec)) ? 1 : 0;
395         break;
396     default:
397         result = 0;
398         break;
399     }
400
401     if (result == 0)
402         EC_KEY_free(ec);
403
404     return result;
405 }
406
407 /* ----------- keygen callbacks --------------------------------------*/
408 /* Generates GOST_R3410 2001 key and assigns it using specified type */
409 static int pkey_gost2001cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
410 {
411     EC_KEY *ec;
412     if (!pkey_gost2001_paramgen(ctx, pkey))
413         return 0;
414     ec = EVP_PKEY_get0(pkey);
415     gost_ec_keygen(ec);
416     return 1;
417 }
418
419 /* Generates GOST_R3410 2012 key and assigns it using specified type */
420 static int pkey_gost2012cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
421 {
422     if (!pkey_gost2012_paramgen(ctx, pkey))
423         return 0;
424
425     gost_ec_keygen(EVP_PKEY_get0(pkey));
426     return 1;
427 }
428
429 /* ----------- sign callbacks --------------------------------------*/
430 /*
431  * Packs signature according to Cryptopro rules
432  * and frees up ECDSA_SIG structure
433  */
434 int pack_sign_cp(ECDSA_SIG *s, int order, unsigned char *sig, size_t *siglen)
435 {
436     const BIGNUM *sig_r = NULL, *sig_s = NULL;
437     ECDSA_SIG_get0(s, &sig_r, &sig_s);
438     *siglen = 2 * order;
439     memset(sig, 0, *siglen);
440     store_bignum(sig_s, sig, order);
441     store_bignum(sig_r, sig + order, order);
442     ECDSA_SIG_free(s);
443     return 1;
444 }
445
446 static int pkey_gost_ec_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
447                                 size_t *siglen, const unsigned char *tbs,
448                                 size_t tbs_len)
449 {
450     ECDSA_SIG *unpacked_sig = NULL;
451     EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
452     int order = 0;
453
454     if (!siglen)
455         return 0;
456     if (!pkey)
457         return 0;
458
459     switch (EVP_PKEY_base_id(pkey)) {
460     case NID_id_GostR3410_2001:
461     case NID_id_GostR3410_2012_256:
462         order = 64;
463         break;
464     case NID_id_GostR3410_2012_512:
465         order = 128;
466         break;
467     default:
468         return 0;
469     }
470
471     if (!sig) {
472         *siglen = order;
473         return 1;
474     }
475     unpacked_sig = gost_ec_sign(tbs, tbs_len, EVP_PKEY_get0(pkey));
476     if (!unpacked_sig) {
477         return 0;
478     }
479     return pack_sign_cp(unpacked_sig, order / 2, sig, siglen);
480 }
481
482 /* ------------------- verify callbacks ---------------------------*/
483 /* Unpack signature according to cryptopro rules  */
484 ECDSA_SIG *unpack_cp_signature(const unsigned char *sigbuf, size_t siglen)
485 {
486     ECDSA_SIG *sig;
487     BIGNUM *r = NULL, *s = NULL;
488
489     sig = ECDSA_SIG_new();
490     if (sig == NULL) {
491         GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, ERR_R_MALLOC_FAILURE);
492         return NULL;
493     }
494     s = BN_bin2bn(sigbuf, siglen / 2, NULL);
495     r = BN_bin2bn(sigbuf + siglen / 2, siglen / 2, NULL);
496                 ECDSA_SIG_set0(sig, r, s);
497     return sig;
498 }
499
500 static int pkey_gost_ec_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
501                                   size_t siglen, const unsigned char *tbs,
502                                   size_t tbs_len)
503 {
504     int ok = 0;
505     EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
506     ECDSA_SIG *s = (sig) ? unpack_cp_signature(sig, siglen) : NULL;
507     if (!s)
508         return 0;
509 #ifdef DEBUG_SIGN
510     fprintf(stderr, "R=");
511     BN_print_fp(stderr, ECDSA_SIG_get0_r(s));
512     fprintf(stderr, "\nS=");
513     BN_print_fp(stderr, ECDSA_SIG_get0_s(s));
514     fprintf(stderr, "\n");
515 #endif
516     if (pub_key)
517         ok = gost_ec_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key));
518     ECDSA_SIG_free(s);
519     return ok;
520 }
521
522 /* ------------- encrypt init -------------------------------------*/
523 /* Generates ephermeral key */
524 static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
525 {
526     return 1;
527 }
528
529 /* --------------- Derive init ------------------------------------*/
530 static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
531 {
532     return 1;
533 }
534
535 /* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
536 static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
537 {
538     struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
539     EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
540
541     if (!data)
542         return 0;
543     memset(data, 0, sizeof(*data));
544     data->mac_size = 4;
545     data->mac_param_nid = NID_undef;
546
547     if (pkey) {
548         struct gost_mac_key *key = EVP_PKEY_get0(pkey);
549         if (key) {
550             data->mac_param_nid = key->mac_param_nid;
551             data->mac_size = key->mac_size;
552         }
553     }
554
555     EVP_PKEY_CTX_set_data(ctx, data);
556     return 1;
557 }
558
559 static int pkey_gost_omac_init(EVP_PKEY_CTX *ctx, size_t mac_size)
560 {
561     struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
562     EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
563
564     if (!data)
565         return 0;
566     memset(data, 0, sizeof(*data));
567     data->mac_size = mac_size;
568     data->mac_param_nid = NID_undef;
569
570     if (pkey) {
571         struct gost_mac_key *key = EVP_PKEY_get0(pkey);
572         if (key) {
573             data->mac_param_nid = key->mac_param_nid;
574             data->mac_size = key->mac_size;
575         }
576     }
577
578     EVP_PKEY_CTX_set_data(ctx, data);
579     return 1;
580 }
581
582 static int pkey_gost_magma_mac_init(EVP_PKEY_CTX *ctx)
583 {
584         return pkey_gost_omac_init(ctx, 8);
585 }
586
587 static int pkey_gost_grasshopper_mac_init(EVP_PKEY_CTX *ctx)
588 {
589         return pkey_gost_omac_init(ctx, 16);
590 }
591
592 static void pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx)
593 {
594     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
595     if (data)
596         OPENSSL_free(data);
597 }
598
599 static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, ossl3_const EVP_PKEY_CTX *src)
600 {
601     struct gost_mac_pmeth_data *dst_data, *src_data;
602     if (!pkey_gost_mac_init(dst)) {
603         return 0;
604     }
605     src_data = EVP_PKEY_CTX_get_data(src);
606     dst_data = EVP_PKEY_CTX_get_data(dst);
607     if (!src_data || !dst_data)
608         return 0;
609
610     *dst_data = *src_data;
611     return 1;
612 }
613
614 static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
615 {
616     struct gost_mac_pmeth_data *data =
617         (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
618
619     switch (type) {
620     case EVP_PKEY_CTRL_MD:
621         {
622             int nid = EVP_MD_type((const EVP_MD *)p2);
623             if (nid != NID_id_Gost28147_89_MAC && nid != NID_gost_mac_12) {
624                 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
625                         GOST_R_INVALID_DIGEST_TYPE);
626                 return 0;
627             }
628             data->md = (EVP_MD *)p2;
629             return 1;
630         }
631
632     case EVP_PKEY_CTRL_GET_MD:
633         *(const EVP_MD **)p2 = data->md;
634         return 1;
635
636     case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
637     case EVP_PKEY_CTRL_PKCS7_DECRYPT:
638     case EVP_PKEY_CTRL_PKCS7_SIGN:
639         return 1;
640     case EVP_PKEY_CTRL_SET_MAC_KEY:
641         if (p1 != 32) {
642             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
643             return 0;
644         }
645
646         memcpy(data->key, p2, 32);
647         data->key_set = 1;
648         return 1;
649     case EVP_PKEY_CTRL_GOST_PARAMSET:
650         {
651             struct gost_cipher_info *param = p2;
652             data->mac_param_nid = param->nid;
653             return 1;
654         }
655     case EVP_PKEY_CTRL_DIGESTINIT:
656         {
657             EVP_MD_CTX *mctx = p2;
658             if (!data->key_set) {
659                 struct gost_mac_key *key;
660                 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
661                 if (!pkey) {
662                     GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
663                             GOST_R_MAC_KEY_NOT_SET);
664                     return 0;
665                 }
666                 key = EVP_PKEY_get0(pkey);
667                 if (!key) {
668                     GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
669                             GOST_R_MAC_KEY_NOT_SET);
670                     return 0;
671                 }
672                 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
673                     (mctx, EVP_MD_CTRL_SET_KEY, 0, key);
674             } else {
675                 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
676                     (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
677             }
678         }
679     case EVP_PKEY_CTRL_MAC_LEN:
680         {
681             if (p1 < 1 || p1 > 8) {
682
683                 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_SIZE);
684                 return 0;
685             }
686             data->mac_size = p1;
687             return 1;
688         }
689     }
690     return -2;
691 }
692
693 static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
694                                   const char *type, const char *value)
695 {
696     if (strcmp(type, key_ctrl_string) == 0) {
697         if (strlen(value) != 32) {
698             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
699                     GOST_R_INVALID_MAC_KEY_LENGTH);
700             return 0;
701         }
702         return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
703                                   32, (char *)value);
704     }
705     if (strcmp(type, hexkey_ctrl_string) == 0) {
706         long keylen;
707         int ret;
708         unsigned char *keybuf = string_to_hex(value, &keylen);
709         if (!keybuf || keylen != 32) {
710             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
711                     GOST_R_INVALID_MAC_KEY_LENGTH);
712             OPENSSL_free(keybuf);
713             return 0;
714         }
715         ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf);
716         OPENSSL_free(keybuf);
717         return ret;
718
719     }
720     if (!strcmp(type, maclen_ctrl_string)) {
721         char *endptr;
722         long size = strtol(value, &endptr, 10);
723         if (*endptr != '\0') {
724             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_SIZE);
725             return 0;
726         }
727         return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN, size, NULL);
728     }
729     if (strcmp(type, param_ctrl_string) == 0) {
730         ASN1_OBJECT *obj = OBJ_txt2obj(value, 0);
731         const struct gost_cipher_info *param = NULL;
732         if (obj == NULL) {
733             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
734             return 0;
735         }
736
737         param = get_encryption_params(obj);
738                                 ASN1_OBJECT_free(obj);
739         if (param == NULL) {
740             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
741             return 0;
742         }
743
744
745         return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, 0,
746                                   (void *)param);
747     }
748     return -2;
749 }
750
751 static int pkey_gost_omac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2, size_t max_size)
752 {
753     struct gost_mac_pmeth_data *data =
754         (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
755
756     switch (type) {
757     case EVP_PKEY_CTRL_MD:
758         {
759             int nid = EVP_MD_type((const EVP_MD *)p2);
760             if (nid != NID_magma_mac && nid != NID_grasshopper_mac
761                 && nid != NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac /* FIXME beldmit */
762                 && nid != NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac) {
763                 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
764                         GOST_R_INVALID_DIGEST_TYPE);
765                 return 0;
766             }
767             data->md = (EVP_MD *)p2;
768             return 1;
769         }
770
771     case EVP_PKEY_CTRL_GET_MD:
772         *(const EVP_MD **)p2 = data->md;
773         return 1;
774
775     case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
776     case EVP_PKEY_CTRL_PKCS7_DECRYPT:
777     case EVP_PKEY_CTRL_PKCS7_SIGN:
778         return 1;
779     case EVP_PKEY_CTRL_SET_MAC_KEY:
780         if (p1 != 32) {
781             GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
782             return 0;
783         }
784
785         memcpy(data->key, p2, 32);
786         data->key_set = 1;
787         return 1;
788     case EVP_PKEY_CTRL_DIGESTINIT:
789         {
790             EVP_MD_CTX *mctx = p2;
791             if (!data->key_set) {
792                 struct gost_mac_key *key;
793                 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
794                 if (!pkey) {
795                     GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
796                             GOST_R_MAC_KEY_NOT_SET);
797                     return 0;
798                 }
799                 key = EVP_PKEY_get0(pkey);
800                 if (!key) {
801                     GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
802                             GOST_R_MAC_KEY_NOT_SET);
803                     return 0;
804                 }
805                 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
806                     (mctx, EVP_MD_CTRL_SET_KEY, 0, key);
807             } else {
808                 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
809                     (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
810             }
811         }
812     case EVP_PKEY_CTRL_MAC_LEN:
813         {
814             if (p1 < 1 || p1 > max_size) {
815
816                 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_SIZE);
817                 return 0;
818             }
819             data->mac_size = p1;
820             return 1;
821         }
822     }
823     return -2;
824 }
825
826 static int pkey_gost_magma_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
827 {
828         return pkey_gost_omac_ctrl(ctx, type, p1, p2, 8);
829 }
830
831 static int pkey_gost_grasshopper_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
832 {
833         return pkey_gost_omac_ctrl(ctx, type, p1, p2, 16);
834 }
835
836 static int pkey_gost_omac_ctrl_str(EVP_PKEY_CTX *ctx,
837                                   const char *type, const char *value, size_t max_size)
838 {
839     if (strcmp(type, key_ctrl_string) == 0) {
840         if (strlen(value) != 32) {
841             GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR,
842                     GOST_R_INVALID_MAC_KEY_LENGTH);
843             return 0;
844         }
845         return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
846                                   32, (char *)value);
847     }
848     if (strcmp(type, hexkey_ctrl_string) == 0) {
849         long keylen;
850         int ret;
851         unsigned char *keybuf = string_to_hex(value, &keylen);
852         if (!keybuf || keylen != 32) {
853             GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR,
854                     GOST_R_INVALID_MAC_KEY_LENGTH);
855             OPENSSL_free(keybuf);
856             return 0;
857         }
858         ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf);
859         OPENSSL_free(keybuf);
860         return ret;
861
862     }
863     if (!strcmp(type, maclen_ctrl_string)) {
864         char *endptr;
865         long size = strtol(value, &endptr, 10);
866         if (*endptr != '\0') {
867             GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR, GOST_R_INVALID_MAC_SIZE);
868             return 0;
869         }
870         return pkey_gost_omac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN, size, NULL, max_size);
871     }
872     return -2;
873 }
874
875 static int pkey_gost_magma_mac_ctrl_str(EVP_PKEY_CTX *ctx,
876                                   const char *type, const char *value)
877 {
878         return pkey_gost_omac_ctrl_str(ctx, type, value, 8);
879 }
880
881 static int pkey_gost_grasshopper_mac_ctrl_str(EVP_PKEY_CTX *ctx,
882                                   const char *type, const char *value)
883 {
884         return pkey_gost_omac_ctrl_str(ctx, type, value, 8);
885 }
886
887 static int pkey_gost_mac_keygen_base(EVP_PKEY_CTX *ctx,
888                                      EVP_PKEY *pkey, int mac_nid)
889 {
890     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
891     struct gost_mac_key *keydata;
892     if (!data || !data->key_set) {
893         GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN_BASE, GOST_R_MAC_KEY_NOT_SET);
894         return 0;
895     }
896     keydata = OPENSSL_malloc(sizeof(struct gost_mac_key));
897     if (keydata == NULL)
898         return 0;
899     memcpy(keydata->key, data->key, 32);
900     keydata->mac_param_nid = data->mac_param_nid;
901     keydata->mac_size = data->mac_size;
902     EVP_PKEY_assign(pkey, mac_nid, keydata);
903     return 1;
904 }
905
906 static int pkey_gost_mac_keygen_12(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
907 {
908     return pkey_gost_mac_keygen_base(ctx, pkey, NID_gost_mac_12);
909 }
910
911 static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
912 {
913     return pkey_gost_mac_keygen_base(ctx, pkey, NID_id_Gost28147_89_MAC);
914 }
915
916 static int pkey_gost_magma_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
917 {
918     return pkey_gost_mac_keygen_base(ctx, pkey, NID_magma_mac);
919 }
920
921 static int pkey_gost_grasshopper_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
922 {
923     return pkey_gost_mac_keygen_base(ctx, pkey, NID_grasshopper_mac);
924 }
925
926 static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
927 {
928     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
929
930     if (data == NULL) {
931         pkey_gost_mac_init(ctx);
932     }
933
934     data = EVP_PKEY_CTX_get_data(ctx);
935     if (!data) {
936         GOSTerr(GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
937         return 0;
938     }
939
940     return 1;
941 }
942
943 static int pkey_gost_magma_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
944 {
945     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
946
947     if (data == NULL) {
948         pkey_gost_omac_init(ctx, 4);
949     }
950
951     data = EVP_PKEY_CTX_get_data(ctx);
952     if (!data) {
953         GOSTerr(GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
954         return 0;
955     }
956
957     return 1;
958 }
959
960 static int pkey_gost_grasshopper_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
961 {
962     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
963
964     if (data == NULL) {
965         pkey_gost_omac_init(ctx, 8);
966     }
967
968     data = EVP_PKEY_CTX_get_data(ctx);
969     if (!data) {
970         GOSTerr(GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
971         return 0;
972     }
973
974     return 1;
975 }
976
977 static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
978                                  size_t *siglen, EVP_MD_CTX *mctx)
979 {
980     unsigned int tmpsiglen;
981     int ret;
982     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
983
984     if (!siglen)
985         return 0;
986     tmpsiglen = *siglen;        /* for platforms where sizeof(int) !=
987                                  * sizeof(size_t) */
988
989     if (!sig) {
990         *siglen = data->mac_size;
991         return 1;
992     }
993
994     EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
995         (mctx, EVP_MD_CTRL_XOF_LEN, data->mac_size, NULL);
996     ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen);
997     *siglen = data->mac_size;
998     return ret;
999 }
1000
1001 /* ----------- misc callbacks -------------------------------------*/
1002
1003 /* Callback for both EVP_PKEY_check() and EVP_PKEY_public_check. */
1004 static int pkey_gost_check(EVP_PKEY *pkey)
1005 {
1006     return EC_KEY_check_key(EVP_PKEY_get0(pkey));
1007 }
1008
1009 /* ----------------------------------------------------------------*/
1010 int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags)
1011 {
1012     *pmeth = EVP_PKEY_meth_new(id, flags);
1013     if (!*pmeth)
1014         return 0;
1015
1016     switch (id) {
1017     case NID_id_GostR3410_2001:
1018         EVP_PKEY_meth_set_ctrl(*pmeth,
1019                                pkey_gost_ctrl, pkey_gost_ec_ctrl_str_256);
1020         EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign);
1021         EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost_ec_cp_verify);
1022
1023         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2001cp_keygen);
1024
1025         EVP_PKEY_meth_set_encrypt(*pmeth,
1026                                   pkey_gost_encrypt_init,
1027                                   pkey_gost_encrypt);
1028         EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_gost_decrypt);
1029         EVP_PKEY_meth_set_derive(*pmeth,
1030                                  pkey_gost_derive_init, pkey_gost_ec_derive);
1031         EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,
1032                                    pkey_gost2001_paramgen);
1033         EVP_PKEY_meth_set_check(*pmeth, pkey_gost_check);
1034         EVP_PKEY_meth_set_public_check(*pmeth, pkey_gost_check);
1035         break;
1036     case NID_id_GostR3410_2012_256:
1037         EVP_PKEY_meth_set_ctrl(*pmeth,
1038                                pkey_gost_ctrl, pkey_gost_ec_ctrl_str_256);
1039         EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign);
1040         EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost_ec_cp_verify);
1041
1042         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen);
1043
1044         EVP_PKEY_meth_set_encrypt(*pmeth,
1045                                   pkey_gost_encrypt_init,
1046                                   pkey_gost_encrypt);
1047         EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_gost_decrypt);
1048         EVP_PKEY_meth_set_derive(*pmeth,
1049                                  pkey_gost_derive_init, pkey_gost_ec_derive);
1050         EVP_PKEY_meth_set_paramgen(*pmeth,
1051                                    pkey_gost_paramgen_init,
1052                                    pkey_gost2012_paramgen);
1053         EVP_PKEY_meth_set_check(*pmeth, pkey_gost_check);
1054         EVP_PKEY_meth_set_public_check(*pmeth, pkey_gost_check);
1055         break;
1056     case NID_id_GostR3410_2012_512:
1057         EVP_PKEY_meth_set_ctrl(*pmeth,
1058                                pkey_gost_ctrl, pkey_gost_ec_ctrl_str_512);
1059         EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign);
1060         EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost_ec_cp_verify);
1061
1062         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen);
1063
1064         EVP_PKEY_meth_set_encrypt(*pmeth,
1065                                   pkey_gost_encrypt_init,
1066                                   pkey_gost_encrypt);
1067         EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_gost_decrypt);
1068         EVP_PKEY_meth_set_derive(*pmeth,
1069                                  pkey_gost_derive_init, pkey_gost_ec_derive);
1070         EVP_PKEY_meth_set_paramgen(*pmeth,
1071                                    pkey_gost_paramgen_init,
1072                                    pkey_gost2012_paramgen);
1073         EVP_PKEY_meth_set_check(*pmeth, pkey_gost_check);
1074         EVP_PKEY_meth_set_public_check(*pmeth, pkey_gost_check);
1075         break;
1076     case NID_id_Gost28147_89_MAC:
1077         EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl,
1078                                pkey_gost_mac_ctrl_str);
1079         EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_mac_signctx_init,
1080                                   pkey_gost_mac_signctx);
1081         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_mac_keygen);
1082         EVP_PKEY_meth_set_init(*pmeth, pkey_gost_mac_init);
1083         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
1084         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
1085         return 1;
1086     case NID_gost_mac_12:
1087         EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl,
1088                                pkey_gost_mac_ctrl_str);
1089         EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_mac_signctx_init,
1090                                   pkey_gost_mac_signctx);
1091         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_mac_keygen_12);
1092         EVP_PKEY_meth_set_init(*pmeth, pkey_gost_mac_init);
1093         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
1094         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
1095         return 1;
1096     case NID_magma_mac:
1097         EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_magma_mac_ctrl,
1098                                pkey_gost_magma_mac_ctrl_str);
1099         EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_magma_mac_signctx_init,
1100                                   pkey_gost_mac_signctx);
1101         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_magma_mac_keygen);
1102         EVP_PKEY_meth_set_init(*pmeth, pkey_gost_magma_mac_init);
1103         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
1104         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
1105         return 1;
1106     case NID_grasshopper_mac:
1107     case NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac: /* FIXME beldmit */
1108         EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_grasshopper_mac_ctrl,
1109                                pkey_gost_grasshopper_mac_ctrl_str);
1110         EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_grasshopper_mac_signctx_init,
1111                                   pkey_gost_mac_signctx);
1112         EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_grasshopper_mac_keygen);
1113         EVP_PKEY_meth_set_init(*pmeth, pkey_gost_grasshopper_mac_init);
1114         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
1115         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
1116         return 1;
1117     default:                   /* Unsupported method */
1118         return 0;
1119     }
1120     EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
1121     EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);
1122
1123     EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
1124     /*
1125      * FIXME derive etc...
1126      */
1127
1128     return 1;
1129 }