blob: 367c79d46ac18a42ba635ef964aed0fd209d0bd6 [file] [log] [blame]
Harald Weltee93c5e92023-02-21 22:18:11 +01001/*! \file auth_xor.c
2 * GSM XOR-2G algorithm as specified in Annex 4 (A.4.1.2) of 3GPP TS 51.010-1.
3 * This is implemented by typical GSM MS tester */
4
5/*
6 * (C) 2023 by Harald Welte <laforge@gnumonks.org>
7 *
8 * All Rights Reserved
9 *
10 * Author: Daniel Willmann <dwillmann@sysmocom.de>
11 *
12 * All Rights Reserved
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 */
25
26#include <string.h>
27#include <stdint.h>
28#include <errno.h>
29
30#include <osmocom/crypt/auth.h>
31
32/*! \addtogroup auth
33 * @{
34 */
35
36static void xor(uint8_t *out, const uint8_t *a, const uint8_t *b, size_t len)
37{
38 size_t i;
39
40 for (i = 0; i < len; i++)
41 out[i] = a[i] ^ b[i];
42}
43
44/* GSM XOR-2G algorithm as specified in Annex 4 (A.4.1.2) of 3GPP TS 51.010-1. */
45static int xor2g_gen_vec(struct osmo_auth_vector *vec,
Harald Welte08450c92023-05-30 10:55:37 +020046 struct osmo_sub_auth_data2 *aud,
47 const uint8_t *_rand)
Harald Weltee93c5e92023-02-21 22:18:11 +010048{
49 uint8_t res1[16];
50
Harald Welte5248c472023-05-30 11:09:17 +020051 OSMO_ASSERT(aud->algo == OSMO_AUTH_ALG_XOR_2G);
52
Harald Weltee93c5e92023-02-21 22:18:11 +010053 if (aud->type != OSMO_AUTH_TYPE_GSM)
54 return -ENOTSUP;
55
56 /* Step 1: XOR to the challenge RAND, a predefined number Ki, having the same bit length (128 bits) as
57 * RAND. */
58 xor(res1, aud->u.gsm.ki, _rand, sizeof(res1));
59
60 /* Step 2: The most significant 32 bits of RES1 form SRES. */
61 memcpy(vec->sres, res1, 4);
62 /* The next 64 bits of RES1 form Kc */
63 memcpy(vec->kc, res1+4, 8);
64
65 vec->auth_types = OSMO_AUTH_TYPE_GSM;
66 return 0;
67}
68
69static struct osmo_auth_impl xor2g_alg = {
70 .algo = OSMO_AUTH_ALG_XOR_2G,
71 .name = "XOR-2G (libosmogsm built-in)",
72 .priority = 1000,
73 .gen_vec = &xor2g_gen_vec,
74};
75
76static __attribute__((constructor)) void on_dso_load_xor(void)
77{
78 osmo_auth_register(&xor2g_alg);
79}
80
81/*! @} */