Skip to content

Commit 8c961f9

Browse files
committed
keystore: remove _get_prv
It is now in `bitbox02_rust::keystore`. The remaining use of it in keystore.c is to derive the private key at a keypath, which we can do by exposing the Rust function we have for that to C. With this commit, the last use of libwally for bip32 derivation is gone.
1 parent 0062964 commit 8c961f9

File tree

3 files changed

+40
-59
lines changed

3 files changed

+40
-59
lines changed

src/keystore.c

Lines changed: 18 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -522,41 +522,6 @@ bool keystore_bip39_mnemonic_to_seed(const char* mnemonic, uint8_t* seed_out, si
522522
return bip39_mnemonic_to_bytes(NULL, mnemonic, seed_out, 32, seed_len_out) == WALLY_OK;
523523
}
524524

525-
static bool _get_xprv(const uint32_t* keypath, const size_t keypath_len, struct ext_key* xprv_out)
526-
{
527-
if (keystore_is_locked()) {
528-
return false;
529-
}
530-
531-
uint8_t bip39_seed[64] = {0};
532-
UTIL_CLEANUP_64(bip39_seed);
533-
if (!keystore_copy_bip39_seed(bip39_seed)) {
534-
return false;
535-
}
536-
struct ext_key xprv_master __attribute__((__cleanup__(keystore_zero_xkey))) = {0};
537-
538-
if (bip32_key_from_seed(
539-
bip39_seed, BIP32_ENTROPY_LEN_512, BIP32_VER_MAIN_PRIVATE, 0, &xprv_master) !=
540-
WALLY_OK) {
541-
return false;
542-
}
543-
util_zero(bip39_seed, sizeof(bip39_seed));
544-
if (keypath_len == 0) {
545-
*xprv_out = xprv_master;
546-
} else if (
547-
bip32_key_from_parent_path(
548-
&xprv_master, keypath, keypath_len, BIP32_FLAG_KEY_PRIVATE, xprv_out) != WALLY_OK) {
549-
keystore_zero_xkey(xprv_out);
550-
return false;
551-
}
552-
return true;
553-
}
554-
555-
void keystore_zero_xkey(struct ext_key* xkey)
556-
{
557-
util_zero(xkey, sizeof(struct ext_key));
558-
}
559-
560525
bool keystore_get_bip39_word(uint16_t idx, char** word_out)
561526
{
562527
return bip39_get_word(NULL, idx, word_out) == WALLY_OK;
@@ -569,18 +534,17 @@ bool keystore_secp256k1_nonce_commit(
569534
const uint8_t* host_commitment,
570535
uint8_t* signer_commitment_out)
571536
{
572-
struct ext_key xprv __attribute__((__cleanup__(keystore_zero_xkey))) = {0};
573-
if (!_get_xprv(keypath, keypath_len, &xprv)) {
537+
uint8_t private_key[32] = {0};
538+
UTIL_CLEANUP_32(private_key);
539+
if (!rust_secp256k1_get_private_key(
540+
keypath, keypath_len, rust_util_bytes_mut(private_key, sizeof(private_key)))) {
574541
return false;
575542
}
543+
576544
const secp256k1_context* ctx = wally_get_secp_context();
577545
secp256k1_ecdsa_s2c_opening signer_commitment;
578546
if (!secp256k1_ecdsa_anti_exfil_signer_commit(
579-
ctx,
580-
&signer_commitment,
581-
msg32,
582-
xprv.priv_key + 1, // first byte is 0,
583-
host_commitment)) {
547+
ctx, &signer_commitment, msg32, private_key, host_commitment)) {
584548
return false;
585549
}
586550

@@ -601,19 +565,17 @@ bool keystore_secp256k1_sign(
601565
if (keystore_is_locked()) {
602566
return false;
603567
}
604-
struct ext_key xprv __attribute__((__cleanup__(keystore_zero_xkey))) = {0};
605-
if (!_get_xprv(keypath, keypath_len, &xprv)) {
568+
uint8_t private_key[32] = {0};
569+
UTIL_CLEANUP_32(private_key);
570+
if (!rust_secp256k1_get_private_key(
571+
keypath, keypath_len, rust_util_bytes_mut(private_key, sizeof(private_key)))) {
606572
return false;
607573
}
574+
608575
const secp256k1_context* ctx = wally_get_secp_context();
609576
secp256k1_ecdsa_signature secp256k1_sig = {0};
610577
if (!secp256k1_anti_exfil_sign(
611-
ctx,
612-
&secp256k1_sig,
613-
msg32,
614-
xprv.priv_key + 1, // first byte is 0
615-
host_nonce32,
616-
recid_out)) {
578+
ctx, &secp256k1_sig, msg32, private_key, host_nonce32, recid_out)) {
617579
return false;
618580
}
619581
if (!secp256k1_ecdsa_signature_serialize_compact(ctx, sig_compact_out, &secp256k1_sig)) {
@@ -687,13 +649,15 @@ static bool _schnorr_keypair(
687649
if (keystore_is_locked()) {
688650
return false;
689651
}
690-
struct ext_key xprv __attribute__((__cleanup__(keystore_zero_xkey))) = {0};
691-
if (!_get_xprv(keypath, keypath_len, &xprv)) {
652+
uint8_t private_key[32] = {0};
653+
UTIL_CLEANUP_32(private_key);
654+
if (!rust_secp256k1_get_private_key(
655+
keypath, keypath_len, rust_util_bytes_mut(private_key, sizeof(private_key)))) {
692656
return false;
693657
}
694-
const uint8_t* secret_key = xprv.priv_key + 1; // first byte is 0;
658+
695659
const secp256k1_context* ctx = wally_get_secp_context();
696-
if (!secp256k1_keypair_create(ctx, keypair_out, secret_key)) {
660+
if (!secp256k1_keypair_create(ctx, keypair_out, private_key)) {
697661
return false;
698662
}
699663
if (tweak != NULL) {

src/keystore.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,6 @@ USE_RESULT bool keystore_bip39_mnemonic_to_seed(
146146
uint8_t* seed_out,
147147
size_t* seed_len_out);
148148

149-
/**
150-
* Safely destroy a xpub or xprv.
151-
*/
152-
void keystore_zero_xkey(struct ext_key* xkey);
153-
154149
/**
155150
* Returns the pointer to a word in the word list for the given index.
156151
* @param[in] idx The index into the word list. Must be smaller than BIP39_WORDLIST_LEN.

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,28 @@ pub extern "C" fn rust_cipher_decrypt(
116116
}
117117
}
118118

119+
/// # Safety
120+
///
121+
/// keypath pointer has point to a buffer of length `keypath_len` uint32 elements.
122+
#[cfg(feature = "firmware")]
123+
#[no_mangle]
124+
pub unsafe extern "C" fn rust_secp256k1_get_private_key(
125+
keypath: *const u32,
126+
keypath_len: usize,
127+
mut out: crate::util::BytesMut,
128+
) -> bool {
129+
match bitbox02_rust::keystore::secp256k1_get_private_key(core::slice::from_raw_parts(
130+
keypath,
131+
keypath_len,
132+
)) {
133+
Ok(private_key) => {
134+
out.as_mut().copy_from_slice(&private_key);
135+
true
136+
}
137+
Err(()) => false,
138+
}
139+
}
140+
119141
/// # Safety
120142
///
121143
/// The pointer `data` must point to a buffer of length `len`.

0 commit comments

Comments
 (0)