summaryrefslogtreecommitdiffabout
path: root/pwmanager/libcrypt/cipher/sha256.c
Unidiff
Diffstat (limited to 'pwmanager/libcrypt/cipher/sha256.c') (more/less context) (show whitespace changes)
-rw-r--r--pwmanager/libcrypt/cipher/sha256.c310
1 files changed, 310 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/cipher/sha256.c b/pwmanager/libcrypt/cipher/sha256.c
new file mode 100644
index 0000000..712c4e0
--- a/dev/null
+++ b/pwmanager/libcrypt/cipher/sha256.c
@@ -0,0 +1,310 @@
1/* sha256.c - SHA256 hash function
2 *Copyright (C) 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21
22/* Test vectors:
23
24 "abc"
25 ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
26
27 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
28 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
29
30 "a" one million times
31 cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
32
33 */
34
35
36#include <config.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <assert.h>
41#include "g10lib.h"
42#include "memory.h"
43#include "bithelp.h"
44#include "cipher.h"
45
46typedef struct {
47 u32 h0,h1,h2,h3,h4,h5,h6,h7;
48 u32 nblocks;
49 byte buf[64];
50 int count;
51} SHA256_CONTEXT;
52
53
54static void
55sha256_init (void *context)
56{
57 SHA256_CONTEXT *hd = context;
58
59 hd->h0 = 0x6a09e667;
60 hd->h1 = 0xbb67ae85;
61 hd->h2 = 0x3c6ef372;
62 hd->h3 = 0xa54ff53a;
63 hd->h4 = 0x510e527f;
64 hd->h5 = 0x9b05688c;
65 hd->h6 = 0x1f83d9ab;
66 hd->h7 = 0x5be0cd19;
67
68 hd->nblocks = 0;
69 hd->count = 0;
70}
71
72
73/*
74 Transform the message X which consists of 16 32-bit-words. See FIPS
75 180-2 for details. */
76#define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */
77#define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */
78#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */
79#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */
80#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
81#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
82#define R(a,b,c,d,e,f,g,h,k,w) do \
83 { \
84 t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
85 t2 = Sum0((a)) + Maj((a),(b),(c)); \
86 h = g; \
87 g = f; \
88 f = e; \
89 e = d + t1; \
90 d = c; \
91 c = b; \
92 b = a; \
93 a = t1 + t2; \
94 } while (0)
95
96static void
97transform (SHA256_CONTEXT *hd, byte *data)
98{
99 static const u32 K[64] = {
100 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
101 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
102 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
103 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
104 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
105 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
106 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
107 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
108 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
109 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
110 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
111 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
112 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
113 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
114 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
115 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
116 };
117
118 u32 a,b,c,d,e,f,g,h,t1,t2;
119 u32 x[16];
120 u32 w[64];
121 int i;
122
123 a = hd->h0;
124 b = hd->h1;
125 c = hd->h2;
126 d = hd->h3;
127 e = hd->h4;
128 f = hd->h5;
129 g = hd->h6;
130 h = hd->h7;
131
132#ifdef WORDS_BIGENDIAN
133 memcpy (x, data, 64);
134#else
135 {
136 byte *p2;
137
138 for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 )
139 {
140 p2[3] = *data++;
141 p2[2] = *data++;
142 p2[1] = *data++;
143 p2[0] = *data++;
144 }
145 }
146#endif
147
148 for (i=0; i < 16; i++)
149 w[i] = x[i];
150 for (; i < 64; i++)
151 w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
152
153 for (i=0; i < 64; i++)
154 R(a,b,c,d,e,f,g,h,K[i],w[i]);
155
156 hd->h0 += a;
157 hd->h1 += b;
158 hd->h2 += c;
159 hd->h3 += d;
160 hd->h4 += e;
161 hd->h5 += f;
162 hd->h6 += g;
163 hd->h7 += h;
164}
165#undef Cho
166#undef Maj
167#undef Sum0
168#undef Sum1
169#undef S0
170#undef S1
171#undef R
172
173
174/* Update the message digest with the contents of INBUF with length
175 INLEN. */
176static void
177sha256_write (void *context, byte *inbuf, size_t inlen)
178{
179 SHA256_CONTEXT *hd = context;
180
181 if (hd->count == 64)
182 { /* flush the buffer */
183 transform (hd, hd->buf);
184 _gcry_burn_stack (74*4+32);
185 hd->count = 0;
186 hd->nblocks++;
187 }
188 if (!inbuf)
189 return;
190 if (hd->count)
191 {
192 for (; inlen && hd->count < 64; inlen--)
193 hd->buf[hd->count++] = *inbuf++;
194 sha256_write (hd, NULL, 0);
195 if (!inlen)
196 return;
197 }
198
199 while (inlen >= 64)
200 {
201 transform (hd, inbuf);
202 hd->count = 0;
203 hd->nblocks++;
204 inlen -= 64;
205 inbuf += 64;
206 }
207 _gcry_burn_stack (74*4+32);
208 for (; inlen && hd->count < 64; inlen--)
209 hd->buf[hd->count++] = *inbuf++;
210}
211
212
213/*
214 The routine finally terminates the computation and returns the
215 digest. The handle is prepared for a new cycle, but adding bytes
216 to the handle will the destroy the returned buffer. Returns: 32
217 bytes with the message the digest. */
218static void
219sha256_final(void *context)
220{
221 SHA256_CONTEXT *hd = context;
222 u32 t, msb, lsb;
223 byte *p;
224
225 sha256_write (hd, NULL, 0); /* flush */;
226
227 t = hd->nblocks;
228 /* multiply by 64 to make a byte count */
229 lsb = t << 6;
230 msb = t >> 26;
231 /* add the count */
232 t = lsb;
233 if ((lsb += hd->count) < t)
234 msb++;
235 /* multiply by 8 to make a bit count */
236 t = lsb;
237 lsb <<= 3;
238 msb <<= 3;
239 msb |= t >> 29;
240
241 if (hd->count < 56)
242 { /* enough room */
243 hd->buf[hd->count++] = 0x80; /* pad */
244 while (hd->count < 56)
245 hd->buf[hd->count++] = 0; /* pad */
246 }
247 else
248 { /* need one extra block */
249 hd->buf[hd->count++] = 0x80; /* pad character */
250 while (hd->count < 64)
251 hd->buf[hd->count++] = 0;
252 sha256_write (hd, NULL, 0); /* flush */;
253 memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
254 }
255 /* append the 64 bit count */
256 hd->buf[56] = msb >> 24;
257 hd->buf[57] = msb >> 16;
258 hd->buf[58] = msb >> 8;
259 hd->buf[59] = msb;
260 hd->buf[60] = lsb >> 24;
261 hd->buf[61] = lsb >> 16;
262 hd->buf[62] = lsb >> 8;
263 hd->buf[63] = lsb;
264 transform (hd, hd->buf);
265 _gcry_burn_stack (74*4+32);
266
267 p = hd->buf;
268#ifdef WORDS_BIGENDIAN
269#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
270#else /* little endian */
271 #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
272 *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
273#endif
274 X(0);
275 X(1);
276 X(2);
277 X(3);
278 X(4);
279 X(5);
280 X(6);
281 X(7);
282#undef X
283}
284
285static byte *
286sha256_read (void *context)
287{
288 SHA256_CONTEXT *hd = context;
289
290 return hd->buf;
291}
292
293static byte asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */
294 { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
295 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
296 0x00, 0x04, 0x20 };
297
298static gcry_md_oid_spec_t oid_spec_sha256[] =
299 {
300 /* According to the OpenPGG draft rfc2440-bis06 */
301 { "2.16.840.1.101.3.4.2.1" },
302 { NULL },
303 };
304
305gcry_md_spec_t _gcry_digest_spec_sha256 =
306 {
307 "SHA256", asn, DIM (asn), oid_spec_sha256, 32,
308 sha256_init, sha256_write, sha256_final, sha256_read,
309 sizeof (SHA256_CONTEXT)
310 };