1 | /***************************************************************************
|
---|
2 | * _ _ ____ _
|
---|
3 | * Project ___| | | | _ \| |
|
---|
4 | * / __| | | | |_) | |
|
---|
5 | * | (__| |_| | _ <| |___
|
---|
6 | * \___|\___/|_| \_\_____|
|
---|
7 | *
|
---|
8 | * Copyright (C) Evgeny Grin (Karlson2k), <k2k@narod.ru>.
|
---|
9 | *
|
---|
10 | * This software is licensed as described in the file COPYING, which
|
---|
11 | * you should have received as part of this distribution. The terms
|
---|
12 | * are also available at https://curl.se/docs/copyright.html.
|
---|
13 | *
|
---|
14 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
---|
15 | * copies of the Software, and permit persons to whom the Software is
|
---|
16 | * furnished to do so, under the terms of the COPYING file.
|
---|
17 | *
|
---|
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
---|
19 | * KIND, either express or implied.
|
---|
20 | *
|
---|
21 | * SPDX-License-Identifier: curl
|
---|
22 | *
|
---|
23 | ***************************************************************************/
|
---|
24 |
|
---|
25 | #include "curl_setup.h"
|
---|
26 |
|
---|
27 | #if !defined(CURL_DISABLE_DIGEST_AUTH) && !defined(CURL_DISABLE_SHA512_256)
|
---|
28 |
|
---|
29 | #include "curl_sha512_256.h"
|
---|
30 | #include "warnless.h"
|
---|
31 |
|
---|
32 | /* The recommended order of the TLS backends:
|
---|
33 | * * OpenSSL
|
---|
34 | * * GnuTLS
|
---|
35 | * * wolfSSL
|
---|
36 | * * Schannel SSPI
|
---|
37 | * * SecureTransport (Darwin)
|
---|
38 | * * mbedTLS
|
---|
39 | * * BearSSL
|
---|
40 | * * rustls
|
---|
41 | * Skip the backend if it does not support the required algorithm */
|
---|
42 |
|
---|
43 | #if defined(USE_OPENSSL)
|
---|
44 | # include <openssl/opensslv.h>
|
---|
45 | # if (!defined(LIBRESSL_VERSION_NUMBER) && \
|
---|
46 | defined(OPENSSL_VERSION_NUMBER) && \
|
---|
47 | (OPENSSL_VERSION_NUMBER >= 0x10100010L)) || \
|
---|
48 | (defined(LIBRESSL_VERSION_NUMBER) && \
|
---|
49 | (LIBRESSL_VERSION_NUMBER >= 0x3080000fL))
|
---|
50 | # include <openssl/opensslconf.h>
|
---|
51 | # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
|
---|
52 | # include <openssl/evp.h>
|
---|
53 | # define USE_OPENSSL_SHA512_256 1
|
---|
54 | # define HAS_SHA512_256_IMPLEMENTATION 1
|
---|
55 | # endif
|
---|
56 | # endif
|
---|
57 | #endif /* USE_OPENSSL */
|
---|
58 |
|
---|
59 |
|
---|
60 | #if !defined(HAS_SHA512_256_IMPLEMENTATION) && defined(USE_GNUTLS)
|
---|
61 | # include <nettle/sha.h>
|
---|
62 | # if defined(SHA512_256_DIGEST_SIZE)
|
---|
63 | # define USE_GNUTLS_SHA512_256 1
|
---|
64 | # define HAS_SHA512_256_IMPLEMENTATION 1
|
---|
65 | # endif
|
---|
66 | #endif /* ! HAS_SHA512_256_IMPLEMENTATION && USE_GNUTLS */
|
---|
67 |
|
---|
68 | #if defined(USE_OPENSSL_SHA512_256)
|
---|
69 |
|
---|
70 | /* OpenSSL does not provide macros for SHA-512/256 sizes */
|
---|
71 |
|
---|
72 | /**
|
---|
73 | * Size of the SHA-512/256 single processing block in bytes.
|
---|
74 | */
|
---|
75 | #define SHA512_256_BLOCK_SIZE 128
|
---|
76 |
|
---|
77 | /**
|
---|
78 | * Size of the SHA-512/256 resulting digest in bytes.
|
---|
79 | * This is the final digest size, not intermediate hash.
|
---|
80 | */
|
---|
81 | #define SHA512_256_DIGEST_SIZE SHA512_256_DIGEST_LENGTH
|
---|
82 |
|
---|
83 | /**
|
---|
84 | * Context type used for SHA-512/256 calculations
|
---|
85 | */
|
---|
86 | typedef EVP_MD_CTX *Curl_sha512_256_ctx;
|
---|
87 |
|
---|
88 | /**
|
---|
89 | * Initialise structure for SHA-512/256 calculation.
|
---|
90 | *
|
---|
91 | * @param context the calculation context
|
---|
92 | * @return CURLE_OK if succeed,
|
---|
93 | * error code otherwise
|
---|
94 | */
|
---|
95 | static CURLcode
|
---|
96 | Curl_sha512_256_init(void *context)
|
---|
97 | {
|
---|
98 | Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
---|
99 |
|
---|
100 | *ctx = EVP_MD_CTX_create();
|
---|
101 | if(!*ctx)
|
---|
102 | return CURLE_OUT_OF_MEMORY;
|
---|
103 |
|
---|
104 | if(EVP_DigestInit_ex(*ctx, EVP_sha512_256(), NULL)) {
|
---|
105 | /* Check whether the header and this file use the same numbers */
|
---|
106 | DEBUGASSERT(EVP_MD_CTX_size(*ctx) == SHA512_256_DIGEST_SIZE);
|
---|
107 | /* Check whether the block size is correct */
|
---|
108 | DEBUGASSERT(EVP_MD_CTX_block_size(*ctx) == SHA512_256_BLOCK_SIZE);
|
---|
109 |
|
---|
110 | return CURLE_OK; /* Success */
|
---|
111 | }
|
---|
112 |
|
---|
113 | /* Cleanup */
|
---|
114 | EVP_MD_CTX_destroy(*ctx);
|
---|
115 | return CURLE_FAILED_INIT;
|
---|
116 | }
|
---|
117 |
|
---|
118 |
|
---|
119 | /**
|
---|
120 | * Process portion of bytes.
|
---|
121 | *
|
---|
122 | * @param context the calculation context
|
---|
123 | * @param data bytes to add to hash
|
---|
124 | * @return CURLE_OK if succeed,
|
---|
125 | * error code otherwise
|
---|
126 | */
|
---|
127 | static CURLcode
|
---|
128 | Curl_sha512_256_update(void *context,
|
---|
129 | const unsigned char *data,
|
---|
130 | size_t length)
|
---|
131 | {
|
---|
132 | Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
---|
133 |
|
---|
134 | if(!EVP_DigestUpdate(*ctx, data, length))
|
---|
135 | return CURLE_SSL_CIPHER;
|
---|
136 |
|
---|
137 | return CURLE_OK;
|
---|
138 | }
|
---|
139 |
|
---|
140 |
|
---|
141 | /**
|
---|
142 | * Finalise SHA-512/256 calculation, return digest.
|
---|
143 | *
|
---|
144 | * @param context the calculation context
|
---|
145 | * @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes
|
---|
146 | * @return CURLE_OK if succeed,
|
---|
147 | * error code otherwise
|
---|
148 | */
|
---|
149 | static CURLcode
|
---|
150 | Curl_sha512_256_finish(unsigned char *digest,
|
---|
151 | void *context)
|
---|
152 | {
|
---|
153 | CURLcode ret;
|
---|
154 | Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
---|
155 |
|
---|
156 | #ifdef __NetBSD__
|
---|
157 | /* Use a larger buffer to work around a bug in NetBSD:
|
---|
158 | https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58039 */
|
---|
159 | unsigned char tmp_digest[SHA512_256_DIGEST_SIZE * 2];
|
---|
160 | ret = EVP_DigestFinal_ex(*ctx,
|
---|
161 | tmp_digest, NULL) ? CURLE_OK : CURLE_SSL_CIPHER;
|
---|
162 | if(ret == CURLE_OK)
|
---|
163 | memcpy(digest, tmp_digest, SHA512_256_DIGEST_SIZE);
|
---|
164 | #else /* ! __NetBSD__ */
|
---|
165 | ret = EVP_DigestFinal_ex(*ctx, digest, NULL) ? CURLE_OK : CURLE_SSL_CIPHER;
|
---|
166 | #endif /* ! __NetBSD__ */
|
---|
167 |
|
---|
168 | EVP_MD_CTX_destroy(*ctx);
|
---|
169 | *ctx = NULL;
|
---|
170 |
|
---|
171 | return ret;
|
---|
172 | }
|
---|
173 |
|
---|
174 | #elif defined(USE_GNUTLS_SHA512_256)
|
---|
175 |
|
---|
176 | /**
|
---|
177 | * Context type used for SHA-512/256 calculations
|
---|
178 | */
|
---|
179 | typedef struct sha512_256_ctx Curl_sha512_256_ctx;
|
---|
180 |
|
---|
181 | /**
|
---|
182 | * Initialise structure for SHA-512/256 calculation.
|
---|
183 | *
|
---|
184 | * @param context the calculation context
|
---|
185 | * @return always CURLE_OK
|
---|
186 | */
|
---|
187 | static CURLcode
|
---|
188 | Curl_sha512_256_init(void *context)
|
---|
189 | {
|
---|
190 | Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
---|
191 |
|
---|
192 | /* Check whether the header and this file use the same numbers */
|
---|
193 | DEBUGASSERT(SHA512_256_DIGEST_LENGTH == SHA512_256_DIGEST_SIZE);
|
---|
194 |
|
---|
195 | sha512_256_init(ctx);
|
---|
196 |
|
---|
197 | return CURLE_OK;
|
---|
198 | }
|
---|
199 |
|
---|
200 |
|
---|
201 | /**
|
---|
202 | * Process portion of bytes.
|
---|
203 | *
|
---|
204 | * @param context the calculation context
|
---|
205 | * @param data bytes to add to hash
|
---|
206 | * @param length number of bytes in @a data
|
---|
207 | * @return always CURLE_OK
|
---|
208 | */
|
---|
209 | static CURLcode
|
---|
210 | Curl_sha512_256_update(void *context,
|
---|
211 | const unsigned char *data,
|
---|
212 | size_t length)
|
---|
213 | {
|
---|
214 | Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
---|
215 |
|
---|
216 | DEBUGASSERT((data != NULL) || (length == 0));
|
---|
217 |
|
---|
218 | sha512_256_update(ctx, length, (const uint8_t *)data);
|
---|
219 |
|
---|
220 | return CURLE_OK;
|
---|
221 | }
|
---|
222 |
|
---|
223 |
|
---|
224 | /**
|
---|
225 | * Finalise SHA-512/256 calculation, return digest.
|
---|
226 | *
|
---|
227 | * @param context the calculation context
|
---|
228 | * @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes
|
---|
229 | * @return always CURLE_OK
|
---|
230 | */
|
---|
231 | static CURLcode
|
---|
232 | Curl_sha512_256_finish(unsigned char *digest,
|
---|
233 | void *context)
|
---|
234 | {
|
---|
235 | Curl_sha512_256_ctx *const ctx = (Curl_sha512_256_ctx *)context;
|
---|
236 |
|
---|
237 | sha512_256_digest(ctx, (size_t)SHA512_256_DIGEST_SIZE, (uint8_t *)digest);
|
---|
238 |
|
---|
239 | return CURLE_OK;
|
---|
240 | }
|
---|
241 |
|
---|
242 | #else /* No system or TLS backend SHA-512/256 implementation available */
|
---|
243 |
|
---|
244 | /* Use local implementation */
|
---|
245 | #define HAS_SHA512_256_IMPLEMENTATION 1
|
---|
246 |
|
---|
247 | /* ** This implementation of SHA-512/256 hash calculation was originally ** *
|
---|
248 | * ** written by Evgeny Grin (Karlson2k) for GNU libmicrohttpd. ** *
|
---|
249 | * ** The author ported the code to libcurl. The ported code is provided ** *
|
---|
250 | * ** under curl license. ** *
|
---|
251 | * ** This is a minimal version with minimal optimisations. Performance ** *
|
---|
252 | * ** can be significantly improved. Big-endian store and load macros ** *
|
---|
253 | * ** are obvious targets for optimisation. ** */
|
---|
254 |
|
---|
255 | #ifdef __GNUC__
|
---|
256 | # if defined(__has_attribute) && defined(__STDC_VERSION__)
|
---|
257 | # if __has_attribute(always_inline) && __STDC_VERSION__ >= 199901
|
---|
258 | # define MHDX_INLINE inline __attribute__((always_inline))
|
---|
259 | # endif
|
---|
260 | # endif
|
---|
261 | #endif
|
---|
262 |
|
---|
263 | #if !defined(MHDX_INLINE) && \
|
---|
264 | defined(_MSC_VER) && !defined(__GNUC__) && !defined(__clang__)
|
---|
265 | # if _MSC_VER >= 1400
|
---|
266 | # define MHDX_INLINE __forceinline
|
---|
267 | # else
|
---|
268 | # define MHDX_INLINE /* empty */
|
---|
269 | # endif
|
---|
270 | #endif
|
---|
271 |
|
---|
272 | #if !defined(MHDX_INLINE)
|
---|
273 | # if defined(inline)
|
---|
274 | /* Assume that 'inline' macro was already defined correctly by
|
---|
275 | * the build system. */
|
---|
276 | # define MHDX_INLINE inline
|
---|
277 | # elif defined(__cplusplus)
|
---|
278 | /* The code is compiled with C++ compiler.
|
---|
279 | * C++ always supports 'inline'. */
|
---|
280 | # define MHDX_INLINE inline
|
---|
281 | # elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901
|
---|
282 | /* C99 (and later) supports 'inline' keyword */
|
---|
283 | # define MHDX_INLINE inline
|
---|
284 | # elif defined(__GNUC__) && __GNUC__ >= 3
|
---|
285 | /* GCC supports '__inline__' as an extension */
|
---|
286 | # define MHDX_INLINE __inline__
|
---|
287 | # else
|
---|
288 | # define MHDX_INLINE /* empty */
|
---|
289 | # endif
|
---|
290 | #endif
|
---|
291 |
|
---|
292 | /* Bits manipulation macros and functions.
|
---|
293 | Can be moved to other headers to reuse. */
|
---|
294 |
|
---|
295 | #define MHDX_GET_64BIT_BE(ptr) \
|
---|
296 | ( ((curl_uint64_t)(((const unsigned char*)(ptr))[0]) << 56) | \
|
---|
297 | ((curl_uint64_t)(((const unsigned char*)(ptr))[1]) << 48) | \
|
---|
298 | ((curl_uint64_t)(((const unsigned char*)(ptr))[2]) << 40) | \
|
---|
299 | ((curl_uint64_t)(((const unsigned char*)(ptr))[3]) << 32) | \
|
---|
300 | ((curl_uint64_t)(((const unsigned char*)(ptr))[4]) << 24) | \
|
---|
301 | ((curl_uint64_t)(((const unsigned char*)(ptr))[5]) << 16) | \
|
---|
302 | ((curl_uint64_t)(((const unsigned char*)(ptr))[6]) << 8) | \
|
---|
303 | (curl_uint64_t)(((const unsigned char*)(ptr))[7]) )
|
---|
304 |
|
---|
305 | #define MHDX_PUT_64BIT_BE(ptr,val) do { \
|
---|
306 | ((unsigned char*)(ptr))[7]=(unsigned char)((curl_uint64_t)(val)); \
|
---|
307 | ((unsigned char*)(ptr))[6]=(unsigned char)(((curl_uint64_t)(val)) >> 8); \
|
---|
308 | ((unsigned char*)(ptr))[5]=(unsigned char)(((curl_uint64_t)(val)) >> 16); \
|
---|
309 | ((unsigned char*)(ptr))[4]=(unsigned char)(((curl_uint64_t)(val)) >> 24); \
|
---|
310 | ((unsigned char*)(ptr))[3]=(unsigned char)(((curl_uint64_t)(val)) >> 32); \
|
---|
311 | ((unsigned char*)(ptr))[2]=(unsigned char)(((curl_uint64_t)(val)) >> 40); \
|
---|
312 | ((unsigned char*)(ptr))[1]=(unsigned char)(((curl_uint64_t)(val)) >> 48); \
|
---|
313 | ((unsigned char*)(ptr))[0]=(unsigned char)(((curl_uint64_t)(val)) >> 56); \
|
---|
314 | } while(0)
|
---|
315 |
|
---|
316 | /* Defined as a function. The macro version may duplicate the binary code
|
---|
317 | * size as each argument is used twice, so if any calculation is used
|
---|
318 | * as an argument, the calculation could be done twice. */
|
---|
319 | static MHDX_INLINE curl_uint64_t
|
---|
320 | MHDx_rotr64(curl_uint64_t value, unsigned int bits)
|
---|
321 | {
|
---|
322 | bits %= 64;
|
---|
323 | if(0 == bits)
|
---|
324 | return value;
|
---|
325 | /* Defined in a form which modern compiler could optimise. */
|
---|
326 | return (value >> bits) | (value << (64 - bits));
|
---|
327 | }
|
---|
328 |
|
---|
329 | /* SHA-512/256 specific data */
|
---|
330 |
|
---|
331 | /**
|
---|
332 | * Number of bits in a single SHA-512/256 word.
|
---|
333 | */
|
---|
334 | #define SHA512_256_WORD_SIZE_BITS 64
|
---|
335 |
|
---|
336 | /**
|
---|
337 | * Number of bytes in a single SHA-512/256 word.
|
---|
338 | */
|
---|
339 | #define SHA512_256_BYTES_IN_WORD (SHA512_256_WORD_SIZE_BITS / 8)
|
---|
340 |
|
---|
341 | /**
|
---|
342 | * Hash is kept internally as 8 64-bit words.
|
---|
343 | * This is the intermediate hash size, used during computing the final digest.
|
---|
344 | */
|
---|
345 | #define SHA512_256_HASH_SIZE_WORDS 8
|
---|
346 |
|
---|
347 | /**
|
---|
348 | * Size of the SHA-512/256 resulting digest in words.
|
---|
349 | * This is the final digest size, not intermediate hash.
|
---|
350 | */
|
---|
351 | #define SHA512_256_DIGEST_SIZE_WORDS (SHA512_256_HASH_SIZE_WORDS / 2)
|
---|
352 |
|
---|
353 | /**
|
---|
354 | * Size of the SHA-512/256 resulting digest in bytes
|
---|
355 | * This is the final digest size, not intermediate hash.
|
---|
356 | */
|
---|
357 | #define SHA512_256_DIGEST_SIZE \
|
---|
358 | (SHA512_256_DIGEST_SIZE_WORDS * SHA512_256_BYTES_IN_WORD)
|
---|
359 |
|
---|
360 | /**
|
---|
361 | * Size of the SHA-512/256 single processing block in bits.
|
---|
362 | */
|
---|
363 | #define SHA512_256_BLOCK_SIZE_BITS 1024
|
---|
364 |
|
---|
365 | /**
|
---|
366 | * Size of the SHA-512/256 single processing block in bytes.
|
---|
367 | */
|
---|
368 | #define SHA512_256_BLOCK_SIZE (SHA512_256_BLOCK_SIZE_BITS / 8)
|
---|
369 |
|
---|
370 | /**
|
---|
371 | * Size of the SHA-512/256 single processing block in words.
|
---|
372 | */
|
---|
373 | #define SHA512_256_BLOCK_SIZE_WORDS \
|
---|
374 | (SHA512_256_BLOCK_SIZE_BITS / SHA512_256_WORD_SIZE_BITS)
|
---|
375 |
|
---|
376 | /**
|
---|
377 | * SHA-512/256 calculation context
|
---|
378 | */
|
---|
379 | struct mhdx_sha512_256ctx
|
---|
380 | {
|
---|
381 | /**
|
---|
382 | * Intermediate hash value. The variable is properly aligned. Smart
|
---|
383 | * compilers may automatically use fast load/store instruction for big
|
---|
384 | * endian data on little endian machine.
|
---|
385 | */
|
---|
386 | curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS];
|
---|
387 | /**
|
---|
388 | * SHA-512/256 input data buffer. The buffer is properly aligned. Smart
|
---|
389 | * compilers may automatically use fast load/store instruction for big
|
---|
390 | * endian data on little endian machine.
|
---|
391 | */
|
---|
392 | curl_uint64_t buffer[SHA512_256_BLOCK_SIZE_WORDS];
|
---|
393 | /**
|
---|
394 | * The number of bytes, lower part
|
---|
395 | */
|
---|
396 | curl_uint64_t count;
|
---|
397 | /**
|
---|
398 | * The number of bits, high part. Unlike lower part, this counts the number
|
---|
399 | * of bits, not bytes.
|
---|
400 | */
|
---|
401 | curl_uint64_t count_bits_hi;
|
---|
402 | };
|
---|
403 |
|
---|
404 | /**
|
---|
405 | * Context type used for SHA-512/256 calculations
|
---|
406 | */
|
---|
407 | typedef struct mhdx_sha512_256ctx Curl_sha512_256_ctx;
|
---|
408 |
|
---|
409 |
|
---|
410 | /**
|
---|
411 | * Initialise structure for SHA-512/256 calculation.
|
---|
412 | *
|
---|
413 | * @param context the calculation context
|
---|
414 | * @return always CURLE_OK
|
---|
415 | */
|
---|
416 | static CURLcode
|
---|
417 | MHDx_sha512_256_init(void *context)
|
---|
418 | {
|
---|
419 | struct mhdx_sha512_256ctx *const ctx = (struct mhdx_sha512_256ctx *) context;
|
---|
420 |
|
---|
421 | /* Check whether the header and this file use the same numbers */
|
---|
422 | DEBUGASSERT(SHA512_256_DIGEST_LENGTH == SHA512_256_DIGEST_SIZE);
|
---|
423 |
|
---|
424 | DEBUGASSERT(sizeof(curl_uint64_t) == 8);
|
---|
425 |
|
---|
426 | /* Initial hash values, see FIPS PUB 180-4 section 5.3.6.2 */
|
---|
427 | /* Values generated by "IV Generation Function" as described in
|
---|
428 | * section 5.3.6 */
|
---|
429 | ctx->H[0] = CURL_UINT64_C(0x22312194FC2BF72C);
|
---|
430 | ctx->H[1] = CURL_UINT64_C(0x9F555FA3C84C64C2);
|
---|
431 | ctx->H[2] = CURL_UINT64_C(0x2393B86B6F53B151);
|
---|
432 | ctx->H[3] = CURL_UINT64_C(0x963877195940EABD);
|
---|
433 | ctx->H[4] = CURL_UINT64_C(0x96283EE2A88EFFE3);
|
---|
434 | ctx->H[5] = CURL_UINT64_C(0xBE5E1E2553863992);
|
---|
435 | ctx->H[6] = CURL_UINT64_C(0x2B0199FC2C85B8AA);
|
---|
436 | ctx->H[7] = CURL_UINT64_C(0x0EB72DDC81C52CA2);
|
---|
437 |
|
---|
438 | /* Initialise number of bytes and high part of number of bits. */
|
---|
439 | ctx->count = CURL_UINT64_C(0);
|
---|
440 | ctx->count_bits_hi = CURL_UINT64_C(0);
|
---|
441 |
|
---|
442 | return CURLE_OK;
|
---|
443 | }
|
---|
444 |
|
---|
445 |
|
---|
446 | /**
|
---|
447 | * Base of the SHA-512/256 transformation.
|
---|
448 | * Gets a full 128 bytes block of data and updates hash values;
|
---|
449 | * @param H hash values
|
---|
450 | * @param data the data buffer with #SHA512_256_BLOCK_SIZE bytes block
|
---|
451 | */
|
---|
452 | static void
|
---|
453 | MHDx_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
---|
454 | const void *data)
|
---|
455 | {
|
---|
456 | /* Working variables,
|
---|
457 | see FIPS PUB 180-4 section 6.7, 6.4. */
|
---|
458 | curl_uint64_t a = H[0];
|
---|
459 | curl_uint64_t b = H[1];
|
---|
460 | curl_uint64_t c = H[2];
|
---|
461 | curl_uint64_t d = H[3];
|
---|
462 | curl_uint64_t e = H[4];
|
---|
463 | curl_uint64_t f = H[5];
|
---|
464 | curl_uint64_t g = H[6];
|
---|
465 | curl_uint64_t h = H[7];
|
---|
466 |
|
---|
467 | /* Data buffer, used as a cyclic buffer.
|
---|
468 | See FIPS PUB 180-4 section 5.2.2, 6.7, 6.4. */
|
---|
469 | curl_uint64_t W[16];
|
---|
470 |
|
---|
471 | /* 'Ch' and 'Maj' macro functions are defined with widely-used optimisation.
|
---|
472 | See FIPS PUB 180-4 formulae 4.8, 4.9. */
|
---|
473 | #define Ch(x,y,z) ( (z) ^ ((x) & ((y) ^ (z))) )
|
---|
474 | #define Maj(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
|
---|
475 |
|
---|
476 | /* Four 'Sigma' macro functions.
|
---|
477 | See FIPS PUB 180-4 formulae 4.10, 4.11, 4.12, 4.13. */
|
---|
478 | #define SIG0(x) \
|
---|
479 | ( MHDx_rotr64((x), 28) ^ MHDx_rotr64((x), 34) ^ MHDx_rotr64((x), 39) )
|
---|
480 | #define SIG1(x) \
|
---|
481 | ( MHDx_rotr64((x), 14) ^ MHDx_rotr64((x), 18) ^ MHDx_rotr64((x), 41) )
|
---|
482 | #define sig0(x) \
|
---|
483 | ( MHDx_rotr64((x), 1) ^ MHDx_rotr64((x), 8) ^ ((x) >> 7) )
|
---|
484 | #define sig1(x) \
|
---|
485 | ( MHDx_rotr64((x), 19) ^ MHDx_rotr64((x), 61) ^ ((x) >> 6) )
|
---|
486 |
|
---|
487 | if(1) {
|
---|
488 | unsigned int t;
|
---|
489 | /* K constants array.
|
---|
490 | See FIPS PUB 180-4 section 4.2.3 for K values. */
|
---|
491 | static const curl_uint64_t K[80] = {
|
---|
492 | CURL_UINT64_C(0x428a2f98d728ae22), CURL_UINT64_C(0x7137449123ef65cd),
|
---|
493 | CURL_UINT64_C(0xb5c0fbcfec4d3b2f), CURL_UINT64_C(0xe9b5dba58189dbbc),
|
---|
494 | CURL_UINT64_C(0x3956c25bf348b538), CURL_UINT64_C(0x59f111f1b605d019),
|
---|
495 | CURL_UINT64_C(0x923f82a4af194f9b), CURL_UINT64_C(0xab1c5ed5da6d8118),
|
---|
496 | CURL_UINT64_C(0xd807aa98a3030242), CURL_UINT64_C(0x12835b0145706fbe),
|
---|
497 | CURL_UINT64_C(0x243185be4ee4b28c), CURL_UINT64_C(0x550c7dc3d5ffb4e2),
|
---|
498 | CURL_UINT64_C(0x72be5d74f27b896f), CURL_UINT64_C(0x80deb1fe3b1696b1),
|
---|
499 | CURL_UINT64_C(0x9bdc06a725c71235), CURL_UINT64_C(0xc19bf174cf692694),
|
---|
500 | CURL_UINT64_C(0xe49b69c19ef14ad2), CURL_UINT64_C(0xefbe4786384f25e3),
|
---|
501 | CURL_UINT64_C(0x0fc19dc68b8cd5b5), CURL_UINT64_C(0x240ca1cc77ac9c65),
|
---|
502 | CURL_UINT64_C(0x2de92c6f592b0275), CURL_UINT64_C(0x4a7484aa6ea6e483),
|
---|
503 | CURL_UINT64_C(0x5cb0a9dcbd41fbd4), CURL_UINT64_C(0x76f988da831153b5),
|
---|
504 | CURL_UINT64_C(0x983e5152ee66dfab), CURL_UINT64_C(0xa831c66d2db43210),
|
---|
505 | CURL_UINT64_C(0xb00327c898fb213f), CURL_UINT64_C(0xbf597fc7beef0ee4),
|
---|
506 | CURL_UINT64_C(0xc6e00bf33da88fc2), CURL_UINT64_C(0xd5a79147930aa725),
|
---|
507 | CURL_UINT64_C(0x06ca6351e003826f), CURL_UINT64_C(0x142929670a0e6e70),
|
---|
508 | CURL_UINT64_C(0x27b70a8546d22ffc), CURL_UINT64_C(0x2e1b21385c26c926),
|
---|
509 | CURL_UINT64_C(0x4d2c6dfc5ac42aed), CURL_UINT64_C(0x53380d139d95b3df),
|
---|
510 | CURL_UINT64_C(0x650a73548baf63de), CURL_UINT64_C(0x766a0abb3c77b2a8),
|
---|
511 | CURL_UINT64_C(0x81c2c92e47edaee6), CURL_UINT64_C(0x92722c851482353b),
|
---|
512 | CURL_UINT64_C(0xa2bfe8a14cf10364), CURL_UINT64_C(0xa81a664bbc423001),
|
---|
513 | CURL_UINT64_C(0xc24b8b70d0f89791), CURL_UINT64_C(0xc76c51a30654be30),
|
---|
514 | CURL_UINT64_C(0xd192e819d6ef5218), CURL_UINT64_C(0xd69906245565a910),
|
---|
515 | CURL_UINT64_C(0xf40e35855771202a), CURL_UINT64_C(0x106aa07032bbd1b8),
|
---|
516 | CURL_UINT64_C(0x19a4c116b8d2d0c8), CURL_UINT64_C(0x1e376c085141ab53),
|
---|
517 | CURL_UINT64_C(0x2748774cdf8eeb99), CURL_UINT64_C(0x34b0bcb5e19b48a8),
|
---|
518 | CURL_UINT64_C(0x391c0cb3c5c95a63), CURL_UINT64_C(0x4ed8aa4ae3418acb),
|
---|
519 | CURL_UINT64_C(0x5b9cca4f7763e373), CURL_UINT64_C(0x682e6ff3d6b2b8a3),
|
---|
520 | CURL_UINT64_C(0x748f82ee5defb2fc), CURL_UINT64_C(0x78a5636f43172f60),
|
---|
521 | CURL_UINT64_C(0x84c87814a1f0ab72), CURL_UINT64_C(0x8cc702081a6439ec),
|
---|
522 | CURL_UINT64_C(0x90befffa23631e28), CURL_UINT64_C(0xa4506cebde82bde9),
|
---|
523 | CURL_UINT64_C(0xbef9a3f7b2c67915), CURL_UINT64_C(0xc67178f2e372532b),
|
---|
524 | CURL_UINT64_C(0xca273eceea26619c), CURL_UINT64_C(0xd186b8c721c0c207),
|
---|
525 | CURL_UINT64_C(0xeada7dd6cde0eb1e), CURL_UINT64_C(0xf57d4f7fee6ed178),
|
---|
526 | CURL_UINT64_C(0x06f067aa72176fba), CURL_UINT64_C(0x0a637dc5a2c898a6),
|
---|
527 | CURL_UINT64_C(0x113f9804bef90dae), CURL_UINT64_C(0x1b710b35131c471b),
|
---|
528 | CURL_UINT64_C(0x28db77f523047d84), CURL_UINT64_C(0x32caab7b40c72493),
|
---|
529 | CURL_UINT64_C(0x3c9ebe0a15c9bebc), CURL_UINT64_C(0x431d67c49c100d4c),
|
---|
530 | CURL_UINT64_C(0x4cc5d4becb3e42b6), CURL_UINT64_C(0x597f299cfc657e2a),
|
---|
531 | CURL_UINT64_C(0x5fcb6fab3ad6faec), CURL_UINT64_C(0x6c44198c4a475817)
|
---|
532 | };
|
---|
533 |
|
---|
534 | /* One step of SHA-512/256 computation,
|
---|
535 | see FIPS PUB 180-4 section 6.4.2 step 3.
|
---|
536 | * Note: this macro updates working variables in-place, without rotation.
|
---|
537 | * Note: the first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in
|
---|
538 | FIPS PUB 180-4 section 6.4.2 step 3.
|
---|
539 | the second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in
|
---|
540 | FIPS PUB 180-4 section 6.4.2 step 3.
|
---|
541 | * Note: 'wt' must be used exactly one time in this macro as macro for
|
---|
542 | 'wt' calculation may change other data as well every time when
|
---|
543 | used. */
|
---|
544 | #define SHA2STEP64(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \
|
---|
545 | (vD) += ((vH) += SIG1 ((vE)) + Ch ((vE),(vF),(vG)) + (kt) + (wt)); \
|
---|
546 | (vH) += SIG0 ((vA)) + Maj ((vA),(vB),(vC)); } while (0)
|
---|
547 |
|
---|
548 | /* One step of SHA-512/256 computation with working variables rotation,
|
---|
549 | see FIPS PUB 180-4 section 6.4.2 step 3. This macro version reassigns
|
---|
550 | all working variables on each step. */
|
---|
551 | #define SHA2STEP64RV(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \
|
---|
552 | curl_uint64_t tmp_h_ = (vH); \
|
---|
553 | SHA2STEP64((vA),(vB),(vC),(vD),(vE),(vF),(vG),tmp_h_,(kt),(wt)); \
|
---|
554 | (vH) = (vG); \
|
---|
555 | (vG) = (vF); \
|
---|
556 | (vF) = (vE); \
|
---|
557 | (vE) = (vD); \
|
---|
558 | (vD) = (vC); \
|
---|
559 | (vC) = (vB); \
|
---|
560 | (vB) = (vA); \
|
---|
561 | (vA) = tmp_h_; } while(0)
|
---|
562 |
|
---|
563 | /* Get value of W(t) from input data buffer for 0 <= t <= 15,
|
---|
564 | See FIPS PUB 180-4 section 6.2.
|
---|
565 | Input data must be read in big-endian bytes order,
|
---|
566 | see FIPS PUB 180-4 section 3.1.2. */
|
---|
567 | #define SHA512_GET_W_FROM_DATA(buf,t) \
|
---|
568 | MHDX_GET_64BIT_BE( \
|
---|
569 | ((const unsigned char*) (buf)) + (t) * SHA512_256_BYTES_IN_WORD)
|
---|
570 |
|
---|
571 | /* During first 16 steps, before making any calculation on each step, the
|
---|
572 | W element is read from the input data buffer as a big-endian value and
|
---|
573 | stored in the array of W elements. */
|
---|
574 | for(t = 0; t < 16; ++t) {
|
---|
575 | SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t], \
|
---|
576 | W[t] = SHA512_GET_W_FROM_DATA(data, t));
|
---|
577 | }
|
---|
578 |
|
---|
579 | /* 'W' generation and assignment for 16 <= t <= 79.
|
---|
580 | See FIPS PUB 180-4 section 6.4.2.
|
---|
581 | As only the last 16 'W' are used in calculations, it is possible to
|
---|
582 | use 16 elements array of W as a cyclic buffer.
|
---|
583 | Note: ((t-16) & 15) have same value as (t & 15) */
|
---|
584 | #define Wgen(w,t) \
|
---|
585 | (curl_uint64_t)( (w)[(t - 16) & 15] + sig1((w)[((t) - 2) & 15]) \
|
---|
586 | + (w)[((t) - 7) & 15] + sig0((w)[((t) - 15) & 15]) )
|
---|
587 |
|
---|
588 | /* During the last 64 steps, before making any calculation on each step,
|
---|
589 | current W element is generated from other W elements of the cyclic
|
---|
590 | buffer and the generated value is stored back in the cyclic buffer. */
|
---|
591 | for(t = 16; t < 80; ++t) {
|
---|
592 | SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t], \
|
---|
593 | W[t & 15] = Wgen(W, t));
|
---|
594 | }
|
---|
595 | }
|
---|
596 |
|
---|
597 | /* Compute and store the intermediate hash.
|
---|
598 | See FIPS PUB 180-4 section 6.4.2 step 4. */
|
---|
599 | H[0] += a;
|
---|
600 | H[1] += b;
|
---|
601 | H[2] += c;
|
---|
602 | H[3] += d;
|
---|
603 | H[4] += e;
|
---|
604 | H[5] += f;
|
---|
605 | H[6] += g;
|
---|
606 | H[7] += h;
|
---|
607 | }
|
---|
608 |
|
---|
609 |
|
---|
610 | /**
|
---|
611 | * Process portion of bytes.
|
---|
612 | *
|
---|
613 | * @param context the calculation context
|
---|
614 | * @param data bytes to add to hash
|
---|
615 | * @param length number of bytes in @a data
|
---|
616 | * @return always CURLE_OK
|
---|
617 | */
|
---|
618 | static CURLcode
|
---|
619 | MHDx_sha512_256_update(void *context,
|
---|
620 | const unsigned char *data,
|
---|
621 | size_t length)
|
---|
622 | {
|
---|
623 | unsigned int bytes_have; /**< Number of bytes in the context buffer */
|
---|
624 | struct mhdx_sha512_256ctx *const ctx = (struct mhdx_sha512_256ctx *)context;
|
---|
625 | /* the void pointer here is required to mute Intel compiler warning */
|
---|
626 | void *const ctx_buf = ctx->buffer;
|
---|
627 |
|
---|
628 | DEBUGASSERT((data != NULL) || (length == 0));
|
---|
629 |
|
---|
630 | if(0 == length)
|
---|
631 | return CURLE_OK; /* Shortcut, do nothing */
|
---|
632 |
|
---|
633 | /* Note: (count & (SHA512_256_BLOCK_SIZE-1))
|
---|
634 | equals (count % SHA512_256_BLOCK_SIZE) for this block size. */
|
---|
635 | bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1));
|
---|
636 | ctx->count += length;
|
---|
637 | if(length > ctx->count)
|
---|
638 | ctx->count_bits_hi += 1U << 3; /* Value wrap */
|
---|
639 | ctx->count_bits_hi += ctx->count >> 61;
|
---|
640 | ctx->count &= CURL_UINT64_C(0x1FFFFFFFFFFFFFFF);
|
---|
641 |
|
---|
642 | if(0 != bytes_have) {
|
---|
643 | unsigned int bytes_left = SHA512_256_BLOCK_SIZE - bytes_have;
|
---|
644 | if(length >= bytes_left) {
|
---|
645 | /* Combine new data with data in the buffer and process the full
|
---|
646 | block. */
|
---|
647 | memcpy(((unsigned char *) ctx_buf) + bytes_have,
|
---|
648 | data,
|
---|
649 | bytes_left);
|
---|
650 | data += bytes_left;
|
---|
651 | length -= bytes_left;
|
---|
652 | MHDx_sha512_256_transform(ctx->H, ctx->buffer);
|
---|
653 | bytes_have = 0;
|
---|
654 | }
|
---|
655 | }
|
---|
656 |
|
---|
657 | while(SHA512_256_BLOCK_SIZE <= length) {
|
---|
658 | /* Process any full blocks of new data directly,
|
---|
659 | without copying to the buffer. */
|
---|
660 | MHDx_sha512_256_transform(ctx->H, data);
|
---|
661 | data += SHA512_256_BLOCK_SIZE;
|
---|
662 | length -= SHA512_256_BLOCK_SIZE;
|
---|
663 | }
|
---|
664 |
|
---|
665 | if(0 != length) {
|
---|
666 | /* Copy incomplete block of new data (if any)
|
---|
667 | to the buffer. */
|
---|
668 | memcpy(((unsigned char *) ctx_buf) + bytes_have, data, length);
|
---|
669 | }
|
---|
670 |
|
---|
671 | return CURLE_OK;
|
---|
672 | }
|
---|
673 |
|
---|
674 |
|
---|
675 |
|
---|
676 | /**
|
---|
677 | * Size of "length" insertion in bits.
|
---|
678 | * See FIPS PUB 180-4 section 5.1.2.
|
---|
679 | */
|
---|
680 | #define SHA512_256_SIZE_OF_LEN_ADD_BITS 128
|
---|
681 |
|
---|
682 | /**
|
---|
683 | * Size of "length" insertion in bytes.
|
---|
684 | */
|
---|
685 | #define SHA512_256_SIZE_OF_LEN_ADD (SHA512_256_SIZE_OF_LEN_ADD_BITS / 8)
|
---|
686 |
|
---|
687 | /**
|
---|
688 | * Finalise SHA-512/256 calculation, return digest.
|
---|
689 | *
|
---|
690 | * @param context the calculation context
|
---|
691 | * @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes
|
---|
692 | * @return always CURLE_OK
|
---|
693 | */
|
---|
694 | static CURLcode
|
---|
695 | MHDx_sha512_256_finish(unsigned char *digest,
|
---|
696 | void *context)
|
---|
697 | {
|
---|
698 | struct mhdx_sha512_256ctx *const ctx = (struct mhdx_sha512_256ctx *)context;
|
---|
699 | curl_uint64_t num_bits; /**< Number of processed bits */
|
---|
700 | unsigned int bytes_have; /**< Number of bytes in the context buffer */
|
---|
701 | /* the void pointer here is required to mute Intel compiler warning */
|
---|
702 | void *const ctx_buf = ctx->buffer;
|
---|
703 |
|
---|
704 | /* Memorise the number of processed bits.
|
---|
705 | The padding and other data added here during the postprocessing must
|
---|
706 | not change the amount of hashed data. */
|
---|
707 | num_bits = ctx->count << 3;
|
---|
708 |
|
---|
709 | /* Note: (count & (SHA512_256_BLOCK_SIZE-1))
|
---|
710 | equals (count % SHA512_256_BLOCK_SIZE) for this block size. */
|
---|
711 | bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1));
|
---|
712 |
|
---|
713 | /* Input data must be padded with a single bit "1", then with zeros and
|
---|
714 | the finally the length of data in bits must be added as the final bytes
|
---|
715 | of the last block.
|
---|
716 | See FIPS PUB 180-4 section 5.1.2. */
|
---|
717 |
|
---|
718 | /* Data is always processed in form of bytes (not by individual bits),
|
---|
719 | therefore position of the first padding bit in byte is always
|
---|
720 | predefined (0x80). */
|
---|
721 | /* Buffer always have space at least for one byte (as full buffers are
|
---|
722 | processed when formed). */
|
---|
723 | ((unsigned char *) ctx_buf)[bytes_have++] = 0x80U;
|
---|
724 |
|
---|
725 | if(SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD) {
|
---|
726 | /* No space in the current block to put the total length of message.
|
---|
727 | Pad the current block with zeros and process it. */
|
---|
728 | if(bytes_have < SHA512_256_BLOCK_SIZE)
|
---|
729 | memset(((unsigned char *) ctx_buf) + bytes_have, 0,
|
---|
730 | SHA512_256_BLOCK_SIZE - bytes_have);
|
---|
731 | /* Process the full block. */
|
---|
732 | MHDx_sha512_256_transform(ctx->H, ctx->buffer);
|
---|
733 | /* Start the new block. */
|
---|
734 | bytes_have = 0;
|
---|
735 | }
|
---|
736 |
|
---|
737 | /* Pad the rest of the buffer with zeros. */
|
---|
738 | memset(((unsigned char *) ctx_buf) + bytes_have, 0,
|
---|
739 | SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have);
|
---|
740 | /* Put high part of number of bits in processed message and then lower
|
---|
741 | part of number of bits as big-endian values.
|
---|
742 | See FIPS PUB 180-4 section 5.1.2. */
|
---|
743 | /* Note: the target location is predefined and buffer is always aligned */
|
---|
744 | MHDX_PUT_64BIT_BE(((unsigned char *) ctx_buf) \
|
---|
745 | + SHA512_256_BLOCK_SIZE \
|
---|
746 | - SHA512_256_SIZE_OF_LEN_ADD, \
|
---|
747 | ctx->count_bits_hi);
|
---|
748 | MHDX_PUT_64BIT_BE(((unsigned char *) ctx_buf) \
|
---|
749 | + SHA512_256_BLOCK_SIZE \
|
---|
750 | - SHA512_256_SIZE_OF_LEN_ADD \
|
---|
751 | + SHA512_256_BYTES_IN_WORD, \
|
---|
752 | num_bits);
|
---|
753 | /* Process the full final block. */
|
---|
754 | MHDx_sha512_256_transform(ctx->H, ctx->buffer);
|
---|
755 |
|
---|
756 | /* Put in BE mode the leftmost part of the hash as the final digest.
|
---|
757 | See FIPS PUB 180-4 section 6.7. */
|
---|
758 |
|
---|
759 | MHDX_PUT_64BIT_BE((digest + 0 * SHA512_256_BYTES_IN_WORD), ctx->H[0]);
|
---|
760 | MHDX_PUT_64BIT_BE((digest + 1 * SHA512_256_BYTES_IN_WORD), ctx->H[1]);
|
---|
761 | MHDX_PUT_64BIT_BE((digest + 2 * SHA512_256_BYTES_IN_WORD), ctx->H[2]);
|
---|
762 | MHDX_PUT_64BIT_BE((digest + 3 * SHA512_256_BYTES_IN_WORD), ctx->H[3]);
|
---|
763 |
|
---|
764 | /* Erase potentially sensitive data. */
|
---|
765 | memset(ctx, 0, sizeof(struct mhdx_sha512_256ctx));
|
---|
766 |
|
---|
767 | return CURLE_OK;
|
---|
768 | }
|
---|
769 |
|
---|
770 | /* Map to the local implementation */
|
---|
771 | #define Curl_sha512_256_init MHDx_sha512_256_init
|
---|
772 | #define Curl_sha512_256_update MHDx_sha512_256_update
|
---|
773 | #define Curl_sha512_256_finish MHDx_sha512_256_finish
|
---|
774 |
|
---|
775 | #endif /* Local SHA-512/256 code */
|
---|
776 |
|
---|
777 |
|
---|
778 | /**
|
---|
779 | * Compute SHA-512/256 hash for the given data in one function call
|
---|
780 | * @param[out] output the pointer to put the hash
|
---|
781 | * @param[in] input the pointer to the data to process
|
---|
782 | * @param input_size the size of the data pointed by @a input
|
---|
783 | * @return always #CURLE_OK
|
---|
784 | */
|
---|
785 | CURLcode
|
---|
786 | Curl_sha512_256it(unsigned char *output, const unsigned char *input,
|
---|
787 | size_t input_size)
|
---|
788 | {
|
---|
789 | Curl_sha512_256_ctx ctx;
|
---|
790 | CURLcode res;
|
---|
791 |
|
---|
792 | res = Curl_sha512_256_init(&ctx);
|
---|
793 | if(res != CURLE_OK)
|
---|
794 | return res;
|
---|
795 |
|
---|
796 | res = Curl_sha512_256_update(&ctx, (const void *) input, input_size);
|
---|
797 |
|
---|
798 | if(res != CURLE_OK) {
|
---|
799 | (void) Curl_sha512_256_finish(output, &ctx);
|
---|
800 | return res;
|
---|
801 | }
|
---|
802 |
|
---|
803 | return Curl_sha512_256_finish(output, &ctx);
|
---|
804 | }
|
---|
805 |
|
---|
806 | /* Wrapper function, takes 'unsigned int' as length type, returns void */
|
---|
807 | static void
|
---|
808 | Curl_sha512_256_update_i(void *context,
|
---|
809 | const unsigned char *data,
|
---|
810 | unsigned int length)
|
---|
811 | {
|
---|
812 | /* Hypothetically the function may fail, but assume it does not */
|
---|
813 | (void) Curl_sha512_256_update(context, data, length);
|
---|
814 | }
|
---|
815 |
|
---|
816 | /* Wrapper function, returns void */
|
---|
817 | static void
|
---|
818 | Curl_sha512_256_finish_v(unsigned char *result,
|
---|
819 | void *context)
|
---|
820 | {
|
---|
821 | /* Hypothetically the function may fail, but assume it does not */
|
---|
822 | (void) Curl_sha512_256_finish(result, context);
|
---|
823 | }
|
---|
824 |
|
---|
825 | /* Wrapper function, takes 'unsigned int' as length type, returns void */
|
---|
826 |
|
---|
827 | const struct HMAC_params Curl_HMAC_SHA512_256[] = {
|
---|
828 | {
|
---|
829 | /* Initialize context procedure. */
|
---|
830 | Curl_sha512_256_init,
|
---|
831 | /* Update context with data. */
|
---|
832 | Curl_sha512_256_update_i,
|
---|
833 | /* Get final result procedure. */
|
---|
834 | Curl_sha512_256_finish_v,
|
---|
835 | /* Context structure size. */
|
---|
836 | sizeof(Curl_sha512_256_ctx),
|
---|
837 | /* Maximum key length (bytes). */
|
---|
838 | SHA512_256_BLOCK_SIZE,
|
---|
839 | /* Result length (bytes). */
|
---|
840 | SHA512_256_DIGEST_SIZE
|
---|
841 | }
|
---|
842 | };
|
---|
843 |
|
---|
844 | #endif /* !CURL_DISABLE_DIGEST_AUTH && !CURL_DISABLE_SHA512_256 */
|
---|