[mask_rom, sig_verify] Add keys to mask ROM
This change defines an array of structs for storing keys in mask ROM,
moves the keys used in tests to this array, and updates the functions in
rsa_verify.c to use the new types.
Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/mask_rom/rsa_verify.c b/sw/device/silicon_creator/mask_rom/rsa_verify.c
index 4f96502..f01c343 100644
--- a/sw/device/silicon_creator/mask_rom/rsa_verify.c
+++ b/sw/device/silicon_creator/mask_rom/rsa_verify.c
@@ -4,51 +4,46 @@
#include "sw/device/silicon_creator/mask_rom/rsa_verify.h"
-#include <memory.h>
#include <stddef.h>
-/**
- * Constants used in this file.
- */
-enum {
- /**
- * Number of bits of RSA modulus.
- */
- kRsaNumBits = kRsaNumWords * sizeof(uint32_t) * 8,
-};
+#include "sw/device/lib/base/memory.h"
+#include "sw/device/silicon_creator/mask_rom/sig_verify_keys.h"
/**
- * Subtracts `b` from `a` in-place, i.e. `a -= b`.
+ * Subtracts the modulus of `key` from `a` in-place, i.e. `a -= n`.
*
- * Since a can be smaller than b, this function also returns the borrow.
+ * Since `a` can be smaller than the modulus, this function also returns the
+ * borrow.
*
- * @param a A `kRsaNumWords` long buffer, little-endian.
- * @param b A `kRsaNumWords` long buffer, little-endian.
+ * @param key An RSA public key.
+ * @param[in,out] a Buffer that holds `a`, little-endian.
* @return Borrow.
*/
-static uint32_t subtract(uint32_t *a, const uint32_t *b) {
+static uint32_t subtract_modulus(const sigverify_rsa_key_t *key,
+ sigverify_rsa_buffer_t *a) {
uint32_t borrow = 0;
- for (size_t i = 0; i < kRsaNumWords; ++i) {
- uint64_t diff = (uint64_t)a[i] - b[i] - borrow;
- borrow = diff > a[i];
- a[i] = (uint32_t)diff;
+ for (size_t i = 0; i < ARRAYSIZE(a->data); ++i) {
+ uint64_t diff = (uint64_t)a->data[i] - key->n.data[i] - borrow;
+ borrow = diff > a->data[i];
+ a->data[i] = (uint32_t)diff;
}
return borrow;
}
/**
- * Checks if `a` is greater than or equal to `b`.
+ * Checks if `a` is greater than or equal to the modulus of `key`.
*
- * @param a A `kRsaNumWords` long buffer, little-endian.
- * @param b A `kRsaNumWords` long buffer, little-endian.
+ * @param key An RSA public key.
+ * @param a Buffer that holds `a`, little-endian.
* @return Comparison result.
*/
-static bool greater_equal(const uint32_t *a, const uint32_t *b) {
+static bool greater_equal_modulus(const sigverify_rsa_key_t *key,
+ const sigverify_rsa_buffer_t *a) {
// TODO(#33): Hardening?
// Note: Loop terminates when `i` wraps around.
- for (size_t i = kRsaNumWords - 1; i < kRsaNumWords; --i) {
- if (a[i] != b[i]) {
- return a[i] > b[i];
+ for (size_t i = ARRAYSIZE(a->data) - 1; i < ARRAYSIZE(a->data); --i) {
+ if (a->data[i] != key->n.data[i]) {
+ return a->data[i] > key->n.data[i];
}
}
return true;
@@ -57,40 +52,41 @@
/**
* Shifts `a` left one bit in-place, i.e. `a <<= 1`.
*
- * Since the result may not fit in `kRsaNumWords`, this function also returns
- * the most significant bit of the result.
+ * Since the result may not fit in `a`, this function also returns the most
+ * significant bit of the result.
*
- * @param a A `kRsaNumWords` long buffer, little-endian.
+ * @param[in,out] a Buffer that holds `a`, little-endian.
* @return Most significant bit of the result.
*/
-static uint32_t shift_left(uint32_t *a) {
- const uint32_t msb = a[kRsaNumWords - 1] >> 31;
- for (size_t i = kRsaNumWords - 1; i > 0; --i) {
- a[i] = (a[i] << 1) | (a[i - 1] >> 31);
+static uint32_t shift_left(sigverify_rsa_buffer_t *a) {
+ const uint32_t msb = a->data[ARRAYSIZE(a->data) - 1] >> 31;
+ for (size_t i = ARRAYSIZE(a->data) - 1; i > 0; --i) {
+ a->data[i] = (a->data[i] << 1) | (a->data[i - 1] >> 31);
}
- a[0] <<= 1;
+ a->data[0] <<= 1;
return msb;
}
/**
- * Calculates R^2 mod m, where R = b^kRsaNumWords, and b is 2^32.
+ * Calculates R^2 mod n, where R = 2^kSigVerifyRsaNumBits.
*
- * @param m A `kRsaNumWords` long buffer, little-endian.
- * @param[out] result A `kRsaNumWords` long buffer, little-endian.
+ * @param key An RSA public key.
+ * @param[out] result Buffer to write the result to, little-endian.
*/
-static void calc_r_square(const uint32_t *m, uint32_t *result) {
- memset(result, 0, kRsaNumWords * sizeof(uint32_t));
- // Since R/2 < m < R, this subtraction ensures that result = R mod m and
- // fits in `kRsaNumWords` going into the loop.
- subtract(result, m);
+static void calc_r_square(const sigverify_rsa_key_t *key,
+ sigverify_rsa_buffer_t *result) {
+ memset(result->data, 0, sizeof(result->data));
+ // Since R/2 < n < R, this subtraction ensures that result = R mod n and
+ // fits in `kSigVerifyRsaNumWords` going into the loop.
+ subtract_modulus(key, result);
// Iteratively shift and reduce `result`.
- for (size_t i = 0; i < kRsaNumBits; ++i) {
+ for (size_t i = 0; i < kSigVerifyRsaNumBits; ++i) {
uint32_t msb = shift_left(result);
- // Reduce until result < m. Doing this at every iteration minimizes the
+ // Reduce until result < n. Doing this at every iteration minimizes the
// total number of subtractions that we need to perform.
- while (msb > 0 || greater_equal(result, m)) {
- msb -= subtract(result, m);
+ while (msb > 0 || greater_equal_modulus(key, result)) {
+ msb -= subtract_modulus(key, result);
}
}
}
@@ -103,11 +99,11 @@
// 2.2. result = (result + x_i * y + u_i * m) / b
// 3. If result >= m then result = result - m
// 4. Return result
-void mont_mul(const uint32_t *x, const uint32_t *y, const uint32_t *m,
- const uint32_t m0_inv, uint32_t *result) {
- memset(result, 0, kRsaNumWords * sizeof(uint32_t));
+void mont_mul(const sigverify_rsa_key_t *key, const sigverify_rsa_buffer_t *x,
+ const sigverify_rsa_buffer_t *y, sigverify_rsa_buffer_t *result) {
+ memset(result->data, 0, sizeof(result->data));
- for (size_t i = 0; i < kRsaNumWords; ++i) {
+ for (size_t i = 0; i < ARRAYSIZE(x->data); ++i) {
// The loop below reads one word ahead of writes to avoid a separate loop
// for the division by `b` in step 2.2 of the algorithm. Thus, `acc0` and
// `acc1` are initialized here before the loop. `acc0` holds the sum of
@@ -118,70 +114,69 @@
// 0xffff_ffff_ffff_ffff.
// Holds the sum of the first two addends in step 2.2.
- uint64_t acc0 = (uint64_t)x[i] * y[0] + result[0];
- const uint32_t u_i = (uint32_t)acc0 * m0_inv;
+ uint64_t acc0 = (uint64_t)x->data[i] * y->data[0] + result->data[0];
+ const uint32_t u_i = (uint32_t)acc0 * key->n0_inv;
// Holds the sum of the all three addends in step 2.2.
- uint64_t acc1 = (uint64_t)u_i * m[0] + (uint32_t)acc0;
+ uint64_t acc1 = (uint64_t)u_i * key->n.data[0] + (uint32_t)acc0;
// Process the i^th digit of `x`, i.e. `x[i]`.
- for (size_t j = 1; j < kRsaNumWords; ++j) {
- acc0 = (uint64_t)x[i] * y[j] + result[j] + (acc0 >> 32);
- acc1 = (uint64_t)u_i * m[j] + (uint32_t)acc0 + (acc1 >> 32);
- result[j - 1] = (uint32_t)acc1;
+ for (size_t j = 1; j < ARRAYSIZE(result->data); ++j) {
+ acc0 = (uint64_t)x->data[i] * y->data[j] + result->data[j] + (acc0 >> 32);
+ acc1 = (uint64_t)u_i * key->n.data[j] + (uint32_t)acc0 + (acc1 >> 32);
+ result->data[j - 1] = (uint32_t)acc1;
}
acc0 = (acc0 >> 32) + (acc1 >> 32);
- result[kRsaNumWords - 1] = (uint32_t)acc0;
+ result->data[ARRAYSIZE(result->data) - 1] = (uint32_t)acc0;
// The intermediate result of this algorithm before the check below is
- // bounded by R + m (Eq. (4) in Montgomery Arithmetic from a Software
- // Perspective, Bos. J. W, Montgomery, P. L.) where `m` is an integer with
- // `kRsaNumWords` base 2^32 digits, `R` is 2^(`kRsaNumWords`*32), and m < R.
- // Therefore, if there is a carry, then `result` is not the least
- // non-negative residue of x*y*R^-1 mod m. Since `acc0 >> 32` here is at
- // most 1, we can subtract `m` from `result` without taking it into account
- // and fit `result` into `kRsaNumWords`. Since this is not a direct
- // comparison with `m`, the final result is not guaranteed to be the the
- // least non-negative residue of x*y*R^-1 mod m.
+ // bounded by R + n (Eq. (4) in Montgomery Arithmetic from a Software
+ // Perspective, Bos. J. W, Montgomery, P. L.) where n is the modulus of
+ // `key` and n < R. Therefore, if there is a carry, then `result` is not the
+ // least non-negative residue of x*y*R^-1 mod n. Since `acc0 >> 32` here is
+ // at most 1, we can subtract the modulus from `result` without taking it
+ // into account and fit `result` into `kSigVerifyRsaNumWords`. Since this is
+ // not a direct comparison with the modulus, the final result is not
+ // guaranteed to be the the least non-negative residue of x*y*R^-1 mod n.
if (acc0 >> 32) {
- subtract(result, m);
+ subtract_modulus(key, result);
}
}
}
-bool mod_exp(const uint32_t *sig, const rsa_verify_exponent_t e,
- const uint32_t *m, const uint32_t m0_inv, uint32_t *result) {
- uint32_t buf[kRsaNumWords];
+bool sigverify_mod_exp_ibex(const sigverify_rsa_key_t *key,
+ const sigverify_rsa_buffer_t *sig,
+ sigverify_rsa_buffer_t *result) {
+ sigverify_rsa_buffer_t buf;
- if (e == kRsaVerifyExponent3) {
- // buf = R^2 mod m
- calc_r_square(m, buf);
- // result = sig * R mod m
- mont_mul(sig, buf, m, m0_inv, result);
- // buf = sig^2 * R mod m
- mont_mul(result, result, m, m0_inv, buf);
- } else if (e == kRsaVerifyExponent65537) {
- // result = R^2 mod m
- calc_r_square(m, result);
- // buf = sig * R mod m
- mont_mul(sig, result, m, m0_inv, buf);
+ if (key->exponent == 3) {
+ // buf = R^2 mod n
+ calc_r_square(key, &buf);
+ // result = sig * R mod n
+ mont_mul(key, sig, &buf, result);
+ // buf = sig^2 * R mod n
+ mont_mul(key, result, result, &buf);
+ } else if (key->exponent == 65537) {
+ // result = R^2 mod n
+ calc_r_square(key, result);
+ // buf = sig * R mod n
+ mont_mul(key, sig, result, &buf);
for (size_t i = 0; i < 8; ++i) {
- // result = sig^{2*i+1} * R mod m (sig's exponent: 2, 8, 32, ..., 32768)
- mont_mul(buf, buf, m, m0_inv, result);
- // buf = sig^{4*i+2} * R mod m (sig's exponent: 4, 16, 64, ..., 65536)
- mont_mul(result, result, m, m0_inv, buf);
+ // result = sig^{2*i+1} * R mod n (sig's exponent: 2, 8, 32, ..., 32768)
+ mont_mul(key, &buf, &buf, result);
+ // buf = sig^{4*i+2} * R mod n (sig's exponent: 4, 16, 64, ..., 65536)
+ mont_mul(key, result, result, &buf);
}
} else {
return false;
}
- // result = sig^e mod m
- mont_mul(buf, sig, m, m0_inv, result);
+ // result = sig^e mod n
+ mont_mul(key, &buf, sig, result);
// We need this check because the result of `mont_mul` is not guaranteed to be
- // the least non-negative residue. We need to subtract `m` from `result` at
- // most once because `m` is the modulus of an RSA public key and therefore
- // R/2 < m < R.
- if (greater_equal(result, m)) {
- subtract(result, m);
+ // the least non-negative residue. We need to subtract the modulus n from
+ // `result` at most once because R/2 < n < R.
+ if (greater_equal_modulus(key, result)) {
+ subtract_modulus(key, result);
}
return true;
diff --git a/sw/device/silicon_creator/mask_rom/rsa_verify.h b/sw/device/silicon_creator/mask_rom/rsa_verify.h
index 9a602b6..5495b2d 100644
--- a/sw/device/silicon_creator/mask_rom/rsa_verify.h
+++ b/sw/device/silicon_creator/mask_rom/rsa_verify.h
@@ -8,78 +8,51 @@
#include <stdbool.h>
#include <stdint.h>
+#include "sw/device/silicon_creator/mask_rom/sig_verify_keys.h"
+
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
-enum {
- /**
- * Number of words of the modulus and signature for RSA-3072.
- */
- kRsaNumWords = 96,
-};
-
-/**
- * Exponent to use for signature verification.
- *
- * This determines the e in s^e mod n.
- */
-// TODO(#22): May need to be updated after we decide on a key storage format.
-typedef enum rsa_verify_exponent {
- /**
- * e = 3.
- */
- kRsaVerifyExponent3,
- /**
- * e = 65537.
- */
- kRsaVerifyExponent65537,
-} rsa_verify_exponent_t;
-
// FIXME: Make static and move this comment to the source file. This is here
// just to be able to add a simple test.
/**
* Computes the Montgomery reduction of the product of two integers.
*
- * Given x, y, m, and m', this function computes x*y*R^-1 mod m, where
- * - x, y, and m are integers with kRsaNumWords base 2^32 digits,
- * - m' = -m^-1 mod b,
- * - R is (2^32)^kRsaNumWords, e.g. 2^3072 for RSA-3072, and
- * - b is 2^32.
+ * Given an RSA public key, x, and y this function computes x*y*R^-1 mod n,
+ * where
+ * - x and y are integers with `kSigVerifyRsaNumWords` base 2^32 digits,
+ * - n is the modulus of the key, and
+ * - R is 2^`kSigVerifyRsaNumBits`, e.g. 2^3072 for RSA-3072.
*
* See Handbook of Applied Cryptography, Ch. 14, Alg. 14.36.
*
- * @param x A `kRsaNumWords` long buffer, little-endian.
- * @param y A `kRsaNumWords` long buffer, little-endian.
- * @param m A `kRsaNumWords` long buffer, little-endian.
- * @param m0_inv Negative of the multiplicative inverse of m modulo b.
- * @param[out] result A `kRsaNumWords` long buffer, little-endian.
+ * @param key An RSA public key.
+ * @param x Buffer that holds `x`, little-endian.
+ * @param y Buffer that holds `y`, little-endian.
+ * @param[out] result Buffer to write the result to, little-endian.
*/
-void mont_mul(const uint32_t *x, const uint32_t *y, const uint32_t *m,
- uint32_t m0_inv, uint32_t *result);
+void mont_mul(const sigverify_rsa_key_t *key, const sigverify_rsa_buffer_t *x,
+ const sigverify_rsa_buffer_t *y, sigverify_rsa_buffer_t *result);
/**
- * Computes the modular exponentiation of an integer.
+ * Computes the modular exponentiation of an RSA signature.
*
- * Given sig, e, m, and m', this function computes sig^e mod m using Montgomery
- * multiplication, where
- * - sig and m are integers with kRsaNumWords base b digits,
- * - e is the exponent (3 or 65537),
- * - m' = -m^-1 mod b,
- * - b is 2^32.
+ * Given an RSA public key and sig, this function computes sig^e mod n using
+ * Montgomery multiplication, where
+ * - sig is an RSA signature,
+ * - e and n are the exponent and the modulus of the key, respectively.
*
- * @param sig A `kRsaNumWords` long buffer, little-endian.
- * @param exponent Exponent to use for signature verification.
- * @param m A `kRsaNumWords` long buffer, little-endian.
- * @param m0_inv Negative of the multiplicative inverse of m modulo b.
- * @param[out] result A `kRsaNumWords` long buffer, little-endian.
+ * @param key An RSA public key.
+ * @param sig Buffer that holds the signature, little-endian.
+ * @param result Buffer to write the result to, little-endian.
* @return True if successful, false otherwise.
*/
-// TODO(#22): Update this after we decide on a key storage format.
// FIXME: Error codes are still under discussion, update after we reach a
// decision.
-bool mod_exp(const uint32_t *sig, rsa_verify_exponent_t e, const uint32_t *m,
- uint32_t m0_inv, uint32_t *result);
+bool sigverify_mod_exp_ibex(const sigverify_rsa_key_t *key,
+ const sigverify_rsa_buffer_t *sig,
+ sigverify_rsa_buffer_t *result);
#ifdef __cplusplus
} // extern "C"
diff --git a/sw/device/silicon_creator/mask_rom/sig_verify_keys.c b/sw/device/silicon_creator/mask_rom/sig_verify_keys.c
new file mode 100644
index 0000000..00372d1
--- /dev/null
+++ b/sw/device/silicon_creator/mask_rom/sig_verify_keys.c
@@ -0,0 +1,110 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "sw/device/silicon_creator/mask_rom/sig_verify_keys.h"
+
+/**
+ * Public keys for signature verification.
+ */
+const sigverify_rsa_key_t kSigVerifyRsaKeys[kSigVerifyNumRsaKeys] = {
+ [0] =
+ {
+ // Private exponent d:
+ // 0xbebf06e3, 0x59d7e511, 0xe619ae0c, 0xb93ce7f6, 0xa83b89ca,
+ // 0x53c176f4, 0x869ef22b, 0xf8df4b83, 0x12ab013a, 0x98c927fc,
+ // 0xa4d57150, 0x0ce4696f, 0xdc931298, 0x2ced7d20, 0x973b5537,
+ // 0x2069a742, 0xf1559248, 0x13158c94, 0x16fef892, 0x82581bed,
+ // 0x15a7cba4, 0xc72a52e0, 0x7455bd70, 0x23eab41c, 0x0158da45,
+ // 0x82db6557, 0xec7bc157, 0x111b4eb0, 0x81c487dc, 0xf166df69,
+ // 0xde9a6b93, 0xedec8247, 0x6ddc889a, 0x5224cc0a, 0xce4b46fd,
+ // 0xde1e8772, 0x6417d968, 0x1d960144, 0x72dffbec, 0xd2619e50,
+ // 0x4ce73407, 0x25d7da23, 0xae72329a, 0xe43d4e29, 0x3e177edf,
+ // 0x70c58f2c, 0x8c9b7735, 0x514af916, 0x7e40bb19, 0xfab769ff,
+ // 0xdebb08e7, 0x6814f4f4, 0x352e82b3, 0x29c4d1b5, 0x61d485c8,
+ // 0x5cdb05a4, 0xcc6dd5cb, 0xd36a6e38, 0xf987ff5b, 0x2d060e8b,
+ // 0x84e66f62, 0xb0812761, 0x43414a06, 0xd21ff673, 0xa1317052,
+ // 0xf6f8cc01, 0x51c14c15, 0x1809b28f, 0x176965e5, 0x19b912be,
+ // 0x4097243f, 0xd7db29e3, 0xdf239b2c, 0xd08adbd2, 0xe25a3638,
+ // 0x2aac03ff, 0xa852eef0, 0xc41587cb, 0x8e20154b, 0x5232c192,
+ // 0x1d222a04, 0x5dedf724, 0x2fc54533, 0x3280b58b, 0x48e91ae9,
+ // 0x7748ae0c, 0x5a41dee3, 0xf5d82e3e, 0x85ff1006, 0x84bd1a55,
+ // 0x51f24349, 0x6f3e7cb3, 0x2cdaa80f, 0x947efef7, 0x07bffad6,
+ // 0x60417307,
+ .n = {{
+ 0x6a6a75e1, 0xa018ddc5, 0x687bb168, 0x8e8205a5, 0x7dbfffa7,
+ 0xc8722ac5, 0xf84d21cf, 0xe1312531, 0x0ce3f8a3, 0xa825f988,
+ 0x57f51964, 0xb27e206a, 0x8e1dd008, 0x1c4fb8d7, 0x824fb142,
+ 0x1c8be7b3, 0x7b9d6366, 0xc56ad0f2, 0xef762d5b, 0x4b1431e3,
+ 0x8ae28eb9, 0xd41db7aa, 0x43cccdf7, 0x91b74a84, 0x80183850,
+ 0x30e74d0d, 0xb62ed015, 0x235574d2, 0x8c28f251, 0x4f40def2,
+ 0x24e2efdb, 0x9ebd1ff2, 0xfa7b49ee, 0x2819a938, 0x6e66b8c8,
+ 0x24e41546, 0x4d783a7c, 0xd2947d3d, 0x1ab269e9, 0xfad39f16,
+ 0xaab78f7b, 0x49d8b510, 0x35bf0dfb, 0xeb274754, 0x069eccc9,
+ 0xc13c437e, 0xe3bc0f60, 0xc9e0e12f, 0xc253ac43, 0x89c240e0,
+ 0xc4aba4e5, 0xedf34bc0, 0x5402c462, 0x4021b0bd, 0x996b6241,
+ 0xc3d9945f, 0xa137ac60, 0xf0250bf5, 0xc8c7100f, 0xb70d6b88,
+ 0x78916a8c, 0x33370e5d, 0x3970dcb9, 0xaf4c58b4, 0x5f78cb0d,
+ 0xb02d90b7, 0xeb6c3d05, 0x04afc71a, 0x45185f0f, 0x987caa5b,
+ 0x33976249, 0x565afdbc, 0x80a85056, 0x59e07655, 0x9a29e77d,
+ 0x7a8dfb7f, 0x782e0204, 0x4d6713ff, 0x131000ea, 0xe18e1206,
+ 0x21f57f30, 0xf24f038b, 0x59cf874d, 0x24c50525, 0xb52f170d,
+ 0x46c9adde, 0x90e82c73, 0x1344ceaf, 0x663209f2, 0x24bd4fbf,
+ 0x5e4ed04d, 0x0fce770a, 0x81f78793, 0xa792e13e, 0xa6c7bf58,
+ 0xe1df9be8,
+ }},
+ .n0_inv = 4036719071,
+ .exponent = 65537,
+ },
+ [1] =
+ {
+ // Private exponent d:
+ // 0x129c022b, 0x13e47956, 0xdfec2aca, 0xb814ecac, 0x72c55992,
+ // 0xfcf87ab5, 0x29091c15, 0xed118f4d, 0xcdf98cba, 0x8ce9d3c4,
+ // 0x5870f4aa, 0x1466b189, 0xf61cd198, 0x898e7523, 0xb083e2af,
+ // 0x41c9533c, 0xf3a3d236, 0xb85f886e, 0x3a3d6426, 0x310a128e,
+ // 0x6bd63e65, 0xa8b5a275, 0xb01bd973, 0x0bfd31a7, 0xc0860d67,
+ // 0x9c82b2e4, 0x58b5313d, 0x10a5cdbb, 0x4c8756e1, 0xde699fc1,
+ // 0x64b7ea15, 0x0de1a5ab, 0x5ec3810e, 0xcdab8036, 0x2914896e,
+ // 0x3fc10cdd, 0x029e6787, 0x8a9fb6ee, 0x114d4a63, 0x48e7fb42,
+ // 0x28593dc1, 0x72ae9ccf, 0x921ad67b, 0xcccc6d1e, 0x79956f79,
+ // 0x6bc6189e, 0x1cb13c91, 0x80c0e7c9, 0x0c6ea14b, 0xf631e8ac,
+ // 0x866f54e7, 0xe1771b9a, 0x57026f77, 0xa4068cb9, 0xde218576,
+ // 0x932e8df6, 0xd0641b5b, 0x65cc6e0f, 0x3fdaac0e, 0x9d036254,
+ // 0x74f8e2f2, 0x55245512, 0xa3626209, 0x8bdec1d9, 0x393ce8b3,
+ // 0xa013b9bb, 0xf9708b92, 0x62aa3401, 0x7eed6670, 0xcc084151,
+ // 0xc594ff05, 0x359ba561, 0x6735cc4a, 0xbba98282, 0x3dec3980,
+ // 0xe91eb975, 0x854dc579, 0x09c5dc6f, 0x660655d4, 0x46d4c3fc,
+ // 0x7b942f7c, 0x756586c2, 0x7057ce35, 0x2ca213c7, 0xd900854e,
+ // 0xb22aab06, 0xb8c816a0, 0x941aa9ae, 0x864e97a1, 0xf69ecc7d,
+ // 0x5a3b56bc, 0xca0180ca, 0x67012e82, 0x4f7ac33c, 0x391a1b40,
+ // 0x1e70f217,
+ .n = {{
+ 0x3489eab3, 0x23e3d222, 0xbe69ae96, 0xccc537fa, 0xf83c6774,
+ 0xe683f91b, 0x9c588896, 0x44654dec, 0x96729ce1, 0x625a6410,
+ 0x6435e750, 0xec42933f, 0x130c9e34, 0xeb1834b6, 0x2a117689,
+ 0xb3b2f7bf, 0x21f92171, 0x4c1a1765, 0x9a92fe4b, 0xac9b5286,
+ 0x0049c14f, 0x2531d556, 0x3f6e28ae, 0xe12124a6, 0x40b11690,
+ 0xecfb1d29, 0x9af61602, 0x3d0f71b9, 0x1b9246cf, 0xbe254ff6,
+ 0xb2003ba0, 0x440c6682, 0x251589aa, 0xb65e34bb, 0x3c17861f,
+ 0xc24717a0, 0x35588598, 0xf8b64e80, 0x71cd790b, 0xa7ba410a,
+ 0x98ece611, 0x3502cc9b, 0xc75ac49f, 0x415dd4ee, 0x657989ed,
+ 0x784146ac, 0x3d6dada5, 0xb59e1a7a, 0x4a97c7c6, 0xc52b7408,
+ 0x269bfd6f, 0x48caa59f, 0x0a0e9ccf, 0xd8274c58, 0x34c920c7,
+ 0x731753c9, 0xe258a425, 0x62ca945e, 0x7f200856, 0xae144df9,
+ 0xbdd551af, 0xfed9fe6e, 0xd44e4c37, 0x47388b19, 0x576d7435,
+ 0xc0765a63, 0xd8a3456f, 0x4ffd380b, 0xf99066a2, 0xc83187e8,
+ 0xa17dfa22, 0x41a5e04a, 0x6b42c9bd, 0x65f90f0e, 0x73895904,
+ 0x76b858bf, 0x1fd2a0db, 0x3aa32a9d, 0x642602f8, 0xa8fc97ea,
+ 0xe5791ce9, 0xc061288e, 0xa20ed540, 0x0bcc76ac, 0x16031fd5,
+ 0x2d000229, 0x54b087c4, 0x789ffa18, 0x25d78dc9, 0xc7b8caf1,
+ 0x1d64086d, 0xbc0904be, 0x6a071710, 0xdce0936a, 0x569ca381,
+ 0xb6a5ac8b,
+ }},
+ .n0_inv = 0x88df2b85,
+ .exponent = 3,
+ },
+};
+
+// `extern` declarations for `inline` functions in the header.
+extern uint32_t sigverify_rsa_key_id_get(const sigverify_rsa_key_t *key);
diff --git a/sw/device/silicon_creator/mask_rom/sig_verify_keys.h b/sw/device/silicon_creator/mask_rom/sig_verify_keys.h
new file mode 100644
index 0000000..f2202fd
--- /dev/null
+++ b/sw/device/silicon_creator/mask_rom/sig_verify_keys.h
@@ -0,0 +1,85 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_MASK_ROM_SIG_VERIFY_KEYS_H_
+#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_MASK_ROM_SIG_VERIFY_KEYS_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+enum {
+ /**
+ * Length of an RSA-3072 modulus or signature in bits.
+ */
+ kSigVerifyRsaNumBits = 3072,
+ /**
+ * Length of an RSA-3072 modulus or signature in words.
+ */
+ kSigVerifyRsaNumWords = kSigVerifyRsaNumBits / (sizeof(uint32_t) * 8),
+ /**
+ * Number of RSA public keys.
+ */
+ kSigVerifyNumRsaKeys = 2,
+};
+
+/**
+ * A type that holds `kSigVerifyRsaNumWords` words.
+ *
+ * This can be used for RSA-3072 moduli, signatures, and intermediate values
+ * during modular exponentiation.
+ */
+typedef struct sigverify_rsa_buffer {
+ uint32_t data[kSigVerifyRsaNumWords];
+} sigverify_rsa_buffer_t;
+
+/**
+ * An RSA public key.
+ *
+ * Note: Defined here to be able to use in tests.
+ */
+// TODO(#22): Additional field(s) for key types/domains (or can store along with
+// exponent).
+typedef struct sigverify_rsa_key {
+ /**
+ * Modulus, a `kSigVerifyRsaNumWords` base 2^32 digit integer, little-endian.
+ */
+ sigverify_rsa_buffer_t n;
+ /**
+ * Negative of the multiplicative inverse of n modulo 2^32.
+ */
+ uint32_t n0_inv;
+ /**
+ * Exponent.
+ */
+ uint32_t exponent;
+} sigverify_rsa_key_t;
+
+/**
+ * Public keys for signature verification.
+ *
+ * Note: Declared here to be able to use in tests.
+ */
+extern const sigverify_rsa_key_t kSigVerifyRsaKeys[kSigVerifyNumRsaKeys];
+
+/**
+ * Gets the ID of an RSA public key.
+ *
+ * ID of a key is the least significant byte of its modulus.
+ * Callers must make sure that `key` is valid before calling this function.
+ *
+ * @param key An RSA public key.
+ * @return ID of the key.
+ */
+inline uint32_t sigverify_rsa_key_id_get(const sigverify_rsa_key_t *key) {
+ return key->n.data[0];
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_MASK_ROM_SIG_VERIFY_KEYS_H_
diff --git a/sw/device/tests/silicon_creator/mask_rom/meson.build b/sw/device/tests/silicon_creator/mask_rom/meson.build
index 6e32aed..93e1a4d 100644
--- a/sw/device/tests/silicon_creator/mask_rom/meson.build
+++ b/sw/device/tests/silicon_creator/mask_rom/meson.build
@@ -6,6 +6,7 @@
'rsa_verify_unittest',
sources: [
meson.source_root() / 'sw/device/silicon_creator/mask_rom/rsa_verify.c',
+ meson.source_root() / 'sw/device/silicon_creator/mask_rom/sig_verify_keys.c',
'rsa_verify_unittest.cc',
],
dependencies: [
diff --git a/sw/device/tests/silicon_creator/mask_rom/rsa_verify_unittest.cc b/sw/device/tests/silicon_creator/mask_rom/rsa_verify_unittest.cc
index 01c5555..5f28d5b 100644
--- a/sw/device/tests/silicon_creator/mask_rom/rsa_verify_unittest.cc
+++ b/sw/device/tests/silicon_creator/mask_rom/rsa_verify_unittest.cc
@@ -4,14 +4,14 @@
#include "sw/device/silicon_creator/mask_rom/rsa_verify.h"
+#include <unordered_set>
+
+#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace rsa_verify_unittest {
namespace {
-// Convenience alias for mont_mul parameters.
-using RsaBuffer = std::array<uint32_t, kRsaNumWords>;
-
TEST(MontMul, SmallNumbers) {
// Values are from ex. 14.35 in Handbook of Applied Cryptography except for m'
// and expected result are computed for base 2^32 and R = 2^3072 (96 base 2^32
@@ -19,39 +19,24 @@
// - m' = -m^-1 mod b = 3837733825
// - R^-1 mod m = 72136
// - x * y * R^-1 mod m = 55123
- constexpr RsaBuffer x{5792};
- constexpr RsaBuffer y{1229};
- constexpr RsaBuffer m{72639};
- constexpr uint32_t m0_inv = 3837733825;
- constexpr RsaBuffer exp_result{55123};
+ constexpr sigverify_rsa_buffer_t x{5792};
+ constexpr sigverify_rsa_buffer_t y{1229};
+ constexpr sigverify_rsa_key_t key{
+ .n = {72639},
+ .n0_inv = 3837733825,
+ .exponent = 3,
+ };
+ constexpr sigverify_rsa_buffer_t exp_res{55123};
// Uninitialized on purpose.
- RsaBuffer act_res;
+ sigverify_rsa_buffer_t act_res;
- mont_mul(x.data(), y.data(), m.data(), m0_inv, act_res.data());
+ mont_mul(&key, &x, &y, &act_res);
- EXPECT_EQ(exp_result, act_res);
+ EXPECT_THAT(exp_res.data, ::testing::ElementsAreArray(act_res.data));
}
TEST(MontMul, LargeNumbers) {
- constexpr RsaBuffer m{
- 0x6a6a75e1, 0xa018ddc5, 0x687bb168, 0x8e8205a5, 0x7dbfffa7, 0xc8722ac5,
- 0xf84d21cf, 0xe1312531, 0x0ce3f8a3, 0xa825f988, 0x57f51964, 0xb27e206a,
- 0x8e1dd008, 0x1c4fb8d7, 0x824fb142, 0x1c8be7b3, 0x7b9d6366, 0xc56ad0f2,
- 0xef762d5b, 0x4b1431e3, 0x8ae28eb9, 0xd41db7aa, 0x43cccdf7, 0x91b74a84,
- 0x80183850, 0x30e74d0d, 0xb62ed015, 0x235574d2, 0x8c28f251, 0x4f40def2,
- 0x24e2efdb, 0x9ebd1ff2, 0xfa7b49ee, 0x2819a938, 0x6e66b8c8, 0x24e41546,
- 0x4d783a7c, 0xd2947d3d, 0x1ab269e9, 0xfad39f16, 0xaab78f7b, 0x49d8b510,
- 0x35bf0dfb, 0xeb274754, 0x069eccc9, 0xc13c437e, 0xe3bc0f60, 0xc9e0e12f,
- 0xc253ac43, 0x89c240e0, 0xc4aba4e5, 0xedf34bc0, 0x5402c462, 0x4021b0bd,
- 0x996b6241, 0xc3d9945f, 0xa137ac60, 0xf0250bf5, 0xc8c7100f, 0xb70d6b88,
- 0x78916a8c, 0x33370e5d, 0x3970dcb9, 0xaf4c58b4, 0x5f78cb0d, 0xb02d90b7,
- 0xeb6c3d05, 0x04afc71a, 0x45185f0f, 0x987caa5b, 0x33976249, 0x565afdbc,
- 0x80a85056, 0x59e07655, 0x9a29e77d, 0x7a8dfb7f, 0x782e0204, 0x4d6713ff,
- 0x131000ea, 0xe18e1206, 0x21f57f30, 0xf24f038b, 0x59cf874d, 0x24c50525,
- 0xb52f170d, 0x46c9adde, 0x90e82c73, 0x1344ceaf, 0x663209f2, 0x24bd4fbf,
- 0x5e4ed04d, 0x0fce770a, 0x81f78793, 0xa792e13e, 0xa6c7bf58, 0xe1df9be8,
- };
- constexpr RsaBuffer sig{
+ constexpr sigverify_rsa_buffer_t sig{
0xceb7e983, 0xe693b200, 0xf9153989, 0xcf899599, 0x1ec09fae, 0xf2f88007,
0x2a24eed5, 0x9c5b7c4e, 0x21a153b2, 0xaf7583ae, 0x04fdd694, 0x7550094b,
0xb2a69ac4, 0xe49d8022, 0x7ed6f162, 0x14bb3a1b, 0xbb29d8dd, 0x5c5815c2,
@@ -69,8 +54,7 @@
0xa29d7536, 0x55c19326, 0x9ebbc63e, 0x20c75aee, 0xef6783d7, 0x59ffdba5,
0x879b937b, 0x43a5c74c, 0x82b8f825, 0xfdf04b3a, 0x8fc62fbe, 0x114e6da5,
};
- constexpr uint32_t m0_inv = 4036719071;
- constexpr RsaBuffer exp_result{
+ constexpr sigverify_rsa_buffer_t exp_res{
0x7603d6bd, 0xe7714c93, 0x97cf4c0a, 0xa2f79f2b, 0xd6d9a47a, 0x666d8e1d,
0x298e418a, 0xdbb713ec, 0x84d319fd, 0x1e89e6c3, 0xa4671f40, 0xc324a13b,
0x528c47d0, 0xa4dd82ef, 0x07d00906, 0xa42d7bc9, 0xdaa7dabb, 0x7833ef95,
@@ -89,61 +73,23 @@
0x59e45235, 0x11ca6d14, 0x43334239, 0xfe7cd561, 0xb161f750, 0xafcef8de,
};
// Uninitialized on purpose.
- RsaBuffer act_res;
+ sigverify_rsa_buffer_t act_res;
- mont_mul(sig.data(), sig.data(), m.data(), m0_inv, act_res.data());
+ mont_mul(&kSigVerifyRsaKeys[0], &sig, &sig, &act_res);
- EXPECT_EQ(exp_result, act_res);
+ EXPECT_THAT(act_res.data, ::testing::ElementsAreArray(exp_res.data));
}
TEST(ModExp, BadExp) {
- RsaBuffer empty{};
- rsa_verify_exponent_t bad_enum =
- static_cast<rsa_verify_exponent_t>(kRsaVerifyExponent65537 + 1);
+ // Exponent = 0
+ constexpr sigverify_rsa_key_t bad_key{};
+ sigverify_rsa_buffer_t empty;
- EXPECT_EQ(mod_exp(empty.data(), bad_enum, empty.data(), 0, empty.data()),
- false);
+ EXPECT_EQ(sigverify_mod_exp_ibex(&bad_key, &empty, &empty), false);
}
TEST(ModExp, Exp65537) {
- // Private key d: {
- // 0xbebf06e3, 0x59d7e511, 0xe619ae0c, 0xb93ce7f6, 0xa83b89ca, 0x53c176f4,
- // 0x869ef22b, 0xf8df4b83, 0x12ab013a, 0x98c927fc, 0xa4d57150, 0x0ce4696f,
- // 0xdc931298, 0x2ced7d20, 0x973b5537, 0x2069a742, 0xf1559248, 0x13158c94,
- // 0x16fef892, 0x82581bed, 0x15a7cba4, 0xc72a52e0, 0x7455bd70, 0x23eab41c,
- // 0x0158da45, 0x82db6557, 0xec7bc157, 0x111b4eb0, 0x81c487dc, 0xf166df69,
- // 0xde9a6b93, 0xedec8247, 0x6ddc889a, 0x5224cc0a, 0xce4b46fd, 0xde1e8772,
- // 0x6417d968, 0x1d960144, 0x72dffbec, 0xd2619e50, 0x4ce73407, 0x25d7da23,
- // 0xae72329a, 0xe43d4e29, 0x3e177edf, 0x70c58f2c, 0x8c9b7735, 0x514af916,
- // 0x7e40bb19, 0xfab769ff, 0xdebb08e7, 0x6814f4f4, 0x352e82b3, 0x29c4d1b5,
- // 0x61d485c8, 0x5cdb05a4, 0xcc6dd5cb, 0xd36a6e38, 0xf987ff5b, 0x2d060e8b,
- // 0x84e66f62, 0xb0812761, 0x43414a06, 0xd21ff673, 0xa1317052, 0xf6f8cc01,
- // 0x51c14c15, 0x1809b28f, 0x176965e5, 0x19b912be, 0x4097243f, 0xd7db29e3,
- // 0xdf239b2c, 0xd08adbd2, 0xe25a3638, 0x2aac03ff, 0xa852eef0, 0xc41587cb,
- // 0x8e20154b, 0x5232c192, 0x1d222a04, 0x5dedf724, 0x2fc54533, 0x3280b58b,
- // 0x48e91ae9, 0x7748ae0c, 0x5a41dee3, 0xf5d82e3e, 0x85ff1006, 0x84bd1a55,
- // 0x51f24349, 0x6f3e7cb3, 0x2cdaa80f, 0x947efef7, 0x07bffad6, 0x60417307,
- // };
- constexpr RsaBuffer m{
- 0x6a6a75e1, 0xa018ddc5, 0x687bb168, 0x8e8205a5, 0x7dbfffa7, 0xc8722ac5,
- 0xf84d21cf, 0xe1312531, 0x0ce3f8a3, 0xa825f988, 0x57f51964, 0xb27e206a,
- 0x8e1dd008, 0x1c4fb8d7, 0x824fb142, 0x1c8be7b3, 0x7b9d6366, 0xc56ad0f2,
- 0xef762d5b, 0x4b1431e3, 0x8ae28eb9, 0xd41db7aa, 0x43cccdf7, 0x91b74a84,
- 0x80183850, 0x30e74d0d, 0xb62ed015, 0x235574d2, 0x8c28f251, 0x4f40def2,
- 0x24e2efdb, 0x9ebd1ff2, 0xfa7b49ee, 0x2819a938, 0x6e66b8c8, 0x24e41546,
- 0x4d783a7c, 0xd2947d3d, 0x1ab269e9, 0xfad39f16, 0xaab78f7b, 0x49d8b510,
- 0x35bf0dfb, 0xeb274754, 0x069eccc9, 0xc13c437e, 0xe3bc0f60, 0xc9e0e12f,
- 0xc253ac43, 0x89c240e0, 0xc4aba4e5, 0xedf34bc0, 0x5402c462, 0x4021b0bd,
- 0x996b6241, 0xc3d9945f, 0xa137ac60, 0xf0250bf5, 0xc8c7100f, 0xb70d6b88,
- 0x78916a8c, 0x33370e5d, 0x3970dcb9, 0xaf4c58b4, 0x5f78cb0d, 0xb02d90b7,
- 0xeb6c3d05, 0x04afc71a, 0x45185f0f, 0x987caa5b, 0x33976249, 0x565afdbc,
- 0x80a85056, 0x59e07655, 0x9a29e77d, 0x7a8dfb7f, 0x782e0204, 0x4d6713ff,
- 0x131000ea, 0xe18e1206, 0x21f57f30, 0xf24f038b, 0x59cf874d, 0x24c50525,
- 0xb52f170d, 0x46c9adde, 0x90e82c73, 0x1344ceaf, 0x663209f2, 0x24bd4fbf,
- 0x5e4ed04d, 0x0fce770a, 0x81f78793, 0xa792e13e, 0xa6c7bf58, 0xe1df9be8,
- };
- constexpr uint32_t m0_inv = 4036719071;
- constexpr RsaBuffer sig{
+ constexpr sigverify_rsa_buffer_t sig{
0xceb7e983, 0xe693b200, 0xf9153989, 0xcf899599, 0x1ec09fae, 0xf2f88007,
0x2a24eed5, 0x9c5b7c4e, 0x21a153b2, 0xaf7583ae, 0x04fdd694, 0x7550094b,
0xb2a69ac4, 0xe49d8022, 0x7ed6f162, 0x14bb3a1b, 0xbb29d8dd, 0x5c5815c2,
@@ -161,7 +107,7 @@
0xa29d7536, 0x55c19326, 0x9ebbc63e, 0x20c75aee, 0xef6783d7, 0x59ffdba5,
0x879b937b, 0x43a5c74c, 0x82b8f825, 0xfdf04b3a, 0x8fc62fbe, 0x114e6da5,
};
- constexpr RsaBuffer exp_res{
+ constexpr sigverify_rsa_buffer_t exp_res{
0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555,
0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555,
0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555,
@@ -180,53 +126,15 @@
0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555,
};
// Uninitialized on purpose.
- RsaBuffer act_res;
+ sigverify_rsa_buffer_t act_res;
- EXPECT_EQ(mod_exp(sig.data(), kRsaVerifyExponent65537, m.data(), m0_inv,
- act_res.data()),
+ EXPECT_EQ(sigverify_mod_exp_ibex(&kSigVerifyRsaKeys[0], &sig, &act_res),
true);
- EXPECT_EQ(exp_res, act_res);
+ EXPECT_THAT(act_res.data, ::testing::ElementsAreArray(exp_res.data));
}
TEST(ModExp, Exp3) {
- // Private key d: {
- // 0x129c022b, 0x13e47956, 0xdfec2aca, 0xb814ecac, 0x72c55992, 0xfcf87ab5,
- // 0x29091c15, 0xed118f4d, 0xcdf98cba, 0x8ce9d3c4, 0x5870f4aa, 0x1466b189,
- // 0xf61cd198, 0x898e7523, 0xb083e2af, 0x41c9533c, 0xf3a3d236, 0xb85f886e,
- // 0x3a3d6426, 0x310a128e, 0x6bd63e65, 0xa8b5a275, 0xb01bd973, 0x0bfd31a7,
- // 0xc0860d67, 0x9c82b2e4, 0x58b5313d, 0x10a5cdbb, 0x4c8756e1, 0xde699fc1,
- // 0x64b7ea15, 0x0de1a5ab, 0x5ec3810e, 0xcdab8036, 0x2914896e, 0x3fc10cdd,
- // 0x029e6787, 0x8a9fb6ee, 0x114d4a63, 0x48e7fb42, 0x28593dc1, 0x72ae9ccf,
- // 0x921ad67b, 0xcccc6d1e, 0x79956f79, 0x6bc6189e, 0x1cb13c91, 0x80c0e7c9,
- // 0x0c6ea14b, 0xf631e8ac, 0x866f54e7, 0xe1771b9a, 0x57026f77, 0xa4068cb9,
- // 0xde218576, 0x932e8df6, 0xd0641b5b, 0x65cc6e0f, 0x3fdaac0e, 0x9d036254,
- // 0x74f8e2f2, 0x55245512, 0xa3626209, 0x8bdec1d9, 0x393ce8b3, 0xa013b9bb,
- // 0xf9708b92, 0x62aa3401, 0x7eed6670, 0xcc084151, 0xc594ff05, 0x359ba561,
- // 0x6735cc4a, 0xbba98282, 0x3dec3980, 0xe91eb975, 0x854dc579, 0x09c5dc6f,
- // 0x660655d4, 0x46d4c3fc, 0x7b942f7c, 0x756586c2, 0x7057ce35, 0x2ca213c7,
- // 0xd900854e, 0xb22aab06, 0xb8c816a0, 0x941aa9ae, 0x864e97a1, 0xf69ecc7d,
- // 0x5a3b56bc, 0xca0180ca, 0x67012e82, 0x4f7ac33c, 0x391a1b40, 0x1e70f217,
- // };
- constexpr RsaBuffer m{
- 0x3489eab3, 0x23e3d222, 0xbe69ae96, 0xccc537fa, 0xf83c6774, 0xe683f91b,
- 0x9c588896, 0x44654dec, 0x96729ce1, 0x625a6410, 0x6435e750, 0xec42933f,
- 0x130c9e34, 0xeb1834b6, 0x2a117689, 0xb3b2f7bf, 0x21f92171, 0x4c1a1765,
- 0x9a92fe4b, 0xac9b5286, 0x0049c14f, 0x2531d556, 0x3f6e28ae, 0xe12124a6,
- 0x40b11690, 0xecfb1d29, 0x9af61602, 0x3d0f71b9, 0x1b9246cf, 0xbe254ff6,
- 0xb2003ba0, 0x440c6682, 0x251589aa, 0xb65e34bb, 0x3c17861f, 0xc24717a0,
- 0x35588598, 0xf8b64e80, 0x71cd790b, 0xa7ba410a, 0x98ece611, 0x3502cc9b,
- 0xc75ac49f, 0x415dd4ee, 0x657989ed, 0x784146ac, 0x3d6dada5, 0xb59e1a7a,
- 0x4a97c7c6, 0xc52b7408, 0x269bfd6f, 0x48caa59f, 0x0a0e9ccf, 0xd8274c58,
- 0x34c920c7, 0x731753c9, 0xe258a425, 0x62ca945e, 0x7f200856, 0xae144df9,
- 0xbdd551af, 0xfed9fe6e, 0xd44e4c37, 0x47388b19, 0x576d7435, 0xc0765a63,
- 0xd8a3456f, 0x4ffd380b, 0xf99066a2, 0xc83187e8, 0xa17dfa22, 0x41a5e04a,
- 0x6b42c9bd, 0x65f90f0e, 0x73895904, 0x76b858bf, 0x1fd2a0db, 0x3aa32a9d,
- 0x642602f8, 0xa8fc97ea, 0xe5791ce9, 0xc061288e, 0xa20ed540, 0x0bcc76ac,
- 0x16031fd5, 0x2d000229, 0x54b087c4, 0x789ffa18, 0x25d78dc9, 0xc7b8caf1,
- 0x1d64086d, 0xbc0904be, 0x6a071710, 0xdce0936a, 0x569ca381, 0xb6a5ac8b,
- };
- constexpr uint32_t m0_inv = 0x88df2b85;
- constexpr RsaBuffer sig{
+ constexpr sigverify_rsa_buffer_t sig{
0xca60cb6e, 0xd3a786de, 0x37623afb, 0x7f6cbc1a, 0x5366d957, 0xe69ffe2f,
0x3560dc40, 0xf8b205c5, 0xa612764f, 0xb0415cf7, 0x5c5b87d9, 0xe0081c67,
0xadc8d9bd, 0xdd072b18, 0x8e22b48b, 0x758b9df3, 0xb208d5ab, 0x5f1bcb08,
@@ -244,7 +152,7 @@
0x3daf21c0, 0x819ee37e, 0x0bba9299, 0x90727884, 0xc74908f9, 0xec095a40,
0x8e2120dd, 0xfbefd497, 0x2227f721, 0xb7abdc98, 0xf7e55656, 0x3be75b5c,
};
- constexpr RsaBuffer exp_res{
+ constexpr sigverify_rsa_buffer_t exp_res{
0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555,
0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555,
0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555,
@@ -263,12 +171,20 @@
0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555,
};
// Uninitialized on purpose.
- RsaBuffer act_res;
+ sigverify_rsa_buffer_t act_res;
- EXPECT_EQ(mod_exp(sig.data(), kRsaVerifyExponent3, m.data(), m0_inv,
- act_res.data()),
+ EXPECT_EQ(sigverify_mod_exp_ibex(&kSigVerifyRsaKeys[1], &sig, &act_res),
true);
- EXPECT_EQ(exp_res, act_res);
+ EXPECT_THAT(act_res.data, ::testing::ElementsAreArray(exp_res.data));
+}
+
+TEST(Keys, UniqueIds) {
+ std::unordered_set<uint32_t> ids;
+ for (auto const &key : kSigVerifyRsaKeys) {
+ ids.insert(sigverify_rsa_key_id_get(&key));
+ }
+
+ EXPECT_EQ(ids.size(), kSigVerifyNumRsaKeys);
}
} // namespace