1 |
jpp |
1.1 |
From e3d6fca1af033d00c47bcd8f9ba28fcf1aa476aa Mon Sep 17 00:00:00 2001 |
2 |
|
|
From: Clemens Lang <cllang@redhat.com> |
3 |
|
|
Date: Tue, 7 Jun 2022 12:02:49 +0200 |
4 |
|
|
Subject: [PATCH] fips: Expose a FIPS indicator |
5 |
|
|
|
6 |
|
|
FIPS 140-3 requires us to indicate whether an operation was using |
7 |
|
|
approved services or not. The FIPS 140-3 implementation guidelines |
8 |
|
|
provide two basic approaches to doing this: implicit indicators, and |
9 |
|
|
explicit indicators. |
10 |
|
|
|
11 |
|
|
Implicit indicators are basically the concept of "if the operation |
12 |
|
|
passes, it was approved". We were originally aiming for implicit |
13 |
|
|
indicators in our copy of OpenSSL. However, this proved to be a problem, |
14 |
|
|
because we wanted to certify a signature service, and FIPS 140-3 |
15 |
|
|
requires that a signature service computes the digest to be signed |
16 |
|
|
within the boundaries of the FIPS module. Since we were planning to |
17 |
|
|
certify fips.so only, this means that EVP_PKEY_sign/EVP_PKEY_verify |
18 |
|
|
would have to be blocked. Unfortunately, EVP_SignFinal uses |
19 |
|
|
EVP_PKEY_sign internally, but outside of fips.so and thus outside of the |
20 |
|
|
FIPS module boundary. This means that using implicit indicators in |
21 |
|
|
combination with certifying only fips.so would require us to block both |
22 |
|
|
EVP_PKEY_sign and EVP_SignFinal, which are the two APIs currently used |
23 |
|
|
by most users of OpenSSL for signatures. |
24 |
|
|
|
25 |
|
|
EVP_DigestSign would be acceptable, but has only been added in 3.0 and |
26 |
|
|
is thus not yet widely used. |
27 |
|
|
|
28 |
|
|
As a consequence, we've decided to introduce explicit indicators so that |
29 |
|
|
EVP_PKEY_sign and EVP_SignFinal can continue to work for now, but |
30 |
|
|
FIPS-aware applications can query the explicit indicator to check |
31 |
|
|
whether the operation was approved. |
32 |
|
|
|
33 |
|
|
To avoid affecting the ABI and public API too much, this is implemented |
34 |
|
|
as an exported symbol in fips.so and a private header, so applications |
35 |
|
|
that wish to use this will have to dlopen(3) fips.so, locate the |
36 |
|
|
function using dlsym(3), and then call it. These applications will have |
37 |
|
|
to build against the private header in order to use the returned |
38 |
|
|
pointer. |
39 |
|
|
|
40 |
|
|
Modify util/mkdef.pl to support exposing a symbol only for a specific |
41 |
|
|
provider identified by its name and path. |
42 |
|
|
|
43 |
|
|
Signed-off-by: Clemens Lang <cllang@redhat.com> |
44 |
|
|
--- |
45 |
|
|
doc/build.info | 6 ++ |
46 |
|
|
doc/man7/fips_module_indicators.pod | 154 ++++++++++++++++++++++++++++ |
47 |
|
|
providers/fips/fipsprov.c | 71 +++++++++++++ |
48 |
|
|
providers/fips/indicator.h | 66 ++++++++++++ |
49 |
|
|
util/mkdef.pl | 25 ++++- |
50 |
|
|
util/providers.num | 1 + |
51 |
|
|
6 files changed, 322 insertions(+), 1 deletion(-) |
52 |
|
|
create mode 100644 doc/man7/fips_module_indicators.pod |
53 |
|
|
create mode 100644 providers/fips/indicator.h |
54 |
|
|
|
55 |
|
|
diff --git a/doc/build.info b/doc/build.info |
56 |
|
|
index b0aa4297a4..af235113bb 100644 |
57 |
|
|
--- a/doc/build.info |
58 |
|
|
+++ b/doc/build.info |
59 |
|
|
@@ -4389,6 +4389,10 @@ DEPEND[html/man7/fips_module.html]=man7/fips_module.pod |
60 |
|
|
GENERATE[html/man7/fips_module.html]=man7/fips_module.pod |
61 |
|
|
DEPEND[man/man7/fips_module.7]=man7/fips_module.pod |
62 |
|
|
GENERATE[man/man7/fips_module.7]=man7/fips_module.pod |
63 |
|
|
+DEPEND[html/man7/fips_module_indicators.html]=man7/fips_module_indicators.pod |
64 |
|
|
+GENERATE[html/man7/fips_module_indicators.html]=man7/fips_module_indicators.pod |
65 |
|
|
+DEPEND[man/man7/fips_module_indicators.7]=man7/fips_module_indicators.pod |
66 |
|
|
+GENERATE[man/man7/fips_module_indicators.7]=man7/fips_module_indicators.pod |
67 |
|
|
DEPEND[html/man7/life_cycle-cipher.html]=man7/life_cycle-cipher.pod |
68 |
|
|
GENERATE[html/man7/life_cycle-cipher.html]=man7/life_cycle-cipher.pod |
69 |
|
|
DEPEND[man/man7/life_cycle-cipher.7]=man7/life_cycle-cipher.pod |
70 |
|
|
@@ -4631,6 +4635,7 @@ html/man7/ct.html \ |
71 |
|
|
html/man7/des_modes.html \ |
72 |
|
|
html/man7/evp.html \ |
73 |
|
|
html/man7/fips_module.html \ |
74 |
|
|
+html/man7/fips_module_indicators.html \ |
75 |
|
|
html/man7/life_cycle-cipher.html \ |
76 |
|
|
html/man7/life_cycle-digest.html \ |
77 |
|
|
html/man7/life_cycle-kdf.html \ |
78 |
|
|
@@ -4754,6 +4759,7 @@ man/man7/ct.7 \ |
79 |
|
|
man/man7/des_modes.7 \ |
80 |
|
|
man/man7/evp.7 \ |
81 |
|
|
man/man7/fips_module.7 \ |
82 |
|
|
+man/man7/fips_module_indicators.7 \ |
83 |
|
|
man/man7/life_cycle-cipher.7 \ |
84 |
|
|
man/man7/life_cycle-digest.7 \ |
85 |
|
|
man/man7/life_cycle-kdf.7 \ |
86 |
|
|
diff --git a/doc/man7/fips_module_indicators.pod b/doc/man7/fips_module_indicators.pod |
87 |
|
|
new file mode 100644 |
88 |
|
|
index 0000000000..23db2b395c |
89 |
|
|
--- /dev/null |
90 |
|
|
+++ b/doc/man7/fips_module_indicators.pod |
91 |
|
|
@@ -0,0 +1,154 @@ |
92 |
|
|
+=pod |
93 |
|
|
+ |
94 |
|
|
+=head1 NAME |
95 |
|
|
+ |
96 |
|
|
+fips_module_indicators - Red Hat OpenSSL FIPS module indicators guide |
97 |
|
|
+ |
98 |
|
|
+=head1 DESCRIPTION |
99 |
|
|
+ |
100 |
|
|
+This guide documents how the Red Hat Enterprise Linux 9 OpenSSL FIPS provider |
101 |
|
|
+implements Approved Security Service Indicators according to the FIPS 140-3 |
102 |
|
|
+Implementation Guidelines, section 2.4.C. See |
103 |
|
|
+L<https://csrc.nist.gov/CSRC/media/Projects/cryptographic-module-validation-program/documents/fips%20140-3/FIPS%20140-3%20IG.pdf> |
104 |
|
|
+for the FIPS 140-3 Implementation Guidelines. |
105 |
|
|
+ |
106 |
|
|
+For all approved services except signatures, the Red Hat OpenSSL FIPS provider |
107 |
|
|
+uses the return code as the indicator as understood by FIPS 140-3. That means |
108 |
|
|
+that every operation that succeeds denotes use of an approved security service. |
109 |
|
|
+Operations that do not succeed may not have been approved security services, or |
110 |
|
|
+may have been used incorrectly. |
111 |
|
|
+ |
112 |
|
|
+For signatures, an explicit indicator API is available to determine whether |
113 |
|
|
+a selected operation is an approved security service, in combination with the |
114 |
|
|
+return code of the operation. For a signature operation to be approved, the |
115 |
|
|
+explicit indicator must claim it as approved, and it must succeed. |
116 |
|
|
+ |
117 |
|
|
+=head2 Querying the explicit indicator |
118 |
|
|
+ |
119 |
|
|
+The Red Hat OpenSSL FIPS provider exports a symbol named |
120 |
|
|
+I<redhat_ossl_query_fipsindicator> that provides information on which signature |
121 |
|
|
+operations are approved security functions. To use this function, either link |
122 |
|
|
+against I<fips.so> directly, or load it at runtime using dlopen(3) and |
123 |
|
|
+dlsym(3). |
124 |
|
|
+ |
125 |
|
|
+ #include <openssl/core_dispatch.h> |
126 |
|
|
+ #include "providers/fips/indicator.h" |
127 |
|
|
+ |
128 |
|
|
+ void *provider = dlopen("/usr/lib64/ossl-modules/fips.so", RTLD_LAZY); |
129 |
|
|
+ if (provider == NULL) { |
130 |
|
|
+ fprintf(stderr, "%s\n", dlerror()); |
131 |
|
|
+ // handle error |
132 |
|
|
+ } |
133 |
|
|
+ |
134 |
|
|
+ const OSSL_RH_FIPSINDICATOR_ALORITHM *(*redhat_ossl_query_fipsindicator)(int) \ |
135 |
|
|
+ = dlsym(provider, "redhat_ossl_query_fipsindicator"); |
136 |
|
|
+ if (redhat_ossl_query_fipsindicator == NULL) { |
137 |
|
|
+ fprintf(stderr, "%s\n", dlerror()); |
138 |
|
|
+ fprintf(stderr, "Does your copy of fips.so have the required Red Hat" |
139 |
|
|
+ " patches?\n"); |
140 |
|
|
+ // handle error |
141 |
|
|
+ } |
142 |
|
|
+ |
143 |
|
|
+Note that this uses the I<providers/fips/indicator.h> header, which is not |
144 |
|
|
+public. Install the I<openssl-debugsource> package from the I<BaseOS-debuginfo> |
145 |
|
|
+repository using I<dnf debuginfo-install openssl> and include |
146 |
|
|
+I</usr/src/debug/openssl-3.*/> in the compiler's include path. |
147 |
|
|
+ |
148 |
|
|
+I<redhat_ossl_query_fipsindicator> expects an operation ID as its only |
149 |
|
|
+argument. Currently, the only supported operation ID is I<OSSL_OP_SIGNATURE> to |
150 |
|
|
+obtain the indicators for signature operations. On success, the return value is |
151 |
|
|
+a pointer to an array of I<OSSL_RH_FIPSINDICATOR_STRUCT>s. On failure, NULL is |
152 |
|
|
+returned. The last entry in the array is indicated by I<algorithm_names> being |
153 |
|
|
+NULL. |
154 |
|
|
+ |
155 |
|
|
+ typedef struct ossl_rh_fipsindicator_algorithm_st { |
156 |
|
|
+ const char *algorithm_names; /* key */ |
157 |
|
|
+ const char *property_definition; /* key */ |
158 |
|
|
+ const OSSL_RH_FIPSINDICATOR_DISPATCH *indicators; |
159 |
|
|
+ } OSSL_RH_FIPSINDICATOR_ALGORITHM; |
160 |
|
|
+ |
161 |
|
|
+ typedef struct ossl_rh_fipsindicator_dispatch_st { |
162 |
|
|
+ int function_id; |
163 |
|
|
+ int approved; |
164 |
|
|
+ } OSSL_RH_FIPSINDICATOR_DISPATCH; |
165 |
|
|
+ |
166 |
|
|
+The I<algorithm_names> field is a colon-separated list of algorithm names from |
167 |
|
|
+one of the I<PROV_NAMES_...> constants, e.g., I<PROV_NAMES_RSA>. strtok(3) can |
168 |
|
|
+be used to locate the appropriate entry. See the example below, where |
169 |
|
|
+I<algorithm> contains the algorithm name to search for: |
170 |
|
|
+ |
171 |
|
|
+ const OSSL_RH_FIPSINDICATOR_DISPATCH *indicator_dispatch = NULL; |
172 |
|
|
+ const OSSL_RH_FIPSINDICATOR_ALGORITHM *indicator = |
173 |
|
|
+ redhat_ossl_query_fipsindicator(operation_id); |
174 |
|
|
+ if (indicator == NULL) { |
175 |
|
|
+ fprintf(stderr, "No indicator for operation, probably using implicit" |
176 |
|
|
+ " indicators.\n"); |
177 |
|
|
+ // handle error |
178 |
|
|
+ } |
179 |
|
|
+ |
180 |
|
|
+ for (; indicator->algorithm_names != NULL; ++indicator) { |
181 |
|
|
+ char *algorithm_names = strdup(indicator->algorithm_names); |
182 |
|
|
+ if (algorithm_names == NULL) { |
183 |
|
|
+ perror("strdup(3)"); |
184 |
|
|
+ // handle error |
185 |
|
|
+ } |
186 |
|
|
+ |
187 |
|
|
+ const char *algorithm_name = strtok(algorithm_names, ":"); |
188 |
|
|
+ for (; algorithm_name != NULL; algorithm_name = strtok(NULL, ":")) { |
189 |
|
|
+ if (strcasecmp(algorithm_name, algorithm) == 0) { |
190 |
|
|
+ indicator_dispatch = indicator->indicators; |
191 |
|
|
+ free(algorithm_names); |
192 |
|
|
+ algorithm_names = NULL; |
193 |
|
|
+ break; |
194 |
|
|
+ } |
195 |
|
|
+ } |
196 |
|
|
+ free(algorithm_names); |
197 |
|
|
+ } |
198 |
|
|
+ if (indicator_dispatch == NULL) { |
199 |
|
|
+ fprintf(stderr, "No indicator for algorithm %s.\n", algorithm); |
200 |
|
|
+ // handle error |
201 |
|
|
+ } |
202 |
|
|
+ |
203 |
|
|
+If an appropriate I<OSSL_RH_FIPSINDICATOR_DISPATCH> array is available for the |
204 |
|
|
+given algorithm name, it maps function IDs to their approval status. The last |
205 |
|
|
+entry is indicated by a zero I<function_id>. I<approved> is |
206 |
|
|
+I<OSSL_RH_FIPSINDICATOR_APPROVED> if the operation is an approved security |
207 |
|
|
+service, or part of an approved security service, or |
208 |
|
|
+I<OSSL_RH_FIPSINDICATOR_UNAPPROVED> otherwise. Any other value is invalid. |
209 |
|
|
+Function IDs are I<OSSL_FUNC_*> constants from I<openssl/core_dispatch.h>, |
210 |
|
|
+e.g., I<OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE> or I<OSSL_FUNC_SIGNATURE_SIGN>. |
211 |
|
|
+ |
212 |
|
|
+Assuming I<function_id> is the function in question, the following code can be |
213 |
|
|
+used to query the approval status: |
214 |
|
|
+ |
215 |
|
|
+ for (; indicator_dispatch->function_id != 0; ++indicator_dispatch) { |
216 |
|
|
+ if (indicator_dispatch->function_id == function_id) { |
217 |
|
|
+ switch (indicator_dispatch->approved) { |
218 |
|
|
+ case OSSL_RH_FIPSINDICATOR_APPROVED: |
219 |
|
|
+ // approved security service |
220 |
|
|
+ break; |
221 |
|
|
+ case OSSL_RH_FIPSINDICATOR_UNAPPROVED: |
222 |
|
|
+ // unapproved security service |
223 |
|
|
+ break; |
224 |
|
|
+ default: |
225 |
|
|
+ // invalid result |
226 |
|
|
+ break; |
227 |
|
|
+ } |
228 |
|
|
+ break; |
229 |
|
|
+ } |
230 |
|
|
+ } |
231 |
|
|
+ |
232 |
|
|
+=head1 SEE ALSO |
233 |
|
|
+ |
234 |
|
|
+L<fips_module(7)>, L<provider(7)> |
235 |
|
|
+ |
236 |
|
|
+=head1 COPYRIGHT |
237 |
|
|
+ |
238 |
|
|
+Copyright 2022 Red Hat, Inc. All Rights Reserved. |
239 |
|
|
+ |
240 |
|
|
+Licensed under the Apache License 2.0 (the "License"). You may not use |
241 |
|
|
+this file except in compliance with the License. You can obtain a copy |
242 |
|
|
+in the file LICENSE in the source distribution or at |
243 |
|
|
+L<https://www.openssl.org/source/license.html>. |
244 |
|
|
+ |
245 |
|
|
+=cut |
246 |
|
|
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c |
247 |
|
|
index de391ce067..1cfd71c5cf 100644 |
248 |
|
|
--- a/providers/fips/fipsprov.c |
249 |
|
|
+++ b/providers/fips/fipsprov.c |
250 |
|
|
@@ -23,6 +23,7 @@ |
251 |
|
|
#include "prov/seeding.h" |
252 |
|
|
#include "self_test.h" |
253 |
|
|
#include "internal/core.h" |
254 |
|
|
+#include "indicator.h" |
255 |
|
|
|
256 |
|
|
static const char FIPS_DEFAULT_PROPERTIES[] = "provider=fips,fips=yes"; |
257 |
|
|
static const char FIPS_UNAPPROVED_PROPERTIES[] = "provider=fips,fips=no"; |
258 |
|
|
@@ -425,6 +426,68 @@ static const OSSL_ALGORITHM fips_signature[] = { |
259 |
|
|
{ NULL, NULL, NULL } |
260 |
|
|
}; |
261 |
|
|
|
262 |
|
|
+static const OSSL_RH_FIPSINDICATOR_DISPATCH redhat_rsa_signature_indicators[] = { |
263 |
|
|
+ { OSSL_FUNC_SIGNATURE_NEWCTX, OSSL_RH_FIPSINDICATOR_APPROVED }, |
264 |
|
|
+ { OSSL_FUNC_SIGNATURE_SIGN_INIT, OSSL_RH_FIPSINDICATOR_UNAPPROVED }, |
265 |
|
|
+ { OSSL_FUNC_SIGNATURE_SIGN, OSSL_RH_FIPSINDICATOR_UNAPPROVED }, |
266 |
|
|
+ { OSSL_FUNC_SIGNATURE_VERIFY_INIT, OSSL_RH_FIPSINDICATOR_UNAPPROVED }, |
267 |
|
|
+ { OSSL_FUNC_SIGNATURE_VERIFY, OSSL_RH_FIPSINDICATOR_UNAPPROVED }, |
268 |
|
|
+ { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT, OSSL_RH_FIPSINDICATOR_UNAPPROVED }, |
269 |
|
|
+ { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER, OSSL_RH_FIPSINDICATOR_UNAPPROVED }, |
270 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, OSSL_RH_FIPSINDICATOR_APPROVED }, |
271 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, OSSL_RH_FIPSINDICATOR_APPROVED }, |
272 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, OSSL_RH_FIPSINDICATOR_APPROVED }, |
273 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, OSSL_RH_FIPSINDICATOR_APPROVED }, |
274 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, OSSL_RH_FIPSINDICATOR_APPROVED }, |
275 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, OSSL_RH_FIPSINDICATOR_APPROVED }, |
276 |
|
|
+ { OSSL_FUNC_SIGNATURE_FREECTX, OSSL_RH_FIPSINDICATOR_APPROVED }, |
277 |
|
|
+ { OSSL_FUNC_SIGNATURE_DUPCTX, OSSL_RH_FIPSINDICATOR_APPROVED }, |
278 |
|
|
+ { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
279 |
|
|
+ { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
280 |
|
|
+ { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
281 |
|
|
+ { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
282 |
|
|
+ { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
283 |
|
|
+ { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
284 |
|
|
+ { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
285 |
|
|
+ { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
286 |
|
|
+ { 0, OSSL_RH_FIPSINDICATOR_UNAPPROVED } |
287 |
|
|
+}; |
288 |
|
|
+ |
289 |
|
|
+static const OSSL_RH_FIPSINDICATOR_DISPATCH redhat_ecdsa_signature_indicators[] = { |
290 |
|
|
+ { OSSL_FUNC_SIGNATURE_NEWCTX, OSSL_RH_FIPSINDICATOR_APPROVED }, |
291 |
|
|
+ { OSSL_FUNC_SIGNATURE_SIGN_INIT, OSSL_RH_FIPSINDICATOR_UNAPPROVED }, |
292 |
|
|
+ { OSSL_FUNC_SIGNATURE_SIGN, OSSL_RH_FIPSINDICATOR_UNAPPROVED }, |
293 |
|
|
+ { OSSL_FUNC_SIGNATURE_VERIFY_INIT, OSSL_RH_FIPSINDICATOR_UNAPPROVED }, |
294 |
|
|
+ { OSSL_FUNC_SIGNATURE_VERIFY, OSSL_RH_FIPSINDICATOR_UNAPPROVED }, |
295 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, OSSL_RH_FIPSINDICATOR_APPROVED }, |
296 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, OSSL_RH_FIPSINDICATOR_APPROVED }, |
297 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, OSSL_RH_FIPSINDICATOR_APPROVED }, |
298 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, OSSL_RH_FIPSINDICATOR_APPROVED }, |
299 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, OSSL_RH_FIPSINDICATOR_APPROVED }, |
300 |
|
|
+ { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, OSSL_RH_FIPSINDICATOR_APPROVED }, |
301 |
|
|
+ { OSSL_FUNC_SIGNATURE_FREECTX, OSSL_RH_FIPSINDICATOR_APPROVED }, |
302 |
|
|
+ { OSSL_FUNC_SIGNATURE_DUPCTX, OSSL_RH_FIPSINDICATOR_APPROVED }, |
303 |
|
|
+ { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
304 |
|
|
+ { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
305 |
|
|
+ { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
306 |
|
|
+ { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
307 |
|
|
+ { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
308 |
|
|
+ { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
309 |
|
|
+ { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
310 |
|
|
+ { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED }, |
311 |
|
|
+ { 0, OSSL_RH_FIPSINDICATOR_UNAPPROVED } |
312 |
|
|
+}; |
313 |
|
|
+ |
314 |
|
|
+static const OSSL_RH_FIPSINDICATOR_ALGORITHM redhat_indicator_fips_signature[] = { |
315 |
|
|
+ { PROV_NAMES_RSA, FIPS_DEFAULT_PROPERTIES, |
316 |
|
|
+ redhat_rsa_signature_indicators }, |
317 |
|
|
+#ifndef OPENSSL_NO_EC |
318 |
|
|
+ { PROV_NAMES_ECDSA, FIPS_DEFAULT_PROPERTIES, |
319 |
|
|
+ redhat_ecdsa_signature_indicators }, |
320 |
|
|
+#endif |
321 |
|
|
+ { NULL, NULL, NULL } |
322 |
|
|
+}; |
323 |
|
|
+ |
324 |
|
|
static const OSSL_ALGORITHM fips_asym_cipher[] = { |
325 |
|
|
{ PROV_NAMES_RSA, FIPS_DEFAULT_PROPERTIES, ossl_rsa_asym_cipher_functions }, |
326 |
|
|
{ NULL, NULL, NULL } |
327 |
|
|
@@ -527,6 +590,14 @@ static void fips_deinit_casecmp(void) { |
328 |
|
|
return NULL; |
329 |
|
|
} |
330 |
|
|
|
331 |
|
|
+const OSSL_RH_FIPSINDICATOR_ALGORITHM *redhat_ossl_query_fipsindicator(int operation_id) { |
332 |
|
|
+ switch (operation_id) { |
333 |
|
|
+ case OSSL_OP_SIGNATURE: |
334 |
|
|
+ return redhat_indicator_fips_signature; |
335 |
|
|
+ } |
336 |
|
|
+ return NULL; |
337 |
|
|
+} |
338 |
|
|
+ |
339 |
|
|
static void fips_teardown(void *provctx) |
340 |
|
|
{ |
341 |
|
|
OSSL_LIB_CTX_free(PROV_LIBCTX_OF(provctx)); |
342 |
|
|
diff --git a/providers/fips/indicator.h b/providers/fips/indicator.h |
343 |
|
|
new file mode 100644 |
344 |
|
|
index 0000000000..b323efe44c |
345 |
|
|
--- /dev/null |
346 |
|
|
+++ b/providers/fips/indicator.h |
347 |
|
|
@@ -0,0 +1,66 @@ |
348 |
|
|
+/* |
349 |
|
|
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
350 |
|
|
+ * |
351 |
|
|
+ * Licensed under the Apache License 2.0 (the "License"). You may not use |
352 |
|
|
+ * this file except in compliance with the License. You can obtain a copy |
353 |
|
|
+ * in the file LICENSE in the source distribution or at |
354 |
|
|
+ * https://www.openssl.org/source/license.html |
355 |
|
|
+ */ |
356 |
|
|
+ |
357 |
|
|
+#ifndef OPENSSL_FIPS_INDICATOR_H |
358 |
|
|
+# define OPENSSL_FIPS_INDICATOR_H |
359 |
|
|
+# pragma once |
360 |
|
|
+ |
361 |
|
|
+# ifdef __cplusplus |
362 |
|
|
+extern "C" { |
363 |
|
|
+# endif |
364 |
|
|
+ |
365 |
|
|
+# define OSSL_RH_FIPSINDICATOR_UNAPPROVED (0) |
366 |
|
|
+# define OSSL_RH_FIPSINDICATOR_APPROVED (1) |
367 |
|
|
+ |
368 |
|
|
+/* |
369 |
|
|
+ * FIPS indicator dispatch table element. function_id numbers and the |
370 |
|
|
+ * functions are defined in core_dispatch.h, see macros with |
371 |
|
|
+ * 'OSSL_CORE_MAKE_FUNC' in their names. |
372 |
|
|
+ * |
373 |
|
|
+ * An array of these is always terminated by function_id == 0 |
374 |
|
|
+ */ |
375 |
|
|
+typedef struct ossl_rh_fipsindicator_dispatch_st { |
376 |
|
|
+ int function_id; |
377 |
|
|
+ int approved; |
378 |
|
|
+} OSSL_RH_FIPSINDICATOR_DISPATCH; |
379 |
|
|
+ |
380 |
|
|
+/* |
381 |
|
|
+ * Type to tie together algorithm names, property definition string and the |
382 |
|
|
+ * algorithm implementation's FIPS indicator status in the form of a FIPS |
383 |
|
|
+ * indicator dispatch table. |
384 |
|
|
+ * |
385 |
|
|
+ * An array of these is always terminated by algorithm_names == NULL |
386 |
|
|
+ */ |
387 |
|
|
+typedef struct ossl_rh_fipsindicator_algorithm_st { |
388 |
|
|
+ const char *algorithm_names; /* key */ |
389 |
|
|
+ const char *property_definition; /* key */ |
390 |
|
|
+ const OSSL_RH_FIPSINDICATOR_DISPATCH *indicators; |
391 |
|
|
+} OSSL_RH_FIPSINDICATOR_ALGORITHM; |
392 |
|
|
+ |
393 |
|
|
+/** |
394 |
|
|
+ * Query FIPS indicator status for the given operation. Possible values for |
395 |
|
|
+ * 'operation_id' are currently only OSSL_OP_SIGNATURE, as all other algorithms |
396 |
|
|
+ * use implicit indicators. The return value is an array of |
397 |
|
|
+ * OSSL_RH_FIPSINDICATOR_ALGORITHMs, terminated by an entry with |
398 |
|
|
+ * algorithm_names == NULL. 'algorithm_names' is a colon-separated list of |
399 |
|
|
+ * algorithm names, 'property_definition' a comma-separated list of properties, |
400 |
|
|
+ * and 'indicators' is a list of OSSL_RH_FIPSINDICATOR_DISPATCH structs. This |
401 |
|
|
+ * list is terminated by function_id == 0. 'function_id' is one of the |
402 |
|
|
+ * OSSL_FUNC_* constants, e.g., OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL. |
403 |
|
|
+ * |
404 |
|
|
+ * If there is no entry in the returned struct for the given operation_id, |
405 |
|
|
+ * algorithm name, or function_id, the algorithm is unapproved. |
406 |
|
|
+ */ |
407 |
|
|
+const OSSL_RH_FIPSINDICATOR_ALGORITHM *redhat_ossl_query_fipsindicator(int operation_id); |
408 |
|
|
+ |
409 |
|
|
+# ifdef __cplusplus |
410 |
|
|
+} |
411 |
|
|
+# endif |
412 |
|
|
+ |
413 |
|
|
+#endif |
414 |
|
|
diff --git a/util/mkdef.pl b/util/mkdef.pl |
415 |
|
|
index a1c76f7c97..eda39b71ee 100755 |
416 |
|
|
--- a/util/mkdef.pl |
417 |
|
|
+++ b/util/mkdef.pl |
418 |
|
|
@@ -149,7 +149,8 @@ $ordinal_opts{filter} = |
419 |
|
|
return |
420 |
|
|
$item->exists() |
421 |
|
|
&& platform_filter($item) |
422 |
|
|
- && feature_filter($item); |
423 |
|
|
+ && feature_filter($item) |
424 |
|
|
+ && fips_filter($item, $name); |
425 |
|
|
}; |
426 |
|
|
my $ordinals = OpenSSL::Ordinals->new(from => $ordinals_file); |
427 |
|
|
|
428 |
|
|
@@ -205,6 +206,28 @@ sub feature_filter { |
429 |
|
|
return $verdict; |
430 |
|
|
} |
431 |
|
|
|
432 |
|
|
+sub fips_filter { |
433 |
|
|
+ my $item = shift; |
434 |
|
|
+ my $name = uc(shift); |
435 |
|
|
+ my @features = ( $item->features() ); |
436 |
|
|
+ |
437 |
|
|
+ # True if no features are defined |
438 |
|
|
+ return 1 if scalar @features == 0; |
439 |
|
|
+ |
440 |
|
|
+ my @matches = grep(/^ONLY_.*$/, @features); |
441 |
|
|
+ if (@matches) { |
442 |
|
|
+ # There is at least one only_* flag on this symbol, check if any of |
443 |
|
|
+ # them match the name |
444 |
|
|
+ for (@matches) { |
445 |
|
|
+ if ($_ eq "ONLY_${name}") { |
446 |
|
|
+ return 1; |
447 |
|
|
+ } |
448 |
|
|
+ } |
449 |
|
|
+ return 0; |
450 |
|
|
+ } |
451 |
|
|
+ return 1; |
452 |
|
|
+} |
453 |
|
|
+ |
454 |
|
|
sub sorter_unix { |
455 |
|
|
my $by_name = OpenSSL::Ordinals::by_name(); |
456 |
|
|
my %weight = ( |
457 |
|
|
diff --git a/util/providers.num b/util/providers.num |
458 |
|
|
index 4e2fa81b98..77879d0e5f 100644 |
459 |
|
|
--- a/util/providers.num |
460 |
|
|
+++ b/util/providers.num |
461 |
|
|
@@ -1 +1,2 @@ |
462 |
|
|
OSSL_provider_init 1 * EXIST::FUNCTION: |
463 |
|
|
+redhat_ossl_query_fipsindicator 1 * EXIST::FUNCTION:ONLY_PROVIDERS/FIPS |
464 |
|
|
-- |
465 |
|
|
2.35.3 |
466 |
|
|
|