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 <openssl/md5.h>
17 #include <openssl/sha.h>
18 
19 #include "error/s2n_errno.h"
20 
21 #include "crypto/s2n_hmac.h"
22 #include "crypto/s2n_hash.h"
23 #include "crypto/s2n_fips.h"
24 
25 #include "utils/s2n_safety.h"
26 #include "utils/s2n_blob.h"
27 #include "utils/s2n_mem.h"
28 
29 #include <stdint.h>
30 
s2n_hash_hmac_alg(s2n_hash_algorithm hash_alg,s2n_hmac_algorithm * out)31 int s2n_hash_hmac_alg(s2n_hash_algorithm hash_alg, s2n_hmac_algorithm *out)
32 {
33     POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
34     switch(hash_alg) {
35     case S2N_HASH_NONE:       *out = S2N_HMAC_NONE;   break;
36     case S2N_HASH_MD5:        *out = S2N_HMAC_MD5;    break;
37     case S2N_HASH_SHA1:       *out = S2N_HMAC_SHA1;   break;
38     case S2N_HASH_SHA224:     *out = S2N_HMAC_SHA224; break;
39     case S2N_HASH_SHA256:     *out = S2N_HMAC_SHA256; break;
40     case S2N_HASH_SHA384:     *out = S2N_HMAC_SHA384; break;
41     case S2N_HASH_SHA512:     *out = S2N_HMAC_SHA512; break;
42     case S2N_HASH_MD5_SHA1:   /* Fall through ... */
43     default:
44         POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM);
45     }
46     return S2N_SUCCESS;
47 }
48 
s2n_hmac_hash_alg(s2n_hmac_algorithm hmac_alg,s2n_hash_algorithm * out)49 int s2n_hmac_hash_alg(s2n_hmac_algorithm hmac_alg, s2n_hash_algorithm *out)
50 {
51     POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
52     switch(hmac_alg) {
53     case S2N_HMAC_NONE:       *out = S2N_HASH_NONE;   break;
54     case S2N_HMAC_MD5:        *out = S2N_HASH_MD5;    break;
55     case S2N_HMAC_SHA1:       *out = S2N_HASH_SHA1;   break;
56     case S2N_HMAC_SHA224:     *out = S2N_HASH_SHA224; break;
57     case S2N_HMAC_SHA256:     *out = S2N_HASH_SHA256; break;
58     case S2N_HMAC_SHA384:     *out = S2N_HASH_SHA384; break;
59     case S2N_HMAC_SHA512:     *out = S2N_HASH_SHA512; break;
60     case S2N_HMAC_SSLv3_MD5:  *out = S2N_HASH_MD5;    break;
61     case S2N_HMAC_SSLv3_SHA1: *out = S2N_HASH_SHA1;   break;
62     default:
63         POSIX_BAIL(S2N_ERR_HMAC_INVALID_ALGORITHM);
64     }
65     return S2N_SUCCESS;
66 }
67 
s2n_hmac_digest_size(s2n_hmac_algorithm hmac_alg,uint8_t * out)68 int s2n_hmac_digest_size(s2n_hmac_algorithm hmac_alg, uint8_t *out)
69 {
70     s2n_hash_algorithm hash_alg;
71     POSIX_GUARD(s2n_hmac_hash_alg(hmac_alg, &hash_alg));
72     POSIX_GUARD(s2n_hash_digest_size(hash_alg, out));
73     return S2N_SUCCESS;
74 }
75 
76 /* Return 1 if hmac algorithm is available, 0 otherwise. */
s2n_hmac_is_available(s2n_hmac_algorithm hmac_alg)77 bool s2n_hmac_is_available(s2n_hmac_algorithm hmac_alg)
78 {
79     switch(hmac_alg) {
80     case S2N_HMAC_MD5:
81     case S2N_HMAC_SSLv3_MD5:
82     case S2N_HMAC_SSLv3_SHA1:
83         /* Set is_available to 0 if in FIPS mode, as MD5/SSLv3 algs are not available in FIPS mode. */
84         return !s2n_is_in_fips_mode();
85     case S2N_HMAC_NONE:
86     case S2N_HMAC_SHA1:
87     case S2N_HMAC_SHA224:
88     case S2N_HMAC_SHA256:
89     case S2N_HMAC_SHA384:
90     case S2N_HMAC_SHA512:
91         return true;
92     }
93     return false;
94 }
95 
s2n_sslv3_mac_init(struct s2n_hmac_state * state,s2n_hmac_algorithm alg,const void * key,uint32_t klen)96 static int s2n_sslv3_mac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen)
97 {
98     for (int i = 0; i < state->xor_pad_size; i++) {
99         state->xor_pad[i] = 0x36;
100     }
101 
102     POSIX_GUARD(s2n_hash_update(&state->inner_just_key, key, klen));
103     POSIX_GUARD(s2n_hash_update(&state->inner_just_key, state->xor_pad, state->xor_pad_size));
104 
105     for (int i = 0; i < state->xor_pad_size; i++) {
106         state->xor_pad[i] = 0x5c;
107     }
108 
109     POSIX_GUARD(s2n_hash_update(&state->outer_just_key, key, klen));
110     POSIX_GUARD(s2n_hash_update(&state->outer_just_key, state->xor_pad, state->xor_pad_size));
111 
112     return S2N_SUCCESS;
113 }
114 
s2n_tls_hmac_init(struct s2n_hmac_state * state,s2n_hmac_algorithm alg,const void * key,uint32_t klen)115 static int s2n_tls_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen)
116 {
117     memset(&state->xor_pad, 0, sizeof(state->xor_pad));
118 
119     if (klen > state->xor_pad_size) {
120         POSIX_GUARD(s2n_hash_update(&state->outer, key, klen));
121         POSIX_GUARD(s2n_hash_digest(&state->outer, state->digest_pad, state->digest_size));
122         POSIX_CHECKED_MEMCPY(state->xor_pad, state->digest_pad, state->digest_size);
123     } else {
124         POSIX_CHECKED_MEMCPY(state->xor_pad, key, klen);
125     }
126 
127     for (int i = 0; i < state->xor_pad_size; i++) {
128         state->xor_pad[i] ^= 0x36;
129     }
130 
131     POSIX_GUARD(s2n_hash_update(&state->inner_just_key, state->xor_pad, state->xor_pad_size));
132 
133     /* 0x36 xor 0x5c == 0x6a */
134     for (int i = 0; i < state->xor_pad_size; i++) {
135         state->xor_pad[i] ^= 0x6a;
136     }
137 
138     POSIX_GUARD(s2n_hash_update(&state->outer_just_key, state->xor_pad, state->xor_pad_size));
139     return S2N_SUCCESS;
140 }
141 
s2n_hmac_xor_pad_size(s2n_hmac_algorithm hmac_alg,uint16_t * xor_pad_size)142 int s2n_hmac_xor_pad_size(s2n_hmac_algorithm hmac_alg, uint16_t *xor_pad_size)
143 {
144     POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(xor_pad_size, sizeof(*xor_pad_size)), S2N_ERR_PRECONDITION_VIOLATION);
145     switch(hmac_alg) {
146     case S2N_HMAC_NONE:       *xor_pad_size = 64;   break;
147     case S2N_HMAC_MD5:        *xor_pad_size = 64;   break;
148     case S2N_HMAC_SHA1:       *xor_pad_size = 64;   break;
149     case S2N_HMAC_SHA224:     *xor_pad_size = 64;   break;
150     case S2N_HMAC_SHA256:     *xor_pad_size = 64;   break;
151     case S2N_HMAC_SHA384:     *xor_pad_size = 128;  break;
152     case S2N_HMAC_SHA512:     *xor_pad_size = 128;  break;
153     case S2N_HMAC_SSLv3_MD5:  *xor_pad_size = 48;   break;
154     case S2N_HMAC_SSLv3_SHA1: *xor_pad_size = 40;   break;
155     default:
156         POSIX_BAIL(S2N_ERR_HMAC_INVALID_ALGORITHM);
157     }
158     return S2N_SUCCESS;
159 }
160 
s2n_hmac_hash_block_size(s2n_hmac_algorithm hmac_alg,uint16_t * block_size)161 int s2n_hmac_hash_block_size(s2n_hmac_algorithm hmac_alg, uint16_t *block_size)
162 {
163     POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(block_size, sizeof(*block_size)), S2N_ERR_PRECONDITION_VIOLATION);
164     switch(hmac_alg) {
165     case S2N_HMAC_NONE:       *block_size = 64;   break;
166     case S2N_HMAC_MD5:        *block_size = 64;   break;
167     case S2N_HMAC_SHA1:       *block_size = 64;   break;
168     case S2N_HMAC_SHA224:     *block_size = 64;   break;
169     case S2N_HMAC_SHA256:     *block_size = 64;   break;
170     case S2N_HMAC_SHA384:     *block_size = 128;  break;
171     case S2N_HMAC_SHA512:     *block_size = 128;  break;
172     case S2N_HMAC_SSLv3_MD5:  *block_size = 64;   break;
173     case S2N_HMAC_SSLv3_SHA1: *block_size = 64;   break;
174     default:
175         POSIX_BAIL(S2N_ERR_HMAC_INVALID_ALGORITHM);
176     }
177     return S2N_SUCCESS;
178 }
179 
s2n_hmac_new(struct s2n_hmac_state * state)180 int s2n_hmac_new(struct s2n_hmac_state *state)
181 {
182     POSIX_ENSURE_REF(state);
183     POSIX_GUARD(s2n_hash_new(&state->inner));
184     POSIX_GUARD(s2n_hash_new(&state->inner_just_key));
185     POSIX_GUARD(s2n_hash_new(&state->outer));
186     POSIX_GUARD(s2n_hash_new(&state->outer_just_key));
187     POSIX_POSTCONDITION(s2n_hmac_state_validate(state));
188     return S2N_SUCCESS;
189 }
190 
s2n_hmac_state_validate(struct s2n_hmac_state * state)191 S2N_RESULT s2n_hmac_state_validate(struct s2n_hmac_state *state)
192 {
193     RESULT_ENSURE_REF(state);
194     RESULT_GUARD(s2n_hash_state_validate(&state->inner));
195     RESULT_GUARD(s2n_hash_state_validate(&state->inner_just_key));
196     RESULT_GUARD(s2n_hash_state_validate(&state->outer));
197     RESULT_GUARD(s2n_hash_state_validate(&state->outer_just_key));
198     return S2N_RESULT_OK;
199 }
200 
s2n_hmac_init(struct s2n_hmac_state * state,s2n_hmac_algorithm alg,const void * key,uint32_t klen)201 int s2n_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen)
202 {
203     POSIX_ENSURE_REF(state);
204     if (!s2n_hmac_is_available(alg)) {
205         /* Prevent hmacs from being used if they are not available. */
206         POSIX_BAIL(S2N_ERR_HMAC_INVALID_ALGORITHM);
207     }
208 
209     state->alg = alg;
210     POSIX_GUARD(s2n_hmac_hash_block_size(alg, &state->hash_block_size));
211     state->currently_in_hash_block = 0;
212     POSIX_GUARD(s2n_hmac_xor_pad_size(alg, &state->xor_pad_size));
213     POSIX_GUARD(s2n_hmac_digest_size(alg, &state->digest_size));
214 
215     POSIX_ENSURE_GTE(sizeof(state->xor_pad), state->xor_pad_size);
216     POSIX_ENSURE_GTE(sizeof(state->digest_pad), state->digest_size);
217     /* key needs to be as large as the biggest block size */
218     POSIX_ENSURE_GTE(sizeof(state->xor_pad), state->hash_block_size);
219 
220     s2n_hash_algorithm hash_alg;
221     POSIX_GUARD(s2n_hmac_hash_alg(alg, &hash_alg));
222 
223     POSIX_GUARD(s2n_hash_init(&state->inner, hash_alg));
224     POSIX_GUARD(s2n_hash_init(&state->inner_just_key, hash_alg));
225     POSIX_GUARD(s2n_hash_init(&state->outer, hash_alg));
226     POSIX_GUARD(s2n_hash_init(&state->outer_just_key, hash_alg));
227 
228     if (alg == S2N_HMAC_SSLv3_SHA1 || alg == S2N_HMAC_SSLv3_MD5) {
229         POSIX_GUARD(s2n_sslv3_mac_init(state, alg, key, klen));
230     } else {
231         POSIX_GUARD(s2n_tls_hmac_init(state, alg, key, klen));
232     }
233 
234     /* Once we have produced inner_just_key and outer_just_key, don't need the key material in xor_pad, so wipe it.
235      * Since xor_pad is used as a source of bytes in s2n_hmac_digest_two_compression_rounds,
236      * this also prevents uninitilized bytes being used.
237      */
238     memset(&state->xor_pad, 0, sizeof(state->xor_pad));
239     POSIX_GUARD(s2n_hmac_reset(state));
240 
241     return S2N_SUCCESS;
242 }
243 
s2n_hmac_update(struct s2n_hmac_state * state,const void * in,uint32_t size)244 int s2n_hmac_update(struct s2n_hmac_state *state, const void *in, uint32_t size)
245 {
246     POSIX_PRECONDITION(s2n_hmac_state_validate(state));
247     POSIX_ENSURE(state->hash_block_size != 0, S2N_ERR_PRECONDITION_VIOLATION);
248     /* Keep track of how much of the current hash block is full
249      *
250      * Why the 4294949760 constant in this code? 4294949760 is the highest 32-bit
251      * value that is congruent to 0 modulo all of our HMAC block sizes, that is also
252      * at least 16k smaller than 2^32. It therefore has no effect on the mathematical
253      * result, and no valid record size can cause it to overflow.
254      *
255      * The value was found with the following python code;
256      *
257      * x = (2 ** 32) - (2 ** 14)
258      * while True:
259      *   if x % 40 | x % 48 | x % 64 | x % 128 == 0:
260      *     break
261      *   x -= 1
262      * print x
263      *
264      * What it does do however is ensure that the mod operation takes a
265      * constant number of instruction cycles, regardless of the size of the
266      * input. On some platforms, including Intel, the operation can take a
267      * smaller number of cycles if the input is "small".
268      */
269     const uint32_t HIGHEST_32_BIT = 4294949760;
270     POSIX_ENSURE(size <= (UINT32_MAX - HIGHEST_32_BIT), S2N_ERR_INTEGER_OVERFLOW);
271     uint32_t value = (HIGHEST_32_BIT + size) % state->hash_block_size;
272     POSIX_GUARD(s2n_add_overflow(state->currently_in_hash_block, value, &state->currently_in_hash_block));
273     state->currently_in_hash_block %= state->hash_block_size;
274 
275     return s2n_hash_update(&state->inner, in, size);
276 }
277 
s2n_hmac_digest(struct s2n_hmac_state * state,void * out,uint32_t size)278 int s2n_hmac_digest(struct s2n_hmac_state *state, void *out, uint32_t size)
279 {
280     POSIX_PRECONDITION(s2n_hmac_state_validate(state));
281     POSIX_GUARD(s2n_hash_digest(&state->inner, state->digest_pad, state->digest_size));
282     POSIX_GUARD(s2n_hash_copy(&state->outer, &state->outer_just_key));
283     POSIX_GUARD(s2n_hash_update(&state->outer, state->digest_pad, state->digest_size));
284 
285     return s2n_hash_digest(&state->outer, out, size);
286 }
287 
s2n_hmac_digest_two_compression_rounds(struct s2n_hmac_state * state,void * out,uint32_t size)288 int s2n_hmac_digest_two_compression_rounds(struct s2n_hmac_state *state, void *out, uint32_t size)
289 {
290     /* Do the "real" work of this function. */
291     POSIX_GUARD(s2n_hmac_digest(state, out, size));
292 
293     /* If there were 9 or more bytes of space left in the current hash block
294      * then the serialized length, plus an 0x80 byte, will have fit in that block.
295      * If there were fewer than 9 then adding the length will have caused an extra
296      * compression block round. This digest function always does two compression rounds,
297      * even if there is no need for the second.
298      *
299      * 17 bytes if the block size is 128.
300      */
301     const uint8_t space_left = (state->hash_block_size == 128) ? 17 : 9;
302     if ((int64_t)state->currently_in_hash_block > (state->hash_block_size - space_left)) {
303         return S2N_SUCCESS;
304     }
305 
306     /* Can't reuse a hash after it has been finalized, so reset and push another block in */
307     POSIX_GUARD(s2n_hash_reset(&state->inner));
308 
309     /* No-op s2n_hash_update to normalize timing and guard against Lucky13. This does not affect the value of *out. */
310     return s2n_hash_update(&state->inner, state->xor_pad, state->hash_block_size);
311 }
312 
s2n_hmac_free(struct s2n_hmac_state * state)313 int s2n_hmac_free(struct s2n_hmac_state *state)
314 {
315     if (state) {
316         POSIX_GUARD(s2n_hash_free(&state->inner));
317         POSIX_GUARD(s2n_hash_free(&state->inner_just_key));
318         POSIX_GUARD(s2n_hash_free(&state->outer));
319         POSIX_GUARD(s2n_hash_free(&state->outer_just_key));
320     }
321 
322     return S2N_SUCCESS;
323 }
324 
s2n_hmac_reset(struct s2n_hmac_state * state)325 int s2n_hmac_reset(struct s2n_hmac_state *state)
326 {
327     POSIX_PRECONDITION(s2n_hmac_state_validate(state));
328     POSIX_ENSURE(state->hash_block_size != 0, S2N_ERR_PRECONDITION_VIOLATION);
329     POSIX_GUARD(s2n_hash_copy(&state->inner, &state->inner_just_key));
330 
331     uint64_t bytes_in_hash;
332     POSIX_GUARD(s2n_hash_get_currently_in_hash_total(&state->inner, &bytes_in_hash));
333     bytes_in_hash %= state->hash_block_size;
334     POSIX_ENSURE(bytes_in_hash <= UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
335     /* The length of the key is not private, so don't need to do tricky math here */
336     state->currently_in_hash_block = bytes_in_hash;
337     return S2N_SUCCESS;
338 }
339 
s2n_hmac_digest_verify(const void * a,const void * b,uint32_t len)340 int s2n_hmac_digest_verify(const void *a, const void *b, uint32_t len)
341 {
342     return S2N_SUCCESS - !s2n_constant_time_equals(a, b, len);
343 }
344 
s2n_hmac_copy(struct s2n_hmac_state * to,struct s2n_hmac_state * from)345 int s2n_hmac_copy(struct s2n_hmac_state *to, struct s2n_hmac_state *from)
346 {
347     POSIX_PRECONDITION(s2n_hmac_state_validate(to));
348     POSIX_PRECONDITION(s2n_hmac_state_validate(from));
349     /* memcpy cannot be used on s2n_hmac_state as the underlying s2n_hash implementation's
350      * copy must be used. This is enforced when the s2n_hash implementation is s2n_evp_hash.
351      */
352     to->alg = from->alg;
353     to->hash_block_size = from->hash_block_size;
354     to->currently_in_hash_block = from->currently_in_hash_block;
355     to->xor_pad_size = from->xor_pad_size;
356     to->digest_size = from->digest_size;
357 
358     POSIX_GUARD(s2n_hash_copy(&to->inner, &from->inner));
359     POSIX_GUARD(s2n_hash_copy(&to->inner_just_key, &from->inner_just_key));
360     POSIX_GUARD(s2n_hash_copy(&to->outer, &from->outer));
361     POSIX_GUARD(s2n_hash_copy(&to->outer_just_key, &from->outer_just_key));
362 
363 
364     POSIX_CHECKED_MEMCPY(to->xor_pad, from->xor_pad, sizeof(to->xor_pad));
365     POSIX_CHECKED_MEMCPY(to->digest_pad, from->digest_pad, sizeof(to->digest_pad));
366     POSIX_POSTCONDITION(s2n_hmac_state_validate(to));
367     POSIX_POSTCONDITION(s2n_hmac_state_validate(from));
368     return S2N_SUCCESS;
369 }
370 
371 
372 /* Preserve the handlers for hmac state pointers to avoid re-allocation
373  * Only valid if the HMAC is in EVP mode
374  */
s2n_hmac_save_evp_hash_state(struct s2n_hmac_evp_backup * backup,struct s2n_hmac_state * hmac)375 int s2n_hmac_save_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac)
376 {
377     POSIX_ENSURE_REF(backup);
378     POSIX_PRECONDITION(s2n_hmac_state_validate(hmac));
379     backup->inner = hmac->inner.digest.high_level;
380     backup->inner_just_key = hmac->inner_just_key.digest.high_level;
381     backup->outer = hmac->outer.digest.high_level;
382     backup->outer_just_key = hmac->outer_just_key.digest.high_level;
383     return S2N_SUCCESS;
384 }
385 
s2n_hmac_restore_evp_hash_state(struct s2n_hmac_evp_backup * backup,struct s2n_hmac_state * hmac)386 int s2n_hmac_restore_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac)
387 {
388     POSIX_ENSURE_REF(backup);
389     POSIX_PRECONDITION(s2n_hmac_state_validate(hmac));
390     hmac->inner.digest.high_level = backup->inner;
391     hmac->inner_just_key.digest.high_level = backup->inner_just_key;
392     hmac->outer.digest.high_level = backup->outer;
393     hmac->outer_just_key.digest.high_level = backup->outer_just_key;
394     POSIX_POSTCONDITION(s2n_hmac_state_validate(hmac));
395     return S2N_SUCCESS;
396 }
397