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 */
15 #include <openssl/opensslv.h> /* For OPENSSL_VERSION_MAJOR */
20 #include "e_gost_err.h"
23 #ifdef OPENSSL_VERSION_MAJOR
25 #define ossl3_const const
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)
32 struct gost_pmeth_data *data;
33 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
35 data = OPENSSL_malloc(sizeof(*data));
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:
46 const EC_GROUP *group =
47 EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey));
49 data->sign_param_nid = EC_GROUP_get_curve_name(group);
59 EVP_PKEY_CTX_set_data(ctx, data);
63 /* Copies contents of gost_pmeth_data structure */
64 static int pkey_gost_copy(EVP_PKEY_CTX *dst, ossl3_const EVP_PKEY_CTX *src)
66 struct gost_pmeth_data *dst_data, *src_data;
67 if (!pkey_gost_init(dst)) {
70 src_data = EVP_PKEY_CTX_get_data(src);
71 dst_data = EVP_PKEY_CTX_get_data(dst);
72 if (!src_data || !dst_data)
75 *dst_data = *src_data;
76 if (src_data->shared_ukm) {
77 dst_data->shared_ukm = NULL;
82 /* Frees up gost_pmeth_data structure */
83 static void pkey_gost_cleanup(EVP_PKEY_CTX *ctx)
85 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
88 OPENSSL_free(data->shared_ukm);
92 /* --------------------- control functions ------------------------------*/
93 static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
95 struct gost_pmeth_data *pctx =
96 (struct gost_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
101 case EVP_PKEY_CTRL_MD:
103 EVP_PKEY *key = EVP_PKEY_CTX_get0_pkey(ctx);
104 int pkey_nid = (key == NULL) ? NID_undef : EVP_PKEY_base_id(key);
106 OPENSSL_assert(p2 != NULL);
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;
118 case NID_id_GostR3411_2012_256:
119 if (pkey_nid == NID_id_GostR3410_2012_256) {
120 pctx->md = (EVP_MD *)p2;
125 case NID_id_GostR3411_2012_512:
126 if (pkey_nid == NID_id_GostR3410_2012_512) {
127 pctx->md = (EVP_MD *)p2;
133 GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
137 case EVP_PKEY_CTRL_GET_MD:
138 *(const EVP_MD **)p2 = pctx->md;
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:
152 case EVP_PKEY_CTRL_GOST_PARAMSET:
153 pctx->sign_param_nid = (int)p1;
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);
162 memcpy(pctx->shared_ukm, p2, (int)p1);
163 pctx->shared_ukm_size = p1;
165 case EVP_PKEY_CTRL_CIPHER:
166 pctx->cipher_nid = p1;
168 case EVP_PKEY_CTRL_PEER_KEY:
169 if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */
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);
178 GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_CTRL_CALL_FAILED);
182 static int pkey_gost_ec_ctrl_str_common(EVP_PKEY_CTX *ctx,
183 const char *type, const char *value)
185 if (0 == strcmp(type, ukm_ctrl_string)) {
186 unsigned char ukm_buf[32], *tmp = NULL;
188 tmp = OPENSSL_hexstr2buf(value, &len);
194 GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_COMMON, GOST_R_CTRL_CALL_FAILED);
197 memcpy(ukm_buf, tmp, len);
200 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_SET_IV, len, ukm_buf);
205 static int pkey_gost_ec_ctrl_str_256(EVP_PKEY_CTX *ctx,
206 const char *type, const char *value)
208 if (strcmp(type, param_ctrl_string) == 0) {
214 if (strlen(value) == 1) {
215 switch (toupper((unsigned char)value[0])) {
217 param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
220 param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
223 param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
226 param_nid = NID_id_GostR3410_2001_TestParamSet;
231 } else if ((strlen(value) == 2)
232 && (toupper((unsigned char)value[0]) == 'X')) {
233 switch (toupper((unsigned char)value[1])) {
235 param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
238 param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
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])) {
248 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetA;
251 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetB;
254 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetC;
257 param_nid = NID_id_tc26_gost_3410_2012_256_paramSetD;
263 R3410_ec_params *p = R3410_2001_paramset;
264 param_nid = OBJ_txt2nid(value);
265 if (param_nid == NID_undef) {
268 for (; p->nid != NID_undef; p++) {
269 if (p->nid == param_nid)
272 if (p->nid == NID_undef) {
273 GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_256,
274 GOST_R_INVALID_PARAMSET);
279 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
283 return pkey_gost_ec_ctrl_str_common(ctx, type, value);
286 static int pkey_gost_ec_ctrl_str_512(EVP_PKEY_CTX *ctx,
287 const char *type, const char *value)
289 int param_nid = NID_undef;
291 if (strcmp(type, param_ctrl_string))
292 return pkey_gost_ec_ctrl_str_common(ctx, type, value);
297 if (strlen(value) == 1) {
298 switch (toupper((unsigned char)value[0])) {
300 param_nid = NID_id_tc26_gost_3410_2012_512_paramSetA;
304 param_nid = NID_id_tc26_gost_3410_2012_512_paramSetB;
308 param_nid = NID_id_tc26_gost_3410_2012_512_paramSetC;
315 R3410_ec_params *p = R3410_2012_512_paramset;
316 param_nid = OBJ_txt2nid(value);
317 if (param_nid == NID_undef)
320 while (p->nid != NID_undef && p->nid != param_nid)
323 if (p->nid == NID_undef) {
324 GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_512,
325 GOST_R_INVALID_PARAMSET);
330 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, param_nid, NULL);
333 /* --------------------- key generation --------------------------------*/
335 static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx)
340 static int pkey_gost2001_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
342 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
345 if (!data || data->sign_param_nid == NID_undef) {
346 GOSTerr(GOST_F_PKEY_GOST2001_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
351 if (!fill_GOST_EC_params(ec, data->sign_param_nid)
352 || !EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) {
359 static int pkey_gost2012_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
361 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
365 if (!data || data->sign_param_nid == NID_undef) {
366 GOSTerr(GOST_F_PKEY_GOST2012_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
371 if (!fill_GOST_EC_params(ec, data->sign_param_nid)) {
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:
382 (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_512, ec)) ? 1 : 0;
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:
396 (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_256, ec)) ? 1 : 0;
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)
414 if (!pkey_gost2001_paramgen(ctx, pkey))
416 ec = EVP_PKEY_get0(pkey);
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)
424 if (!pkey_gost2012_paramgen(ctx, pkey))
427 gost_ec_keygen(EVP_PKEY_get0(pkey));
431 /* ----------- sign callbacks --------------------------------------*/
433 * Packs signature according to Cryptopro rules
434 * and frees up ECDSA_SIG structure
436 int pack_sign_cp(ECDSA_SIG *s, int order, unsigned char *sig, size_t *siglen)
438 const BIGNUM *sig_r = NULL, *sig_s = NULL;
439 ECDSA_SIG_get0(s, &sig_r, &sig_s);
441 memset(sig, 0, *siglen);
442 store_bignum(sig_s, sig, order);
443 store_bignum(sig_r, sig + order, order);
448 static int pkey_gost_ec_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
449 size_t *siglen, const unsigned char *tbs,
452 ECDSA_SIG *unpacked_sig = NULL;
453 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
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:
467 case NID_id_GostR3410_2012_512:
478 unpacked_sig = gost_ec_sign(tbs, tbs_len, EVP_PKEY_get0(pkey));
482 return pack_sign_cp(unpacked_sig, order / 2, sig, siglen);
485 /* ------------------- verify callbacks ---------------------------*/
486 /* Unpack signature according to cryptopro rules */
487 ECDSA_SIG *unpack_cp_signature(const unsigned char *sigbuf, size_t siglen)
490 BIGNUM *r = NULL, *s = NULL;
492 sig = ECDSA_SIG_new();
494 GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, ERR_R_MALLOC_FAILURE);
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);
503 static int pkey_gost_ec_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
504 size_t siglen, const unsigned char *tbs,
508 EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
509 ECDSA_SIG *s = (sig) ? unpack_cp_signature(sig, siglen) : NULL;
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");
520 ok = gost_ec_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key));
525 /* ------------- encrypt init -------------------------------------*/
526 /* Generates ephermeral key */
527 static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
532 /* --------------- Derive init ------------------------------------*/
533 static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
538 /* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
539 static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
541 struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
542 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
546 memset(data, 0, sizeof(*data));
548 data->mac_param_nid = NID_undef;
551 struct gost_mac_key *key = EVP_PKEY_get0(pkey);
553 data->mac_param_nid = key->mac_param_nid;
554 data->mac_size = key->mac_size;
558 EVP_PKEY_CTX_set_data(ctx, data);
562 static int pkey_gost_omac_init(EVP_PKEY_CTX *ctx, size_t mac_size)
564 struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
565 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
569 memset(data, 0, sizeof(*data));
570 data->mac_size = mac_size;
571 data->mac_param_nid = NID_undef;
574 struct gost_mac_key *key = EVP_PKEY_get0(pkey);
576 data->mac_param_nid = key->mac_param_nid;
577 data->mac_size = key->mac_size;
581 EVP_PKEY_CTX_set_data(ctx, data);
585 static int pkey_gost_magma_mac_init(EVP_PKEY_CTX *ctx)
587 return pkey_gost_omac_init(ctx, 8);
590 static int pkey_gost_grasshopper_mac_init(EVP_PKEY_CTX *ctx)
592 return pkey_gost_omac_init(ctx, 16);
595 static void pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx)
597 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
602 static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, ossl3_const EVP_PKEY_CTX *src)
604 struct gost_mac_pmeth_data *dst_data, *src_data;
605 if (!pkey_gost_mac_init(dst)) {
608 src_data = EVP_PKEY_CTX_get_data(src);
609 dst_data = EVP_PKEY_CTX_get_data(dst);
610 if (!src_data || !dst_data)
613 *dst_data = *src_data;
617 static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
619 struct gost_mac_pmeth_data *data =
620 (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
623 case EVP_PKEY_CTRL_MD:
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);
631 data->md = (EVP_MD *)p2;
635 case EVP_PKEY_CTRL_GET_MD:
636 *(const EVP_MD **)p2 = data->md;
639 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
640 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
641 case EVP_PKEY_CTRL_PKCS7_SIGN:
643 case EVP_PKEY_CTRL_SET_MAC_KEY:
645 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
649 memcpy(data->key, p2, 32);
652 case EVP_PKEY_CTRL_GOST_PARAMSET:
654 struct gost_cipher_info *param = p2;
655 data->mac_param_nid = param->nid;
658 case EVP_PKEY_CTRL_DIGESTINIT:
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);
665 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
666 GOST_R_MAC_KEY_NOT_SET);
669 key = EVP_PKEY_get0(pkey);
671 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
672 GOST_R_MAC_KEY_NOT_SET);
675 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
676 (mctx, EVP_MD_CTRL_SET_KEY, 0, key);
678 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
679 (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
682 case EVP_PKEY_CTRL_MAC_LEN:
684 if (p1 < 1 || p1 > 8) {
686 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_SIZE);
696 static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
697 const char *type, const char *value)
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);
705 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
708 if (strcmp(type, hexkey_ctrl_string) == 0) {
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);
718 ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf);
719 OPENSSL_free(keybuf);
723 if (!strcmp(type, maclen_ctrl_string)) {
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);
730 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN, size, NULL);
732 if (strcmp(type, param_ctrl_string) == 0) {
733 ASN1_OBJECT *obj = OBJ_txt2obj(value, 0);
734 const struct gost_cipher_info *param = NULL;
736 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
740 param = get_encryption_params(obj);
741 ASN1_OBJECT_free(obj);
743 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
748 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, 0,
754 static int pkey_gost_omac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2, size_t max_size)
756 struct gost_mac_pmeth_data *data =
757 (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
760 case EVP_PKEY_CTRL_MD:
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);
770 data->md = (EVP_MD *)p2;
774 case EVP_PKEY_CTRL_GET_MD:
775 *(const EVP_MD **)p2 = data->md;
778 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
779 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
780 case EVP_PKEY_CTRL_PKCS7_SIGN:
782 case EVP_PKEY_CTRL_SET_MAC_KEY:
784 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
788 memcpy(data->key, p2, 32);
791 case EVP_PKEY_CTRL_DIGESTINIT:
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);
798 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
799 GOST_R_MAC_KEY_NOT_SET);
802 key = EVP_PKEY_get0(pkey);
804 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
805 GOST_R_MAC_KEY_NOT_SET);
808 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
809 (mctx, EVP_MD_CTRL_SET_KEY, 0, key);
811 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
812 (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
815 case EVP_PKEY_CTRL_MAC_LEN:
817 if (p1 < 1 || p1 > max_size) {
819 GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_SIZE);
829 static int pkey_gost_magma_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
831 return pkey_gost_omac_ctrl(ctx, type, p1, p2, 8);
834 static int pkey_gost_grasshopper_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
836 return pkey_gost_omac_ctrl(ctx, type, p1, p2, 16);
839 static int pkey_gost_omac_ctrl_str(EVP_PKEY_CTX *ctx,
840 const char *type, const char *value, size_t max_size)
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);
848 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
851 if (strcmp(type, hexkey_ctrl_string) == 0) {
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);
861 ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf);
862 OPENSSL_free(keybuf);
866 if (!strcmp(type, maclen_ctrl_string)) {
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);
873 return pkey_gost_omac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN, size, NULL, max_size);
878 static int pkey_gost_magma_mac_ctrl_str(EVP_PKEY_CTX *ctx,
879 const char *type, const char *value)
881 return pkey_gost_omac_ctrl_str(ctx, type, value, 8);
884 static int pkey_gost_grasshopper_mac_ctrl_str(EVP_PKEY_CTX *ctx,
885 const char *type, const char *value)
887 return pkey_gost_omac_ctrl_str(ctx, type, value, 8);
890 static int pkey_gost_mac_keygen_base(EVP_PKEY_CTX *ctx,
891 EVP_PKEY *pkey, int mac_nid)
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);
899 keydata = OPENSSL_malloc(sizeof(struct gost_mac_key));
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);
909 static int pkey_gost_mac_keygen_12(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
911 return pkey_gost_mac_keygen_base(ctx, pkey, NID_gost_mac_12);
914 static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
916 return pkey_gost_mac_keygen_base(ctx, pkey, NID_id_Gost28147_89_MAC);
919 static int pkey_gost_magma_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
921 return pkey_gost_mac_keygen_base(ctx, pkey, NID_magma_mac);
924 static int pkey_gost_grasshopper_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
926 return pkey_gost_mac_keygen_base(ctx, pkey, NID_grasshopper_mac);
929 static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
931 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
934 pkey_gost_mac_init(ctx);
937 data = EVP_PKEY_CTX_get_data(ctx);
939 GOSTerr(GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
946 static int pkey_gost_magma_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
948 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
951 pkey_gost_omac_init(ctx, 4);
954 data = EVP_PKEY_CTX_get_data(ctx);
956 GOSTerr(GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
963 static int pkey_gost_grasshopper_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
965 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
968 pkey_gost_omac_init(ctx, 8);
971 data = EVP_PKEY_CTX_get_data(ctx);
973 GOSTerr(GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
980 static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
981 size_t *siglen, EVP_MD_CTX *mctx)
983 unsigned int tmpsiglen;
985 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
989 tmpsiglen = *siglen; /* for platforms where sizeof(int) !=
993 *siglen = data->mac_size;
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;
1004 /* ----------- misc callbacks -------------------------------------*/
1006 /* Callback for both EVP_PKEY_check() and EVP_PKEY_public_check. */
1007 static int pkey_gost_check(EVP_PKEY *pkey)
1009 return EC_KEY_check_key(EVP_PKEY_get0(pkey));
1012 /* ----------------------------------------------------------------*/
1013 int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags)
1015 *pmeth = EVP_PKEY_meth_new(id, flags);
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);
1027 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2001cp_keygen);
1029 EVP_PKEY_meth_set_encrypt(*pmeth,
1030 pkey_gost_encrypt_init,
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);
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);
1046 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen);
1048 EVP_PKEY_meth_set_encrypt(*pmeth,
1049 pkey_gost_encrypt_init,
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);
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);
1066 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen);
1068 EVP_PKEY_meth_set_encrypt(*pmeth,
1069 pkey_gost_encrypt_init,
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);
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);
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);
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);
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);
1121 default: /* Unsupported method */
1124 EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
1125 EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);
1127 EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
1129 * FIXME derive etc...