<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/7310">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved; Verified
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">libosmogsm: add support for XOR authentication<br><br>Change-Id: I1afaf0a9e2dce43aec87964bacefb21ed4d3d565<br>Related: OS#2475<br>---<br>M src/gsm/Makefile.am<br>A src/gsm/auth_xor.c<br>2 files changed, 188 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am</span><br><span>index 0aa0de3..f13ba9d 100644</span><br><span>--- a/src/gsm/Makefile.am</span><br><span>+++ b/src/gsm/Makefile.am</span><br><span>@@ -26,7 +26,7 @@</span><br><span>                  gprs_cipher_core.c gprs_rlc.c gsm0480.c abis_nm.c gsm0502.c \</span><br><span>                        gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c gsm0414.c \</span><br><span>                      lapd_core.c lapdm.c kasumi.c gsm29205.c gsm_04_08_gprs.c \</span><br><span style="color: hsl(0, 100%, 40%);">-                      auth_core.c auth_comp128v1.c auth_comp128v23.c \</span><br><span style="color: hsl(120, 100%, 40%);">+                      auth_core.c auth_comp128v1.c auth_comp128v23.c auth_xor.c \</span><br><span>                  auth_milenage.c milenage/aes-encblock.c gea.c \</span><br><span>                      milenage/aes-internal.c milenage/aes-internal-enc.c \</span><br><span>                        milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \</span><br><span>diff --git a/src/gsm/auth_xor.c b/src/gsm/auth_xor.c</span><br><span>new file mode 100644</span><br><span>index 0000000..36e006e</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/auth_xor.c</span><br><span>@@ -0,0 +1,187 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \file auth_xor.c</span><br><span style="color: hsl(120, 100%, 40%);">+ * GSM/GPRS/3G authentication core infrastructure */</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2018 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2017 by sysmocom s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Daniel Willmann <dwillmann@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/bit64gen.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/crypt/auth.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \addtogroup auth</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void xor(uint8_t *out, const uint8_t *a, const uint8_t *b, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   size_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   for (i = 0; i < len; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+          out[i] = a[i] ^ b[i];</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%);">+/* 3GPP TS 34.108, section 8.1.2.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+static int xor_gen_vec(struct osmo_auth_vector *vec,</span><br><span style="color: hsl(120, 100%, 40%);">+                      struct osmo_sub_auth_data *aud,</span><br><span style="color: hsl(120, 100%, 40%);">+                       const uint8_t *_rand)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t xdout[16], cdout[8];</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t ak[6], xmac[8];</span><br><span style="color: hsl(120, 100%, 40%);">+       int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Step 1: xdout = (ki or k) ^ rand */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (aud->type == OSMO_AUTH_TYPE_GSM)</span><br><span style="color: hsl(120, 100%, 40%);">+               xor(xdout, aud->u.gsm.ki, _rand, sizeof(xdout));</span><br><span style="color: hsl(120, 100%, 40%);">+   else if (aud->type == OSMO_AUTH_TYPE_UMTS)</span><br><span style="color: hsl(120, 100%, 40%);">+         xor(xdout, aud->u.umts.k, _rand, sizeof(xdout));</span><br><span style="color: hsl(120, 100%, 40%);">+   else</span><br><span style="color: hsl(120, 100%, 40%);">+          return -ENOTSUP;</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%);">+    * Step 2: res = xdout</span><br><span style="color: hsl(120, 100%, 40%);">+         *</span><br><span style="color: hsl(120, 100%, 40%);">+     * Suggested length for res is 128 bits, i.e. 16 bytes,</span><br><span style="color: hsl(120, 100%, 40%);">+        * but also can be in range: 30 < n < 128 bits.</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+   memcpy(vec->res, xdout, sizeof(xdout));</span><br><span style="color: hsl(120, 100%, 40%);">+    vec->res_len = sizeof(xdout);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* ck = xdout[1-15,0] */</span><br><span style="color: hsl(120, 100%, 40%);">+      memcpy(vec->ck, xdout + 1, sizeof(xdout) - 1);</span><br><span style="color: hsl(120, 100%, 40%);">+     vec->ck[15] = xdout[0];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* ik = xdout[2-15,0-1] */</span><br><span style="color: hsl(120, 100%, 40%);">+    memcpy(vec->ik, xdout + 2, sizeof(xdout) - 2);</span><br><span style="color: hsl(120, 100%, 40%);">+     memcpy(vec->ik + sizeof(xdout) - 2, xdout, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* ak = xdout[3-8] */</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(ak, xdout + 3, sizeof(ak));</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%);">+    * 3GPP TS 33.102, clause 6.8.1.2, b</span><br><span style="color: hsl(120, 100%, 40%);">+   * sres = c2(res) = res[0-3] ^ res[4-7] ^ res[8-11] ^ res[12-15]</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+   for (i = 0; i < 4; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          vec->sres[i]  = vec->res[i] ^ vec->res[i + 4];</span><br><span style="color: hsl(120, 100%, 40%);">+               vec->sres[i] ^= vec->res[i + 8] ^ vec->res[i + 12];</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%);">+   /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * 3GPP TS 33.102, clause 6.8.1.2, c</span><br><span style="color: hsl(120, 100%, 40%);">+   * kc = c3(ck, ik) = ck[0-7] ^ ck[8-15] ^ ik[0-7] ^ ik[8-15]</span><br><span style="color: hsl(120, 100%, 40%);">+   * FIXME: do we really have CK/IK for GSM?</span><br><span style="color: hsl(120, 100%, 40%);">+     */</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_auth_c3(vec->kc, vec->ck, vec->ik);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* The further part is UMTS specific */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (aud->type != OSMO_AUTH_TYPE_UMTS) {</span><br><span style="color: hsl(120, 100%, 40%);">+            vec->auth_types = OSMO_AUTH_TYPE_GSM;</span><br><span style="color: hsl(120, 100%, 40%);">+              return 0;</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%);">+   /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * Step 3: cdout = sqn[0-5] || amf[0-1]</span><br><span style="color: hsl(120, 100%, 40%);">+        * NOTE (for USIM): sqn[0-5] = autn[0-5] ^ ak[0-5]</span><br><span style="color: hsl(120, 100%, 40%);">+     */</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_store64be_ext(aud->u.umts.sqn, cdout, 6);</span><br><span style="color: hsl(120, 100%, 40%);">+     memcpy(cdout + 6, aud->u.umts.amf, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Step 4: xmac = xdout[0-8] ^ cdout[0-8] */</span><br><span style="color: hsl(120, 100%, 40%);">+  xor(xmac, xdout, cdout, sizeof(xmac));</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%);">+    * Step 5: autn = sqn ^ ak || amf || mac</span><br><span style="color: hsl(120, 100%, 40%);">+       * NOTE: cdout still contains SQN from step 3</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+   xor(vec->autn, cdout, ak, sizeof(ak));</span><br><span style="color: hsl(120, 100%, 40%);">+     memcpy(vec->autn + 6, aud->u.umts.amf, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+      memcpy(vec->autn + 8, xmac, sizeof(xmac));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       vec->auth_types = OSMO_AUTH_TYPE_UMTS | OSMO_AUTH_TYPE_GSM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return 0;</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%);">+/* 3GPP TS 34.108, section 8.1.2.2 */</span><br><span style="color: hsl(120, 100%, 40%);">+static int xor_gen_vec_auts(struct osmo_auth_vector *vec,</span><br><span style="color: hsl(120, 100%, 40%);">+                          struct osmo_sub_auth_data *aud,</span><br><span style="color: hsl(120, 100%, 40%);">+                       const uint8_t *auts,</span><br><span style="color: hsl(120, 100%, 40%);">+                          const uint8_t *rand_auts,</span><br><span style="color: hsl(120, 100%, 40%);">+                     const uint8_t *_rand)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t xdout[16], cdout[8];</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t ak[6], xmac[8];</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t sqnms[6];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Step 1: xdout = (ki or k) ^ rand */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (aud->type == OSMO_AUTH_TYPE_GSM)</span><br><span style="color: hsl(120, 100%, 40%);">+               xor(xdout, aud->u.gsm.ki, _rand, sizeof(xdout));</span><br><span style="color: hsl(120, 100%, 40%);">+   else if (aud->type == OSMO_AUTH_TYPE_UMTS)</span><br><span style="color: hsl(120, 100%, 40%);">+         xor(xdout, aud->u.umts.k, _rand, sizeof(xdout));</span><br><span style="color: hsl(120, 100%, 40%);">+   else</span><br><span style="color: hsl(120, 100%, 40%);">+          return -ENOTSUP;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Step 2: ak = xdout[2-8] */</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(ak, xdout + 3, 6);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* sqnms = auts[0-5] ^ ak[0-5] */</span><br><span style="color: hsl(120, 100%, 40%);">+     xor(sqnms, auts, ak, sizeof(ak));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* cdout = sqnms || amf* (dummy) */</span><br><span style="color: hsl(120, 100%, 40%);">+   memcpy(cdout, sqnms, 6);</span><br><span style="color: hsl(120, 100%, 40%);">+      memset(cdout + 6, 0x00, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* xmac = xdout[0-7] ^ cdout[0-7] */</span><br><span style="color: hsl(120, 100%, 40%);">+  xor(xmac, xdout, cdout, 8);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Compare the last 64 bits of received AUTS with the locally-generated MAC-S */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (memcmp(auts + 6, xmac, 8))</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Update the "largest used SQN" from the USIM,</span><br><span style="color: hsl(120, 100%, 40%);">+      * milenage_gen_vec() will increment it. */</span><br><span style="color: hsl(120, 100%, 40%);">+   aud->u.umts.sqn_ms = osmo_load64be_ext(sqnms, 6) >> 16;</span><br><span style="color: hsl(120, 100%, 40%);">+      aud->u.umts.sqn = aud->u.umts.sqn_ms;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return xor_gen_vec(vec, aud, _rand);</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%);">+static struct osmo_auth_impl xor_alg = {</span><br><span style="color: hsl(120, 100%, 40%);">+   .algo = OSMO_AUTH_ALG_XOR,</span><br><span style="color: hsl(120, 100%, 40%);">+    .name = "XOR (libosmogsm built-in)",</span><br><span style="color: hsl(120, 100%, 40%);">+        .priority = 1000,</span><br><span style="color: hsl(120, 100%, 40%);">+     .gen_vec = &xor_gen_vec,</span><br><span style="color: hsl(120, 100%, 40%);">+  .gen_vec_auts = &xor_gen_vec_auts,</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%);">+static __attribute__((constructor)) void on_dso_load_xor(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_auth_register(&xor_alg);</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%);">+/*! @} */</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/7310">change 7310</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/c/libosmocore/+/7310"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I1afaf0a9e2dce43aec87964bacefb21ed4d3d565 </div>
<div style="display:none"> Gerrit-Change-Number: 7310 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </div>
<div style="display:none"> Gerrit-Owner: fixeria <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: daniel <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>