155714Skris/* crypto/sha/sha_locl.h */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296465Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296465Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296465Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296465Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296465Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdlib.h>
6055714Skris#include <string.h>
6155714Skris
6255714Skris#include <openssl/opensslconf.h>
6359191Skris#include <openssl/sha.h>
6455714Skris
6559191Skris#define DATA_ORDER_IS_BIG_ENDIAN
6655714Skris
6759191Skris#define HASH_LONG               SHA_LONG
6859191Skris#define HASH_CTX                SHA_CTX
6959191Skris#define HASH_CBLOCK             SHA_CBLOCK
70296465Sdelphij#define HASH_MAKE_STRING(c,s)   do {    \
71296465Sdelphij        unsigned long ll;               \
72296465Sdelphij        ll=(c)->h0; HOST_l2c(ll,(s));   \
73296465Sdelphij        ll=(c)->h1; HOST_l2c(ll,(s));   \
74296465Sdelphij        ll=(c)->h2; HOST_l2c(ll,(s));   \
75296465Sdelphij        ll=(c)->h3; HOST_l2c(ll,(s));   \
76296465Sdelphij        ll=(c)->h4; HOST_l2c(ll,(s));   \
77296465Sdelphij        } while (0)
7855714Skris
7959191Skris#if defined(SHA_0)
8055714Skris
81296465Sdelphij# define HASH_UPDATE                    SHA_Update
82296465Sdelphij# define HASH_TRANSFORM                 SHA_Transform
83296465Sdelphij# define HASH_FINAL                     SHA_Final
84296465Sdelphij# define HASH_INIT                      SHA_Init
85296465Sdelphij# define HASH_BLOCK_DATA_ORDER          sha_block_data_order
86296465Sdelphij# define Xupdate(a,ix,ia,ib,ic,id)      (ix=(a)=(ia^ib^ic^id))
8755714Skris
88296465Sdelphijstatic void sha_block_data_order(SHA_CTX *c, const void *p, size_t num);
8955714Skris
9059191Skris#elif defined(SHA_1)
9155714Skris
92296465Sdelphij# define HASH_UPDATE                    SHA1_Update
93296465Sdelphij# define HASH_TRANSFORM                 SHA1_Transform
94296465Sdelphij# define HASH_FINAL                     SHA1_Final
95296465Sdelphij# define HASH_INIT                      SHA1_Init
96296465Sdelphij# define HASH_BLOCK_DATA_ORDER          sha1_block_data_order
9759191Skris# if defined(__MWERKS__) && defined(__MC68K__)
9859191Skris   /* Metrowerks for Motorola fails otherwise:-( <appro@fy.chalmers.se> */
99296465Sdelphij#  define Xupdate(a,ix,ia,ib,ic,id)     do { (a)=(ia^ib^ic^id);         \
100296465Sdelphij                                             ix=(a)=ROTATE((a),1);      \
101296465Sdelphij                                        } while (0)
10259191Skris# else
103296465Sdelphij#  define Xupdate(a,ix,ia,ib,ic,id)     ( (a)=(ia^ib^ic^id),    \
104296465Sdelphij                                          ix=(a)=ROTATE((a),1)  \
105296465Sdelphij                                        )
10659191Skris# endif
10755714Skris
108296465Sdelphij# ifndef SHA1_ASM
109194206Ssimonstatic
110296465Sdelphij# endif
111296465Sdelphijvoid sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
11255714Skris
11359191Skris#else
11459191Skris# error "Either SHA_0 or SHA_1 must be defined."
11559191Skris#endif
11655714Skris
11759191Skris#include "md32_common.h"
11855714Skris
11959191Skris#define INIT_DATA_h0 0x67452301UL
12059191Skris#define INIT_DATA_h1 0xefcdab89UL
12159191Skris#define INIT_DATA_h2 0x98badcfeUL
12259191Skris#define INIT_DATA_h3 0x10325476UL
12359191Skris#define INIT_DATA_h4 0xc3d2e1f0UL
12455714Skris
125194206Ssimon#if defined(SHA_0) && defined(OPENSSL_FIPS)
126194206SsimonFIPS_NON_FIPS_MD_Init(SHA)
127194206Ssimon#else
128296465Sdelphijint HASH_INIT(SHA_CTX *c)
129194206Ssimon#endif
130296465Sdelphij{
131194206Ssimon#if defined(SHA_1) && defined(OPENSSL_FIPS)
132296465Sdelphij    FIPS_selftest_check();
133194206Ssimon#endif
134296465Sdelphij    c->h0 = INIT_DATA_h0;
135296465Sdelphij    c->h1 = INIT_DATA_h1;
136296465Sdelphij    c->h2 = INIT_DATA_h2;
137296465Sdelphij    c->h3 = INIT_DATA_h3;
138296465Sdelphij    c->h4 = INIT_DATA_h4;
139296465Sdelphij    c->Nl = 0;
140296465Sdelphij    c->Nh = 0;
141296465Sdelphij    c->num = 0;
142296465Sdelphij    return 1;
143296465Sdelphij}
14455714Skris
145296465Sdelphij#define K_00_19 0x5a827999UL
14659191Skris#define K_20_39 0x6ed9eba1UL
14759191Skris#define K_40_59 0x8f1bbcdcUL
14859191Skris#define K_60_79 0xca62c1d6UL
14959191Skris
150296465Sdelphij/*
151296465Sdelphij * As pointed out by Wei Dai <weidai@eskimo.com>, F() below can be simplified
152296465Sdelphij * to the code in F_00_19.  Wei attributes these optimisations to Peter
153296465Sdelphij * Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define
154296465Sdelphij * F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another
155296465Sdelphij * tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a
15655714Skris */
157296465Sdelphij#define F_00_19(b,c,d)  ((((c) ^ (d)) & (b)) ^ (d))
158296465Sdelphij#define F_20_39(b,c,d)  ((b) ^ (c) ^ (d))
159296465Sdelphij#define F_40_59(b,c,d)  (((b) & (c)) | (((b)|(c)) & (d)))
160296465Sdelphij#define F_60_79(b,c,d)  F_20_39(b,c,d)
16155714Skris
162160814Ssimon#ifndef OPENSSL_SMALL_FOOTPRINT
163160814Ssimon
164296465Sdelphij# define BODY_00_15(i,a,b,c,d,e,f,xi) \
165296465Sdelphij        (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
166296465Sdelphij        (b)=ROTATE((b),30);
16755714Skris
168296465Sdelphij# define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
169296465Sdelphij        Xupdate(f,xi,xa,xb,xc,xd); \
170296465Sdelphij        (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
171296465Sdelphij        (b)=ROTATE((b),30);
17255714Skris
173296465Sdelphij# define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
174296465Sdelphij        Xupdate(f,xi,xa,xb,xc,xd); \
175296465Sdelphij        (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
176296465Sdelphij        (b)=ROTATE((b),30);
17755714Skris
178296465Sdelphij# define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
179296465Sdelphij        Xupdate(f,xa,xa,xb,xc,xd); \
180296465Sdelphij        (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
181296465Sdelphij        (b)=ROTATE((b),30);
18255714Skris
183296465Sdelphij# define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
184296465Sdelphij        Xupdate(f,xa,xa,xb,xc,xd); \
185296465Sdelphij        (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
186296465Sdelphij        (b)=ROTATE((b),30);
18755714Skris
188296465Sdelphij# define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
189296465Sdelphij        Xupdate(f,xa,xa,xb,xc,xd); \
190296465Sdelphij        (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
191296465Sdelphij        (b)=ROTATE((b),30);
19255714Skris
193296465Sdelphij# ifdef X
194296465Sdelphij#  undef X
195296465Sdelphij# endif
196296465Sdelphij# ifndef MD32_XARRAY
19759191Skris  /*
19859191Skris   * Originally X was an array. As it's automatic it's natural
19959191Skris   * to expect RISC compiler to accomodate at least part of it in
20059191Skris   * the register bank, isn't it? Unfortunately not all compilers
20159191Skris   * "find" this expectation reasonable:-( On order to make such
20259191Skris   * compilers generate better code I replace X[] with a bunch of
20359191Skris   * X0, X1, etc. See the function body below...
204296465Sdelphij   *                                    <appro@fy.chalmers.se>
20559191Skris   */
206296465Sdelphij#  define X(i)   XX##i
207296465Sdelphij# else
20859191Skris  /*
20959191Skris   * However! Some compilers (most notably HP C) get overwhelmed by
21059191Skris   * that many local variables so that we have to have the way to
21159191Skris   * fall down to the original behavior.
21259191Skris   */
213296465Sdelphij#  define X(i)   XX[i]
214296465Sdelphij# endif
21559191Skris
216296465Sdelphij# if !defined(SHA_1) || !defined(SHA1_ASM)
217296465Sdelphijstatic void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num)
218296465Sdelphij{
219296465Sdelphij    const unsigned char *data = p;
220296465Sdelphij    register unsigned MD32_REG_T A, B, C, D, E, T, l;
221296465Sdelphij#  ifndef MD32_XARRAY
222296465Sdelphij    unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
223296465Sdelphij        XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
224296465Sdelphij#  else
225296465Sdelphij    SHA_LONG XX[16];
226296465Sdelphij#  endif
22759191Skris
228296465Sdelphij    A = c->h0;
229296465Sdelphij    B = c->h1;
230296465Sdelphij    C = c->h2;
231296465Sdelphij    D = c->h3;
232296465Sdelphij    E = c->h4;
23359191Skris
234296465Sdelphij    for (;;) {
235296465Sdelphij        const union {
236296465Sdelphij            long one;
237296465Sdelphij            char little;
238296465Sdelphij        } is_endian = {
239296465Sdelphij            1
240296465Sdelphij        };
241194206Ssimon
242296465Sdelphij        if (!is_endian.little && sizeof(SHA_LONG) == 4
243296465Sdelphij            && ((size_t)p % 4) == 0) {
244296465Sdelphij            const SHA_LONG *W = (const SHA_LONG *)data;
24559191Skris
246296465Sdelphij            X(0) = W[0];
247296465Sdelphij            X(1) = W[1];
248296465Sdelphij            BODY_00_15(0, A, B, C, D, E, T, X(0));
249296465Sdelphij            X(2) = W[2];
250296465Sdelphij            BODY_00_15(1, T, A, B, C, D, E, X(1));
251296465Sdelphij            X(3) = W[3];
252296465Sdelphij            BODY_00_15(2, E, T, A, B, C, D, X(2));
253296465Sdelphij            X(4) = W[4];
254296465Sdelphij            BODY_00_15(3, D, E, T, A, B, C, X(3));
255296465Sdelphij            X(5) = W[5];
256296465Sdelphij            BODY_00_15(4, C, D, E, T, A, B, X(4));
257296465Sdelphij            X(6) = W[6];
258296465Sdelphij            BODY_00_15(5, B, C, D, E, T, A, X(5));
259296465Sdelphij            X(7) = W[7];
260296465Sdelphij            BODY_00_15(6, A, B, C, D, E, T, X(6));
261296465Sdelphij            X(8) = W[8];
262296465Sdelphij            BODY_00_15(7, T, A, B, C, D, E, X(7));
263296465Sdelphij            X(9) = W[9];
264296465Sdelphij            BODY_00_15(8, E, T, A, B, C, D, X(8));
265296465Sdelphij            X(10) = W[10];
266296465Sdelphij            BODY_00_15(9, D, E, T, A, B, C, X(9));
267296465Sdelphij            X(11) = W[11];
268296465Sdelphij            BODY_00_15(10, C, D, E, T, A, B, X(10));
269296465Sdelphij            X(12) = W[12];
270296465Sdelphij            BODY_00_15(11, B, C, D, E, T, A, X(11));
271296465Sdelphij            X(13) = W[13];
272296465Sdelphij            BODY_00_15(12, A, B, C, D, E, T, X(12));
273296465Sdelphij            X(14) = W[14];
274296465Sdelphij            BODY_00_15(13, T, A, B, C, D, E, X(13));
275296465Sdelphij            X(15) = W[15];
276296465Sdelphij            BODY_00_15(14, E, T, A, B, C, D, X(14));
277296465Sdelphij            BODY_00_15(15, D, E, T, A, B, C, X(15));
27859191Skris
279296465Sdelphij            data += SHA_CBLOCK;
280296465Sdelphij        } else {
281296465Sdelphij            HOST_c2l(data, l);
282296465Sdelphij            X(0) = l;
283296465Sdelphij            HOST_c2l(data, l);
284296465Sdelphij            X(1) = l;
285296465Sdelphij            BODY_00_15(0, A, B, C, D, E, T, X(0));
286296465Sdelphij            HOST_c2l(data, l);
287296465Sdelphij            X(2) = l;
288296465Sdelphij            BODY_00_15(1, T, A, B, C, D, E, X(1));
289296465Sdelphij            HOST_c2l(data, l);
290296465Sdelphij            X(3) = l;
291296465Sdelphij            BODY_00_15(2, E, T, A, B, C, D, X(2));
292296465Sdelphij            HOST_c2l(data, l);
293296465Sdelphij            X(4) = l;
294296465Sdelphij            BODY_00_15(3, D, E, T, A, B, C, X(3));
295296465Sdelphij            HOST_c2l(data, l);
296296465Sdelphij            X(5) = l;
297296465Sdelphij            BODY_00_15(4, C, D, E, T, A, B, X(4));
298296465Sdelphij            HOST_c2l(data, l);
299296465Sdelphij            X(6) = l;
300296465Sdelphij            BODY_00_15(5, B, C, D, E, T, A, X(5));
301296465Sdelphij            HOST_c2l(data, l);
302296465Sdelphij            X(7) = l;
303296465Sdelphij            BODY_00_15(6, A, B, C, D, E, T, X(6));
304296465Sdelphij            HOST_c2l(data, l);
305296465Sdelphij            X(8) = l;
306296465Sdelphij            BODY_00_15(7, T, A, B, C, D, E, X(7));
307296465Sdelphij            HOST_c2l(data, l);
308296465Sdelphij            X(9) = l;
309296465Sdelphij            BODY_00_15(8, E, T, A, B, C, D, X(8));
310296465Sdelphij            HOST_c2l(data, l);
311296465Sdelphij            X(10) = l;
312296465Sdelphij            BODY_00_15(9, D, E, T, A, B, C, X(9));
313296465Sdelphij            HOST_c2l(data, l);
314296465Sdelphij            X(11) = l;
315296465Sdelphij            BODY_00_15(10, C, D, E, T, A, B, X(10));
316296465Sdelphij            HOST_c2l(data, l);
317296465Sdelphij            X(12) = l;
318296465Sdelphij            BODY_00_15(11, B, C, D, E, T, A, X(11));
319296465Sdelphij            HOST_c2l(data, l);
320296465Sdelphij            X(13) = l;
321296465Sdelphij            BODY_00_15(12, A, B, C, D, E, T, X(12));
322296465Sdelphij            HOST_c2l(data, l);
323296465Sdelphij            X(14) = l;
324296465Sdelphij            BODY_00_15(13, T, A, B, C, D, E, X(13));
325296465Sdelphij            HOST_c2l(data, l);
326296465Sdelphij            X(15) = l;
327296465Sdelphij            BODY_00_15(14, E, T, A, B, C, D, X(14));
328296465Sdelphij            BODY_00_15(15, D, E, T, A, B, C, X(15));
329296465Sdelphij        }
33059191Skris
331296465Sdelphij        BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13));
332296465Sdelphij        BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14));
333296465Sdelphij        BODY_16_19(18, A, B, C, D, E, T, X(2), X(2), X(4), X(10), X(15));
334296465Sdelphij        BODY_16_19(19, T, A, B, C, D, E, X(3), X(3), X(5), X(11), X(0));
33559191Skris
336296465Sdelphij        BODY_20_31(20, E, T, A, B, C, D, X(4), X(4), X(6), X(12), X(1));
337296465Sdelphij        BODY_20_31(21, D, E, T, A, B, C, X(5), X(5), X(7), X(13), X(2));
338296465Sdelphij        BODY_20_31(22, C, D, E, T, A, B, X(6), X(6), X(8), X(14), X(3));
339296465Sdelphij        BODY_20_31(23, B, C, D, E, T, A, X(7), X(7), X(9), X(15), X(4));
340296465Sdelphij        BODY_20_31(24, A, B, C, D, E, T, X(8), X(8), X(10), X(0), X(5));
341296465Sdelphij        BODY_20_31(25, T, A, B, C, D, E, X(9), X(9), X(11), X(1), X(6));
342296465Sdelphij        BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X(2), X(7));
343296465Sdelphij        BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X(3), X(8));
344296465Sdelphij        BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X(4), X(9));
345296465Sdelphij        BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X(5), X(10));
346296465Sdelphij        BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X(0), X(6), X(11));
347296465Sdelphij        BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X(1), X(7), X(12));
34859191Skris
349296465Sdelphij        BODY_32_39(32, E, T, A, B, C, D, X(0), X(2), X(8), X(13));
350296465Sdelphij        BODY_32_39(33, D, E, T, A, B, C, X(1), X(3), X(9), X(14));
351296465Sdelphij        BODY_32_39(34, C, D, E, T, A, B, X(2), X(4), X(10), X(15));
352296465Sdelphij        BODY_32_39(35, B, C, D, E, T, A, X(3), X(5), X(11), X(0));
353296465Sdelphij        BODY_32_39(36, A, B, C, D, E, T, X(4), X(6), X(12), X(1));
354296465Sdelphij        BODY_32_39(37, T, A, B, C, D, E, X(5), X(7), X(13), X(2));
355296465Sdelphij        BODY_32_39(38, E, T, A, B, C, D, X(6), X(8), X(14), X(3));
356296465Sdelphij        BODY_32_39(39, D, E, T, A, B, C, X(7), X(9), X(15), X(4));
35759191Skris
358296465Sdelphij        BODY_40_59(40, C, D, E, T, A, B, X(8), X(10), X(0), X(5));
359296465Sdelphij        BODY_40_59(41, B, C, D, E, T, A, X(9), X(11), X(1), X(6));
360296465Sdelphij        BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X(2), X(7));
361296465Sdelphij        BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X(3), X(8));
362296465Sdelphij        BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X(4), X(9));
363296465Sdelphij        BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X(5), X(10));
364296465Sdelphij        BODY_40_59(46, C, D, E, T, A, B, X(14), X(0), X(6), X(11));
365296465Sdelphij        BODY_40_59(47, B, C, D, E, T, A, X(15), X(1), X(7), X(12));
366296465Sdelphij        BODY_40_59(48, A, B, C, D, E, T, X(0), X(2), X(8), X(13));
367296465Sdelphij        BODY_40_59(49, T, A, B, C, D, E, X(1), X(3), X(9), X(14));
368296465Sdelphij        BODY_40_59(50, E, T, A, B, C, D, X(2), X(4), X(10), X(15));
369296465Sdelphij        BODY_40_59(51, D, E, T, A, B, C, X(3), X(5), X(11), X(0));
370296465Sdelphij        BODY_40_59(52, C, D, E, T, A, B, X(4), X(6), X(12), X(1));
371296465Sdelphij        BODY_40_59(53, B, C, D, E, T, A, X(5), X(7), X(13), X(2));
372296465Sdelphij        BODY_40_59(54, A, B, C, D, E, T, X(6), X(8), X(14), X(3));
373296465Sdelphij        BODY_40_59(55, T, A, B, C, D, E, X(7), X(9), X(15), X(4));
374296465Sdelphij        BODY_40_59(56, E, T, A, B, C, D, X(8), X(10), X(0), X(5));
375296465Sdelphij        BODY_40_59(57, D, E, T, A, B, C, X(9), X(11), X(1), X(6));
376296465Sdelphij        BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X(2), X(7));
377296465Sdelphij        BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X(3), X(8));
37859191Skris
379296465Sdelphij        BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X(4), X(9));
380296465Sdelphij        BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X(5), X(10));
381296465Sdelphij        BODY_60_79(62, E, T, A, B, C, D, X(14), X(0), X(6), X(11));
382296465Sdelphij        BODY_60_79(63, D, E, T, A, B, C, X(15), X(1), X(7), X(12));
383296465Sdelphij        BODY_60_79(64, C, D, E, T, A, B, X(0), X(2), X(8), X(13));
384296465Sdelphij        BODY_60_79(65, B, C, D, E, T, A, X(1), X(3), X(9), X(14));
385296465Sdelphij        BODY_60_79(66, A, B, C, D, E, T, X(2), X(4), X(10), X(15));
386296465Sdelphij        BODY_60_79(67, T, A, B, C, D, E, X(3), X(5), X(11), X(0));
387296465Sdelphij        BODY_60_79(68, E, T, A, B, C, D, X(4), X(6), X(12), X(1));
388296465Sdelphij        BODY_60_79(69, D, E, T, A, B, C, X(5), X(7), X(13), X(2));
389296465Sdelphij        BODY_60_79(70, C, D, E, T, A, B, X(6), X(8), X(14), X(3));
390296465Sdelphij        BODY_60_79(71, B, C, D, E, T, A, X(7), X(9), X(15), X(4));
391296465Sdelphij        BODY_60_79(72, A, B, C, D, E, T, X(8), X(10), X(0), X(5));
392296465Sdelphij        BODY_60_79(73, T, A, B, C, D, E, X(9), X(11), X(1), X(6));
393296465Sdelphij        BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X(2), X(7));
394296465Sdelphij        BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X(3), X(8));
395296465Sdelphij        BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X(4), X(9));
396296465Sdelphij        BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X(5), X(10));
397296465Sdelphij        BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11));
398296465Sdelphij        BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12));
39959191Skris
400296465Sdelphij        c->h0 = (c->h0 + E) & 0xffffffffL;
401296465Sdelphij        c->h1 = (c->h1 + T) & 0xffffffffL;
402296465Sdelphij        c->h2 = (c->h2 + A) & 0xffffffffL;
403296465Sdelphij        c->h3 = (c->h3 + B) & 0xffffffffL;
404296465Sdelphij        c->h4 = (c->h4 + C) & 0xffffffffL;
40559191Skris
406296465Sdelphij        if (--num == 0)
407296465Sdelphij            break;
40859191Skris
409296465Sdelphij        A = c->h0;
410296465Sdelphij        B = c->h1;
411296465Sdelphij        C = c->h2;
412296465Sdelphij        D = c->h3;
413296465Sdelphij        E = c->h4;
414160814Ssimon
415296465Sdelphij    }
416296465Sdelphij}
417296465Sdelphij# endif
418160814Ssimon
419296465Sdelphij#else                           /* OPENSSL_SMALL_FOOTPRINT */
420160814Ssimon
421296465Sdelphij# define BODY_00_15(xi)           do {   \
422296465Sdelphij        T=E+K_00_19+F_00_19(B,C,D);     \
423296465Sdelphij        E=D, D=C, C=ROTATE(B,30), B=A;  \
424296465Sdelphij        A=ROTATE(A,5)+T+xi;         } while(0)
425160814Ssimon
426296465Sdelphij# define BODY_16_19(xa,xb,xc,xd)  do {   \
427296465Sdelphij        Xupdate(T,xa,xa,xb,xc,xd);      \
428296465Sdelphij        T+=E+K_00_19+F_00_19(B,C,D);    \
429296465Sdelphij        E=D, D=C, C=ROTATE(B,30), B=A;  \
430296465Sdelphij        A=ROTATE(A,5)+T;            } while(0)
431160814Ssimon
432296465Sdelphij# define BODY_20_39(xa,xb,xc,xd)  do {   \
433296465Sdelphij        Xupdate(T,xa,xa,xb,xc,xd);      \
434296465Sdelphij        T+=E+K_20_39+F_20_39(B,C,D);    \
435296465Sdelphij        E=D, D=C, C=ROTATE(B,30), B=A;  \
436296465Sdelphij        A=ROTATE(A,5)+T;            } while(0)
437160814Ssimon
438296465Sdelphij# define BODY_40_59(xa,xb,xc,xd)  do {   \
439296465Sdelphij        Xupdate(T,xa,xa,xb,xc,xd);      \
440296465Sdelphij        T+=E+K_40_59+F_40_59(B,C,D);    \
441296465Sdelphij        E=D, D=C, C=ROTATE(B,30), B=A;  \
442296465Sdelphij        A=ROTATE(A,5)+T;            } while(0)
443160814Ssimon
444296465Sdelphij# define BODY_60_79(xa,xb,xc,xd)  do {   \
445296465Sdelphij        Xupdate(T,xa,xa,xb,xc,xd);      \
446296465Sdelphij        T=E+K_60_79+F_60_79(B,C,D);     \
447296465Sdelphij        E=D, D=C, C=ROTATE(B,30), B=A;  \
448296465Sdelphij        A=ROTATE(A,5)+T+xa;         } while(0)
449160814Ssimon
450296465Sdelphij# if !defined(SHA_1) || !defined(SHA1_ASM)
451296465Sdelphijstatic void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num)
452296465Sdelphij{
453296465Sdelphij    const unsigned char *data = p;
454296465Sdelphij    register unsigned MD32_REG_T A, B, C, D, E, T, l;
455296465Sdelphij    int i;
456296465Sdelphij    SHA_LONG X[16];
457160814Ssimon
458296465Sdelphij    A = c->h0;
459296465Sdelphij    B = c->h1;
460296465Sdelphij    C = c->h2;
461296465Sdelphij    D = c->h3;
462296465Sdelphij    E = c->h4;
463160814Ssimon
464296465Sdelphij    for (;;) {
465296465Sdelphij        for (i = 0; i < 16; i++) {
466296465Sdelphij            HOST_c2l(data, l);
467296465Sdelphij            X[i] = l;
468296465Sdelphij            BODY_00_15(X[i]);
469296465Sdelphij        }
470296465Sdelphij        for (i = 0; i < 4; i++) {
471296465Sdelphij            BODY_16_19(X[i], X[i + 2], X[i + 8], X[(i + 13) & 15]);
472296465Sdelphij        }
473296465Sdelphij        for (; i < 24; i++) {
474296465Sdelphij            BODY_20_39(X[i & 15], X[(i + 2) & 15], X[(i + 8) & 15],
475296465Sdelphij                       X[(i + 13) & 15]);
476296465Sdelphij        }
477296465Sdelphij        for (i = 0; i < 20; i++) {
478296465Sdelphij            BODY_40_59(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15],
479296465Sdelphij                       X[(i + 5) & 15]);
480296465Sdelphij        }
481296465Sdelphij        for (i = 4; i < 24; i++) {
482296465Sdelphij            BODY_60_79(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15],
483296465Sdelphij                       X[(i + 5) & 15]);
484296465Sdelphij        }
485160814Ssimon
486296465Sdelphij        c->h0 = (c->h0 + A) & 0xffffffffL;
487296465Sdelphij        c->h1 = (c->h1 + B) & 0xffffffffL;
488296465Sdelphij        c->h2 = (c->h2 + C) & 0xffffffffL;
489296465Sdelphij        c->h3 = (c->h3 + D) & 0xffffffffL;
490296465Sdelphij        c->h4 = (c->h4 + E) & 0xffffffffL;
491160814Ssimon
492296465Sdelphij        if (--num == 0)
493296465Sdelphij            break;
494160814Ssimon
495296465Sdelphij        A = c->h0;
496296465Sdelphij        B = c->h1;
497296465Sdelphij        C = c->h2;
498296465Sdelphij        D = c->h3;
499296465Sdelphij        E = c->h4;
500160814Ssimon
501296465Sdelphij    }
502296465Sdelphij}
503296465Sdelphij# endif
504296465Sdelphij
505160814Ssimon#endif
506