123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- /*
- * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
- #include <stddef.h>
- #include <string.h>
- #include <openssl/provider.h>
- #include <openssl/params.h>
- #include <openssl/core_names.h>
- #include <openssl/self_test.h>
- #include <openssl/evp.h>
- #include "testutil.h"
- typedef enum OPTION_choice {
- OPT_ERR = -1,
- OPT_EOF = 0,
- OPT_PROVIDER_NAME,
- OPT_CONFIG_FILE,
- OPT_TEST_ENUM
- } OPTION_CHOICE;
- struct self_test_arg {
- int count;
- };
- static OSSL_LIB_CTX *libctx = NULL;
- static char *provider_name = NULL;
- static struct self_test_arg self_test_args = { 0 };
- const OPTIONS *test_get_options(void)
- {
- static const OPTIONS test_options[] = {
- OPT_TEST_OPTIONS_DEFAULT_USAGE,
- { "provider_name", OPT_PROVIDER_NAME, 's',
- "The name of the provider to load" },
- { "config", OPT_CONFIG_FILE, '<',
- "The configuration file to use for the libctx" },
- { NULL }
- };
- return test_options;
- }
- static int self_test_events(const OSSL_PARAM params[], void *arg,
- const char *title, int corrupt)
- {
- struct self_test_arg *args = arg;
- const OSSL_PARAM *p = NULL;
- const char *phase = NULL, *type = NULL, *desc = NULL;
- int ret = 0;
- if (args->count == 0)
- BIO_printf(bio_out, "\n%s\n", title);
- args->count++;
- p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_PHASE);
- if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
- goto err;
- phase = (const char *)p->data;
- p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_DESC);
- if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
- goto err;
- desc = (const char *)p->data;
- p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_TYPE);
- if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
- goto err;
- type = (const char *)p->data;
- if (strcmp(phase, OSSL_SELF_TEST_PHASE_START) == 0)
- BIO_printf(bio_out, "%s : (%s) : ", desc, type);
- else if (strcmp(phase, OSSL_SELF_TEST_PHASE_PASS) == 0
- || strcmp(phase, OSSL_SELF_TEST_PHASE_FAIL) == 0)
- BIO_printf(bio_out, "%s\n", phase);
- /*
- * The self test code will internally corrupt the KAT test result if an
- * error is returned during the corrupt phase.
- */
- if (corrupt && strcmp(phase, OSSL_SELF_TEST_PHASE_CORRUPT) == 0)
- goto err;
- ret = 1;
- err:
- return ret;
- }
- static int self_test_on_demand_fail(const OSSL_PARAM params[], void *arg)
- {
- return self_test_events(params, arg, "On Demand Failure", 1);
- }
- static int self_test_on_demand(const OSSL_PARAM params[], void *arg)
- {
- return self_test_events(params, arg, "On Demand", 0);
- }
- static int self_test_on_load(const OSSL_PARAM params[], void *arg)
- {
- return self_test_events(params, arg, "On Loading", 0);
- }
- static int get_provider_params(const OSSL_PROVIDER *prov)
- {
- int ret = 0;
- OSSL_PARAM params[5];
- char *name, *version, *buildinfo;
- int status;
- const OSSL_PARAM *gettable, *p;
- if (!TEST_ptr(gettable = OSSL_PROVIDER_gettable_params(prov))
- || !TEST_ptr(p = OSSL_PARAM_locate_const(gettable, OSSL_PROV_PARAM_NAME))
- || !TEST_ptr(p = OSSL_PARAM_locate_const(gettable, OSSL_PROV_PARAM_VERSION))
- || !TEST_ptr(p = OSSL_PARAM_locate_const(gettable, OSSL_PROV_PARAM_STATUS))
- || !TEST_ptr(p = OSSL_PARAM_locate_const(gettable, OSSL_PROV_PARAM_BUILDINFO)))
- goto end;
- params[0] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_NAME, &name, 0);
- params[1] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION,
- &version, 0);
- params[2] = OSSL_PARAM_construct_int(OSSL_PROV_PARAM_STATUS, &status);
- params[3] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_BUILDINFO,
- &buildinfo, 0);
- params[4] = OSSL_PARAM_construct_end();
- OSSL_PARAM_set_all_unmodified(params);
- if (!TEST_true(OSSL_PROVIDER_get_params(prov, params)))
- goto end;
- if (!TEST_true(OSSL_PARAM_modified(params + 0))
- || !TEST_true(OSSL_PARAM_modified(params + 1))
- || !TEST_true(OSSL_PARAM_modified(params + 2))
- || !TEST_true(OSSL_PARAM_modified(params + 3))
- || !TEST_true(status == 1))
- goto end;
- ret = 1;
- end:
- return ret;
- }
- static int test_provider_status(void)
- {
- int ret = 0;
- unsigned int status = 0;
- OSSL_PROVIDER *prov = NULL;
- OSSL_PARAM params[2];
- EVP_MD *fetch = NULL;
- if (!TEST_ptr(prov = OSSL_PROVIDER_load(libctx, provider_name)))
- goto err;
- if (!get_provider_params(prov))
- goto err;
- /* Test that the provider status is ok */
- params[0] = OSSL_PARAM_construct_uint(OSSL_PROV_PARAM_STATUS, &status);
- params[1] = OSSL_PARAM_construct_end();
- if (!TEST_true(OSSL_PROVIDER_get_params(prov, params))
- || !TEST_true(status == 1))
- goto err;
- if (!TEST_ptr(fetch = EVP_MD_fetch(libctx, "SHA256", NULL)))
- goto err;
- EVP_MD_free(fetch);
- fetch = NULL;
- /* Test that the provider self test is ok */
- self_test_args.count = 0;
- OSSL_SELF_TEST_set_callback(libctx, self_test_on_demand, &self_test_args);
- if (!TEST_true(OSSL_PROVIDER_self_test(prov)))
- goto err;
- /* Setup a callback that corrupts the self tests and causes status failures */
- self_test_args.count = 0;
- OSSL_SELF_TEST_set_callback(libctx, self_test_on_demand_fail, &self_test_args);
- if (!TEST_false(OSSL_PROVIDER_self_test(prov)))
- goto err;
- if (!TEST_true(OSSL_PROVIDER_get_params(prov, params))
- || !TEST_uint_eq(status, 0))
- goto err;
- if (!TEST_ptr_null(fetch = EVP_MD_fetch(libctx, "SHA256", NULL)))
- goto err;
- ret = 1;
- err:
- EVP_MD_free(fetch);
- OSSL_PROVIDER_unload(prov);
- return ret;
- }
- static int test_provider_gettable_params(void)
- {
- OSSL_PROVIDER *prov;
- int ret;
- if (!TEST_ptr(prov = OSSL_PROVIDER_load(libctx, provider_name)))
- return 0;
- ret = get_provider_params(prov);
- OSSL_PROVIDER_unload(prov);
- return ret;
- }
- int setup_tests(void)
- {
- OPTION_CHOICE o;
- char *config_file = NULL;
- while ((o = opt_next()) != OPT_EOF) {
- switch (o) {
- case OPT_CONFIG_FILE:
- config_file = opt_arg();
- break;
- case OPT_PROVIDER_NAME:
- provider_name = opt_arg();
- break;
- case OPT_TEST_CASES:
- break;
- default:
- case OPT_ERR:
- return 0;
- }
- }
- libctx = OSSL_LIB_CTX_new();
- if (libctx == NULL)
- return 0;
- if (strcmp(provider_name, "fips") == 0) {
- self_test_args.count = 0;
- OSSL_SELF_TEST_set_callback(libctx, self_test_on_load, &self_test_args);
- if (!OSSL_LIB_CTX_load_config(libctx, config_file)) {
- opt_printf_stderr("Failed to load config\n");
- return 0;
- }
- ADD_TEST(test_provider_status);
- } else {
- ADD_TEST(test_provider_gettable_params);
- }
- return 1;
- }
- void cleanup_tests(void)
- {
- OSSL_LIB_CTX_free(libctx);
- }
|