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
40 static void
be64enc_vect(unsigned char * dst,const uint64_t * src,size_t len)41 be64enc_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
50 static void
be64dec_vect(uint64_t * dst,const unsigned char * src,size_t len)51 be64dec_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
60 static 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
113 static void
SHA512_Transform(uint64_t * state,const uint8_t block[128],uint64_t W[80],uint64_t S[8])114 SHA512_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
163 static 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
172 static void
SHA512_Pad(crypto_hash_sha512_state * state,uint64_t tmp64[80+8])173 SHA512_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
194 int
crypto_hash_sha512_init(crypto_hash_sha512_state * state)195 crypto_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
209 int
crypto_hash_sha512_update(crypto_hash_sha512_state * state,const unsigned char * in,unsigned long long inlen)210 crypto_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
258 int
crypto_hash_sha512_final(crypto_hash_sha512_state * state,unsigned char * out)259 crypto_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
271 int
crypto_hash_sha512(unsigned char * out,const unsigned char * in,unsigned long long inlen)272 crypto_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