==> src/sha256_stream.c <==1/* Buffering bytes into 64-byte blocks, the FIPS 180-4 padding, the digest. */
2#include "sha256_stream.h"
3#include "sha256_compress.h"
4
5static void block(sha256_stream *s) {
6 uint32_t w[16];
7 for (int i = 0; i < 16; i++)
8 w[i] = (uint32_t)s->block[4 * i] << 24 | (uint32_t)s->block[4 * i + 1] << 16 | (uint32_t)s->block[4 * i + 2] << 8 | s->block[4 * i + 3];
9 sha256_compress(s->h, w);
10 s->used = 0;
11}
12
13void sha256_stream_init(sha256_stream *s) {
14 for (int i = 0; i < 8; i++) s->h[i] = SHA256_H0[i];
15 s->bytes = 0;
16 s->used = 0;
17}
18
19void sha256_stream_update(sha256_stream *s, const void *data, size_t n) {
20 const uint8_t *p = data;
21 s->bytes += n;
22 while (n > 0) {
23 size_t k = 64 - s->used < n ? 64 - s->used : n;
24 for (size_t i = 0; i < k; i++) s->block[s->used + i] = p[i];
25 s->used += k;
26 p += k;
27 n -= k;
28 if (s->used == 64) block(s);
29 }
30}
31
32void sha256_stream_final(sha256_stream *s, uint8_t out[32]) {
33 uint64_t bits = s->bytes * 8;
34 s->block[s->used++] = 0x80;
35 if (s->used > 56) {
36 while (s->used < 64) s->block[s->used++] = 0;
37 block(s);
38 }
39 while (s->used < 56) s->block[s->used++] = 0;
40 for (int i = 0; i < 8; i++) s->block[56 + i] = (uint8_t)(bits >> (56 - 8 * i));
41 block(s);
42 for (int i = 0; i < 8; i++)
43 for (int k = 0; k < 4; k++) out[4 * i + k] = (uint8_t)(s->h[i] >> (24 - 8 * k));
44}
45
46void sha256_stream_hex(const uint8_t digest[32], char out[65]) {
47 static const char hex[] = "0123456789abcdef";
48 for (int i = 0; i < 32; i++) {
49 out[2 * i] = hex[digest[i] >> 4];
50 out[2 * i + 1] = hex[digest[i] & 15];
51 }
52 out[64] = 0;
53}