Skip to content

Commit aad37ef

Browse files
committed
unit-test/keystore: simplify by removing granular mocking
cmocka mocking is a big pain. If you modify unit tests, it is very hard to track down where and how the mocking has to be modified. The unit test nearly becomes the implementation itself. We can simplify and not mock all of this. The quality of the unit tests is not impacted, as the mock_securechip.c already does KDF on mock slot values and the resulting seed is checked, so if the keystore.c implementation changes (e.g. using different KDF slots or number of rounds or different hmac keys/values), the unit test will fail.
1 parent d178b97 commit aad37ef

File tree

2 files changed

+1
-75
lines changed

2 files changed

+1
-75
lines changed

test/unit-test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ set(TEST_LIST
210210
cleanup
211211
"-Wl,--wrap=util_cleanup_32"
212212
keystore
213-
"-Wl,--wrap=secp256k1_anti_exfil_sign,--wrap=memory_is_initialized,--wrap=memory_is_seeded,--wrap=memory_get_failed_unlock_attempts,--wrap=memory_reset_failed_unlock_attempts,--wrap=memory_increment_failed_unlock_attempts,--wrap=memory_set_encrypted_seed_and_hmac,--wrap=memory_get_encrypted_seed_and_hmac,--wrap=memory_get_salt_root,--wrap=reset_reset,--wrap=salt_hash_data,--wrap=cipher_aes_hmac_encrypt,--wrap=random_32_bytes,--wrap=securechip_kdf"
213+
"-Wl,--wrap=secp256k1_anti_exfil_sign,--wrap=memory_is_initialized,--wrap=memory_is_seeded,--wrap=memory_get_failed_unlock_attempts,--wrap=memory_reset_failed_unlock_attempts,--wrap=memory_increment_failed_unlock_attempts,--wrap=memory_set_encrypted_seed_and_hmac,--wrap=memory_get_encrypted_seed_and_hmac,--wrap=memory_get_salt_root,--wrap=reset_reset,--wrap=random_32_bytes"
214214
keystore_antiklepto
215215
""
216216
keystore_functional

test/unit-test/test_keystore.c

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,6 @@
3535

3636
#define PASSWORD ("password")
3737

38-
int __real_securechip_kdf(securechip_slot_t slot, const uint8_t* msg, size_t len, uint8_t* kdf_out);
39-
int __wrap_securechip_kdf(securechip_slot_t slot, const uint8_t* msg, size_t len, uint8_t* kdf_out)
40-
{
41-
check_expected(slot);
42-
return __real_securechip_kdf(slot, msg, len, kdf_out);
43-
}
44-
4538
static uint8_t _salt_root[KEYSTORE_MAX_SEED_LENGTH] = {
4639
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
4740
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
@@ -112,41 +105,6 @@ int __wrap_secp256k1_anti_exfil_sign(
112105
return __real_secp256k1_anti_exfil_sign(ctx, sig, msg32, seckey, host_data32, recid);
113106
}
114107

115-
bool __real_salt_hash_data(
116-
const uint8_t* data,
117-
size_t data_len,
118-
const char* purpose,
119-
uint8_t* hash_out);
120-
bool __wrap_salt_hash_data(
121-
const uint8_t* data,
122-
size_t data_len,
123-
const char* purpose,
124-
uint8_t* hash_out)
125-
{
126-
check_expected(data);
127-
check_expected(data_len);
128-
check_expected(purpose);
129-
return __real_salt_hash_data(data, data_len, purpose, hash_out);
130-
}
131-
132-
bool __real_cipher_aes_hmac_encrypt(
133-
const unsigned char* in,
134-
int in_len,
135-
uint8_t* out,
136-
int* out_len,
137-
const uint8_t* secret);
138-
139-
bool __wrap_cipher_aes_hmac_encrypt(
140-
const unsigned char* in,
141-
int in_len,
142-
uint8_t* out,
143-
int* out_len,
144-
const uint8_t* secret)
145-
{
146-
check_expected(secret);
147-
return __real_cipher_aes_hmac_encrypt(in, in_len, out, out_len, secret);
148-
}
149-
150108
/** Reset the SmartEEPROM configuration. */
151109
static void _smarteeprom_reset(void)
152110
{
@@ -298,35 +256,10 @@ static void _test_keystore_secp256k1_sign(void** state)
298256
assert_true(_pubkeys_equal(ctx, &recovered_pubkey, &expected_pubkey));
299257
}
300258
}
301-
302-
static void _expect_stretch(const char* password)
303-
{
304-
expect_memory(__wrap_salt_hash_data, data, password, strlen(password));
305-
expect_value(__wrap_salt_hash_data, data_len, strlen(password));
306-
expect_string(__wrap_salt_hash_data, purpose, "keystore_seed_access_in");
307-
308-
// KDF 1
309-
expect_value(__wrap_securechip_kdf, slot, SECURECHIP_SLOT_ROLLKEY);
310-
311-
// KDF 2
312-
expect_value(__wrap_securechip_kdf, slot, SECURECHIP_SLOT_KDF);
313-
314-
// KDF 3
315-
expect_value(__wrap_securechip_kdf, slot, SECURECHIP_SLOT_KDF);
316-
317-
expect_memory(__wrap_salt_hash_data, data, password, strlen(password));
318-
expect_value(__wrap_salt_hash_data, data_len, strlen(password));
319-
expect_string(__wrap_salt_hash_data, purpose, "keystore_seed_access_out");
320-
}
321-
322259
static void _expect_encrypt_and_store_seed(void)
323260
{
324261
will_return(__wrap_memory_is_initialized, false);
325262

326-
_expect_stretch(PASSWORD); // first stretch to encrypt
327-
_expect_stretch(PASSWORD); // second stretch to verify
328-
329-
expect_memory(__wrap_cipher_aes_hmac_encrypt, secret, _expected_secret, 32);
330263
// For the AES IV:
331264
will_return(__wrap_random_32_bytes, _aes_iv);
332265
}
@@ -349,15 +282,13 @@ static void _test_keystore_create_and_unlock_twice(void** state)
349282
_smarteeprom_reset();
350283

351284
will_return(__wrap_memory_is_seeded, true);
352-
_expect_stretch(PASSWORD);
353285
assert_int_equal(KEYSTORE_OK, keystore_unlock(PASSWORD, &remaining_attempts, NULL));
354286

355287
// Create new (different) seed.
356288
_expect_encrypt_and_store_seed();
357289
assert_int_equal(keystore_encrypt_and_store_seed(_mock_seed_2, 32, PASSWORD), KEYSTORE_OK);
358290

359291
will_return(__wrap_memory_is_seeded, true);
360-
_expect_stretch(PASSWORD);
361292
assert_int_equal(KEYSTORE_OK, keystore_unlock(PASSWORD, &remaining_attempts, NULL));
362293
}
363294

@@ -375,7 +306,6 @@ static void _perform_some_unlocks(void)
375306
for (int i = 0; i < 3; i++) {
376307
_reset_reset_called = false;
377308
will_return(__wrap_memory_is_seeded, true);
378-
_expect_stretch(PASSWORD);
379309
assert_int_equal(KEYSTORE_OK, keystore_unlock(PASSWORD, &remaining_attempts, NULL));
380310
assert_int_equal(remaining_attempts, MAX_UNLOCK_ATTEMPTS);
381311
assert_false(_reset_reset_called);
@@ -402,7 +332,6 @@ static void _test_keystore_unlock(void** state)
402332
for (int i = 1; i <= MAX_UNLOCK_ATTEMPTS; i++) {
403333
_reset_reset_called = false;
404334
will_return(__wrap_memory_is_seeded, true);
405-
_expect_stretch("invalid password");
406335
assert_int_equal(
407336
i >= MAX_UNLOCK_ATTEMPTS ? KEYSTORE_ERR_MAX_ATTEMPTS_EXCEEDED
408337
: KEYSTORE_ERR_INCORRECT_PASSWORD,
@@ -483,9 +412,6 @@ static void _test_keystore_create_and_store_seed(void** state)
483412
size_t seed_len = test_sizes[i];
484413
// Seed random is xored with host entropy and the salted/hashed user password.
485414
will_return(__wrap_random_32_bytes, seed_random);
486-
expect_memory(__wrap_salt_hash_data, data, PASSWORD, strlen(PASSWORD));
487-
expect_value(__wrap_salt_hash_data, data_len, strlen(PASSWORD));
488-
expect_string(__wrap_salt_hash_data, purpose, "keystore_seed_generation");
489415
_expect_encrypt_and_store_seed();
490416
assert_int_equal(
491417
keystore_create_and_store_seed(PASSWORD, host_entropy, seed_len), KEYSTORE_OK);

0 commit comments

Comments
 (0)