xref: /openbsd-src/lib/libcrypto/sm3/sm3.c (revision c18e04ad920918958912f30a26b4d8cbb7002e4d)
1 /*	$OpenBSD: sm3.c,v 1.18 2024/12/12 09:54:44 tb Exp $	*/
2 /*
3  * Copyright (c) 2018, Ribose Inc
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <string.h>
19 
20 #include <openssl/opensslconf.h>
21 
22 #include <openssl/sm3.h>
23 
24 #include "crypto_internal.h"
25 
26 /* Ensure that SM3_WORD and uint32_t are equivalent size. */
27 CTASSERT(sizeof(SM3_WORD) == sizeof(uint32_t));
28 
29 #ifndef OPENSSL_NO_SM3
30 
31 #define P0(X) (X ^ crypto_rol_u32(X, 9) ^ crypto_rol_u32(X, 17))
32 #define P1(X) (X ^ crypto_rol_u32(X, 15) ^ crypto_rol_u32(X, 23))
33 
34 #define FF0(X, Y, Z) (X ^ Y ^ Z)
35 #define GG0(X, Y, Z) (X ^ Y ^ Z)
36 
37 #define FF1(X, Y, Z) ((X & Y) | ((X | Y) & Z))
38 #define GG1(X, Y, Z) ((Z ^ (X & (Y ^ Z))))
39 
40 #define EXPAND(W0, W7, W13, W3, W10) \
41 	(P1(W0 ^ W7 ^ crypto_rol_u32(W13, 15)) ^ crypto_rol_u32(W3, 7) ^ W10)
42 
43 #define ROUND(A, B, C, D, E, F, G, H, TJ, Wi, Wj, FF, GG)	do {	\
44 	const SM3_WORD A12 = crypto_rol_u32(A, 12);				\
45 	const SM3_WORD A12_SM = A12 + E + TJ;				\
46 	const SM3_WORD SS1 = crypto_rol_u32(A12_SM, 7);				\
47 	const SM3_WORD TT1 = FF(A, B, C) + D + (SS1 ^ A12) + (Wj);	\
48 	const SM3_WORD TT2 = GG(E, F, G) + H + SS1 + Wi;		\
49 	B = crypto_rol_u32(B, 9);						\
50 	D = TT1;							\
51 	F = crypto_rol_u32(F, 19);						\
52 	H = P0(TT2);							\
53 } while(0)
54 
55 #define R1(A, B, C, D, E, F, G, H, TJ, Wi, Wj) \
56 	ROUND(A, B, C, D, E, F, G, H, TJ, Wi, Wj, FF0, GG0)
57 
58 #define R2(A, B, C, D, E, F, G, H, TJ, Wi, Wj) \
59 	ROUND(A, B, C, D, E, F, G, H, TJ, Wi, Wj, FF1, GG1)
60 
61 static void
62 sm3_block_data_order(SM3_CTX *ctx, const void *_in, size_t num)
63 {
64 	const uint8_t *in = _in;
65 	const SM3_WORD *in32;
66 	SM3_WORD A, B, C, D, E, F, G, H;
67 	SM3_WORD W00, W01, W02, W03, W04, W05, W06, W07;
68 	SM3_WORD W08, W09, W10, W11, W12, W13, W14, W15;
69 
70 	while (num-- != 0) {
71 		A = ctx->A;
72 		B = ctx->B;
73 		C = ctx->C;
74 		D = ctx->D;
75 		E = ctx->E;
76 		F = ctx->F;
77 		G = ctx->G;
78 		H = ctx->H;
79 
80 		/*
81 		 * We have to load all message bytes immediately since SM3 reads
82 		 * them slightly out of order.
83 		 */
84 		if ((uintptr_t)in % 4 == 0) {
85 			/* Input is 32 bit aligned. */
86 			in32 = (const SM3_WORD *)in;
87 			W00 = be32toh(in32[0]);
88 			W01 = be32toh(in32[1]);
89 			W02 = be32toh(in32[2]);
90 			W03 = be32toh(in32[3]);
91 			W04 = be32toh(in32[4]);
92 			W05 = be32toh(in32[5]);
93 			W06 = be32toh(in32[6]);
94 			W07 = be32toh(in32[7]);
95 			W08 = be32toh(in32[8]);
96 			W09 = be32toh(in32[9]);
97 			W10 = be32toh(in32[10]);
98 			W11 = be32toh(in32[11]);
99 			W12 = be32toh(in32[12]);
100 			W13 = be32toh(in32[13]);
101 			W14 = be32toh(in32[14]);
102 			W15 = be32toh(in32[15]);
103 		} else {
104 			/* Input is not 32 bit aligned. */
105 			W00 = crypto_load_be32toh(&in[0 * 4]);
106 			W01 = crypto_load_be32toh(&in[1 * 4]);
107 			W02 = crypto_load_be32toh(&in[2 * 4]);
108 			W03 = crypto_load_be32toh(&in[3 * 4]);
109 			W04 = crypto_load_be32toh(&in[4 * 4]);
110 			W05 = crypto_load_be32toh(&in[5 * 4]);
111 			W06 = crypto_load_be32toh(&in[6 * 4]);
112 			W07 = crypto_load_be32toh(&in[7 * 4]);
113 			W08 = crypto_load_be32toh(&in[8 * 4]);
114 			W09 = crypto_load_be32toh(&in[9 * 4]);
115 			W10 = crypto_load_be32toh(&in[10 * 4]);
116 			W11 = crypto_load_be32toh(&in[11 * 4]);
117 			W12 = crypto_load_be32toh(&in[12 * 4]);
118 			W13 = crypto_load_be32toh(&in[13 * 4]);
119 			W14 = crypto_load_be32toh(&in[14 * 4]);
120 			W15 = crypto_load_be32toh(&in[15 * 4]);
121 		}
122 		in += SM3_CBLOCK;
123 
124 		R1(A, B, C, D, E, F, G, H, 0x79cc4519, W00, W00 ^ W04);
125 		W00 = EXPAND(W00, W07, W13, W03, W10);
126 		R1(D, A, B, C, H, E, F, G, 0xf3988a32, W01, W01 ^ W05);
127 		W01 = EXPAND(W01, W08, W14, W04, W11);
128 		R1(C, D, A, B, G, H, E, F, 0xe7311465, W02, W02 ^ W06);
129 		W02 = EXPAND(W02, W09, W15, W05, W12);
130 		R1(B, C, D, A, F, G, H, E, 0xce6228cb, W03, W03 ^ W07);
131 		W03 = EXPAND(W03, W10, W00, W06, W13);
132 		R1(A, B, C, D, E, F, G, H, 0x9cc45197, W04, W04 ^ W08);
133 		W04 = EXPAND(W04, W11, W01, W07, W14);
134 		R1(D, A, B, C, H, E, F, G, 0x3988a32f, W05, W05 ^ W09);
135 		W05 = EXPAND(W05, W12, W02, W08, W15);
136 		R1(C, D, A, B, G, H, E, F, 0x7311465e, W06, W06 ^ W10);
137 		W06 = EXPAND(W06, W13, W03, W09, W00);
138 		R1(B, C, D, A, F, G, H, E, 0xe6228cbc, W07, W07 ^ W11);
139 		W07 = EXPAND(W07, W14, W04, W10, W01);
140 		R1(A, B, C, D, E, F, G, H, 0xcc451979, W08, W08 ^ W12);
141 		W08 = EXPAND(W08, W15, W05, W11, W02);
142 		R1(D, A, B, C, H, E, F, G, 0x988a32f3, W09, W09 ^ W13);
143 		W09 = EXPAND(W09, W00, W06, W12, W03);
144 		R1(C, D, A, B, G, H, E, F, 0x311465e7, W10, W10 ^ W14);
145 		W10 = EXPAND(W10, W01, W07, W13, W04);
146 		R1(B, C, D, A, F, G, H, E, 0x6228cbce, W11, W11 ^ W15);
147 		W11 = EXPAND(W11, W02, W08, W14, W05);
148 		R1(A, B, C, D, E, F, G, H, 0xc451979c, W12, W12 ^ W00);
149 		W12 = EXPAND(W12, W03, W09, W15, W06);
150 		R1(D, A, B, C, H, E, F, G, 0x88a32f39, W13, W13 ^ W01);
151 		W13 = EXPAND(W13, W04, W10, W00, W07);
152 		R1(C, D, A, B, G, H, E, F, 0x11465e73, W14, W14 ^ W02);
153 		W14 = EXPAND(W14, W05, W11, W01, W08);
154 		R1(B, C, D, A, F, G, H, E, 0x228cbce6, W15, W15 ^ W03);
155 		W15 = EXPAND(W15, W06, W12, W02, W09);
156 		R2(A, B, C, D, E, F, G, H, 0x9d8a7a87, W00, W00 ^ W04);
157 		W00 = EXPAND(W00, W07, W13, W03, W10);
158 		R2(D, A, B, C, H, E, F, G, 0x3b14f50f, W01, W01 ^ W05);
159 		W01 = EXPAND(W01, W08, W14, W04, W11);
160 		R2(C, D, A, B, G, H, E, F, 0x7629ea1e, W02, W02 ^ W06);
161 		W02 = EXPAND(W02, W09, W15, W05, W12);
162 		R2(B, C, D, A, F, G, H, E, 0xec53d43c, W03, W03 ^ W07);
163 		W03 = EXPAND(W03, W10, W00, W06, W13);
164 		R2(A, B, C, D, E, F, G, H, 0xd8a7a879, W04, W04 ^ W08);
165 		W04 = EXPAND(W04, W11, W01, W07, W14);
166 		R2(D, A, B, C, H, E, F, G, 0xb14f50f3, W05, W05 ^ W09);
167 		W05 = EXPAND(W05, W12, W02, W08, W15);
168 		R2(C, D, A, B, G, H, E, F, 0x629ea1e7, W06, W06 ^ W10);
169 		W06 = EXPAND(W06, W13, W03, W09, W00);
170 		R2(B, C, D, A, F, G, H, E, 0xc53d43ce, W07, W07 ^ W11);
171 		W07 = EXPAND(W07, W14, W04, W10, W01);
172 		R2(A, B, C, D, E, F, G, H, 0x8a7a879d, W08, W08 ^ W12);
173 		W08 = EXPAND(W08, W15, W05, W11, W02);
174 		R2(D, A, B, C, H, E, F, G, 0x14f50f3b, W09, W09 ^ W13);
175 		W09 = EXPAND(W09, W00, W06, W12, W03);
176 		R2(C, D, A, B, G, H, E, F, 0x29ea1e76, W10, W10 ^ W14);
177 		W10 = EXPAND(W10, W01, W07, W13, W04);
178 		R2(B, C, D, A, F, G, H, E, 0x53d43cec, W11, W11 ^ W15);
179 		W11 = EXPAND(W11, W02, W08, W14, W05);
180 		R2(A, B, C, D, E, F, G, H, 0xa7a879d8, W12, W12 ^ W00);
181 		W12 = EXPAND(W12, W03, W09, W15, W06);
182 		R2(D, A, B, C, H, E, F, G, 0x4f50f3b1, W13, W13 ^ W01);
183 		W13 = EXPAND(W13, W04, W10, W00, W07);
184 		R2(C, D, A, B, G, H, E, F, 0x9ea1e762, W14, W14 ^ W02);
185 		W14 = EXPAND(W14, W05, W11, W01, W08);
186 		R2(B, C, D, A, F, G, H, E, 0x3d43cec5, W15, W15 ^ W03);
187 		W15 = EXPAND(W15, W06, W12, W02, W09);
188 		R2(A, B, C, D, E, F, G, H, 0x7a879d8a, W00, W00 ^ W04);
189 		W00 = EXPAND(W00, W07, W13, W03, W10);
190 		R2(D, A, B, C, H, E, F, G, 0xf50f3b14, W01, W01 ^ W05);
191 		W01 = EXPAND(W01, W08, W14, W04, W11);
192 		R2(C, D, A, B, G, H, E, F, 0xea1e7629, W02, W02 ^ W06);
193 		W02 = EXPAND(W02, W09, W15, W05, W12);
194 		R2(B, C, D, A, F, G, H, E, 0xd43cec53, W03, W03 ^ W07);
195 		W03 = EXPAND(W03, W10, W00, W06, W13);
196 		R2(A, B, C, D, E, F, G, H, 0xa879d8a7, W04, W04 ^ W08);
197 		W04 = EXPAND(W04, W11, W01, W07, W14);
198 		R2(D, A, B, C, H, E, F, G, 0x50f3b14f, W05, W05 ^ W09);
199 		W05 = EXPAND(W05, W12, W02, W08, W15);
200 		R2(C, D, A, B, G, H, E, F, 0xa1e7629e, W06, W06 ^ W10);
201 		W06 = EXPAND(W06, W13, W03, W09, W00);
202 		R2(B, C, D, A, F, G, H, E, 0x43cec53d, W07, W07 ^ W11);
203 		W07 = EXPAND(W07, W14, W04, W10, W01);
204 		R2(A, B, C, D, E, F, G, H, 0x879d8a7a, W08, W08 ^ W12);
205 		W08 = EXPAND(W08, W15, W05, W11, W02);
206 		R2(D, A, B, C, H, E, F, G, 0x0f3b14f5, W09, W09 ^ W13);
207 		W09 = EXPAND(W09, W00, W06, W12, W03);
208 		R2(C, D, A, B, G, H, E, F, 0x1e7629ea, W10, W10 ^ W14);
209 		W10 = EXPAND(W10, W01, W07, W13, W04);
210 		R2(B, C, D, A, F, G, H, E, 0x3cec53d4, W11, W11 ^ W15);
211 		W11 = EXPAND(W11, W02, W08, W14, W05);
212 		R2(A, B, C, D, E, F, G, H, 0x79d8a7a8, W12, W12 ^ W00);
213 		W12 = EXPAND(W12, W03, W09, W15, W06);
214 		R2(D, A, B, C, H, E, F, G, 0xf3b14f50, W13, W13 ^ W01);
215 		W13 = EXPAND(W13, W04, W10, W00, W07);
216 		R2(C, D, A, B, G, H, E, F, 0xe7629ea1, W14, W14 ^ W02);
217 		W14 = EXPAND(W14, W05, W11, W01, W08);
218 		R2(B, C, D, A, F, G, H, E, 0xcec53d43, W15, W15 ^ W03);
219 		W15 = EXPAND(W15, W06, W12, W02, W09);
220 		R2(A, B, C, D, E, F, G, H, 0x9d8a7a87, W00, W00 ^ W04);
221 		W00 = EXPAND(W00, W07, W13, W03, W10);
222 		R2(D, A, B, C, H, E, F, G, 0x3b14f50f, W01, W01 ^ W05);
223 		W01 = EXPAND(W01, W08, W14, W04, W11);
224 		R2(C, D, A, B, G, H, E, F, 0x7629ea1e, W02, W02 ^ W06);
225 		W02 = EXPAND(W02, W09, W15, W05, W12);
226 		R2(B, C, D, A, F, G, H, E, 0xec53d43c, W03, W03 ^ W07);
227 		W03 = EXPAND(W03, W10, W00, W06, W13);
228 		R2(A, B, C, D, E, F, G, H, 0xd8a7a879, W04, W04 ^ W08);
229 		R2(D, A, B, C, H, E, F, G, 0xb14f50f3, W05, W05 ^ W09);
230 		R2(C, D, A, B, G, H, E, F, 0x629ea1e7, W06, W06 ^ W10);
231 		R2(B, C, D, A, F, G, H, E, 0xc53d43ce, W07, W07 ^ W11);
232 		R2(A, B, C, D, E, F, G, H, 0x8a7a879d, W08, W08 ^ W12);
233 		R2(D, A, B, C, H, E, F, G, 0x14f50f3b, W09, W09 ^ W13);
234 		R2(C, D, A, B, G, H, E, F, 0x29ea1e76, W10, W10 ^ W14);
235 		R2(B, C, D, A, F, G, H, E, 0x53d43cec, W11, W11 ^ W15);
236 		R2(A, B, C, D, E, F, G, H, 0xa7a879d8, W12, W12 ^ W00);
237 		R2(D, A, B, C, H, E, F, G, 0x4f50f3b1, W13, W13 ^ W01);
238 		R2(C, D, A, B, G, H, E, F, 0x9ea1e762, W14, W14 ^ W02);
239 		R2(B, C, D, A, F, G, H, E, 0x3d43cec5, W15, W15 ^ W03);
240 
241 		ctx->A ^= A;
242 		ctx->B ^= B;
243 		ctx->C ^= C;
244 		ctx->D ^= D;
245 		ctx->E ^= E;
246 		ctx->F ^= F;
247 		ctx->G ^= G;
248 		ctx->H ^= H;
249 	}
250 }
251 
252 int
253 SM3_Init(SM3_CTX *c)
254 {
255 	memset(c, 0, sizeof(*c));
256 
257 	c->A = 0x7380166fUL;
258 	c->B = 0x4914b2b9UL;
259 	c->C = 0x172442d7UL;
260 	c->D = 0xda8a0600UL;
261 	c->E = 0xa96f30bcUL;
262 	c->F = 0x163138aaUL;
263 	c->G = 0xe38dee4dUL;
264 	c->H = 0xb0fb0e4eUL;
265 
266 	return 1;
267 }
268 LCRYPTO_ALIAS(SM3_Init);
269 
270 int
271 SM3_Update(SM3_CTX *c, const void *data_, size_t len)
272 {
273 	const unsigned char *data = data_;
274 	unsigned char *p;
275 	SM3_WORD l;
276 	size_t n;
277 
278 	if (len == 0)
279 		return 1;
280 
281 	l = (c->Nl + (((SM3_WORD)len) << 3))&0xffffffffUL;
282 	/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
283 	 * Wei Dai <weidai@eskimo.com> for pointing it out. */
284 	if (l < c->Nl) /* overflow */
285 		c->Nh++;
286 	c->Nh+=(SM3_WORD)(len>>29);	/* might cause compiler warning on 16-bit */
287 	c->Nl = l;
288 
289 	n = c->num;
290 	if (n != 0) {
291 		p = (unsigned char *)c->data;
292 
293 		if (len >= SM3_CBLOCK || len + n >= SM3_CBLOCK) {
294 			memcpy(p + n, data, SM3_CBLOCK - n);
295 			sm3_block_data_order(c, p, 1);
296 			n = SM3_CBLOCK - n;
297 			data += n;
298 			len -= n;
299 			c->num = 0;
300 			memset(p, 0, SM3_CBLOCK);	/* keep it zeroed */
301 		} else {
302 			memcpy(p + n, data, len);
303 			c->num += (unsigned int)len;
304 			return 1;
305 		}
306 	}
307 
308 	n = len / SM3_CBLOCK;
309 	if (n > 0) {
310 		sm3_block_data_order(c, data, n);
311 		n *= SM3_CBLOCK;
312 		data += n;
313 		len -= n;
314 	}
315 
316 	if (len != 0) {
317 		p = (unsigned char *)c->data;
318 		c->num = (unsigned int)len;
319 		memcpy(p, data, len);
320 	}
321 	return 1;
322 }
323 LCRYPTO_ALIAS(SM3_Update);
324 
325 int
326 SM3_Final(unsigned char *md, SM3_CTX *c)
327 {
328 	unsigned char *p = (unsigned char *)c->data;
329 	size_t n = c->num;
330 
331 	p[n] = 0x80; /* there is always room for one */
332 	n++;
333 
334 	if (n > (SM3_CBLOCK - 8)) {
335 		memset(p + n, 0, SM3_CBLOCK - n);
336 		n = 0;
337 		sm3_block_data_order(c, p, 1);
338 	}
339 
340 	memset(p + n, 0, SM3_CBLOCK - 8 - n);
341 	c->data[SM3_LBLOCK - 2] = htobe32(c->Nh);
342 	c->data[SM3_LBLOCK - 1] = htobe32(c->Nl);
343 
344 	sm3_block_data_order(c, p, 1);
345 	c->num = 0;
346 	memset(p, 0, SM3_CBLOCK);
347 
348 	crypto_store_htobe32(&md[0 * 4], c->A);
349 	crypto_store_htobe32(&md[1 * 4], c->B);
350 	crypto_store_htobe32(&md[2 * 4], c->C);
351 	crypto_store_htobe32(&md[3 * 4], c->D);
352 	crypto_store_htobe32(&md[4 * 4], c->E);
353 	crypto_store_htobe32(&md[5 * 4], c->F);
354 	crypto_store_htobe32(&md[6 * 4], c->G);
355 	crypto_store_htobe32(&md[7 * 4], c->H);
356 
357 	return 1;
358 }
359 LCRYPTO_ALIAS(SM3_Final);
360 
361 #endif /* !OPENSSL_NO_SM3 */
362