Upgraded GRUB2 to 2.00 release.
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / lib / libgcrypt-grub / cipher / sha256.c
blob7df503f8f917a84e26d40033e73ee095f22d117b
1 /* This file was automatically imported with
2 import_gcry.py. Please don't modify it */
3 #include <grub/dl.h>
4 GRUB_MOD_LICENSE ("GPLv3+");
5 /* sha256.c - SHA256 hash function
6 * Copyright (C) 2003, 2006, 2008 Free Software Foundation, Inc.
8 * This file is part of Libgcrypt.
10 * Libgcrypt is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as
12 * published by the Free Software Foundation; either version 2.1 of
13 * the License, or (at your option) any later version.
15 * Libgcrypt is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
25 /* Test vectors:
27 "abc"
28 SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7
29 SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
31 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
32 SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525
33 SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
35 "a" one million times
36 SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67
37 SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
43 #include "g10lib.h"
44 #include "memory.h"
45 #include "bithelp.h"
46 #include "cipher.h"
47 #include "hash-common.h"
49 typedef struct {
50 u32 h0,h1,h2,h3,h4,h5,h6,h7;
51 u32 nblocks;
52 byte buf[64];
53 int count;
54 } SHA256_CONTEXT;
57 static void
58 sha256_init (void *context)
60 SHA256_CONTEXT *hd = context;
62 hd->h0 = 0x6a09e667;
63 hd->h1 = 0xbb67ae85;
64 hd->h2 = 0x3c6ef372;
65 hd->h3 = 0xa54ff53a;
66 hd->h4 = 0x510e527f;
67 hd->h5 = 0x9b05688c;
68 hd->h6 = 0x1f83d9ab;
69 hd->h7 = 0x5be0cd19;
71 hd->nblocks = 0;
72 hd->count = 0;
76 static void
77 sha224_init (void *context)
79 SHA256_CONTEXT *hd = context;
81 hd->h0 = 0xc1059ed8;
82 hd->h1 = 0x367cd507;
83 hd->h2 = 0x3070dd17;
84 hd->h3 = 0xf70e5939;
85 hd->h4 = 0xffc00b31;
86 hd->h5 = 0x68581511;
87 hd->h6 = 0x64f98fa7;
88 hd->h7 = 0xbefa4fa4;
90 hd->nblocks = 0;
91 hd->count = 0;
96 Transform the message X which consists of 16 32-bit-words. See FIPS
97 180-2 for details. */
98 #define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */
99 #define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */
100 #define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */
101 #define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */
102 #define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
103 #define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
104 #define R(a,b,c,d,e,f,g,h,k,w) do \
106 t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
107 t2 = Sum0((a)) + Maj((a),(b),(c)); \
108 h = g; \
109 g = f; \
110 f = e; \
111 e = d + t1; \
112 d = c; \
113 c = b; \
114 b = a; \
115 a = t1 + t2; \
116 } while (0)
118 static void
119 transform (SHA256_CONTEXT *hd, const unsigned char *data)
121 static const u32 K[64] = {
122 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
123 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
124 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
125 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
126 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
127 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
128 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
129 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
130 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
131 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
132 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
133 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
134 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
135 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
136 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
137 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
140 u32 a,b,c,d,e,f,g,h,t1,t2;
141 u32 x[16];
142 u32 w[64];
143 int i;
145 a = hd->h0;
146 b = hd->h1;
147 c = hd->h2;
148 d = hd->h3;
149 e = hd->h4;
150 f = hd->h5;
151 g = hd->h6;
152 h = hd->h7;
154 #ifdef WORDS_BIGENDIAN
155 memcpy (x, data, 64);
156 #else
158 byte *p2;
160 for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 )
162 p2[3] = *data++;
163 p2[2] = *data++;
164 p2[1] = *data++;
165 p2[0] = *data++;
168 #endif
170 for (i=0; i < 16; i++)
171 w[i] = x[i];
172 for (; i < 64; i++)
173 w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
175 for (i=0; i < 64; i++)
176 R(a,b,c,d,e,f,g,h,K[i],w[i]);
178 hd->h0 += a;
179 hd->h1 += b;
180 hd->h2 += c;
181 hd->h3 += d;
182 hd->h4 += e;
183 hd->h5 += f;
184 hd->h6 += g;
185 hd->h7 += h;
187 #undef Cho
188 #undef Maj
189 #undef Sum0
190 #undef Sum1
191 #undef S0
192 #undef S1
193 #undef R
196 /* Update the message digest with the contents of INBUF with length
197 INLEN. */
198 static void
199 sha256_write (void *context, const void *inbuf_arg, size_t inlen)
201 const unsigned char *inbuf = inbuf_arg;
202 SHA256_CONTEXT *hd = context;
204 if (hd->count == 64)
205 { /* flush the buffer */
206 transform (hd, hd->buf);
207 _gcry_burn_stack (74*4+32);
208 hd->count = 0;
209 hd->nblocks++;
211 if (!inbuf)
212 return;
213 if (hd->count)
215 for (; inlen && hd->count < 64; inlen--)
216 hd->buf[hd->count++] = *inbuf++;
217 sha256_write (hd, NULL, 0);
218 if (!inlen)
219 return;
222 while (inlen >= 64)
224 transform (hd, inbuf);
225 hd->count = 0;
226 hd->nblocks++;
227 inlen -= 64;
228 inbuf += 64;
230 _gcry_burn_stack (74*4+32);
231 for (; inlen && hd->count < 64; inlen--)
232 hd->buf[hd->count++] = *inbuf++;
237 The routine finally terminates the computation and returns the
238 digest. The handle is prepared for a new cycle, but adding bytes
239 to the handle will the destroy the returned buffer. Returns: 32
240 bytes with the message the digest. */
241 static void
242 sha256_final(void *context)
244 SHA256_CONTEXT *hd = context;
245 u32 t, msb, lsb;
246 byte *p;
248 sha256_write (hd, NULL, 0); /* flush */;
250 t = hd->nblocks;
251 /* multiply by 64 to make a byte count */
252 lsb = t << 6;
253 msb = t >> 26;
254 /* add the count */
255 t = lsb;
256 if ((lsb += hd->count) < t)
257 msb++;
258 /* multiply by 8 to make a bit count */
259 t = lsb;
260 lsb <<= 3;
261 msb <<= 3;
262 msb |= t >> 29;
264 if (hd->count < 56)
265 { /* enough room */
266 hd->buf[hd->count++] = 0x80; /* pad */
267 while (hd->count < 56)
268 hd->buf[hd->count++] = 0; /* pad */
270 else
271 { /* need one extra block */
272 hd->buf[hd->count++] = 0x80; /* pad character */
273 while (hd->count < 64)
274 hd->buf[hd->count++] = 0;
275 sha256_write (hd, NULL, 0); /* flush */;
276 memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
278 /* append the 64 bit count */
279 hd->buf[56] = msb >> 24;
280 hd->buf[57] = msb >> 16;
281 hd->buf[58] = msb >> 8;
282 hd->buf[59] = msb;
283 hd->buf[60] = lsb >> 24;
284 hd->buf[61] = lsb >> 16;
285 hd->buf[62] = lsb >> 8;
286 hd->buf[63] = lsb;
287 transform (hd, hd->buf);
288 _gcry_burn_stack (74*4+32);
290 p = hd->buf;
291 #ifdef WORDS_BIGENDIAN
292 #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
293 #else /* little endian */
294 #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
295 *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
296 #endif
297 X(0);
298 X(1);
299 X(2);
300 X(3);
301 X(4);
302 X(5);
303 X(6);
304 X(7);
305 #undef X
308 static byte *
309 sha256_read (void *context)
311 SHA256_CONTEXT *hd = context;
313 return hd->buf;
319 Self-test section.
326 /* Run a full self-test for ALGO and return 0 on success. */
331 static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
332 { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
333 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
334 0x1C
337 static gcry_md_oid_spec_t oid_spec_sha224[] =
339 /* From RFC3874, Section 4 */
340 { "2.16.840.1.101.3.4.2.4" },
341 { NULL },
344 static byte asn256[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */
345 { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
346 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
347 0x00, 0x04, 0x20 };
349 static gcry_md_oid_spec_t oid_spec_sha256[] =
351 /* According to the OpenPGP draft rfc2440-bis06 */
352 { "2.16.840.1.101.3.4.2.1" },
353 /* PKCS#1 sha256WithRSAEncryption */
354 { "1.2.840.113549.1.1.11" },
356 { NULL },
359 gcry_md_spec_t _gcry_digest_spec_sha224 =
361 "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
362 sha224_init, sha256_write, sha256_final, sha256_read,
363 sizeof (SHA256_CONTEXT)
365 #ifdef GRUB_UTIL
366 .modname = "gcry_sha256",
367 #endif
368 .blocksize = 64
371 gcry_md_spec_t _gcry_digest_spec_sha256 =
373 "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
374 sha256_init, sha256_write, sha256_final, sha256_read,
375 sizeof (SHA256_CONTEXT)
377 #ifdef GRUB_UTIL
378 .modname = "gcry_sha256",
379 #endif
380 .blocksize = 64
384 GRUB_MOD_INIT(gcry_sha256)
386 grub_md_register (&_gcry_digest_spec_sha224);
387 grub_md_register (&_gcry_digest_spec_sha256);
390 GRUB_MOD_FINI(gcry_sha256)
392 grub_md_unregister (&_gcry_digest_spec_sha224);
393 grub_md_unregister (&_gcry_digest_spec_sha256);