1*1ab7ad13Schristos /* $NetBSD: sha2.c,v 1.26 2024/01/20 14:55:02 christos Exp $ */
277c9e419Schristos /* $KAME: sha2.c,v 1.9 2003/07/20 00:28:38 itojun Exp $ */
377c9e419Schristos
477c9e419Schristos /*
577c9e419Schristos * sha2.c
677c9e419Schristos *
777c9e419Schristos * Version 1.0.0beta1
877c9e419Schristos *
977c9e419Schristos * Written by Aaron D. Gifford <me@aarongifford.com>
1077c9e419Schristos *
1177c9e419Schristos * Copyright 2000 Aaron D. Gifford. All rights reserved.
1277c9e419Schristos *
1377c9e419Schristos * Redistribution and use in source and binary forms, with or without
1477c9e419Schristos * modification, are permitted provided that the following conditions
1577c9e419Schristos * are met:
1677c9e419Schristos * 1. Redistributions of source code must retain the above copyright
1777c9e419Schristos * notice, this list of conditions and the following disclaimer.
1877c9e419Schristos * 2. Redistributions in binary form must reproduce the above copyright
1977c9e419Schristos * notice, this list of conditions and the following disclaimer in the
2077c9e419Schristos * documentation and/or other materials provided with the distribution.
2177c9e419Schristos * 3. Neither the name of the copyright holder nor the names of contributors
2277c9e419Schristos * may be used to endorse or promote products derived from this software
2377c9e419Schristos * without specific prior written permission.
2477c9e419Schristos *
2577c9e419Schristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
2677c9e419Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2777c9e419Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2877c9e419Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE
2977c9e419Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3077c9e419Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3177c9e419Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3277c9e419Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3377c9e419Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3477c9e419Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3577c9e419Schristos * SUCH DAMAGE.
3677c9e419Schristos *
3777c9e419Schristos */
3877c9e419Schristos
3994cd590dSjoerg #if HAVE_NBTOOL_CONFIG_H
4094cd590dSjoerg #include "nbtool_config.h"
4194cd590dSjoerg #endif
4294cd590dSjoerg
4377c9e419Schristos #include <sys/cdefs.h>
4477c9e419Schristos
4577c9e419Schristos #if defined(_KERNEL) || defined(_STANDALONE)
46*1ab7ad13Schristos __KERNEL_RCSID(0, "$NetBSD: sha2.c,v 1.26 2024/01/20 14:55:02 christos Exp $");
4777c9e419Schristos
48ab353978Stsutsui #include <sys/param.h> /* XXX: to pull <machine/macros.h> for vax memset(9) */
4977c9e419Schristos #include <lib/libkern/libkern.h>
5077c9e419Schristos
5177c9e419Schristos #else
5277c9e419Schristos
5377c9e419Schristos #if defined(LIBC_SCCS) && !defined(lint)
54*1ab7ad13Schristos __RCSID("$NetBSD: sha2.c,v 1.26 2024/01/20 14:55:02 christos Exp $");
5577c9e419Schristos #endif /* LIBC_SCCS and not lint */
5677c9e419Schristos
5777c9e419Schristos #include "namespace.h"
5877c9e419Schristos #include <string.h>
5977c9e419Schristos
6077c9e419Schristos #endif
6177c9e419Schristos
62*1ab7ad13Schristos #ifndef _LIBC_INTERNAL
63*1ab7ad13Schristos #define _LIBC_INTERNAL
64*1ab7ad13Schristos #endif
65*1ab7ad13Schristos
6677c9e419Schristos #include <sys/types.h>
6777c9e419Schristos #include <sys/sha2.h>
6894cd590dSjoerg
6994cd590dSjoerg #if HAVE_SYS_ENDIAN_H
70c8f28effSjoerg # include <sys/endian.h>
7194cd590dSjoerg #endif
7277c9e419Schristos
7377c9e419Schristos /*** SHA-256/384/512 Various Length Definitions ***********************/
7477c9e419Schristos /* NOTE: Most of these are in sha2.h */
7577c9e419Schristos #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
7677c9e419Schristos #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
7777c9e419Schristos #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
7877c9e419Schristos
7977c9e419Schristos /*
8077c9e419Schristos * Macro for incrementally adding the unsigned 64-bit integer n to the
8177c9e419Schristos * unsigned 128-bit integer (represented using a two-element array of
8277c9e419Schristos * 64-bit words):
8377c9e419Schristos */
8477c9e419Schristos #define ADDINC128(w,n) { \
858c33577aSjoerg (w)[0] += (uint64_t)(n); \
8677c9e419Schristos if ((w)[0] < (n)) { \
8777c9e419Schristos (w)[1]++; \
8877c9e419Schristos } \
8977c9e419Schristos }
9077c9e419Schristos
9177c9e419Schristos /*** THE SIX LOGICAL FUNCTIONS ****************************************/
9277c9e419Schristos /*
9377c9e419Schristos * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
9477c9e419Schristos *
9577c9e419Schristos * NOTE: The naming of R and S appears backwards here (R is a SHIFT and
9677c9e419Schristos * S is a ROTATION) because the SHA-256/384/512 description document
9777c9e419Schristos * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
9877c9e419Schristos * same "backwards" definition.
9977c9e419Schristos */
10077c9e419Schristos /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
10177c9e419Schristos #define R(b,x) ((x) >> (b))
10277c9e419Schristos /* 32-bit Rotate-right (used in SHA-256): */
10377c9e419Schristos #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
10477c9e419Schristos /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
10577c9e419Schristos #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
10677c9e419Schristos
10777c9e419Schristos /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
10877c9e419Schristos #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
10977c9e419Schristos #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
11077c9e419Schristos
11177c9e419Schristos /* Four of six logical functions used in SHA-256: */
11277c9e419Schristos #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
11377c9e419Schristos #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
11477c9e419Schristos #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
11577c9e419Schristos #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
11677c9e419Schristos
11777c9e419Schristos /* Four of six logical functions used in SHA-384 and SHA-512: */
11877c9e419Schristos #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
11977c9e419Schristos #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
12077c9e419Schristos #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
12177c9e419Schristos #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
12277c9e419Schristos
12377c9e419Schristos /*** INTERNAL FUNCTION PROTOTYPES *************************************/
12477c9e419Schristos /* NOTE: These should not be accessed directly from outside this
12577c9e419Schristos * library -- they are intended for private internal visibility/use
12677c9e419Schristos * only.
12777c9e419Schristos */
128ace49726Schristos static void SHA512_Last(SHA512_CTX *);
12977c9e419Schristos
13077c9e419Schristos
13177c9e419Schristos /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
13277c9e419Schristos /* Hash constant words K for SHA-256: */
1338c33577aSjoerg static const uint32_t K256[64] = {
13477c9e419Schristos 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
13577c9e419Schristos 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
13677c9e419Schristos 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
13777c9e419Schristos 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
13877c9e419Schristos 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
13977c9e419Schristos 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
14077c9e419Schristos 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
14177c9e419Schristos 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
14277c9e419Schristos 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
14377c9e419Schristos 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
14477c9e419Schristos 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
14577c9e419Schristos 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
14677c9e419Schristos 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
14777c9e419Schristos 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
14877c9e419Schristos 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
14977c9e419Schristos 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
15077c9e419Schristos };
15177c9e419Schristos
15209d5d441Sjoerg /* Initial hash value H for SHA-224: */
1538c33577aSjoerg static const uint32_t sha224_initial_hash_value[8] = {
15409d5d441Sjoerg 0xc1059ed8UL,
15509d5d441Sjoerg 0x367cd507UL,
15609d5d441Sjoerg 0x3070dd17UL,
15709d5d441Sjoerg 0xf70e5939UL,
15809d5d441Sjoerg 0xffc00b31UL,
15909d5d441Sjoerg 0x68581511UL,
16009d5d441Sjoerg 0x64f98fa7UL,
16109d5d441Sjoerg 0xbefa4fa4UL
16209d5d441Sjoerg };
16309d5d441Sjoerg
16477c9e419Schristos /* Initial hash value H for SHA-256: */
1658c33577aSjoerg static const uint32_t sha256_initial_hash_value[8] = {
16677c9e419Schristos 0x6a09e667UL,
16777c9e419Schristos 0xbb67ae85UL,
16877c9e419Schristos 0x3c6ef372UL,
16977c9e419Schristos 0xa54ff53aUL,
17077c9e419Schristos 0x510e527fUL,
17177c9e419Schristos 0x9b05688cUL,
17277c9e419Schristos 0x1f83d9abUL,
17377c9e419Schristos 0x5be0cd19UL
17477c9e419Schristos };
17577c9e419Schristos
17677c9e419Schristos /* Hash constant words K for SHA-384 and SHA-512: */
1778c33577aSjoerg static const uint64_t K512[80] = {
17877c9e419Schristos 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
17977c9e419Schristos 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
18077c9e419Schristos 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
18177c9e419Schristos 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
18277c9e419Schristos 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
18377c9e419Schristos 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
18477c9e419Schristos 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
18577c9e419Schristos 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
18677c9e419Schristos 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
18777c9e419Schristos 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
18877c9e419Schristos 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
18977c9e419Schristos 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
19077c9e419Schristos 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
19177c9e419Schristos 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
19277c9e419Schristos 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
19377c9e419Schristos 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
19477c9e419Schristos 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
19577c9e419Schristos 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
19677c9e419Schristos 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
19777c9e419Schristos 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
19877c9e419Schristos 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
19977c9e419Schristos 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
20077c9e419Schristos 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
20177c9e419Schristos 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
20277c9e419Schristos 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
20377c9e419Schristos 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
20477c9e419Schristos 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
20577c9e419Schristos 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
20677c9e419Schristos 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
20777c9e419Schristos 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
20877c9e419Schristos 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
20977c9e419Schristos 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
21077c9e419Schristos 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
21177c9e419Schristos 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
21277c9e419Schristos 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
21377c9e419Schristos 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
21477c9e419Schristos 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
21577c9e419Schristos 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
21677c9e419Schristos 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
21777c9e419Schristos 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
21877c9e419Schristos };
21977c9e419Schristos
22077c9e419Schristos /* Initial hash value H for SHA-384 */
2218c33577aSjoerg static const uint64_t sha384_initial_hash_value[8] = {
22277c9e419Schristos 0xcbbb9d5dc1059ed8ULL,
22377c9e419Schristos 0x629a292a367cd507ULL,
22477c9e419Schristos 0x9159015a3070dd17ULL,
22577c9e419Schristos 0x152fecd8f70e5939ULL,
22677c9e419Schristos 0x67332667ffc00b31ULL,
22777c9e419Schristos 0x8eb44a8768581511ULL,
22877c9e419Schristos 0xdb0c2e0d64f98fa7ULL,
22977c9e419Schristos 0x47b5481dbefa4fa4ULL
23077c9e419Schristos };
23177c9e419Schristos
23277c9e419Schristos /* Initial hash value H for SHA-512 */
2338c33577aSjoerg static const uint64_t sha512_initial_hash_value[8] = {
23477c9e419Schristos 0x6a09e667f3bcc908ULL,
23577c9e419Schristos 0xbb67ae8584caa73bULL,
23677c9e419Schristos 0x3c6ef372fe94f82bULL,
23777c9e419Schristos 0xa54ff53a5f1d36f1ULL,
23877c9e419Schristos 0x510e527fade682d1ULL,
23977c9e419Schristos 0x9b05688c2b3e6c1fULL,
24077c9e419Schristos 0x1f83d9abfb41bd6bULL,
24177c9e419Schristos 0x5be0cd19137e2179ULL
24277c9e419Schristos };
24377c9e419Schristos
244b1aca4e8Sskrll #if !defined(_KERNEL) && !defined(_STANDALONE)
245b1aca4e8Sskrll #if defined(__weak_alias)
__weak_alias(SHA224_Init,_SHA224_Init)24609d5d441Sjoerg __weak_alias(SHA224_Init,_SHA224_Init)
24709d5d441Sjoerg __weak_alias(SHA224_Update,_SHA224_Update)
24809d5d441Sjoerg __weak_alias(SHA224_Final,_SHA224_Final)
24909d5d441Sjoerg __weak_alias(SHA224_Transform,_SHA224_Transform)
25009d5d441Sjoerg
25177c9e419Schristos __weak_alias(SHA256_Init,_SHA256_Init)
25277c9e419Schristos __weak_alias(SHA256_Update,_SHA256_Update)
25377c9e419Schristos __weak_alias(SHA256_Final,_SHA256_Final)
25477c9e419Schristos __weak_alias(SHA256_Transform,_SHA256_Transform)
25577c9e419Schristos
25677c9e419Schristos __weak_alias(SHA384_Init,_SHA384_Init)
25777c9e419Schristos __weak_alias(SHA384_Update,_SHA384_Update)
25877c9e419Schristos __weak_alias(SHA384_Final,_SHA384_Final)
25977c9e419Schristos __weak_alias(SHA384_Transform,_SHA384_Transform)
26077c9e419Schristos
26177c9e419Schristos __weak_alias(SHA512_Init,_SHA512_Init)
26277c9e419Schristos __weak_alias(SHA512_Update,_SHA512_Update)
26377c9e419Schristos __weak_alias(SHA512_Final,_SHA512_Final)
26477c9e419Schristos __weak_alias(SHA512_Transform,_SHA512_Transform)
26577c9e419Schristos #endif
266b1aca4e8Sskrll #endif
26777c9e419Schristos
26809d5d441Sjoerg /*** SHA-256: *********************************************************/
26902c42980Sjoerg int
27002c42980Sjoerg SHA256_Init(SHA256_CTX *context)
27102c42980Sjoerg {
27246f23cedSchristos if (context == NULL)
27309d5d441Sjoerg return 1;
27446f23cedSchristos
27546f23cedSchristos memcpy(context->state, sha256_initial_hash_value,
27646f23cedSchristos (size_t)(SHA256_DIGEST_LENGTH));
27777c9e419Schristos memset(context->buffer, 0, (size_t)(SHA256_BLOCK_LENGTH));
27877c9e419Schristos context->bitcount = 0;
27909d5d441Sjoerg
28009d5d441Sjoerg return 1;
28109d5d441Sjoerg }
28209d5d441Sjoerg
28377c9e419Schristos #ifdef SHA2_UNROLL_TRANSFORM
28477c9e419Schristos
28577c9e419Schristos /* Unrolled SHA-256 round macros: */
28677c9e419Schristos
28777c9e419Schristos #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
288af7cd4f3Schristos W256[j] = be32dec(data); \
289c8f28effSjoerg ++data; \
29077c9e419Schristos T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
29177c9e419Schristos K256[j] + W256[j]; \
29277c9e419Schristos (d) += T1; \
29377c9e419Schristos (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
29477c9e419Schristos j++
29577c9e419Schristos
29677c9e419Schristos #define ROUND256(a,b,c,d,e,f,g,h) \
29777c9e419Schristos s0 = W256[(j+1)&0x0f]; \
29877c9e419Schristos s0 = sigma0_256(s0); \
29977c9e419Schristos s1 = W256[(j+14)&0x0f]; \
30077c9e419Schristos s1 = sigma1_256(s1); \
30177c9e419Schristos T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
30277c9e419Schristos (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
30377c9e419Schristos (d) += T1; \
30477c9e419Schristos (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
30577c9e419Schristos j++
30677c9e419Schristos
30702c42980Sjoerg void
SHA256_Transform(SHA256_CTX * context,const uint32_t * data)30802c42980Sjoerg SHA256_Transform(SHA256_CTX *context, const uint32_t *data)
30902c42980Sjoerg {
3108c33577aSjoerg uint32_t a, b, c, d, e, f, g, h, s0, s1;
3118c33577aSjoerg uint32_t T1, *W256;
31277c9e419Schristos int j;
31377c9e419Schristos
3148c33577aSjoerg W256 = (uint32_t *)context->buffer;
31577c9e419Schristos
31677c9e419Schristos /* Initialize registers with the prev. intermediate value */
31777c9e419Schristos a = context->state[0];
31877c9e419Schristos b = context->state[1];
31977c9e419Schristos c = context->state[2];
32077c9e419Schristos d = context->state[3];
32177c9e419Schristos e = context->state[4];
32277c9e419Schristos f = context->state[5];
32377c9e419Schristos g = context->state[6];
32477c9e419Schristos h = context->state[7];
32577c9e419Schristos
32677c9e419Schristos j = 0;
32777c9e419Schristos do {
32877c9e419Schristos /* Rounds 0 to 15 (unrolled): */
32977c9e419Schristos ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
33077c9e419Schristos ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
33177c9e419Schristos ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
33277c9e419Schristos ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
33377c9e419Schristos ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
33477c9e419Schristos ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
33577c9e419Schristos ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
33677c9e419Schristos ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
33777c9e419Schristos } while (j < 16);
33877c9e419Schristos
33977c9e419Schristos /* Now for the remaining rounds to 64: */
34077c9e419Schristos do {
34177c9e419Schristos ROUND256(a,b,c,d,e,f,g,h);
34277c9e419Schristos ROUND256(h,a,b,c,d,e,f,g);
34377c9e419Schristos ROUND256(g,h,a,b,c,d,e,f);
34477c9e419Schristos ROUND256(f,g,h,a,b,c,d,e);
34577c9e419Schristos ROUND256(e,f,g,h,a,b,c,d);
34677c9e419Schristos ROUND256(d,e,f,g,h,a,b,c);
34777c9e419Schristos ROUND256(c,d,e,f,g,h,a,b);
34877c9e419Schristos ROUND256(b,c,d,e,f,g,h,a);
34977c9e419Schristos } while (j < 64);
35077c9e419Schristos
35177c9e419Schristos /* Compute the current intermediate hash value */
35277c9e419Schristos context->state[0] += a;
35377c9e419Schristos context->state[1] += b;
35477c9e419Schristos context->state[2] += c;
35577c9e419Schristos context->state[3] += d;
35677c9e419Schristos context->state[4] += e;
35777c9e419Schristos context->state[5] += f;
35877c9e419Schristos context->state[6] += g;
35977c9e419Schristos context->state[7] += h;
36077c9e419Schristos
36177c9e419Schristos /* Clean up */
36277c9e419Schristos a = b = c = d = e = f = g = h = T1 = 0;
36377c9e419Schristos }
36477c9e419Schristos
36577c9e419Schristos #else /* SHA2_UNROLL_TRANSFORM */
36677c9e419Schristos
36702c42980Sjoerg void
SHA256_Transform(SHA256_CTX * context,const uint32_t * data)36802c42980Sjoerg SHA256_Transform(SHA256_CTX *context, const uint32_t *data)
36902c42980Sjoerg {
3708c33577aSjoerg uint32_t a, b, c, d, e, f, g, h, s0, s1;
3718c33577aSjoerg uint32_t T1, T2, *W256;
37277c9e419Schristos int j;
37377c9e419Schristos
3748c33577aSjoerg W256 = (uint32_t *)(void *)context->buffer;
37577c9e419Schristos
37677c9e419Schristos /* Initialize registers with the prev. intermediate value */
37777c9e419Schristos a = context->state[0];
37877c9e419Schristos b = context->state[1];
37977c9e419Schristos c = context->state[2];
38077c9e419Schristos d = context->state[3];
38177c9e419Schristos e = context->state[4];
38277c9e419Schristos f = context->state[5];
38377c9e419Schristos g = context->state[6];
38477c9e419Schristos h = context->state[7];
38577c9e419Schristos
38677c9e419Schristos j = 0;
38777c9e419Schristos do {
388af7cd4f3Schristos W256[j] = be32dec(data);
389c8f28effSjoerg ++data;
39077c9e419Schristos /* Apply the SHA-256 compression function to update a..h */
39177c9e419Schristos T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
39277c9e419Schristos T2 = Sigma0_256(a) + Maj(a, b, c);
39377c9e419Schristos h = g;
39477c9e419Schristos g = f;
39577c9e419Schristos f = e;
39677c9e419Schristos e = d + T1;
39777c9e419Schristos d = c;
39877c9e419Schristos c = b;
39977c9e419Schristos b = a;
40077c9e419Schristos a = T1 + T2;
40177c9e419Schristos
40277c9e419Schristos j++;
40377c9e419Schristos } while (j < 16);
40477c9e419Schristos
40577c9e419Schristos do {
40677c9e419Schristos /* Part of the message block expansion: */
40777c9e419Schristos s0 = W256[(j+1)&0x0f];
40877c9e419Schristos s0 = sigma0_256(s0);
40977c9e419Schristos s1 = W256[(j+14)&0x0f];
41077c9e419Schristos s1 = sigma1_256(s1);
41177c9e419Schristos
41277c9e419Schristos /* Apply the SHA-256 compression function to update a..h */
41377c9e419Schristos T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
41477c9e419Schristos (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
41577c9e419Schristos T2 = Sigma0_256(a) + Maj(a, b, c);
41677c9e419Schristos h = g;
41777c9e419Schristos g = f;
41877c9e419Schristos f = e;
41977c9e419Schristos e = d + T1;
42077c9e419Schristos d = c;
42177c9e419Schristos c = b;
42277c9e419Schristos b = a;
42377c9e419Schristos a = T1 + T2;
42477c9e419Schristos
42577c9e419Schristos j++;
42677c9e419Schristos } while (j < 64);
42777c9e419Schristos
42877c9e419Schristos /* Compute the current intermediate hash value */
42977c9e419Schristos context->state[0] += a;
43077c9e419Schristos context->state[1] += b;
43177c9e419Schristos context->state[2] += c;
43277c9e419Schristos context->state[3] += d;
43377c9e419Schristos context->state[4] += e;
43477c9e419Schristos context->state[5] += f;
43577c9e419Schristos context->state[6] += g;
43677c9e419Schristos context->state[7] += h;
43777c9e419Schristos
43877c9e419Schristos /* Clean up */
43977c9e419Schristos a = b = c = d = e = f = g = h = T1 = T2 = 0;
44077c9e419Schristos }
44177c9e419Schristos
44277c9e419Schristos #endif /* SHA2_UNROLL_TRANSFORM */
44377c9e419Schristos
44402c42980Sjoerg int
SHA256_Update(SHA256_CTX * context,const uint8_t * data,size_t len)44502c42980Sjoerg SHA256_Update(SHA256_CTX *context, const uint8_t *data, size_t len)
44602c42980Sjoerg {
44777c9e419Schristos unsigned int freespace, usedspace;
44877c9e419Schristos
44977c9e419Schristos if (len == 0) {
45077c9e419Schristos /* Calling with no data is valid - we do nothing */
45109d5d441Sjoerg return 1;
45277c9e419Schristos }
45377c9e419Schristos
45477c9e419Schristos usedspace = (unsigned int)((context->bitcount >> 3) %
45577c9e419Schristos SHA256_BLOCK_LENGTH);
45677c9e419Schristos if (usedspace > 0) {
45777c9e419Schristos /* Calculate how much free space is available in the buffer */
45877c9e419Schristos freespace = SHA256_BLOCK_LENGTH - usedspace;
45977c9e419Schristos
46077c9e419Schristos if (len >= freespace) {
46177c9e419Schristos /* Fill the buffer completely and process it */
46246f23cedSchristos memcpy(&context->buffer[usedspace], data,
46346f23cedSchristos (size_t)(freespace));
46477c9e419Schristos context->bitcount += freespace << 3;
46577c9e419Schristos len -= freespace;
46677c9e419Schristos data += freespace;
46746f23cedSchristos SHA256_Transform(context,
46846f23cedSchristos (uint32_t *)(void *)context->buffer);
46977c9e419Schristos } else {
47077c9e419Schristos /* The buffer is not yet full */
47177c9e419Schristos memcpy(&context->buffer[usedspace], data, len);
47277c9e419Schristos context->bitcount += len << 3;
47377c9e419Schristos /* Clean up: */
47477c9e419Schristos usedspace = freespace = 0;
47509d5d441Sjoerg return 1;
47677c9e419Schristos }
47777c9e419Schristos }
47817c77a58Sjoerg /*
47917c77a58Sjoerg * Process as many complete blocks as possible.
48017c77a58Sjoerg *
48117c77a58Sjoerg * Check alignment of the data pointer. If it is 32bit aligned,
48217c77a58Sjoerg * SHA256_Transform can be called directly on the data stream,
48317c77a58Sjoerg * otherwise enforce the alignment by copy into the buffer.
48417c77a58Sjoerg */
48517c77a58Sjoerg if ((uintptr_t)data % 4 == 0) {
48677c9e419Schristos while (len >= SHA256_BLOCK_LENGTH) {
48717c77a58Sjoerg SHA256_Transform(context,
4888c33577aSjoerg (const uint32_t *)(const void *)data);
48977c9e419Schristos context->bitcount += SHA256_BLOCK_LENGTH << 3;
49077c9e419Schristos len -= SHA256_BLOCK_LENGTH;
49177c9e419Schristos data += SHA256_BLOCK_LENGTH;
49277c9e419Schristos }
49317c77a58Sjoerg } else {
49417c77a58Sjoerg while (len >= SHA256_BLOCK_LENGTH) {
49517c77a58Sjoerg memcpy(context->buffer, data, SHA256_BLOCK_LENGTH);
49617c77a58Sjoerg SHA256_Transform(context,
4978c33577aSjoerg (const uint32_t *)(const void *)context->buffer);
49817c77a58Sjoerg context->bitcount += SHA256_BLOCK_LENGTH << 3;
49917c77a58Sjoerg len -= SHA256_BLOCK_LENGTH;
50017c77a58Sjoerg data += SHA256_BLOCK_LENGTH;
50117c77a58Sjoerg }
50217c77a58Sjoerg }
50377c9e419Schristos if (len > 0) {
50477c9e419Schristos /* There's left-overs, so save 'em */
50577c9e419Schristos memcpy(context->buffer, data, len);
50677c9e419Schristos context->bitcount += len << 3;
50777c9e419Schristos }
50877c9e419Schristos /* Clean up: */
50977c9e419Schristos usedspace = freespace = 0;
51009d5d441Sjoerg
51109d5d441Sjoerg return 1;
51277c9e419Schristos }
51377c9e419Schristos
51402c42980Sjoerg static int
SHA224_256_Final(uint8_t digest[],SHA256_CTX * context,size_t len)51502c42980Sjoerg SHA224_256_Final(uint8_t digest[], SHA256_CTX *context, size_t len)
51602c42980Sjoerg {
51777c9e419Schristos unsigned int usedspace;
518c8f28effSjoerg size_t i;
51977c9e419Schristos
52077c9e419Schristos /* If no digest buffer is passed, we don't bother doing this: */
5218c33577aSjoerg if (digest != NULL) {
52246f23cedSchristos usedspace = (unsigned int)((context->bitcount >> 3) %
52346f23cedSchristos SHA256_BLOCK_LENGTH);
524c8f28effSjoerg context->bitcount = htobe64(context->bitcount);
52577c9e419Schristos if (usedspace > 0) {
52677c9e419Schristos /* Begin padding with a 1 bit: */
52777c9e419Schristos context->buffer[usedspace++] = 0x80;
52877c9e419Schristos
52977c9e419Schristos if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
53077c9e419Schristos /* Set-up for the last transform: */
53146f23cedSchristos memset(&context->buffer[usedspace], 0,
53246f23cedSchristos (size_t)(SHA256_SHORT_BLOCK_LENGTH -
53346f23cedSchristos usedspace));
53477c9e419Schristos } else {
53577c9e419Schristos if (usedspace < SHA256_BLOCK_LENGTH) {
53646f23cedSchristos memset(&context->buffer[usedspace], 0,
53746f23cedSchristos (size_t)(SHA256_BLOCK_LENGTH -
53846f23cedSchristos usedspace));
53977c9e419Schristos }
54077c9e419Schristos /* Do second-to-last transform: */
54146f23cedSchristos SHA256_Transform(context,
54246f23cedSchristos (uint32_t *)(void *)context->buffer);
54377c9e419Schristos
54477c9e419Schristos /* And set-up for the last transform: */
54546f23cedSchristos memset(context->buffer, 0,
54646f23cedSchristos (size_t)(SHA256_SHORT_BLOCK_LENGTH));
54777c9e419Schristos }
54877c9e419Schristos } else {
54977c9e419Schristos /* Set-up for the last transform: */
55046f23cedSchristos memset(context->buffer, 0,
55146f23cedSchristos (size_t)(SHA256_SHORT_BLOCK_LENGTH));
55277c9e419Schristos
55377c9e419Schristos /* Begin padding with a 1 bit: */
55477c9e419Schristos *context->buffer = 0x80;
55577c9e419Schristos }
55677c9e419Schristos /* Set the bit count: */
55713573b19Schristos memcpy(&context->buffer[SHA256_SHORT_BLOCK_LENGTH],
55813573b19Schristos &context->bitcount, sizeof(context->bitcount));
55977c9e419Schristos
56077c9e419Schristos /* Final transform: */
5618c33577aSjoerg SHA256_Transform(context, (uint32_t *)(void *)context->buffer);
56277c9e419Schristos
563c8f28effSjoerg for (i = 0; i < len / 4; i++)
56485b087f1Sjoerg be32enc(digest + 4 * i, context->state[i]);
56577c9e419Schristos }
56677c9e419Schristos
56777c9e419Schristos /* Clean up state data: */
56877c9e419Schristos memset(context, 0, sizeof(*context));
56977c9e419Schristos usedspace = 0;
57009d5d441Sjoerg
57109d5d441Sjoerg return 1;
57209d5d441Sjoerg }
57309d5d441Sjoerg
57402c42980Sjoerg int
SHA256_Final(uint8_t digest[SHA256_DIGEST_LENGTH],SHA256_CTX * context)575b0d97acfSchristos SHA256_Final(uint8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *context)
57602c42980Sjoerg {
57709d5d441Sjoerg return SHA224_256_Final(digest, context, SHA256_DIGEST_LENGTH);
57877c9e419Schristos }
57977c9e419Schristos
58046f23cedSchristos /*** SHA-224: *********************************************************/
58146f23cedSchristos int
SHA224_Init(SHA224_CTX * context)58246f23cedSchristos SHA224_Init(SHA224_CTX *context)
58346f23cedSchristos {
58446f23cedSchristos if (context == NULL)
58546f23cedSchristos return 1;
58646f23cedSchristos
587faf14618Sjoerg /* The state and buffer size are driven by SHA256, not by SHA224. */
58846f23cedSchristos memcpy(context->state, sha224_initial_hash_value,
589faf14618Sjoerg (size_t)(SHA256_DIGEST_LENGTH));
590faf14618Sjoerg memset(context->buffer, 0, (size_t)(SHA256_BLOCK_LENGTH));
59146f23cedSchristos context->bitcount = 0;
59246f23cedSchristos
59346f23cedSchristos return 1;
59446f23cedSchristos }
59546f23cedSchristos
59646f23cedSchristos int
SHA224_Update(SHA224_CTX * context,const uint8_t * data,size_t len)59746f23cedSchristos SHA224_Update(SHA224_CTX *context, const uint8_t *data, size_t len)
59846f23cedSchristos {
59946f23cedSchristos return SHA256_Update((SHA256_CTX *)context, data, len);
60046f23cedSchristos }
60146f23cedSchristos
60246f23cedSchristos void
SHA224_Transform(SHA224_CTX * context,const uint32_t * data)603cd4c43c9Smartin SHA224_Transform(SHA224_CTX *context, const uint32_t *data)
60446f23cedSchristos {
605cd4c43c9Smartin SHA256_Transform((SHA256_CTX *)context, data);
60646f23cedSchristos }
60746f23cedSchristos
60846f23cedSchristos int
SHA224_Final(uint8_t digest[SHA224_DIGEST_LENGTH],SHA224_CTX * context)609b0d97acfSchristos SHA224_Final(uint8_t digest[SHA224_DIGEST_LENGTH], SHA224_CTX *context)
61046f23cedSchristos {
61146f23cedSchristos return SHA224_256_Final(digest, (SHA256_CTX *)context,
61246f23cedSchristos SHA224_DIGEST_LENGTH);
61346f23cedSchristos }
61446f23cedSchristos
61577c9e419Schristos /*** SHA-512: *********************************************************/
61602c42980Sjoerg int
SHA512_Init(SHA512_CTX * context)61702c42980Sjoerg SHA512_Init(SHA512_CTX *context)
61802c42980Sjoerg {
6198c33577aSjoerg if (context == NULL)
62009d5d441Sjoerg return 1;
6218c33577aSjoerg
62246f23cedSchristos memcpy(context->state, sha512_initial_hash_value,
62346f23cedSchristos (size_t)(SHA512_DIGEST_LENGTH));
62477c9e419Schristos memset(context->buffer, 0, (size_t)(SHA512_BLOCK_LENGTH));
62577c9e419Schristos context->bitcount[0] = context->bitcount[1] = 0;
62609d5d441Sjoerg
62709d5d441Sjoerg return 1;
62877c9e419Schristos }
62977c9e419Schristos
63077c9e419Schristos #ifdef SHA2_UNROLL_TRANSFORM
63177c9e419Schristos
63277c9e419Schristos /* Unrolled SHA-512 round macros: */
63377c9e419Schristos #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
634af7cd4f3Schristos W512[j] = be64dec(data); \
635c8f28effSjoerg ++data; \
63677c9e419Schristos T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
63777c9e419Schristos K512[j] + W512[j]; \
63877c9e419Schristos (d) += T1, \
63977c9e419Schristos (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
64077c9e419Schristos j++
64177c9e419Schristos
64277c9e419Schristos #define ROUND512(a,b,c,d,e,f,g,h) \
64377c9e419Schristos s0 = W512[(j+1)&0x0f]; \
64477c9e419Schristos s0 = sigma0_512(s0); \
64577c9e419Schristos s1 = W512[(j+14)&0x0f]; \
64677c9e419Schristos s1 = sigma1_512(s1); \
64777c9e419Schristos T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
64877c9e419Schristos (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
64977c9e419Schristos (d) += T1; \
65077c9e419Schristos (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
65177c9e419Schristos j++
65277c9e419Schristos
65302c42980Sjoerg void
SHA512_Transform(SHA512_CTX * context,const uint64_t * data)65402c42980Sjoerg SHA512_Transform(SHA512_CTX *context, const uint64_t *data)
65502c42980Sjoerg {
6568c33577aSjoerg uint64_t a, b, c, d, e, f, g, h, s0, s1;
6578c33577aSjoerg uint64_t T1, *W512 = (uint64_t *)context->buffer;
65877c9e419Schristos int j;
65977c9e419Schristos
66077c9e419Schristos /* Initialize registers with the prev. intermediate value */
66177c9e419Schristos a = context->state[0];
66277c9e419Schristos b = context->state[1];
66377c9e419Schristos c = context->state[2];
66477c9e419Schristos d = context->state[3];
66577c9e419Schristos e = context->state[4];
66677c9e419Schristos f = context->state[5];
66777c9e419Schristos g = context->state[6];
66877c9e419Schristos h = context->state[7];
66977c9e419Schristos
67077c9e419Schristos j = 0;
67177c9e419Schristos do {
67277c9e419Schristos ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
67377c9e419Schristos ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
67477c9e419Schristos ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
67577c9e419Schristos ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
67677c9e419Schristos ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
67777c9e419Schristos ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
67877c9e419Schristos ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
67977c9e419Schristos ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
68077c9e419Schristos } while (j < 16);
68177c9e419Schristos
68277c9e419Schristos /* Now for the remaining rounds up to 79: */
68377c9e419Schristos do {
68477c9e419Schristos ROUND512(a,b,c,d,e,f,g,h);
68577c9e419Schristos ROUND512(h,a,b,c,d,e,f,g);
68677c9e419Schristos ROUND512(g,h,a,b,c,d,e,f);
68777c9e419Schristos ROUND512(f,g,h,a,b,c,d,e);
68877c9e419Schristos ROUND512(e,f,g,h,a,b,c,d);
68977c9e419Schristos ROUND512(d,e,f,g,h,a,b,c);
69077c9e419Schristos ROUND512(c,d,e,f,g,h,a,b);
69177c9e419Schristos ROUND512(b,c,d,e,f,g,h,a);
69277c9e419Schristos } while (j < 80);
69377c9e419Schristos
69477c9e419Schristos /* Compute the current intermediate hash value */
69577c9e419Schristos context->state[0] += a;
69677c9e419Schristos context->state[1] += b;
69777c9e419Schristos context->state[2] += c;
69877c9e419Schristos context->state[3] += d;
69977c9e419Schristos context->state[4] += e;
70077c9e419Schristos context->state[5] += f;
70177c9e419Schristos context->state[6] += g;
70277c9e419Schristos context->state[7] += h;
70377c9e419Schristos
70477c9e419Schristos /* Clean up */
70577c9e419Schristos a = b = c = d = e = f = g = h = T1 = 0;
70677c9e419Schristos }
70777c9e419Schristos
70877c9e419Schristos #else /* SHA2_UNROLL_TRANSFORM */
70977c9e419Schristos
71002c42980Sjoerg void
SHA512_Transform(SHA512_CTX * context,const uint64_t * data)71102c42980Sjoerg SHA512_Transform(SHA512_CTX *context, const uint64_t *data)
71202c42980Sjoerg {
7138c33577aSjoerg uint64_t a, b, c, d, e, f, g, h, s0, s1;
7148c33577aSjoerg uint64_t T1, T2, *W512 = (void *)context->buffer;
71577c9e419Schristos int j;
71677c9e419Schristos
71777c9e419Schristos /* Initialize registers with the prev. intermediate value */
71877c9e419Schristos a = context->state[0];
71977c9e419Schristos b = context->state[1];
72077c9e419Schristos c = context->state[2];
72177c9e419Schristos d = context->state[3];
72277c9e419Schristos e = context->state[4];
72377c9e419Schristos f = context->state[5];
72477c9e419Schristos g = context->state[6];
72577c9e419Schristos h = context->state[7];
72677c9e419Schristos
72777c9e419Schristos j = 0;
72877c9e419Schristos do {
729af7cd4f3Schristos W512[j] = be64dec(data);
730c8f28effSjoerg ++data;
73177c9e419Schristos /* Apply the SHA-512 compression function to update a..h */
73277c9e419Schristos T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
73377c9e419Schristos T2 = Sigma0_512(a) + Maj(a, b, c);
73477c9e419Schristos h = g;
73577c9e419Schristos g = f;
73677c9e419Schristos f = e;
73777c9e419Schristos e = d + T1;
73877c9e419Schristos d = c;
73977c9e419Schristos c = b;
74077c9e419Schristos b = a;
74177c9e419Schristos a = T1 + T2;
74277c9e419Schristos
74377c9e419Schristos j++;
74477c9e419Schristos } while (j < 16);
74577c9e419Schristos
74677c9e419Schristos do {
74777c9e419Schristos /* Part of the message block expansion: */
74877c9e419Schristos s0 = W512[(j+1)&0x0f];
74977c9e419Schristos s0 = sigma0_512(s0);
75077c9e419Schristos s1 = W512[(j+14)&0x0f];
75177c9e419Schristos s1 = sigma1_512(s1);
75277c9e419Schristos
75377c9e419Schristos /* Apply the SHA-512 compression function to update a..h */
75477c9e419Schristos T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
75577c9e419Schristos (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
75677c9e419Schristos T2 = Sigma0_512(a) + Maj(a, b, c);
75777c9e419Schristos h = g;
75877c9e419Schristos g = f;
75977c9e419Schristos f = e;
76077c9e419Schristos e = d + T1;
76177c9e419Schristos d = c;
76277c9e419Schristos c = b;
76377c9e419Schristos b = a;
76477c9e419Schristos a = T1 + T2;
76577c9e419Schristos
76677c9e419Schristos j++;
76777c9e419Schristos } while (j < 80);
76877c9e419Schristos
76977c9e419Schristos /* Compute the current intermediate hash value */
77077c9e419Schristos context->state[0] += a;
77177c9e419Schristos context->state[1] += b;
77277c9e419Schristos context->state[2] += c;
77377c9e419Schristos context->state[3] += d;
77477c9e419Schristos context->state[4] += e;
77577c9e419Schristos context->state[5] += f;
77677c9e419Schristos context->state[6] += g;
77777c9e419Schristos context->state[7] += h;
77877c9e419Schristos
77977c9e419Schristos /* Clean up */
78077c9e419Schristos a = b = c = d = e = f = g = h = T1 = T2 = 0;
78177c9e419Schristos }
78277c9e419Schristos
78377c9e419Schristos #endif /* SHA2_UNROLL_TRANSFORM */
78477c9e419Schristos
78502c42980Sjoerg int
SHA512_Update(SHA512_CTX * context,const uint8_t * data,size_t len)78602c42980Sjoerg SHA512_Update(SHA512_CTX *context, const uint8_t *data, size_t len)
78702c42980Sjoerg {
78877c9e419Schristos unsigned int freespace, usedspace;
78977c9e419Schristos
79077c9e419Schristos if (len == 0) {
79177c9e419Schristos /* Calling with no data is valid - we do nothing */
79209d5d441Sjoerg return 1;
79377c9e419Schristos }
79477c9e419Schristos
79546f23cedSchristos usedspace = (unsigned int)((context->bitcount[0] >> 3) %
79646f23cedSchristos SHA512_BLOCK_LENGTH);
79777c9e419Schristos if (usedspace > 0) {
79877c9e419Schristos /* Calculate how much free space is available in the buffer */
79977c9e419Schristos freespace = SHA512_BLOCK_LENGTH - usedspace;
80077c9e419Schristos
80177c9e419Schristos if (len >= freespace) {
80277c9e419Schristos /* Fill the buffer completely and process it */
80346f23cedSchristos memcpy(&context->buffer[usedspace], data,
80446f23cedSchristos (size_t)(freespace));
80577c9e419Schristos ADDINC128(context->bitcount, freespace << 3);
80677c9e419Schristos len -= freespace;
80777c9e419Schristos data += freespace;
80846f23cedSchristos SHA512_Transform(context,
80946f23cedSchristos (uint64_t *)(void *)context->buffer);
81077c9e419Schristos } else {
81177c9e419Schristos /* The buffer is not yet full */
81277c9e419Schristos memcpy(&context->buffer[usedspace], data, len);
81377c9e419Schristos ADDINC128(context->bitcount, len << 3);
81477c9e419Schristos /* Clean up: */
81577c9e419Schristos usedspace = freespace = 0;
81609d5d441Sjoerg return 1;
81777c9e419Schristos }
81877c9e419Schristos }
81917c77a58Sjoerg /*
82017c77a58Sjoerg * Process as many complete blocks as possible.
82117c77a58Sjoerg *
82217c77a58Sjoerg * Check alignment of the data pointer. If it is 64bit aligned,
82317c77a58Sjoerg * SHA512_Transform can be called directly on the data stream,
82417c77a58Sjoerg * otherwise enforce the alignment by copy into the buffer.
82517c77a58Sjoerg */
82617c77a58Sjoerg if ((uintptr_t)data % 8 == 0) {
82777c9e419Schristos while (len >= SHA512_BLOCK_LENGTH) {
82817c77a58Sjoerg SHA512_Transform(context,
8298c33577aSjoerg (const uint64_t*)(const void *)data);
83077c9e419Schristos ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
83177c9e419Schristos len -= SHA512_BLOCK_LENGTH;
83277c9e419Schristos data += SHA512_BLOCK_LENGTH;
83377c9e419Schristos }
83417c77a58Sjoerg } else {
83517c77a58Sjoerg while (len >= SHA512_BLOCK_LENGTH) {
83617c77a58Sjoerg memcpy(context->buffer, data, SHA512_BLOCK_LENGTH);
83717c77a58Sjoerg SHA512_Transform(context,
838de07feb2Sdrochner (const void *)context->buffer);
83917c77a58Sjoerg ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
84017c77a58Sjoerg len -= SHA512_BLOCK_LENGTH;
84117c77a58Sjoerg data += SHA512_BLOCK_LENGTH;
84217c77a58Sjoerg }
84317c77a58Sjoerg }
84477c9e419Schristos if (len > 0) {
84577c9e419Schristos /* There's left-overs, so save 'em */
84677c9e419Schristos memcpy(context->buffer, data, len);
84777c9e419Schristos ADDINC128(context->bitcount, len << 3);
84877c9e419Schristos }
84977c9e419Schristos /* Clean up: */
85077c9e419Schristos usedspace = freespace = 0;
85109d5d441Sjoerg
85209d5d441Sjoerg return 1;
85377c9e419Schristos }
85477c9e419Schristos
85502c42980Sjoerg static void
SHA512_Last(SHA512_CTX * context)85602c42980Sjoerg SHA512_Last(SHA512_CTX *context)
85702c42980Sjoerg {
85877c9e419Schristos unsigned int usedspace;
85977c9e419Schristos
86077c9e419Schristos usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH);
861c8f28effSjoerg context->bitcount[0] = htobe64(context->bitcount[0]);
862c8f28effSjoerg context->bitcount[1] = htobe64(context->bitcount[1]);
86377c9e419Schristos if (usedspace > 0) {
86477c9e419Schristos /* Begin padding with a 1 bit: */
86577c9e419Schristos context->buffer[usedspace++] = 0x80;
86677c9e419Schristos
86777c9e419Schristos if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
86877c9e419Schristos /* Set-up for the last transform: */
86946f23cedSchristos memset(&context->buffer[usedspace], 0,
87046f23cedSchristos (size_t)(SHA512_SHORT_BLOCK_LENGTH - usedspace));
87177c9e419Schristos } else {
87277c9e419Schristos if (usedspace < SHA512_BLOCK_LENGTH) {
87346f23cedSchristos memset(&context->buffer[usedspace], 0,
87446f23cedSchristos (size_t)(SHA512_BLOCK_LENGTH - usedspace));
87577c9e419Schristos }
87677c9e419Schristos /* Do second-to-last transform: */
87746f23cedSchristos SHA512_Transform(context,
87846f23cedSchristos (uint64_t *)(void *)context->buffer);
87977c9e419Schristos
88077c9e419Schristos /* And set-up for the last transform: */
88146f23cedSchristos memset(context->buffer, 0,
88246f23cedSchristos (size_t)(SHA512_BLOCK_LENGTH - 2));
88377c9e419Schristos }
88477c9e419Schristos } else {
88577c9e419Schristos /* Prepare for final transform: */
88677c9e419Schristos memset(context->buffer, 0, (size_t)(SHA512_SHORT_BLOCK_LENGTH));
88777c9e419Schristos
88877c9e419Schristos /* Begin padding with a 1 bit: */
88977c9e419Schristos *context->buffer = 0x80;
89077c9e419Schristos }
89177c9e419Schristos /* Store the length of input data (in bits): */
89213573b19Schristos memcpy(&context->buffer[SHA512_SHORT_BLOCK_LENGTH],
89313573b19Schristos &context->bitcount[1], sizeof(context->bitcount[1]));
89413573b19Schristos memcpy(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8],
89513573b19Schristos &context->bitcount[0], sizeof(context->bitcount[0]));
89677c9e419Schristos
89777c9e419Schristos /* Final transform: */
8988c33577aSjoerg SHA512_Transform(context, (uint64_t *)(void *)context->buffer);
89977c9e419Schristos }
90077c9e419Schristos
90102c42980Sjoerg int
SHA512_Final(uint8_t digest[SHA512_DIGEST_LENGTH],SHA512_CTX * context)902b0d97acfSchristos SHA512_Final(uint8_t digest[SHA512_DIGEST_LENGTH], SHA512_CTX *context)
90302c42980Sjoerg {
904c8f28effSjoerg size_t i;
90577c9e419Schristos
90677c9e419Schristos /* If no digest buffer is passed, we don't bother doing this: */
9078c33577aSjoerg if (digest != NULL) {
90877c9e419Schristos SHA512_Last(context);
90977c9e419Schristos
91077c9e419Schristos /* Save the hash data for output: */
911c8f28effSjoerg for (i = 0; i < 8; ++i)
912e51ee4c4Sjoerg be64enc(digest + 8 * i, context->state[i]);
91377c9e419Schristos }
91477c9e419Schristos
91577c9e419Schristos /* Zero out state data */
91677c9e419Schristos memset(context, 0, sizeof(*context));
91709d5d441Sjoerg
91809d5d441Sjoerg return 1;
91977c9e419Schristos }
92077c9e419Schristos
92177c9e419Schristos /*** SHA-384: *********************************************************/
92202c42980Sjoerg int
SHA384_Init(SHA384_CTX * context)92302c42980Sjoerg SHA384_Init(SHA384_CTX *context)
92402c42980Sjoerg {
92546f23cedSchristos if (context == NULL)
92609d5d441Sjoerg return 1;
92746f23cedSchristos
92846f23cedSchristos memcpy(context->state, sha384_initial_hash_value,
92946f23cedSchristos (size_t)(SHA512_DIGEST_LENGTH));
93077c9e419Schristos memset(context->buffer, 0, (size_t)(SHA384_BLOCK_LENGTH));
93177c9e419Schristos context->bitcount[0] = context->bitcount[1] = 0;
93209d5d441Sjoerg
93309d5d441Sjoerg return 1;
93477c9e419Schristos }
93577c9e419Schristos
93602c42980Sjoerg int
SHA384_Update(SHA384_CTX * context,const uint8_t * data,size_t len)93702c42980Sjoerg SHA384_Update(SHA384_CTX *context, const uint8_t *data, size_t len)
93802c42980Sjoerg {
93909d5d441Sjoerg return SHA512_Update((SHA512_CTX *)context, data, len);
94077c9e419Schristos }
94177c9e419Schristos
94202c42980Sjoerg void
SHA384_Transform(SHA512_CTX * context,const uint64_t * data)94302c42980Sjoerg SHA384_Transform(SHA512_CTX *context, const uint64_t *data)
94402c42980Sjoerg {
94577c9e419Schristos SHA512_Transform((SHA512_CTX *)context, data);
94677c9e419Schristos }
94777c9e419Schristos
94802c42980Sjoerg int
SHA384_Final(uint8_t digest[SHA384_DIGEST_LENGTH],SHA384_CTX * context)949b0d97acfSchristos SHA384_Final(uint8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context)
95002c42980Sjoerg {
951c8f28effSjoerg size_t i;
95277c9e419Schristos
95377c9e419Schristos /* If no digest buffer is passed, we don't bother doing this: */
9548c33577aSjoerg if (digest != NULL) {
95577c9e419Schristos SHA512_Last((SHA512_CTX *)context);
95677c9e419Schristos
95777c9e419Schristos /* Save the hash data for output: */
958c8f28effSjoerg for (i = 0; i < 6; ++i)
95985b087f1Sjoerg be64enc(digest + 8 * i, context->state[i]);
96077c9e419Schristos }
96177c9e419Schristos
96277c9e419Schristos /* Zero out state data */
96377c9e419Schristos memset(context, 0, sizeof(*context));
96409d5d441Sjoerg
96509d5d441Sjoerg return 1;
96677c9e419Schristos }
967