xref: /trueos/lib/libmd/sha512c.c (revision 8fe640108653f13042f1b15213769e338aa524f6)
1 /*-
2  * Copyright 2005 Colin Percival
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/endian.h>
31 #include <sys/types.h>
32 
33 #include <string.h>
34 
35 #include "sha512.h"
36 
37 #if BYTE_ORDER == BIG_ENDIAN
38 
39 /* Copy a vector of big-endian uint64_t into a vector of bytes */
40 #define be64enc_vect(dst, src, len)	\
41 	memcpy((void *)dst, (const void *)src, (size_t)len)
42 
43 /* Copy a vector of bytes into a vector of big-endian uint64_t */
44 #define be64dec_vect(dst, src, len)	\
45 	memcpy((void *)dst, (const void *)src, (size_t)len)
46 
47 #else /* BYTE_ORDER != BIG_ENDIAN */
48 
49 /*
50  * Encode a length len/4 vector of (uint64_t) into a length len vector of
51  * (unsigned char) in big-endian form.  Assumes len is a multiple of 8.
52  */
53 static void
be64enc_vect(unsigned char * dst,const uint64_t * src,size_t len)54 be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
55 {
56 	size_t i;
57 
58 	for (i = 0; i < len / 8; i++)
59 		be64enc(dst + i * 8, src[i]);
60 }
61 
62 /*
63  * Decode a big-endian length len vector of (unsigned char) into a length
64  * len/4 vector of (uint64_t).  Assumes len is a multiple of 8.
65  */
66 static void
be64dec_vect(uint64_t * dst,const unsigned char * src,size_t len)67 be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
68 {
69 	size_t i;
70 
71 	for (i = 0; i < len / 8; i++)
72 		dst[i] = be64dec(src + i * 8);
73 }
74 
75 #endif /* BYTE_ORDER != BIG_ENDIAN */
76 
77 /* Elementary functions used by SHA512 */
78 #define Ch(x, y, z)	((x & (y ^ z)) ^ z)
79 #define Maj(x, y, z)	((x & (y | z)) | (y & z))
80 #define SHR(x, n)	(x >> n)
81 #define ROTR(x, n)	((x >> n) | (x << (64 - n)))
82 #define S0(x)		(ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
83 #define S1(x)		(ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
84 #define s0(x)		(ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
85 #define s1(x)		(ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
86 
87 /* SHA512 round function */
88 #define RND(a, b, c, d, e, f, g, h, k)			\
89 	t0 = h + S1(e) + Ch(e, f, g) + k;		\
90 	t1 = S0(a) + Maj(a, b, c);			\
91 	d += t0;					\
92 	h  = t0 + t1;
93 
94 /* Adjusted round function for rotating state */
95 #define RNDr(S, W, i, k)			\
96 	RND(S[(80 - i) % 8], S[(81 - i) % 8],	\
97 	    S[(82 - i) % 8], S[(83 - i) % 8],	\
98 	    S[(84 - i) % 8], S[(85 - i) % 8],	\
99 	    S[(86 - i) % 8], S[(87 - i) % 8],	\
100 	    W[i] + k)
101 
102 /*
103  * SHA512 block compression function.  The 512-bit state is transformed via
104  * the 512-bit input block to produce a new state.
105  */
106 static void
SHA512_Transform(uint64_t * state,const unsigned char block[128])107 SHA512_Transform(uint64_t * state, const unsigned char block[128])
108 {
109 	uint64_t W[80];
110 	uint64_t S[8];
111 	uint64_t t0, t1;
112 	int i;
113 
114 	/* 1. Prepare message schedule W. */
115 	be64dec_vect(W, block, 128);
116 	for (i = 16; i < 80; i++)
117 		W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
118 
119 	/* 2. Initialize working variables. */
120 	memcpy(S, state, 64);
121 
122 	/* 3. Mix. */
123 	RNDr(S, W, 0, 0x428a2f98d728ae22ULL);
124 	RNDr(S, W, 1, 0x7137449123ef65cdULL);
125 	RNDr(S, W, 2, 0xb5c0fbcfec4d3b2fULL);
126 	RNDr(S, W, 3, 0xe9b5dba58189dbbcULL);
127 	RNDr(S, W, 4, 0x3956c25bf348b538ULL);
128 	RNDr(S, W, 5, 0x59f111f1b605d019ULL);
129 	RNDr(S, W, 6, 0x923f82a4af194f9bULL);
130 	RNDr(S, W, 7, 0xab1c5ed5da6d8118ULL);
131 	RNDr(S, W, 8, 0xd807aa98a3030242ULL);
132 	RNDr(S, W, 9, 0x12835b0145706fbeULL);
133 	RNDr(S, W, 10, 0x243185be4ee4b28cULL);
134 	RNDr(S, W, 11, 0x550c7dc3d5ffb4e2ULL);
135 	RNDr(S, W, 12, 0x72be5d74f27b896fULL);
136 	RNDr(S, W, 13, 0x80deb1fe3b1696b1ULL);
137 	RNDr(S, W, 14, 0x9bdc06a725c71235ULL);
138 	RNDr(S, W, 15, 0xc19bf174cf692694ULL);
139 	RNDr(S, W, 16, 0xe49b69c19ef14ad2ULL);
140 	RNDr(S, W, 17, 0xefbe4786384f25e3ULL);
141 	RNDr(S, W, 18, 0x0fc19dc68b8cd5b5ULL);
142 	RNDr(S, W, 19, 0x240ca1cc77ac9c65ULL);
143 	RNDr(S, W, 20, 0x2de92c6f592b0275ULL);
144 	RNDr(S, W, 21, 0x4a7484aa6ea6e483ULL);
145 	RNDr(S, W, 22, 0x5cb0a9dcbd41fbd4ULL);
146 	RNDr(S, W, 23, 0x76f988da831153b5ULL);
147 	RNDr(S, W, 24, 0x983e5152ee66dfabULL);
148 	RNDr(S, W, 25, 0xa831c66d2db43210ULL);
149 	RNDr(S, W, 26, 0xb00327c898fb213fULL);
150 	RNDr(S, W, 27, 0xbf597fc7beef0ee4ULL);
151 	RNDr(S, W, 28, 0xc6e00bf33da88fc2ULL);
152 	RNDr(S, W, 29, 0xd5a79147930aa725ULL);
153 	RNDr(S, W, 30, 0x06ca6351e003826fULL);
154 	RNDr(S, W, 31, 0x142929670a0e6e70ULL);
155 	RNDr(S, W, 32, 0x27b70a8546d22ffcULL);
156 	RNDr(S, W, 33, 0x2e1b21385c26c926ULL);
157 	RNDr(S, W, 34, 0x4d2c6dfc5ac42aedULL);
158 	RNDr(S, W, 35, 0x53380d139d95b3dfULL);
159 	RNDr(S, W, 36, 0x650a73548baf63deULL);
160 	RNDr(S, W, 37, 0x766a0abb3c77b2a8ULL);
161 	RNDr(S, W, 38, 0x81c2c92e47edaee6ULL);
162 	RNDr(S, W, 39, 0x92722c851482353bULL);
163 	RNDr(S, W, 40, 0xa2bfe8a14cf10364ULL);
164 	RNDr(S, W, 41, 0xa81a664bbc423001ULL);
165 	RNDr(S, W, 42, 0xc24b8b70d0f89791ULL);
166 	RNDr(S, W, 43, 0xc76c51a30654be30ULL);
167 	RNDr(S, W, 44, 0xd192e819d6ef5218ULL);
168 	RNDr(S, W, 45, 0xd69906245565a910ULL);
169 	RNDr(S, W, 46, 0xf40e35855771202aULL);
170 	RNDr(S, W, 47, 0x106aa07032bbd1b8ULL);
171 	RNDr(S, W, 48, 0x19a4c116b8d2d0c8ULL);
172 	RNDr(S, W, 49, 0x1e376c085141ab53ULL);
173 	RNDr(S, W, 50, 0x2748774cdf8eeb99ULL);
174 	RNDr(S, W, 51, 0x34b0bcb5e19b48a8ULL);
175 	RNDr(S, W, 52, 0x391c0cb3c5c95a63ULL);
176 	RNDr(S, W, 53, 0x4ed8aa4ae3418acbULL);
177 	RNDr(S, W, 54, 0x5b9cca4f7763e373ULL);
178 	RNDr(S, W, 55, 0x682e6ff3d6b2b8a3ULL);
179 	RNDr(S, W, 56, 0x748f82ee5defb2fcULL);
180 	RNDr(S, W, 57, 0x78a5636f43172f60ULL);
181 	RNDr(S, W, 58, 0x84c87814a1f0ab72ULL);
182 	RNDr(S, W, 59, 0x8cc702081a6439ecULL);
183 	RNDr(S, W, 60, 0x90befffa23631e28ULL);
184 	RNDr(S, W, 61, 0xa4506cebde82bde9ULL);
185 	RNDr(S, W, 62, 0xbef9a3f7b2c67915ULL);
186 	RNDr(S, W, 63, 0xc67178f2e372532bULL);
187 	RNDr(S, W, 64, 0xca273eceea26619cULL);
188 	RNDr(S, W, 65, 0xd186b8c721c0c207ULL);
189 	RNDr(S, W, 66, 0xeada7dd6cde0eb1eULL);
190 	RNDr(S, W, 67, 0xf57d4f7fee6ed178ULL);
191 	RNDr(S, W, 68, 0x06f067aa72176fbaULL);
192 	RNDr(S, W, 69, 0x0a637dc5a2c898a6ULL);
193 	RNDr(S, W, 70, 0x113f9804bef90daeULL);
194 	RNDr(S, W, 71, 0x1b710b35131c471bULL);
195 	RNDr(S, W, 72, 0x28db77f523047d84ULL);
196 	RNDr(S, W, 73, 0x32caab7b40c72493ULL);
197 	RNDr(S, W, 74, 0x3c9ebe0a15c9bebcULL);
198 	RNDr(S, W, 75, 0x431d67c49c100d4cULL);
199 	RNDr(S, W, 76, 0x4cc5d4becb3e42b6ULL);
200 	RNDr(S, W, 77, 0x597f299cfc657e2aULL);
201 	RNDr(S, W, 78, 0x5fcb6fab3ad6faecULL);
202 	RNDr(S, W, 79, 0x6c44198c4a475817ULL);
203 
204 	/* 4. Mix local working variables into global state */
205 	for (i = 0; i < 8; i++)
206 		state[i] += S[i];
207 }
208 
209 static unsigned char PAD[128] = {
210 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
211 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
212 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
213 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
214 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
215 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
216 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
218 };
219 
220 /* Add padding and terminating bit-count. */
221 static void
SHA512_Pad(SHA512_CTX * ctx)222 SHA512_Pad(SHA512_CTX * ctx)
223 {
224 	unsigned char len[16];
225 	uint64_t r, plen;
226 
227 	/*
228 	 * Convert length to a vector of bytes -- we do this now rather
229 	 * than later because the length will change after we pad.
230 	 */
231 	be64enc_vect(len, ctx->count, 16);
232 
233 	/* Add 1--128 bytes so that the resulting length is 112 mod 128 */
234 	r = (ctx->count[1] >> 3) & 0x7f;
235 	plen = (r < 112) ? (112 - r) : (240 - r);
236 	SHA512_Update(ctx, PAD, (size_t)plen);
237 
238 	/* Add the terminating bit-count */
239 	SHA512_Update(ctx, len, 16);
240 }
241 
242 /* SHA-512 initialization.  Begins a SHA-512 operation. */
243 void
SHA512_Init(SHA512_CTX * ctx)244 SHA512_Init(SHA512_CTX * ctx)
245 {
246 
247 	/* Zero bits processed so far */
248 	ctx->count[0] = ctx->count[1] = 0;
249 
250 	/* Magic initialization constants */
251 	ctx->state[0] = 0x6a09e667f3bcc908ULL;
252 	ctx->state[1] = 0xbb67ae8584caa73bULL;
253 	ctx->state[2] = 0x3c6ef372fe94f82bULL;
254 	ctx->state[3] = 0xa54ff53a5f1d36f1ULL;
255 	ctx->state[4] = 0x510e527fade682d1ULL;
256 	ctx->state[5] = 0x9b05688c2b3e6c1fULL;
257 	ctx->state[6] = 0x1f83d9abfb41bd6bULL;
258 	ctx->state[7] = 0x5be0cd19137e2179ULL;
259 }
260 
261 /* Add bytes into the hash */
262 void
SHA512_Update(SHA512_CTX * ctx,const void * in,size_t len)263 SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len)
264 {
265 	uint64_t bitlen[2];
266 	uint64_t r;
267 	const unsigned char *src = in;
268 
269 	/* Number of bytes left in the buffer from previous updates */
270 	r = (ctx->count[1] >> 3) & 0x7f;
271 
272 	/* Convert the length into a number of bits */
273 	bitlen[1] = ((uint64_t)len) << 3;
274 	bitlen[0] = ((uint64_t)len) >> 61;
275 
276 	/* Update number of bits */
277 	if ((ctx->count[1] += bitlen[1]) < bitlen[1])
278 		ctx->count[0]++;
279 	ctx->count[0] += bitlen[0];
280 
281 	/* Handle the case where we don't need to perform any transforms */
282 	if (len < 128 - r) {
283 		memcpy(&ctx->buf[r], src, len);
284 		return;
285 	}
286 
287 	/* Finish the current block */
288 	memcpy(&ctx->buf[r], src, 128 - r);
289 	SHA512_Transform(ctx->state, ctx->buf);
290 	src += 128 - r;
291 	len -= 128 - r;
292 
293 	/* Perform complete blocks */
294 	while (len >= 128) {
295 		SHA512_Transform(ctx->state, src);
296 		src += 128;
297 		len -= 128;
298 	}
299 
300 	/* Copy left over data into buffer */
301 	memcpy(ctx->buf, src, len);
302 }
303 
304 /*
305  * SHA-512 finalization.  Pads the input data, exports the hash value,
306  * and clears the context state.
307  */
308 void
SHA512_Final(unsigned char digest[64],SHA512_CTX * ctx)309 SHA512_Final(unsigned char digest[64], SHA512_CTX * ctx)
310 {
311 
312 	/* Add padding */
313 	SHA512_Pad(ctx);
314 
315 	/* Write the hash */
316 	be64enc_vect(digest, ctx->state, 64);
317 
318 	/* Clear the context state */
319 	memset((void *)ctx, 0, sizeof(*ctx));
320 }
321