Skip to content

Commit 8ce40a7

Browse files
committed
securechip: replace sign interface function with native Rust impl
The securechip unsafe sign key slot in the ATECC608 was only used as an alternative to adding firmware code for signing using hte NIST P-256 curve. The Optiga Trust M does not support the same functionality - one can't write a private key to this chip and extract the corresponding pubkey. Since we want one interface for both chips, we remove the unsafe sign functionality and replace it with the Rust p256 crate. It is only used in U2F. As an alternative, one could use the native MCU PUKCC/PUKCL feature to derive a pubkey and sign using this curve (see pukcc.c), but I could not get it to work. Using the Rust crate is much easier to implement / use. This adds 10592 bytes of binary space. If we need it back, we should try again to use PUKCC instead and offload these operations to the MCU.
1 parent fe8ee46 commit 8ce40a7

File tree

366 files changed

+58802
-1683
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

366 files changed

+58802
-1683
lines changed

src/atecc/atecc.c

Lines changed: 2 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ typedef enum {
3434
ATECC_SLOT_ROLLKEY = 3,
3535
ATECC_SLOT_KDF = 4,
3636
ATECC_SLOT_ATTESTATION = 5,
37-
ATECC_SLOT_ECC_UNSAFE_SIGN = 6,
37+
// Deprecated as the equivalent does not exist in the Optiga chip.
38+
ATECC_SLOT_ECC_UNSAFE_SIGN_DEPRECATED = 6,
3839
ATECC_SLOT_DATA0 = 9,
3940
// The other slots are currently not in use.
4041
} atecc_slot_t;
@@ -631,74 +632,6 @@ bool atecc_random(uint8_t* rand_out)
631632
return false;
632633
}
633634

634-
// Length of priv_key must be 32 bytes
635-
static bool _ecc_write_priv_key(const uint8_t* priv_key)
636-
{
637-
uint8_t atca_priv_key[36] = {0};
638-
memcpy(atca_priv_key + 4, priv_key, 32);
639-
640-
uint8_t encryption_key[32] = {0};
641-
UTIL_CLEANUP_32(encryption_key);
642-
_interface_functions->get_encryption_key(encryption_key);
643-
644-
uint8_t nonce_contribution[32] = {0};
645-
UTIL_CLEANUP_32(nonce_contribution);
646-
_interface_functions->random_32_bytes(nonce_contribution);
647-
#if NONCE_NUMIN_SIZE > 32
648-
#error "size mismatch"
649-
#endif
650-
651-
ATCA_STATUS result = _authorize_key();
652-
if (result != ATCA_SUCCESS) {
653-
return false;
654-
}
655-
656-
return atcab_priv_write(
657-
ATECC_SLOT_ECC_UNSAFE_SIGN,
658-
atca_priv_key,
659-
ATECC_SLOT_ENCRYPTION_KEY,
660-
encryption_key,
661-
nonce_contribution) == ATCA_SUCCESS;
662-
}
663-
664-
bool atecc_ecc_generate_public_key(uint8_t* priv_key, uint8_t* pub_key)
665-
{
666-
if (!_ecc_write_priv_key(priv_key)) {
667-
return false;
668-
}
669-
670-
ATCA_STATUS result = _authorize_key();
671-
if (result != ATCA_SUCCESS) {
672-
return false;
673-
}
674-
675-
result = atcab_get_pubkey(ATECC_SLOT_ECC_UNSAFE_SIGN, pub_key);
676-
if (result != ATCA_SUCCESS) {
677-
return false;
678-
}
679-
680-
return true;
681-
}
682-
683-
bool atecc_ecc_unsafe_sign(const uint8_t* priv_key, const uint8_t* msg, uint8_t* sig)
684-
{
685-
if (!_ecc_write_priv_key(priv_key)) {
686-
return false;
687-
}
688-
689-
ATCA_STATUS result = _authorize_key();
690-
if (result != ATCA_SUCCESS) {
691-
return false;
692-
}
693-
694-
result = atcab_sign(ATECC_SLOT_ECC_UNSAFE_SIGN, msg, sig);
695-
if (result != ATCA_SUCCESS) {
696-
return false;
697-
}
698-
699-
return true;
700-
}
701-
702635
#if APP_U2F == 1 || FACTORYSETUP == 1
703636
// Read a "standard" sized block from a data slot (must be 32 bytes)
704637
static bool _read_data_slot_block(uint8_t* bytes, uint16_t slot, uint8_t block)

src/atecc/atecc.h

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -98,24 +98,6 @@ USE_RESULT bool atecc_monotonic_increments_remaining(uint32_t* remaining_out);
9898
*/
9999
USE_RESULT bool atecc_random(uint8_t* rand_out);
100100

101-
/**
102-
* Generates the matching public key to the provided private key. Will put private key in unsafe
103-
* ECC slot.
104-
* @param[in] priv_key Private key (32 bytes).
105-
* @param[out] pub_key Public key. Format will be the X and Y coordinates in big-endian (64 bytes).
106-
* @return True if success
107-
*/
108-
USE_RESULT bool atecc_ecc_generate_public_key(uint8_t* priv_key, uint8_t* pub_key);
109-
110-
/**
111-
* Sign hash with private key. Will put private key in unsafe ECC slot.
112-
* @param[in] priv_key Private key to use for signing (32 bytes)
113-
* @param[in] msg Message to sign (32 bytes)
114-
* @param[out] sig Signature (64 bytes)
115-
* @return True if success
116-
*/
117-
USE_RESULT bool atecc_ecc_unsafe_sign(const uint8_t* priv_key, const uint8_t* msg, uint8_t* sig);
118-
119101
#if APP_U2F == 1 || FACTORYSETUP == 1
120102
/**
121103
* Set the u2f counter to `counter`. Should only be used for initialization.

src/rust/Cargo.lock

Lines changed: 136 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rust/bitbox02-rust-c/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ bitbox02-rust = { path = "../bitbox02-rust", optional = true }
2828
bitbox02 = { path = "../bitbox02", optional = true }
2929
bitbox02-noise = { path = "../bitbox02-noise", optional = true }
3030
util = { path = "../util" }
31+
p256 = { version = "0.13.2", default-features = false, features = ["arithmetic", "ecdsa"], optional = true }
3132
hex = { workspace = true }
3233
sha2 = { workspace = true, optional = true }
3334
sha3 = { workspace = true, optional = true }
@@ -62,7 +63,7 @@ target-c-unit-tests = [
6263
platform-bitbox02 = []
6364

6465
bootloader = []
65-
firmware = ["bitbox02-rust", "bitbox02", "bitbox02-noise", "sha2"]
66+
firmware = ["bitbox02-rust", "bitbox02", "bitbox02-noise", "sha2", "p256"]
6667

6768
# Only to be enabled in Rust unit tests.
6869
testing = ["bitbox02-rust/testing", "bitbox02/testing"]

src/rust/bitbox02-rust-c/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ mod async_usb;
3131
#[cfg(feature = "firmware")]
3232
mod noise;
3333
#[cfg(feature = "firmware")]
34+
mod p256;
35+
#[cfg(feature = "firmware")]
3436
mod sha2;
3537
#[cfg(feature = "firmware")]
3638
mod workflow;

0 commit comments

Comments
 (0)