]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/engine/eng_openssl.c
Add UEFI flag for rand build
[thirdparty/openssl.git] / crypto / engine / eng_openssl.c
CommitLineData
2b671586 1/* crypto/engine/eng_openssl.c */
0f113f3e
MC
2/*
3 * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project
4 * 2000.
5270e702
RL
5 */
6/* ====================================================================
2b671586 7 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
5270e702
RL
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
0f113f3e 14 * notice, this list of conditions and the following disclaimer.
5270e702
RL
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
e172d60d
BM
59/* ====================================================================
60 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
0f113f3e 61 * ECDH support in OpenSSL originally developed by
e172d60d
BM
62 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
63 */
5270e702 64
5270e702
RL
65#include <stdio.h>
66#include <openssl/crypto.h>
b39fc560 67#include "internal/cryptlib.h"
5270e702
RL
68#include <openssl/engine.h>
69#include <openssl/dso.h>
0dc09233 70#include <openssl/pem.h>
67753262 71#include <openssl/evp.h>
3a87a9b9 72#include <openssl/rand.h>
3eeaab4b 73#ifndef OPENSSL_NO_RSA
0f113f3e 74# include <openssl/rsa.h>
3eeaab4b
NL
75#endif
76#ifndef OPENSSL_NO_DSA
0f113f3e 77# include <openssl/dsa.h>
3eeaab4b
NL
78#endif
79#ifndef OPENSSL_NO_DH
0f113f3e 80# include <openssl/dh.h>
3eeaab4b 81#endif
5270e702 82
e77906b9
DSH
83#include <openssl/hmac.h>
84#include <openssl/x509v3.h>
85
0f113f3e
MC
86/*
87 * This testing gunk is implemented (and explained) lower down. It also
88 * assumes the application explicitly calls "ENGINE_load_openssl()" because
89 * this is no longer automatic in ENGINE_load_builtin_engines().
90 */
3b04cdd7 91#define TEST_ENG_OPENSSL_RC4
0dc09233 92#define TEST_ENG_OPENSSL_PKEY
e77906b9 93/* #define TEST_ENG_OPENSSL_HMAC */
fa71cc7b 94/* #define TEST_ENG_OPENSSL_HMAC_INIT */
3b04cdd7
GT
95/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
96#define TEST_ENG_OPENSSL_RC4_P_INIT
97/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
98#define TEST_ENG_OPENSSL_SHA
3b04cdd7
GT
99/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
100/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
101/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
102/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
103
439ae4d3
RL
104/* Now check what of those algorithms are actually enabled */
105#ifdef OPENSSL_NO_RC4
0f113f3e
MC
106# undef TEST_ENG_OPENSSL_RC4
107# undef TEST_ENG_OPENSSL_RC4_OTHERS
108# undef TEST_ENG_OPENSSL_RC4_P_INIT
109# undef TEST_ENG_OPENSSL_RC4_P_CIPHER
439ae4d3 110#endif
439ae4d3 111
3b04cdd7
GT
112#ifdef TEST_ENG_OPENSSL_RC4
113static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
0f113f3e 114 const int **nids, int nid);
3b04cdd7
GT
115#endif
116#ifdef TEST_ENG_OPENSSL_SHA
117static int openssl_digests(ENGINE *e, const EVP_MD **digest,
0f113f3e 118 const int **nids, int nid);
3b04cdd7
GT
119#endif
120
0dc09233
DSH
121#ifdef TEST_ENG_OPENSSL_PKEY
122static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
0f113f3e
MC
123 UI_METHOD *ui_method,
124 void *callback_data);
0dc09233
DSH
125#endif
126
e77906b9
DSH
127#ifdef TEST_ENG_OPENSSL_HMAC
128static int ossl_register_hmac_meth(void);
129static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
0f113f3e 130 const int **nids, int nid);
e77906b9
DSH
131#endif
132
59bc3126
GT
133/* The constants used when creating the ENGINE */
134static const char *engine_openssl_id = "openssl";
b6d1e52d 135static const char *engine_openssl_name = "Software engine support";
5270e702 136
0f113f3e
MC
137/*
138 * This internal function is used by ENGINE_openssl() and possibly by the
139 * "dynamic" ENGINE support too
140 */
329636d6 141static int bind_helper(ENGINE *e)
0f113f3e
MC
142{
143 if (!ENGINE_set_id(e, engine_openssl_id)
144 || !ENGINE_set_name(e, engine_openssl_name)
0dc09233 145#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
0f113f3e
MC
146# ifndef OPENSSL_NO_RSA
147 || !ENGINE_set_RSA(e, RSA_get_default_method())
148# endif
149# ifndef OPENSSL_NO_DSA
150 || !ENGINE_set_DSA(e, DSA_get_default_method())
151# endif
10bf4fc2 152# ifndef OPENSSL_NO_EC
0f113f3e 153 || !ENGINE_set_ECDH(e, ECDH_OpenSSL())
0f113f3e
MC
154 || !ENGINE_set_ECDSA(e, ECDSA_OpenSSL())
155# endif
156# ifndef OPENSSL_NO_DH
157 || !ENGINE_set_DH(e, DH_get_default_method())
158# endif
159 || !ENGINE_set_RAND(e, RAND_SSLeay())
160# ifdef TEST_ENG_OPENSSL_RC4
161 || !ENGINE_set_ciphers(e, openssl_ciphers)
162# endif
163# ifdef TEST_ENG_OPENSSL_SHA
164 || !ENGINE_set_digests(e, openssl_digests)
165# endif
0dc09233
DSH
166#endif
167#ifdef TEST_ENG_OPENSSL_PKEY
0f113f3e 168 || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
e77906b9
DSH
169#endif
170#ifdef TEST_ENG_OPENSSL_HMAC
0f113f3e
MC
171 || !ossl_register_hmac_meth()
172 || !ENGINE_set_pkey_meths(e, ossl_pkey_meths)
9e78e6c3 173#endif
0f113f3e
MC
174 )
175 return 0;
176 /*
177 * If we add errors to this ENGINE, ensure the error handling is setup
178 * here
179 */
180 /* openssl_load_error_strings(); */
181 return 1;
182}
329636d6
GT
183
184static ENGINE *engine_openssl(void)
0f113f3e
MC
185{
186 ENGINE *ret = ENGINE_new();
187 if (!ret)
188 return NULL;
189 if (!bind_helper(ret)) {
190 ENGINE_free(ret);
191 return NULL;
192 }
193 return ret;
194}
3b04cdd7
GT
195
196void ENGINE_load_openssl(void)
0f113f3e
MC
197{
198 ENGINE *toadd = engine_openssl();
199 if (!toadd)
200 return;
201 ENGINE_add(toadd);
202 /*
203 * If the "add" worked, it gets a structural reference. So either way, we
204 * release our just-created reference.
205 */
206 ENGINE_free(toadd);
207 ERR_clear_error();
208}
209
210/*
211 * This stuff is needed if this ENGINE is being compiled into a
212 * self-contained shared-library.
213 */
329636d6
GT
214#ifdef ENGINE_DYNAMIC_SUPPORT
215static int bind_fn(ENGINE *e, const char *id)
0f113f3e
MC
216{
217 if (id && (strcmp(id, engine_openssl_id) != 0))
218 return 0;
219 if (!bind_helper(e))
220 return 0;
221 return 1;
222}
329636d6 223
0f113f3e
MC
224IMPLEMENT_DYNAMIC_CHECK_FN()
225 IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
226#endif /* ENGINE_DYNAMIC_SUPPORT */
3b04cdd7 227#ifdef TEST_ENG_OPENSSL_RC4
3a83462d
MC
228/*-
229 * This section of code compiles an "alternative implementation" of two modes of
3b04cdd7
GT
230 * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
231 * should under normal circumstances go via this support rather than the default
232 * EVP support. There are other symbols to tweak the testing;
3b04cdd7 233 * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
004aa803 234 * we're asked for a cipher we don't support (should not happen).
3b04cdd7
GT
235 * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
236 * the "init_key" handler is called.
237 * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
238 */
0f113f3e
MC
239# include <openssl/rc4.h>
240# define TEST_RC4_KEY_SIZE 16
241static const int test_cipher_nids[] = { NID_rc4, NID_rc4_40 };
242
f756fb43 243static const int test_cipher_nids_number = 2;
3b04cdd7 244typedef struct {
0f113f3e
MC
245 unsigned char key[TEST_RC4_KEY_SIZE];
246 RC4_KEY ks;
247} TEST_RC4_KEY;
248# define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data)
3b04cdd7 249static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
0f113f3e
MC
250 const unsigned char *iv, int enc)
251{
252# ifdef TEST_ENG_OPENSSL_RC4_P_INIT
253 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
254# endif
255 memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx));
256 RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
257 test(ctx)->key);
258 return 1;
259}
260
3b04cdd7 261static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
0f113f3e
MC
262 const unsigned char *in, size_t inl)
263{
264# ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
265 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
266# endif
267 RC4(&test(ctx)->ks, inl, in, out);
268 return 1;
269}
270
271static const EVP_CIPHER test_r4_cipher = {
272 NID_rc4,
273 1, TEST_RC4_KEY_SIZE, 0,
274 EVP_CIPH_VARIABLE_LENGTH,
275 test_rc4_init_key,
276 test_rc4_cipher,
277 NULL,
278 sizeof(TEST_RC4_KEY),
279 NULL,
280 NULL,
281 NULL,
282 NULL
283};
284
285static const EVP_CIPHER test_r4_40_cipher = {
286 NID_rc4_40,
287 1, 5 /* 40 bit */ , 0,
288 EVP_CIPH_VARIABLE_LENGTH,
289 test_rc4_init_key,
290 test_rc4_cipher,
291 NULL,
292 sizeof(TEST_RC4_KEY),
293 NULL,
294 NULL,
295 NULL,
296 NULL
297};
298
3b04cdd7 299static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
0f113f3e
MC
300 const int **nids, int nid)
301{
302 if (!cipher) {
303 /* We are returning a list of supported nids */
304 *nids = test_cipher_nids;
305 return test_cipher_nids_number;
306 }
307 /* We are being asked for a specific cipher */
308 if (nid == NID_rc4)
309 *cipher = &test_r4_cipher;
310 else if (nid == NID_rc4_40)
311 *cipher = &test_r4_40_cipher;
312 else {
313# ifdef TEST_ENG_OPENSSL_RC4_OTHERS
314 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
315 "nid %d\n", nid);
316# endif
317 *cipher = NULL;
318 return 0;
319 }
320 return 1;
321}
3b04cdd7
GT
322#endif
323
324#ifdef TEST_ENG_OPENSSL_SHA
325/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
0f113f3e
MC
326# include <openssl/sha.h>
327static const int test_digest_nids[] = { NID_sha1 };
328
f756fb43 329static const int test_digest_nids_number = 1;
3b04cdd7 330static int test_sha1_init(EVP_MD_CTX *ctx)
0f113f3e
MC
331{
332# ifdef TEST_ENG_OPENSSL_SHA_P_INIT
333 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
334# endif
335 return SHA1_Init(ctx->md_data);
336}
337
338static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count)
339{
340# ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
341 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
342# endif
343 return SHA1_Update(ctx->md_data, data, count);
344}
345
346static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
347{
348# ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
349 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
350# endif
351 return SHA1_Final(md, ctx->md_data);
352}
353
354static const EVP_MD test_sha_md = {
355 NID_sha1,
356 NID_sha1WithRSAEncryption,
357 SHA_DIGEST_LENGTH,
358 0,
359 test_sha1_init,
360 test_sha1_update,
361 test_sha1_final,
362 NULL,
363 NULL,
364 EVP_PKEY_RSA_method,
365 SHA_CBLOCK,
366 sizeof(EVP_MD *) + sizeof(SHA_CTX),
367};
368
3b04cdd7 369static int openssl_digests(ENGINE *e, const EVP_MD **digest,
0f113f3e
MC
370 const int **nids, int nid)
371{
372 if (!digest) {
373 /* We are returning a list of supported nids */
374 *nids = test_digest_nids;
375 return test_digest_nids_number;
376 }
377 /* We are being asked for a specific digest */
378 if (nid == NID_sha1)
379 *digest = &test_sha_md;
380 else {
381# ifdef TEST_ENG_OPENSSL_SHA_OTHERS
382 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
383 "nid %d\n", nid);
384# endif
385 *digest = NULL;
386 return 0;
387 }
388 return 1;
389}
3b04cdd7 390#endif
0dc09233
DSH
391
392#ifdef TEST_ENG_OPENSSL_PKEY
393static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
0f113f3e
MC
394 UI_METHOD *ui_method,
395 void *callback_data)
396{
397 BIO *in;
398 EVP_PKEY *key;
399 fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n",
400 key_id);
401 in = BIO_new_file(key_id, "r");
402 if (!in)
403 return NULL;
404 key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
405 BIO_free(in);
406 return key;
407}
0dc09233 408#endif
e77906b9
DSH
409
410#ifdef TEST_ENG_OPENSSL_HMAC
411
0f113f3e
MC
412/*
413 * Experimental HMAC redirection implementation: mainly copied from
e77906b9
DSH
414 * hm_pmeth.c
415 */
416
417/* HMAC pkey context structure */
418
0f113f3e
MC
419typedef struct {
420 const EVP_MD *md; /* MD for HMAC use */
421 ASN1_OCTET_STRING ktmp; /* Temp storage for key */
422 HMAC_CTX ctx;
423} OSSL_HMAC_PKEY_CTX;
e77906b9
DSH
424
425static int ossl_hmac_init(EVP_PKEY_CTX *ctx)
0f113f3e
MC
426{
427 OSSL_HMAC_PKEY_CTX *hctx;
b4faea50 428 hctx = OPENSSL_malloc(sizeof(*hctx));
0f113f3e
MC
429 if (!hctx)
430 return 0;
431 hctx->md = NULL;
432 hctx->ktmp.data = NULL;
433 hctx->ktmp.length = 0;
434 hctx->ktmp.flags = 0;
435 hctx->ktmp.type = V_ASN1_OCTET_STRING;
436 HMAC_CTX_init(&hctx->ctx);
437 EVP_PKEY_CTX_set_data(ctx, hctx);
438 EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0);
439# ifdef TEST_ENG_OPENSSL_HMAC_INIT
440 fprintf(stderr, "(TEST_ENG_OPENSSL_HMAC) ossl_hmac_init() called\n");
441# endif
442 return 1;
443}
e77906b9
DSH
444
445static int ossl_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
0f113f3e
MC
446{
447 OSSL_HMAC_PKEY_CTX *sctx, *dctx;
448 if (!ossl_hmac_init(dst))
449 return 0;
450 sctx = EVP_PKEY_CTX_get_data(src);
451 dctx = EVP_PKEY_CTX_get_data(dst);
452 dctx->md = sctx->md;
453 HMAC_CTX_init(&dctx->ctx);
454 if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx))
455 return 0;
456 if (sctx->ktmp.data) {
457 if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
458 sctx->ktmp.data, sctx->ktmp.length))
459 return 0;
460 }
461 return 1;
462}
e77906b9
DSH
463
464static void ossl_hmac_cleanup(EVP_PKEY_CTX *ctx)
0f113f3e 465{
4b45c6e5
RS
466 OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
467
0f113f3e 468 HMAC_CTX_cleanup(&hctx->ctx);
4b45c6e5 469 OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
0f113f3e
MC
470 OPENSSL_free(hctx);
471}
e77906b9
DSH
472
473static int ossl_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
474{
475 ASN1_OCTET_STRING *hkey = NULL;
476 OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
477 if (!hctx->ktmp.data)
478 return 0;
479 hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
480 if (!hkey)
481 return 0;
482 EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
483
484 return 1;
485}
486
487static int ossl_int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
488{
489 OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx->pctx);
490 if (!HMAC_Update(&hctx->ctx, data, count))
491 return 0;
492 return 1;
493}
e77906b9
DSH
494
495static int ossl_hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
0f113f3e
MC
496{
497 EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
498 mctx->update = ossl_int_update;
499 return 1;
500}
501
502static int ossl_hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
503 size_t *siglen, EVP_MD_CTX *mctx)
504{
505 unsigned int hlen;
506 OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
507 int l = EVP_MD_CTX_size(mctx);
508
509 if (l < 0)
510 return 0;
511 *siglen = l;
512 if (!sig)
513 return 1;
514
515 if (!HMAC_Final(&hctx->ctx, sig, &hlen))
516 return 0;
517 *siglen = (size_t)hlen;
518 return 1;
519}
e77906b9
DSH
520
521static int ossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
0f113f3e
MC
522{
523 OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
524 EVP_PKEY *pk;
525 ASN1_OCTET_STRING *key;
526 switch (type) {
527
528 case EVP_PKEY_CTRL_SET_MAC_KEY:
529 if ((!p2 && p1 > 0) || (p1 < -1))
530 return 0;
531 if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
532 return 0;
533 break;
534
535 case EVP_PKEY_CTRL_MD:
536 hctx->md = p2;
537 break;
538
539 case EVP_PKEY_CTRL_DIGESTINIT:
540 pk = EVP_PKEY_CTX_get0_pkey(ctx);
541 key = EVP_PKEY_get0(pk);
542 if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md, NULL))
543 return 0;
544 break;
545
546 default:
547 return -2;
548
549 }
550 return 1;
551}
e77906b9
DSH
552
553static int ossl_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
0f113f3e
MC
554 const char *type, const char *value)
555{
556 if (!value) {
557 return 0;
558 }
86885c28 559 if (strcmp(type, "key") == 0) {
0f113f3e
MC
560 void *p = (void *)value;
561 return ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, -1, p);
562 }
86885c28 563 if (strcmp(type, "hexkey") == 0) {
0f113f3e
MC
564 unsigned char *key;
565 int r;
566 long keylen;
567 key = string_to_hex(value, &keylen);
568 if (!key)
569 return 0;
570 r = ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
571 OPENSSL_free(key);
572 return r;
573 }
574 return -2;
575}
e77906b9
DSH
576
577static EVP_PKEY_METHOD *ossl_hmac_meth;
578
579static int ossl_register_hmac_meth(void)
0f113f3e
MC
580{
581 EVP_PKEY_METHOD *meth;
582 meth = EVP_PKEY_meth_new(EVP_PKEY_HMAC, 0);
583 if (!meth)
584 return 0;
585 EVP_PKEY_meth_set_init(meth, ossl_hmac_init);
586 EVP_PKEY_meth_set_copy(meth, ossl_hmac_copy);
587 EVP_PKEY_meth_set_cleanup(meth, ossl_hmac_cleanup);
e77906b9 588
0f113f3e 589 EVP_PKEY_meth_set_keygen(meth, 0, ossl_hmac_keygen);
e77906b9 590
0f113f3e
MC
591 EVP_PKEY_meth_set_signctx(meth, ossl_hmac_signctx_init,
592 ossl_hmac_signctx);
e77906b9 593
0f113f3e
MC
594 EVP_PKEY_meth_set_ctrl(meth, ossl_hmac_ctrl, ossl_hmac_ctrl_str);
595 ossl_hmac_meth = meth;
596 return 1;
597}
e77906b9
DSH
598
599static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
0f113f3e
MC
600 const int **nids, int nid)
601{
602 static int ossl_pkey_nids[] = {
603 EVP_PKEY_HMAC,
604 0
605 };
606 if (!pmeth) {
607 *nids = ossl_pkey_nids;
608 return 1;
609 }
610
611 if (nid == EVP_PKEY_HMAC) {
612 *pmeth = ossl_hmac_meth;
613 return 1;
614 }
615
616 *pmeth = NULL;
617 return 0;
618}
e77906b9
DSH
619
620#endif