Coverage Report

Created: 2022-11-30 06:20

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