aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2015-09-08 15:54:40 -0400
committerRob Austein <sra@hactrn.net>2015-09-08 15:54:40 -0400
commite946b4661607736f1b89a7a107729382cb85fd55 (patch)
tree992a1b76109d22b87edea8fd07df07371440e389
parent12fd92723d71325b74a6c94eee4ca504773ad9da (diff)
parent5106b886fe0d8af948bf28be2a571c247afc6020 (diff)
Merge branch 'master' into ecdsa
This required a bit of manual cleanup in hal.h, hash.c, and rsa.c. No intended changes to functionality provided by parent comments, just a few tweaks to track API changes beyond git's ken.
-rw-r--r--hal.h60
-rw-r--r--hash.c180
-rw-r--r--modexp.c104
-rw-r--r--rsa.c22
-rw-r--r--tests/test-rsa.c4
5 files changed, 238 insertions, 132 deletions
diff --git a/hal.h b/hal.h
index 547894e..4a5e239 100644
--- a/hal.h
+++ b/hal.h
@@ -390,39 +390,33 @@
* MATH segment.
*/
-/* Modexp core */
-#define MODEXP_ADDR_BASE (SEGMENT_OFFSET_MATH + (0x00 * CORE_SIZE))
-#define MODEXP_ADDR_NAME0 (MODEXP_ADDR_BASE + ADDR_NAME0)
-#define MODEXP_ADDR_NAME1 (MODEXP_ADDR_BASE + ADDR_NAME1)
-#define MODEXP_ADDR_VERSION (MODEXP_ADDR_BASE + ADDR_VERSION)
-#define MODEXP_ADDR_CTRL (MODEXP_ADDR_BASE + ADDR_CTRL)
-#define MODEXP_CTRL_INIT_BIT (1)
-#define MODEXP_CTRL_NEXT_BIT (2)
-#define MODEXP_ADDR_STATUS (MODEXP_ADDR_BASE + ADDR_STATUS)
+#define MATH_CORE_SIZE (0x400)
-#define MODEXP_ADDR_DELAY (MODEXP_ADDR_BASE + 0x13)
-#define MODEXP_STATUS_READY (1)
-
-#define MODEXP_MODULUS_LENGTH (MODEXP_ADDR_BASE + 0x20)
-#define MODEXP_EXPONENT_LENGTH (MODEXP_ADDR_BASE + 0x21)
-#define MODEXP_LENGTH (MODEXP_ADDR_BASE + 0x22)
-
-#define MODEXP_MODULUS_PTR_RST (MODEXP_ADDR_BASE + 0x30)
-#define MODEXP_MODULUS_DATA (MODEXP_ADDR_BASE + 0x31)
-
-#define MODEXP_EXPONENT_PTR_RST (MODEXP_ADDR_BASE + 0x40)
-#define MODEXP_EXPONENT_DATA (MODEXP_ADDR_BASE + 0x41)
-
-#define MODEXP_MESSAGE_PTR_RST (MODEXP_ADDR_BASE + 0x50)
-#define MODEXP_MESSAGE_DATA (MODEXP_ADDR_BASE + 0x51)
-
-#define MODEXP_RESULT_PTR_RST (MODEXP_ADDR_BASE + 0x60)
-#define MODEXP_RESULT_DATA (MODEXP_ADDR_BASE + 0x61)
-
-#define MODEXP_NAME0 "mode"
-#define MODEXP_NAME1 "xp "
-#define MODEXP_VERSION "0.51"
+/*
+ * ModExpS6 core. MODEXPS6_OPERAND_BITS is size in bits of largest
+ * supported modulus.
+ */
+#define MODEXPS6_ADDR_BASE (SEGMENT_OFFSET_MATH + (0x00 * MATH_CORE_SIZE))
+#define MODEXPS6_OPERAND_BITS (4096)
+#define MODEXPS6_OPERAND_WORDS (MODEXPS6_OPERAND_BITS/32)
+#define MODEXPS6_ADDR_REGISTERS (MODEXPS6_ADDR_BASE + 0*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_ADDR_OPERANDS (MODEXPS6_ADDR_BASE + 4*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_ADDR_NAME0 (MODEXPS6_ADDR_REGISTERS + ADDR_NAME0)
+#define MODEXPS6_ADDR_NAME1 (MODEXPS6_ADDR_REGISTERS + ADDR_NAME1)
+#define MODEXPS6_ADDR_VERSION (MODEXPS6_ADDR_REGISTERS + ADDR_VERSION)
+#define MODEXPS6_ADDR_CTRL (MODEXPS6_ADDR_REGISTERS + ADDR_CTRL)
+#define MODEXPS6_ADDR_STATUS (MODEXPS6_ADDR_REGISTERS + ADDR_STATUS)
+#define MODEXPS6_ADDR_MODE (MODEXPS6_ADDR_REGISTERS + 0x10)
+#define MODEXPS6_ADDR_MODULUS_WIDTH (MODEXPS6_ADDR_REGISTERS + 0x11)
+#define MODEXPS6_ADDR_EXPONENT_WIDTH (MODEXPS6_ADDR_REGISTERS + 0x12)
+#define MODEXPS6_ADDR_MODULUS (MODEXPS6_ADDR_OPERANDS + 0*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_ADDR_MESSAGE (MODEXPS6_ADDR_OPERANDS + 1*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_ADDR_EXPONENT (MODEXPS6_ADDR_OPERANDS + 2*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_ADDR_RESULT (MODEXPS6_ADDR_OPERANDS + 3*MODEXPS6_OPERAND_WORDS)
+#define MODEXPS6_NAME0 "mode"
+#define MODEXPS6_NAME1 "xps6"
+#define MODEXPS6_VERSION "0.10"
/*
* C API error codes. Defined in this form so we can keep the tokens
@@ -525,6 +519,7 @@ typedef struct {
const uint8_t * const digest_algorithm_id;
size_t digest_algorithm_id_length;
const hal_hash_driver_t *driver;
+ unsigned can_restore_state : 1;
} hal_hash_descriptor_t;
/*
@@ -574,6 +569,9 @@ extern hal_error_t hal_hmac_update(hal_hmac_state_t *state,
extern hal_error_t hal_hmac_finalize(hal_hmac_state_t *state,
uint8_t *hmac, const size_t length);
+extern void hal_hash_cleanup(hal_hash_state_t **state);
+
+extern void hal_hmac_cleanup(hal_hmac_state_t **state);
/*
* AES key wrap functions.
diff --git a/hash.c b/hash.c
index ce086f4..e06278d 100644
--- a/hash.c
+++ b/hash.c
@@ -76,7 +76,8 @@ struct hal_hash_driver {
};
/*
- * Hash state.
+ * Hash state. For now we assume that the only core state we need to
+ * save and restore is the current digest value.
*/
struct hal_hash_state {
@@ -84,11 +85,15 @@ struct hal_hash_state {
const hal_hash_driver_t *driver;
uint64_t msg_length_high; /* Total data hashed in this message */
uint64_t msg_length_low; /* (128 bits in SHA-512 cases) */
- uint8_t block[HAL_MAX_HASH_BLOCK_LENGTH]; /* Block we're accumulating */
+ uint8_t block[HAL_MAX_HASH_BLOCK_LENGTH], /* Block we're accumulating */
+ core_state[HAL_MAX_HASH_DIGEST_LENGTH]; /* Saved core state */
size_t block_used; /* How much of the block we've used */
unsigned block_count; /* Blocks sent */
+ unsigned flags;
};
+#define STATE_FLAG_STATE_ALLOCATED 0x1 /* State buffer dynamically allocated */
+
/*
* HMAC state. Right now this just holds the key block and a hash
* context; if and when we figure out how PCLSR the hash cores, we
@@ -185,42 +190,42 @@ const hal_hash_descriptor_t hal_hash_sha1[1] = {{
SHA1_BLOCK_LEN, SHA1_DIGEST_LEN,
sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha1, sizeof(dalgid_sha1),
- &sha1_driver
+ &sha1_driver, 0
}};
const hal_hash_descriptor_t hal_hash_sha256[1] = {{
SHA256_BLOCK_LEN, SHA256_DIGEST_LEN,
sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha256, sizeof(dalgid_sha256),
- &sha256_driver
+ &sha256_driver, 1
}};
const hal_hash_descriptor_t hal_hash_sha512_224[1] = {{
SHA512_BLOCK_LEN, SHA512_224_DIGEST_LEN,
sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha512_224, sizeof(dalgid_sha512_224),
- &sha512_224_driver
+ &sha512_224_driver, 0
}};
const hal_hash_descriptor_t hal_hash_sha512_256[1] = {{
SHA512_BLOCK_LEN, SHA512_256_DIGEST_LEN,
sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha512_256, sizeof(dalgid_sha512_256),
- &sha512_256_driver
+ &sha512_256_driver, 0
}};
const hal_hash_descriptor_t hal_hash_sha384[1] = {{
SHA512_BLOCK_LEN, SHA384_DIGEST_LEN,
sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha384, sizeof(dalgid_sha384),
- &sha384_driver
+ &sha384_driver, 0
}};
const hal_hash_descriptor_t hal_hash_sha512[1] = {{
SHA512_BLOCK_LEN, SHA512_DIGEST_LEN,
sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t),
dalgid_sha512, sizeof(dalgid_sha512),
- &sha512_driver
+ &sha512_driver, 0
}};
/*
@@ -274,13 +279,21 @@ hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor,
const hal_hash_driver_t * const driver = check_driver(descriptor);
hal_hash_state_t *state = state_buffer;
- if (driver == NULL || state == NULL || state_ == NULL ||
- state_length < descriptor->hash_state_length)
+ if (driver == NULL || state_ == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (state_buffer != NULL && state_length < descriptor->hash_state_length)
return HAL_ERROR_BAD_ARGUMENTS;
+ if (state_buffer == NULL && (state = malloc(descriptor->hash_state_length)) == NULL)
+ return HAL_ERROR_ALLOCATION_FAILURE;
+
memset(state, 0, sizeof(*state));
state->descriptor = descriptor;
state->driver = driver;
+
+ if (state_buffer == NULL)
+ state->flags |= STATE_FLAG_STATE_ALLOCATED;
*state_ = state;
@@ -288,6 +301,62 @@ hal_error_t hal_hash_initialize(const hal_hash_descriptor_t * const descriptor,
}
/*
+ * Clean up hash state. No-op unless memory was dynamically allocated.
+ */
+
+void hal_hash_cleanup(hal_hash_state_t **state_)
+{
+ if (state_ == NULL)
+ return;
+
+ hal_hash_state_t *state = *state_;
+
+ if (state == NULL || (state->flags & STATE_FLAG_STATE_ALLOCATED) == 0)
+ return;
+
+ memset(state, 0, state->descriptor->hash_state_length);
+ free(state);
+ *state_ = NULL;
+}
+
+/*
+ * Read hash result from core. At least for now, this also serves to
+ * read current hash state from core.
+ */
+
+static hal_error_t hash_read_digest(const hal_hash_driver_t * const driver,
+ uint8_t *digest,
+ const size_t digest_length)
+{
+ hal_error_t err;
+
+ assert(digest != NULL && digest_length % 4 == 0);
+
+ if ((err = hal_io_wait_valid(driver->status_addr)) != HAL_OK)
+ return err;
+
+ return hal_io_read(driver->digest_addr, digest, digest_length);
+}
+
+/*
+ * Write hash state back to core.
+ */
+
+static hal_error_t hash_write_digest(const hal_hash_driver_t * const driver,
+ const uint8_t * const digest,
+ const size_t digest_length)
+{
+ hal_error_t err;
+
+ assert(digest != NULL && digest_length % 4 == 0);
+
+ if ((err = hal_io_wait_ready(driver->status_addr)) != HAL_OK)
+ return err;
+
+ return hal_io_write(driver->digest_addr, digest, digest_length);
+}
+
+/*
* Send one block to a core.
*/
@@ -299,43 +368,38 @@ static hal_error_t hash_write_block(hal_hash_state_t * const state)
assert(state != NULL && state->descriptor != NULL && state->driver != NULL);
assert(state->descriptor->block_length % 4 == 0);
+ assert(state->descriptor->digest_length <= sizeof(state->core_state) ||
+ !state->descriptor->can_restore_state);
+
if (debug)
fprintf(stderr, "[ %s ]\n", state->block_count == 0 ? "init" : "next");
- if ((err = hal_io_write(state->driver->block_addr, state->block, state->descriptor->block_length)) != HAL_OK)
+ if ((err = hal_io_wait_ready(state->driver->status_addr)) != HAL_OK)
+ return err;
+
+ if (state->descriptor->can_restore_state &&
+ state->block_count != 0 &&
+ (err = hash_write_digest(state->driver, state->core_state,
+ state->descriptor->digest_length)) != HAL_OK)
+ return err;
+
+ if ((err = hal_io_write(state->driver->block_addr, state->block,
+ state->descriptor->block_length)) != HAL_OK)
return err;
ctrl_cmd[0] = ctrl_cmd[1] = ctrl_cmd[2] = 0;
ctrl_cmd[3] = state->block_count == 0 ? CTRL_INIT : CTRL_NEXT;
ctrl_cmd[3] |= state->driver->ctrl_mode;
- /*
- * Not sure why we're waiting for ready here, but it's what the old
- * (read: tested) code did, so keep that behavior for now.
- */
-
if ((err = hal_io_write(state->driver->ctrl_addr, ctrl_cmd, sizeof(ctrl_cmd))) != HAL_OK)
return err;
- return hal_io_wait_valid(state->driver->status_addr);
-}
-
-/*
- * Read hash result from core.
- */
-
-static hal_error_t hash_read_digest(const hal_hash_driver_t * const driver,
- uint8_t *digest,
- const size_t digest_length)
-{
- hal_error_t err;
-
- assert(digest != NULL && digest_length % 4 == 0);
-
- if ((err = hal_io_wait_valid(driver->status_addr)) != HAL_OK)
+ if (state->descriptor->can_restore_state &&
+ (err = hash_read_digest(state->driver, state->core_state,
+ state->descriptor->digest_length)) != HAL_OK)
return err;
- return hal_io_read(driver->digest_addr, digest, digest_length);
+ return hal_io_wait_valid(state->driver->status_addr);
}
/*
@@ -483,14 +547,20 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
{
const hal_hash_driver_t * const driver = check_driver(descriptor);
hal_hmac_state_t *state = state_buffer;
- hal_hash_state_t *h = NULL;
hal_error_t err;
int i;
- if (descriptor == NULL || driver == NULL || state == NULL || state_ == NULL ||
- state_length < descriptor->hmac_state_length)
+ if (descriptor == NULL || driver == NULL || state_ == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
+ if (state_buffer != NULL && state_length < descriptor->hmac_state_length)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (state_buffer == NULL && (state = malloc(descriptor->hmac_state_length)) == NULL)
+ return HAL_ERROR_ALLOCATION_FAILURE;
+
+ hal_hash_state_t *h = &state->hash_state;
+
assert(descriptor->block_length <= sizeof(state->keybuf));
#if 0
@@ -505,7 +575,10 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
if ((err = hal_hash_initialize(descriptor, &h, &state->hash_state,
sizeof(state->hash_state))) != HAL_OK)
- return err;
+ goto fail;
+
+ if (state_buffer == NULL)
+ h->flags |= STATE_FLAG_STATE_ALLOCATED;
/*
* If the supplied HMAC key is longer than the hash block length, we
@@ -522,7 +595,7 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
(err = hal_hash_finalize(h, state->keybuf, sizeof(state->keybuf))) != HAL_OK ||
(err = hal_hash_initialize(descriptor, &h, &state->hash_state,
sizeof(state->hash_state))) != HAL_OK)
- return err;
+ goto fail;
/*
* XOR the key with the IPAD value, then start the inner hash.
@@ -532,7 +605,7 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
state->keybuf[i] ^= HMAC_IPAD;
if ((err = hal_hash_update(h, state->keybuf, descriptor->block_length)) != HAL_OK)
- return err;
+ goto fail;
/*
* Prepare the key for the final hash. Since we just XORed key with
@@ -553,6 +626,35 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor,
*state_ = state;
return HAL_OK;
+
+ fail:
+ if (state_buffer == NULL)
+ free(state);
+ return err;
+}
+
+/*
+ * Clean up HMAC state. No-op unless memory was dynamically allocated.
+ */
+
+void hal_hmac_cleanup(hal_hmac_state_t **state_)
+{
+ if (state_ == NULL)
+ return;
+
+ hal_hmac_state_t *state = *state_;
+
+ if (state == NULL)
+ return;
+
+ hal_hash_state_t *h = &state->hash_state;
+
+ if ((h->flags & STATE_FLAG_STATE_ALLOCATED) == 0)
+ return;
+
+ memset(state, 0, h->descriptor->hmac_state_length);
+ free(state);
+ *state_ = NULL;
}
/*
diff --git a/modexp.c b/modexp.c
index 1e3d292..11a8d21 100644
--- a/modexp.c
+++ b/modexp.c
@@ -91,60 +91,41 @@ static hal_error_t set_register(const off_t addr,
}
/*
- * Get value of a block memory.
+ * Get value of a data buffer. We reverse the order of 32-bit words
+ * in the buffer during the transfer to match what the modexps6 core
+ * expects.
*/
-static hal_error_t get_blockmem(const off_t reset_addr,
- const off_t data_addr,
- uint8_t *value,
- const size_t length,
- const size_t io_len)
+static hal_error_t get_buffer(const off_t data_addr,
+ uint8_t *value,
+ const size_t length)
{
- uint8_t discard[4];
size_t i;
assert(value != NULL && length % 4 == 0);
- assert(io_len >= length && io_len % 4 == 0);
-
- check(set_register(reset_addr, 1));
-
- for (i = 0; i < io_len - length; i += 4) {
- check(hal_io_read(data_addr, discard, 4));
- if (discard[0] != 0 || discard[1] != 0 || discard[2] != 0 || discard[3] != 0)
- return HAL_ERROR_IO_UNEXPECTED;
- }
-
for (i = 0; i < length; i += 4)
- check(hal_io_read(data_addr, &value[i], 4));
+ check(hal_io_read(data_addr + i/4, &value[length - 4 - i], 4));
return HAL_OK;
}
/*
- * Set value of a block memory.
+ * Set value of a data buffer. We reverse the order of 32-bit words
+ * in the buffer during the transfer to match what the modexps6 core
+ * expects.
*/
-static hal_error_t set_blockmem(const off_t reset_addr,
- const off_t data_addr,
- const uint8_t * const value,
- const size_t length,
- const size_t io_len)
+static hal_error_t set_buffer(const off_t data_addr,
+ const uint8_t * const value,
+ const size_t length)
{
- const uint8_t zero[4] = { 0, 0, 0, 0 };
size_t i;
assert(value != NULL && length % 4 == 0);
- assert(io_len >= length && io_len % 4 == 0);
-
- check(set_register(reset_addr, 1));
-
- for (i = 0; i < io_len - length; i += 4)
- check(hal_io_write(data_addr, zero, 4));
-
for (i = 0; i < length; i += 4)
- check(hal_io_write(data_addr, &value[i], 4));
+ check(hal_io_write(data_addr + i/4, &value[length - 4 - i], 4));
return HAL_OK;
}
@@ -175,35 +156,52 @@ hal_error_t hal_modexp(const uint8_t * const msg, const size_t msg_len, /* Messa
return HAL_ERROR_BAD_ARGUMENTS;
/*
- * This insanity is a work-around for a current bug in the ModExp
- * core: we have to zero-pad everything out to the size of the
- * modulus plus 32-bits. Some kind of overflow issue. All of this
- * "io_len" nonsense can go away once that's fixed.
+ * We probably ought to take the mode (fast vs constant-time) as an
+ * argument, but for the moment we just guess that really short
+ * exponent means we're using the public key and can use fast mode,
+ * all other cases are something to do with the private key and
+ * therefore must use constant-time mode.
+ *
+ * Unclear whether it's worth trying to figure out exactly how long
+ * the operands are: assuming a multiple of eight is safe, but makes
+ * a bit more work for the core; checking to see how many bits are
+ * really set leaves the core sitting idle while the main CPU does
+ * these checks. No way to know which is faster without testing;
+ * take simple approach for the moment.
*/
- const size_t io_len = mod_len + 4;
- assert((io_len & 3) == 0);
+ /* Select mode (1 = fast, 0 = safe) */
+ check(set_register(MODEXPS6_ADDR_MODE, (exp_len <= 4)));
- check(set_blockmem(MODEXP_MODULUS_PTR_RST, MODEXP_MODULUS_DATA, mod, mod_len, io_len));
- check(set_blockmem(MODEXP_MESSAGE_PTR_RST, MODEXP_MESSAGE_DATA, msg, msg_len, io_len));
- check(set_register(MODEXP_MODULUS_LENGTH, /* mod_len */ io_len / 4));
+ /* Set modulus size in bits */
+ check(set_register(MODEXPS6_ADDR_MODULUS_WIDTH, mod_len * 8));
- check(set_blockmem(MODEXP_EXPONENT_PTR_RST, MODEXP_EXPONENT_DATA, exp, exp_len, exp_len));
- check(set_register(MODEXP_EXPONENT_LENGTH, exp_len / 4));
+ /* Write new modulus */
+ check(set_buffer(MODEXPS6_ADDR_MODULUS, mod, mod_len));
- check(hal_io_wait_ready(MODEXP_ADDR_STATUS));
+ /* Pre-calcuate speed-up coefficient */
+ check(hal_io_init(MODEXPS6_ADDR_CTRL));
- check(set_register(MODEXP_ADDR_CTRL, 1));
+ /* Wait for calculation to complete */
+ check(hal_io_wait_ready(MODEXPS6_ADDR_STATUS));
- /*
- * ModExp core is not very fast (yet), so wait a long time for a
- * response, but not forever.
- */
+ /* Write new message */
+ check(set_buffer(MODEXPS6_ADDR_MESSAGE, msg, msg_len));
+
+ /* Set new exponent length in bits */
+ check(set_register(MODEXPS6_ADDR_EXPONENT_WIDTH, exp_len * 8));
+
+ /* Set new exponent */
+ check(set_buffer(MODEXPS6_ADDR_EXPONENT, exp, exp_len));
+
+ /* Start calculation */
+ check(hal_io_next(MODEXPS6_ADDR_CTRL));
- int timeout = 0x7FFFFFFF;
- check(hal_io_wait(MODEXP_ADDR_STATUS, STATUS_READY, &timeout));
+ /* Wait for result */
+ check(hal_io_wait_valid(MODEXPS6_ADDR_STATUS));
- check(get_blockmem(MODEXP_RESULT_PTR_RST, MODEXP_RESULT_DATA, result, mod_len, io_len));
+ /* Extract result */
+ check(get_buffer(MODEXPS6_ADDR_RESULT, result, mod_len));
return HAL_OK;
}
diff --git a/rsa.c b/rsa.c
index b863fdd..3962a74 100644
--- a/rsa.c
+++ b/rsa.c
@@ -76,7 +76,7 @@
*/
#ifndef HAL_RSA_USE_MODEXP
-#define HAL_RSA_USE_MODEXP 0
+#define HAL_RSA_USE_MODEXP 1
#endif
/*
@@ -169,7 +169,7 @@ static hal_error_t unpack_fp(const fp_int * const bn, uint8_t *buffer, const siz
* wrap result back up as a bignum.
*/
-static hal_error_t modexp(const fp_int * const msg,
+static hal_error_t modexp(const fp_int * msg,
const fp_int * const exp,
const fp_int * const mod,
fp_int *res)
@@ -178,13 +178,21 @@ static hal_error_t modexp(const fp_int * const msg,
assert(msg != NULL && exp != NULL && mod != NULL && res != NULL);
- const size_t msg_len = fp_unsigned_bin_size(msg);
- const size_t exp_len = fp_unsigned_bin_size(exp);
- const size_t mod_len = fp_unsigned_bin_size(mod);
+ fp_int reduced_msg;
+
+ if (fp_cmp_mag(unconst_fp_int(msg), unconst_fp_int(mod)) != FP_LT) {
+ fp_init(&reduced_msg);
+ fp_mod(unconst_fp_int(msg), unconst_fp_int(mod), &reduced_msg);
+ msg = &reduced_msg;
+ }
- const size_t len = (MAX(MAX(msg_len, exp_len), mod_len) + 3) & ~3;
+ const size_t exp_len = (fp_unsigned_bin_size(unconst_fp_int(exp)) + 3) & ~3;
+ const size_t mod_len = (fp_unsigned_bin_size(unconst_fp_int(mod)) + 3) & ~3;
- uint8_t msgbuf[len], expbuf[len], modbuf[len], resbuf[len];
+ uint8_t msgbuf[mod_len];
+ uint8_t expbuf[exp_len];
+ uint8_t modbuf[mod_len];
+ uint8_t resbuf[mod_len];
if ((err = unpack_fp(msg, msgbuf, sizeof(msgbuf))) != HAL_OK ||
(err = unpack_fp(exp, expbuf, sizeof(expbuf))) != HAL_OK ||
diff --git a/tests/test-rsa.c b/tests/test-rsa.c
index 0751189..46afa03 100644
--- a/tests/test-rsa.c
+++ b/tests/test-rsa.c
@@ -287,8 +287,8 @@ int main(int argc, char *argv[])
* Initialize EIM and report what core we're running.
*/
- if ((err = hal_io_read(MODEXP_ADDR_NAME0, name, sizeof(name))) != HAL_OK ||
- (err = hal_io_read(MODEXP_ADDR_VERSION, version, sizeof(version))) != HAL_OK) {
+ if ((err = hal_io_read(MODEXPS6_ADDR_NAME0, name, sizeof(name))) != HAL_OK ||
+ (err = hal_io_read(MODEXPS6_ADDR_VERSION, version, sizeof(version))) != HAL_OK) {
printf("Initialization failed: %s\n", hal_error_string(err));
return 1;
}