xref: /optee_os/core/crypto/sm3.c (revision 47645577c806e80b6477193eff5ebc7de710ddf2)
1*47645577SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2*47645577SJerome Forissier /*
3*47645577SJerome Forissier  * Copyright (c) 2019 Huawei Technologies Co., Ltd
4*47645577SJerome Forissier  */
5*47645577SJerome Forissier /*
6*47645577SJerome Forissier  * SM3 Hash algorithm
7*47645577SJerome Forissier  * thanks to Xyssl
8*47645577SJerome Forissier  * author:goldboar
9*47645577SJerome Forissier  * email:goldboar@163.com
10*47645577SJerome Forissier  * 2011-10-26
11*47645577SJerome Forissier  */
12*47645577SJerome Forissier 
13*47645577SJerome Forissier #include <string.h>
14*47645577SJerome Forissier #include <string_ext.h>
15*47645577SJerome Forissier 
16*47645577SJerome Forissier #include "sm3.h"
17*47645577SJerome Forissier 
18*47645577SJerome Forissier #define GET_UINT32_BE(n, b, i)				\
19*47645577SJerome Forissier 	do {						\
20*47645577SJerome Forissier 		(n) = ((uint32_t)(b)[(i)] << 24)     |	\
21*47645577SJerome Forissier 		      ((uint32_t)(b)[(i) + 1] << 16) |	\
22*47645577SJerome Forissier 		      ((uint32_t)(b)[(i) + 2] <<  8) |	\
23*47645577SJerome Forissier 		      ((uint32_t)(b)[(i) + 3]);		\
24*47645577SJerome Forissier 	} while (0)
25*47645577SJerome Forissier 
26*47645577SJerome Forissier #define PUT_UINT32_BE(n, b, i)				\
27*47645577SJerome Forissier 	do {						\
28*47645577SJerome Forissier 		(b)[(i)] = (uint8_t)((n) >> 24);	\
29*47645577SJerome Forissier 		(b)[(i) + 1] = (uint8_t)((n) >> 16);	\
30*47645577SJerome Forissier 		(b)[(i) + 2] = (uint8_t)((n) >>  8);	\
31*47645577SJerome Forissier 		(b)[(i) + 3] = (uint8_t)((n));		\
32*47645577SJerome Forissier 	} while (0)
33*47645577SJerome Forissier 
34*47645577SJerome Forissier void sm3_init(struct sm3_context *ctx)
35*47645577SJerome Forissier {
36*47645577SJerome Forissier 	ctx->total[0] = 0;
37*47645577SJerome Forissier 	ctx->total[1] = 0;
38*47645577SJerome Forissier 
39*47645577SJerome Forissier 	ctx->state[0] = 0x7380166F;
40*47645577SJerome Forissier 	ctx->state[1] = 0x4914B2B9;
41*47645577SJerome Forissier 	ctx->state[2] = 0x172442D7;
42*47645577SJerome Forissier 	ctx->state[3] = 0xDA8A0600;
43*47645577SJerome Forissier 	ctx->state[4] = 0xA96F30BC;
44*47645577SJerome Forissier 	ctx->state[5] = 0x163138AA;
45*47645577SJerome Forissier 	ctx->state[6] = 0xE38DEE4D;
46*47645577SJerome Forissier 	ctx->state[7] = 0xB0FB0E4E;
47*47645577SJerome Forissier }
48*47645577SJerome Forissier 
49*47645577SJerome Forissier static void sm3_process(struct sm3_context *ctx, const uint8_t data[64])
50*47645577SJerome Forissier {
51*47645577SJerome Forissier 	uint32_t SS1, SS2, TT1, TT2, W[68], W1[64];
52*47645577SJerome Forissier 	uint32_t A, B, C, D, E, F, G, H;
53*47645577SJerome Forissier 	uint32_t T[64];
54*47645577SJerome Forissier 	uint32_t Temp1, Temp2, Temp3, Temp4, Temp5;
55*47645577SJerome Forissier 	int j;
56*47645577SJerome Forissier 
57*47645577SJerome Forissier 	for (j = 0; j < 16; j++)
58*47645577SJerome Forissier 		T[j] = 0x79CC4519;
59*47645577SJerome Forissier 	for (j = 16; j < 64; j++)
60*47645577SJerome Forissier 		T[j] = 0x7A879D8A;
61*47645577SJerome Forissier 
62*47645577SJerome Forissier 	GET_UINT32_BE(W[0], data,  0);
63*47645577SJerome Forissier 	GET_UINT32_BE(W[1], data,  4);
64*47645577SJerome Forissier 	GET_UINT32_BE(W[2], data,  8);
65*47645577SJerome Forissier 	GET_UINT32_BE(W[3], data, 12);
66*47645577SJerome Forissier 	GET_UINT32_BE(W[4], data, 16);
67*47645577SJerome Forissier 	GET_UINT32_BE(W[5], data, 20);
68*47645577SJerome Forissier 	GET_UINT32_BE(W[6], data, 24);
69*47645577SJerome Forissier 	GET_UINT32_BE(W[7], data, 28);
70*47645577SJerome Forissier 	GET_UINT32_BE(W[8], data, 32);
71*47645577SJerome Forissier 	GET_UINT32_BE(W[9], data, 36);
72*47645577SJerome Forissier 	GET_UINT32_BE(W[10], data, 40);
73*47645577SJerome Forissier 	GET_UINT32_BE(W[11], data, 44);
74*47645577SJerome Forissier 	GET_UINT32_BE(W[12], data, 48);
75*47645577SJerome Forissier 	GET_UINT32_BE(W[13], data, 52);
76*47645577SJerome Forissier 	GET_UINT32_BE(W[14], data, 56);
77*47645577SJerome Forissier 	GET_UINT32_BE(W[15], data, 60);
78*47645577SJerome Forissier 
79*47645577SJerome Forissier #define FF0(x, y, z)	((x) ^ (y) ^ (z))
80*47645577SJerome Forissier #define FF1(x, y, z)	(((x) & (y)) | ((x) & (z)) | ((y) & (z)))
81*47645577SJerome Forissier 
82*47645577SJerome Forissier #define GG0(x, y, z)	((x) ^ (y) ^ (z))
83*47645577SJerome Forissier #define GG1(x, y, z)	(((x) & (y)) | ((~(x)) & (z)))
84*47645577SJerome Forissier 
85*47645577SJerome Forissier #define SHL(x, n)	((x) << (n))
86*47645577SJerome Forissier #define ROTL(x, n)	(SHL((x), (n)) | ((x) >> (32 - (n))))
87*47645577SJerome Forissier 
88*47645577SJerome Forissier #define P0(x)	((x) ^ ROTL((x), 9) ^ ROTL((x), 17))
89*47645577SJerome Forissier #define P1(x)	((x) ^ ROTL((x), 15) ^ ROTL((x), 23))
90*47645577SJerome Forissier 
91*47645577SJerome Forissier 	for (j = 16; j < 68; j++) {
92*47645577SJerome Forissier 		/*
93*47645577SJerome Forissier 		 * W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^
94*47645577SJerome Forissier 		 *        ROTL(W[j - 13],7 ) ^ W[j-6];
95*47645577SJerome Forissier 		 */
96*47645577SJerome Forissier 
97*47645577SJerome Forissier 		Temp1 = W[j - 16] ^ W[j - 9];
98*47645577SJerome Forissier 		Temp2 = ROTL(W[j - 3], 15);
99*47645577SJerome Forissier 		Temp3 = Temp1 ^ Temp2;
100*47645577SJerome Forissier 		Temp4 = P1(Temp3);
101*47645577SJerome Forissier 		Temp5 =  ROTL(W[j - 13], 7) ^ W[j - 6];
102*47645577SJerome Forissier 		W[j] = Temp4 ^ Temp5;
103*47645577SJerome Forissier 	}
104*47645577SJerome Forissier 
105*47645577SJerome Forissier 	for (j =  0; j < 64; j++)
106*47645577SJerome Forissier 		W1[j] = W[j] ^ W[j + 4];
107*47645577SJerome Forissier 
108*47645577SJerome Forissier 	A = ctx->state[0];
109*47645577SJerome Forissier 	B = ctx->state[1];
110*47645577SJerome Forissier 	C = ctx->state[2];
111*47645577SJerome Forissier 	D = ctx->state[3];
112*47645577SJerome Forissier 	E = ctx->state[4];
113*47645577SJerome Forissier 	F = ctx->state[5];
114*47645577SJerome Forissier 	G = ctx->state[6];
115*47645577SJerome Forissier 	H = ctx->state[7];
116*47645577SJerome Forissier 
117*47645577SJerome Forissier 	for (j = 0; j < 16; j++) {
118*47645577SJerome Forissier 		SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7);
119*47645577SJerome Forissier 		SS2 = SS1 ^ ROTL(A, 12);
120*47645577SJerome Forissier 		TT1 = FF0(A, B, C) + D + SS2 + W1[j];
121*47645577SJerome Forissier 		TT2 = GG0(E, F, G) + H + SS1 + W[j];
122*47645577SJerome Forissier 		D = C;
123*47645577SJerome Forissier 		C = ROTL(B, 9);
124*47645577SJerome Forissier 		B = A;
125*47645577SJerome Forissier 		A = TT1;
126*47645577SJerome Forissier 		H = G;
127*47645577SJerome Forissier 		G = ROTL(F, 19);
128*47645577SJerome Forissier 		F = E;
129*47645577SJerome Forissier 		E = P0(TT2);
130*47645577SJerome Forissier 	}
131*47645577SJerome Forissier 
132*47645577SJerome Forissier 	for (j = 16; j < 64; j++) {
133*47645577SJerome Forissier 		SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7);
134*47645577SJerome Forissier 		SS2 = SS1 ^ ROTL(A, 12);
135*47645577SJerome Forissier 		TT1 = FF1(A, B, C) + D + SS2 + W1[j];
136*47645577SJerome Forissier 		TT2 = GG1(E, F, G) + H + SS1 + W[j];
137*47645577SJerome Forissier 		D = C;
138*47645577SJerome Forissier 		C = ROTL(B, 9);
139*47645577SJerome Forissier 		B = A;
140*47645577SJerome Forissier 		A = TT1;
141*47645577SJerome Forissier 		H = G;
142*47645577SJerome Forissier 		G = ROTL(F, 19);
143*47645577SJerome Forissier 		F = E;
144*47645577SJerome Forissier 		E = P0(TT2);
145*47645577SJerome Forissier 	}
146*47645577SJerome Forissier 
147*47645577SJerome Forissier 	ctx->state[0] ^= A;
148*47645577SJerome Forissier 	ctx->state[1] ^= B;
149*47645577SJerome Forissier 	ctx->state[2] ^= C;
150*47645577SJerome Forissier 	ctx->state[3] ^= D;
151*47645577SJerome Forissier 	ctx->state[4] ^= E;
152*47645577SJerome Forissier 	ctx->state[5] ^= F;
153*47645577SJerome Forissier 	ctx->state[6] ^= G;
154*47645577SJerome Forissier 	ctx->state[7] ^= H;
155*47645577SJerome Forissier }
156*47645577SJerome Forissier 
157*47645577SJerome Forissier void sm3_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen)
158*47645577SJerome Forissier {
159*47645577SJerome Forissier 	size_t fill;
160*47645577SJerome Forissier 	size_t left;
161*47645577SJerome Forissier 
162*47645577SJerome Forissier 	if (!ilen)
163*47645577SJerome Forissier 		return;
164*47645577SJerome Forissier 
165*47645577SJerome Forissier 	left = ctx->total[0] & 0x3F;
166*47645577SJerome Forissier 	fill = 64 - left;
167*47645577SJerome Forissier 
168*47645577SJerome Forissier 	ctx->total[0] += ilen;
169*47645577SJerome Forissier 
170*47645577SJerome Forissier 	if (ctx->total[0] < ilen)
171*47645577SJerome Forissier 		ctx->total[1]++;
172*47645577SJerome Forissier 
173*47645577SJerome Forissier 	if (left && ilen >= fill) {
174*47645577SJerome Forissier 		memcpy(ctx->buffer + left, input, fill);
175*47645577SJerome Forissier 		sm3_process(ctx, ctx->buffer);
176*47645577SJerome Forissier 		input += fill;
177*47645577SJerome Forissier 		ilen -= fill;
178*47645577SJerome Forissier 		left = 0;
179*47645577SJerome Forissier 	}
180*47645577SJerome Forissier 
181*47645577SJerome Forissier 	while (ilen >= 64) {
182*47645577SJerome Forissier 		sm3_process(ctx, input);
183*47645577SJerome Forissier 		input += 64;
184*47645577SJerome Forissier 		ilen -= 64;
185*47645577SJerome Forissier 	}
186*47645577SJerome Forissier 
187*47645577SJerome Forissier 	if (ilen > 0)
188*47645577SJerome Forissier 		memcpy(ctx->buffer + left, input, ilen);
189*47645577SJerome Forissier }
190*47645577SJerome Forissier 
191*47645577SJerome Forissier static const uint8_t sm3_padding[64] = {
192*47645577SJerome Forissier 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
193*47645577SJerome Forissier 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
194*47645577SJerome Forissier 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
195*47645577SJerome Forissier 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
196*47645577SJerome Forissier };
197*47645577SJerome Forissier 
198*47645577SJerome Forissier void sm3_final(struct sm3_context *ctx, uint8_t output[32])
199*47645577SJerome Forissier {
200*47645577SJerome Forissier 	uint32_t last, padn;
201*47645577SJerome Forissier 	uint32_t high, low;
202*47645577SJerome Forissier 	uint8_t msglen[8];
203*47645577SJerome Forissier 
204*47645577SJerome Forissier 	high = (ctx->total[0] >> 29) | (ctx->total[1] <<  3);
205*47645577SJerome Forissier 	low  = ctx->total[0] << 3;
206*47645577SJerome Forissier 
207*47645577SJerome Forissier 	PUT_UINT32_BE(high, msglen, 0);
208*47645577SJerome Forissier 	PUT_UINT32_BE(low,  msglen, 4);
209*47645577SJerome Forissier 
210*47645577SJerome Forissier 	last = ctx->total[0] & 0x3F;
211*47645577SJerome Forissier 	padn = (last < 56) ? (56 - last) : (120 - last);
212*47645577SJerome Forissier 
213*47645577SJerome Forissier 	sm3_update(ctx, sm3_padding, padn);
214*47645577SJerome Forissier 	sm3_update(ctx, msglen, 8);
215*47645577SJerome Forissier 
216*47645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[0], output,  0);
217*47645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[1], output,  4);
218*47645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[2], output,  8);
219*47645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[3], output, 12);
220*47645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[4], output, 16);
221*47645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[5], output, 20);
222*47645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[6], output, 24);
223*47645577SJerome Forissier 	PUT_UINT32_BE(ctx->state[7], output, 28);
224*47645577SJerome Forissier }
225*47645577SJerome Forissier 
226*47645577SJerome Forissier void sm3(const uint8_t *input, size_t ilen, uint8_t output[32])
227*47645577SJerome Forissier {
228*47645577SJerome Forissier 	struct sm3_context ctx = { };
229*47645577SJerome Forissier 
230*47645577SJerome Forissier 	sm3_init(&ctx);
231*47645577SJerome Forissier 	sm3_update(&ctx, input, ilen);
232*47645577SJerome Forissier 	sm3_final(&ctx, output);
233*47645577SJerome Forissier 
234*47645577SJerome Forissier 	memzero_explicit(&ctx, sizeof(ctx));
235*47645577SJerome Forissier }
236*47645577SJerome Forissier 
237*47645577SJerome Forissier void sm3_hmac_init(struct sm3_context *ctx, const uint8_t *key, size_t keylen)
238*47645577SJerome Forissier {
239*47645577SJerome Forissier 	size_t i;
240*47645577SJerome Forissier 	uint8_t sum[32];
241*47645577SJerome Forissier 
242*47645577SJerome Forissier 	if (keylen > 64) {
243*47645577SJerome Forissier 		sm3(key, keylen, sum);
244*47645577SJerome Forissier 		keylen = 32;
245*47645577SJerome Forissier 		key = sum;
246*47645577SJerome Forissier 	}
247*47645577SJerome Forissier 
248*47645577SJerome Forissier 	memset(ctx->ipad, 0x36, 64);
249*47645577SJerome Forissier 	memset(ctx->opad, 0x5C, 64);
250*47645577SJerome Forissier 
251*47645577SJerome Forissier 	for (i = 0; i < keylen; i++) {
252*47645577SJerome Forissier 		ctx->ipad[i] ^= key[i];
253*47645577SJerome Forissier 		ctx->opad[i] ^= key[i];
254*47645577SJerome Forissier 	}
255*47645577SJerome Forissier 
256*47645577SJerome Forissier 	sm3_init(ctx);
257*47645577SJerome Forissier 	sm3_update(ctx, ctx->ipad, 64);
258*47645577SJerome Forissier 
259*47645577SJerome Forissier 	memzero_explicit(sum, sizeof(sum));
260*47645577SJerome Forissier }
261*47645577SJerome Forissier 
262*47645577SJerome Forissier void sm3_hmac_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen)
263*47645577SJerome Forissier {
264*47645577SJerome Forissier 	sm3_update(ctx, input, ilen);
265*47645577SJerome Forissier }
266*47645577SJerome Forissier 
267*47645577SJerome Forissier void sm3_hmac_final(struct sm3_context *ctx, uint8_t output[32])
268*47645577SJerome Forissier {
269*47645577SJerome Forissier 	uint8_t tmpbuf[32];
270*47645577SJerome Forissier 
271*47645577SJerome Forissier 	sm3_final(ctx, tmpbuf);
272*47645577SJerome Forissier 	sm3_init(ctx);
273*47645577SJerome Forissier 	sm3_update(ctx, ctx->opad, 64);
274*47645577SJerome Forissier 	sm3_update(ctx, tmpbuf, 32);
275*47645577SJerome Forissier 	sm3_final(ctx, output);
276*47645577SJerome Forissier 
277*47645577SJerome Forissier 	memzero_explicit(tmpbuf, sizeof(tmpbuf));
278*47645577SJerome Forissier }
279*47645577SJerome Forissier 
280*47645577SJerome Forissier void sm3_hmac(const uint8_t *key, size_t keylen, const uint8_t *input,
281*47645577SJerome Forissier 	      size_t ilen, uint8_t output[32])
282*47645577SJerome Forissier {
283*47645577SJerome Forissier 	struct sm3_context ctx;
284*47645577SJerome Forissier 
285*47645577SJerome Forissier 	sm3_hmac_init(&ctx, key, keylen);
286*47645577SJerome Forissier 	sm3_hmac_update(&ctx, input, ilen);
287*47645577SJerome Forissier 	sm3_hmac_final(&ctx, output);
288*47645577SJerome Forissier 
289*47645577SJerome Forissier 	memzero_explicit(&ctx, sizeof(ctx));
290*47645577SJerome Forissier }
291