19 #include "app_config.h"
21 #if defined(HAVE_SHA256) || defined(HAVE_SHA224)
31 const cx_hash_info_t cx_sha224_info
36 (cx_err_t(*)(cx_hash_t * ctx)) cx_sha224_init_no_throw,
37 (cx_err_t(*)(cx_hash_t * ctx,
const uint8_t *data,
size_t len)) cx_sha256_update,
38 (cx_err_t(*)(cx_hash_t * ctx,
uint8_t *digest)) cx_sha256_final,
44 const cx_hash_info_t cx_sha256_info
49 (cx_err_t(*)(cx_hash_t * ctx)) cx_sha256_init_no_throw,
50 (cx_err_t(*)(cx_hash_t * ctx,
const uint8_t *data,
size_t len)) cx_sha256_update,
51 (cx_err_t(*)(cx_hash_t * ctx,
uint8_t *digest)) cx_sha256_final,
56 static const uint32_t primeSqrt[] = {
57 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
58 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
59 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
60 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
61 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
62 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
63 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
64 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
67 #if defined(HAVE_SHA224)
68 static const uint32_t hzero_224[] = {0xc1059ed8,
78 static const uint32_t hzero[] = {0x6a09e667,
87 #define sig256(x, a, b, c) (cx_rotr((x), a) ^ cx_rotr((x), b) ^ cx_shr((x), c))
88 #define sum256(x, a, b, c) (cx_rotr((x), a) ^ cx_rotr((x), b) ^ cx_rotr((x), c))
90 #define sigma0(x) sig256(x, 7, 18, 3)
91 #define sigma1(x) sig256(x, 17, 19, 10)
92 #define sum0(x) sum256(x, 2, 13, 22)
93 #define sum1(x) sum256(x, 6, 11, 25)
98 #define ch(x, y, z) (z ^ (x & (y ^ z)))
99 #define maj(x, y, z) ((x & y) | (z & (x | y)))
101 #if defined(HAVE_SHA224)
102 cx_err_t cx_sha224_init_no_throw(cx_sha256_t *hash)
104 memset(hash, 0,
sizeof(cx_sha256_t));
105 hash->header.info = &cx_sha224_info;
106 memmove(hash->acc, hzero_224,
sizeof(hzero));
111 cx_err_t cx_sha256_init_no_throw(cx_sha256_t *hash)
113 memset(hash, 0,
sizeof(cx_sha256_t));
114 hash->header.info = &cx_sha256_info;
115 memmove(hash->acc, hzero,
sizeof(hzero));
119 static void cx_sha256_block(cx_sha256_t *hash)
124 uint32_t *accumulator;
137 X = ((uint32_t *) &hash->block[0]);
138 accumulator = (uint32_t *) &hash->acc[0];
139 memmove(ACC, accumulator,
sizeof(ACC));
141 #ifdef ARCH_LITTLE_ENDIAN
157 for (
int j = 0; j < 64; j++) {
161 X[j & 0xF] = (sigma1(X[(j - 2) & 0xF]) + X[(j - 7) & 0xF] + sigma0(X[(j - 15) & 0xF])
162 + X[(j - 16) & 0xF]);
165 t1 = H + sum1(E) + ch(E, F, G) + primeSqrt[j] + X[j & 0xF];
166 t2 = sum0(A) + maj(A, B, C);
177 memmove(&ACC[1], &ACC[0],
sizeof(ACC) -
sizeof(uint32_t));
194 cx_err_t cx_sha256_update(cx_sha256_t *ctx,
const uint8_t *data,
size_t len)
200 return CX_INVALID_PARAMETER;
202 if (data == NULL && len != 0) {
203 return CX_INVALID_PARAMETER;
211 return CX_INVALID_PARAMETER;
215 if (blen + len >= 64) {
221 memcpy(ctx->block + blen, data, r);
222 cx_sha256_block(ctx);
225 ctx->header.counter++;
233 memcpy(ctx->block + blen, data, len);
239 cx_err_t cx_sha256_final(cx_sha256_t *ctx,
uint8_t *digest)
246 block[ctx->blen] = 0x80;
249 bitlen = (((uint64_t) ctx->header.counter) * 64UL + (uint64_t) ctx->blen - 1UL) * 8UL;
251 if (64 - ctx->blen < 8) {
252 memset(block + ctx->blen, 0, 64 - ctx->blen);
253 cx_sha256_block(ctx);
257 memset(block + ctx->blen, 0, 64 - ctx->blen);
258 #ifdef ARCH_LITTLE_ENDIAN
261 (*(uint64_t *) &block[64 - 8]) = bitlen;
263 cx_sha256_block(ctx);
265 #ifdef ARCH_LITTLE_ENDIAN
269 #if defined(HAVE_SHA224)
270 if (ctx->header.info->md_type == CX_SHA224) {
271 memcpy(digest, ctx->acc, CX_SHA224_SIZE);
276 memcpy(digest, ctx->acc, CX_SHA256_SIZE);
281 size_t cx_hash_sha256(
const uint8_t *in,
size_t in_len,
uint8_t *out,
size_t out_len)
283 if (out_len < CX_SHA256_SIZE) {
286 cx_sha256_init_no_throw(&
G_cx.sha256);
287 if (cx_sha256_update(&
G_cx.sha256, in, in_len) != CX_OK) {
290 cx_sha256_final(&
G_cx.sha256, out);
291 explicit_bzero(&
G_cx.sha256,
sizeof(cx_sha256_t));
292 return CX_SHA256_SIZE;
void cx_swap_uint64(uint64bits_t *v)
void cx_swap_buffer32(uint32_t *v, size_t len)