1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <string.h> 11e1051a39Sopenharmony_ci#include <stdio.h> 12e1051a39Sopenharmony_ci#include <openssl/opensslconf.h> 13e1051a39Sopenharmony_ci#include <openssl/core.h> 14e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 15e1051a39Sopenharmony_ci#include <openssl/core_names.h> 16e1051a39Sopenharmony_ci#include <openssl/params.h> 17e1051a39Sopenharmony_ci#include "prov/bio.h" 18e1051a39Sopenharmony_ci#include "prov/provider_ctx.h" 19e1051a39Sopenharmony_ci#include "prov/providercommon.h" 20e1051a39Sopenharmony_ci#include "prov/implementations.h" 21e1051a39Sopenharmony_ci#include "prov/provider_util.h" 22e1051a39Sopenharmony_ci#include "internal/nelem.h" 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_ci/* 25e1051a39Sopenharmony_ci * Forward declarations to ensure that interface functions are correctly 26e1051a39Sopenharmony_ci * defined. 27e1051a39Sopenharmony_ci */ 28e1051a39Sopenharmony_cistatic OSSL_FUNC_provider_gettable_params_fn base_gettable_params; 29e1051a39Sopenharmony_cistatic OSSL_FUNC_provider_get_params_fn base_get_params; 30e1051a39Sopenharmony_cistatic OSSL_FUNC_provider_query_operation_fn base_query; 31e1051a39Sopenharmony_ci 32e1051a39Sopenharmony_ci/* Functions provided by the core */ 33e1051a39Sopenharmony_cistatic OSSL_FUNC_core_gettable_params_fn *c_gettable_params = NULL; 34e1051a39Sopenharmony_cistatic OSSL_FUNC_core_get_params_fn *c_get_params = NULL; 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ci/* Parameters we provide to the core */ 37e1051a39Sopenharmony_cistatic const OSSL_PARAM base_param_types[] = { 38e1051a39Sopenharmony_ci OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0), 39e1051a39Sopenharmony_ci OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), 40e1051a39Sopenharmony_ci OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0), 41e1051a39Sopenharmony_ci OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0), 42e1051a39Sopenharmony_ci OSSL_PARAM_END 43e1051a39Sopenharmony_ci}; 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_cistatic const OSSL_PARAM *base_gettable_params(void *provctx) 46e1051a39Sopenharmony_ci{ 47e1051a39Sopenharmony_ci return base_param_types; 48e1051a39Sopenharmony_ci} 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_cistatic int base_get_params(void *provctx, OSSL_PARAM params[]) 51e1051a39Sopenharmony_ci{ 52e1051a39Sopenharmony_ci OSSL_PARAM *p; 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME); 55e1051a39Sopenharmony_ci if (p != NULL 56e1051a39Sopenharmony_ci && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL Base Provider")) 57e1051a39Sopenharmony_ci return 0; 58e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION); 59e1051a39Sopenharmony_ci if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR)) 60e1051a39Sopenharmony_ci return 0; 61e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO); 62e1051a39Sopenharmony_ci if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR)) 63e1051a39Sopenharmony_ci return 0; 64e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS); 65e1051a39Sopenharmony_ci if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running())) 66e1051a39Sopenharmony_ci return 0; 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ci return 1; 69e1051a39Sopenharmony_ci} 70e1051a39Sopenharmony_ci 71e1051a39Sopenharmony_cistatic const OSSL_ALGORITHM base_encoder[] = { 72e1051a39Sopenharmony_ci#define ENCODER_PROVIDER "base" 73e1051a39Sopenharmony_ci#include "encoders.inc" 74e1051a39Sopenharmony_ci { NULL, NULL, NULL } 75e1051a39Sopenharmony_ci#undef ENCODER_PROVIDER 76e1051a39Sopenharmony_ci}; 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_cistatic const OSSL_ALGORITHM base_decoder[] = { 79e1051a39Sopenharmony_ci#define DECODER_PROVIDER "base" 80e1051a39Sopenharmony_ci#include "decoders.inc" 81e1051a39Sopenharmony_ci { NULL, NULL, NULL } 82e1051a39Sopenharmony_ci#undef DECODER_PROVIDER 83e1051a39Sopenharmony_ci}; 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_cistatic const OSSL_ALGORITHM base_store[] = { 86e1051a39Sopenharmony_ci#define STORE(name, _fips, func_table) \ 87e1051a39Sopenharmony_ci { name, "provider=base,fips=" _fips, (func_table) }, 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci#include "stores.inc" 90e1051a39Sopenharmony_ci { NULL, NULL, NULL } 91e1051a39Sopenharmony_ci#undef STORE 92e1051a39Sopenharmony_ci}; 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_cistatic const OSSL_ALGORITHM *base_query(void *provctx, int operation_id, 95e1051a39Sopenharmony_ci int *no_cache) 96e1051a39Sopenharmony_ci{ 97e1051a39Sopenharmony_ci *no_cache = 0; 98e1051a39Sopenharmony_ci switch (operation_id) { 99e1051a39Sopenharmony_ci case OSSL_OP_ENCODER: 100e1051a39Sopenharmony_ci return base_encoder; 101e1051a39Sopenharmony_ci case OSSL_OP_DECODER: 102e1051a39Sopenharmony_ci return base_decoder; 103e1051a39Sopenharmony_ci case OSSL_OP_STORE: 104e1051a39Sopenharmony_ci return base_store; 105e1051a39Sopenharmony_ci } 106e1051a39Sopenharmony_ci return NULL; 107e1051a39Sopenharmony_ci} 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_cistatic void base_teardown(void *provctx) 110e1051a39Sopenharmony_ci{ 111e1051a39Sopenharmony_ci BIO_meth_free(ossl_prov_ctx_get0_core_bio_method(provctx)); 112e1051a39Sopenharmony_ci ossl_prov_ctx_free(provctx); 113e1051a39Sopenharmony_ci} 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_ci/* Functions we provide to the core */ 116e1051a39Sopenharmony_cistatic const OSSL_DISPATCH base_dispatch_table[] = { 117e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))base_teardown }, 118e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, 119e1051a39Sopenharmony_ci (void (*)(void))base_gettable_params }, 120e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))base_get_params }, 121e1051a39Sopenharmony_ci { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))base_query }, 122e1051a39Sopenharmony_ci { 0, NULL } 123e1051a39Sopenharmony_ci}; 124e1051a39Sopenharmony_ci 125e1051a39Sopenharmony_ciOSSL_provider_init_fn ossl_base_provider_init; 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ciint ossl_base_provider_init(const OSSL_CORE_HANDLE *handle, 128e1051a39Sopenharmony_ci const OSSL_DISPATCH *in, const OSSL_DISPATCH **out, 129e1051a39Sopenharmony_ci void **provctx) 130e1051a39Sopenharmony_ci{ 131e1051a39Sopenharmony_ci OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; 132e1051a39Sopenharmony_ci BIO_METHOD *corebiometh; 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ci if (!ossl_prov_bio_from_dispatch(in)) 135e1051a39Sopenharmony_ci return 0; 136e1051a39Sopenharmony_ci for (; in->function_id != 0; in++) { 137e1051a39Sopenharmony_ci switch (in->function_id) { 138e1051a39Sopenharmony_ci case OSSL_FUNC_CORE_GETTABLE_PARAMS: 139e1051a39Sopenharmony_ci c_gettable_params = OSSL_FUNC_core_gettable_params(in); 140e1051a39Sopenharmony_ci break; 141e1051a39Sopenharmony_ci case OSSL_FUNC_CORE_GET_PARAMS: 142e1051a39Sopenharmony_ci c_get_params = OSSL_FUNC_core_get_params(in); 143e1051a39Sopenharmony_ci break; 144e1051a39Sopenharmony_ci case OSSL_FUNC_CORE_GET_LIBCTX: 145e1051a39Sopenharmony_ci c_get_libctx = OSSL_FUNC_core_get_libctx(in); 146e1051a39Sopenharmony_ci break; 147e1051a39Sopenharmony_ci default: 148e1051a39Sopenharmony_ci /* Just ignore anything we don't understand */ 149e1051a39Sopenharmony_ci break; 150e1051a39Sopenharmony_ci } 151e1051a39Sopenharmony_ci } 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ci if (c_get_libctx == NULL) 154e1051a39Sopenharmony_ci return 0; 155e1051a39Sopenharmony_ci 156e1051a39Sopenharmony_ci /* 157e1051a39Sopenharmony_ci * We want to make sure that all calls from this provider that requires 158e1051a39Sopenharmony_ci * a library context use the same context as the one used to call our 159e1051a39Sopenharmony_ci * functions. We do that by passing it along in the provider context. 160e1051a39Sopenharmony_ci * 161e1051a39Sopenharmony_ci * This only works for built-in providers. Most providers should 162e1051a39Sopenharmony_ci * create their own library context. 163e1051a39Sopenharmony_ci */ 164e1051a39Sopenharmony_ci if ((*provctx = ossl_prov_ctx_new()) == NULL 165e1051a39Sopenharmony_ci || (corebiometh = ossl_bio_prov_init_bio_method()) == NULL) { 166e1051a39Sopenharmony_ci ossl_prov_ctx_free(*provctx); 167e1051a39Sopenharmony_ci *provctx = NULL; 168e1051a39Sopenharmony_ci return 0; 169e1051a39Sopenharmony_ci } 170e1051a39Sopenharmony_ci ossl_prov_ctx_set0_libctx(*provctx, 171e1051a39Sopenharmony_ci (OSSL_LIB_CTX *)c_get_libctx(handle)); 172e1051a39Sopenharmony_ci ossl_prov_ctx_set0_handle(*provctx, handle); 173e1051a39Sopenharmony_ci ossl_prov_ctx_set0_core_bio_method(*provctx, corebiometh); 174e1051a39Sopenharmony_ci 175e1051a39Sopenharmony_ci *out = base_dispatch_table; 176e1051a39Sopenharmony_ci 177e1051a39Sopenharmony_ci return 1; 178e1051a39Sopenharmony_ci} 179