Make core code available within the FIPS module
[openssl.git] / providers / fips / fipsprov.c
1 /*
2  * Copyright 2019 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 <string.h>
11 #include <stdio.h>
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 "internal/cryptlib.h"
18
19 /* Functions provided by the core */
20 static OSSL_core_get_param_types_fn *c_get_param_types = NULL;
21 static OSSL_core_get_params_fn *c_get_params = NULL;
22 static OSSL_core_put_error_fn *c_put_error = NULL;
23 static OSSL_core_add_error_vdata_fn *c_add_error_vdata = NULL;
24
25 /* Parameters we provide to the core */
26 static const OSSL_ITEM fips_param_types[] = {
27     { OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_NAME },
28     { OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_VERSION },
29     { OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_BUILDINFO },
30     { 0, NULL }
31 };
32
33 static void fips_teardown(void)
34 {
35     do_default_context_deinit();
36 }
37
38 static const OSSL_ITEM *fips_get_param_types(const OSSL_PROVIDER *prov)
39 {
40     return fips_param_types;
41 }
42
43 static int fips_get_params(const OSSL_PROVIDER *prov,
44                             const OSSL_PARAM params[])
45 {
46     const OSSL_PARAM *p;
47
48     p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
49     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL FIPS Provider"))
50         return 0;
51     p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
52     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR))
53         return 0;
54     p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO);
55     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR))
56         return 0;
57
58     return 1;
59 }
60
61 extern const OSSL_DISPATCH sha256_functions[];
62
63 static const OSSL_ALGORITHM fips_digests[] = {
64     { "SHA256", "fips=yes", sha256_functions },
65     { NULL, NULL, NULL }
66 };
67
68 static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
69                                          int operation_id,
70                                          int *no_cache)
71 {
72     *no_cache = 0;
73     switch (operation_id) {
74     case OSSL_OP_DIGEST:
75         return fips_digests;
76     }
77     return NULL;
78 }
79
80 /* Functions we provide to the core */
81 static const OSSL_DISPATCH fips_dispatch_table[] = {
82     { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))fips_teardown },
83     { OSSL_FUNC_PROVIDER_GET_PARAM_TYPES, (void (*)(void))fips_get_param_types },
84     { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))fips_get_params },
85     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
86     { 0, NULL }
87 };
88
89 int OSSL_provider_init(const OSSL_PROVIDER *provider,
90                        const OSSL_DISPATCH *in,
91                        const OSSL_DISPATCH **out,
92                        void **provctx)
93 {
94     for (; in->function_id != 0; in++) {
95         switch (in->function_id) {
96         case OSSL_FUNC_CORE_GET_PARAM_TYPES:
97             c_get_param_types = OSSL_get_core_get_param_types(in);
98             break;
99         case OSSL_FUNC_CORE_GET_PARAMS:
100             c_get_params = OSSL_get_core_get_params(in);
101             break;
102         case OSSL_FUNC_CORE_PUT_ERROR:
103             c_put_error = OSSL_get_core_put_error(in);
104             break;
105         case OSSL_FUNC_CORE_ADD_ERROR_VDATA:
106             c_add_error_vdata = OSSL_get_core_add_error_vdata(in);
107             break;
108         /* Just ignore anything we don't understand */
109         default:
110             break;
111         }
112     }
113
114     *out = fips_dispatch_table;
115     return 1;
116 }
117
118 OSSL_provider_init_fn fips_intern_provider_init;
119 int fips_intern_provider_init(const OSSL_PROVIDER *provider,
120                               const OSSL_DISPATCH *in,
121                               const OSSL_DISPATCH **out)
122 {
123     /*
124      * The internal init function used when the FIPS module uses EVP to call
125      * another algorithm also in the FIPS module.
126      */
127     return 1;
128 }
129
130 void ERR_put_error(int lib, int func, int reason, const char *file, int line)
131 {
132     /*
133      * TODO(3.0): This works for the FIPS module because we're going to be
134      * using lib/func/reason codes that libcrypto already knows about. This
135      * won't work for third party providers that have their own error mechanisms,
136      * so we'll need to come up with something else for them.
137      */
138     c_put_error(lib, func, reason, file, line);
139 }
140
141 void ERR_add_error_data(int num, ...)
142 {
143     va_list args;
144     va_start(args, num);
145     ERR_add_error_vdata(num, args);
146     va_end(args);
147 }
148
149 void ERR_add_error_vdata(int num, va_list args)
150 {
151     c_add_error_vdata(num, args);
152 }