1/* Copyright (c) 1998,2011,2014 Apple Inc.  All Rights Reserved.
2 *
3 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
4 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
5 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE,
7 * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
10 *
11 * ckSHA1_priv.c - low-level SHA-1 hash algorithm.
12 *
13 * Revision History
14 * ----------------
15 * 05 Jan 1998 at Apple
16 *	Created, based on source by Peter C. Gutmann.
17 *	Mods: made reentrant, added NIST fix to expand(), eliminated
18 *	unnecessary copy to local W[] array.
19 */
20
21
22/* NIST proposed Secure Hash Standard.
23
24   Written 2 September 1992, Peter C. Gutmann.
25   This implementation placed in the public domain.
26
27   Comments to pgut1@cs.aukuni.ac.nz */
28
29#include "ckconfig.h"
30
31#if	!CRYPTKIT_LIBMD_DIGEST
32
33#include "ckSHA1_priv.h"
34#include "platform.h"
35#include <string.h>
36
37/* The SHS f()-functions */
38
39#define f1(x,y,z)   ( ( x & y ) | ( ~x & z ) )              /* Rounds  0-19 */
40#define f2(x,y,z)   ( x ^ y ^ z )                           /* Rounds 20-39 */
41#define f3(x,y,z)   ( ( x & y ) | ( x & z ) | ( y & z ) )   /* Rounds 40-59 */
42#define f4(x,y,z)   ( x ^ y ^ z )                           /* Rounds 60-79 */
43
44/* The SHS Mysterious Constants */
45
46#define K1  0x5A827999L     /* Rounds  0-19 */
47#define K2  0x6ED9EBA1L     /* Rounds 20-39 */
48#define K3  0x8F1BBCDCL     /* Rounds 40-59 */
49#define K4  0xCA62C1D6L     /* Rounds 60-79 */
50
51/* SHS initial values */
52
53#define h0init  0x67452301L
54#define h1init  0xEFCDAB89L
55#define h2init  0x98BADCFEL
56#define h3init  0x10325476L
57#define h4init  0xC3D2E1F0L
58
59/* 32-bit rotate - kludged with shifts */
60
61#define S(n,X)  ( ( X << n ) | ( X >> ( 32 - n ) ) )
62
63/* The initial expanding function */
64
65/*
66 * 06 Jan 1998. Added left circular shift per NIST FIPS-180-1 (at
67 * http://www.nist.gov/itl/div897/pubs/fip180-1.htm). Also see
68 * B. Schneier, Applied Cryptography, Second Edition, section 18.7
69 * for info on this addenda to the original NIST spec.
70 */
71#define expand(count) {	\
72    W[count] = W[count - 3] ^ W[count - 8] ^ W[count - 14] ^ W[count - 16]; \
73    W[count] = S(1, W[count]); \
74}
75
76/* The four SHS sub-rounds */
77
78#define subRound1(count)    \
79    { \
80    temp = S( 5, A ) + f1( B, C, D ) + E + W[ count ] + K1; \
81    E = D; \
82    D = C; \
83    C = S( 30, B ); \
84    B = A; \
85    A = temp; \
86    }
87
88#define subRound2(count)    \
89    { \
90    temp = S( 5, A ) + f2( B, C, D ) + E + W[ count ] + K2; \
91    E = D; \
92    D = C; \
93    C = S( 30, B ); \
94    B = A; \
95    A = temp; \
96    }
97
98#define subRound3(count)    \
99    { \
100    temp = S( 5, A ) + f3( B, C, D ) + E + W[ count ] + K3; \
101    E = D; \
102    D = C; \
103    C = S( 30, B ); \
104    B = A; \
105    A = temp; \
106    }
107
108#define subRound4(count)    \
109    { \
110    temp = S( 5, A ) + f4( B, C, D ) + E + W[ count ] + K4; \
111    E = D; \
112    D = C; \
113    C = S( 30, B ); \
114    B = A; \
115    A = temp; \
116    }
117
118/* Initialize the SHS values */
119
120void shsInit( SHS_INFO *shsInfo )
121    {
122    /* Set the h-vars to their initial values */
123    shsInfo->digest[ 0 ] = h0init;
124    shsInfo->digest[ 1 ] = h1init;
125    shsInfo->digest[ 2 ] = h2init;
126    shsInfo->digest[ 3 ] = h3init;
127    shsInfo->digest[ 4 ] = h4init;
128
129    /* Initialise bit count */
130    shsInfo->countLo = shsInfo->countHi = 0L;
131    }
132
133/* Perform the SHS transformation.  Note that this code, like MD5, seems to
134   break some optimizing compilers - it may be necessary to split it into
135   sections, eg based on the four subrounds */
136
137static void shsTransform( SHS_INFO *shsInfo )
138{
139    LONG *W, temp;
140    LONG A, B, C, D, E;
141
142    /* Step A.  Copy the data buffer into the local work buffer. */
143    /* 07 Jan 1998, dmitch: skip this bogus move, and let the caller
144     * copy data directly into the W[] array. To minimize changes,
145     * we'll just increase the size of shsInfo->data[] and make W
146     * a pointer here.
147     */
148    W = shsInfo->data;
149
150    /* Step B.  Expand the 16 words into 64 temporary data words */
151
152    /*
153     * Note: I tried optimizing this via a for loop, and for some reason,
154     * the "optimized" version ran slower on PPC than the original
155     * unrolled version. The optimized version does run faster on i486 than
156     * the unrolled version.
157     *
158     * Similarly, the set of subRounds, below, runs slower on i486 when
159     * optimized via 4 'for' loops. The "optimized" version of that is
160     * a wash on PPC.
161     *
162     * Conclusion: leave both of 'em unrolled. We could ifdef per machine,
163     * but this would get messy once we had more than two architectures.
164     * We may want to revisit this.  --dpm
165     */
166    expand( 16 ); expand( 17 ); expand( 18 ); expand( 19 ); expand( 20 );
167    expand( 21 ); expand( 22 ); expand( 23 ); expand( 24 ); expand( 25 );
168    expand( 26 ); expand( 27 ); expand( 28 ); expand( 29 ); expand( 30 );
169    expand( 31 ); expand( 32 ); expand( 33 ); expand( 34 ); expand( 35 );
170    expand( 36 ); expand( 37 ); expand( 38 ); expand( 39 ); expand( 40 );
171    expand( 41 ); expand( 42 ); expand( 43 ); expand( 44 ); expand( 45 );
172    expand( 46 ); expand( 47 ); expand( 48 ); expand( 49 ); expand( 50 );
173    expand( 51 ); expand( 52 ); expand( 53 ); expand( 54 ); expand( 55 );
174    expand( 56 ); expand( 57 ); expand( 58 ); expand( 59 ); expand( 60 );
175    expand( 61 ); expand( 62 ); expand( 63 ); expand( 64 ); expand( 65 );
176    expand( 66 ); expand( 67 ); expand( 68 ); expand( 69 ); expand( 70 );
177    expand( 71 ); expand( 72 ); expand( 73 ); expand( 74 ); expand( 75 );
178    expand( 76 ); expand( 77 ); expand( 78 ); expand( 79 );
179
180    /* Step C.  Set up first buffer */
181    A = shsInfo->digest[ 0 ];
182    B = shsInfo->digest[ 1 ];
183    C = shsInfo->digest[ 2 ];
184    D = shsInfo->digest[ 3 ];
185    E = shsInfo->digest[ 4 ];
186
187    /* Step D.  Serious mangling, divided into four sub-rounds */
188    subRound1( 0 ); subRound1( 1 ); subRound1( 2 ); subRound1( 3 );
189    subRound1( 4 ); subRound1( 5 ); subRound1( 6 ); subRound1( 7 );
190    subRound1( 8 ); subRound1( 9 ); subRound1( 10 ); subRound1( 11 );
191    subRound1( 12 ); subRound1( 13 ); subRound1( 14 ); subRound1( 15 );
192    subRound1( 16 ); subRound1( 17 ); subRound1( 18 ); subRound1( 19 );
193    subRound2( 20 ); subRound2( 21 ); subRound2( 22 ); subRound2( 23 );
194    subRound2( 24 ); subRound2( 25 ); subRound2( 26 ); subRound2( 27 );
195    subRound2( 28 ); subRound2( 29 ); subRound2( 30 ); subRound2( 31 );
196    subRound2( 32 ); subRound2( 33 ); subRound2( 34 ); subRound2( 35 );
197    subRound2( 36 ); subRound2( 37 ); subRound2( 38 ); subRound2( 39 );
198    subRound3( 40 ); subRound3( 41 ); subRound3( 42 ); subRound3( 43 );
199    subRound3( 44 ); subRound3( 45 ); subRound3( 46 ); subRound3( 47 );
200    subRound3( 48 ); subRound3( 49 ); subRound3( 50 ); subRound3( 51 );
201    subRound3( 52 ); subRound3( 53 ); subRound3( 54 ); subRound3( 55 );
202    subRound3( 56 ); subRound3( 57 ); subRound3( 58 ); subRound3( 59 );
203    subRound4( 60 ); subRound4( 61 ); subRound4( 62 ); subRound4( 63 );
204    subRound4( 64 ); subRound4( 65 ); subRound4( 66 ); subRound4( 67 );
205    subRound4( 68 ); subRound4( 69 ); subRound4( 70 ); subRound4( 71 );
206    subRound4( 72 ); subRound4( 73 ); subRound4( 74 ); subRound4( 75 );
207    subRound4( 76 ); subRound4( 77 ); subRound4( 78 ); subRound4( 79 );
208
209    /* Step E.  Build message digest */
210    shsInfo->digest[ 0 ] += A;
211    shsInfo->digest[ 1 ] += B;
212    shsInfo->digest[ 2 ] += C;
213    shsInfo->digest[ 3 ] += D;
214    shsInfo->digest[ 4 ] += E;
215}
216
217/* __LITTLE_ENDIAN__ is in fact #defined on OS X on  PPC.... */
218//#ifdef __LITTLE_ENDIAN__
219#if 0
220
221/* When run on a little-endian CPU we need to perform byte reversal on an
222   array of longwords.  It is possible to make the code endianness-
223   independant by fiddling around with data at the byte level, but this
224   makes for very slow code, so we rely on the user to sort out endianness
225   at compile time */
226
227static void byteReverse( buffer, byteCount )
228  LONG *buffer;
229  int byteCount;
230
231    {
232    LONG value;
233    int count;
234
235    byteCount /= sizeof( LONG );
236    for( count = 0; count < byteCount; count++ )
237	{
238	value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
239	buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
240	}
241    }
242
243#else	/* __LITTLE_ENDIAN__ */
244
245/*
246 * Nop for big-endian machines
247 */
248#define byteReverse( buffer, byteCount )
249
250#endif /* __LITTLE_ENDIAN__ */
251
252
253/* Update SHS for a block of data.  This code assumes that the buffer size
254   is a multiple of SHS_BLOCKSIZE bytes long, which makes the code a lot
255   more efficient since it does away with the need to handle partial blocks
256   between calls to shsUpdate() */
257
258void shsUpdate(
259  SHS_INFO *shsInfo,
260  const BYTE *buffer,
261  int count)
262
263    {
264    /* Update bitcount */
265    if( ( shsInfo->countLo + ( ( LONG ) count << 3 ) ) < shsInfo->countLo )
266	shsInfo->countHi++; /* Carry from low to high bitCount */
267    shsInfo->countLo += ( ( LONG ) count << 3 );
268    shsInfo->countHi += ( ( LONG ) count >> 29 );
269
270    /* Process data in SHS_BLOCKSIZE chunks */
271    while( count >= SHS_BLOCKSIZE )
272	{
273	memcpy( shsInfo->data, buffer, SHS_BLOCKSIZE );
274	byteReverse( shsInfo->data, SHS_BLOCKSIZE );
275	shsTransform( shsInfo );
276	buffer += SHS_BLOCKSIZE;
277	count -= SHS_BLOCKSIZE;
278	}
279
280    /* Handle any remaining bytes of data.  This should only happen once
281       on the final lot of data */
282    memcpy( shsInfo->data, buffer, count );
283    }
284
285void shsFinal(SHS_INFO *shsInfo)
286    {
287    int count;
288    LONG lowBitcount = shsInfo->countLo, highBitcount = shsInfo->countHi;
289
290    /* Compute number of bytes mod 64 */
291    count = ( int ) ( ( shsInfo->countLo >> 3 ) & 0x3F );
292
293    /* Set the first char of padding to 0x80.  This is safe since there is
294       always at least one byte free */
295    ( ( BYTE * ) shsInfo->data )[ count++ ] = 0x80;
296
297    /* Pad out to 56 mod 64 */
298    if( count > 56 )
299	{
300	/* Two lots of padding:  Pad the first block to 64 bytes */
301	memset( ( BYTE * ) &shsInfo->data + count, 0, 64 - count );
302	byteReverse( shsInfo->data, SHS_BLOCKSIZE );
303	shsTransform( shsInfo );
304
305	/* Now fill the next block with 56 bytes */
306	memset( &shsInfo->data, 0, 56 );
307	}
308    else
309	/* Pad block to 56 bytes */
310	memset( ( BYTE * ) &shsInfo->data + count, 0, 56 - count );
311	byteReverse( shsInfo->data, SHS_BLOCKSIZE );
312
313    /* Append length in bits and transform */
314    shsInfo->data[ 14 ] = highBitcount;
315    shsInfo->data[ 15 ] = lowBitcount;
316
317    shsTransform( shsInfo );
318    byteReverse( shsInfo->data, SHS_DIGESTSIZE );
319    }
320
321#endif	/* CRYPTKIT_LIBMD_DIGEST */
322