diff --git a/core/embed/trezorhal/optiga.h b/core/embed/trezorhal/optiga.h index a09d083078..8e73161ac2 100644 --- a/core/embed/trezorhal/optiga.h +++ b/core/embed/trezorhal/optiga.h @@ -67,4 +67,8 @@ int __wur optiga_pin_verify(OPTIGA_UI_PROGRESS ui_progress, const uint8_t pin_secret[OPTIGA_PIN_SECRET_SIZE], uint8_t out_secret[OPTIGA_PIN_SECRET_SIZE]); +int __wur optiga_pin_get_fails(uint32_t *ctr); + +int __wur optiga_pin_fails_increase(uint32_t count); + #endif diff --git a/core/embed/trezorhal/optiga/optiga.c b/core/embed/trezorhal/optiga/optiga.c index 71527bf6fb..aa03b98660 100644 --- a/core/embed/trezorhal/optiga/optiga.c +++ b/core/embed/trezorhal/optiga/optiga.c @@ -631,3 +631,36 @@ int optiga_pin_verify(OPTIGA_UI_PROGRESS ui_progress, OPTIGA_PIN_SECRET_SIZE, out_secret); return OPTIGA_SUCCESS; } + +static int optiga_get_counter(uint16_t oid, uint32_t *ctr) { + uint8_t counter[8] = {0}; + size_t counter_size = 0; + optiga_result res = optiga_get_data_object(oid, false, counter, + sizeof(counter), &counter_size); + if (res != OPTIGA_SUCCESS) { + return res; + } + + if (counter_size != sizeof(counter)) { + return OPTIGA_ERR_SIZE; + } + + *ctr = counter[0]; + *ctr = (*ctr << 8) + counter[1]; + *ctr = (*ctr << 8) + counter[2]; + *ctr = (*ctr << 8) + counter[3]; + + return OPTIGA_SUCCESS; +} + +int optiga_pin_get_fails(uint32_t *ctr) { + return optiga_get_counter(OID_PIN_COUNTER, ctr); +} + +int optiga_pin_fails_increase(uint32_t count) { + if (count > 0xff) { + return OPTIGA_ERR_PARAM; + } + + return optiga_count_data_object(OID_PIN_COUNTER, count); +} diff --git a/core/embed/trezorhal/optiga/optiga_commands.c b/core/embed/trezorhal/optiga/optiga_commands.c index 75bc2df046..183054cafa 100644 --- a/core/embed/trezorhal/optiga/optiga_commands.c +++ b/core/embed/trezorhal/optiga/optiga_commands.c @@ -338,6 +338,39 @@ optiga_result optiga_set_data_object(uint16_t oid, bool set_metadata, return ret; } +/* + * https://github.com/Infineon/optiga-trust-m/blob/develop/documents/OPTIGA%E2%84%A2%20Trust%20M%20Solution%20Reference%20Manual.md#setdataobject + */ +optiga_result optiga_count_data_object(uint16_t oid, uint8_t count) { + if (count == 0) { + return OPTIGA_SUCCESS; + } + + tx_size = 9; + if (tx_size > sizeof(tx_buffer)) { + return OPTIGA_ERR_PARAM; + } + + uint8_t *ptr = tx_buffer; + *(ptr++) = 0x82; // command code + *(ptr++) = 0x02; // count data object + write_uint16(&ptr, tx_size - 4); + + write_uint16(&ptr, oid); + write_uint16(&ptr, 0); // offset + + *(ptr++) = count; + + optiga_result ret = optiga_execute_command(tx_buffer, tx_size, tx_buffer, + sizeof(tx_buffer), &tx_size); + if (ret != OPTIGA_SUCCESS) { + return ret; + } + + ret = process_output_fixedlen(NULL, 0); + return ret; +} + /* * https://github.com/Infineon/optiga-trust-m/blob/develop/documents/OPTIGA%E2%84%A2%20Trust%20M%20Solution%20Reference%20Manual.md#getrandom */ diff --git a/core/embed/trezorhal/optiga_commands.h b/core/embed/trezorhal/optiga_commands.h index 4d271a812d..3992b2637b 100644 --- a/core/embed/trezorhal/optiga_commands.h +++ b/core/embed/trezorhal/optiga_commands.h @@ -157,6 +157,7 @@ optiga_result optiga_get_data_object(uint16_t oid, bool get_metadata, size_t *data_size); optiga_result optiga_set_data_object(uint16_t oid, bool set_metadata, const uint8_t *data, size_t data_size); +optiga_result optiga_count_data_object(uint16_t oid, uint8_t count); optiga_result optiga_get_random(uint8_t *random, size_t random_size); optiga_result optiga_encrypt_sym(optiga_sym_mode mode, uint16_t oid, const uint8_t *input, size_t input_size, diff --git a/core/embed/trezorhal/unix/optiga.c b/core/embed/trezorhal/unix/optiga.c index 5c97225dfd..0ab666049c 100644 --- a/core/embed/trezorhal/unix/optiga.c +++ b/core/embed/trezorhal/unix/optiga.c @@ -167,3 +167,10 @@ int optiga_pin_verify(OPTIGA_UI_PROGRESS ui_progress, ui_progress(OPTIGA_PIN_DERIVE_MS); return OPTIGA_SUCCESS; } + +int optiga_pin_get_fails(uint32_t *ctr) { + *ctr = 0; + return OPTIGA_SUCCESS; +} + +int optiga_pin_fails_increase(uint32_t count) { return OPTIGA_SUCCESS; }