mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-02 19:40:57 +00:00
feat(core): Distinguish Optiga errors from invalid PIN.
This commit is contained in:
parent
4c7979ae30
commit
1fa2929607
@ -30,9 +30,15 @@
|
|||||||
#define OPTIGA_DEVICE_ECC_KEY_INDEX 0
|
#define OPTIGA_DEVICE_ECC_KEY_INDEX 0
|
||||||
#define OPTIGA_COMMAND_ERROR_OFFSET 0x100
|
#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)
|
#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.
|
// Size of secrets used in PIN processing, e.g. salted PIN, master secret etc.
|
||||||
#define OPTIGA_PIN_SECRET_SIZE 32
|
#define OPTIGA_PIN_SECRET_SIZE 32
|
||||||
|
|
||||||
|
@ -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 optiga_secret[OPTIGA_PIN_SECRET_SIZE] = {0};
|
||||||
uint8_t stretched_pin[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);
|
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));
|
memzero(stretched_pin, sizeof(stretched_pin));
|
||||||
if (!ret) {
|
if (ret != OPTIGA_SUCCESS) {
|
||||||
memzero(optiga_secret, sizeof(optiga_secret));
|
memzero(optiga_secret, sizeof(optiga_secret));
|
||||||
return secfalse;
|
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 optiga_secret[OPTIGA_PIN_SECRET_SIZE] = {0};
|
||||||
uint8_t stretched_pin[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);
|
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));
|
memzero(stretched_pin, sizeof(stretched_pin));
|
||||||
if (!ret) {
|
if (ret != OPTIGA_SUCCESS) {
|
||||||
memzero(optiga_secret, sizeof(optiga_secret));
|
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;
|
return secfalse;
|
||||||
}
|
}
|
||||||
derive_kek_optiga(optiga_secret, kek, keiv);
|
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 kek[SHA256_DIGEST_LENGTH] = {0};
|
||||||
uint8_t keiv[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.
|
// 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
|
// Wipe storage if too many failures
|
||||||
wait_random();
|
wait_random();
|
||||||
if (ctr + 1 >= PIN_MAX_TRIES) {
|
if (ctr + 1 >= PIN_MAX_TRIES) {
|
||||||
@ -1213,6 +1218,7 @@ static secbool unlock(const uint8_t *pin, size_t pin_len,
|
|||||||
}
|
}
|
||||||
return secfalse;
|
return secfalse;
|
||||||
}
|
}
|
||||||
|
memzero(&legacy_pin, sizeof(legacy_pin));
|
||||||
memzero(kek, sizeof(kek));
|
memzero(kek, sizeof(kek));
|
||||||
memzero(keiv, sizeof(keiv));
|
memzero(keiv, sizeof(keiv));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user