<p>Stefan Sperling has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/12349">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">improve handling of BSC-chosen algo in CIPHER MODE COMPLETE<br><br>The BSC may choose to omit the chosenEntryptionAlgorithm IE in<br>the CIPHER MODE COMPLETE command. When this happens, we used to<br>default to A5/1 and disregarded the list of ciphers which we<br>requested in the CIPHER MODE CMD. Fall back to the best cipher<br>instead of hard-coding a fallback to A5/1.<br><br>If the BSC does specify an algorithm, ensure that the chosen value<br>falls within the range allowed by GSM 04.08, and ensure that the<br>chosen value matches one of the values we sent in CIPHER MODE CMD.<br><br>Change-Id: I3260bee43cfe135ebfc33c13aee3c4ba43466c81<br>Related: OS#2872<br>---<br>M include/osmocom/msc/gsm_04_08.h<br>M src/libmsc/a_iface_bssap.c<br>M src/libmsc/gsm_04_08.c<br>3 files changed, 53 insertions(+), 5 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/49/12349/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/msc/gsm_04_08.h b/include/osmocom/msc/gsm_04_08.h</span><br><span>index 5ff16de..79f7e0f 100644</span><br><span>--- a/include/osmocom/msc/gsm_04_08.h</span><br><span>+++ b/include/osmocom/msc/gsm_04_08.h</span><br><span>@@ -77,5 +77,7 @@</span><br><span> </span><br><span> int gsm48_tch_rtp_create(struct gsm_trans *trans);</span><br><span> int gsm48_conn_sendmsg(struct msgb *msg, struct ran_conn *conn, struct gsm_trans *trans);</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_classmark;</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm48_classmark_supports_a5(const struct gsm_classmark *cm, uint8_t a5);</span><br><span> </span><br><span> #endif</span><br><span>diff --git a/src/libmsc/a_iface_bssap.c b/src/libmsc/a_iface_bssap.c</span><br><span>index d84a234..69824c7 100644</span><br><span>--- a/src/libmsc/a_iface_bssap.c</span><br><span>+++ b/src/libmsc/a_iface_bssap.c</span><br><span>@@ -35,6 +35,7 @@</span><br><span> #include <osmocom/msc/a_reset.h></span><br><span> #include <osmocom/msc/transaction.h></span><br><span> #include <osmocom/msc/msc_mgcp.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/msc/gsm_04_08.h></span><br><span> </span><br><span> #include <errno.h></span><br><span> </span><br><span>@@ -386,14 +387,59 @@</span><br><span>      * is not able to deal with msg = NULL and apperently</span><br><span>         * ran_conn_cipher_mode_compl() was never meant to be used without L3 data.</span><br><span>   * This needs to be discussed further! */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t alg_id = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm_network *net = conn->network;</span><br><span style="color: hsl(120, 100%, 40%);">+   int alg_id = -1;</span><br><span>     struct rate_ctr_group *msc = conn->network->msc_ctrs;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm0808_encrypt_info ei = { 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+       int i, j = 0;</span><br><span> </span><br><span>    LOGPCONN(conn, LOGL_DEBUG, "Rx BSSMAP CIPHER MODE COMPLETE\n");</span><br><span> </span><br><span>        if (TLVP_PRESENT(tp, GSM0808_IE_CHOSEN_ENCR_ALG)) {</span><br><span style="color: hsl(0, 100%, 40%);">-             alg_id = TLVP_VAL(tp, GSM0808_IE_CHOSEN_ENCR_ALG)[0] - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             uint8_t val = TLVP_VAL(tp, GSM0808_IE_CHOSEN_ENCR_ALG)[0];</span><br><span style="color: hsl(120, 100%, 40%);">+            if (val < GSM0808_ALG_ID_A5_0 || val > GSM0808_ALG_ID_A5_7) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   LOGPCONN(conn, LOGL_ERROR, "Invalid encryption algorithm in CIPHER MODE COMPLETE: 0x%x\n", val);</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             alg_id = val - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* The BSC did not choose an algorithm. We sort this out below. */</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Recompute the ENCRYPTION INFORMATION IE we sent in CIPHER MODE CMD. */</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < 8; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          int supported;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              /* A5/n permitted by osmo-msc.cfg? */</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!(net->a5_encryption_mask & (1 << i)))</span><br><span style="color: hsl(120, 100%, 40%);">+                       continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* A5/n supported by MS? */</span><br><span style="color: hsl(120, 100%, 40%);">+           supported = gsm48_classmark_supports_a5(&conn->vsub->classmark, i);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (supported == 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                   ei.perm_algo[j++] = vlr_ciph_to_gsm0808_alg_id(i);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     ei.perm_algo_len = j;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (alg_id == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+           if (ei.perm_algo_len > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        /* Pick the best available algorithm. */</span><br><span style="color: hsl(120, 100%, 40%);">+                      alg_id = ei.perm_algo[ei.perm_algo_len - 1] - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+              } else</span><br><span style="color: hsl(120, 100%, 40%);">+                        alg_id = VLR_CIPH_NONE;</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGPCONN(conn, LOGL_NOTICE, "BSC didn't specify algorithm in CIHPER MODE COMPLETE; falling back to A5/%d\n", alg_id);</span><br><span style="color: hsl(120, 100%, 40%);">+   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              int chosen = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+              for (j = 0; j < ei.perm_algo_len; j++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (ei.perm_algo[j] == alg_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              chosen = j;</span><br><span style="color: hsl(120, 100%, 40%);">+                           break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (chosen == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   LOGPCONN(conn, LOGL_ERROR, "Unsupported encryption algorithm in CIHPER MODE COMPLETE: A5/%d\n", alg_id);</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span>    }</span><br><span> </span><br><span>        if (TLVP_PRESENT(tp, GSM0808_IE_LAYER_3_MESSAGE_CONTENTS)) {</span><br><span>diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c</span><br><span>index dc0476b..bfad853 100644</span><br><span>--- a/src/libmsc/gsm_04_08.c</span><br><span>+++ b/src/libmsc/gsm_04_08.c</span><br><span>@@ -122,7 +122,7 @@</span><br><span>  * Return 1 when the given A5/n is permitted, 0 when not, and negative if the respective MS CLASSMARK is</span><br><span>  * not known, where the negative number indicates the classmark type: -2 means Classmark 2 is not</span><br><span>  * available. */</span><br><span style="color: hsl(0, 100%, 40%);">-static int classmark_supports_a5(const struct gsm_classmark *cm, uint8_t a5)</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm48_classmark_supports_a5(const struct gsm_classmark *cm, uint8_t a5)</span><br><span> {</span><br><span>   switch (a5) {</span><br><span>        case 0:</span><br><span>@@ -1618,7 +1618,7 @@</span><br><span>                      continue;</span><br><span> </span><br><span>                /* A5/n supported by MS? */</span><br><span style="color: hsl(0, 100%, 40%);">-             supported = classmark_supports_a5(&conn->vsub->classmark, i);</span><br><span style="color: hsl(120, 100%, 40%);">+               supported = gsm48_classmark_supports_a5(&conn->vsub->classmark, i);</span><br><span>                if (supported == 1) {</span><br><span>                        ei.perm_algo[j++] = vlr_ciph_to_gsm0808_alg_id(i);</span><br><span>                   /* A higher A5/n is supported, so no need to request a Classmark</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12349">change 12349</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/12349"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-msc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I3260bee43cfe135ebfc33c13aee3c4ba43466c81 </div>
<div style="display:none"> Gerrit-Change-Number: 12349 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Stefan Sperling <stsp@stsp.name> </div>