Coverage Report

Created: 2022-11-30 06:20

/src/openssl/engines/ccgost/gost_ameth.c
Line
Count
Source (jump to first uncovered line)
1
/**********************************************************************
2
 *                          gost_ameth.c                              *
3
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
4
 *         This file is distributed under the same license as OpenSSL *
5
 *                                                                    *
6
 *       Implementation of RFC 4490/4491 ASN1 method                  *
7
 *       for OpenSSL                                                  *
8
 *          Requires OpenSSL 0.9.9 for compilation                    *
9
 **********************************************************************/
10
#include <string.h>
11
#include <openssl/crypto.h>
12
#include <openssl/err.h>
13
#include <openssl/engine.h>
14
#include <openssl/evp.h>
15
#include <openssl/asn1.h>
16
#ifndef OPENSSL_NO_CMS
17
# include <openssl/cms.h>
18
#endif
19
#include "gost_params.h"
20
#include "gost_lcl.h"
21
#include "e_gost_err.h"
22
23
int gost94_nid_by_params(DSA *p)
24
0
{
25
0
    R3410_params *gost_params;
26
0
    BIGNUM *q = BN_new();
27
0
    for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) {
28
0
        BN_dec2bn(&q, gost_params->q);
29
0
        if (!BN_cmp(q, p->q)) {
30
0
            BN_free(q);
31
0
            return gost_params->nid;
32
0
        }
33
0
    }
34
0
    BN_free(q);
35
0
    return NID_undef;
36
0
}
37
38
static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key)
39
0
{
40
0
    ASN1_STRING *params = ASN1_STRING_new();
41
0
    GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
42
0
    int pkey_param_nid = NID_undef;
43
44
0
    if (!params || !gkp) {
45
0
        GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE);
46
0
        ASN1_STRING_free(params);
47
0
        params = NULL;
48
0
        goto err;
49
0
    }
50
0
    switch (EVP_PKEY_base_id(key)) {
51
0
    case NID_id_GostR3410_2001:
52
0
        pkey_param_nid =
53
0
            EC_GROUP_get_curve_name(EC_KEY_get0_group
54
0
                                    (EVP_PKEY_get0((EVP_PKEY *)key)));
55
0
        break;
56
0
    case NID_id_GostR3410_94:
57
0
        pkey_param_nid =
58
0
            (int)gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key));
59
0
        if (pkey_param_nid == NID_undef) {
60
0
            GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
61
0
                    GOST_R_INVALID_GOST94_PARMSET);
62
0
            ASN1_STRING_free(params);
63
0
            params = NULL;
64
0
            goto err;
65
0
        }
66
0
        break;
67
0
    }
68
0
    gkp->key_params = OBJ_nid2obj(pkey_param_nid);
69
0
    gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
70
    /*
71
     * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);
72
     */
73
0
    params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
74
0
    if (params->length <= 0) {
75
0
        GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE);
76
0
        ASN1_STRING_free(params);
77
0
        params = NULL;
78
0
        goto err;
79
0
    }
80
0
    params->type = V_ASN1_SEQUENCE;
81
0
 err:
82
0
    GOST_KEY_PARAMS_free(gkp);
83
0
    return params;
84
0
}
85
86
/*
87
 * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting
88
 * NID and parameters
89
 */
90
static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
91
0
{
92
0
    ASN1_OBJECT *palg_obj = NULL;
93
0
    int ptype = V_ASN1_UNDEF;
94
0
    int pkey_nid = NID_undef, param_nid = NID_undef;
95
0
    void *_pval;
96
0
    ASN1_STRING *pval = NULL;
97
0
    const unsigned char *p;
98
0
    GOST_KEY_PARAMS *gkp = NULL;
99
100
0
    X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg);
101
0
    pval = _pval;
102
0
    if (ptype != V_ASN1_SEQUENCE) {
103
0
        GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
104
0
                GOST_R_BAD_KEY_PARAMETERS_FORMAT);
105
0
        return 0;
106
0
    }
107
0
    p = pval->data;
108
0
    pkey_nid = OBJ_obj2nid(palg_obj);
109
110
0
    gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length);
111
0
    if (!gkp) {
112
0
        GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
113
0
                GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
114
0
        return 0;
115
0
    }
116
0
    param_nid = OBJ_obj2nid(gkp->key_params);
117
0
    GOST_KEY_PARAMS_free(gkp);
118
0
    if(!EVP_PKEY_set_type(pkey, pkey_nid)) {
119
0
        GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR);
120
0
        return 0;
121
0
    }
122
0
    switch (pkey_nid) {
123
0
    case NID_id_GostR3410_94:
124
0
        {
125
0
            DSA *dsa = EVP_PKEY_get0(pkey);
126
0
            if (!dsa) {
127
0
                dsa = DSA_new();
128
0
                if (!EVP_PKEY_assign(pkey, pkey_nid, dsa))
129
0
                    return 0;
130
0
            }
131
0
            if (!fill_GOST94_params(dsa, param_nid))
132
0
                return 0;
133
0
            break;
134
0
        }
135
0
    case NID_id_GostR3410_2001:
136
0
        {
137
0
            EC_KEY *ec = EVP_PKEY_get0(pkey);
138
0
            if (!ec) {
139
0
                ec = EC_KEY_new();
140
0
                if (!EVP_PKEY_assign(pkey, pkey_nid, ec))
141
0
                    return 0;
142
0
            }
143
0
            if (!fill_GOST2001_params(ec, param_nid))
144
0
                return 0;
145
0
        }
146
0
    }
147
148
0
    return 1;
149
0
}
150
151
static int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv)
152
0
{
153
0
    switch (EVP_PKEY_base_id(pkey)) {
154
0
    case NID_id_GostR3410_94:
155
0
        {
156
0
            DSA *dsa = EVP_PKEY_get0(pkey);
157
0
            if (!dsa) {
158
0
                dsa = DSA_new();
159
0
                EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa);
160
0
            }
161
0
            dsa->priv_key = BN_dup(priv);
162
0
            if (!EVP_PKEY_missing_parameters(pkey))
163
0
                gost94_compute_public(dsa);
164
0
            break;
165
0
        }
166
0
    case NID_id_GostR3410_2001:
167
0
        {
168
0
            EC_KEY *ec = EVP_PKEY_get0(pkey);
169
0
            if (!ec) {
170
0
                ec = EC_KEY_new();
171
0
                EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec);
172
0
            }
173
0
            if (!EC_KEY_set_private_key(ec, priv))
174
0
                return 0;
175
0
            if (!EVP_PKEY_missing_parameters(pkey))
176
0
                gost2001_compute_public(ec);
177
0
            break;
178
0
        }
179
0
    }
180
0
    return 1;
181
0
}
182
183
BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey)
184
0
{
185
0
    switch (EVP_PKEY_base_id(pkey)) {
186
0
    case NID_id_GostR3410_94:
187
0
        {
188
0
            DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey);
189
0
            if (!dsa) {
190
0
                return NULL;
191
0
            }
192
0
            if (!dsa->priv_key)
193
0
                return NULL;
194
0
            return dsa->priv_key;
195
0
            break;
196
0
        }
197
0
    case NID_id_GostR3410_2001:
198
0
        {
199
0
            EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
200
0
            const BIGNUM *priv;
201
0
            if (!ec) {
202
0
                return NULL;
203
0
            }
204
0
            if (!(priv = EC_KEY_get0_private_key(ec)))
205
0
                return NULL;
206
0
            return (BIGNUM *)priv;
207
0
            break;
208
0
        }
209
0
    }
210
0
    return NULL;
211
0
}
212
213
static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
214
0
{
215
0
    switch (op) {
216
0
    case ASN1_PKEY_CTRL_PKCS7_SIGN:
217
0
        if (arg1 == 0) {
218
0
            X509_ALGOR *alg1 = NULL, *alg2 = NULL;
219
0
            int nid = EVP_PKEY_base_id(pkey);
220
0
            PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2,
221
0
                                        NULL, &alg1, &alg2);
222
0
            X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
223
0
                            V_ASN1_NULL, 0);
224
0
            if (nid == NID_undef) {
225
0
                return (-1);
226
0
            }
227
0
            X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
228
0
        }
229
0
        return 1;
230
0
#ifndef OPENSSL_NO_CMS
231
0
    case ASN1_PKEY_CTRL_CMS_SIGN:
232
0
        if (arg1 == 0) {
233
0
            X509_ALGOR *alg1 = NULL, *alg2 = NULL;
234
0
            int nid = EVP_PKEY_base_id(pkey);
235
0
            CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2,
236
0
                                     NULL, NULL, &alg1, &alg2);
237
0
            X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
238
0
                            V_ASN1_NULL, 0);
239
0
            if (nid == NID_undef) {
240
0
                return (-1);
241
0
            }
242
0
            X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
243
0
        }
244
0
        return 1;
245
0
#endif
246
0
    case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
247
0
        if (arg1 == 0) {
248
0
            X509_ALGOR *alg;
249
0
            ASN1_STRING *params = encode_gost_algor_params(pkey);
250
0
            if (!params) {
251
0
                return -1;
252
0
            }
253
0
            PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg);
254
0
            X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
255
0
                            V_ASN1_SEQUENCE, params);
256
0
        }
257
0
        return 1;
258
0
#ifndef OPENSSL_NO_CMS
259
0
    case ASN1_PKEY_CTRL_CMS_ENVELOPE:
260
0
        if (arg1 == 0) {
261
0
            X509_ALGOR *alg = NULL;
262
0
            ASN1_STRING *params = encode_gost_algor_params(pkey);
263
0
            if (!params) {
264
0
                return -1;
265
0
            }
266
0
            CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL,
267
0
                                             NULL, &alg);
268
0
            X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE,
269
0
                            params);
270
0
        }
271
0
        return 1;
272
0
#endif
273
0
    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
274
0
        *(int *)arg2 = NID_id_GostR3411_94;
275
0
        return 2;
276
0
    }
277
278
0
    return -2;
279
0
}
280
281
/* --------------------- free functions * ------------------------------*/
282
static void pkey_free_gost94(EVP_PKEY *key)
283
0
{
284
0
    if (key->pkey.dsa) {
285
0
        DSA_free(key->pkey.dsa);
286
0
    }
287
0
}
288
289
static void pkey_free_gost01(EVP_PKEY *key)
290
0
{
291
0
    if (key->pkey.ec) {
292
0
        EC_KEY_free(key->pkey.ec);
293
0
    }
294
0
}
295
296
/* ------------------ private key functions  -----------------------------*/
297
static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
298
0
{
299
0
    const unsigned char *pkey_buf = NULL, *p = NULL;
300
0
    int priv_len = 0;
301
0
    BIGNUM *pk_num = NULL;
302
0
    int ret = 0;
303
0
    X509_ALGOR *palg = NULL;
304
0
    ASN1_OBJECT *palg_obj = NULL;
305
0
    ASN1_INTEGER *priv_key = NULL;
306
307
0
    if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf))
308
0
        return 0;
309
0
    p = pkey_buf;
310
0
    if (!decode_gost_algor_params(pk, palg)) {
311
0
        return 0;
312
0
    }
313
0
    if (V_ASN1_OCTET_STRING == *p) {
314
        /* New format - Little endian octet string */
315
0
        unsigned char rev_buf[32];
316
0
        int i;
317
0
        ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len);
318
0
        if (!s || s->length != 32) {
319
0
            GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
320
0
            return 0;
321
0
        }
322
0
        for (i = 0; i < 32; i++) {
323
0
            rev_buf[31 - i] = s->data[i];
324
0
        }
325
0
        ASN1_STRING_free(s);
326
0
        pk_num = getbnfrombuf(rev_buf, 32);
327
0
    } else {
328
0
        priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
329
0
        if (!priv_key)
330
0
            return 0;
331
0
        ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL);
332
0
        ASN1_INTEGER_free(priv_key);
333
0
        if (!ret) {
334
0
            GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
335
0
            return 0;
336
0
        }
337
0
    }
338
339
0
    ret = gost_set_priv_key(pk, pk_num);
340
0
    BN_free(pk_num);
341
0
    return ret;
342
0
}
343
344
/* ----------------------------------------------------------------------*/
345
static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
346
0
{
347
0
    ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
348
0
    ASN1_STRING *params = encode_gost_algor_params(pk);
349
0
    unsigned char *priv_buf = NULL;
350
0
    int priv_len;
351
352
0
    ASN1_INTEGER *asn1key = NULL;
353
0
    if (!params) {
354
0
        return 0;
355
0
    }
356
0
    asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL);
357
0
    priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf);
358
0
    ASN1_INTEGER_free(asn1key);
359
0
    return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params,
360
0
                           priv_buf, priv_len);
361
0
}
362
363
/* --------- printing keys --------------------------------*/
364
static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent,
365
                         ASN1_PCTX *pctx, int type)
366
0
{
367
0
    int param_nid = NID_undef;
368
369
0
    if (type == 2) {
370
0
        BIGNUM *key;
371
372
0
        if (!BIO_indent(out, indent, 128))
373
0
            return 0;
374
0
        BIO_printf(out, "Private key: ");
375
0
        key = gost_get0_priv_key(pkey);
376
0
        if (!key)
377
0
            BIO_printf(out, "<undefined>");
378
0
        else
379
0
            BN_print(out, key);
380
0
        BIO_printf(out, "\n");
381
0
    }
382
0
    if (type >= 1) {
383
0
        BIGNUM *pubkey;
384
385
0
        pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
386
0
        BIO_indent(out, indent, 128);
387
0
        BIO_printf(out, "Public key: ");
388
0
        BN_print(out, pubkey);
389
0
        BIO_printf(out, "\n");
390
0
    }
391
392
0
    param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
393
0
    BIO_indent(out, indent, 128);
394
0
    BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid));
395
0
    return 1;
396
0
}
397
398
static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
399
                              ASN1_PCTX *pctx)
400
0
{
401
0
    return print_gost_94(out, pkey, indent, pctx, 0);
402
0
}
403
404
static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
405
                            ASN1_PCTX *pctx)
406
0
{
407
0
    return print_gost_94(out, pkey, indent, pctx, 1);
408
0
}
409
410
static int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
411
                             ASN1_PCTX *pctx)
412
0
{
413
0
    return print_gost_94(out, pkey, indent, pctx, 2);
414
0
}
415
416
static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent,
417
                         ASN1_PCTX *pctx, int type)
418
0
{
419
0
    int param_nid = NID_undef;
420
0
    if (type == 2) {
421
0
        BIGNUM *key;
422
423
0
        if (!BIO_indent(out, indent, 128))
424
0
            return 0;
425
0
        BIO_printf(out, "Private key: ");
426
0
        key = gost_get0_priv_key(pkey);
427
0
        if (!key)
428
0
            BIO_printf(out, "<undefined)");
429
0
        else
430
0
            BN_print(out, key);
431
0
        BIO_printf(out, "\n");
432
0
    }
433
0
    if (type >= 1) {
434
0
        BN_CTX *ctx = BN_CTX_new();
435
0
        BIGNUM *X, *Y;
436
0
        const EC_POINT *pubkey;
437
0
        const EC_GROUP *group;
438
439
0
        if (!ctx) {
440
0
            GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE);
441
0
            return 0;
442
0
        }
443
0
        BN_CTX_start(ctx);
444
0
        X = BN_CTX_get(ctx);
445
0
        Y = BN_CTX_get(ctx);
446
0
        pubkey =
447
0
            EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
448
0
        group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
449
0
        if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) {
450
0
            GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB);
451
0
            BN_CTX_free(ctx);
452
0
            return 0;
453
0
        }
454
0
        if (!BIO_indent(out, indent, 128))
455
0
            return 0;
456
0
        BIO_printf(out, "Public key:\n");
457
0
        if (!BIO_indent(out, indent + 3, 128))
458
0
            return 0;
459
0
        BIO_printf(out, "X:");
460
0
        BN_print(out, X);
461
0
        BIO_printf(out, "\n");
462
0
        BIO_indent(out, indent + 3, 128);
463
0
        BIO_printf(out, "Y:");
464
0
        BN_print(out, Y);
465
0
        BIO_printf(out, "\n");
466
0
        BN_CTX_end(ctx);
467
0
        BN_CTX_free(ctx);
468
0
    }
469
470
0
    param_nid =
471
0
        EC_GROUP_get_curve_name(EC_KEY_get0_group
472
0
                                (EVP_PKEY_get0((EVP_PKEY *)pkey)));
473
0
    if (!BIO_indent(out, indent, 128))
474
0
        return 0;
475
0
    BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid));
476
0
    return 1;
477
0
}
478
479
static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
480
                              ASN1_PCTX *pctx)
481
0
{
482
0
    return print_gost_01(out, pkey, indent, pctx, 0);
483
0
}
484
485
static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
486
                            ASN1_PCTX *pctx)
487
0
{
488
0
    return print_gost_01(out, pkey, indent, pctx, 1);
489
0
}
490
491
static int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
492
                             ASN1_PCTX *pctx)
493
0
{
494
0
    return print_gost_01(out, pkey, indent, pctx, 2);
495
0
}
496
497
/* ---------------------------------------------------------------------*/
498
static int param_missing_gost94(const EVP_PKEY *pk)
499
0
{
500
0
    const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
501
0
    if (!dsa)
502
0
        return 1;
503
0
    if (!dsa->q)
504
0
        return 1;
505
0
    return 0;
506
0
}
507
508
static int param_missing_gost01(const EVP_PKEY *pk)
509
0
{
510
0
    const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
511
0
    if (!ec)
512
0
        return 1;
513
0
    if (!EC_KEY_get0_group(ec))
514
0
        return 1;
515
0
    return 0;
516
0
}
517
518
static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from)
519
0
{
520
0
    const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from);
521
0
    DSA *dto = EVP_PKEY_get0(to);
522
0
    if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
523
0
        GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS);
524
0
        return 0;
525
0
    }
526
0
    if (!dfrom) {
527
0
        GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING);
528
0
        return 0;
529
0
    }
530
0
    if (!dto) {
531
0
        dto = DSA_new();
532
0
        EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto);
533
0
    }
534
0
#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x);
535
0
    COPYBIGNUM(dto, dfrom, p)
536
0
        COPYBIGNUM(dto, dfrom, q)
537
0
        COPYBIGNUM(dto, dfrom, g)
538
539
0
        if (dto->priv_key)
540
0
        gost94_compute_public(dto);
541
0
    return 1;
542
0
}
543
544
static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
545
0
{
546
0
    EC_KEY *eto = EVP_PKEY_get0(to);
547
0
    const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from);
548
0
    if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
549
0
        GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS);
550
0
        return 0;
551
0
    }
552
0
    if (!efrom) {
553
0
        GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING);
554
0
        return 0;
555
0
    }
556
0
    if (!eto) {
557
0
        eto = EC_KEY_new();
558
0
        if(!eto) {
559
0
            GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE);
560
0
            return 0;
561
0
        }
562
0
        if(!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) {
563
0
            GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR);
564
0
            return 0;
565
0
        }
566
0
    }
567
0
    if(!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) {
568
0
        GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR);
569
0
        return 0;
570
0
    }
571
0
    if (EC_KEY_get0_private_key(eto)) {
572
0
        gost2001_compute_public(eto);
573
0
    }
574
0
    return 1;
575
0
}
576
577
static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
578
0
{
579
0
    const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
580
0
    const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
581
0
    if (!BN_cmp(da->q, db->q))
582
0
        return 1;
583
0
    return 0;
584
0
}
585
586
static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
587
0
{
588
0
    if (EC_GROUP_get_curve_name
589
0
        (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) ==
590
0
        EC_GROUP_get_curve_name(EC_KEY_get0_group
591
0
                                (EVP_PKEY_get0((EVP_PKEY *)b)))) {
592
0
        return 1;
593
0
    }
594
0
    return 0;
595
596
0
}
597
598
/* ---------- Public key functions * --------------------------------------*/
599
static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
600
0
{
601
0
    X509_ALGOR *palg = NULL;
602
0
    const unsigned char *pubkey_buf = NULL;
603
0
    unsigned char *databuf;
604
0
    ASN1_OBJECT *palgobj = NULL;
605
0
    int pub_len, i, j;
606
0
    DSA *dsa;
607
0
    ASN1_OCTET_STRING *octet = NULL;
608
609
0
    if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub))
610
0
        return 0;
611
0
    EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL);
612
0
    if (!decode_gost_algor_params(pk, palg))
613
0
        return 0;
614
0
    octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
615
0
    if (!octet) {
616
0
        GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE);
617
0
        return 0;
618
0
    }
619
0
    databuf = OPENSSL_malloc(octet->length);
620
0
    if (databuf == NULL) {
621
0
        GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE);
622
0
        return 0;
623
0
    }
624
0
    for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) {
625
0
        databuf[j] = octet->data[i];
626
0
    }
627
0
    dsa = EVP_PKEY_get0(pk);
628
0
    dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL);
629
0
    ASN1_OCTET_STRING_free(octet);
630
0
    OPENSSL_free(databuf);
631
0
    return 1;
632
633
0
}
634
635
static int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk)
636
0
{
637
0
    ASN1_OBJECT *algobj = NULL;
638
0
    ASN1_OCTET_STRING *octet = NULL;
639
0
    void *pval = NULL;
640
0
    unsigned char *buf = NULL, *databuf, *sptr;
641
0
    int i, j, data_len, ret = 0;
642
643
0
    int ptype = V_ASN1_UNDEF;
644
0
    DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
645
0
    algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
646
0
    if (pk->save_parameters) {
647
0
        ASN1_STRING *params = encode_gost_algor_params(pk);
648
0
        pval = params;
649
0
        ptype = V_ASN1_SEQUENCE;
650
0
    }
651
0
    data_len = BN_num_bytes(dsa->pub_key);
652
0
    databuf = OPENSSL_malloc(data_len);
653
0
    if (databuf == NULL)
654
0
        return 0;
655
0
    BN_bn2bin(dsa->pub_key, databuf);
656
0
    octet = ASN1_OCTET_STRING_new();
657
0
    ASN1_STRING_set(octet, NULL, data_len);
658
0
    sptr = ASN1_STRING_data(octet);
659
0
    for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
660
0
        sptr[i] = databuf[j];
661
0
    }
662
0
    OPENSSL_free(databuf);
663
0
    ret = i2d_ASN1_OCTET_STRING(octet, &buf);
664
0
    ASN1_BIT_STRING_free(octet);
665
0
    if (ret < 0)
666
0
        return 0;
667
0
    return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
668
0
}
669
670
static int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub)
671
0
{
672
0
    X509_ALGOR *palg = NULL;
673
0
    const unsigned char *pubkey_buf = NULL;
674
0
    unsigned char *databuf;
675
0
    ASN1_OBJECT *palgobj = NULL;
676
0
    int pub_len, i, j;
677
0
    EC_POINT *pub_key;
678
0
    BIGNUM *X, *Y;
679
0
    ASN1_OCTET_STRING *octet = NULL;
680
0
    int len;
681
0
    const EC_GROUP *group;
682
683
0
    if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub))
684
0
        return 0;
685
0
    EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL);
686
0
    if (!decode_gost_algor_params(pk, palg))
687
0
        return 0;
688
0
    group = EC_KEY_get0_group(EVP_PKEY_get0(pk));
689
0
    octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
690
0
    if (!octet) {
691
0
        GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
692
0
        return 0;
693
0
    }
694
0
    databuf = OPENSSL_malloc(octet->length);
695
0
    if (databuf == NULL) {
696
0
        GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
697
0
        return 0;
698
0
    }
699
0
    for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) {
700
0
        databuf[j] = octet->data[i];
701
0
    }
702
0
    len = octet->length / 2;
703
0
    ASN1_OCTET_STRING_free(octet);
704
705
0
    Y = getbnfrombuf(databuf, len);
706
0
    X = getbnfrombuf(databuf + len, len);
707
0
    OPENSSL_free(databuf);
708
0
    pub_key = EC_POINT_new(group);
709
0
    if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) {
710
0
        GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB);
711
0
        EC_POINT_free(pub_key);
712
0
        BN_free(X);
713
0
        BN_free(Y);
714
0
        return 0;
715
0
    }
716
0
    BN_free(X);
717
0
    BN_free(Y);
718
0
    if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) {
719
0
        GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB);
720
0
        EC_POINT_free(pub_key);
721
0
        return 0;
722
0
    }
723
0
    EC_POINT_free(pub_key);
724
0
    return 1;
725
726
0
}
727
728
static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
729
0
{
730
0
    ASN1_OBJECT *algobj = NULL;
731
0
    ASN1_OCTET_STRING *octet = NULL;
732
0
    void *pval = NULL;
733
0
    unsigned char *buf = NULL, *databuf, *sptr;
734
0
    int i, j, data_len, ret = 0;
735
0
    const EC_POINT *pub_key;
736
0
    BIGNUM *X, *Y, *order;
737
0
    const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
738
0
    int ptype = V_ASN1_UNDEF;
739
740
0
    algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
741
0
    if (pk->save_parameters) {
742
0
        ASN1_STRING *params = encode_gost_algor_params(pk);
743
0
        pval = params;
744
0
        ptype = V_ASN1_SEQUENCE;
745
0
    }
746
0
    order = BN_new();
747
0
    EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL);
748
0
    pub_key = EC_KEY_get0_public_key(ec);
749
0
    if (!pub_key) {
750
0
        GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED);
751
0
        return 0;
752
0
    }
753
0
    X = BN_new();
754
0
    Y = BN_new();
755
0
    if(!X || !Y) {
756
0
        GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE);
757
0
        if(X) BN_free(X);
758
0
        if(Y) BN_free(Y);
759
0
        BN_free(order);
760
0
        return 0;
761
0
    }
762
0
    if(!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
763
0
                                        pub_key, X, Y, NULL)) {
764
0
        GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR);
765
0
        BN_free(X);
766
0
        BN_free(Y);
767
0
        BN_free(order);
768
0
        return 0;
769
0
    }
770
0
    data_len = 2 * BN_num_bytes(order);
771
0
    BN_free(order);
772
0
    databuf = OPENSSL_malloc(data_len);
773
0
    if (databuf == NULL) {
774
0
        GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE);
775
0
        return 0;
776
0
    }
777
0
    memset(databuf, 0, data_len);
778
779
0
    store_bignum(X, databuf + data_len / 2, data_len / 2);
780
0
    store_bignum(Y, databuf, data_len / 2);
781
782
0
    BN_free(X);
783
0
    BN_free(Y);
784
0
    octet = ASN1_OCTET_STRING_new();
785
0
    ASN1_STRING_set(octet, NULL, data_len);
786
0
    sptr = ASN1_STRING_data(octet);
787
0
    for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
788
0
        sptr[i] = databuf[j];
789
0
    }
790
0
    OPENSSL_free(databuf);
791
0
    ret = i2d_ASN1_OCTET_STRING(octet, &buf);
792
0
    ASN1_BIT_STRING_free(octet);
793
0
    if (ret < 0)
794
0
        return 0;
795
0
    return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
796
0
}
797
798
static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
799
0
{
800
0
    const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
801
0
    const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
802
0
    if (da && db && da->pub_key && db->pub_key
803
0
        && !BN_cmp(da->pub_key, db->pub_key)) {
804
0
        return 1;
805
0
    }
806
0
    return 0;
807
0
}
808
809
static int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
810
0
{
811
0
    const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a);
812
0
    const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b);
813
0
    const EC_POINT *ka, *kb;
814
0
    int ret = 0;
815
0
    if (!ea || !eb)
816
0
        return 0;
817
0
    ka = EC_KEY_get0_public_key(ea);
818
0
    kb = EC_KEY_get0_public_key(eb);
819
0
    if (!ka || !kb)
820
0
        return 0;
821
0
    ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL));
822
0
    return ret;
823
0
}
824
825
static int pkey_size_gost(const EVP_PKEY *pk)
826
0
{
827
0
    return 64;
828
0
}
829
830
static int pkey_bits_gost(const EVP_PKEY *pk)
831
0
{
832
0
    return 256;
833
0
}
834
835
/* ---------------------- ASN1 METHOD for GOST MAC  -------------------*/
836
static void mackey_free_gost(EVP_PKEY *pk)
837
0
{
838
0
    if (pk->pkey.ptr) {
839
0
        OPENSSL_free(pk->pkey.ptr);
840
0
    }
841
0
}
842
843
static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
844
0
{
845
0
    switch (op) {
846
0
    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
847
0
        *(int *)arg2 = NID_id_Gost28147_89_MAC;
848
0
        return 2;
849
0
    }
850
0
    return -2;
851
0
}
852
853
static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
854
0
{
855
0
    int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
856
0
    return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder);
857
0
}
858
859
static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
860
0
{
861
0
    int nid =
862
0
        EC_GROUP_get_curve_name(EC_KEY_get0_group
863
0
                                (EVP_PKEY_get0((EVP_PKEY *)pkey)));
864
0
    return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder);
865
0
}
866
867
static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder,
868
                               int derlen)
869
0
{
870
0
    ASN1_OBJECT *obj = NULL;
871
0
    DSA *dsa = EVP_PKEY_get0(pkey);
872
0
    int nid;
873
0
    if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
874
0
        return 0;
875
0
    }
876
0
    nid = OBJ_obj2nid(obj);
877
0
    ASN1_OBJECT_free(obj);
878
0
    if (!dsa) {
879
0
        dsa = DSA_new();
880
0
        if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa))
881
0
            return 0;
882
0
    }
883
0
    if (!fill_GOST94_params(dsa, nid))
884
0
        return 0;
885
0
    return 1;
886
0
}
887
888
static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder,
889
                                 int derlen)
890
0
{
891
0
    ASN1_OBJECT *obj = NULL;
892
0
    int nid;
893
0
    EC_KEY *ec = EVP_PKEY_get0(pkey);
894
0
    if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
895
0
        return 0;
896
0
    }
897
0
    nid = OBJ_obj2nid(obj);
898
0
    ASN1_OBJECT_free(obj);
899
0
    if (!ec) {
900
0
        ec = EC_KEY_new();
901
0
        if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec))
902
0
            return 0;
903
0
    }
904
0
    if (!fill_GOST2001_params(ec, nid))
905
0
        return 0;
906
0
    return 1;
907
0
}
908
909
/* ----------------------------------------------------------------------*/
910
int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth,
911
                        const char *pemstr, const char *info)
912
57
{
913
57
    *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info);
914
57
    if (!*ameth)
915
0
        return 0;
916
57
    switch (nid) {
917
19
    case NID_id_GostR3410_94:
918
19
        EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94);
919
19
        EVP_PKEY_asn1_set_private(*ameth,
920
19
                                  priv_decode_gost, priv_encode_gost,
921
19
                                  priv_print_gost94);
922
923
19
        EVP_PKEY_asn1_set_param(*ameth,
924
19
                                gost94_param_decode, gost94_param_encode,
925
19
                                param_missing_gost94, param_copy_gost94,
926
19
                                param_cmp_gost94, param_print_gost94);
927
19
        EVP_PKEY_asn1_set_public(*ameth,
928
19
                                 pub_decode_gost94, pub_encode_gost94,
929
19
                                 pub_cmp_gost94, pub_print_gost94,
930
19
                                 pkey_size_gost, pkey_bits_gost);
931
932
19
        EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost);
933
19
        break;
934
19
    case NID_id_GostR3410_2001:
935
19
        EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01);
936
19
        EVP_PKEY_asn1_set_private(*ameth,
937
19
                                  priv_decode_gost, priv_encode_gost,
938
19
                                  priv_print_gost01);
939
940
19
        EVP_PKEY_asn1_set_param(*ameth,
941
19
                                gost2001_param_decode, gost2001_param_encode,
942
19
                                param_missing_gost01, param_copy_gost01,
943
19
                                param_cmp_gost01, param_print_gost01);
944
19
        EVP_PKEY_asn1_set_public(*ameth,
945
19
                                 pub_decode_gost01, pub_encode_gost01,
946
19
                                 pub_cmp_gost01, pub_print_gost01,
947
19
                                 pkey_size_gost, pkey_bits_gost);
948
949
19
        EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost);
950
19
        break;
951
19
    case NID_id_Gost28147_89_MAC:
952
19
        EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
953
19
        EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost);
954
19
        break;
955
57
    }
956
57
    return 1;
957
57
}