Line data Source code
1 : /* sha256.c - SHA256 hash function
2 : * Copyright (C) 2003, 2006, 2008, 2009 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, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 :
21 : /* Test vectors:
22 :
23 : "abc"
24 : SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7
25 : SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
26 :
27 : "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
28 : SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525
29 : SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
30 :
31 : "a" one million times
32 : SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67
33 : SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
34 :
35 : */
36 :
37 :
38 : #include <config.h>
39 : #include <stdio.h>
40 : #include <stdlib.h>
41 : #include <string.h>
42 :
43 : #include "g10lib.h"
44 : #include "bithelp.h"
45 : #include "bufhelp.h"
46 : #include "cipher.h"
47 : #include "hash-common.h"
48 :
49 :
50 : /* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */
51 : #undef USE_SSSE3
52 : #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
53 : defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
54 : (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
55 : defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
56 : # define USE_SSSE3 1
57 : #endif
58 :
59 : /* USE_AVX indicates whether to compile with Intel AVX code. */
60 : #undef USE_AVX
61 : #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
62 : defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
63 : (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
64 : defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
65 : # define USE_AVX 1
66 : #endif
67 :
68 : /* USE_AVX2 indicates whether to compile with Intel AVX2/BMI2 code. */
69 : #undef USE_AVX2
70 : #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \
71 : defined(HAVE_GCC_INLINE_ASM_BMI2) && \
72 : defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
73 : (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
74 : defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
75 : # define USE_AVX2 1
76 : #endif
77 :
78 : /* USE_ARM_CE indicates whether to enable ARMv8 Crypto Extension assembly
79 : * code. */
80 : #undef USE_ARM_CE
81 : #ifdef ENABLE_ARM_CRYPTO_SUPPORT
82 : # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
83 : && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
84 : && defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO)
85 : # define USE_ARM_CE 1
86 : # elif defined(__AARCH64EL__) \
87 : && defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) \
88 : && defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
89 : # define USE_ARM_CE 1
90 : # endif
91 : #endif
92 :
93 :
94 : typedef struct {
95 : gcry_md_block_ctx_t bctx;
96 : u32 h0,h1,h2,h3,h4,h5,h6,h7;
97 : #ifdef USE_SSSE3
98 : unsigned int use_ssse3:1;
99 : #endif
100 : #ifdef USE_AVX
101 : unsigned int use_avx:1;
102 : #endif
103 : #ifdef USE_AVX2
104 : unsigned int use_avx2:1;
105 : #endif
106 : #ifdef USE_ARM_CE
107 : unsigned int use_arm_ce:1;
108 : #endif
109 : } SHA256_CONTEXT;
110 :
111 :
112 : static unsigned int
113 : transform (void *c, const unsigned char *data, size_t nblks);
114 :
115 :
116 : static void
117 0 : sha256_init (void *context, unsigned int flags)
118 : {
119 0 : SHA256_CONTEXT *hd = context;
120 0 : unsigned int features = _gcry_get_hw_features ();
121 :
122 : (void)flags;
123 :
124 0 : hd->h0 = 0x6a09e667;
125 0 : hd->h1 = 0xbb67ae85;
126 0 : hd->h2 = 0x3c6ef372;
127 0 : hd->h3 = 0xa54ff53a;
128 0 : hd->h4 = 0x510e527f;
129 0 : hd->h5 = 0x9b05688c;
130 0 : hd->h6 = 0x1f83d9ab;
131 0 : hd->h7 = 0x5be0cd19;
132 :
133 0 : hd->bctx.nblocks = 0;
134 0 : hd->bctx.nblocks_high = 0;
135 0 : hd->bctx.count = 0;
136 0 : hd->bctx.blocksize = 64;
137 0 : hd->bctx.bwrite = transform;
138 :
139 : #ifdef USE_SSSE3
140 0 : hd->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
141 : #endif
142 : #ifdef USE_AVX
143 : /* AVX implementation uses SHLD which is known to be slow on non-Intel CPUs.
144 : * Therefore use this implementation on Intel CPUs only. */
145 0 : hd->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD);
146 : #endif
147 : #ifdef USE_AVX2
148 0 : hd->use_avx2 = (features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2);
149 : #endif
150 : #ifdef USE_ARM_CE
151 : hd->use_arm_ce = (features & HWF_ARM_SHA2) != 0;
152 : #endif
153 : (void)features;
154 0 : }
155 :
156 :
157 : static void
158 0 : sha224_init (void *context, unsigned int flags)
159 : {
160 0 : SHA256_CONTEXT *hd = context;
161 0 : unsigned int features = _gcry_get_hw_features ();
162 :
163 : (void)flags;
164 :
165 0 : hd->h0 = 0xc1059ed8;
166 0 : hd->h1 = 0x367cd507;
167 0 : hd->h2 = 0x3070dd17;
168 0 : hd->h3 = 0xf70e5939;
169 0 : hd->h4 = 0xffc00b31;
170 0 : hd->h5 = 0x68581511;
171 0 : hd->h6 = 0x64f98fa7;
172 0 : hd->h7 = 0xbefa4fa4;
173 :
174 0 : hd->bctx.nblocks = 0;
175 0 : hd->bctx.nblocks_high = 0;
176 0 : hd->bctx.count = 0;
177 0 : hd->bctx.blocksize = 64;
178 0 : hd->bctx.bwrite = transform;
179 :
180 : #ifdef USE_SSSE3
181 0 : hd->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
182 : #endif
183 : #ifdef USE_AVX
184 : /* AVX implementation uses SHLD which is known to be slow on non-Intel CPUs.
185 : * Therefore use this implementation on Intel CPUs only. */
186 0 : hd->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD);
187 : #endif
188 : #ifdef USE_AVX2
189 0 : hd->use_avx2 = (features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2);
190 : #endif
191 : #ifdef USE_ARM_CE
192 : hd->use_arm_ce = (features & HWF_ARM_SHA2) != 0;
193 : #endif
194 : (void)features;
195 0 : }
196 :
197 :
198 : /*
199 : Transform the message X which consists of 16 32-bit-words. See FIPS
200 : 180-2 for details. */
201 : #define R(a,b,c,d,e,f,g,h,k,w) do \
202 : { \
203 : t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
204 : t2 = Sum0((a)) + Maj((a),(b),(c)); \
205 : d += t1; \
206 : h = t1 + t2; \
207 : } while (0)
208 :
209 : /* (4.2) same as SHA-1's F1. */
210 : #define Cho(x, y, z) (z ^ (x & (y ^ z)))
211 :
212 : /* (4.3) same as SHA-1's F3 */
213 : #define Maj(x, y, z) ((x & y) + (z & (x ^ y)))
214 :
215 : /* (4.4) */
216 : #define Sum0(x) (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22))
217 :
218 : /* (4.5) */
219 : #define Sum1(x) (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25))
220 :
221 : /* Message expansion */
222 : #define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
223 : #define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
224 : #define I(i) ( w[i] = buf_get_be32(data + i * 4) )
225 : #define W(i) ( w[i&0x0f] = S1(w[(i-2) &0x0f]) \
226 : + w[(i-7) &0x0f] \
227 : + S0(w[(i-15)&0x0f]) \
228 : + w[(i-16)&0x0f] )
229 :
230 : static unsigned int
231 0 : transform_blk (void *ctx, const unsigned char *data)
232 : {
233 0 : SHA256_CONTEXT *hd = ctx;
234 : static const u32 K[64] = {
235 : 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
236 : 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
237 : 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
238 : 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
239 : 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
240 : 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
241 : 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
242 : 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
243 : 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
244 : 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
245 : 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
246 : 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
247 : 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
248 : 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
249 : 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
250 : 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
251 : };
252 :
253 : u32 a,b,c,d,e,f,g,h,t1,t2;
254 : u32 w[16];
255 :
256 0 : a = hd->h0;
257 0 : b = hd->h1;
258 0 : c = hd->h2;
259 0 : d = hd->h3;
260 0 : e = hd->h4;
261 0 : f = hd->h5;
262 0 : g = hd->h6;
263 0 : h = hd->h7;
264 :
265 0 : R(a, b, c, d, e, f, g, h, K[0], I(0));
266 0 : R(h, a, b, c, d, e, f, g, K[1], I(1));
267 0 : R(g, h, a, b, c, d, e, f, K[2], I(2));
268 0 : R(f, g, h, a, b, c, d, e, K[3], I(3));
269 0 : R(e, f, g, h, a, b, c, d, K[4], I(4));
270 0 : R(d, e, f, g, h, a, b, c, K[5], I(5));
271 0 : R(c, d, e, f, g, h, a, b, K[6], I(6));
272 0 : R(b, c, d, e, f, g, h, a, K[7], I(7));
273 0 : R(a, b, c, d, e, f, g, h, K[8], I(8));
274 0 : R(h, a, b, c, d, e, f, g, K[9], I(9));
275 0 : R(g, h, a, b, c, d, e, f, K[10], I(10));
276 0 : R(f, g, h, a, b, c, d, e, K[11], I(11));
277 0 : R(e, f, g, h, a, b, c, d, K[12], I(12));
278 0 : R(d, e, f, g, h, a, b, c, K[13], I(13));
279 0 : R(c, d, e, f, g, h, a, b, K[14], I(14));
280 0 : R(b, c, d, e, f, g, h, a, K[15], I(15));
281 :
282 0 : R(a, b, c, d, e, f, g, h, K[16], W(16));
283 0 : R(h, a, b, c, d, e, f, g, K[17], W(17));
284 0 : R(g, h, a, b, c, d, e, f, K[18], W(18));
285 0 : R(f, g, h, a, b, c, d, e, K[19], W(19));
286 0 : R(e, f, g, h, a, b, c, d, K[20], W(20));
287 0 : R(d, e, f, g, h, a, b, c, K[21], W(21));
288 0 : R(c, d, e, f, g, h, a, b, K[22], W(22));
289 0 : R(b, c, d, e, f, g, h, a, K[23], W(23));
290 0 : R(a, b, c, d, e, f, g, h, K[24], W(24));
291 0 : R(h, a, b, c, d, e, f, g, K[25], W(25));
292 0 : R(g, h, a, b, c, d, e, f, K[26], W(26));
293 0 : R(f, g, h, a, b, c, d, e, K[27], W(27));
294 0 : R(e, f, g, h, a, b, c, d, K[28], W(28));
295 0 : R(d, e, f, g, h, a, b, c, K[29], W(29));
296 0 : R(c, d, e, f, g, h, a, b, K[30], W(30));
297 0 : R(b, c, d, e, f, g, h, a, K[31], W(31));
298 :
299 0 : R(a, b, c, d, e, f, g, h, K[32], W(32));
300 0 : R(h, a, b, c, d, e, f, g, K[33], W(33));
301 0 : R(g, h, a, b, c, d, e, f, K[34], W(34));
302 0 : R(f, g, h, a, b, c, d, e, K[35], W(35));
303 0 : R(e, f, g, h, a, b, c, d, K[36], W(36));
304 0 : R(d, e, f, g, h, a, b, c, K[37], W(37));
305 0 : R(c, d, e, f, g, h, a, b, K[38], W(38));
306 0 : R(b, c, d, e, f, g, h, a, K[39], W(39));
307 0 : R(a, b, c, d, e, f, g, h, K[40], W(40));
308 0 : R(h, a, b, c, d, e, f, g, K[41], W(41));
309 0 : R(g, h, a, b, c, d, e, f, K[42], W(42));
310 0 : R(f, g, h, a, b, c, d, e, K[43], W(43));
311 0 : R(e, f, g, h, a, b, c, d, K[44], W(44));
312 0 : R(d, e, f, g, h, a, b, c, K[45], W(45));
313 0 : R(c, d, e, f, g, h, a, b, K[46], W(46));
314 0 : R(b, c, d, e, f, g, h, a, K[47], W(47));
315 :
316 0 : R(a, b, c, d, e, f, g, h, K[48], W(48));
317 0 : R(h, a, b, c, d, e, f, g, K[49], W(49));
318 0 : R(g, h, a, b, c, d, e, f, K[50], W(50));
319 0 : R(f, g, h, a, b, c, d, e, K[51], W(51));
320 0 : R(e, f, g, h, a, b, c, d, K[52], W(52));
321 0 : R(d, e, f, g, h, a, b, c, K[53], W(53));
322 0 : R(c, d, e, f, g, h, a, b, K[54], W(54));
323 0 : R(b, c, d, e, f, g, h, a, K[55], W(55));
324 0 : R(a, b, c, d, e, f, g, h, K[56], W(56));
325 0 : R(h, a, b, c, d, e, f, g, K[57], W(57));
326 0 : R(g, h, a, b, c, d, e, f, K[58], W(58));
327 0 : R(f, g, h, a, b, c, d, e, K[59], W(59));
328 0 : R(e, f, g, h, a, b, c, d, K[60], W(60));
329 0 : R(d, e, f, g, h, a, b, c, K[61], W(61));
330 0 : R(c, d, e, f, g, h, a, b, K[62], W(62));
331 0 : R(b, c, d, e, f, g, h, a, K[63], W(63));
332 :
333 0 : hd->h0 += a;
334 0 : hd->h1 += b;
335 0 : hd->h2 += c;
336 0 : hd->h3 += d;
337 0 : hd->h4 += e;
338 0 : hd->h5 += f;
339 0 : hd->h6 += g;
340 0 : hd->h7 += h;
341 :
342 0 : return /*burn_stack*/ 26*4+32;
343 : }
344 : #undef S0
345 : #undef S1
346 : #undef R
347 :
348 :
349 : /* Assembly implementations use SystemV ABI, ABI conversion and additional
350 : * stack to store XMM6-XMM15 needed on Win64. */
351 : #undef ASM_FUNC_ABI
352 : #undef ASM_EXTRA_STACK
353 : #if defined(USE_SSSE3) || defined(USE_AVX) || defined(USE_AVX2)
354 : # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
355 : # define ASM_FUNC_ABI __attribute__((sysv_abi))
356 : # define ASM_EXTRA_STACK (10 * 16)
357 : # else
358 : # define ASM_FUNC_ABI
359 : # define ASM_EXTRA_STACK 0
360 : # endif
361 : #endif
362 :
363 :
364 : #ifdef USE_SSSE3
365 : unsigned int _gcry_sha256_transform_amd64_ssse3(const void *input_data,
366 : u32 state[8],
367 : size_t num_blks) ASM_FUNC_ABI;
368 : #endif
369 :
370 : #ifdef USE_AVX
371 : unsigned int _gcry_sha256_transform_amd64_avx(const void *input_data,
372 : u32 state[8],
373 : size_t num_blks) ASM_FUNC_ABI;
374 : #endif
375 :
376 : #ifdef USE_AVX2
377 : unsigned int _gcry_sha256_transform_amd64_avx2(const void *input_data,
378 : u32 state[8],
379 : size_t num_blks) ASM_FUNC_ABI;
380 : #endif
381 :
382 : #ifdef USE_ARM_CE
383 : unsigned int _gcry_sha256_transform_armv8_ce(u32 state[8],
384 : const void *input_data,
385 : size_t num_blks);
386 : #endif
387 :
388 : static unsigned int
389 0 : transform (void *ctx, const unsigned char *data, size_t nblks)
390 : {
391 0 : SHA256_CONTEXT *hd = ctx;
392 : unsigned int burn;
393 :
394 : #ifdef USE_AVX2
395 0 : if (hd->use_avx2)
396 0 : return _gcry_sha256_transform_amd64_avx2 (data, &hd->h0, nblks)
397 0 : + 4 * sizeof(void*) + ASM_EXTRA_STACK;
398 : #endif
399 :
400 : #ifdef USE_AVX
401 0 : if (hd->use_avx)
402 0 : return _gcry_sha256_transform_amd64_avx (data, &hd->h0, nblks)
403 0 : + 4 * sizeof(void*) + ASM_EXTRA_STACK;
404 : #endif
405 :
406 : #ifdef USE_SSSE3
407 0 : if (hd->use_ssse3)
408 0 : return _gcry_sha256_transform_amd64_ssse3 (data, &hd->h0, nblks)
409 0 : + 4 * sizeof(void*) + ASM_EXTRA_STACK;
410 : #endif
411 :
412 : #ifdef USE_ARM_CE
413 : if (hd->use_arm_ce)
414 : return _gcry_sha256_transform_armv8_ce (&hd->h0, data, nblks);
415 : #endif
416 :
417 : do
418 : {
419 0 : burn = transform_blk (hd, data);
420 0 : data += 64;
421 : }
422 0 : while (--nblks);
423 :
424 : #ifdef ASM_EXTRA_STACK
425 : /* 'transform_blk' is typically inlined and XMM6-XMM15 are stored at
426 : * the prologue of this function. Therefore need to add ASM_EXTRA_STACK to
427 : * here too.
428 : */
429 0 : burn += ASM_EXTRA_STACK;
430 : #endif
431 :
432 0 : return burn;
433 : }
434 :
435 :
436 : /*
437 : The routine finally terminates the computation and returns the
438 : digest. The handle is prepared for a new cycle, but adding bytes
439 : to the handle will the destroy the returned buffer. Returns: 32
440 : bytes with the message the digest. */
441 : static void
442 0 : sha256_final(void *context)
443 : {
444 0 : SHA256_CONTEXT *hd = context;
445 : u32 t, th, msb, lsb;
446 : byte *p;
447 : unsigned int burn;
448 :
449 0 : _gcry_md_block_write (hd, NULL, 0); /* flush */;
450 :
451 0 : t = hd->bctx.nblocks;
452 : if (sizeof t == sizeof hd->bctx.nblocks)
453 : th = hd->bctx.nblocks_high;
454 : else
455 0 : th = hd->bctx.nblocks >> 32;
456 :
457 : /* multiply by 64 to make a byte count */
458 0 : lsb = t << 6;
459 0 : msb = (th << 6) | (t >> 26);
460 : /* add the count */
461 0 : t = lsb;
462 0 : if ((lsb += hd->bctx.count) < t)
463 0 : msb++;
464 : /* multiply by 8 to make a bit count */
465 0 : t = lsb;
466 0 : lsb <<= 3;
467 0 : msb <<= 3;
468 0 : msb |= t >> 29;
469 :
470 0 : if (hd->bctx.count < 56)
471 : { /* enough room */
472 0 : hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
473 0 : while (hd->bctx.count < 56)
474 0 : hd->bctx.buf[hd->bctx.count++] = 0; /* pad */
475 : }
476 : else
477 : { /* need one extra block */
478 0 : hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
479 0 : while (hd->bctx.count < 64)
480 0 : hd->bctx.buf[hd->bctx.count++] = 0;
481 0 : _gcry_md_block_write (hd, NULL, 0); /* flush */;
482 0 : memset (hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
483 : }
484 : /* append the 64 bit count */
485 0 : buf_put_be32(hd->bctx.buf + 56, msb);
486 0 : buf_put_be32(hd->bctx.buf + 60, lsb);
487 0 : burn = transform (hd, hd->bctx.buf, 1);
488 0 : _gcry_burn_stack (burn);
489 :
490 0 : p = hd->bctx.buf;
491 : #define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0)
492 0 : X(0);
493 0 : X(1);
494 0 : X(2);
495 0 : X(3);
496 0 : X(4);
497 0 : X(5);
498 0 : X(6);
499 0 : X(7);
500 : #undef X
501 0 : }
502 :
503 : static byte *
504 0 : sha256_read (void *context)
505 : {
506 0 : SHA256_CONTEXT *hd = context;
507 :
508 0 : return hd->bctx.buf;
509 : }
510 :
511 :
512 :
513 : /*
514 : Self-test section.
515 : */
516 :
517 :
518 : static gpg_err_code_t
519 0 : selftests_sha224 (int extended, selftest_report_func_t report)
520 : {
521 : const char *what;
522 : const char *errtxt;
523 :
524 0 : what = "short string";
525 0 : errtxt = _gcry_hash_selftest_check_one
526 : (GCRY_MD_SHA224, 0,
527 : "abc", 3,
528 : "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3"
529 : "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7", 28);
530 0 : if (errtxt)
531 0 : goto failed;
532 :
533 0 : if (extended)
534 : {
535 0 : what = "long string";
536 0 : errtxt = _gcry_hash_selftest_check_one
537 : (GCRY_MD_SHA224, 0,
538 : "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
539 : "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50"
540 : "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28);
541 0 : if (errtxt)
542 0 : goto failed;
543 :
544 0 : what = "one million \"a\"";
545 0 : errtxt = _gcry_hash_selftest_check_one
546 : (GCRY_MD_SHA224, 1,
547 : NULL, 0,
548 : "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b"
549 : "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67", 28);
550 0 : if (errtxt)
551 0 : goto failed;
552 : }
553 :
554 0 : return 0; /* Succeeded. */
555 :
556 : failed:
557 0 : if (report)
558 0 : report ("digest", GCRY_MD_SHA224, what, errtxt);
559 0 : return GPG_ERR_SELFTEST_FAILED;
560 : }
561 :
562 : static gpg_err_code_t
563 0 : selftests_sha256 (int extended, selftest_report_func_t report)
564 : {
565 : const char *what;
566 : const char *errtxt;
567 :
568 0 : what = "short string";
569 0 : errtxt = _gcry_hash_selftest_check_one
570 : (GCRY_MD_SHA256, 0,
571 : "abc", 3,
572 : "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
573 : "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32);
574 0 : if (errtxt)
575 0 : goto failed;
576 :
577 0 : if (extended)
578 : {
579 0 : what = "long string";
580 0 : errtxt = _gcry_hash_selftest_check_one
581 : (GCRY_MD_SHA256, 0,
582 : "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
583 : "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
584 : "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1",
585 : 32);
586 0 : if (errtxt)
587 0 : goto failed;
588 :
589 0 : what = "one million \"a\"";
590 0 : errtxt = _gcry_hash_selftest_check_one
591 : (GCRY_MD_SHA256, 1,
592 : NULL, 0,
593 : "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
594 : "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0",
595 : 32);
596 0 : if (errtxt)
597 0 : goto failed;
598 : }
599 :
600 0 : return 0; /* Succeeded. */
601 :
602 : failed:
603 0 : if (report)
604 0 : report ("digest", GCRY_MD_SHA256, what, errtxt);
605 0 : return GPG_ERR_SELFTEST_FAILED;
606 : }
607 :
608 :
609 : /* Run a full self-test for ALGO and return 0 on success. */
610 : static gpg_err_code_t
611 0 : run_selftests (int algo, int extended, selftest_report_func_t report)
612 : {
613 : gpg_err_code_t ec;
614 :
615 0 : switch (algo)
616 : {
617 : case GCRY_MD_SHA224:
618 0 : ec = selftests_sha224 (extended, report);
619 0 : break;
620 : case GCRY_MD_SHA256:
621 0 : ec = selftests_sha256 (extended, report);
622 0 : break;
623 : default:
624 0 : ec = GPG_ERR_DIGEST_ALGO;
625 0 : break;
626 :
627 : }
628 0 : return ec;
629 : }
630 :
631 :
632 :
633 :
634 : static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
635 : { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
636 : 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
637 : 0x1C
638 : };
639 :
640 : static gcry_md_oid_spec_t oid_spec_sha224[] =
641 : {
642 : /* From RFC3874, Section 4 */
643 : { "2.16.840.1.101.3.4.2.4" },
644 : { NULL },
645 : };
646 :
647 : static byte asn256[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */
648 : { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
649 : 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
650 : 0x00, 0x04, 0x20 };
651 :
652 : static gcry_md_oid_spec_t oid_spec_sha256[] =
653 : {
654 : /* According to the OpenPGP draft rfc2440-bis06 */
655 : { "2.16.840.1.101.3.4.2.1" },
656 : /* PKCS#1 sha256WithRSAEncryption */
657 : { "1.2.840.113549.1.1.11" },
658 :
659 : { NULL },
660 : };
661 :
662 : gcry_md_spec_t _gcry_digest_spec_sha224 =
663 : {
664 : GCRY_MD_SHA224, {0, 1},
665 : "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
666 : sha224_init, _gcry_md_block_write, sha256_final, sha256_read, NULL,
667 : sizeof (SHA256_CONTEXT),
668 : run_selftests
669 : };
670 :
671 : gcry_md_spec_t _gcry_digest_spec_sha256 =
672 : {
673 : GCRY_MD_SHA256, {0, 1},
674 : "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
675 : sha256_init, _gcry_md_block_write, sha256_final, sha256_read, NULL,
676 : sizeof (SHA256_CONTEXT),
677 : run_selftests
678 : };
|