17a3f5d11SAllan Jude /*- 27a3f5d11SAllan Jude * Copyright 2005 Colin Percival 31780e407SAllan Jude * Copyright (c) 2015 Allan Jude <allanjude@FreeBSD.org> 47a3f5d11SAllan Jude * All rights reserved. 57a3f5d11SAllan Jude * 67a3f5d11SAllan Jude * Redistribution and use in source and binary forms, with or without 77a3f5d11SAllan Jude * modification, are permitted provided that the following conditions 87a3f5d11SAllan Jude * are met: 97a3f5d11SAllan Jude * 1. Redistributions of source code must retain the above copyright 107a3f5d11SAllan Jude * notice, this list of conditions and the following disclaimer. 117a3f5d11SAllan Jude * 2. Redistributions in binary form must reproduce the above copyright 127a3f5d11SAllan Jude * notice, this list of conditions and the following disclaimer in the 137a3f5d11SAllan Jude * documentation and/or other materials provided with the distribution. 147a3f5d11SAllan Jude * 157a3f5d11SAllan Jude * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 167a3f5d11SAllan Jude * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 177a3f5d11SAllan Jude * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 187a3f5d11SAllan Jude * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 197a3f5d11SAllan Jude * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 207a3f5d11SAllan Jude * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 217a3f5d11SAllan Jude * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 227a3f5d11SAllan Jude * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 237a3f5d11SAllan Jude * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 247a3f5d11SAllan Jude * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 257a3f5d11SAllan Jude * SUCH DAMAGE. 267a3f5d11SAllan Jude */ 277a3f5d11SAllan Jude 287a3f5d11SAllan Jude #include <sys/cdefs.h> 297a3f5d11SAllan Jude __FBSDID("$FreeBSD$"); 307a3f5d11SAllan Jude 317a3f5d11SAllan Jude #include <sys/endian.h> 327a3f5d11SAllan Jude #include <sys/types.h> 337a3f5d11SAllan Jude 347a3f5d11SAllan Jude #ifdef _KERNEL 357a3f5d11SAllan Jude #include <sys/systm.h> 367a3f5d11SAllan Jude #else 377a3f5d11SAllan Jude #include <string.h> 387a3f5d11SAllan Jude #endif 397a3f5d11SAllan Jude 407a3f5d11SAllan Jude #include "sha512.h" 411780e407SAllan Jude #include "sha512t.h" 427a3f5d11SAllan Jude #include "sha384.h" 4371bf1c4cSAndrew Turner #include "sha512c_impl.h" 4471bf1c4cSAndrew Turner 4571bf1c4cSAndrew Turner #if defined(ARM64_SHA512) 4671bf1c4cSAndrew Turner #include <sys/auxv.h> 4771bf1c4cSAndrew Turner #include <machine/ifunc.h> 4871bf1c4cSAndrew Turner #endif 497a3f5d11SAllan Jude 507a3f5d11SAllan Jude #if BYTE_ORDER == BIG_ENDIAN 517a3f5d11SAllan Jude 527a3f5d11SAllan Jude /* Copy a vector of big-endian uint64_t into a vector of bytes */ 537a3f5d11SAllan Jude #define be64enc_vect(dst, src, len) \ 547a3f5d11SAllan Jude memcpy((void *)dst, (const void *)src, (size_t)len) 557a3f5d11SAllan Jude 567a3f5d11SAllan Jude /* Copy a vector of bytes into a vector of big-endian uint64_t */ 577a3f5d11SAllan Jude #define be64dec_vect(dst, src, len) \ 587a3f5d11SAllan Jude memcpy((void *)dst, (const void *)src, (size_t)len) 597a3f5d11SAllan Jude 607a3f5d11SAllan Jude #else /* BYTE_ORDER != BIG_ENDIAN */ 617a3f5d11SAllan Jude 627a3f5d11SAllan Jude /* 63*6680cfe8SSebastian Huber * Encode a length (len + 7) / 8 vector of (uint64_t) into a length len 64*6680cfe8SSebastian Huber * vector of (unsigned char) in big-endian form. Assumes len is a 65*6680cfe8SSebastian Huber * multiple of 4. 667a3f5d11SAllan Jude */ 67*6680cfe8SSebastian Huber static inline void 687a3f5d11SAllan Jude be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len) 697a3f5d11SAllan Jude { 707a3f5d11SAllan Jude size_t i; 717a3f5d11SAllan Jude 727a3f5d11SAllan Jude for (i = 0; i < len / 8; i++) 737a3f5d11SAllan Jude be64enc(dst + i * 8, src[i]); 74*6680cfe8SSebastian Huber if (len % 8 == 4) 75*6680cfe8SSebastian Huber be32enc(dst + i * 8, src[i] >> 32); 767a3f5d11SAllan Jude } 777a3f5d11SAllan Jude 787a3f5d11SAllan Jude /* 797a3f5d11SAllan Jude * Decode a big-endian length len vector of (unsigned char) into a length 80*6680cfe8SSebastian Huber * len/8 vector of (uint64_t). Assumes len is a multiple of 8. 817a3f5d11SAllan Jude */ 82*6680cfe8SSebastian Huber static inline void 837a3f5d11SAllan Jude be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len) 847a3f5d11SAllan Jude { 857a3f5d11SAllan Jude size_t i; 867a3f5d11SAllan Jude 877a3f5d11SAllan Jude for (i = 0; i < len / 8; i++) 887a3f5d11SAllan Jude dst[i] = be64dec(src + i * 8); 897a3f5d11SAllan Jude } 907a3f5d11SAllan Jude 917a3f5d11SAllan Jude #endif /* BYTE_ORDER != BIG_ENDIAN */ 927a3f5d11SAllan Jude 93696c3895SColin Percival /* SHA512 round constants. */ 94696c3895SColin Percival static const uint64_t K[80] = { 95696c3895SColin Percival 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 96696c3895SColin Percival 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 97696c3895SColin Percival 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 98696c3895SColin Percival 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 99696c3895SColin Percival 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 100696c3895SColin Percival 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 101696c3895SColin Percival 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 102696c3895SColin Percival 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 103696c3895SColin Percival 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 104696c3895SColin Percival 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 105696c3895SColin Percival 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 106696c3895SColin Percival 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 107696c3895SColin Percival 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 108696c3895SColin Percival 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 109696c3895SColin Percival 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 110696c3895SColin Percival 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 111696c3895SColin Percival 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 112696c3895SColin Percival 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 113696c3895SColin Percival 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 114696c3895SColin Percival 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 115696c3895SColin Percival 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 116696c3895SColin Percival 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 117696c3895SColin Percival 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 118696c3895SColin Percival 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 119696c3895SColin Percival 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 120696c3895SColin Percival 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 121696c3895SColin Percival 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 122696c3895SColin Percival 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 123696c3895SColin Percival 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 124696c3895SColin Percival 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 125696c3895SColin Percival 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 126696c3895SColin Percival 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 127696c3895SColin Percival 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 128696c3895SColin Percival 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 129696c3895SColin Percival 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 130696c3895SColin Percival 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 131696c3895SColin Percival 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 132696c3895SColin Percival 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 133696c3895SColin Percival 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 134696c3895SColin Percival 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL 135696c3895SColin Percival }; 136696c3895SColin Percival 1377a3f5d11SAllan Jude /* Elementary functions used by SHA512 */ 1387a3f5d11SAllan Jude #define Ch(x, y, z) ((x & (y ^ z)) ^ z) 1397a3f5d11SAllan Jude #define Maj(x, y, z) ((x & (y | z)) | (y & z)) 1407a3f5d11SAllan Jude #define SHR(x, n) (x >> n) 1417a3f5d11SAllan Jude #define ROTR(x, n) ((x >> n) | (x << (64 - n))) 1427a3f5d11SAllan Jude #define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) 1437a3f5d11SAllan Jude #define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) 1447a3f5d11SAllan Jude #define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) 1457a3f5d11SAllan Jude #define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6)) 1467a3f5d11SAllan Jude 1477a3f5d11SAllan Jude /* SHA512 round function */ 1487a3f5d11SAllan Jude #define RND(a, b, c, d, e, f, g, h, k) \ 149696c3895SColin Percival h += S1(e) + Ch(e, f, g) + k; \ 150696c3895SColin Percival d += h; \ 151696c3895SColin Percival h += S0(a) + Maj(a, b, c); 1527a3f5d11SAllan Jude 1537a3f5d11SAllan Jude /* Adjusted round function for rotating state */ 154696c3895SColin Percival #define RNDr(S, W, i, ii) \ 1557a3f5d11SAllan Jude RND(S[(80 - i) % 8], S[(81 - i) % 8], \ 1567a3f5d11SAllan Jude S[(82 - i) % 8], S[(83 - i) % 8], \ 1577a3f5d11SAllan Jude S[(84 - i) % 8], S[(85 - i) % 8], \ 1587a3f5d11SAllan Jude S[(86 - i) % 8], S[(87 - i) % 8], \ 159696c3895SColin Percival W[i + ii] + K[i + ii]) 160696c3895SColin Percival 161696c3895SColin Percival /* Message schedule computation */ 162696c3895SColin Percival #define MSCH(W, ii, i) \ 163696c3895SColin Percival W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii] 1647a3f5d11SAllan Jude 1657a3f5d11SAllan Jude /* 1667a3f5d11SAllan Jude * SHA512 block compression function. The 512-bit state is transformed via 1677a3f5d11SAllan Jude * the 512-bit input block to produce a new state. 1687a3f5d11SAllan Jude */ 1697a3f5d11SAllan Jude static void 17071bf1c4cSAndrew Turner #if defined(ARM64_SHA512) 17171bf1c4cSAndrew Turner SHA512_Transform_c(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH]) 17271bf1c4cSAndrew Turner #else 1737a3f5d11SAllan Jude SHA512_Transform(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH]) 17471bf1c4cSAndrew Turner #endif 1757a3f5d11SAllan Jude { 1767a3f5d11SAllan Jude uint64_t W[80]; 1777a3f5d11SAllan Jude uint64_t S[8]; 1787a3f5d11SAllan Jude int i; 1797a3f5d11SAllan Jude 180696c3895SColin Percival /* 1. Prepare the first part of the message schedule W. */ 1817a3f5d11SAllan Jude be64dec_vect(W, block, SHA512_BLOCK_LENGTH); 1827a3f5d11SAllan Jude 1837a3f5d11SAllan Jude /* 2. Initialize working variables. */ 1847a3f5d11SAllan Jude memcpy(S, state, SHA512_DIGEST_LENGTH); 1857a3f5d11SAllan Jude 1867a3f5d11SAllan Jude /* 3. Mix. */ 187696c3895SColin Percival for (i = 0; i < 80; i += 16) { 188696c3895SColin Percival RNDr(S, W, 0, i); 189696c3895SColin Percival RNDr(S, W, 1, i); 190696c3895SColin Percival RNDr(S, W, 2, i); 191696c3895SColin Percival RNDr(S, W, 3, i); 192696c3895SColin Percival RNDr(S, W, 4, i); 193696c3895SColin Percival RNDr(S, W, 5, i); 194696c3895SColin Percival RNDr(S, W, 6, i); 195696c3895SColin Percival RNDr(S, W, 7, i); 196696c3895SColin Percival RNDr(S, W, 8, i); 197696c3895SColin Percival RNDr(S, W, 9, i); 198696c3895SColin Percival RNDr(S, W, 10, i); 199696c3895SColin Percival RNDr(S, W, 11, i); 200696c3895SColin Percival RNDr(S, W, 12, i); 201696c3895SColin Percival RNDr(S, W, 13, i); 202696c3895SColin Percival RNDr(S, W, 14, i); 203696c3895SColin Percival RNDr(S, W, 15, i); 204696c3895SColin Percival 205696c3895SColin Percival if (i == 64) 206696c3895SColin Percival break; 207696c3895SColin Percival MSCH(W, 0, i); 208696c3895SColin Percival MSCH(W, 1, i); 209696c3895SColin Percival MSCH(W, 2, i); 210696c3895SColin Percival MSCH(W, 3, i); 211696c3895SColin Percival MSCH(W, 4, i); 212696c3895SColin Percival MSCH(W, 5, i); 213696c3895SColin Percival MSCH(W, 6, i); 214696c3895SColin Percival MSCH(W, 7, i); 215696c3895SColin Percival MSCH(W, 8, i); 216696c3895SColin Percival MSCH(W, 9, i); 217696c3895SColin Percival MSCH(W, 10, i); 218696c3895SColin Percival MSCH(W, 11, i); 219696c3895SColin Percival MSCH(W, 12, i); 220696c3895SColin Percival MSCH(W, 13, i); 221696c3895SColin Percival MSCH(W, 14, i); 222696c3895SColin Percival MSCH(W, 15, i); 223696c3895SColin Percival } 2247a3f5d11SAllan Jude 2257a3f5d11SAllan Jude /* 4. Mix local working variables into global state */ 2267a3f5d11SAllan Jude for (i = 0; i < 8; i++) 2277a3f5d11SAllan Jude state[i] += S[i]; 2287a3f5d11SAllan Jude } 2297a3f5d11SAllan Jude 23071bf1c4cSAndrew Turner #if defined(ARM64_SHA512) 23171bf1c4cSAndrew Turner static void 23271bf1c4cSAndrew Turner SHA512_Transform_arm64(uint64_t * state, 23371bf1c4cSAndrew Turner const unsigned char block[SHA512_BLOCK_LENGTH]) 23471bf1c4cSAndrew Turner { 23571bf1c4cSAndrew Turner SHA512_Transform_arm64_impl(state, block, K); 23671bf1c4cSAndrew Turner } 23771bf1c4cSAndrew Turner 23871bf1c4cSAndrew Turner DEFINE_UIFUNC(static, void, SHA512_Transform, 23971bf1c4cSAndrew Turner (uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH])) 24071bf1c4cSAndrew Turner { 24171bf1c4cSAndrew Turner u_long hwcap; 24271bf1c4cSAndrew Turner 24371bf1c4cSAndrew Turner if (elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)) == 0) { 24471bf1c4cSAndrew Turner if ((hwcap & HWCAP_SHA512) != 0) { 24571bf1c4cSAndrew Turner return (SHA512_Transform_arm64); 24671bf1c4cSAndrew Turner } 24771bf1c4cSAndrew Turner } 24871bf1c4cSAndrew Turner 24971bf1c4cSAndrew Turner return (SHA512_Transform_c); 25071bf1c4cSAndrew Turner } 25171bf1c4cSAndrew Turner #endif 25271bf1c4cSAndrew Turner 2537a3f5d11SAllan Jude static unsigned char PAD[SHA512_BLOCK_LENGTH] = { 2547a3f5d11SAllan Jude 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2557a3f5d11SAllan Jude 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2567a3f5d11SAllan Jude 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2577a3f5d11SAllan Jude 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2587a3f5d11SAllan Jude 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2597a3f5d11SAllan Jude 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2607a3f5d11SAllan Jude 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2617a3f5d11SAllan Jude 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 2627a3f5d11SAllan Jude }; 2637a3f5d11SAllan Jude 2647a3f5d11SAllan Jude /* Add padding and terminating bit-count. */ 2657a3f5d11SAllan Jude static void 2667a3f5d11SAllan Jude SHA512_Pad(SHA512_CTX * ctx) 2677a3f5d11SAllan Jude { 268696c3895SColin Percival size_t r; 2697a3f5d11SAllan Jude 270696c3895SColin Percival /* Figure out how many bytes we have buffered. */ 2717a3f5d11SAllan Jude r = (ctx->count[1] >> 3) & 0x7f; 2727a3f5d11SAllan Jude 273696c3895SColin Percival /* Pad to 112 mod 128, transforming if we finish a block en route. */ 274696c3895SColin Percival if (r < 112) { 275696c3895SColin Percival /* Pad to 112 mod 128. */ 276696c3895SColin Percival memcpy(&ctx->buf[r], PAD, 112 - r); 277696c3895SColin Percival } else { 278696c3895SColin Percival /* Finish the current block and mix. */ 279696c3895SColin Percival memcpy(&ctx->buf[r], PAD, 128 - r); 280696c3895SColin Percival SHA512_Transform(ctx->state, ctx->buf); 281696c3895SColin Percival 282696c3895SColin Percival /* The start of the final block is all zeroes. */ 283696c3895SColin Percival memset(&ctx->buf[0], 0, 112); 284696c3895SColin Percival } 285696c3895SColin Percival 286696c3895SColin Percival /* Add the terminating bit-count. */ 287696c3895SColin Percival be64enc_vect(&ctx->buf[112], ctx->count, 16); 288696c3895SColin Percival 289696c3895SColin Percival /* Mix in the final block. */ 290696c3895SColin Percival SHA512_Transform(ctx->state, ctx->buf); 2917a3f5d11SAllan Jude } 2927a3f5d11SAllan Jude 2937a3f5d11SAllan Jude /* SHA-512 initialization. Begins a SHA-512 operation. */ 2947a3f5d11SAllan Jude void 2957a3f5d11SAllan Jude SHA512_Init(SHA512_CTX * ctx) 2967a3f5d11SAllan Jude { 2977a3f5d11SAllan Jude 2987a3f5d11SAllan Jude /* Zero bits processed so far */ 2997a3f5d11SAllan Jude ctx->count[0] = ctx->count[1] = 0; 3007a3f5d11SAllan Jude 3017a3f5d11SAllan Jude /* Magic initialization constants */ 3027a3f5d11SAllan Jude ctx->state[0] = 0x6a09e667f3bcc908ULL; 3037a3f5d11SAllan Jude ctx->state[1] = 0xbb67ae8584caa73bULL; 3047a3f5d11SAllan Jude ctx->state[2] = 0x3c6ef372fe94f82bULL; 3057a3f5d11SAllan Jude ctx->state[3] = 0xa54ff53a5f1d36f1ULL; 3067a3f5d11SAllan Jude ctx->state[4] = 0x510e527fade682d1ULL; 3077a3f5d11SAllan Jude ctx->state[5] = 0x9b05688c2b3e6c1fULL; 3087a3f5d11SAllan Jude ctx->state[6] = 0x1f83d9abfb41bd6bULL; 3097a3f5d11SAllan Jude ctx->state[7] = 0x5be0cd19137e2179ULL; 3107a3f5d11SAllan Jude } 3117a3f5d11SAllan Jude 3127a3f5d11SAllan Jude /* Add bytes into the hash */ 3137a3f5d11SAllan Jude void 3147a3f5d11SAllan Jude SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len) 3157a3f5d11SAllan Jude { 3167a3f5d11SAllan Jude uint64_t bitlen[2]; 3177a3f5d11SAllan Jude uint64_t r; 3187a3f5d11SAllan Jude const unsigned char *src = in; 3197a3f5d11SAllan Jude 3207a3f5d11SAllan Jude /* Number of bytes left in the buffer from previous updates */ 3217a3f5d11SAllan Jude r = (ctx->count[1] >> 3) & 0x7f; 3227a3f5d11SAllan Jude 3237a3f5d11SAllan Jude /* Convert the length into a number of bits */ 3247a3f5d11SAllan Jude bitlen[1] = ((uint64_t)len) << 3; 3257a3f5d11SAllan Jude bitlen[0] = ((uint64_t)len) >> 61; 3267a3f5d11SAllan Jude 3277a3f5d11SAllan Jude /* Update number of bits */ 3287a3f5d11SAllan Jude if ((ctx->count[1] += bitlen[1]) < bitlen[1]) 3297a3f5d11SAllan Jude ctx->count[0]++; 3307a3f5d11SAllan Jude ctx->count[0] += bitlen[0]; 3317a3f5d11SAllan Jude 3327a3f5d11SAllan Jude /* Handle the case where we don't need to perform any transforms */ 3337a3f5d11SAllan Jude if (len < SHA512_BLOCK_LENGTH - r) { 3347a3f5d11SAllan Jude memcpy(&ctx->buf[r], src, len); 3357a3f5d11SAllan Jude return; 3367a3f5d11SAllan Jude } 3377a3f5d11SAllan Jude 3387a3f5d11SAllan Jude /* Finish the current block */ 3397a3f5d11SAllan Jude memcpy(&ctx->buf[r], src, SHA512_BLOCK_LENGTH - r); 3407a3f5d11SAllan Jude SHA512_Transform(ctx->state, ctx->buf); 3417a3f5d11SAllan Jude src += SHA512_BLOCK_LENGTH - r; 3427a3f5d11SAllan Jude len -= SHA512_BLOCK_LENGTH - r; 3437a3f5d11SAllan Jude 3447a3f5d11SAllan Jude /* Perform complete blocks */ 3457a3f5d11SAllan Jude while (len >= SHA512_BLOCK_LENGTH) { 3467a3f5d11SAllan Jude SHA512_Transform(ctx->state, src); 3477a3f5d11SAllan Jude src += SHA512_BLOCK_LENGTH; 3487a3f5d11SAllan Jude len -= SHA512_BLOCK_LENGTH; 3497a3f5d11SAllan Jude } 3507a3f5d11SAllan Jude 3517a3f5d11SAllan Jude /* Copy left over data into buffer */ 3527a3f5d11SAllan Jude memcpy(ctx->buf, src, len); 3537a3f5d11SAllan Jude } 3547a3f5d11SAllan Jude 3557a3f5d11SAllan Jude /* 3567a3f5d11SAllan Jude * SHA-512 finalization. Pads the input data, exports the hash value, 3577a3f5d11SAllan Jude * and clears the context state. 3587a3f5d11SAllan Jude */ 3597a3f5d11SAllan Jude void 360571ebf76SConrad Meyer SHA512_Final(unsigned char digest[static SHA512_DIGEST_LENGTH], SHA512_CTX *ctx) 3617a3f5d11SAllan Jude { 3627a3f5d11SAllan Jude 3637a3f5d11SAllan Jude /* Add padding */ 3647a3f5d11SAllan Jude SHA512_Pad(ctx); 3657a3f5d11SAllan Jude 3667a3f5d11SAllan Jude /* Write the hash */ 3677a3f5d11SAllan Jude be64enc_vect(digest, ctx->state, SHA512_DIGEST_LENGTH); 3687a3f5d11SAllan Jude 3697a3f5d11SAllan Jude /* Clear the context state */ 37066bdf50fSXin LI explicit_bzero(ctx, sizeof(*ctx)); 3717a3f5d11SAllan Jude } 3727a3f5d11SAllan Jude 3731780e407SAllan Jude /*** SHA-512t: *********************************************************/ 3741780e407SAllan Jude /* 3751780e407SAllan Jude * the SHA512t transforms are identical to SHA512 so reuse the existing function 3761780e407SAllan Jude */ 3771780e407SAllan Jude void 3781780e407SAllan Jude SHA512_224_Init(SHA512_CTX * ctx) 3791780e407SAllan Jude { 3801780e407SAllan Jude 3811780e407SAllan Jude /* Zero bits processed so far */ 3821780e407SAllan Jude ctx->count[0] = ctx->count[1] = 0; 3831780e407SAllan Jude 3841780e407SAllan Jude /* Magic initialization constants */ 3851780e407SAllan Jude ctx->state[0] = 0x8c3d37c819544da2ULL; 3861780e407SAllan Jude ctx->state[1] = 0x73e1996689dcd4d6ULL; 3871780e407SAllan Jude ctx->state[2] = 0x1dfab7ae32ff9c82ULL; 3881780e407SAllan Jude ctx->state[3] = 0x679dd514582f9fcfULL; 3891780e407SAllan Jude ctx->state[4] = 0x0f6d2b697bd44da8ULL; 3901780e407SAllan Jude ctx->state[5] = 0x77e36f7304c48942ULL; 3911780e407SAllan Jude ctx->state[6] = 0x3f9d85a86a1d36c8ULL; 3921780e407SAllan Jude ctx->state[7] = 0x1112e6ad91d692a1ULL; 3931780e407SAllan Jude } 3941780e407SAllan Jude 3951780e407SAllan Jude void 3961780e407SAllan Jude SHA512_224_Update(SHA512_CTX * ctx, const void *in, size_t len) 3971780e407SAllan Jude { 3981780e407SAllan Jude 3991780e407SAllan Jude SHA512_Update(ctx, in, len); 4001780e407SAllan Jude } 4011780e407SAllan Jude 4021780e407SAllan Jude void 4031780e407SAllan Jude SHA512_224_Final(unsigned char digest[static SHA512_224_DIGEST_LENGTH], SHA512_CTX * ctx) 4041780e407SAllan Jude { 4051780e407SAllan Jude 4061780e407SAllan Jude /* Add padding */ 4071780e407SAllan Jude SHA512_Pad(ctx); 4081780e407SAllan Jude 4091780e407SAllan Jude /* Write the hash */ 4101780e407SAllan Jude be64enc_vect(digest, ctx->state, SHA512_224_DIGEST_LENGTH); 4111780e407SAllan Jude 4121780e407SAllan Jude /* Clear the context state */ 41366bdf50fSXin LI explicit_bzero(ctx, sizeof(*ctx)); 4141780e407SAllan Jude } 4151780e407SAllan Jude 4161780e407SAllan Jude void 4171780e407SAllan Jude SHA512_256_Init(SHA512_CTX * ctx) 4181780e407SAllan Jude { 4191780e407SAllan Jude 4201780e407SAllan Jude /* Zero bits processed so far */ 4211780e407SAllan Jude ctx->count[0] = ctx->count[1] = 0; 4221780e407SAllan Jude 4231780e407SAllan Jude /* Magic initialization constants */ 4241780e407SAllan Jude ctx->state[0] = 0x22312194fc2bf72cULL; 4251780e407SAllan Jude ctx->state[1] = 0x9f555fa3c84c64c2ULL; 4261780e407SAllan Jude ctx->state[2] = 0x2393b86b6f53b151ULL; 4271780e407SAllan Jude ctx->state[3] = 0x963877195940eabdULL; 4281780e407SAllan Jude ctx->state[4] = 0x96283ee2a88effe3ULL; 4291780e407SAllan Jude ctx->state[5] = 0xbe5e1e2553863992ULL; 4301780e407SAllan Jude ctx->state[6] = 0x2b0199fc2c85b8aaULL; 4311780e407SAllan Jude ctx->state[7] = 0x0eb72ddc81c52ca2ULL; 4321780e407SAllan Jude } 4331780e407SAllan Jude 4341780e407SAllan Jude void 4351780e407SAllan Jude SHA512_256_Update(SHA512_CTX * ctx, const void *in, size_t len) 4361780e407SAllan Jude { 4371780e407SAllan Jude 4381780e407SAllan Jude SHA512_Update(ctx, in, len); 4391780e407SAllan Jude } 4401780e407SAllan Jude 4411780e407SAllan Jude void 4421780e407SAllan Jude SHA512_256_Final(unsigned char digest[static SHA512_256_DIGEST_LENGTH], SHA512_CTX * ctx) 4431780e407SAllan Jude { 4441780e407SAllan Jude 4451780e407SAllan Jude /* Add padding */ 4461780e407SAllan Jude SHA512_Pad(ctx); 4471780e407SAllan Jude 4481780e407SAllan Jude /* Write the hash */ 4491780e407SAllan Jude be64enc_vect(digest, ctx->state, SHA512_256_DIGEST_LENGTH); 4501780e407SAllan Jude 4511780e407SAllan Jude /* Clear the context state */ 45266bdf50fSXin LI explicit_bzero(ctx, sizeof(*ctx)); 4531780e407SAllan Jude } 4541780e407SAllan Jude 4557a3f5d11SAllan Jude /*** SHA-384: *********************************************************/ 4567a3f5d11SAllan Jude /* 4577a3f5d11SAllan Jude * the SHA384 and SHA512 transforms are identical, so SHA384 is skipped 4587a3f5d11SAllan Jude */ 4597a3f5d11SAllan Jude 4607a3f5d11SAllan Jude /* SHA-384 initialization. Begins a SHA-384 operation. */ 4617a3f5d11SAllan Jude void 4627a3f5d11SAllan Jude SHA384_Init(SHA384_CTX * ctx) 4637a3f5d11SAllan Jude { 4647a3f5d11SAllan Jude 4657a3f5d11SAllan Jude /* Zero bits processed so far */ 4667a3f5d11SAllan Jude ctx->count[0] = ctx->count[1] = 0; 4677a3f5d11SAllan Jude 4687a3f5d11SAllan Jude /* Magic initialization constants */ 4697a3f5d11SAllan Jude ctx->state[0] = 0xcbbb9d5dc1059ed8ULL; 4707a3f5d11SAllan Jude ctx->state[1] = 0x629a292a367cd507ULL; 4717a3f5d11SAllan Jude ctx->state[2] = 0x9159015a3070dd17ULL; 4727a3f5d11SAllan Jude ctx->state[3] = 0x152fecd8f70e5939ULL; 4737a3f5d11SAllan Jude ctx->state[4] = 0x67332667ffc00b31ULL; 4747a3f5d11SAllan Jude ctx->state[5] = 0x8eb44a8768581511ULL; 4757a3f5d11SAllan Jude ctx->state[6] = 0xdb0c2e0d64f98fa7ULL; 4767a3f5d11SAllan Jude ctx->state[7] = 0x47b5481dbefa4fa4ULL; 4777a3f5d11SAllan Jude } 4787a3f5d11SAllan Jude 4797a3f5d11SAllan Jude /* Add bytes into the SHA-384 hash */ 4807a3f5d11SAllan Jude void 4817a3f5d11SAllan Jude SHA384_Update(SHA384_CTX * ctx, const void *in, size_t len) 4827a3f5d11SAllan Jude { 4837a3f5d11SAllan Jude 4847a3f5d11SAllan Jude SHA512_Update((SHA512_CTX *)ctx, in, len); 4857a3f5d11SAllan Jude } 4867a3f5d11SAllan Jude 4877a3f5d11SAllan Jude /* 4887a3f5d11SAllan Jude * SHA-384 finalization. Pads the input data, exports the hash value, 4897a3f5d11SAllan Jude * and clears the context state. 4907a3f5d11SAllan Jude */ 4917a3f5d11SAllan Jude void 492571ebf76SConrad Meyer SHA384_Final(unsigned char digest[static SHA384_DIGEST_LENGTH], SHA384_CTX *ctx) 4937a3f5d11SAllan Jude { 4947a3f5d11SAllan Jude 4957a3f5d11SAllan Jude /* Add padding */ 4967a3f5d11SAllan Jude SHA512_Pad((SHA512_CTX *)ctx); 4977a3f5d11SAllan Jude 4987a3f5d11SAllan Jude /* Write the hash */ 4997a3f5d11SAllan Jude be64enc_vect(digest, ctx->state, SHA384_DIGEST_LENGTH); 5007a3f5d11SAllan Jude 5017a3f5d11SAllan Jude /* Clear the context state */ 50266bdf50fSXin LI explicit_bzero(ctx, sizeof(*ctx)); 5037a3f5d11SAllan Jude } 5047a3f5d11SAllan Jude 5057a3f5d11SAllan Jude #ifdef WEAK_REFS 5067a3f5d11SAllan Jude /* When building libmd, provide weak references. Note: this is not 5077a3f5d11SAllan Jude activated in the context of compiling these sources for internal 5087a3f5d11SAllan Jude use in libcrypt. 5097a3f5d11SAllan Jude */ 5107a3f5d11SAllan Jude #undef SHA512_Init 5117a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Init, SHA512_Init); 5127a3f5d11SAllan Jude #undef SHA512_Update 5137a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Update, SHA512_Update); 5147a3f5d11SAllan Jude #undef SHA512_Final 5157a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Final, SHA512_Final); 5167a3f5d11SAllan Jude #undef SHA512_Transform 5177a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Transform, SHA512_Transform); 5187a3f5d11SAllan Jude 5191780e407SAllan Jude #undef SHA512_224_Init 5201780e407SAllan Jude __weak_reference(_libmd_SHA512_224_Init, SHA512_224_Init); 5211780e407SAllan Jude #undef SHA512_224_Update 5221780e407SAllan Jude __weak_reference(_libmd_SHA512_224_Update, SHA512_224_Update); 5231780e407SAllan Jude #undef SHA512_224_Final 5241780e407SAllan Jude __weak_reference(_libmd_SHA512_224_Final, SHA512_224_Final); 5251780e407SAllan Jude 5261780e407SAllan Jude #undef SHA512_256_Init 5271780e407SAllan Jude __weak_reference(_libmd_SHA512_256_Init, SHA512_256_Init); 5281780e407SAllan Jude #undef SHA512_256_Update 5291780e407SAllan Jude __weak_reference(_libmd_SHA512_256_Update, SHA512_256_Update); 5301780e407SAllan Jude #undef SHA512_256_Final 5311780e407SAllan Jude __weak_reference(_libmd_SHA512_256_Final, SHA512_256_Final); 5321780e407SAllan Jude 5337a3f5d11SAllan Jude #undef SHA384_Init 5347a3f5d11SAllan Jude __weak_reference(_libmd_SHA384_Init, SHA384_Init); 5357a3f5d11SAllan Jude #undef SHA384_Update 5367a3f5d11SAllan Jude __weak_reference(_libmd_SHA384_Update, SHA384_Update); 5377a3f5d11SAllan Jude #undef SHA384_Final 5387a3f5d11SAllan Jude __weak_reference(_libmd_SHA384_Final, SHA384_Final); 5397a3f5d11SAllan Jude #endif 540