Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/cddl/boot/zfs/sha256.c
107442 views
1
/*
2
* CDDL HEADER START
3
*
4
* The contents of this file are subject to the terms of the
5
* Common Development and Distribution License, Version 1.0 only
6
* (the "License"). You may not use this file except in compliance
7
* with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or http://www.opensolaris.org/os/licensing.
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
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24
* Use is subject to license terms.
25
*/
26
/*
27
* Copyright 2013 Saso Kiselkov. All rights reserved.
28
* Copyright 2015 Toomas Soome <[email protected]>
29
*/
30
31
/*
32
* SHA-256 and SHA-512/256 hashes, as specified in FIPS 180-4, available at:
33
* http://csrc.nist.gov/cryptval
34
*
35
* This is a very compact implementation of SHA-256 and SHA-512/256.
36
* It is designed to be simple and portable, not to be fast.
37
*/
38
39
/*
40
* The literal definitions according to FIPS180-4 would be:
41
*
42
* Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
43
* Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
44
*
45
* We use logical equivalents which require one less op.
46
*/
47
#define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
48
#define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y))))
49
#define ROTR(x, n) (((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n))))
50
51
/* SHA-224/256 operations */
52
#define BIGSIGMA0_256(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
53
#define BIGSIGMA1_256(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
54
#define SIGMA0_256(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
55
#define SIGMA1_256(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
56
57
/* SHA-384/512 operations */
58
#define BIGSIGMA0_512(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
59
#define BIGSIGMA1_512(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
60
#define SIGMA0_512(x) (ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
61
#define SIGMA1_512(x) (ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))
62
63
/* SHA-256 round constants */
64
static const uint32_t SHA256_K[64] = {
65
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
66
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
67
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
68
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
69
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
70
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
71
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
72
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
73
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
74
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
75
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
76
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
77
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
78
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
79
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
80
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
81
};
82
83
/* SHA-512 round constants */
84
static const uint64_t SHA512_K[80] = {
85
0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
86
0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
87
0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
88
0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
89
0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
90
0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
91
0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
92
0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
93
0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
94
0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
95
0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
96
0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
97
0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
98
0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
99
0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
100
0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
101
0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
102
0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
103
0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
104
0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
105
0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
106
0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
107
0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
108
0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
109
0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
110
0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
111
0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
112
0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
113
0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
114
0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
115
0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
116
0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
117
0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
118
0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
119
0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
120
0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
121
0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
122
0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
123
0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
124
0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
125
};
126
127
static void
128
SHA256Transform(uint32_t *H, const uint8_t *cp)
129
{
130
uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
131
132
/* copy chunk into the first 16 words of the message schedule */
133
for (t = 0; t < 16; t++, cp += sizeof (uint32_t))
134
W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
135
136
/* extend the first 16 words into the remaining 48 words */
137
for (t = 16; t < 64; t++)
138
W[t] = SIGMA1_256(W[t - 2]) + W[t - 7] +
139
SIGMA0_256(W[t - 15]) + W[t - 16];
140
141
/* init working variables to the current hash value */
142
a = H[0]; b = H[1]; c = H[2]; d = H[3];
143
e = H[4]; f = H[5]; g = H[6]; h = H[7];
144
145
/* iterate the compression function for all rounds of the hash */
146
for (t = 0; t < 64; t++) {
147
T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
148
T2 = BIGSIGMA0_256(a) + Maj(a, b, c);
149
h = g; g = f; f = e; e = d + T1;
150
d = c; c = b; b = a; a = T1 + T2;
151
}
152
153
/* add the compressed chunk to the current hash value */
154
H[0] += a; H[1] += b; H[2] += c; H[3] += d;
155
H[4] += e; H[5] += f; H[6] += g; H[7] += h;
156
}
157
158
static void
159
SHA512Transform(uint64_t *H, const uint8_t *cp)
160
{
161
uint64_t a, b, c, d, e, f, g, h, t, T1, T2, W[80];
162
163
/* copy chunk into the first 16 words of the message schedule */
164
for (t = 0; t < 16; t++, cp += sizeof (uint64_t))
165
W[t] = ((uint64_t)cp[0] << 56) | ((uint64_t)cp[1] << 48) |
166
((uint64_t)cp[2] << 40) | ((uint64_t)cp[3] << 32) |
167
((uint64_t)cp[4] << 24) | ((uint64_t)cp[5] << 16) |
168
((uint64_t)cp[6] << 8) | (uint64_t)cp[7];
169
170
/* extend the first 16 words into the remaining 64 words */
171
for (t = 16; t < 80; t++)
172
W[t] = SIGMA1_512(W[t - 2]) + W[t - 7] +
173
SIGMA0_512(W[t - 15]) + W[t - 16];
174
175
/* init working variables to the current hash value */
176
a = H[0]; b = H[1]; c = H[2]; d = H[3];
177
e = H[4]; f = H[5]; g = H[6]; h = H[7];
178
179
/* iterate the compression function for all rounds of the hash */
180
for (t = 0; t < 80; t++) {
181
T1 = h + BIGSIGMA1_512(e) + Ch(e, f, g) + SHA512_K[t] + W[t];
182
T2 = BIGSIGMA0_512(a) + Maj(a, b, c);
183
h = g; g = f; f = e; e = d + T1;
184
d = c; c = b; b = a; a = T1 + T2;
185
}
186
187
/* add the compressed chunk to the current hash value */
188
H[0] += a; H[1] += b; H[2] += c; H[3] += d;
189
H[4] += e; H[5] += f; H[6] += g; H[7] += h;
190
}
191
192
/*
193
* Implements the SHA-224 and SHA-256 hash algos - to select between them
194
* pass the appropriate initial values of 'H' and truncate the last 32 bits
195
* in case of SHA-224.
196
*/
197
static void
198
SHA256(uint32_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
199
{
200
uint8_t pad[128];
201
unsigned padsize = size & 63;
202
unsigned i, k;
203
204
/* process all blocks up to the last one */
205
for (i = 0; i < size - padsize; i += 64)
206
SHA256Transform(H, (const uint8_t *)buf + i);
207
208
/* process the last block and padding */
209
for (k = 0; k < padsize; k++)
210
pad[k] = ((const uint8_t *)buf)[k + i];
211
212
for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
213
pad[padsize] = 0;
214
215
for (i = 0; i < 8; i++)
216
pad[padsize++] = (size << 3) >> (56 - 8 * i);
217
218
for (i = 0; i < padsize; i += 64)
219
SHA256Transform(H, pad + i);
220
221
ZIO_SET_CHECKSUM(zcp,
222
(uint64_t)H[0] << 32 | H[1],
223
(uint64_t)H[2] << 32 | H[3],
224
(uint64_t)H[4] << 32 | H[5],
225
(uint64_t)H[6] << 32 | H[7]);
226
}
227
228
/*
229
* encode 64bit data in big-endian format.
230
*/
231
static void
232
Encode64(uint8_t *output, uint64_t *input, size_t len)
233
{
234
size_t i, j;
235
for (i = 0, j = 0; j < len; i++, j += 8) {
236
output[j] = (input[i] >> 56) & 0xff;
237
output[j + 1] = (input[i] >> 48) & 0xff;
238
output[j + 2] = (input[i] >> 40) & 0xff;
239
output[j + 3] = (input[i] >> 32) & 0xff;
240
output[j + 4] = (input[i] >> 24) & 0xff;
241
output[j + 5] = (input[i] >> 16) & 0xff;
242
output[j + 6] = (input[i] >> 8) & 0xff;
243
output[j + 7] = input[i] & 0xff;
244
}
245
}
246
247
/*
248
* Implements the SHA-384, SHA-512 and SHA-512/t hash algos - to select
249
* between them pass the appropriate initial values for 'H'. The output
250
* of this function is truncated to the first 256 bits that fit into 'zcp'.
251
*/
252
static void
253
SHA512(uint64_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
254
{
255
uint64_t c64[2];
256
uint8_t pad[256];
257
unsigned padsize = size & 127;
258
unsigned i, k;
259
260
/* process all blocks up to the last one */
261
for (i = 0; i < size - padsize; i += 128)
262
SHA512Transform(H, (const uint8_t *)buf + i);
263
264
/* process the last block and padding */
265
for (k = 0; k < padsize; k++)
266
pad[k] = ((const uint8_t *)buf)[k + i];
267
268
if (padsize < 112) {
269
for (pad[padsize++] = 0x80; padsize < 112; padsize++)
270
pad[padsize] = 0;
271
} else {
272
for (pad[padsize++] = 0x80; padsize < 240; padsize++)
273
pad[padsize] = 0;
274
}
275
276
c64[0] = 0;
277
c64[1] = size << 3;
278
Encode64(pad+padsize, c64, sizeof (c64));
279
padsize += sizeof (c64);
280
281
for (i = 0; i < padsize; i += 128)
282
SHA512Transform(H, pad + i);
283
284
/* truncate the output to the first 256 bits which fit into 'zcp' */
285
Encode64((uint8_t *)zcp, H, sizeof (uint64_t) * 4);
286
}
287
288
static void
289
zio_checksum_SHA256(const void *buf, uint64_t size,
290
const void *ctx_template __unused, zio_cksum_t *zcp)
291
{
292
/* SHA-256 as per FIPS 180-4. */
293
uint32_t H[] = {
294
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
295
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
296
};
297
SHA256(H, buf, size, zcp);
298
}
299
300
static void
301
zio_checksum_SHA512_native(const void *buf, uint64_t size,
302
const void *ctx_template __unused, zio_cksum_t *zcp)
303
{
304
/* SHA-512/256 as per FIPS 180-4. */
305
uint64_t H[] = {
306
0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL,
307
0x2393B86B6F53B151ULL, 0x963877195940EABDULL,
308
0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL,
309
0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL
310
};
311
SHA512(H, buf, size, zcp);
312
}
313
314
static void
315
zio_checksum_SHA512_byteswap(const void *buf, uint64_t size,
316
const void *ctx_template, zio_cksum_t *zcp)
317
{
318
zio_cksum_t tmp;
319
320
zio_checksum_SHA512_native(buf, size, ctx_template, &tmp);
321
zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]);
322
zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]);
323
zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]);
324
zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]);
325
}
326
327