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