xref: /freebsd/sys/contrib/openzfs/module/icp/algs/sha2/sha2_generic.c (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * CDDL HEADER START
4  *
5  * The contents of this file are subject to the terms of the
6  * Common Development and Distribution License (the "License").
7  * You may not use this file except in compliance with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or https://opensource.org/licenses/CDDL-1.0.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Based on public domain code in cppcrypto 0.10.
25  * Copyright (c) 2022 Tino Reichardt <milky-zfs@mcmilk.de>
26  */
27 
28 #include <sys/zfs_context.h>
29 #include <sys/zfs_impl.h>
30 #include <sys/sha2.h>
31 
32 #include <sha2/sha2_impl.h>
33 
34 /*
35  * On i386, gcc brings this for sha512_generic():
36  * error: the frame size of 1040 bytes is larger than 1024
37  */
38 #if defined(__GNUC__) && defined(_ILP32)
39 #pragma GCC diagnostic ignored "-Wframe-larger-than="
40 #endif
41 
42 /* SHA256 */
43 static const uint32_t SHA256_K[64] = {
44 	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
45 	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
46 	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
47 	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
48 	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
49 	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
50 	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
51 	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
52 	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
53 	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
54 	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
55 	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
56 	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
57 	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
58 	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
59 	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
60 };
61 
62 #define	Ch(x, y, z)	((z) ^ ((x) & ((y) ^ (z))))
63 #define	Maj(x, y, z)	(((y) & (z)) | (((y) | (z)) & (x)))
64 
65 #define	rotr32(x, n)	(((x) >> n) | ((x) << (32 - n)))
66 #define	sum0(x)		(rotr32((x),  2) ^ rotr32((x), 13) ^ rotr32((x), 22))
67 #define	sum1(x)		(rotr32((x),  6) ^ rotr32((x), 11) ^ rotr32((x), 25))
68 #define	sigma0(x)	(rotr32((x),  7) ^ rotr32((x), 18) ^ ((x) >> 3))
69 #define	sigma1(x)	(rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))
70 
71 #define	WU(j) (W[j & 15] += sigma1(W[(j + 14) & 15]) \
72 	+ W[(j + 9) & 15] + sigma0(W[(j + 1) & 15]))
73 
74 #define	COMPRESS(i, j, K) \
75 	T1 = h + sum1(e) + Ch(e, f, g) + K[i + j] + (i? WU(j): W[j]); \
76 	T2 = sum0(a) + Maj(a, b, c); \
77 	h = g, g = f, f = e, e = d + T1; \
78 	d = c, c = b, b = a, a = T1 + T2;
79 
sha256_generic(uint32_t state[8],const void * data,size_t num_blks)80 static void sha256_generic(uint32_t state[8], const void *data, size_t num_blks)
81 {
82 	uint64_t blk;
83 
84 	for (blk = 0; blk < num_blks; blk++) {
85 		uint32_t W[16];
86 		uint32_t a, b, c, d, e, f, g, h;
87 		uint32_t T1, T2;
88 		int i;
89 
90 		for (i = 0; i < 16; i++) {
91 			W[i] = BE_32( \
92 			    (((const uint32_t *)(data))[blk * 16 + i]));
93 		}
94 
95 		a = state[0];
96 		b = state[1];
97 		c = state[2];
98 		d = state[3];
99 		e = state[4];
100 		f = state[5];
101 		g = state[6];
102 		h = state[7];
103 
104 		for (i = 0; i <= 63; i += 16) {
105 			COMPRESS(i, 0, SHA256_K);
106 			COMPRESS(i, 1, SHA256_K);
107 			COMPRESS(i, 2, SHA256_K);
108 			COMPRESS(i, 3, SHA256_K);
109 			COMPRESS(i, 4, SHA256_K);
110 			COMPRESS(i, 5, SHA256_K);
111 			COMPRESS(i, 6, SHA256_K);
112 			COMPRESS(i, 7, SHA256_K);
113 			COMPRESS(i, 8, SHA256_K);
114 			COMPRESS(i, 9, SHA256_K);
115 			COMPRESS(i, 10, SHA256_K);
116 			COMPRESS(i, 11, SHA256_K);
117 			COMPRESS(i, 12, SHA256_K);
118 			COMPRESS(i, 13, SHA256_K);
119 			COMPRESS(i, 14, SHA256_K);
120 			COMPRESS(i, 15, SHA256_K);
121 		}
122 
123 		state[0] += a;
124 		state[1] += b;
125 		state[2] += c;
126 		state[3] += d;
127 		state[4] += e;
128 		state[5] += f;
129 		state[6] += g;
130 		state[7] += h;
131 	}
132 }
133 
134 #undef sum0
135 #undef sum1
136 #undef sigma0
137 #undef sigma1
138 
139 #define	rotr64(x, n)	(((x) >> n) | ((x) << (64 - n)))
140 #define	sum0(x)		(rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39))
141 #define	sum1(x)		(rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41))
142 #define	sigma0(x)	(rotr64((x),  1) ^ rotr64((x),  8) ^ ((x) >> 7))
143 #define	sigma1(x)	(rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6))
144 
145 /* SHA512 */
146 static const uint64_t SHA512_K[80] = {
147 	0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
148 	0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
149 	0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
150 	0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
151 	0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
152 	0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
153 	0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
154 	0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
155 	0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
156 	0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
157 	0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
158 	0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
159 	0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
160 	0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
161 	0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
162 	0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
163 	0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
164 	0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
165 	0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
166 	0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
167 	0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
168 	0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
169 	0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
170 	0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
171 	0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
172 	0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
173 	0x5fcb6fab3ad6faec, 0x6c44198c4a475817
174 };
175 
sha512_generic(uint64_t state[8],const void * data,size_t num_blks)176 static void sha512_generic(uint64_t state[8], const void *data, size_t num_blks)
177 {
178 	uint64_t blk;
179 
180 	for (blk = 0; blk < num_blks; blk++) {
181 		uint64_t W[16];
182 		uint64_t a, b, c, d, e, f, g, h;
183 		uint64_t T1, T2;
184 		int i;
185 
186 		for (i = 0; i < 16; i++) {
187 			W[i] = BE_64( \
188 			    (((const uint64_t *)(data))[blk * 16 + i]));
189 		}
190 
191 		a = state[0];
192 		b = state[1];
193 		c = state[2];
194 		d = state[3];
195 		e = state[4];
196 		f = state[5];
197 		g = state[6];
198 		h = state[7];
199 
200 		for (i = 0; i <= 79; i += 16) {
201 			COMPRESS(i, 0, SHA512_K);
202 			COMPRESS(i, 1, SHA512_K);
203 			COMPRESS(i, 2, SHA512_K);
204 			COMPRESS(i, 3, SHA512_K);
205 			COMPRESS(i, 4, SHA512_K);
206 			COMPRESS(i, 5, SHA512_K);
207 			COMPRESS(i, 6, SHA512_K);
208 			COMPRESS(i, 7, SHA512_K);
209 			COMPRESS(i, 8, SHA512_K);
210 			COMPRESS(i, 9, SHA512_K);
211 			COMPRESS(i, 10, SHA512_K);
212 			COMPRESS(i, 11, SHA512_K);
213 			COMPRESS(i, 12, SHA512_K);
214 			COMPRESS(i, 13, SHA512_K);
215 			COMPRESS(i, 14, SHA512_K);
216 			COMPRESS(i, 15, SHA512_K);
217 		}
218 		state[0] += a;
219 		state[1] += b;
220 		state[2] += c;
221 		state[3] += d;
222 		state[4] += e;
223 		state[5] += f;
224 		state[6] += g;
225 		state[7] += h;
226 	}
227 }
228 
sha256_update(sha256_ctx * ctx,const uint8_t * data,size_t len)229 static void sha256_update(sha256_ctx *ctx, const uint8_t *data, size_t len)
230 {
231 	uint64_t pos = ctx->count[0];
232 	uint64_t total = ctx->count[1];
233 	uint8_t *m = ctx->wbuf;
234 	const sha256_ops_t *ops = ctx->ops;
235 
236 	if (pos && pos + len >= 64) {
237 		memcpy(m + pos, data, 64 - pos);
238 		ops->transform(ctx->state, m, 1);
239 		len -= 64 - pos;
240 		total += (64 - pos) * 8;
241 		data += 64 - pos;
242 		pos = 0;
243 	}
244 
245 	if (len >= 64) {
246 		uint32_t blocks = len / 64;
247 		uint32_t bytes = blocks * 64;
248 		ops->transform(ctx->state, data, blocks);
249 		len -= bytes;
250 		total += (bytes) * 8;
251 		data += bytes;
252 	}
253 	memcpy(m + pos, data, len);
254 
255 	pos += len;
256 	total += len * 8;
257 	ctx->count[0] = pos;
258 	ctx->count[1] = total;
259 }
260 
sha512_update(sha512_ctx * ctx,const uint8_t * data,size_t len)261 static void sha512_update(sha512_ctx *ctx, const uint8_t *data, size_t len)
262 {
263 	uint64_t pos = ctx->count[0];
264 	uint64_t total = ctx->count[1];
265 	uint8_t *m = ctx->wbuf;
266 	const sha512_ops_t *ops = ctx->ops;
267 
268 	if (pos && pos + len >= 128) {
269 		memcpy(m + pos, data, 128 - pos);
270 		ops->transform(ctx->state, m, 1);
271 		len -= 128 - pos;
272 		total += (128 - pos) * 8;
273 		data += 128 - pos;
274 		pos = 0;
275 	}
276 
277 	if (len >= 128) {
278 		uint64_t blocks = len / 128;
279 		uint64_t bytes = blocks * 128;
280 		ops->transform(ctx->state, data, blocks);
281 		len -= bytes;
282 		total += (bytes) * 8;
283 		data += bytes;
284 	}
285 	memcpy(m + pos, data, len);
286 
287 	pos += len;
288 	total += len * 8;
289 	ctx->count[0] = pos;
290 	ctx->count[1] = total;
291 }
292 
sha256_final(sha256_ctx * ctx,uint8_t * result,int bits)293 static void sha256_final(sha256_ctx *ctx, uint8_t *result, int bits)
294 {
295 	uint64_t mlen, pos = ctx->count[0];
296 	uint8_t *m = ctx->wbuf;
297 	uint32_t *R = (uint32_t *)result;
298 	const sha256_ops_t *ops = ctx->ops;
299 
300 	m[pos++] = 0x80;
301 	if (pos > 56) {
302 		memset(m + pos, 0, 64 - pos);
303 		ops->transform(ctx->state, m, 1);
304 		pos = 0;
305 	}
306 
307 	memset(m + pos, 0, 64 - pos);
308 	mlen = BE_64(ctx->count[1]);
309 	memcpy(m + (64 - 8), &mlen, 64 / 8);
310 	ops->transform(ctx->state, m, 1);
311 
312 	switch (bits) {
313 	case 224: /* 28 - unused currently /TR */
314 		R[0] = BE_32(ctx->state[0]);
315 		R[1] = BE_32(ctx->state[1]);
316 		R[2] = BE_32(ctx->state[2]);
317 		R[3] = BE_32(ctx->state[3]);
318 		R[4] = BE_32(ctx->state[4]);
319 		R[5] = BE_32(ctx->state[5]);
320 		R[6] = BE_32(ctx->state[6]);
321 		break;
322 	case 256: /* 32 */
323 		R[0] = BE_32(ctx->state[0]);
324 		R[1] = BE_32(ctx->state[1]);
325 		R[2] = BE_32(ctx->state[2]);
326 		R[3] = BE_32(ctx->state[3]);
327 		R[4] = BE_32(ctx->state[4]);
328 		R[5] = BE_32(ctx->state[5]);
329 		R[6] = BE_32(ctx->state[6]);
330 		R[7] = BE_32(ctx->state[7]);
331 		break;
332 	}
333 
334 	memset(ctx, 0, sizeof (*ctx));
335 }
336 
sha512_final(sha512_ctx * ctx,uint8_t * result,int bits)337 static void sha512_final(sha512_ctx *ctx, uint8_t *result, int bits)
338 {
339 	uint64_t mlen, pos = ctx->count[0];
340 	uint8_t *m = ctx->wbuf, *r;
341 	uint64_t *R = (uint64_t *)result;
342 	const sha512_ops_t *ops = ctx->ops;
343 
344 	m[pos++] = 0x80;
345 	if (pos > 112) {
346 		memset(m + pos, 0, 128 - pos);
347 		ops->transform(ctx->state, m, 1);
348 		pos = 0;
349 	}
350 
351 	memset(m + pos, 0, 128 - pos);
352 	mlen = BE_64(ctx->count[1]);
353 	memcpy(m + (128 - 8), &mlen, 64 / 8);
354 	ops->transform(ctx->state, m, 1);
355 
356 	switch (bits) {
357 	case 224: /* 28 => 3,5 x 8 */
358 		r = result + 24;
359 		R[0] = BE_64(ctx->state[0]);
360 		R[1] = BE_64(ctx->state[1]);
361 		R[2] = BE_64(ctx->state[2]);
362 		/* last 4 bytes are special here */
363 		*r++ = (uint8_t)(ctx->state[3] >> 56);
364 		*r++ = (uint8_t)(ctx->state[3] >> 48);
365 		*r++ = (uint8_t)(ctx->state[3] >> 40);
366 		*r++ = (uint8_t)(ctx->state[3] >> 32);
367 		break;
368 	case 256: /* 32 */
369 		R[0] = BE_64(ctx->state[0]);
370 		R[1] = BE_64(ctx->state[1]);
371 		R[2] = BE_64(ctx->state[2]);
372 		R[3] = BE_64(ctx->state[3]);
373 		break;
374 	case 384: /* 48 */
375 		R[0] = BE_64(ctx->state[0]);
376 		R[1] = BE_64(ctx->state[1]);
377 		R[2] = BE_64(ctx->state[2]);
378 		R[3] = BE_64(ctx->state[3]);
379 		R[4] = BE_64(ctx->state[4]);
380 		R[5] = BE_64(ctx->state[5]);
381 		break;
382 	case 512: /* 64 */
383 		R[0] = BE_64(ctx->state[0]);
384 		R[1] = BE_64(ctx->state[1]);
385 		R[2] = BE_64(ctx->state[2]);
386 		R[3] = BE_64(ctx->state[3]);
387 		R[4] = BE_64(ctx->state[4]);
388 		R[5] = BE_64(ctx->state[5]);
389 		R[6] = BE_64(ctx->state[6]);
390 		R[7] = BE_64(ctx->state[7]);
391 		break;
392 	}
393 
394 	memset(ctx, 0, sizeof (*ctx));
395 }
396 
397 /* SHA2 Init function */
398 void
SHA2Init(int algotype,SHA2_CTX * ctx)399 SHA2Init(int algotype, SHA2_CTX *ctx)
400 {
401 	sha256_ctx *ctx256 = &ctx->sha256;
402 	sha512_ctx *ctx512 = &ctx->sha512;
403 
404 	ASSERT3S(algotype, >=, SHA512_HMAC_MECH_INFO_TYPE);
405 	ASSERT3S(algotype, <=, SHA512_256);
406 
407 	memset(ctx, 0, sizeof (*ctx));
408 	ctx->algotype = algotype;
409 	switch (ctx->algotype) {
410 		case SHA256:
411 			ctx256->state[0] = 0x6a09e667;
412 			ctx256->state[1] = 0xbb67ae85;
413 			ctx256->state[2] = 0x3c6ef372;
414 			ctx256->state[3] = 0xa54ff53a;
415 			ctx256->state[4] = 0x510e527f;
416 			ctx256->state[5] = 0x9b05688c;
417 			ctx256->state[6] = 0x1f83d9ab;
418 			ctx256->state[7] = 0x5be0cd19;
419 			ctx256->count[0] = 0;
420 			ctx256->ops = sha256_get_ops();
421 			break;
422 		case SHA512:
423 		case SHA512_HMAC_MECH_INFO_TYPE:
424 			ctx512->state[0] = 0x6a09e667f3bcc908ULL;
425 			ctx512->state[1] = 0xbb67ae8584caa73bULL;
426 			ctx512->state[2] = 0x3c6ef372fe94f82bULL;
427 			ctx512->state[3] = 0xa54ff53a5f1d36f1ULL;
428 			ctx512->state[4] = 0x510e527fade682d1ULL;
429 			ctx512->state[5] = 0x9b05688c2b3e6c1fULL;
430 			ctx512->state[6] = 0x1f83d9abfb41bd6bULL;
431 			ctx512->state[7] = 0x5be0cd19137e2179ULL;
432 			ctx512->count[0] = 0;
433 			ctx512->count[1] = 0;
434 			ctx512->ops = sha512_get_ops();
435 			break;
436 		case SHA512_256:
437 			ctx512->state[0] = 0x22312194fc2bf72cULL;
438 			ctx512->state[1] = 0x9f555fa3c84c64c2ULL;
439 			ctx512->state[2] = 0x2393b86b6f53b151ULL;
440 			ctx512->state[3] = 0x963877195940eabdULL;
441 			ctx512->state[4] = 0x96283ee2a88effe3ULL;
442 			ctx512->state[5] = 0xbe5e1e2553863992ULL;
443 			ctx512->state[6] = 0x2b0199fc2c85b8aaULL;
444 			ctx512->state[7] = 0x0eb72ddc81c52ca2ULL;
445 			ctx512->count[0] = 0;
446 			ctx512->count[1] = 0;
447 			ctx512->ops = sha512_get_ops();
448 			break;
449 	}
450 }
451 
452 /* SHA2 Update function */
453 void
SHA2Update(SHA2_CTX * ctx,const void * data,size_t len)454 SHA2Update(SHA2_CTX *ctx, const void *data, size_t len)
455 {
456 	/* check for zero input length */
457 	if (len == 0)
458 		return;
459 
460 	ASSERT3P(data, !=, NULL);
461 
462 	switch (ctx->algotype) {
463 		case SHA256:
464 			sha256_update(&ctx->sha256, data, len);
465 			break;
466 		case SHA512:
467 		case SHA512_HMAC_MECH_INFO_TYPE:
468 			sha512_update(&ctx->sha512, data, len);
469 			break;
470 		case SHA512_256:
471 			sha512_update(&ctx->sha512, data, len);
472 			break;
473 	}
474 }
475 
476 /* SHA2Final function */
477 void
SHA2Final(void * digest,SHA2_CTX * ctx)478 SHA2Final(void *digest, SHA2_CTX *ctx)
479 {
480 	switch (ctx->algotype) {
481 		case SHA256:
482 			sha256_final(&ctx->sha256, digest, 256);
483 			break;
484 		case SHA512:
485 		case SHA512_HMAC_MECH_INFO_TYPE:
486 			sha512_final(&ctx->sha512, digest, 512);
487 			break;
488 		case SHA512_256:
489 			sha512_final(&ctx->sha512, digest, 256);
490 			break;
491 	}
492 }
493 
494 /* the generic implementation is always okay */
sha2_is_supported(void)495 static boolean_t sha2_is_supported(void)
496 {
497 	return (B_TRUE);
498 }
499 
500 const sha256_ops_t sha256_generic_impl = {
501 	.name = "generic",
502 	.transform = sha256_generic,
503 	.is_supported = sha2_is_supported
504 };
505 
506 const sha512_ops_t sha512_generic_impl = {
507 	.name = "generic",
508 	.transform = sha512_generic,
509 	.is_supported = sha2_is_supported
510 };
511