Skip to content

Commit 4aea522

Browse files
committed
keystore: split retaining/deleting seeds into functions
Intermediate commit for clarity. These two functions can then be changed to not keep the seed in RAM in plantext, but to encrypt them.
1 parent 7901849 commit 4aea522

File tree

2 files changed

+45
-28
lines changed

2 files changed

+45
-28
lines changed

src/keystore.c

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,6 @@ static bool _is_unlocked_bip39 = false;
4747
// Must be defined if _is_unlocked is true. ONLY ACCESS THIS WITH _copy_bip39_seed().
4848
static uint8_t _retained_bip39_seed[64] = {0};
4949

50-
#ifdef TESTING
51-
void keystore_mock_unlocked(const uint8_t* seed, size_t seed_len, const uint8_t* bip39_seed)
52-
{
53-
_is_unlocked_device = seed != NULL;
54-
if (seed != NULL) {
55-
_seed_length = seed_len;
56-
memcpy(_retained_seed, seed, seed_len);
57-
}
58-
_is_unlocked_bip39 = bip39_seed != NULL;
59-
if (bip39_seed != NULL) {
60-
memcpy(_retained_bip39_seed, bip39_seed, sizeof(_retained_bip39_seed));
61-
}
62-
}
63-
#endif
64-
6550
/**
6651
* We allow seeds of 16, 24 or 32 bytes.
6752
*/
@@ -319,6 +304,25 @@ static void _free_string(char** str)
319304
wally_free_string(*str);
320305
}
321306

307+
static void _retain_seed(const uint8_t* seed, size_t seed_len)
308+
{
309+
memcpy(_retained_seed, seed, seed_len);
310+
_seed_length = seed_len;
311+
}
312+
313+
USE_RESULT static bool _retain_bip39_seed(const uint8_t* bip39_seed)
314+
{
315+
memcpy(_retained_bip39_seed, bip39_seed, sizeof(_retained_bip39_seed));
316+
return true;
317+
}
318+
319+
static void _delete_retained_seeds(void)
320+
{
321+
_seed_length = 0;
322+
util_zero(_retained_seed, sizeof(_retained_seed));
323+
util_zero(_retained_bip39_seed, sizeof(_retained_bip39_seed));
324+
}
325+
322326
keystore_error_t keystore_unlock(
323327
const char* password,
324328
uint8_t* remaining_attempts_out,
@@ -354,8 +358,7 @@ keystore_error_t keystore_unlock(
354358
Abort("Seed has suddenly changed. This should never happen.");
355359
}
356360
} else {
357-
memcpy(_retained_seed, seed, seed_len);
358-
_seed_length = seed_len;
361+
_retain_seed(seed, seed_len);
359362
_is_unlocked_device = true;
360363
}
361364
bitbox02_smarteeprom_reset_unlock_attempts();
@@ -396,7 +399,9 @@ bool keystore_unlock_bip39(const char* mnemonic_passphrase)
396399
mnemonic, mnemonic_passphrase, bip39_seed, sizeof(bip39_seed), NULL) != WALLY_OK) {
397400
return false;
398401
}
399-
memcpy(_retained_bip39_seed, bip39_seed, sizeof(bip39_seed));
402+
if (!_retain_bip39_seed(bip39_seed)) {
403+
return false;
404+
}
400405
_is_unlocked_bip39 = true;
401406
return true;
402407
}
@@ -405,9 +410,7 @@ void keystore_lock(void)
405410
{
406411
_is_unlocked_device = false;
407412
_is_unlocked_bip39 = false;
408-
_seed_length = 0;
409-
util_zero(_retained_seed, sizeof(_retained_seed));
410-
util_zero(_retained_bip39_seed, sizeof(_retained_bip39_seed));
413+
_delete_retained_seeds();
411414
}
412415

413416
bool keystore_is_locked(void)
@@ -789,3 +792,17 @@ bool keystore_secp256k1_schnorr_bip86_sign(
789792
}
790793
return secp256k1_schnorrsig_verify(ctx, sig64_out, msg32, 32, &pubkey) == 1;
791794
}
795+
796+
#ifdef TESTING
797+
void keystore_mock_unlocked(const uint8_t* seed, size_t seed_len, const uint8_t* bip39_seed)
798+
{
799+
_is_unlocked_device = seed != NULL;
800+
if (seed != NULL) {
801+
_retain_seed(seed, seed_len);
802+
}
803+
_is_unlocked_bip39 = bip39_seed != NULL;
804+
if (bip39_seed != NULL) {
805+
memcpy(_retained_bip39_seed, bip39_seed, sizeof(_retained_bip39_seed));
806+
}
807+
}
808+
#endif

src/keystore.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,6 @@ typedef enum {
4545
KEYSTORE_ERR_ENCRYPT,
4646
} keystore_error_t;
4747

48-
#ifdef TESTING
49-
/**
50-
* convenience to mock the keystore state (locked, seed) in tests.
51-
*/
52-
void keystore_mock_unlocked(const uint8_t* seed, size_t seed_len, const uint8_t* bip39_seed);
53-
#endif
54-
5548
/**
5649
* Copies the retained seed into the given buffer. The caller must
5750
* zero the seed with util_zero once it is no longer needed.
@@ -284,4 +277,11 @@ USE_RESULT bool keystore_secp256k1_schnorr_bip86_sign(
284277
const uint8_t* msg32,
285278
uint8_t* sig64_out);
286279

280+
#ifdef TESTING
281+
/**
282+
* convenience to mock the keystore state (locked, seed) in tests.
283+
*/
284+
void keystore_mock_unlocked(const uint8_t* seed, size_t seed_len, const uint8_t* bip39_seed);
285+
#endif
286+
287287
#endif

0 commit comments

Comments
 (0)