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