Skip to content

Commit 6f234ba

Browse files
committed
Merge branch 'port-antiklepto-test'
2 parents 0dc87c7 + 74c7256 commit 6f234ba

File tree

9 files changed

+109
-140
lines changed

9 files changed

+109
-140
lines changed

src/keystore.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ bool keystore_copy_seed(uint8_t* seed_out, size_t* length_out)
7878
"keystore_retained_seed_access_in",
7979
"keystore_retained_seed_access_out",
8080
rust_util_bytes_mut(
81-
retained_seed_encryption_key,
82-
sizeof(retained_seed_encryption_key)))) {
81+
retained_seed_encryption_key, sizeof(retained_seed_encryption_key)))) {
8382
return false;
8483
}
8584
size_t len = _retained_seed_encrypted_len - 48;
@@ -112,8 +111,7 @@ bool keystore_copy_bip39_seed(uint8_t* bip39_seed_out)
112111
"keystore_retained_bip39_seed_access_in",
113112
"keystore_retained_bip39_seed_access_out",
114113
rust_util_bytes_mut(
115-
retained_bip39_seed_encryption_key,
116-
sizeof(retained_bip39_seed_encryption_key)))) {
114+
retained_bip39_seed_encryption_key, sizeof(retained_bip39_seed_encryption_key)))) {
117115
return false;
118116
}
119117
size_t len = _retained_bip39_seed_encrypted_len - 48;
@@ -295,8 +293,7 @@ USE_RESULT static bool _retain_bip39_seed(const uint8_t* bip39_seed)
295293
"keystore_retained_bip39_seed_access_in",
296294
"keystore_retained_bip39_seed_access_out",
297295
rust_util_bytes_mut(
298-
retained_bip39_seed_encryption_key,
299-
sizeof(retained_bip39_seed_encryption_key)))) {
296+
retained_bip39_seed_encryption_key, sizeof(retained_bip39_seed_encryption_key)))) {
300297
return false;
301298
}
302299
size_t len = sizeof(_retained_bip39_seed_encrypted);
@@ -542,20 +539,15 @@ bool keystore_secp256k1_sign(
542539
}
543540

544541
#ifdef TESTING
545-
void keystore_mock_unlocked(const uint8_t* seed, size_t seed_len, const uint8_t* bip39_seed)
542+
void keystore_mock_unlocked(const uint8_t* seed, size_t seed_len)
546543
{
547544
_is_unlocked_device = seed != NULL;
548545
if (seed != NULL) {
549546
if (_retain_seed(seed, seed_len) != KEYSTORE_OK) {
550547
Abort("couldn't retain seed");
551548
}
552549
}
553-
_is_unlocked_bip39 = bip39_seed != NULL;
554-
if (bip39_seed != NULL) {
555-
if (!_retain_bip39_seed(bip39_seed)) {
556-
Abort("couldn't retain bip39 seed");
557-
}
558-
}
550+
_is_unlocked_bip39 = false;
559551
}
560552

561553
const uint8_t* keystore_test_get_retained_seed_encrypted(size_t* len_out)

src/keystore.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ USE_RESULT bool keystore_secp256k1_sign(
188188
/**
189189
* convenience to mock the keystore state (locked, seed) in tests.
190190
*/
191-
void keystore_mock_unlocked(const uint8_t* seed, size_t seed_len, const uint8_t* bip39_seed);
191+
void keystore_mock_unlocked(const uint8_t* seed, size_t seed_len);
192192

193193
const uint8_t* keystore_test_get_retained_seed_encrypted(size_t* len_out);
194194
const uint8_t* keystore_test_get_retained_bip39_seed_encrypted(size_t* len_out);

src/rust/bitbox02-rust/src/hww/api/bitcoin/signtx.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2695,8 +2695,8 @@ mod tests {
26952695
let host_nonce = hex!("abababababababababababababababababababababababababababababababab");
26962696
// The host nonce commitment value does not impact this test, but an invalid commitment
26972697
// would fail the antiklepto signature check on the host. The host check is skipped here and
2698-
// tested in test_keystore_antiklepto.c. That the host nonce was included in the sig is
2699-
// tested by the siganture fixture test below.x
2698+
// tested in keystore::tests::test_secp256k1_antiklepto_protocol. That the host nonce was included in the sig is
2699+
// tested by the signature fixture test below.
27002700
let host_nonce_commitment = pb::AntiKleptoHostNonceCommitment {
27012701
commitment: bitbox02::secp256k1::ecdsa_anti_exfil_host_commit(SECP256K1, &host_nonce)
27022702
.unwrap(),

src/rust/bitbox02-rust/src/keystore.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,67 @@ mod tests {
12071207
);
12081208
}
12091209

1210+
#[test]
1211+
fn test_secp256k1_antiklepto_protocol() {
1212+
mock_unlocked();
1213+
1214+
let mut keypath = [84 + HARDENED, 1 + HARDENED, 0 + HARDENED, 0, 0];
1215+
let mut msg = [0x23u8; 32];
1216+
let mut host_nonce = [0x55u8; 32];
1217+
1218+
for index in 0..3 {
1219+
keypath[4] = index;
1220+
msg[0] = index as u8;
1221+
host_nonce[0] = index as u8;
1222+
1223+
// Protocol steps are described in secp256k1/include/secp256k1_ecdsa_s2c.h under
1224+
// "ECDSA Anti-Klepto Protocol".
1225+
1226+
// Protocol step 1.
1227+
let host_commitment_vec =
1228+
bitbox02::secp256k1::ecdsa_anti_exfil_host_commit(SECP256K1, &host_nonce).unwrap();
1229+
let host_commitment: [u8; 32] = host_commitment_vec.try_into().unwrap();
1230+
1231+
// Get pubkey at keypath.
1232+
let private_key = secp256k1_get_private_key(&keypath).unwrap();
1233+
let private_key_bytes: [u8; 32] = private_key.as_slice().try_into().unwrap();
1234+
let secret_key = secp256k1::SecretKey::from_slice(&private_key_bytes).unwrap();
1235+
let public_key = secret_key.public_key(SECP256K1);
1236+
1237+
// Commit - protocol step 2.
1238+
let signer_commitment =
1239+
secp256k1_nonce_commit(&private_key_bytes, &msg, &host_commitment).unwrap();
1240+
// Protocol step 3: host_nonce sent from host to signer to be used in step 4.
1241+
// Sign - protocol step 4.
1242+
let sign_result = secp256k1_sign(&private_key_bytes, &msg, &host_nonce).unwrap();
1243+
1244+
let signature =
1245+
secp256k1::ecdsa::Signature::from_compact(&sign_result.signature).unwrap();
1246+
// Protocol step 5: host verification.
1247+
bitbox02::secp256k1::anti_exfil_host_verify(
1248+
SECP256K1,
1249+
&signature,
1250+
&msg,
1251+
&public_key,
1252+
&host_nonce,
1253+
&signer_commitment,
1254+
)
1255+
.unwrap();
1256+
1257+
let message = secp256k1::Message::from_digest_slice(&msg).unwrap();
1258+
let recoverable_sig = secp256k1::ecdsa::RecoverableSignature::from_compact(
1259+
&sign_result.signature,
1260+
secp256k1::ecdsa::RecoveryId::from_i32(sign_result.recid as i32).unwrap(),
1261+
)
1262+
.unwrap();
1263+
assert!(
1264+
SECP256K1
1265+
.verify_ecdsa(&message, &recoverable_sig.to_standard(), &public_key)
1266+
.is_ok()
1267+
);
1268+
}
1269+
}
1270+
12101271
#[test]
12111272
fn test_secp256k1_schnorr_sign() {
12121273
mock_unlocked_using_mnemonic(

src/rust/bitbox02-sys/build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ const ALLOWLIST_TYPES: &[&str] = &[
5151
"confirm_params_t",
5252
"trinary_input_string_params_t",
5353
"securechip_error_t",
54+
"secp256k1_ecdsa_s2c_opening",
55+
"secp256k1_ecdsa_signature",
56+
"secp256k1_pubkey",
5457
];
5558

5659
const ALLOWLIST_FNS: &[&str] = &[
@@ -141,6 +144,8 @@ const ALLOWLIST_FNS: &[&str] = &[
141144
"sd_write_bin",
142145
"sdcard_create",
143146
"secp256k1_ecdsa_anti_exfil_host_commit",
147+
"secp256k1_ecdsa_s2c_opening_parse",
148+
"secp256k1_anti_exfil_host_verify",
144149
"securechip_attestation_sign",
145150
"securechip_kdf",
146151
"securechip_model",

src/rust/bitbox02/src/keystore.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,5 @@ pub fn _encrypt_and_store_seed(seed: &[u8], password: &str) -> Result<(), Error>
225225

226226
#[cfg(feature = "testing")]
227227
pub fn mock_unlocked(seed: &[u8]) {
228-
unsafe {
229-
bitbox02_sys::keystore_mock_unlocked(seed.as_ptr(), seed.len() as _, core::ptr::null())
230-
}
228+
unsafe { bitbox02_sys::keystore_mock_unlocked(seed.as_ptr(), seed.len() as _) }
231229
}

src/rust/bitbox02/src/secp256k1.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,40 @@ pub fn ecdsa_anti_exfil_host_commit(secp: &Secp256k1<All>, rand32: &[u8]) -> Res
3232
}
3333
}
3434

35+
#[cfg(feature = "testing")]
36+
pub fn anti_exfil_host_verify(
37+
secp: &Secp256k1<All>,
38+
signature: &bitcoin::secp256k1::ecdsa::Signature,
39+
msg: &[u8; 32],
40+
pubkey: &bitcoin::secp256k1::PublicKey,
41+
host_nonce: &[u8; 32],
42+
signer_commitment: &[u8; 33],
43+
) -> Result<(), ()> {
44+
let mut opening = core::mem::MaybeUninit::<bitbox02_sys::secp256k1_ecdsa_s2c_opening>::uninit();
45+
let parse_res = unsafe {
46+
bitbox02_sys::secp256k1_ecdsa_s2c_opening_parse(
47+
secp.ctx().as_ptr().cast(),
48+
opening.as_mut_ptr(),
49+
signer_commitment.as_ptr(),
50+
)
51+
};
52+
if parse_res != 1 {
53+
return Err(());
54+
}
55+
let opening = unsafe { opening.assume_init() };
56+
let verify_res = unsafe {
57+
bitbox02_sys::secp256k1_anti_exfil_host_verify(
58+
secp.ctx().as_ptr().cast(),
59+
signature.as_c_ptr() as *const bitbox02_sys::secp256k1_ecdsa_signature,
60+
msg.as_ptr(),
61+
pubkey.as_c_ptr() as *const bitbox02_sys::secp256k1_pubkey,
62+
host_nonce.as_ptr(),
63+
&opening,
64+
)
65+
};
66+
if verify_res == 1 { Ok(()) } else { Err(()) }
67+
}
68+
3569
pub fn dleq_prove(
3670
secp: &Secp256k1<All>,
3771
sk: &[u8; 32],

test/unit-test/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ target_include_directories(mocks
4949
set(TEST_LIST
5050
cleanup
5151
"-Wl,--wrap=util_cleanup_32"
52-
keystore_antiklepto
53-
""
5452
gestures
5553
""
5654
random

test/unit-test/test_keystore_antiklepto.c

Lines changed: 0 additions & 119 deletions
This file was deleted.

0 commit comments

Comments
 (0)