From 121e9a4164e65dfb68b2bf09297a8537a2f659c5 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 20 Apr 2016 13:13:19 +0200 Subject: [PATCH] Start to use struct osmo_auth_vector from gsm_auth_tuple Rather than having a 'private' structure for kc, sres and rand, we now finally (with 4 years delay) use osmo_auth_vector from libosmogsm, which encapsulates authentication vectors that can be either GSM triplets or UMTS quintuples or a combination of both. gsm_auth_tuple becomes a wrapper around osmo_auth_vector, adding use_count and key_seq to it. key_seq is no longer initialized inside gprs_gsup_messages.c, as there is no CKSN / key_seq inside the message anyway. If a usre of the code needs key_seq, they need to manage it themselves. --- openbsc/include/openbsc/gprs_gsup_messages.h | 4 +- openbsc/include/openbsc/gsm_data.h | 5 +-- openbsc/src/gprs/gprs_gmm.c | 12 +++--- openbsc/src/gprs/gprs_gsup_messages.c | 43 +++++++++----------- openbsc/src/gprs/gprs_subscriber.c | 13 +++--- openbsc/src/gprs/sgsn_vty.c | 12 +++--- openbsc/src/libmsc/auth.c | 8 ++-- openbsc/src/libmsc/db.c | 18 ++++---- openbsc/src/libmsc/gsm_04_08.c | 10 ++--- openbsc/src/libmsc/vty_interface_layer3.c | 6 +-- openbsc/tests/mm_auth/mm_auth_test.c | 6 +-- openbsc/tests/sgsn/sgsn_test.c | 2 +- 12 files changed, 69 insertions(+), 70 deletions(-) diff --git a/openbsc/include/openbsc/gprs_gsup_messages.h b/openbsc/include/openbsc/gprs_gsup_messages.h index 8cbc809f7..66a75a801 100644 --- a/openbsc/include/openbsc/gprs_gsup_messages.h +++ b/openbsc/include/openbsc/gprs_gsup_messages.h @@ -104,8 +104,8 @@ struct gprs_gsup_message { enum gprs_gsup_cancel_type cancel_type; int pdp_info_compl; int freeze_ptmsi; - struct gsm_auth_tuple auth_tuples[GPRS_GSUP_MAX_NUM_AUTH_INFO]; - size_t num_auth_tuples; + struct osmo_auth_vector auth_vectors[GPRS_GSUP_MAX_NUM_AUTH_INFO]; + size_t num_auth_vectors; struct gprs_gsup_pdp_info pdp_infos[GPRS_GSUP_MAX_NUM_PDP_INFO]; size_t num_pdp_infos; const uint8_t *msisdn_enc; diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 6d7aba358..f229e7499 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -5,6 +5,7 @@ #include #include +#include #include @@ -47,9 +48,7 @@ struct gsm_auth_info { struct gsm_auth_tuple { int use_count; int key_seq; - uint8_t rand[16]; - uint8_t sres[4]; - uint8_t kc[8]; + struct osmo_auth_vector vec; }; #define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */ diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 5f0a5fda1..6b6e741fa 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -512,9 +512,9 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx, at = &ctx->auth_triplet; - if (TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_SRES) != sizeof(at->sres) || - memcmp(TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES), at->sres, - sizeof(at->sres)) != 0) { + if (TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_SRES) != sizeof(at->vec.sres) || + memcmp(TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES), at->vec.sres, + sizeof(at->vec.sres)) != 0) { LOGMMCTXP(LOGL_NOTICE, ctx, "Received SRES doesn't match\n"); rc = gsm48_tx_gmm_auth_ciph_rej(ctx); @@ -637,7 +637,8 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) struct gsm_auth_tuple *at = &ctx->auth_triplet; mmctx_timer_start(ctx, 3360, sgsn->cfg.timers.T3360); - return gsm48_tx_gmm_auth_ciph_req(ctx, at->rand, at->key_seq, + return gsm48_tx_gmm_auth_ciph_req(ctx, at->vec.rand, + at->key_seq, GPRS_ALGO_GEA0); } @@ -1468,7 +1469,8 @@ static void mmctx_timer_cb(void *_mm) } at = &mm->auth_triplet; - gsm48_tx_gmm_auth_ciph_req(mm, at->rand, at->key_seq, GPRS_ALGO_GEA0); + gsm48_tx_gmm_auth_ciph_req(mm, at->vec.rand, at->key_seq, + GPRS_ALGO_GEA0); osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3360, 0); break; case 3370: /* waiting for IDENTITY RESPONSE */ diff --git a/openbsc/src/gprs/gprs_gsup_messages.c b/openbsc/src/gprs/gprs_gsup_messages.c index 07485f7f9..0b1dc9b00 100644 --- a/openbsc/src/gprs/gprs_gsup_messages.c +++ b/openbsc/src/gprs/gprs_gsup_messages.c @@ -3,6 +3,7 @@ /* * (C) 2014 by Sysmocom s.f.m.c. GmbH * (C) 2015 by Holger Hans Peter Freyther + * (C) 2016 by Harald Welte * All Rights Reserved * * Author: Jacob Erlbeck @@ -82,7 +83,7 @@ static int decode_pdp_info(uint8_t *data, size_t data_len, } static int decode_auth_info(uint8_t *data, size_t data_len, - struct gsm_auth_tuple *auth_tuple) + struct osmo_auth_vector *auth_vector) { int rc; uint8_t tag; @@ -100,24 +101,24 @@ static int decode_auth_info(uint8_t *data, size_t data_len, switch (iei) { case GPRS_GSUP_RAND_IE: - if (value_len != sizeof(auth_tuple->rand)) + if (value_len != sizeof(auth_vector->rand)) goto parse_error; - memcpy(auth_tuple->rand, value, value_len); + memcpy(auth_vector->rand, value, value_len); break; case GPRS_GSUP_SRES_IE: - if (value_len != sizeof(auth_tuple->sres)) + if (value_len != sizeof(auth_vector->sres)) goto parse_error; - memcpy(auth_tuple->sres, value, value_len); + memcpy(auth_vector->sres, value, value_len); break; case GPRS_GSUP_KC_IE: - if (value_len != sizeof(auth_tuple->kc)) + if (value_len != sizeof(auth_vector->kc)) goto parse_error; - memcpy(auth_tuple->kc, value, value_len); + memcpy(auth_vector->kc, value, value_len); break; default: @@ -149,7 +150,7 @@ int gprs_gsup_decode(const uint8_t *const_data, size_t data_len, uint8_t *value; size_t value_len; static const struct gprs_gsup_pdp_info empty_pdp_info = {0}; - static const struct gsm_auth_tuple empty_auth_info = {0}; + static const struct osmo_auth_vector empty_auth_info = {0}; static const struct gprs_gsup_message empty_gsup_message = {0}; *gsup_msg = empty_gsup_message; @@ -183,7 +184,7 @@ int gprs_gsup_decode(const uint8_t *const_data, size_t data_len, while (data_len > 0) { enum gprs_gsup_iei iei; struct gprs_gsup_pdp_info pdp_info; - struct gsm_auth_tuple auth_info; + struct osmo_auth_vector auth_info; rc = gprs_shift_tlv(&data, &data_len, &tag, &value, &value_len); if (rc < 0) @@ -252,7 +253,7 @@ int gprs_gsup_decode(const uint8_t *const_data, size_t data_len, break; case GPRS_GSUP_AUTH_TUPLE_IE: - if (gsup_msg->num_auth_tuples >= GPRS_GSUP_MAX_NUM_AUTH_INFO) { + if (gsup_msg->num_auth_vectors >= GPRS_GSUP_MAX_NUM_AUTH_INFO) { LOGP(DGPRS, LOGL_ERROR, "GSUP IE type %d (AUTH_INFO) max exceeded\n", iei); @@ -260,13 +261,12 @@ int gprs_gsup_decode(const uint8_t *const_data, size_t data_len, } auth_info = empty_auth_info; - auth_info.key_seq = gsup_msg->num_auth_tuples; rc = decode_auth_info(value, value_len, &auth_info); if (rc < 0) return rc; - gsup_msg->auth_tuples[gsup_msg->num_auth_tuples++] = + gsup_msg->auth_vectors[gsup_msg->num_auth_vectors++] = auth_info; break; @@ -325,7 +325,7 @@ static void encode_pdp_info(struct msgb *msg, enum gprs_gsup_iei iei, } static void encode_auth_info(struct msgb *msg, enum gprs_gsup_iei iei, - const struct gsm_auth_tuple *auth_tuple) + const struct osmo_auth_vector *auth_vector) { uint8_t *len_field; size_t old_len; @@ -334,13 +334,13 @@ static void encode_auth_info(struct msgb *msg, enum gprs_gsup_iei iei, old_len = msgb_length(msg); msgb_tlv_put(msg, GPRS_GSUP_RAND_IE, - sizeof(auth_tuple->rand), auth_tuple->rand); + sizeof(auth_vector->rand), auth_vector->rand); msgb_tlv_put(msg, GPRS_GSUP_SRES_IE, - sizeof(auth_tuple->sres), auth_tuple->sres); + sizeof(auth_vector->sres), auth_vector->sres); msgb_tlv_put(msg, GPRS_GSUP_KC_IE, - sizeof(auth_tuple->kc), auth_tuple->kc); + sizeof(auth_vector->kc), auth_vector->kc); /* Update length field */ *len_field = msgb_length(msg) - old_len; @@ -406,14 +406,11 @@ void gprs_gsup_encode(struct msgb *msg, const struct gprs_gsup_message *gsup_msg } } - for (idx = 0; idx < gsup_msg->num_auth_tuples; idx++) { - const struct gsm_auth_tuple *auth_info; + for (idx = 0; idx < gsup_msg->num_auth_vectors; idx++) { + const struct osmo_auth_vector *auth_vector; - auth_info = &gsup_msg->auth_tuples[idx]; + auth_vector = &gsup_msg->auth_vectors[idx]; - if (auth_info->key_seq == GSM_KEY_SEQ_INVAL) - continue; - - encode_auth_info(msg, GPRS_GSUP_AUTH_TUPLE_IE, auth_info); + encode_auth_info(msg, GPRS_GSUP_AUTH_TUPLE_IE, auth_vector); } } diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index 3467293be..678c1de6a 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -199,18 +199,18 @@ static int gprs_subscr_handle_gsup_auth_res(struct gsm_subscriber *subscr, struct sgsn_subscriber_data *sdata = subscr->sgsn_data; LOGGSUBSCRP(LOGL_INFO, subscr, - "Got SendAuthenticationInfoResult, num_auth_tuples = %zu\n", - gsup_msg->num_auth_tuples); + "Got SendAuthenticationInfoResult, num_auth_vectors = %zu\n", + gsup_msg->num_auth_vectors); - if (gsup_msg->num_auth_tuples > 0) { + if (gsup_msg->num_auth_vectors > 0) { memset(sdata->auth_triplets, 0, sizeof(sdata->auth_triplets)); for (idx = 0; idx < ARRAY_SIZE(sdata->auth_triplets); idx++) sdata->auth_triplets[idx].key_seq = GSM_KEY_SEQ_INVAL; } - for (idx = 0; idx < gsup_msg->num_auth_tuples; idx++) { - size_t key_seq = gsup_msg->auth_tuples[idx].key_seq; + for (idx = 0; idx < gsup_msg->num_auth_vectors; idx++) { + size_t key_seq = idx; LOGGSUBSCRP(LOGL_DEBUG, subscr, "Adding auth tuple, cksn = %zu\n", key_seq); if (key_seq >= ARRAY_SIZE(sdata->auth_triplets)) { @@ -219,7 +219,8 @@ static int gprs_subscr_handle_gsup_auth_res(struct gsm_subscriber *subscr, key_seq); continue; } - sdata->auth_triplets[key_seq] = gsup_msg->auth_tuples[idx]; + sdata->auth_triplets[key_seq].vec = gsup_msg->auth_vectors[idx]; + sdata->auth_triplets[key_seq].key_seq = key_seq; } sdata->auth_triplets_updated = 1; diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 3f6116393..50f0e8f6e 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -613,11 +613,11 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, vty_out(vty, " seq # : %d, ", at->key_seq); vty_out(vty, " RAND : %s, ", - osmo_hexdump(at->rand, sizeof(at->rand))); + osmo_hexdump(at->vec.rand, sizeof(at->vec.rand))); vty_out(vty, " SRES : %s, ", - osmo_hexdump(at->sres, sizeof(at->sres))); + osmo_hexdump(at->vec.sres, sizeof(at->vec.sres))); vty_out(vty, " Kc : %s%s", - osmo_hexdump(at->kc, sizeof(at->kc)), + osmo_hexdump(at->vec.kc, sizeof(at->vec.kc)), VTY_NEWLINE); } @@ -704,17 +704,17 @@ DEFUN(update_subscr_insert_auth_triplet, update_subscr_insert_auth_triplet_cmd, OSMO_ASSERT(subscr->sgsn_data); - if (osmo_hexparse(sres_str, &at.sres[0], sizeof(at.sres)) < 0) { + if (osmo_hexparse(sres_str, &at.vec.sres[0], sizeof(at.vec.sres)) < 0) { vty_out(vty, "%% invalid SRES value '%s'%s", sres_str, VTY_NEWLINE); goto failed; } - if (osmo_hexparse(rand_str, &at.rand[0], sizeof(at.rand)) < 0) { + if (osmo_hexparse(rand_str, &at.vec.rand[0], sizeof(at.vec.rand)) < 0) { vty_out(vty, "%% invalid RAND value '%s'%s", rand_str, VTY_NEWLINE); goto failed; } - if (osmo_hexparse(kc_str, &at.kc[0], sizeof(at.kc)) < 0) { + if (osmo_hexparse(kc_str, &at.vec.kc[0], sizeof(at.vec.kc)) < 0) { vty_out(vty, "%% invalid Kc value '%s'%s", kc_str, VTY_NEWLINE); goto failed; diff --git a/openbsc/src/libmsc/auth.c b/openbsc/src/libmsc/auth.c index f30d56dce..9191ae8b3 100644 --- a/openbsc/src/libmsc/auth.c +++ b/openbsc/src/libmsc/auth.c @@ -54,9 +54,9 @@ _use_xor(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple) } for (i=0; i<4; i++) - atuple->sres[i] = atuple->rand[i] ^ ainfo->a3a8_ki[i]; + atuple->vec.sres[i] = atuple->vec.rand[i] ^ ainfo->a3a8_ki[i]; for (i=4; i<12; i++) - atuple->kc[i-4] = atuple->rand[i] ^ ainfo->a3a8_ki[i]; + atuple->vec.kc[i-4] = atuple->vec.rand[i] ^ ainfo->a3a8_ki[i]; return 0; } @@ -71,7 +71,7 @@ _use_comp128_v1(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple) return -1; } - comp128(ainfo->a3a8_ki, atuple->rand, atuple->sres, atuple->kc); + comp128(ainfo->a3a8_ki, atuple->vec.rand, atuple->vec.sres, atuple->vec.kc); return 0; } @@ -122,7 +122,7 @@ int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple, } atuple->use_count = 1; - if (RAND_bytes(atuple->rand, sizeof(atuple->rand)) != 1) { + if (RAND_bytes(atuple->vec.rand, sizeof(atuple->vec.rand)) != 1) { LOGP(DMM, LOGL_NOTICE, "RAND_bytes failed, can't generate new auth tuple\n"); return AUTH_ERROR; } diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index 267b5ef41..a23ec89ae 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -700,25 +700,25 @@ int db_get_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple, atuple->key_seq = dbi_result_get_ulonglong(result, "key_seq"); len = dbi_result_get_field_length(result, "rand"); - if (len != sizeof(atuple->rand)) + if (len != sizeof(atuple->vec.rand)) goto err_size; blob = dbi_result_get_binary(result, "rand"); - memcpy(atuple->rand, blob, len); + memcpy(atuple->vec.rand, blob, len); len = dbi_result_get_field_length(result, "sres"); - if (len != sizeof(atuple->sres)) + if (len != sizeof(atuple->vec.sres)) goto err_size; blob = dbi_result_get_binary(result, "sres"); - memcpy(atuple->sres, blob, len); + memcpy(atuple->vec.sres, blob, len); len = dbi_result_get_field_length(result, "kc"); - if (len != sizeof(atuple->kc)) + if (len != sizeof(atuple->vec.kc)) goto err_size; blob = dbi_result_get_binary(result, "kc"); - memcpy(atuple->kc, blob, len); + memcpy(atuple->vec.kc, blob, len); dbi_result_free(result); @@ -759,11 +759,11 @@ int db_sync_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple, /* Update / Insert */ dbi_conn_quote_binary_copy(conn, - atuple->rand, sizeof(atuple->rand), &rand_str); + atuple->vec.rand, sizeof(atuple->vec.rand), &rand_str); dbi_conn_quote_binary_copy(conn, - atuple->sres, sizeof(atuple->sres), &sres_str); + atuple->vec.sres, sizeof(atuple->vec.sres), &sres_str); dbi_conn_quote_binary_copy(conn, - atuple->kc, sizeof(atuple->kc), &kc_str); + atuple->vec.kc, sizeof(atuple->vec.kc), &kc_str); if (!upd) { result = dbi_conn_queryf(conn, diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 05cb88679..f02f784fe 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -234,11 +234,11 @@ int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq, /* Then do whatever is needed ... */ if (rc == AUTH_DO_AUTH_THEN_CIPH) { /* Start authentication */ - return gsm48_tx_mm_auth_req(conn, op->atuple.rand, op->atuple.key_seq); + return gsm48_tx_mm_auth_req(conn, op->atuple.vec.rand, op->atuple.key_seq); } else if (rc == AUTH_DO_CIPH) { /* Start ciphering directly */ return gsm0808_cipher_mode(conn, net->a5_encryption, - op->atuple.kc, 8, 0); + op->atuple.vec.kc, 8, 0); } return -EINVAL; /* not reached */ @@ -1102,12 +1102,12 @@ static int gsm48_rx_mm_auth_resp(struct gsm_subscriber_connection *conn, struct } /* Validate SRES */ - if (memcmp(conn->sec_operation->atuple.sres, ar->sres,4)) { + if (memcmp(conn->sec_operation->atuple.vec.sres, ar->sres,4)) { int rc; gsm_cbfn *cb = conn->sec_operation->cb; DEBUGPC(DMM, "Invalid (expected %s)\n", - osmo_hexdump(conn->sec_operation->atuple.sres, 4)); + osmo_hexdump(conn->sec_operation->atuple.vec.sres, 4)); if (cb) cb(GSM_HOOK_RR_SECURITY, GSM_SECURITY_AUTH_FAILED, @@ -1122,7 +1122,7 @@ static int gsm48_rx_mm_auth_resp(struct gsm_subscriber_connection *conn, struct /* Start ciphering */ return gsm0808_cipher_mode(conn, net->a5_encryption, - conn->sec_operation->atuple.kc, 8, 0); + conn->sec_operation->atuple.vec.kc, 8, 0); } /* Receive a GSM 04.08 Mobility Management (MM) message */ diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 790fedf39..4c2088a0f 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -94,13 +94,13 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr) vty_out(vty, " seq # : %d%s", atuple.key_seq, VTY_NEWLINE); vty_out(vty, " RAND : %s%s", - osmo_hexdump(atuple.rand, sizeof(atuple.rand)), + osmo_hexdump(atuple.vec.rand, sizeof(atuple.vec.rand)), VTY_NEWLINE); vty_out(vty, " SRES : %s%s", - osmo_hexdump(atuple.sres, sizeof(atuple.sres)), + osmo_hexdump(atuple.vec.sres, sizeof(atuple.vec.sres)), VTY_NEWLINE); vty_out(vty, " Kc : %s%s", - osmo_hexdump(atuple.kc, sizeof(atuple.kc)), + osmo_hexdump(atuple.vec.kc, sizeof(atuple.vec.kc)), VTY_NEWLINE); } diff --git a/openbsc/tests/mm_auth/mm_auth_test.c b/openbsc/tests/mm_auth/mm_auth_test.c index 34d96f187..b8777a8c5 100644 --- a/openbsc/tests/mm_auth/mm_auth_test.c +++ b/openbsc/tests/mm_auth/mm_auth_test.c @@ -26,9 +26,9 @@ static char *auth_tuple_str(struct gsm_auth_tuple *atuple) print2buf("gsm_auth_tuple {\n"); print2buf(" .use_count = %d\n", atuple->use_count); print2buf(" .key_seq = %d\n", atuple->key_seq); - print2buf(" .rand = %s\n", osmo_hexdump(atuple->rand, sizeof(atuple->rand))); - print2buf(" .sres = %s\n", osmo_hexdump(atuple->sres, sizeof(atuple->sres))); - print2buf(" .kc = %s\n", osmo_hexdump(atuple->kc, sizeof(atuple->kc))); + print2buf(" .rand = %s\n", osmo_hexdump(atuple->vec.rand, sizeof(atuple->vec.rand))); + print2buf(" .sres = %s\n", osmo_hexdump(atuple->vec.sres, sizeof(atuple->vec.sres))); + print2buf(" .kc = %s\n", osmo_hexdump(atuple->vec.kc, sizeof(atuple->vec.kc))); print2buf("}\n"); #undef print2buf diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 1acd6f2f8..fe41e759b 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -1132,7 +1132,7 @@ static void test_gmm_attach_subscr_fake_auth(void) int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx) { struct gsm_auth_tuple at = { - .sres = {0x51, 0xe5, 0x51, 0xe5}, + .vec.sres = {0x51, 0xe5, 0x51, 0xe5}, .key_seq = 0 };