From e0e1b3758ea2c0f6e361e37d6af15444d0de9003 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 22 Mar 2024 20:37:47 +0100 Subject: [PATCH] Added support for dynamic number of maximum retries. 3 by default Signed-off-by: Pol Henarejos --- src/openpgp/files.h | 1 + src/openpgp/openpgp.c | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/openpgp/files.h b/src/openpgp/files.h index b6deed3..e75e1f2 100644 --- a/src/openpgp/files.h +++ b/src/openpgp/files.h @@ -28,6 +28,7 @@ #define EF_ALGO_PRIV2 0x10c2 #define EF_ALGO_PRIV3 0x10c3 #define EF_PW_PRIV 0x10c4 +#define EF_PW_RETRIES 0x10c5 #define EF_PK_SIG 0x10d1 #define EF_PK_DEC 0x10d2 #define EF_PK_AUT 0x10d3 diff --git a/src/openpgp/openpgp.c b/src/openpgp/openpgp.c index 8c0e5dd..e62946e 100644 --- a/src/openpgp/openpgp.c +++ b/src/openpgp/openpgp.c @@ -270,7 +270,6 @@ void scan_files() { flash_write_data_to_file(ef, def, sizeof(def)); } } - if ((ef = search_by_fid(EF_SEX, NULL, SPECIFY_ANY))) { if (!ef->data) { printf("Sex is empty. Initializing to default\r\n"); @@ -278,6 +277,13 @@ void scan_files() { flash_write_data_to_file(ef, def, sizeof(def)); } } + if ((ef = search_by_fid(EF_PW_RETRIES, NULL, SPECIFY_ANY))) { + if (!ef->data) { + printf("PW retries is empty. Initializing to default\r\n"); + const uint8_t def[] = { 0x1, 3, 3, 3 }; + flash_write_data_to_file(ef, def, sizeof(def)); + } + } low_flash_available(); } @@ -847,16 +853,21 @@ int pin_reset_retries(const file_t *pin, bool force) { return CCID_ERR_NULL_PARAM; } file_t *pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF); - if (!pw_status) { + file_t *pw_retries = search_by_fid(EF_PW_RETRIES, NULL, SPECIFY_EF); + if (!pw_status || !pw_retries) { return CCID_ERR_FILE_NOT_FOUND; } + if (3 + (pin->fid & 0xf) >= file_get_size(pw_status) || (pin->fid & 0xf) >= file_get_size(pw_retries)) { + return CCID_ERR_MEMORY_FATAL; + } uint8_t p[64]; memcpy(p, file_get_data(pw_status), file_get_size(pw_status)); uint8_t retries = p[3 + (pin->fid & 0xf)]; if (retries == 0 && force == false) { //blocked return CCID_ERR_BLOCKED; } - p[3 + (pin->fid & 0xf)] = 3; + uint8_t max_retries = file_get_data(pw_retries)[(pin->fid & 0xf)]; + p[3 + (pin->fid & 0xf)] = max_retries; int r = flash_write_data_to_file(pw_status, p, file_get_size(pw_status)); low_flash_available(); return r;