smtp: use the upload buffer size for scratch buffer malloc
[platform/upstream/curl.git] / lib / sha256.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2016, Florin Petriuc, <petriuc.florin@gmail.com>
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.haxx.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  ***************************************************************************/
22
23 #include "curl_setup.h"
24
25 #ifndef CURL_DISABLE_CRYPTO_AUTH
26
27 #include "warnless.h"
28 #include "curl_sha256.h"
29
30 #if defined(USE_OPENSSL)
31
32 #include <openssl/opensslv.h>
33
34 #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
35 #define USE_OPENSSL_SHA256
36 #endif
37
38 #endif
39
40 #ifdef USE_OPENSSL_SHA256
41 /* When OpenSSL is available we use the SHA256-function from OpenSSL */
42 #include <openssl/sha.h>
43 #else
44
45 /* When no other crypto library is available we use this code segment */
46
47 /* ===== start - public domain SHA256 implementation ===== */
48 /* This is based on SHA256 implementation in LibTomCrypt that was released into
49  * public domain by Tom St Denis. */
50
51 #define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \
52                          (((unsigned long)(a)[1]) << 16) | \
53                          (((unsigned long)(a)[2]) <<  8) | \
54                           ((unsigned long)(a)[3]))
55 #define WPA_PUT_BE32(a, val)                                        \
56 do {                                                                \
57   (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \
58   (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \
59   (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff);  \
60   (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff);         \
61 } while(0)
62
63 #ifdef HAVE_LONGLONG
64 #define WPA_PUT_BE64(a, val)                                    \
65 do {                                                            \
66   (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56);  \
67   (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48);  \
68   (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40);  \
69   (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32);  \
70   (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24);  \
71   (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16);  \
72   (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8);   \
73   (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \
74 } while(0)
75 #else
76 #define WPA_PUT_BE64(a, val)                                  \
77 do {                                                          \
78   (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56);  \
79   (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48);  \
80   (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40);  \
81   (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32);  \
82   (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24);  \
83   (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16);  \
84   (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8);   \
85   (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \
86 } while(0)
87 #endif
88
89 typedef struct sha256_state {
90 #ifdef HAVE_LONGLONG
91   unsigned long long length;
92 #else
93   unsigned __int64 length;
94 #endif
95   unsigned long state[8], curlen;
96   unsigned char buf[64];
97 } SHA256_CTX;
98 /* the K array */
99 static const unsigned long K[64] = {
100   0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
101   0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
102   0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
103   0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
104   0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
105   0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
106   0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
107   0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
108   0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
109   0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
110   0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
111   0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
112   0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
113 };
114 /* Various logical functions */
115 #define RORc(x, y) \
116 (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \
117    ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL)
118 #define Ch(x,y,z)   (z ^ (x & (y ^ z)))
119 #define Maj(x,y,z)  (((x | y) & z) | (x & y))
120 #define S(x, n)     RORc((x), (n))
121 #define R(x, n)     (((x)&0xFFFFFFFFUL)>>(n))
122 #define Sigma0(x)   (S(x, 2) ^ S(x, 13) ^ S(x, 22))
123 #define Sigma1(x)   (S(x, 6) ^ S(x, 11) ^ S(x, 25))
124 #define Gamma0(x)   (S(x, 7) ^ S(x, 18) ^ R(x, 3))
125 #define Gamma1(x)   (S(x, 17) ^ S(x, 19) ^ R(x, 10))
126 #ifndef MIN
127 #define MIN(x, y)   (((x) < (y)) ? (x) : (y))
128 #endif
129 /* compress 512-bits */
130 static int sha256_compress(struct sha256_state *md,
131                            unsigned char *buf)
132 {
133   unsigned long S[8], W[64], t0, t1;
134   unsigned long t;
135   int i;
136   /* copy state into S */
137   for(i = 0; i < 8; i++) {
138     S[i] = md->state[i];
139   }
140   /* copy the state into 512-bits into W[0..15] */
141   for(i = 0; i < 16; i++)
142     W[i] = WPA_GET_BE32(buf + (4 * i));
143   /* fill W[16..63] */
144   for(i = 16; i < 64; i++) {
145     W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
146       W[i - 16];
147   }
148   /* Compress */
149 #define RND(a,b,c,d,e,f,g,h,i)                    \
150   t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
151   t1 = Sigma0(a) + Maj(a, b, c);                  \
152   d += t0;                                        \
153   h = t0 + t1;
154   for(i = 0; i < 64; ++i) {
155     RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
156     t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
157     S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
158   }
159   /* feedback */
160   for(i = 0; i < 8; i++) {
161     md->state[i] = md->state[i] + S[i];
162   }
163   return 0;
164 }
165 /* Initialize the hash state */
166 static void SHA256_Init(struct sha256_state *md)
167 {
168   md->curlen = 0;
169   md->length = 0;
170   md->state[0] = 0x6A09E667UL;
171   md->state[1] = 0xBB67AE85UL;
172   md->state[2] = 0x3C6EF372UL;
173   md->state[3] = 0xA54FF53AUL;
174   md->state[4] = 0x510E527FUL;
175   md->state[5] = 0x9B05688CUL;
176   md->state[6] = 0x1F83D9ABUL;
177   md->state[7] = 0x5BE0CD19UL;
178 }
179 /**
180    Process a block of memory though the hash
181    @param md     The hash state
182    @param in     The data to hash
183    @param inlen  The length of the data (octets)
184    @return CRYPT_OK if successful
185 */
186 static int SHA256_Update(struct sha256_state *md,
187                          const unsigned char *in,
188                          unsigned long inlen)
189 {
190   unsigned long n;
191 #define block_size 64
192   if(md->curlen > sizeof(md->buf))
193     return -1;
194   while(inlen > 0) {
195     if(md->curlen == 0 && inlen >= block_size) {
196       if(sha256_compress(md, (unsigned char *)in) < 0)
197         return -1;
198       md->length += block_size * 8;
199       in += block_size;
200       inlen -= block_size;
201     }
202     else {
203       n = MIN(inlen, (block_size - md->curlen));
204       memcpy(md->buf + md->curlen, in, n);
205       md->curlen += n;
206       in += n;
207       inlen -= n;
208       if(md->curlen == block_size) {
209         if(sha256_compress(md, md->buf) < 0)
210           return -1;
211         md->length += 8 * block_size;
212         md->curlen = 0;
213       }
214     }
215   }
216   return 0;
217 }
218 /**
219    Terminate the hash to get the digest
220    @param md  The hash state
221    @param out [out] The destination of the hash (32 bytes)
222    @return CRYPT_OK if successful
223 */
224 static int SHA256_Final(unsigned char *out,
225                         struct sha256_state *md)
226 {
227   int i;
228   if(md->curlen >= sizeof(md->buf))
229     return -1;
230   /* increase the length of the message */
231   md->length += md->curlen * 8;
232   /* append the '1' bit */
233   md->buf[md->curlen++] = (unsigned char)0x80;
234   /* if the length is currently above 56 bytes we append zeros
235    * then compress.  Then we can fall back to padding zeros and length
236    * encoding like normal.
237    */
238   if(md->curlen > 56) {
239     while(md->curlen < 64) {
240       md->buf[md->curlen++] = (unsigned char)0;
241     }
242     sha256_compress(md, md->buf);
243     md->curlen = 0;
244   }
245   /* pad up to 56 bytes of zeroes */
246   while(md->curlen < 56) {
247     md->buf[md->curlen++] = (unsigned char)0;
248   }
249   /* store length */
250   WPA_PUT_BE64(md->buf + 56, md->length);
251   sha256_compress(md, md->buf);
252   /* copy output */
253   for(i = 0; i < 8; i++)
254     WPA_PUT_BE32(out + (4 * i), md->state[i]);
255   return 0;
256 }
257 /* ===== end - public domain SHA256 implementation ===== */
258
259 #endif
260
261 void Curl_sha256it(unsigned char *outbuffer, /* 32 unsigned chars */
262                    const unsigned char *input)
263 {
264   SHA256_CTX ctx;
265   SHA256_Init(&ctx);
266   SHA256_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
267   SHA256_Final(outbuffer, &ctx);
268 }
269
270 #endif /* CURL_DISABLE_CRYPTO_AUTH */