source: rtems/cpukit/libmd/sha512c.c @ a67b9443

Last change on this file since a67b9443 was a67b9443, checked in by Sebastian Huber <sebastian.huber@…>, on 02/06/23 at 16:57:28

sha512_224: Fix SHA512_224_Final() on little-endian machines.

PR: 266863
MFC after: 1 week
Reviewed by: allanjude, cperciva, des
Differential Revision: https://reviews.freebsd.org/D38372

  • Property mode set to 100644
File size: 12.9 KB
Line 
1/*-
2 * Copyright 2005 Colin Percival
3 * Copyright (c) 2015 Allan Jude <allanjude@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD$");
30
31#include <sys/endian.h>
32#include <sys/types.h>
33
34#include <string.h>
35
36#include "sha512.h"
37#include "sha512t.h"
38#include "sha384.h"
39
40#if BYTE_ORDER == BIG_ENDIAN
41
42/* Copy a vector of big-endian uint64_t into a vector of bytes */
43#define be64enc_vect(dst, src, len)     \
44        memcpy((void *)dst, (const void *)src, (size_t)len)
45
46/* Copy a vector of bytes into a vector of big-endian uint64_t */
47#define be64dec_vect(dst, src, len)     \
48        memcpy((void *)dst, (const void *)src, (size_t)len)
49
50#else /* BYTE_ORDER != BIG_ENDIAN */
51
52/*
53 * Encode a length (len + 7) / 8 vector of (uint64_t) into a length len
54 * vector of (unsigned char) in big-endian form.  Assumes len is a
55 * multiple of 4.
56 */
57static inline void
58be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
59{
60        size_t i;
61
62        for (i = 0; i < len / 8; i++)
63                be64enc(dst + i * 8, src[i]);
64        if (len % 8 == 4)
65                be32enc(dst + i * 8, src[i] >> 32);
66}
67
68/*
69 * Decode a big-endian length len vector of (unsigned char) into a length
70 * len/8 vector of (uint64_t).  Assumes len is a multiple of 8.
71 */
72static inline void
73be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
74{
75        size_t i;
76
77        for (i = 0; i < len / 8; i++)
78                dst[i] = be64dec(src + i * 8);
79}
80
81#endif /* BYTE_ORDER != BIG_ENDIAN */
82
83/* SHA512 round constants. */
84static const uint64_t 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/* Elementary functions used by SHA512 */
128#define Ch(x, y, z)     ((x & (y ^ z)) ^ z)
129#define Maj(x, y, z)    ((x & (y | z)) | (y & z))
130#define SHR(x, n)       (x >> n)
131#define ROTR(x, n)      ((x >> n) | (x << (64 - n)))
132#define S0(x)           (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
133#define S1(x)           (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
134#define s0(x)           (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
135#define s1(x)           (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
136
137/* SHA512 round function */
138#define RND(a, b, c, d, e, f, g, h, k)                  \
139        h += S1(e) + Ch(e, f, g) + k;                   \
140        d += h;                                         \
141        h += S0(a) + Maj(a, b, c);
142
143/* Adjusted round function for rotating state */
144#define RNDr(S, W, i, ii)                       \
145        RND(S[(80 - i) % 8], S[(81 - i) % 8],   \
146            S[(82 - i) % 8], S[(83 - i) % 8],   \
147            S[(84 - i) % 8], S[(85 - i) % 8],   \
148            S[(86 - i) % 8], S[(87 - i) % 8],   \
149            W[i + ii] + K[i + ii])
150
151/* Message schedule computation */
152#define MSCH(W, ii, i)                          \
153        W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
154
155/*
156 * SHA512 block compression function.  The 512-bit state is transformed via
157 * the 512-bit input block to produce a new state.
158 */
159static void
160SHA512_Transform(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH])
161{
162        uint64_t W[80];
163        uint64_t S[8];
164        int i;
165
166        /* 1. Prepare the first part of the message schedule W. */
167        be64dec_vect(W, block, SHA512_BLOCK_LENGTH);
168
169        /* 2. Initialize working variables. */
170        memcpy(S, state, SHA512_DIGEST_LENGTH);
171
172        /* 3. Mix. */
173        for (i = 0; i < 80; i += 16) {
174                RNDr(S, W, 0, i);
175                RNDr(S, W, 1, i);
176                RNDr(S, W, 2, i);
177                RNDr(S, W, 3, i);
178                RNDr(S, W, 4, i);
179                RNDr(S, W, 5, i);
180                RNDr(S, W, 6, i);
181                RNDr(S, W, 7, i);
182                RNDr(S, W, 8, i);
183                RNDr(S, W, 9, i);
184                RNDr(S, W, 10, i);
185                RNDr(S, W, 11, i);
186                RNDr(S, W, 12, i);
187                RNDr(S, W, 13, i);
188                RNDr(S, W, 14, i);
189                RNDr(S, W, 15, i);
190
191                if (i == 64)
192                        break;
193                MSCH(W, 0, i);
194                MSCH(W, 1, i);
195                MSCH(W, 2, i);
196                MSCH(W, 3, i);
197                MSCH(W, 4, i);
198                MSCH(W, 5, i);
199                MSCH(W, 6, i);
200                MSCH(W, 7, i);
201                MSCH(W, 8, i);
202                MSCH(W, 9, i);
203                MSCH(W, 10, i);
204                MSCH(W, 11, i);
205                MSCH(W, 12, i);
206                MSCH(W, 13, i);
207                MSCH(W, 14, i);
208                MSCH(W, 15, i);
209        }
210
211        /* 4. Mix local working variables into global state */
212        for (i = 0; i < 8; i++)
213                state[i] += S[i];
214}
215
216static const unsigned char PAD[SHA512_BLOCK_LENGTH] = {
217        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
219        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
220        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
222        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
225};
226
227/* Add padding and terminating bit-count. */
228static void
229SHA512_Pad(SHA512_CTX * ctx)
230{
231        size_t r;
232
233        /* Figure out how many bytes we have buffered. */
234        r = (ctx->count[1] >> 3) & 0x7f;
235
236        /* Pad to 112 mod 128, transforming if we finish a block en route. */
237        if (r < 112) {
238                /* Pad to 112 mod 128. */
239                memcpy(&ctx->buf[r], PAD, 112 - r);
240        } else {
241                /* Finish the current block and mix. */
242                memcpy(&ctx->buf[r], PAD, 128 - r);
243                SHA512_Transform(ctx->state, ctx->buf);
244
245                /* The start of the final block is all zeroes. */
246                memset(&ctx->buf[0], 0, 112);
247        }
248
249        /* Add the terminating bit-count. */
250        be64enc_vect(&ctx->buf[112], ctx->count, 16);
251
252        /* Mix in the final block. */
253        SHA512_Transform(ctx->state, ctx->buf);
254}
255
256/* SHA-512 initialization.  Begins a SHA-512 operation. */
257void
258SHA512_Init(SHA512_CTX * ctx)
259{
260
261        /* Zero bits processed so far */
262        ctx->count[0] = ctx->count[1] = 0;
263
264        /* Magic initialization constants */
265        ctx->state[0] = 0x6a09e667f3bcc908ULL;
266        ctx->state[1] = 0xbb67ae8584caa73bULL;
267        ctx->state[2] = 0x3c6ef372fe94f82bULL;
268        ctx->state[3] = 0xa54ff53a5f1d36f1ULL;
269        ctx->state[4] = 0x510e527fade682d1ULL;
270        ctx->state[5] = 0x9b05688c2b3e6c1fULL;
271        ctx->state[6] = 0x1f83d9abfb41bd6bULL;
272        ctx->state[7] = 0x5be0cd19137e2179ULL;
273}
274
275/* Add bytes into the hash */
276void
277SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len)
278{
279        uint64_t bitlen[2];
280        uint64_t r;
281        const unsigned char *src = in;
282
283        /* Number of bytes left in the buffer from previous updates */
284        r = (ctx->count[1] >> 3) & 0x7f;
285
286        /* Convert the length into a number of bits */
287        bitlen[1] = ((uint64_t)len) << 3;
288        bitlen[0] = ((uint64_t)len) >> 61;
289
290        /* Update number of bits */
291        if ((ctx->count[1] += bitlen[1]) < bitlen[1])
292                ctx->count[0]++;
293        ctx->count[0] += bitlen[0];
294
295        /* Handle the case where we don't need to perform any transforms */
296        if (len < SHA512_BLOCK_LENGTH - r) {
297                memcpy(&ctx->buf[r], src, len);
298                return;
299        }
300
301        /* Finish the current block */
302        memcpy(&ctx->buf[r], src, SHA512_BLOCK_LENGTH - r);
303        SHA512_Transform(ctx->state, ctx->buf);
304        src += SHA512_BLOCK_LENGTH - r;
305        len -= SHA512_BLOCK_LENGTH - r;
306
307        /* Perform complete blocks */
308        while (len >= SHA512_BLOCK_LENGTH) {
309                SHA512_Transform(ctx->state, src);
310                src += SHA512_BLOCK_LENGTH;
311                len -= SHA512_BLOCK_LENGTH;
312        }
313
314        /* Copy left over data into buffer */
315        memcpy(ctx->buf, src, len);
316}
317
318/*
319 * SHA-512 finalization.  Pads the input data, exports the hash value,
320 * and clears the context state.
321 */
322void
323SHA512_Final(unsigned char digest[static SHA512_DIGEST_LENGTH], SHA512_CTX *ctx)
324{
325
326        /* Add padding */
327        SHA512_Pad(ctx);
328
329        /* Write the hash */
330        be64enc_vect(digest, ctx->state, SHA512_DIGEST_LENGTH);
331
332        /* Clear the context state */
333        explicit_bzero(ctx, sizeof(*ctx));
334}
335
336/*** SHA-512t: *********************************************************/
337/*
338 * the SHA512t transforms are identical to SHA512 so reuse the existing function
339 */
340void
341SHA512_224_Init(SHA512_CTX * ctx)
342{
343
344        /* Zero bits processed so far */
345        ctx->count[0] = ctx->count[1] = 0;
346
347        /* Magic initialization constants */
348        ctx->state[0] = 0x8c3d37c819544da2ULL;
349        ctx->state[1] = 0x73e1996689dcd4d6ULL;
350        ctx->state[2] = 0x1dfab7ae32ff9c82ULL;
351        ctx->state[3] = 0x679dd514582f9fcfULL;
352        ctx->state[4] = 0x0f6d2b697bd44da8ULL;
353        ctx->state[5] = 0x77e36f7304c48942ULL;
354        ctx->state[6] = 0x3f9d85a86a1d36c8ULL;
355        ctx->state[7] = 0x1112e6ad91d692a1ULL;
356}
357
358void
359SHA512_224_Update(SHA512_CTX * ctx, const void *in, size_t len)
360{
361
362        SHA512_Update(ctx, in, len);
363}
364
365void
366SHA512_224_Final(unsigned char digest[static SHA512_224_DIGEST_LENGTH], SHA512_CTX * ctx)
367{
368
369        /* Add padding */
370        SHA512_Pad(ctx);
371
372        /* Write the hash */
373        be64enc_vect(digest, ctx->state, SHA512_224_DIGEST_LENGTH);
374
375        /* Clear the context state */
376        explicit_bzero(ctx, sizeof(*ctx));
377}
378
379void
380SHA512_256_Init(SHA512_CTX * ctx)
381{
382
383        /* Zero bits processed so far */
384        ctx->count[0] = ctx->count[1] = 0;
385
386        /* Magic initialization constants */
387        ctx->state[0] = 0x22312194fc2bf72cULL;
388        ctx->state[1] = 0x9f555fa3c84c64c2ULL;
389        ctx->state[2] = 0x2393b86b6f53b151ULL;
390        ctx->state[3] = 0x963877195940eabdULL;
391        ctx->state[4] = 0x96283ee2a88effe3ULL;
392        ctx->state[5] = 0xbe5e1e2553863992ULL;
393        ctx->state[6] = 0x2b0199fc2c85b8aaULL;
394        ctx->state[7] = 0x0eb72ddc81c52ca2ULL;
395}
396
397void
398SHA512_256_Update(SHA512_CTX * ctx, const void *in, size_t len)
399{
400
401        SHA512_Update(ctx, in, len);
402}
403
404void
405SHA512_256_Final(unsigned char digest[static SHA512_256_DIGEST_LENGTH], SHA512_CTX * ctx)
406{
407
408        /* Add padding */
409        SHA512_Pad(ctx);
410
411        /* Write the hash */
412        be64enc_vect(digest, ctx->state, SHA512_256_DIGEST_LENGTH);
413
414        /* Clear the context state */
415        explicit_bzero(ctx, sizeof(*ctx));
416}
417
418/*** SHA-384: *********************************************************/
419/*
420 * the SHA384 and SHA512 transforms are identical, so SHA384 is skipped
421 */
422
423/* SHA-384 initialization.  Begins a SHA-384 operation. */
424void
425SHA384_Init(SHA384_CTX * ctx)
426{
427
428        /* Zero bits processed so far */
429        ctx->count[0] = ctx->count[1] = 0;
430
431        /* Magic initialization constants */
432        ctx->state[0] = 0xcbbb9d5dc1059ed8ULL;
433        ctx->state[1] = 0x629a292a367cd507ULL;
434        ctx->state[2] = 0x9159015a3070dd17ULL;
435        ctx->state[3] = 0x152fecd8f70e5939ULL;
436        ctx->state[4] = 0x67332667ffc00b31ULL;
437        ctx->state[5] = 0x8eb44a8768581511ULL;
438        ctx->state[6] = 0xdb0c2e0d64f98fa7ULL;
439        ctx->state[7] = 0x47b5481dbefa4fa4ULL;
440}
441
442/* Add bytes into the SHA-384 hash */
443void
444SHA384_Update(SHA384_CTX * ctx, const void *in, size_t len)
445{
446
447        SHA512_Update((SHA512_CTX *)ctx, in, len);
448}
449
450/*
451 * SHA-384 finalization.  Pads the input data, exports the hash value,
452 * and clears the context state.
453 */
454void
455SHA384_Final(unsigned char digest[static SHA384_DIGEST_LENGTH], SHA384_CTX *ctx)
456{
457
458        /* Add padding */
459        SHA512_Pad((SHA512_CTX *)ctx);
460
461        /* Write the hash */
462        be64enc_vect(digest, ctx->state, SHA384_DIGEST_LENGTH);
463
464        /* Clear the context state */
465        explicit_bzero(ctx, sizeof(*ctx));
466}
Note: See TracBrowser for help on using the repository browser.