xref: /freebsd/sys/contrib/openzfs/module/icp/algs/sha2/sha2_generic.c (revision e6e941e659ab7b3db6786103c1cdc30735a82e32)
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 
80 static void
icp_sha256_generic(uint32_t state[8],const void * data,size_t num_blks)81 icp_sha256_generic(uint32_t state[8], const void *data, size_t num_blks)
82 {
83 	uint64_t blk;
84 
85 	for (blk = 0; blk < num_blks; blk++) {
86 		uint32_t W[16];
87 		uint32_t a, b, c, d, e, f, g, h;
88 		uint32_t T1, T2;
89 		int i;
90 
91 		for (i = 0; i < 16; i++) {
92 			W[i] = BE_32( \
93 			    (((const uint32_t *)(data))[blk * 16 + i]));
94 		}
95 
96 		a = state[0];
97 		b = state[1];
98 		c = state[2];
99 		d = state[3];
100 		e = state[4];
101 		f = state[5];
102 		g = state[6];
103 		h = state[7];
104 
105 		for (i = 0; i <= 63; i += 16) {
106 			COMPRESS(i, 0, SHA256_K);
107 			COMPRESS(i, 1, SHA256_K);
108 			COMPRESS(i, 2, SHA256_K);
109 			COMPRESS(i, 3, SHA256_K);
110 			COMPRESS(i, 4, SHA256_K);
111 			COMPRESS(i, 5, SHA256_K);
112 			COMPRESS(i, 6, SHA256_K);
113 			COMPRESS(i, 7, SHA256_K);
114 			COMPRESS(i, 8, SHA256_K);
115 			COMPRESS(i, 9, SHA256_K);
116 			COMPRESS(i, 10, SHA256_K);
117 			COMPRESS(i, 11, SHA256_K);
118 			COMPRESS(i, 12, SHA256_K);
119 			COMPRESS(i, 13, SHA256_K);
120 			COMPRESS(i, 14, SHA256_K);
121 			COMPRESS(i, 15, SHA256_K);
122 		}
123 
124 		state[0] += a;
125 		state[1] += b;
126 		state[2] += c;
127 		state[3] += d;
128 		state[4] += e;
129 		state[5] += f;
130 		state[6] += g;
131 		state[7] += h;
132 	}
133 }
134 
135 #undef sum0
136 #undef sum1
137 #undef sigma0
138 #undef sigma1
139 
140 #define	rotr64(x, n)	(((x) >> n) | ((x) << (64 - n)))
141 #define	sum0(x)		(rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39))
142 #define	sum1(x)		(rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41))
143 #define	sigma0(x)	(rotr64((x),  1) ^ rotr64((x),  8) ^ ((x) >> 7))
144 #define	sigma1(x)	(rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6))
145 
146 /* SHA512 */
147 static const uint64_t SHA512_K[80] = {
148 	0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
149 	0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
150 	0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
151 	0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
152 	0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
153 	0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
154 	0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
155 	0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
156 	0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
157 	0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
158 	0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
159 	0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
160 	0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
161 	0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
162 	0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
163 	0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
164 	0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
165 	0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
166 	0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
167 	0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
168 	0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
169 	0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
170 	0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
171 	0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
172 	0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
173 	0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
174 	0x5fcb6fab3ad6faec, 0x6c44198c4a475817
175 };
176 
177 static void
icp_sha512_generic(uint64_t state[8],const void * data,size_t num_blks)178 icp_sha512_generic(uint64_t state[8], const void *data, size_t num_blks)
179 {
180 	uint64_t blk;
181 
182 	for (blk = 0; blk < num_blks; blk++) {
183 		uint64_t W[16];
184 		uint64_t a, b, c, d, e, f, g, h;
185 		uint64_t T1, T2;
186 		int i;
187 
188 		for (i = 0; i < 16; i++) {
189 			W[i] = BE_64( \
190 			    (((const uint64_t *)(data))[blk * 16 + i]));
191 		}
192 
193 		a = state[0];
194 		b = state[1];
195 		c = state[2];
196 		d = state[3];
197 		e = state[4];
198 		f = state[5];
199 		g = state[6];
200 		h = state[7];
201 
202 		for (i = 0; i <= 79; i += 16) {
203 			COMPRESS(i, 0, SHA512_K);
204 			COMPRESS(i, 1, SHA512_K);
205 			COMPRESS(i, 2, SHA512_K);
206 			COMPRESS(i, 3, SHA512_K);
207 			COMPRESS(i, 4, SHA512_K);
208 			COMPRESS(i, 5, SHA512_K);
209 			COMPRESS(i, 6, SHA512_K);
210 			COMPRESS(i, 7, SHA512_K);
211 			COMPRESS(i, 8, SHA512_K);
212 			COMPRESS(i, 9, SHA512_K);
213 			COMPRESS(i, 10, SHA512_K);
214 			COMPRESS(i, 11, SHA512_K);
215 			COMPRESS(i, 12, SHA512_K);
216 			COMPRESS(i, 13, SHA512_K);
217 			COMPRESS(i, 14, SHA512_K);
218 			COMPRESS(i, 15, SHA512_K);
219 		}
220 		state[0] += a;
221 		state[1] += b;
222 		state[2] += c;
223 		state[3] += d;
224 		state[4] += e;
225 		state[5] += f;
226 		state[6] += g;
227 		state[7] += h;
228 	}
229 }
230 
231 static void
icp_sha256_update(sha256_ctx * ctx,const uint8_t * data,size_t len)232 icp_sha256_update(sha256_ctx *ctx, const uint8_t *data, size_t len)
233 {
234 	uint64_t pos = ctx->count[0];
235 	uint64_t total = ctx->count[1];
236 	uint8_t *m = ctx->wbuf;
237 	const sha256_ops_t *ops = ctx->ops;
238 
239 	if (pos && pos + len >= 64) {
240 		memcpy(m + pos, data, 64 - pos);
241 		ops->transform(ctx->state, m, 1);
242 		len -= 64 - pos;
243 		total += (64 - pos) * 8;
244 		data += 64 - pos;
245 		pos = 0;
246 	}
247 
248 	if (len >= 64) {
249 		uint32_t blocks = len / 64;
250 		uint32_t bytes = blocks * 64;
251 		ops->transform(ctx->state, data, blocks);
252 		len -= bytes;
253 		total += (bytes) * 8;
254 		data += bytes;
255 	}
256 	memcpy(m + pos, data, len);
257 
258 	pos += len;
259 	total += len * 8;
260 	ctx->count[0] = pos;
261 	ctx->count[1] = total;
262 }
263 
264 static void
icp_sha512_update(sha512_ctx * ctx,const uint8_t * data,size_t len)265 icp_sha512_update(sha512_ctx *ctx, const uint8_t *data, size_t len)
266 {
267 	uint64_t pos = ctx->count[0];
268 	uint64_t total = ctx->count[1];
269 	uint8_t *m = ctx->wbuf;
270 	const sha512_ops_t *ops = ctx->ops;
271 
272 	if (pos && pos + len >= 128) {
273 		memcpy(m + pos, data, 128 - pos);
274 		ops->transform(ctx->state, m, 1);
275 		len -= 128 - pos;
276 		total += (128 - pos) * 8;
277 		data += 128 - pos;
278 		pos = 0;
279 	}
280 
281 	if (len >= 128) {
282 		uint64_t blocks = len / 128;
283 		uint64_t bytes = blocks * 128;
284 		ops->transform(ctx->state, data, blocks);
285 		len -= bytes;
286 		total += (bytes) * 8;
287 		data += bytes;
288 	}
289 	memcpy(m + pos, data, len);
290 
291 	pos += len;
292 	total += len * 8;
293 	ctx->count[0] = pos;
294 	ctx->count[1] = total;
295 }
296 
297 static void
icp_sha256_final(sha256_ctx * ctx,uint8_t * result,int bits)298 icp_sha256_final(sha256_ctx *ctx, uint8_t *result, int bits)
299 {
300 	uint64_t mlen, pos = ctx->count[0];
301 	uint8_t *m = ctx->wbuf;
302 	uint32_t *R = (uint32_t *)result;
303 	const sha256_ops_t *ops = ctx->ops;
304 
305 	m[pos++] = 0x80;
306 	if (pos > 56) {
307 		memset(m + pos, 0, 64 - pos);
308 		ops->transform(ctx->state, m, 1);
309 		pos = 0;
310 	}
311 
312 	memset(m + pos, 0, 64 - pos);
313 	mlen = BE_64(ctx->count[1]);
314 	memcpy(m + (64 - 8), &mlen, 64 / 8);
315 	ops->transform(ctx->state, m, 1);
316 
317 	switch (bits) {
318 	case 224: /* 28 - unused currently /TR */
319 		R[0] = BE_32(ctx->state[0]);
320 		R[1] = BE_32(ctx->state[1]);
321 		R[2] = BE_32(ctx->state[2]);
322 		R[3] = BE_32(ctx->state[3]);
323 		R[4] = BE_32(ctx->state[4]);
324 		R[5] = BE_32(ctx->state[5]);
325 		R[6] = BE_32(ctx->state[6]);
326 		break;
327 	case 256: /* 32 */
328 		R[0] = BE_32(ctx->state[0]);
329 		R[1] = BE_32(ctx->state[1]);
330 		R[2] = BE_32(ctx->state[2]);
331 		R[3] = BE_32(ctx->state[3]);
332 		R[4] = BE_32(ctx->state[4]);
333 		R[5] = BE_32(ctx->state[5]);
334 		R[6] = BE_32(ctx->state[6]);
335 		R[7] = BE_32(ctx->state[7]);
336 		break;
337 	}
338 
339 	memset(ctx, 0, sizeof (*ctx));
340 }
341 
342 static void
icp_sha512_final(sha512_ctx * ctx,uint8_t * result,int bits)343 icp_sha512_final(sha512_ctx *ctx, uint8_t *result, int bits)
344 {
345 	uint64_t mlen, pos = ctx->count[0];
346 	uint8_t *m = ctx->wbuf, *r;
347 	uint64_t *R = (uint64_t *)result;
348 	const sha512_ops_t *ops = ctx->ops;
349 
350 	m[pos++] = 0x80;
351 	if (pos > 112) {
352 		memset(m + pos, 0, 128 - pos);
353 		ops->transform(ctx->state, m, 1);
354 		pos = 0;
355 	}
356 
357 	memset(m + pos, 0, 128 - pos);
358 	mlen = BE_64(ctx->count[1]);
359 	memcpy(m + (128 - 8), &mlen, 64 / 8);
360 	ops->transform(ctx->state, m, 1);
361 
362 	switch (bits) {
363 	case 224: /* 28 => 3,5 x 8 */
364 		r = result + 24;
365 		R[0] = BE_64(ctx->state[0]);
366 		R[1] = BE_64(ctx->state[1]);
367 		R[2] = BE_64(ctx->state[2]);
368 		/* last 4 bytes are special here */
369 		*r++ = (uint8_t)(ctx->state[3] >> 56);
370 		*r++ = (uint8_t)(ctx->state[3] >> 48);
371 		*r++ = (uint8_t)(ctx->state[3] >> 40);
372 		*r++ = (uint8_t)(ctx->state[3] >> 32);
373 		break;
374 	case 256: /* 32 */
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 		break;
380 	case 384: /* 48 */
381 		R[0] = BE_64(ctx->state[0]);
382 		R[1] = BE_64(ctx->state[1]);
383 		R[2] = BE_64(ctx->state[2]);
384 		R[3] = BE_64(ctx->state[3]);
385 		R[4] = BE_64(ctx->state[4]);
386 		R[5] = BE_64(ctx->state[5]);
387 		break;
388 	case 512: /* 64 */
389 		R[0] = BE_64(ctx->state[0]);
390 		R[1] = BE_64(ctx->state[1]);
391 		R[2] = BE_64(ctx->state[2]);
392 		R[3] = BE_64(ctx->state[3]);
393 		R[4] = BE_64(ctx->state[4]);
394 		R[5] = BE_64(ctx->state[5]);
395 		R[6] = BE_64(ctx->state[6]);
396 		R[7] = BE_64(ctx->state[7]);
397 		break;
398 	}
399 
400 	memset(ctx, 0, sizeof (*ctx));
401 }
402 
403 /* SHA2 Init function */
404 void
SHA2Init(int algotype,SHA2_CTX * ctx)405 SHA2Init(int algotype, SHA2_CTX *ctx)
406 {
407 	sha256_ctx *ctx256 = &ctx->sha256;
408 	sha512_ctx *ctx512 = &ctx->sha512;
409 
410 	ASSERT3S(algotype, >=, SHA512_HMAC_MECH_INFO_TYPE);
411 	ASSERT3S(algotype, <=, SHA512_256);
412 
413 	memset(ctx, 0, sizeof (*ctx));
414 	ctx->algotype = algotype;
415 	switch (ctx->algotype) {
416 		case SHA256:
417 			ctx256->state[0] = 0x6a09e667;
418 			ctx256->state[1] = 0xbb67ae85;
419 			ctx256->state[2] = 0x3c6ef372;
420 			ctx256->state[3] = 0xa54ff53a;
421 			ctx256->state[4] = 0x510e527f;
422 			ctx256->state[5] = 0x9b05688c;
423 			ctx256->state[6] = 0x1f83d9ab;
424 			ctx256->state[7] = 0x5be0cd19;
425 			ctx256->count[0] = 0;
426 			ctx256->ops = sha256_get_ops();
427 			break;
428 		case SHA512:
429 		case SHA512_HMAC_MECH_INFO_TYPE:
430 			ctx512->state[0] = 0x6a09e667f3bcc908ULL;
431 			ctx512->state[1] = 0xbb67ae8584caa73bULL;
432 			ctx512->state[2] = 0x3c6ef372fe94f82bULL;
433 			ctx512->state[3] = 0xa54ff53a5f1d36f1ULL;
434 			ctx512->state[4] = 0x510e527fade682d1ULL;
435 			ctx512->state[5] = 0x9b05688c2b3e6c1fULL;
436 			ctx512->state[6] = 0x1f83d9abfb41bd6bULL;
437 			ctx512->state[7] = 0x5be0cd19137e2179ULL;
438 			ctx512->count[0] = 0;
439 			ctx512->count[1] = 0;
440 			ctx512->ops = sha512_get_ops();
441 			break;
442 		case SHA512_256:
443 			ctx512->state[0] = 0x22312194fc2bf72cULL;
444 			ctx512->state[1] = 0x9f555fa3c84c64c2ULL;
445 			ctx512->state[2] = 0x2393b86b6f53b151ULL;
446 			ctx512->state[3] = 0x963877195940eabdULL;
447 			ctx512->state[4] = 0x96283ee2a88effe3ULL;
448 			ctx512->state[5] = 0xbe5e1e2553863992ULL;
449 			ctx512->state[6] = 0x2b0199fc2c85b8aaULL;
450 			ctx512->state[7] = 0x0eb72ddc81c52ca2ULL;
451 			ctx512->count[0] = 0;
452 			ctx512->count[1] = 0;
453 			ctx512->ops = sha512_get_ops();
454 			break;
455 	}
456 }
457 
458 /* SHA2 Update function */
459 void
SHA2Update(SHA2_CTX * ctx,const void * data,size_t len)460 SHA2Update(SHA2_CTX *ctx, const void *data, size_t len)
461 {
462 	/* check for zero input length */
463 	if (len == 0)
464 		return;
465 
466 	ASSERT3P(data, !=, NULL);
467 
468 	switch (ctx->algotype) {
469 		case SHA256:
470 			icp_sha256_update(&ctx->sha256, data, len);
471 			break;
472 		case SHA512:
473 		case SHA512_HMAC_MECH_INFO_TYPE:
474 			icp_sha512_update(&ctx->sha512, data, len);
475 			break;
476 		case SHA512_256:
477 			icp_sha512_update(&ctx->sha512, data, len);
478 			break;
479 	}
480 }
481 
482 /* SHA2Final function */
483 void
SHA2Final(void * digest,SHA2_CTX * ctx)484 SHA2Final(void *digest, SHA2_CTX *ctx)
485 {
486 	switch (ctx->algotype) {
487 		case SHA256:
488 			icp_sha256_final(&ctx->sha256, digest, 256);
489 			break;
490 		case SHA512:
491 		case SHA512_HMAC_MECH_INFO_TYPE:
492 			icp_sha512_final(&ctx->sha512, digest, 512);
493 			break;
494 		case SHA512_256:
495 			icp_sha512_final(&ctx->sha512, digest, 256);
496 			break;
497 	}
498 }
499 
500 /* the generic implementation is always okay */
501 static boolean_t
icp_sha2_is_supported(void)502 icp_sha2_is_supported(void)
503 {
504 	return (B_TRUE);
505 }
506 
507 const sha256_ops_t sha256_generic_impl = {
508 	.name = "generic",
509 	.transform = icp_sha256_generic,
510 	.is_supported = icp_sha2_is_supported
511 };
512 
513 const sha512_ops_t sha512_generic_impl = {
514 	.name = "generic",
515 	.transform = icp_sha512_generic,
516 	.is_supported = icp_sha2_is_supported
517 };
518