| 25 | #define SIG1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10)) |
| 26 | |
| 27 | static void sha256_transform(cbm_sha256_ctx *c, const uint8_t *data) { |
| 28 | /* Scratch comes from the context, not this frame: a 256-byte local here |
| 29 | * is fake-stacked by ASan's use-after-return mode on every 64-byte block |
| 30 | * (see the note on cbm_sha256_ctx::sched). Identical values, allocated |
| 31 | * once per hash instead of once per block. */ |
| 32 | uint32_t *m = c->sched; |
| 33 | for (int i = 0, j = 0; i < 16; i++, j += 4) { |
| 34 | m[i] = ((uint32_t)data[j] << 24) | ((uint32_t)data[j + 1] << 16) | |
| 35 | ((uint32_t)data[j + 2] << 8) | (uint32_t)data[j + 3]; |
| 36 | } |
| 37 | for (int i = 16; i < 64; i++) { |
| 38 | m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; |
| 39 | } |
| 40 | |
| 41 | uint32_t a = c->state[0], b = c->state[1], cc = c->state[2], d = c->state[3]; |
| 42 | uint32_t e = c->state[4], f = c->state[5], g = c->state[6], h = c->state[7]; |
| 43 | |
| 44 | for (int i = 0; i < 64; i++) { |
| 45 | uint32_t t1 = h + EP1(e) + CH(e, f, g) + K[i] + m[i]; |
| 46 | uint32_t t2 = EP0(a) + MAJ(a, b, cc); |
| 47 | h = g; |
| 48 | g = f; |
| 49 | f = e; |
| 50 | e = d + t1; |
| 51 | d = cc; |
| 52 | cc = b; |
| 53 | b = a; |
| 54 | a = t1 + t2; |
| 55 | } |
| 56 | |
| 57 | c->state[0] += a; |
| 58 | c->state[1] += b; |
| 59 | c->state[2] += cc; |
| 60 | c->state[3] += d; |
| 61 | c->state[4] += e; |
| 62 | c->state[5] += f; |
| 63 | c->state[6] += g; |
| 64 | c->state[7] += h; |
| 65 | } |
| 66 | |
| 67 | void cbm_sha256_init(cbm_sha256_ctx *c) { |
| 68 | c->bitlen = 0; |
no outgoing calls
no test coverage detected