s2n_hmac.c 16 KB

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