Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SHA2 Increment with arbitrary length (non-block sizes) #1614

Merged
merged 10 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/common/sha2/sha2.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ void OQS_SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, s
);
}

void OQS_SHA2_sha256_inc(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t len) {
C_OR_ARM(
oqs_sha2_sha256_inc_c((sha256ctx *) state, in, len),
oqs_sha2_sha256_inc_armv8((sha256ctx *) state, in, len)
);
}

void OQS_SHA2_sha256_inc_finalize(uint8_t *out, OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inlen) {
oqs_sha2_sha256_inc_finalize_c(out, (sha256ctx *) state, in, inlen);
}
Expand Down
27 changes: 27 additions & 0 deletions src/common/sha2/sha2.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ extern "C" {
typedef struct {
/** Internal state */
void *ctx;
/** current number of bytes in data */
size_t data_len;
/** unprocessed data buffer */
uint8_t data[128];
} OQS_SHA2_sha224_ctx;

/**
Expand All @@ -43,6 +47,10 @@ void OQS_SHA2_sha256(uint8_t *output, const uint8_t *input, size_t inplen);
typedef struct {
/** Internal state */
void *ctx;
/** current number of bytes in data */
size_t data_len;
/** unprocessed data buffer */
uint8_t data[128];
} OQS_SHA2_sha256_ctx;

/**
Expand Down Expand Up @@ -78,6 +86,17 @@ void OQS_SHA2_sha256_inc_ctx_clone(OQS_SHA2_sha256_ctx *dest, const OQS_SHA2_sha
*/
void OQS_SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inblocks);

/**
* \brief Process message bytes with SHA-256 and update the state.
*
* \warning The state must be initialized by OQS_SHA2_sha256_inc_init or OQS_SHA2_sha256_inc_ctx_clone.
*
* \param state The state to update
* \param in Message input byte array
* \param len The number of bytes of message to process
*/
void OQS_SHA2_sha256_inc(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t len);

/**
* \brief Process more message bytes with SHA-256 and return the hash code in the output byte array.
*
Expand Down Expand Up @@ -117,6 +136,10 @@ void OQS_SHA2_sha384(uint8_t *output, const uint8_t *input, size_t inplen);
typedef struct {
/** Internal state. */
void *ctx;
/** current number of bytes in data */
size_t data_len;
/** unprocessed data buffer */
uint8_t data[128];
} OQS_SHA2_sha384_ctx;

/**
Expand Down Expand Up @@ -191,6 +214,10 @@ void OQS_SHA2_sha512(uint8_t *output, const uint8_t *input, size_t inplen);
typedef struct {
/** Internal state. */
void *ctx;
/** current number of bytes in data */
size_t data_len;
/** unprocessed data buffer */
uint8_t data[128];
} OQS_SHA2_sha512_ctx;

/**
Expand Down
99 changes: 86 additions & 13 deletions src/common/sha2/sha2_armv8.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <oqs/oqs.h>

#include "sha2_local.h"

#include <string.h>
#include <stdint.h>
// ARM includes
#include <arm_acle.h>
Expand Down Expand Up @@ -167,23 +167,43 @@ static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes,
return length;

}

void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const uint8_t *in, size_t inlen) {
uint8_t padded[128];
uint64_t bytes = load_bigendian_64(state->ctx + 32) + inlen;

crypto_hashblocks_sha256_armv8(state->ctx, in, inlen);
in += inlen;
inlen &= 63;
in -= inlen;
size_t new_inlen = state->data_len + inlen;
size_t tmp_len = new_inlen;
const uint8_t *new_in;
uint8_t *tmp_in = NULL;

if (new_inlen == inlen) {
new_in = in;
} else { //Combine incremental data with final input
tmp_in = malloc(tmp_len);
SWilson4 marked this conversation as resolved.
Show resolved Hide resolved
if (tmp_in == NULL) {
exit(111);
}

memcpy(tmp_in, state->data, state->data_len);
memcpy(tmp_in + state->data_len, in, inlen);
new_in = tmp_in;
}

uint64_t bytes = load_bigendian_64(state->ctx + 32) + new_inlen;

crypto_hashblocks_sha256_armv8(state->ctx, new_in, new_inlen);
new_in += new_inlen;
new_inlen &= 63;
new_in -= new_inlen;


for (size_t i = 0; i < inlen; ++i) {
padded[i] = in[i];
for (size_t i = 0; i < new_inlen; ++i) {
padded[i] = new_in[i];
}
padded[inlen] = 0x80;
padded[new_inlen] = 0x80;

if (inlen < 56) {
for (size_t i = inlen + 1; i < 56; ++i) {
if (new_inlen < 56) {
for (size_t i = new_inlen + 1; i < 56; ++i) {
padded[i] = 0;
}
padded[56] = (uint8_t) (bytes >> 53);
Expand All @@ -196,7 +216,7 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui
padded[63] = (uint8_t) (bytes << 3);
crypto_hashblocks_sha256_armv8(state->ctx, padded, 64);
} else {
for (size_t i = inlen + 1; i < 120; ++i) {
for (size_t i = new_inlen + 1; i < 120; ++i) {
padded[i] = 0;
}
padded[120] = (uint8_t) (bytes >> 53);
Expand All @@ -214,6 +234,7 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui
out[i] = state->ctx[i];
}
oqs_sha2_sha256_inc_ctx_release_c(state);
OQS_MEM_secure_free(tmp_in, tmp_len);
}

void oqs_sha2_sha224_inc_finalize_armv8(uint8_t *out, sha224ctx *state, const uint8_t *in, size_t inlen) {
Expand All @@ -227,11 +248,63 @@ void oqs_sha2_sha224_inc_finalize_armv8(uint8_t *out, sha224ctx *state, const ui

void oqs_sha2_sha256_inc_blocks_armv8(sha256ctx *state, const uint8_t *in, size_t inblocks) {
uint64_t bytes = load_bigendian_64(state->ctx + 32);
const uint8_t *new_in;
size_t buf_len = 64 * inblocks;
uint8_t *tmp_in = NULL;

/* Process any existing incremental data first */
if (state->data_len) {
tmp_in = malloc(buf_len);
SWilson4 marked this conversation as resolved.
Show resolved Hide resolved
if (tmp_in == NULL) {
exit(111);
}

memcpy(tmp_in, state->data, state->data_len);
memcpy(tmp_in + state->data_len, in, buf_len - state->data_len);

/* store the reminder input as incremental data */
memcpy(state->data, in + (buf_len - state->data_len), state->data_len);
new_in = tmp_in;
} else {
new_in = in;
}

crypto_hashblocks_sha256_armv8(state->ctx, in, 64 * inblocks);
crypto_hashblocks_sha256_armv8(state->ctx, new_in, 64 * inblocks);
bytes += 64 * inblocks;

store_bigendian_64(state->ctx + 32, bytes);
OQS_MEM_secure_free(tmp_in, buf_len);
}

void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) {
uint64_t bytes = 0;
while (len) {
size_t incr = 64 - state->data_len;
if (incr > len) {
incr = len;
}

for (size_t i = 0; i < incr; ++i, state->data_len++) {
state->data[state->data_len] = in[i];
}

if (state->data_len < 64) {
break;
}

/*
* Process a complete block now
*/
bytes = load_bigendian_64(state->ctx + 32) + 64;
crypto_hashblocks_sha256_armv8(state->ctx, state->data, 64);
store_bigendian_64(state->ctx + 32, bytes);

/*
* update the remaining input
*/
len -= incr;
state->data_len = 0;
}
}

void oqs_sha2_sha224_inc_blocks_armv8(sha224ctx *state, const uint8_t *in, size_t inblocks) {
Expand Down
Loading
Loading