Change in osmo-msc[master]: [WIP] a5/4 support

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Hoernchen gerrit-no-reply at lists.osmocom.org
Wed Jun 9 02:05:03 UTC 2021


Hoernchen has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-msc/+/24633 )


Change subject: [WIP] a5/4 support
......................................................................

[WIP] a5/4 support

Change-Id: I1b3136f0b2728013677b62647c033aade2933299
Related: SYS#5324
---
M include/osmocom/msc/msc_common.h
M include/osmocom/msc/ran_msg.h
M src/libmsc/msc_ho.c
M src/libmsc/ran_msg_a.c
4 files changed, 61 insertions(+), 7 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/33/24633/1

diff --git a/include/osmocom/msc/msc_common.h b/include/osmocom/msc/msc_common.h
index 8a43e69..20f5d15 100644
--- a/include/osmocom/msc/msc_common.h
+++ b/include/osmocom/msc/msc_common.h
@@ -32,6 +32,7 @@
 	uint8_t alg_id;
 	uint8_t key_len;
 	uint8_t key[MAX_A5_KEY_LEN];
+	uint8_t kc128[MAX_A5_KEY_LEN];
 };
 
 enum complete_layer3_type {
diff --git a/include/osmocom/msc/ran_msg.h b/include/osmocom/msc/ran_msg.h
index 1303ba3..772d1ec 100644
--- a/include/osmocom/msc/ran_msg.h
+++ b/include/osmocom/msc/ran_msg.h
@@ -118,6 +118,7 @@
 		 * alg_id == 1 means A5/0 i.e. no encryption, alg_id == 4 means A5/3.
 		 * alg_id == 0 means no such IE was present. */
 		struct geran_encr *chosen_encryption;
+		bool umts_aka;
 	} geran;
 	struct gsm0808_cell_id cell_id_serving;
 	struct gsm0808_cell_id cell_id_target;
diff --git a/src/libmsc/msc_ho.c b/src/libmsc/msc_ho.c
index d89a24c..7a8db3f 100644
--- a/src/libmsc/msc_ho.c
+++ b/src/libmsc/msc_ho.c
@@ -392,6 +392,7 @@
 			.geran = {
 				.chosen_encryption = &msc_a->geran_encr,
 				.a5_encryption_mask = net->a5_encryption_mask,
+				.umts_aka = vsub->sec_ctx == VLR_SEC_CTX_UMTS  ? true : false,
 			},
 			.bssap_cause = GSM0808_CAUSE_BETTER_CELL,
 			.current_channel_type_1_present = msc_a->ho.info.current_channel_type_1_present,
diff --git a/src/libmsc/ran_msg_a.c b/src/libmsc/ran_msg_a.c
index 4cce289..477e5d9 100644
--- a/src/libmsc/ran_msg_a.c
+++ b/src/libmsc/ran_msg_a.c
@@ -25,6 +25,7 @@
 #include <osmocom/core/byteswap.h>
 
 #include <osmocom/crypt/auth.h>
+#include <osmocom/crypt/kdf.h>
 
 #include <osmocom/gsm/tlv.h>
 #include <osmocom/gsm/gsm0808.h>
@@ -482,6 +483,7 @@
 	const struct tlv_p_entry *ie_aoip_transp_addr = TLVP_GET(tp, GSM0808_IE_AOIP_TRASP_ADDR);
 	const struct tlv_p_entry *ie_codec_list_msc_preferred = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC_LIST);
 	const struct tlv_p_entry *ie_call_id = TLVP_GET(tp, GSM0808_IE_CALL_ID);
+	const struct tlv_p_entry *ie_kc128 = TLVP_GET(tp, GSM0808_IE_KC_128);
 	const struct tlv_p_entry *ie_global_call_ref = TLVP_GET(tp, GSM0808_IE_GLOBAL_CALL_REF);
 
 	struct gsm0808_channel_type channel_type;
@@ -524,6 +526,16 @@
 			geran_encr.key_len = encr_info.key_len;
 		}
 
+		if(r->geran.a5_encryption_mask & (1 << 4)) {
+			if (ie_kc128) {
+				memcpy(geran_encr.kc128, ie_kc128->val, 16);
+			} else {
+				LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Encryption Information IE:"
+					  " A5/4 supported, but missing kc128 IE!\n");
+				return -EINVAL;
+			}
+		}
+
 		r->geran.chosen_encryption = &geran_encr;
 	}
 
@@ -1019,13 +1031,16 @@
 	case 3:
 		*dst = GSM0808_ALG_ID_A5_3;
 		return 0;
+	case 4:
+		*dst = GSM0808_ALG_ID_A5_4;
+		return 0;
 	default:
 		return -ENOTSUP;
 	}
 }
 
 static int make_encrypt_info_perm_algo(struct osmo_fsm_inst *fi, struct gsm0808_encrypt_info *ei,
-				       uint8_t a5_encryption_mask, const struct osmo_gsm48_classmark *cm)
+					   uint8_t a5_encryption_mask, const struct osmo_gsm48_classmark *cm, bool umts_aka)
 {
 	int i;
 	int j = 0;
@@ -1036,6 +1051,10 @@
 		if (!(a5_encryption_mask & (1 << i)))
 			continue;
 
+		/* no a5/4 without umts aka */
+		if(i > 3 && !umts_aka)
+			continue;
+
 		/* A5/n supported by MS? */
 		supported = osmo_gsm48_classmark_supports_a5(cm, i);
 		if (supported != 1)
@@ -1056,13 +1075,17 @@
  */
 osmo_static_assert(sizeof(((struct gsm0808_encrypt_info*)0)->key) >= sizeof(((struct osmo_auth_vector*)0)->kc),
 		   gsm0808_encrypt_info_key_fits_osmo_auth_vec_kc);
+
 static struct msgb *ran_a_make_cipher_mode_command(struct osmo_fsm_inst *fi, const struct ran_cipher_mode_command *cm)
 {
 	struct gsm0808_encrypt_info ei = {};
 	char buf[16 * 2 + 1];
 	const uint8_t cipher_response_mode = 1;
+	uint8_t kc128[16];
+	bool has_a54 = false;
+	int i;
 
-	if (make_encrypt_info_perm_algo(fi, &ei, cm->geran.a5_encryption_mask, cm->classmark))
+	if (make_encrypt_info_perm_algo(fi, &ei, cm->geran.a5_encryption_mask, cm->classmark, cm->geran.umts_aka))
 		return NULL;
 
 	if (ei.perm_algo_len == 0) {
@@ -1072,13 +1095,23 @@
 		return NULL;
 	}
 
+	for( i= 0; i < ei.perm_algo_len; i++) {
+		has_a54 = ei.perm_algo[i] == GSM0808_ALG_ID_A5_4;
+		if (has_a54)
+			break;
+	}
+
 	/* In case of UMTS AKA, the Kc for ciphering must be derived from the 3G auth
 	 * tokens.  vec->kc was calculated from the GSM algorithm and is not
 	 * necessarily a match for the UMTS AKA tokens. */
-	if (cm->geran.umts_aka)
+	if (cm->geran.umts_aka) {
 		osmo_auth_c3(ei.key, cm->vec->ck, cm->vec->ik);
-	else
+
+		/* unconditionally derive key if aka, due to HO req */
+		osmo_kdf_kc128(cm->vec->ck, cm->vec->ik, kc128);
+	} else {
 		memcpy(ei.key, cm->vec->kc, sizeof(cm->vec->kc));
+	}
 	ei.key_len = sizeof(cm->vec->kc);
 
 	/* Store chosen GERAN key where the caller asked it to be stored.
@@ -1090,12 +1123,16 @@
 		}
 		memcpy(cm->geran.chosen_key->key, ei.key, ei.key_len);
 		cm->geran.chosen_key->key_len = ei.key_len;
+
+		if (cm->geran.umts_aka)
+			memcpy(cm->geran.chosen_key->kc128, kc128, 16);
 	}
 
+
 	LOG_RAN_A_ENC(fi, LOGL_DEBUG, "Tx BSSMAP CIPHER MODE COMMAND to BSC, %u ciphers (%s) key %s\n",
 		       ei.perm_algo_len, osmo_hexdump_nospc(ei.perm_algo, ei.perm_algo_len),
 		       osmo_hexdump_buf(buf, sizeof(buf), ei.key, ei.key_len, NULL, false));
-	return gsm0808_create_cipher(&ei, cm->geran.retrieve_imeisv ? &cipher_response_mode : NULL);
+	return gsm0808_create_cipher(&ei, has_a54 ? kc128 : NULL, cm->geran.retrieve_imeisv ? &cipher_response_mode : NULL);
 }
 
 struct msgb *ran_a_make_handover_request(struct osmo_fsm_inst *log_fi, const struct ran_handover_request *n)
@@ -1120,6 +1157,9 @@
 		.global_call_reference = n->global_call_reference,
 		.global_call_reference_len = n->global_call_reference_len,
 	};
+	bool has_a54_in_set = false;
+	uint8_t kc128[16];
+	int i;
 
 	if (!n->geran.channel_type) {
 		LOG_RAN_A_ENC(log_fi, LOGL_ERROR, "Channel Type required for encoding Handover Request in BSSAP\n");
@@ -1128,7 +1168,15 @@
 	r.channel_type = *n->geran.channel_type;
 
 	/* Encryption Information */
-	make_encrypt_info_perm_algo(log_fi, &r.encryption_information, n->geran.a5_encryption_mask, n->classmark);
+	make_encrypt_info_perm_algo(log_fi, &r.encryption_information, n->geran.a5_encryption_mask, n->classmark, n->geran.umts_aka);
+
+	/* kc128 is only included if intersection offers a5/4 */
+	for( i= 0; i < r.encryption_information.perm_algo_len; i++) {
+		has_a54_in_set = r.encryption_information.perm_algo[i] == GSM0808_ALG_ID_A5_4;
+		if (has_a54_in_set)
+			break;
+	}
+
 	if (n->geran.chosen_encryption && n->geran.chosen_encryption->key_len) {
 		/* Prevent both source / destination buffer overrun / overflow */
 		if (n->geran.chosen_encryption->key_len > sizeof(r.encryption_information.key)
@@ -1141,6 +1189,9 @@
 		       n->geran.chosen_encryption->key, n->geran.chosen_encryption->key_len);
 		r.encryption_information.key_len = n->geran.chosen_encryption->key_len;
 		r.chosen_encryption_algorithm_serving = n->geran.chosen_encryption->alg_id;
+
+        if (has_a54_in_set)
+            memcpy(kc128, n->geran.chosen_encryption->kc128, 16);
 	}
 
 	if (n->classmark)
@@ -1156,7 +1207,7 @@
 		r.aoip_transport_layer = &ss;
 	}
 
-	return gsm0808_create_handover_request(&r);
+	return gsm0808_create_handover_request(&r, has_a54_in_set ? kc128 : NULL);
 }
 
 static struct msgb *ran_a_make_handover_request_ack(struct osmo_fsm_inst *caller_fi, const struct ran_handover_request_ack *r)

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-msc/+/24633
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-Change-Id: I1b3136f0b2728013677b62647c033aade2933299
Gerrit-Change-Number: 24633
Gerrit-PatchSet: 1
Gerrit-Owner: Hoernchen <ewild at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210609/7e5cc6a1/attachment.htm>


More information about the gerrit-log mailing list