1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-19 05:58:09 +00:00

feat(core): Distinguish Optiga errors from invalid PIN.

This commit is contained in:
Andrew Kozlik 2023-10-02 19:18:11 +02:00
parent 68876170fe
commit aed5912fbf
2 changed files with 24 additions and 12 deletions

View File

@ -30,9 +30,15 @@
#define OPTIGA_DEVICE_ECC_KEY_INDEX 0
#define OPTIGA_COMMAND_ERROR_OFFSET 0x100
// Error code 7: Access conditions not satisfied
// Error code 0x07: Access conditions not satisfied
#define OPTIGA_ERR_ACCESS_COND_NOT_SAT (OPTIGA_COMMAND_ERROR_OFFSET + 0x07)
// Error code 0x0E: Counter threshold limit exceeded
#define OPTIGA_ERR_COUNTER_EXCEEDED (OPTIGA_COMMAND_ERROR_OFFSET + 0x0E)
// Error code 0x2F: Authorization failure
#define OPTIGA_ERR_AUTH_FAIL (OPTIGA_COMMAND_ERROR_OFFSET + 0x2F)
// Size of secrets used in PIN processing, e.g. salted PIN, master secret etc.
#define OPTIGA_PIN_SECRET_SIZE 32

View File

@ -602,9 +602,9 @@ static secbool __wur derive_kek_set(const uint8_t *pin, size_t pin_len,
uint8_t optiga_secret[OPTIGA_PIN_SECRET_SIZE] = {0};
uint8_t stretched_pin[OPTIGA_PIN_SECRET_SIZE] = {0};
stretch_pin_optiga(pin, pin_len, storage_salt, ext_salt, stretched_pin);
bool ret = optiga_pin_set(ui_progress, stretched_pin, optiga_secret);
int ret = optiga_pin_set(ui_progress, stretched_pin, optiga_secret);
memzero(stretched_pin, sizeof(stretched_pin));
if (!ret) {
if (ret != OPTIGA_SUCCESS) {
memzero(optiga_secret, sizeof(optiga_secret));
return secfalse;
}
@ -625,10 +625,17 @@ static secbool __wur derive_kek_unlock(const uint8_t *pin, size_t pin_len,
uint8_t optiga_secret[OPTIGA_PIN_SECRET_SIZE] = {0};
uint8_t stretched_pin[OPTIGA_PIN_SECRET_SIZE] = {0};
stretch_pin_optiga(pin, pin_len, storage_salt, ext_salt, stretched_pin);
bool ret = optiga_pin_verify(ui_progress, stretched_pin, optiga_secret);
int ret = optiga_pin_verify(ui_progress, stretched_pin, optiga_secret);
memzero(stretched_pin, sizeof(stretched_pin));
if (!ret) {
if (ret != OPTIGA_SUCCESS) {
memzero(optiga_secret, sizeof(optiga_secret));
if (ret == OPTIGA_ERR_COUNTER_EXCEEDED) {
// Unreachable code. Wipe should have already been triggered in unlock().
storage_wipe();
show_pin_too_many_screen();
}
ensure(ret == OPTIGA_ERR_AUTH_FAIL ? sectrue : secfalse,
"optiga_pin_verify failed");
return secfalse;
}
derive_kek_optiga(optiga_secret, kek, keiv);
@ -1196,15 +1203,13 @@ static secbool unlock(const uint8_t *pin, size_t pin_len,
}
uint8_t kek[SHA256_DIGEST_LENGTH] = {0};
uint8_t keiv[SHA256_DIGEST_LENGTH] = {0};
if (sectrue != derive_kek_unlock(unlock_pin, unlock_pin_len,
(const uint8_t *)rand_salt, ext_salt, kek,
keiv)) {
return secfalse;
}
memzero(&legacy_pin, sizeof(legacy_pin));
// Check whether the entered PIN is correct.
if (sectrue != decrypt_dek(kek, keiv)) {
if (sectrue != derive_kek_unlock(unlock_pin, unlock_pin_len,
(const uint8_t *)rand_salt, ext_salt, kek,
keiv) ||
sectrue != decrypt_dek(kek, keiv)) {
memzero(&legacy_pin, sizeof(legacy_pin));
// Wipe storage if too many failures
wait_random();
if (ctr + 1 >= PIN_MAX_TRIES) {
@ -1213,6 +1218,7 @@ static secbool unlock(const uint8_t *pin, size_t pin_len,
}
return secfalse;
}
memzero(&legacy_pin, sizeof(legacy_pin));
memzero(kek, sizeof(kek));
memzero(keiv, sizeof(keiv));