diff --git a/src/gsm/auth_milenage.c b/src/gsm/auth_milenage.c index 1635ac6b2..e18076218 100644 --- a/src/gsm/auth_milenage.c +++ b/src/gsm/auth_milenage.c @@ -30,10 +30,14 @@ static int milenage_gen_vec(struct osmo_auth_vector *vec, const uint8_t *_rand) { size_t res_len = sizeof(vec->res); + uint64_t next_sqn; uint8_t sqn[6]; int rc; - osmo_store64be_ext(aud->u.umts.sqn, sqn, 6); + /* keep the incremented SQN local until gsm_milenage() succeeded. */ + next_sqn = aud->u.umts.sqn + 1; + + osmo_store64be_ext(next_sqn, sqn, 6); milenage_generate(aud->u.umts.opc, aud->u.umts.amf, aud->u.umts.k, sqn, _rand, vec->autn, vec->ik, vec->ck, vec->res, &res_len); @@ -43,7 +47,9 @@ static int milenage_gen_vec(struct osmo_auth_vector *vec, return rc; vec->auth_types = OSMO_AUTH_TYPE_UMTS | OSMO_AUTH_TYPE_GSM; - aud->u.umts.sqn++; + + /* for storage in the caller's AUC database */ + aud->u.umts.sqn = next_sqn; return 0; } @@ -72,7 +78,7 @@ static int milenage_gen_vec_auts(struct osmo_auth_vector *vec, if (rc < 0) return rc; - aud->u.umts.sqn = 1 + (osmo_load64be_ext(sqn_out, 6) >> 16); + aud->u.umts.sqn = osmo_load64be_ext(sqn_out, 6) >> 16; return milenage_gen_vec(vec, aud, _rand); } diff --git a/tests/auth/milenage_test.c b/tests/auth/milenage_test.c index 187b9adbc..405da6582 100644 --- a/tests/auth/milenage_test.c +++ b/tests/auth/milenage_test.c @@ -36,7 +36,7 @@ static struct osmo_sub_auth_data test_aud = { .k = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, .amf = { 0x00, 0x00 }, - .sqn = 0x22, + .sqn = 0x21, }, }; diff --git a/tests/auth/milenage_test.ok b/tests/auth/milenage_test.ok index 20c47c61f..b0eb44bb8 100644 --- a/tests/auth/milenage_test.ok +++ b/tests/auth/milenage_test.ok @@ -5,7 +5,7 @@ CK: 72 00 a1 84 d8 f2 c7 58 fb df 87 90 0d db f2 75 RES: e9 fc 88 cc c8 a3 53 81 SRES: 21 5f db 4d Kc: 6d e8 16 a7 59 a4 29 12 -AUTS success: tuple generated with SQN = 33 +AUTS success: tuple generated with SQN = 32 MILENAGE supported: 1 OP: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 OPC: c6 a1 3b 37 87 8f 5b 82 6f 4f 81 62 a1 c8 d8 79 diff --git a/utils/osmo-auc-gen.c b/utils/osmo-auc-gen.c index 6fa7cec77..4e2456a72 100644 --- a/utils/osmo-auc-gen.c +++ b/utils/osmo-auc-gen.c @@ -198,6 +198,10 @@ int main(int argc, char **argv) } ul = strtoul(optarg, 0, 10); test_aud.u.umts.sqn = ul; + /* Before calculating the UMTS auth vector, + * osmo_auth_gen_vec() increments the SQN. SQN-1 here + * to end up with the SQN the user requested. */ + test_aud.u.umts.sqn--; break; case 'r': rc = osmo_hexparse(optarg, _rand, sizeof(_rand)); @@ -260,16 +264,14 @@ int main(int argc, char **argv) else { dump_auth_vec(vec); if (test_aud.type == OSMO_AUTH_TYPE_UMTS) - /* After generating, SQN is incremented, so -1 */ - printf("SQN:\t%" PRIu64 "\n", test_aud.u.umts.sqn - 1); + printf("SQN:\t%" PRIu64 "\n", test_aud.u.umts.sqn); } /* After recovering SQN.MS from AUTS, milenage_gen_vec_auts() does - * aud->u.umts.sqn++, and after vector generation milenage_gen_vec() - * does another ++, so to show SQN.MS we need to -2 */ + * aud->u.umts.sqn++, so to show SQN.MS we need to -1 */ if (auts_is_set) printf("AUTS success: SQN.MS = %" PRIu64 "\n", - test_aud.u.umts.sqn - 2); + test_aud.u.umts.sqn - 1); exit(0); }