[PATCH] openbsc[master]: SGSN: move cipher application to separate function

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/.

Max gerrit-no-reply at lists.osmocom.org
Mon Jul 11 10:58:28 UTC 2016


Review at  https://gerrit.osmocom.org/493

SGSN: move cipher application to separate function

Split out generation and application of GEA gamma into separate function
which can be used for both encryption and decryption.

Change-Id: I442f2ead57e40d9bcd24e7f1b261041371595360
Related: OS#1582
---
M openbsc/src/gprs/gprs_llc.c
1 file changed, 42 insertions(+), 41 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/93/493/1

diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c
index 1519111..6efa662 100644
--- a/openbsc/src/gprs/gprs_llc.c
+++ b/openbsc/src/gprs/gprs_llc.c
@@ -345,6 +345,40 @@
 	return gprs_llc_tx_u(msg, lle->sapi, command, GPRS_LLC_U_XID, 1);
 }
 
+/* encrypt information field + FCS, if needed! */
+static int apply_gea(struct gprs_llc_lle *lle, uint16_t crypt_len, uint16_t nu,
+		     uint32_t oc, uint8_t sapi, uint8_t *fcs, uint8_t *data)
+{
+	uint8_t cipher_out[GSM0464_CIPH_MAX_BLOCK];
+
+	if (lle->llme->algo == GPRS_ALGO_GEA0)
+		return -EINVAL;
+
+	/* Compute the 'Input' Paraemeter */
+	uint32_t iv = gprs_cipher_gen_input_ui(lle->llme->iov_ui, sapi,
+							 nu, oc);
+	/* Compute gamma that we need to XOR with the data */
+	int r = gprs_cipher_run(cipher_out, crypt_len, lle->llme->algo,
+				lle->llme->kc, iv,
+				fcs ? GPRS_CIPH_SGSN2MS : GPRS_CIPH_MS2SGSN);
+	if (r < 0) {
+		LOGP(DLLC, LOGL_ERROR, "Error producing %s gamma for UI "
+		     "frame: %d\n", get_value_string(gprs_cipher_names,
+						     lle->llme->algo), r);
+		return -ENOMSG;
+	}
+
+	if (fcs) {
+		data += 3;
+	}
+
+	/* XOR the cipher output with the data */
+	for (r = 0; r < crypt_len; r++)
+		*(data + r) ^= cipher_out[r];
+
+	return 0;
+}
+
 /* Transmit a UI frame over the given SAPI:
    'encryptable' indicates whether particular message can be encrypted according
    to 3GPP TS 24.008 § 4.7.1.2
@@ -410,30 +444,12 @@
 	fcs[1] = (fcs_calc >> 8) & 0xff;
 	fcs[2] = (fcs_calc >> 16) & 0xff;
 
-	/* encrypt information field + FCS, if needed! */
 	if (lle->llme->algo != GPRS_ALGO_GEA0 && encryptable) {
-		uint32_t iov_ui = 0; /* FIXME: randomly select for TLLI */
-		uint16_t crypt_len = (fcs + 3) - (llch + 3);
-		uint8_t cipher_out[GSM0464_CIPH_MAX_BLOCK];
-		uint32_t iv;
-		int rc, i;
-		uint8_t *kc = lle->llme->kc;
-
-		/* Compute the 'Input' Paraemeter */
-		iv = gprs_cipher_gen_input_ui(iov_ui, sapi, nu, oc);
-
-		/* Compute the keystream that we need to XOR with the data */
-		rc = gprs_cipher_run(cipher_out, crypt_len, lle->llme->algo,
-				     kc, iv, GPRS_CIPH_SGSN2MS);
+		int rc = apply_gea(lle, fcs - llch, nu, oc, sapi, fcs, llch);
 		if (rc < 0) {
-			LOGP(DLLC, LOGL_ERROR, "Error crypting UI frame: %d\n", rc);
 			msgb_free(msg);
 			return rc;
 		}
-
-		/* XOR the cipher output with the information field + FCS */
-		for (i = 0; i < crypt_len; i++)
-			*(llch + 3 + i) ^= cipher_out[i];
 
 		/* Mark frame as encrypted */
 		ctrl[1] |= 0x02;
@@ -615,32 +631,17 @@
 
 	/* decrypt information field + FCS, if needed! */
 	if (llhp.is_encrypted) {
-		uint32_t iov_ui = 0; /* FIXME: randomly select for TLLI */
-		uint16_t crypt_len = llhp.data_len + 3;
-		uint8_t cipher_out[GSM0464_CIPH_MAX_BLOCK];
-		uint32_t iv;
-		uint8_t *kc = lle->llme->kc;
-		int rc, i;
-
-		if (lle->llme->algo == GPRS_ALGO_GEA0) {
+		if (lle->llme->algo != GPRS_ALGO_GEA0) {
+			rc = apply_gea(lle, llhp.data_len + 3, llhp.seq_tx,
+				       lle->oc_ui_recv, lle->sapi, NULL,
+				       llhp.data);
+			if (rc < 0)
+				return rc;
+		} else {
 			LOGP(DLLC, LOGL_NOTICE, "encrypted frame for LLC that "
 				"has no KC/Algo! Dropping.\n");
 			return 0;
 		}
-
-		iv = gprs_cipher_gen_input_ui(iov_ui, lle->sapi, llhp.seq_tx,
-						lle->oc_ui_recv);
-		rc = gprs_cipher_run(cipher_out, crypt_len, lle->llme->algo,
-				     kc, iv, GPRS_CIPH_MS2SGSN);
-		if (rc < 0) {
-			LOGP(DLLC, LOGL_ERROR, "Error decrypting frame: %d\n",
-			     rc);
-			return rc;
-		}
-
-		/* XOR the cipher output with the information field + FCS */
-		for (i = 0; i < crypt_len; i++)
-			*(llhp.data + i) ^= cipher_out[i];
 	} else {
 		if (lle->llme->algo != GPRS_ALGO_GEA0 &&
 		    lle->llme->cksn != GSM_KEY_SEQ_INVAL)

-- 
To view, visit https://gerrit.osmocom.org/493
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I442f2ead57e40d9bcd24e7f1b261041371595360
Gerrit-PatchSet: 1
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>



More information about the gerrit-log mailing list