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