1FIPS_MODULE_INDICATORS(7ossl) OpenSSL FIPS_MODULE_INDICATORS(7ossl)
2
3
4
6 fips_module_indicators - Red Hat OpenSSL FIPS module indicators guide
7
9 This guide documents how the Red Hat Enterprise Linux 9 OpenSSL FIPS
10 provider implements Approved Security Service Indicators according to
11 the FIPS 140-3 Implementation Guidelines, section 2.4.C. See
12 <https://csrc.nist.gov/CSRC/media/Projects/cryptographic-module-validation-program/documents/fips%20140-3/FIPS%20140-3%20IG.pdf>
13 for the FIPS 140-3 Implementation Guidelines.
14
15 For all approved services except signatures, the Red Hat OpenSSL FIPS
16 provider uses the return code as the indicator as understood by FIPS
17 140-3. That means that every operation that succeeds denotes use of an
18 approved security service. Operations that do not succeed may not have
19 been approved security services, or may have been used incorrectly.
20
21 For signatures, an explicit indicator API is available to determine
22 whether a selected operation is an approved security service, in
23 combination with the return code of the operation. For a signature
24 operation to be approved, the explicit indicator must claim it as
25 approved, and it must succeed.
26
27 Querying the explicit indicator
28 The Red Hat OpenSSL FIPS provider exports a symbol named
29 redhat_ossl_query_fipsindicator that provides information on which
30 signature operations are approved security functions. To use this
31 function, either link against fips.so directly, or load it at runtime
32 using dlopen(3) and dlsym(3).
33
34 #include <openssl/core_dispatch.h>
35 #include "providers/fips/indicator.h"
36
37 void *provider = dlopen("/usr/lib64/ossl-modules/fips.so", RTLD_LAZY);
38 if (provider == NULL) {
39 fprintf(stderr, "%s\n", dlerror());
40 // handle error
41 }
42
43 const OSSL_RH_FIPSINDICATOR_ALORITHM *(*redhat_ossl_query_fipsindicator)(int) \
44 = dlsym(provider, "redhat_ossl_query_fipsindicator");
45 if (redhat_ossl_query_fipsindicator == NULL) {
46 fprintf(stderr, "%s\n", dlerror());
47 fprintf(stderr, "Does your copy of fips.so have the required Red Hat"
48 " patches?\n");
49 // handle error
50 }
51
52 Note that this uses the providers/fips/indicator.h header, which is not
53 public. Install the openssl-debugsource package from the BaseOS-
54 debuginfo repository using dnf debuginfo-install openssl and include
55 /usr/src/debug/openssl-3.*/ in the compiler's include path.
56
57 redhat_ossl_query_fipsindicator expects an operation ID as its only
58 argument. Currently, the only supported operation ID is
59 OSSL_OP_SIGNATURE to obtain the indicators for signature operations. On
60 success, the return value is a pointer to an array of
61 OSSL_RH_FIPSINDICATOR_STRUCTs. On failure, NULL is returned. The last
62 entry in the array is indicated by algorithm_names being NULL.
63
64 typedef struct ossl_rh_fipsindicator_algorithm_st {
65 const char *algorithm_names; /* key */
66 const char *property_definition; /* key */
67 const OSSL_RH_FIPSINDICATOR_DISPATCH *indicators;
68 } OSSL_RH_FIPSINDICATOR_ALGORITHM;
69
70 typedef struct ossl_rh_fipsindicator_dispatch_st {
71 int function_id;
72 int approved;
73 } OSSL_RH_FIPSINDICATOR_DISPATCH;
74
75 The algorithm_names field is a colon-separated list of algorithm names
76 from one of the PROV_NAMES_... constants, e.g., PROV_NAMES_RSA.
77 strtok(3) can be used to locate the appropriate entry. See the example
78 below, where algorithm contains the algorithm name to search for:
79
80 const OSSL_RH_FIPSINDICATOR_DISPATCH *indicator_dispatch = NULL;
81 const OSSL_RH_FIPSINDICATOR_ALGORITHM *indicator =
82 redhat_ossl_query_fipsindicator(operation_id);
83 if (indicator == NULL) {
84 fprintf(stderr, "No indicator for operation, probably using implicit"
85 " indicators.\n");
86 // handle error
87 }
88
89 for (; indicator->algorithm_names != NULL; ++indicator) {
90 char *algorithm_names = strdup(indicator->algorithm_names);
91 if (algorithm_names == NULL) {
92 perror("strdup(3)");
93 // handle error
94 }
95
96 const char *algorithm_name = strtok(algorithm_names, ":");
97 for (; algorithm_name != NULL; algorithm_name = strtok(NULL, ":")) {
98 if (strcasecmp(algorithm_name, algorithm) == 0) {
99 indicator_dispatch = indicator->indicators;
100 free(algorithm_names);
101 algorithm_names = NULL;
102 break;
103 }
104 }
105 free(algorithm_names);
106 }
107 if (indicator_dispatch == NULL) {
108 fprintf(stderr, "No indicator for algorithm %s.\n", algorithm);
109 // handle error
110 }
111
112 If an appropriate OSSL_RH_FIPSINDICATOR_DISPATCH array is available for
113 the given algorithm name, it maps function IDs to their approval
114 status. The last entry is indicated by a zero function_id. approved is
115 OSSL_RH_FIPSINDICATOR_APPROVED if the operation is an approved security
116 service, or part of an approved security service, or
117 OSSL_RH_FIPSINDICATOR_UNAPPROVED otherwise. Any other value is invalid.
118 Function IDs are OSSL_FUNC_* constants from openssl/core_dispatch.h,
119 e.g., OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE or
120 OSSL_FUNC_SIGNATURE_SIGN.
121
122 Assuming function_id is the function in question, the following code
123 can be used to query the approval status:
124
125 for (; indicator_dispatch->function_id != 0; ++indicator_dispatch) {
126 if (indicator_dispatch->function_id == function_id) {
127 switch (indicator_dispatch->approved) {
128 case OSSL_RH_FIPSINDICATOR_APPROVED:
129 // approved security service
130 break;
131 case OSSL_RH_FIPSINDICATOR_UNAPPROVED:
132 // unapproved security service
133 break;
134 default:
135 // invalid result
136 break;
137 }
138 break;
139 }
140 }
141
143 fips_module(7), provider(7)
144
146 Copyright 2022 Red Hat, Inc. All Rights Reserved.
147
148 Licensed under the Apache License 2.0 (the "License"). You may not use
149 this file except in compliance with the License. You can obtain a copy
150 in the file LICENSE in the source distribution or at
151 <https://www.openssl.org/source/license.html>.
152
153
154
1553.1.1 2023-08-31 FIPS_MODULE_INDICATORS(7ossl)