2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
12 #include <openssl/core.h>
13 #include <openssl/core_numbers.h>
14 #include <openssl/core_names.h>
15 #include <openssl/params.h>
16 #include <openssl/err.h>
17 #include <openssl/evp.h>
19 /* TODO(3.0): Needed for dummy_evp_call(). To be removed */
20 #include <openssl/sha.h>
21 #include <openssl/rand_drbg.h>
23 #include "internal/cryptlib.h"
24 #include "internal/property.h"
25 #include "internal/evp_int.h"
26 #include "internal/provider_algs.h"
27 #include "internal/provider_ctx.h"
28 #include "internal/providercommon.h"
30 extern OSSL_core_thread_start_fn *c_thread_start;
33 * TODO(3.0): Should these be stored in the provider side provctx? Could they
34 * ever be different from one init to the next? Unfortunately we can't do this
35 * at the moment because c_put_error/c_add_error_vdata do not provide
36 * us with the OPENSSL_CTX as a parameter.
38 /* Functions provided by the core */
39 static OSSL_core_get_param_types_fn *c_get_param_types;
40 static OSSL_core_get_params_fn *c_get_params;
41 OSSL_core_thread_start_fn *c_thread_start;
42 static OSSL_core_put_error_fn *c_put_error;
43 static OSSL_core_add_error_vdata_fn *c_add_error_vdata;
44 static OSSL_CRYPTO_malloc_fn *c_CRYPTO_malloc;
45 static OSSL_CRYPTO_zalloc_fn *c_CRYPTO_zalloc;
46 static OSSL_CRYPTO_free_fn *c_CRYPTO_free;
47 static OSSL_CRYPTO_clear_free_fn *c_CRYPTO_clear_free;
48 static OSSL_CRYPTO_realloc_fn *c_CRYPTO_realloc;
49 static OSSL_CRYPTO_clear_realloc_fn *c_CRYPTO_clear_realloc;
50 static OSSL_CRYPTO_secure_malloc_fn *c_CRYPTO_secure_malloc;
51 static OSSL_CRYPTO_secure_zalloc_fn *c_CRYPTO_secure_zalloc;
52 static OSSL_CRYPTO_secure_free_fn *c_CRYPTO_secure_free;
53 static OSSL_CRYPTO_secure_clear_free_fn *c_CRYPTO_secure_clear_free;
54 static OSSL_CRYPTO_secure_allocated_fn *c_CRYPTO_secure_allocated;
56 typedef struct fips_global_st {
57 const OSSL_PROVIDER *prov;
60 static void *fips_prov_ossl_ctx_new(OPENSSL_CTX *libctx)
62 FIPS_GLOBAL *fgbl = OPENSSL_zalloc(sizeof(*fgbl));
67 static void fips_prov_ossl_ctx_free(void *fgbl)
72 static const OPENSSL_CTX_METHOD fips_prov_ossl_ctx_method = {
73 fips_prov_ossl_ctx_new,
74 fips_prov_ossl_ctx_free,
78 /* Parameters we provide to the core */
79 static const OSSL_PARAM fips_param_types[] = {
80 OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0),
81 OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0),
82 OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0),
86 /* TODO(3.0): To be removed */
87 static int dummy_evp_call(void *provctx)
89 OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
90 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
91 EVP_MD *sha256 = EVP_MD_fetch(libctx, "SHA256", NULL);
92 char msg[] = "Hello World!";
93 const unsigned char exptd[] = {
94 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
95 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28,
96 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69
98 unsigned int dgstlen = 0;
99 unsigned char dgst[SHA256_DIGEST_LENGTH];
101 BN_CTX *bnctx = NULL;
102 BIGNUM *a = NULL, *b = NULL;
103 unsigned char randbuf[128];
104 RAND_DRBG *drbg = OPENSSL_CTX_get0_public_drbg(libctx);
106 if (ctx == NULL || sha256 == NULL || drbg == NULL)
109 if (!EVP_DigestInit_ex(ctx, sha256, NULL))
111 if (!EVP_DigestUpdate(ctx, msg, sizeof(msg) - 1))
113 if (!EVP_DigestFinal(ctx, dgst, &dgstlen))
115 if (dgstlen != sizeof(exptd) || memcmp(dgst, exptd, sizeof(exptd)) != 0)
118 bnctx = BN_CTX_new_ex(libctx);
122 a = BN_CTX_get(bnctx);
123 b = BN_CTX_get(bnctx);
129 || BN_cmp(a, b) != 0)
132 if (RAND_DRBG_bytes(drbg, randbuf, sizeof(randbuf)) <= 0)
135 if (!BN_rand_ex(a, 256, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, bnctx))
143 EVP_MD_CTX_free(ctx);
144 EVP_MD_meth_free(sha256);
148 static const OSSL_PARAM *fips_get_param_types(const OSSL_PROVIDER *prov)
150 return fips_param_types;
153 static int fips_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
157 p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
158 if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL FIPS Provider"))
160 p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
161 if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR))
163 p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO);
164 if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR))
170 /* FIPS specific version of the function of the same name in provlib.c */
171 const char *ossl_prov_util_nid_to_name(int nid)
173 /* We don't have OBJ_nid2n() in FIPS_MODE so we have an explicit list */
201 case NID_aes_256_ecb:
202 return "AES-256-ECB";
203 case NID_aes_192_ecb:
204 return "AES-192-ECB";
205 case NID_aes_128_ecb:
206 return "AES-128-ECB";
207 case NID_aes_256_cbc:
208 return "AES-256-CBC";
209 case NID_aes_192_cbc:
210 return "AES-192-CBC";
211 case NID_aes_128_cbc:
212 return "AES-128-CBC";
213 case NID_aes_256_ctr:
214 return "AES-256-CTR";
215 case NID_aes_192_ctr:
216 return "AES-192-CTR";
217 case NID_aes_128_ctr:
218 return "AES-128-CTR";
224 static const OSSL_ALGORITHM fips_digests[] = {
225 { "SHA1", "fips=yes", sha1_functions },
226 { "SHA224", "fips=yes", sha224_functions },
227 { "SHA256", "fips=yes", sha256_functions },
228 { "SHA384", "fips=yes", sha384_functions },
229 { "SHA512", "fips=yes", sha512_functions },
230 { "SHA512-224", "fips=yes", sha512_224_functions },
231 { "SHA512-256", "fips=yes", sha512_256_functions },
232 { "SHA3-224", "fips=yes", sha3_224_functions },
233 { "SHA3-256", "fips=yes", sha3_256_functions },
234 { "SHA3-384", "fips=yes", sha3_384_functions },
235 { "SHA3-512", "fips=yes", sha3_512_functions },
236 { "KMAC128", "fips=yes", keccak_kmac_128_functions },
237 { "KMAC256", "fips=yes", keccak_kmac_256_functions },
242 static const OSSL_ALGORITHM fips_ciphers[] = {
243 { "AES-256-ECB", "fips=yes", aes256ecb_functions },
244 { "AES-192-ECB", "fips=yes", aes192ecb_functions },
245 { "AES-128-ECB", "fips=yes", aes128ecb_functions },
246 { "AES-256-CBC", "fips=yes", aes256cbc_functions },
247 { "AES-192-CBC", "fips=yes", aes192cbc_functions },
248 { "AES-128-CBC", "fips=yes", aes128cbc_functions },
249 { "AES-256-CTR", "fips=yes", aes256ctr_functions },
250 { "AES-192-CTR", "fips=yes", aes192ctr_functions },
251 { "AES-128-CTR", "fips=yes", aes128ctr_functions },
255 static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
260 switch (operation_id) {
269 /* Functions we provide to the core */
270 static const OSSL_DISPATCH fips_dispatch_table[] = {
272 * To release our resources we just need to free the OPENSSL_CTX so we just
273 * use OPENSSL_CTX_free directly as our teardown function
275 { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OPENSSL_CTX_free },
276 { OSSL_FUNC_PROVIDER_GET_PARAM_TYPES, (void (*)(void))fips_get_param_types },
277 { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))fips_get_params },
278 { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
282 /* Functions we provide to ourself */
283 static const OSSL_DISPATCH intern_dispatch_table[] = {
284 { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
289 int OSSL_provider_init(const OSSL_PROVIDER *provider,
290 const OSSL_DISPATCH *in,
291 const OSSL_DISPATCH **out,
297 for (; in->function_id != 0; in++) {
298 switch (in->function_id) {
299 case OSSL_FUNC_CORE_GET_PARAM_TYPES:
300 c_get_param_types = OSSL_get_core_get_param_types(in);
302 case OSSL_FUNC_CORE_GET_PARAMS:
303 c_get_params = OSSL_get_core_get_params(in);
305 case OSSL_FUNC_CORE_THREAD_START:
306 c_thread_start = OSSL_get_core_thread_start(in);
308 case OSSL_FUNC_CORE_PUT_ERROR:
309 c_put_error = OSSL_get_core_put_error(in);
311 case OSSL_FUNC_CORE_ADD_ERROR_VDATA:
312 c_add_error_vdata = OSSL_get_core_add_error_vdata(in);
314 case OSSL_FUNC_CRYPTO_MALLOC:
315 c_CRYPTO_malloc = OSSL_get_CRYPTO_malloc(in);
317 case OSSL_FUNC_CRYPTO_ZALLOC:
318 c_CRYPTO_zalloc = OSSL_get_CRYPTO_zalloc(in);
320 case OSSL_FUNC_CRYPTO_FREE:
321 c_CRYPTO_free = OSSL_get_CRYPTO_free(in);
323 case OSSL_FUNC_CRYPTO_CLEAR_FREE:
324 c_CRYPTO_clear_free = OSSL_get_CRYPTO_clear_free(in);
326 case OSSL_FUNC_CRYPTO_REALLOC:
327 c_CRYPTO_realloc = OSSL_get_CRYPTO_realloc(in);
329 case OSSL_FUNC_CRYPTO_CLEAR_REALLOC:
330 c_CRYPTO_clear_realloc = OSSL_get_CRYPTO_clear_realloc(in);
332 case OSSL_FUNC_CRYPTO_SECURE_MALLOC:
333 c_CRYPTO_secure_malloc = OSSL_get_CRYPTO_secure_malloc(in);
335 case OSSL_FUNC_CRYPTO_SECURE_ZALLOC:
336 c_CRYPTO_secure_zalloc = OSSL_get_CRYPTO_secure_zalloc(in);
338 case OSSL_FUNC_CRYPTO_SECURE_FREE:
339 c_CRYPTO_secure_free = OSSL_get_CRYPTO_secure_free(in);
341 case OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE:
342 c_CRYPTO_secure_clear_free = OSSL_get_CRYPTO_secure_clear_free(in);
344 case OSSL_FUNC_CRYPTO_SECURE_ALLOCATED:
345 c_CRYPTO_secure_allocated = OSSL_get_CRYPTO_secure_allocated(in);
348 /* Just ignore anything we don't understand */
353 /* Create a context. */
354 if ((ctx = OPENSSL_CTX_new()) == NULL)
356 if ((fgbl = openssl_ctx_get_data(ctx, OPENSSL_CTX_FIPS_PROV_INDEX,
357 &fips_prov_ossl_ctx_method)) == NULL) {
358 OPENSSL_CTX_free(ctx);
361 fgbl->prov = provider;
362 *out = fips_dispatch_table;
366 * TODO(3.0): Remove me. This is just a dummy call to demonstrate making
367 * EVP calls from within the FIPS module.
369 if (!dummy_evp_call(*provctx)) {
370 OPENSSL_CTX_free(*provctx);
379 * The internal init function used when the FIPS module uses EVP to call
380 * another algorithm also in the FIPS module. This is a recursive call that has
381 * been made from within the FIPS module itself. To make this work, we populate
382 * the provider context of this inner instance with the same library context
383 * that was used in the EVP call that initiated this recursive call.
385 OSSL_provider_init_fn fips_intern_provider_init;
386 int fips_intern_provider_init(const OSSL_PROVIDER *provider,
387 const OSSL_DISPATCH *in,
388 const OSSL_DISPATCH **out,
391 OSSL_core_get_library_context_fn *c_get_libctx = NULL;
393 for (; in->function_id != 0; in++) {
394 switch (in->function_id) {
395 case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT:
396 c_get_libctx = OSSL_get_core_get_library_context(in);
403 if (c_get_libctx == NULL)
406 *provctx = c_get_libctx(provider);
409 * Safety measure... we should get the library context that was
410 * created up in OSSL_provider_init().
412 if (*provctx == NULL)
415 *out = intern_dispatch_table;
419 void ERR_put_error(int lib, int func, int reason, const char *file, int line)
422 * TODO(3.0) the first argument is currently NULL but is expected to
423 * be passed something else in the future, either an OSSL_PROVIDER or
424 * a OPENSSL_CTX pointer.
426 c_put_error(NULL, ERR_PACK(lib, func, reason), file, line);
427 ERR_add_error_data(1, "(in the FIPS module)");
430 void ERR_add_error_data(int num, ...)
435 ERR_add_error_vdata(num, args);
439 void ERR_add_error_vdata(int num, va_list args)
441 c_add_error_vdata(NULL, num, args);
444 const OSSL_PROVIDER *FIPS_get_provider(OPENSSL_CTX *ctx)
446 FIPS_GLOBAL *fgbl = openssl_ctx_get_data(ctx, OPENSSL_CTX_FIPS_PROV_INDEX,
447 &fips_prov_ossl_ctx_method);
455 void *CRYPTO_malloc(size_t num, const char *file, int line)
457 return c_CRYPTO_malloc(num, file, line);
460 void *CRYPTO_zalloc(size_t num, const char *file, int line)
462 return c_CRYPTO_zalloc(num, file, line);
465 void CRYPTO_free(void *ptr, const char *file, int line)
467 c_CRYPTO_free(ptr, file, line);
470 void CRYPTO_clear_free(void *ptr, size_t num, const char *file, int line)
472 c_CRYPTO_clear_free(ptr, num, file, line);
475 void *CRYPTO_realloc(void *addr, size_t num, const char *file, int line)
477 return c_CRYPTO_realloc(addr, num, file, line);
480 void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num,
481 const char *file, int line)
483 return c_CRYPTO_clear_realloc(addr, old_num, num, file, line);
486 void *CRYPTO_secure_malloc(size_t num, const char *file, int line)
488 return c_CRYPTO_secure_malloc(num, file, line);
491 void *CRYPTO_secure_zalloc(size_t num, const char *file, int line)
493 return c_CRYPTO_secure_zalloc(num, file, line);
496 void CRYPTO_secure_free(void *ptr, const char *file, int line)
498 c_CRYPTO_secure_free(ptr, file, line);
501 void CRYPTO_secure_clear_free(void *ptr, size_t num, const char *file, int line)
503 c_CRYPTO_secure_clear_free(ptr, num, file, line);
506 int CRYPTO_secure_allocated(const void *ptr)
508 return c_CRYPTO_secure_allocated(ptr);