LCOV - code coverage report
Current view: top level - crypto - s2n_hmac.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 192 261 73.6 %
Date: 2025-08-15 07:28:39 Functions: 16 20 80.0 %
Branches: 159 352 45.2 %

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

Generated by: LCOV version 1.14