Frank Denis
3 years ago
21 changed files with 217 additions and 111 deletions
@ -0,0 +1,133 @@ |
|||
#include <assert.h> |
|||
#include <errno.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
|
|||
#include "core_h2c.h" |
|||
#include "crypto_hash_sha256.h" |
|||
#include "crypto_hash_sha512.h" |
|||
#include "private/common.h" |
|||
|
|||
#define HASH_BYTES crypto_hash_sha256_BYTES |
|||
#define HASH_BLOCKBYTES 64U |
|||
|
|||
static int |
|||
core_h2c_string_to_hash_sha256(unsigned char *h, const size_t h_len, const char *ctx, |
|||
const unsigned char *msg, size_t msg_len) |
|||
{ |
|||
crypto_hash_sha256_state st; |
|||
const unsigned char empty_block[HASH_BLOCKBYTES] = { 0 }; |
|||
unsigned char u0[HASH_BYTES]; |
|||
unsigned char ux[HASH_BYTES] = { 0 }; |
|||
unsigned char t[3] = { 0U, (unsigned char) h_len, 0U}; |
|||
unsigned char ctx_len_u8; |
|||
size_t ctx_len = ctx != NULL ? strlen(ctx) : 0U; |
|||
size_t i, j; |
|||
|
|||
assert(h_len <= 0xff); |
|||
if (ctx_len > (size_t) 0xff) { |
|||
crypto_hash_sha256_init(&st); |
|||
crypto_hash_sha256_update(&st, |
|||
(const unsigned char *) "H2C-OVERSIZE-DST-", |
|||
sizeof "H2C-OVERSIZE-DST-" - 1U); |
|||
crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); |
|||
crypto_hash_sha256_final(&st, u0); |
|||
ctx = (const char *) u0; |
|||
ctx_len = HASH_BYTES; |
|||
COMPILER_ASSERT(HASH_BYTES <= (size_t) 0xff); |
|||
} |
|||
ctx_len_u8 = (unsigned char) ctx_len; |
|||
crypto_hash_sha256_init(&st); |
|||
crypto_hash_sha256_update(&st, empty_block, sizeof empty_block); |
|||
crypto_hash_sha256_update(&st, msg, msg_len); |
|||
crypto_hash_sha256_update(&st, t, 3U); |
|||
crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); |
|||
crypto_hash_sha256_update(&st, &ctx_len_u8, 1U); |
|||
crypto_hash_sha256_final(&st, u0); |
|||
|
|||
for (i = 0U; i < h_len; i += HASH_BYTES) { |
|||
for (j = 0U; j < HASH_BYTES; j++) { |
|||
ux[j] ^= u0[j]; |
|||
} |
|||
t[2]++; |
|||
crypto_hash_sha256_init(&st); |
|||
crypto_hash_sha256_update(&st, ux, HASH_BYTES); |
|||
crypto_hash_sha256_update(&st, &t[2], 1U); |
|||
crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); |
|||
crypto_hash_sha256_update(&st, &ctx_len_u8, 1U); |
|||
crypto_hash_sha256_final(&st, ux); |
|||
memcpy(&h[i], ux, h_len - i >= (sizeof ux) ? (sizeof ux) : h_len - i); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
#undef HASH_BYTES |
|||
#undef HASH_BLOCKBYTES |
|||
|
|||
#define HASH_BYTES crypto_hash_sha512_BYTES |
|||
#define HASH_BLOCKBYTES 128U |
|||
|
|||
static int |
|||
core_h2c_string_to_hash_sha512(unsigned char *h, const size_t h_len, const char *ctx, |
|||
const unsigned char *msg, size_t msg_len) |
|||
{ |
|||
crypto_hash_sha512_state st; |
|||
const unsigned char empty_block[HASH_BLOCKBYTES] = { 0 }; |
|||
unsigned char u0[HASH_BYTES]; |
|||
unsigned char ux[HASH_BYTES] = { 0 }; |
|||
unsigned char t[3] = { 0U, (unsigned char) h_len, 0U}; |
|||
unsigned char ctx_len_u8; |
|||
size_t ctx_len = ctx != NULL ? strlen(ctx) : 0U; |
|||
size_t i, j; |
|||
|
|||
assert(h_len <= 0xff); |
|||
if (ctx_len > (size_t) 0xff) { |
|||
crypto_hash_sha512_init(&st); |
|||
crypto_hash_sha512_update(&st, |
|||
(const unsigned char *) "H2C-OVERSIZE-DST-", |
|||
sizeof "H2C-OVERSIZE-DST-" - 1U); |
|||
crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); |
|||
crypto_hash_sha512_final(&st, u0); |
|||
ctx = (const char *) u0; |
|||
ctx_len = HASH_BYTES; |
|||
COMPILER_ASSERT(HASH_BYTES <= (size_t) 0xff); |
|||
} |
|||
ctx_len_u8 = (unsigned char) ctx_len; |
|||
crypto_hash_sha512_init(&st); |
|||
crypto_hash_sha512_update(&st, empty_block, sizeof empty_block); |
|||
crypto_hash_sha512_update(&st, msg, msg_len); |
|||
crypto_hash_sha512_update(&st, t, 3U); |
|||
crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); |
|||
crypto_hash_sha512_update(&st, &ctx_len_u8, 1U); |
|||
crypto_hash_sha512_final(&st, u0); |
|||
|
|||
for (i = 0U; i < h_len; i += HASH_BYTES) { |
|||
for (j = 0U; j < HASH_BYTES; j++) { |
|||
ux[j] ^= u0[j]; |
|||
} |
|||
t[2]++; |
|||
crypto_hash_sha512_init(&st); |
|||
crypto_hash_sha512_update(&st, ux, HASH_BYTES); |
|||
crypto_hash_sha512_update(&st, &t[2], 1U); |
|||
crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); |
|||
crypto_hash_sha512_update(&st, &ctx_len_u8, 1U); |
|||
crypto_hash_sha512_final(&st, ux); |
|||
memcpy(&h[i], ux, h_len - i >= (sizeof ux) ? (sizeof ux) : h_len - i); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
int |
|||
core_h2c_string_to_hash(unsigned char *h, const size_t h_len, const char *ctx, |
|||
const unsigned char *msg, size_t msg_len, int hash_alg) |
|||
{ |
|||
switch (hash_alg) { |
|||
case CORE_H2C_SHA256: |
|||
return core_h2c_string_to_hash_sha256(h, h_len, ctx, msg, msg_len); |
|||
case CORE_H2C_SHA512: |
|||
return core_h2c_string_to_hash_sha512(h, h_len, ctx, msg, msg_len); |
|||
default: |
|||
errno = EINVAL; |
|||
return -1; |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
#ifndef core_h2c_H |
|||
#define core_h2c_H |
|||
|
|||
#define CORE_H2C_SHA256 1 |
|||
#define CORE_H2C_SHA512 2 |
|||
|
|||
int core_h2c_string_to_hash(unsigned char *h, const size_t h_len, const char *ctx, |
|||
const unsigned char *msg, size_t msg_len, |
|||
int hash_alg); |
|||
#endif |
Loading…
Reference in new issue