tizen 2.3 release
[framework/system/deviced.git] / src / icd / sha2.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 /*
17  * FILE:        sha2.c
18  * AUTHOR:      Aaron D. Gifford <me@aarongifford.com>
19  *
20  * A licence was granted to the ASF by Aaron on 4 November 2003.
21  */
22 #include <string.h>
23 #include <unistd.h>
24 #include "sha2.h"
25
26 //#define UINT64_C(x) x##ULL
27
28 /*** SHA-256/384/512 Various Length Definitions ***********************/
29 #define SECKM_SHA256_SHORT_BLOCK_LENGTH       (SECKM_SHA256_BLOCK_LENGTH - 8)
30
31 /*** ENDIAN REVERSAL MACROS *******************************************/
32 #define REVERSE32(w,x)  { \
33         sha2_word32 tmp = (w); \
34         tmp = (tmp >> 16) | (tmp << 16); \
35         (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
36 }
37 #define REVERSE64(w,x)  { \
38         sha2_word64 tmp = (w); \
39         tmp = (tmp >> 32) | (tmp << 32); \
40         tmp = ((tmp & UINT64_C(0xff00ff00ff00ff00)) >> 8) | \
41               ((tmp & UINT64_C(0x00ff00ff00ff00ff)) << 8); \
42         (x) = ((tmp & UINT64_C(0xffff0000ffff0000)) >> 16) | \
43               ((tmp & UINT64_C(0x0000ffff0000ffff)) << 16); \
44 }
45
46 /*** SHA-256/384/512 Machine Architecture Definitions *****************/
47 typedef unsigned char   sha2_byte;         /* Exactly 1 byte */
48 typedef uint32_t sha2_word32; /* Exactly 4 bytes */
49 typedef uint64_t sha2_word64; /* Exactly 8 bytes */
50
51 /*
52  * Macro for incrementally adding the unsigned 64-bit integer n to the
53  * unsigned 128-bit integer (represented using a two-element array of
54  * 64-bit words):
55  */
56 #define ADDINC128(w,n)  { \
57         (w)[0] += (sha2_word64)(n); \
58         if ((w)[0] < (n)) { \
59                 (w)[1]++; \
60         } \
61 }
62
63 #define MEMSET_BZERO(p,l)       memset((p), 0, (l))
64 #define MEMCPY_BCOPY(d,s,l)     memcpy((d), (s), (l))
65
66 /*** THE SIX LOGICAL FUNCTIONS ****************************************/
67 /*
68  * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
69  *
70  *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
71  *   S is a ROTATION) because the SHA-256/384/512 description document
72  *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
73  *   same "backwards" definition.
74  */
75 /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
76 #define R(b,x)          ((x) >> (b))
77 /* 32-bit Rotate-right (used in SHA-256): */
78 #define S32(b,x)        (((x) >> (b)) | ((x) << (32 - (b))))
79 /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
80 #define S64(b,x)        (((x) >> (b)) | ((x) << (64 - (b))))
81
82 /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
83 #define Ch(x,y,z)       (((x) & (y)) ^ ((~(x)) & (z)))
84 #define Maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
85
86 /* Four of six logical functions used in SHA-256: */
87 #define Sigma0_256(x)   (S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
88 #define Sigma1_256(x)   (S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
89 #define sigma0_256(x)   (S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
90 #define sigma1_256(x)   (S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
91
92 /* Four of six logical functions used in SHA-384 and SHA-512: */
93 #define Sigma0_512(x)   (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
94 #define Sigma1_512(x)   (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
95 #define sigma0_512(x)   (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
96 #define sigma1_512(x)   (S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
97
98 /*** INTERNAL FUNCTION PROTOTYPES *************************************/
99 /* NOTE: These should not be accessed directly from outside this
100  * library -- they are intended for private internal visibility/use
101  * only.
102  */
103 void SECKM_SHA256_Transform(SECKM_SHA256_CTX*, const sha2_word32*);
104
105 /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
106 /* Hash constant words K for SHA-256: */
107 static const sha2_word32 K256[64] =
108 { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
109         0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
110         0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
111         0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
112         0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
113         0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
114         0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
115         0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
116         0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
117         0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
118         0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
119         0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
120         0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL };
121
122 /* Initial hash value H for SHA-256: */
123 static const sha2_word32 SECKM_SHA256_initial_hash_value[8] =
124 { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 0x510e527fUL,
125         0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL };
126
127 /*** SHA-256: *********************************************************/
128 void SECKM_SHA256_Init(SECKM_SHA256_CTX* context)
129 {
130     if (context == (SECKM_SHA256_CTX*) 0)
131     {
132         return;
133     }
134     MEMCPY_BCOPY(context->state, SECKM_SHA256_initial_hash_value, SECKM_SHA256_DIGEST_LENGTH);
135     MEMSET_BZERO(context->buffer, SECKM_SHA256_BLOCK_LENGTH);
136     context->bitcount = 0;
137 }
138
139 void SECKM_SHA256_Transform(SECKM_SHA256_CTX* context, const sha2_word32* data)
140 {
141     sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
142     sha2_word32 T1, T2, *W256;
143     int j;
144
145     W256 = (sha2_word32*) context->buffer;
146
147     /* Initialize registers with the prev. intermediate value */
148     a = context->state[0];
149     b = context->state[1];
150     c = context->state[2];
151     d = context->state[3];
152     e = context->state[4];
153     f = context->state[5];
154     g = context->state[6];
155     h = context->state[7];
156
157     j = 0;
158     do
159     {
160         /* Copy data while converting to host byte order */
161         REVERSE32(*data++,W256[j]);
162         /* Apply the SHA-256 compression function to update a..h */
163         T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
164         T2 = Sigma0_256(a) + Maj(a, b, c);
165         h = g;
166         g = f;
167         f = e;
168         e = d + T1;
169         d = c;
170         c = b;
171         b = a;
172         a = T1 + T2;
173
174         j++;
175     } while (j < 16);
176
177     do
178     {
179         /* Part of the message block expansion: */
180         s0 = W256[(j + 1) & 0x0f];
181         s0 = sigma0_256(s0);
182         s1 = W256[(j + 14) & 0x0f];
183         s1 = sigma1_256(s1);
184
185         /* Apply the SHA-256 compression function to update a..h */
186         T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j & 0x0f] += s1
187                 + W256[(j + 9) & 0x0f] + s0);
188         T2 = Sigma0_256(a) + Maj(a, b, c);
189         h = g;
190         g = f;
191         f = e;
192         e = d + T1;
193         d = c;
194         c = b;
195         b = a;
196         a = T1 + T2;
197
198         j++;
199     } while (j < 64);
200
201     /* Compute the current intermediate hash value */
202     context->state[0] += a;
203     context->state[1] += b;
204     context->state[2] += c;
205     context->state[3] += d;
206     context->state[4] += e;
207     context->state[5] += f;
208     context->state[6] += g;
209     context->state[7] += h;
210
211     /* Clean up */
212     a = b = c = d = e = f = g = h = T1 = T2 = 0;
213 }
214
215 void SECKM_SHA256_Update(SECKM_SHA256_CTX* context, const sha2_byte *data, size_t len)
216 {
217     unsigned int freespace, usedspace;
218
219     if (len == 0)
220     {
221         /* Calling with no data is valid - we do nothing */
222         return;
223     }
224
225     /* Sanity check: */
226     if (context == (SECKM_SHA256_CTX*) 0 || data == (sha2_byte*) 0)
227         return;
228
229     usedspace = (unsigned int) ((context->bitcount >> 3) % SECKM_SHA256_BLOCK_LENGTH);
230     if (usedspace > 0)
231     {
232         /* Calculate how much free space is available in the buffer */
233         freespace = SECKM_SHA256_BLOCK_LENGTH - usedspace;
234
235         if (len >= freespace)
236         {
237             /* Fill the buffer completely and process it */
238             MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
239             context->bitcount += freespace << 3;
240             len -= freespace;
241             data += freespace;
242             SECKM_SHA256_Transform(context, (sha2_word32*) context->buffer);
243         }
244         else
245         {
246             /* The buffer is not yet full */
247             MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
248             context->bitcount += len << 3;
249             /* Clean up: */
250             usedspace = freespace = 0;
251             return;
252         }
253     }
254     while (len >= SECKM_SHA256_BLOCK_LENGTH)
255     {
256         /* Process as many complete blocks as we can */
257         SECKM_SHA256_Transform(context, (sha2_word32*) data);
258         context->bitcount += SECKM_SHA256_BLOCK_LENGTH << 3;
259         len -= SECKM_SHA256_BLOCK_LENGTH;
260         data += SECKM_SHA256_BLOCK_LENGTH;
261     }
262     if (len > 0)
263     {
264         /* There's left-overs, so save 'em */
265         MEMCPY_BCOPY(context->buffer, data, len);
266         context->bitcount += len << 3;
267     }
268     /* Clean up: */
269     usedspace = freespace = 0;
270 }
271
272 void SECKM_SHA256_Final(SECKM_SHA256_CTX* context, sha2_byte digest[])
273 {
274     sha2_word32 *d = (sha2_word32*) digest;
275     unsigned int usedspace;
276
277     /* Sanity check: */
278     if (context == (SECKM_SHA256_CTX*) 0)
279         return;
280
281     /* If no digest buffer is passed, we don't bother doing this: */
282     if (digest != (sha2_byte*) 0)
283     {
284         usedspace = (unsigned int) ((context->bitcount >> 3)
285                 % SECKM_SHA256_BLOCK_LENGTH);
286         /* Convert FROM host byte order */
287         REVERSE64(context->bitcount,context->bitcount);
288
289         if (usedspace > 0)
290         {
291             /* Begin padding with a 1 bit: */
292             context->buffer[usedspace++] = 0x80;
293
294             if (usedspace <= SECKM_SHA256_SHORT_BLOCK_LENGTH)
295             {
296                 /* Set-up for the last transform: */
297                 MEMSET_BZERO(&context->buffer[usedspace], SECKM_SHA256_SHORT_BLOCK_LENGTH - usedspace);
298             }
299             else
300             {
301                 if (usedspace < SECKM_SHA256_BLOCK_LENGTH)
302                 {
303                     MEMSET_BZERO(&context->buffer[usedspace], SECKM_SHA256_BLOCK_LENGTH - usedspace);
304                 }
305                 /* Do second-to-last transform: */
306                 SECKM_SHA256_Transform(context, (sha2_word32*) context->buffer);
307
308                 /* And set-up for the last transform: */
309                 MEMSET_BZERO(context->buffer, SECKM_SHA256_SHORT_BLOCK_LENGTH);
310             }
311         }
312         else
313         {
314             /* Set-up for the last transform: */
315             MEMSET_BZERO(context->buffer, SECKM_SHA256_SHORT_BLOCK_LENGTH);
316
317             /* Begin padding with a 1 bit: */
318             *context->buffer = 0x80;
319         }
320         /* Set the bit count: */
321         *(sha2_word64*) &context->buffer[SECKM_SHA256_SHORT_BLOCK_LENGTH]
322                 = context->bitcount;
323
324         /* Final transform: */
325         SECKM_SHA256_Transform(context, (sha2_word32*) context->buffer);
326
327         {
328             /* Convert TO host byte order */
329             int j;
330             for (j = 0; j < 8; j++)
331             {
332                 REVERSE32(context->state[j],context->state[j]);
333                 *d++ = context->state[j];
334             }
335         }
336     }
337
338     /* Clean up state data: */
339     MEMSET_BZERO(context, sizeof(*context));
340     usedspace = 0;
341 }
342
343 #ifdef FIPS_MODE
344
345 struct sha_testvec {
346         unsigned char *plaintext;
347         unsigned char *digest;
348         unsigned char psize;
349 };
350
351 /*
352  * SHA256 test vectors from from NIST
353  */
354 #define SHA256_TEST_VECTORS     1
355
356 static struct sha_testvec SHA256_tv[] = {
357         {
358                 .plaintext = (unsigned char *) "abc",
359                 .psize  = 3,
360                 .digest = (unsigned char *)
361                           "\xba\x78\x16\xbf\x8f\x01\xcf\xea"
362                           "\x41\x41\x40\xde\x5d\xae\x22\x23"
363                           "\xb0\x03\x61\xa3\x96\x17\x7a\x9c"
364                           "\xb4\x10\xff\x61\xf2\x00\x15\xad",
365         },
366         {
367                 .plaintext = "\x3b\xc4\x10\xe5\xef\x25\xb2\xea\x5b\xb0\xe5\x15\xc9\xd6\x64\x07\xe9\xd6\x82\x96\xc6\xe1\xbd\x14\xf9\x7b\x95\xd4\x1c\x24\x9f\xeb\x82\x38\xd5\x34\x25\x14\x30\x97\xe0\x7a\x79\x8a\xdf\x37\x5c\xd7\x53\x02\xbe\xa0\x6a\xa8\x50\xa1\x7e\x66\x64\xb6\x8d\x96",
368                 .psize  = 62,
369                 .digest = "\x56\x4a\x57\xf4\xda\xa0\xcb\x7d\x2e\xef\x3d\x4c\x2e\xb1\xed\x29\xfd\xb6\xe9\xe8\x8e\x35\x62\x3c\x0e\x30\x8c\xb9\x10\xa8\x7d\xce",
370         },
371         {
372                 .plaintext = "\xef\x1a\x07\x28\x77\x22\x4d\x78\x67\xf8\x1c\x57\x21\x01\x92\x80\x46\xf3\xdf\x6f\x32\x44\xef\x74\xc5\xe3\x4a\x07\x69\x25\x38\x5b\x50\x02\x28\x36\xfe\x81\x52\xff\x08\x71\x9c\x19\x1b\x5a\xba\x6f\x3f\xb3\x9a\x50\x5d\x55\xff\x7e\xff\x30\x6c\x81\x58\x3d\x43",
373                 .psize  = 63,
374                 .digest = "\x69\x16\xf3\x45\xa6\x92\x0c\xc3\x13\xa8\xbe\xc7\x63\x55\x4c\x64\xbb\xbc\x78\x28\x07\xae\x4c\x78\x1f\xda\x6e\x48\xcd\x1c\x49\x1a",
375         },
376         {
377                 .plaintext = "\xc3\x11\xf1\x64\x83\xb3\xad\x91\x21\xa9\x99\xa3\xa5\x2f\x12\x58\x63\x96\x33\x2f\x73\xea\xeb\x28\x62\xd3\x53\xcb\x27\xb9\x3f\x6b\x59\x2b\x14\xac\x9f\x82\xd9\x43\x67\xc1\x90\xfd\xdb\xc0\xc6\x03\x10\x8a\x69\x5c\x81\x03\xda\xb3\xbd\xce\x43\x5b\x5c\x6d\x2b\x90",
378                 .psize  = 64,
379                 .digest = "\xa1\xf3\x34\xef\x0e\x59\x88\x90\x65\x48\x0d\xdf\x16\x47\x8f\xd3\xdf\xc3\x0f\xea\x33\xe7\x80\x92\xfe\x1e\x08\x85\x0b\xed\xb9\xea",
380         },
381 };
382
383 /* Self Tests SHA256; Please refer to test_vectors.h for the data structures and test vectors used
384  * Returns:
385  *    0 - all tests passed
386  *    1...SHA256_TEST_VECTORS - error (and corresponding test vector number, 1-based)
387  */
388 int SECKM_SHA2_selftest (void) {
389         int        i;
390     SECKM_SHA256_CTX ctx;
391     unsigned char output[SECKM_SHA256_DIGEST_LENGTH];
392
393         for (i = 0; i < SHA256_TEST_VECTORS; i++ ) {
394         SECKM_SHA256_Init(&ctx);
395         SECKM_SHA256_Update(&ctx, SHA256_tv[i].plaintext, SHA256_tv[i].psize);
396         SECKM_SHA256_Final(&ctx, output);
397
398                 if (memcmp(output, SHA256_tv[i].digest, SECKM_SHA256_DIGEST_LENGTH)) {
399                         LOG_KM ("SHA2 Selftest failed: %d\n", i+1);
400                         return i+1;
401                 }
402         }
403         return 0;
404 }
405
406 #endif /* FIPS_MODE */