- reject reserved HashId values across lookup/parse/encode paths - add reserved-range registry table and remove 0x0000 from runtime list - forbid SHA-256 impl overrides; add streaming hash API - update tgk_store_mem test to use unsupported but non-reserved hash id - document ASL store digest-length constraint in README
219 lines
5.8 KiB
C
219 lines
5.8 KiB
C
#include "sha256.h"
|
|
|
|
#include <string.h>
|
|
|
|
static uint32_t amduat_sha256_rotr(uint32_t v, uint32_t n) {
|
|
return (v >> n) | (v << (32u - n));
|
|
}
|
|
|
|
static uint32_t amduat_sha256_ch(uint32_t x, uint32_t y, uint32_t z) {
|
|
return (x & y) ^ (~x & z);
|
|
}
|
|
|
|
static uint32_t amduat_sha256_maj(uint32_t x, uint32_t y, uint32_t z) {
|
|
return (x & y) ^ (x & z) ^ (y & z);
|
|
}
|
|
|
|
static uint32_t amduat_sha256_big_sigma0(uint32_t x) {
|
|
return amduat_sha256_rotr(x, 2u) ^ amduat_sha256_rotr(x, 13u) ^
|
|
amduat_sha256_rotr(x, 22u);
|
|
}
|
|
|
|
static uint32_t amduat_sha256_big_sigma1(uint32_t x) {
|
|
return amduat_sha256_rotr(x, 6u) ^ amduat_sha256_rotr(x, 11u) ^
|
|
amduat_sha256_rotr(x, 25u);
|
|
}
|
|
|
|
static uint32_t amduat_sha256_small_sigma0(uint32_t x) {
|
|
return amduat_sha256_rotr(x, 7u) ^ amduat_sha256_rotr(x, 18u) ^ (x >> 3u);
|
|
}
|
|
|
|
static uint32_t amduat_sha256_small_sigma1(uint32_t x) {
|
|
return amduat_sha256_rotr(x, 17u) ^ amduat_sha256_rotr(x, 19u) ^ (x >> 10u);
|
|
}
|
|
|
|
static uint32_t amduat_sha256_load_be32(const uint8_t *data) {
|
|
return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) |
|
|
((uint32_t)data[2] << 8) | (uint32_t)data[3];
|
|
}
|
|
|
|
static void amduat_sha256_store_be32(uint8_t *out, uint32_t v) {
|
|
out[0] = (uint8_t)(v >> 24);
|
|
out[1] = (uint8_t)(v >> 16);
|
|
out[2] = (uint8_t)(v >> 8);
|
|
out[3] = (uint8_t)(v);
|
|
}
|
|
|
|
static void amduat_sha256_store_be64(uint8_t *out, uint64_t v) {
|
|
out[0] = (uint8_t)(v >> 56);
|
|
out[1] = (uint8_t)(v >> 48);
|
|
out[2] = (uint8_t)(v >> 40);
|
|
out[3] = (uint8_t)(v >> 32);
|
|
out[4] = (uint8_t)(v >> 24);
|
|
out[5] = (uint8_t)(v >> 16);
|
|
out[6] = (uint8_t)(v >> 8);
|
|
out[7] = (uint8_t)(v);
|
|
}
|
|
|
|
static void amduat_sha256_transform(amduat_sha256_ctx_t *ctx,
|
|
const uint8_t block[64]) {
|
|
static const uint32_t k[64] = {
|
|
0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu,
|
|
0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u, 0xd807aa98u, 0x12835b01u,
|
|
0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u,
|
|
0xc19bf174u, 0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu,
|
|
0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau, 0x983e5152u,
|
|
0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u,
|
|
0x06ca6351u, 0x14292967u, 0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu,
|
|
0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u,
|
|
0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u,
|
|
0xd6990624u, 0xf40e3585u, 0x106aa070u, 0x19a4c116u, 0x1e376c08u,
|
|
0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu,
|
|
0x682e6ff3u, 0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u,
|
|
0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u};
|
|
uint32_t w[64];
|
|
uint32_t a;
|
|
uint32_t b;
|
|
uint32_t c;
|
|
uint32_t d;
|
|
uint32_t e;
|
|
uint32_t f;
|
|
uint32_t g;
|
|
uint32_t h;
|
|
uint32_t t1;
|
|
uint32_t t2;
|
|
size_t i;
|
|
|
|
for (i = 0; i < 16; ++i) {
|
|
w[i] = amduat_sha256_load_be32(block + (i * 4));
|
|
}
|
|
for (i = 16; i < 64; ++i) {
|
|
w[i] = amduat_sha256_small_sigma1(w[i - 2]) + w[i - 7] +
|
|
amduat_sha256_small_sigma0(w[i - 15]) + w[i - 16];
|
|
}
|
|
|
|
a = ctx->state[0];
|
|
b = ctx->state[1];
|
|
c = ctx->state[2];
|
|
d = ctx->state[3];
|
|
e = ctx->state[4];
|
|
f = ctx->state[5];
|
|
g = ctx->state[6];
|
|
h = ctx->state[7];
|
|
|
|
for (i = 0; i < 64; ++i) {
|
|
t1 = h + amduat_sha256_big_sigma1(e) + amduat_sha256_ch(e, f, g) + k[i] +
|
|
w[i];
|
|
t2 = amduat_sha256_big_sigma0(a) + amduat_sha256_maj(a, b, c);
|
|
h = g;
|
|
g = f;
|
|
f = e;
|
|
e = d + t1;
|
|
d = c;
|
|
c = b;
|
|
b = a;
|
|
a = t1 + t2;
|
|
}
|
|
|
|
ctx->state[0] += a;
|
|
ctx->state[1] += b;
|
|
ctx->state[2] += c;
|
|
ctx->state[3] += d;
|
|
ctx->state[4] += e;
|
|
ctx->state[5] += f;
|
|
ctx->state[6] += g;
|
|
ctx->state[7] += h;
|
|
}
|
|
|
|
void amduat_sha256_init(amduat_sha256_ctx_t *ctx) {
|
|
ctx->state[0] = 0x6a09e667u;
|
|
ctx->state[1] = 0xbb67ae85u;
|
|
ctx->state[2] = 0x3c6ef372u;
|
|
ctx->state[3] = 0xa54ff53au;
|
|
ctx->state[4] = 0x510e527fu;
|
|
ctx->state[5] = 0x9b05688cu;
|
|
ctx->state[6] = 0x1f83d9abu;
|
|
ctx->state[7] = 0x5be0cd19u;
|
|
ctx->bitlen = 0;
|
|
ctx->buffer_len = 0;
|
|
}
|
|
|
|
void amduat_sha256_update(amduat_sha256_ctx_t *ctx,
|
|
const uint8_t *data,
|
|
size_t len) {
|
|
size_t i;
|
|
|
|
if (len == 0) {
|
|
return;
|
|
}
|
|
|
|
ctx->bitlen += (uint64_t)len * 8u;
|
|
|
|
i = 0;
|
|
if (ctx->buffer_len > 0) {
|
|
size_t to_copy = 64u - ctx->buffer_len;
|
|
if (to_copy > len) {
|
|
to_copy = len;
|
|
}
|
|
memcpy(ctx->buffer + ctx->buffer_len, data, to_copy);
|
|
ctx->buffer_len += to_copy;
|
|
i += to_copy;
|
|
|
|
if (ctx->buffer_len == 64u) {
|
|
amduat_sha256_transform(ctx, ctx->buffer);
|
|
ctx->buffer_len = 0;
|
|
}
|
|
}
|
|
|
|
for (; i + 64u <= len; i += 64u) {
|
|
amduat_sha256_transform(ctx, data + i);
|
|
}
|
|
|
|
if (i < len) {
|
|
ctx->buffer_len = len - i;
|
|
memcpy(ctx->buffer, data + i, ctx->buffer_len);
|
|
}
|
|
}
|
|
|
|
void amduat_sha256_final(amduat_sha256_ctx_t *ctx, uint8_t out[32]) {
|
|
size_t i;
|
|
|
|
i = ctx->buffer_len;
|
|
ctx->buffer[i++] = 0x80u;
|
|
|
|
if (i > 56u) {
|
|
memset(ctx->buffer + i, 0, 64u - i);
|
|
amduat_sha256_transform(ctx, ctx->buffer);
|
|
i = 0;
|
|
}
|
|
|
|
memset(ctx->buffer + i, 0, 56u - i);
|
|
amduat_sha256_store_be64(ctx->buffer + 56u, ctx->bitlen);
|
|
amduat_sha256_transform(ctx, ctx->buffer);
|
|
|
|
for (i = 0; i < 8; ++i) {
|
|
amduat_sha256_store_be32(out + (i * 4u), ctx->state[i]);
|
|
}
|
|
}
|
|
|
|
bool amduat_hash_asl1_sha256_digest(void *ctx,
|
|
amduat_octets_t input,
|
|
uint8_t *out,
|
|
size_t out_len) {
|
|
amduat_sha256_ctx_t sha_ctx;
|
|
|
|
(void)ctx;
|
|
|
|
if (out == NULL || out_len < 32u) {
|
|
return false;
|
|
}
|
|
if (input.len > 0 && input.data == NULL) {
|
|
return false;
|
|
}
|
|
|
|
amduat_sha256_init(&sha_ctx);
|
|
amduat_sha256_update(&sha_ctx, input.data, input.len);
|
|
amduat_sha256_final(&sha_ctx, out);
|
|
return true;
|
|
}
|