1*66bae5e7Schristos /*
2*66bae5e7Schristos  * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
3*66bae5e7Schristos  *
4*66bae5e7Schristos  * Licensed under the Apache License 2.0 (the "License").  You may not use
5*66bae5e7Schristos  * this file except in compliance with the License.  You can obtain a copy
6*66bae5e7Schristos  * in the file LICENSE in the source distribution or at
7*66bae5e7Schristos  * https://www.openssl.org/source/license.html
8*66bae5e7Schristos  */
9*66bae5e7Schristos 
10*66bae5e7Schristos #include <stddef.h>
11*66bae5e7Schristos #include <string.h>
12*66bae5e7Schristos #include <openssl/provider.h>
13*66bae5e7Schristos #include <openssl/params.h>
14*66bae5e7Schristos #include <openssl/core_names.h>
15*66bae5e7Schristos #include <openssl/self_test.h>
16*66bae5e7Schristos #include <openssl/evp.h>
17*66bae5e7Schristos #include "testutil.h"
18*66bae5e7Schristos 
19*66bae5e7Schristos typedef enum OPTION_choice {
20*66bae5e7Schristos     OPT_ERR = -1,
21*66bae5e7Schristos     OPT_EOF = 0,
22*66bae5e7Schristos     OPT_PROVIDER_NAME,
23*66bae5e7Schristos     OPT_CONFIG_FILE,
24*66bae5e7Schristos     OPT_TEST_ENUM
25*66bae5e7Schristos } OPTION_CHOICE;
26*66bae5e7Schristos 
27*66bae5e7Schristos struct self_test_arg {
28*66bae5e7Schristos     int count;
29*66bae5e7Schristos };
30*66bae5e7Schristos 
31*66bae5e7Schristos static OSSL_LIB_CTX *libctx = NULL;
32*66bae5e7Schristos static char *provider_name = NULL;
33*66bae5e7Schristos static struct self_test_arg self_test_args = { 0 };
34*66bae5e7Schristos 
test_get_options(void)35*66bae5e7Schristos const OPTIONS *test_get_options(void)
36*66bae5e7Schristos {
37*66bae5e7Schristos     static const OPTIONS test_options[] = {
38*66bae5e7Schristos         OPT_TEST_OPTIONS_DEFAULT_USAGE,
39*66bae5e7Schristos         { "provider_name", OPT_PROVIDER_NAME, 's',
40*66bae5e7Schristos           "The name of the provider to load" },
41*66bae5e7Schristos         { "config", OPT_CONFIG_FILE, '<',
42*66bae5e7Schristos           "The configuration file to use for the libctx" },
43*66bae5e7Schristos         { NULL }
44*66bae5e7Schristos     };
45*66bae5e7Schristos     return test_options;
46*66bae5e7Schristos }
47*66bae5e7Schristos 
self_test_events(const OSSL_PARAM params[],void * arg,const char * title,int corrupt)48*66bae5e7Schristos static int self_test_events(const OSSL_PARAM params[], void *arg,
49*66bae5e7Schristos                             const char *title, int corrupt)
50*66bae5e7Schristos {
51*66bae5e7Schristos     struct self_test_arg *args = arg;
52*66bae5e7Schristos     const OSSL_PARAM *p = NULL;
53*66bae5e7Schristos     const char *phase = NULL, *type = NULL, *desc = NULL;
54*66bae5e7Schristos     int ret = 0;
55*66bae5e7Schristos 
56*66bae5e7Schristos     if (args->count == 0)
57*66bae5e7Schristos         BIO_printf(bio_out, "\n%s\n", title);
58*66bae5e7Schristos     args->count++;
59*66bae5e7Schristos 
60*66bae5e7Schristos     p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_PHASE);
61*66bae5e7Schristos     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
62*66bae5e7Schristos         goto err;
63*66bae5e7Schristos     phase = (const char *)p->data;
64*66bae5e7Schristos 
65*66bae5e7Schristos     p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_DESC);
66*66bae5e7Schristos     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
67*66bae5e7Schristos         goto err;
68*66bae5e7Schristos     desc = (const char *)p->data;
69*66bae5e7Schristos 
70*66bae5e7Schristos     p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_TYPE);
71*66bae5e7Schristos     if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
72*66bae5e7Schristos         goto err;
73*66bae5e7Schristos     type = (const char *)p->data;
74*66bae5e7Schristos 
75*66bae5e7Schristos     if (strcmp(phase, OSSL_SELF_TEST_PHASE_START) == 0)
76*66bae5e7Schristos         BIO_printf(bio_out, "%s : (%s) : ", desc, type);
77*66bae5e7Schristos     else if (strcmp(phase, OSSL_SELF_TEST_PHASE_PASS) == 0
78*66bae5e7Schristos              || strcmp(phase, OSSL_SELF_TEST_PHASE_FAIL) == 0)
79*66bae5e7Schristos         BIO_printf(bio_out, "%s\n", phase);
80*66bae5e7Schristos     /*
81*66bae5e7Schristos      * The self test code will internally corrupt the KAT test result if an
82*66bae5e7Schristos      * error is returned during the corrupt phase.
83*66bae5e7Schristos      */
84*66bae5e7Schristos     if (corrupt && strcmp(phase, OSSL_SELF_TEST_PHASE_CORRUPT) == 0)
85*66bae5e7Schristos         goto err;
86*66bae5e7Schristos     ret = 1;
87*66bae5e7Schristos err:
88*66bae5e7Schristos     return ret;
89*66bae5e7Schristos }
90*66bae5e7Schristos 
self_test_on_demand_fail(const OSSL_PARAM params[],void * arg)91*66bae5e7Schristos static int self_test_on_demand_fail(const OSSL_PARAM params[], void *arg)
92*66bae5e7Schristos {
93*66bae5e7Schristos     return self_test_events(params, arg, "On Demand Failure", 1);
94*66bae5e7Schristos }
95*66bae5e7Schristos 
self_test_on_demand(const OSSL_PARAM params[],void * arg)96*66bae5e7Schristos static int self_test_on_demand(const OSSL_PARAM params[], void *arg)
97*66bae5e7Schristos {
98*66bae5e7Schristos     return self_test_events(params, arg, "On Demand", 0);
99*66bae5e7Schristos }
100*66bae5e7Schristos 
self_test_on_load(const OSSL_PARAM params[],void * arg)101*66bae5e7Schristos static int self_test_on_load(const OSSL_PARAM params[], void *arg)
102*66bae5e7Schristos {
103*66bae5e7Schristos     return self_test_events(params, arg, "On Loading", 0);
104*66bae5e7Schristos }
105*66bae5e7Schristos 
get_provider_params(const OSSL_PROVIDER * prov)106*66bae5e7Schristos static int get_provider_params(const OSSL_PROVIDER *prov)
107*66bae5e7Schristos {
108*66bae5e7Schristos     int ret = 0;
109*66bae5e7Schristos     OSSL_PARAM params[5];
110*66bae5e7Schristos     char *name, *version, *buildinfo;
111*66bae5e7Schristos     int status;
112*66bae5e7Schristos     const OSSL_PARAM *gettable, *p;
113*66bae5e7Schristos 
114*66bae5e7Schristos     if (!TEST_ptr(gettable = OSSL_PROVIDER_gettable_params(prov))
115*66bae5e7Schristos         || !TEST_ptr(p = OSSL_PARAM_locate_const(gettable, OSSL_PROV_PARAM_NAME))
116*66bae5e7Schristos         || !TEST_ptr(p = OSSL_PARAM_locate_const(gettable, OSSL_PROV_PARAM_VERSION))
117*66bae5e7Schristos         || !TEST_ptr(p = OSSL_PARAM_locate_const(gettable, OSSL_PROV_PARAM_STATUS))
118*66bae5e7Schristos         || !TEST_ptr(p = OSSL_PARAM_locate_const(gettable, OSSL_PROV_PARAM_BUILDINFO)))
119*66bae5e7Schristos         goto end;
120*66bae5e7Schristos 
121*66bae5e7Schristos     params[0] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_NAME, &name, 0);
122*66bae5e7Schristos     params[1] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION,
123*66bae5e7Schristos                                               &version, 0);
124*66bae5e7Schristos     params[2] = OSSL_PARAM_construct_int(OSSL_PROV_PARAM_STATUS, &status);
125*66bae5e7Schristos     params[3] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_BUILDINFO,
126*66bae5e7Schristos                                               &buildinfo, 0);
127*66bae5e7Schristos     params[4] = OSSL_PARAM_construct_end();
128*66bae5e7Schristos     OSSL_PARAM_set_all_unmodified(params);
129*66bae5e7Schristos     if (!TEST_true(OSSL_PROVIDER_get_params(prov, params)))
130*66bae5e7Schristos         goto end;
131*66bae5e7Schristos     if (!TEST_true(OSSL_PARAM_modified(params + 0))
132*66bae5e7Schristos         || !TEST_true(OSSL_PARAM_modified(params + 1))
133*66bae5e7Schristos         || !TEST_true(OSSL_PARAM_modified(params + 2))
134*66bae5e7Schristos         || !TEST_true(OSSL_PARAM_modified(params + 3))
135*66bae5e7Schristos         || !TEST_true(status == 1))
136*66bae5e7Schristos         goto end;
137*66bae5e7Schristos 
138*66bae5e7Schristos     ret = 1;
139*66bae5e7Schristos end:
140*66bae5e7Schristos     return ret;
141*66bae5e7Schristos }
142*66bae5e7Schristos 
test_provider_status(void)143*66bae5e7Schristos static int test_provider_status(void)
144*66bae5e7Schristos {
145*66bae5e7Schristos     int ret = 0;
146*66bae5e7Schristos     unsigned int status = 0;
147*66bae5e7Schristos     OSSL_PROVIDER *prov = NULL;
148*66bae5e7Schristos     OSSL_PARAM params[2];
149*66bae5e7Schristos     EVP_MD *fetch = NULL;
150*66bae5e7Schristos 
151*66bae5e7Schristos     if (!TEST_ptr(prov = OSSL_PROVIDER_load(libctx, provider_name)))
152*66bae5e7Schristos         goto err;
153*66bae5e7Schristos     if (!get_provider_params(prov))
154*66bae5e7Schristos         goto err;
155*66bae5e7Schristos 
156*66bae5e7Schristos     /* Test that the provider status is ok */
157*66bae5e7Schristos     params[0] = OSSL_PARAM_construct_uint(OSSL_PROV_PARAM_STATUS, &status);
158*66bae5e7Schristos     params[1] = OSSL_PARAM_construct_end();
159*66bae5e7Schristos     if (!TEST_true(OSSL_PROVIDER_get_params(prov, params))
160*66bae5e7Schristos         || !TEST_true(status == 1))
161*66bae5e7Schristos         goto err;
162*66bae5e7Schristos     if (!TEST_ptr(fetch = EVP_MD_fetch(libctx, "SHA256", NULL)))
163*66bae5e7Schristos         goto err;
164*66bae5e7Schristos     EVP_MD_free(fetch);
165*66bae5e7Schristos     fetch = NULL;
166*66bae5e7Schristos 
167*66bae5e7Schristos     /* Test that the provider self test is ok */
168*66bae5e7Schristos     self_test_args.count = 0;
169*66bae5e7Schristos     OSSL_SELF_TEST_set_callback(libctx, self_test_on_demand, &self_test_args);
170*66bae5e7Schristos     if (!TEST_true(OSSL_PROVIDER_self_test(prov)))
171*66bae5e7Schristos         goto err;
172*66bae5e7Schristos 
173*66bae5e7Schristos     /* Setup a callback that corrupts the self tests and causes status failures */
174*66bae5e7Schristos     self_test_args.count = 0;
175*66bae5e7Schristos     OSSL_SELF_TEST_set_callback(libctx, self_test_on_demand_fail, &self_test_args);
176*66bae5e7Schristos     if (!TEST_false(OSSL_PROVIDER_self_test(prov)))
177*66bae5e7Schristos         goto err;
178*66bae5e7Schristos     if (!TEST_true(OSSL_PROVIDER_get_params(prov, params))
179*66bae5e7Schristos         || !TEST_uint_eq(status, 0))
180*66bae5e7Schristos         goto err;
181*66bae5e7Schristos     if (!TEST_ptr_null(fetch = EVP_MD_fetch(libctx, "SHA256", NULL)))
182*66bae5e7Schristos         goto err;
183*66bae5e7Schristos 
184*66bae5e7Schristos     ret = 1;
185*66bae5e7Schristos err:
186*66bae5e7Schristos     EVP_MD_free(fetch);
187*66bae5e7Schristos     OSSL_PROVIDER_unload(prov);
188*66bae5e7Schristos     return ret;
189*66bae5e7Schristos }
190*66bae5e7Schristos 
test_provider_gettable_params(void)191*66bae5e7Schristos static int test_provider_gettable_params(void)
192*66bae5e7Schristos {
193*66bae5e7Schristos     OSSL_PROVIDER *prov;
194*66bae5e7Schristos     int ret;
195*66bae5e7Schristos 
196*66bae5e7Schristos     if (!TEST_ptr(prov = OSSL_PROVIDER_load(libctx, provider_name)))
197*66bae5e7Schristos         return 0;
198*66bae5e7Schristos     ret = get_provider_params(prov);
199*66bae5e7Schristos     OSSL_PROVIDER_unload(prov);
200*66bae5e7Schristos     return ret;
201*66bae5e7Schristos }
202*66bae5e7Schristos 
setup_tests(void)203*66bae5e7Schristos int setup_tests(void)
204*66bae5e7Schristos {
205*66bae5e7Schristos     OPTION_CHOICE o;
206*66bae5e7Schristos     char *config_file = NULL;
207*66bae5e7Schristos 
208*66bae5e7Schristos     while ((o = opt_next()) != OPT_EOF) {
209*66bae5e7Schristos         switch (o) {
210*66bae5e7Schristos         case OPT_CONFIG_FILE:
211*66bae5e7Schristos             config_file = opt_arg();
212*66bae5e7Schristos             break;
213*66bae5e7Schristos         case OPT_PROVIDER_NAME:
214*66bae5e7Schristos             provider_name = opt_arg();
215*66bae5e7Schristos             break;
216*66bae5e7Schristos         case OPT_TEST_CASES:
217*66bae5e7Schristos            break;
218*66bae5e7Schristos         default:
219*66bae5e7Schristos         case OPT_ERR:
220*66bae5e7Schristos             return 0;
221*66bae5e7Schristos         }
222*66bae5e7Schristos     }
223*66bae5e7Schristos 
224*66bae5e7Schristos     libctx = OSSL_LIB_CTX_new();
225*66bae5e7Schristos     if (libctx == NULL)
226*66bae5e7Schristos         return 0;
227*66bae5e7Schristos 
228*66bae5e7Schristos     if (strcmp(provider_name, "fips") == 0) {
229*66bae5e7Schristos         self_test_args.count = 0;
230*66bae5e7Schristos         OSSL_SELF_TEST_set_callback(libctx, self_test_on_load, &self_test_args);
231*66bae5e7Schristos         if (!OSSL_LIB_CTX_load_config(libctx, config_file)) {
232*66bae5e7Schristos             opt_printf_stderr("Failed to load config\n");
233*66bae5e7Schristos             return 0;
234*66bae5e7Schristos         }
235*66bae5e7Schristos         ADD_TEST(test_provider_status);
236*66bae5e7Schristos     } else {
237*66bae5e7Schristos         ADD_TEST(test_provider_gettable_params);
238*66bae5e7Schristos     }
239*66bae5e7Schristos     return 1;
240*66bae5e7Schristos }
241*66bae5e7Schristos 
cleanup_tests(void)242*66bae5e7Schristos void cleanup_tests(void)
243*66bae5e7Schristos {
244*66bae5e7Schristos     OSSL_LIB_CTX_free(libctx);
245*66bae5e7Schristos }
246