| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- #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;
- }
- }
|