1 /**********************************************************************
3 * Copyright (c) 2005-2013 Cryptocom LTD *
4 * This file is distributed under the same license as OpenSSL *
6 * Implementation of RFC 4357 (GOST R 34.10) Publick key method *
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 */
19 #include "e_gost_err.h"
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)
25 struct gost_pmeth_data *data;
26 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
28 data = OPENSSL_malloc(sizeof(*data));
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:
38 const EC_GROUP *group =
39 EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey));
41 data->sign_param_nid = EC_GROUP_get_curve_name(group);
51 EVP_PKEY_CTX_set_data(ctx, data);
55 /* Copies contents of gost_pmeth_data structure */
56 static int pkey_gost_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
58 struct gost_pmeth_data *dst_data, *src_data;
59 if (!pkey_gost_init(dst)) {
62 src_data = EVP_PKEY_CTX_get_data(src);
63 dst_data = EVP_PKEY_CTX_get_data(dst);
64 if (!src_data || !dst_data)
67 *dst_data = *src_data;
68 if (src_data->shared_ukm) {
69 dst_data->shared_ukm = NULL;
74 /* Frees up gost_pmeth_data structure */
75 static void pkey_gost_cleanup(EVP_PKEY_CTX *ctx)
77 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
80 OPENSSL_free(data->shared_ukm);
84 /* --------------------- control functions ------------------------------*/
85 static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
87 struct gost_pmeth_data *pctx =
88 (struct gost_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
93 case EVP_PKEY_CTRL_MD:
95 EVP_PKEY *key = EVP_PKEY_CTX_get0_pkey(ctx);
96 int pkey_nid = (key == NULL) ? NID_undef : EVP_PKEY_base_id(key);
98 OPENSSL_assert(p2 != NULL);
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;
109 case NID_id_GostR3411_2012_256:
110 if (pkey_nid == NID_id_GostR3410_2012_256) {
111 pctx->md = (EVP_MD *)p2;
116 case NID_id_GostR3411_2012_512:
117 if (pkey_nid == NID_id_GostR3410_2012_512) {
118 pctx->md = (EVP_MD *)p2;
124 GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
128 case EVP_PKEY_CTRL_GET_MD:
129 *(const EVP_MD **)p2 = pctx->md;
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:
143 case EVP_PKEY_CTRL_GOST_PARAMSET:
144 pctx->sign_param_nid = (int)p1;
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);
153 memcpy(pctx->shared_ukm, p2, (int)p1);
154 pctx->shared_ukm_size = p1;
156 case EVP_PKEY_CTRL_CIPHER:
157 pctx->cipher_nid = p1;
159 case EVP_PKEY_CTRL_PEER_KEY:
160 if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */
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);
169 GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_CTRL_CALL_FAILED);
173 static int pkey_gost_ec_ctrl_str_256(EVP_PKEY_CTX *ctx,
174 const char *type, const char *value)
178 if (strcmp(type, param_ctrl_string) == 0) {
182 if (strlen(value) == 1) {
183 switch (toupper((unsigned char)value[0])) {
185 param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
188 param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
191 param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
194 param_nid = NID_id_GostR3410_2001_TestParamSet;
199 } else if ((strlen(value) == 2)
200 && (toupper((unsigned char)value[0]) == 'X')) {
201 switch (toupper((unsigned char)value[1])) {
203 param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
206 param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
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])) {
216 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetA;
219 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetB;
222 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetC;
225 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetD;
231 R3410_ec_params *p = R3410_2001_paramset;
232 param_nid = OBJ_txt2nid(value);
233 if (param_nid == NID_undef) {
236 for (; p->nid != NID_undef; p++) {
237 if (p->nid == param_nid)
240 if (p->nid == NID_undef) {
241 GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_256,
242 GOST_R_INVALID_PARAMSET);
247 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
253 static int pkey_gost_ec_ctrl_str_512(EVP_PKEY_CTX *ctx,
254 const char *type, const char *value)
256 int param_nid = NID_undef;
258 if (strcmp(type, param_ctrl_string))
264 if (strlen(value) == 1) {
265 switch (toupper((unsigned char)value[0])) {
267 param_nid = NID_id_tc26_gost_3410_2012_512_paramSetA;
271 param_nid = NID_id_tc26_gost_3410_2012_512_paramSetB;
275 param_nid = NID_id_tc26_gost_3410_2012_512_paramSetC;
282 R3410_ec_params *p = R3410_2012_512_paramset;
283 param_nid = OBJ_txt2nid(value);
284 if (param_nid == NID_undef)
287 while (p->nid != NID_undef && p->nid != param_nid)
290 if (p->nid == NID_undef) {
291 GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_512,
292 GOST_R_INVALID_PARAMSET);
297 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, param_nid, NULL);
300 /* --------------------- key generation --------------------------------*/
302 static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx)
307 static int pkey_gost2001_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
309 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
312 if (!data || data->sign_param_nid == NID_undef) {
313 GOSTerr(GOST_F_PKEY_GOST2001_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
318 if (!fill_GOST_EC_params(ec, data->sign_param_nid)
319 || !EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) {
326 static int pkey_gost2012_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
328 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
332 if (!data || data->sign_param_nid == NID_undef) {
333 GOSTerr(GOST_F_PKEY_GOST2012_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
338 if (!fill_GOST_EC_params(ec, data->sign_param_nid)) {
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:
348 (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_512, ec)) ? 1 : 0;
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:
362 (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_256, ec)) ? 1 : 0;
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)
380 if (!pkey_gost2001_paramgen(ctx, pkey))
382 ec = EVP_PKEY_get0(pkey);
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)
390 if (!pkey_gost2012_paramgen(ctx, pkey))
393 gost_ec_keygen(EVP_PKEY_get0(pkey));
397 /* ----------- sign callbacks --------------------------------------*/
399 * Packs signature according to Cryptopro rules
400 * and frees up ECDSA_SIG structure
402 int pack_sign_cp(ECDSA_SIG *s, int order, unsigned char *sig, size_t *siglen)
404 const BIGNUM *sig_r = NULL, *sig_s = NULL;
405 ECDSA_SIG_get0(s, &sig_r, &sig_s);
407 memset(sig, 0, *siglen);
408 store_bignum(sig_s, sig, order);
409 store_bignum(sig_r, sig + order, order);
414 static int pkey_gost_ec_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
415 size_t *siglen, const unsigned char *tbs,
418 ECDSA_SIG *unpacked_sig = NULL;
419 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
427 switch (EVP_PKEY_base_id(pkey)) {
428 case NID_id_GostR3410_2001:
429 case NID_id_GostR3410_2012_256:
432 case NID_id_GostR3410_2012_512:
443 unpacked_sig = gost_ec_sign(tbs, tbs_len, EVP_PKEY_get0(pkey));
447 return pack_sign_cp(unpacked_sig, order / 2, sig, siglen);
450 /* ------------------- verify callbacks ---------------------------*/
451 /* Unpack signature according to cryptopro rules */
452 ECDSA_SIG *unpack_cp_signature(const unsigned char *sigbuf, size_t siglen)
455 BIGNUM *r = NULL, *s = NULL;
457 sig = ECDSA_SIG_new();
459 GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, ERR_R_MALLOC_FAILURE);
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);
468 static int pkey_gost_ec_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
469 size_t siglen, const unsigned char *tbs,
473 EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
474 ECDSA_SIG *s = (sig) ? unpack_cp_signature(sig, siglen) : NULL;
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");
485 ok = gost_ec_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key));
490 /* ------------- encrypt init -------------------------------------*/
491 /* Generates ephermeral key */
492 static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
497 /* --------------- Derive init ------------------------------------*/
498 static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
503 /* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
504 static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
506 struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
507 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
511 memset(data, 0, sizeof(*data));
513 data->mac_param_nid = NID_undef;
516 struct gost_mac_key *key = EVP_PKEY_get0(pkey);
518 data->mac_param_nid = key->mac_param_nid;
519 data->mac_size = key->mac_size;
523 EVP_PKEY_CTX_set_data(ctx, data);
527 static int pkey_gost_omac_init(EVP_PKEY_CTX *ctx, size_t mac_size)
529 struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
530 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
534 memset(data, 0, sizeof(*data));
535 data->mac_size = mac_size;
536 data->mac_param_nid = NID_undef;
539 struct gost_mac_key *key = EVP_PKEY_get0(pkey);
541 data->mac_param_nid = key->mac_param_nid;
542 data->mac_size = key->mac_size;
546 EVP_PKEY_CTX_set_data(ctx, data);
550 static int pkey_gost_magma_mac_init(EVP_PKEY_CTX *ctx)
552 return pkey_gost_omac_init(ctx, 8);
555 static int pkey_gost_grasshopper_mac_init(EVP_PKEY_CTX *ctx)
557 return pkey_gost_omac_init(ctx, 16);
560 static void pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx)
562 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
567 static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
569 struct gost_mac_pmeth_data *dst_data, *src_data;
570 if (!pkey_gost_mac_init(dst)) {
573 src_data = EVP_PKEY_CTX_get_data(src);
574 dst_data = EVP_PKEY_CTX_get_data(dst);
575 if (!src_data || !dst_data)
578 *dst_data = *src_data;
582 static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
584 struct gost_mac_pmeth_data *data =
585 (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
588 case EVP_PKEY_CTRL_MD:
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);
596 data->md = (EVP_MD *)p2;
600 case EVP_PKEY_CTRL_GET_MD:
601 *(const EVP_MD **)p2 = data->md;
604 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
605 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
606 case EVP_PKEY_CTRL_PKCS7_SIGN:
608 case EVP_PKEY_CTRL_SET_MAC_KEY:
610 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
614 memcpy(data->key, p2, 32);
617 case EVP_PKEY_CTRL_GOST_PARAMSET:
619 struct gost_cipher_info *param = p2;
620 data->mac_param_nid = param->nid;
623 case EVP_PKEY_CTRL_DIGESTINIT:
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);
630 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
631 GOST_R_MAC_KEY_NOT_SET);
634 key = EVP_PKEY_get0(pkey);
636 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
637 GOST_R_MAC_KEY_NOT_SET);
640 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
641 (mctx, EVP_MD_CTRL_SET_KEY, 0, key);
643 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
644 (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
647 case EVP_PKEY_CTRL_MAC_LEN:
649 if (p1 < 1 || p1 > 8) {
651 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_SIZE);
661 static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
662 const char *type, const char *value)
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);
670 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
673 if (strcmp(type, hexkey_ctrl_string) == 0) {
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);
683 ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf);
684 OPENSSL_free(keybuf);
688 if (!strcmp(type, maclen_ctrl_string)) {
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);
695 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN, size, NULL);
697 if (strcmp(type, param_ctrl_string) == 0) {
698 ASN1_OBJECT *obj = OBJ_txt2obj(value, 0);
699 const struct gost_cipher_info *param = NULL;
701 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
705 param = get_encryption_params(obj);
706 ASN1_OBJECT_free(obj);
708 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
713 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, 0,
719 static int pkey_gost_omac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2, size_t max_size)
721 struct gost_mac_pmeth_data *data =
722 (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
725 case EVP_PKEY_CTRL_MD:
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);
735 data->md = (EVP_MD *)p2;
739 case EVP_PKEY_CTRL_GET_MD:
740 *(const EVP_MD **)p2 = data->md;
743 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
744 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
745 case EVP_PKEY_CTRL_PKCS7_SIGN:
747 case EVP_PKEY_CTRL_SET_MAC_KEY:
749 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
753 memcpy(data->key, p2, 32);
756 case EVP_PKEY_CTRL_DIGESTINIT:
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);
763 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
764 GOST_R_MAC_KEY_NOT_SET);
767 key = EVP_PKEY_get0(pkey);
769 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
770 GOST_R_MAC_KEY_NOT_SET);
773 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
774 (mctx, EVP_MD_CTRL_SET_KEY, 0, key);
776 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
777 (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
780 case EVP_PKEY_CTRL_MAC_LEN:
782 if (p1 < 1 || p1 > max_size) {
784 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_SIZE);
794 static int pkey_gost_magma_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
796 return pkey_gost_omac_ctrl(ctx, type, p1, p2, 8);
799 static int pkey_gost_grasshopper_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
801 return pkey_gost_omac_ctrl(ctx, type, p1, p2, 16);
804 static int pkey_gost_omac_ctrl_str(EVP_PKEY_CTX *ctx,
805 const char *type, const char *value, size_t max_size)
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);
813 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
816 if (strcmp(type, hexkey_ctrl_string) == 0) {
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);
826 ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf);
827 OPENSSL_free(keybuf);
831 if (!strcmp(type, maclen_ctrl_string)) {
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);
838 return pkey_gost_omac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN, size, NULL, max_size);
843 static int pkey_gost_magma_mac_ctrl_str(EVP_PKEY_CTX *ctx,
844 const char *type, const char *value)
846 return pkey_gost_omac_ctrl_str(ctx, type, value, 8);
849 static int pkey_gost_grasshopper_mac_ctrl_str(EVP_PKEY_CTX *ctx,
850 const char *type, const char *value)
852 return pkey_gost_omac_ctrl_str(ctx, type, value, 8);
855 static int pkey_gost_mac_keygen_base(EVP_PKEY_CTX *ctx,
856 EVP_PKEY *pkey, int mac_nid)
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);
864 keydata = OPENSSL_malloc(sizeof(struct gost_mac_key));
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);
874 static int pkey_gost_mac_keygen_12(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
876 return pkey_gost_mac_keygen_base(ctx, pkey, NID_gost_mac_12);
879 static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
881 return pkey_gost_mac_keygen_base(ctx, pkey, NID_id_Gost28147_89_MAC);
884 static int pkey_gost_magma_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
886 return pkey_gost_mac_keygen_base(ctx, pkey, NID_magma_mac);
889 static int pkey_gost_grasshopper_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
891 return pkey_gost_mac_keygen_base(ctx, pkey, NID_grasshopper_mac);
894 static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
896 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
899 pkey_gost_mac_init(ctx);
902 data = EVP_PKEY_CTX_get_data(ctx);
904 GOSTerr(GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
911 static int pkey_gost_magma_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
913 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
916 pkey_gost_omac_init(ctx, 4);
919 data = EVP_PKEY_CTX_get_data(ctx);
921 GOSTerr(GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
928 static int pkey_gost_grasshopper_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
930 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
933 pkey_gost_omac_init(ctx, 8);
936 data = EVP_PKEY_CTX_get_data(ctx);
938 GOSTerr(GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
945 static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
946 size_t *siglen, EVP_MD_CTX *mctx)
948 unsigned int tmpsiglen;
950 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
954 tmpsiglen = *siglen; /* for platforms where sizeof(int) !=
958 *siglen = data->mac_size;
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;
969 /* ----------- misc callbacks -------------------------------------*/
971 /* Callback for both EVP_PKEY_check() and EVP_PKEY_public_check. */
972 static int pkey_gost_check(EVP_PKEY *pkey)
974 return EC_KEY_check_key(EVP_PKEY_get0(pkey));
977 /* ----------------------------------------------------------------*/
978 int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags)
980 *pmeth = EVP_PKEY_meth_new(id, flags);
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);
991 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2001cp_keygen);
993 EVP_PKEY_meth_set_encrypt(*pmeth,
994 pkey_gost_encrypt_init,
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);
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);
1010 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen);
1012 EVP_PKEY_meth_set_encrypt(*pmeth,
1013 pkey_gost_encrypt_init,
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);
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);
1030 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen);
1032 EVP_PKEY_meth_set_encrypt(*pmeth,
1033 pkey_gost_encrypt_init,
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);
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);
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);
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);
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);
1085 default: /* Unsupported method */
1088 EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
1089 EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);
1091 EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
1093 * FIXME derive etc...