/src/libgcrypt/cipher/sha512.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* sha512.c - SHA384 and SHA512 hash functions |
2 | | * Copyright (C) 2003, 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 from FIPS-180-2: |
22 | | * |
23 | | * "abc" |
24 | | * 384: |
25 | | * CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163 |
26 | | * 1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7 |
27 | | * 512: |
28 | | * DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A |
29 | | * 2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F |
30 | | * |
31 | | * "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" |
32 | | * 384: |
33 | | * 09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2 |
34 | | * 2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039 |
35 | | * 512: |
36 | | * 8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018 |
37 | | * 501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909 |
38 | | * |
39 | | * "a" x 1000000 |
40 | | * 384: |
41 | | * 9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852 |
42 | | * 7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985 |
43 | | * 512: |
44 | | * E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB |
45 | | * DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B |
46 | | */ |
47 | | |
48 | | |
49 | | #include <config.h> |
50 | | #include <string.h> |
51 | | #include "g10lib.h" |
52 | | #include "bithelp.h" |
53 | | #include "bufhelp.h" |
54 | | #include "cipher.h" |
55 | | #include "hash-common.h" |
56 | | |
57 | | |
58 | | /* Helper macro to force alignment to 64 bytes. */ |
59 | | #ifdef HAVE_GCC_ATTRIBUTE_ALIGNED |
60 | | # define ATTR_ALIGNED_64 __attribute__ ((aligned (64))) |
61 | | #else |
62 | | # define ATTR_ALIGNED_64 |
63 | | #endif |
64 | | |
65 | | |
66 | | /* USE_ARM_NEON_ASM indicates whether to enable ARM NEON assembly code. */ |
67 | | #undef USE_ARM_NEON_ASM |
68 | | #ifdef ENABLE_NEON_SUPPORT |
69 | | # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \ |
70 | | && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \ |
71 | | && defined(HAVE_GCC_INLINE_ASM_NEON) |
72 | | # define USE_ARM_NEON_ASM 1 |
73 | | # endif |
74 | | #endif /*ENABLE_NEON_SUPPORT*/ |
75 | | |
76 | | |
77 | | /* USE_ARM_ASM indicates whether to enable ARM assembly code. */ |
78 | | #undef USE_ARM_ASM |
79 | | #if defined(__ARMEL__) && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) |
80 | | # define USE_ARM_ASM 1 |
81 | | #endif |
82 | | |
83 | | /* USE_ARM64_SHA512 indicates whether to enable ARMv8 SHA512 extension assembly |
84 | | * code. */ |
85 | | #undef USE_ARM64_SHA512 |
86 | | #ifdef ENABLE_ARM_CRYPTO_SUPPORT |
87 | | # if defined(__AARCH64EL__) \ |
88 | | && defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) \ |
89 | | && defined(HAVE_GCC_INLINE_ASM_AARCH64_SHA3_SHA512_SM3_SM4) |
90 | | # define USE_ARM64_SHA512 1 |
91 | | # endif |
92 | | #endif |
93 | | |
94 | | |
95 | | /* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */ |
96 | | #undef USE_SSSE3 |
97 | | #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \ |
98 | | defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \ |
99 | | (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ |
100 | | defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) |
101 | | # define USE_SSSE3 1 |
102 | | #endif |
103 | | |
104 | | |
105 | | /* USE_AVX indicates whether to compile with Intel AVX code. */ |
106 | | #undef USE_AVX |
107 | | #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \ |
108 | | defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \ |
109 | | (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ |
110 | | defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) |
111 | | # define USE_AVX 1 |
112 | | #endif |
113 | | |
114 | | |
115 | | /* USE_AVX2 indicates whether to compile with Intel AVX2/rorx code. */ |
116 | | #undef USE_AVX2 |
117 | | #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \ |
118 | | defined(HAVE_GCC_INLINE_ASM_BMI2) && \ |
119 | | defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \ |
120 | | (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ |
121 | | defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) |
122 | | # define USE_AVX2 1 |
123 | | #endif |
124 | | |
125 | | |
126 | | /* USE_AVX512 indicates whether to compile with Intel AVX512 code. */ |
127 | | #undef USE_AVX512 |
128 | | #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX512) && \ |
129 | | defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \ |
130 | | (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ |
131 | | defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) |
132 | | # define USE_AVX512 1 |
133 | | #endif |
134 | | |
135 | | |
136 | | /* USE_SSSE3_I386 indicates whether to compile with Intel SSSE3/i386 code. */ |
137 | | #undef USE_SSSE3_I386 |
138 | | #if defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4 && \ |
139 | | defined(HAVE_GCC_INLINE_ASM_SSSE3) |
140 | | # define USE_SSSE3_I386 1 |
141 | | #endif |
142 | | |
143 | | |
144 | | /* USE_PPC_CRYPTO indicates whether to enable PowerPC vector crypto |
145 | | * accelerated code. */ |
146 | | #undef USE_PPC_CRYPTO |
147 | | #ifdef ENABLE_PPC_CRYPTO_SUPPORT |
148 | | # if defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \ |
149 | | defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC) |
150 | | # if __GNUC__ >= 4 |
151 | | # define USE_PPC_CRYPTO 1 |
152 | | # endif |
153 | | # endif |
154 | | #endif |
155 | | |
156 | | |
157 | | /* USE_S390X_CRYPTO indicates whether to enable zSeries code. */ |
158 | | #undef USE_S390X_CRYPTO |
159 | | #if defined(HAVE_GCC_INLINE_ASM_S390X) |
160 | | # define USE_S390X_CRYPTO 1 |
161 | | #endif /* USE_S390X_CRYPTO */ |
162 | | |
163 | | |
164 | | typedef struct |
165 | | { |
166 | | u64 h[8]; |
167 | | } SHA512_STATE; |
168 | | |
169 | | typedef struct |
170 | | { |
171 | | gcry_md_block_ctx_t bctx; |
172 | | SHA512_STATE state; |
173 | | #ifdef USE_S390X_CRYPTO |
174 | | u64 final_len_msb, final_len_lsb; /* needs to be right after state.h[7]. */ |
175 | | int use_s390x_crypto; |
176 | | #endif |
177 | | } SHA512_CONTEXT; |
178 | | |
179 | | |
180 | | static ATTR_ALIGNED_64 const u64 k[] = |
181 | | { |
182 | | U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd), |
183 | | U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc), |
184 | | U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019), |
185 | | U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118), |
186 | | U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe), |
187 | | U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2), |
188 | | U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1), |
189 | | U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694), |
190 | | U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3), |
191 | | U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65), |
192 | | U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483), |
193 | | U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5), |
194 | | U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210), |
195 | | U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4), |
196 | | U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725), |
197 | | U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70), |
198 | | U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926), |
199 | | U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df), |
200 | | U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8), |
201 | | U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b), |
202 | | U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001), |
203 | | U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30), |
204 | | U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910), |
205 | | U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8), |
206 | | U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53), |
207 | | U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8), |
208 | | U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb), |
209 | | U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3), |
210 | | U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60), |
211 | | U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec), |
212 | | U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9), |
213 | | U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b), |
214 | | U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207), |
215 | | U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178), |
216 | | U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6), |
217 | | U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b), |
218 | | U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493), |
219 | | U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c), |
220 | | U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a), |
221 | | U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817) |
222 | | }; |
223 | | |
224 | | |
225 | | /* AMD64 assembly implementations use SystemV ABI, ABI conversion and additional |
226 | | * stack to store XMM6-XMM15 needed on Win64. */ |
227 | | #undef ASM_FUNC_ABI |
228 | | #undef ASM_EXTRA_STACK |
229 | | #if defined(USE_SSSE3) || defined(USE_AVX) || defined(USE_AVX2) \ |
230 | | || defined(USE_AVX512) |
231 | | # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS |
232 | | # define ASM_FUNC_ABI __attribute__((sysv_abi)) |
233 | | # define ASM_EXTRA_STACK (10 * 16 + 4 * sizeof(void *)) |
234 | | # else |
235 | | # define ASM_FUNC_ABI |
236 | 0 | # define ASM_EXTRA_STACK 0 |
237 | | # endif |
238 | | #endif |
239 | | |
240 | | |
241 | | #ifdef USE_ARM64_SHA512 |
242 | | unsigned int _gcry_sha512_transform_armv8_ce (u64 state[8], |
243 | | const unsigned char *data, |
244 | | size_t num_blks, |
245 | | const u64 k[]); |
246 | | |
247 | | static unsigned int |
248 | | do_sha512_transform_armv8_ce(void *ctx, const unsigned char *data, |
249 | | size_t nblks) |
250 | | { |
251 | | SHA512_CONTEXT *hd = ctx; |
252 | | return _gcry_sha512_transform_armv8_ce (hd->state.h, data, nblks, k); |
253 | | } |
254 | | #endif |
255 | | |
256 | | #ifdef USE_ARM_NEON_ASM |
257 | | unsigned int _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd, |
258 | | const unsigned char *data, |
259 | | const u64 k[], size_t num_blks); |
260 | | |
261 | | static unsigned int |
262 | | do_sha512_transform_armv7_neon(void *ctx, const unsigned char *data, |
263 | | size_t nblks) |
264 | | { |
265 | | SHA512_CONTEXT *hd = ctx; |
266 | | return _gcry_sha512_transform_armv7_neon (&hd->state, data, k, nblks); |
267 | | } |
268 | | #endif |
269 | | |
270 | | #ifdef USE_SSSE3 |
271 | | unsigned int _gcry_sha512_transform_amd64_ssse3(const void *input_data, |
272 | | void *state, |
273 | | size_t num_blks) ASM_FUNC_ABI; |
274 | | |
275 | | static unsigned int |
276 | | do_sha512_transform_amd64_ssse3(void *ctx, const unsigned char *data, |
277 | | size_t nblks) |
278 | 0 | { |
279 | 0 | SHA512_CONTEXT *hd = ctx; |
280 | 0 | unsigned int burn; |
281 | 0 | burn = _gcry_sha512_transform_amd64_ssse3 (data, &hd->state, nblks); |
282 | 0 | burn += burn > 0 ? ASM_EXTRA_STACK : 0; |
283 | 0 | return burn; |
284 | 0 | } |
285 | | #endif |
286 | | |
287 | | #ifdef USE_AVX |
288 | | unsigned int _gcry_sha512_transform_amd64_avx(const void *input_data, |
289 | | void *state, |
290 | | size_t num_blks) ASM_FUNC_ABI; |
291 | | |
292 | | static unsigned int |
293 | | do_sha512_transform_amd64_avx(void *ctx, const unsigned char *data, |
294 | | size_t nblks) |
295 | 0 | { |
296 | 0 | SHA512_CONTEXT *hd = ctx; |
297 | 0 | unsigned int burn; |
298 | 0 | burn = _gcry_sha512_transform_amd64_avx (data, &hd->state, nblks); |
299 | 0 | burn += burn > 0 ? ASM_EXTRA_STACK : 0; |
300 | 0 | return burn; |
301 | 0 | } |
302 | | #endif |
303 | | |
304 | | #ifdef USE_AVX2 |
305 | | unsigned int _gcry_sha512_transform_amd64_avx2(const void *input_data, |
306 | | void *state, |
307 | | size_t num_blks) ASM_FUNC_ABI; |
308 | | |
309 | | static unsigned int |
310 | | do_sha512_transform_amd64_avx2(void *ctx, const unsigned char *data, |
311 | | size_t nblks) |
312 | 1.99k | { |
313 | 1.99k | SHA512_CONTEXT *hd = ctx; |
314 | 1.99k | unsigned int burn; |
315 | 1.99k | burn = _gcry_sha512_transform_amd64_avx2 (data, &hd->state, nblks); |
316 | 1.99k | burn += burn > 0 ? ASM_EXTRA_STACK : 0; |
317 | 1.99k | return burn; |
318 | 1.99k | } |
319 | | #endif |
320 | | |
321 | | #ifdef USE_AVX512 |
322 | | unsigned int _gcry_sha512_transform_amd64_avx512(const void *input_data, |
323 | | void *state, |
324 | | size_t num_blks) ASM_FUNC_ABI; |
325 | | |
326 | | static unsigned int |
327 | | do_sha512_transform_amd64_avx512(void *ctx, const unsigned char *data, |
328 | | size_t nblks) |
329 | 0 | { |
330 | 0 | SHA512_CONTEXT *hd = ctx; |
331 | 0 | unsigned int burn; |
332 | 0 | burn = _gcry_sha512_transform_amd64_avx512 (data, &hd->state, nblks); |
333 | 0 | burn += burn > 0 ? ASM_EXTRA_STACK : 0; |
334 | 0 | return burn; |
335 | 0 | } |
336 | | #endif |
337 | | |
338 | | #ifdef USE_SSSE3_I386 |
339 | | unsigned int _gcry_sha512_transform_i386_ssse3(u64 state[8], |
340 | | const unsigned char *input_data, |
341 | | size_t num_blks); |
342 | | |
343 | | static unsigned int |
344 | | do_sha512_transform_i386_ssse3(void *ctx, const unsigned char *data, |
345 | | size_t nblks) |
346 | | { |
347 | | SHA512_CONTEXT *hd = ctx; |
348 | | return _gcry_sha512_transform_i386_ssse3 (hd->state.h, data, nblks); |
349 | | } |
350 | | #endif |
351 | | |
352 | | |
353 | | #ifdef USE_ARM_ASM |
354 | | unsigned int _gcry_sha512_transform_arm (SHA512_STATE *hd, |
355 | | const unsigned char *data, |
356 | | const u64 k[], size_t num_blks); |
357 | | |
358 | | static unsigned int |
359 | | do_transform_generic (void *context, const unsigned char *data, size_t nblks) |
360 | | { |
361 | | SHA512_CONTEXT *hd = context; |
362 | | return _gcry_sha512_transform_arm (&hd->state, data, k, nblks); |
363 | | } |
364 | | #else |
365 | | static unsigned int |
366 | | do_transform_generic (void *context, const unsigned char *data, size_t nblks); |
367 | | #endif |
368 | | |
369 | | |
370 | | #ifdef USE_PPC_CRYPTO |
371 | | unsigned int _gcry_sha512_transform_ppc8(u64 state[8], |
372 | | const unsigned char *input_data, |
373 | | size_t num_blks); |
374 | | |
375 | | unsigned int _gcry_sha512_transform_ppc9(u64 state[8], |
376 | | const unsigned char *input_data, |
377 | | size_t num_blks); |
378 | | |
379 | | static unsigned int |
380 | | do_sha512_transform_ppc8(void *ctx, const unsigned char *data, size_t nblks) |
381 | | { |
382 | | SHA512_CONTEXT *hd = ctx; |
383 | | return _gcry_sha512_transform_ppc8 (hd->state.h, data, nblks); |
384 | | } |
385 | | |
386 | | static unsigned int |
387 | | do_sha512_transform_ppc9(void *ctx, const unsigned char *data, size_t nblks) |
388 | | { |
389 | | SHA512_CONTEXT *hd = ctx; |
390 | | return _gcry_sha512_transform_ppc9 (hd->state.h, data, nblks); |
391 | | } |
392 | | #endif |
393 | | |
394 | | |
395 | | #ifdef USE_S390X_CRYPTO |
396 | | #include "asm-inline-s390x.h" |
397 | | |
398 | | static unsigned int |
399 | | do_sha512_transform_s390x (void *ctx, const unsigned char *data, size_t nblks) |
400 | | { |
401 | | SHA512_CONTEXT *hd = ctx; |
402 | | |
403 | | kimd_execute (KMID_FUNCTION_SHA512, hd->state.h, data, nblks * 128); |
404 | | return 0; |
405 | | } |
406 | | |
407 | | static unsigned int |
408 | | do_sha512_final_s390x (void *ctx, const unsigned char *data, size_t datalen, |
409 | | u64 len_msb, u64 len_lsb) |
410 | | { |
411 | | SHA512_CONTEXT *hd = ctx; |
412 | | |
413 | | /* Make sure that 'final_len' is positioned at correct offset relative |
414 | | * to 'state.h[0]'. This is because we are passing 'state.h[0]' pointer as |
415 | | * start of parameter block to 'klmd' instruction. */ |
416 | | |
417 | | gcry_assert (offsetof (SHA512_CONTEXT, final_len_msb) |
418 | | - offsetof (SHA512_CONTEXT, state.h[0]) == 8 * sizeof(u64)); |
419 | | gcry_assert (offsetof (SHA512_CONTEXT, final_len_lsb) |
420 | | - offsetof (SHA512_CONTEXT, final_len_msb) == 1 * sizeof(u64)); |
421 | | |
422 | | hd->final_len_msb = len_msb; |
423 | | hd->final_len_lsb = len_lsb; |
424 | | |
425 | | klmd_execute (KMID_FUNCTION_SHA512, hd->state.h, data, datalen); |
426 | | return 0; |
427 | | } |
428 | | #endif |
429 | | |
430 | | |
431 | | static void |
432 | | sha512_init_common (SHA512_CONTEXT *ctx, unsigned int flags) |
433 | 7.97k | { |
434 | 7.97k | unsigned int features = _gcry_get_hw_features (); |
435 | | |
436 | 7.97k | (void)flags; |
437 | 7.97k | (void)k; |
438 | | |
439 | 7.97k | ctx->bctx.nblocks = 0; |
440 | 7.97k | ctx->bctx.nblocks_high = 0; |
441 | 7.97k | ctx->bctx.count = 0; |
442 | 7.97k | ctx->bctx.blocksize_shift = _gcry_ctz(128); |
443 | | |
444 | | /* Order of feature checks is important here; last match will be |
445 | | * selected. Keep slower implementations at the top and faster at |
446 | | * the bottom. */ |
447 | 7.97k | ctx->bctx.bwrite = do_transform_generic; |
448 | | #ifdef USE_ARM_NEON_ASM |
449 | | if ((features & HWF_ARM_NEON) != 0) |
450 | | ctx->bctx.bwrite = do_sha512_transform_armv7_neon; |
451 | | #endif |
452 | | #ifdef USE_ARM64_SHA512 |
453 | | if ((features & HWF_ARM_NEON) && (features & HWF_ARM_SHA512)) |
454 | | ctx->bctx.bwrite = do_sha512_transform_armv8_ce; |
455 | | #endif |
456 | 7.97k | #ifdef USE_SSSE3 |
457 | 7.97k | if ((features & HWF_INTEL_SSSE3) != 0) |
458 | 7.97k | ctx->bctx.bwrite = do_sha512_transform_amd64_ssse3; |
459 | 7.97k | #endif |
460 | 7.97k | #ifdef USE_AVX |
461 | 7.97k | if ((features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD)) |
462 | 7.97k | ctx->bctx.bwrite = do_sha512_transform_amd64_avx; |
463 | 7.97k | #endif |
464 | 7.97k | #ifdef USE_AVX2 |
465 | 7.97k | if ((features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2)) |
466 | 7.97k | ctx->bctx.bwrite = do_sha512_transform_amd64_avx2; |
467 | 7.97k | #endif |
468 | 7.97k | #ifdef USE_AVX512 |
469 | 7.97k | if ((features & HWF_INTEL_AVX512) && (features & HWF_INTEL_CPU)) |
470 | 0 | ctx->bctx.bwrite = do_sha512_transform_amd64_avx512; |
471 | 7.97k | #endif |
472 | | #ifdef USE_PPC_CRYPTO |
473 | | if ((features & HWF_PPC_VCRYPTO) != 0) |
474 | | ctx->bctx.bwrite = do_sha512_transform_ppc8; |
475 | | if ((features & HWF_PPC_VCRYPTO) != 0 && (features & HWF_PPC_ARCH_3_00) != 0) |
476 | | ctx->bctx.bwrite = do_sha512_transform_ppc9; |
477 | | #endif |
478 | | #ifdef USE_SSSE3_I386 |
479 | | if ((features & HWF_INTEL_SSSE3) != 0) |
480 | | ctx->bctx.bwrite = do_sha512_transform_i386_ssse3; |
481 | | #endif |
482 | | #ifdef USE_S390X_CRYPTO |
483 | | ctx->use_s390x_crypto = 0; |
484 | | if ((features & HWF_S390X_MSA) != 0) |
485 | | { |
486 | | if ((kimd_query () & km_function_to_mask (KMID_FUNCTION_SHA512)) && |
487 | | (klmd_query () & km_function_to_mask (KMID_FUNCTION_SHA512))) |
488 | | { |
489 | | ctx->bctx.bwrite = do_sha512_transform_s390x; |
490 | | ctx->use_s390x_crypto = 1; |
491 | | } |
492 | | } |
493 | | #endif |
494 | 7.97k | (void)features; |
495 | 7.97k | } |
496 | | |
497 | | |
498 | | static void |
499 | | sha512_init (void *context, unsigned int flags) |
500 | 865 | { |
501 | 865 | SHA512_CONTEXT *ctx = context; |
502 | 865 | SHA512_STATE *hd = &ctx->state; |
503 | | |
504 | 865 | hd->h[0] = U64_C(0x6a09e667f3bcc908); |
505 | 865 | hd->h[1] = U64_C(0xbb67ae8584caa73b); |
506 | 865 | hd->h[2] = U64_C(0x3c6ef372fe94f82b); |
507 | 865 | hd->h[3] = U64_C(0xa54ff53a5f1d36f1); |
508 | 865 | hd->h[4] = U64_C(0x510e527fade682d1); |
509 | 865 | hd->h[5] = U64_C(0x9b05688c2b3e6c1f); |
510 | 865 | hd->h[6] = U64_C(0x1f83d9abfb41bd6b); |
511 | 865 | hd->h[7] = U64_C(0x5be0cd19137e2179); |
512 | | |
513 | 865 | sha512_init_common (ctx, flags); |
514 | 865 | } |
515 | | |
516 | | static void |
517 | | sha384_init (void *context, unsigned int flags) |
518 | 7.11k | { |
519 | 7.11k | SHA512_CONTEXT *ctx = context; |
520 | 7.11k | SHA512_STATE *hd = &ctx->state; |
521 | | |
522 | 7.11k | hd->h[0] = U64_C(0xcbbb9d5dc1059ed8); |
523 | 7.11k | hd->h[1] = U64_C(0x629a292a367cd507); |
524 | 7.11k | hd->h[2] = U64_C(0x9159015a3070dd17); |
525 | 7.11k | hd->h[3] = U64_C(0x152fecd8f70e5939); |
526 | 7.11k | hd->h[4] = U64_C(0x67332667ffc00b31); |
527 | 7.11k | hd->h[5] = U64_C(0x8eb44a8768581511); |
528 | 7.11k | hd->h[6] = U64_C(0xdb0c2e0d64f98fa7); |
529 | 7.11k | hd->h[7] = U64_C(0x47b5481dbefa4fa4); |
530 | | |
531 | 7.11k | sha512_init_common (ctx, flags); |
532 | 7.11k | } |
533 | | |
534 | | |
535 | | static void |
536 | | sha512_256_init (void *context, unsigned int flags) |
537 | 0 | { |
538 | 0 | SHA512_CONTEXT *ctx = context; |
539 | 0 | SHA512_STATE *hd = &ctx->state; |
540 | |
|
541 | 0 | hd->h[0] = U64_C(0x22312194fc2bf72c); |
542 | 0 | hd->h[1] = U64_C(0x9f555fa3c84c64c2); |
543 | 0 | hd->h[2] = U64_C(0x2393b86b6f53b151); |
544 | 0 | hd->h[3] = U64_C(0x963877195940eabd); |
545 | 0 | hd->h[4] = U64_C(0x96283ee2a88effe3); |
546 | 0 | hd->h[5] = U64_C(0xbe5e1e2553863992); |
547 | 0 | hd->h[6] = U64_C(0x2b0199fc2c85b8aa); |
548 | 0 | hd->h[7] = U64_C(0x0eb72ddc81c52ca2); |
549 | |
|
550 | 0 | sha512_init_common (ctx, flags); |
551 | 0 | } |
552 | | |
553 | | |
554 | | static void |
555 | | sha512_224_init (void *context, unsigned int flags) |
556 | 0 | { |
557 | 0 | SHA512_CONTEXT *ctx = context; |
558 | 0 | SHA512_STATE *hd = &ctx->state; |
559 | |
|
560 | 0 | hd->h[0] = U64_C(0x8c3d37c819544da2); |
561 | 0 | hd->h[1] = U64_C(0x73e1996689dcd4d6); |
562 | 0 | hd->h[2] = U64_C(0x1dfab7ae32ff9c82); |
563 | 0 | hd->h[3] = U64_C(0x679dd514582f9fcf); |
564 | 0 | hd->h[4] = U64_C(0x0f6d2b697bd44da8); |
565 | 0 | hd->h[5] = U64_C(0x77e36f7304c48942); |
566 | 0 | hd->h[6] = U64_C(0x3f9d85a86a1d36c8); |
567 | 0 | hd->h[7] = U64_C(0x1112e6ad91d692a1); |
568 | |
|
569 | 0 | sha512_init_common (ctx, flags); |
570 | 0 | } |
571 | | |
572 | | |
573 | | |
574 | | #ifndef USE_ARM_ASM |
575 | | |
576 | | static inline u64 |
577 | | ROTR (u64 x, u64 n) |
578 | 0 | { |
579 | 0 | return ((x >> n) | (x << (64 - n))); |
580 | 0 | } |
581 | | |
582 | | static inline u64 |
583 | | Ch (u64 x, u64 y, u64 z) |
584 | 0 | { |
585 | 0 | return ((x & y) ^ ( ~x & z)); |
586 | 0 | } |
587 | | |
588 | | static inline u64 |
589 | | Maj (u64 x, u64 y, u64 z) |
590 | 0 | { |
591 | 0 | return ((x & y) ^ (x & z) ^ (y & z)); |
592 | 0 | } |
593 | | |
594 | | static inline u64 |
595 | | Sum0 (u64 x) |
596 | 0 | { |
597 | 0 | return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39)); |
598 | 0 | } |
599 | | |
600 | | static inline u64 |
601 | | Sum1 (u64 x) |
602 | 0 | { |
603 | 0 | return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41)); |
604 | 0 | } |
605 | | |
606 | | /**************** |
607 | | * Transform the message W which consists of 16 64-bit-words |
608 | | */ |
609 | | static unsigned int |
610 | | do_transform_generic (void *context, const unsigned char *data, size_t nblks) |
611 | 0 | { |
612 | 0 | SHA512_CONTEXT *ctx = context; |
613 | 0 | SHA512_STATE *hd = &ctx->state; |
614 | |
|
615 | 0 | do |
616 | 0 | { |
617 | 0 | u64 a, b, c, d, e, f, g, h; |
618 | 0 | u64 w[16]; |
619 | 0 | int t; |
620 | | |
621 | | /* get values from the chaining vars */ |
622 | 0 | a = hd->h[0]; |
623 | 0 | b = hd->h[1]; |
624 | 0 | c = hd->h[2]; |
625 | 0 | d = hd->h[3]; |
626 | 0 | e = hd->h[4]; |
627 | 0 | f = hd->h[5]; |
628 | 0 | g = hd->h[6]; |
629 | 0 | h = hd->h[7]; |
630 | |
|
631 | 0 | for ( t = 0; t < 16; t++ ) |
632 | 0 | w[t] = buf_get_be64(data + t * 8); |
633 | |
|
634 | 0 | #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) |
635 | 0 | #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) |
636 | |
|
637 | 0 | for (t = 0; t < 80 - 16; ) |
638 | 0 | { |
639 | 0 | u64 t1, t2; |
640 | |
|
641 | 0 | t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0]; |
642 | 0 | w[0] += S1 (w[14]) + w[9] + S0 (w[1]); |
643 | 0 | t2 = Sum0 (a) + Maj (a, b, c); |
644 | 0 | d += t1; |
645 | 0 | h = t1 + t2; |
646 | |
|
647 | 0 | t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1]; |
648 | 0 | w[1] += S1 (w[15]) + w[10] + S0 (w[2]); |
649 | 0 | t2 = Sum0 (h) + Maj (h, a, b); |
650 | 0 | c += t1; |
651 | 0 | g = t1 + t2; |
652 | |
|
653 | 0 | t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2]; |
654 | 0 | w[2] += S1 (w[0]) + w[11] + S0 (w[3]); |
655 | 0 | t2 = Sum0 (g) + Maj (g, h, a); |
656 | 0 | b += t1; |
657 | 0 | f = t1 + t2; |
658 | |
|
659 | 0 | t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3]; |
660 | 0 | w[3] += S1 (w[1]) + w[12] + S0 (w[4]); |
661 | 0 | t2 = Sum0 (f) + Maj (f, g, h); |
662 | 0 | a += t1; |
663 | 0 | e = t1 + t2; |
664 | |
|
665 | 0 | t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4]; |
666 | 0 | w[4] += S1 (w[2]) + w[13] + S0 (w[5]); |
667 | 0 | t2 = Sum0 (e) + Maj (e, f, g); |
668 | 0 | h += t1; |
669 | 0 | d = t1 + t2; |
670 | |
|
671 | 0 | t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5]; |
672 | 0 | w[5] += S1 (w[3]) + w[14] + S0 (w[6]); |
673 | 0 | t2 = Sum0 (d) + Maj (d, e, f); |
674 | 0 | g += t1; |
675 | 0 | c = t1 + t2; |
676 | |
|
677 | 0 | t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6]; |
678 | 0 | w[6] += S1 (w[4]) + w[15] + S0 (w[7]); |
679 | 0 | t2 = Sum0 (c) + Maj (c, d, e); |
680 | 0 | f += t1; |
681 | 0 | b = t1 + t2; |
682 | |
|
683 | 0 | t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7]; |
684 | 0 | w[7] += S1 (w[5]) + w[0] + S0 (w[8]); |
685 | 0 | t2 = Sum0 (b) + Maj (b, c, d); |
686 | 0 | e += t1; |
687 | 0 | a = t1 + t2; |
688 | |
|
689 | 0 | t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8]; |
690 | 0 | w[8] += S1 (w[6]) + w[1] + S0 (w[9]); |
691 | 0 | t2 = Sum0 (a) + Maj (a, b, c); |
692 | 0 | d += t1; |
693 | 0 | h = t1 + t2; |
694 | |
|
695 | 0 | t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9]; |
696 | 0 | w[9] += S1 (w[7]) + w[2] + S0 (w[10]); |
697 | 0 | t2 = Sum0 (h) + Maj (h, a, b); |
698 | 0 | c += t1; |
699 | 0 | g = t1 + t2; |
700 | |
|
701 | 0 | t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10]; |
702 | 0 | w[10] += S1 (w[8]) + w[3] + S0 (w[11]); |
703 | 0 | t2 = Sum0 (g) + Maj (g, h, a); |
704 | 0 | b += t1; |
705 | 0 | f = t1 + t2; |
706 | |
|
707 | 0 | t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11]; |
708 | 0 | w[11] += S1 (w[9]) + w[4] + S0 (w[12]); |
709 | 0 | t2 = Sum0 (f) + Maj (f, g, h); |
710 | 0 | a += t1; |
711 | 0 | e = t1 + t2; |
712 | |
|
713 | 0 | t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12]; |
714 | 0 | w[12] += S1 (w[10]) + w[5] + S0 (w[13]); |
715 | 0 | t2 = Sum0 (e) + Maj (e, f, g); |
716 | 0 | h += t1; |
717 | 0 | d = t1 + t2; |
718 | |
|
719 | 0 | t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13]; |
720 | 0 | w[13] += S1 (w[11]) + w[6] + S0 (w[14]); |
721 | 0 | t2 = Sum0 (d) + Maj (d, e, f); |
722 | 0 | g += t1; |
723 | 0 | c = t1 + t2; |
724 | |
|
725 | 0 | t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14]; |
726 | 0 | w[14] += S1 (w[12]) + w[7] + S0 (w[15]); |
727 | 0 | t2 = Sum0 (c) + Maj (c, d, e); |
728 | 0 | f += t1; |
729 | 0 | b = t1 + t2; |
730 | |
|
731 | 0 | t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15]; |
732 | 0 | w[15] += S1 (w[13]) + w[8] + S0 (w[0]); |
733 | 0 | t2 = Sum0 (b) + Maj (b, c, d); |
734 | 0 | e += t1; |
735 | 0 | a = t1 + t2; |
736 | |
|
737 | 0 | t += 16; |
738 | 0 | } |
739 | |
|
740 | 0 | for (; t < 80; ) |
741 | 0 | { |
742 | 0 | u64 t1, t2; |
743 | |
|
744 | 0 | t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0]; |
745 | 0 | t2 = Sum0 (a) + Maj (a, b, c); |
746 | 0 | d += t1; |
747 | 0 | h = t1 + t2; |
748 | |
|
749 | 0 | t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1]; |
750 | 0 | t2 = Sum0 (h) + Maj (h, a, b); |
751 | 0 | c += t1; |
752 | 0 | g = t1 + t2; |
753 | |
|
754 | 0 | t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2]; |
755 | 0 | t2 = Sum0 (g) + Maj (g, h, a); |
756 | 0 | b += t1; |
757 | 0 | f = t1 + t2; |
758 | |
|
759 | 0 | t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3]; |
760 | 0 | t2 = Sum0 (f) + Maj (f, g, h); |
761 | 0 | a += t1; |
762 | 0 | e = t1 + t2; |
763 | |
|
764 | 0 | t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4]; |
765 | 0 | t2 = Sum0 (e) + Maj (e, f, g); |
766 | 0 | h += t1; |
767 | 0 | d = t1 + t2; |
768 | |
|
769 | 0 | t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5]; |
770 | 0 | t2 = Sum0 (d) + Maj (d, e, f); |
771 | 0 | g += t1; |
772 | 0 | c = t1 + t2; |
773 | |
|
774 | 0 | t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6]; |
775 | 0 | t2 = Sum0 (c) + Maj (c, d, e); |
776 | 0 | f += t1; |
777 | 0 | b = t1 + t2; |
778 | |
|
779 | 0 | t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7]; |
780 | 0 | t2 = Sum0 (b) + Maj (b, c, d); |
781 | 0 | e += t1; |
782 | 0 | a = t1 + t2; |
783 | |
|
784 | 0 | t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8]; |
785 | 0 | t2 = Sum0 (a) + Maj (a, b, c); |
786 | 0 | d += t1; |
787 | 0 | h = t1 + t2; |
788 | |
|
789 | 0 | t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9]; |
790 | 0 | t2 = Sum0 (h) + Maj (h, a, b); |
791 | 0 | c += t1; |
792 | 0 | g = t1 + t2; |
793 | |
|
794 | 0 | t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10]; |
795 | 0 | t2 = Sum0 (g) + Maj (g, h, a); |
796 | 0 | b += t1; |
797 | 0 | f = t1 + t2; |
798 | |
|
799 | 0 | t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11]; |
800 | 0 | t2 = Sum0 (f) + Maj (f, g, h); |
801 | 0 | a += t1; |
802 | 0 | e = t1 + t2; |
803 | |
|
804 | 0 | t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12]; |
805 | 0 | t2 = Sum0 (e) + Maj (e, f, g); |
806 | 0 | h += t1; |
807 | 0 | d = t1 + t2; |
808 | |
|
809 | 0 | t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13]; |
810 | 0 | t2 = Sum0 (d) + Maj (d, e, f); |
811 | 0 | g += t1; |
812 | 0 | c = t1 + t2; |
813 | |
|
814 | 0 | t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14]; |
815 | 0 | t2 = Sum0 (c) + Maj (c, d, e); |
816 | 0 | f += t1; |
817 | 0 | b = t1 + t2; |
818 | |
|
819 | 0 | t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15]; |
820 | 0 | t2 = Sum0 (b) + Maj (b, c, d); |
821 | 0 | e += t1; |
822 | 0 | a = t1 + t2; |
823 | |
|
824 | 0 | t += 16; |
825 | 0 | } |
826 | | |
827 | | /* Update chaining vars. */ |
828 | 0 | hd->h[0] += a; |
829 | 0 | hd->h[1] += b; |
830 | 0 | hd->h[2] += c; |
831 | 0 | hd->h[3] += d; |
832 | 0 | hd->h[4] += e; |
833 | 0 | hd->h[5] += f; |
834 | 0 | hd->h[6] += g; |
835 | 0 | hd->h[7] += h; |
836 | |
|
837 | 0 | data += 128; |
838 | 0 | } |
839 | 0 | while (--nblks); |
840 | |
|
841 | 0 | return (8 + 16) * sizeof(u64) + sizeof(u32) + 3 * sizeof(void*); |
842 | 0 | } |
843 | | #endif /*!USE_ARM_ASM*/ |
844 | | |
845 | | |
846 | | /* The routine final terminates the computation and |
847 | | * returns the digest. |
848 | | * The handle is prepared for a new cycle, but adding bytes to the |
849 | | * handle will the destroy the returned buffer. |
850 | | * Returns: 64 bytes representing the digest. When used for sha384, |
851 | | * we take the leftmost 48 of those bytes. |
852 | | */ |
853 | | |
854 | | static void |
855 | | sha512_final (void *context) |
856 | 0 | { |
857 | 0 | SHA512_CONTEXT *hd = context; |
858 | 0 | unsigned int burn; |
859 | 0 | u64 t, th, msb, lsb; |
860 | 0 | byte *p; |
861 | |
|
862 | 0 | t = hd->bctx.nblocks; |
863 | | /* if (sizeof t == sizeof hd->bctx.nblocks) */ |
864 | 0 | th = hd->bctx.nblocks_high; |
865 | | /* else */ |
866 | | /* th = hd->bctx.nblocks >> 64; In case we ever use u128 */ |
867 | | |
868 | | /* multiply by 128 to make a byte count */ |
869 | 0 | lsb = t << 7; |
870 | 0 | msb = (th << 7) | (t >> 57); |
871 | | /* add the count */ |
872 | 0 | t = lsb; |
873 | 0 | if ((lsb += hd->bctx.count) < t) |
874 | 0 | msb++; |
875 | | /* multiply by 8 to make a bit count */ |
876 | 0 | t = lsb; |
877 | 0 | lsb <<= 3; |
878 | 0 | msb <<= 3; |
879 | 0 | msb |= t >> 61; |
880 | |
|
881 | 0 | if (0) |
882 | 0 | { } |
883 | | #ifdef USE_S390X_CRYPTO |
884 | | else if (hd->use_s390x_crypto) |
885 | | { |
886 | | burn = do_sha512_final_s390x (hd, hd->bctx.buf, hd->bctx.count, msb, lsb); |
887 | | } |
888 | | #endif |
889 | 0 | else |
890 | 0 | { |
891 | 0 | if (hd->bctx.count < 112) |
892 | 0 | { |
893 | | /* enough room */ |
894 | 0 | hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ |
895 | 0 | if (hd->bctx.count < 112) |
896 | 0 | memset (&hd->bctx.buf[hd->bctx.count], 0, 112 - hd->bctx.count); |
897 | 0 | } |
898 | 0 | else |
899 | 0 | { |
900 | | /* need one extra block */ |
901 | 0 | hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ |
902 | 0 | if (hd->bctx.count < 128) |
903 | 0 | memset (&hd->bctx.buf[hd->bctx.count], 0, 128 - hd->bctx.count); |
904 | 0 | hd->bctx.count = 128; |
905 | 0 | _gcry_md_block_write (context, NULL, 0); /* flush */ |
906 | 0 | memset (hd->bctx.buf, 0, 112); /* fill next block with zeroes */ |
907 | 0 | } |
908 | | /* append the 128 bit count */ |
909 | 0 | buf_put_be64(hd->bctx.buf + 112, msb); |
910 | 0 | buf_put_be64(hd->bctx.buf + 120, lsb); |
911 | 0 | burn = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 1); |
912 | 0 | } |
913 | |
|
914 | 0 | p = hd->bctx.buf; |
915 | 0 | #define X(a) do { buf_put_be64(p, hd->state.h[a]); p += 8; } while (0) |
916 | 0 | X (0); |
917 | 0 | X (1); |
918 | 0 | X (2); |
919 | 0 | X (3); |
920 | 0 | X (4); |
921 | 0 | X (5); |
922 | | /* Note that these last two chunks are included even for SHA384. |
923 | | We just ignore them. */ |
924 | 0 | X (6); |
925 | 0 | X (7); |
926 | 0 | #undef X |
927 | |
|
928 | 0 | hd->bctx.count = 0; |
929 | |
|
930 | 0 | _gcry_burn_stack (burn); |
931 | 0 | } |
932 | | |
933 | | static byte * |
934 | | sha512_read (void *context) |
935 | 0 | { |
936 | 0 | SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context; |
937 | 0 | return hd->bctx.buf; |
938 | 0 | } |
939 | | |
940 | | |
941 | | /* Shortcut functions which puts the hash value of the supplied buffer iov |
942 | | * into outbuf which must have a size of 64 bytes. */ |
943 | | static void |
944 | | _gcry_sha512_hash_buffers (void *outbuf, size_t nbytes, |
945 | | const gcry_buffer_t *iov, int iovcnt) |
946 | 0 | { |
947 | 0 | SHA512_CONTEXT hd; |
948 | |
|
949 | 0 | (void)nbytes; |
950 | |
|
951 | 0 | sha512_init (&hd, 0); |
952 | 0 | for (;iovcnt > 0; iov++, iovcnt--) |
953 | 0 | _gcry_md_block_write (&hd, |
954 | 0 | (const char*)iov[0].data + iov[0].off, iov[0].len); |
955 | 0 | sha512_final (&hd); |
956 | 0 | memcpy (outbuf, hd.bctx.buf, 64); |
957 | 0 | } |
958 | | |
959 | | |
960 | | |
961 | | /* Shortcut functions which puts the hash value of the supplied buffer iov |
962 | | * into outbuf which must have a size of 48 bytes. */ |
963 | | static void |
964 | | _gcry_sha384_hash_buffers (void *outbuf, size_t nbytes, |
965 | | const gcry_buffer_t *iov, int iovcnt) |
966 | 0 | { |
967 | 0 | SHA512_CONTEXT hd; |
968 | |
|
969 | 0 | (void)nbytes; |
970 | |
|
971 | 0 | sha384_init (&hd, 0); |
972 | 0 | for (;iovcnt > 0; iov++, iovcnt--) |
973 | 0 | _gcry_md_block_write (&hd, |
974 | 0 | (const char*)iov[0].data + iov[0].off, iov[0].len); |
975 | 0 | sha512_final (&hd); |
976 | 0 | memcpy (outbuf, hd.bctx.buf, 48); |
977 | 0 | } |
978 | | |
979 | | |
980 | | |
981 | | /* Shortcut functions which puts the hash value of the supplied buffer iov |
982 | | * into outbuf which must have a size of 32 bytes. */ |
983 | | static void |
984 | | _gcry_sha512_256_hash_buffers (void *outbuf, size_t nbytes, |
985 | | const gcry_buffer_t *iov, int iovcnt) |
986 | 0 | { |
987 | 0 | SHA512_CONTEXT hd; |
988 | |
|
989 | 0 | (void)nbytes; |
990 | |
|
991 | 0 | sha512_256_init (&hd, 0); |
992 | 0 | for (;iovcnt > 0; iov++, iovcnt--) |
993 | 0 | _gcry_md_block_write (&hd, |
994 | 0 | (const char*)iov[0].data + iov[0].off, iov[0].len); |
995 | 0 | sha512_final (&hd); |
996 | 0 | memcpy (outbuf, hd.bctx.buf, 32); |
997 | 0 | } |
998 | | |
999 | | |
1000 | | |
1001 | | /* Shortcut functions which puts the hash value of the supplied buffer iov |
1002 | | * into outbuf which must have a size of 28 bytes. */ |
1003 | | static void |
1004 | | _gcry_sha512_224_hash_buffers (void *outbuf, size_t nbytes, |
1005 | | const gcry_buffer_t *iov, int iovcnt) |
1006 | 0 | { |
1007 | 0 | SHA512_CONTEXT hd; |
1008 | |
|
1009 | 0 | (void)nbytes; |
1010 | |
|
1011 | 0 | sha512_224_init (&hd, 0); |
1012 | 0 | for (;iovcnt > 0; iov++, iovcnt--) |
1013 | 0 | _gcry_md_block_write (&hd, |
1014 | 0 | (const char*)iov[0].data + iov[0].off, iov[0].len); |
1015 | 0 | sha512_final (&hd); |
1016 | 0 | memcpy (outbuf, hd.bctx.buf, 28); |
1017 | 0 | } |
1018 | | |
1019 | | |
1020 | | |
1021 | | /* |
1022 | | Self-test section. |
1023 | | */ |
1024 | | |
1025 | | |
1026 | | static gpg_err_code_t |
1027 | | selftests_sha384 (int extended, selftest_report_func_t report) |
1028 | 0 | { |
1029 | 0 | const char *what; |
1030 | 0 | const char *errtxt; |
1031 | |
|
1032 | 0 | what = "short string"; |
1033 | 0 | errtxt = _gcry_hash_selftest_check_one |
1034 | 0 | (GCRY_MD_SHA384, 0, |
1035 | 0 | "abc", 3, |
1036 | 0 | "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07" |
1037 | 0 | "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed" |
1038 | 0 | "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7", 48); |
1039 | 0 | if (errtxt) |
1040 | 0 | goto failed; |
1041 | | |
1042 | 0 | if (extended) |
1043 | 0 | { |
1044 | 0 | what = "long string"; |
1045 | 0 | errtxt = _gcry_hash_selftest_check_one |
1046 | 0 | (GCRY_MD_SHA384, 0, |
1047 | 0 | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" |
1048 | 0 | "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, |
1049 | 0 | "\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47" |
1050 | 0 | "\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12" |
1051 | 0 | "\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39", |
1052 | 0 | 48); |
1053 | 0 | if (errtxt) |
1054 | 0 | goto failed; |
1055 | | |
1056 | 0 | what = "one million \"a\""; |
1057 | 0 | errtxt = _gcry_hash_selftest_check_one |
1058 | 0 | (GCRY_MD_SHA384, 1, |
1059 | 0 | NULL, 0, |
1060 | 0 | "\x9D\x0E\x18\x09\x71\x64\x74\xCB\x08\x6E\x83\x4E\x31\x0A\x4A\x1C" |
1061 | 0 | "\xED\x14\x9E\x9C\x00\xF2\x48\x52\x79\x72\xCE\xC5\x70\x4C\x2A\x5B" |
1062 | 0 | "\x07\xB8\xB3\xDC\x38\xEC\xC4\xEB\xAE\x97\xDD\xD8\x7F\x3D\x89\x85", |
1063 | 0 | 48); |
1064 | 0 | if (errtxt) |
1065 | 0 | goto failed; |
1066 | 0 | } |
1067 | | |
1068 | 0 | return 0; /* Succeeded. */ |
1069 | | |
1070 | 0 | failed: |
1071 | 0 | if (report) |
1072 | 0 | report ("digest", GCRY_MD_SHA384, what, errtxt); |
1073 | 0 | return GPG_ERR_SELFTEST_FAILED; |
1074 | 0 | } |
1075 | | |
1076 | | static gpg_err_code_t |
1077 | | selftests_sha512 (int extended, selftest_report_func_t report) |
1078 | 0 | { |
1079 | 0 | const char *what; |
1080 | 0 | const char *errtxt; |
1081 | |
|
1082 | 0 | what = "short string"; |
1083 | 0 | errtxt = _gcry_hash_selftest_check_one |
1084 | 0 | (GCRY_MD_SHA512, 0, |
1085 | 0 | "abc", 3, |
1086 | 0 | "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31" |
1087 | 0 | "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A" |
1088 | 0 | "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD" |
1089 | 0 | "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F", 64); |
1090 | 0 | if (errtxt) |
1091 | 0 | goto failed; |
1092 | | |
1093 | 0 | if (extended) |
1094 | 0 | { |
1095 | 0 | what = "long string"; |
1096 | 0 | errtxt = _gcry_hash_selftest_check_one |
1097 | 0 | (GCRY_MD_SHA512, 0, |
1098 | 0 | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" |
1099 | 0 | "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, |
1100 | 0 | "\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F" |
1101 | 0 | "\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18" |
1102 | 0 | "\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A" |
1103 | 0 | "\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09", |
1104 | 0 | 64); |
1105 | 0 | if (errtxt) |
1106 | 0 | goto failed; |
1107 | | |
1108 | 0 | what = "one million \"a\""; |
1109 | 0 | errtxt = _gcry_hash_selftest_check_one |
1110 | 0 | (GCRY_MD_SHA512, 1, |
1111 | 0 | NULL, 0, |
1112 | 0 | "\xE7\x18\x48\x3D\x0C\xE7\x69\x64\x4E\x2E\x42\xC7\xBC\x15\xB4\x63" |
1113 | 0 | "\x8E\x1F\x98\xB1\x3B\x20\x44\x28\x56\x32\xA8\x03\xAF\xA9\x73\xEB" |
1114 | 0 | "\xDE\x0F\xF2\x44\x87\x7E\xA6\x0A\x4C\xB0\x43\x2C\xE5\x77\xC3\x1B" |
1115 | 0 | "\xEB\x00\x9C\x5C\x2C\x49\xAA\x2E\x4E\xAD\xB2\x17\xAD\x8C\xC0\x9B", |
1116 | 0 | 64); |
1117 | 0 | if (errtxt) |
1118 | 0 | goto failed; |
1119 | 0 | } |
1120 | | |
1121 | 0 | return 0; /* Succeeded. */ |
1122 | | |
1123 | 0 | failed: |
1124 | 0 | if (report) |
1125 | 0 | report ("digest", GCRY_MD_SHA512, what, errtxt); |
1126 | 0 | return GPG_ERR_SELFTEST_FAILED; |
1127 | 0 | } |
1128 | | |
1129 | | static gpg_err_code_t |
1130 | | selftests_sha512_224 (int extended, selftest_report_func_t report) |
1131 | 0 | { |
1132 | 0 | const char *what; |
1133 | 0 | const char *errtxt; |
1134 | |
|
1135 | 0 | what = "short string"; |
1136 | 0 | errtxt = _gcry_hash_selftest_check_one |
1137 | 0 | (GCRY_MD_SHA512_224, 0, |
1138 | 0 | "abc", 3, |
1139 | 0 | "\x46\x34\x27\x0F\x70\x7B\x6A\x54\xDA\xAE\x75\x30\x46\x08\x42\xE2" |
1140 | 0 | "\x0E\x37\xED\x26\x5C\xEE\xE9\xA4\x3E\x89\x24\xAA", |
1141 | 0 | 28); |
1142 | 0 | if (errtxt) |
1143 | 0 | goto failed; |
1144 | | |
1145 | 0 | if (extended) |
1146 | 0 | { |
1147 | 0 | what = "long string"; |
1148 | 0 | errtxt = _gcry_hash_selftest_check_one |
1149 | 0 | (GCRY_MD_SHA512_224, 0, |
1150 | 0 | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" |
1151 | 0 | "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, |
1152 | 0 | "\x23\xFE\xC5\xBB\x94\xD6\x0B\x23\x30\x81\x92\x64\x0B\x0C\x45\x33" |
1153 | 0 | "\x35\xD6\x64\x73\x4F\xE4\x0E\x72\x68\x67\x4A\xF9", |
1154 | 0 | 28); |
1155 | 0 | if (errtxt) |
1156 | 0 | goto failed; |
1157 | | |
1158 | 0 | what = "one million \"a\""; |
1159 | 0 | errtxt = _gcry_hash_selftest_check_one |
1160 | 0 | (GCRY_MD_SHA512_224, 1, |
1161 | 0 | NULL, 0, |
1162 | 0 | "\x37\xab\x33\x1d\x76\xf0\xd3\x6d\xe4\x22\xbd\x0e\xde\xb2\x2a\x28" |
1163 | 0 | "\xac\xcd\x48\x7b\x7a\x84\x53\xae\x96\x5d\xd2\x87", |
1164 | 0 | 28); |
1165 | 0 | if (errtxt) |
1166 | 0 | goto failed; |
1167 | 0 | } |
1168 | | |
1169 | 0 | return 0; /* Succeeded. */ |
1170 | | |
1171 | 0 | failed: |
1172 | 0 | if (report) |
1173 | 0 | report ("digest", GCRY_MD_SHA512_224, what, errtxt); |
1174 | 0 | return GPG_ERR_SELFTEST_FAILED; |
1175 | 0 | } |
1176 | | |
1177 | | static gpg_err_code_t |
1178 | | selftests_sha512_256 (int extended, selftest_report_func_t report) |
1179 | 0 | { |
1180 | 0 | const char *what; |
1181 | 0 | const char *errtxt; |
1182 | |
|
1183 | 0 | what = "short string"; |
1184 | 0 | errtxt = _gcry_hash_selftest_check_one |
1185 | 0 | (GCRY_MD_SHA512_256, 0, |
1186 | 0 | "abc", 3, |
1187 | 0 | "\x53\x04\x8E\x26\x81\x94\x1E\xF9\x9B\x2E\x29\xB7\x6B\x4C\x7D\xAB" |
1188 | 0 | "\xE4\xC2\xD0\xC6\x34\xFC\x6D\x46\xE0\xE2\xF1\x31\x07\xE7\xAF\x23", |
1189 | 0 | 32); |
1190 | 0 | if (errtxt) |
1191 | 0 | goto failed; |
1192 | | |
1193 | 0 | if (extended) |
1194 | 0 | { |
1195 | 0 | what = "long string"; |
1196 | 0 | errtxt = _gcry_hash_selftest_check_one |
1197 | 0 | (GCRY_MD_SHA512_256, 0, |
1198 | 0 | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" |
1199 | 0 | "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, |
1200 | 0 | "\x39\x28\xE1\x84\xFB\x86\x90\xF8\x40\xDA\x39\x88\x12\x1D\x31\xBE" |
1201 | 0 | "\x65\xCB\x9D\x3E\xF8\x3E\xE6\x14\x6F\xEA\xC8\x61\xE1\x9B\x56\x3A", |
1202 | 0 | 32); |
1203 | 0 | if (errtxt) |
1204 | 0 | goto failed; |
1205 | | |
1206 | 0 | what = "one million \"a\""; |
1207 | 0 | errtxt = _gcry_hash_selftest_check_one |
1208 | 0 | (GCRY_MD_SHA512_256, 1, |
1209 | 0 | NULL, 0, |
1210 | 0 | "\x9a\x59\xa0\x52\x93\x01\x87\xa9\x70\x38\xca\xe6\x92\xf3\x07\x08" |
1211 | 0 | "\xaa\x64\x91\x92\x3e\xf5\x19\x43\x94\xdc\x68\xd5\x6c\x74\xfb\x21", |
1212 | 0 | 32); |
1213 | 0 | if (errtxt) |
1214 | 0 | goto failed; |
1215 | 0 | } |
1216 | | |
1217 | 0 | return 0; /* Succeeded. */ |
1218 | | |
1219 | 0 | failed: |
1220 | 0 | if (report) |
1221 | 0 | report ("digest", GCRY_MD_SHA512_256, what, errtxt); |
1222 | 0 | return GPG_ERR_SELFTEST_FAILED; |
1223 | 0 | } |
1224 | | |
1225 | | |
1226 | | /* Run a full self-test for ALGO and return 0 on success. */ |
1227 | | static gpg_err_code_t |
1228 | | run_selftests (int algo, int extended, selftest_report_func_t report) |
1229 | 0 | { |
1230 | 0 | gpg_err_code_t ec; |
1231 | |
|
1232 | 0 | switch (algo) |
1233 | 0 | { |
1234 | 0 | case GCRY_MD_SHA384: |
1235 | 0 | ec = selftests_sha384 (extended, report); |
1236 | 0 | break; |
1237 | 0 | case GCRY_MD_SHA512: |
1238 | 0 | ec = selftests_sha512 (extended, report); |
1239 | 0 | break; |
1240 | 0 | case GCRY_MD_SHA512_224: |
1241 | 0 | ec = selftests_sha512_224 (extended, report); |
1242 | 0 | break; |
1243 | 0 | case GCRY_MD_SHA512_256: |
1244 | 0 | ec = selftests_sha512_256 (extended, report); |
1245 | 0 | break; |
1246 | 0 | default: |
1247 | 0 | ec = GPG_ERR_DIGEST_ALGO; |
1248 | 0 | break; |
1249 | |
|
1250 | 0 | } |
1251 | 0 | return ec; |
1252 | 0 | } |
1253 | | |
1254 | | |
1255 | | |
1256 | | |
1257 | | static const byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */ |
1258 | | { |
1259 | | 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, |
1260 | | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, |
1261 | | 0x00, 0x04, 0x40 |
1262 | | }; |
1263 | | |
1264 | | static const gcry_md_oid_spec_t oid_spec_sha512[] = |
1265 | | { |
1266 | | { "2.16.840.1.101.3.4.2.3" }, |
1267 | | |
1268 | | /* PKCS#1 sha512WithRSAEncryption */ |
1269 | | { "1.2.840.113549.1.1.13" }, |
1270 | | /* ANSI X9.62 ecdsaWithSHA512 */ |
1271 | | { "1.2.840.10045.4.3.4" }, |
1272 | | |
1273 | | { NULL } |
1274 | | }; |
1275 | | |
1276 | | const gcry_md_spec_t _gcry_digest_spec_sha512 = |
1277 | | { |
1278 | | GCRY_MD_SHA512, {0, 1}, |
1279 | | "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64, |
1280 | | sha512_init, _gcry_md_block_write, sha512_final, sha512_read, NULL, |
1281 | | _gcry_sha512_hash_buffers, |
1282 | | sizeof (SHA512_CONTEXT), |
1283 | | run_selftests |
1284 | | }; |
1285 | | |
1286 | | static const byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */ |
1287 | | { |
1288 | | 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, |
1289 | | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, |
1290 | | 0x00, 0x04, 0x30 |
1291 | | }; |
1292 | | |
1293 | | static const gcry_md_oid_spec_t oid_spec_sha384[] = |
1294 | | { |
1295 | | { "2.16.840.1.101.3.4.2.2" }, |
1296 | | |
1297 | | /* PKCS#1 sha384WithRSAEncryption */ |
1298 | | { "1.2.840.113549.1.1.12" }, |
1299 | | |
1300 | | /* SHA384WithECDSA: RFC 7427 (A.3.3.) */ |
1301 | | { "1.2.840.10045.4.3.3" }, |
1302 | | |
1303 | | /* ANSI X9.62 ecdsaWithSHA384 */ |
1304 | | { "1.2.840.10045.4.3.3" }, |
1305 | | |
1306 | | { NULL }, |
1307 | | }; |
1308 | | |
1309 | | const gcry_md_spec_t _gcry_digest_spec_sha384 = |
1310 | | { |
1311 | | GCRY_MD_SHA384, {0, 1}, |
1312 | | "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48, |
1313 | | sha384_init, _gcry_md_block_write, sha512_final, sha512_read, NULL, |
1314 | | _gcry_sha384_hash_buffers, |
1315 | | sizeof (SHA512_CONTEXT), |
1316 | | run_selftests |
1317 | | }; |
1318 | | |
1319 | | static const byte sha512_256_asn[] = |
1320 | | { |
1321 | | 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, |
1322 | | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x06, 0x05, |
1323 | | 0x00, 0x04, 0x20 |
1324 | | }; |
1325 | | |
1326 | | static const gcry_md_oid_spec_t oid_spec_sha512_256[] = |
1327 | | { |
1328 | | { "2.16.840.1.101.3.4.2.6" }, |
1329 | | |
1330 | | { NULL }, |
1331 | | }; |
1332 | | |
1333 | | const gcry_md_spec_t _gcry_digest_spec_sha512_256 = |
1334 | | { |
1335 | | GCRY_MD_SHA512_256, {0, 1}, |
1336 | | "SHA512_256", sha512_256_asn, DIM (sha512_256_asn), oid_spec_sha512_256, 32, |
1337 | | sha512_256_init, _gcry_md_block_write, sha512_final, sha512_read, NULL, |
1338 | | _gcry_sha512_256_hash_buffers, |
1339 | | sizeof (SHA512_CONTEXT), |
1340 | | run_selftests |
1341 | | }; |
1342 | | |
1343 | | static const byte sha512_224_asn[] = |
1344 | | { |
1345 | | 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, |
1346 | | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05, 0x05, |
1347 | | 0x00, 0x04, 0x1c |
1348 | | }; |
1349 | | |
1350 | | static const gcry_md_oid_spec_t oid_spec_sha512_224[] = |
1351 | | { |
1352 | | { "2.16.840.1.101.3.4.2.5" }, |
1353 | | |
1354 | | { NULL }, |
1355 | | }; |
1356 | | |
1357 | | const gcry_md_spec_t _gcry_digest_spec_sha512_224 = |
1358 | | { |
1359 | | GCRY_MD_SHA512_224, {0, 1}, |
1360 | | "SHA512_224", sha512_224_asn, DIM (sha512_224_asn), oid_spec_sha512_224, 28, |
1361 | | sha512_224_init, _gcry_md_block_write, sha512_final, sha512_read, NULL, |
1362 | | _gcry_sha512_224_hash_buffers, |
1363 | | sizeof (SHA512_CONTEXT), |
1364 | | run_selftests |
1365 | | }; |