From afaa6d3640d963e670b68910f3da06c1d53fa017 Mon Sep 17 00:00:00 2001 From: Tiago Oliveira Date: Thu, 12 Oct 2023 19:57:56 +0100 Subject: [PATCH] armv7m: sha256 ref --- src/crypto_hash/sha256/armv7m/ref/Makefile | 3 + src/crypto_hash/sha256/armv7m/ref/hash.jazz | 10 + .../sha256/armv7m/ref/include/api.h | 18 + src/crypto_hash/sha256/armv7m/ref/sha256.jinc | 418 ++++++++++++++++++ .../sha256/armv7m/ref/sha256_globals.jinc | 31 ++ 5 files changed, 480 insertions(+) create mode 100644 src/crypto_hash/sha256/armv7m/ref/Makefile create mode 100644 src/crypto_hash/sha256/armv7m/ref/hash.jazz create mode 100644 src/crypto_hash/sha256/armv7m/ref/include/api.h create mode 100644 src/crypto_hash/sha256/armv7m/ref/sha256.jinc create mode 100644 src/crypto_hash/sha256/armv7m/ref/sha256_globals.jinc diff --git a/src/crypto_hash/sha256/armv7m/ref/Makefile b/src/crypto_hash/sha256/armv7m/ref/Makefile new file mode 100644 index 00000000..586e8a2f --- /dev/null +++ b/src/crypto_hash/sha256/armv7m/ref/Makefile @@ -0,0 +1,3 @@ +override JFLAGS += -arch arm-m4 +SRCS := hash.jazz +include ../../../../Makefile.common diff --git a/src/crypto_hash/sha256/armv7m/ref/hash.jazz b/src/crypto_hash/sha256/armv7m/ref/hash.jazz new file mode 100644 index 00000000..07996721 --- /dev/null +++ b/src/crypto_hash/sha256/armv7m/ref/hash.jazz @@ -0,0 +1,10 @@ +require "sha256.jinc" + +export fn jade_hash_sha256_armv7m_ref(reg u32 hash input input_length) -> reg u32 +{ + reg u32 r; + __sha256_ref(hash, input, input_length); + r = 0; + return r; +} + diff --git a/src/crypto_hash/sha256/armv7m/ref/include/api.h b/src/crypto_hash/sha256/armv7m/ref/include/api.h new file mode 100644 index 00000000..ac5bca50 --- /dev/null +++ b/src/crypto_hash/sha256/armv7m/ref/include/api.h @@ -0,0 +1,18 @@ +#ifndef JADE_HASH_sha256_armv7m_ref_API_H +#define JADE_HASH_sha256_armv7m_ref_API_H + +#define JADE_HASH_sha256_armv7m_ref_BYTES 32 + +#define JADE_HASH_sha256_armv7m_ref_ALGNAME "SHA256" +#define JADE_HASH_sha256_armv7m_ref_ARCH "armv7m" +#define JADE_HASH_sha256_armv7m_ref_IMPL "ref" + +#include + +int jade_hash_sha256_armv7m_ref( + uint8_t *hash, + const uint8_t *input, + uint32_t input_length +); + +#endif diff --git a/src/crypto_hash/sha256/armv7m/ref/sha256.jinc b/src/crypto_hash/sha256/armv7m/ref/sha256.jinc new file mode 100644 index 00000000..65405b0f --- /dev/null +++ b/src/crypto_hash/sha256/armv7m/ref/sha256.jinc @@ -0,0 +1,418 @@ + +require "sha256_globals.jinc" + +inline fn __initH_ref(reg ptr u32[8] H) -> reg ptr u32[8] +{ + inline int i; + reg ptr u32[8] H0; + reg u32 t; + + H0 = SHA256_H0; + + for i=0 to 8 + { t = H0[i]; + H[i] = t; } + + return H; +} + +inline fn __load_H_ref(reg ptr u32[8] H) -> reg u32, reg u32, reg u32, reg u32, + reg u32, reg u32, reg u32, reg u32 +{ + reg u32 a b c d e f g h; + + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + f = H[5]; + g = H[6]; + h = H[7]; + + return a, b, c, d, e, f, g, h; +} + +inline fn __store_H_ref(reg ptr u32[8] H, reg u32 a b c d e f g h) -> reg ptr u32[8] +{ + H[0] = a; + H[1] = b; + H[2] = c; + H[3] = d; + H[4] = e; + H[5] = f; + H[6] = g; + H[7] = h; + + return H; +} + +inline fn REV(reg u32 a) -> reg u32 +{ + // a = #REV(a); // USE this instruction when available + + inline int i; + reg u32 t b; + + t = (a & 0xff); + + for i=0 to 3 + { t <<= 8; + a >>= 8; + b = (a & 0xff); + t |= b; + } + + return t; +} + +inline fn __store_ref(reg u32 out, reg ptr u32[8] H) +{ + inline int i; + reg u32 v; + + for i=0 to 8 + { v = H[i]; + v = REV(v); + (u32)[out + i*4] = v; + } +} + +inline fn __SHR_ref(reg u32 x, inline int c) -> reg u32 +{ + reg u32 r; + r = x; + r >>= c; + return r; +} + +inline fn __ROTR_ref(reg u32 x, inline int c) -> reg u32 +{ + reg u32 r; + r = x; + r = #ROR(r, c); + return r; +} + +//(x & y) ^ (!x & z) +inline fn __CH_ref(reg u32 x y z) -> reg u32 +{ + reg u32 r s; + + r = x; + r &= y; + s = x; + s = !s; + s &= z; + r ^= s; + + return r; +} + +//(x & y) ^ (x & z) ^ (y & z) +inline fn __MAJ_ref(reg u32 x y z) -> reg u32 +{ + reg u32 r s; + + r = x; + r &= y; + s = x; + s &= z; + r ^= s; + s = y; + s &= z; + r ^= s; + + return r; +} + +// (x >>> 2) ^ (x >>> 13) ^ (x >>> 22) +inline fn __BSIG0_ref(reg u32 x) -> reg u32 +{ + reg u32 r s; + + r = __ROTR_ref(x, 2); + s = __ROTR_ref(x,13); + r ^= s; + s = __ROTR_ref(x,22); + r ^= s; + + return r; +} + +// (x >>> 6) ^ (x >>> 11) ^ (x >>> 25) +inline fn __BSIG1_ref(reg u32 x) -> reg u32 +{ + reg u32 r s; + + r = __ROTR_ref(x, 6); + s = __ROTR_ref(x,11); + r ^= s; + s = __ROTR_ref(x,25); + r ^= s; + + return r; +} + +// (x >>> 7) ^ (x >>> 18) ^ (x >> 3) +inline fn __SSIG0_ref(reg u32 x) -> reg u32 +{ + reg u32 r s; + + r = __ROTR_ref(x, 7); + s = __ROTR_ref(x,18); + r ^= s; + s = __SHR_ref(x,3); + r ^= s; + + return r; +} + +// (x >>> 17) ^ (x >>> 19) ^ (x >> 10) +inline fn __SSIG1_ref(reg u32 x) -> reg u32 +{ + reg u32 r s; + + r = __ROTR_ref(x,17); + s = __ROTR_ref(x,19); + r ^= s; + s = __SHR_ref(x,10); + r ^= s; + + return r; +} + +// Wt = SSIG1(W(t-2)) + W(t-7) + SSIG0(t-15) + W(t-16) +inline fn __Wt_ref(reg ptr u32[64] W, reg u32 t) -> reg ptr u32[64] +{ + reg u32 wt wt2 wt7 wt16 wt15; + + t -= 2; + wt2 = W[(int)t]; // -2 + wt = __SSIG1_ref(wt2); t -= 5; + wt7 = W[(int)t]; // -7 + wt += wt7; t -= 8; + wt15 = W[(int)t]; // -15 + wt15 = __SSIG0_ref(wt15); + wt += wt15; t -= 1; + wt16 = W[(int)t]; // -16 + wt += wt16; + t += 16; + W[(int)t] = wt; + + return W; +} + +#[returnaddress="stack"] +fn _blocks_inner(reg ptr u32[64] W, reg ptr u32[8] H) -> reg ptr u32[64], reg ptr u32[8] +{ + reg u32 a b c d e f g h r T1 T2 Kt Wt i t; + stack u32 ts ds hs; + + reg ptr u32[64] K; + K = SHA256_K; + + i = 16; + while(i < 64) + { W = __Wt_ref(W, i); + i += 1; + } + + a, b, c, d, e, f, g, h = __load_H_ref(H); + ds = d; + hs = h; + + t = 0; + while(t < 64) + { + ts = t; + + //T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt + r = __BSIG1_ref(e); + T1 = hs; + T1 += r; + r = __CH_ref(e,f,g); + T1 += r; + + Kt = K[(int)t]; + T1 += Kt; + + Wt = W[(int)t]; + T1 += Wt; + + //T2 = BSIG0(a) + MAJ(a,b,c) + T2 = __BSIG0_ref(a); + r = __MAJ_ref(a,b,c); + T2 += r; + + hs = g; + g = f; + f = e; + e = ds; + e += T1; + ds = c; + c = b; + b = a; + a = T1; + a += T2; + + t = ts; + t += 1; + } + + d = ds; + h = hs; + + t = H[0]; + a += t; t = H[1]; + b += t; t = H[2]; + c += t; t = H[3]; + d += t; t = H[4]; + e += t; t = H[5]; + f += t; t = H[6]; + g += t; t = H[7]; + h += t; + + H = __store_H_ref(H,a,b,c,d,e,f,g,h); + + return W, H; +} + +inline fn _blocks_0_ref(reg ptr u32[8] H, reg u32 in, reg u32 inlen) -> reg ptr u32[8], reg u32, reg u32 +{ + inline int t; + reg u32 v; + stack u32 in_s inlen_s; + stack u32[64] _W; + reg ptr u32[64] W K; + + W = _W; + + while(inlen >= 64) + { + for t=0 to 16 + { v = (u32)[in + t*4]; + v = REV(v); + W[t] = v; + } + + in_s = in; + inlen_s = inlen; + + W, H = _blocks_inner(W, H); + + in = in_s; + inlen = inlen_s; + + in += 64; + inlen -= 64; + } + + return H, in, inlen; +} + +inline fn _blocks_1_ref(reg ptr u32[8] H, reg ptr u32[32] blocks, reg u32 nblocks) -> reg ptr u32[8] +{ + inline int t; + reg u32 i v oblocks; + stack u32 i_s nblocks_s; + stack u32[64] _W; + reg ptr u32[64] W K; + + W = _W; + + // nblocks can be 1 or 2 => the following loop executes at most 2 times + // - for the first loop execution: index for blocks is 0; for the second is 16 + // - hence, nblocks << 4 and i += 16 + i = 0; + nblocks <<= 4; + nblocks_s = nblocks; + + while(i < nblocks) + { + for t=0 to 16 + { v = blocks[(int)i]; + i += 1; + v = REV(v); + W[t] = v; + } + i_s = i; + + W, H = _blocks_inner(W, H); + + i = i_s; + nblocks = nblocks_s; + } + + return H; +} + +inline fn __lastblocks_ref(reg ptr u32[32] blocks, reg u32 in inlen bits) -> stack u32[32], reg u32 +{ + reg u32 zero i v j nblocks; + + // Zero-fill the blocks array + zero = 0; + i = 0; + while(i < 32) + { blocks[(int)i] = zero; + i += 1; + } + + // copy in to blocks + i = 0; + while(i < inlen) + { v = (32u)(u8)[in + i]; + blocks[u8 (int)i] = (8u) v; + i += 1; + } + + // set first byte after input to 0x80 + v = 0x80; + blocks[u8 (int)i] = (8u) v; + + + // check if one or two blocks are needed + if(inlen < 56) // 448 / 8 = 56 + { j = (64-4); nblocks = 1; i = 63; } + else + { j = (128-4); nblocks = 2; i = 127; } + + while(i >= j) + { blocks[u8 (int)i] = (8u) bits; + bits >>= 8; + i -= 1; + } + + return blocks, nblocks; +} + +inline fn __sha256_ref(reg u32 out in, reg u32 inlen) +{ + stack u32 s_out s_inlen; + reg u32 bits nblocks; + + stack u32[8] _H; + reg ptr u32[8] H; + stack u32[32] _blocks; + reg ptr u32[32] blocks; + + H = _H; + + s_out = out; + s_inlen = inlen; + + H = __initH_ref(H); + H, in, inlen = _blocks_0_ref(H, in, inlen); + + blocks = _blocks; + bits = s_inlen; + bits <<= 3; + blocks, nblocks = __lastblocks_ref(blocks, in, inlen, bits); + + H = _blocks_1_ref(H, blocks, nblocks); + + out = s_out; + __store_ref(out, H); +} + diff --git a/src/crypto_hash/sha256/armv7m/ref/sha256_globals.jinc b/src/crypto_hash/sha256/armv7m/ref/sha256_globals.jinc new file mode 100644 index 00000000..b9d4ceec --- /dev/null +++ b/src/crypto_hash/sha256/armv7m/ref/sha256_globals.jinc @@ -0,0 +1,31 @@ + +u32[64] SHA256_K = { + 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 +}; + +u32[8] SHA256_H0 = { + 0x6a09e667, + 0xbb67ae85, + 0x3c6ef372, + 0xa54ff53a, + 0x510e527f, + 0x9b05688c, + 0x1f83d9ab, + 0x5be0cd19 +}; +