]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/WolfSSL/ctaocrypt/src/sha256.c
Rename the CyaSSL directory to WolfSSL
[freertos] / FreeRTOS-Plus / Source / WolfSSL / ctaocrypt / src / sha256.c
1 /* sha256.c
2  *
3  * Copyright (C) 2006-2014 wolfSSL Inc.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22
23 /* code submitted by raphael.huck@efixo.com */
24
25 #ifdef HAVE_CONFIG_H
26     #include <config.h>
27 #endif
28
29 #include <cyassl/ctaocrypt/settings.h>
30
31 #if !defined(NO_SHA256)
32
33 #ifdef CYASSL_PIC32MZ_HASH
34 #define InitSha256   InitSha256_sw
35 #define Sha256Update Sha256Update_sw
36 #define Sha256Final  Sha256Final_sw
37 #endif
38
39 #ifdef HAVE_FIPS
40     /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
41     #define FIPS_NO_WRAPPERS
42 #endif
43
44 #include <cyassl/ctaocrypt/sha256.h>
45 #include <cyassl/ctaocrypt/logging.h>
46 #include <cyassl/ctaocrypt/error-crypt.h>
47
48 #ifdef NO_INLINE
49     #include <cyassl/ctaocrypt/misc.h>
50 #else
51     #include <ctaocrypt/src/misc.c>
52 #endif
53
54 #ifdef FREESCALE_MMCAU
55     #include "cau_api.h"
56 #endif
57
58 #ifndef min
59
60     static INLINE word32 min(word32 a, word32 b)
61     {
62         return a > b ? b : a;
63     }
64
65 #endif /* min */
66
67
68 int InitSha256(Sha256* sha256)
69 {
70     #ifdef FREESCALE_MMCAU
71         cau_sha256_initialize_output(sha256->digest);
72     #else
73         sha256->digest[0] = 0x6A09E667L;
74         sha256->digest[1] = 0xBB67AE85L;
75         sha256->digest[2] = 0x3C6EF372L;
76         sha256->digest[3] = 0xA54FF53AL;
77         sha256->digest[4] = 0x510E527FL;
78         sha256->digest[5] = 0x9B05688CL;
79         sha256->digest[6] = 0x1F83D9ABL;
80         sha256->digest[7] = 0x5BE0CD19L;
81     #endif
82
83     sha256->buffLen = 0;
84     sha256->loLen   = 0;
85     sha256->hiLen   = 0;
86
87     return 0;
88 }
89
90 #ifdef FREESCALE_MMCAU
91     #define XTRANSFORM(S,B)  Transform((S), (B))
92
93 static int Transform(Sha256* sha256, byte* buf)
94 {
95     cau_sha256_hash_n(buf, 1, sha256->digest);
96
97     return 0;
98 }
99
100 #else
101     #define XTRANSFORM(S,B)  Transform((S))
102
103 static const word32 K[64] = {
104     0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
105     0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
106     0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L,
107     0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL,
108     0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L,
109     0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L,
110     0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL,
111     0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L,
112     0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L,
113     0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L,
114     0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL,
115     0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L,
116     0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L
117 };
118
119 #define Ch(x,y,z)       (z ^ (x & (y ^ z)))
120 #define Maj(x,y,z)      (((x | y) & z) | (x & y))
121 #define S(x, n)         rotrFixed(x, n)
122 #define R(x, n)         (((x)&0xFFFFFFFFU)>>(n))
123 #define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
124 #define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
125 #define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
126 #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
127
128 #define RND(a,b,c,d,e,f,g,h,i) \
129      t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
130      t1 = Sigma0(a) + Maj(a, b, c); \
131      d += t0; \
132      h  = t0 + t1;
133
134
135 static int Transform(Sha256* sha256)
136 {
137     word32 S[8], t0, t1;
138     int i;
139
140 #ifdef CYASSL_SMALL_STACK
141     word32* W;
142
143     W = (word32*) XMALLOC(sizeof(word32) * 64, NULL, DYNAMIC_TYPE_TMP_BUFFER);
144     if (W == NULL)
145         return MEMORY_E;
146 #else
147     word32 W[64];
148 #endif
149
150     /* Copy context->state[] to working vars */
151     for (i = 0; i < 8; i++)
152         S[i] = sha256->digest[i];
153
154     for (i = 0; i < 16; i++)
155         W[i] = sha256->buffer[i];
156
157     for (i = 16; i < 64; i++)
158         W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16];
159
160     for (i = 0; i < 64; i += 8) {
161         RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
162         RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
163         RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
164         RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
165         RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
166         RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
167         RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
168         RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
169     }
170
171     /* Add the working vars back into digest state[] */
172     for (i = 0; i < 8; i++) {
173         sha256->digest[i] += S[i];
174     }
175
176 #ifdef CYASSL_SMALL_STACK
177     XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
178 #endif
179
180     return 0;
181 }
182
183 #endif /* FREESCALE_MMCAU */
184
185
186 static INLINE void AddLength(Sha256* sha256, word32 len)
187 {
188     word32 tmp = sha256->loLen;
189     if ( (sha256->loLen += len) < tmp)
190         sha256->hiLen++;                       /* carry low to high */
191 }
192
193
194 int Sha256Update(Sha256* sha256, const byte* data, word32 len)
195 {
196     /* do block size increments */
197     byte* local = (byte*)sha256->buffer;
198
199     while (len) {
200         word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen);
201         XMEMCPY(&local[sha256->buffLen], data, add);
202
203         sha256->buffLen += add;
204         data            += add;
205         len             -= add;
206
207         if (sha256->buffLen == SHA256_BLOCK_SIZE) {
208             int ret;
209
210             #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
211                 ByteReverseWords(sha256->buffer, sha256->buffer,
212                                  SHA256_BLOCK_SIZE);
213             #endif
214
215             ret = XTRANSFORM(sha256, local);
216             if (ret != 0)
217                 return ret;
218
219             AddLength(sha256, SHA256_BLOCK_SIZE);
220             sha256->buffLen = 0;
221         }
222     }
223
224     return 0;
225 }
226
227
228 int Sha256Final(Sha256* sha256, byte* hash)
229 {
230     byte* local = (byte*)sha256->buffer;
231     int ret;
232
233     AddLength(sha256, sha256->buffLen);  /* before adding pads */
234
235     local[sha256->buffLen++] = 0x80;     /* add 1 */
236
237     /* pad with zeros */
238     if (sha256->buffLen > SHA256_PAD_SIZE) {
239         XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen);
240         sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen;
241
242         #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
243             ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE);
244         #endif
245
246         ret = XTRANSFORM(sha256, local);
247         if (ret != 0)
248             return ret;
249
250         sha256->buffLen = 0;
251     }
252     XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen);
253
254     /* put lengths in bits */
255     sha256->hiLen = (sha256->loLen >> (8*sizeof(sha256->loLen) - 3)) +
256                  (sha256->hiLen << 3);
257     sha256->loLen = sha256->loLen << 3;
258
259     /* store lengths */
260     #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
261         ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE);
262     #endif
263     /* ! length ordering dependent on digest endian type ! */
264     XMEMCPY(&local[SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32));
265     XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
266             sizeof(word32));
267
268     #ifdef FREESCALE_MMCAU
269         /* Kinetis requires only these bytes reversed */
270         ByteReverseWords(&sha256->buffer[SHA256_PAD_SIZE/sizeof(word32)],
271                          &sha256->buffer[SHA256_PAD_SIZE/sizeof(word32)],
272                          2 * sizeof(word32));
273     #endif
274
275     ret = XTRANSFORM(sha256, local);
276     if (ret != 0)
277         return ret;
278
279     #ifdef LITTLE_ENDIAN_ORDER
280         ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE);
281     #endif
282     XMEMCPY(hash, sha256->digest, SHA256_DIGEST_SIZE);
283
284     return InitSha256(sha256);  /* reset state */
285 }
286
287
288 int Sha256Hash(const byte* data, word32 len, byte* hash)
289 {
290     int ret = 0;
291 #ifdef CYASSL_SMALL_STACK
292     Sha256* sha256;
293 #else
294     Sha256 sha256[1];
295 #endif
296
297 #ifdef CYASSL_SMALL_STACK
298     sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL, DYNAMIC_TYPE_TMP_BUFFER);
299     if (sha256 == NULL)
300         return MEMORY_E;
301 #endif
302
303     if ((ret = InitSha256(sha256)) != 0) {
304         CYASSL_MSG("InitSha256 failed");
305     }
306     else if ((ret = Sha256Update(sha256, data, len)) != 0) {
307         CYASSL_MSG("Sha256Update failed");
308     }
309     else if ((ret = Sha256Final(sha256, hash)) != 0) {
310         CYASSL_MSG("Sha256Final failed");
311     }
312
313 #ifdef CYASSL_SMALL_STACK
314     XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
315 #endif
316
317     return ret;
318 }
319
320
321 #endif /* NO_SHA256 */
322