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