197447ea4SJohn-Mark Gurney /*- 297447ea4SJohn-Mark Gurney * Copyright 2005 Colin Percival 397447ea4SJohn-Mark Gurney * All rights reserved. 497447ea4SJohn-Mark Gurney * 597447ea4SJohn-Mark Gurney * Redistribution and use in source and binary forms, with or without 697447ea4SJohn-Mark Gurney * modification, are permitted provided that the following conditions 797447ea4SJohn-Mark Gurney * are met: 897447ea4SJohn-Mark Gurney * 1. Redistributions of source code must retain the above copyright 997447ea4SJohn-Mark Gurney * notice, this list of conditions and the following disclaimer. 1097447ea4SJohn-Mark Gurney * 2. Redistributions in binary form must reproduce the above copyright 1197447ea4SJohn-Mark Gurney * notice, this list of conditions and the following disclaimer in the 1297447ea4SJohn-Mark Gurney * documentation and/or other materials provided with the distribution. 1397447ea4SJohn-Mark Gurney * 1497447ea4SJohn-Mark Gurney * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1597447ea4SJohn-Mark Gurney * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1697447ea4SJohn-Mark Gurney * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1797447ea4SJohn-Mark Gurney * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1897447ea4SJohn-Mark Gurney * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1997447ea4SJohn-Mark Gurney * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2097447ea4SJohn-Mark Gurney * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2197447ea4SJohn-Mark Gurney * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2297447ea4SJohn-Mark Gurney * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2397447ea4SJohn-Mark Gurney * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2497447ea4SJohn-Mark Gurney * SUCH DAMAGE. 2597447ea4SJohn-Mark Gurney */ 2697447ea4SJohn-Mark Gurney 2797447ea4SJohn-Mark Gurney #include <sys/cdefs.h> 2897447ea4SJohn-Mark Gurney __FBSDID("$FreeBSD$"); 2997447ea4SJohn-Mark Gurney 3097447ea4SJohn-Mark Gurney #include <sys/endian.h> 3197447ea4SJohn-Mark Gurney #include <sys/types.h> 3297447ea4SJohn-Mark Gurney 338083f14fSJohn-Mark Gurney #ifdef _KERNEL 348083f14fSJohn-Mark Gurney #include <sys/systm.h> 358083f14fSJohn-Mark Gurney #else 3697447ea4SJohn-Mark Gurney #include <string.h> 378083f14fSJohn-Mark Gurney #endif 3897447ea4SJohn-Mark Gurney 39*1245c6d1SConrad Meyer #include "sha224.h" 4097447ea4SJohn-Mark Gurney #include "sha256.h" 4197447ea4SJohn-Mark Gurney 4297447ea4SJohn-Mark Gurney #if BYTE_ORDER == BIG_ENDIAN 4397447ea4SJohn-Mark Gurney 4497447ea4SJohn-Mark Gurney /* Copy a vector of big-endian uint32_t into a vector of bytes */ 4597447ea4SJohn-Mark Gurney #define be32enc_vect(dst, src, len) \ 4697447ea4SJohn-Mark Gurney memcpy((void *)dst, (const void *)src, (size_t)len) 4797447ea4SJohn-Mark Gurney 4897447ea4SJohn-Mark Gurney /* Copy a vector of bytes into a vector of big-endian uint32_t */ 4997447ea4SJohn-Mark Gurney #define be32dec_vect(dst, src, len) \ 5097447ea4SJohn-Mark Gurney memcpy((void *)dst, (const void *)src, (size_t)len) 5197447ea4SJohn-Mark Gurney 5297447ea4SJohn-Mark Gurney #else /* BYTE_ORDER != BIG_ENDIAN */ 5397447ea4SJohn-Mark Gurney 5497447ea4SJohn-Mark Gurney /* 5597447ea4SJohn-Mark Gurney * Encode a length len/4 vector of (uint32_t) into a length len vector of 5697447ea4SJohn-Mark Gurney * (unsigned char) in big-endian form. Assumes len is a multiple of 4. 5797447ea4SJohn-Mark Gurney */ 5897447ea4SJohn-Mark Gurney static void 5997447ea4SJohn-Mark Gurney be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len) 6097447ea4SJohn-Mark Gurney { 6197447ea4SJohn-Mark Gurney size_t i; 6297447ea4SJohn-Mark Gurney 6397447ea4SJohn-Mark Gurney for (i = 0; i < len / 4; i++) 6497447ea4SJohn-Mark Gurney be32enc(dst + i * 4, src[i]); 6597447ea4SJohn-Mark Gurney } 6697447ea4SJohn-Mark Gurney 6797447ea4SJohn-Mark Gurney /* 6897447ea4SJohn-Mark Gurney * Decode a big-endian length len vector of (unsigned char) into a length 6997447ea4SJohn-Mark Gurney * len/4 vector of (uint32_t). Assumes len is a multiple of 4. 7097447ea4SJohn-Mark Gurney */ 7197447ea4SJohn-Mark Gurney static void 7297447ea4SJohn-Mark Gurney be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len) 7397447ea4SJohn-Mark Gurney { 7497447ea4SJohn-Mark Gurney size_t i; 7597447ea4SJohn-Mark Gurney 7697447ea4SJohn-Mark Gurney for (i = 0; i < len / 4; i++) 7797447ea4SJohn-Mark Gurney dst[i] = be32dec(src + i * 4); 7897447ea4SJohn-Mark Gurney } 7997447ea4SJohn-Mark Gurney 8097447ea4SJohn-Mark Gurney #endif /* BYTE_ORDER != BIG_ENDIAN */ 8197447ea4SJohn-Mark Gurney 82696c3895SColin Percival /* SHA256 round constants. */ 83696c3895SColin Percival static const uint32_t K[64] = { 84696c3895SColin Percival 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 85696c3895SColin Percival 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 86696c3895SColin Percival 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 87696c3895SColin Percival 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 88696c3895SColin Percival 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 89696c3895SColin Percival 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 90696c3895SColin Percival 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 91696c3895SColin Percival 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 92696c3895SColin Percival 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 93696c3895SColin Percival 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 94696c3895SColin Percival 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 95696c3895SColin Percival 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 96696c3895SColin Percival 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 97696c3895SColin Percival 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 98696c3895SColin Percival 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 99696c3895SColin Percival 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 100696c3895SColin Percival }; 101696c3895SColin Percival 10297447ea4SJohn-Mark Gurney /* Elementary functions used by SHA256 */ 10397447ea4SJohn-Mark Gurney #define Ch(x, y, z) ((x & (y ^ z)) ^ z) 10497447ea4SJohn-Mark Gurney #define Maj(x, y, z) ((x & (y | z)) | (y & z)) 10597447ea4SJohn-Mark Gurney #define SHR(x, n) (x >> n) 10697447ea4SJohn-Mark Gurney #define ROTR(x, n) ((x >> n) | (x << (32 - n))) 10797447ea4SJohn-Mark Gurney #define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) 10897447ea4SJohn-Mark Gurney #define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) 10997447ea4SJohn-Mark Gurney #define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) 11097447ea4SJohn-Mark Gurney #define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) 11197447ea4SJohn-Mark Gurney 11297447ea4SJohn-Mark Gurney /* SHA256 round function */ 11397447ea4SJohn-Mark Gurney #define RND(a, b, c, d, e, f, g, h, k) \ 114696c3895SColin Percival h += S1(e) + Ch(e, f, g) + k; \ 115696c3895SColin Percival d += h; \ 116696c3895SColin Percival h += S0(a) + Maj(a, b, c); 11797447ea4SJohn-Mark Gurney 11897447ea4SJohn-Mark Gurney /* Adjusted round function for rotating state */ 119696c3895SColin Percival #define RNDr(S, W, i, ii) \ 12097447ea4SJohn-Mark Gurney RND(S[(64 - i) % 8], S[(65 - i) % 8], \ 12197447ea4SJohn-Mark Gurney S[(66 - i) % 8], S[(67 - i) % 8], \ 12297447ea4SJohn-Mark Gurney S[(68 - i) % 8], S[(69 - i) % 8], \ 12397447ea4SJohn-Mark Gurney S[(70 - i) % 8], S[(71 - i) % 8], \ 124696c3895SColin Percival W[i + ii] + K[i + ii]) 125696c3895SColin Percival 126696c3895SColin Percival /* Message schedule computation */ 127696c3895SColin Percival #define MSCH(W, ii, i) \ 128696c3895SColin Percival W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii] 12997447ea4SJohn-Mark Gurney 13097447ea4SJohn-Mark Gurney /* 13197447ea4SJohn-Mark Gurney * SHA256 block compression function. The 256-bit state is transformed via 13297447ea4SJohn-Mark Gurney * the 512-bit input block to produce a new state. 13397447ea4SJohn-Mark Gurney */ 13497447ea4SJohn-Mark Gurney static void 13597447ea4SJohn-Mark Gurney SHA256_Transform(uint32_t * state, const unsigned char block[64]) 13697447ea4SJohn-Mark Gurney { 13797447ea4SJohn-Mark Gurney uint32_t W[64]; 13897447ea4SJohn-Mark Gurney uint32_t S[8]; 13997447ea4SJohn-Mark Gurney int i; 14097447ea4SJohn-Mark Gurney 141696c3895SColin Percival /* 1. Prepare the first part of the message schedule W. */ 14297447ea4SJohn-Mark Gurney be32dec_vect(W, block, 64); 14397447ea4SJohn-Mark Gurney 14497447ea4SJohn-Mark Gurney /* 2. Initialize working variables. */ 14597447ea4SJohn-Mark Gurney memcpy(S, state, 32); 14697447ea4SJohn-Mark Gurney 14797447ea4SJohn-Mark Gurney /* 3. Mix. */ 148696c3895SColin Percival for (i = 0; i < 64; i += 16) { 149696c3895SColin Percival RNDr(S, W, 0, i); 150696c3895SColin Percival RNDr(S, W, 1, i); 151696c3895SColin Percival RNDr(S, W, 2, i); 152696c3895SColin Percival RNDr(S, W, 3, i); 153696c3895SColin Percival RNDr(S, W, 4, i); 154696c3895SColin Percival RNDr(S, W, 5, i); 155696c3895SColin Percival RNDr(S, W, 6, i); 156696c3895SColin Percival RNDr(S, W, 7, i); 157696c3895SColin Percival RNDr(S, W, 8, i); 158696c3895SColin Percival RNDr(S, W, 9, i); 159696c3895SColin Percival RNDr(S, W, 10, i); 160696c3895SColin Percival RNDr(S, W, 11, i); 161696c3895SColin Percival RNDr(S, W, 12, i); 162696c3895SColin Percival RNDr(S, W, 13, i); 163696c3895SColin Percival RNDr(S, W, 14, i); 164696c3895SColin Percival RNDr(S, W, 15, i); 165696c3895SColin Percival 166696c3895SColin Percival if (i == 48) 167696c3895SColin Percival break; 168696c3895SColin Percival MSCH(W, 0, i); 169696c3895SColin Percival MSCH(W, 1, i); 170696c3895SColin Percival MSCH(W, 2, i); 171696c3895SColin Percival MSCH(W, 3, i); 172696c3895SColin Percival MSCH(W, 4, i); 173696c3895SColin Percival MSCH(W, 5, i); 174696c3895SColin Percival MSCH(W, 6, i); 175696c3895SColin Percival MSCH(W, 7, i); 176696c3895SColin Percival MSCH(W, 8, i); 177696c3895SColin Percival MSCH(W, 9, i); 178696c3895SColin Percival MSCH(W, 10, i); 179696c3895SColin Percival MSCH(W, 11, i); 180696c3895SColin Percival MSCH(W, 12, i); 181696c3895SColin Percival MSCH(W, 13, i); 182696c3895SColin Percival MSCH(W, 14, i); 183696c3895SColin Percival MSCH(W, 15, i); 184696c3895SColin Percival } 18597447ea4SJohn-Mark Gurney 18697447ea4SJohn-Mark Gurney /* 4. Mix local working variables into global state */ 18797447ea4SJohn-Mark Gurney for (i = 0; i < 8; i++) 18897447ea4SJohn-Mark Gurney state[i] += S[i]; 18997447ea4SJohn-Mark Gurney } 19097447ea4SJohn-Mark Gurney 19197447ea4SJohn-Mark Gurney static unsigned char PAD[64] = { 19297447ea4SJohn-Mark Gurney 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19397447ea4SJohn-Mark Gurney 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19497447ea4SJohn-Mark Gurney 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19597447ea4SJohn-Mark Gurney 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 19697447ea4SJohn-Mark Gurney }; 19797447ea4SJohn-Mark Gurney 19897447ea4SJohn-Mark Gurney /* Add padding and terminating bit-count. */ 19997447ea4SJohn-Mark Gurney static void 20097447ea4SJohn-Mark Gurney SHA256_Pad(SHA256_CTX * ctx) 20197447ea4SJohn-Mark Gurney { 202696c3895SColin Percival size_t r; 20397447ea4SJohn-Mark Gurney 204696c3895SColin Percival /* Figure out how many bytes we have buffered. */ 20597447ea4SJohn-Mark Gurney r = (ctx->count >> 3) & 0x3f; 20697447ea4SJohn-Mark Gurney 207696c3895SColin Percival /* Pad to 56 mod 64, transforming if we finish a block en route. */ 208696c3895SColin Percival if (r < 56) { 209696c3895SColin Percival /* Pad to 56 mod 64. */ 210696c3895SColin Percival memcpy(&ctx->buf[r], PAD, 56 - r); 211696c3895SColin Percival } else { 212696c3895SColin Percival /* Finish the current block and mix. */ 213696c3895SColin Percival memcpy(&ctx->buf[r], PAD, 64 - r); 214696c3895SColin Percival SHA256_Transform(ctx->state, ctx->buf); 215696c3895SColin Percival 216696c3895SColin Percival /* The start of the final block is all zeroes. */ 217696c3895SColin Percival memset(&ctx->buf[0], 0, 56); 218696c3895SColin Percival } 219696c3895SColin Percival 220696c3895SColin Percival /* Add the terminating bit-count. */ 221696c3895SColin Percival be64enc(&ctx->buf[56], ctx->count); 222696c3895SColin Percival 223696c3895SColin Percival /* Mix in the final block. */ 224696c3895SColin Percival SHA256_Transform(ctx->state, ctx->buf); 22597447ea4SJohn-Mark Gurney } 22697447ea4SJohn-Mark Gurney 22797447ea4SJohn-Mark Gurney /* SHA-256 initialization. Begins a SHA-256 operation. */ 22897447ea4SJohn-Mark Gurney void 22997447ea4SJohn-Mark Gurney SHA256_Init(SHA256_CTX * ctx) 23097447ea4SJohn-Mark Gurney { 23197447ea4SJohn-Mark Gurney 23297447ea4SJohn-Mark Gurney /* Zero bits processed so far */ 23397447ea4SJohn-Mark Gurney ctx->count = 0; 23497447ea4SJohn-Mark Gurney 23597447ea4SJohn-Mark Gurney /* Magic initialization constants */ 23697447ea4SJohn-Mark Gurney ctx->state[0] = 0x6A09E667; 23797447ea4SJohn-Mark Gurney ctx->state[1] = 0xBB67AE85; 23897447ea4SJohn-Mark Gurney ctx->state[2] = 0x3C6EF372; 23997447ea4SJohn-Mark Gurney ctx->state[3] = 0xA54FF53A; 24097447ea4SJohn-Mark Gurney ctx->state[4] = 0x510E527F; 24197447ea4SJohn-Mark Gurney ctx->state[5] = 0x9B05688C; 24297447ea4SJohn-Mark Gurney ctx->state[6] = 0x1F83D9AB; 24397447ea4SJohn-Mark Gurney ctx->state[7] = 0x5BE0CD19; 24497447ea4SJohn-Mark Gurney } 24597447ea4SJohn-Mark Gurney 24697447ea4SJohn-Mark Gurney /* Add bytes into the hash */ 24797447ea4SJohn-Mark Gurney void 24897447ea4SJohn-Mark Gurney SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len) 24997447ea4SJohn-Mark Gurney { 25097447ea4SJohn-Mark Gurney uint64_t bitlen; 25197447ea4SJohn-Mark Gurney uint32_t r; 25297447ea4SJohn-Mark Gurney const unsigned char *src = in; 25397447ea4SJohn-Mark Gurney 25497447ea4SJohn-Mark Gurney /* Number of bytes left in the buffer from previous updates */ 25597447ea4SJohn-Mark Gurney r = (ctx->count >> 3) & 0x3f; 25697447ea4SJohn-Mark Gurney 25797447ea4SJohn-Mark Gurney /* Convert the length into a number of bits */ 25897447ea4SJohn-Mark Gurney bitlen = len << 3; 25997447ea4SJohn-Mark Gurney 26097447ea4SJohn-Mark Gurney /* Update number of bits */ 26197447ea4SJohn-Mark Gurney ctx->count += bitlen; 26297447ea4SJohn-Mark Gurney 26397447ea4SJohn-Mark Gurney /* Handle the case where we don't need to perform any transforms */ 26497447ea4SJohn-Mark Gurney if (len < 64 - r) { 26597447ea4SJohn-Mark Gurney memcpy(&ctx->buf[r], src, len); 26697447ea4SJohn-Mark Gurney return; 26797447ea4SJohn-Mark Gurney } 26897447ea4SJohn-Mark Gurney 26997447ea4SJohn-Mark Gurney /* Finish the current block */ 27097447ea4SJohn-Mark Gurney memcpy(&ctx->buf[r], src, 64 - r); 27197447ea4SJohn-Mark Gurney SHA256_Transform(ctx->state, ctx->buf); 27297447ea4SJohn-Mark Gurney src += 64 - r; 27397447ea4SJohn-Mark Gurney len -= 64 - r; 27497447ea4SJohn-Mark Gurney 27597447ea4SJohn-Mark Gurney /* Perform complete blocks */ 27697447ea4SJohn-Mark Gurney while (len >= 64) { 27797447ea4SJohn-Mark Gurney SHA256_Transform(ctx->state, src); 27897447ea4SJohn-Mark Gurney src += 64; 27997447ea4SJohn-Mark Gurney len -= 64; 28097447ea4SJohn-Mark Gurney } 28197447ea4SJohn-Mark Gurney 28297447ea4SJohn-Mark Gurney /* Copy left over data into buffer */ 28397447ea4SJohn-Mark Gurney memcpy(ctx->buf, src, len); 28497447ea4SJohn-Mark Gurney } 28597447ea4SJohn-Mark Gurney 28697447ea4SJohn-Mark Gurney /* 28797447ea4SJohn-Mark Gurney * SHA-256 finalization. Pads the input data, exports the hash value, 28897447ea4SJohn-Mark Gurney * and clears the context state. 28997447ea4SJohn-Mark Gurney */ 29097447ea4SJohn-Mark Gurney void 291571ebf76SConrad Meyer SHA256_Final(unsigned char digest[static SHA256_DIGEST_LENGTH], SHA256_CTX *ctx) 29297447ea4SJohn-Mark Gurney { 29397447ea4SJohn-Mark Gurney 29497447ea4SJohn-Mark Gurney /* Add padding */ 29597447ea4SJohn-Mark Gurney SHA256_Pad(ctx); 29697447ea4SJohn-Mark Gurney 29797447ea4SJohn-Mark Gurney /* Write the hash */ 298571ebf76SConrad Meyer be32enc_vect(digest, ctx->state, SHA256_DIGEST_LENGTH); 29997447ea4SJohn-Mark Gurney 30097447ea4SJohn-Mark Gurney /* Clear the context state */ 301571ebf76SConrad Meyer memset(ctx, 0, sizeof(*ctx)); 30297447ea4SJohn-Mark Gurney } 3032ff9c4f9SJohn-Mark Gurney 304*1245c6d1SConrad Meyer /*** SHA-224: *********************************************************/ 305*1245c6d1SConrad Meyer /* 306*1245c6d1SConrad Meyer * the SHA224 and SHA256 transforms are identical 307*1245c6d1SConrad Meyer */ 308*1245c6d1SConrad Meyer 309*1245c6d1SConrad Meyer /* SHA-224 initialization. Begins a SHA-224 operation. */ 310*1245c6d1SConrad Meyer void 311*1245c6d1SConrad Meyer SHA224_Init(SHA224_CTX * ctx) 312*1245c6d1SConrad Meyer { 313*1245c6d1SConrad Meyer 314*1245c6d1SConrad Meyer /* Zero bits processed so far */ 315*1245c6d1SConrad Meyer ctx->count = 0; 316*1245c6d1SConrad Meyer 317*1245c6d1SConrad Meyer /* Magic initialization constants */ 318*1245c6d1SConrad Meyer ctx->state[0] = 0xC1059ED8; 319*1245c6d1SConrad Meyer ctx->state[1] = 0x367CD507; 320*1245c6d1SConrad Meyer ctx->state[2] = 0x3070DD17; 321*1245c6d1SConrad Meyer ctx->state[3] = 0xF70E5939; 322*1245c6d1SConrad Meyer ctx->state[4] = 0xFFC00B31; 323*1245c6d1SConrad Meyer ctx->state[5] = 0x68581511; 324*1245c6d1SConrad Meyer ctx->state[6] = 0x64f98FA7; 325*1245c6d1SConrad Meyer ctx->state[7] = 0xBEFA4FA4; 326*1245c6d1SConrad Meyer } 327*1245c6d1SConrad Meyer 328*1245c6d1SConrad Meyer /* Add bytes into the SHA-224 hash */ 329*1245c6d1SConrad Meyer void 330*1245c6d1SConrad Meyer SHA224_Update(SHA224_CTX * ctx, const void *in, size_t len) 331*1245c6d1SConrad Meyer { 332*1245c6d1SConrad Meyer 333*1245c6d1SConrad Meyer SHA256_Update((SHA256_CTX *)ctx, in, len); 334*1245c6d1SConrad Meyer } 335*1245c6d1SConrad Meyer 336*1245c6d1SConrad Meyer /* 337*1245c6d1SConrad Meyer * SHA-224 finalization. Pads the input data, exports the hash value, 338*1245c6d1SConrad Meyer * and clears the context state. 339*1245c6d1SConrad Meyer */ 340*1245c6d1SConrad Meyer void 341*1245c6d1SConrad Meyer SHA224_Final(unsigned char digest[static SHA224_DIGEST_LENGTH], SHA224_CTX *ctx) 342*1245c6d1SConrad Meyer { 343*1245c6d1SConrad Meyer 344*1245c6d1SConrad Meyer /* Add padding */ 345*1245c6d1SConrad Meyer SHA256_Pad((SHA256_CTX *)ctx); 346*1245c6d1SConrad Meyer 347*1245c6d1SConrad Meyer /* Write the hash */ 348*1245c6d1SConrad Meyer be32enc_vect(digest, ctx->state, SHA224_DIGEST_LENGTH); 349*1245c6d1SConrad Meyer 350*1245c6d1SConrad Meyer /* Clear the context state */ 351*1245c6d1SConrad Meyer explicit_bzero(ctx, sizeof(*ctx)); 352*1245c6d1SConrad Meyer } 353*1245c6d1SConrad Meyer 3542ff9c4f9SJohn-Mark Gurney #ifdef WEAK_REFS 3552ff9c4f9SJohn-Mark Gurney /* When building libmd, provide weak references. Note: this is not 3562ff9c4f9SJohn-Mark Gurney activated in the context of compiling these sources for internal 3572ff9c4f9SJohn-Mark Gurney use in libcrypt. 3582ff9c4f9SJohn-Mark Gurney */ 3592ff9c4f9SJohn-Mark Gurney #undef SHA256_Init 3602ff9c4f9SJohn-Mark Gurney __weak_reference(_libmd_SHA256_Init, SHA256_Init); 3612ff9c4f9SJohn-Mark Gurney #undef SHA256_Update 3622ff9c4f9SJohn-Mark Gurney __weak_reference(_libmd_SHA256_Update, SHA256_Update); 3632ff9c4f9SJohn-Mark Gurney #undef SHA256_Final 3642ff9c4f9SJohn-Mark Gurney __weak_reference(_libmd_SHA256_Final, SHA256_Final); 3652ff9c4f9SJohn-Mark Gurney #undef SHA256_Transform 3662ff9c4f9SJohn-Mark Gurney __weak_reference(_libmd_SHA256_Transform, SHA256_Transform); 367*1245c6d1SConrad Meyer 368*1245c6d1SConrad Meyer #undef SHA224_Init 369*1245c6d1SConrad Meyer __weak_reference(_libmd_SHA224_Init, SHA224_Init); 370*1245c6d1SConrad Meyer #undef SHA224_Update 371*1245c6d1SConrad Meyer __weak_reference(_libmd_SHA224_Update, SHA224_Update); 372*1245c6d1SConrad Meyer #undef SHA224_Final 373*1245c6d1SConrad Meyer __weak_reference(_libmd_SHA224_Final, SHA224_Final); 3742ff9c4f9SJohn-Mark Gurney #endif 375