1 /*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15
16 #include "error/s2n_errno.h"
17
18 #include "crypto/s2n_hash.h"
19 #include "crypto/s2n_hmac.h"
20 #include "crypto/s2n_openssl.h"
21 #include "crypto/s2n_fips.h"
22
23 #include "utils/s2n_safety.h"
24
s2n_hash_digest_size(s2n_hash_algorithm alg,uint8_t * out)25 int s2n_hash_digest_size(s2n_hash_algorithm alg, uint8_t *out)
26 {
27 POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
28 switch (alg) {
29 case S2N_HASH_NONE: *out = 0; break;
30 case S2N_HASH_MD5: *out = MD5_DIGEST_LENGTH; break;
31 case S2N_HASH_SHA1: *out = SHA_DIGEST_LENGTH; break;
32 case S2N_HASH_SHA224: *out = SHA224_DIGEST_LENGTH; break;
33 case S2N_HASH_SHA256: *out = SHA256_DIGEST_LENGTH; break;
34 case S2N_HASH_SHA384: *out = SHA384_DIGEST_LENGTH; break;
35 case S2N_HASH_SHA512: *out = SHA512_DIGEST_LENGTH; break;
36 case S2N_HASH_MD5_SHA1: *out = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; break;
37 default:
38 POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
39 }
40 return S2N_SUCCESS;
41 }
42
43 /* NOTE: s2n_hash_const_time_get_currently_in_hash_block takes advantage of the fact that
44 * hash_block_size is a power of 2. This is true for all hashes we currently support
45 * If this ever becomes untrue, this would require fixing*/
s2n_hash_block_size(s2n_hash_algorithm alg,uint64_t * block_size)46 int s2n_hash_block_size(s2n_hash_algorithm alg, uint64_t *block_size)
47 {
48 POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(block_size, sizeof(*block_size)), S2N_ERR_PRECONDITION_VIOLATION);
49 switch(alg) {
50 case S2N_HASH_NONE: *block_size = 64; break;
51 case S2N_HASH_MD5: *block_size = 64; break;
52 case S2N_HASH_SHA1: *block_size = 64; break;
53 case S2N_HASH_SHA224: *block_size = 64; break;
54 case S2N_HASH_SHA256: *block_size = 64; break;
55 case S2N_HASH_SHA384: *block_size = 128; break;
56 case S2N_HASH_SHA512: *block_size = 128; break;
57 case S2N_HASH_MD5_SHA1: *block_size = 64; break;
58 default:
59 POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
60 }
61 return S2N_SUCCESS;
62 }
63
64 /* Return true if hash algorithm is available, false otherwise. */
s2n_hash_is_available(s2n_hash_algorithm alg)65 bool s2n_hash_is_available(s2n_hash_algorithm alg)
66 {
67 switch (alg) {
68 case S2N_HASH_MD5:
69 case S2N_HASH_MD5_SHA1:
70 /* return false if in FIPS mode, as MD5 algs are not available in FIPS mode. */
71 return !s2n_is_in_fips_mode();
72 case S2N_HASH_NONE:
73 case S2N_HASH_SHA1:
74 case S2N_HASH_SHA224:
75 case S2N_HASH_SHA256:
76 case S2N_HASH_SHA384:
77 case S2N_HASH_SHA512:
78 return true;
79 case S2N_HASH_SENTINEL:
80 return false;
81 }
82 return false;
83 }
84
s2n_hash_is_ready_for_input(struct s2n_hash_state * state)85 int s2n_hash_is_ready_for_input(struct s2n_hash_state *state)
86 {
87 POSIX_PRECONDITION(s2n_hash_state_validate(state));
88 return state->is_ready_for_input;
89 }
90
s2n_low_level_hash_new(struct s2n_hash_state * state)91 static int s2n_low_level_hash_new(struct s2n_hash_state *state)
92 {
93 /* s2n_hash_new will always call the corresponding implementation of the s2n_hash
94 * being used. For the s2n_low_level_hash implementation, new is a no-op.
95 */
96
97 state->is_ready_for_input = 0;
98 state->currently_in_hash = 0;
99 return S2N_SUCCESS;
100 }
101
s2n_low_level_hash_init(struct s2n_hash_state * state,s2n_hash_algorithm alg)102 static int s2n_low_level_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg)
103 {
104 switch (alg) {
105 case S2N_HASH_NONE:
106 break;
107 case S2N_HASH_MD5:
108 POSIX_GUARD_OSSL(MD5_Init(&state->digest.low_level.md5), S2N_ERR_HASH_INIT_FAILED);
109 break;
110 case S2N_HASH_SHA1:
111 POSIX_GUARD_OSSL(SHA1_Init(&state->digest.low_level.sha1), S2N_ERR_HASH_INIT_FAILED);
112 break;
113 case S2N_HASH_SHA224:
114 POSIX_GUARD_OSSL(SHA224_Init(&state->digest.low_level.sha224), S2N_ERR_HASH_INIT_FAILED);
115 break;
116 case S2N_HASH_SHA256:
117 POSIX_GUARD_OSSL(SHA256_Init(&state->digest.low_level.sha256), S2N_ERR_HASH_INIT_FAILED);
118 break;
119 case S2N_HASH_SHA384:
120 POSIX_GUARD_OSSL(SHA384_Init(&state->digest.low_level.sha384), S2N_ERR_HASH_INIT_FAILED);
121 break;
122 case S2N_HASH_SHA512:
123 POSIX_GUARD_OSSL(SHA512_Init(&state->digest.low_level.sha512), S2N_ERR_HASH_INIT_FAILED);
124 break;
125 case S2N_HASH_MD5_SHA1:
126 POSIX_GUARD_OSSL(SHA1_Init(&state->digest.low_level.md5_sha1.sha1), S2N_ERR_HASH_INIT_FAILED);;
127 POSIX_GUARD_OSSL(MD5_Init(&state->digest.low_level.md5_sha1.md5), S2N_ERR_HASH_INIT_FAILED);;
128 break;
129
130 default:
131 POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
132 }
133
134 state->alg = alg;
135 state->is_ready_for_input = 1;
136 state->currently_in_hash = 0;
137
138 return 0;
139 }
140
s2n_low_level_hash_update(struct s2n_hash_state * state,const void * data,uint32_t size)141 static int s2n_low_level_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size)
142 {
143 POSIX_ENSURE(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
144
145 switch (state->alg) {
146 case S2N_HASH_NONE:
147 break;
148 case S2N_HASH_MD5:
149 POSIX_GUARD_OSSL(MD5_Update(&state->digest.low_level.md5, data, size), S2N_ERR_HASH_UPDATE_FAILED);
150 break;
151 case S2N_HASH_SHA1:
152 POSIX_GUARD_OSSL(SHA1_Update(&state->digest.low_level.sha1, data, size), S2N_ERR_HASH_UPDATE_FAILED);
153 break;
154 case S2N_HASH_SHA224:
155 POSIX_GUARD_OSSL(SHA224_Update(&state->digest.low_level.sha224, data, size), S2N_ERR_HASH_UPDATE_FAILED);
156 break;
157 case S2N_HASH_SHA256:
158 POSIX_GUARD_OSSL(SHA256_Update(&state->digest.low_level.sha256, data, size), S2N_ERR_HASH_UPDATE_FAILED);
159 break;
160 case S2N_HASH_SHA384:
161 POSIX_GUARD_OSSL(SHA384_Update(&state->digest.low_level.sha384, data, size), S2N_ERR_HASH_UPDATE_FAILED);
162 break;
163 case S2N_HASH_SHA512:
164 POSIX_GUARD_OSSL(SHA512_Update(&state->digest.low_level.sha512, data, size), S2N_ERR_HASH_UPDATE_FAILED);
165 break;
166 case S2N_HASH_MD5_SHA1:
167 POSIX_GUARD_OSSL(SHA1_Update(&state->digest.low_level.md5_sha1.sha1, data, size), S2N_ERR_HASH_UPDATE_FAILED);
168 POSIX_GUARD_OSSL(MD5_Update(&state->digest.low_level.md5_sha1.md5, data, size), S2N_ERR_HASH_UPDATE_FAILED);
169 break;
170 default:
171 POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
172 }
173
174 POSIX_ENSURE(size <= (UINT64_MAX - state->currently_in_hash), S2N_ERR_INTEGER_OVERFLOW);
175 state->currently_in_hash += size;
176
177 return S2N_SUCCESS;
178 }
179
s2n_low_level_hash_digest(struct s2n_hash_state * state,void * out,uint32_t size)180 static int s2n_low_level_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size)
181 {
182 POSIX_ENSURE(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
183
184 switch (state->alg) {
185 case S2N_HASH_NONE:
186 break;
187 case S2N_HASH_MD5:
188 POSIX_ENSURE_EQ(size, MD5_DIGEST_LENGTH);
189 POSIX_GUARD_OSSL(MD5_Final(out, &state->digest.low_level.md5), S2N_ERR_HASH_DIGEST_FAILED);
190 break;
191 case S2N_HASH_SHA1:
192 POSIX_ENSURE_EQ(size, SHA_DIGEST_LENGTH);
193 POSIX_GUARD_OSSL(SHA1_Final(out, &state->digest.low_level.sha1), S2N_ERR_HASH_DIGEST_FAILED);
194 break;
195 case S2N_HASH_SHA224:
196 POSIX_ENSURE_EQ(size, SHA224_DIGEST_LENGTH);
197 POSIX_GUARD_OSSL(SHA224_Final(out, &state->digest.low_level.sha224), S2N_ERR_HASH_DIGEST_FAILED);
198 break;
199 case S2N_HASH_SHA256:
200 POSIX_ENSURE_EQ(size, SHA256_DIGEST_LENGTH);
201 POSIX_GUARD_OSSL(SHA256_Final(out, &state->digest.low_level.sha256), S2N_ERR_HASH_DIGEST_FAILED);
202 break;
203 case S2N_HASH_SHA384:
204 POSIX_ENSURE_EQ(size, SHA384_DIGEST_LENGTH);
205 POSIX_GUARD_OSSL(SHA384_Final(out, &state->digest.low_level.sha384), S2N_ERR_HASH_DIGEST_FAILED);
206 break;
207 case S2N_HASH_SHA512:
208 POSIX_ENSURE_EQ(size, SHA512_DIGEST_LENGTH);
209 POSIX_GUARD_OSSL(SHA512_Final(out, &state->digest.low_level.sha512), S2N_ERR_HASH_DIGEST_FAILED);
210 break;
211 case S2N_HASH_MD5_SHA1:
212 POSIX_ENSURE_EQ(size, MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH);
213 POSIX_GUARD_OSSL(SHA1_Final(((uint8_t *) out) + MD5_DIGEST_LENGTH, &state->digest.low_level.md5_sha1.sha1), S2N_ERR_HASH_DIGEST_FAILED);
214 POSIX_GUARD_OSSL(MD5_Final(out, &state->digest.low_level.md5_sha1.md5), S2N_ERR_HASH_DIGEST_FAILED);
215 break;
216 default:
217 POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
218 }
219
220 state->currently_in_hash = 0;
221 state->is_ready_for_input = 0;
222 return 0;
223 }
224
s2n_low_level_hash_copy(struct s2n_hash_state * to,struct s2n_hash_state * from)225 static int s2n_low_level_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from)
226 {
227 POSIX_CHECKED_MEMCPY(to, from, sizeof(struct s2n_hash_state));
228 return 0;
229 }
230
s2n_low_level_hash_reset(struct s2n_hash_state * state)231 static int s2n_low_level_hash_reset(struct s2n_hash_state *state)
232 {
233 /* hash_init resets the ready_for_input and currently_in_hash fields. */
234 return s2n_low_level_hash_init(state, state->alg);
235 }
236
s2n_low_level_hash_free(struct s2n_hash_state * state)237 static int s2n_low_level_hash_free(struct s2n_hash_state *state)
238 {
239 /* s2n_hash_free will always call the corresponding implementation of the s2n_hash
240 * being used. For the s2n_low_level_hash implementation, free is a no-op.
241 */
242 state->is_ready_for_input = 0;
243 return S2N_SUCCESS;
244 }
245
s2n_evp_hash_new(struct s2n_hash_state * state)246 static int s2n_evp_hash_new(struct s2n_hash_state *state)
247 {
248 POSIX_ENSURE_REF(state->digest.high_level.evp.ctx = S2N_EVP_MD_CTX_NEW());
249 POSIX_ENSURE_REF(state->digest.high_level.evp_md5_secondary.ctx = S2N_EVP_MD_CTX_NEW());
250 state->is_ready_for_input = 0;
251 state->currently_in_hash = 0;
252
253 return S2N_SUCCESS;
254 }
255
s2n_evp_hash_allow_md5_for_fips(struct s2n_hash_state * state)256 static int s2n_evp_hash_allow_md5_for_fips(struct s2n_hash_state *state)
257 {
258 /* This is only to be used for s2n_hash_states that will require MD5 to be used
259 * to comply with the TLS 1.0 and 1.1 RFC's for the PRF. MD5 cannot be used
260 * outside of the TLS 1.0 and 1.1 PRF when in FIPS mode. When needed, this must
261 * be called prior to s2n_hash_init().
262 */
263 POSIX_GUARD(s2n_digest_allow_md5_for_fips(&state->digest.high_level.evp_md5_secondary));
264 return s2n_digest_allow_md5_for_fips(&state->digest.high_level.evp);
265 }
266
s2n_evp_hash_init(struct s2n_hash_state * state,s2n_hash_algorithm alg)267 static int s2n_evp_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg)
268 {
269 POSIX_ENSURE_REF(state->digest.high_level.evp.ctx);
270 POSIX_ENSURE_REF(state->digest.high_level.evp_md5_secondary.ctx);
271 switch (alg) {
272 case S2N_HASH_NONE:
273 break;
274 case S2N_HASH_MD5:
275 POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_md5(), NULL), S2N_ERR_HASH_INIT_FAILED);
276 break;
277 case S2N_HASH_SHA1:
278 POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha1(), NULL), S2N_ERR_HASH_INIT_FAILED);
279 break;
280 case S2N_HASH_SHA224:
281 POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha224(), NULL), S2N_ERR_HASH_INIT_FAILED);
282 break;
283 case S2N_HASH_SHA256:
284 POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha256(), NULL), S2N_ERR_HASH_INIT_FAILED);
285 break;
286 case S2N_HASH_SHA384:
287 POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha384(), NULL), S2N_ERR_HASH_INIT_FAILED);
288 break;
289 case S2N_HASH_SHA512:
290 POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha512(), NULL), S2N_ERR_HASH_INIT_FAILED);
291 break;
292 case S2N_HASH_MD5_SHA1:
293 POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha1(), NULL), S2N_ERR_HASH_INIT_FAILED);
294 POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp_md5_secondary.ctx, EVP_md5(), NULL), S2N_ERR_HASH_INIT_FAILED);
295 break;
296 default:
297 POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
298 }
299
300 state->alg = alg;
301 state->is_ready_for_input = 1;
302 state->currently_in_hash = 0;
303
304 return S2N_SUCCESS;
305 }
306
s2n_evp_hash_update(struct s2n_hash_state * state,const void * data,uint32_t size)307 static int s2n_evp_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size)
308 {
309 POSIX_ENSURE(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
310
311 switch (state->alg) {
312 case S2N_HASH_NONE:
313 break;
314 case S2N_HASH_MD5:
315 case S2N_HASH_SHA1:
316 case S2N_HASH_SHA224:
317 case S2N_HASH_SHA256:
318 case S2N_HASH_SHA384:
319 case S2N_HASH_SHA512:
320 POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
321 POSIX_GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED);
322 break;
323 case S2N_HASH_MD5_SHA1:
324 POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
325 POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp_md5_secondary.ctx));
326 POSIX_GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED);
327 POSIX_GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp_md5_secondary.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED);
328 break;
329 default:
330 POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
331 }
332
333 POSIX_ENSURE(size <= (UINT64_MAX - state->currently_in_hash), S2N_ERR_INTEGER_OVERFLOW);
334 state->currently_in_hash += size;
335
336 return S2N_SUCCESS;
337 }
338
s2n_evp_hash_digest(struct s2n_hash_state * state,void * out,uint32_t size)339 static int s2n_evp_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size)
340 {
341 POSIX_ENSURE(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
342
343 unsigned int digest_size = size;
344 uint8_t expected_digest_size;
345 POSIX_GUARD(s2n_hash_digest_size(state->alg, &expected_digest_size));
346 POSIX_ENSURE_EQ(digest_size, expected_digest_size);
347
348 /* Used for S2N_HASH_MD5_SHA1 case to specify the exact size of each digest. */
349 uint8_t sha1_digest_size;
350 unsigned int sha1_primary_digest_size;
351 unsigned int md5_secondary_digest_size;
352
353 switch (state->alg) {
354 case S2N_HASH_NONE:
355 break;
356 case S2N_HASH_MD5:
357 case S2N_HASH_SHA1:
358 case S2N_HASH_SHA224:
359 case S2N_HASH_SHA256:
360 case S2N_HASH_SHA384:
361 case S2N_HASH_SHA512:
362 POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
363 POSIX_ENSURE(EVP_MD_CTX_size(state->digest.high_level.evp.ctx) <= digest_size, S2N_ERR_HASH_DIGEST_FAILED);
364 POSIX_GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp.ctx, out, &digest_size), S2N_ERR_HASH_DIGEST_FAILED);
365 break;
366 case S2N_HASH_MD5_SHA1:
367 POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
368 POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp_md5_secondary.ctx));
369 POSIX_GUARD(s2n_hash_digest_size(S2N_HASH_SHA1, &sha1_digest_size));
370 sha1_primary_digest_size = sha1_digest_size;
371 md5_secondary_digest_size = digest_size - sha1_primary_digest_size;
372 POSIX_ENSURE(EVP_MD_CTX_size(state->digest.high_level.evp.ctx) <= sha1_digest_size, S2N_ERR_HASH_DIGEST_FAILED);
373 POSIX_ENSURE(EVP_MD_CTX_size(state->digest.high_level.evp_md5_secondary.ctx) <= md5_secondary_digest_size, S2N_ERR_HASH_DIGEST_FAILED);
374
375 POSIX_GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp.ctx, ((uint8_t *) out) + MD5_DIGEST_LENGTH, &sha1_primary_digest_size), S2N_ERR_HASH_DIGEST_FAILED);
376 POSIX_GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp_md5_secondary.ctx, out, &md5_secondary_digest_size), S2N_ERR_HASH_DIGEST_FAILED);
377 break;
378 default:
379 POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
380 }
381
382 state->currently_in_hash = 0;
383 state->is_ready_for_input = 0;
384 return S2N_SUCCESS;
385 }
386
s2n_evp_hash_copy(struct s2n_hash_state * to,struct s2n_hash_state * from)387 static int s2n_evp_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from)
388 {
389 bool is_md5_allowed_for_fips = false;
390 switch (from->alg) {
391 case S2N_HASH_NONE:
392 break;
393 case S2N_HASH_MD5:
394 POSIX_GUARD_RESULT(s2n_digest_is_md5_allowed_for_fips(&from->digest.high_level.evp, &is_md5_allowed_for_fips));
395 if (is_md5_allowed_for_fips) {
396 POSIX_GUARD(s2n_hash_allow_md5_for_fips(to));
397 }
398 FALL_THROUGH;
399 case S2N_HASH_SHA1:
400 case S2N_HASH_SHA224:
401 case S2N_HASH_SHA256:
402 case S2N_HASH_SHA384:
403 case S2N_HASH_SHA512:
404 POSIX_ENSURE_REF(to->digest.high_level.evp.ctx);
405 POSIX_GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp.ctx, from->digest.high_level.evp.ctx), S2N_ERR_HASH_COPY_FAILED);
406 break;
407 case S2N_HASH_MD5_SHA1:
408 POSIX_ENSURE_REF(to->digest.high_level.evp.ctx);
409 POSIX_ENSURE_REF(to->digest.high_level.evp_md5_secondary.ctx);
410 POSIX_GUARD_RESULT(s2n_digest_is_md5_allowed_for_fips(&from->digest.high_level.evp, &is_md5_allowed_for_fips));
411 if (is_md5_allowed_for_fips) {
412 POSIX_GUARD(s2n_hash_allow_md5_for_fips(to));
413 }
414 POSIX_GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp.ctx, from->digest.high_level.evp.ctx), S2N_ERR_HASH_COPY_FAILED);
415 POSIX_GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp_md5_secondary.ctx, from->digest.high_level.evp_md5_secondary.ctx), S2N_ERR_HASH_COPY_FAILED);
416 break;
417 default:
418 POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
419 }
420
421 to->hash_impl = from->hash_impl;
422 to->alg = from->alg;
423 to->is_ready_for_input = from->is_ready_for_input;
424 to->currently_in_hash = from->currently_in_hash;
425
426 return S2N_SUCCESS;
427 }
428
s2n_evp_hash_reset(struct s2n_hash_state * state)429 static int s2n_evp_hash_reset(struct s2n_hash_state *state)
430 {
431 int reset_md5_for_fips = 0;
432 bool is_md5_allowed_for_fips = false;
433 POSIX_GUARD_RESULT(s2n_digest_is_md5_allowed_for_fips(&state->digest.high_level.evp, &is_md5_allowed_for_fips));
434 if ((state->alg == S2N_HASH_MD5 || state->alg == S2N_HASH_MD5_SHA1) && is_md5_allowed_for_fips) {
435 reset_md5_for_fips = 1;
436 }
437
438 POSIX_GUARD_OSSL(S2N_EVP_MD_CTX_RESET(state->digest.high_level.evp.ctx), S2N_ERR_HASH_WIPE_FAILED);
439
440 if (state->alg == S2N_HASH_MD5_SHA1) {
441 POSIX_GUARD_OSSL(S2N_EVP_MD_CTX_RESET(state->digest.high_level.evp_md5_secondary.ctx), S2N_ERR_HASH_WIPE_FAILED);
442 }
443
444 if (reset_md5_for_fips) {
445 POSIX_GUARD(s2n_hash_allow_md5_for_fips(state));
446 }
447
448 /* hash_init resets the ready_for_input and currently_in_hash fields. */
449 return s2n_evp_hash_init(state, state->alg);
450 }
451
s2n_evp_hash_free(struct s2n_hash_state * state)452 static int s2n_evp_hash_free(struct s2n_hash_state *state)
453 {
454 S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp.ctx);
455 S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp_md5_secondary.ctx);
456 state->digest.high_level.evp.ctx = NULL;
457 state->digest.high_level.evp_md5_secondary.ctx = NULL;
458 state->is_ready_for_input = 0;
459 return S2N_SUCCESS;
460 }
461
462 static const struct s2n_hash s2n_low_level_hash = {
463 .alloc = &s2n_low_level_hash_new,
464 .allow_md5_for_fips = NULL,
465 .init = &s2n_low_level_hash_init,
466 .update = &s2n_low_level_hash_update,
467 .digest = &s2n_low_level_hash_digest,
468 .copy = &s2n_low_level_hash_copy,
469 .reset = &s2n_low_level_hash_reset,
470 .free = &s2n_low_level_hash_free,
471 };
472
473 static const struct s2n_hash s2n_evp_hash = {
474 .alloc = &s2n_evp_hash_new,
475 .allow_md5_for_fips = &s2n_evp_hash_allow_md5_for_fips,
476 .init = &s2n_evp_hash_init,
477 .update = &s2n_evp_hash_update,
478 .digest = &s2n_evp_hash_digest,
479 .copy = &s2n_evp_hash_copy,
480 .reset = &s2n_evp_hash_reset,
481 .free = &s2n_evp_hash_free,
482 };
483
s2n_hash_set_impl(struct s2n_hash_state * state)484 static int s2n_hash_set_impl(struct s2n_hash_state *state)
485 {
486 state->hash_impl = s2n_is_in_fips_mode() ? &s2n_evp_hash : &s2n_low_level_hash;
487
488 return S2N_SUCCESS;
489 }
490
s2n_hash_new(struct s2n_hash_state * state)491 int s2n_hash_new(struct s2n_hash_state *state)
492 {
493 POSIX_ENSURE_REF(state);
494 /* Set hash_impl on initial hash creation.
495 * When in FIPS mode, the EVP API's must be used for hashes.
496 */
497 POSIX_GUARD(s2n_hash_set_impl(state));
498
499 POSIX_ENSURE_REF(state->hash_impl->alloc);
500
501 POSIX_GUARD(state->hash_impl->alloc(state));
502 return S2N_SUCCESS;
503 }
504
s2n_hash_state_validate(struct s2n_hash_state * state)505 S2N_RESULT s2n_hash_state_validate(struct s2n_hash_state *state)
506 {
507 RESULT_ENSURE_REF(state);
508 return S2N_RESULT_OK;
509 }
510
s2n_hash_allow_md5_for_fips(struct s2n_hash_state * state)511 int s2n_hash_allow_md5_for_fips(struct s2n_hash_state *state)
512 {
513 POSIX_ENSURE_REF(state);
514 /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
515 * When in FIPS mode, the EVP API's must be used for hashes.
516 */
517 POSIX_GUARD(s2n_hash_set_impl(state));
518
519 POSIX_ENSURE_REF(state->hash_impl->allow_md5_for_fips);
520
521 return state->hash_impl->allow_md5_for_fips(state);
522 }
523
s2n_hash_init(struct s2n_hash_state * state,s2n_hash_algorithm alg)524 int s2n_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg)
525 {
526 POSIX_ENSURE_REF(state);
527 /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
528 * When in FIPS mode, the EVP API's must be used for hashes.
529 */
530 POSIX_GUARD(s2n_hash_set_impl(state));
531
532 bool is_md5_allowed_for_fips = false;
533 POSIX_GUARD_RESULT(s2n_digest_is_md5_allowed_for_fips(&state->digest.high_level.evp, &is_md5_allowed_for_fips));
534
535 if (s2n_hash_is_available(alg) ||
536 ((alg == S2N_HASH_MD5 || alg == S2N_HASH_MD5_SHA1) && is_md5_allowed_for_fips)) {
537 /* s2n will continue to initialize an "unavailable" hash when s2n is in FIPS mode and
538 * FIPS is forcing the hash to be made available.
539 */
540 POSIX_ENSURE_REF(state->hash_impl->init);
541
542 return state->hash_impl->init(state, alg);
543 } else {
544 POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
545 }
546 }
547
s2n_hash_update(struct s2n_hash_state * state,const void * data,uint32_t size)548 int s2n_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size)
549 {
550 POSIX_PRECONDITION(s2n_hash_state_validate(state));
551 POSIX_ENSURE(S2N_MEM_IS_READABLE(data, size), S2N_ERR_PRECONDITION_VIOLATION);
552 POSIX_ENSURE_REF(state->hash_impl->update);
553
554 return state->hash_impl->update(state, data, size);
555 }
556
s2n_hash_digest(struct s2n_hash_state * state,void * out,uint32_t size)557 int s2n_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size)
558 {
559 POSIX_PRECONDITION(s2n_hash_state_validate(state));
560 POSIX_ENSURE(S2N_MEM_IS_READABLE(out, size), S2N_ERR_PRECONDITION_VIOLATION);
561 POSIX_ENSURE_REF(state->hash_impl->digest);
562
563 return state->hash_impl->digest(state, out, size);
564 }
565
s2n_hash_copy(struct s2n_hash_state * to,struct s2n_hash_state * from)566 int s2n_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from)
567 {
568 POSIX_PRECONDITION(s2n_hash_state_validate(to));
569 POSIX_PRECONDITION(s2n_hash_state_validate(from));
570 POSIX_ENSURE_REF(from->hash_impl->copy);
571
572 return from->hash_impl->copy(to, from);
573 }
574
s2n_hash_reset(struct s2n_hash_state * state)575 int s2n_hash_reset(struct s2n_hash_state *state)
576 {
577 POSIX_ENSURE_REF(state);
578 /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
579 * When in FIPS mode, the EVP API's must be used for hashes.
580 */
581 POSIX_GUARD(s2n_hash_set_impl(state));
582
583 POSIX_ENSURE_REF(state->hash_impl->reset);
584
585 return state->hash_impl->reset(state);
586 }
587
s2n_hash_free(struct s2n_hash_state * state)588 int s2n_hash_free(struct s2n_hash_state *state)
589 {
590 if (state == NULL)
591 {
592 return S2N_SUCCESS;
593 }
594 /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
595 * When in FIPS mode, the EVP API's must be used for hashes.
596 */
597 POSIX_GUARD(s2n_hash_set_impl(state));
598
599 POSIX_ENSURE_REF(state->hash_impl->free);
600
601 return state->hash_impl->free(state);
602 }
603
s2n_hash_get_currently_in_hash_total(struct s2n_hash_state * state,uint64_t * out)604 int s2n_hash_get_currently_in_hash_total(struct s2n_hash_state *state, uint64_t *out)
605 {
606 POSIX_PRECONDITION(s2n_hash_state_validate(state));
607 POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
608 POSIX_ENSURE(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
609
610 *out = state->currently_in_hash;
611 return S2N_SUCCESS;
612 }
613
614
615 /* Calculate, in constant time, the number of bytes currently in the hash_block */
s2n_hash_const_time_get_currently_in_hash_block(struct s2n_hash_state * state,uint64_t * out)616 int s2n_hash_const_time_get_currently_in_hash_block(struct s2n_hash_state *state, uint64_t *out)
617 {
618 POSIX_PRECONDITION(s2n_hash_state_validate(state));
619 POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
620 POSIX_ENSURE(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
621 uint64_t hash_block_size;
622 POSIX_GUARD(s2n_hash_block_size(state->alg, &hash_block_size));
623
624 /* Requires that hash_block_size is a power of 2. This is true for all hashes we currently support
625 * If this ever becomes untrue, this would require fixing this*/
626 *out = state->currently_in_hash & (hash_block_size - 1);
627 return S2N_SUCCESS;
628 }
629