-
Notifications
You must be signed in to change notification settings - Fork 792
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[crypto] Factor out OTBN RSA testing utilities.
Use the same testing library for otbn_rsa_test and power_virus_systemtest. The testing library bypasses everything other than the core OTBN operation, which is helpful for tests that may have other blocks in different configurations than the cryptolib expects (e.g. entropy or HMAC). Signed-off-by: Jade Philipoom <[email protected]>
- Loading branch information
1 parent
87873f7
commit 5bcd7d0
Showing
6 changed files
with
299 additions
and
136 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.