LCOV - code coverage report
Current view: top level - externals/tinycrypt/lib/source - sha256.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 89 0.0 %
Date: 2024-09-16 20:15:30 Functions: 0 6 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 20 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* sha256.c - TinyCrypt SHA-256 crypto hash algorithm implementation */
       2                 :            : 
       3                 :            : /*
       4                 :            :  *  Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
       5                 :            :  *
       6                 :            :  *  Redistribution and use in source and binary forms, with or without
       7                 :            :  *  modification, are permitted provided that the following conditions are met:
       8                 :            :  *
       9                 :            :  *    - Redistributions of source code must retain the above copyright notice,
      10                 :            :  *     this list of conditions and the following disclaimer.
      11                 :            :  *
      12                 :            :  *    - Redistributions in binary form must reproduce the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer in the
      14                 :            :  *    documentation and/or other materials provided with the distribution.
      15                 :            :  *
      16                 :            :  *    - Neither the name of Intel Corporation nor the names of its contributors
      17                 :            :  *    may be used to endorse or promote products derived from this software
      18                 :            :  *    without specific prior written permission.
      19                 :            :  *
      20                 :            :  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
      21                 :            :  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      22                 :            :  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      23                 :            :  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      24                 :            :  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      25                 :            :  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      26                 :            :  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      27                 :            :  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      28                 :            :  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      29                 :            :  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      30                 :            :  *  POSSIBILITY OF SUCH DAMAGE.
      31                 :            :  */
      32                 :            : 
      33                 :            : #include <tinycrypt/sha256.h>
      34                 :            : #include <tinycrypt/constants.h>
      35                 :            : #include <tinycrypt/utils.h>
      36                 :            : 
      37                 :            : static void compress(unsigned int *iv, const uint8_t *data);
      38                 :            : 
      39                 :          0 : int tc_sha256_init(TCSha256State_t s)
      40                 :            : {
      41                 :            :         /* input sanity check: */
      42         [ #  # ]:          0 :         if (s == (TCSha256State_t) 0) {
      43                 :            :                 return TC_CRYPTO_FAIL;
      44                 :            :         }
      45                 :            : 
      46                 :            :         /*
      47                 :            :          * Setting the initial state values.
      48                 :            :          * These values correspond to the first 32 bits of the fractional parts
      49                 :            :          * of the square roots of the first 8 primes: 2, 3, 5, 7, 11, 13, 17
      50                 :            :          * and 19.
      51                 :            :          */
      52                 :          0 :         _set((uint8_t *) s, 0x00, sizeof(*s));
      53                 :          0 :         s->iv[0] = 0x6a09e667;
      54                 :          0 :         s->iv[1] = 0xbb67ae85;
      55                 :          0 :         s->iv[2] = 0x3c6ef372;
      56                 :          0 :         s->iv[3] = 0xa54ff53a;
      57                 :          0 :         s->iv[4] = 0x510e527f;
      58                 :          0 :         s->iv[5] = 0x9b05688c;
      59                 :          0 :         s->iv[6] = 0x1f83d9ab;
      60                 :          0 :         s->iv[7] = 0x5be0cd19;
      61                 :            : 
      62                 :          0 :         return TC_CRYPTO_SUCCESS;
      63                 :            : }
      64                 :            : 
      65                 :          0 : int tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen)
      66                 :            : {
      67                 :            :         /* input sanity check: */
      68                 :          0 :         if (s == (TCSha256State_t) 0 ||
      69         [ #  # ]:          0 :             data == (void *) 0) {
      70                 :            :                 return TC_CRYPTO_FAIL;
      71         [ #  # ]:          0 :         } else if (datalen == 0) {
      72                 :            :                 return TC_CRYPTO_SUCCESS;
      73                 :            :         }
      74                 :            : 
      75         [ #  # ]:          0 :         while (datalen-- > 0) {
      76                 :          0 :                 s->leftover[s->leftover_offset++] = *(data++);
      77         [ #  # ]:          0 :                 if (s->leftover_offset >= TC_SHA256_BLOCK_SIZE) {
      78                 :          0 :                         compress(s->iv, s->leftover);
      79                 :          0 :                         s->leftover_offset = 0;
      80                 :          0 :                         s->bits_hashed += (TC_SHA256_BLOCK_SIZE << 3);
      81                 :            :                 }
      82                 :            :         }
      83                 :            : 
      84                 :            :         return TC_CRYPTO_SUCCESS;
      85                 :            : }
      86                 :            : 
      87                 :          0 : int tc_sha256_final(uint8_t *digest, TCSha256State_t s)
      88                 :            : {
      89                 :          0 :         unsigned int i;
      90                 :            : 
      91                 :            :         /* input sanity check: */
      92                 :          0 :         if (digest == (uint8_t *) 0 ||
      93         [ #  # ]:          0 :             s == (TCSha256State_t) 0) {
      94                 :            :                 return TC_CRYPTO_FAIL;
      95                 :            :         }
      96                 :            : 
      97                 :          0 :         s->bits_hashed += (s->leftover_offset << 3);
      98                 :            : 
      99                 :          0 :         s->leftover[s->leftover_offset++] = 0x80; /* always room for one byte */
     100         [ #  # ]:          0 :         if (s->leftover_offset > (sizeof(s->leftover) - 8)) {
     101                 :            :                 /* there is not room for all the padding in this block */
     102                 :          0 :                 _set(s->leftover + s->leftover_offset, 0x00,
     103                 :            :                      sizeof(s->leftover) - s->leftover_offset);
     104                 :          0 :                 compress(s->iv, s->leftover);
     105                 :          0 :                 s->leftover_offset = 0;
     106                 :            :         }
     107                 :            : 
     108                 :            :         /* add the padding and the length in big-Endian format */
     109                 :          0 :         _set(s->leftover + s->leftover_offset, 0x00,
     110                 :          0 :              sizeof(s->leftover) - 8 - s->leftover_offset);
     111                 :          0 :         s->leftover[sizeof(s->leftover) - 1] = (uint8_t)(s->bits_hashed);
     112                 :          0 :         s->leftover[sizeof(s->leftover) - 2] = (uint8_t)(s->bits_hashed >> 8);
     113                 :          0 :         s->leftover[sizeof(s->leftover) - 3] = (uint8_t)(s->bits_hashed >> 16);
     114                 :          0 :         s->leftover[sizeof(s->leftover) - 4] = (uint8_t)(s->bits_hashed >> 24);
     115                 :          0 :         s->leftover[sizeof(s->leftover) - 5] = (uint8_t)(s->bits_hashed >> 32);
     116                 :          0 :         s->leftover[sizeof(s->leftover) - 6] = (uint8_t)(s->bits_hashed >> 40);
     117                 :          0 :         s->leftover[sizeof(s->leftover) - 7] = (uint8_t)(s->bits_hashed >> 48);
     118                 :          0 :         s->leftover[sizeof(s->leftover) - 8] = (uint8_t)(s->bits_hashed >> 56);
     119                 :            : 
     120                 :            :         /* hash the padding and length */
     121                 :          0 :         compress(s->iv, s->leftover);
     122                 :            : 
     123                 :            :         /* copy the iv out to digest */
     124         [ #  # ]:          0 :         for (i = 0; i < TC_SHA256_STATE_BLOCKS; ++i) {
     125                 :          0 :                 unsigned int t = *((unsigned int *) &s->iv[i]);
     126                 :          0 :                 *digest++ = (uint8_t)(t >> 24);
     127                 :          0 :                 *digest++ = (uint8_t)(t >> 16);
     128                 :          0 :                 *digest++ = (uint8_t)(t >> 8);
     129                 :          0 :                 *digest++ = (uint8_t)(t);
     130                 :            :         }
     131                 :            : 
     132                 :            :         /* destroy the current state */
     133                 :          0 :         _set(s, 0, sizeof(*s));
     134                 :            : 
     135                 :          0 :         return TC_CRYPTO_SUCCESS;
     136                 :            : }
     137                 :            : 
     138                 :            : /*
     139                 :            :  * Initializing SHA-256 Hash constant words K.
     140                 :            :  * These values correspond to the first 32 bits of the fractional parts of the
     141                 :            :  * cube roots of the first 64 primes between 2 and 311.
     142                 :            :  */
     143                 :            : static const unsigned int k256[64] = {
     144                 :            :         0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
     145                 :            :         0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
     146                 :            :         0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
     147                 :            :         0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
     148                 :            :         0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
     149                 :            :         0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
     150                 :            :         0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
     151                 :            :         0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
     152                 :            :         0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
     153                 :            :         0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
     154                 :            :         0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
     155                 :            : };
     156                 :            : 
     157                 :          0 : static inline unsigned int ROTR(unsigned int a, unsigned int n)
     158                 :            : {
     159                 :          0 :         return (((a) >> n) | ((a) << (32 - n)));
     160                 :            : }
     161                 :            : 
     162                 :            : #define Sigma0(a)(ROTR((a), 2) ^ ROTR((a), 13) ^ ROTR((a), 22))
     163                 :            : #define Sigma1(a)(ROTR((a), 6) ^ ROTR((a), 11) ^ ROTR((a), 25))
     164                 :            : #define sigma0(a)(ROTR((a), 7) ^ ROTR((a), 18) ^ ((a) >> 3))
     165                 :            : #define sigma1(a)(ROTR((a), 17) ^ ROTR((a), 19) ^ ((a) >> 10))
     166                 :            : 
     167                 :            : #define Ch(a, b, c)(((a) & (b)) ^ ((~(a)) & (c)))
     168                 :            : #define Maj(a, b, c)(((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c)))
     169                 :            : 
     170                 :          0 : static inline unsigned int BigEndian(const uint8_t **c)
     171                 :            : {
     172                 :          0 :         unsigned int n = 0;
     173                 :            : 
     174                 :          0 :         n = (((unsigned int)(*((*c)++))) << 24);
     175                 :          0 :         n |= ((unsigned int)(*((*c)++)) << 16);
     176                 :          0 :         n |= ((unsigned int)(*((*c)++)) << 8);
     177                 :          0 :         n |= ((unsigned int)(*((*c)++)));
     178                 :          0 :         return n;
     179                 :            : }
     180                 :            : 
     181                 :          0 : static void compress(unsigned int *iv, const uint8_t *data)
     182                 :            : {
     183                 :          0 :         unsigned int a, b, c, d, e, f, g, h;
     184                 :          0 :         unsigned int s0, s1;
     185                 :          0 :         unsigned int t1, t2;
     186                 :          0 :         unsigned int work_space[16];
     187                 :          0 :         unsigned int n;
     188                 :          0 :         unsigned int i;
     189                 :            : 
     190                 :          0 :         a = iv[0]; b = iv[1]; c = iv[2]; d = iv[3];
     191                 :          0 :         e = iv[4]; f = iv[5]; g = iv[6]; h = iv[7];
     192                 :            : 
     193         [ #  # ]:          0 :         for (i = 0; i < 16; ++i) {
     194                 :          0 :                 n = BigEndian(&data);
     195                 :          0 :                 t1 = work_space[i] = n;
     196                 :          0 :                 t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
     197                 :          0 :                 t2 = Sigma0(a) + Maj(a, b, c);
     198                 :          0 :                 h = g; g = f; f = e; e = d + t1;
     199                 :          0 :                 d = c; c = b; b = a; a = t1 + t2;
     200                 :            :         }
     201                 :            : 
     202         [ #  # ]:          0 :         for ( ; i < 64; ++i) {
     203                 :          0 :                 s0 = work_space[(i+1)&0x0f];
     204                 :          0 :                 s0 = sigma0(s0);
     205                 :          0 :                 s1 = work_space[(i+14)&0x0f];
     206                 :          0 :                 s1 = sigma1(s1);
     207                 :            : 
     208                 :          0 :                 t1 = work_space[i&0xf] += s0 + s1 + work_space[(i+9)&0xf];
     209                 :          0 :                 t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
     210                 :          0 :                 t2 = Sigma0(a) + Maj(a, b, c);
     211                 :          0 :                 h = g; g = f; f = e; e = d + t1;
     212                 :          0 :                 d = c; c = b; b = a; a = t1 + t2;
     213                 :            :         }
     214                 :            : 
     215                 :          0 :         iv[0] += a; iv[1] += b; iv[2] += c; iv[3] += d;
     216                 :          0 :         iv[4] += e; iv[5] += f; iv[6] += g; iv[7] += h;
     217                 :          0 : }

Generated by: LCOV version 1.14