OpenCoverage

eng_openssl.c

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

Generated by Squish Coco 4.2.2