Deleted Added
full compact
gost_pmeth.c (256281) gost_pmeth.c (280304)
1/**********************************************************************
2 * gost_pmeth.c *
3 * Copyright (c) 2005-2006 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 0.9.9 for compilation *
9 **********************************************************************/
10#include <openssl/evp.h>
11#include <openssl/objects.h>
12#include <openssl/ec.h>
1/**********************************************************************
2 * gost_pmeth.c *
3 * Copyright (c) 2005-2006 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 0.9.9 for compilation *
9 **********************************************************************/
10#include <openssl/evp.h>
11#include <openssl/objects.h>
12#include <openssl/ec.h>
13#include <openssl/x509v3.h> /*For string_to_hex */
13#include <openssl/x509v3.h> /* For string_to_hex */
14#include <stdlib.h>
15#include <string.h>
16#include <ctype.h>
17#include "gost_params.h"
18#include "gost_lcl.h"
19#include "e_gost_err.h"
14#include <stdlib.h>
15#include <string.h>
16#include <ctype.h>
17#include "gost_params.h"
18#include "gost_lcl.h"
19#include "e_gost_err.h"
20/*-------init, cleanup, copy - uniform for all algs ---------------*/
20/* -----init, cleanup, copy - uniform for all algs ---------------*/
21/* Allocates new gost_pmeth_data structure and assigns it as data */
22static int pkey_gost_init(EVP_PKEY_CTX *ctx)
21/* Allocates new gost_pmeth_data structure and assigns it as data */
22static int pkey_gost_init(EVP_PKEY_CTX *ctx)
23 {
24 struct gost_pmeth_data *data;
25 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
26 data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
27 if (!data) return 0;
28 memset(data,0,sizeof(struct gost_pmeth_data));
29 if (pkey && EVP_PKEY_get0(pkey))
30 {
31 switch (EVP_PKEY_base_id(pkey)) {
32 case NID_id_GostR3410_94:
33 data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey));
34 break;
35 case NID_id_GostR3410_2001:
36 data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
37 break;
38 default:
39 return 0;
40 }
41 }
42 EVP_PKEY_CTX_set_data(ctx,data);
43 return 1;
44 }
23{
24 struct gost_pmeth_data *data;
25 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
26 data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
27 if (!data)
28 return 0;
29 memset(data, 0, sizeof(struct gost_pmeth_data));
30 if (pkey && EVP_PKEY_get0(pkey)) {
31 switch (EVP_PKEY_base_id(pkey)) {
32 case NID_id_GostR3410_94:
33 data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey));
34 break;
35 case NID_id_GostR3410_2001:
36 data->sign_param_nid =
37 EC_GROUP_get_curve_name(EC_KEY_get0_group
38 (EVP_PKEY_get0((EVP_PKEY *)pkey)));
39 break;
40 default:
41 return 0;
42 }
43 }
44 EVP_PKEY_CTX_set_data(ctx, data);
45 return 1;
46}
45
46/* Copies contents of gost_pmeth_data structure */
47static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
47
48/* Copies contents of gost_pmeth_data structure */
49static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
48 {
49 struct gost_pmeth_data *dst_data,*src_data;
50 if (!pkey_gost_init(dst))
51 {
52 return 0;
53 }
54 src_data = EVP_PKEY_CTX_get_data(src);
55 dst_data = EVP_PKEY_CTX_get_data(dst);
56 *dst_data = *src_data;
57 if (src_data -> shared_ukm) {
58 dst_data->shared_ukm=NULL;
59 }
60 return 1;
61 }
50{
51 struct gost_pmeth_data *dst_data, *src_data;
52 if (!pkey_gost_init(dst)) {
53 return 0;
54 }
55 src_data = EVP_PKEY_CTX_get_data(src);
56 dst_data = EVP_PKEY_CTX_get_data(dst);
57 *dst_data = *src_data;
58 if (src_data->shared_ukm) {
59 dst_data->shared_ukm = NULL;
60 }
61 return 1;
62}
62
63/* Frees up gost_pmeth_data structure */
63
64/* Frees up gost_pmeth_data structure */
64static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx)
65 {
66 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
67 if (data->shared_ukm) OPENSSL_free(data->shared_ukm);
68 OPENSSL_free(data);
69 }
65static void pkey_gost_cleanup(EVP_PKEY_CTX *ctx)
66{
67 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
68 if (data->shared_ukm)
69 OPENSSL_free(data->shared_ukm);
70 OPENSSL_free(data);
71}
70
71/* --------------------- control functions ------------------------------*/
72static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
72
73/* --------------------- control functions ------------------------------*/
74static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
73 {
74 struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
75 switch (type)
76 {
77 case EVP_PKEY_CTRL_MD:
78 {
79 if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94)
80 {
81 GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
82 return 0;
83 }
84 pctx->md = (EVP_MD *)p2;
85 return 1;
86 }
87 break;
75{
76 struct gost_pmeth_data *pctx =
77 (struct gost_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
78 switch (type) {
79 case EVP_PKEY_CTRL_MD:
80 {
81 if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94) {
82 GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
83 return 0;
84 }
85 pctx->md = (EVP_MD *)p2;
86 return 1;
87 }
88 break;
88
89
89 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
90 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
91 case EVP_PKEY_CTRL_PKCS7_SIGN:
92 case EVP_PKEY_CTRL_DIGESTINIT:
93#ifndef OPENSSL_NO_CMS
94 case EVP_PKEY_CTRL_CMS_ENCRYPT:
95 case EVP_PKEY_CTRL_CMS_DECRYPT:
96 case EVP_PKEY_CTRL_CMS_SIGN:
97#endif
98 return 1;
90 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
91 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
92 case EVP_PKEY_CTRL_PKCS7_SIGN:
93 case EVP_PKEY_CTRL_DIGESTINIT:
94#ifndef OPENSSL_NO_CMS
95 case EVP_PKEY_CTRL_CMS_ENCRYPT:
96 case EVP_PKEY_CTRL_CMS_DECRYPT:
97 case EVP_PKEY_CTRL_CMS_SIGN:
98#endif
99 return 1;
99
100
100 case EVP_PKEY_CTRL_GOST_PARAMSET:
101 pctx->sign_param_nid = (int)p1;
102 return 1;
103 case EVP_PKEY_CTRL_SET_IV:
104 pctx->shared_ukm=OPENSSL_malloc((int)p1);
105 memcpy(pctx->shared_ukm,p2,(int) p1);
106 return 1;
107 case EVP_PKEY_CTRL_PEER_KEY:
108 if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */
109 return 1;
110 if (p1 == 2) /* TLS: peer key used? */
111 return pctx->peer_key_used;
112 if (p1 == 3) /* TLS: peer key used! */
113 return (pctx->peer_key_used = 1);
114 return -2;
115 }
116 return -2;
117 }
101 case EVP_PKEY_CTRL_GOST_PARAMSET:
102 pctx->sign_param_nid = (int)p1;
103 return 1;
104 case EVP_PKEY_CTRL_SET_IV:
105 pctx->shared_ukm = OPENSSL_malloc((int)p1);
106 memcpy(pctx->shared_ukm, p2, (int)p1);
107 return 1;
108 case EVP_PKEY_CTRL_PEER_KEY:
109 if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */
110 return 1;
111 if (p1 == 2) /* TLS: peer key used? */
112 return pctx->peer_key_used;
113 if (p1 == 3) /* TLS: peer key used! */
114 return (pctx->peer_key_used = 1);
115 return -2;
116 }
117 return -2;
118}
118
119
119
120static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
120static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
121 const char *type, const char *value)
122 {
123 int param_nid=0;
124 if(!strcmp(type, param_ctrl_string))
125 {
126 if (!value)
127 {
128 return 0;
129 }
130 if (strlen(value) == 1)
131 {
132 switch(toupper((unsigned char)value[0]))
133 {
134 case 'A':
135 param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
136 break;
137 case 'B':
138 param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet;
139 break;
140 case 'C':
141 param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet;
142 break;
143 case 'D':
144 param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet;
145 break;
146 default:
147 return 0;
148 break;
149 }
150 }
151 else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X'))
152 {
153 switch (toupper((unsigned char)value[1]))
154 {
155 case 'A':
156 param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
157 break;
158 case 'B':
159 param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet;
160 break;
161 case 'C':
162 param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet;
163 break;
164 default:
165 return 0;
166 break;
167 }
168 }
169 else
170 {
171 R3410_params *p = R3410_paramset;
172 param_nid = OBJ_txt2nid(value);
173 if (param_nid == NID_undef)
174 {
175 return 0;
176 }
177 for (;p->nid != NID_undef;p++)
178 {
179 if (p->nid == param_nid) break;
180 }
181 if (p->nid == NID_undef)
182 {
183 GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR,
184 GOST_R_INVALID_PARAMSET);
185 return 0;
186 }
187 }
121 const char *type, const char *value)
122{
123 int param_nid = 0;
124 if (!strcmp(type, param_ctrl_string)) {
125 if (!value) {
126 return 0;
127 }
128 if (strlen(value) == 1) {
129 switch (toupper((unsigned char)value[0])) {
130 case 'A':
131 param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
132 break;
133 case 'B':
134 param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet;
135 break;
136 case 'C':
137 param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet;
138 break;
139 case 'D':
140 param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet;
141 break;
142 default:
143 return 0;
144 break;
145 }
146 } else if ((strlen(value) == 2)
147 && (toupper((unsigned char)value[0]) == 'X')) {
148 switch (toupper((unsigned char)value[1])) {
149 case 'A':
150 param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
151 break;
152 case 'B':
153 param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet;
154 break;
155 case 'C':
156 param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet;
157 break;
158 default:
159 return 0;
160 break;
161 }
162 } else {
163 R3410_params *p = R3410_paramset;
164 param_nid = OBJ_txt2nid(value);
165 if (param_nid == NID_undef) {
166 return 0;
167 }
168 for (; p->nid != NID_undef; p++) {
169 if (p->nid == param_nid)
170 break;
171 }
172 if (p->nid == NID_undef) {
173 GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR, GOST_R_INVALID_PARAMSET);
174 return 0;
175 }
176 }
188
177
189 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
190 param_nid, NULL);
191 }
192 return -2;
193 }
178 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
179 param_nid, NULL);
180 }
181 return -2;
182}
194
195static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
183
184static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
196 const char *type, const char *value)
197 {
198 int param_nid=0;
199 if(!strcmp(type, param_ctrl_string))
200 {
201 if (!value)
202 {
203 return 0;
204 }
205 if (strlen(value) == 1)
206 {
207 switch(toupper((unsigned char)value[0]))
208 {
209 case 'A':
210 param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
211 break;
212 case 'B':
213 param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
214 break;
215 case 'C':
216 param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
217 break;
218 case '0':
219 param_nid = NID_id_GostR3410_2001_TestParamSet;
220 break;
221 default:
222 return 0;
223 break;
224 }
225 }
226 else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X'))
227 {
228 switch (toupper((unsigned char)value[1]))
229 {
230 case 'A':
231 param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
232 break;
233 case 'B':
234 param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
235 break;
236 default:
237 return 0;
238 break;
239 }
240 }
241 else
242 {
243 R3410_2001_params *p = R3410_2001_paramset;
244 param_nid = OBJ_txt2nid(value);
245 if (param_nid == NID_undef)
246 {
247 return 0;
248 }
249 for (;p->nid != NID_undef;p++)
250 {
251 if (p->nid == param_nid) break;
252 }
253 if (p->nid == NID_undef)
254 {
255 GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR,
256 GOST_R_INVALID_PARAMSET);
257 return 0;
258 }
259 }
185 const char *type, const char *value)
186{
187 int param_nid = 0;
188 if (!strcmp(type, param_ctrl_string)) {
189 if (!value) {
190 return 0;
191 }
192 if (strlen(value) == 1) {
193 switch (toupper((unsigned char)value[0])) {
194 case 'A':
195 param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
196 break;
197 case 'B':
198 param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
199 break;
200 case 'C':
201 param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
202 break;
203 case '0':
204 param_nid = NID_id_GostR3410_2001_TestParamSet;
205 break;
206 default:
207 return 0;
208 break;
209 }
210 } else if ((strlen(value) == 2)
211 && (toupper((unsigned char)value[0]) == 'X')) {
212 switch (toupper((unsigned char)value[1])) {
213 case 'A':
214 param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
215 break;
216 case 'B':
217 param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
218 break;
219 default:
220 return 0;
221 break;
222 }
223 } else {
224 R3410_2001_params *p = R3410_2001_paramset;
225 param_nid = OBJ_txt2nid(value);
226 if (param_nid == NID_undef) {
227 return 0;
228 }
229 for (; p->nid != NID_undef; p++) {
230 if (p->nid == param_nid)
231 break;
232 }
233 if (p->nid == NID_undef) {
234 GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR, GOST_R_INVALID_PARAMSET);
235 return 0;
236 }
237 }
260
238
261 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
262 param_nid, NULL);
263 }
264 return -2;
265 }
239 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
240 param_nid, NULL);
241 }
242 return -2;
243}
266
267/* --------------------- key generation --------------------------------*/
268
244
245/* --------------------- key generation --------------------------------*/
246
269static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) {
270 return 1;
271}
272static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
273 {
274 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
275 DSA *dsa=NULL;
276 if (data->sign_param_nid == NID_undef)
277 {
278 GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN,
279 GOST_R_NO_PARAMETERS_SET);
280 return 0;
281 }
282 dsa = DSA_new();
283 if (!fill_GOST94_params(dsa,data->sign_param_nid))
284 {
285 DSA_free(dsa);
286 return 0;
287 }
288 EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa);
289 return 1;
290 }
247static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx)
248{
249 return 1;
250}
251
252static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
253{
254 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
255 DSA *dsa = NULL;
256 if (data->sign_param_nid == NID_undef) {
257 GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
258 return 0;
259 }
260 dsa = DSA_new();
261 if (!fill_GOST94_params(dsa, data->sign_param_nid)) {
262 DSA_free(dsa);
263 return 0;
264 }
265 EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa);
266 return 1;
267}
268
291static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
269static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
292 {
293 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
294 EC_KEY *ec=NULL;
270{
271 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
272 EC_KEY *ec = NULL;
295
273
296 if (data->sign_param_nid == NID_undef)
297 {
298 GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN,
299 GOST_R_NO_PARAMETERS_SET);
300 return 0;
301 }
302 if (!ec)
303 ec = EC_KEY_new();
304 if (!fill_GOST2001_params(ec,data->sign_param_nid))
305 {
306 EC_KEY_free(ec);
307 return 0;
308 }
309 EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec);
310 return 1;
311 }
274 if (data->sign_param_nid == NID_undef) {
275 GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
276 return 0;
277 }
278 if (!ec)
279 ec = EC_KEY_new();
280 if (!fill_GOST2001_params(ec, data->sign_param_nid)) {
281 EC_KEY_free(ec);
282 return 0;
283 }
284 EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec);
285 return 1;
286}
312
313/* Generates Gost_R3410_94_cp key */
314static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
287
288/* Generates Gost_R3410_94_cp key */
289static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
315 {
316 DSA *dsa;
317 if (!pkey_gost94_paramgen(ctx,pkey)) return 0;
318 dsa = EVP_PKEY_get0(pkey);
319 gost_sign_keygen(dsa);
320 return 1;
321 }
290{
291 DSA *dsa;
292 if (!pkey_gost94_paramgen(ctx, pkey))
293 return 0;
294 dsa = EVP_PKEY_get0(pkey);
295 gost_sign_keygen(dsa);
296 return 1;
297}
322
323/* Generates GOST_R3410 2001 key and assigns it using specified type */
324static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
298
299/* Generates GOST_R3410 2001 key and assigns it using specified type */
300static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
325 {
326 EC_KEY *ec;
327 if (!pkey_gost01_paramgen(ctx,pkey)) return 0;
328 ec = EVP_PKEY_get0(pkey);
329 gost2001_keygen(ec);
330 return 1;
331 }
301{
302 EC_KEY *ec;
303 if (!pkey_gost01_paramgen(ctx, pkey))
304 return 0;
305 ec = EVP_PKEY_get0(pkey);
306 gost2001_keygen(ec);
307 return 1;
308}
332
309
333
334
335/* ----------- sign callbacks --------------------------------------*/
336
310/* ----------- sign callbacks --------------------------------------*/
311
337static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
338 const unsigned char *tbs, size_t tbs_len)
339 {
340 DSA_SIG *unpacked_sig=NULL;
341 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
342 if (!siglen) return 0;
343 if (!sig)
344 {
345 *siglen= 64; /* better to check size of pkey->pkey.dsa-q */
346 return 1;
347 }
348 unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
349 if (!unpacked_sig)
350 {
351 return 0;
352 }
353 return pack_sign_cp(unpacked_sig,32,sig,siglen);
354 }
312static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
313 size_t *siglen, const unsigned char *tbs,
314 size_t tbs_len)
315{
316 DSA_SIG *unpacked_sig = NULL;
317 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
318 if (!siglen)
319 return 0;
320 if (!sig) {
321 *siglen = 64; /* better to check size of pkey->pkey.dsa-q */
322 return 1;
323 }
324 unpacked_sig = gost_do_sign(tbs, tbs_len, EVP_PKEY_get0(pkey));
325 if (!unpacked_sig) {
326 return 0;
327 }
328 return pack_sign_cp(unpacked_sig, 32, sig, siglen);
329}
355
330
356static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
357 const unsigned char *tbs, size_t tbs_len)
358 {
359 DSA_SIG *unpacked_sig=NULL;
360 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
361 if (!siglen) return 0;
362 if (!sig)
363 {
364 *siglen= 64; /* better to check size of curve order*/
365 return 1;
366 }
367 unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
368 if (!unpacked_sig)
369 {
370 return 0;
371 }
372 return pack_sign_cp(unpacked_sig,32,sig,siglen);
373 }
331static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
332 size_t *siglen, const unsigned char *tbs,
333 size_t tbs_len)
334{
335 DSA_SIG *unpacked_sig = NULL;
336 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
337 if (!siglen)
338 return 0;
339 if (!sig) {
340 *siglen = 64; /* better to check size of curve order */
341 return 1;
342 }
343 unpacked_sig = gost2001_do_sign(tbs, tbs_len, EVP_PKEY_get0(pkey));
344 if (!unpacked_sig) {
345 return 0;
346 }
347 return pack_sign_cp(unpacked_sig, 32, sig, siglen);
348}
374
375/* ------------------- verify callbacks ---------------------------*/
376
377static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
349
350/* ------------------- verify callbacks ---------------------------*/
351
352static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
378 size_t siglen, const unsigned char *tbs, size_t tbs_len)
379 {
380 int ok = 0;
381 EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
382 DSA_SIG *s=unpack_cp_signature(sig,siglen);
383 if (!s) return 0;
384 if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
385 DSA_SIG_free(s);
386 return ok;
387 }
353 size_t siglen, const unsigned char *tbs,
354 size_t tbs_len)
355{
356 int ok = 0;
357 EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
358 DSA_SIG *s = unpack_cp_signature(sig, siglen);
359 if (!s)
360 return 0;
361 if (pub_key)
362 ok = gost_do_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key));
363 DSA_SIG_free(s);
364 return ok;
365}
388
366
389
390static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
367static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
391 size_t siglen, const unsigned char *tbs, size_t tbs_len)
392 {
393 int ok = 0;
394 EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
395 DSA_SIG *s=unpack_cp_signature(sig,siglen);
396 if (!s) return 0;
397#ifdef DEBUG_SIGN
398 fprintf(stderr,"R=");
399 BN_print_fp(stderr,s->r);
400 fprintf(stderr,"\nS=");
401 BN_print_fp(stderr,s->s);
402 fprintf(stderr,"\n");
403#endif
404 if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
405 DSA_SIG_free(s);
406 return ok;
407 }
368 size_t siglen, const unsigned char *tbs,
369 size_t tbs_len)
370{
371 int ok = 0;
372 EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
373 DSA_SIG *s = unpack_cp_signature(sig, siglen);
374 if (!s)
375 return 0;
376#ifdef DEBUG_SIGN
377 fprintf(stderr, "R=");
378 BN_print_fp(stderr, s->r);
379 fprintf(stderr, "\nS=");
380 BN_print_fp(stderr, s->s);
381 fprintf(stderr, "\n");
382#endif
383 if (pub_key)
384 ok = gost2001_do_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key));
385 DSA_SIG_free(s);
386 return ok;
387}
408
409/* ------------- encrypt init -------------------------------------*/
410/* Generates ephermeral key */
411static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
388
389/* ------------- encrypt init -------------------------------------*/
390/* Generates ephermeral key */
391static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
412 {
413 return 1;
414 }
392{
393 return 1;
394}
395
415/* --------------- Derive init ------------------------------------*/
416static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
417{
396/* --------------- Derive init ------------------------------------*/
397static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
398{
418 return 1;
399 return 1;
419}
400}
401
420/* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
421static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
402/* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
403static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
422 {
423 struct gost_mac_pmeth_data *data;
424 data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data));
425 if (!data) return 0;
426 memset(data,0,sizeof(struct gost_mac_pmeth_data));
427 EVP_PKEY_CTX_set_data(ctx,data);
428 return 1;
429 }
430static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx)
431 {
432 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
433 OPENSSL_free(data);
434 }
404{
405 struct gost_mac_pmeth_data *data;
406 data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data));
407 if (!data)
408 return 0;
409 memset(data, 0, sizeof(struct gost_mac_pmeth_data));
410 EVP_PKEY_CTX_set_data(ctx, data);
411 return 1;
412}
413
414static void pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx)
415{
416 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
417 OPENSSL_free(data);
418}
419
435static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
420static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
436 {
437 struct gost_mac_pmeth_data *dst_data,*src_data;
438 if (!pkey_gost_mac_init(dst))
439 {
440 return 0;
441 }
442 src_data = EVP_PKEY_CTX_get_data(src);
443 dst_data = EVP_PKEY_CTX_get_data(dst);
444 *dst_data = *src_data;
445 return 1;
446 }
447
421{
422 struct gost_mac_pmeth_data *dst_data, *src_data;
423 if (!pkey_gost_mac_init(dst)) {
424 return 0;
425 }
426 src_data = EVP_PKEY_CTX_get_data(src);
427 dst_data = EVP_PKEY_CTX_get_data(dst);
428 *dst_data = *src_data;
429 return 1;
430}
431
448static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
432static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
449 {
450 struct gost_mac_pmeth_data *data =
451(struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
433{
434 struct gost_mac_pmeth_data *data =
435 (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
452
436
453 switch (type)
454 {
455 case EVP_PKEY_CTRL_MD:
456 {
457 if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC)
458 {
459 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE);
460 return 0;
461 }
462 data->md = (EVP_MD *)p2;
463 return 1;
464 }
465 break;
437 switch (type) {
438 case EVP_PKEY_CTRL_MD:
439 {
440 if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC) {
441 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
442 GOST_R_INVALID_DIGEST_TYPE);
443 return 0;
444 }
445 data->md = (EVP_MD *)p2;
446 return 1;
447 }
448 break;
466
449
467 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
468 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
469 case EVP_PKEY_CTRL_PKCS7_SIGN:
470 return 1;
471 case EVP_PKEY_CTRL_SET_MAC_KEY:
472 if (p1 != 32)
473 {
474 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
475 GOST_R_INVALID_MAC_KEY_LENGTH);
476 return 0;
477 }
450 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
451 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
452 case EVP_PKEY_CTRL_PKCS7_SIGN:
453 return 1;
454 case EVP_PKEY_CTRL_SET_MAC_KEY:
455 if (p1 != 32) {
456 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
457 return 0;
458 }
478
459
479 memcpy(data->key,p2,32);
480 data->key_set = 1;
481 return 1;
482 case EVP_PKEY_CTRL_DIGESTINIT:
483 {
484 EVP_MD_CTX *mctx = p2;
485 void *key;
486 if (!data->key_set)
487 {
488 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
489 if (!pkey)
490 {
491 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
492 return 0;
493 }
494 key = EVP_PKEY_get0(pkey);
495 if (!key)
496 {
497 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
498 return 0;
499 }
500 } else {
501 key = &(data->key);
502 }
503 return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key);
504 }
505 }
506 return -2;
507 }
460 memcpy(data->key, p2, 32);
461 data->key_set = 1;
462 return 1;
463 case EVP_PKEY_CTRL_DIGESTINIT:
464 {
465 EVP_MD_CTX *mctx = p2;
466 void *key;
467 if (!data->key_set) {
468 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
469 if (!pkey) {
470 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
471 GOST_R_MAC_KEY_NOT_SET);
472 return 0;
473 }
474 key = EVP_PKEY_get0(pkey);
475 if (!key) {
476 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
477 GOST_R_MAC_KEY_NOT_SET);
478 return 0;
479 }
480 } else {
481 key = &(data->key);
482 }
483 return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32, key);
484 }
485 }
486 return -2;
487}
488
508static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
489static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
509 const char *type, const char *value)
510 {
511 if (!strcmp(type, key_ctrl_string))
512 {
513 if (strlen(value)!=32)
514 {
515 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
516 GOST_R_INVALID_MAC_KEY_LENGTH);
517 return 0;
518 }
519 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
520 32,(char *)value);
521 }
522 if (!strcmp(type, hexkey_ctrl_string))
523 {
524 long keylen; int ret;
525 unsigned char *keybuf=string_to_hex(value,&keylen);
526 if (keylen != 32)
527 {
528 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
529 GOST_R_INVALID_MAC_KEY_LENGTH);
530 OPENSSL_free(keybuf);
531 return 0;
532 }
533 ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
534 32,keybuf);
535 OPENSSL_free(keybuf);
536 return ret;
537
538 }
539 return -2;
540 }
490 const char *type, const char *value)
491{
492 if (!strcmp(type, key_ctrl_string)) {
493 if (strlen(value) != 32) {
494 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
495 GOST_R_INVALID_MAC_KEY_LENGTH);
496 return 0;
497 }
498 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
499 32, (char *)value);
500 }
501 if (!strcmp(type, hexkey_ctrl_string)) {
502 long keylen;
503 int ret;
504 unsigned char *keybuf = string_to_hex(value, &keylen);
505 if (keylen != 32) {
506 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
507 GOST_R_INVALID_MAC_KEY_LENGTH);
508 OPENSSL_free(keybuf);
509 return 0;
510 }
511 ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf);
512 OPENSSL_free(keybuf);
513 return ret;
541
514
515 }
516 return -2;
517}
518
542static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
519static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
543 {
544 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
545 unsigned char *keydata;
546 if (!data->key_set)
547 {
548 GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN,GOST_R_MAC_KEY_NOT_SET);
549 return 0;
550 }
551 keydata = OPENSSL_malloc(32);
552 memcpy(keydata,data->key,32);
553 EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata);
554 return 1;
555 }
520{
521 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
522 unsigned char *keydata;
523 if (!data->key_set) {
524 GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET);
525 return 0;
526 }
527 keydata = OPENSSL_malloc(32);
528 memcpy(keydata, data->key, 32);
529 EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata);
530 return 1;
531}
556
557static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
532
533static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
558 {
559 return 1;
534{
535 return 1;
560}
561
536}
537
562static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx)
563 {
564 unsigned int tmpsiglen=*siglen; /* for platforms where sizeof(int)!=sizeof(size_t)*/
565 int ret;
566 if (!sig)
567 {
568 *siglen = 4;
569 return 1;
570 }
571 ret=EVP_DigestFinal_ex(mctx,sig,&tmpsiglen);
572 *siglen = tmpsiglen;
573 return ret;
574 }
538static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
539 size_t *siglen, EVP_MD_CTX *mctx)
540{
541 unsigned int tmpsiglen = *siglen; /* for platforms where
542 * sizeof(int)!=sizeof(size_t) */
543 int ret;
544 if (!sig) {
545 *siglen = 4;
546 return 1;
547 }
548 ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen);
549 *siglen = tmpsiglen;
550 return ret;
551}
552
575/* ----------------------------------------------------------------*/
553/* ----------------------------------------------------------------*/
576int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags)
577 {
578 *pmeth = EVP_PKEY_meth_new(id, flags);
579 if (!*pmeth) return 0;
554int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags)
555{
556 *pmeth = EVP_PKEY_meth_new(id, flags);
557 if (!*pmeth)
558 return 0;
580
559
581 switch (id)
582 {
583 case NID_id_GostR3410_94:
584 EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94_str);
585 EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cp_keygen);
586 EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign);
587 EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify);
588 EVP_PKEY_meth_set_encrypt(*pmeth,
589 pkey_gost_encrypt_init, pkey_GOST94cp_encrypt);
590 EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt);
591 EVP_PKEY_meth_set_derive(*pmeth,
592 pkey_gost_derive_init, pkey_gost94_derive);
593 EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost94_paramgen);
594 break;
595 case NID_id_GostR3410_2001:
596 EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl01_str);
597 EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign);
598 EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify);
560 switch (id) {
561 case NID_id_GostR3410_94:
562 EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost_ctrl94_str);
563 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost94cp_keygen);
564 EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign);
565 EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify);
566 EVP_PKEY_meth_set_encrypt(*pmeth,
567 pkey_gost_encrypt_init,
568 pkey_GOST94cp_encrypt);
569 EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt);
570 EVP_PKEY_meth_set_derive(*pmeth,
571 pkey_gost_derive_init, pkey_gost94_derive);
572 EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,
573 pkey_gost94_paramgen);
574 break;
575 case NID_id_GostR3410_2001:
576 EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost_ctrl01_str);
577 EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign);
578 EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify);
599
579
600 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen);
580 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen);
601
581
602 EVP_PKEY_meth_set_encrypt(*pmeth,
603 pkey_gost_encrypt_init, pkey_GOST01cp_encrypt);
604 EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt);
605 EVP_PKEY_meth_set_derive(*pmeth,
606 pkey_gost_derive_init, pkey_gost2001_derive);
607 EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost01_paramgen);
608 break;
609 case NID_id_Gost28147_89_MAC:
610 EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_gost_mac_ctrl_str);
611 EVP_PKEY_meth_set_signctx(*pmeth,pkey_gost_mac_signctx_init, pkey_gost_mac_signctx);
612 EVP_PKEY_meth_set_keygen(*pmeth,NULL, pkey_gost_mac_keygen);
613 EVP_PKEY_meth_set_init(*pmeth,pkey_gost_mac_init);
614 EVP_PKEY_meth_set_cleanup(*pmeth,pkey_gost_mac_cleanup);
615 EVP_PKEY_meth_set_copy(*pmeth,pkey_gost_mac_copy);
616 return 1;
617 default: /*Unsupported method*/
618 return 0;
619 }
620 EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
621 EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);
582 EVP_PKEY_meth_set_encrypt(*pmeth,
583 pkey_gost_encrypt_init,
584 pkey_GOST01cp_encrypt);
585 EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt);
586 EVP_PKEY_meth_set_derive(*pmeth,
587 pkey_gost_derive_init, pkey_gost2001_derive);
588 EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,
589 pkey_gost01_paramgen);
590 break;
591 case NID_id_Gost28147_89_MAC:
592 EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl,
593 pkey_gost_mac_ctrl_str);
594 EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_mac_signctx_init,
595 pkey_gost_mac_signctx);
596 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_mac_keygen);
597 EVP_PKEY_meth_set_init(*pmeth, pkey_gost_mac_init);
598 EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
599 EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
600 return 1;
601 default: /* Unsupported method */
602 return 0;
603 }
604 EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
605 EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);
622
606
623 EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
624 /*FIXME derive etc...*/
625
626 return 1;
627 }
607 EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
608 /*
609 * FIXME derive etc...
610 */
628
611
612 return 1;
613}