Annotation of embedaddon/curl/lib/sha256.c, revision 1.1.1.1
1.1 misho 1: /***************************************************************************
2: * _ _ ____ _
3: * Project ___| | | | _ \| |
4: * / __| | | | |_) | |
5: * | (__| |_| | _ <| |___
6: * \___|\___/|_| \_\_____|
7: *
8: * Copyright (C) 2017, Florin Petriuc, <petriuc.florin@gmail.com>
9: * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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.haxx.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:
31: #if defined(USE_OPENSSL)
32:
33: #include <openssl/opensslv.h>
34:
35: #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
36: #define USE_OPENSSL_SHA256
37: #endif
38:
39: #endif /* USE_OPENSSL */
40:
41: #ifdef USE_MBEDTLS
42: #include <mbedtls/version.h>
43:
44: #if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
45: #define HAS_RESULT_CODE_BASED_FUNCTIONS
46: #endif
47: #endif /* USE_MBEDTLS */
48:
49: /* Please keep the SSL backend-specific #if branches in this order:
50: *
51: * 1. USE_OPENSSL
52: * 2. USE_GNUTLS_NETTLE
53: * 3. USE_GNUTLS
54: * 4. USE_MBEDTLS
55: * 5. USE_COMMON_CRYPTO
56: * 6. USE_WIN32_CRYPTO
57: *
58: * This ensures that the same SSL branch gets activated throughout this source
59: * file even if multiple backends are enabled at the same time.
60: */
61:
62: #if defined(USE_OPENSSL_SHA256)
63:
64: /* When OpenSSL is available we use the SHA256-function from OpenSSL */
65: #include <openssl/sha.h>
66:
67: #elif defined(USE_GNUTLS_NETTLE)
68:
69: #include <nettle/sha.h>
70:
71: #include "curl_memory.h"
72:
73: /* The last #include file should be: */
74: #include "memdebug.h"
75:
76: typedef struct sha256_ctx SHA256_CTX;
77:
78: static void SHA256_Init(SHA256_CTX *ctx)
79: {
80: sha256_init(ctx);
81: }
82:
83: static void SHA256_Update(SHA256_CTX *ctx,
84: const unsigned char *data,
85: unsigned int length)
86: {
87: sha256_update(ctx, length, data);
88: }
89:
90: static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
91: {
92: sha256_digest(ctx, SHA256_DIGEST_SIZE, digest);
93: }
94:
95: #elif defined(USE_GNUTLS)
96:
97: #include <gcrypt.h>
98:
99: #include "curl_memory.h"
100:
101: /* The last #include file should be: */
102: #include "memdebug.h"
103:
104: typedef gcry_md_hd_t SHA256_CTX;
105:
106: static void SHA256_Init(SHA256_CTX *ctx)
107: {
108: gcry_md_open(ctx, GCRY_MD_SHA256, 0);
109: }
110:
111: static void SHA256_Update(SHA256_CTX *ctx,
112: const unsigned char *data,
113: unsigned int length)
114: {
115: gcry_md_write(*ctx, data, length);
116: }
117:
118: static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
119: {
120: memcpy(digest, gcry_md_read(*ctx, 0), SHA256_DIGEST_LENGTH);
121: gcry_md_close(*ctx);
122: }
123:
124: #elif defined(USE_MBEDTLS)
125:
126: #include <mbedtls/sha256.h>
127:
128: #include "curl_memory.h"
129:
130: /* The last #include file should be: */
131: #include "memdebug.h"
132:
133: typedef mbedtls_sha256_context SHA256_CTX;
134:
135: static void SHA256_Init(SHA256_CTX *ctx)
136: {
137: #if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
138: mbedtls_sha256_starts(ctx, 0);
139: #else
140: (void) mbedtls_sha256_starts_ret(ctx, 0);
141: #endif
142: }
143:
144: static void SHA256_Update(SHA256_CTX *ctx,
145: const unsigned char *data,
146: unsigned int length)
147: {
148: #if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
149: mbedtls_sha256_update(ctx, data, length);
150: #else
151: (void) mbedtls_sha256_update_ret(ctx, data, length);
152: #endif
153: }
154:
155: static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
156: {
157: #if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
158: mbedtls_sha256_finish(ctx, digest);
159: #else
160: (void) mbedtls_sha256_finish_ret(ctx, digest);
161: #endif
162: }
163:
164: #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
165: (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
166: (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
167: (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
168:
169: #include <CommonCrypto/CommonDigest.h>
170:
171: #include "curl_memory.h"
172:
173: /* The last #include file should be: */
174: #include "memdebug.h"
175:
176: typedef CC_SHA256_CTX SHA256_CTX;
177:
178: static void SHA256_Init(SHA256_CTX *ctx)
179: {
180: (void) CC_SHA256_Init(ctx);
181: }
182:
183: static void SHA256_Update(SHA256_CTX *ctx,
184: const unsigned char *data,
185: unsigned int length)
186: {
187: (void) CC_SHA256_Update(ctx, data, length);
188: }
189:
190: static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
191: {
192: (void) CC_SHA256_Final(digest, ctx);
193: }
194:
195: #elif defined(USE_WIN32_CRYPTO)
196:
197: #include <wincrypt.h>
198:
199: typedef struct {
200: HCRYPTPROV hCryptProv;
201: HCRYPTHASH hHash;
202: } SHA256_CTX;
203:
204: #if !defined(CALG_SHA_256)
205: #define CALG_SHA_256 0x0000800c
206: #endif
207:
208: static void SHA256_Init(SHA256_CTX *ctx)
209: {
210: if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
211: CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
212: CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
213: }
214: }
215:
216: static void SHA256_Update(SHA256_CTX *ctx,
217: const unsigned char *data,
218: unsigned int length)
219: {
220: CryptHashData(ctx->hHash, (unsigned char *) data, length, 0);
221: }
222:
223: static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
224: {
225: unsigned long length;
226:
227: CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
228: if(length == SHA256_DIGEST_LENGTH)
229: CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
230:
231: if(ctx->hHash)
232: CryptDestroyHash(ctx->hHash);
233:
234: if(ctx->hCryptProv)
235: CryptReleaseContext(ctx->hCryptProv, 0);
236: }
237:
238: #else
239:
240: /* When no other crypto library is available we use this code segment */
241:
242: /* This is based on SHA256 implementation in LibTomCrypt that was released into
243: * public domain by Tom St Denis. */
244:
245: #define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \
246: (((unsigned long)(a)[1]) << 16) | \
247: (((unsigned long)(a)[2]) << 8) | \
248: ((unsigned long)(a)[3]))
249: #define WPA_PUT_BE32(a, val) \
250: do { \
251: (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \
252: (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \
253: (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff); \
254: (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff); \
255: } while(0)
256:
257: #ifdef HAVE_LONGLONG
258: #define WPA_PUT_BE64(a, val) \
259: do { \
260: (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56); \
261: (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48); \
262: (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40); \
263: (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32); \
264: (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24); \
265: (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16); \
266: (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8); \
267: (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \
268: } while(0)
269: #else
270: #define WPA_PUT_BE64(a, val) \
271: do { \
272: (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56); \
273: (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48); \
274: (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40); \
275: (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32); \
276: (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24); \
277: (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16); \
278: (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8); \
279: (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \
280: } while(0)
281: #endif
282:
283: typedef struct sha256_state {
284: #ifdef HAVE_LONGLONG
285: unsigned long long length;
286: #else
287: unsigned __int64 length;
288: #endif
289: unsigned long state[8], curlen;
290: unsigned char buf[64];
291: } SHA256_CTX;
292:
293: /* The K array */
294: static const unsigned long K[64] = {
295: 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
296: 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
297: 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
298: 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
299: 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
300: 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
301: 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
302: 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
303: 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
304: 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
305: 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
306: 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
307: 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
308: };
309:
310: /* Various logical functions */
311: #define RORc(x, y) \
312: (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \
313: ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL)
314: #define Ch(x,y,z) (z ^ (x & (y ^ z)))
315: #define Maj(x,y,z) (((x | y) & z) | (x & y))
316: #define S(x, n) RORc((x), (n))
317: #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
318: #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
319: #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
320: #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
321: #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
322:
323: /* Compress 512-bits */
324: static int sha256_compress(struct sha256_state *md,
325: unsigned char *buf)
326: {
327: unsigned long S[8], W[64];
328: int i;
329:
330: /* Copy state into S */
331: for(i = 0; i < 8; i++) {
332: S[i] = md->state[i];
333: }
334: /* copy the state into 512-bits into W[0..15] */
335: for(i = 0; i < 16; i++)
336: W[i] = WPA_GET_BE32(buf + (4 * i));
337: /* fill W[16..63] */
338: for(i = 16; i < 64; i++) {
339: W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
340: W[i - 16];
341: }
342:
343: /* Compress */
344: #define RND(a,b,c,d,e,f,g,h,i) \
345: unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
346: unsigned long t1 = Sigma0(a) + Maj(a, b, c); \
347: d += t0; \
348: h = t0 + t1;
349: for(i = 0; i < 64; ++i) {
350: unsigned long t;
351: RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
352: t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
353: S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
354: }
355:
356: /* Feedback */
357: for(i = 0; i < 8; i++) {
358: md->state[i] = md->state[i] + S[i];
359: }
360:
361: return 0;
362: }
363:
364: /* Initialize the hash state */
365: static void SHA256_Init(struct sha256_state *md)
366: {
367: md->curlen = 0;
368: md->length = 0;
369: md->state[0] = 0x6A09E667UL;
370: md->state[1] = 0xBB67AE85UL;
371: md->state[2] = 0x3C6EF372UL;
372: md->state[3] = 0xA54FF53AUL;
373: md->state[4] = 0x510E527FUL;
374: md->state[5] = 0x9B05688CUL;
375: md->state[6] = 0x1F83D9ABUL;
376: md->state[7] = 0x5BE0CD19UL;
377: }
378:
379: /*
380: Process a block of memory though the hash
381: @param md The hash state
382: @param in The data to hash
383: @param inlen The length of the data (octets)
384: @return CRYPT_OK if successful
385: */
386: static int SHA256_Update(struct sha256_state *md,
387: const unsigned char *in,
388: unsigned long inlen)
389: {
390: unsigned long n;
391:
392: #define block_size 64
393: if(md->curlen > sizeof(md->buf))
394: return -1;
395: while(inlen > 0) {
396: if(md->curlen == 0 && inlen >= block_size) {
397: if(sha256_compress(md, (unsigned char *)in) < 0)
398: return -1;
399: md->length += block_size * 8;
400: in += block_size;
401: inlen -= block_size;
402: }
403: else {
404: n = CURLMIN(inlen, (block_size - md->curlen));
405: memcpy(md->buf + md->curlen, in, n);
406: md->curlen += n;
407: in += n;
408: inlen -= n;
409: if(md->curlen == block_size) {
410: if(sha256_compress(md, md->buf) < 0)
411: return -1;
412: md->length += 8 * block_size;
413: md->curlen = 0;
414: }
415: }
416: }
417:
418: return 0;
419: }
420:
421: /*
422: Terminate the hash to get the digest
423: @param md The hash state
424: @param out [out] The destination of the hash (32 bytes)
425: @return CRYPT_OK if successful
426: */
427: static int SHA256_Final(unsigned char *out,
428: struct sha256_state *md)
429: {
430: int i;
431:
432: if(md->curlen >= sizeof(md->buf))
433: return -1;
434:
435: /* Increase the length of the message */
436: md->length += md->curlen * 8;
437:
438: /* Append the '1' bit */
439: md->buf[md->curlen++] = (unsigned char)0x80;
440:
441: /* If the length is currently above 56 bytes we append zeros
442: * then compress. Then we can fall back to padding zeros and length
443: * encoding like normal.
444: */
445: if(md->curlen > 56) {
446: while(md->curlen < 64) {
447: md->buf[md->curlen++] = (unsigned char)0;
448: }
449: sha256_compress(md, md->buf);
450: md->curlen = 0;
451: }
452:
453: /* Pad up to 56 bytes of zeroes */
454: while(md->curlen < 56) {
455: md->buf[md->curlen++] = (unsigned char)0;
456: }
457:
458: /* Store length */
459: WPA_PUT_BE64(md->buf + 56, md->length);
460: sha256_compress(md, md->buf);
461:
462: /* Copy output */
463: for(i = 0; i < 8; i++)
464: WPA_PUT_BE32(out + (4 * i), md->state[i]);
465:
466: return 0;
467: }
468:
469: #endif /* CRYPTO LIBS */
470:
471: /*
472: * Curl_sha256it()
473: *
474: * Generates a SHA256 hash for the given input data.
475: *
476: * Parameters:
477: *
478: * output [in/out] - The output buffer.
479: * input [in] - The input data.
480: * length [in] - The input length.
481: */
482: void Curl_sha256it(unsigned char *output, const unsigned char *input,
483: const size_t length)
484: {
485: SHA256_CTX ctx;
486:
487: SHA256_Init(&ctx);
488: SHA256_Update(&ctx, input, curlx_uztoui(length));
489: SHA256_Final(output, &ctx);
490: }
491:
492: #endif /* CURL_DISABLE_CRYPTO_AUTH */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>