1
2/*-
3 * Copyright 2005,2007,2009 Colin Percival
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
29#include <limits.h>
30#include <stdint.h>
31#include <stdlib.h>
32#include <string.h>
33
34#include <sys/types.h>
35
36#include "crypto_hash_sha512.h"
37#include "private/common.h"
38#include "utils.h"
39
40static void
41be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
42{
43    size_t i;
44
45    for (i = 0; i < len / 8; i++) {
46        STORE64_BE(dst + i * 8, src[i]);
47    }
48}
49
50static void
51be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
52{
53    size_t i;
54
55    for (i = 0; i < len / 8; i++) {
56        dst[i] = LOAD64_BE(src + i * 8);
57    }
58}
59
60static const uint64_t Krnd[80] = {
61    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
62    0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
63    0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
64    0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
65    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
66    0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
67    0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
68    0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
69    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
70    0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
71    0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
72    0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
73    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
74    0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
75    0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
76    0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
77    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
78    0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
79    0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
80    0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
81    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
82    0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
83    0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
84    0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
85    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
86    0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
87    0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
88};
89
90#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
91#define Maj(x, y, z) ((x & (y | z)) | (y & z))
92#define SHR(x, n) (x >> n)
93#define ROTR(x, n) ROTR64(x, n)
94#define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
95#define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
96#define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
97#define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
98
99#define RND(a, b, c, d, e, f, g, h, k) \
100    h += S1(e) + Ch(e, f, g) + k;      \
101    d += h;                            \
102    h += S0(a) + Maj(a, b, c);
103
104#define RNDr(S, W, i, ii)                                                   \
105    RND(S[(80 - i) % 8], S[(81 - i) % 8], S[(82 - i) % 8], S[(83 - i) % 8], \
106        S[(84 - i) % 8], S[(85 - i) % 8], S[(86 - i) % 8], S[(87 - i) % 8], \
107        W[i + ii] + Krnd[i + ii])
108
109#define MSCH(W, ii, i) \
110    W[i + ii + 16] =   \
111        s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
112
113static void
114SHA512_Transform(uint64_t *state, const uint8_t block[128], uint64_t W[80],
115                 uint64_t S[8])
116{
117    int i;
118
119    be64dec_vect(W, block, 128);
120    memcpy(S, state, 64);
121    for (i = 0; i < 80; i += 16) {
122        RNDr(S, W, 0, i);
123        RNDr(S, W, 1, i);
124        RNDr(S, W, 2, i);
125        RNDr(S, W, 3, i);
126        RNDr(S, W, 4, i);
127        RNDr(S, W, 5, i);
128        RNDr(S, W, 6, i);
129        RNDr(S, W, 7, i);
130        RNDr(S, W, 8, i);
131        RNDr(S, W, 9, i);
132        RNDr(S, W, 10, i);
133        RNDr(S, W, 11, i);
134        RNDr(S, W, 12, i);
135        RNDr(S, W, 13, i);
136        RNDr(S, W, 14, i);
137        RNDr(S, W, 15, i);
138        if (i == 64) {
139            break;
140        }
141        MSCH(W, 0, i);
142        MSCH(W, 1, i);
143        MSCH(W, 2, i);
144        MSCH(W, 3, i);
145        MSCH(W, 4, i);
146        MSCH(W, 5, i);
147        MSCH(W, 6, i);
148        MSCH(W, 7, i);
149        MSCH(W, 8, i);
150        MSCH(W, 9, i);
151        MSCH(W, 10, i);
152        MSCH(W, 11, i);
153        MSCH(W, 12, i);
154        MSCH(W, 13, i);
155        MSCH(W, 14, i);
156        MSCH(W, 15, i);
157    }
158    for (i = 0; i < 8; i++) {
159        state[i] += S[i];
160    }
161}
162
163static const uint8_t PAD[128] = {
164    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
165    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
166    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
167    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
170};
171
172static void
173SHA512_Pad(crypto_hash_sha512_state *state, uint64_t tmp64[80 + 8])
174{
175    unsigned int r;
176    unsigned int i;
177
178    r = (unsigned int) ((state->count[1] >> 3) & 0x7f);
179    if (r < 112) {
180        for (i = 0; i < 112 - r; i++) {
181            state->buf[r + i] = PAD[i];
182        }
183    } else {
184        for (i = 0; i < 128 - r; i++) {
185            state->buf[r + i] = PAD[i];
186        }
187        SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]);
188        memset(&state->buf[0], 0, 112);
189    }
190    be64enc_vect(&state->buf[112], state->count, 16);
191    SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]);
192}
193
194int
195crypto_hash_sha512_init(crypto_hash_sha512_state *state)
196{
197    static const uint64_t sha512_initial_state[8] = {
198        0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
199        0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
200        0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
201    };
202
203    state->count[0] = state->count[1] = (uint64_t) 0U;
204    memcpy(state->state, sha512_initial_state, sizeof sha512_initial_state);
205
206    return 0;
207}
208
209int
210crypto_hash_sha512_update(crypto_hash_sha512_state *state,
211                          const unsigned char *in, unsigned long long inlen)
212{
213    uint64_t           tmp64[80 + 8];
214    uint64_t           bitlen[2];
215    unsigned long long i;
216    unsigned long long r;
217
218    if (inlen <= 0U) {
219        return 0;
220    }
221    r = (unsigned long long) ((state->count[1] >> 3) & 0x7f);
222
223    bitlen[1] = ((uint64_t) inlen) << 3;
224    bitlen[0] = ((uint64_t) inlen) >> 61;
225    /* LCOV_EXCL_START */
226    if ((state->count[1] += bitlen[1]) < bitlen[1]) {
227        state->count[0]++;
228    }
229    /* LCOV_EXCL_STOP */
230    state->count[0] += bitlen[0];
231    if (inlen < 128 - r) {
232        for (i = 0; i < inlen; i++) {
233            state->buf[r + i] = in[i];
234        }
235        return 0;
236    }
237    for (i = 0; i < 128 - r; i++) {
238        state->buf[r + i] = in[i];
239    }
240    SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]);
241    in += 128 - r;
242    inlen -= 128 - r;
243
244    while (inlen >= 128) {
245        SHA512_Transform(state->state, in, &tmp64[0], &tmp64[80]);
246        in += 128;
247        inlen -= 128;
248    }
249    inlen &= 127;
250    for (i = 0; i < inlen; i++) {
251        state->buf[i] = in[i];
252    }
253    sodium_memzero((void *) tmp64, sizeof tmp64);
254
255    return 0;
256}
257
258int
259crypto_hash_sha512_final(crypto_hash_sha512_state *state, unsigned char *out)
260{
261    uint64_t tmp64[80 + 8];
262
263    SHA512_Pad(state, tmp64);
264    be64enc_vect(out, state->state, 64);
265    sodium_memzero((void *) tmp64, sizeof tmp64);
266    sodium_memzero((void *) state, sizeof *state);
267
268    return 0;
269}
270
271int
272crypto_hash_sha512(unsigned char *out, const unsigned char *in,
273                   unsigned long long inlen)
274{
275    crypto_hash_sha512_state state;
276
277    crypto_hash_sha512_init(&state);
278    crypto_hash_sha512_update(&state, in, inlen);
279    crypto_hash_sha512_final(&state, out);
280
281    return 0;
282}
283