VirtualBox

source: vbox/trunk/src/libs/curl-7.83.1/lib/sha256.c@ 97138

最後變更 在這個檔案從97138是 95312,由 vboxsync 提交於 3 年 前

libs/{curl,libxml2}: OSE export fixes, bugref:8515

  • 屬性 svn:eol-style 設為 native
檔案大小: 15.2 KB
 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2017, Florin Petriuc, <[email protected]>
9 * Copyright (C) 2018 - 2022, Daniel Stenberg, <[email protected]>, et al.
10 *
11 * This software is licensed as described in the file COPYING, which
12 * you should have received as part of this distribution. The terms
13 * are also available at https://curl.se/docs/copyright.html.
14 *
15 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16 * copies of the Software, and permit persons to whom the Software is
17 * furnished to do so, under the terms of the COPYING file.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ***************************************************************************/
23
24#include "curl_setup.h"
25
26#ifndef CURL_DISABLE_CRYPTO_AUTH
27
28#include "warnless.h"
29#include "curl_sha256.h"
30#include "curl_hmac.h"
31
32#ifdef USE_WOLFSSL
33#include <wolfssl/options.h>
34#ifndef NO_SHA256
35#define USE_OPENSSL_SHA256
36#endif
37#endif
38
39#if defined(USE_OPENSSL)
40
41#include <openssl/opensslv.h>
42
43#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
44#define USE_OPENSSL_SHA256
45#endif
46
47#endif /* USE_OPENSSL */
48
49#ifdef USE_MBEDTLS
50#include <mbedtls/version.h>
51
52#if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \
53 (MBEDTLS_VERSION_NUMBER < 0x03000000)
54 #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
55#endif
56#endif /* USE_MBEDTLS */
57
58/* Please keep the SSL backend-specific #if branches in this order:
59 *
60 * 1. USE_OPENSSL
61 * 2. USE_GNUTLS
62 * 3. USE_MBEDTLS
63 * 4. USE_COMMON_CRYPTO
64 * 5. USE_WIN32_CRYPTO
65 *
66 * This ensures that the same SSL branch gets activated throughout this source
67 * file even if multiple backends are enabled at the same time.
68 */
69
70#if defined(USE_OPENSSL_SHA256)
71
72/* When OpenSSL or wolfSSL is available is available we use their
73 * SHA256-functions.
74 */
75#if defined(USE_OPENSSL)
76#include <openssl/evp.h>
77#elif defined(USE_WOLFSSL)
78#include <wolfssl/openssl/evp.h>
79#endif
80
81#include "curl_memory.h"
82
83/* The last #include file should be: */
84#include "memdebug.h"
85
86struct sha256_ctx {
87 EVP_MD_CTX *openssl_ctx;
88};
89typedef struct sha256_ctx my_sha256_ctx;
90
91static CURLcode my_sha256_init(my_sha256_ctx *ctx)
92{
93 ctx->openssl_ctx = EVP_MD_CTX_create();
94 if(!ctx->openssl_ctx)
95 return CURLE_OUT_OF_MEMORY;
96
97 EVP_DigestInit_ex(ctx->openssl_ctx, EVP_sha256(), NULL);
98 return CURLE_OK;
99}
100
101static void my_sha256_update(my_sha256_ctx *ctx,
102 const unsigned char *data,
103 unsigned int length)
104{
105 EVP_DigestUpdate(ctx->openssl_ctx, data, length);
106}
107
108static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
109{
110 EVP_DigestFinal_ex(ctx->openssl_ctx, digest, NULL);
111 EVP_MD_CTX_destroy(ctx->openssl_ctx);
112}
113
114#elif defined(USE_GNUTLS)
115
116#include <nettle/sha.h>
117
118#include "curl_memory.h"
119
120/* The last #include file should be: */
121#include "memdebug.h"
122
123typedef struct sha256_ctx my_sha256_ctx;
124
125static CURLcode my_sha256_init(my_sha256_ctx *ctx)
126{
127 sha256_init(ctx);
128 return CURLE_OK;
129}
130
131static void my_sha256_update(my_sha256_ctx *ctx,
132 const unsigned char *data,
133 unsigned int length)
134{
135 sha256_update(ctx, length, data);
136}
137
138static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
139{
140 sha256_digest(ctx, SHA256_DIGEST_SIZE, digest);
141}
142
143#elif defined(USE_MBEDTLS)
144
145#include <mbedtls/sha256.h>
146
147#include "curl_memory.h"
148
149/* The last #include file should be: */
150#include "memdebug.h"
151
152typedef mbedtls_sha256_context my_sha256_ctx;
153
154static CURLcode my_sha256_init(my_sha256_ctx *ctx)
155{
156#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
157 (void) mbedtls_sha256_starts(ctx, 0);
158#else
159 (void) mbedtls_sha256_starts_ret(ctx, 0);
160#endif
161 return CURLE_OK;
162}
163
164static void my_sha256_update(my_sha256_ctx *ctx,
165 const unsigned char *data,
166 unsigned int length)
167{
168#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
169 (void) mbedtls_sha256_update(ctx, data, length);
170#else
171 (void) mbedtls_sha256_update_ret(ctx, data, length);
172#endif
173}
174
175static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
176{
177#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
178 (void) mbedtls_sha256_finish(ctx, digest);
179#else
180 (void) mbedtls_sha256_finish_ret(ctx, digest);
181#endif
182}
183
184#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
185 (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
186 (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
187 (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
188
189#include <CommonCrypto/CommonDigest.h>
190
191#include "curl_memory.h"
192
193/* The last #include file should be: */
194#include "memdebug.h"
195
196typedef CC_SHA256_CTX my_sha256_ctx;
197
198static CURLcode my_sha256_init(my_sha256_ctx *ctx)
199{
200 (void) CC_SHA256_Init(ctx);
201 return CURLE_OK;
202}
203
204static void my_sha256_update(my_sha256_ctx *ctx,
205 const unsigned char *data,
206 unsigned int length)
207{
208 (void) CC_SHA256_Update(ctx, data, length);
209}
210
211static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
212{
213 (void) CC_SHA256_Final(digest, ctx);
214}
215
216#elif defined(USE_WIN32_CRYPTO)
217
218#include <wincrypt.h>
219
220struct sha256_ctx {
221 HCRYPTPROV hCryptProv;
222 HCRYPTHASH hHash;
223};
224typedef struct sha256_ctx my_sha256_ctx;
225
226#if !defined(CALG_SHA_256)
227#define CALG_SHA_256 0x0000800c
228#endif
229
230static CURLcode my_sha256_init(my_sha256_ctx *ctx)
231{
232 if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
233 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
234 CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
235 }
236
237 return CURLE_OK;
238}
239
240static void my_sha256_update(my_sha256_ctx *ctx,
241 const unsigned char *data,
242 unsigned int length)
243{
244 CryptHashData(ctx->hHash, (unsigned char *) data, length, 0);
245}
246
247static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
248{
249 unsigned long length = 0;
250
251 CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
252 if(length == SHA256_DIGEST_LENGTH)
253 CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
254
255 if(ctx->hHash)
256 CryptDestroyHash(ctx->hHash);
257
258 if(ctx->hCryptProv)
259 CryptReleaseContext(ctx->hCryptProv, 0);
260}
261
262#else
263
264/* When no other crypto library is available we use this code segment */
265
266/* This is based on SHA256 implementation in LibTomCrypt that was released into
267 * public domain by Tom St Denis. */
268
269#define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \
270 (((unsigned long)(a)[1]) << 16) | \
271 (((unsigned long)(a)[2]) << 8) | \
272 ((unsigned long)(a)[3]))
273#define WPA_PUT_BE32(a, val) \
274do { \
275 (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \
276 (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \
277 (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff); \
278 (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff); \
279} while(0)
280
281#ifdef HAVE_LONGLONG
282#define WPA_PUT_BE64(a, val) \
283do { \
284 (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56); \
285 (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48); \
286 (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40); \
287 (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32); \
288 (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24); \
289 (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16); \
290 (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8); \
291 (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \
292} while(0)
293#else
294#define WPA_PUT_BE64(a, val) \
295do { \
296 (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56); \
297 (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48); \
298 (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40); \
299 (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32); \
300 (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24); \
301 (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16); \
302 (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8); \
303 (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \
304} while(0)
305#endif
306
307struct sha256_state {
308#ifdef HAVE_LONGLONG
309 unsigned long long length;
310#else
311 unsigned __int64 length;
312#endif
313 unsigned long state[8], curlen;
314 unsigned char buf[64];
315};
316typedef struct sha256_state my_sha256_ctx;
317
318/* The K array */
319static const unsigned long K[64] = {
320 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
321 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
322 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
323 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
324 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
325 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
326 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
327 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
328 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
329 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
330 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
331 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
332 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
333};
334
335/* Various logical functions */
336#define RORc(x, y) \
337(((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \
338 ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL)
339#define Ch(x,y,z) (z ^ (x & (y ^ z)))
340#define Maj(x,y,z) (((x | y) & z) | (x & y))
341#define S(x, n) RORc((x), (n))
342#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
343#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
344#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
345#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
346#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
347
348/* Compress 512-bits */
349static int sha256_compress(struct sha256_state *md,
350 unsigned char *buf)
351{
352 unsigned long S[8], W[64];
353 int i;
354
355 /* Copy state into S */
356 for(i = 0; i < 8; i++) {
357 S[i] = md->state[i];
358 }
359 /* copy the state into 512-bits into W[0..15] */
360 for(i = 0; i < 16; i++)
361 W[i] = WPA_GET_BE32(buf + (4 * i));
362 /* fill W[16..63] */
363 for(i = 16; i < 64; i++) {
364 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
365 W[i - 16];
366 }
367
368 /* Compress */
369#define RND(a,b,c,d,e,f,g,h,i) \
370 do { \
371 unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
372 unsigned long t1 = Sigma0(a) + Maj(a, b, c); \
373 d += t0; \
374 h = t0 + t1; \
375 } while(0)
376
377 for(i = 0; i < 64; ++i) {
378 unsigned long t;
379 RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
380 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
381 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
382 }
383
384 /* Feedback */
385 for(i = 0; i < 8; i++) {
386 md->state[i] = md->state[i] + S[i];
387 }
388
389 return 0;
390}
391
392/* Initialize the hash state */
393static CURLcode my_sha256_init(struct sha256_state *md)
394{
395 md->curlen = 0;
396 md->length = 0;
397 md->state[0] = 0x6A09E667UL;
398 md->state[1] = 0xBB67AE85UL;
399 md->state[2] = 0x3C6EF372UL;
400 md->state[3] = 0xA54FF53AUL;
401 md->state[4] = 0x510E527FUL;
402 md->state[5] = 0x9B05688CUL;
403 md->state[6] = 0x1F83D9ABUL;
404 md->state[7] = 0x5BE0CD19UL;
405
406 return CURLE_OK;
407}
408
409/*
410 Process a block of memory though the hash
411 @param md The hash state
412 @param in The data to hash
413 @param inlen The length of the data (octets)
414 @return 0 if successful
415*/
416static int my_sha256_update(struct sha256_state *md,
417 const unsigned char *in,
418 unsigned long inlen)
419{
420 unsigned long n;
421
422#define block_size 64
423 if(md->curlen > sizeof(md->buf))
424 return -1;
425 while(inlen > 0) {
426 if(md->curlen == 0 && inlen >= block_size) {
427 if(sha256_compress(md, (unsigned char *)in) < 0)
428 return -1;
429 md->length += block_size * 8;
430 in += block_size;
431 inlen -= block_size;
432 }
433 else {
434 n = CURLMIN(inlen, (block_size - md->curlen));
435 memcpy(md->buf + md->curlen, in, n);
436 md->curlen += n;
437 in += n;
438 inlen -= n;
439 if(md->curlen == block_size) {
440 if(sha256_compress(md, md->buf) < 0)
441 return -1;
442 md->length += 8 * block_size;
443 md->curlen = 0;
444 }
445 }
446 }
447
448 return 0;
449}
450
451/*
452 Terminate the hash to get the digest
453 @param md The hash state
454 @param out [out] The destination of the hash (32 bytes)
455 @return 0 if successful
456*/
457static int my_sha256_final(unsigned char *out,
458 struct sha256_state *md)
459{
460 int i;
461
462 if(md->curlen >= sizeof(md->buf))
463 return -1;
464
465 /* Increase the length of the message */
466 md->length += md->curlen * 8;
467
468 /* Append the '1' bit */
469 md->buf[md->curlen++] = (unsigned char)0x80;
470
471 /* If the length is currently above 56 bytes we append zeros
472 * then compress. Then we can fall back to padding zeros and length
473 * encoding like normal.
474 */
475 if(md->curlen > 56) {
476 while(md->curlen < 64) {
477 md->buf[md->curlen++] = (unsigned char)0;
478 }
479 sha256_compress(md, md->buf);
480 md->curlen = 0;
481 }
482
483 /* Pad up to 56 bytes of zeroes */
484 while(md->curlen < 56) {
485 md->buf[md->curlen++] = (unsigned char)0;
486 }
487
488 /* Store length */
489 WPA_PUT_BE64(md->buf + 56, md->length);
490 sha256_compress(md, md->buf);
491
492 /* Copy output */
493 for(i = 0; i < 8; i++)
494 WPA_PUT_BE32(out + (4 * i), md->state[i]);
495
496 return 0;
497}
498
499#endif /* CRYPTO LIBS */
500
501/*
502 * Curl_sha256it()
503 *
504 * Generates a SHA256 hash for the given input data.
505 *
506 * Parameters:
507 *
508 * output [in/out] - The output buffer.
509 * input [in] - The input data.
510 * length [in] - The input length.
511 *
512 * Returns CURLE_OK on success.
513 */
514CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input,
515 const size_t length)
516{
517 CURLcode result;
518 my_sha256_ctx ctx;
519
520 result = my_sha256_init(&ctx);
521 if(!result) {
522 my_sha256_update(&ctx, input, curlx_uztoui(length));
523 my_sha256_final(output, &ctx);
524 }
525 return result;
526}
527
528
529const struct HMAC_params Curl_HMAC_SHA256[] = {
530 {
531 /* Hash initialization function. */
532 CURLX_FUNCTION_CAST(HMAC_hinit_func, my_sha256_init),
533 /* Hash update function. */
534 CURLX_FUNCTION_CAST(HMAC_hupdate_func, my_sha256_update),
535 /* Hash computation end function. */
536 CURLX_FUNCTION_CAST(HMAC_hfinal_func, my_sha256_final),
537 /* Size of hash context structure. */
538 sizeof(my_sha256_ctx),
539 /* Maximum key length. */
540 64,
541 /* Result size. */
542 32
543 }
544};
545
546
547#endif /* CURL_DISABLE_CRYPTO_AUTH */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette