diff options
| author | eunhhu <[email protected]> | 2026-10-04 12:46:34 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-10-04 12:46:34 +0100 |
| commit | 9fd2e16b68e1a83e2605e8a9cbd9b6d04a4da2f6 (patch) | |
| tree | 2ae9aaf2cc5f3e5d4eef0209d013ac8332c02984 /serve/sha256.c | |
| parent | 1ff4fd3b1ae2b2ada273d7ffaee8501c9d43d5c0 (diff) | |
| download | pure-9fd2e16b68e1a83e2605e8a9cbd9b6d04a4da2f6.tar.gz pure-9fd2e16b68e1a83e2605e8a9cbd9b6d04a4da2f6.zip | |
Take an app's requests only with a token its tokens file grants (017, 3b)
An app given a tokens file (tokens=FILE in --apps, --tokens FILE for the
one app of a host) answers a request only when it bears a token
(Authorization: Bearer) whose SHA-256 the file lists with a grant: read
for its views, queries and documents, write for all, input=NAME for
those inputs alone; 401 unauthorized (WWW-Authenticate: Bearer) without
one, 403 forbidden past its grant. A delivery sealed by a key --sender
names needs none. The digests are compared in constant time; a
connection keeps its last token's digest, so the same token is hashed
once. SHA-256 is the host's own (serve/sha256.c), no OpenSSL loaded. A
reading puts a changed tokens file in place with the app running on; a
file that is not one stops the app. pure-serve --make-token GRANT makes
a token and its line. load takes PURE_LOAD_TOKEN.
Diffstat (limited to 'serve/sha256.c')
| -rw-r--r-- | serve/sha256.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/serve/sha256.c b/serve/sha256.c new file mode 100644 index 0000000..01e49c7 --- /dev/null +++ b/serve/sha256.c @@ -0,0 +1,50 @@ +#include "sha256.h" +#include <stdint.h> +#include <string.h> + +static const uint32_t K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, + 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, + 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; + +static uint32_t rotate(uint32_t x, unsigned n) { return x >> n | x << (32 - n); } + +/* One 64-byte block into the state. */ +static void block(uint32_t h[8], const unsigned char *p) { + uint32_t w[64]; + for (unsigned i = 0; i < 16; ++i) w[i] = (uint32_t)p[4 * i] << 24 | (uint32_t)p[4 * i + 1] << 16 | (uint32_t)p[4 * i + 2] << 8 | p[4 * i + 3]; + for (unsigned i = 16; i < 64; ++i) { + uint32_t s0 = rotate(w[i - 15], 7) ^ rotate(w[i - 15], 18) ^ w[i - 15] >> 3; + uint32_t s1 = rotate(w[i - 2], 17) ^ rotate(w[i - 2], 19) ^ w[i - 2] >> 10; + w[i] = w[i - 16] + s0 + w[i - 7] + s1; + } + uint32_t a = h[0], b = h[1], c = h[2], d = h[3], e = h[4], f = h[5], g = h[6], k = h[7]; + for (unsigned i = 0; i < 64; ++i) { + uint32_t t1 = k + (rotate(e, 6) ^ rotate(e, 11) ^ rotate(e, 25)) + ((e & f) ^ (~e & g)) + K[i] + w[i]; + uint32_t t2 = (rotate(a, 2) ^ rotate(a, 13) ^ rotate(a, 22)) + ((a & b) ^ (a & c) ^ (b & c)); + k = g, g = f, f = e, e = d + t1, d = c, c = b, b = a, a = t1 + t2; + } + h[0] += a, h[1] += b, h[2] += c, h[3] += d, h[4] += e, h[5] += f, h[6] += g, h[7] += k; +} + +void pure_sha256(const void *data, size_t size, unsigned char out[32]) { + uint32_t h[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + const unsigned char *p = data; + size_t whole = size / 64 * 64; + for (size_t at = 0; at < whole; at += 64) block(h, p + at); + /* The rest, a 1 bit, zeros, and the length in bits (one block more when it does not fit). */ + unsigned char last[128] = {0}; + size_t rest = size - whole, blocks = rest < 56 ? 1 : 2; + if (rest) memcpy(last, p + whole, rest); + last[rest] = 0x80; + uint64_t bits = (uint64_t)size * 8; + for (unsigned i = 0; i < 8; ++i) last[blocks * 64 - 1 - i] = (unsigned char)(bits >> (8 * i)); + for (size_t at = 0; at < blocks * 64; at += 64) block(h, last + at); + for (unsigned i = 0; i < 8; ++i) + out[4 * i] = (unsigned char)(h[i] >> 24), out[4 * i + 1] = (unsigned char)(h[i] >> 16), + out[4 * i + 2] = (unsigned char)(h[i] >> 8), out[4 * i + 3] = (unsigned char)h[i]; +} |
