• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SHA256_Init(SHA256_CTX * ctx)78 static void SHA256_Init(SHA256_CTX *ctx)
79 {
80   sha256_init(ctx);
81 }
82 
SHA256_Update(SHA256_CTX * ctx,const unsigned char * data,unsigned int length)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 
SHA256_Final(unsigned char * digest,SHA256_CTX * ctx)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 
SHA256_Init(SHA256_CTX * ctx)106 static void SHA256_Init(SHA256_CTX *ctx)
107 {
108   gcry_md_open(ctx, GCRY_MD_SHA256, 0);
109 }
110 
SHA256_Update(SHA256_CTX * ctx,const unsigned char * data,unsigned int length)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 
SHA256_Final(unsigned char * digest,SHA256_CTX * ctx)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 
SHA256_Init(SHA256_CTX * ctx)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 
SHA256_Update(SHA256_CTX * ctx,const unsigned char * data,unsigned int length)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 
SHA256_Final(unsigned char * digest,SHA256_CTX * ctx)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 
SHA256_Init(SHA256_CTX * ctx)178 static void SHA256_Init(SHA256_CTX *ctx)
179 {
180   (void) CC_SHA256_Init(ctx);
181 }
182 
SHA256_Update(SHA256_CTX * ctx,const unsigned char * data,unsigned int length)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 
SHA256_Final(unsigned char * digest,SHA256_CTX * ctx)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 struct sha256_ctx {
200   HCRYPTPROV hCryptProv;
201   HCRYPTHASH hHash;
202 };
203 typedef struct sha256_ctx SHA256_CTX;
204 
205 #if !defined(CALG_SHA_256)
206 #define CALG_SHA_256 0x0000800c
207 #endif
208 
SHA256_Init(SHA256_CTX * ctx)209 static void SHA256_Init(SHA256_CTX *ctx)
210 {
211   if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
212                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
213     CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
214   }
215 }
216 
SHA256_Update(SHA256_CTX * ctx,const unsigned char * data,unsigned int length)217 static void SHA256_Update(SHA256_CTX *ctx,
218                           const unsigned char *data,
219                           unsigned int length)
220 {
221   CryptHashData(ctx->hHash, (unsigned char *) data, length, 0);
222 }
223 
SHA256_Final(unsigned char * digest,SHA256_CTX * ctx)224 static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
225 {
226   unsigned long length = 0;
227 
228   CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
229   if(length == SHA256_DIGEST_LENGTH)
230     CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
231 
232   if(ctx->hHash)
233     CryptDestroyHash(ctx->hHash);
234 
235   if(ctx->hCryptProv)
236     CryptReleaseContext(ctx->hCryptProv, 0);
237 }
238 
239 #else
240 
241 /* When no other crypto library is available we use this code segment */
242 
243 /* This is based on SHA256 implementation in LibTomCrypt that was released into
244  * public domain by Tom St Denis. */
245 
246 #define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \
247                          (((unsigned long)(a)[1]) << 16) | \
248                          (((unsigned long)(a)[2]) <<  8) | \
249                           ((unsigned long)(a)[3]))
250 #define WPA_PUT_BE32(a, val)                                        \
251 do {                                                                \
252   (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \
253   (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \
254   (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff);  \
255   (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff);         \
256 } while(0)
257 
258 #ifdef HAVE_LONGLONG
259 #define WPA_PUT_BE64(a, val)                                    \
260 do {                                                            \
261   (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56);  \
262   (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48);  \
263   (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40);  \
264   (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32);  \
265   (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24);  \
266   (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16);  \
267   (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8);   \
268   (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \
269 } while(0)
270 #else
271 #define WPA_PUT_BE64(a, val)                                  \
272 do {                                                          \
273   (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56);  \
274   (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48);  \
275   (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40);  \
276   (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32);  \
277   (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24);  \
278   (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16);  \
279   (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8);   \
280   (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \
281 } while(0)
282 #endif
283 
284 struct sha256_state {
285 #ifdef HAVE_LONGLONG
286   unsigned long long length;
287 #else
288   unsigned __int64 length;
289 #endif
290   unsigned long state[8], curlen;
291   unsigned char buf[64];
292 };
293 typedef struct sha256_state SHA256_CTX;
294 
295 /* The K array */
296 static const unsigned long K[64] = {
297   0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
298   0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
299   0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
300   0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
301   0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
302   0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
303   0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
304   0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
305   0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
306   0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
307   0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
308   0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
309   0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
310 };
311 
312 /* Various logical functions */
313 #define RORc(x, y) \
314 (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \
315    ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL)
316 #define Ch(x,y,z)   (z ^ (x & (y ^ z)))
317 #define Maj(x,y,z)  (((x | y) & z) | (x & y))
318 #define S(x, n)     RORc((x), (n))
319 #define R(x, n)     (((x)&0xFFFFFFFFUL)>>(n))
320 #define Sigma0(x)   (S(x, 2) ^ S(x, 13) ^ S(x, 22))
321 #define Sigma1(x)   (S(x, 6) ^ S(x, 11) ^ S(x, 25))
322 #define Gamma0(x)   (S(x, 7) ^ S(x, 18) ^ R(x, 3))
323 #define Gamma1(x)   (S(x, 17) ^ S(x, 19) ^ R(x, 10))
324 
325 /* Compress 512-bits */
sha256_compress(struct sha256_state * md,unsigned char * buf)326 static int sha256_compress(struct sha256_state *md,
327                            unsigned char *buf)
328 {
329   unsigned long S[8], W[64];
330   int i;
331 
332   /* Copy state into S */
333   for(i = 0; i < 8; i++) {
334     S[i] = md->state[i];
335   }
336   /* copy the state into 512-bits into W[0..15] */
337   for(i = 0; i < 16; i++)
338     W[i] = WPA_GET_BE32(buf + (4 * i));
339   /* fill W[16..63] */
340   for(i = 16; i < 64; i++) {
341     W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
342       W[i - 16];
343   }
344 
345   /* Compress */
346 #define RND(a,b,c,d,e,f,g,h,i)                                  \
347   unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
348   unsigned long t1 = Sigma0(a) + Maj(a, b, c);                  \
349   d += t0;                                                      \
350   h = t0 + t1;
351   for(i = 0; i < 64; ++i) {
352     unsigned long t;
353     RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
354     t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
355     S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
356   }
357 
358   /* Feedback */
359   for(i = 0; i < 8; i++) {
360     md->state[i] = md->state[i] + S[i];
361   }
362 
363   return 0;
364 }
365 
366 /* Initialize the hash state */
SHA256_Init(struct sha256_state * md)367 static void SHA256_Init(struct sha256_state *md)
368 {
369   md->curlen = 0;
370   md->length = 0;
371   md->state[0] = 0x6A09E667UL;
372   md->state[1] = 0xBB67AE85UL;
373   md->state[2] = 0x3C6EF372UL;
374   md->state[3] = 0xA54FF53AUL;
375   md->state[4] = 0x510E527FUL;
376   md->state[5] = 0x9B05688CUL;
377   md->state[6] = 0x1F83D9ABUL;
378   md->state[7] = 0x5BE0CD19UL;
379 }
380 
381 /*
382    Process a block of memory though the hash
383    @param md     The hash state
384    @param in     The data to hash
385    @param inlen  The length of the data (octets)
386    @return CRYPT_OK if successful
387 */
SHA256_Update(struct sha256_state * md,const unsigned char * in,unsigned long inlen)388 static int SHA256_Update(struct sha256_state *md,
389                          const unsigned char *in,
390                          unsigned long inlen)
391 {
392   unsigned long n;
393 
394 #define block_size 64
395   if(md->curlen > sizeof(md->buf))
396     return -1;
397   while(inlen > 0) {
398     if(md->curlen == 0 && inlen >= block_size) {
399       if(sha256_compress(md, (unsigned char *)in) < 0)
400         return -1;
401       md->length += block_size * 8;
402       in += block_size;
403       inlen -= block_size;
404     }
405     else {
406       n = CURLMIN(inlen, (block_size - md->curlen));
407       memcpy(md->buf + md->curlen, in, n);
408       md->curlen += n;
409       in += n;
410       inlen -= n;
411       if(md->curlen == block_size) {
412         if(sha256_compress(md, md->buf) < 0)
413           return -1;
414         md->length += 8 * block_size;
415         md->curlen = 0;
416       }
417     }
418   }
419 
420   return 0;
421 }
422 
423 /*
424    Terminate the hash to get the digest
425    @param md  The hash state
426    @param out [out] The destination of the hash (32 bytes)
427    @return CRYPT_OK if successful
428 */
SHA256_Final(unsigned char * out,struct sha256_state * md)429 static int SHA256_Final(unsigned char *out,
430                         struct sha256_state *md)
431 {
432   int i;
433 
434   if(md->curlen >= sizeof(md->buf))
435     return -1;
436 
437   /* Increase the length of the message */
438   md->length += md->curlen * 8;
439 
440   /* Append the '1' bit */
441   md->buf[md->curlen++] = (unsigned char)0x80;
442 
443   /* If the length is currently above 56 bytes we append zeros
444    * then compress.  Then we can fall back to padding zeros and length
445    * encoding like normal.
446    */
447   if(md->curlen > 56) {
448     while(md->curlen < 64) {
449       md->buf[md->curlen++] = (unsigned char)0;
450     }
451     sha256_compress(md, md->buf);
452     md->curlen = 0;
453   }
454 
455   /* Pad up to 56 bytes of zeroes */
456   while(md->curlen < 56) {
457     md->buf[md->curlen++] = (unsigned char)0;
458   }
459 
460   /* Store length */
461   WPA_PUT_BE64(md->buf + 56, md->length);
462   sha256_compress(md, md->buf);
463 
464   /* Copy output */
465   for(i = 0; i < 8; i++)
466     WPA_PUT_BE32(out + (4 * i), md->state[i]);
467 
468   return 0;
469 }
470 
471 #endif /* CRYPTO LIBS */
472 
473 /*
474  * Curl_sha256it()
475  *
476  * Generates a SHA256 hash for the given input data.
477  *
478  * Parameters:
479  *
480  * output [in/out] - The output buffer.
481  * input  [in]     - The input data.
482  * length [in]     - The input length.
483  */
Curl_sha256it(unsigned char * output,const unsigned char * input,const size_t length)484 void Curl_sha256it(unsigned char *output, const unsigned char *input,
485                    const size_t length)
486 {
487   SHA256_CTX ctx;
488 
489   SHA256_Init(&ctx);
490   SHA256_Update(&ctx, input, curlx_uztoui(length));
491   SHA256_Final(output, &ctx);
492 }
493 
494 #endif /* CURL_DISABLE_CRYPTO_AUTH */
495