summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/gost/gostr341001_ameth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/gost/gostr341001_ameth.c')
-rw-r--r--src/lib/libcrypto/gost/gostr341001_ameth.c727
1 files changed, 0 insertions, 727 deletions
diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c b/src/lib/libcrypto/gost/gostr341001_ameth.c
deleted file mode 100644
index e8e8c8aa82..0000000000
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ /dev/null
@@ -1,727 +0,0 @@
1/* $OpenBSD: gostr341001_ameth.c,v 1.24 2024/01/04 17:01:26 tb Exp $ */
2/*
3 * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
4 * Copyright (c) 2005-2006 Cryptocom LTD
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. All advertising materials mentioning features or use of this
19 * software must display the following acknowledgment:
20 * "This product includes software developed by the OpenSSL Project
21 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
22 *
23 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24 * endorse or promote products derived from this software without
25 * prior written permission. For written permission, please contact
26 * openssl-core@openssl.org.
27 *
28 * 5. Products derived from this software may not be called "OpenSSL"
29 * nor may "OpenSSL" appear in their names without prior written
30 * permission of the OpenSSL Project.
31 *
32 * 6. Redistributions of any form whatsoever must retain the following
33 * acknowledgment:
34 * "This product includes software developed by the OpenSSL Project
35 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48 * OF THE POSSIBILITY OF SUCH DAMAGE.
49 * ====================================================================
50 */
51
52#include <string.h>
53
54#include <openssl/opensslconf.h>
55
56#ifndef OPENSSL_NO_GOST
57#include <openssl/bn.h>
58#include <openssl/evp.h>
59#include <openssl/ec.h>
60#include <openssl/err.h>
61#include <openssl/x509.h>
62#include <openssl/gost.h>
63
64
65#include "asn1_local.h"
66#include "evp_local.h"
67#include "gost_local.h"
68#include "gost_asn1.h"
69
70static void
71pkey_free_gost01(EVP_PKEY *key)
72{
73 GOST_KEY_free(key->pkey.gost);
74}
75
76/*
77 * Parses GOST algorithm parameters from X509_ALGOR and
78 * modifies pkey setting NID and parameters
79 */
80static int
81decode_gost01_algor_params(EVP_PKEY *pkey, const unsigned char **p, int len)
82{
83 int param_nid = NID_undef, digest_nid = NID_undef;
84 GOST_KEY_PARAMS *gkp = NULL;
85 EC_GROUP *group;
86 GOST_KEY *ec;
87
88 gkp = d2i_GOST_KEY_PARAMS(NULL, p, len);
89 if (gkp == NULL) {
90 GOSTerror(GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
91 return 0;
92 }
93 param_nid = OBJ_obj2nid(gkp->key_params);
94 digest_nid = OBJ_obj2nid(gkp->hash_params);
95 GOST_KEY_PARAMS_free(gkp);
96
97 ec = pkey->pkey.gost;
98 if (ec == NULL) {
99 ec = GOST_KEY_new();
100 if (ec == NULL) {
101 GOSTerror(ERR_R_MALLOC_FAILURE);
102 return 0;
103 }
104 if (EVP_PKEY_assign_GOST(pkey, ec) == 0) {
105 GOST_KEY_free(ec);
106 return 0;
107 }
108 }
109
110 group = EC_GROUP_new_by_curve_name(param_nid);
111 if (group == NULL) {
112 GOSTerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
113 return 0;
114 }
115 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
116 if (GOST_KEY_set_group(ec, group) == 0) {
117 EC_GROUP_free(group);
118 return 0;
119 }
120 EC_GROUP_free(group);
121 if (GOST_KEY_set_digest(ec, digest_nid) == 0)
122 return 0;
123 return 1;
124}
125
126static ASN1_STRING *
127encode_gost01_algor_params(const EVP_PKEY *key)
128{
129 ASN1_STRING *params = ASN1_STRING_new();
130 GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
131 int pkey_param_nid = NID_undef;
132
133 if (params == NULL || gkp == NULL) {
134 GOSTerror(ERR_R_MALLOC_FAILURE);
135 ASN1_STRING_free(params);
136 params = NULL;
137 goto err;
138 }
139
140 pkey_param_nid =
141 EC_GROUP_get_curve_name(GOST_KEY_get0_group(key->pkey.gost));
142 gkp->key_params = OBJ_nid2obj(pkey_param_nid);
143 gkp->hash_params = OBJ_nid2obj(GOST_KEY_get_digest(key->pkey.gost));
144 /*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); */
145 params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
146 if (params->length <= 0) {
147 GOSTerror(ERR_R_MALLOC_FAILURE);
148 ASN1_STRING_free(params);
149 params = NULL;
150 goto err;
151 }
152 params->type = V_ASN1_SEQUENCE;
153err:
154 GOST_KEY_PARAMS_free(gkp);
155 return params;
156}
157
158static int
159pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
160{
161 const GOST_KEY *ea = a->pkey.gost;
162 const GOST_KEY *eb = b->pkey.gost;
163 const EC_POINT *ka, *kb;
164 int ret = 0;
165
166 if (ea == NULL || eb == NULL)
167 return 0;
168 ka = GOST_KEY_get0_public_key(ea);
169 kb = GOST_KEY_get0_public_key(eb);
170 if (ka == NULL || kb == NULL)
171 return 0;
172 ret = (0 == EC_POINT_cmp(GOST_KEY_get0_group(ea), ka, kb, NULL));
173 return ret;
174}
175
176static int
177pkey_size_gost01(const EVP_PKEY *pk)
178{
179 if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512)
180 return 128;
181 return 64;
182}
183
184static int
185pkey_bits_gost01(const EVP_PKEY *pk)
186{
187 if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512)
188 return 512;
189 return 256;
190}
191
192static int
193pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub)
194{
195 X509_ALGOR *palg = NULL;
196 const unsigned char *pubkey_buf = NULL;
197 const unsigned char *p;
198 ASN1_OBJECT *palgobj = NULL;
199 int pub_len;
200 BIGNUM *X, *Y;
201 ASN1_OCTET_STRING *octet = NULL;
202 int len;
203 int ret;
204 int ptype = V_ASN1_UNDEF;
205 ASN1_STRING *pval = NULL;
206
207 if (X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)
208 == 0)
209 return 0;
210 /* Called for the side effect of freeing pk->pkey. */
211 if (!EVP_PKEY_set_type(pk, EVP_PKEY_GOSTR01))
212 return 0;
213 X509_ALGOR_get0(NULL, &ptype, (const void **)&pval, palg);
214 if (ptype != V_ASN1_SEQUENCE) {
215 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
216 return 0;
217 }
218 p = pval->data;
219 if (decode_gost01_algor_params(pk, &p, pval->length) == 0) {
220 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
221 return 0;
222 }
223
224 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
225 if (octet == NULL) {
226 GOSTerror(ERR_R_MALLOC_FAILURE);
227 return 0;
228 }
229 len = octet->length / 2;
230
231 X = GOST_le2bn(octet->data, len, NULL);
232 Y = GOST_le2bn(octet->data + len, len, NULL);
233
234 ASN1_OCTET_STRING_free(octet);
235
236 ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y);
237 if (ret == 0)
238 GOSTerror(ERR_R_EC_LIB);
239
240 BN_free(X);
241 BN_free(Y);
242
243 return ret;
244}
245
246static int
247pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
248{
249 ASN1_OBJECT *algobj = NULL;
250 ASN1_OCTET_STRING *octet = NULL;
251 ASN1_STRING *params = NULL;
252 void *pval = NULL;
253 unsigned char *buf = NULL, *sptr;
254 int key_size, ret = 0;
255 const EC_POINT *pub_key;
256 BIGNUM *X = NULL, *Y = NULL;
257 const GOST_KEY *ec = pk->pkey.gost;
258 int ptype = V_ASN1_UNDEF;
259
260 algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec)));
261 if (pk->save_parameters) {
262 params = encode_gost01_algor_params(pk);
263 if (params == NULL)
264 return 0;
265 pval = params;
266 ptype = V_ASN1_SEQUENCE;
267 }
268
269 key_size = GOST_KEY_get_size(ec);
270
271 pub_key = GOST_KEY_get0_public_key(ec);
272 if (pub_key == NULL) {
273 GOSTerror(GOST_R_PUBLIC_KEY_UNDEFINED);
274 goto err;
275 }
276
277 octet = ASN1_OCTET_STRING_new();
278 if (octet == NULL) {
279 GOSTerror(ERR_R_MALLOC_FAILURE);
280 goto err;
281 }
282
283 ret = ASN1_STRING_set(octet, NULL, 2 * key_size);
284 if (ret == 0) {
285 GOSTerror(ERR_R_INTERNAL_ERROR);
286 goto err;
287 }
288
289 sptr = ASN1_STRING_data(octet);
290
291 X = BN_new();
292 Y = BN_new();
293 if (X == NULL || Y == NULL) {
294 GOSTerror(ERR_R_MALLOC_FAILURE);
295 goto err;
296 }
297
298 if (EC_POINT_get_affine_coordinates(GOST_KEY_get0_group(ec),
299 pub_key, X, Y, NULL) == 0) {
300 GOSTerror(ERR_R_EC_LIB);
301 goto err;
302 }
303
304 GOST_bn2le(X, sptr, key_size);
305 GOST_bn2le(Y, sptr + key_size, key_size);
306
307 BN_free(Y);
308 BN_free(X);
309
310 ret = i2d_ASN1_OCTET_STRING(octet, &buf);
311 ASN1_BIT_STRING_free(octet);
312 if (ret < 0)
313 return 0;
314
315 return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
316
317err:
318 BN_free(Y);
319 BN_free(X);
320 ASN1_BIT_STRING_free(octet);
321 ASN1_STRING_free(params);
322 return 0;
323}
324
325static int
326param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx)
327{
328 int param_nid =
329 EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost));
330
331 if (BIO_indent(out, indent, 128) == 0)
332 return 0;
333 BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid));
334 if (BIO_indent(out, indent, 128) == 0)
335 return 0;
336 BIO_printf(out, "Digest Algorithm: %s\n",
337 OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost)));
338 return 1;
339}
340
341static int
342pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx)
343{
344 BN_CTX *ctx = BN_CTX_new();
345 BIGNUM *X, *Y;
346 const EC_POINT *pubkey;
347 const EC_GROUP *group;
348
349 if (ctx == NULL) {
350 GOSTerror(ERR_R_MALLOC_FAILURE);
351 return 0;
352 }
353 BN_CTX_start(ctx);
354 if ((X = BN_CTX_get(ctx)) == NULL)
355 goto err;
356 if ((Y = BN_CTX_get(ctx)) == NULL)
357 goto err;
358 pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost);
359 group = GOST_KEY_get0_group(pkey->pkey.gost);
360 if (EC_POINT_get_affine_coordinates(group, pubkey, X, Y, ctx) == 0) {
361 GOSTerror(ERR_R_EC_LIB);
362 goto err;
363 }
364 if (BIO_indent(out, indent, 128) == 0)
365 goto err;
366 BIO_printf(out, "Public key:\n");
367 if (BIO_indent(out, indent + 3, 128) == 0)
368 goto err;
369 BIO_printf(out, "X:");
370 BN_print(out, X);
371 BIO_printf(out, "\n");
372 if (BIO_indent(out, indent + 3, 128) == 0)
373 goto err;
374 BIO_printf(out, "Y:");
375 BN_print(out, Y);
376 BIO_printf(out, "\n");
377
378 BN_CTX_end(ctx);
379 BN_CTX_free(ctx);
380
381 return param_print_gost01(out, pkey, indent, pctx);
382
383err:
384 BN_CTX_end(ctx);
385 BN_CTX_free(ctx);
386 return 0;
387}
388
389static int
390priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx)
391{
392 const BIGNUM *key;
393
394 if (BIO_indent(out, indent, 128) == 0)
395 return 0;
396 BIO_printf(out, "Private key: ");
397 key = GOST_KEY_get0_private_key(pkey->pkey.gost);
398 if (key == NULL)
399 BIO_printf(out, "<undefined)");
400 else
401 BN_print(out, key);
402 BIO_printf(out, "\n");
403
404 return pub_print_gost01(out, pkey, indent, pctx);
405}
406
407static int
408priv_decode_gost01(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf)
409{
410 const unsigned char *pkey_buf = NULL, *p = NULL;
411 int priv_len = 0;
412 BIGNUM *pk_num = NULL;
413 int ret = 0;
414 const X509_ALGOR *palg = NULL;
415 const ASN1_OBJECT *palg_obj = NULL;
416 ASN1_INTEGER *priv_key = NULL;
417 GOST_KEY *ec;
418 int ptype = V_ASN1_UNDEF;
419 ASN1_STRING *pval = NULL;
420
421 if (PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf) == 0) {
422 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
423 return 0;
424 }
425 /* Called for the side effect of freeing pk->pkey. */
426 if (!EVP_PKEY_set_type(pk, EVP_PKEY_GOSTR01))
427 return 0;
428 X509_ALGOR_get0(NULL, &ptype, (const void **)&pval, palg);
429 if (ptype != V_ASN1_SEQUENCE) {
430 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
431 return 0;
432 }
433 p = pval->data;
434 if (decode_gost01_algor_params(pk, &p, pval->length) == 0) {
435 GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
436 return 0;
437 }
438 p = pkey_buf;
439 if (V_ASN1_OCTET_STRING == *p) {
440 /* New format - Little endian octet string */
441 ASN1_OCTET_STRING *s =
442 d2i_ASN1_OCTET_STRING(NULL, &p, priv_len);
443
444 if (s == NULL) {
445 GOSTerror(EVP_R_DECODE_ERROR);
446 ASN1_STRING_free(s);
447 return 0;
448 }
449
450 pk_num = GOST_le2bn(s->data, s->length, NULL);
451 ASN1_STRING_free(s);
452 } else {
453 priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
454 if (priv_key == NULL)
455 return 0;
456 ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL);
457 ASN1_INTEGER_free(priv_key);
458 if (ret == 0) {
459 GOSTerror(EVP_R_DECODE_ERROR);
460 return 0;
461 }
462 }
463
464 ec = pk->pkey.gost;
465 if (ec == NULL) {
466 ec = GOST_KEY_new();
467 if (ec == NULL) {
468 BN_free(pk_num);
469 return 0;
470 }
471 if (EVP_PKEY_assign_GOST(pk, ec) == 0) {
472 BN_free(pk_num);
473 GOST_KEY_free(ec);
474 return 0;
475 }
476 }
477 if (GOST_KEY_set_private_key(ec, pk_num) == 0) {
478 BN_free(pk_num);
479 return 0;
480 }
481 ret = 0;
482 if (EVP_PKEY_missing_parameters(pk) == 0)
483 ret = gost2001_compute_public(ec) != 0;
484 BN_free(pk_num);
485
486 return ret;
487}
488
489static int
490priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
491{
492 ASN1_OBJECT *algobj =
493 OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost)));
494 ASN1_STRING *params = encode_gost01_algor_params(pk);
495 unsigned char *priv_buf = NULL;
496 int priv_len;
497 ASN1_INTEGER *asn1key = NULL;
498
499 if (params == NULL)
500 return 0;
501
502 asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost),
503 NULL);
504 if (asn1key == NULL) {
505 ASN1_STRING_free(params);
506 return 0;
507 }
508 priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf);
509 ASN1_INTEGER_free(asn1key);
510 return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf,
511 priv_len);
512}
513
514static int
515param_encode_gost01(const EVP_PKEY *pkey, unsigned char **pder)
516{
517 ASN1_STRING *params = encode_gost01_algor_params(pkey);
518 int len;
519
520 if (params == NULL)
521 return 0;
522 len = params->length;
523 if (pder != NULL)
524 memcpy(*pder, params->data, params->length);
525 ASN1_STRING_free(params);
526 return len;
527}
528
529static int
530param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
531{
532 ASN1_OBJECT *obj = NULL;
533 int nid;
534 GOST_KEY *ec;
535 EC_GROUP *group;
536 int ret;
537
538 /* New format */
539 if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder)
540 return decode_gost01_algor_params(pkey, pder, derlen);
541
542 /* Compatibility */
543 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
544 GOSTerror(ERR_R_MALLOC_FAILURE);
545 return 0;
546 }
547 nid = OBJ_obj2nid(obj);
548 ASN1_OBJECT_free(obj);
549
550 ec = GOST_KEY_new();
551 if (ec == NULL) {
552 GOSTerror(ERR_R_MALLOC_FAILURE);
553 return 0;
554 }
555 group = EC_GROUP_new_by_curve_name(nid);
556 if (group == NULL) {
557 GOSTerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
558 GOST_KEY_free(ec);
559 return 0;
560 }
561
562 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
563 if (GOST_KEY_set_group(ec, group) == 0) {
564 GOSTerror(ERR_R_EC_LIB);
565 EC_GROUP_free(group);
566 GOST_KEY_free(ec);
567 return 0;
568 }
569 EC_GROUP_free(group);
570 if (GOST_KEY_set_digest(ec,
571 NID_id_GostR3411_94_CryptoProParamSet) == 0) {
572 GOSTerror(GOST_R_INVALID_DIGEST_TYPE);
573 GOST_KEY_free(ec);
574 return 0;
575 }
576 ret = EVP_PKEY_assign_GOST(pkey, ec);
577 if (ret == 0)
578 GOST_KEY_free(ec);
579 return ret;
580}
581
582static int
583param_missing_gost01(const EVP_PKEY *pk)
584{
585 const GOST_KEY *ec = pk->pkey.gost;
586
587 if (ec == NULL)
588 return 1;
589 if (GOST_KEY_get0_group(ec) == NULL)
590 return 1;
591 if (GOST_KEY_get_digest(ec) == NID_undef)
592 return 1;
593 return 0;
594}
595
596static int
597param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
598{
599 GOST_KEY *eto = to->pkey.gost;
600 const GOST_KEY *efrom = from->pkey.gost;
601 int ret = 1;
602
603 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
604 GOSTerror(GOST_R_INCOMPATIBLE_ALGORITHMS);
605 return 0;
606 }
607 if (efrom == NULL) {
608 GOSTerror(GOST_R_KEY_PARAMETERS_MISSING);
609 return 0;
610 }
611 if (eto == NULL) {
612 eto = GOST_KEY_new();
613 if (eto == NULL) {
614 GOSTerror(ERR_R_MALLOC_FAILURE);
615 return 0;
616 }
617 if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) {
618 GOST_KEY_free(eto);
619 return 0;
620 }
621 }
622 GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom));
623 GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom));
624 if (GOST_KEY_get0_private_key(eto) != NULL)
625 ret = gost2001_compute_public(eto);
626
627 return ret;
628}
629
630static int
631param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
632{
633 if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) !=
634 EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost)))
635 return 0;
636
637 if (GOST_KEY_get_digest(a->pkey.gost) !=
638 GOST_KEY_get_digest(b->pkey.gost))
639 return 0;
640
641 return 1;
642}
643
644static int
645pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2)
646{
647 X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL;
648 int digest = GOST_KEY_get_digest(pkey->pkey.gost);
649
650 switch (op) {
651 case ASN1_PKEY_CTRL_PKCS7_SIGN:
652 if (arg1 == 0)
653 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
654 break;
655
656 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
657 if (arg1 == 0)
658 PKCS7_RECIP_INFO_get0_alg(arg2, &alg3);
659 break;
660 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
661 *(int *)arg2 = GostR3410_get_md_digest(digest);
662 return 2;
663
664 default:
665 return -2;
666 }
667
668 if (alg1)
669 X509_ALGOR_set0(alg1, OBJ_nid2obj(GostR3410_get_md_digest(digest)), V_ASN1_NULL, 0);
670 if (alg2)
671 X509_ALGOR_set0(alg2, OBJ_nid2obj(GostR3410_get_pk_digest(digest)), V_ASN1_NULL, 0);
672 if (alg3) {
673 ASN1_STRING *params = encode_gost01_algor_params(pkey);
674 if (params == NULL) {
675 return -1;
676 }
677 X509_ALGOR_set0(alg3,
678 OBJ_nid2obj(GostR3410_get_pk_digest(digest)),
679 V_ASN1_SEQUENCE, params);
680 }
681
682 return 1;
683}
684
685const EVP_PKEY_ASN1_METHOD gostr01_asn1_meth = {
686 .base_method = &gostr01_asn1_meth,
687 .pkey_id = EVP_PKEY_GOSTR01,
688 .pkey_flags = ASN1_PKEY_SIGPARAM_NULL,
689
690 .pem_str = "GOST2001",
691 .info = "GOST R 34.10-2001",
692
693 .pkey_free = pkey_free_gost01,
694 .pkey_ctrl = pkey_ctrl_gost01,
695
696 .priv_decode = priv_decode_gost01,
697 .priv_encode = priv_encode_gost01,
698 .priv_print = priv_print_gost01,
699
700 .param_decode = param_decode_gost01,
701 .param_encode = param_encode_gost01,
702 .param_missing = param_missing_gost01,
703 .param_copy = param_copy_gost01,
704 .param_cmp = param_cmp_gost01,
705 .param_print = param_print_gost01,
706
707 .pub_decode = pub_decode_gost01,
708 .pub_encode = pub_encode_gost01,
709 .pub_cmp = pub_cmp_gost01,
710 .pub_print = pub_print_gost01,
711 .pkey_size = pkey_size_gost01,
712 .pkey_bits = pkey_bits_gost01,
713};
714
715const EVP_PKEY_ASN1_METHOD gostr12_256_asn1_meth = {
716 .base_method = &gostr01_asn1_meth,
717 .pkey_id = EVP_PKEY_GOSTR12_256,
718 .pkey_flags = ASN1_PKEY_ALIAS,
719};
720
721const EVP_PKEY_ASN1_METHOD gostr12_512_asn1_meth = {
722 .base_method = &gostr01_asn1_meth,
723 .pkey_id = EVP_PKEY_GOSTR12_512,
724 .pkey_flags = ASN1_PKEY_ALIAS,
725};
726
727#endif