Add ST_DONGLE and ST_NUCLEO_F103
[gnuk/gnuk.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_output_bswap32 (unsigned char *dst, const uint32_t *p)
56 {
57   int i;
58   uint32_t q = 0;
59
60   for (i = 0; i < 32; i++)
61     {
62       if ((i & 3) == 0)
63         q = __builtin_bswap32 (p[i >> 2]); /* bswap32 is GCC extention */
64       dst[i] = q >> ((i & 3) * 8);
65     }
66 }
67
68 #define rotr32(x,n)   (((x) >> n) | ((x) << (32 - n)))
69
70 #define ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))
71 #define maj(x,y,z)      (((x) & (y)) | ((z) & ((x) ^ (y))))
72
73 /* round transforms for SHA256 compression functions */
74 #define vf(n,i) v[(n - i) & 7]
75
76 #define hf(i) (p[i & 15] += \
77     g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15]))
78
79 #define v_cycle0(i)                                 \
80     p[i] = __builtin_bswap32 (p[i]);                \
81     vf(7,i) += p[i] + k_0[i]                        \
82     + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i));   \
83     vf(3,i) += vf(7,i);                             \
84     vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i))
85
86 #define v_cycle(i, j)                               \
87     vf(7,i) += hf(i) + k_0[i+j]                     \
88     + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i));   \
89     vf(3,i) += vf(7,i);                             \
90     vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i))
91
92 #define s_0(x)  (rotr32((x),  2) ^ rotr32((x), 13) ^ rotr32((x), 22))
93 #define s_1(x)  (rotr32((x),  6) ^ rotr32((x), 11) ^ rotr32((x), 25))
94 #define g_0(x)  (rotr32((x),  7) ^ rotr32((x), 18) ^ ((x) >>  3))
95 #define g_1(x)  (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))
96 #define k_0     k256
97
98 static const uint32_t k256[64] = {
99   0X428A2F98, 0X71374491, 0XB5C0FBCF, 0XE9B5DBA5,
100   0X3956C25B, 0X59F111F1, 0X923F82A4, 0XAB1C5ED5,
101   0XD807AA98, 0X12835B01, 0X243185BE, 0X550C7DC3,
102   0X72BE5D74, 0X80DEB1FE, 0X9BDC06A7, 0XC19BF174,
103   0XE49B69C1, 0XEFBE4786, 0X0FC19DC6, 0X240CA1CC,
104   0X2DE92C6F, 0X4A7484AA, 0X5CB0A9DC, 0X76F988DA,
105   0X983E5152, 0XA831C66D, 0XB00327C8, 0XBF597FC7,
106   0XC6E00BF3, 0XD5A79147, 0X06CA6351, 0X14292967,
107   0X27B70A85, 0X2E1B2138, 0X4D2C6DFC, 0X53380D13,
108   0X650A7354, 0X766A0ABB, 0X81C2C92E, 0X92722C85,
109   0XA2BFE8A1, 0XA81A664B, 0XC24B8B70, 0XC76C51A3,
110   0XD192E819, 0XD6990624, 0XF40E3585, 0X106AA070,
111   0X19A4C116, 0X1E376C08, 0X2748774C, 0X34B0BCB5,
112   0X391C0CB3, 0X4ED8AA4A, 0X5B9CCA4F, 0X682E6FF3,
113   0X748F82EE, 0X78A5636F, 0X84C87814, 0X8CC70208,
114   0X90BEFFFA, 0XA4506CEB, 0XBEF9A3F7, 0XC67178F2,
115 };
116
117 void
118 sha256_process (sha256_context *ctx)
119 {
120   uint32_t i;
121   uint32_t *p = ctx->wbuf;
122   uint32_t v[8];
123
124   memcpy (v, ctx->state, 8 * sizeof (uint32_t));
125
126   v_cycle0 ( 0); v_cycle0 ( 1); v_cycle0 ( 2); v_cycle0 ( 3);
127   v_cycle0 ( 4); v_cycle0 ( 5); v_cycle0 ( 6); v_cycle0 ( 7);
128   v_cycle0 ( 8); v_cycle0 ( 9); v_cycle0 (10); v_cycle0 (11);
129   v_cycle0 (12); v_cycle0 (13); v_cycle0 (14); v_cycle0 (15);
130
131   for (i = 16; i < 64; i += 16)
132     {
133       v_cycle ( 0, i); v_cycle ( 1, i); v_cycle ( 2, i); v_cycle ( 3, i);
134       v_cycle ( 4, i); v_cycle ( 5, i); v_cycle ( 6, i); v_cycle ( 7, i);
135       v_cycle ( 8, i); v_cycle ( 9, i); v_cycle (10, i); v_cycle (11, i);
136       v_cycle (12, i); v_cycle (13, i); v_cycle (14, i); v_cycle (15, i);
137     }
138
139   ctx->state[0] += v[0];
140   ctx->state[1] += v[1];
141   ctx->state[2] += v[2];
142   ctx->state[3] += v[3];
143   ctx->state[4] += v[4];
144   ctx->state[5] += v[5];
145   ctx->state[6] += v[6];
146   ctx->state[7] += v[7];
147 }
148
149 void
150 sha256_update (sha256_context *ctx, const unsigned char *input,
151                unsigned int ilen)
152 {
153   uint32_t left = (ctx->total[0] & SHA256_MASK);
154   uint32_t fill = SHA256_BLOCK_SIZE - left;
155
156   ctx->total[0] += ilen;
157   if (ctx->total[0] < ilen)
158     ctx->total[1]++;
159
160   while (ilen >= fill)
161     {
162       memcpy (((unsigned char*)ctx->wbuf) + left, input, fill);
163       sha256_process (ctx);
164       input += fill;
165       ilen -= fill;
166       left = 0;
167       fill = SHA256_BLOCK_SIZE;
168     }
169
170   memcpy (((unsigned char*)ctx->wbuf) + left, input, ilen);
171 }
172
173 void
174 sha256_finish (sha256_context *ctx, unsigned char output[32])
175 {
176   uint32_t last = (ctx->total[0] & SHA256_MASK);
177
178   ctx->wbuf[last >> 2] = __builtin_bswap32 (ctx->wbuf[last >> 2]);
179   ctx->wbuf[last >> 2] &= 0xffffff80 << (8 * (~last & 3));
180   ctx->wbuf[last >> 2] |= 0x00000080 << (8 * (~last & 3));
181   ctx->wbuf[last >> 2] = __builtin_bswap32 (ctx->wbuf[last >> 2]);
182
183   if (last > SHA256_BLOCK_SIZE - 9)
184     {
185       if (last < 60)
186         ctx->wbuf[15] = 0;
187       sha256_process (ctx);
188       last = 0;
189     }
190   else
191     last = (last >> 2) + 1;
192
193   while (last < 14)
194     ctx->wbuf[last++] = 0;
195
196   ctx->wbuf[14] = __builtin_bswap32 ((ctx->total[0] >> 29) | (ctx->total[1] << 3));
197   ctx->wbuf[15] = __builtin_bswap32 (ctx->total[0] << 3);
198   sha256_process (ctx);
199
200   memcpy_output_bswap32 (output, ctx->state);
201   memset (ctx, 0, sizeof (sha256_context));
202 }
203
204 static const uint32_t initial_state[8] =
205 {
206   0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
207   0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
208 };
209
210 void
211 sha256_start (sha256_context *ctx)
212 {
213   ctx->total[0] = ctx->total[1] = 0;
214   memcpy (ctx->state, initial_state, 8 * sizeof(uint32_t));
215 }
216
217 void
218 sha256 (const unsigned char *input, unsigned int ilen,
219         unsigned char output[32])
220 {
221   sha256_context ctx;
222
223   sha256_start (&ctx);
224   sha256_update (&ctx, input, ilen);
225   sha256_finish (&ctx, output);
226 }