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 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 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 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 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 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 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 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 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