1*9cb04522Stb /* $OpenBSD: sha256.c,v 1.32 2024/06/01 07:36:16 tb Exp $ */
25650a0e1Sdjm /* ====================================================================
3770e2486Sjsing * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
4770e2486Sjsing *
5770e2486Sjsing * Redistribution and use in source and binary forms, with or without
6770e2486Sjsing * modification, are permitted provided that the following conditions
7770e2486Sjsing * are met:
8770e2486Sjsing *
9770e2486Sjsing * 1. Redistributions of source code must retain the above copyright
10770e2486Sjsing * notice, this list of conditions and the following disclaimer.
11770e2486Sjsing *
12770e2486Sjsing * 2. Redistributions in binary form must reproduce the above copyright
13770e2486Sjsing * notice, this list of conditions and the following disclaimer in
14770e2486Sjsing * the documentation and/or other materials provided with the
15770e2486Sjsing * distribution.
16770e2486Sjsing *
17770e2486Sjsing * 3. All advertising materials mentioning features or use of this
18770e2486Sjsing * software must display the following acknowledgment:
19770e2486Sjsing * "This product includes software developed by the OpenSSL Project
20770e2486Sjsing * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21770e2486Sjsing *
22770e2486Sjsing * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23770e2486Sjsing * endorse or promote products derived from this software without
24770e2486Sjsing * prior written permission. For written permission, please contact
25770e2486Sjsing * openssl-core@openssl.org.
26770e2486Sjsing *
27770e2486Sjsing * 5. Products derived from this software may not be called "OpenSSL"
28770e2486Sjsing * nor may "OpenSSL" appear in their names without prior written
29770e2486Sjsing * permission of the OpenSSL Project.
30770e2486Sjsing *
31770e2486Sjsing * 6. Redistributions of any form whatsoever must retain the following
32770e2486Sjsing * acknowledgment:
33770e2486Sjsing * "This product includes software developed by the OpenSSL Project
34770e2486Sjsing * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35770e2486Sjsing *
36770e2486Sjsing * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37770e2486Sjsing * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38770e2486Sjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39770e2486Sjsing * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40770e2486Sjsing * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41770e2486Sjsing * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42770e2486Sjsing * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43770e2486Sjsing * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44770e2486Sjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45770e2486Sjsing * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46770e2486Sjsing * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47770e2486Sjsing * OF THE POSSIBILITY OF SUCH DAMAGE.
485650a0e1Sdjm * ====================================================================
49770e2486Sjsing *
50770e2486Sjsing * This product includes cryptographic software written by Eric Young
51770e2486Sjsing * (eay@cryptsoft.com). This product includes software written by Tim
52770e2486Sjsing * Hudson (tjh@cryptsoft.com).
535650a0e1Sdjm */
548cf4d6a6Sjsing
55b6c209beSbcook #include <endian.h>
565650a0e1Sdjm #include <stdlib.h>
575650a0e1Sdjm #include <string.h>
585650a0e1Sdjm
59a2833576Sjsing #include <openssl/opensslconf.h>
60a2833576Sjsing
615650a0e1Sdjm #include <openssl/crypto.h>
625650a0e1Sdjm #include <openssl/sha.h>
63a2833576Sjsing
64e609121dSjsing #include "crypto_internal.h"
65e609121dSjsing
66a2833576Sjsing #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
675650a0e1Sdjm
68e609121dSjsing /* Ensure that SHA_LONG and uint32_t are equivalent. */
69e609121dSjsing CTASSERT(sizeof(SHA_LONG) == sizeof(uint32_t));
70e609121dSjsing
71b039d949Sjsing #ifdef SHA256_ASM
72b039d949Sjsing void sha256_block_data_order(SHA256_CTX *ctx, const void *_in, size_t num);
735650a0e1Sdjm #endif
745650a0e1Sdjm
755650a0e1Sdjm #ifndef SHA256_ASM
765650a0e1Sdjm static const SHA_LONG K256[64] = {
775650a0e1Sdjm 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
785650a0e1Sdjm 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
795650a0e1Sdjm 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
805650a0e1Sdjm 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
815650a0e1Sdjm 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
825650a0e1Sdjm 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
835650a0e1Sdjm 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
845650a0e1Sdjm 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
855650a0e1Sdjm 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
865650a0e1Sdjm 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
875650a0e1Sdjm 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
885650a0e1Sdjm 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
895650a0e1Sdjm 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
905650a0e1Sdjm 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
915650a0e1Sdjm 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
9299570d72Sjsing 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL,
9399570d72Sjsing };
945650a0e1Sdjm
95d83e85e7Sjsing static inline SHA_LONG
Sigma0(SHA_LONG x)96d83e85e7Sjsing Sigma0(SHA_LONG x)
97d83e85e7Sjsing {
98d83e85e7Sjsing return crypto_ror_u32(x, 2) ^ crypto_ror_u32(x, 13) ^
99d83e85e7Sjsing crypto_ror_u32(x, 22);
100d83e85e7Sjsing }
1015650a0e1Sdjm
102d83e85e7Sjsing static inline SHA_LONG
Sigma1(SHA_LONG x)103d83e85e7Sjsing Sigma1(SHA_LONG x)
104d83e85e7Sjsing {
105d83e85e7Sjsing return crypto_ror_u32(x, 6) ^ crypto_ror_u32(x, 11) ^
106d83e85e7Sjsing crypto_ror_u32(x, 25);
107d83e85e7Sjsing }
1085650a0e1Sdjm
109d83e85e7Sjsing static inline SHA_LONG
sigma0(SHA_LONG x)110d83e85e7Sjsing sigma0(SHA_LONG x)
111d83e85e7Sjsing {
112d83e85e7Sjsing return crypto_ror_u32(x, 7) ^ crypto_ror_u32(x, 18) ^ (x >> 3);
113d83e85e7Sjsing }
1145650a0e1Sdjm
115d83e85e7Sjsing static inline SHA_LONG
sigma1(SHA_LONG x)116d83e85e7Sjsing sigma1(SHA_LONG x)
117d83e85e7Sjsing {
118d83e85e7Sjsing return crypto_ror_u32(x, 17) ^ crypto_ror_u32(x, 19) ^ (x >> 10);
119d83e85e7Sjsing }
120d83e85e7Sjsing
121d83e85e7Sjsing static inline SHA_LONG
Ch(SHA_LONG x,SHA_LONG y,SHA_LONG z)122d83e85e7Sjsing Ch(SHA_LONG x, SHA_LONG y, SHA_LONG z)
123d83e85e7Sjsing {
124d83e85e7Sjsing return (x & y) ^ (~x & z);
125d83e85e7Sjsing }
126d83e85e7Sjsing
127d83e85e7Sjsing static inline SHA_LONG
Maj(SHA_LONG x,SHA_LONG y,SHA_LONG z)128d83e85e7Sjsing Maj(SHA_LONG x, SHA_LONG y, SHA_LONG z)
129d83e85e7Sjsing {
130d83e85e7Sjsing return (x & y) ^ (x & z) ^ (y & z);
131d83e85e7Sjsing }
132d83e85e7Sjsing
133d83e85e7Sjsing static inline void
sha256_msg_schedule_update(SHA_LONG * W0,SHA_LONG W1,SHA_LONG W9,SHA_LONG W14)13471b54e50Sjsing sha256_msg_schedule_update(SHA_LONG *W0, SHA_LONG W1, SHA_LONG W9, SHA_LONG W14)
135d83e85e7Sjsing {
136d83e85e7Sjsing *W0 = sigma1(W14) + W9 + sigma0(W1) + *W0;
137d83e85e7Sjsing }
138d83e85e7Sjsing
139d83e85e7Sjsing static inline void
sha256_round(SHA_LONG * a,SHA_LONG * b,SHA_LONG * c,SHA_LONG * d,SHA_LONG * e,SHA_LONG * f,SHA_LONG * g,SHA_LONG * h,SHA_LONG Kt,SHA_LONG Wt)14071b54e50Sjsing sha256_round(SHA_LONG *a, SHA_LONG *b, SHA_LONG *c, SHA_LONG *d, SHA_LONG *e,
14171b54e50Sjsing SHA_LONG *f, SHA_LONG *g, SHA_LONG *h, SHA_LONG Kt, SHA_LONG Wt)
142d83e85e7Sjsing {
143d83e85e7Sjsing SHA_LONG T1, T2;
144d83e85e7Sjsing
145d83e85e7Sjsing T1 = *h + Sigma1(*e) + Ch(*e, *f, *g) + Kt + Wt;
146d83e85e7Sjsing T2 = Sigma0(*a) + Maj(*a, *b, *c);
147d83e85e7Sjsing
148d83e85e7Sjsing *h = *g;
149d83e85e7Sjsing *g = *f;
150d83e85e7Sjsing *f = *e;
151d83e85e7Sjsing *e = *d + T1;
152d83e85e7Sjsing *d = *c;
153d83e85e7Sjsing *c = *b;
154d83e85e7Sjsing *b = *a;
155d83e85e7Sjsing *a = T1 + T2;
156d83e85e7Sjsing }
1575650a0e1Sdjm
15899570d72Sjsing static void
sha256_block_data_order(SHA256_CTX * ctx,const void * _in,size_t num)159b039d949Sjsing sha256_block_data_order(SHA256_CTX *ctx, const void *_in, size_t num)
1605650a0e1Sdjm {
161b039d949Sjsing const uint8_t *in = _in;
162b039d949Sjsing const SHA_LONG *in32;
163d83e85e7Sjsing SHA_LONG a, b, c, d, e, f, g, h;
1645650a0e1Sdjm SHA_LONG X[16];
1655650a0e1Sdjm int i;
1665650a0e1Sdjm
1675650a0e1Sdjm while (num--) {
16899570d72Sjsing a = ctx->h[0];
16999570d72Sjsing b = ctx->h[1];
17099570d72Sjsing c = ctx->h[2];
17199570d72Sjsing d = ctx->h[3];
17299570d72Sjsing e = ctx->h[4];
17399570d72Sjsing f = ctx->h[5];
17499570d72Sjsing g = ctx->h[6];
17599570d72Sjsing h = ctx->h[7];
1765650a0e1Sdjm
177b039d949Sjsing if ((size_t)in % 4 == 0) {
178b039d949Sjsing /* Input is 32 bit aligned. */
179b039d949Sjsing in32 = (const SHA_LONG *)in;
180b039d949Sjsing X[0] = be32toh(in32[0]);
181b039d949Sjsing X[1] = be32toh(in32[1]);
182b039d949Sjsing X[2] = be32toh(in32[2]);
183b039d949Sjsing X[3] = be32toh(in32[3]);
184b039d949Sjsing X[4] = be32toh(in32[4]);
185b039d949Sjsing X[5] = be32toh(in32[5]);
186b039d949Sjsing X[6] = be32toh(in32[6]);
187b039d949Sjsing X[7] = be32toh(in32[7]);
188b039d949Sjsing X[8] = be32toh(in32[8]);
189b039d949Sjsing X[9] = be32toh(in32[9]);
190b039d949Sjsing X[10] = be32toh(in32[10]);
191b039d949Sjsing X[11] = be32toh(in32[11]);
192b039d949Sjsing X[12] = be32toh(in32[12]);
193b039d949Sjsing X[13] = be32toh(in32[13]);
194b039d949Sjsing X[14] = be32toh(in32[14]);
195b039d949Sjsing X[15] = be32toh(in32[15]);
19699570d72Sjsing } else {
197b039d949Sjsing /* Input is not 32 bit aligned. */
198b039d949Sjsing X[0] = crypto_load_be32toh(&in[0 * 4]);
199b039d949Sjsing X[1] = crypto_load_be32toh(&in[1 * 4]);
200b039d949Sjsing X[2] = crypto_load_be32toh(&in[2 * 4]);
201b039d949Sjsing X[3] = crypto_load_be32toh(&in[3 * 4]);
202b039d949Sjsing X[4] = crypto_load_be32toh(&in[4 * 4]);
203b039d949Sjsing X[5] = crypto_load_be32toh(&in[5 * 4]);
204b039d949Sjsing X[6] = crypto_load_be32toh(&in[6 * 4]);
205b039d949Sjsing X[7] = crypto_load_be32toh(&in[7 * 4]);
206b039d949Sjsing X[8] = crypto_load_be32toh(&in[8 * 4]);
207b039d949Sjsing X[9] = crypto_load_be32toh(&in[9 * 4]);
208b039d949Sjsing X[10] = crypto_load_be32toh(&in[10 * 4]);
209b039d949Sjsing X[11] = crypto_load_be32toh(&in[11 * 4]);
210b039d949Sjsing X[12] = crypto_load_be32toh(&in[12 * 4]);
211b039d949Sjsing X[13] = crypto_load_be32toh(&in[13 * 4]);
212b039d949Sjsing X[14] = crypto_load_be32toh(&in[14 * 4]);
213b039d949Sjsing X[15] = crypto_load_be32toh(&in[15 * 4]);
2145650a0e1Sdjm }
215b039d949Sjsing in += SHA256_CBLOCK;
2165650a0e1Sdjm
217d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[0], X[0]);
218d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[1], X[1]);
219d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[2], X[2]);
220d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[3], X[3]);
221d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[4], X[4]);
222d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[5], X[5]);
223d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[6], X[6]);
224d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[7], X[7]);
225d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[8], X[8]);
226d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[9], X[9]);
227d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[10], X[10]);
228d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[11], X[11]);
229d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[12], X[12]);
230d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[13], X[13]);
231d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[14], X[14]);
232d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[15], X[15]);
2331fd3fa42Sjsing
234d83e85e7Sjsing for (i = 16; i < 64; i += 16) {
235d83e85e7Sjsing sha256_msg_schedule_update(&X[0], X[1], X[9], X[14]);
236d83e85e7Sjsing sha256_msg_schedule_update(&X[1], X[2], X[10], X[15]);
237d83e85e7Sjsing sha256_msg_schedule_update(&X[2], X[3], X[11], X[0]);
238d83e85e7Sjsing sha256_msg_schedule_update(&X[3], X[4], X[12], X[1]);
239d83e85e7Sjsing sha256_msg_schedule_update(&X[4], X[5], X[13], X[2]);
240d83e85e7Sjsing sha256_msg_schedule_update(&X[5], X[6], X[14], X[3]);
241d83e85e7Sjsing sha256_msg_schedule_update(&X[6], X[7], X[15], X[4]);
242d83e85e7Sjsing sha256_msg_schedule_update(&X[7], X[8], X[0], X[5]);
243d83e85e7Sjsing sha256_msg_schedule_update(&X[8], X[9], X[1], X[6]);
244d83e85e7Sjsing sha256_msg_schedule_update(&X[9], X[10], X[2], X[7]);
245d83e85e7Sjsing sha256_msg_schedule_update(&X[10], X[11], X[3], X[8]);
246d83e85e7Sjsing sha256_msg_schedule_update(&X[11], X[12], X[4], X[9]);
247d83e85e7Sjsing sha256_msg_schedule_update(&X[12], X[13], X[5], X[10]);
248d83e85e7Sjsing sha256_msg_schedule_update(&X[13], X[14], X[6], X[11]);
249d83e85e7Sjsing sha256_msg_schedule_update(&X[14], X[15], X[7], X[12]);
250d83e85e7Sjsing sha256_msg_schedule_update(&X[15], X[0], X[8], X[13]);
2511fd3fa42Sjsing
252d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 0], X[0]);
253d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 1], X[1]);
254d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 2], X[2]);
255d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 3], X[3]);
256d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 4], X[4]);
257d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 5], X[5]);
258d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 6], X[6]);
259d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 7], X[7]);
260d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 8], X[8]);
261d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 9], X[9]);
262d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 10], X[10]);
263d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 11], X[11]);
264d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 12], X[12]);
265d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 13], X[13]);
266d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 14], X[14]);
267d83e85e7Sjsing sha256_round(&a, &b, &c, &d, &e, &f, &g, &h, K256[i + 15], X[15]);
2685650a0e1Sdjm }
2695650a0e1Sdjm
27099570d72Sjsing ctx->h[0] += a;
27199570d72Sjsing ctx->h[1] += b;
27299570d72Sjsing ctx->h[2] += c;
27399570d72Sjsing ctx->h[3] += d;
27499570d72Sjsing ctx->h[4] += e;
27599570d72Sjsing ctx->h[5] += f;
27699570d72Sjsing ctx->h[6] += g;
27799570d72Sjsing ctx->h[7] += h;
2785650a0e1Sdjm }
2795650a0e1Sdjm }
2805650a0e1Sdjm #endif /* SHA256_ASM */
2815650a0e1Sdjm
282a94aa803Sjsing int
SHA224_Init(SHA256_CTX * c)283a94aa803Sjsing SHA224_Init(SHA256_CTX *c)
284a94aa803Sjsing {
285a94aa803Sjsing memset(c, 0, sizeof(*c));
286a94aa803Sjsing
287a94aa803Sjsing c->h[0] = 0xc1059ed8UL;
288a94aa803Sjsing c->h[1] = 0x367cd507UL;
289a94aa803Sjsing c->h[2] = 0x3070dd17UL;
290a94aa803Sjsing c->h[3] = 0xf70e5939UL;
291a94aa803Sjsing c->h[4] = 0xffc00b31UL;
292a94aa803Sjsing c->h[5] = 0x68581511UL;
293a94aa803Sjsing c->h[6] = 0x64f98fa7UL;
294a94aa803Sjsing c->h[7] = 0xbefa4fa4UL;
295a94aa803Sjsing
296a94aa803Sjsing c->md_len = SHA224_DIGEST_LENGTH;
297a94aa803Sjsing
298a94aa803Sjsing return 1;
299a94aa803Sjsing }
30065be244dSbeck LCRYPTO_ALIAS(SHA224_Init);
301a94aa803Sjsing
302a94aa803Sjsing int
SHA224_Update(SHA256_CTX * c,const void * data,size_t len)303a94aa803Sjsing SHA224_Update(SHA256_CTX *c, const void *data, size_t len)
304a94aa803Sjsing {
305a94aa803Sjsing return SHA256_Update(c, data, len);
306a94aa803Sjsing }
30765be244dSbeck LCRYPTO_ALIAS(SHA224_Update);
308a94aa803Sjsing
309a94aa803Sjsing int
SHA224_Final(unsigned char * md,SHA256_CTX * c)310a94aa803Sjsing SHA224_Final(unsigned char *md, SHA256_CTX *c)
311a94aa803Sjsing {
312a94aa803Sjsing return SHA256_Final(md, c);
313a94aa803Sjsing }
31465be244dSbeck LCRYPTO_ALIAS(SHA224_Final);
315a94aa803Sjsing
316a94aa803Sjsing unsigned char *
SHA224(const unsigned char * d,size_t n,unsigned char * md)317a94aa803Sjsing SHA224(const unsigned char *d, size_t n, unsigned char *md)
318a94aa803Sjsing {
319a94aa803Sjsing SHA256_CTX c;
320a94aa803Sjsing
321a94aa803Sjsing SHA224_Init(&c);
322a94aa803Sjsing SHA256_Update(&c, d, n);
323a94aa803Sjsing SHA256_Final(md, &c);
324a94aa803Sjsing
325a94aa803Sjsing explicit_bzero(&c, sizeof(c));
326a94aa803Sjsing
327a94aa803Sjsing return (md);
328a94aa803Sjsing }
32965be244dSbeck LCRYPTO_ALIAS(SHA224);
330a94aa803Sjsing
331a94aa803Sjsing int
SHA256_Init(SHA256_CTX * c)332a94aa803Sjsing SHA256_Init(SHA256_CTX *c)
333a94aa803Sjsing {
334a94aa803Sjsing memset(c, 0, sizeof(*c));
335a94aa803Sjsing
336a94aa803Sjsing c->h[0] = 0x6a09e667UL;
337a94aa803Sjsing c->h[1] = 0xbb67ae85UL;
338a94aa803Sjsing c->h[2] = 0x3c6ef372UL;
339a94aa803Sjsing c->h[3] = 0xa54ff53aUL;
340a94aa803Sjsing c->h[4] = 0x510e527fUL;
341a94aa803Sjsing c->h[5] = 0x9b05688cUL;
342a94aa803Sjsing c->h[6] = 0x1f83d9abUL;
343a94aa803Sjsing c->h[7] = 0x5be0cd19UL;
344a94aa803Sjsing
345a94aa803Sjsing c->md_len = SHA256_DIGEST_LENGTH;
346a94aa803Sjsing
347a94aa803Sjsing return 1;
348a94aa803Sjsing }
34965be244dSbeck LCRYPTO_ALIAS(SHA256_Init);
350a94aa803Sjsing
351a94aa803Sjsing int
SHA256_Update(SHA256_CTX * c,const void * data_,size_t len)352627637adSjsing SHA256_Update(SHA256_CTX *c, const void *data_, size_t len)
353a94aa803Sjsing {
354a94aa803Sjsing const unsigned char *data = data_;
355a94aa803Sjsing unsigned char *p;
356a94aa803Sjsing SHA_LONG l;
357a94aa803Sjsing size_t n;
358a94aa803Sjsing
359a94aa803Sjsing if (len == 0)
360a94aa803Sjsing return 1;
361a94aa803Sjsing
362a94aa803Sjsing l = (c->Nl + (((SHA_LONG)len) << 3)) & 0xffffffffUL;
363a94aa803Sjsing /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
364a94aa803Sjsing * Wei Dai <weidai@eskimo.com> for pointing it out. */
365a94aa803Sjsing if (l < c->Nl) /* overflow */
366a94aa803Sjsing c->Nh++;
367a94aa803Sjsing c->Nh += (SHA_LONG)(len >> 29); /* might cause compiler warning on 16-bit */
368a94aa803Sjsing c->Nl = l;
369a94aa803Sjsing
370a94aa803Sjsing n = c->num;
371a94aa803Sjsing if (n != 0) {
372a94aa803Sjsing p = (unsigned char *)c->data;
373a94aa803Sjsing
374a94aa803Sjsing if (len >= SHA_CBLOCK || len + n >= SHA_CBLOCK) {
375a94aa803Sjsing memcpy(p + n, data, SHA_CBLOCK - n);
376a94aa803Sjsing sha256_block_data_order(c, p, 1);
377a94aa803Sjsing n = SHA_CBLOCK - n;
378a94aa803Sjsing data += n;
379a94aa803Sjsing len -= n;
380a94aa803Sjsing c->num = 0;
381a94aa803Sjsing memset(p, 0, SHA_CBLOCK); /* keep it zeroed */
382a94aa803Sjsing } else {
383a94aa803Sjsing memcpy(p + n, data, len);
384a94aa803Sjsing c->num += (unsigned int)len;
385a94aa803Sjsing return 1;
386a94aa803Sjsing }
387a94aa803Sjsing }
388a94aa803Sjsing
389a94aa803Sjsing n = len/SHA_CBLOCK;
390a94aa803Sjsing if (n > 0) {
391a94aa803Sjsing sha256_block_data_order(c, data, n);
392a94aa803Sjsing n *= SHA_CBLOCK;
393a94aa803Sjsing data += n;
394a94aa803Sjsing len -= n;
395a94aa803Sjsing }
396a94aa803Sjsing
397a94aa803Sjsing if (len != 0) {
398a94aa803Sjsing p = (unsigned char *)c->data;
399a94aa803Sjsing c->num = (unsigned int)len;
400a94aa803Sjsing memcpy(p, data, len);
401a94aa803Sjsing }
402a94aa803Sjsing return 1;
403a94aa803Sjsing }
40465be244dSbeck LCRYPTO_ALIAS(SHA256_Update);
405a94aa803Sjsing
406a94aa803Sjsing void
SHA256_Transform(SHA256_CTX * c,const unsigned char * data)407627637adSjsing SHA256_Transform(SHA256_CTX *c, const unsigned char *data)
408a94aa803Sjsing {
409a94aa803Sjsing sha256_block_data_order(c, data, 1);
410a94aa803Sjsing }
41165be244dSbeck LCRYPTO_ALIAS(SHA256_Transform);
412a94aa803Sjsing
413a94aa803Sjsing int
SHA256_Final(unsigned char * md,SHA256_CTX * c)414627637adSjsing SHA256_Final(unsigned char *md, SHA256_CTX *c)
415a94aa803Sjsing {
416a94aa803Sjsing unsigned char *p = (unsigned char *)c->data;
417a94aa803Sjsing size_t n = c->num;
418a94aa803Sjsing unsigned int nn;
419a94aa803Sjsing
420a94aa803Sjsing p[n] = 0x80; /* there is always room for one */
421a94aa803Sjsing n++;
422a94aa803Sjsing
423a94aa803Sjsing if (n > (SHA_CBLOCK - 8)) {
424a94aa803Sjsing memset(p + n, 0, SHA_CBLOCK - n);
425a94aa803Sjsing n = 0;
426a94aa803Sjsing sha256_block_data_order(c, p, 1);
427a94aa803Sjsing }
428a94aa803Sjsing
429e609121dSjsing memset(p + n, 0, SHA_CBLOCK - 8 - n);
430e609121dSjsing c->data[SHA_LBLOCK - 2] = htobe32(c->Nh);
431e609121dSjsing c->data[SHA_LBLOCK - 1] = htobe32(c->Nl);
432e609121dSjsing
433a94aa803Sjsing sha256_block_data_order(c, p, 1);
434a94aa803Sjsing c->num = 0;
435a94aa803Sjsing memset(p, 0, SHA_CBLOCK);
436a94aa803Sjsing
437a94aa803Sjsing /*
438a94aa803Sjsing * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
439a94aa803Sjsing * default: case below covers for it. It's not clear however if it's
440a94aa803Sjsing * permitted to truncate to amount of bytes not divisible by 4. I bet not,
441a94aa803Sjsing * but if it is, then default: case shall be extended. For reference.
442a94aa803Sjsing * Idea behind separate cases for pre-defined lengths is to let the
443a94aa803Sjsing * compiler decide if it's appropriate to unroll small loops.
444a94aa803Sjsing */
445a94aa803Sjsing switch (c->md_len) {
446a94aa803Sjsing case SHA224_DIGEST_LENGTH:
447a94aa803Sjsing for (nn = 0; nn < SHA224_DIGEST_LENGTH / 4; nn++) {
448e609121dSjsing crypto_store_htobe32(md, c->h[nn]);
449e609121dSjsing md += 4;
450a94aa803Sjsing }
451a94aa803Sjsing break;
452a94aa803Sjsing
453a94aa803Sjsing case SHA256_DIGEST_LENGTH:
454a94aa803Sjsing for (nn = 0; nn < SHA256_DIGEST_LENGTH / 4; nn++) {
455e609121dSjsing crypto_store_htobe32(md, c->h[nn]);
456e609121dSjsing md += 4;
457a94aa803Sjsing }
458a94aa803Sjsing break;
459a94aa803Sjsing
460a94aa803Sjsing default:
461a94aa803Sjsing if (c->md_len > SHA256_DIGEST_LENGTH)
462a94aa803Sjsing return 0;
463a94aa803Sjsing for (nn = 0; nn < c->md_len / 4; nn++) {
464e609121dSjsing crypto_store_htobe32(md, c->h[nn]);
465e609121dSjsing md += 4;
466a94aa803Sjsing }
467a94aa803Sjsing break;
468a94aa803Sjsing }
469a94aa803Sjsing
470a94aa803Sjsing return 1;
471a94aa803Sjsing }
47265be244dSbeck LCRYPTO_ALIAS(SHA256_Final);
473a94aa803Sjsing
474a94aa803Sjsing unsigned char *
SHA256(const unsigned char * d,size_t n,unsigned char * md)475a94aa803Sjsing SHA256(const unsigned char *d, size_t n, unsigned char *md)
476a94aa803Sjsing {
477a94aa803Sjsing SHA256_CTX c;
478a94aa803Sjsing
479a94aa803Sjsing SHA256_Init(&c);
480a94aa803Sjsing SHA256_Update(&c, d, n);
481a94aa803Sjsing SHA256_Final(md, &c);
482a94aa803Sjsing
483a94aa803Sjsing explicit_bzero(&c, sizeof(c));
484a94aa803Sjsing
485a94aa803Sjsing return (md);
486a94aa803Sjsing }
48765be244dSbeck LCRYPTO_ALIAS(SHA256);
488a94aa803Sjsing
4895650a0e1Sdjm #endif /* OPENSSL_NO_SHA256 */
490