Skip to content
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
33 changes: 33 additions & 0 deletions sw/device/lib/crypto/impl/ecc/curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ OTBN_DECLARE_SYMBOL_ADDR(run_curve25519, MODE_SIGN_STAGE2);
OTBN_DECLARE_SYMBOL_ADDR(run_curve25519, MODE_VERIFY);
OTBN_DECLARE_SYMBOL_ADDR(run_curve25519, MODE_X25519);
OTBN_DECLARE_SYMBOL_ADDR(run_curve25519, MODE_X25519_KEYGEN);
OTBN_DECLARE_SYMBOL_ADDR(run_curve25519, MODE_X25519_SIDELOAD);
OTBN_DECLARE_SYMBOL_ADDR(run_curve25519, MODE_X25519_KEYGEN_SIDELOAD);

static const uint32_t kOtbnCurve25519ModeKeygen =
OTBN_ADDR_T_INIT(run_curve25519, MODE_KEYGEN);
Expand All @@ -97,6 +99,10 @@ static const uint32_t kOtbnCurve25519ModeX25519 =
OTBN_ADDR_T_INIT(run_curve25519, MODE_X25519);
static const uint32_t kOtbnCurve25519ModeX25519Keygen =
OTBN_ADDR_T_INIT(run_curve25519, MODE_X25519_KEYGEN);
static const uint32_t kOtbnCurve25519ModeX25519Sideload =
OTBN_ADDR_T_INIT(run_curve25519, MODE_X25519_SIDELOAD);
static const uint32_t kOtbnCurve25519ModeX25519KeygenSideload =
OTBN_ADDR_T_INIT(run_curve25519, MODE_X25519_KEYGEN_SIDELOAD);

enum {
/*
Expand Down Expand Up @@ -318,6 +324,33 @@ status_t curve25519_x25519_start(
return otbn_execute();
}

status_t curve25519_x25519_keygen_sideload_start(void) {
// Load the Curve25519 app.
HARDENED_TRY(otbn_load_app(kOtbnAppCurve25519));

// Set mode to jump into the hardware sideload keygen path.
uint32_t mode = kOtbnCurve25519ModeX25519KeygenSideload;
HARDENED_TRY(otbn_dmem_write(kCurve25519ModeWords, &mode, kOtbnVarMode));

// Start the OTBN routine.
return otbn_execute();
}

status_t curve25519_x25519_sideload_start(
const uint32_t public_key[kCurve25519PointWords]) {
// Load the Curve25519 app. Fails if OTBN is non-idle.
HARDENED_TRY(otbn_load_app(kOtbnAppCurve25519));

uint32_t mode = kOtbnCurve25519ModeX25519Sideload;
HARDENED_TRY(otbn_dmem_write(kCurve25519ModeWords, &mode, kOtbnVarMode));

HARDENED_TRY(otbn_dmem_write(kCurve25519PointWords, public_key,
kOtbnVarX25519PublicKey));

// Start the OTBN routine.
return otbn_execute();
}

status_t curve25519_x25519_finalize(
uint32_t shared_secret[kCurve25519PointWords]) {
// Spin here waiting for OTBN to complete.
Expand Down
21 changes: 21 additions & 0 deletions sw/device/lib/crypto/impl/ecc/curve25519.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,27 @@ status_t curve25519_x25519_start(
const uint32_t private_key[kCurve25519ScalarWords],
const uint32_t public_key[kCurve25519PointWords]);

/**
* Start the X25519 keygen operation on OTBN using a sideloaded hardware key.
*
* @return Result of the operation.
*/
status_t curve25519_x25519_keygen_sideload_start(void);

/**
* Start the X25519 operation on OTBN using a sideloaded hardware key.
*
* This routine writes the public key and mode to OTBN. It assumes the
* Key Manager has already programmed the private key into OTBN's
* sideload registers (KEY_S0_L and KEY_S1_L).
*
* @param public_key Public key u-coordinate.
* @return Result of the operation.
*/
OT_WARN_UNUSED_RESULT
status_t curve25519_x25519_sideload_start(
const uint32_t public_key[kCurve25519PointWords]);

/**
* Finish an async X25519 key exchange operation on OTBN.
*
Expand Down
74 changes: 49 additions & 25 deletions sw/device/lib/crypto/impl/ecc_curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,22 +702,33 @@ otcrypto_status_t otcrypto_x25519_keygen_async_start(
HARDENED_TRY(
curve25519_private_key_length_check(private_key, kOtcryptoKeyModeX25519));

uint32_t private_key_unmasked[kCurve25519ScalarWords];
uint32_t *share0 = private_key->keyblob;
uint32_t *share1 =
private_key->keyblob + keyblob_share_num_words(private_key->config);
HARDENED_TRY(hardened_add(share0, share1, kCurve25519ScalarWords,
private_key_unmasked));
if (private_key->config.hw_backed == kHardenedBoolTrue) {
HARDENED_CHECK_EQ(launder32(private_key->config.hw_backed),
kHardenedBoolTrue);

HARDENED_TRY(keyblob_sideload_key_otbn(private_key));

return otcrypto_eval_exit(curve25519_x25519_keygen_sideload_start());
} else if (private_key->config.hw_backed == kHardenedBoolFalse) {
uint32_t private_key_unmasked[kCurve25519ScalarWords];
uint32_t *share0 = private_key->keyblob;
uint32_t *share1 =
private_key->keyblob + keyblob_share_num_words(private_key->config);

HARDENED_TRY(ed25519_clamp(private_key_unmasked));
HARDENED_TRY(hardened_add(share0, share1, kCurve25519ScalarWords,
private_key_unmasked));

// Start the OTBN key exchange app.
HARDENED_TRY(curve25519_x25519_keygen_start(private_key_unmasked));
HARDENED_TRY(ed25519_clamp(private_key_unmasked));

// Wipe the unmasked private key.
HARDENED_TRY(hardened_memshred(private_key_unmasked, kCurve25519ScalarWords));
// Start the OTBN key exchange app.
HARDENED_TRY(curve25519_x25519_keygen_start(private_key_unmasked));

return otcrypto_eval_exit(OTCRYPTO_OK);
// Wipe the unmasked private key.
return otcrypto_eval_exit(
hardened_memshred(private_key_unmasked, kCurve25519ScalarWords));
}

return OTCRYPTO_BAD_ARGS;
}

otcrypto_status_t otcrypto_x25519_keygen_async_finalize(
Expand All @@ -737,23 +748,36 @@ otcrypto_status_t otcrypto_x25519_async_start(
HARDENED_TRY(
curve25519_public_key_length_check(public_key, kOtcryptoKeyModeX25519));

uint32_t private_key_unmasked[kCurve25519ScalarWords];
// Unmask the private key.
uint32_t *share0 = private_key->keyblob;
uint32_t *share1 =
private_key->keyblob + keyblob_share_num_words(private_key->config);
HARDENED_TRY(hardened_add(share0, share1, kCurve25519ScalarWords,
private_key_unmasked));
if (private_key->config.hw_backed == kHardenedBoolTrue) {
HARDENED_CHECK_EQ(launder32(private_key->config.hw_backed),
kHardenedBoolTrue);

HARDENED_TRY(ed25519_clamp(private_key_unmasked));
HARDENED_TRY(keyblob_sideload_key_otbn(private_key));

// Start the OTBN key exchange app.
HARDENED_TRY(curve25519_x25519_start(private_key_unmasked, public_key->key));
return otcrypto_eval_exit(
curve25519_x25519_sideload_start(public_key->key));

// Wipe the unmasked private key.
HARDENED_TRY(hardened_memshred(private_key_unmasked, kCurve25519ScalarWords));
} else if (private_key->config.hw_backed == kHardenedBoolFalse) {
uint32_t private_key_unmasked[kCurve25519ScalarWords];

return otcrypto_eval_exit(OTCRYPTO_OK);
// Unmask the private key
uint32_t *share0 = private_key->keyblob;
uint32_t *share1 =
private_key->keyblob + keyblob_share_num_words(private_key->config);
HARDENED_TRY(hardened_add(share0, share1, kCurve25519ScalarWords,
private_key_unmasked));
HARDENED_TRY(ed25519_clamp(private_key_unmasked));

// Start the standard OTBN key exchange app
HARDENED_TRY(
curve25519_x25519_start(private_key_unmasked, public_key->key));

// Wipe the unmasked private key from CPU memory and return
return otcrypto_eval_exit(
hardened_memshred(private_key_unmasked, kCurve25519ScalarWords));
}

return OTCRYPTO_BAD_ARGS;
}

otcrypto_status_t otcrypto_x25519_async_finalize(
Expand Down
8 changes: 4 additions & 4 deletions sw/device/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2289,7 +2289,7 @@ opentitan_test(
"//sw/device/lib/testing/test_framework:ottf_alerts",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:retention_sram",
"//sw/otbn/crypto:x25519_sideload",
"//sw/otbn/crypto:run_curve25519",
],
)

Expand Down Expand Up @@ -2319,7 +2319,7 @@ opentitan_test(
"//sw/device/lib/testing:sram_ctrl_testutils",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:retention_sram",
"//sw/otbn/crypto:x25519_sideload",
"//sw/otbn/crypto:run_curve25519",
],
)

Expand Down Expand Up @@ -2522,7 +2522,7 @@ opentitan_test(
"//sw/device/lib/testing:otbn_testutils",
"//sw/device/lib/testing/test_framework:ottf_alerts",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/otbn/crypto:x25519_sideload",
"//sw/otbn/crypto:run_curve25519",
],
)

Expand Down Expand Up @@ -2553,7 +2553,7 @@ opentitan_test(
"//sw/device/lib/testing:keymgr_testutils",
"//sw/device/lib/testing:otbn_testutils",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/otbn/crypto:x25519_sideload",
"//sw/otbn/crypto:run_curve25519",
],
)

Expand Down
27 changes: 27 additions & 0 deletions sw/device/tests/crypto/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,33 @@ opentitan_test(
],
)

opentitan_test(
name = "x25519_sideload_functest",
srcs = ["x25519_sideload_functest.c"],
exec_env = CRYPTOTEST_EXEC_ENVS,
verilator = verilator_params(
timeout = "eternal",
# This test can take > 60 minutes, so mark it manual as it shouldn't
# run in CI/nightlies.
tags = ["manual"],
),
deps = [
"//sw/device/lib/base:hardened_memory",
"//sw/device/lib/crypto/drivers:otbn",
"//sw/device/lib/crypto/impl:config",
"//sw/device/lib/crypto/impl:ecc_curve25519",
"//sw/device/lib/crypto/impl:entropy_src",
"//sw/device/lib/crypto/impl:integrity",
"//sw/device/lib/crypto/impl:key_transport",
"//sw/device/lib/crypto/impl:keyblob",
"//sw/device/lib/crypto/impl:sha2",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing:entropy_testutils",
"//sw/device/lib/testing:keymgr_testutils",
"//sw/device/lib/testing/test_framework:ottf_main",
],
)

opentitan_test(
name = "entropy_src_functest",
srcs = ["entropy_src_functest.c"],
Expand Down
Loading
Loading