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