xref: /rk3399_rockchip-uboot/lib/sha256.c (revision da29f2991d75fc8aa3289407a0e686a4a22f8c9e)
178acc472SPeter Tyser /*
278acc472SPeter Tyser  * FIPS-180-2 compliant SHA-256 implementation
378acc472SPeter Tyser  *
478acc472SPeter Tyser  * Copyright (C) 2001-2003  Christophe Devine
578acc472SPeter Tyser  *
61a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
778acc472SPeter Tyser  */
878acc472SPeter Tyser 
978acc472SPeter Tyser #ifndef USE_HOSTCC
1078acc472SPeter Tyser #include <common.h>
11822ef00eSAndreas Bießmann #include <linux/string.h>
12822ef00eSAndreas Bießmann #else
13822ef00eSAndreas Bießmann #include <string.h>
1478acc472SPeter Tyser #endif /* USE_HOSTCC */
1578acc472SPeter Tyser #include <watchdog.h>
162b9912e6SJeroen Hofstee #include <u-boot/sha256.h>
1778acc472SPeter Tyser 
18*da29f299SAndrew Duda const uint8_t sha256_der_prefix[SHA256_DER_LEN] = {
19*da29f299SAndrew Duda 	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
20*da29f299SAndrew Duda 	0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
21*da29f299SAndrew Duda 	0x00, 0x04, 0x20
22*da29f299SAndrew Duda };
23*da29f299SAndrew Duda 
2478acc472SPeter Tyser /*
2578acc472SPeter Tyser  * 32-bit integer manipulation macros (big endian)
2678acc472SPeter Tyser  */
2778acc472SPeter Tyser #ifndef GET_UINT32_BE
2878acc472SPeter Tyser #define GET_UINT32_BE(n,b,i) {				\
2978acc472SPeter Tyser 	(n) = ( (unsigned long) (b)[(i)    ] << 24 )	\
3078acc472SPeter Tyser 	    | ( (unsigned long) (b)[(i) + 1] << 16 )	\
3178acc472SPeter Tyser 	    | ( (unsigned long) (b)[(i) + 2] <<  8 )	\
3278acc472SPeter Tyser 	    | ( (unsigned long) (b)[(i) + 3]       );	\
3378acc472SPeter Tyser }
3478acc472SPeter Tyser #endif
3578acc472SPeter Tyser #ifndef PUT_UINT32_BE
3678acc472SPeter Tyser #define PUT_UINT32_BE(n,b,i) {				\
3778acc472SPeter Tyser 	(b)[(i)    ] = (unsigned char) ( (n) >> 24 );	\
3878acc472SPeter Tyser 	(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );	\
3978acc472SPeter Tyser 	(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );	\
4078acc472SPeter Tyser 	(b)[(i) + 3] = (unsigned char) ( (n)       );	\
4178acc472SPeter Tyser }
4278acc472SPeter Tyser #endif
4378acc472SPeter Tyser 
4478acc472SPeter Tyser void sha256_starts(sha256_context * ctx)
4578acc472SPeter Tyser {
4678acc472SPeter Tyser 	ctx->total[0] = 0;
4778acc472SPeter Tyser 	ctx->total[1] = 0;
4878acc472SPeter Tyser 
4978acc472SPeter Tyser 	ctx->state[0] = 0x6A09E667;
5078acc472SPeter Tyser 	ctx->state[1] = 0xBB67AE85;
5178acc472SPeter Tyser 	ctx->state[2] = 0x3C6EF372;
5278acc472SPeter Tyser 	ctx->state[3] = 0xA54FF53A;
5378acc472SPeter Tyser 	ctx->state[4] = 0x510E527F;
5478acc472SPeter Tyser 	ctx->state[5] = 0x9B05688C;
5578acc472SPeter Tyser 	ctx->state[6] = 0x1F83D9AB;
5678acc472SPeter Tyser 	ctx->state[7] = 0x5BE0CD19;
5778acc472SPeter Tyser }
5878acc472SPeter Tyser 
59ec7381fbSSimon Glass static void sha256_process(sha256_context *ctx, const uint8_t data[64])
6078acc472SPeter Tyser {
6178acc472SPeter Tyser 	uint32_t temp1, temp2;
6278acc472SPeter Tyser 	uint32_t W[64];
6378acc472SPeter Tyser 	uint32_t A, B, C, D, E, F, G, H;
6478acc472SPeter Tyser 
6578acc472SPeter Tyser 	GET_UINT32_BE(W[0], data, 0);
6678acc472SPeter Tyser 	GET_UINT32_BE(W[1], data, 4);
6778acc472SPeter Tyser 	GET_UINT32_BE(W[2], data, 8);
6878acc472SPeter Tyser 	GET_UINT32_BE(W[3], data, 12);
6978acc472SPeter Tyser 	GET_UINT32_BE(W[4], data, 16);
7078acc472SPeter Tyser 	GET_UINT32_BE(W[5], data, 20);
7178acc472SPeter Tyser 	GET_UINT32_BE(W[6], data, 24);
7278acc472SPeter Tyser 	GET_UINT32_BE(W[7], data, 28);
7378acc472SPeter Tyser 	GET_UINT32_BE(W[8], data, 32);
7478acc472SPeter Tyser 	GET_UINT32_BE(W[9], data, 36);
7578acc472SPeter Tyser 	GET_UINT32_BE(W[10], data, 40);
7678acc472SPeter Tyser 	GET_UINT32_BE(W[11], data, 44);
7778acc472SPeter Tyser 	GET_UINT32_BE(W[12], data, 48);
7878acc472SPeter Tyser 	GET_UINT32_BE(W[13], data, 52);
7978acc472SPeter Tyser 	GET_UINT32_BE(W[14], data, 56);
8078acc472SPeter Tyser 	GET_UINT32_BE(W[15], data, 60);
8178acc472SPeter Tyser 
8278acc472SPeter Tyser #define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
8378acc472SPeter Tyser #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
8478acc472SPeter Tyser 
8578acc472SPeter Tyser #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
8678acc472SPeter Tyser #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
8778acc472SPeter Tyser 
8878acc472SPeter Tyser #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
8978acc472SPeter Tyser #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
9078acc472SPeter Tyser 
9178acc472SPeter Tyser #define F0(x,y,z) ((x & y) | (z & (x | y)))
9278acc472SPeter Tyser #define F1(x,y,z) (z ^ (x & (y ^ z)))
9378acc472SPeter Tyser 
9478acc472SPeter Tyser #define R(t)					\
9578acc472SPeter Tyser (						\
9678acc472SPeter Tyser 	W[t] = S1(W[t - 2]) + W[t - 7] +	\
9778acc472SPeter Tyser 		S0(W[t - 15]) + W[t - 16]	\
9878acc472SPeter Tyser )
9978acc472SPeter Tyser 
10078acc472SPeter Tyser #define P(a,b,c,d,e,f,g,h,x,K) {		\
10178acc472SPeter Tyser 	temp1 = h + S3(e) + F1(e,f,g) + K + x;	\
10278acc472SPeter Tyser 	temp2 = S2(a) + F0(a,b,c);		\
10378acc472SPeter Tyser 	d += temp1; h = temp1 + temp2;		\
10478acc472SPeter Tyser }
10578acc472SPeter Tyser 
10678acc472SPeter Tyser 	A = ctx->state[0];
10778acc472SPeter Tyser 	B = ctx->state[1];
10878acc472SPeter Tyser 	C = ctx->state[2];
10978acc472SPeter Tyser 	D = ctx->state[3];
11078acc472SPeter Tyser 	E = ctx->state[4];
11178acc472SPeter Tyser 	F = ctx->state[5];
11278acc472SPeter Tyser 	G = ctx->state[6];
11378acc472SPeter Tyser 	H = ctx->state[7];
11478acc472SPeter Tyser 
11578acc472SPeter Tyser 	P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
11678acc472SPeter Tyser 	P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
11778acc472SPeter Tyser 	P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
11878acc472SPeter Tyser 	P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
11978acc472SPeter Tyser 	P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
12078acc472SPeter Tyser 	P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
12178acc472SPeter Tyser 	P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
12278acc472SPeter Tyser 	P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
12378acc472SPeter Tyser 	P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
12478acc472SPeter Tyser 	P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
12578acc472SPeter Tyser 	P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
12678acc472SPeter Tyser 	P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
12778acc472SPeter Tyser 	P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
12878acc472SPeter Tyser 	P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
12978acc472SPeter Tyser 	P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
13078acc472SPeter Tyser 	P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
13178acc472SPeter Tyser 	P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
13278acc472SPeter Tyser 	P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
13378acc472SPeter Tyser 	P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
13478acc472SPeter Tyser 	P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
13578acc472SPeter Tyser 	P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
13678acc472SPeter Tyser 	P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
13778acc472SPeter Tyser 	P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
13878acc472SPeter Tyser 	P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
13978acc472SPeter Tyser 	P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
14078acc472SPeter Tyser 	P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
14178acc472SPeter Tyser 	P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
14278acc472SPeter Tyser 	P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
14378acc472SPeter Tyser 	P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
14478acc472SPeter Tyser 	P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
14578acc472SPeter Tyser 	P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
14678acc472SPeter Tyser 	P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
14778acc472SPeter Tyser 	P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
14878acc472SPeter Tyser 	P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
14978acc472SPeter Tyser 	P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
15078acc472SPeter Tyser 	P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
15178acc472SPeter Tyser 	P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
15278acc472SPeter Tyser 	P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
15378acc472SPeter Tyser 	P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
15478acc472SPeter Tyser 	P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
15578acc472SPeter Tyser 	P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
15678acc472SPeter Tyser 	P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
15778acc472SPeter Tyser 	P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
15878acc472SPeter Tyser 	P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
15978acc472SPeter Tyser 	P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
16078acc472SPeter Tyser 	P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
16178acc472SPeter Tyser 	P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
16278acc472SPeter Tyser 	P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
16378acc472SPeter Tyser 	P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
16478acc472SPeter Tyser 	P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
16578acc472SPeter Tyser 	P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
16678acc472SPeter Tyser 	P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
16778acc472SPeter Tyser 	P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
16878acc472SPeter Tyser 	P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
16978acc472SPeter Tyser 	P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
17078acc472SPeter Tyser 	P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
17178acc472SPeter Tyser 	P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
17278acc472SPeter Tyser 	P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
17378acc472SPeter Tyser 	P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
17478acc472SPeter Tyser 	P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
17578acc472SPeter Tyser 	P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
17678acc472SPeter Tyser 	P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
17778acc472SPeter Tyser 	P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
17878acc472SPeter Tyser 	P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
17978acc472SPeter Tyser 
18078acc472SPeter Tyser 	ctx->state[0] += A;
18178acc472SPeter Tyser 	ctx->state[1] += B;
18278acc472SPeter Tyser 	ctx->state[2] += C;
18378acc472SPeter Tyser 	ctx->state[3] += D;
18478acc472SPeter Tyser 	ctx->state[4] += E;
18578acc472SPeter Tyser 	ctx->state[5] += F;
18678acc472SPeter Tyser 	ctx->state[6] += G;
18778acc472SPeter Tyser 	ctx->state[7] += H;
18878acc472SPeter Tyser }
18978acc472SPeter Tyser 
190ec7381fbSSimon Glass void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
19178acc472SPeter Tyser {
19278acc472SPeter Tyser 	uint32_t left, fill;
19378acc472SPeter Tyser 
19478acc472SPeter Tyser 	if (!length)
19578acc472SPeter Tyser 		return;
19678acc472SPeter Tyser 
19778acc472SPeter Tyser 	left = ctx->total[0] & 0x3F;
19878acc472SPeter Tyser 	fill = 64 - left;
19978acc472SPeter Tyser 
20078acc472SPeter Tyser 	ctx->total[0] += length;
20178acc472SPeter Tyser 	ctx->total[0] &= 0xFFFFFFFF;
20278acc472SPeter Tyser 
20378acc472SPeter Tyser 	if (ctx->total[0] < length)
20478acc472SPeter Tyser 		ctx->total[1]++;
20578acc472SPeter Tyser 
20678acc472SPeter Tyser 	if (left && length >= fill) {
20778acc472SPeter Tyser 		memcpy((void *) (ctx->buffer + left), (void *) input, fill);
20878acc472SPeter Tyser 		sha256_process(ctx, ctx->buffer);
20978acc472SPeter Tyser 		length -= fill;
21078acc472SPeter Tyser 		input += fill;
21178acc472SPeter Tyser 		left = 0;
21278acc472SPeter Tyser 	}
21378acc472SPeter Tyser 
21478acc472SPeter Tyser 	while (length >= 64) {
21578acc472SPeter Tyser 		sha256_process(ctx, input);
21678acc472SPeter Tyser 		length -= 64;
21778acc472SPeter Tyser 		input += 64;
21878acc472SPeter Tyser 	}
21978acc472SPeter Tyser 
22078acc472SPeter Tyser 	if (length)
22178acc472SPeter Tyser 		memcpy((void *) (ctx->buffer + left), (void *) input, length);
22278acc472SPeter Tyser }
22378acc472SPeter Tyser 
22478acc472SPeter Tyser static uint8_t sha256_padding[64] = {
22578acc472SPeter Tyser 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22678acc472SPeter Tyser 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22778acc472SPeter Tyser 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22878acc472SPeter Tyser 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
22978acc472SPeter Tyser };
23078acc472SPeter Tyser 
23178acc472SPeter Tyser void sha256_finish(sha256_context * ctx, uint8_t digest[32])
23278acc472SPeter Tyser {
23378acc472SPeter Tyser 	uint32_t last, padn;
23478acc472SPeter Tyser 	uint32_t high, low;
23578acc472SPeter Tyser 	uint8_t msglen[8];
23678acc472SPeter Tyser 
23778acc472SPeter Tyser 	high = ((ctx->total[0] >> 29)
23878acc472SPeter Tyser 		| (ctx->total[1] << 3));
23978acc472SPeter Tyser 	low = (ctx->total[0] << 3);
24078acc472SPeter Tyser 
24178acc472SPeter Tyser 	PUT_UINT32_BE(high, msglen, 0);
24278acc472SPeter Tyser 	PUT_UINT32_BE(low, msglen, 4);
24378acc472SPeter Tyser 
24478acc472SPeter Tyser 	last = ctx->total[0] & 0x3F;
24578acc472SPeter Tyser 	padn = (last < 56) ? (56 - last) : (120 - last);
24678acc472SPeter Tyser 
24778acc472SPeter Tyser 	sha256_update(ctx, sha256_padding, padn);
24878acc472SPeter Tyser 	sha256_update(ctx, msglen, 8);
24978acc472SPeter Tyser 
25078acc472SPeter Tyser 	PUT_UINT32_BE(ctx->state[0], digest, 0);
25178acc472SPeter Tyser 	PUT_UINT32_BE(ctx->state[1], digest, 4);
25278acc472SPeter Tyser 	PUT_UINT32_BE(ctx->state[2], digest, 8);
25378acc472SPeter Tyser 	PUT_UINT32_BE(ctx->state[3], digest, 12);
25478acc472SPeter Tyser 	PUT_UINT32_BE(ctx->state[4], digest, 16);
25578acc472SPeter Tyser 	PUT_UINT32_BE(ctx->state[5], digest, 20);
25678acc472SPeter Tyser 	PUT_UINT32_BE(ctx->state[6], digest, 24);
25778acc472SPeter Tyser 	PUT_UINT32_BE(ctx->state[7], digest, 28);
25878acc472SPeter Tyser }
259ec7381fbSSimon Glass 
260ec7381fbSSimon Glass /*
261ec7381fbSSimon Glass  * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz'
262ec7381fbSSimon Glass  * bytes of input processed.
263ec7381fbSSimon Glass  */
264ec7381fbSSimon Glass void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
265ec7381fbSSimon Glass 		unsigned char *output, unsigned int chunk_sz)
266ec7381fbSSimon Glass {
267ec7381fbSSimon Glass 	sha256_context ctx;
268ec7381fbSSimon Glass #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
2692842c1c2SHeiko Schocher 	const unsigned char *end;
2702842c1c2SHeiko Schocher 	unsigned char *curr;
271ec7381fbSSimon Glass 	int chunk;
272ec7381fbSSimon Glass #endif
273ec7381fbSSimon Glass 
274ec7381fbSSimon Glass 	sha256_starts(&ctx);
275ec7381fbSSimon Glass 
276ec7381fbSSimon Glass #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
2772842c1c2SHeiko Schocher 	curr = (unsigned char *)input;
278ec7381fbSSimon Glass 	end = input + ilen;
279ec7381fbSSimon Glass 	while (curr < end) {
280ec7381fbSSimon Glass 		chunk = end - curr;
281ec7381fbSSimon Glass 		if (chunk > chunk_sz)
282ec7381fbSSimon Glass 			chunk = chunk_sz;
283ec7381fbSSimon Glass 		sha256_update(&ctx, curr, chunk);
284ec7381fbSSimon Glass 		curr += chunk;
285ec7381fbSSimon Glass 		WATCHDOG_RESET();
286ec7381fbSSimon Glass 	}
287ec7381fbSSimon Glass #else
288ec7381fbSSimon Glass 	sha256_update(&ctx, input, ilen);
289ec7381fbSSimon Glass #endif
290ec7381fbSSimon Glass 
291ec7381fbSSimon Glass 	sha256_finish(&ctx, output);
292ec7381fbSSimon Glass }
293