Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
常顺宇
OpenXG-RAN
Commits
0ee578f4
Commit
0ee578f4
authored
Aug 19, 2020
by
Laurent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add authentication request
parent
59964b0f
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
701 additions
and
37 deletions
+701
-37
executables/nr-uesoftmodem.c
executables/nr-uesoftmodem.c
+9
-2
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+3
-1
openair3/NAS/COMMON/NR_NAS_defs.h
openair3/NAS/COMMON/NR_NAS_defs.h
+33
-5
openair3/NAS/COMMON/aes.h
openair3/NAS/COMMON/aes.h
+184
-0
openair3/NAS/COMMON/milenage.h
openair3/NAS/COMMON/milenage.h
+337
-0
openair3/NAS/NR_UE/nr_user_def.h
openair3/NAS/NR_UE/nr_user_def.h
+6
-1
openair3/NAS/NR_UE/ue_process_nas.c
openair3/NAS/NR_UE/ue_process_nas.c
+9
-10
openair3/NAS/gNB/network_process_nas.c
openair3/NAS/gNB/network_process_nas.c
+67
-10
openair3/NAS/gNB/network_process_nas.h
openair3/NAS/gNB/network_process_nas.h
+16
-0
openair3/UICC/usim_interface.c
openair3/UICC/usim_interface.c
+25
-5
openair3/UICC/usim_interface.h
openair3/UICC/usim_interface.h
+12
-3
No files found.
executables/nr-uesoftmodem.c
View file @
0ee578f4
...
@@ -86,6 +86,7 @@ unsigned short config_frames[4] = {2,9,11,13};
...
@@ -86,6 +86,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "executables/softmodem-common.h"
#include "executables/softmodem-common.h"
#include "executables/thread-common.h"
#include "executables/thread-common.h"
#include <openair3/NAS/NR_UE/nr_user_def.h>
#include <openair3/NAS/NR_UE/nr_user_def.h>
#include <openair3/NAS/gNB/network_process_nas.h>
// Raphael : missing
// Raphael : missing
pthread_cond_t
nfapi_sync_cond
;
pthread_cond_t
nfapi_sync_cond
;
...
@@ -761,8 +762,14 @@ int main( int argc, char **argv ) {
...
@@ -761,8 +762,14 @@ int main( int argc, char **argv ) {
mlockall
(
MCL_CURRENT
|
MCL_FUTURE
);
mlockall
(
MCL_CURRENT
|
MCL_FUTURE
);
char
*
resp
;
char
*
resp
;
nr_user_nas_t
UErrc
=
{
0
};
nr_user_nas_t
UErrc
=
{
0
};
int
size
=
identityResponse
(
&
resp
,
&
UErrc
);
NRUEcontext_t
UEnas
=
{
0
};
int
size
=
identityRequest
((
void
**
)
&
resp
,
&
UEnas
);
log_dump
(
NAS
,
resp
,
size
,
LOG_DUMP_CHAR
,
" identity Request:
\n
"
);;
size
=
identityResponse
((
void
**
)
&
resp
,
&
UErrc
);
log_dump
(
NAS
,
resp
,
size
,
LOG_DUMP_CHAR
,
" identity Response:
\n
"
);;
size
=
authenticationRequest
((
void
**
)
&
resp
,
&
UEnas
);
log_dump
(
NAS
,
resp
,
size
,
LOG_DUMP_CHAR
,
" authentication request:
\n
"
);;
if
(
IS_SOFTMODEM_DOFORMS
)
{
if
(
IS_SOFTMODEM_DOFORMS
)
{
load_softscope
(
"nr"
,
PHY_vars_UE_g
[
0
][
0
]);
load_softscope
(
"nr"
,
PHY_vars_UE_g
[
0
][
0
]);
...
...
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
View file @
0ee578f4
...
@@ -69,6 +69,7 @@
...
@@ -69,6 +69,7 @@
#include "NR_TAG.h"
#include "NR_TAG.h"
#include <openair3/NAS/COMMON/NR_NAS_defs.h>
#include <openair3/NAS/COMMON/NR_NAS_defs.h>
#include <openair3/UICC/usim_interface.h>
/* Defs */
/* Defs */
...
@@ -282,7 +283,8 @@ typedef struct NR_preamble_ue {
...
@@ -282,7 +283,8 @@ typedef struct NR_preamble_ue {
}
NR_preamble_ue
;
}
NR_preamble_ue
;
typedef
struct
{
typedef
struct
{
boolean_t
fiveG_connected
;
boolean_t
fiveG_connected
;
uicc_t
*
uicc
;
}
NRUEcontext_t
;
}
NRUEcontext_t
;
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
...
...
openair3/NAS/COMMON/NR_NAS_defs.h
View file @
0ee578f4
/* TS 24.007 possible L3 formats:
Table 11.1: Formats of information elements
Format Meaning IEI present LI present Value part present
T Type only yes no no
V Value only no no yes
TV Type and Value yes no yes
LV Length and Value no yes yes
TLV Type, Length and Value yes yes yes
LV-E Length and Value no yes yes
TLV-E Type, Length and Value yes yes yes
*/
//TS 24.501, chap 9.2 => TS 24.007
//TS 24.501, chap 9.2 => TS 24.007
typedef
enum
{
typedef
enum
{
SGSsessionmanagementmessages
=
0x2e
,
//LTEbox: 0xC0 ???
SGSsessionmanagementmessages
=
0x2e
,
//LTEbox: 0xC0 ???
...
@@ -190,6 +202,12 @@ static const cause_text_info_t cause_secu_text_info[] = {
...
@@ -190,6 +202,12 @@ static const cause_text_info_t cause_secu_text_info[] = {
FOREACH_CAUSE_SECU
(
CAUSE_TEXT
)
FOREACH_CAUSE_SECU
(
CAUSE_TEXT
)
};
};
// IEI (information element identifier) are spread in each message definition
#define IEI_RAND 0x21
#define IEI_AUTN 0x20
#define IEI_EAP 0x78
#define IEI_AuthenticationResponse 0x2d
#define CAUSE_ENUM(LabEl, nUmID ) LabEl = nUmID,
#define CAUSE_ENUM(LabEl, nUmID ) LabEl = nUmID,
//! Tasks id of each task
//! Tasks id of each task
typedef
enum
{
typedef
enum
{
...
@@ -226,7 +244,8 @@ typedef struct __attribute__((packed)) {
...
@@ -226,7 +244,8 @@ typedef struct __attribute__((packed)) {
Security_header_t
sh
:
8
;
Security_header_t
sh
:
8
;
SGSmobilitymanagementmessages_t
mt
:
8
;
SGSmobilitymanagementmessages_t
mt
:
8
;
uint16_t
len
;
uint16_t
len
;
}
Identityresponse_t
;
}
Identityresponse_t
;
typedef
struct
__attribute__
((
packed
))
{
typedef
struct
__attribute__
((
packed
))
{
Identityresponse_t
common
;
Identityresponse_t
common
;
...
@@ -246,16 +265,24 @@ typedef struct __attribute__((packed)) {
...
@@ -246,16 +265,24 @@ typedef struct __attribute__((packed)) {
int
protectScheme
:
4
;
int
protectScheme
:
4
;
int
spare
:
4
;
int
spare
:
4
;
uint8_t
hplmnId
;
uint8_t
hplmnId
;
}
IdentityresponseIMSI_t
;
}
IdentityresponseIMSI_t
;
typedef
struct
{
typedef
struct
__attribute__
((
packed
))
{
Extendedprotocoldiscriminator_t
epd
:
8
;
Extendedprotocoldiscriminator_t
epd
:
8
;
Security_header_t
sh
:
8
;
Security_header_t
sh
:
8
;
SGSmobilitymanagementmessages_t
mt
:
8
;
SGSmobilitymanagementmessages_t
mt
:
8
;
int
ngKSI
:
4
;
int
ngKSI
:
4
;
int
spare
:
4
;
int
spare
:
4
;
int
ABBALen
:
8
;
int
ABBALen
:
8
;
}
authenticationrequestHeader_t
;
int
ABBA
:
16
;
uint8_t
ieiRAND
;
uint8_t
RAND
[
16
];
uint8_t
ieiAUTN
;
uint8_t
AUTNlen
;
uint8_t
AUTN
[
16
];
}
authenticationrequestHeader_t
;
typedef
struct
{
typedef
struct
{
Extendedprotocoldiscriminator_t
epd
:
8
;
Extendedprotocoldiscriminator_t
epd
:
8
;
...
@@ -264,4 +291,5 @@ typedef struct {
...
@@ -264,4 +291,5 @@ typedef struct {
}
authenticationresponseHeader_t
;
}
authenticationresponseHeader_t
;
//AUTHENTICATION RESULT
//AUTHENTICATION RESULT
openair3/NAS/COMMON/aes.h
0 → 100644
View file @
0ee578f4
#ifndef AES_H
#define EAS_H
// Implemented from Wikipedia description and OpenAir HSS
/*--------------------- Rijndael S box table ----------------------*/
static
const
uint8_t
S
[
256
]
=
{
0x63
,
0x7C
,
0x77
,
0x7B
,
0xF2
,
0x6B
,
0x6F
,
0xC5
,
0x30
,
0x01
,
0x67
,
0x2B
,
0xFE
,
0xD7
,
0xAB
,
0x76
,
0xCA
,
0x82
,
0xC9
,
0x7D
,
0xFA
,
0x59
,
0x47
,
0xF0
,
0xAD
,
0xD4
,
0xA2
,
0xAF
,
0x9C
,
0xA4
,
0x72
,
0xC0
,
0xB7
,
0xFD
,
0x93
,
0x26
,
0x36
,
0x3F
,
0xF7
,
0xCC
,
0x34
,
0xA5
,
0xE5
,
0xF1
,
0x71
,
0xD8
,
0x31
,
0x15
,
0x04
,
0xC7
,
0x23
,
0xC3
,
0x18
,
0x96
,
0x05
,
0x9A
,
0x07
,
0x12
,
0x80
,
0xE2
,
0xEB
,
0x27
,
0xB2
,
0x75
,
0x09
,
0x83
,
0x2C
,
0x1A
,
0x1B
,
0x6E
,
0x5A
,
0xA0
,
0x52
,
0x3B
,
0xD6
,
0xB3
,
0x29
,
0xE3
,
0x2F
,
0x84
,
0x53
,
0xD1
,
0x00
,
0xED
,
0x20
,
0xFC
,
0xB1
,
0x5B
,
0x6A
,
0xCB
,
0xBE
,
0x39
,
0x4A
,
0x4C
,
0x58
,
0xCF
,
0xD0
,
0xEF
,
0xAA
,
0xFB
,
0x43
,
0x4D
,
0x33
,
0x85
,
0x45
,
0xF9
,
0x02
,
0x7F
,
0x50
,
0x3C
,
0x9F
,
0xA8
,
0x51
,
0xA3
,
0x40
,
0x8F
,
0x92
,
0x9D
,
0x38
,
0xF5
,
0xBC
,
0xB6
,
0xDA
,
0x21
,
0x10
,
0xFF
,
0xF3
,
0xD2
,
0xCD
,
0x0C
,
0x13
,
0xEC
,
0x5F
,
0x97
,
0x44
,
0x17
,
0xC4
,
0xA7
,
0x7E
,
0x3D
,
0x64
,
0x5D
,
0x19
,
0x73
,
0x60
,
0x81
,
0x4F
,
0xDC
,
0x22
,
0x2A
,
0x90
,
0x88
,
0x46
,
0xEE
,
0xB8
,
0x14
,
0xDE
,
0x5E
,
0x0B
,
0xDB
,
0xE0
,
0x32
,
0x3A
,
0x0A
,
0x49
,
0x06
,
0x24
,
0x5C
,
0xC2
,
0xD3
,
0xAC
,
0x62
,
0x91
,
0x95
,
0xE4
,
0x79
,
0xE7
,
0xC8
,
0x37
,
0x6D
,
0x8D
,
0xD5
,
0x4E
,
0xA9
,
0x6C
,
0x56
,
0xF4
,
0xEA
,
0x65
,
0x7A
,
0xAE
,
0x08
,
0xBA
,
0x78
,
0x25
,
0x2E
,
0x1C
,
0xA6
,
0xB4
,
0xC6
,
0xE8
,
0xDD
,
0x74
,
0x1F
,
0x4B
,
0xBD
,
0x8B
,
0x8A
,
0x70
,
0x3E
,
0xB5
,
0x66
,
0x48
,
0x03
,
0xF6
,
0x0E
,
0x61
,
0x35
,
0x57
,
0xB9
,
0x86
,
0xC1
,
0x1D
,
0x9E
,
0xE1
,
0xF8
,
0x98
,
0x11
,
0x69
,
0xD9
,
0x8E
,
0x94
,
0x9B
,
0x1E
,
0x87
,
0xE9
,
0xCE
,
0x55
,
0x28
,
0xDF
,
0x8C
,
0xA1
,
0x89
,
0x0D
,
0xBF
,
0xE6
,
0x42
,
0x68
,
0x41
,
0x99
,
0x2D
,
0x0F
,
0xB0
,
0x54
,
0xBB
,
0x16
};
/*------- This array does the multiplication by x in GF(2^8) ------*/
static
const
uint8_t
Xtime
[
256
]
=
{
0
,
2
,
4
,
6
,
8
,
10
,
12
,
14
,
16
,
18
,
20
,
22
,
24
,
26
,
28
,
30
,
32
,
34
,
36
,
38
,
40
,
42
,
44
,
46
,
48
,
50
,
52
,
54
,
56
,
58
,
60
,
62
,
64
,
66
,
68
,
70
,
72
,
74
,
76
,
78
,
80
,
82
,
84
,
86
,
88
,
90
,
92
,
94
,
96
,
98
,
100
,
102
,
104
,
106
,
108
,
110
,
112
,
114
,
116
,
118
,
120
,
122
,
124
,
126
,
128
,
130
,
132
,
134
,
136
,
138
,
140
,
142
,
144
,
146
,
148
,
150
,
152
,
154
,
156
,
158
,
160
,
162
,
164
,
166
,
168
,
170
,
172
,
174
,
176
,
178
,
180
,
182
,
184
,
186
,
188
,
190
,
192
,
194
,
196
,
198
,
200
,
202
,
204
,
206
,
208
,
210
,
212
,
214
,
216
,
218
,
220
,
222
,
224
,
226
,
228
,
230
,
232
,
234
,
236
,
238
,
240
,
242
,
244
,
246
,
248
,
250
,
252
,
254
,
27
,
25
,
31
,
29
,
19
,
17
,
23
,
21
,
11
,
9
,
15
,
13
,
3
,
1
,
7
,
5
,
59
,
57
,
63
,
61
,
51
,
49
,
55
,
53
,
43
,
41
,
47
,
45
,
35
,
33
,
39
,
37
,
91
,
89
,
95
,
93
,
83
,
81
,
87
,
85
,
75
,
73
,
79
,
77
,
67
,
65
,
71
,
69
,
123
,
121
,
127
,
125
,
115
,
113
,
119
,
117
,
107
,
105
,
111
,
109
,
99
,
97
,
103
,
101
,
155
,
153
,
159
,
157
,
147
,
145
,
151
,
149
,
139
,
137
,
143
,
141
,
131
,
129
,
135
,
133
,
187
,
185
,
191
,
189
,
179
,
177
,
183
,
181
,
171
,
169
,
175
,
173
,
163
,
161
,
167
,
165
,
219
,
217
,
223
,
221
,
211
,
209
,
215
,
213
,
203
,
201
,
207
,
205
,
195
,
193
,
199
,
197
,
251
,
249
,
255
,
253
,
243
,
241
,
247
,
245
,
235
,
233
,
239
,
237
,
227
,
225
,
231
,
229
};
/*-------------------------------------------------------------------
Rijndael key schedule function. Takes 16-byte key and creates
all Rijndael's internal subkeys ready for encryption.
-----------------------------------------------------------------*/
static
inline
void
RijndaelKeySchedule
(
const
uint8_t
key
[
16
],
uint8_t
roundKeys
[
11
][
4
][
4
])
{
//first round key equals key
for
(
int
i
=
0
;
i
<
16
;
i
++
)
roundKeys
[
0
][
i
&
0x03
][
i
>>
2
]
=
key
[
i
];
//now calculate round keys
uint8_t
roundConst
=
1
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
int
next
=
i
+
1
;
roundKeys
[
next
][
0
][
0
]
=
S
[
roundKeys
[
i
][
1
][
3
]]
^
roundKeys
[
i
][
0
][
0
]
^
roundConst
;
roundKeys
[
next
][
1
][
0
]
=
S
[
roundKeys
[
i
][
2
][
3
]]
^
roundKeys
[
i
][
1
][
0
];
roundKeys
[
next
][
2
][
0
]
=
S
[
roundKeys
[
i
][
3
][
3
]]
^
roundKeys
[
i
][
2
][
0
];
roundKeys
[
next
][
3
][
0
]
=
S
[
roundKeys
[
i
][
0
][
3
]]
^
roundKeys
[
i
][
3
][
0
];
for
(
int
j
=
0
;
j
<
4
;
j
++
)
{
roundKeys
[
next
][
j
][
1
]
=
roundKeys
[
i
][
j
][
1
]
^
roundKeys
[
next
][
j
][
0
];
roundKeys
[
next
][
j
][
2
]
=
roundKeys
[
i
][
j
][
2
]
^
roundKeys
[
next
][
j
][
1
];
roundKeys
[
next
][
j
][
3
]
=
roundKeys
[
i
][
j
][
3
]
^
roundKeys
[
next
][
j
][
2
];
}
roundConst
=
Xtime
[
roundConst
];
}
return
;
}
/* Round key addition function */
static
inline
void
KeyAdd
(
uint8_t
state
[
4
][
4
],
uint8_t
roundKeys
[
11
][
4
][
4
],
int
round
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
for
(
int
j
=
0
;
j
<
4
;
j
++
)
state
[
i
][
j
]
^=
roundKeys
[
round
][
i
][
j
];
return
;
}
/* Byte substitution transformation */
static
inline
void
ByteSub
(
uint8_t
state
[
4
][
4
])
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
for
(
int
j
=
0
;
j
<
4
;
j
++
)
state
[
i
][
j
]
=
S
[
state
[
i
][
j
]];
return
;
}
/* Row shift transformation */
static
inline
void
ShiftRow
(
uint8_t
state
[
4
][
4
])
{
// left rotate row 1 by 1
uint8_t
temp
=
state
[
1
][
0
];
state
[
1
][
0
]
=
state
[
1
][
1
];
state
[
1
][
1
]
=
state
[
1
][
2
];
state
[
1
][
2
]
=
state
[
1
][
3
];
state
[
1
][
3
]
=
temp
;
//left rotate row 2 by 2
temp
=
state
[
2
][
0
];
state
[
2
][
0
]
=
state
[
2
][
2
];
state
[
2
][
2
]
=
temp
;
temp
=
state
[
2
][
1
];
state
[
2
][
1
]
=
state
[
2
][
3
];
state
[
2
][
3
]
=
temp
;
// left rotate row 3 by 3
temp
=
state
[
3
][
0
];
state
[
3
][
0
]
=
state
[
3
][
3
];
state
[
3
][
3
]
=
state
[
3
][
2
];
state
[
3
][
2
]
=
state
[
3
][
1
];
state
[
3
][
1
]
=
temp
;
return
;
}
/* MixColumn transformation*/
static
inline
void
MixColumn
(
uint8_t
state
[
4
][
4
])
{
// do one column at a time
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
uint8_t
temp
=
state
[
0
][
i
]
^
state
[
1
][
i
]
^
state
[
2
][
i
]
^
state
[
3
][
i
];
uint8_t
tmp0
=
state
[
0
][
i
];
// Xtime array does multiply by x in GF2^8
uint8_t
tmp
=
Xtime
[
state
[
0
][
i
]
^
state
[
1
][
i
]];
state
[
0
][
i
]
^=
temp
^
tmp
;
tmp
=
Xtime
[
state
[
1
][
i
]
^
state
[
2
][
i
]];
state
[
1
][
i
]
^=
temp
^
tmp
;
tmp
=
Xtime
[
state
[
2
][
i
]
^
state
[
3
][
i
]];
state
[
2
][
i
]
^=
temp
^
tmp
;
tmp
=
Xtime
[
state
[
3
][
i
]
^
tmp0
];
state
[
3
][
i
]
^=
temp
^
tmp
;
}
return
;
}
/*-------------------------------------------------------------------
Rijndael encryption function. Takes 16-byte input and creates
16-byte output (using round keys already derived from 16-byte
key).
-----------------------------------------------------------------*/
static
inline
void
RijndaelEncrypt
(
const
uint8_t
input
[
16
],
uint8_t
output
[
16
],
uint8_t
roundKeys
[
11
][
4
][
4
])
{
uint8_t
state
[
4
][
4
];
int
r
;
// initialise state array from input byte string
for
(
int
i
=
0
;
i
<
16
;
i
++
)
state
[
i
&
0x3
][
i
>>
2
]
=
input
[
i
];
// add first round_key
KeyAdd
(
state
,
roundKeys
,
0
);
// do lots of full rounds
for
(
r
=
1
;
r
<=
9
;
r
++
)
{
ByteSub
(
state
);
ShiftRow
(
state
);
MixColumn
(
state
);
KeyAdd
(
state
,
roundKeys
,
r
);
}
// final round
ByteSub
(
state
);
ShiftRow
(
state
);
KeyAdd
(
state
,
roundKeys
,
r
);
// produce output byte string from state array
for
(
int
i
=
0
;
i
<
16
;
i
++
)
output
[
i
]
=
state
[
i
&
0x3
][
i
>>
2
];
return
;
}
static
inline
void
aes_128_encrypt_block
(
const
uint8_t
*
key
,
const
uint8_t
*
clear
,
uint8_t
*
cyphered
)
{
uint8_t
roundKeys
[
11
][
4
][
4
];
RijndaelKeySchedule
(
key
,
roundKeys
);
RijndaelEncrypt
(
clear
,
cyphered
,
roundKeys
);
}
#endif
openair3/NAS/COMMON/milenage.h
0 → 100644
View file @
0ee578f4
/*
Adpatatipn of SW from hereafter license
Author: laurent.thomas@open-cells.com
*/
/*
3GPP AKA - Milenage algorithm (3GPP TS 35.205, .206, .207, .208)
Copyright (c) 2006-2007 <j@w1.fi>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
Alternatively, this software may be distributed under the terms of BSD
license.
See README and COPYING for more details.
This file implements an example authentication algorithm defined for 3GPP
AKA. This can be used to implement a simple HLR/AuC into hlr_auc_gw to allow
EAP-AKA to be tested properly with real USIM cards.
This implementations assumes that the r1..r5 and c1..c5 constants defined in
TS 35.206 are used, i.e., r1=64, r2=0, r3=32, r4=64, r5=96, c1=00..00,
c2=00..01, c3=00..02, c4=00..04, c5=00..08. The block cipher is assumed to
be AES (Rijndael).
*/
#ifndef MILENAGE_H
#define MILENAGE_H
#include <openair3/NAS/COMMON/aes.h>
#define u8 uint8_t
/**
milenage_f1 - Milenage f1 and f1* algorithms
@opc: OPc = 128-bit value derived from OP and K
@k: K = 128-bit subscriber key
@_rand: RAND = 128-bit random challenge
@sqn: SQN = 48-bit sequence number
@amf: AMF = 16-bit authentication management field
@mac_a: Buffer for MAC-A = 64-bit network authentication code, or %NULL
@mac_s: Buffer for MAC-S = 64-bit resync authentication code, or %NULL
Returns: true on success, false on failure
*/
bool
milenage_f1
(
const
u8
*
opc
,
const
u8
*
k
,
const
u8
*
_rand
,
const
u8
*
sqn
,
const
u8
*
amf
,
u8
*
mac_a
,
u8
*
mac_s
)
{
u8
tmp1
[
16
],
tmp2
[
16
],
tmp3
[
16
];
int
i
;
/* tmp1 = TEMP = E_K(RAND XOR OP_C) */
for
(
i
=
0
;
i
<
16
;
i
++
)
tmp1
[
i
]
=
_rand
[
i
]
^
opc
[
i
];
aes_128_encrypt_block
(
k
,
tmp1
,
tmp1
);
/* tmp2 = IN1 = SQN || AMF || SQN || AMF */
memcpy
(
tmp2
,
sqn
,
6
);
memcpy
(
tmp2
+
6
,
amf
,
2
);
memcpy
(
tmp2
+
8
,
tmp2
,
8
);
/* OUT1 = E_K(TEMP XOR rot(IN1 XOR OP_C, r1) XOR c1) XOR OP_C */
/* rotate (tmp2 XOR OP_C) by r1 (= 0x40 = 8 bytes) */
for
(
i
=
0
;
i
<
16
;
i
++
)
tmp3
[(
i
+
8
)
%
16
]
=
tmp2
[
i
]
^
opc
[
i
];
/* XOR with TEMP = E_K(RAND XOR OP_C) */
for
(
i
=
0
;
i
<
16
;
i
++
)
tmp3
[
i
]
^=
tmp1
[
i
];
/* XOR with c1 (= ..00, i.e., NOP) */
/* f1 || f1* = E_K(tmp3) XOR OP_c */
aes_128_encrypt_block
(
k
,
tmp3
,
tmp1
);
for
(
i
=
0
;
i
<
16
;
i
++
)
tmp1
[
i
]
^=
opc
[
i
];
if
(
mac_a
)
memcpy
(
mac_a
,
tmp1
,
8
);
/* f1 */
if
(
mac_s
)
memcpy
(
mac_s
,
tmp1
+
8
,
8
);
/* f1* */
return
true
;
}
/**
milenage_f2345 - Milenage f2, f3, f4, f5, f5* algorithms
@opc: OPc = 128-bit value derived from OP and K
@k: K = 128-bit subscriber key
@_rand: RAND = 128-bit random challenge
@res: Buffer for RES = 64-bit signed response (f2), or %NULL
@ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
@ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
@ak: Buffer for AK = 48-bit anonymity key (f5), or %NULL
@akstar: Buffer for AK = 48-bit anonymity key (f5*), or %NULL
Returns: true on success, false on failure
*/
bool
milenage_f2345
(
const
u8
*
opc
,
const
u8
*
k
,
const
u8
*
_rand
,
u8
*
res
,
u8
*
ck
,
u8
*
ik
,
u8
*
ak
,
u8
*
akstar
)
{
u8
tmp1
[
16
],
tmp2
[
16
],
tmp3
[
16
];
int
i
;
/* tmp2 = TEMP = E_K(RAND XOR OP_C) */
for
(
i
=
0
;
i
<
16
;
i
++
)
tmp1
[
i
]
=
_rand
[
i
]
^
opc
[
i
];
aes_128_encrypt_block
(
k
,
tmp1
,
tmp2
);
/* OUT2 = E_K(rot(TEMP XOR OP_C, r2) XOR c2) XOR OP_C */
/* OUT3 = E_K(rot(TEMP XOR OP_C, r3) XOR c3) XOR OP_C */
/* OUT4 = E_K(rot(TEMP XOR OP_C, r4) XOR c4) XOR OP_C */
/* OUT5 = E_K(rot(TEMP XOR OP_C, r5) XOR c5) XOR OP_C */
/* f2 and f5 */
/* rotate by r2 (= 0, i.e., NOP) */
for
(
i
=
0
;
i
<
16
;
i
++
)
tmp1
[
i
]
=
tmp2
[
i
]
^
opc
[
i
];
tmp1
[
15
]
^=
1
;
/* XOR c2 (= ..01) */
/* f5 || f2 = E_K(tmp1) XOR OP_c */
aes_128_encrypt_block
(
k
,
tmp1
,
tmp3
);
for
(
i
=
0
;
i
<
16
;
i
++
)
tmp3
[
i
]
^=
opc
[
i
];
if
(
res
)
memcpy
(
res
,
tmp3
+
8
,
8
);
/* f2 */
if
(
ak
)
memcpy
(
ak
,
tmp3
,
6
);
/* f5 */
/* f3 */
if
(
ck
)
{
/* rotate by r3 = 0x20 = 4 bytes */
for
(
i
=
0
;
i
<
16
;
i
++
)
tmp1
[(
i
+
12
)
%
16
]
=
tmp2
[
i
]
^
opc
[
i
];
tmp1
[
15
]
^=
2
;
/* XOR c3 (= ..02) */
aes_128_encrypt_block
(
k
,
tmp1
,
ck
);
for
(
i
=
0
;
i
<
16
;
i
++
)
ck
[
i
]
^=
opc
[
i
];
}
/* f4 */
if
(
ik
)
{
/* rotate by r4 = 0x40 = 8 bytes */
for
(
i
=
0
;
i
<
16
;
i
++
)
tmp1
[(
i
+
8
)
%
16
]
=
tmp2
[
i
]
^
opc
[
i
];
tmp1
[
15
]
^=
4
;
/* XOR c4 (= ..04) */
aes_128_encrypt_block
(
k
,
tmp1
,
ik
);
for
(
i
=
0
;
i
<
16
;
i
++
)
ik
[
i
]
^=
opc
[
i
];
}
/* f5* */
if
(
akstar
)
{
/* rotate by r5 = 0x60 = 12 bytes */
for
(
i
=
0
;
i
<
16
;
i
++
)
tmp1
[(
i
+
4
)
%
16
]
=
tmp2
[
i
]
^
opc
[
i
];
tmp1
[
15
]
^=
8
;
/* XOR c5 (= ..08) */
aes_128_encrypt_block
(
k
,
tmp1
,
tmp1
);
for
(
i
=
0
;
i
<
6
;
i
++
)
akstar
[
i
]
=
tmp1
[
i
]
^
opc
[
i
];
}
return
true
;
}
/**
milenage_generate - Generate AKA AUTN,IK,CK,RES
@opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
@amf: AMF = 16-bit authentication management field
@k: K = 128-bit subscriber key
@sqn: SQN = 48-bit sequence number
@_rand: RAND = 128-bit random challenge
@autn: Buffer for AUTN = 128-bit authentication token
@ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
@ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
@res: Buffer for RES = 64-bit signed response (f2), or %NULL
@res_len: Max length for res; set to used length or 0 on failure
*/
bool
milenage_generate
(
const
u8
*
opc
,
const
u8
*
amf
,
const
u8
*
k
,
const
u8
*
sqn
,
const
u8
*
_rand
,
u8
*
autn
,
u8
*
ik
,
u8
*
ck
,
u8
*
res
)
{
int
i
;
u8
mac_a
[
8
],
ak
[
6
];
if
(
!
milenage_f1
(
opc
,
k
,
_rand
,
sqn
,
amf
,
mac_a
,
NULL
)
||
!
milenage_f2345
(
opc
,
k
,
_rand
,
res
,
ck
,
ik
,
ak
,
NULL
))
return
false
;
/* AUTN = (SQN ^ AK) || AMF || MAC */
for
(
i
=
0
;
i
<
6
;
i
++
)
autn
[
i
]
=
sqn
[
i
]
^
ak
[
i
];
memcpy
(
autn
+
6
,
amf
,
2
);
memcpy
(
autn
+
8
,
mac_a
,
8
);
return
true
;
}
/**
milenage_auts - Milenage AUTS validation
@opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
@k: K = 128-bit subscriber key
@_rand: RAND = 128-bit random challenge
@auts: AUTS = 112-bit authentication token from client
@sqn: Buffer for SQN = 48-bit sequence number
Returns: 0 = success (sqn filled), -1 on failure
*/
#define p(a) printf("%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", (int)((a)[0]), (int)((a)[1]), (int)((a)[2]), (int)((a)[3]),(int)((a)[4]), (int)((a)[5]));
bool
milenage_auts
(
const
u8
*
opc
,
const
u8
*
k
,
const
u8
*
_rand
,
const
u8
*
auts
,
u8
*
sqn
)
{
u8
amf
[
2
]
=
{
0x00
,
0x00
};
/* TS 33.102 v7.0.0, 6.3.3 */
u8
ak
[
6
],
mac_s
[
8
];
int
i
;
if
(
!
milenage_f2345
(
opc
,
k
,
_rand
,
NULL
,
NULL
,
NULL
,
NULL
,
ak
))
return
false
;
for
(
i
=
0
;
i
<
6
;
i
++
)
sqn
[
i
]
=
auts
[
i
]
^
ak
[
i
];
//p(sqn);
if
(
!
milenage_f1
(
opc
,
k
,
_rand
,
sqn
,
amf
,
NULL
,
mac_s
)
||
memcmp
(
mac_s
,
auts
+
6
,
8
)
!=
0
)
return
false
;
return
true
;
}
/**
gsm_milenage - Generate GSM-Milenage (3GPP TS 55.205) authentication triplet
@opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
@k: K = 128-bit subscriber key
@_rand: RAND = 128-bit random challenge
@sres: Buffer for SRES = 32-bit SRES
@kc: Buffer for Kc = 64-bit Kc
Returns: 0 on success, -1 on failure
*/
bool
gsm_milenage
(
const
u8
*
opc
,
const
u8
*
k
,
const
u8
*
_rand
,
u8
*
sres
,
u8
*
kc
)
{
u8
res
[
8
],
ck
[
16
],
ik
[
16
];
int
i
;
if
(
milenage_f2345
(
opc
,
k
,
_rand
,
res
,
ck
,
ik
,
NULL
,
NULL
))
return
false
;
for
(
i
=
0
;
i
<
8
;
i
++
)
kc
[
i
]
=
ck
[
i
]
^
ck
[
i
+
8
]
^
ik
[
i
]
^
ik
[
i
+
8
];
#ifdef GSM_MILENAGE_ALT_SRES
memcpy
(
sres
,
res
,
4
);
#else
/* GSM_MILENAGE_ALT_SRES */
for
(
i
=
0
;
i
<
4
;
i
++
)
sres
[
i
]
=
res
[
i
]
^
res
[
i
+
4
];
#endif
/* GSM_MILENAGE_ALT_SRES */
return
true
;
}
/**
milenage_generate - Generate AKA AUTN,IK,CK,RES
@opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
@k: K = 128-bit subscriber key
@sqn: SQN = 48-bit sequence number
@_rand: RAND = 128-bit random challenge
@autn: AUTN = 128-bit authentication token
@ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
@ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
@res: Buffer for RES = 64-bit signed response (f2), or %NULL
@res_len: Variable that will be set to RES length
@auts: 112-bit buffer for AUTS
Returns: 0 on success, -1 on failure, or -2 on synchronization failure
*/
int
milenage_check
(
const
u8
*
opc
,
const
u8
*
k
,
const
u8
*
sqn
,
const
u8
*
_rand
,
const
u8
*
autn
,
u8
*
ik
,
u8
*
ck
,
u8
*
res
,
size_t
*
res_len
,
u8
*
auts
)
{
int
i
;
u8
mac_a
[
8
],
ak
[
6
],
rx_sqn
[
6
];
const
u8
*
amf
;
if
(
milenage_f2345
(
opc
,
k
,
_rand
,
res
,
ck
,
ik
,
ak
,
NULL
))
return
-
1
;
*
res_len
=
8
;
/* AUTN = (SQN ^ AK) || AMF || MAC */
for
(
i
=
0
;
i
<
6
;
i
++
)
rx_sqn
[
i
]
=
autn
[
i
]
^
ak
[
i
];
if
(
memcmp
(
rx_sqn
,
sqn
,
6
)
<=
0
)
{
u8
auts_amf
[
2
]
=
{
0x00
,
0x00
};
/* TS 33.102 v7.0.0, 6.3.3 */
if
(
milenage_f2345
(
opc
,
k
,
_rand
,
NULL
,
NULL
,
NULL
,
NULL
,
ak
))
return
-
1
;
for
(
i
=
0
;
i
<
6
;
i
++
)
auts
[
i
]
=
sqn
[
i
]
^
ak
[
i
];
if
(
milenage_f1
(
opc
,
k
,
_rand
,
sqn
,
auts_amf
,
NULL
,
auts
+
6
))
return
-
1
;
return
-
2
;
}
amf
=
autn
+
6
;
if
(
milenage_f1
(
opc
,
k
,
_rand
,
rx_sqn
,
amf
,
mac_a
,
NULL
))
return
-
1
;
if
(
memcmp
(
mac_a
,
autn
+
8
,
8
)
!=
0
)
{
printf
(
"Milenage: MAC mismatch
\n
"
);
return
-
1
;
}
return
0
;
}
void
milenage_opc_gen
(
const
u8
*
k
,
const
u8
*
op
,
u8
*
opc
)
{
int
i
;
/* Encrypt OP using K */
aes_128_encrypt_block
(
k
,
op
,
opc
);
/* XOR the resulting Ek(OP) with OP */
for
(
i
=
0
;
i
<
16
;
i
++
)
opc
[
i
]
=
opc
[
i
]
^
op
[
i
];
}
#endif
openair3/NAS/NR_UE/nr_user_def.h
View file @
0ee578f4
#ifndef NR_USER_DEF_H
#define NR_USER_DEF_H
#include <openair3/UICC/usim_interface.h>
#include <openair3/UICC/usim_interface.h>
typedef
struct
{
typedef
struct
{
uicc_t
*
uicc
;
uicc_t
*
uicc
;
}
nr_user_nas_t
;
}
nr_user_nas_t
;
#define myCalloc(var, type) type * var=(type*)calloc(sizeof(type),1);
int
identityResponse
(
void
**
msg
,
nr_user_nas_t
*
UE
);
int
identityResponse
(
void
**
msg
,
nr_user_nas_t
*
UE
);
#endif
openair3/NAS/NR_UE/ue_process_nas.c
View file @
0ee578f4
...
@@ -76,7 +76,7 @@ int identityResponse(void **msg, nr_user_nas_t *UE) {
...
@@ -76,7 +76,7 @@ int identityResponse(void **msg, nr_user_nas_t *UE) {
UE
->
uicc
=
init_uicc
(
"uicc"
);
UE
->
uicc
=
init_uicc
(
"uicc"
);
// TS 24.501 9.11.3.4
// TS 24.501 9.11.3.4
int
imsiL
=
strlen
(
UE
->
uicc
->
imsi
);
int
imsiL
=
strlen
(
UE
->
uicc
->
imsi
Str
);
int
msinL
=
imsiL
-
3
-
UE
->
uicc
->
nmc_size
;
int
msinL
=
imsiL
-
3
-
UE
->
uicc
->
nmc_size
;
int
respSize
=
sizeof
(
IdentityresponseIMSI_t
)
+
(
msinL
+
1
)
/
2
;
int
respSize
=
sizeof
(
IdentityresponseIMSI_t
)
+
(
msinL
+
1
)
/
2
;
IdentityresponseIMSI_t
*
resp
=
(
IdentityresponseIMSI_t
*
)
calloc
(
respSize
,
1
);
IdentityresponseIMSI_t
*
resp
=
(
IdentityresponseIMSI_t
*
)
calloc
(
respSize
,
1
);
...
@@ -85,17 +85,17 @@ int identityResponse(void **msg, nr_user_nas_t *UE) {
...
@@ -85,17 +85,17 @@ int identityResponse(void **msg, nr_user_nas_t *UE) {
resp
->
common
.
mt
=
Identityresponse
;
resp
->
common
.
mt
=
Identityresponse
;
resp
->
common
.
len
=
htons
(
respSize
-
sizeof
(
Identityresponse_t
));
resp
->
common
.
len
=
htons
(
respSize
-
sizeof
(
Identityresponse_t
));
resp
->
mi
=
SUCI
;
resp
->
mi
=
SUCI
;
resp
->
mcc1
=
UE
->
uicc
->
imsi
[
0
]
-
'0'
;
resp
->
mcc1
=
UE
->
uicc
->
imsi
Str
[
0
]
-
'0'
;
resp
->
mcc2
=
UE
->
uicc
->
imsi
[
1
]
-
'0'
;
resp
->
mcc2
=
UE
->
uicc
->
imsi
Str
[
1
]
-
'0'
;
resp
->
mcc3
=
UE
->
uicc
->
imsi
[
2
]
-
'0'
;
resp
->
mcc3
=
UE
->
uicc
->
imsi
Str
[
2
]
-
'0'
;
resp
->
mnc1
=
UE
->
uicc
->
imsi
[
3
]
-
'0'
;
resp
->
mnc1
=
UE
->
uicc
->
imsi
Str
[
3
]
-
'0'
;
resp
->
mnc2
=
UE
->
uicc
->
imsi
[
4
]
-
'0'
;
resp
->
mnc2
=
UE
->
uicc
->
imsi
Str
[
4
]
-
'0'
;
resp
->
mnc3
=
UE
->
uicc
->
nmc_size
==
2
?
0xF
:
UE
->
uicc
->
imsi
[
3
]
-
'0'
;
resp
->
mnc3
=
UE
->
uicc
->
nmc_size
==
2
?
0xF
:
UE
->
uicc
->
imsi
Str
[
3
]
-
'0'
;
// TBD: routing to fill (FF ?)
// TBD: routing to fill (FF ?)
char
*
out
=
(
char
*
)(
resp
+
1
);
char
*
out
=
(
char
*
)(
resp
+
1
);
char
*
ptr
=
UE
->
uicc
->
imsi
+
3
+
UE
->
uicc
->
nmc_size
;
char
*
ptr
=
UE
->
uicc
->
imsi
Str
+
3
+
UE
->
uicc
->
nmc_size
;
while
(
ptr
<
UE
->
uicc
->
imsi
+
strlen
(
UE
->
uicc
->
imsi
)
)
{
while
(
ptr
<
UE
->
uicc
->
imsi
Str
+
strlen
(
UE
->
uicc
->
imsiStr
)
)
{
*
out
=
((
*
(
ptr
+
1
)
-
'0'
)
<<
4
)
|
(
*
(
ptr
)
-
'0'
);
*
out
=
((
*
(
ptr
+
1
)
-
'0'
)
<<
4
)
|
(
*
(
ptr
)
-
'0'
);
out
++
;
out
++
;
ptr
+=
2
;
ptr
+=
2
;
...
@@ -105,7 +105,6 @@ int identityResponse(void **msg, nr_user_nas_t *UE) {
...
@@ -105,7 +105,6 @@ int identityResponse(void **msg, nr_user_nas_t *UE) {
*
out
=
((
*
(
ptr
-
1
)
-
'0'
))
|
0xF0
;
*
out
=
((
*
(
ptr
-
1
)
-
'0'
))
|
0xF0
;
*
msg
=
resp
;
*
msg
=
resp
;
log_dump
(
NAS
,
resp
,
respSize
,
LOG_DUMP_CHAR
,
"
\n
"
);
return
respSize
;
return
respSize
;
}
}
...
...
openair3/NAS/gNB/network_process_nas.c
View file @
0ee578f4
#include <openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h>
#include <openair3/NAS/NR_UE/nr_user_def.h>
#include <openair3/NAS/COMMON/milenage.h>
#include <openair3/NAS/gNB/network_process_nas.h>
void
SGSabortUE
(
void
*
msg
,
NRUEcontext_t
*
UE
)
{
void
SGSabortUE
(
void
*
msg
,
NRUEcontext_t
*
UE
)
{
}
}
...
@@ -33,25 +35,29 @@ void processNAS(void *msg, NRUEcontext_t *UE) {
...
@@ -33,25 +35,29 @@ void processNAS(void *msg, NRUEcontext_t *UE) {
SGSabortUE
(
msg
,
UE
);
SGSabortUE
(
msg
,
UE
);
else
{
else
{
switch
(
header
->
epd
)
{
switch
(
header
->
epd
)
{
SGSmobilitymanagementmessages:
case
SGSmobilitymanagementmessages
:
switch
(
header
->
mt
)
{
switch
(
header
->
mt
)
{
Registrationrequest:
case
Registrationrequest
:
SGSregistrationReq
(
msg
,
UE
);
SGSregistrationReq
(
msg
,
UE
);
break
;
break
;
DeregistrationrequestUEoriginating:
case
DeregistrationrequestUEoriginating
:
SGSderegistrationUEReq
(
msg
,
UE
);
SGSderegistrationUEReq
(
msg
,
UE
);
break
;
break
;
Authenticationresponse:
case
Authenticationresponse
:
SGSauthenticationResp
(
msg
,
UE
);
SGSauthenticationResp
(
msg
,
UE
);
break
;
break
;
Identityresponse:
case
Identityresponse
:
SGSidentityResp
(
msg
,
UE
);
SGSidentityResp
(
msg
,
UE
);
break
;
break
;
Securitymodecomplete:
case
Securitymodecomplete
:
SGSsecurityModeComplete
(
msg
,
UE
);
SGSsecurityModeComplete
(
msg
,
UE
);
break
;
break
;
Registrationcomplete:
case
Registrationcomplete
:
SGSregistrationComplete
(
msg
,
UE
);
SGSregistrationComplete
(
msg
,
UE
);
break
;
break
;
...
@@ -60,7 +66,8 @@ Registrationcomplete:
...
@@ -60,7 +66,8 @@ Registrationcomplete:
}
}
break
;
break
;
SGSsessionmanagementmessages:
case
SGSsessionmanagementmessages
:
SGSabortUE
(
msg
,
UE
);
SGSabortUE
(
msg
,
UE
);
break
;
break
;
...
@@ -75,10 +82,60 @@ SGSsessionmanagementmessages:
...
@@ -75,10 +82,60 @@ SGSsessionmanagementmessages:
*/
*/
int
identityRequest
(
void
**
msg
,
NRUEcontext_t
*
UE
)
{
int
identityRequest
(
void
**
msg
,
NRUEcontext_t
*
UE
)
{
myCalloc
(
req
,
Identityrequest_t
);
req
->
epd
=
SGSmobilitymanagementmessages
;
req
->
sh
=
0
;
req
->
mt
=
Identityrequest
;
req
->
it
=
SUCI
;
*
msg
=
req
;
return
sizeof
(
Identityrequest_t
);
}
}
int
authenticationRequest
(
void
**
msg
,
NRUEcontext_t
*
UE
)
{
int
authenticationRequest
(
void
**
msg
,
NRUEcontext_t
*
UE
)
{
if
(
UE
->
uicc
==
NULL
)
// config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE
UE
->
uicc
=
init_uicc
(
"uicc"
);
myCalloc
(
req
,
authenticationrequestHeader_t
);
req
->
epd
=
SGSmobilitymanagementmessages
;
req
->
sh
=
0
;
req
->
mt
=
Authenticationrequest
;
// native security context => bit 4 to 0
// probably from TS 33.501, table A-8.1
// N-NAS-int-alg (Native NAS integrity)
/*
N-NAS-enc-alg 0x01
N-NAS-int-alg 0x02
N-RRC-enc-alg 0x03
N-RRC-int-alg 0x04
N-UP-enc-alg 0x05
N-UP-int-alg 0x06
*/
req
->
ngKSI
=
2
;
// TS 33.501, Annex A.7.1: Initial set of security features defined for 5GS.
req
->
ABBALen
=
2
;
req
->
ABBA
=
0
;
//rand (TV)
req
->
ieiRAND
=
IEI_RAND
;
FILE
*
h
=
fopen
(
"/dev/random"
,
"r"
);
if
(
sizeof
(
req
->
RAND
)
!=
fread
(
req
->
RAND
,
1
,
sizeof
(
req
->
RAND
),
h
)
)
LOG_E
(
NAS
,
"can't read /dev/random
\n
"
);
fclose
(
h
);
// challenge/AUTN (TLV)
req
->
ieiAUTN
=
IEI_AUTN
;
req
->
AUTNlen
=
sizeof
(
req
->
AUTN
);
uint8_t
ik
[
16
],
ck
[
16
],
res
[
8
];
milenage_generate
(
UE
->
uicc
->
opc
,
UE
->
uicc
->
amf
,
UE
->
uicc
->
key
,
UE
->
uicc
->
sqn
,
req
->
RAND
,
req
->
AUTN
,
ik
,
ck
,
res
);
// EAP message (TLV-E)
// not developped
*
msg
=
req
;
return
sizeof
(
authenticationrequestHeader_t
);
}
}
int
securityModeCommand
(
void
**
msg
,
NRUEcontext_t
*
UE
)
{
int
securityModeCommand
(
void
**
msg
,
NRUEcontext_t
*
UE
)
{
*
msg
=
NULL
;
return
0
;
}
}
openair3/NAS/gNB/network_process_nas.h
0 → 100644
View file @
0ee578f4
#ifndef NET_PROCESS_NAS_H
#define NET_PROCESS_NAS_H
#include <openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h>
void
SGSabortUE
(
void
*
msg
,
NRUEcontext_t
*
UE
)
;
void
SGSregistrationReq
(
void
*
msg
,
NRUEcontext_t
*
UE
);
void
SGSderegistrationUEReq
(
void
*
msg
,
NRUEcontext_t
*
UE
);
void
SGSauthenticationResp
(
void
*
msg
,
NRUEcontext_t
*
UE
);
void
SGSidentityResp
(
void
*
msg
,
NRUEcontext_t
*
UE
);
void
SGSsecurityModeComplete
(
void
*
msg
,
NRUEcontext_t
*
UE
);
void
SGSregistrationComplete
(
void
*
msg
,
NRUEcontext_t
*
UE
);
void
processNAS
(
void
*
msg
,
NRUEcontext_t
*
UE
);
int
identityRequest
(
void
**
msg
,
NRUEcontext_t
*
UE
);
int
authenticationRequest
(
void
**
msg
,
NRUEcontext_t
*
UE
);
int
securityModeCommand
(
void
**
msg
,
NRUEcontext_t
*
UE
);
#endif
openair3/UICC/usim_interface.c
View file @
0ee578f4
...
@@ -33,18 +33,38 @@
...
@@ -33,18 +33,38 @@
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define UICC_PARAMS_DESC {\
#define UICC_PARAMS_DESC {\
{"imsi", "USIM IMSI\n", 0, strptr:&(uicc->imsi), defstrval:"", TYPE_STRING, 0 },\
{"imsi", "USIM IMSI\n", 0, strptr:&(uicc->imsiStr), defstrval:"", TYPE_STRING, 0 },\
{"nmc_size" "number of digits in NMC", 0, iptr:&(uicc->nmc_size), defintval:2, TYPE_INT, 0 },\
{"nmc_size" "number of digits in NMC", 0, iptr:&(uicc->nmc_size), defintval:2, TYPE_INT, 0 },\
{"key", "USIM Ki\n", 0, strptr:&(uicc->key), defstrval:"", TYPE_STRING, 0 },\
{"key", "USIM Ki\n", 0, strptr:&(uicc->keyStr), defstrval:"", TYPE_STRING, 0 },\
{"opc", "USIM OPc\n", 0, strptr:&(uicc->opc), defstrval:"", TYPE_STRING, 0 },\
{"opc", "USIM OPc\n", 0, strptr:&(uicc->opcStr), defstrval:"", TYPE_STRING, 0 },\
{"amf", "USIM amf\n", 0, strptr:&(uicc->amfStr), defstrval:"8000", TYPE_STRING, 0 },\
{"sqn", "USIM sqn\n", 0, strptr:&(uicc->sqnStr), defstrval:"000000", TYPE_STRING, 0 },\
};
};
const
char
*
hexTable
=
"0123456789abcdef"
;
static
inline
void
to_hex
(
char
*
in
,
uint8_t
*
out
,
bool
swap
)
{
if
(
swap
)
for
(
size_t
i
=
0
;
in
[
i
]
!=
0
;
i
++
)
{
out
+=
hexTable
[
in
[
i
]
&
0xf
];
out
+=
hexTable
[
in
[
i
]
>>
4
&
0xf
];
}
else
{
for
(
size_t
i
=
0
;
in
[
i
]
!=
0
;
i
++
)
{
out
+=
hexTable
[
in
[
i
]
>>
4
&
0xf
];
out
+=
hexTable
[
in
[
i
]
&
0xf
];
}
}
}
uicc_t
*
init_uicc
(
char
*
sectionName
)
{
uicc_t
*
init_uicc
(
char
*
sectionName
)
{
uicc_t
*
uicc
=
(
uicc_t
*
)
calloc
(
sizeof
(
uicc_t
),
1
);
uicc_t
*
uicc
=
(
uicc_t
*
)
calloc
(
sizeof
(
uicc_t
),
1
);
paramdef_t
uicc_params
[]
=
UICC_PARAMS_DESC
;
paramdef_t
uicc_params
[]
=
UICC_PARAMS_DESC
;
int
ret
=
config_get
(
uicc_params
,
sizeof
(
uicc_params
)
/
sizeof
(
paramdef_t
),
sectionName
);
int
ret
=
config_get
(
uicc_params
,
sizeof
(
uicc_params
)
/
sizeof
(
paramdef_t
),
sectionName
);
AssertFatal
(
ret
>=
0
,
"configuration couldn't be performed"
);
AssertFatal
(
ret
>=
0
,
"configuration couldn't be performed"
);
LOG_I
(
HW
,
"UICC simulation: IMSI=%s, Ki=%s, OPc=%s
\n
"
,
uicc
->
imsi
,
uicc
->
key
,
uicc
->
opc
);
LOG_I
(
HW
,
"UICC simulation: IMSI=%s, Ki=%s, OPc=%s
\n
"
,
uicc
->
imsiStr
,
uicc
->
keyStr
,
uicc
->
opcStr
);
to_hex
(
uicc
->
keyStr
,
uicc
->
key
,
false
);
to_hex
(
uicc
->
opcStr
,
uicc
->
opc
,
false
);
to_hex
(
uicc
->
sqnStr
,
uicc
->
sqn
,
false
);
to_hex
(
uicc
->
amfStr
,
uicc
->
amf
,
false
);
return
uicc
;
return
uicc
;
}
}
openair3/UICC/usim_interface.h
View file @
0ee578f4
...
@@ -20,6 +20,8 @@
...
@@ -20,6 +20,8 @@
* For more information about the OpenAirInterface (OAI) Software Alliance:
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
* contact@openairinterface.org
*/
*/
#ifndef USIM_INTERFACE_H
#define USIM_INTERFACE_H
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
...
@@ -34,9 +36,15 @@
...
@@ -34,9 +36,15 @@
#include "common_lib.h"
#include "common_lib.h"
typedef
struct
{
typedef
struct
{
char
*
imsi
;
char
*
imsiStr
;
char
*
key
;
char
*
keyStr
;
char
*
opc
;
char
*
opcStr
;
char
*
amfStr
;
char
*
sqnStr
;
uint8_t
key
[
16
];
uint8_t
opc
[
16
];
uint8_t
amf
[
2
];
uint8_t
sqn
[
6
];
int
nmc_size
;
int
nmc_size
;
}
uicc_t
;
}
uicc_t
;
...
@@ -44,3 +52,4 @@ typedef struct {
...
@@ -44,3 +52,4 @@ typedef struct {
* Read the configuration file, section name variable to be able to manage several UICC
* Read the configuration file, section name variable to be able to manage several UICC
*/
*/
uicc_t
*
init_uicc
(
char
*
sectionName
);
uicc_t
*
init_uicc
(
char
*
sectionName
);
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment