fix reset handling
[gnuk/neug.git] / src / sha256.c
1 /*
2  * sha256.c -- Compute SHA-256 hash
3  *
4  * Just for little endian architecture.
5  *
6  * Code taken from:
7  *  http://gladman.plushost.co.uk/oldsite/cryptography_technology/sha/index.php
8  *
9  *  File names are sha2.c, sha2.h, brg_types.h, brg_endian.h
10  *  in the archive sha2-07-01-07.zip.
11  *
12  * Code is modified in the style of PolarSSL API.
13  *
14  * See original copyright notice below.
15  */
16 /*
17  ---------------------------------------------------------------------------
18  Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.
19
20  LICENSE TERMS
21
22  The free distribution and use of this software in both source and binary
23  form is allowed (with or without changes) provided that:
24
25    1. distributions of this source code include the above copyright
26       notice, this list of conditions and the following disclaimer;
27
28    2. distributions in binary form include the above copyright
29       notice, this list of conditions and the following disclaimer
30       in the documentation and/or other associated materials;
31
32    3. the copyright holder's name is not used to endorse products
33       built using this software without specific written permission.
34
35  ALTERNATIVELY, provided that this notice is retained in full, this product
36  may be distributed under the terms of the GNU General Public License (GPL),
37  in which case the provisions of the GPL apply INSTEAD OF those given above.
38
39  DISCLAIMER
40
41  This software is provided 'as is' with no explicit or implied warranties
42  in respect of its properties, including, but not limited to, correctness
43  and/or fitness for purpose.
44  ---------------------------------------------------------------------------
45  Issue Date: 01/08/2005
46 */
47
48 #include <string.h>
49 #include <stdint.h>
50 #include <stdlib.h>
51 #include "sha256.h"
52
53 #define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
54
55 static void memcpy_bswap32 (void *dst, const uint32_t *p, int n)
56 {
57   uint32_t *q = (uint32_t *)dst;
58
59   n >>= 2;
60   while (n--)
61     q[n] = __builtin_bswap32 (p[n]); /* bswap32 is GCC extention */
62 }
63
64 #define rotr32(x,n)   (((x) >> n) | ((x) << (32 - n)))
65
66 #define ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))
67 #define maj(x,y,z)      (((x) & (y)) | ((z) & ((x) ^ (y))))
68
69 /* round transforms for SHA256 compression functions */
70 #define vf(n,i) v[(n - i) & 7]
71
72 #define hf(i) (p[i & 15] += \
73     g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15]))
74
75 #define v_cycle0(i)                                 \
76     p[i] = __builtin_bswap32 (p[i]);                \
77     vf(7,i) += p[i] + k_0[i]                        \
78     + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i));   \
79     vf(3,i) += vf(7,i);                             \
80     vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i))
81
82 #define v_cycle(i, j)                               \
83     vf(7,i) += hf(i) + k_0[i+j]                     \
84     + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i));   \
85     vf(3,i) += vf(7,i);                             \
86     vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i))
87
88 #define s_0(x)  (rotr32((x),  2) ^ rotr32((x), 13) ^ rotr32((x), 22))
89 #define s_1(x)  (rotr32((x),  6) ^ rotr32((x), 11) ^ rotr32((x), 25))
90 #define g_0(x)  (rotr32((x),  7) ^ rotr32((x), 18) ^ ((x) >>  3))
91 #define g_1(x)  (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))
92 #define k_0     k256
93
94 static const uint32_t k256[64] = {
95   0X428A2F98, 0X71374491, 0XB5C0FBCF, 0XE9B5DBA5,
96   0X3956C25B, 0X59F111F1, 0X923F82A4, 0XAB1C5ED5,
97   0XD807AA98, 0X12835B01, 0X243185BE, 0X550C7DC3,
98   0X72BE5D74, 0X80DEB1FE, 0X9BDC06A7, 0XC19BF174,
99   0XE49B69C1, 0XEFBE4786, 0X0FC19DC6, 0X240CA1CC,
100   0X2DE92C6F, 0X4A7484AA, 0X5CB0A9DC, 0X76F988DA,
101   0X983E5152, 0XA831C66D, 0XB00327C8, 0XBF597FC7,
102   0XC6E00BF3, 0XD5A79147, 0X06CA6351, 0X14292967,
103   0X27B70A85, 0X2E1B2138, 0X4D2C6DFC, 0X53380D13,
104   0X650A7354, 0X766A0ABB, 0X81C2C92E, 0X92722C85,
105   0XA2BFE8A1, 0XA81A664B, 0XC24B8B70, 0XC76C51A3,
106   0XD192E819, 0XD6990624, 0XF40E3585, 0X106AA070,
107   0X19A4C116, 0X1E376C08, 0X2748774C, 0X34B0BCB5,
108   0X391C0CB3, 0X4ED8AA4A, 0X5B9CCA4F, 0X682E6FF3,
109   0X748F82EE, 0X78A5636F, 0X84C87814, 0X8CC70208,
110   0X90BEFFFA, 0XA4506CEB, 0XBEF9A3F7, 0XC67178F2,
111 };
112
113 void
114 sha256_process (sha256_context *ctx)
115 {
116   uint32_t i;
117   uint32_t *p = ctx->wbuf;
118   uint32_t v[8];
119
120   memcpy (v, ctx->state, 8 * sizeof (uint32_t));
121
122   v_cycle0 ( 0); v_cycle0 ( 1); v_cycle0 ( 2); v_cycle0 ( 3);
123   v_cycle0 ( 4); v_cycle0 ( 5); v_cycle0 ( 6); v_cycle0 ( 7);
124   v_cycle0 ( 8); v_cycle0 ( 9); v_cycle0 (10); v_cycle0 (11);
125   v_cycle0 (12); v_cycle0 (13); v_cycle0 (14); v_cycle0 (15);
126
127   for (i = 16; i < 64; i += 16)
128     {
129       v_cycle ( 0, i); v_cycle ( 1, i); v_cycle ( 2, i); v_cycle ( 3, i);
130       v_cycle ( 4, i); v_cycle ( 5, i); v_cycle ( 6, i); v_cycle ( 7, i);
131       v_cycle ( 8, i); v_cycle ( 9, i); v_cycle (10, i); v_cycle (11, i);
132       v_cycle (12, i); v_cycle (13, i); v_cycle (14, i); v_cycle (15, i);
133     }
134
135   ctx->state[0] += v[0];
136   ctx->state[1] += v[1];
137   ctx->state[2] += v[2];
138   ctx->state[3] += v[3];
139   ctx->state[4] += v[4];
140   ctx->state[5] += v[5];
141   ctx->state[6] += v[6];
142   ctx->state[7] += v[7];
143 }
144
145 void
146 sha256_update (sha256_context *ctx, const unsigned char *input,
147                unsigned int ilen)
148 {
149   uint32_t left = (ctx->total[0] & SHA256_MASK);
150   uint32_t fill = SHA256_BLOCK_SIZE - left;
151
152   ctx->total[0] += ilen;
153   if (ctx->total[0] < ilen)
154     ctx->total[1]++;
155
156   while (ilen >= fill)
157     {
158       memcpy (((unsigned char*)ctx->wbuf) + left, input, fill);
159       sha256_process (ctx);
160       input += fill;
161       ilen -= fill;
162       left = 0;
163       fill = SHA256_BLOCK_SIZE;
164     }
165
166   memcpy (((unsigned char*)ctx->wbuf) + left, input, ilen);
167 }
168
169 void
170 sha256_finish (sha256_context *ctx, unsigned char output[32])
171 {
172   uint32_t last = (ctx->total[0] & SHA256_MASK);
173
174   ctx->wbuf[last >> 2] = __builtin_bswap32 (ctx->wbuf[last >> 2]);
175   ctx->wbuf[last >> 2] &= 0xffffff80 << (8 * (~last & 3));
176   ctx->wbuf[last >> 2] |= 0x00000080 << (8 * (~last & 3));
177   ctx->wbuf[last >> 2] = __builtin_bswap32 (ctx->wbuf[last >> 2]);
178
179   if (last > SHA256_BLOCK_SIZE - 9)
180     {
181       if (last < 60)
182         ctx->wbuf[15] = 0;
183       sha256_process (ctx);
184       last = 0;
185     }
186   else
187     last = (last >> 2) + 1;
188
189   while (last < 14)
190     ctx->wbuf[last++] = 0;
191
192   ctx->wbuf[14] = __builtin_bswap32 ((ctx->total[0] >> 29) | (ctx->total[1] << 3));
193   ctx->wbuf[15] = __builtin_bswap32 (ctx->total[0] << 3);
194   sha256_process (ctx);
195
196   memcpy_bswap32 (output, ctx->state, SHA256_DIGEST_SIZE);
197   memset (ctx, 0, sizeof (sha256_context));
198 }
199
200 const uint32_t initial_state[8] =
201 {
202   0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
203   0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
204 };
205
206 void
207 sha256_start (sha256_context *ctx)
208 {
209   ctx->total[0] = ctx->total[1] = 0;
210   memcpy (ctx->state, initial_state, 8 * sizeof(uint32_t));
211 }
212
213 void
214 sha256 (const unsigned char *input, unsigned int ilen,
215         unsigned char output[32])
216 {
217   sha256_context ctx;
218
219   sha256_start (&ctx);
220   sha256_update (&ctx, input, ilen);
221   sha256_finish (&ctx, output);
222 }