diff --git a/src/softsim/milenage/milenage_usim.c b/src/softsim/milenage/milenage_usim.c index afd1ab4..78d066d 100644 --- a/src/softsim/milenage/milenage_usim.c +++ b/src/softsim/milenage/milenage_usim.c @@ -141,6 +141,8 @@ int milenage_usim_check(const struct milenage_key_data *kd, } /* C.2.2 successful case: SEQ > SEQ_MS(i) */ + wpa_printf(MSG_DEBUG, "Milenage: ind %d", ind); + sd->dirty_ind = ind; sd->seq[ind] = rx_seq; amf = autn + 6; diff --git a/src/softsim/milenage/milenage_usim.h b/src/softsim/milenage/milenage_usim.h index 61eab0f..7ae0bc5 100644 --- a/src/softsim/milenage/milenage_usim.h +++ b/src/softsim/milenage/milenage_usim.h @@ -22,6 +22,7 @@ * Appendix C.3 * */ #define MILENAGE_IND_LEN 5 +#define NO_IND_UPDATE (-1) struct milenage_key_data { u8 k[16]; /* Secret key K */ @@ -33,6 +34,7 @@ struct milenage_key_data { struct milenage_seq_data { uint64_t seq[(1 << MILENAGE_IND_LEN)]; /* array of SEQ_MS indexed by IND */ uint64_t delta; /* limit "delta" as per 33.102. Typically configured to 2**28 */ + int8_t dirty_ind; /* IND of the SEQ_MS updated, -1 no file to be updated */ }; struct milenage_result { diff --git a/src/softsim/uicc/uicc_auth.c b/src/softsim/uicc/uicc_auth.c index ba3edc4..4be6d5d 100644 --- a/src/softsim/uicc/uicc_auth.c +++ b/src/softsim/uicc/uicc_auth.c @@ -148,6 +148,7 @@ static int get_seq_data(struct milenage_seq_data *seq_data) SS_LOGP(SAUTH, LDEBUG, "seq data file (%s) loaded\n", ss_fs_utils_dump_path(&seq_data_path)); } else { seq_data->delta = ss_uint64_load_from_be(seq_data_raw->data); + seq_data->dirty_ind = NO_IND_UPDATE; SS_LOGP(SAUTH, LDEBUG, "delta data file (%s) loaded\n", ss_fs_utils_dump_path(&seq_data_path)); } @@ -166,34 +167,32 @@ static int update_seq_data(struct milenage_seq_data *seq_data) uint8_t write_buffer[sizeof(seq_data->delta)]; // 8 bytes int rc; - int file_offset = 0; ss_fs_init(&seq_data_path); - for (file_offset = 0; file_offset < SS_ARRAY_SIZE(seq_data->seq) + 1; file_offset++) { - rc = ss_fs_select(&seq_data_path, SEQ_DATA_FID_BASE + file_offset); + if (seq_data->dirty_ind == NO_IND_UPDATE) { + SS_LOGP(SAUTH, LERROR, "seq data index not found -- abort\n"); + ss_path_reset(&seq_data_path); + return -EINVAL; + } - if (rc < 0) { - SS_LOGP(SAUTH, LERROR, "seq data file (%04x) not found -- abort\n", KEY_DATA_FID); - ss_path_reset(&seq_data_path); - return -EINVAL; - } + rc = ss_fs_select(&seq_data_path, SEQ_DATA_FID_BASE + seq_data->dirty_ind); - if (file_offset < SS_ARRAY_SIZE(seq_data->seq)) { - ss_uint64_store_to_be(write_buffer, seq_data->seq[file_offset]); + if (rc < 0) { + SS_LOGP(SAUTH, LERROR, "seq data file (%04x) not found -- abort\n", KEY_DATA_FID); + ss_path_reset(&seq_data_path); + return -EINVAL; + } - } else { - ss_uint64_store_to_be(write_buffer, seq_data->delta); - } + ss_uint64_store_to_be(write_buffer, seq_data->seq[seq_data->dirty_ind]); - rc = ss_storage_write_file(&seq_data_path, write_buffer, 0, sizeof(write_buffer)); + rc = ss_storage_write_file(&seq_data_path, write_buffer, 0, sizeof(write_buffer)); - if (rc < 0) { - SS_LOGP(SAUTH, LERROR, "seq data file (%s) not writeable -- abort\n", - ss_fs_utils_dump_path(&seq_data_path)); - ss_path_reset(&seq_data_path); - return -EINVAL; - } + if (rc < 0) { + SS_LOGP(SAUTH, LERROR, "seq data file (%s) not writeable -- abort\n", + ss_fs_utils_dump_path(&seq_data_path)); + ss_path_reset(&seq_data_path); + return -EINVAL; } SS_LOGP(SAUTH, LDEBUG, "seq data file (%s) updated\n", ss_fs_utils_dump_path(&seq_data_path));