/src/boringssl/crypto/fipsmodule/bcm_interface.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2024, Google Inc. |
2 | | * |
3 | | * Permission to use, copy, modify, and/or distribute this software for any |
4 | | * purpose with or without fee is hereby granted, provided that the above |
5 | | * copyright notice and this permission notice appear in all copies. |
6 | | * |
7 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
8 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
9 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
10 | | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
11 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
12 | | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
13 | | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ |
14 | | |
15 | | #ifndef OPENSSL_HEADER_CRYPTO_BCM_INTERFACE_H |
16 | | #define OPENSSL_HEADER_CRYPTO_BCM_INTERFACE_H |
17 | | |
18 | | #include <openssl/bcm_public.h> |
19 | | |
20 | | // This header will eventually become the interface between BCM and the |
21 | | // rest of libcrypto. More cleanly separating the two is still a work in |
22 | | // progress (see https://crbug.com/boringssl/722) so, at the moment, we |
23 | | // consider this no different from any other header in BCM. |
24 | | // |
25 | | // Over time, calls from libcrypto to BCM will all move to this header |
26 | | // and the separation will become more meaningful. |
27 | | |
28 | | #if defined(__cplusplus) |
29 | | extern "C" { |
30 | | #endif |
31 | | |
32 | | // Enumerated types for return values from bcm functions, both infallible |
33 | | // and fallible functions. Two success values are used to correspond to the |
34 | | // FIPS service indicator. For the moment, the official service indicator |
35 | | // remains the counter, not these values. Once we fully transition to |
36 | | // these return values from bcm we will change that. |
37 | | enum bcm_infallible_t { |
38 | | bcm_infallible_approved, |
39 | | bcm_infallible_not_approved, |
40 | | }; |
41 | | |
42 | | enum bcm_status_t { |
43 | | bcm_status_approved, |
44 | | bcm_status_not_approved, |
45 | | |
46 | | // Failure codes, which must all be negative. |
47 | | bcm_status_failure, |
48 | | }; |
49 | | typedef enum bcm_status_t bcm_status; |
50 | | typedef enum bcm_infallible_t bcm_infallible; |
51 | | |
52 | 0 | OPENSSL_INLINE int bcm_success(bcm_status status) { |
53 | 0 | return status == bcm_status_approved || status == bcm_status_not_approved; |
54 | 0 | } Unexecuted instantiation: bcm.c:bcm_success Unexecuted instantiation: rand_extra.c:bcm_success Unexecuted instantiation: sha1.c:bcm_success Unexecuted instantiation: sha256.c:bcm_success Unexecuted instantiation: sha512.c:bcm_success |
55 | | |
56 | | |
57 | | // Random number generator. |
58 | | |
59 | | #if defined(BORINGSSL_FIPS) |
60 | | |
61 | | // We overread from /dev/urandom or RDRAND by a factor of 10 and XOR to whiten. |
62 | | // TODO(bbe): disentangle this value which is used to calculate the size of the |
63 | | // stack buffer in RAND_need entropy based on a calculation. |
64 | | #define BORINGSSL_FIPS_OVERREAD 10 |
65 | | |
66 | | #endif // BORINGSSL_FIPS |
67 | | |
68 | | // BCM_rand_load_entropy supplies |entropy_len| bytes of entropy to the BCM |
69 | | // module. The |want_additional_input| parameter is true iff the entropy was |
70 | | // obtained from a source other than the system, e.g. directly from the CPU. |
71 | | bcm_infallible BCM_rand_load_entropy(const uint8_t *entropy, size_t entropy_len, |
72 | | int want_additional_input); |
73 | | |
74 | | // BCM_rand_bytes is the same as the public |RAND_bytes| function, other |
75 | | // than returning a bcm_infallible status indicator. |
76 | | OPENSSL_EXPORT bcm_infallible BCM_rand_bytes(uint8_t *out, size_t out_len); |
77 | | |
78 | | // BCM_rand_bytes_hwrng attempts to fill |out| with |len| bytes of entropy from |
79 | | // the CPU hardware random number generator if one is present. |
80 | | // bcm_status_approved is returned on success, and a failure status is |
81 | | // returned otherwise. |
82 | | bcm_status BCM_rand_bytes_hwrng(uint8_t *out, size_t len); |
83 | | |
84 | | // BCM_rand_bytes_with_additional_data samples from the RNG after mixing 32 |
85 | | // bytes from |user_additional_data| in. |
86 | | bcm_infallible BCM_rand_bytes_with_additional_data( |
87 | | uint8_t *out, size_t out_len, const uint8_t user_additional_data[32]); |
88 | | |
89 | | |
90 | | // SHA-1 |
91 | | |
92 | | // BCM_SHA_DIGEST_LENGTH is the length of a SHA-1 digest. |
93 | 2 | #define BCM_SHA_DIGEST_LENGTH 20 |
94 | | |
95 | | // BCM_sha1_init initialises |sha|. |
96 | | bcm_infallible BCM_sha1_init(SHA_CTX *sha); |
97 | | |
98 | | // BCM_SHA1_transform is a low-level function that performs a single, SHA-1 |
99 | | // block transformation using the state from |sha| and |SHA_CBLOCK| bytes from |
100 | | // |block|. |
101 | | bcm_infallible BCM_sha1_transform(SHA_CTX *c, |
102 | | const uint8_t data[BCM_SHA_CBLOCK]); |
103 | | |
104 | | // BCM_sha1_update adds |len| bytes from |data| to |sha|. |
105 | | bcm_infallible BCM_sha1_update(SHA_CTX *c, const void *data, size_t len); |
106 | | |
107 | | // BCM_sha1_final adds the final padding to |sha| and writes the resulting |
108 | | // digest to |out|, which must have at least |SHA_DIGEST_LENGTH| bytes of space. |
109 | | bcm_infallible BCM_sha1_final(uint8_t out[BCM_SHA_DIGEST_LENGTH], SHA_CTX *c); |
110 | | |
111 | | |
112 | | // BCM_fips_186_2_prf derives |out_len| bytes from |xkey| using the PRF |
113 | | // defined in FIPS 186-2, Appendix 3.1, with change notice 1 applied. The b |
114 | | // parameter is 160 and seed, XKEY, is also 160 bits. The optional XSEED user |
115 | | // input is all zeros. |
116 | | // |
117 | | // The PRF generates a sequence of 320-bit numbers. Each number is encoded as a |
118 | | // 40-byte string in big-endian and then concatenated to form |out|. If |
119 | | // |out_len| is not a multiple of 40, the result is truncated. This matches the |
120 | | // construction used in Section 7 of RFC 4186 and Section 7 of RFC 4187. |
121 | | // |
122 | | // This PRF is based on SHA-1, a weak hash function, and should not be used |
123 | | // in new protocols. It is provided for compatibility with some legacy EAP |
124 | | // methods. |
125 | | bcm_infallible BCM_fips_186_2_prf(uint8_t *out, size_t out_len, |
126 | | const uint8_t xkey[BCM_SHA_DIGEST_LENGTH]); |
127 | | |
128 | | |
129 | | // SHA-224 |
130 | | |
131 | | // SHA224_DIGEST_LENGTH is the length of a SHA-224 digest. |
132 | 2.50k | #define BCM_SHA224_DIGEST_LENGTH 28 |
133 | | |
134 | | // BCM_sha224_unit initialises |sha|. |
135 | | bcm_infallible BCM_sha224_init(SHA256_CTX *sha); |
136 | | |
137 | | // BCM_sha224_update adds |len| bytes from |data| to |sha|. |
138 | | bcm_infallible BCM_sha224_update(SHA256_CTX *sha, const void *data, size_t len); |
139 | | |
140 | | // BCM_sha224_final adds the final padding to |sha| and writes the resulting |
141 | | // digest to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of |
142 | | // space. It aborts on programmer error. |
143 | | bcm_infallible BCM_sha224_final(uint8_t out[BCM_SHA224_DIGEST_LENGTH], |
144 | | SHA256_CTX *sha); |
145 | | |
146 | | |
147 | | // SHA-256 |
148 | | |
149 | | // BCM_SHA256_DIGEST_LENGTH is the length of a SHA-256 digest. |
150 | 792 | #define BCM_SHA256_DIGEST_LENGTH 32 |
151 | | |
152 | | // BCM_sha256_init initialises |sha|. |
153 | | bcm_infallible BCM_sha256_init(SHA256_CTX *sha); |
154 | | |
155 | | // BCM_sha256_update adds |len| bytes from |data| to |sha|. |
156 | | bcm_infallible BCM_sha256_update(SHA256_CTX *sha, const void *data, size_t len); |
157 | | |
158 | | // BCM_sha256_final adds the final padding to |sha| and writes the resulting |
159 | | // digest to |out|, which must have at least |BCM_SHA256_DIGEST_LENGTH| bytes of |
160 | | // space. It aborts on programmer error. |
161 | | bcm_infallible BCM_sha256_final(uint8_t out[BCM_SHA256_DIGEST_LENGTH], |
162 | | SHA256_CTX *sha); |
163 | | |
164 | | // BCM_sha256_transform is a low-level function that performs a single, SHA-256 |
165 | | // block transformation using the state from |sha| and |BCM_SHA256_CBLOCK| bytes |
166 | | // from |block|. |
167 | | bcm_infallible BCM_sha256_transform(SHA256_CTX *sha, |
168 | | const uint8_t block[BCM_SHA256_CBLOCK]); |
169 | | |
170 | | // BCM_sha256_transform_blocks is a low-level function that takes |num_blocks| * |
171 | | // |BCM_SHA256_CBLOCK| bytes of data and performs SHA-256 transforms on it to |
172 | | // update |state|. |
173 | | bcm_infallible BCM_sha256_transform_blocks(uint32_t state[8], |
174 | | const uint8_t *data, |
175 | | size_t num_blocks); |
176 | | |
177 | | |
178 | | // SHA-384. |
179 | | |
180 | | // BCM_SHA384_DIGEST_LENGTH is the length of a SHA-384 digest. |
181 | 2.41k | #define BCM_SHA384_DIGEST_LENGTH 48 |
182 | | |
183 | | // BCM_sha384_init initialises |sha|. |
184 | | bcm_infallible BCM_sha384_init(SHA512_CTX *sha); |
185 | | |
186 | | // BCM_sha384_update adds |len| bytes from |data| to |sha|. |
187 | | bcm_infallible BCM_sha384_update(SHA512_CTX *sha, const void *data, size_t len); |
188 | | |
189 | | // BCM_sha384_final adds the final padding to |sha| and writes the resulting |
190 | | // digest to |out|, which must have at least |BCM_sha384_DIGEST_LENGTH| bytes of |
191 | | // space. It may abort on programmer error. |
192 | | bcm_infallible BCM_sha384_final(uint8_t out[BCM_SHA384_DIGEST_LENGTH], |
193 | | SHA512_CTX *sha); |
194 | | |
195 | | |
196 | | // SHA-512. |
197 | | |
198 | | // BCM_SHA512_DIGEST_LENGTH is the length of a SHA-512 digest. |
199 | 347 | #define BCM_SHA512_DIGEST_LENGTH 64 |
200 | | |
201 | | // BCM_sha512_init initialises |sha|. |
202 | | bcm_infallible BCM_sha512_init(SHA512_CTX *sha); |
203 | | |
204 | | // BCM_sha512_update adds |len| bytes from |data| to |sha|. |
205 | | bcm_infallible BCM_sha512_update(SHA512_CTX *sha, const void *data, size_t len); |
206 | | |
207 | | // BCM_sha512_final adds the final padding to |sha| and writes the resulting |
208 | | // digest to |out|, which must have at least |BCM_sha512_DIGEST_LENGTH| bytes of |
209 | | // space. |
210 | | bcm_infallible BCM_sha512_final(uint8_t out[BCM_SHA512_DIGEST_LENGTH], |
211 | | SHA512_CTX *sha); |
212 | | |
213 | | // BCM_sha512_transform is a low-level function that performs a single, SHA-512 |
214 | | // block transformation using the state from |sha| and |BCM_sha512_CBLOCK| bytes |
215 | | // from |block|. |
216 | | bcm_infallible BCM_sha512_transform(SHA512_CTX *sha, |
217 | | const uint8_t block[BCM_SHA512_CBLOCK]); |
218 | | |
219 | | |
220 | | // SHA-512-256 |
221 | | // |
222 | | // See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6 |
223 | | |
224 | 900 | #define BCM_SHA512_256_DIGEST_LENGTH 32 |
225 | | |
226 | | // BCM_sha512_256_init initialises |sha|. |
227 | | bcm_infallible BCM_sha512_256_init(SHA512_CTX *sha); |
228 | | |
229 | | // BCM_sha512_256_update adds |len| bytes from |data| to |sha|. |
230 | | bcm_infallible BCM_sha512_256_update(SHA512_CTX *sha, const void *data, |
231 | | size_t len); |
232 | | |
233 | | // BCM_sha512_256_final adds the final padding to |sha| and writes the resulting |
234 | | // digest to |out|, which must have at least |BCM_sha512_256_DIGEST_LENGTH| |
235 | | // bytes of space. It may abort on programmer error. |
236 | | bcm_infallible BCM_sha512_256_final(uint8_t out[BCM_SHA512_256_DIGEST_LENGTH], |
237 | | SHA512_CTX *sha); |
238 | | |
239 | | |
240 | | #if defined(__cplusplus) |
241 | | } // extern C |
242 | | #endif |
243 | | |
244 | | #endif // OPENSSL_HEADER_CRYPTO_BCM_INTERFACE_H |