Diffstat (limited to 'pwmanager/libcrypt/cipher/sha256.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | pwmanager/libcrypt/cipher/sha256.c | 310 |
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 | |||
46 | typedef 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 | |||
54 | static void | ||
55 | sha256_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 | |||
96 | static void | ||
97 | transform (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. */ | ||
176 | static void | ||
177 | sha256_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. */ | ||
218 | static void | ||
219 | sha256_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 | |||
285 | static byte * | ||
286 | sha256_read (void *context) | ||
287 | { | ||
288 | SHA256_CONTEXT *hd = context; | ||
289 | |||
290 | return hd->buf; | ||
291 | } | ||
292 | |||
293 | static 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 | |||
298 | static 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 | |||
305 | gcry_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 | }; | ||