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