The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
ts_34_108.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: 792b1d3914d1710904d715234b66ad2e45771112 $
19  * @file ts_34_108.h
20  * @brief Implementation of the TS.34.108 dummy USMI algorithm
21  *
22  * @copyright 2019 The FreeRADIUS server project
23  * @copyright 2019 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
24  */
25 
26 #include <stddef.h>
27 #include <string.h>
28 
29 #include <freeradius-devel/util/proto.h>
30 #include "common.h"
31 #include "ts_34_108.h"
32 
34  "TS.34.108 Ki and RAND sizes must be identical");
35 
36 #define TS_34_108_XDOUT_SIZE TS_34_108_RAND_SIZE
37 #define TS_34_108_CDOUT_SIZE 8
38 #define TS_34_108_XMAC_SIZE 8
39 
45  uint8_t const amf[TS_34_108_AMF_SIZE],
46  uint8_t const ki[TS_34_108_KI_SIZE],
47  uint64_t sqn,
48  uint8_t const rand[TS_34_108_RAND_SIZE])
49 {
50  size_t i;
54  uint8_t sqn_buff[TS_34_108_SQN_SIZE];
55  uint8_t *p;
56 
57  /*
58  * Step 1:
59  * XOR to the challenge RAND, a predefined number K (in which at least
60  * one bit is not zero, see clause 8.2), having the same bit length
61  * (128 * bits) as RAND.
62  */
63  for (i = 0; i < sizeof(xdout); i++) xdout[i] = ki[i] ^ rand[i];
64 
65  /*
66  * Step 2:
67  * RES (test USIM), XRES (SS), CK, IK and AK are extracted from
68  * XDOUT.
69  */
70 
71  /*
72  * RES[bits 0,1, ...n-1,n] = f2(XDOUT,n) = XDOUT[bits 0,1, . . .n-1,n]
73  */
74  memcpy(res, xdout, TS_34_108_RES_SIZE);
75 
76  /*
77  * CK[bits 0,1, ...126,127] = f3(XDOUT) = XDOUT[bits 8,9, ...126,127,0,1, ...6,7]
78  */
79  memcpy(ck, xdout + 1, TS_34_108_CK_SIZE - 1);
80  ck[TS_34_108_CK_SIZE - 1] = xdout[0];
81 
82  /*
83  * IK[bits0,1, ...126,127] = f4(XDOUT) = XDOUT[bits16,17, ...126,127,0,1, ...14,15]
84  */
85  p = ik;
86  memcpy(p, xdout + 2, TS_34_108_CK_SIZE - 2);
87  p[TS_34_108_CK_SIZE - 2] = xdout[0];
88  p[TS_34_108_CK_SIZE - 1] = xdout[1];
89 
90  /*
91  * AK[bits0,1, ...46,47] = f5(XDOUT) = XDOUT[bits24,25, ...70,71]
92  */
93  memcpy(ak, xdout + 3, TS_34_108_AK_SIZE);
94 
95  /*
96  * Step 3:
97  * Concatenate SQN with AMF to obtain CDOUT
98  */
99  uint48_to_buff(sqn_buff, sqn);
100  p = cdout;
101  memcpy(p, sqn_buff, TS_34_108_SQN_SIZE);
102  p += TS_34_108_SQN_SIZE;
103  memcpy(p, amf, TS_34_108_AMF_SIZE);
104 
105  /*
106  * Step 4:
107  * XMAC (test USIM) and MAC (SS) are calculated from XDOUT and CDOUT.
108  */
109  for (i = 0; i < sizeof(xmac); i++) xmac[i] = xdout[i] ^ cdout[i];
110 
111  /*
112  * Step 5:
113  * The SS calculates the authentication token AUTN.
114  */
115  p = autn;
116  for (i = 0; i < sizeof(sqn_buff); i++) p[i] = sqn_buff[i] ^ ak[i];
117  p += sizeof(sqn_buff);
118  memcpy(p, amf, TS_34_108_AMF_SIZE);
119  p += TS_34_108_AMF_SIZE;
120  memcpy(p, xmac, TS_34_108_XMAC_SIZE);
121 
122  return 0;
123 }
#define static_assert
For systems with an old version libc, define static_assert.
Definition: build.h:35
Common code used by multiple SIM algorithms.
static uint8_t * uint48_to_buff(uint8_t out[static 6], uint64_t i)
Copy a 48bit value from a 64bit integer into a uint8_t buff in big endian byte order.
Definition: common.h:37
unsigned char uint8_t
Definition: merged_model.c:30
#define TS_34_108_CDOUT_SIZE
Definition: ts_34_108.c:37
#define TS_34_108_XDOUT_SIZE
Definition: ts_34_108.c:36
int ts_34_108_umts_generate(uint8_t autn[TS_34_108_AUTN_SIZE], uint8_t ik[TS_34_108_IK_SIZE], uint8_t ck[TS_34_108_CK_SIZE], uint8_t ak[TS_34_108_AK_SIZE], uint8_t res[TS_34_108_RES_SIZE], uint8_t const amf[TS_34_108_AMF_SIZE], uint8_t const ki[TS_34_108_KI_SIZE], uint64_t sqn, uint8_t const rand[TS_34_108_RAND_SIZE])
Definition: ts_34_108.c:40
#define TS_34_108_XMAC_SIZE
Definition: ts_34_108.c:38
Implementation of the TS.34.108 dummy USMI algorithm.
#define TS_34_108_RAND_SIZE
Random challenge.
Definition: ts_34_108.h:34
#define TS_34_108_KI_SIZE
Subscriber key.
Definition: ts_34_108.h:30
#define TS_34_108_CK_SIZE
Ciphering key.
Definition: ts_34_108.h:42
#define TS_34_108_IK_SIZE
Integrity key.
Definition: ts_34_108.h:41
#define TS_34_108_SQN_SIZE
Sequence number.
Definition: ts_34_108.h:33
#define TS_34_108_AK_SIZE
Anonymisation key.
Definition: ts_34_108.h:39
#define TS_34_108_AUTN_SIZE
Network authentication key.
Definition: ts_34_108.h:40
#define TS_34_108_AMF_SIZE
Authentication management field.
Definition: ts_34_108.h:32
#define TS_34_108_RES_SIZE
Definition: ts_34_108.h:43