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