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