From 3ddd143b523a7418ac43e5fd7835b86e5d418209 Mon Sep 17 00:00:00 2001
From: Daniel Willmann <dwillmann@sysmocom.de>
Date: Thu, 7 Sep 2017 17:18:25 +0200
Subject: [PATCH] WIP: Add support for XOR authentication

This is work-in-progress in the sense that I wasn't able to do a
successful XOR authentication with osmo-auc-gen
---
 src/gsm/Makefile.am |   2 +-
 src/gsm/auth_xor.c  | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+), 1 deletion(-)
 create mode 100644 src/gsm/auth_xor.c

diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am
index 08cd5e6..28c38b4 100644
--- a/src/gsm/Makefile.am
+++ b/src/gsm/Makefile.am
@@ -25,7 +25,7 @@ libgsmint_la_SOURCES =  a5.c rxlev_stat.c tlv_parser.c comp128.c comp128v23.c \
 			gprs_cipher_core.c gprs_rlc.c gsm0480.c abis_nm.c gsm0502.c \
 			gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c gsm0414.c \
 			lapd_core.c lapdm.c kasumi.c gsm_04_08_gprs.c \
-			auth_core.c auth_comp128v1.c auth_comp128v23.c \
+			auth_core.c auth_comp128v1.c auth_comp128v23.c auth_xor.c \
 			auth_milenage.c milenage/aes-encblock.c gea.c \
 			milenage/aes-internal.c milenage/aes-internal-enc.c \
 			milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \
diff --git a/src/gsm/auth_xor.c b/src/gsm/auth_xor.c
new file mode 100644
index 0000000..23c35f0
--- /dev/null
+++ b/src/gsm/auth_xor.c
@@ -0,0 +1,101 @@
+/*! \file auth_xor.c
+ * GSM/GPRS/3G authentication core infrastructure */
+/*
+ * (C) 2017 by sysmocom s.f.m.c. GmbH
+ * All Rights Reserved
+ *
+ * Author: Daniel Willmann <dwillmann@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <osmocom/crypt/auth.h>
+#include <string.h>
+
+/*! \addtogroup auth
+ *  @{
+ */
+
+static void xor(uint8_t *out, const uint8_t *a, const uint8_t *b, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++) {
+		out[i] = a[i] ^ b[i];
+	}
+}
+
+/* 3GPP TS 34.108 8.1.2.1 XOR auth proceture */
+static int xor_gen_vec(struct osmo_auth_vector *vec,
+			  struct osmo_sub_auth_data *aud,
+			  const uint8_t *_rand)
+{
+	int i;
+	uint8_t xdout[16], ak[6], cdout[8], xmac[8];
+	/* res[16], ck[16], ik[16],*/
+
+
+	// s1: xdout = ki XOR rand
+	xor(xdout, aud->u.umts.k, _rand, sizeof(xdout));
+	
+	// s2: res = xdout
+	memcpy(vec->res, xdout, sizeof(xdout));
+	vec->res_len = 16;
+	// ck = xdout[1-15,0]
+	memcpy(vec->ck, xdout+1, sizeof(xdout)-1);
+	vec->ck[15] = xdout[0];
+	// ik = xdout[2-15,0-1]
+	memcpy(vec->ik, xdout+2, sizeof(xdout)-2);
+	memcpy(vec->ik + 14, xdout, 2);
+	// ak = xdout[3-8]
+	memcpy(ak, xdout + 3, sizeof(ak));
+	// kc = c3(ck, ik)
+	for (i = 0; i < 8; i++)
+		vec->kc[i] = vec->ck[i] ^ vec->ck[i + 8] ^ vec->ik[i] ^ vec->ik[i + 8];
+
+	for (i = 0; i < 4; i++)
+		vec->sres[i] = vec->res[i] ^ vec->res[i + 4];
+
+	// s3: cdout = sqn || amf
+	memcpy(cdout, &aud->u.umts.sqn, 6);
+	0ggmemcpy(cdout + 6, aud->u.umts.amf, sizeof(aud->u.umts.amf));
+	// s4: xmac = xdout[0-8] XOR cdout[0-8]
+	xor(xmac, xdout, cdout, sizeof(xmac));
+	// s5: autn = sqn XOR ak || amv || mac
+	xor(vec->autn, &aud->u.umts.sqn, ak, sizeof(ak));
+	memcpy(vec->autn + 6, aud->u.umts.amf, sizeof(aud->u.umts.amf));
+	memcpy(vec->autn + 8, xmac, sizeof(xmac));
+
+	vec->auth_types = OSMO_AUTH_TYPE_UMTS | OSMO_AUTH_TYPE_GSM;
+
+	return 0;
+}
+
+static struct osmo_auth_impl xor_alg = {
+	.algo = OSMO_AUTH_ALG_XOR,
+	.name = "XOR (libosmogsm built-in)",
+	.priority = 1000,
+	.gen_vec = &xor_gen_vec,
+};
+
+static __attribute__((constructor)) void on_dso_load_xor(void)
+{
+	osmo_auth_register(&xor_alg);
+}
+
+/*! @} */
-- 
2.11.0

