1220496Smarkm/*- 2220496Smarkm * Copyright 2005 Colin Percival 3220496Smarkm * All rights reserved. 4220496Smarkm * 5220496Smarkm * Redistribution and use in source and binary forms, with or without 6220496Smarkm * modification, are permitted provided that the following conditions 7220496Smarkm * are met: 8220496Smarkm * 1. Redistributions of source code must retain the above copyright 9220496Smarkm * notice, this list of conditions and the following disclaimer. 10220496Smarkm * 2. Redistributions in binary form must reproduce the above copyright 11220496Smarkm * notice, this list of conditions and the following disclaimer in the 12220496Smarkm * documentation and/or other materials provided with the distribution. 13220496Smarkm * 14220496Smarkm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15220496Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16220496Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17220496Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18220496Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19220496Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20220496Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21220496Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22220496Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23220496Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24220496Smarkm * SUCH DAMAGE. 25220496Smarkm */ 26220496Smarkm 27220496Smarkm#include <sys/cdefs.h> 28220496Smarkm__FBSDID("$FreeBSD$"); 29220496Smarkm 30220496Smarkm#include <sys/endian.h> 31220496Smarkm#include <sys/types.h> 32220496Smarkm 33220496Smarkm#include <string.h> 34220496Smarkm 35220496Smarkm#include "sha512.h" 36220496Smarkm 37220496Smarkm#if BYTE_ORDER == BIG_ENDIAN 38220496Smarkm 39220496Smarkm/* Copy a vector of big-endian uint64_t into a vector of bytes */ 40220496Smarkm#define be64enc_vect(dst, src, len) \ 41220496Smarkm memcpy((void *)dst, (const void *)src, (size_t)len) 42220496Smarkm 43220496Smarkm/* Copy a vector of bytes into a vector of big-endian uint64_t */ 44220496Smarkm#define be64dec_vect(dst, src, len) \ 45220496Smarkm memcpy((void *)dst, (const void *)src, (size_t)len) 46220496Smarkm 47220496Smarkm#else /* BYTE_ORDER != BIG_ENDIAN */ 48220496Smarkm 49220496Smarkm/* 50220496Smarkm * Encode a length len/4 vector of (uint64_t) into a length len vector of 51220496Smarkm * (unsigned char) in big-endian form. Assumes len is a multiple of 8. 52220496Smarkm */ 53220496Smarkmstatic void 54220496Smarkmbe64enc_vect(unsigned char *dst, const uint64_t *src, size_t len) 55220496Smarkm{ 56220496Smarkm size_t i; 57220496Smarkm 58220496Smarkm for (i = 0; i < len / 8; i++) 59220496Smarkm be64enc(dst + i * 8, src[i]); 60220496Smarkm} 61220496Smarkm 62220496Smarkm/* 63220496Smarkm * Decode a big-endian length len vector of (unsigned char) into a length 64220496Smarkm * len/4 vector of (uint64_t). Assumes len is a multiple of 8. 65220496Smarkm */ 66220496Smarkmstatic void 67220496Smarkmbe64dec_vect(uint64_t *dst, const unsigned char *src, size_t len) 68220496Smarkm{ 69220496Smarkm size_t i; 70220496Smarkm 71220496Smarkm for (i = 0; i < len / 8; i++) 72220496Smarkm dst[i] = be64dec(src + i * 8); 73220496Smarkm} 74220496Smarkm 75220496Smarkm#endif /* BYTE_ORDER != BIG_ENDIAN */ 76220496Smarkm 77220496Smarkm/* Elementary functions used by SHA512 */ 78220496Smarkm#define Ch(x, y, z) ((x & (y ^ z)) ^ z) 79220496Smarkm#define Maj(x, y, z) ((x & (y | z)) | (y & z)) 80220496Smarkm#define SHR(x, n) (x >> n) 81220496Smarkm#define ROTR(x, n) ((x >> n) | (x << (64 - n))) 82220496Smarkm#define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) 83220496Smarkm#define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) 84220496Smarkm#define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) 85220496Smarkm#define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6)) 86220496Smarkm 87220496Smarkm/* SHA512 round function */ 88220496Smarkm#define RND(a, b, c, d, e, f, g, h, k) \ 89220496Smarkm t0 = h + S1(e) + Ch(e, f, g) + k; \ 90220496Smarkm t1 = S0(a) + Maj(a, b, c); \ 91220496Smarkm d += t0; \ 92220496Smarkm h = t0 + t1; 93220496Smarkm 94220496Smarkm/* Adjusted round function for rotating state */ 95220496Smarkm#define RNDr(S, W, i, k) \ 96220496Smarkm RND(S[(80 - i) % 8], S[(81 - i) % 8], \ 97220496Smarkm S[(82 - i) % 8], S[(83 - i) % 8], \ 98220496Smarkm S[(84 - i) % 8], S[(85 - i) % 8], \ 99220496Smarkm S[(86 - i) % 8], S[(87 - i) % 8], \ 100220496Smarkm W[i] + k) 101220496Smarkm 102220496Smarkm/* 103220496Smarkm * SHA512 block compression function. The 512-bit state is transformed via 104220496Smarkm * the 512-bit input block to produce a new state. 105220496Smarkm */ 106220496Smarkmstatic void 107220496SmarkmSHA512_Transform(uint64_t * state, const unsigned char block[128]) 108220496Smarkm{ 109220496Smarkm uint64_t W[80]; 110220496Smarkm uint64_t S[8]; 111220496Smarkm uint64_t t0, t1; 112220496Smarkm int i; 113220496Smarkm 114220496Smarkm /* 1. Prepare message schedule W. */ 115220496Smarkm be64dec_vect(W, block, 128); 116220496Smarkm for (i = 16; i < 80; i++) 117220496Smarkm W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; 118220496Smarkm 119220496Smarkm /* 2. Initialize working variables. */ 120220496Smarkm memcpy(S, state, 64); 121220496Smarkm 122220496Smarkm /* 3. Mix. */ 123220496Smarkm RNDr(S, W, 0, 0x428a2f98d728ae22ULL); 124220496Smarkm RNDr(S, W, 1, 0x7137449123ef65cdULL); 125220496Smarkm RNDr(S, W, 2, 0xb5c0fbcfec4d3b2fULL); 126220496Smarkm RNDr(S, W, 3, 0xe9b5dba58189dbbcULL); 127220496Smarkm RNDr(S, W, 4, 0x3956c25bf348b538ULL); 128220496Smarkm RNDr(S, W, 5, 0x59f111f1b605d019ULL); 129220496Smarkm RNDr(S, W, 6, 0x923f82a4af194f9bULL); 130220496Smarkm RNDr(S, W, 7, 0xab1c5ed5da6d8118ULL); 131220496Smarkm RNDr(S, W, 8, 0xd807aa98a3030242ULL); 132220496Smarkm RNDr(S, W, 9, 0x12835b0145706fbeULL); 133220496Smarkm RNDr(S, W, 10, 0x243185be4ee4b28cULL); 134220496Smarkm RNDr(S, W, 11, 0x550c7dc3d5ffb4e2ULL); 135220496Smarkm RNDr(S, W, 12, 0x72be5d74f27b896fULL); 136220496Smarkm RNDr(S, W, 13, 0x80deb1fe3b1696b1ULL); 137220496Smarkm RNDr(S, W, 14, 0x9bdc06a725c71235ULL); 138220496Smarkm RNDr(S, W, 15, 0xc19bf174cf692694ULL); 139220496Smarkm RNDr(S, W, 16, 0xe49b69c19ef14ad2ULL); 140220496Smarkm RNDr(S, W, 17, 0xefbe4786384f25e3ULL); 141220496Smarkm RNDr(S, W, 18, 0x0fc19dc68b8cd5b5ULL); 142220496Smarkm RNDr(S, W, 19, 0x240ca1cc77ac9c65ULL); 143220496Smarkm RNDr(S, W, 20, 0x2de92c6f592b0275ULL); 144220496Smarkm RNDr(S, W, 21, 0x4a7484aa6ea6e483ULL); 145220496Smarkm RNDr(S, W, 22, 0x5cb0a9dcbd41fbd4ULL); 146220496Smarkm RNDr(S, W, 23, 0x76f988da831153b5ULL); 147220496Smarkm RNDr(S, W, 24, 0x983e5152ee66dfabULL); 148220496Smarkm RNDr(S, W, 25, 0xa831c66d2db43210ULL); 149220496Smarkm RNDr(S, W, 26, 0xb00327c898fb213fULL); 150220496Smarkm RNDr(S, W, 27, 0xbf597fc7beef0ee4ULL); 151220496Smarkm RNDr(S, W, 28, 0xc6e00bf33da88fc2ULL); 152220496Smarkm RNDr(S, W, 29, 0xd5a79147930aa725ULL); 153220496Smarkm RNDr(S, W, 30, 0x06ca6351e003826fULL); 154220496Smarkm RNDr(S, W, 31, 0x142929670a0e6e70ULL); 155220496Smarkm RNDr(S, W, 32, 0x27b70a8546d22ffcULL); 156220496Smarkm RNDr(S, W, 33, 0x2e1b21385c26c926ULL); 157220496Smarkm RNDr(S, W, 34, 0x4d2c6dfc5ac42aedULL); 158220496Smarkm RNDr(S, W, 35, 0x53380d139d95b3dfULL); 159220496Smarkm RNDr(S, W, 36, 0x650a73548baf63deULL); 160220496Smarkm RNDr(S, W, 37, 0x766a0abb3c77b2a8ULL); 161220496Smarkm RNDr(S, W, 38, 0x81c2c92e47edaee6ULL); 162220496Smarkm RNDr(S, W, 39, 0x92722c851482353bULL); 163220496Smarkm RNDr(S, W, 40, 0xa2bfe8a14cf10364ULL); 164220496Smarkm RNDr(S, W, 41, 0xa81a664bbc423001ULL); 165220496Smarkm RNDr(S, W, 42, 0xc24b8b70d0f89791ULL); 166220496Smarkm RNDr(S, W, 43, 0xc76c51a30654be30ULL); 167220496Smarkm RNDr(S, W, 44, 0xd192e819d6ef5218ULL); 168220496Smarkm RNDr(S, W, 45, 0xd69906245565a910ULL); 169220496Smarkm RNDr(S, W, 46, 0xf40e35855771202aULL); 170220496Smarkm RNDr(S, W, 47, 0x106aa07032bbd1b8ULL); 171220496Smarkm RNDr(S, W, 48, 0x19a4c116b8d2d0c8ULL); 172220496Smarkm RNDr(S, W, 49, 0x1e376c085141ab53ULL); 173220496Smarkm RNDr(S, W, 50, 0x2748774cdf8eeb99ULL); 174220496Smarkm RNDr(S, W, 51, 0x34b0bcb5e19b48a8ULL); 175220496Smarkm RNDr(S, W, 52, 0x391c0cb3c5c95a63ULL); 176220496Smarkm RNDr(S, W, 53, 0x4ed8aa4ae3418acbULL); 177220496Smarkm RNDr(S, W, 54, 0x5b9cca4f7763e373ULL); 178220496Smarkm RNDr(S, W, 55, 0x682e6ff3d6b2b8a3ULL); 179220496Smarkm RNDr(S, W, 56, 0x748f82ee5defb2fcULL); 180220496Smarkm RNDr(S, W, 57, 0x78a5636f43172f60ULL); 181220496Smarkm RNDr(S, W, 58, 0x84c87814a1f0ab72ULL); 182220496Smarkm RNDr(S, W, 59, 0x8cc702081a6439ecULL); 183220496Smarkm RNDr(S, W, 60, 0x90befffa23631e28ULL); 184220496Smarkm RNDr(S, W, 61, 0xa4506cebde82bde9ULL); 185220496Smarkm RNDr(S, W, 62, 0xbef9a3f7b2c67915ULL); 186220496Smarkm RNDr(S, W, 63, 0xc67178f2e372532bULL); 187220496Smarkm RNDr(S, W, 64, 0xca273eceea26619cULL); 188220496Smarkm RNDr(S, W, 65, 0xd186b8c721c0c207ULL); 189220496Smarkm RNDr(S, W, 66, 0xeada7dd6cde0eb1eULL); 190220496Smarkm RNDr(S, W, 67, 0xf57d4f7fee6ed178ULL); 191220496Smarkm RNDr(S, W, 68, 0x06f067aa72176fbaULL); 192220496Smarkm RNDr(S, W, 69, 0x0a637dc5a2c898a6ULL); 193220496Smarkm RNDr(S, W, 70, 0x113f9804bef90daeULL); 194220496Smarkm RNDr(S, W, 71, 0x1b710b35131c471bULL); 195220496Smarkm RNDr(S, W, 72, 0x28db77f523047d84ULL); 196220496Smarkm RNDr(S, W, 73, 0x32caab7b40c72493ULL); 197220496Smarkm RNDr(S, W, 74, 0x3c9ebe0a15c9bebcULL); 198220496Smarkm RNDr(S, W, 75, 0x431d67c49c100d4cULL); 199220496Smarkm RNDr(S, W, 76, 0x4cc5d4becb3e42b6ULL); 200220496Smarkm RNDr(S, W, 77, 0x597f299cfc657e2aULL); 201220496Smarkm RNDr(S, W, 78, 0x5fcb6fab3ad6faecULL); 202220496Smarkm RNDr(S, W, 79, 0x6c44198c4a475817ULL); 203220496Smarkm 204220496Smarkm /* 4. Mix local working variables into global state */ 205220496Smarkm for (i = 0; i < 8; i++) 206220496Smarkm state[i] += S[i]; 207220496Smarkm} 208220496Smarkm 209220496Smarkmstatic unsigned char PAD[128] = { 210220496Smarkm 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211220496Smarkm 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212220496Smarkm 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213220496Smarkm 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214220496Smarkm 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215220496Smarkm 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216220496Smarkm 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217220496Smarkm 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 218220496Smarkm}; 219220496Smarkm 220220496Smarkm/* Add padding and terminating bit-count. */ 221220496Smarkmstatic void 222220496SmarkmSHA512_Pad(SHA512_CTX * ctx) 223220496Smarkm{ 224220496Smarkm unsigned char len[16]; 225220496Smarkm uint64_t r, plen; 226220496Smarkm 227220496Smarkm /* 228220496Smarkm * Convert length to a vector of bytes -- we do this now rather 229220496Smarkm * than later because the length will change after we pad. 230220496Smarkm */ 231220496Smarkm be64enc_vect(len, ctx->count, 16); 232220496Smarkm 233220496Smarkm /* Add 1--128 bytes so that the resulting length is 112 mod 128 */ 234220496Smarkm r = (ctx->count[1] >> 3) & 0x7f; 235220496Smarkm plen = (r < 112) ? (112 - r) : (240 - r); 236220496Smarkm SHA512_Update(ctx, PAD, (size_t)plen); 237220496Smarkm 238220496Smarkm /* Add the terminating bit-count */ 239220496Smarkm SHA512_Update(ctx, len, 16); 240220496Smarkm} 241220496Smarkm 242220496Smarkm/* SHA-512 initialization. Begins a SHA-512 operation. */ 243220496Smarkmvoid 244220496SmarkmSHA512_Init(SHA512_CTX * ctx) 245220496Smarkm{ 246220496Smarkm 247220496Smarkm /* Zero bits processed so far */ 248220496Smarkm ctx->count[0] = ctx->count[1] = 0; 249220496Smarkm 250220496Smarkm /* Magic initialization constants */ 251220496Smarkm ctx->state[0] = 0x6a09e667f3bcc908ULL; 252220496Smarkm ctx->state[1] = 0xbb67ae8584caa73bULL; 253220496Smarkm ctx->state[2] = 0x3c6ef372fe94f82bULL; 254220496Smarkm ctx->state[3] = 0xa54ff53a5f1d36f1ULL; 255220496Smarkm ctx->state[4] = 0x510e527fade682d1ULL; 256220496Smarkm ctx->state[5] = 0x9b05688c2b3e6c1fULL; 257220496Smarkm ctx->state[6] = 0x1f83d9abfb41bd6bULL; 258220496Smarkm ctx->state[7] = 0x5be0cd19137e2179ULL; 259220496Smarkm} 260220496Smarkm 261220496Smarkm/* Add bytes into the hash */ 262220496Smarkmvoid 263220496SmarkmSHA512_Update(SHA512_CTX * ctx, const void *in, size_t len) 264220496Smarkm{ 265220496Smarkm uint64_t bitlen[2]; 266220496Smarkm uint64_t r; 267220496Smarkm const unsigned char *src = in; 268220496Smarkm 269220496Smarkm /* Number of bytes left in the buffer from previous updates */ 270220496Smarkm r = (ctx->count[1] >> 3) & 0x7f; 271220496Smarkm 272220496Smarkm /* Convert the length into a number of bits */ 273220496Smarkm bitlen[1] = ((uint64_t)len) << 3; 274220496Smarkm bitlen[0] = ((uint64_t)len) >> 61; 275220496Smarkm 276220496Smarkm /* Update number of bits */ 277220496Smarkm if ((ctx->count[1] += bitlen[1]) < bitlen[1]) 278220496Smarkm ctx->count[0]++; 279220496Smarkm ctx->count[0] += bitlen[0]; 280220496Smarkm 281220496Smarkm /* Handle the case where we don't need to perform any transforms */ 282220496Smarkm if (len < 128 - r) { 283220496Smarkm memcpy(&ctx->buf[r], src, len); 284220496Smarkm return; 285220496Smarkm } 286220496Smarkm 287220496Smarkm /* Finish the current block */ 288220496Smarkm memcpy(&ctx->buf[r], src, 128 - r); 289220496Smarkm SHA512_Transform(ctx->state, ctx->buf); 290220496Smarkm src += 128 - r; 291220496Smarkm len -= 128 - r; 292220496Smarkm 293220496Smarkm /* Perform complete blocks */ 294220496Smarkm while (len >= 128) { 295220496Smarkm SHA512_Transform(ctx->state, src); 296220496Smarkm src += 128; 297220496Smarkm len -= 128; 298220496Smarkm } 299220496Smarkm 300220496Smarkm /* Copy left over data into buffer */ 301220496Smarkm memcpy(ctx->buf, src, len); 302220496Smarkm} 303220496Smarkm 304220496Smarkm/* 305220496Smarkm * SHA-512 finalization. Pads the input data, exports the hash value, 306220496Smarkm * and clears the context state. 307220496Smarkm */ 308220496Smarkmvoid 309220496SmarkmSHA512_Final(unsigned char digest[64], SHA512_CTX * ctx) 310220496Smarkm{ 311220496Smarkm 312220496Smarkm /* Add padding */ 313220496Smarkm SHA512_Pad(ctx); 314220496Smarkm 315220496Smarkm /* Write the hash */ 316220496Smarkm be64enc_vect(digest, ctx->state, 64); 317220496Smarkm 318220496Smarkm /* Clear the context state */ 319220496Smarkm memset((void *)ctx, 0, sizeof(*ctx)); 320220496Smarkm} 321