diff --git a/sw/device/lib/testing/BUILD b/sw/device/lib/testing/BUILD index fc1cf1dc15972..ab4fc58564d5d 100644 --- a/sw/device/lib/testing/BUILD +++ b/sw/device/lib/testing/BUILD @@ -257,6 +257,19 @@ cc_library( ], ) +cc_library( + name = "otbn_testutils_rsa", + srcs = ["otbn_testutils_rsa.c"], + hdrs = ["otbn_testutils_rsa.h"], + target_compatible_with = [OPENTITAN_CPU], + deps = [ + ":otbn_testutils", + "//sw/device/lib/base:status", + "//sw/device/lib/dif:otbn", + "//sw/otbn/crypto:rsa", + ], +) + cc_library( name = "otp_ctrl_testutils", srcs = ["otp_ctrl_testutils.c"], diff --git a/sw/device/lib/testing/otbn_testutils_rsa.c b/sw/device/lib/testing/otbn_testutils_rsa.c new file mode 100644 index 0000000000000..bd9b69be7e452 --- /dev/null +++ b/sw/device/lib/testing/otbn_testutils_rsa.c @@ -0,0 +1,117 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include "sw/device/lib/testing/otbn_testutils_rsa.h" + +#include "sw/device/lib/base/status.h" +#include "sw/device/lib/dif/dif_otbn.h" +#include "sw/device/lib/testing/otbn_testutils.h" + +OTBN_DECLARE_APP_SYMBOLS(rsa); +OTBN_DECLARE_SYMBOL_ADDR(rsa, mode); +OTBN_DECLARE_SYMBOL_ADDR(rsa, n_limbs); +OTBN_DECLARE_SYMBOL_ADDR(rsa, inout); +OTBN_DECLARE_SYMBOL_ADDR(rsa, modulus); +OTBN_DECLARE_SYMBOL_ADDR(rsa, exp); + +static const otbn_app_t kOtbnAppRsa = OTBN_APP_T_INIT(rsa); +static const otbn_addr_t kOtbnVarRsaMode = OTBN_ADDR_T_INIT(rsa, mode); +static const otbn_addr_t kOtbnVarRsaNLimbs = OTBN_ADDR_T_INIT(rsa, n_limbs); +static const otbn_addr_t kOtbnVarRsaInOut = OTBN_ADDR_T_INIT(rsa, inout); +static const otbn_addr_t kOtbnVarRsaModulus = OTBN_ADDR_T_INIT(rsa, modulus); +static const otbn_addr_t kOtbnVarRsaExp = OTBN_ADDR_T_INIT(rsa, exp); + +enum { + kOtbnWideWordBytes = 256 / 8, + kModeEncrypt = 1, + kModeDecrypt = 2, +}; + +status_t otbn_testutils_rsa_load(dif_otbn_t *otbn) { + if (otbn == NULL) { + return INVALID_ARGUMENT(); + } + return otbn_testutils_load_app(otbn, kOtbnAppRsa); +} + +status_t otbn_testutils_rsa_modexp_f4_start(dif_otbn_t *otbn, + const uint8_t *modulus, + const uint8_t *in, + size_t size_bytes) { + if (otbn == NULL || size_bytes % kOtbnWideWordBytes != 0) { + return INVALID_ARGUMENT(); + } + + uint32_t n_limbs = size_bytes / kOtbnWideWordBytes; + if (n_limbs == 0 || n_limbs > 16) { + return INVALID_ARGUMENT(); + } + + // Write input arguments. + uint32_t mode = kModeEncrypt; + TRY(otbn_testutils_write_data(otbn, sizeof(uint32_t), &mode, + kOtbnVarRsaMode)); + TRY(otbn_testutils_write_data(otbn, sizeof(uint32_t), &n_limbs, + kOtbnVarRsaNLimbs)); + TRY(otbn_testutils_write_data(otbn, size_bytes, modulus, kOtbnVarRsaModulus)); + TRY(otbn_testutils_write_data(otbn, size_bytes, in, kOtbnVarRsaInOut)); + + // Call OTBN to start the operation. + return otbn_testutils_execute(otbn); +} + +status_t otbn_testutils_rsa_modexp_consttime_start( + dif_otbn_t *otbn, const uint8_t *modulus, const uint8_t *private_exponent, + const uint8_t *in, size_t size_bytes) { + if (otbn == NULL || size_bytes % kOtbnWideWordBytes != 0) { + return INVALID_ARGUMENT(); + } + + uint32_t n_limbs = size_bytes / kOtbnWideWordBytes; + if (n_limbs == 0 || n_limbs > 16) { + return INVALID_ARGUMENT(); + } + + // Write input arguments. + uint32_t mode = kModeDecrypt; + TRY(otbn_testutils_write_data(otbn, sizeof(mode), &mode, kOtbnVarRsaMode)); + TRY(otbn_testutils_write_data(otbn, sizeof(n_limbs), &n_limbs, + kOtbnVarRsaNLimbs)); + TRY(otbn_testutils_write_data(otbn, size_bytes, modulus, kOtbnVarRsaModulus)); + TRY(otbn_testutils_write_data(otbn, size_bytes, private_exponent, + kOtbnVarRsaExp)); + TRY(otbn_testutils_write_data(otbn, size_bytes, in, kOtbnVarRsaInOut)); + + // Call OTBN to start the operation. + return otbn_testutils_execute(otbn); +} + +static status_t modexp_finalize(dif_otbn_t *otbn, uint8_t *out, + size_t size_bytes) { + if (otbn == NULL || size_bytes % kOtbnWideWordBytes != 0) { + return INVALID_ARGUMENT(); + } + + uint32_t n_limbs = size_bytes / kOtbnWideWordBytes; + if (n_limbs == 0 || n_limbs > 16) { + return INVALID_ARGUMENT(); + } + + // Wait for OTBN to complete. + TRY(otbn_testutils_wait_for_done(otbn, kDifOtbnErrBitsNoError)); + + // Read back results. + return otbn_testutils_read_data(otbn, size_bytes, kOtbnVarRsaInOut, out); +} + +status_t otbn_testutils_rsa_modexp_f4_finalize(dif_otbn_t *otbn, uint8_t *out, + size_t size_bytes) { + return modexp_finalize(otbn, out, size_bytes); +} + +status_t otbn_testutils_rsa_modexp_consttime_finalize(dif_otbn_t *otbn, + uint8_t *out, + size_t size_bytes) { + return modexp_finalize(otbn, out, size_bytes); +} diff --git a/sw/device/lib/testing/otbn_testutils_rsa.h b/sw/device/lib/testing/otbn_testutils_rsa.h new file mode 100644 index 0000000000000..4a5053f47fbb7 --- /dev/null +++ b/sw/device/lib/testing/otbn_testutils_rsa.h @@ -0,0 +1,100 @@ +// 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_LIB_TESTING_OTBN_TESTUTILS_RSA_H_ +#define OPENTITAN_SW_DEVICE_LIB_TESTING_OTBN_TESTUTILS_RSA_H_ + +#include "sw/device/lib/base/status.h" +#include "sw/device/lib/dif/dif_otbn.h" + +/** + * @file Run RSA on OTBN as a testing tool. + * @brief This library is based on the DIF instead of a full OTBN driver, and + * should be used for testing only. The library does not include message + * hashing or encoding. + */ + +/** + * Load the RSA application into OTBN. + * + * @param otbn The OTBN context object. + */ +status_t otbn_testutils_rsa_load(dif_otbn_t *otbn); + +/** + * Start running modular exponentiation with the exponent 65537. + * + * Computes (in^65537) mod n. This corresponds to the core step in encryption + * or signature verification, and is much faster than a general modular + * exponentiation. 65537 is also called "F4" because it is the 4th Fermat + * number (2^16 + 1). + * + * The RSA app should be loaded into OTBN with `otbn_testutils_rsa_load` before + * calling this function. + * + * @param otbn The OTBN context object. + * @param modulus The modulus (n). + * @param in The plaintext message. + * @param size_bytes The size of all buffers in bytes, i.e. the key/modulus + * length (i.e. 128 for RSA 1024). Valid range: 32..512 in + * 32 byte-steps (i.e. RSA 256 to RSA 4096). + */ +status_t otbn_testutils_rsa_modexp_f4_start(dif_otbn_t *otbn, + const uint8_t *modulus, + const uint8_t *in, + size_t size_bytes); + +/** + * Finish modular exponentiation with the exponent 65537. + * + * Waits for OTBN to complete and reads back the result of modular + * exponentiation. Call only after `otbn_testutils_rsa_modexp_f4_start`. + * + * @param otbn The OTBN context object. + * @param out The encrypted message. + * @param size_bytes The size of all buffers in bytes, i.e. the key/modulus + * length (i.e. 128 for RSA 1024). Valid range: 32..512 in + * 32 byte-steps (i.e. RSA 256 to RSA 4096). + */ +status_t otbn_testutils_rsa_modexp_f4_finalize(dif_otbn_t *otbn, uint8_t *out, + size_t size_bytes); + +/** + * Start a constant-time modular exponentiation. + * + * Computes (in^d) mod n. This corresponds to the core step in decryption or + * signature generation and can be very slow. + * + * The RSA app should be loaded into OTBN with `otbn_testutils_rsa_load` before + * calling this function. + * + * @param otbn The OTBN context object. + * @param modulus The modulus (n). + * @param private_exponent The private exponent (d). + * @param in The encrypted message. + * @param out The decrypted (plaintext) message. + * @param size_bytes The size of all buffers in bytes, i.e. the key/modulus + * length (i.e. 128 for RSA 1024). Valid range: 32..512 in + * 32 byte-steps (i.e. RSA 256 to RSA 4096). + */ +status_t otbn_testutils_rsa_modexp_consttime_start( + dif_otbn_t *otbn, const uint8_t *modulus, const uint8_t *private_exponent, + const uint8_t *in, size_t size_bytes); +/** + * Finish modular exponentiation with the exponent 65537. + * + * Waits for OTBN to complete and reads back the result of modular + * exponentiation. Call only after `otbn_testutils_rsa_modexp_consttime_start`. + * + * @param otbn The OTBN context object. + * @param out The encrypted message. + * @param size_bytes The size of all buffers in bytes, i.e. the key/modulus + * length (i.e. 128 for RSA 1024). Valid range: 32..512 in + * 32 byte-steps (i.e. RSA 256 to RSA 4096). + */ +status_t otbn_testutils_rsa_modexp_consttime_finalize(dif_otbn_t *otbn, + uint8_t *out, + size_t size_bytes); + +#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_OTBN_TESTUTILS_RSA_H_ diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD index d870a708c8044..0594e2dadd1f0 100644 --- a/sw/device/tests/BUILD +++ b/sw/device/tests/BUILD @@ -2223,10 +2223,9 @@ opentitan_test( "//sw/device/lib/runtime:ibex", "//sw/device/lib/runtime:log", "//sw/device/lib/testing:entropy_testutils", - "//sw/device/lib/testing:otbn_testutils", + "//sw/device/lib/testing:otbn_testutils_rsa", "//sw/device/lib/testing:profile", "//sw/device/lib/testing/test_framework:ottf_main", - "//sw/otbn/crypto:rsa", ], ) @@ -3714,8 +3713,6 @@ opentitan_test( "//hw/top_earlgrey/sw/autogen:top_earlgrey", "//sw/device/lib/base:math", "//sw/device/lib/base:multibits", - "//sw/device/lib/crypto/drivers:otbn", - "//sw/device/lib/crypto/impl/rsa:rsa_3072_verify", "//sw/device/lib/dif:adc_ctrl", "//sw/device/lib/dif:aes", "//sw/device/lib/dif:csrng", @@ -3740,11 +3737,11 @@ opentitan_test( "//sw/device/lib/testing:entropy_testutils", "//sw/device/lib/testing:hmac_testutils", "//sw/device/lib/testing:i2c_testutils", + "//sw/device/lib/testing:otbn_testutils_rsa", "//sw/device/lib/testing:pinmux_testutils", "//sw/device/lib/testing:spi_device_testutils", "//sw/device/lib/testing/test_framework:check", "//sw/device/lib/testing/test_framework:ottf_main", - "//sw/device/tests/crypto:rsa_3072_verify_testvectors_hardcoded_header", ], ) diff --git a/sw/device/tests/otbn_rsa_test.c b/sw/device/tests/otbn_rsa_test.c index 3f94dd4b169d4..4dbfbbf6daf88 100644 --- a/sw/device/tests/otbn_rsa_test.c +++ b/sw/device/tests/otbn_rsa_test.c @@ -6,7 +6,7 @@ #include "sw/device/lib/runtime/ibex.h" #include "sw/device/lib/runtime/log.h" #include "sw/device/lib/testing/entropy_testutils.h" -#include "sw/device/lib/testing/otbn_testutils.h" +#include "sw/device/lib/testing/otbn_testutils_rsa.h" #include "sw/device/lib/testing/profile.h" #include "sw/device/lib/testing/test_framework/check.h" #include "sw/device/lib/testing/test_framework/ottf_main.h" @@ -67,20 +67,6 @@ static const bool kTestDecrypt = true; */ static const bool kTestRsaGreater1k = false; -OTBN_DECLARE_APP_SYMBOLS(rsa); -OTBN_DECLARE_SYMBOL_ADDR(rsa, mode); -OTBN_DECLARE_SYMBOL_ADDR(rsa, n_limbs); -OTBN_DECLARE_SYMBOL_ADDR(rsa, inout); -OTBN_DECLARE_SYMBOL_ADDR(rsa, modulus); -OTBN_DECLARE_SYMBOL_ADDR(rsa, exp); - -static const otbn_app_t kOtbnAppRsa = OTBN_APP_T_INIT(rsa); -static const otbn_addr_t kOtbnVarRsaMode = OTBN_ADDR_T_INIT(rsa, mode); -static const otbn_addr_t kOtbnVarRsaNLimbs = OTBN_ADDR_T_INIT(rsa, n_limbs); -static const otbn_addr_t kOtbnVarRsaInOut = OTBN_ADDR_T_INIT(rsa, inout); -static const otbn_addr_t kOtbnVarRsaModulus = OTBN_ADDR_T_INIT(rsa, modulus); -static const otbn_addr_t kOtbnVarRsaExp = OTBN_ADDR_T_INIT(rsa, exp); - enum { kRsa512SizeBytes = 512 / 8, kRsa1024SizeBytes = 1024 / 8, @@ -91,89 +77,6 @@ enum { OTTF_DEFINE_TEST_CONFIG(); -/** - * Encrypts a message with RSA. - * - * @param otbn The OTBN context object. - * @param modulus The modulus (n). - * @param in The plaintext message. - * @param out The encrypted message. - * @param size_bytes The size of all buffers in bytes, i.e. the key/modulus - * length (i.e. 128 for RSA 1024). Valid range: 32..512 in - * 32 byte-steps (i.e. RSA 256 to RSA 4096). - */ -static void rsa_encrypt(dif_otbn_t *otbn, const uint8_t *modulus, - const uint8_t *in, uint8_t *out, size_t size_bytes) { - CHECK(otbn != NULL); - CHECK(size_bytes % 32 == 0); - - uint32_t n_limbs = size_bytes / 32; - CHECK(n_limbs != 0 && n_limbs <= 16); - - // Write input arguments. - uint32_t mode = 1; // mode 1 => encrypt - CHECK_STATUS_OK(otbn_testutils_write_data(otbn, sizeof(uint32_t), &mode, - kOtbnVarRsaMode)); - CHECK_STATUS_OK(otbn_testutils_write_data(otbn, sizeof(uint32_t), &n_limbs, - kOtbnVarRsaNLimbs)); - CHECK_STATUS_OK( - otbn_testutils_write_data(otbn, size_bytes, modulus, kOtbnVarRsaModulus)); - CHECK_STATUS_OK( - otbn_testutils_write_data(otbn, size_bytes, in, kOtbnVarRsaInOut)); - - // Call OTBN to perform operation, and wait for it to complete. - CHECK_STATUS_OK(otbn_testutils_execute(otbn)); - CHECK_STATUS_OK(otbn_testutils_wait_for_done(otbn, kDifOtbnErrBitsNoError)); - - // Read back results. - CHECK_STATUS_OK( - otbn_testutils_read_data(otbn, size_bytes, kOtbnVarRsaInOut, out)); -} - -/** - * Decrypts a message with RSA. - * - * @param otbn The OTBN context object. - * @param modulus The modulus (n). - * @param private_exponent The private exponent (d). - * @param in The encrypted message. - * @param out The decrypted (plaintext) message. - * @param size_bytes The size of all buffers in bytes, i.e. the key/modulus - * length (i.e. 128 for RSA 1024). Valid range: 32..512 in - * 32 byte-steps (i.e. RSA 256 to RSA 4096). - */ -static void rsa_decrypt(dif_otbn_t *otbn, const uint8_t *modulus, - const uint8_t *private_exponent, const uint8_t *in, - uint8_t *out, size_t size_bytes) { - CHECK(otbn != NULL); - CHECK(size_bytes % 32 == 0); - - // Limbs are 256b words. - uint32_t n_limbs = size_bytes / 32; - CHECK(n_limbs != 0 && n_limbs <= 16); - - // Write input arguments. - uint32_t mode = 2; // mode 2 => decrypt - CHECK_STATUS_OK( - otbn_testutils_write_data(otbn, sizeof(mode), &mode, kOtbnVarRsaMode)); - CHECK_STATUS_OK(otbn_testutils_write_data(otbn, sizeof(n_limbs), &n_limbs, - kOtbnVarRsaNLimbs)); - CHECK_STATUS_OK( - otbn_testutils_write_data(otbn, size_bytes, modulus, kOtbnVarRsaModulus)); - CHECK_STATUS_OK(otbn_testutils_write_data(otbn, size_bytes, private_exponent, - kOtbnVarRsaExp)); - CHECK_STATUS_OK( - otbn_testutils_write_data(otbn, size_bytes, in, kOtbnVarRsaInOut)); - - // Call OTBN to perform operation - CHECK_STATUS_OK(otbn_testutils_execute(otbn)); - CHECK_STATUS_OK(otbn_testutils_wait_for_done(otbn, kDifOtbnErrBitsNoError)); - - // Read back results. - CHECK_STATUS_OK( - otbn_testutils_read_data(otbn, size_bytes, kOtbnVarRsaInOut, out)); -} - /** * CHECK()s that the actual data matches the expected data. * @@ -218,13 +121,16 @@ static void rsa_roundtrip(uint32_t size_bytes, const uint8_t *modulus, uint64_t t_start = profile_start(); CHECK_DIF_OK( dif_otbn_init(mmio_region_from_addr(TOP_EARLGREY_OTBN_BASE_ADDR), &otbn)); - CHECK_STATUS_OK(otbn_testutils_load_app(&otbn, kOtbnAppRsa)); + CHECK_STATUS_OK(otbn_testutils_rsa_load(&otbn)); profile_end_and_print(t_start, "Initialization"); // Encrypt LOG_INFO("Encrypting"); t_start = profile_start(); - rsa_encrypt(&otbn, modulus, in, out_encrypted, size_bytes); + CHECK_STATUS_OK( + otbn_testutils_rsa_modexp_f4_start(&otbn, modulus, in, size_bytes)); + CHECK_STATUS_OK( + otbn_testutils_rsa_modexp_f4_finalize(&otbn, out_encrypted, size_bytes)); check_data(out_encrypted, encrypted_expected, size_bytes); profile_end_and_print(t_start, "Encryption"); @@ -232,8 +138,10 @@ static void rsa_roundtrip(uint32_t size_bytes, const uint8_t *modulus, // Decrypt LOG_INFO("Decrypting"); t_start = profile_start(); - rsa_decrypt(&otbn, modulus, private_exponent, encrypted_expected, - out_decrypted, size_bytes); + CHECK_STATUS_OK(otbn_testutils_rsa_modexp_consttime_start( + &otbn, modulus, private_exponent, encrypted_expected, size_bytes)); + CHECK_STATUS_OK(otbn_testutils_rsa_modexp_consttime_finalize( + &otbn, out_decrypted, size_bytes)); check_data(out_decrypted, in, size_bytes); profile_end_and_print(t_start, "Decryption"); } diff --git a/sw/device/tests/power_virus_systemtest.c b/sw/device/tests/power_virus_systemtest.c index 9bd4422fbe38e..4a32b22bdfd4e 100644 --- a/sw/device/tests/power_virus_systemtest.c +++ b/sw/device/tests/power_virus_systemtest.c @@ -5,8 +5,6 @@ #include "hw/ip/aes/model/aes_modes.h" #include "sw/device/lib/base/math.h" #include "sw/device/lib/base/multibits.h" -#include "sw/device/lib/crypto/drivers/otbn.h" -#include "sw/device/lib/crypto/impl/rsa/rsa_3072_verify.h" #include "sw/device/lib/dif/dif_adc_ctrl.h" #include "sw/device/lib/dif/dif_aes.h" #include "sw/device/lib/dif/dif_csrng.h" @@ -31,6 +29,7 @@ #include "sw/device/lib/testing/entropy_testutils.h" #include "sw/device/lib/testing/hmac_testutils.h" #include "sw/device/lib/testing/i2c_testutils.h" +#include "sw/device/lib/testing/otbn_testutils_rsa.h" #include "sw/device/lib/testing/pinmux_testutils.h" #include "sw/device/lib/testing/spi_device_testutils.h" #include "sw/device/lib/testing/test_framework/check.h" @@ -51,12 +50,6 @@ #include "spi_host_regs.h" // Generated. #include "uart_regs.h" // Generated. -// The autogen rule that creates this header creates it in a directory named -// after the rule, then manipulates the include path in the -// cc_compilation_context to include that directory, so the compiler will find -// the version of this file matching the Bazel rule under test. -#include "rsa_3072_verify_testvectors.h" - OTTF_DEFINE_TEST_CONFIG(.enable_concurrency = true, .enable_uart_flow_control = true); @@ -220,9 +213,51 @@ static const uint32_t kKmacDigest[] = { 0x839A69B2, 0xD9E4A27D, 0xFDACFB70, 0xAE3300E5, 0xA2F185A5, 0xC3108570, 0x0888072D, 0x2818BD01, 0x6847FE98, 0x6589FC76}; -static rsa_3072_verify_test_vector_t rsa3072_test_vector; -static rsa_3072_int_t rsa3072_encoded_message; -static rsa_3072_constants_t rsa3072_constants; +// Randomly generated public key modulus with public exponent 65537. +static uint32_t kRsa2KModulus[] = { + 0x40d984b1, 0x3611356d, 0x9eb2f35c, 0x031a892c, 0x16354662, 0x6a260bad, + 0xb2b807d6, 0xb7de7ccb, 0x278492e0, 0x41adab06, 0x9e60110f, 0x1414eeff, + 0x8b80e14e, 0x5eb5ae79, 0x0d98fa5b, 0x58bece1f, 0xcf6bdca8, 0x82f5611f, + 0x351e3869, 0x075005d6, 0xe813fe23, 0xdd967a37, 0x682d1c41, 0x9fdd2d8c, + 0x21bdd5fc, 0x4fc459c7, 0x508c9293, 0x1f9ac759, 0x55aacb04, 0x58389f05, + 0x0d0b00fb, 0x59bb4141, 0x68f9e0bf, 0xc2f1a546, 0x0a71ad19, 0x9c400301, + 0xa4f8ecb9, 0xcdf39538, 0xaabe9cb0, 0xd9f7b2dc, 0x0e8b292d, 0x8ef6c717, + 0x720e9520, 0xb0c6a23e, 0xda1e92b1, 0x8b6b4800, 0x2f25082b, 0x7f2d6711, + 0x426fc94f, 0x9926ba5a, 0x89bd4d2b, 0x977718d5, 0x5a8406be, 0x87d090f3, + 0x639f9975, 0x5948488b, 0x1d3d9cd7, 0x28c7956b, 0xebb97a3e, 0x1edbf4e2, + 0x105cc797, 0x924ec514, 0x146810df, 0xb1ab4a49, +}; + +// Valid PKCS1v1.5 signature of "Test message." using SHA-256 as the hash +// function. +static const uint32_t kRsa2KSignature[] = { + 0xab66c6c7, 0x97effc0a, 0x9869cdba, 0x7b6c09fe, 0x2124d28f, 0x793084b3, + 0x4da24b72, 0x4f6c8659, 0x63e3a27b, 0xbbe8d120, 0x8789190f, 0x1722fe46, + 0x25573178, 0x3accbdb3, 0x1eb7ca00, 0xe8eb40aa, 0x1d3b21a8, 0x9997925e, + 0x1793f81d, 0x12728f54, 0x66e40608, 0x4b1057a0, 0xba433eb3, 0x702c73b2, + 0xa9391740, 0xf838710f, 0xf33cf109, 0x595cee1d, 0x07341be9, 0xcfce52b1, + 0x5b48ba7a, 0xf70e5a0e, 0xdbb98c42, 0x85fd6979, 0xcdb760fc, 0xd2e09553, + 0x70bba417, 0x04e52609, 0xc215420e, 0x2407242e, 0x4f19674b, 0x5d996a9d, + 0xf2fb1d05, 0x88e0fc14, 0xe1a38f0c, 0xd111935d, 0xd23bf5b3, 0xdcd7a882, + 0x0f242315, 0xd7247d51, 0xc247d6ec, 0xe2492739, 0x3dfb115c, 0x031aea7a, + 0xcdcb09c0, 0x29318ddb, 0xd0a10dd8, 0x3307018e, 0xe13c5616, 0x98d4db80, + 0x50692a42, 0x41e94a74, 0x0a6f79eb, 0x1c405c66, +}; + +// PKCS1v1.5 encoding of "Test message." using SHA-256 as the hash function. +static const uint32_t kRsa2KEncodedMessage[] = { + 0x20b50917, 0xdc72a118, 0xd13b02ca, 0x4bc0a4ca, 0x807ce588, 0x43e1f083, + 0x966ee07c, 0xb2da997a, 0x05000420, 0x03040201, 0x86480165, 0x0d060960, + 0x00303130, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff, +}; static const uint8_t kUartMessage[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, @@ -969,14 +1004,7 @@ void configure_pwm(void) { } static void configure_otbn(void) { - rsa3072_test_vector = rsa_3072_verify_tests[0]; - // Only one exponent (65537) is currently supported. - CHECK(rsa3072_test_vector.publicKey.e == 65537); - CHECK_STATUS_OK(rsa_3072_encode_sha256(rsa3072_test_vector.msg, - rsa3072_test_vector.msgLen, - &rsa3072_encoded_message)); - CHECK_STATUS_OK(rsa_3072_compute_constants(&rsa3072_test_vector.publicKey, - &rsa3072_constants)); + CHECK_STATUS_OK(otbn_testutils_rsa_load(&otbn)); } static void check_crypto_blocks_idle(void) { @@ -1194,9 +1222,9 @@ static void max_power_task(void *task_parameters) { mmio_region_write32(i2c_2.base_addr, I2C_CTRL_REG_OFFSET, i2c_ctrl_reg); // Issue OTBN start command. - CHECK_STATUS_OK(rsa_3072_verify_start(&rsa3072_test_vector.signature, - &rsa3072_test_vector.publicKey, - &rsa3072_constants)); + CHECK_STATUS_OK(otbn_testutils_rsa_modexp_f4_start( + &otbn, (unsigned char *)kRsa2KModulus, (unsigned char *)kRsa2KSignature, + sizeof(kRsa2KModulus))); // Enable pattgen. mmio_region_write32(pattgen.base_addr, PATTGEN_CTRL_REG_OFFSET, @@ -1260,9 +1288,12 @@ static void max_power_task(void *task_parameters) { CHECK_ARRAYS_EQ(kmac_digest, kKmacDigest, ARRAYSIZE(kKmacDigest)); // Check OTBN operations. - hardened_bool_t result; - CHECK_STATUS_OK(rsa_3072_verify_finalize(&rsa3072_encoded_message, &result)); - CHECK(result == kHardenedBoolTrue); + uint32_t rsa_recovered_message[ARRAYSIZE(kRsa2KEncodedMessage)]; + CHECK_STATUS_OK(otbn_testutils_rsa_modexp_f4_finalize( + &otbn, (unsigned char *)rsa_recovered_message, + sizeof(rsa_recovered_message))); + CHECK_ARRAYS_EQ(rsa_recovered_message, kRsa2KEncodedMessage, + ARRAYSIZE(kRsa2KEncodedMessage)); // Check UART transactions. uint8_t received_uart_data[kUartFifoDepth]; @@ -1354,11 +1385,8 @@ bool test_main(void) { dif_gpio_output_set_enabled(&gpio, /*pin=*/0, kDifToggleEnabled)); configure_adc_ctrl_to_continuously_sample(); configure_entropy_complex(); - // Note: configuration of OTBN must be done *before* configuration of the - // HMAC, as the cryptolib uses HMAC in SHA256 mode, which will cause HMAC - // computation errors later in this test. - configure_otbn(); CHECK_STATUS_OK(configure_aes()); + configure_otbn(); configure_hmac(); configure_kmac(); configure_uart(&uart_1);