Format with .clang-format, included herein for reference
[akaros.git] / kern / lib / random / sha2.c
1 /*      $OpenBSD: sha2.c,v 1.6 2004/05/03 02:57:36 millert Exp $        */
2
3 /*
4  * FILE:        sha2.c
5  * AUTHOR:      Aaron D. Gifford <me@aarongifford.com>
6  *
7  * Copyright (c) 2000-2001, Aaron D. Gifford
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *        notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *        notice, this list of conditions and the following disclaimer in the
17  *        documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the copyright holder nor the names of contributors
19  *        may be used to endorse or promote products derived from this software
20  *        without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.      IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
35  *
36  * contrib/pgcrypto/sha2.c
37  */
38
39 #include "u.h"
40 #include <libc.h>
41 #include "sha2.h"
42
43 /*** SHA-256/512 Various Length Definitions ***********************/
44 enum {
45         SHA256ShortBlockLength = (SHA256BlockLength - 8),
46         SHA512ShortBlockLength = (SHA512_block_length - 16)
47 };
48
49 /*
50  * Macro for incrementally adding the unsigned 64-bit integer n to the
51  * unsigned 128-bit integer (represented using a two-element array of
52  * 64-bit words):
53  */
54 #define ADDINC128(w, n)                                                        \
55         {                                                                          \
56                 (w)[0] += (uint64_t)(n);                                               \
57                 if ((w)[0] < (n)) {                                                    \
58                         (w)[1]++;                                                          \
59                 }                                                                      \
60         }
61
62 /*** THE SIX LOGICAL FUNCTIONS ****************************************/
63 /*
64  * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
65  *
66  *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
67  *   S is a ROTATION) because the SHA-256/384/512 description document
68  *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
69  *   same "backwards" definition.
70  */
71 /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
72 #define R(b, x) ((x) >> (b))
73 /* 32-bit Rotate-right (used in SHA-256): */
74 #define S32(b, x) (((x) >> (b)) | ((x) << (32 - (b))))
75 /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
76 #define S64(b, x) (((x) >> (b)) | ((x) << (64 - (b))))
77
78 /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
79 #define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
80 #define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
81
82 /* Four of six logical functions used in SHA-256: */
83 #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
84 #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
85 #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3, (x)))
86 #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
87
88 /* Four of six logical functions used in SHA-384 and SHA-512: */
89 #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
90 #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
91 #define sigma0_512(x) (S64(1, (x)) ^ S64(8, (x)) ^ R(7, (x)))
92 #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R(6, (x)))
93
94 /*** INTERNAL FUNCTION PROTOTYPES *************************************/
95 /* NOTE: These should not be accessed directly from outside this
96  * library -- they are intended for private internal visibility/use
97  * only.
98  */
99 static void SHA512_Last(SHA512Ctx *);
100 static void SHA256_Transform(SHA256Ctx *, const uint32_t *);
101 static void SHA512_Transform(SHA512Ctx *, const uint64_t *);
102
103 /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
104 /* Hash constant words K for SHA-256: */
105 const uint32_t K256[64] = {
106         0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
107         0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
108         0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
109         0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
110         0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
111         0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
112         0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
113         0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
114         0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
115         0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
116         0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
117         0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
118         0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL};
119
120 /* Initial hash value H for SHA-224: */
121 const uint32_t sha224_initial_hash_value[8] = {
122         0xc1059ed8UL, 0x367cd507UL, 0x3070dd17UL, 0xf70e5939UL,
123         0xffc00b31UL, 0x68581511UL, 0x64f98fa7UL, 0xbefa4fa4UL};
124
125 /* Initial hash value H for SHA-256: */
126 static const uint32_t sha256_initial_hash_value[8] = {
127         0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
128         0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL};
129
130 /* Hash constant words K for SHA-384 and SHA-512: */
131 static const uint64_t K512[80] = {
132         0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
133         0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
134         0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
135         0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
136         0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
137         0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
138         0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
139         0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
140         0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
141         0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
142         0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
143         0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
144         0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
145         0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
146         0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
147         0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
148         0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
149         0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
150         0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
151         0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
152         0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
153         0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
154         0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
155         0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
156         0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
157         0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
158         0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
159
160 /* Initial hash value H for SHA-384 */
161 static const uint64_t sha384_initial_hash_value[8] = {
162         0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
163         0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
164         0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL};
165
166 /* Initial hash value H for SHA-512 */
167 static const uint64_t sha512_initial_hash_value[8] = {
168         0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
169         0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
170         0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
171
172 /*** SHA-256: *********************************************************/
173 void SHA256_Init(SHA256Ctx *context)
174 {
175         if (context == nil)
176                 return;
177         memmove(context->state, sha256_initial_hash_value, SHA256DigestLength);
178         memset(context->buffer, 0, SHA256BlockLength);
179         context->bitcount = 0;
180 }
181 static void SHA256_Transform(SHA256Ctx *context, const uint32_t *data)
182 {
183         uint32_t a, b, c, d, e, f, g, h, s0, s1;
184         uint32_t T1, T2, *W256;
185         int j;
186
187         W256 = (uint32_t *)context->buffer;
188
189         /* Initialize registers with the prev. intermediate value */
190         a = context->state[0];
191         b = context->state[1];
192         c = context->state[2];
193         d = context->state[3];
194         e = context->state[4];
195         f = context->state[5];
196         g = context->state[6];
197         h = context->state[7];
198
199         j = 0;
200         do {
201                 W256[j] = (uint32_t)data[3] | ((uint32_t)data[2] << 8) |
202                                   ((uint32_t)data[1] << 16) | ((uint32_t)data[0] << 24);
203                 data += 4;
204                 /* Apply the SHA-256 compression function to update a..h */
205                 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
206                 T2 = Sigma0_256(a) + Maj(a, b, c);
207                 h = g;
208                 g = f;
209                 f = e;
210                 e = d + T1;
211                 d = c;
212                 c = b;
213                 b = a;
214                 a = T1 + T2;
215
216                 j++;
217         } while (j < 16);
218
219         do {
220                 /* Part of the message block expansion: */
221                 s0 = W256[(j + 1) & 0x0f];
222                 s0 = sigma0_256(s0);
223                 s1 = W256[(j + 14) & 0x0f];
224                 s1 = sigma1_256(s1);
225
226                 /* Apply the SHA-256 compression function to update a..h */
227                 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
228                          (W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0);
229                 T2 = Sigma0_256(a) + Maj(a, b, c);
230                 h = g;
231                 g = f;
232                 f = e;
233                 e = d + T1;
234                 d = c;
235                 c = b;
236                 b = a;
237                 a = T1 + T2;
238
239                 j++;
240         } while (j < 64);
241
242         /* Compute the current intermediate hash value */
243         context->state[0] += a;
244         context->state[1] += b;
245         context->state[2] += c;
246         context->state[3] += d;
247         context->state[4] += e;
248         context->state[5] += f;
249         context->state[6] += g;
250         context->state[7] += h;
251
252         /* Clean up */
253         a = b = c = d = e = f = g = h = T1 = T2 = 0;
254 }
255
256 void SHA256_Update(SHA256Ctx *context, const uint8_t *data, size_t len)
257 {
258         size_t freespace, usedspace;
259
260         /* Calling with no data is valid (we do nothing) */
261         if (len == 0)
262                 return;
263
264         usedspace = (context->bitcount >> 3) % SHA256BlockLength;
265         if (usedspace > 0) {
266                 /* Calculate how much free space is available in the buffer */
267                 freespace = SHA256BlockLength - usedspace;
268
269                 if (len >= freespace) {
270                         /* Fill the buffer completely and process it */
271                         memmove(&context->buffer[usedspace], data, freespace);
272                         context->bitcount += freespace << 3;
273                         len -= freespace;
274                         data += freespace;
275                         SHA256_Transform(context, (uint32_t *)context->buffer);
276                 } else {
277                         /* The buffer is not yet full */
278                         memmove(&context->buffer[usedspace], data, len);
279                         context->bitcount += len << 3;
280                         /* Clean up: */
281                         usedspace = freespace = 0;
282                         return;
283                 }
284         }
285         while (len >= SHA256BlockLength) {
286                 /* Process as many complete blocks as we can */
287                 SHA256_Transform(context, (const uint32_t *)data);
288                 context->bitcount += SHA256BlockLength << 3;
289                 len -= SHA256BlockLength;
290                 data += SHA256BlockLength;
291         }
292         if (len > 0) {
293                 /* There's left-overs, so save 'em */
294                 memmove(context->buffer, data, len);
295                 context->bitcount += len << 3;
296         }
297         /* Clean up: */
298         usedspace = freespace = 0;
299 }
300
301 static void SHA256_Last(SHA256Ctx *context)
302 {
303         unsigned int usedspace;
304
305         usedspace = (context->bitcount >> 3) % SHA256BlockLength;
306
307         if (usedspace > 0) {
308                 /* Begin padding with a 1 bit: */
309                 context->buffer[usedspace++] = 0x80;
310
311                 if (usedspace <= SHA256ShortBlockLength) {
312                         /* Set-up for the last transform: */
313                         memset(&context->buffer[usedspace], 0,
314                                    SHA256ShortBlockLength - usedspace);
315                 } else {
316                         if (usedspace < SHA256BlockLength) {
317                                 memset(&context->buffer[usedspace], 0,
318                                            SHA256BlockLength - usedspace);
319                         }
320                         /* Do second-to-last transform: */
321                         SHA256_Transform(context, (uint32_t *)context->buffer);
322
323                         /* And set-up for the last transform: */
324                         memset(context->buffer, 0, SHA256ShortBlockLength);
325                 }
326         } else {
327                 /* Set-up for the last transform: */
328                 memset(context->buffer, 0, SHA256ShortBlockLength);
329
330                 /* Begin padding with a 1 bit: */
331                 *context->buffer = 0x80;
332         }
333         /* Set the bit count: */
334         *(uint64_t *)&context->buffer[SHA256ShortBlockLength] = context->bitcount;
335
336         /* Final transform: */
337         SHA256_Transform(context, (uint32_t *)context->buffer);
338 }
339
340 void SHA256_Final(uint8_t digest[], SHA256Ctx *context)
341 {
342         /* If no digest buffer is passed, we don't bother doing this: */
343         if (digest != nil) {
344                 SHA256_Last(context);
345
346                 memmove(digest, context->state, SHA256DigestLength);
347         }
348
349         /* Clean up state data: */
350         memset(context, 0, sizeof(*context));
351 }
352
353 /*** SHA-512: *********************************************************/
354 void SHA512_Init(SHA512Ctx *context)
355 {
356         if (context == nil)
357                 return;
358         memmove(context->state, sha512_initial_hash_value, SHA512DigestLength);
359         memset(context->buffer, 0, SHA512_block_length);
360         context->bitcount[0] = context->bitcount[1] = 0;
361 }
362
363 static void SHA512_Transform(SHA512Ctx *context, const uint64_t *data)
364 {
365         uint64_t a, b, c, d, e, f, g, h, s0, s1;
366         uint64_t T1, T2, *W512 = (uint64_t *)context->buffer;
367         int j;
368
369         /* Initialize registers with the prev. intermediate value */
370         a = context->state[0];
371         b = context->state[1];
372         c = context->state[2];
373         d = context->state[3];
374         e = context->state[4];
375         f = context->state[5];
376         g = context->state[6];
377         h = context->state[7];
378
379         j = 0;
380         do {
381                 W512[j] = (uint64_t)data[7] | ((uint64_t)data[6] << 8) |
382                                   ((uint64_t)data[5] << 16) | ((uint64_t)data[4] << 24) |
383                                   ((uint64_t)data[3] << 32) | ((uint64_t)data[2] << 40) |
384                                   ((uint64_t)data[1] << 48) | ((uint64_t)data[0] << 56);
385                 data += 8;
386                 /* Apply the SHA-512 compression function to update a..h */
387                 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
388                 T2 = Sigma0_512(a) + Maj(a, b, c);
389                 h = g;
390                 g = f;
391                 f = e;
392                 e = d + T1;
393                 d = c;
394                 c = b;
395                 b = a;
396                 a = T1 + T2;
397
398                 j++;
399         } while (j < 16);
400
401         do {
402                 /* Part of the message block expansion: */
403                 s0 = W512[(j + 1) & 0x0f];
404                 s0 = sigma0_512(s0);
405                 s1 = W512[(j + 14) & 0x0f];
406                 s1 = sigma1_512(s1);
407
408                 /* Apply the SHA-512 compression function to update a..h */
409                 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
410                          (W512[j & 0x0f] += s1 + W512[(j + 9) & 0x0f] + s0);
411                 T2 = Sigma0_512(a) + Maj(a, b, c);
412                 h = g;
413                 g = f;
414                 f = e;
415                 e = d + T1;
416                 d = c;
417                 c = b;
418                 b = a;
419                 a = T1 + T2;
420
421                 j++;
422         } while (j < 80);
423
424         /* Compute the current intermediate hash value */
425         context->state[0] += a;
426         context->state[1] += b;
427         context->state[2] += c;
428         context->state[3] += d;
429         context->state[4] += e;
430         context->state[5] += f;
431         context->state[6] += g;
432         context->state[7] += h;
433
434         /* Clean up */
435         a = b = c = d = e = f = g = h = T1 = T2 = 0;
436 }
437
438 void SHA512_Update(SHA512Ctx *context, const uint8_t *data, size_t len)
439 {
440         size_t freespace, usedspace;
441
442         /* Calling with no data is valid (we do nothing) */
443         if (len == 0)
444                 return;
445
446         usedspace = (context->bitcount[0] >> 3) % SHA512_block_length;
447         if (usedspace > 0) {
448                 /* Calculate how much free space is available in the buffer */
449                 freespace = SHA512_block_length - usedspace;
450
451                 if (len >= freespace) {
452                         /* Fill the buffer completely and process it */
453                         memmove(&context->buffer[usedspace], data, freespace);
454                         ADDINC128(context->bitcount, freespace << 3);
455                         len -= freespace;
456                         data += freespace;
457                         SHA512_Transform(context, (uint64_t *)context->buffer);
458                 } else {
459                         /* The buffer is not yet full */
460                         memmove(&context->buffer[usedspace], data, len);
461                         ADDINC128(context->bitcount, len << 3);
462                         /* Clean up: */
463                         usedspace = freespace = 0;
464                         return;
465                 }
466         }
467         while (len >= SHA512_block_length) {
468                 /* Process as many complete blocks as we can */
469                 SHA512_Transform(context, (const uint64_t *)data);
470                 ADDINC128(context->bitcount, SHA512_block_length << 3);
471                 len -= SHA512_block_length;
472                 data += SHA512_block_length;
473         }
474         if (len > 0) {
475                 /* There's left-overs, so save 'em */
476                 memmove(context->buffer, data, len);
477                 ADDINC128(context->bitcount, len << 3);
478         }
479         /* Clean up: */
480         usedspace = freespace = 0;
481 }
482
483 static void SHA512_Last(SHA512Ctx *context)
484 {
485         unsigned int usedspace;
486
487         usedspace = (context->bitcount[0] >> 3) % SHA512_block_length;
488
489         if (usedspace > 0) {
490                 /* Begin padding with a 1 bit: */
491                 context->buffer[usedspace++] = 0x80;
492
493                 if (usedspace <= SHA512ShortBlockLength) {
494                         /* Set-up for the last transform: */
495                         memset(&context->buffer[usedspace], 0,
496                                    SHA512ShortBlockLength - usedspace);
497                 } else {
498                         if (usedspace < SHA512_block_length) {
499                                 memset(&context->buffer[usedspace], 0,
500                                            SHA512_block_length - usedspace);
501                         }
502                         /* Do second-to-last transform: */
503                         SHA512_Transform(context, (uint64_t *)context->buffer);
504
505                         /* And set-up for the last transform: */
506                         memset(context->buffer, 0, SHA512_block_length - 2);
507                 }
508         } else {
509                 /* Prepare for final transform: */
510                 memset(context->buffer, 0, SHA512ShortBlockLength);
511
512                 /* Begin padding with a 1 bit: */
513                 *context->buffer = 0x80;
514         }
515         /* Store the length of input data (in bits): */
516         *(uint64_t *)&context->buffer[SHA512ShortBlockLength] =
517                 context->bitcount[1];
518         *(uint64_t *)&context->buffer[SHA512ShortBlockLength + 8] =
519                 context->bitcount[0];
520
521         /* Final transform: */
522         SHA512_Transform(context, (uint64_t *)context->buffer);
523 }
524
525 void SHA512_Final(uint8_t digest[], SHA512Ctx *context)
526 {
527         /* If no digest buffer is passed, we don't bother doing this: */
528         if (digest != nil) {
529                 SHA512_Last(context);
530
531                 /* Save the hash data for output: */
532                 memmove(digest, context->state, SHA512DigestLength);
533         }
534
535         /* Zero out state data */
536         memset(context, 0, sizeof(*context));
537 }
538
539 /*** SHA-384: *********************************************************/
540 void SHA384_Init(SHA384Ctx *context)
541 {
542         if (context == nil)
543                 return;
544         memmove(context->state, sha384_initial_hash_value, SHA512DigestLength);
545         memset(context->buffer, 0, SHA384BlockLength);
546         context->bitcount[0] = context->bitcount[1] = 0;
547 }
548
549 void SHA384_Update(SHA384Ctx *context, const uint8_t *data, size_t len)
550 {
551         SHA512_Update((SHA512Ctx *)context, data, len);
552 }
553
554 void SHA384_Final(uint8_t digest[], SHA384Ctx *context)
555 {
556         /* If no digest buffer is passed, we don't bother doing this: */
557         if (digest != nil) {
558                 SHA512_Last((SHA512Ctx *)context);
559
560                 /* Save the hash data for output: */
561                 memmove(digest, context->state, SHA384DigestLength);
562         }
563
564         /* Zero out state data */
565         memset(context, 0, sizeof(*context));
566 }
567
568 /*** SHA-224: *********************************************************/
569 void SHA224_Init(SHA224Ctx *context)
570 {
571         if (context == nil)
572                 return;
573         memmove(context->state, sha224_initial_hash_value, SHA256DigestLength);
574         memset(context->buffer, 0, SHA256BlockLength);
575         context->bitcount = 0;
576 }
577
578 void SHA224_Update(SHA224Ctx *context, const uint8_t *data, size_t len)
579 {
580         SHA256_Update((SHA256Ctx *)context, data, len);
581 }
582
583 void SHA224_Final(uint8_t digest[], SHA224Ctx *context)
584 {
585         /* If no digest buffer is passed, we don't bother doing this: */
586         if (digest != nil) {
587                 SHA256_Last(context);
588
589                 memmove(digest, context->state, SHA224DigestLength);
590         }
591
592         /* Clean up state data: */
593         memset(context, 0, sizeof(*context));
594 }