From 37745c22019e382b1c1d8e511183c43c38b050ce Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Mon, 3 May 2021 17:04:35 +0300 Subject: sim-auth: Parse auth response according to TS 31.102 --- src/sim-auth.c | 34 ++++++++------ src/simutil.c | 146 ++++++++++++++++++++++++++++++++++++++++++--------------- src/simutil.h | 13 +++-- 3 files changed, 137 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/sim-auth.c b/src/sim-auth.c index 3c3f35e7..6dab52ee 100644 --- a/src/sim-auth.c +++ b/src/sim-auth.c @@ -207,14 +207,10 @@ static void handle_umts(struct ofono_sim_auth *sa, const uint8_t *resp, DBusMessage *reply = NULL; DBusMessageIter iter; DBusMessageIter dict; - const uint8_t *res = NULL; - const uint8_t *ck = NULL; - const uint8_t *ik = NULL; - const uint8_t *auts = NULL; - const uint8_t *kc = NULL; + struct data_block res, ck, ik, auts, sres, kc; if (!sim_parse_umts_authenticate(resp, len, &res, &ck, &ik, - &auts, &kc)) + &auts, &sres, &kc)) goto umts_end; reply = dbus_message_new_method_return(sa->pending->msg); @@ -224,15 +220,23 @@ static void handle_umts(struct ofono_sim_auth *sa, const uint8_t *resp, dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{say}", &dict); - if (auts) { - append_dict_byte_array(&dict, "AUTS", auts, 14); - } else { - append_dict_byte_array(&dict, "RES", res, 8); - append_dict_byte_array(&dict, "CK", ck, 16); - append_dict_byte_array(&dict, "IK", ik, 16); - if (kc) - append_dict_byte_array(&dict, "Kc", kc, 8); - } + if (auts.data) + append_dict_byte_array(&dict, "AUTS", auts.data, auts.len); + + if (sres.data) + append_dict_byte_array(&dict, "SRES", sres.data, sres.len); + + if (res.data) + append_dict_byte_array(&dict, "RES", res.data, res.len); + + if (ck.data) + append_dict_byte_array(&dict, "CK", ck.data, ck.len); + + if (ik.data) + append_dict_byte_array(&dict, "IK", ik.data, ik.len); + + if (kc.data) + append_dict_byte_array(&dict, "Kc", kc.data, kc.len); dbus_message_iter_close_container(&iter, &dict); diff --git a/src/simutil.c b/src/simutil.c index edd7de88..59d8d5dd 100644 --- a/src/simutil.c +++ b/src/simutil.c @@ -1674,63 +1674,135 @@ int sim_build_gsm_authenticate(unsigned char *buffer, int len, return build_authenticate(buffer, rand, NULL); } -gboolean sim_parse_umts_authenticate(const unsigned char *buffer, - int len, const unsigned char **res, const unsigned char **ck, - const unsigned char **ik, const unsigned char **auts, - const unsigned char **kc) +gboolean sim_parse_umts_authenticate(const unsigned char *buffer, int len, + struct data_block *res, struct data_block *ck, + struct data_block *ik, struct data_block *auts, + struct data_block *sres, struct data_block *kc) { - if (len < 16 || !buffer) + const unsigned char *ptr = buffer; + const unsigned char *end = ptr + len; + unsigned int l; + + if (!buffer || len < 2) return FALSE; - switch (buffer[0]) { + memset(res, 0, sizeof(*res)); + memset(ck, 0, sizeof(*ck)); + memset(ik, 0, sizeof(*ik)); + memset(kc, 0, sizeof(*kc)); + memset(auts, 0, sizeof(*auts)); + memset(sres, 0, sizeof(*sres)); + + /* + * TS 31.102 + * 7.1.2.1 GSM/3G security context + */ + switch (*ptr++) { case 0xdb: - /* 'DB' + '08' + RES(16) + '10' + CK(32) + '10' + IK(32) = 43 */ - if (len < 43) - goto umts_end; + /* + * Response parameters/data, case 1, 3G security context, + * command successful: + * + * "Successful 3G authentication" tag = 'DB' + * 'DB' + L3 + RES(L3) + L4 + CK(L4) + L5 + IK(L5) + 8 + Kc(8) + */ + l = *ptr++; /* L3 */ + if ((ptr + l) > end) + return FALSE; - /* success */ - if (buffer[1] != 0x08) - goto umts_end; + res->data = ptr; + res->len = l; + ptr += l; - *res = buffer + 2; + if (ptr == end) + return FALSE; - if (buffer[10] != 0x10) - goto umts_end; + l = *ptr++; /* L4 */ + if ((ptr + l) > end) + return FALSE; - *ck = buffer + 11; + ck->data = ptr; + ck->len = l; + ptr += l; - if (buffer[27] != 0x10) - goto umts_end; + if (ptr == end) + return FALSE; - *ik = buffer + 28; + l = *ptr++; /* L5 */ + if ((ptr + l) > end) + return FALSE; - if (len >= 53 && kc) { - if (buffer[44] != 0x08) - goto umts_end; + ik->data = ptr; + ik->len = l; + ptr += l; - *kc = buffer + 45; - } else { - *kc = NULL; + if (ptr < end) { + l = *ptr++; + if (l != 8 || (ptr + l) != end) + return FALSE; + + kc->data = ptr; + kc->len = l; + ptr += l; } - *auts = NULL; + return TRUE; - break; case 0xdc: - /* sync error */ - if (buffer[1] != 0x0e) - goto umts_end; + /* + * Response parameters/data, case 2, 3G security context, + * synchronisation failure: + * + * "Synchronisation failure" tag = 'DC' + * 'DC' + L1 + AUTS(L1) + */ + l = *ptr++; /* L1 */ + if ((ptr + l) > end) + return FALSE; - *auts = buffer + 2; + auts->data = ptr; + auts->len = l; + ptr += l; - break; - default: - goto umts_end; - } + if (ptr != end) + return FALSE; - return TRUE; + return TRUE; + + case 0x04: + /* + * Response parameters/data, case 3, GSM security context, + * command successful: + * + * 4 + SRES(4) + 8 + Kc(8) + */ + l = 4; /* Already skipped this one */ + if ((ptr + l) > end) + return FALSE; + + sres->data = ptr; + sres->len = l; + ptr += l; + + if (ptr == end) + return FALSE; + + l = *ptr++; /* 8 */ + if (l != 8 || (ptr + l) > end) + return FALSE; -umts_end: + kc->data = ptr; + kc->len = l; + ptr += l; + + if (ptr != end) + return FALSE; + + return TRUE; + + default: + break; + } return FALSE; } diff --git a/src/simutil.h b/src/simutil.h index 33b775a7..f908bbb4 100644 --- a/src/simutil.h +++ b/src/simutil.h @@ -371,6 +371,11 @@ struct comprehension_tlv_builder { struct ber_tlv_builder *parent; }; +struct data_block { + const unsigned char *data; + unsigned int len; +}; + void simple_tlv_iter_init(struct simple_tlv_iter *iter, const unsigned char *pdu, unsigned int len); gboolean simple_tlv_iter_next(struct simple_tlv_iter *iter); @@ -527,10 +532,10 @@ int sim_build_umts_authenticate(unsigned char *buffer, int len, int sim_build_gsm_authenticate(unsigned char *buffer, int len, const unsigned char *rand); -gboolean sim_parse_umts_authenticate(const unsigned char *buffer, - int len, const unsigned char **res, const unsigned char **ck, - const unsigned char **ik, const unsigned char **auts, - const unsigned char **kc); +gboolean sim_parse_umts_authenticate(const unsigned char *buffer, int len, + struct data_block *res, struct data_block *ck, + struct data_block *ik, struct data_block *auts, + struct data_block *sres, struct data_block *kc); gboolean sim_parse_gsm_authenticate(const unsigned char *buffer, int len, const unsigned char **sres, const unsigned char **kc); -- cgit v1.2.1