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