1 // This is an open source non-commercial project. Dear PVS-Studio, please check
2 // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
3
4 /// @file sha256.c
5 ///
6 /// FIPS-180-2 compliant SHA-256 implementation
7 /// GPL by Christophe Devine, applies to older version.
8 /// Modified for md5deep, in public domain.
9 /// Modified For Vim, Mohsin Ahmed, http://www.cs.albany.edu/~mosh
10 /// Mohsin Ahmed states this work is distributed under the VIM License or GPL,
11 /// at your choice.
12 ///
13 /// Vim specific notes:
14 /// sha256_self_test() is implicitly called once.
15
16 #include <stddef.h> // for size_t
17 #include <stdio.h> // for snprintf().
18
19 #include "nvim/sha256.h" // for context_sha256_T
20 #include "nvim/vim.h" // for STRCPY()/STRLEN().
21
22 #ifdef INCLUDE_GENERATED_DECLARATIONS
23 # include "sha256.c.generated.h"
24 #endif
25 #define GET_UINT32(n, b, i) { \
26 (n) = ((uint32_t)(b)[(i)] << 24) \
27 | ((uint32_t)(b)[(i) + 1] << 16) \
28 | ((uint32_t)(b)[(i) + 2] << 8) \
29 | ((uint32_t)(b)[(i) + 3]); \
30 }
31
32 #define PUT_UINT32(n, b, i) { \
33 (b)[(i)] = (char_u)((n) >> 24); \
34 (b)[(i) + 1] = (char_u)((n) >> 16); \
35 (b)[(i) + 2] = (char_u)((n) >> 8); \
36 (b)[(i) + 3] = (char_u)((n)); \
37 }
38
sha256_start(context_sha256_T * ctx)39 void sha256_start(context_sha256_T *ctx)
40 {
41 ctx->total[0] = 0;
42 ctx->total[1] = 0;
43
44 ctx->state[0] = 0x6A09E667;
45 ctx->state[1] = 0xBB67AE85;
46 ctx->state[2] = 0x3C6EF372;
47 ctx->state[3] = 0xA54FF53A;
48 ctx->state[4] = 0x510E527F;
49 ctx->state[5] = 0x9B05688C;
50 ctx->state[6] = 0x1F83D9AB;
51 ctx->state[7] = 0x5BE0CD19;
52 }
53
sha256_process(context_sha256_T * ctx,const char_u data[SHA256_BUFFER_SIZE])54 static void sha256_process(context_sha256_T *ctx, const char_u data[SHA256_BUFFER_SIZE])
55 {
56 uint32_t temp1, temp2, W[SHA256_BUFFER_SIZE];
57 uint32_t A, B, C, D, E, F, G, H;
58
59 GET_UINT32(W[0], data, 0);
60 GET_UINT32(W[1], data, 4);
61 GET_UINT32(W[2], data, 8);
62 GET_UINT32(W[3], data, 12);
63 GET_UINT32(W[4], data, 16);
64 GET_UINT32(W[5], data, 20);
65 GET_UINT32(W[6], data, 24);
66 GET_UINT32(W[7], data, 28);
67 GET_UINT32(W[8], data, 32);
68 GET_UINT32(W[9], data, 36);
69 GET_UINT32(W[10], data, 40);
70 GET_UINT32(W[11], data, 44);
71 GET_UINT32(W[12], data, 48);
72 GET_UINT32(W[13], data, 52);
73 GET_UINT32(W[14], data, 56);
74 GET_UINT32(W[15], data, 60);
75
76 #define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
77 #define ROTR(x, n) (SHR(x, n) | (x << (32 - n)))
78
79 #define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
80 #define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
81
82 #define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
83 #define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
84
85 #define F0(x, y, z) ((x & y) | (z & (x | y)))
86 #define F1(x, y, z) (z ^ (x & (y ^ z)))
87
88 #define R(t) \
89 (W[t] = S1(W[t - 2]) + W[t - 7] + \
90 S0(W[t - 15]) + W[t - 16])
91
92 #define P(a, b, c, d, e, f, g, h, x, K) { \
93 temp1 = h + S3(e) + F1(e, f, g) + K + x; \
94 temp2 = S2(a) + F0(a, b, c); \
95 d += temp1; h = temp1 + temp2; \
96 }
97
98 A = ctx->state[0];
99 B = ctx->state[1];
100 C = ctx->state[2];
101 D = ctx->state[3];
102 E = ctx->state[4];
103 F = ctx->state[5];
104 G = ctx->state[6];
105 H = ctx->state[7];
106
107 P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
108 P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
109 P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
110 P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
111 P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
112 P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
113 P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
114 P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
115 P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
116 P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
117 P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
118 P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
119 P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
120 P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
121 P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
122 P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
123 P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
124 P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
125 P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
126 P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
127 P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
128 P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
129 P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
130 P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
131 P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
132 P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
133 P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
134 P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
135 P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
136 P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
137 P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
138 P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
139 P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
140 P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
141 P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
142 P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
143 P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
144 P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
145 P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
146 P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
147 P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
148 P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
149 P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
150 P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
151 P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
152 P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
153 P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
154 P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
155 P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
156 P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
157 P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
158 P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
159 P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
160 P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
161 P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
162 P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
163 P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
164 P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
165 P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
166 P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
167 P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
168 P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
169 P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
170 P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
171
172 ctx->state[0] += A;
173 ctx->state[1] += B;
174 ctx->state[2] += C;
175 ctx->state[3] += D;
176 ctx->state[4] += E;
177 ctx->state[5] += F;
178 ctx->state[6] += G;
179 ctx->state[7] += H;
180 }
181
sha256_update(context_sha256_T * ctx,const char_u * input,size_t length)182 void sha256_update(context_sha256_T *ctx, const char_u *input, size_t length)
183 {
184 if (length == 0) {
185 return;
186 }
187
188 uint32_t left = ctx->total[0] & (SHA256_BUFFER_SIZE-1); // left < buf size
189
190 ctx->total[0] += (uint32_t)length;
191 ctx->total[0] &= 0xFFFFFFFF;
192
193 if (ctx->total[0] < length) {
194 ctx->total[1]++;
195 }
196
197 size_t fill = SHA256_BUFFER_SIZE - left;
198
199 if (left && (length >= fill)) {
200 memcpy((void *)(ctx->buffer + left), (void *)input, fill);
201 sha256_process(ctx, ctx->buffer);
202 length -= fill;
203 input += fill;
204 left = 0;
205 }
206
207 while (length >= SHA256_BUFFER_SIZE) {
208 sha256_process(ctx, input);
209 length -= SHA256_BUFFER_SIZE;
210 input += SHA256_BUFFER_SIZE;
211 }
212
213 if (length) {
214 memcpy((void *)(ctx->buffer + left), (void *)input, length);
215 }
216 }
217
218 static char_u sha256_padding[SHA256_BUFFER_SIZE] = {
219 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
220 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
223 };
224
sha256_finish(context_sha256_T * ctx,char_u digest[SHA256_SUM_SIZE])225 void sha256_finish(context_sha256_T *ctx, char_u digest[SHA256_SUM_SIZE])
226 {
227 uint32_t last, padn;
228 uint32_t high, low;
229 char_u msglen[8];
230
231 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
232 low = (ctx->total[0] << 3);
233
234 PUT_UINT32(high, msglen, 0);
235 PUT_UINT32(low, msglen, 4);
236
237 last = ctx->total[0] & 0x3F;
238 padn = (last < 56) ? (56 - last) : (120 - last);
239
240 sha256_update(ctx, sha256_padding, padn);
241 sha256_update(ctx, msglen, 8);
242
243 PUT_UINT32(ctx->state[0], digest, 0);
244 PUT_UINT32(ctx->state[1], digest, 4);
245 PUT_UINT32(ctx->state[2], digest, 8);
246 PUT_UINT32(ctx->state[3], digest, 12);
247 PUT_UINT32(ctx->state[4], digest, 16);
248 PUT_UINT32(ctx->state[5], digest, 20);
249 PUT_UINT32(ctx->state[6], digest, 24);
250 PUT_UINT32(ctx->state[7], digest, 28);
251 }
252
253 #define SHA_STEP 2
254
255 /// Gets the hex digest of the buffer.
256 ///
257 /// @param buf
258 /// @param buf_len
259 /// @param salt
260 /// @param salt_len
261 ///
262 /// @returns hex digest of "buf[buf_len]" in a static array.
263 /// if "salt" is not NULL also do "salt[salt_len]".
sha256_bytes(const uint8_t * restrict buf,size_t buf_len,const uint8_t * restrict salt,size_t salt_len)264 const char *sha256_bytes(const uint8_t *restrict buf, size_t buf_len, const uint8_t *restrict salt,
265 size_t salt_len)
266 {
267 char_u sha256sum[SHA256_SUM_SIZE];
268 static char hexit[SHA256_BUFFER_SIZE + 1]; // buf size + NULL
269 context_sha256_T ctx;
270
271 sha256_self_test();
272
273 sha256_start(&ctx);
274 sha256_update(&ctx, buf, buf_len);
275
276 if (salt != NULL) {
277 sha256_update(&ctx, salt, salt_len);
278 }
279 sha256_finish(&ctx, sha256sum);
280
281 for (size_t j = 0; j < SHA256_SUM_SIZE; j++) {
282 snprintf(hexit + j * SHA_STEP, SHA_STEP + 1, "%02x", sha256sum[j]);
283 }
284 hexit[sizeof(hexit) - 1] = '\0';
285 return hexit;
286 }
287
288 // These are the standard FIPS-180-2 test vectors
289 static char *sha_self_test_msg[] = {
290 "abc",
291 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
292 NULL
293 };
294
295 static char *sha_self_test_vector[] = {
296 "ba7816bf8f01cfea414140de5dae2223" \
297 "b00361a396177a9cb410ff61f20015ad",
298 "248d6a61d20638b8e5c026930c3e6039" \
299 "a33ce45964ff2167f6ecedd419db06c1",
300 "cdc76e5c9914fb9281a1c7e284d73e67" \
301 "f1809a48a497200e046d39ccc7112cd0"
302 };
303
304 /// Perform a test on the SHA256 algorithm.
305 ///
306 /// @returns true if not failures generated.
sha256_self_test(void)307 bool sha256_self_test(void)
308 {
309 char output[SHA256_BUFFER_SIZE + 1]; // buf size + NULL
310 context_sha256_T ctx;
311 char_u buf[1000];
312 char_u sha256sum[SHA256_SUM_SIZE];
313 const char *hexit;
314
315 static bool sha256_self_tested = false;
316 static bool failures = false;
317
318 if (sha256_self_tested) {
319 return failures == false;
320 }
321 sha256_self_tested = true;
322
323 for (size_t i = 0; i < 3; i++) {
324 if (i < 2) {
325 hexit = sha256_bytes((uint8_t *)sha_self_test_msg[i],
326 strlen(sha_self_test_msg[i]),
327 NULL, 0);
328 STRCPY(output, hexit);
329 } else {
330 sha256_start(&ctx);
331 memset(buf, 'a', 1000);
332
333 for (size_t j = 0; j < 1000; j++) {
334 sha256_update(&ctx, buf, 1000);
335 }
336 sha256_finish(&ctx, sha256sum);
337
338 for (size_t j = 0; j < SHA256_SUM_SIZE; j++) {
339 snprintf(output + j * SHA_STEP, SHA_STEP+1, "%02x", sha256sum[j]);
340 }
341 }
342
343 if (memcmp(output, sha_self_test_vector[i], SHA256_BUFFER_SIZE)) {
344 failures = true;
345 output[sizeof(output) - 1] = '\0';
346
347 // printf("sha256_self_test %d failed %s\n", i, output);
348 }
349 }
350 return failures == false;
351 }
352