Coverage Report

Created: 2023-06-08 06:40

/src/openssl111/crypto/engine/eng_openssl.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
3
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4
 *
5
 * Licensed under the OpenSSL license (the "License").  You may not use
6
 * this file except in compliance with the License.  You can obtain a copy
7
 * in the file LICENSE in the source distribution or at
8
 * https://www.openssl.org/source/license.html
9
 */
10
11
#include <stdio.h>
12
#include <openssl/crypto.h>
13
#include "internal/cryptlib.h"
14
#include "crypto/engine.h"
15
#include <openssl/pem.h>
16
#include <openssl/evp.h>
17
#include <openssl/rand.h>
18
#include <openssl/rsa.h>
19
#include <openssl/dsa.h>
20
#include <openssl/dh.h>
21
22
#include <openssl/hmac.h>
23
#include <openssl/x509v3.h>
24
25
/*
26
 * This testing gunk is implemented (and explained) lower down. It also
27
 * assumes the application explicitly calls "ENGINE_load_openssl()" because
28
 * this is no longer automatic in ENGINE_load_builtin_engines().
29
 */
30
#define TEST_ENG_OPENSSL_RC4
31
#ifndef OPENSSL_NO_STDIO
32
# define TEST_ENG_OPENSSL_PKEY
33
#endif
34
/* #define TEST_ENG_OPENSSL_HMAC */
35
/* #define TEST_ENG_OPENSSL_HMAC_INIT */
36
/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
37
#ifndef OPENSSL_NO_STDIO
38
# define TEST_ENG_OPENSSL_RC4_P_INIT
39
#endif
40
/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
41
#define TEST_ENG_OPENSSL_SHA
42
/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
43
/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
44
/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
45
/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
46
47
/* Now check what of those algorithms are actually enabled */
48
#ifdef OPENSSL_NO_RC4
49
# undef TEST_ENG_OPENSSL_RC4
50
# undef TEST_ENG_OPENSSL_RC4_OTHERS
51
# undef TEST_ENG_OPENSSL_RC4_P_INIT
52
# undef TEST_ENG_OPENSSL_RC4_P_CIPHER
53
#endif
54
55
static int openssl_destroy(ENGINE *e);
56
57
#ifdef TEST_ENG_OPENSSL_RC4
58
static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
59
                           const int **nids, int nid);
60
#endif
61
#ifdef TEST_ENG_OPENSSL_SHA
62
static int openssl_digests(ENGINE *e, const EVP_MD **digest,
63
                           const int **nids, int nid);
64
#endif
65
66
#ifdef TEST_ENG_OPENSSL_PKEY
67
static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
68
                                      UI_METHOD *ui_method,
69
                                      void *callback_data);
70
#endif
71
72
#ifdef TEST_ENG_OPENSSL_HMAC
73
static int ossl_register_hmac_meth(void);
74
static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
75
                           const int **nids, int nid);
76
#endif
77
78
/* The constants used when creating the ENGINE */
79
static const char *engine_openssl_id = "openssl";
80
static const char *engine_openssl_name = "Software engine support";
81
82
/*
83
 * This internal function is used by ENGINE_openssl() and possibly by the
84
 * "dynamic" ENGINE support too
85
 */
86
static int bind_helper(ENGINE *e)
87
0
{
88
0
    if (!ENGINE_set_id(e, engine_openssl_id)
89
0
        || !ENGINE_set_name(e, engine_openssl_name)
90
0
        || !ENGINE_set_destroy_function(e, openssl_destroy)
91
0
#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
92
0
# ifndef OPENSSL_NO_RSA
93
0
        || !ENGINE_set_RSA(e, RSA_get_default_method())
94
0
# endif
95
0
# ifndef OPENSSL_NO_DSA
96
0
        || !ENGINE_set_DSA(e, DSA_get_default_method())
97
0
# endif
98
0
# ifndef OPENSSL_NO_EC
99
0
        || !ENGINE_set_EC(e, EC_KEY_OpenSSL())
100
0
# endif
101
0
# ifndef OPENSSL_NO_DH
102
0
        || !ENGINE_set_DH(e, DH_get_default_method())
103
0
# endif
104
0
        || !ENGINE_set_RAND(e, RAND_OpenSSL())
105
0
# ifdef TEST_ENG_OPENSSL_RC4
106
0
        || !ENGINE_set_ciphers(e, openssl_ciphers)
107
0
# endif
108
0
# ifdef TEST_ENG_OPENSSL_SHA
109
0
        || !ENGINE_set_digests(e, openssl_digests)
110
0
# endif
111
0
#endif
112
0
#ifdef TEST_ENG_OPENSSL_PKEY
113
0
        || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
114
0
#endif
115
#ifdef TEST_ENG_OPENSSL_HMAC
116
        || !ossl_register_hmac_meth()
117
        || !ENGINE_set_pkey_meths(e, ossl_pkey_meths)
118
#endif
119
0
        )
120
0
        return 0;
121
    /*
122
     * If we add errors to this ENGINE, ensure the error handling is setup
123
     * here
124
     */
125
    /* openssl_load_error_strings(); */
126
0
    return 1;
127
0
}
128
129
static ENGINE *engine_openssl(void)
130
0
{
131
0
    ENGINE *ret = ENGINE_new();
132
0
    if (ret == NULL)
133
0
        return NULL;
134
0
    if (!bind_helper(ret)) {
135
0
        ENGINE_free(ret);
136
0
        return NULL;
137
0
    }
138
0
    return ret;
139
0
}
140
141
void engine_load_openssl_int(void)
142
0
{
143
0
    ENGINE *toadd = engine_openssl();
144
0
    if (!toadd)
145
0
        return;
146
0
    ENGINE_add(toadd);
147
    /*
148
     * If the "add" worked, it gets a structural reference. So either way, we
149
     * release our just-created reference.
150
     */
151
0
    ENGINE_free(toadd);
152
0
    ERR_clear_error();
153
0
}
154
155
/*
156
 * This stuff is needed if this ENGINE is being compiled into a
157
 * self-contained shared-library.
158
 */
159
#ifdef ENGINE_DYNAMIC_SUPPORT
160
static int bind_fn(ENGINE *e, const char *id)
161
{
162
    if (id && (strcmp(id, engine_openssl_id) != 0))
163
        return 0;
164
    if (!bind_helper(e))
165
        return 0;
166
    return 1;
167
}
168
169
IMPLEMENT_DYNAMIC_CHECK_FN()
170
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
171
#endif                          /* ENGINE_DYNAMIC_SUPPORT */
172
#ifdef TEST_ENG_OPENSSL_RC4
173
/*-
174
 * This section of code compiles an "alternative implementation" of two modes of
175
 * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
176
 * should under normal circumstances go via this support rather than the default
177
 * EVP support. There are other symbols to tweak the testing;
178
 *    TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
179
 *        we're asked for a cipher we don't support (should not happen).
180
 *    TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
181
 *        the "init_key" handler is called.
182
 *    TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
183
 */
184
# include <openssl/rc4.h>
185
0
# define TEST_RC4_KEY_SIZE               16
186
typedef struct {
187
    unsigned char key[TEST_RC4_KEY_SIZE];
188
    RC4_KEY ks;
189
} TEST_RC4_KEY;
190
0
# define test(ctx) ((TEST_RC4_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx))
191
static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
192
                             const unsigned char *iv, int enc)
193
0
{
194
0
# ifdef TEST_ENG_OPENSSL_RC4_P_INIT
195
0
    fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
196
0
# endif
197
0
    memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx));
198
0
    RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
199
0
                test(ctx)->key);
200
0
    return 1;
201
0
}
202
203
static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
204
                           const unsigned char *in, size_t inl)
205
0
{
206
# ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
207
    fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
208
# endif
209
0
    RC4(&test(ctx)->ks, inl, in, out);
210
0
    return 1;
211
0
}
212
213
static EVP_CIPHER *r4_cipher = NULL;
214
static const EVP_CIPHER *test_r4_cipher(void)
215
0
{
216
0
    if (r4_cipher == NULL) {
217
0
        EVP_CIPHER *cipher;
218
219
0
        if ((cipher = EVP_CIPHER_meth_new(NID_rc4, 1, TEST_RC4_KEY_SIZE)) == NULL
220
0
            || !EVP_CIPHER_meth_set_iv_length(cipher, 0)
221
0
            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_VARIABLE_LENGTH)
222
0
            || !EVP_CIPHER_meth_set_init(cipher, test_rc4_init_key)
223
0
            || !EVP_CIPHER_meth_set_do_cipher(cipher, test_rc4_cipher)
224
0
            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(TEST_RC4_KEY))) {
225
0
            EVP_CIPHER_meth_free(cipher);
226
0
            cipher = NULL;
227
0
        }
228
0
        r4_cipher = cipher;
229
0
    }
230
0
    return r4_cipher;
231
0
}
232
static void test_r4_cipher_destroy(void)
233
0
{
234
0
    EVP_CIPHER_meth_free(r4_cipher);
235
0
    r4_cipher = NULL;
236
0
}
237
238
static EVP_CIPHER *r4_40_cipher = NULL;
239
static const EVP_CIPHER *test_r4_40_cipher(void)
240
0
{
241
0
    if (r4_40_cipher == NULL) {
242
0
        EVP_CIPHER *cipher;
243
244
0
        if ((cipher = EVP_CIPHER_meth_new(NID_rc4, 1, 5 /* 40 bits */)) == NULL
245
0
            || !EVP_CIPHER_meth_set_iv_length(cipher, 0)
246
0
            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_VARIABLE_LENGTH)
247
0
            || !EVP_CIPHER_meth_set_init(cipher, test_rc4_init_key)
248
0
            || !EVP_CIPHER_meth_set_do_cipher(cipher, test_rc4_cipher)
249
0
            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(TEST_RC4_KEY))) {
250
0
            EVP_CIPHER_meth_free(cipher);
251
0
            cipher = NULL;
252
0
        }
253
0
        r4_40_cipher = cipher;
254
0
    }
255
0
    return r4_40_cipher;
256
0
}
257
static void test_r4_40_cipher_destroy(void)
258
0
{
259
0
    EVP_CIPHER_meth_free(r4_40_cipher);
260
0
    r4_40_cipher = NULL;
261
0
}
262
static int test_cipher_nids(const int **nids)
263
0
{
264
0
    static int cipher_nids[4] = { 0, 0, 0, 0 };
265
0
    static int pos = 0;
266
0
    static int init = 0;
267
268
0
    if (!init) {
269
0
        const EVP_CIPHER *cipher;
270
0
        if ((cipher = test_r4_cipher()) != NULL)
271
0
            cipher_nids[pos++] = EVP_CIPHER_nid(cipher);
272
0
        if ((cipher = test_r4_40_cipher()) != NULL)
273
0
            cipher_nids[pos++] = EVP_CIPHER_nid(cipher);
274
0
        cipher_nids[pos] = 0;
275
0
        init = 1;
276
0
    }
277
0
    *nids = cipher_nids;
278
0
    return pos;
279
0
}
280
281
static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
282
                           const int **nids, int nid)
283
0
{
284
0
    if (!cipher) {
285
        /* We are returning a list of supported nids */
286
0
        return test_cipher_nids(nids);
287
0
    }
288
    /* We are being asked for a specific cipher */
289
0
    if (nid == NID_rc4)
290
0
        *cipher = test_r4_cipher();
291
0
    else if (nid == NID_rc4_40)
292
0
        *cipher = test_r4_40_cipher();
293
0
    else {
294
# ifdef TEST_ENG_OPENSSL_RC4_OTHERS
295
        fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
296
                "nid %d\n", nid);
297
# endif
298
0
        *cipher = NULL;
299
0
        return 0;
300
0
    }
301
0
    return 1;
302
0
}
303
#endif
304
305
#ifdef TEST_ENG_OPENSSL_SHA
306
/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
307
# include <openssl/sha.h>
308
309
static int test_sha1_init(EVP_MD_CTX *ctx)
310
0
{
311
# ifdef TEST_ENG_OPENSSL_SHA_P_INIT
312
    fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
313
# endif
314
0
    return SHA1_Init(EVP_MD_CTX_md_data(ctx));
315
0
}
316
317
static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count)
318
0
{
319
# ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
320
    fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
321
# endif
322
0
    return SHA1_Update(EVP_MD_CTX_md_data(ctx), data, count);
323
0
}
324
325
static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
326
0
{
327
# ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
328
    fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
329
# endif
330
0
    return SHA1_Final(md, EVP_MD_CTX_md_data(ctx));
331
0
}
332
333
static EVP_MD *sha1_md = NULL;
334
static const EVP_MD *test_sha_md(void)
335
0
{
336
0
    if (sha1_md == NULL) {
337
0
        EVP_MD *md;
338
339
0
        if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL
340
0
            || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)
341
0
            || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)
342
0
            || !EVP_MD_meth_set_app_datasize(md,
343
0
                                             sizeof(EVP_MD *) + sizeof(SHA_CTX))
344
0
            || !EVP_MD_meth_set_flags(md, 0)
345
0
            || !EVP_MD_meth_set_init(md, test_sha1_init)
346
0
            || !EVP_MD_meth_set_update(md, test_sha1_update)
347
0
            || !EVP_MD_meth_set_final(md, test_sha1_final)) {
348
0
            EVP_MD_meth_free(md);
349
0
            md = NULL;
350
0
        }
351
0
        sha1_md = md;
352
0
    }
353
0
    return sha1_md;
354
0
}
355
static void test_sha_md_destroy(void)
356
0
{
357
0
    EVP_MD_meth_free(sha1_md);
358
0
    sha1_md = NULL;
359
0
}
360
static int test_digest_nids(const int **nids)
361
0
{
362
0
    static int digest_nids[2] = { 0, 0 };
363
0
    static int pos = 0;
364
0
    static int init = 0;
365
366
0
    if (!init) {
367
0
        const EVP_MD *md;
368
0
        if ((md = test_sha_md()) != NULL)
369
0
            digest_nids[pos++] = EVP_MD_type(md);
370
0
        digest_nids[pos] = 0;
371
0
        init = 1;
372
0
    }
373
0
    *nids = digest_nids;
374
0
    return pos;
375
0
}
376
377
static int openssl_digests(ENGINE *e, const EVP_MD **digest,
378
                           const int **nids, int nid)
379
0
{
380
0
    if (!digest) {
381
        /* We are returning a list of supported nids */
382
0
        return test_digest_nids(nids);
383
0
    }
384
    /* We are being asked for a specific digest */
385
0
    if (nid == NID_sha1)
386
0
        *digest = test_sha_md();
387
0
    else {
388
# ifdef TEST_ENG_OPENSSL_SHA_OTHERS
389
        fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
390
                "nid %d\n", nid);
391
# endif
392
0
        *digest = NULL;
393
0
        return 0;
394
0
    }
395
0
    return 1;
396
0
}
397
#endif
398
399
#ifdef TEST_ENG_OPENSSL_PKEY
400
static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
401
                                      UI_METHOD *ui_method,
402
                                      void *callback_data)
403
0
{
404
0
    BIO *in;
405
0
    EVP_PKEY *key;
406
0
    fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n",
407
0
            key_id);
408
0
    in = BIO_new_file(key_id, "r");
409
0
    if (!in)
410
0
        return NULL;
411
0
    key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
412
0
    BIO_free(in);
413
0
    return key;
414
0
}
415
#endif
416
417
#ifdef TEST_ENG_OPENSSL_HMAC
418
419
/*
420
 * Experimental HMAC redirection implementation: mainly copied from
421
 * hm_pmeth.c
422
 */
423
424
/* HMAC pkey context structure */
425
426
typedef struct {
427
    const EVP_MD *md;           /* MD for HMAC use */
428
    ASN1_OCTET_STRING ktmp;     /* Temp storage for key */
429
    HMAC_CTX *ctx;
430
} OSSL_HMAC_PKEY_CTX;
431
432
static int ossl_hmac_init(EVP_PKEY_CTX *ctx)
433
{
434
    OSSL_HMAC_PKEY_CTX *hctx;
435
436
    if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
437
        ENGINEerr(ENGINE_F_OSSL_HMAC_INIT, ERR_R_MALLOC_FAILURE);
438
        return 0;
439
    }
440
    hctx->ktmp.type = V_ASN1_OCTET_STRING;
441
    hctx->ctx = HMAC_CTX_new();
442
    if (hctx->ctx == NULL) {
443
        OPENSSL_free(hctx);
444
        return 0;
445
    }
446
    EVP_PKEY_CTX_set_data(ctx, hctx);
447
    EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0);
448
# ifdef TEST_ENG_OPENSSL_HMAC_INIT
449
    fprintf(stderr, "(TEST_ENG_OPENSSL_HMAC) ossl_hmac_init() called\n");
450
# endif
451
    return 1;
452
}
453
454
static void ossl_hmac_cleanup(EVP_PKEY_CTX *ctx);
455
456
static int ossl_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
457
{
458
    OSSL_HMAC_PKEY_CTX *sctx, *dctx;
459
460
    /* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */
461
    if (!ossl_hmac_init(dst))
462
        return 0;
463
    sctx = EVP_PKEY_CTX_get_data(src);
464
    dctx = EVP_PKEY_CTX_get_data(dst);
465
    dctx->md = sctx->md;
466
    if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx))
467
        goto err;
468
    if (sctx->ktmp.data) {
469
        if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
470
                                   sctx->ktmp.data, sctx->ktmp.length))
471
            goto err;
472
    }
473
    return 1;
474
err:
475
    /* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */
476
    ossl_hmac_cleanup(dst);
477
    return 0;
478
}
479
480
static void ossl_hmac_cleanup(EVP_PKEY_CTX *ctx)
481
{
482
    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
483
484
    if (hctx) {
485
        HMAC_CTX_free(hctx->ctx);
486
        OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
487
        OPENSSL_free(hctx);
488
        EVP_PKEY_CTX_set_data(ctx, NULL);
489
    }
490
}
491
492
static int ossl_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
493
{
494
    ASN1_OCTET_STRING *hkey = NULL;
495
    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
496
    if (!hctx->ktmp.data)
497
        return 0;
498
    hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
499
    if (!hkey)
500
        return 0;
501
    EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
502
503
    return 1;
504
}
505
506
static int ossl_int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
507
{
508
    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
509
    if (!HMAC_Update(hctx->ctx, data, count))
510
        return 0;
511
    return 1;
512
}
513
514
static int ossl_hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
515
{
516
    EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
517
    EVP_MD_CTX_set_update_fn(mctx, ossl_int_update);
518
    return 1;
519
}
520
521
static int ossl_hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
522
                             size_t *siglen, EVP_MD_CTX *mctx)
523
{
524
    unsigned int hlen;
525
    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
526
    int l = EVP_MD_CTX_size(mctx);
527
528
    if (l < 0)
529
        return 0;
530
    *siglen = l;
531
    if (!sig)
532
        return 1;
533
534
    if (!HMAC_Final(hctx->ctx, sig, &hlen))
535
        return 0;
536
    *siglen = (size_t)hlen;
537
    return 1;
538
}
539
540
static int ossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
541
{
542
    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
543
    EVP_PKEY *pk;
544
    ASN1_OCTET_STRING *key;
545
    switch (type) {
546
547
    case EVP_PKEY_CTRL_SET_MAC_KEY:
548
        if ((!p2 && p1 > 0) || (p1 < -1))
549
            return 0;
550
        if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
551
            return 0;
552
        break;
553
554
    case EVP_PKEY_CTRL_MD:
555
        hctx->md = p2;
556
        break;
557
558
    case EVP_PKEY_CTRL_DIGESTINIT:
559
        pk = EVP_PKEY_CTX_get0_pkey(ctx);
560
        key = EVP_PKEY_get0(pk);
561
        if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md, NULL))
562
            return 0;
563
        break;
564
565
    default:
566
        return -2;
567
568
    }
569
    return 1;
570
}
571
572
static int ossl_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
573
                              const char *type, const char *value)
574
{
575
    if (!value) {
576
        return 0;
577
    }
578
    if (strcmp(type, "key") == 0) {
579
        void *p = (void *)value;
580
        return ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, -1, p);
581
    }
582
    if (strcmp(type, "hexkey") == 0) {
583
        unsigned char *key;
584
        int r;
585
        long keylen;
586
        key = OPENSSL_hexstr2buf(value, &keylen);
587
        if (!key)
588
            return 0;
589
        r = ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
590
        OPENSSL_free(key);
591
        return r;
592
    }
593
    return -2;
594
}
595
596
static EVP_PKEY_METHOD *ossl_hmac_meth;
597
598
static int ossl_register_hmac_meth(void)
599
{
600
    EVP_PKEY_METHOD *meth;
601
    meth = EVP_PKEY_meth_new(EVP_PKEY_HMAC, 0);
602
    if (meth == NULL)
603
        return 0;
604
    EVP_PKEY_meth_set_init(meth, ossl_hmac_init);
605
    EVP_PKEY_meth_set_copy(meth, ossl_hmac_copy);
606
    EVP_PKEY_meth_set_cleanup(meth, ossl_hmac_cleanup);
607
608
    EVP_PKEY_meth_set_keygen(meth, 0, ossl_hmac_keygen);
609
610
    EVP_PKEY_meth_set_signctx(meth, ossl_hmac_signctx_init,
611
                              ossl_hmac_signctx);
612
613
    EVP_PKEY_meth_set_ctrl(meth, ossl_hmac_ctrl, ossl_hmac_ctrl_str);
614
    ossl_hmac_meth = meth;
615
    return 1;
616
}
617
618
static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
619
                           const int **nids, int nid)
620
{
621
    static int ossl_pkey_nids[] = {
622
        EVP_PKEY_HMAC,
623
        0
624
    };
625
    if (!pmeth) {
626
        *nids = ossl_pkey_nids;
627
        return 1;
628
    }
629
630
    if (nid == EVP_PKEY_HMAC) {
631
        *pmeth = ossl_hmac_meth;
632
        return 1;
633
    }
634
635
    *pmeth = NULL;
636
    return 0;
637
}
638
639
#endif
640
641
int openssl_destroy(ENGINE *e)
642
0
{
643
0
    test_sha_md_destroy();
644
0
#ifdef TEST_ENG_OPENSSL_RC4
645
0
    test_r4_cipher_destroy();
646
0
    test_r4_40_cipher_destroy();
647
0
#endif
648
0
    return 1;
649
0
}
650