~ilya-yanok/ubuntu/precise/grub2/fix-for-948716

« back to all changes in this revision

Viewing changes to grub-core/lib/libgcrypt-grub/cipher/sha256.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2011-01-17 13:43:06 UTC
  • mto: (17.6.26 experimental)
  • mto: This revision was merged to the branch mainline in revision 102.
  • Revision ID: james.westby@ubuntu.com-20110117134306-fy7qewn4s3qdx2pl
Tags: upstream-1.99~rc1
ImportĀ upstreamĀ versionĀ 1.99~rc1

Show diffs side-by-side

added added

removed removed

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