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

Last change on this file since f5ee9a0 was f5ee9a0, checked in by Xin LI <delphij@…>, on 07/20/18 at 07:01:28

libmd: Always erase context in _Final method,

and when doing it, consistently use explicit_bzero().

Update manual pages to match the behavior.

Reviewed by: pfg, allanjude, jmg
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D16316

  • Property mode set to 100644
File size: 12.8 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/4 vector of (uint64_t) into a length len vector of
54 * (unsigned char) in big-endian form.  Assumes len is a multiple of 8.
55 */
56static void
57be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
58{
59        size_t i;
60
61        for (i = 0; i < len / 8; i++)
62                be64enc(dst + i * 8, src[i]);
63}
64
65/*
66 * Decode a big-endian length len vector of (unsigned char) into a length
67 * len/4 vector of (uint64_t).  Assumes len is a multiple of 8.
68 */
69static void
70be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
71{
72        size_t i;
73
74        for (i = 0; i < len / 8; i++)
75                dst[i] = be64dec(src + i * 8);
76}
77
78#endif /* BYTE_ORDER != BIG_ENDIAN */
79
80/* SHA512 round constants. */
81static const uint64_t K[80] = {
82        0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
83        0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
84        0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
85        0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
86        0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
87        0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
88        0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
89        0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
90        0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
91        0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
92        0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
93        0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
94        0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
95        0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
96        0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
97        0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
98        0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
99        0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
100        0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
101        0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
102        0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
103        0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
104        0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
105        0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
106        0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
107        0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
108        0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
109        0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
110        0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
111        0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
112        0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
113        0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
114        0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
115        0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
116        0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
117        0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
118        0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
119        0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
120        0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
121        0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
122};
123
124/* Elementary functions used by SHA512 */
125#define Ch(x, y, z)     ((x & (y ^ z)) ^ z)
126#define Maj(x, y, z)    ((x & (y | z)) | (y & z))
127#define SHR(x, n)       (x >> n)
128#define ROTR(x, n)      ((x >> n) | (x << (64 - n)))
129#define S0(x)           (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
130#define S1(x)           (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
131#define s0(x)           (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
132#define s1(x)           (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
133
134/* SHA512 round function */
135#define RND(a, b, c, d, e, f, g, h, k)                  \
136        h += S1(e) + Ch(e, f, g) + k;                   \
137        d += h;                                         \
138        h += S0(a) + Maj(a, b, c);
139
140/* Adjusted round function for rotating state */
141#define RNDr(S, W, i, ii)                       \
142        RND(S[(80 - i) % 8], S[(81 - i) % 8],   \
143            S[(82 - i) % 8], S[(83 - i) % 8],   \
144            S[(84 - i) % 8], S[(85 - i) % 8],   \
145            S[(86 - i) % 8], S[(87 - i) % 8],   \
146            W[i + ii] + K[i + ii])
147
148/* Message schedule computation */
149#define MSCH(W, ii, i)                          \
150        W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
151
152/*
153 * SHA512 block compression function.  The 512-bit state is transformed via
154 * the 512-bit input block to produce a new state.
155 */
156static void
157SHA512_Transform(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH])
158{
159        uint64_t W[80];
160        uint64_t S[8];
161        int i;
162
163        /* 1. Prepare the first part of the message schedule W. */
164        be64dec_vect(W, block, SHA512_BLOCK_LENGTH);
165
166        /* 2. Initialize working variables. */
167        memcpy(S, state, SHA512_DIGEST_LENGTH);
168
169        /* 3. Mix. */
170        for (i = 0; i < 80; i += 16) {
171                RNDr(S, W, 0, i);
172                RNDr(S, W, 1, i);
173                RNDr(S, W, 2, i);
174                RNDr(S, W, 3, i);
175                RNDr(S, W, 4, i);
176                RNDr(S, W, 5, i);
177                RNDr(S, W, 6, i);
178                RNDr(S, W, 7, i);
179                RNDr(S, W, 8, i);
180                RNDr(S, W, 9, i);
181                RNDr(S, W, 10, i);
182                RNDr(S, W, 11, i);
183                RNDr(S, W, 12, i);
184                RNDr(S, W, 13, i);
185                RNDr(S, W, 14, i);
186                RNDr(S, W, 15, i);
187
188                if (i == 64)
189                        break;
190                MSCH(W, 0, i);
191                MSCH(W, 1, i);
192                MSCH(W, 2, i);
193                MSCH(W, 3, i);
194                MSCH(W, 4, i);
195                MSCH(W, 5, i);
196                MSCH(W, 6, i);
197                MSCH(W, 7, i);
198                MSCH(W, 8, i);
199                MSCH(W, 9, i);
200                MSCH(W, 10, i);
201                MSCH(W, 11, i);
202                MSCH(W, 12, i);
203                MSCH(W, 13, i);
204                MSCH(W, 14, i);
205                MSCH(W, 15, i);
206        }
207
208        /* 4. Mix local working variables into global state */
209        for (i = 0; i < 8; i++)
210                state[i] += S[i];
211}
212
213static const unsigned char PAD[SHA512_BLOCK_LENGTH] = {
214        0x80, 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        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};
223
224/* Add padding and terminating bit-count. */
225static void
226SHA512_Pad(SHA512_CTX * ctx)
227{
228        size_t r;
229
230        /* Figure out how many bytes we have buffered. */
231        r = (ctx->count[1] >> 3) & 0x7f;
232
233        /* Pad to 112 mod 128, transforming if we finish a block en route. */
234        if (r < 112) {
235                /* Pad to 112 mod 128. */
236                memcpy(&ctx->buf[r], PAD, 112 - r);
237        } else {
238                /* Finish the current block and mix. */
239                memcpy(&ctx->buf[r], PAD, 128 - r);
240                SHA512_Transform(ctx->state, ctx->buf);
241
242                /* The start of the final block is all zeroes. */
243                memset(&ctx->buf[0], 0, 112);
244        }
245
246        /* Add the terminating bit-count. */
247        be64enc_vect(&ctx->buf[112], ctx->count, 16);
248
249        /* Mix in the final block. */
250        SHA512_Transform(ctx->state, ctx->buf);
251}
252
253/* SHA-512 initialization.  Begins a SHA-512 operation. */
254void
255SHA512_Init(SHA512_CTX * ctx)
256{
257
258        /* Zero bits processed so far */
259        ctx->count[0] = ctx->count[1] = 0;
260
261        /* Magic initialization constants */
262        ctx->state[0] = 0x6a09e667f3bcc908ULL;
263        ctx->state[1] = 0xbb67ae8584caa73bULL;
264        ctx->state[2] = 0x3c6ef372fe94f82bULL;
265        ctx->state[3] = 0xa54ff53a5f1d36f1ULL;
266        ctx->state[4] = 0x510e527fade682d1ULL;
267        ctx->state[5] = 0x9b05688c2b3e6c1fULL;
268        ctx->state[6] = 0x1f83d9abfb41bd6bULL;
269        ctx->state[7] = 0x5be0cd19137e2179ULL;
270}
271
272/* Add bytes into the hash */
273void
274SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len)
275{
276        uint64_t bitlen[2];
277        uint64_t r;
278        const unsigned char *src = in;
279
280        /* Number of bytes left in the buffer from previous updates */
281        r = (ctx->count[1] >> 3) & 0x7f;
282
283        /* Convert the length into a number of bits */
284        bitlen[1] = ((uint64_t)len) << 3;
285        bitlen[0] = ((uint64_t)len) >> 61;
286
287        /* Update number of bits */
288        if ((ctx->count[1] += bitlen[1]) < bitlen[1])
289                ctx->count[0]++;
290        ctx->count[0] += bitlen[0];
291
292        /* Handle the case where we don't need to perform any transforms */
293        if (len < SHA512_BLOCK_LENGTH - r) {
294                memcpy(&ctx->buf[r], src, len);
295                return;
296        }
297
298        /* Finish the current block */
299        memcpy(&ctx->buf[r], src, SHA512_BLOCK_LENGTH - r);
300        SHA512_Transform(ctx->state, ctx->buf);
301        src += SHA512_BLOCK_LENGTH - r;
302        len -= SHA512_BLOCK_LENGTH - r;
303
304        /* Perform complete blocks */
305        while (len >= SHA512_BLOCK_LENGTH) {
306                SHA512_Transform(ctx->state, src);
307                src += SHA512_BLOCK_LENGTH;
308                len -= SHA512_BLOCK_LENGTH;
309        }
310
311        /* Copy left over data into buffer */
312        memcpy(ctx->buf, src, len);
313}
314
315/*
316 * SHA-512 finalization.  Pads the input data, exports the hash value,
317 * and clears the context state.
318 */
319void
320SHA512_Final(unsigned char digest[static SHA512_DIGEST_LENGTH], SHA512_CTX *ctx)
321{
322
323        /* Add padding */
324        SHA512_Pad(ctx);
325
326        /* Write the hash */
327        be64enc_vect(digest, ctx->state, SHA512_DIGEST_LENGTH);
328
329        /* Clear the context state */
330        explicit_bzero(ctx, sizeof(*ctx));
331}
332
333/*** SHA-512t: *********************************************************/
334/*
335 * the SHA512t transforms are identical to SHA512 so reuse the existing function
336 */
337void
338SHA512_224_Init(SHA512_CTX * ctx)
339{
340
341        /* Zero bits processed so far */
342        ctx->count[0] = ctx->count[1] = 0;
343
344        /* Magic initialization constants */
345        ctx->state[0] = 0x8c3d37c819544da2ULL;
346        ctx->state[1] = 0x73e1996689dcd4d6ULL;
347        ctx->state[2] = 0x1dfab7ae32ff9c82ULL;
348        ctx->state[3] = 0x679dd514582f9fcfULL;
349        ctx->state[4] = 0x0f6d2b697bd44da8ULL;
350        ctx->state[5] = 0x77e36f7304c48942ULL;
351        ctx->state[6] = 0x3f9d85a86a1d36c8ULL;
352        ctx->state[7] = 0x1112e6ad91d692a1ULL;
353}
354
355void
356SHA512_224_Update(SHA512_CTX * ctx, const void *in, size_t len)
357{
358
359        SHA512_Update(ctx, in, len);
360}
361
362void
363SHA512_224_Final(unsigned char digest[static SHA512_224_DIGEST_LENGTH], SHA512_CTX * ctx)
364{
365
366        /* Add padding */
367        SHA512_Pad(ctx);
368
369        /* Write the hash */
370        be64enc_vect(digest, ctx->state, SHA512_224_DIGEST_LENGTH);
371
372        /* Clear the context state */
373        explicit_bzero(ctx, sizeof(*ctx));
374}
375
376void
377SHA512_256_Init(SHA512_CTX * ctx)
378{
379
380        /* Zero bits processed so far */
381        ctx->count[0] = ctx->count[1] = 0;
382
383        /* Magic initialization constants */
384        ctx->state[0] = 0x22312194fc2bf72cULL;
385        ctx->state[1] = 0x9f555fa3c84c64c2ULL;
386        ctx->state[2] = 0x2393b86b6f53b151ULL;
387        ctx->state[3] = 0x963877195940eabdULL;
388        ctx->state[4] = 0x96283ee2a88effe3ULL;
389        ctx->state[5] = 0xbe5e1e2553863992ULL;
390        ctx->state[6] = 0x2b0199fc2c85b8aaULL;
391        ctx->state[7] = 0x0eb72ddc81c52ca2ULL;
392}
393
394void
395SHA512_256_Update(SHA512_CTX * ctx, const void *in, size_t len)
396{
397
398        SHA512_Update(ctx, in, len);
399}
400
401void
402SHA512_256_Final(unsigned char digest[static SHA512_256_DIGEST_LENGTH], SHA512_CTX * ctx)
403{
404
405        /* Add padding */
406        SHA512_Pad(ctx);
407
408        /* Write the hash */
409        be64enc_vect(digest, ctx->state, SHA512_256_DIGEST_LENGTH);
410
411        /* Clear the context state */
412        explicit_bzero(ctx, sizeof(*ctx));
413}
414
415/*** SHA-384: *********************************************************/
416/*
417 * the SHA384 and SHA512 transforms are identical, so SHA384 is skipped
418 */
419
420/* SHA-384 initialization.  Begins a SHA-384 operation. */
421void
422SHA384_Init(SHA384_CTX * ctx)
423{
424
425        /* Zero bits processed so far */
426        ctx->count[0] = ctx->count[1] = 0;
427
428        /* Magic initialization constants */
429        ctx->state[0] = 0xcbbb9d5dc1059ed8ULL;
430        ctx->state[1] = 0x629a292a367cd507ULL;
431        ctx->state[2] = 0x9159015a3070dd17ULL;
432        ctx->state[3] = 0x152fecd8f70e5939ULL;
433        ctx->state[4] = 0x67332667ffc00b31ULL;
434        ctx->state[5] = 0x8eb44a8768581511ULL;
435        ctx->state[6] = 0xdb0c2e0d64f98fa7ULL;
436        ctx->state[7] = 0x47b5481dbefa4fa4ULL;
437}
438
439/* Add bytes into the SHA-384 hash */
440void
441SHA384_Update(SHA384_CTX * ctx, const void *in, size_t len)
442{
443
444        SHA512_Update((SHA512_CTX *)ctx, in, len);
445}
446
447/*
448 * SHA-384 finalization.  Pads the input data, exports the hash value,
449 * and clears the context state.
450 */
451void
452SHA384_Final(unsigned char digest[static SHA384_DIGEST_LENGTH], SHA384_CTX *ctx)
453{
454
455        /* Add padding */
456        SHA512_Pad((SHA512_CTX *)ctx);
457
458        /* Write the hash */
459        be64enc_vect(digest, ctx->state, SHA384_DIGEST_LENGTH);
460
461        /* Clear the context state */
462        explicit_bzero(ctx, sizeof(*ctx));
463}
Note: See TracBrowser for help on using the repository browser.