xref: /optee_os/core/crypto/sm3.c (revision f0ead74813951effd2adf67da8f98b2a2ae37337)
147645577SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
247645577SJerome Forissier /*
347645577SJerome Forissier  * Copyright (c) 2019 Huawei Technologies Co., Ltd
447645577SJerome Forissier  */
547645577SJerome Forissier /*
647645577SJerome Forissier  * SM3 Hash algorithm
747645577SJerome Forissier  * thanks to Xyssl
847645577SJerome Forissier  * author:goldboar
947645577SJerome Forissier  * email:goldboar@163.com
1047645577SJerome Forissier  * 2011-10-26
1147645577SJerome Forissier  */
1247645577SJerome Forissier 
1347645577SJerome Forissier #include <string.h>
1447645577SJerome Forissier #include <string_ext.h>
1547645577SJerome Forissier 
1647645577SJerome Forissier #include "sm3.h"
1747645577SJerome Forissier 
1847645577SJerome Forissier #define GET_UINT32_BE(n, b, i)				\
1947645577SJerome Forissier 	do {						\
2047645577SJerome Forissier 		(n) = ((uint32_t)(b)[(i)] << 24)     |	\
2147645577SJerome Forissier 		      ((uint32_t)(b)[(i) + 1] << 16) |	\
2247645577SJerome Forissier 		      ((uint32_t)(b)[(i) + 2] <<  8) |	\
2347645577SJerome Forissier 		      ((uint32_t)(b)[(i) + 3]);		\
2447645577SJerome Forissier 	} while (0)
2547645577SJerome Forissier 
2647645577SJerome Forissier #define PUT_UINT32_BE(n, b, i)				\
2747645577SJerome Forissier 	do {						\
2847645577SJerome Forissier 		(b)[(i)] = (uint8_t)((n) >> 24);	\
2947645577SJerome Forissier 		(b)[(i) + 1] = (uint8_t)((n) >> 16);	\
3047645577SJerome Forissier 		(b)[(i) + 2] = (uint8_t)((n) >>  8);	\
3147645577SJerome Forissier 		(b)[(i) + 3] = (uint8_t)((n));		\
3247645577SJerome Forissier 	} while (0)
3347645577SJerome Forissier 
3447645577SJerome Forissier void sm3_init(struct sm3_context *ctx)
3547645577SJerome Forissier {
3647645577SJerome Forissier 	ctx->total[0] = 0;
3747645577SJerome Forissier 	ctx->total[1] = 0;
3847645577SJerome Forissier 
3947645577SJerome Forissier 	ctx->state[0] = 0x7380166F;
4047645577SJerome Forissier 	ctx->state[1] = 0x4914B2B9;
4147645577SJerome Forissier 	ctx->state[2] = 0x172442D7;
4247645577SJerome Forissier 	ctx->state[3] = 0xDA8A0600;
4347645577SJerome Forissier 	ctx->state[4] = 0xA96F30BC;
4447645577SJerome Forissier 	ctx->state[5] = 0x163138AA;
4547645577SJerome Forissier 	ctx->state[6] = 0xE38DEE4D;
4647645577SJerome Forissier 	ctx->state[7] = 0xB0FB0E4E;
4747645577SJerome Forissier }
4847645577SJerome Forissier 
4947645577SJerome Forissier static void sm3_process(struct sm3_context *ctx, const uint8_t data[64])
5047645577SJerome Forissier {
5147645577SJerome Forissier 	uint32_t SS1, SS2, TT1, TT2, W[68], W1[64];
5247645577SJerome Forissier 	uint32_t A, B, C, D, E, F, G, H;
5347645577SJerome Forissier 	uint32_t T[64];
5447645577SJerome Forissier 	uint32_t Temp1, Temp2, Temp3, Temp4, Temp5;
5547645577SJerome Forissier 	int j;
5647645577SJerome Forissier 
5747645577SJerome Forissier 	for (j = 0; j < 16; j++)
5847645577SJerome Forissier 		T[j] = 0x79CC4519;
5947645577SJerome Forissier 	for (j = 16; j < 64; j++)
6047645577SJerome Forissier 		T[j] = 0x7A879D8A;
6147645577SJerome Forissier 
6247645577SJerome Forissier 	GET_UINT32_BE(W[0], data,  0);
6347645577SJerome Forissier 	GET_UINT32_BE(W[1], data,  4);
6447645577SJerome Forissier 	GET_UINT32_BE(W[2], data,  8);
6547645577SJerome Forissier 	GET_UINT32_BE(W[3], data, 12);
6647645577SJerome Forissier 	GET_UINT32_BE(W[4], data, 16);
6747645577SJerome Forissier 	GET_UINT32_BE(W[5], data, 20);
6847645577SJerome Forissier 	GET_UINT32_BE(W[6], data, 24);
6947645577SJerome Forissier 	GET_UINT32_BE(W[7], data, 28);
7047645577SJerome Forissier 	GET_UINT32_BE(W[8], data, 32);
7147645577SJerome Forissier 	GET_UINT32_BE(W[9], data, 36);
7247645577SJerome Forissier 	GET_UINT32_BE(W[10], data, 40);
7347645577SJerome Forissier 	GET_UINT32_BE(W[11], data, 44);
7447645577SJerome Forissier 	GET_UINT32_BE(W[12], data, 48);
7547645577SJerome Forissier 	GET_UINT32_BE(W[13], data, 52);
7647645577SJerome Forissier 	GET_UINT32_BE(W[14], data, 56);
7747645577SJerome Forissier 	GET_UINT32_BE(W[15], data, 60);
7847645577SJerome Forissier 
7947645577SJerome Forissier #define FF0(x, y, z)	((x) ^ (y) ^ (z))
8047645577SJerome Forissier #define FF1(x, y, z)	(((x) & (y)) | ((x) & (z)) | ((y) & (z)))
8147645577SJerome Forissier 
8247645577SJerome Forissier #define GG0(x, y, z)	((x) ^ (y) ^ (z))
8347645577SJerome Forissier #define GG1(x, y, z)	(((x) & (y)) | ((~(x)) & (z)))
8447645577SJerome Forissier 
8547645577SJerome Forissier #define SHL(x, n)	((x) << (n))
86*f0ead748SJerome Forissier #define ROTL(x, n)	(SHL((x), (n) & 0x1F) | ((x) >> (32 - ((n) & 0x1F))))
8747645577SJerome Forissier 
8847645577SJerome Forissier #define P0(x)	((x) ^ ROTL((x), 9) ^ ROTL((x), 17))
8947645577SJerome Forissier #define P1(x)	((x) ^ ROTL((x), 15) ^ ROTL((x), 23))
9047645577SJerome Forissier 
9147645577SJerome Forissier 	for (j = 16; j < 68; j++) {
9247645577SJerome Forissier 		/*
9347645577SJerome Forissier 		 * W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^
9447645577SJerome Forissier 		 *        ROTL(W[j - 13],7 ) ^ W[j-6];
9547645577SJerome Forissier 		 */
9647645577SJerome Forissier 
9747645577SJerome Forissier 		Temp1 = W[j - 16] ^ W[j - 9];
9847645577SJerome Forissier 		Temp2 = ROTL(W[j - 3], 15);
9947645577SJerome Forissier 		Temp3 = Temp1 ^ Temp2;
10047645577SJerome Forissier 		Temp4 = P1(Temp3);
10147645577SJerome Forissier 		Temp5 =  ROTL(W[j - 13], 7) ^ W[j - 6];
10247645577SJerome Forissier 		W[j] = Temp4 ^ Temp5;
10347645577SJerome Forissier 	}
10447645577SJerome Forissier 
10547645577SJerome Forissier 	for (j =  0; j < 64; j++)
10647645577SJerome Forissier 		W1[j] = W[j] ^ W[j + 4];
10747645577SJerome Forissier 
10847645577SJerome Forissier 	A = ctx->state[0];
10947645577SJerome Forissier 	B = ctx->state[1];
11047645577SJerome Forissier 	C = ctx->state[2];
11147645577SJerome Forissier 	D = ctx->state[3];
11247645577SJerome Forissier 	E = ctx->state[4];
11347645577SJerome Forissier 	F = ctx->state[5];
11447645577SJerome Forissier 	G = ctx->state[6];
11547645577SJerome Forissier 	H = ctx->state[7];
11647645577SJerome Forissier 
11747645577SJerome Forissier 	for (j = 0; j < 16; j++) {
11847645577SJerome Forissier 		SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7);
11947645577SJerome Forissier 		SS2 = SS1 ^ ROTL(A, 12);
12047645577SJerome Forissier 		TT1 = FF0(A, B, C) + D + SS2 + W1[j];
12147645577SJerome Forissier 		TT2 = GG0(E, F, G) + H + SS1 + W[j];
12247645577SJerome Forissier 		D = C;
12347645577SJerome Forissier 		C = ROTL(B, 9);
12447645577SJerome Forissier 		B = A;
12547645577SJerome Forissier 		A = TT1;
12647645577SJerome Forissier 		H = G;
12747645577SJerome Forissier 		G = ROTL(F, 19);
12847645577SJerome Forissier 		F = E;
12947645577SJerome Forissier 		E = P0(TT2);
13047645577SJerome Forissier 	}
13147645577SJerome Forissier 
13247645577SJerome Forissier 	for (j = 16; j < 64; j++) {
13347645577SJerome Forissier 		SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7);
13447645577SJerome Forissier 		SS2 = SS1 ^ ROTL(A, 12);
13547645577SJerome Forissier 		TT1 = FF1(A, B, C) + D + SS2 + W1[j];
13647645577SJerome Forissier 		TT2 = GG1(E, F, G) + H + SS1 + W[j];
13747645577SJerome Forissier 		D = C;
13847645577SJerome Forissier 		C = ROTL(B, 9);
13947645577SJerome Forissier 		B = A;
14047645577SJerome Forissier 		A = TT1;
14147645577SJerome Forissier 		H = G;
14247645577SJerome Forissier 		G = ROTL(F, 19);
14347645577SJerome Forissier 		F = E;
14447645577SJerome Forissier 		E = P0(TT2);
14547645577SJerome Forissier 	}
14647645577SJerome Forissier 
14747645577SJerome Forissier 	ctx->state[0] ^= A;
14847645577SJerome Forissier 	ctx->state[1] ^= B;
14947645577SJerome Forissier 	ctx->state[2] ^= C;
15047645577SJerome Forissier 	ctx->state[3] ^= D;
15147645577SJerome Forissier 	ctx->state[4] ^= E;
15247645577SJerome Forissier 	ctx->state[5] ^= F;
15347645577SJerome Forissier 	ctx->state[6] ^= G;
15447645577SJerome Forissier 	ctx->state[7] ^= H;
15547645577SJerome Forissier }
15647645577SJerome Forissier 
15747645577SJerome Forissier void sm3_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen)
15847645577SJerome Forissier {
15947645577SJerome Forissier 	size_t fill;
16047645577SJerome Forissier 	size_t left;
16147645577SJerome Forissier 
16247645577SJerome Forissier 	if (!ilen)
16347645577SJerome Forissier 		return;
16447645577SJerome Forissier 
16547645577SJerome Forissier 	left = ctx->total[0] & 0x3F;
16647645577SJerome Forissier 	fill = 64 - left;
16747645577SJerome Forissier 
16847645577SJerome Forissier 	ctx->total[0] += ilen;
16947645577SJerome Forissier 
17047645577SJerome Forissier 	if (ctx->total[0] < ilen)
17147645577SJerome Forissier 		ctx->total[1]++;
17247645577SJerome Forissier 
17347645577SJerome Forissier 	if (left && ilen >= fill) {
17447645577SJerome Forissier 		memcpy(ctx->buffer + left, input, fill);
17547645577SJerome Forissier 		sm3_process(ctx, ctx->buffer);
17647645577SJerome Forissier 		input += fill;
17747645577SJerome Forissier 		ilen -= fill;
17847645577SJerome Forissier 		left = 0;
17947645577SJerome Forissier 	}
18047645577SJerome Forissier 
18147645577SJerome Forissier 	while (ilen >= 64) {
18247645577SJerome Forissier 		sm3_process(ctx, input);
18347645577SJerome Forissier 		input += 64;
18447645577SJerome Forissier 		ilen -= 64;
18547645577SJerome Forissier 	}
18647645577SJerome Forissier 
18747645577SJerome Forissier 	if (ilen > 0)
18847645577SJerome Forissier 		memcpy(ctx->buffer + left, input, ilen);
18947645577SJerome Forissier }
19047645577SJerome Forissier 
19147645577SJerome Forissier static const uint8_t sm3_padding[64] = {
19247645577SJerome Forissier 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19347645577SJerome Forissier 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19447645577SJerome Forissier 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19547645577SJerome Forissier 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
19647645577SJerome Forissier };
19747645577SJerome Forissier 
19847645577SJerome Forissier void sm3_final(struct sm3_context *ctx, uint8_t output[32])
19947645577SJerome Forissier {
20047645577SJerome Forissier 	uint32_t last, padn;
20147645577SJerome Forissier 	uint32_t high, low;
20247645577SJerome Forissier 	uint8_t msglen[8];
20347645577SJerome Forissier 
20447645577SJerome Forissier 	high = (ctx->total[0] >> 29) | (ctx->total[1] <<  3);
20547645577SJerome Forissier 	low  = ctx->total[0] << 3;
20647645577SJerome Forissier 
20747645577SJerome Forissier 	PUT_UINT32_BE(high, msglen, 0);
20847645577SJerome Forissier 	PUT_UINT32_BE(low,  msglen, 4);
20947645577SJerome Forissier 
21047645577SJerome Forissier 	last = ctx->total[0] & 0x3F;
21147645577SJerome Forissier 	padn = (last < 56) ? (56 - last) : (120 - last);
21247645577SJerome Forissier 
21347645577SJerome Forissier 	sm3_update(ctx, sm3_padding, padn);
21447645577SJerome Forissier 	sm3_update(ctx, msglen, 8);
21547645577SJerome Forissier 
21647645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[0], output,  0);
21747645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[1], output,  4);
21847645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[2], output,  8);
21947645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[3], output, 12);
22047645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[4], output, 16);
22147645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[5], output, 20);
22247645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[6], output, 24);
22347645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[7], output, 28);
22447645577SJerome Forissier }
22547645577SJerome Forissier 
22647645577SJerome Forissier void sm3(const uint8_t *input, size_t ilen, uint8_t output[32])
22747645577SJerome Forissier {
22847645577SJerome Forissier 	struct sm3_context ctx = { };
22947645577SJerome Forissier 
23047645577SJerome Forissier 	sm3_init(&ctx);
23147645577SJerome Forissier 	sm3_update(&ctx, input, ilen);
23247645577SJerome Forissier 	sm3_final(&ctx, output);
23347645577SJerome Forissier 
23447645577SJerome Forissier 	memzero_explicit(&ctx, sizeof(ctx));
23547645577SJerome Forissier }
23647645577SJerome Forissier 
23747645577SJerome Forissier void sm3_hmac_init(struct sm3_context *ctx, const uint8_t *key, size_t keylen)
23847645577SJerome Forissier {
23947645577SJerome Forissier 	size_t i;
24047645577SJerome Forissier 	uint8_t sum[32];
24147645577SJerome Forissier 
24247645577SJerome Forissier 	if (keylen > 64) {
24347645577SJerome Forissier 		sm3(key, keylen, sum);
24447645577SJerome Forissier 		keylen = 32;
24547645577SJerome Forissier 		key = sum;
24647645577SJerome Forissier 	}
24747645577SJerome Forissier 
24847645577SJerome Forissier 	memset(ctx->ipad, 0x36, 64);
24947645577SJerome Forissier 	memset(ctx->opad, 0x5C, 64);
25047645577SJerome Forissier 
25147645577SJerome Forissier 	for (i = 0; i < keylen; i++) {
25247645577SJerome Forissier 		ctx->ipad[i] ^= key[i];
25347645577SJerome Forissier 		ctx->opad[i] ^= key[i];
25447645577SJerome Forissier 	}
25547645577SJerome Forissier 
25647645577SJerome Forissier 	sm3_init(ctx);
25747645577SJerome Forissier 	sm3_update(ctx, ctx->ipad, 64);
25847645577SJerome Forissier 
25947645577SJerome Forissier 	memzero_explicit(sum, sizeof(sum));
26047645577SJerome Forissier }
26147645577SJerome Forissier 
26247645577SJerome Forissier void sm3_hmac_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen)
26347645577SJerome Forissier {
26447645577SJerome Forissier 	sm3_update(ctx, input, ilen);
26547645577SJerome Forissier }
26647645577SJerome Forissier 
26747645577SJerome Forissier void sm3_hmac_final(struct sm3_context *ctx, uint8_t output[32])
26847645577SJerome Forissier {
26947645577SJerome Forissier 	uint8_t tmpbuf[32];
27047645577SJerome Forissier 
27147645577SJerome Forissier 	sm3_final(ctx, tmpbuf);
27247645577SJerome Forissier 	sm3_init(ctx);
27347645577SJerome Forissier 	sm3_update(ctx, ctx->opad, 64);
27447645577SJerome Forissier 	sm3_update(ctx, tmpbuf, 32);
27547645577SJerome Forissier 	sm3_final(ctx, output);
27647645577SJerome Forissier 
27747645577SJerome Forissier 	memzero_explicit(tmpbuf, sizeof(tmpbuf));
27847645577SJerome Forissier }
27947645577SJerome Forissier 
28047645577SJerome Forissier void sm3_hmac(const uint8_t *key, size_t keylen, const uint8_t *input,
28147645577SJerome Forissier 	      size_t ilen, uint8_t output[32])
28247645577SJerome Forissier {
28347645577SJerome Forissier 	struct sm3_context ctx;
28447645577SJerome Forissier 
28547645577SJerome Forissier 	sm3_hmac_init(&ctx, key, keylen);
28647645577SJerome Forissier 	sm3_hmac_update(&ctx, input, ilen);
28747645577SJerome Forissier 	sm3_hmac_final(&ctx, output);
28847645577SJerome Forissier 
28947645577SJerome Forissier 	memzero_explicit(&ctx, sizeof(ctx));
29047645577SJerome Forissier }
291