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
spbro
OpenXG-RAN
Commits
adc88d3d
Commit
adc88d3d
authored
Aug 27, 2024
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/nr-ue-nas-cleanup' into integration_2024_w34
parents
020662f9
50f8f3de
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
260 additions
and
258 deletions
+260
-258
openair2/RRC/NR_UE/rrc_UE.c
openair2/RRC/NR_UE/rrc_UE.c
+3
-3
openair3/NAS/NR_UE/nr_nas_msg_sim.c
openair3/NAS/NR_UE/nr_nas_msg_sim.c
+256
-255
openair3/NAS/NR_UE/nr_nas_msg_sim.h
openair3/NAS/NR_UE/nr_nas_msg_sim.h
+1
-0
No files found.
openair2/RRC/NR_UE/rrc_UE.c
View file @
adc88d3d
...
...
@@ -188,7 +188,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
if
(
ie
->
nonCriticalExtension
->
dedicatedNAS_MessageList
)
{
struct
NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*
tmp
=
ext
->
dedicatedNAS_MessageList
;
for
(
int
i
=
0
;
i
<
tmp
->
list
.
count
;
i
++
)
{
MessageDef
*
ittiMsg
=
itti_alloc_new_message
(
TASK_RRC_NRUE
,
0
,
NAS_CONN_ESTABLI_CNF
);
MessageDef
*
ittiMsg
=
itti_alloc_new_message
(
TASK_RRC_NRUE
,
rrc
->
ue_id
,
NAS_CONN_ESTABLI_CNF
);
NasConnEstabCnf
*
msg
=
&
NAS_CONN_ESTABLI_CNF
(
ittiMsg
);
msg
->
errCode
=
AS_SUCCESS
;
msg
->
nasMsg
.
length
=
tmp
->
list
.
array
[
i
]
->
size
;
...
...
@@ -1658,7 +1658,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
NR_DedicatedNAS_Message_t
*
dedicatedNAS_Message
=
dlInformationTransfer
->
criticalExtensions
.
choice
.
dlInformationTransfer
->
dedicatedNAS_Message
;
MessageDef
*
ittiMsg
=
itti_alloc_new_message
(
TASK_RRC_NRUE
,
0
,
NAS_DOWNLINK_DATA_IND
);
MessageDef
*
ittiMsg
=
itti_alloc_new_message
(
TASK_RRC_NRUE
,
rrc
->
ue_id
,
NAS_DOWNLINK_DATA_IND
);
NasDlDataInd
*
msg
=
&
NAS_DOWNLINK_DATA_IND
(
ittiMsg
);
msg
->
UEid
=
rrc
->
ue_id
;
msg
->
nasMsg
.
length
=
dedicatedNAS_Message
->
size
;
...
...
@@ -2310,7 +2310,7 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
rrc
->
rnti
=
0
;
// Indicate the release of the RRC connection to upper layers
MessageDef
*
msg_p
=
itti_alloc_new_message
(
TASK_RRC_NRUE
,
0
,
NR_NAS_CONN_RELEASE_IND
);
MessageDef
*
msg_p
=
itti_alloc_new_message
(
TASK_RRC_NRUE
,
rrc
->
ue_id
,
NR_NAS_CONN_RELEASE_IND
);
NR_NAS_CONN_RELEASE_IND
(
msg_p
).
cause
=
release_cause
;
itti_send_msg_to_task
(
TASK_NAS_NRUE
,
rrc
->
ue_id
,
msg_p
);
}
...
...
openair3/NAS/NR_UE/nr_nas_msg_sim.c
View file @
adc88d3d
...
...
@@ -29,7 +29,6 @@
* 2023.01.27 Vladimir Dorovskikh 16 digits IMEISV
*/
#include <string.h> // memset
#include <stdlib.h> // malloc, free
...
...
@@ -52,8 +51,10 @@
#include "openair3/SECU/nas_stream_eia2.h"
#include "openair3/UTILS/conversions.h"
#define MAX_NAS_UE 4
extern
uint16_t
NB_UE_INST
;
static
nr_ue_nas_t
nr_ue_nas
=
{
0
};
static
nr_ue_nas_t
nr_ue_nas
[
MAX_NAS_UE
]
=
{
0
};
static
nr_nas_msg_snssai_t
nas_allowed_nssai
[
8
];
typedef
enum
{
...
...
@@ -98,13 +99,13 @@ security_state_t nas_security_rx_process(nr_ue_nas_t *nas, uint8_t *pdu_buffer,
/* check integrity */
uint8_t
computed_mac
[
4
];
nas_stream_cipher_t
stream_cipher
;
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_dl
;
stream_cipher
.
bearer
=
1
;
/* todo: don't hardcode */
stream_cipher
.
direction
=
1
;
stream_cipher
.
message
=
pdu_buffer
+
6
;
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_dl
;
stream_cipher
.
bearer
=
1
;
/* todo: don't hardcode */
stream_cipher
.
direction
=
1
;
stream_cipher
.
message
=
pdu_buffer
+
6
;
/* length in bits */
stream_cipher
.
blength
=
(
pdu_length
-
6
)
<<
3
;
stream_cipher
.
blength
=
(
pdu_length
-
6
)
<<
3
;
stream_compute_integrity
(
nas
->
security_container
->
integrity_algorithm
,
&
stream_cipher
,
computed_mac
);
uint8_t
*
received_mac
=
pdu_buffer
+
2
;
...
...
@@ -114,13 +115,13 @@ security_state_t nas_security_rx_process(nr_ue_nas_t *nas, uint8_t *pdu_buffer,
/* decipher */
uint8_t
buf
[
pdu_length
-
7
];
stream_cipher
.
context
=
nas
->
security_container
->
ciphering_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_dl
;
stream_cipher
.
bearer
=
1
;
/* todo: don't hardcode */
stream_cipher
.
direction
=
1
;
stream_cipher
.
message
=
pdu_buffer
+
7
;
stream_cipher
.
context
=
nas
->
security_container
->
ciphering_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_dl
;
stream_cipher
.
bearer
=
1
;
/* todo: don't hardcode */
stream_cipher
.
direction
=
1
;
stream_cipher
.
message
=
pdu_buffer
+
7
;
/* length in bits */
stream_cipher
.
blength
=
(
pdu_length
-
7
)
<<
3
;
stream_cipher
.
blength
=
(
pdu_length
-
7
)
<<
3
;
stream_compute_encrypt
(
nas
->
security_container
->
ciphering_algorithm
,
&
stream_cipher
,
buf
);
memcpy
(
pdu_buffer
+
7
,
buf
,
pdu_length
-
7
);
...
...
@@ -129,10 +130,7 @@ security_state_t nas_security_rx_process(nr_ue_nas_t *nas, uint8_t *pdu_buffer,
return
NAS_SECURITY_INTEGRITY_PASSED
;
}
static
int
nas_protected_security_header_encode
(
char
*
buffer
,
const
fgs_nas_message_security_header_t
*
header
,
int
length
)
static
int
nas_protected_security_header_encode
(
char
*
buffer
,
const
fgs_nas_message_security_header_t
*
header
,
int
length
)
{
LOG_FUNC_IN
;
...
...
@@ -142,18 +140,18 @@ static int nas_protected_security_header_encode(
ENCODE_U8
(
buffer
,
header
->
protocol_discriminator
,
size
);
/* Encode the security header type */
ENCODE_U8
(
buffer
+
size
,
(
header
->
security_header_type
&
0xf
),
size
);
ENCODE_U8
(
buffer
+
size
,
(
header
->
security_header_type
&
0xf
),
size
);
/* Encode the message authentication code */
ENCODE_U32
(
buffer
+
size
,
header
->
message_authentication_code
,
size
);
ENCODE_U32
(
buffer
+
size
,
header
->
message_authentication_code
,
size
);
/* Encode the sequence number */
ENCODE_U8
(
buffer
+
size
,
header
->
sequence_number
,
size
);
ENCODE_U8
(
buffer
+
size
,
header
->
sequence_number
,
size
);
LOG_FUNC_RETURN
(
size
);
LOG_FUNC_RETURN
(
size
);
}
static
int
_nas_mm_msg_encode_header
(
const
mm_msg_header_t
*
header
,
uint8_t
*
buffer
,
uint32_t
len
)
{
static
int
_nas_mm_msg_encode_header
(
const
mm_msg_header_t
*
header
,
uint8_t
*
buffer
,
uint32_t
len
)
{
int
size
=
0
;
/* Check the buffer length */
...
...
@@ -163,8 +161,7 @@ static int _nas_mm_msg_encode_header(const mm_msg_header_t *header,
/* Check the protocol discriminator */
if
(
header
->
ex_protocol_discriminator
!=
FGS_MOBILITY_MANAGEMENT_MESSAGE
)
{
LOG_TRACE
(
ERROR
,
"ESM-MSG - Unexpected extened protocol discriminator: 0x%x"
,
header
->
ex_protocol_discriminator
);
LOG_TRACE
(
ERROR
,
"ESM-MSG - Unexpected extened protocol discriminator: 0x%x"
,
header
->
ex_protocol_discriminator
);
return
(
TLV_ENCODE_PROTOCOL_NOT_SUPPORTED
);
}
...
...
@@ -199,7 +196,7 @@ static int fill_guti(FGSMobileIdentity *mi, const Guti5GSMobileIdentity_t *guti)
static
int
fill_imeisv
(
FGSMobileIdentity
*
mi
,
const
uicc_t
*
uicc
)
{
int
i
=
0
;
int
i
=
0
;
mi
->
imeisv
.
typeofidentity
=
FGS_MOBILE_IDENTITY_IMEISV
;
mi
->
imeisv
.
digittac01
=
getImeisvDigit
(
uicc
,
i
++
);
mi
->
imeisv
.
digittac02
=
getImeisvDigit
(
uicc
,
i
++
);
...
...
@@ -217,31 +214,33 @@ static int fill_imeisv(FGSMobileIdentity *mi, const uicc_t *uicc)
mi
->
imeisv
.
digit14
=
getImeisvDigit
(
uicc
,
i
++
);
mi
->
imeisv
.
digitsv1
=
getImeisvDigit
(
uicc
,
i
++
);
mi
->
imeisv
.
digitsv2
=
getImeisvDigit
(
uicc
,
i
++
);
mi
->
imeisv
.
spare
=
0x0f
;
mi
->
imeisv
.
spare
=
0x0f
;
mi
->
imeisv
.
oddeven
=
0
;
return
19
;
}
int
mm_msg_encode
(
MM_msg
*
mm_msg
,
uint8_t
*
buffer
,
uint32_t
len
)
{
int
mm_msg_encode
(
MM_msg
*
mm_msg
,
uint8_t
*
buffer
,
uint32_t
len
)
{
LOG_FUNC_IN
;
int
header_result
;
int
encode_result
;
uint8_t
msg_type
=
mm_msg
->
header
.
message_type
;
/* First encode the EMM message header */
header_result
=
_nas_mm_msg_encode_header
(
&
mm_msg
->
header
,
buffer
,
len
);
if
(
header_result
<
0
)
{
LOG_TRACE
(
ERROR
,
"EMM-MSG - Failed to encode EMM message header "
"(%d)"
,
header_result
);
LOG_TRACE
(
ERROR
,
"EMM-MSG - Failed to encode EMM message header "
"(%d)"
,
header_result
);
LOG_FUNC_RETURN
(
header_result
);
}
buffer
+=
header_result
;
len
-=
header_result
;
switch
(
msg_type
)
{
switch
(
msg_type
)
{
case
REGISTRATION_REQUEST
:
encode_result
=
encode_registration_request
(
&
mm_msg
->
registration_request
,
buffer
,
len
);
break
;
...
...
@@ -258,32 +257,36 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) {
encode_result
=
encode_fgs_uplink_nas_transport
(
&
mm_msg
->
uplink_nas_transport
,
buffer
,
len
);
break
;
case
FGS_DEREGISTRATION_REQUEST_UE_ORIGINATING
:
encode_result
=
encode_fgs_deregistration_request_ue_originating
(
&
mm_msg
->
fgs_deregistration_request_ue_originating
,
buffer
,
len
);
encode_result
=
encode_fgs_deregistration_request_ue_originating
(
&
mm_msg
->
fgs_deregistration_request_ue_originating
,
buffer
,
len
);
break
;
default:
LOG_TRACE
(
ERROR
,
"EMM-MSG - Unexpected message type: 0x%x"
,
mm_msg
->
header
.
message_type
);
LOG_TRACE
(
ERROR
,
"EMM-MSG - Unexpected message type: 0x%x"
,
mm_msg
->
header
.
message_type
);
encode_result
=
TLV_ENCODE_WRONG_MESSAGE_TYPE
;
break
;
/* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */
}
if
(
encode_result
<
0
)
{
LOG_TRACE
(
ERROR
,
"EMM-MSG - Failed to encode L3 EMM message 0x%x "
"(%d)"
,
mm_msg
->
header
.
message_type
,
encode_result
);
LOG_TRACE
(
ERROR
,
"EMM-MSG - Failed to encode L3 EMM message 0x%x "
"(%d)"
,
mm_msg
->
header
.
message_type
,
encode_result
);
}
if
(
encode_result
<
0
)
LOG_FUNC_RETURN
(
encode_result
);
LOG_FUNC_RETURN
(
encode_result
);
LOG_FUNC_RETURN
(
header_result
+
encode_result
);
LOG_FUNC_RETURN
(
header_result
+
encode_result
);
}
void
transferRES
(
uint8_t
ck
[
16
],
uint8_t
ik
[
16
],
uint8_t
*
input
,
uint8_t
rand
[
16
],
uint8_t
*
output
,
uicc_t
*
uicc
)
{
uint8_t
S
[
100
]
=
{
0
};
void
transferRES
(
uint8_t
ck
[
16
],
uint8_t
ik
[
16
],
uint8_t
*
input
,
uint8_t
rand
[
16
],
uint8_t
*
output
,
uicc_t
*
uicc
)
{
uint8_t
S
[
100
]
=
{
0
};
S
[
0
]
=
0x6B
;
servingNetworkName
(
S
+
1
,
uicc
->
imsiStr
,
uicc
->
nmc_size
);
int
netNamesize
=
strlen
((
char
*
)
S
+
1
);
servingNetworkName
(
S
+
1
,
uicc
->
imsiStr
,
uicc
->
nmc_size
);
int
netNamesize
=
strlen
((
char
*
)
S
+
1
);
S
[
1
+
netNamesize
]
=
(
netNamesize
&
0xff00
)
>>
8
;
S
[
2
+
netNamesize
]
=
(
netNamesize
&
0x00ff
);
for
(
int
i
=
0
;
i
<
16
;
i
++
)
...
...
@@ -295,7 +298,7 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16
S
[
29
+
netNamesize
]
=
0x00
;
S
[
30
+
netNamesize
]
=
0x08
;
uint8_t
plmn
[
3
]
=
{
0x02
,
0xf8
,
0x39
};
uint8_t
plmn
[
3
]
=
{
0x02
,
0xf8
,
0x39
};
uint8_t
oldS
[
100
];
oldS
[
0
]
=
0x6B
;
memcpy
(
&
oldS
[
1
],
plmn
,
3
);
...
...
@@ -310,10 +313,9 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16
oldS
[
32
]
=
0x00
;
oldS
[
33
]
=
0x08
;
uint8_t
key
[
32
]
=
{
0
};
memcpy
(
&
key
[
0
],
ck
,
16
);
memcpy
(
&
key
[
16
],
ik
,
16
);
//
KEY
memcpy
(
&
key
[
16
],
ik
,
16
);
//
KEY
uint8_t
out
[
32
]
=
{
0
};
byte_array_t
data
=
{.
buf
=
S
,
.
len
=
31
+
netNamesize
};
...
...
@@ -322,44 +324,47 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16
memcpy
(
output
,
out
+
16
,
16
);
}
void
derive_kausf
(
uint8_t
ck
[
16
],
uint8_t
ik
[
16
],
uint8_t
sqn
[
6
],
uint8_t
kausf
[
32
],
uicc_t
*
uicc
)
{
uint8_t
S
[
100
]
=
{
0
};
void
derive_kausf
(
uint8_t
ck
[
16
],
uint8_t
ik
[
16
],
uint8_t
sqn
[
6
],
uint8_t
kausf
[
32
],
uicc_t
*
uicc
)
{
uint8_t
S
[
100
]
=
{
0
};
uint8_t
key
[
32
]
=
{
0
};
memcpy
(
&
key
[
0
],
ck
,
16
);
memcpy
(
&
key
[
16
],
ik
,
16
);
//
KEY
memcpy
(
&
key
[
16
],
ik
,
16
);
//
KEY
S
[
0
]
=
0x6A
;
servingNetworkName
(
S
+
1
,
uicc
->
imsiStr
,
uicc
->
nmc_size
);
int
netNamesize
=
strlen
((
char
*
)
S
+
1
);
servingNetworkName
(
S
+
1
,
uicc
->
imsiStr
,
uicc
->
nmc_size
);
int
netNamesize
=
strlen
((
char
*
)
S
+
1
);
S
[
1
+
netNamesize
]
=
(
uint8_t
)((
netNamesize
&
0xff00
)
>>
8
);
S
[
2
+
netNamesize
]
=
(
uint8_t
)(
netNamesize
&
0x00ff
);
for
(
int
i
=
0
;
i
<
6
;
i
++
)
{
S
[
3
+
netNamesize
+
i
]
=
sqn
[
i
];
S
[
3
+
netNamesize
+
i
]
=
sqn
[
i
];
}
S
[
9
+
netNamesize
]
=
0x00
;
S
[
10
+
netNamesize
]
=
0x06
;
byte_array_t
data
=
{.
buf
=
S
,
.
len
=
11
+
netNamesize
};
byte_array_t
data
=
{.
buf
=
S
,
.
len
=
11
+
netNamesize
};
kdf
(
key
,
data
,
32
,
kausf
);
}
void
derive_kseaf
(
uint8_t
kausf
[
32
],
uint8_t
kseaf
[
32
],
uicc_t
*
uicc
)
{
uint8_t
S
[
100
]
=
{
0
};
S
[
0
]
=
0x6C
;
//FC
servingNetworkName
(
S
+
1
,
uicc
->
imsiStr
,
uicc
->
nmc_size
);
int
netNamesize
=
strlen
((
char
*
)
S
+
1
);
void
derive_kseaf
(
uint8_t
kausf
[
32
],
uint8_t
kseaf
[
32
],
uicc_t
*
uicc
)
{
uint8_t
S
[
100
]
=
{
0
};
S
[
0
]
=
0x6C
;
// FC
servingNetworkName
(
S
+
1
,
uicc
->
imsiStr
,
uicc
->
nmc_size
);
int
netNamesize
=
strlen
((
char
*
)
S
+
1
);
S
[
1
+
netNamesize
]
=
(
uint8_t
)((
netNamesize
&
0xff00
)
>>
8
);
S
[
2
+
netNamesize
]
=
(
uint8_t
)(
netNamesize
&
0x00ff
);
byte_array_t
data
=
{.
buf
=
S
,
.
len
=
3
+
netNamesize
};
byte_array_t
data
=
{.
buf
=
S
,
.
len
=
3
+
netNamesize
};
kdf
(
kausf
,
data
,
32
,
kseaf
);
}
void
derive_kamf
(
uint8_t
*
kseaf
,
uint8_t
*
kamf
,
uint16_t
abba
,
uicc_t
*
uicc
)
{
void
derive_kamf
(
uint8_t
*
kseaf
,
uint8_t
*
kamf
,
uint16_t
abba
,
uicc_t
*
uicc
)
{
int
imsiLen
=
strlen
(
uicc
->
imsiStr
);
uint8_t
S
[
100
]
=
{
0
};
S
[
0
]
=
0x6D
;
//
FC = 0x6D
memcpy
(
&
S
[
1
],
uicc
->
imsiStr
,
imsiLen
);
S
[
0
]
=
0x6D
;
//
FC = 0x6D
memcpy
(
&
S
[
1
],
uicc
->
imsiStr
,
imsiLen
);
S
[
1
+
imsiLen
]
=
(
uint8_t
)((
imsiLen
&
0xff00
)
>>
8
);
S
[
2
+
imsiLen
]
=
(
uint8_t
)(
imsiLen
&
0x00ff
);
S
[
3
+
imsiLen
]
=
abba
&
0x00ff
;
...
...
@@ -375,8 +380,8 @@ void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) {
void
derive_knas
(
algorithm_type_dist_t
nas_alg_type
,
uint8_t
nas_alg_id
,
uint8_t
kamf
[
32
],
uint8_t
*
knas
)
{
uint8_t
S
[
20
]
=
{
0
};
uint8_t
out
[
32
]
=
{
0
};
S
[
0
]
=
0x69
;
//
FC
uint8_t
out
[
32
]
=
{
0
};
S
[
0
]
=
0x69
;
//
FC
S
[
1
]
=
(
uint8_t
)(
nas_alg_type
&
0xFF
);
S
[
2
]
=
0x00
;
S
[
3
]
=
0x01
;
...
...
@@ -387,14 +392,15 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t
byte_array_t
data
=
{.
buf
=
S
,
.
len
=
7
};
kdf
(
kamf
,
data
,
32
,
out
);
memcpy
(
knas
,
out
+
16
,
16
);
memcpy
(
knas
,
out
+
16
,
16
);
}
void
derive_kgnb
(
uint8_t
kamf
[
32
],
uint32_t
count
,
uint8_t
*
kgnb
){
void
derive_kgnb
(
uint8_t
kamf
[
32
],
uint32_t
count
,
uint8_t
*
kgnb
)
{
/* Compute the KDF input parameter
* S = FC(0x6E) || UL NAS Count || 0x00 0x04 || 0x01 || 0x00 0x01
*/
uint8_t
input
[
32
]
=
{
0
};
uint8_t
input
[
32
]
=
{
0
};
// uint16_t length = 4;
// int offset = 0;
...
...
@@ -419,12 +425,13 @@ void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){
kdf
(
kamf
,
data
,
32
,
kgnb
);
printf
(
"kgnb : "
);
for
(
int
pp
=
0
;
pp
<
32
;
pp
++
)
printf
(
"%02x "
,
kgnb
[
pp
]);
for
(
int
pp
=
0
;
pp
<
32
;
pp
++
)
printf
(
"%02x "
,
kgnb
[
pp
]);
printf
(
"
\n
"
);
}
void
derive_ue_keys
(
uint8_t
*
buf
,
nr_ue_nas_t
*
nas
)
{
void
derive_ue_keys
(
uint8_t
*
buf
,
nr_ue_nas_t
*
nas
)
{
uint8_t
ak
[
6
];
uint8_t
sqn
[
6
];
...
...
@@ -437,8 +444,8 @@ void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) {
uint8_t
*
kgnb
=
nas
->
security
.
kgnb
;
// get RAND for authentication request
for
(
int
index
=
0
;
index
<
16
;
index
++
)
{
rand
[
index
]
=
buf
[
8
+
index
];
for
(
int
index
=
0
;
index
<
16
;
index
++
)
{
rand
[
index
]
=
buf
[
8
+
index
];
}
uint8_t
resTemp
[
16
];
...
...
@@ -447,30 +454,30 @@ void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) {
transferRES
(
ck
,
ik
,
resTemp
,
rand
,
output
,
nas
->
uicc
);
for
(
int
index
=
0
;
index
<
6
;
index
++
)
{
sqn
[
index
]
=
buf
[
26
+
index
];
for
(
int
index
=
0
;
index
<
6
;
index
++
)
{
sqn
[
index
]
=
buf
[
26
+
index
];
}
derive_kausf
(
ck
,
ik
,
sqn
,
kausf
,
nas
->
uicc
);
derive_kseaf
(
kausf
,
kseaf
,
nas
->
uicc
);
derive_kamf
(
kseaf
,
kamf
,
0x0000
,
nas
->
uicc
);
derive_kgnb
(
kamf
,
0
,
kgnb
);
derive_kgnb
(
kamf
,
0
,
kgnb
);
printf
(
"kausf:"
);
for
(
int
i
=
0
;
i
<
32
;
i
++
)
{
for
(
int
i
=
0
;
i
<
32
;
i
++
)
{
printf
(
"%x "
,
kausf
[
i
]);
}
printf
(
"
\n
"
);
printf
(
"kseaf:"
);
for
(
int
i
=
0
;
i
<
32
;
i
++
)
{
for
(
int
i
=
0
;
i
<
32
;
i
++
)
{
printf
(
"%x "
,
kseaf
[
i
]);
}
printf
(
"
\n
"
);
printf
(
"kamf:"
);
for
(
int
i
=
0
;
i
<
32
;
i
++
)
{
for
(
int
i
=
0
;
i
<
32
;
i
++
)
{
printf
(
"%x "
,
kamf
[
i
]);
}
printf
(
"
\n
"
);
...
...
@@ -478,16 +485,18 @@ void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas) {
nr_ue_nas_t
*
get_ue_nas_info
(
module_id_t
module_id
)
{
DevAssert
(
module_id
==
0
);
if
(
!
nr_ue_nas
.
uicc
)
nr_ue_nas
.
uicc
=
checkUicc
(
0
);
return
&
nr_ue_nas
;
DevAssert
(
module_id
<
MAX_NAS_UE
);
if
(
!
nr_ue_nas
[
module_id
].
uicc
)
{
nr_ue_nas
[
module_id
].
uicc
=
checkUicc
(
module_id
);
nr_ue_nas
[
module_id
].
UE_id
=
module_id
;
}
return
&
nr_ue_nas
[
module_id
];
}
void
generateRegistrationRequest
(
as_nas_info_t
*
initialNasMsg
,
nr_ue_nas_t
*
nas
)
{
int
size
=
sizeof
(
mm_msg_header_t
);
fgs_nas_message_t
nas_msg
=
{
0
};
fgs_nas_message_t
nas_msg
=
{
0
};
MM_msg
*
mm_msg
;
mm_msg
=
&
nas_msg
.
plain
.
mm_msg
;
...
...
@@ -496,7 +505,6 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
mm_msg
->
header
.
security_header_type
=
PLAIN_5GS_MSG
;
mm_msg
->
header
.
message_type
=
REGISTRATION_REQUEST
;
// set registration request
mm_msg
->
registration_request
.
protocoldiscriminator
=
FGS_MOBILITY_MANAGEMENT_MESSAGE
;
size
+=
1
;
...
...
@@ -507,7 +515,7 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
mm_msg
->
registration_request
.
fgsregistrationtype
=
INITIAL_REGISTRATION
;
mm_msg
->
registration_request
.
naskeysetidentifier
.
naskeysetidentifier
=
1
;
size
+=
1
;
if
(
nas
->
guti
)
{
if
(
nas
->
guti
)
{
size
+=
fill_guti
(
&
mm_msg
->
registration_request
.
fgsmobileidentity
,
nas
->
guti
);
}
else
{
size
+=
fill_suci
(
&
mm_msg
->
registration_request
.
fgsmobileidentity
,
nas
->
uicc
);
...
...
@@ -538,12 +546,12 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
initialNasMsg
->
data
=
malloc16_clear
(
size
*
sizeof
(
Byte_t
));
nas
->
registration_request_buf
=
initialNasMsg
->
data
;
initialNasMsg
->
length
=
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
),
size
);
initialNasMsg
->
length
=
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
),
size
);
nas
->
registration_request_len
=
initialNasMsg
->
length
;
}
void
generateIdentityResponse
(
as_nas_info_t
*
initialNasMsg
,
uint8_t
identitytype
,
uicc_t
*
uicc
)
{
void
generateIdentityResponse
(
as_nas_info_t
*
initialNasMsg
,
uint8_t
identitytype
,
uicc_t
*
uicc
)
{
int
size
=
sizeof
(
mm_msg_header_t
);
fgs_nas_message_t
nas_msg
;
memset
(
&
nas_msg
,
0
,
sizeof
(
fgs_nas_message_t
));
...
...
@@ -555,7 +563,6 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
mm_msg
->
header
.
security_header_type
=
PLAIN_5GS_MSG
;
mm_msg
->
header
.
message_type
=
FGS_IDENTITY_RESPONSE
;
// set identity response
mm_msg
->
fgs_identity_response
.
protocoldiscriminator
=
FGS_MOBILITY_MANAGEMENT_MESSAGE
;
size
+=
1
;
...
...
@@ -563,15 +570,14 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
size
+=
1
;
mm_msg
->
fgs_identity_response
.
messagetype
=
FGS_IDENTITY_RESPONSE
;
size
+=
1
;
if
(
identitytype
==
FGS_MOBILE_IDENTITY_SUCI
)
{
if
(
identitytype
==
FGS_MOBILE_IDENTITY_SUCI
)
{
size
+=
fill_suci
(
&
mm_msg
->
fgs_identity_response
.
fgsmobileidentity
,
uicc
);
}
// encode the message
initialNasMsg
->
data
=
(
Byte_t
*
)
malloc
(
size
*
sizeof
(
Byte_t
));
initialNasMsg
->
length
=
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
),
size
);
initialNasMsg
->
length
=
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
),
size
);
}
static
void
generateAuthenticationResp
(
nr_ue_nas_t
*
nas
,
as_nas_info_t
*
initialNasMsg
,
uint8_t
*
buf
)
...
...
@@ -579,7 +585,7 @@ static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialN
derive_ue_keys
(
buf
,
nas
);
OctetString
res
;
res
.
length
=
16
;
res
.
value
=
calloc
(
1
,
16
);
res
.
value
=
calloc
(
1
,
16
);
memcpy
(
res
.
value
,
nas
->
security
.
res
,
16
);
int
size
=
sizeof
(
mm_msg_header_t
);
...
...
@@ -601,19 +607,19 @@ static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialN
mm_msg
->
fgs_identity_response
.
messagetype
=
FGS_AUTHENTICATION_RESPONSE
;
size
+=
1
;
//set response parameter
//
set response parameter
mm_msg
->
fgs_auth_response
.
authenticationresponseparameter
.
res
=
res
;
size
+=
18
;
// encode the message
initialNasMsg
->
data
=
(
Byte_t
*
)
malloc
(
size
*
sizeof
(
Byte_t
));
initialNasMsg
->
length
=
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
),
size
);
initialNasMsg
->
length
=
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
),
size
);
}
int
nas_itti_kgnb_refresh_req
(
instance_t
instance
,
const
uint8_t
kgnb
[
32
])
{
MessageDef
*
message_p
;
message_p
=
itti_alloc_new_message
(
TASK_NAS_NRUE
,
0
,
NAS_KENB_REFRESH_REQ
);
message_p
=
itti_alloc_new_message
(
TASK_NAS_NRUE
,
instance
,
NAS_KENB_REFRESH_REQ
);
memcpy
(
NAS_KENB_REFRESH_REQ
(
message_p
).
kenb
,
kgnb
,
sizeof
(
NAS_KENB_REFRESH_REQ
(
message_p
).
kenb
));
return
itti_send_msg_to_task
(
TASK_RRC_NRUE
,
instance
,
message_p
);
}
...
...
@@ -626,7 +632,7 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
MM_msg
*
mm_msg
;
nas_stream_cipher_t
stream_cipher
;
uint8_t
mac
[
4
];
uint8_t
mac
[
4
];
// set security protected header
nas_msg
.
header
.
protocol_discriminator
=
FGS_MOBILITY_MANAGEMENT_MESSAGE
;
nas_msg
.
header
.
security_header_type
=
INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX
;
...
...
@@ -643,55 +649,57 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
// set security mode complete
mm_msg
->
fgs_security_mode_complete
.
protocoldiscriminator
=
FGS_MOBILITY_MANAGEMENT_MESSAGE
;
size
+=
1
;
mm_msg
->
fgs_security_mode_complete
.
securityheadertype
=
PLAIN_5GS_MSG
;
mm_msg
->
fgs_security_mode_complete
.
securityheadertype
=
PLAIN_5GS_MSG
;
size
+=
1
;
mm_msg
->
fgs_security_mode_complete
.
messagetype
=
FGS_SECURITY_MODE_COMPLETE
;
mm_msg
->
fgs_security_mode_complete
.
messagetype
=
FGS_SECURITY_MODE_COMPLETE
;
size
+=
1
;
size
+=
fill_imeisv
(
&
mm_msg
->
fgs_security_mode_complete
.
fgsmobileidentity
,
nas
->
uicc
);
mm_msg
->
fgs_security_mode_complete
.
fgsnasmessagecontainer
.
nasmessagecontainercontents
.
value
=
nas
->
registration_request_buf
;
mm_msg
->
fgs_security_mode_complete
.
fgsnasmessagecontainer
.
nasmessagecontainercontents
.
value
=
nas
->
registration_request_buf
;
mm_msg
->
fgs_security_mode_complete
.
fgsnasmessagecontainer
.
nasmessagecontainercontents
.
length
=
nas
->
registration_request_len
;
size
+=
(
nas
->
registration_request_len
+
2
);
// encode the message
initialNasMsg
->
data
=
(
Byte_t
*
)
malloc
(
size
*
sizeof
(
Byte_t
));
int
security_header_len
=
nas_protected_security_header_encode
((
char
*
)(
initialNasMsg
->
data
),
&
(
nas_msg
.
header
),
size
);
int
security_header_len
=
nas_protected_security_header_encode
((
char
*
)(
initialNasMsg
->
data
),
&
(
nas_msg
.
header
),
size
);
initialNasMsg
->
length
=
security_header_len
+
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
+
security_header_len
),
size
-
security_header_len
);
initialNasMsg
->
length
=
security_header_len
+
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
+
security_header_len
),
size
-
security_header_len
);
/* ciphering */
uint8_t
buf
[
initialNasMsg
->
length
-
7
];
stream_cipher
.
context
=
nas
->
security_container
->
ciphering_context
;
stream_cipher
.
context
=
nas
->
security_container
->
ciphering_context
;
AssertFatal
(
nas
->
security
.
nas_count_ul
<=
0xffffff
,
"fatal: NAS COUNT UL too big (todo: fix that)
\n
"
);
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
7
);
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
7
);
/* length in bits */
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
7
)
<<
3
;
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
7
)
<<
3
;
stream_compute_encrypt
(
nas
->
security_container
->
ciphering_algorithm
,
&
stream_cipher
,
buf
);
memcpy
(
stream_cipher
.
message
,
buf
,
initialNasMsg
->
length
-
7
);
/* integrity protection */
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
6
);
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
6
);
/* length in bits */
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
6
)
<<
3
;
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
6
)
<<
3
;
stream_compute_integrity
(
nas
->
security_container
->
integrity_algorithm
,
&
stream_cipher
,
mac
);
printf
(
"mac %x %x %x %x
\n
"
,
mac
[
0
],
mac
[
1
],
mac
[
2
],
mac
[
3
]);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
initialNasMsg
->
data
[
2
+
i
]
=
mac
[
i
];
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
initialNasMsg
->
data
[
2
+
i
]
=
mac
[
i
];
}
}
static
void
handle_security_mode_command
(
instance_t
instance
,
nr_ue_nas_t
*
nas
,
as_nas_info_t
*
initialNasMsg
,
uint8_t
*
pdu
,
int
pdu_length
)
static
void
handle_security_mode_command
(
nr_ue_nas_t
*
nas
,
as_nas_info_t
*
initialNasMsg
,
uint8_t
*
pdu
,
int
pdu_length
)
{
/* retrieve integrity and ciphering algorithms */
AssertFatal
(
pdu_length
>
10
,
"nas: bad pdu
\n
"
);
...
...
@@ -707,13 +715,13 @@ static void handle_security_mode_command(instance_t instance, nr_ue_nas_t *nas,
derive_knas
(
0x02
,
integrity_algorithm
,
kamf
,
knas_int
);
printf
(
"knas_int: "
);
for
(
int
i
=
0
;
i
<
16
;
i
++
)
{
for
(
int
i
=
0
;
i
<
16
;
i
++
)
{
printf
(
"%x "
,
knas_int
[
i
]);
}
printf
(
"
\n
"
);
printf
(
"knas_enc: "
);
for
(
int
i
=
0
;
i
<
16
;
i
++
)
{
for
(
int
i
=
0
;
i
<
16
;
i
++
)
{
printf
(
"%x "
,
knas_enc
[
i
]);
}
printf
(
"
\n
"
);
...
...
@@ -721,7 +729,7 @@ static void handle_security_mode_command(instance_t instance, nr_ue_nas_t *nas,
/* todo: stream_security_container_delete() is not called anywhere, deal with that */
nas
->
security_container
=
stream_security_container_init
(
ciphering_algorithm
,
integrity_algorithm
,
knas_enc
,
knas_int
);
nas_itti_kgnb_refresh_req
(
instance
,
nas
->
security
.
kgnb
);
nas_itti_kgnb_refresh_req
(
nas
->
UE_id
,
nas
->
security
.
kgnb
);
generateSecurityModeComplete
(
nas
,
initialNasMsg
);
}
...
...
@@ -737,44 +745,46 @@ static void decodeRegistrationAccept(const uint8_t *buf, int len, nr_ue_nas_t *n
int
decoded
=
decode_registration_accept
(
&
reg_acc
,
buf
,
len
);
AssertFatal
(
decoded
>
0
,
"could not decode registration accept
\n
"
);
if
(
reg_acc
.
guti
)
{
AssertFatal
(
reg_acc
.
guti
->
guti
.
typeofidentity
==
FGS_MOBILE_IDENTITY_5G_GUTI
,
"registration accept 5GS Mobile Identity is not GUTI, but %d
\n
"
,
reg_acc
.
guti
->
guti
.
typeofidentity
);
nas
->
guti
=
malloc
(
sizeof
(
*
nas
->
guti
));
AssertFatal
(
nas
->
guti
,
"out of memory
\n
"
);
*
nas
->
guti
=
reg_acc
.
guti
->
guti
;
free
(
reg_acc
.
guti
);
/* no proper memory management for NAS decoded messages */
AssertFatal
(
reg_acc
.
guti
->
guti
.
typeofidentity
==
FGS_MOBILE_IDENTITY_5G_GUTI
,
"registration accept 5GS Mobile Identity is not GUTI, but %d
\n
"
,
reg_acc
.
guti
->
guti
.
typeofidentity
);
nas
->
guti
=
malloc
(
sizeof
(
*
nas
->
guti
));
AssertFatal
(
nas
->
guti
,
"out of memory
\n
"
);
*
nas
->
guti
=
reg_acc
.
guti
->
guti
;
free
(
reg_acc
.
guti
);
/* no proper memory management for NAS decoded messages */
}
else
{
LOG_W
(
NAS
,
"no GUTI in registration accept
\n
"
);
}
}
static
void
generateRegistrationComplete
(
nr_ue_nas_t
*
nas
,
as_nas_info_t
*
initialNasMsg
,
SORTransparentContainer
*
sortransparentcontainer
)
static
void
generateRegistrationComplete
(
nr_ue_nas_t
*
nas
,
as_nas_info_t
*
initialNasMsg
,
SORTransparentContainer
*
sortransparentcontainer
)
{
int
length
=
0
;
int
size
=
0
;
fgs_nas_message_t
nas_msg
;
nas_stream_cipher_t
stream_cipher
;
uint8_t
mac
[
4
];
uint8_t
mac
[
4
];
memset
(
&
nas_msg
,
0
,
sizeof
(
fgs_nas_message_t
));
fgs_nas_message_security_protected_t
*
sp_msg
;
sp_msg
=
&
nas_msg
.
security_protected
;
// set header
sp_msg
->
header
.
protocol_discriminator
=
FGS_MOBILITY_MANAGEMENT_MESSAGE
;
sp_msg
->
header
.
security_header_type
=
INTEGRITY_PROTECTED_AND_CIPHERED
;
sp_msg
->
header
.
security_header_type
=
INTEGRITY_PROTECTED_AND_CIPHERED
;
sp_msg
->
header
.
message_authentication_code
=
0
;
sp_msg
->
header
.
sequence_number
=
nas
->
security
.
nas_count_ul
&
0xff
;
sp_msg
->
header
.
sequence_number
=
nas
->
security
.
nas_count_ul
&
0xff
;
length
=
7
;
sp_msg
->
plain
.
mm_msg
.
registration_complete
.
protocoldiscriminator
=
FGS_MOBILITY_MANAGEMENT_MESSAGE
;
length
+=
1
;
sp_msg
->
plain
.
mm_msg
.
registration_complete
.
securityheadertype
=
PLAIN_5GS_MSG
;
sp_msg
->
plain
.
mm_msg
.
registration_complete
.
sparehalfoctet
=
0
;
sp_msg
->
plain
.
mm_msg
.
registration_complete
.
securityheadertype
=
PLAIN_5GS_MSG
;
sp_msg
->
plain
.
mm_msg
.
registration_complete
.
sparehalfoctet
=
0
;
length
+=
1
;
sp_msg
->
plain
.
mm_msg
.
registration_complete
.
messagetype
=
REGISTRATION_COMPLETE
;
length
+=
1
;
if
(
sortransparentcontainer
)
{
if
(
sortransparentcontainer
)
{
length
+=
sortransparentcontainer
->
sortransparentcontainercontents
.
length
;
}
...
...
@@ -784,62 +794,62 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
/* Encode the first octet of the header (extended protocol discriminator) */
ENCODE_U8
(
initialNasMsg
->
data
+
size
,
sp_msg
->
header
.
protocol_discriminator
,
size
);
/* Encode the security header type */
ENCODE_U8
(
initialNasMsg
->
data
+
size
,
sp_msg
->
header
.
security_header_type
,
size
);
/* Encode the message authentication code */
ENCODE_U32
(
initialNasMsg
->
data
+
size
,
sp_msg
->
header
.
message_authentication_code
,
size
);
/* Encode the sequence number */
ENCODE_U8
(
initialNasMsg
->
data
+
size
,
sp_msg
->
header
.
sequence_number
,
size
);
/* Encode the extended protocol discriminator */
ENCODE_U8
(
initialNasMsg
->
data
+
size
,
sp_msg
->
plain
.
mm_msg
.
registration_complete
.
protocoldiscriminator
,
size
);
/* Encode the security header type */
ENCODE_U8
(
initialNasMsg
->
data
+
size
,
sp_msg
->
plain
.
mm_msg
.
registration_complete
.
securityheadertype
,
size
);
/* Encode the message type */
ENCODE_U8
(
initialNasMsg
->
data
+
size
,
sp_msg
->
plain
.
mm_msg
.
registration_complete
.
messagetype
,
size
);
if
(
sortransparentcontainer
)
{
if
(
sortransparentcontainer
)
{
encode_registration_complete
(
&
sp_msg
->
plain
.
mm_msg
.
registration_complete
,
initialNasMsg
->
data
+
size
,
length
-
size
);
}
/* ciphering */
uint8_t
buf
[
initialNasMsg
->
length
-
7
];
stream_cipher
.
context
=
nas
->
security_container
->
ciphering_context
;
stream_cipher
.
context
=
nas
->
security_container
->
ciphering_context
;
AssertFatal
(
nas
->
security
.
nas_count_ul
<=
0xffffff
,
"fatal: NAS COUNT UL too big (todo: fix that)
\n
"
);
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
7
);
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
7
);
/* length in bits */
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
7
)
<<
3
;
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
7
)
<<
3
;
stream_compute_encrypt
(
nas
->
security_container
->
ciphering_algorithm
,
&
stream_cipher
,
buf
);
memcpy
(
stream_cipher
.
message
,
buf
,
initialNasMsg
->
length
-
7
);
/* integrity protection */
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
6
);
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
6
);
/* length in bits */
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
6
)
<<
3
;
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
6
)
<<
3
;
stream_compute_integrity
(
nas
->
security_container
->
integrity_algorithm
,
&
stream_cipher
,
mac
);
printf
(
"mac %x %x %x %x
\n
"
,
mac
[
0
],
mac
[
1
],
mac
[
2
],
mac
[
3
]);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
initialNasMsg
->
data
[
2
+
i
]
=
mac
[
i
];
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
initialNasMsg
->
data
[
2
+
i
]
=
mac
[
i
];
}
}
void
decodeDownlinkNASTransport
(
as_nas_info_t
*
initialNasMsg
,
uint8_t
*
pdu_buffer
){
void
decodeDownlinkNASTransport
(
as_nas_info_t
*
initialNasMsg
,
uint8_t
*
pdu_buffer
)
{
uint8_t
msg_type
=
*
(
pdu_buffer
+
16
);
if
(
msg_type
==
FGS_PDU_SESSION_ESTABLISHMENT_ACC
)
{
if
(
msg_type
==
FGS_PDU_SESSION_ESTABLISHMENT_ACC
)
{
uint8_t
*
ip_p
=
pdu_buffer
+
39
;
char
ip
[
20
];
sprintf
(
ip
,
"%d.%d.%d.%d"
,
*
(
ip_p
),
*
(
ip_p
+
1
),
*
(
ip_p
+
2
),
*
(
ip_p
+
3
));
...
...
@@ -880,44 +890,46 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
initialNasMsg
->
data
=
calloc
(
size
,
sizeof
(
Byte_t
));
int
security_header_len
=
nas_protected_security_header_encode
((
char
*
)(
initialNasMsg
->
data
),
&
nas_msg
.
header
,
size
);
initialNasMsg
->
length
=
security_header_len
+
mm_msg_encode
(
&
sp_msg
->
plain
.
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
+
security_header_len
),
size
-
security_header_len
);
initialNasMsg
->
length
=
security_header_len
+
mm_msg_encode
(
&
sp_msg
->
plain
.
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
+
security_header_len
),
size
-
security_header_len
);
nas_stream_cipher_t
stream_cipher
;
/* ciphering */
uint8_t
buf
[
initialNasMsg
->
length
-
7
];
stream_cipher
.
context
=
nas
->
security_container
->
ciphering_context
;
stream_cipher
.
context
=
nas
->
security_container
->
ciphering_context
;
AssertFatal
(
nas
->
security
.
nas_count_ul
<=
0xffffff
,
"fatal: NAS COUNT UL too big (todo: fix that)
\n
"
);
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
7
);
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
7
);
/* length in bits */
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
7
)
<<
3
;
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
7
)
<<
3
;
stream_compute_encrypt
(
nas
->
security_container
->
ciphering_algorithm
,
&
stream_cipher
,
buf
);
memcpy
(
stream_cipher
.
message
,
buf
,
initialNasMsg
->
length
-
7
);
/* integrity protection */
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
6
);
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
6
);
/* length in bits */
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
6
)
<<
3
;
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
6
)
<<
3
;
uint8_t
mac
[
4
];
stream_compute_integrity
(
nas
->
security_container
->
integrity_algorithm
,
&
stream_cipher
,
mac
);
printf
(
"mac %x %x %x %x
\n
"
,
mac
[
0
],
mac
[
1
],
mac
[
2
],
mac
[
3
]);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
initialNasMsg
->
data
[
2
+
i
]
=
mac
[
i
];
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
initialNasMsg
->
data
[
2
+
i
]
=
mac
[
i
];
}
}
static
void
generatePduSessionEstablishRequest
(
nr_ue_nas_t
*
nas
,
as_nas_info_t
*
initialNasMsg
,
nas_pdu_session_req_t
*
pdu_req
)
{
int
size
=
0
;
fgs_nas_message_t
nas_msg
=
{
0
};
fgs_nas_message_t
nas_msg
=
{
0
};
// setup pdu session establishment request
uint16_t
req_length
=
7
;
...
...
@@ -931,11 +943,9 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
pdu_session_establish
.
pdusessiontype
=
pdu_req
->
pdusession_type
;
encode_pdu_session_establishment_request
(
&
pdu_session_establish
,
req_buffer
);
MM_msg
*
mm_msg
;
nas_stream_cipher_t
stream_cipher
;
uint8_t
mac
[
4
];
uint8_t
mac
[
4
];
nas_msg
.
header
.
protocol_discriminator
=
FGS_MOBILITY_MANAGEMENT_MESSAGE
;
nas_msg
.
header
.
security_header_type
=
INTEGRITY_PROTECTED_AND_CIPHERED
;
nas_msg
.
header
.
sequence_number
=
nas
->
security
.
nas_count_ul
&
0xff
;
...
...
@@ -952,7 +962,7 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
// set uplink nas transport
mm_msg
->
uplink_nas_transport
.
protocoldiscriminator
=
FGS_MOBILITY_MANAGEMENT_MESSAGE
;
size
+=
1
;
mm_msg
->
uplink_nas_transport
.
securityheadertype
=
PLAIN_5GS_MSG
;
mm_msg
->
uplink_nas_transport
.
securityheadertype
=
PLAIN_5GS_MSG
;
size
+=
1
;
mm_msg
->
uplink_nas_transport
.
messagetype
=
FGS_UPLINK_NAS_TRANSPORT
;
size
+=
1
;
...
...
@@ -962,64 +972,65 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
size
+=
1
;
mm_msg
->
uplink_nas_transport
.
fgspayloadcontainer
.
payloadcontainercontents
.
length
=
req_length
;
mm_msg
->
uplink_nas_transport
.
fgspayloadcontainer
.
payloadcontainercontents
.
value
=
req_buffer
;
size
+=
(
2
+
req_length
);
size
+=
(
2
+
req_length
);
mm_msg
->
uplink_nas_transport
.
pdusessionid
=
pdu_req
->
pdusession_id
;
mm_msg
->
uplink_nas_transport
.
requesttype
=
1
;
size
+=
3
;
const
bool
has_nssai_sd
=
pdu_req
->
sd
!=
0xffffff
;
// 0xffffff means "no SD", TS 23.003
const
size_t
nssai_len
=
has_nssai_sd
?
4
:
1
;
mm_msg
->
uplink_nas_transport
.
snssai
.
length
=
nssai_len
;
//
Fixme: it seems there are a lot of memory errors in this: this value was on the stack,
// but pushed in a itti message to another thread
// this kind of error seems in many places in 5G NAS
//
Fixme: it seems there are a lot of memory errors in this: this value was on the stack,
//
but pushed in a itti message to another thread
//
this kind of error seems in many places in 5G NAS
mm_msg
->
uplink_nas_transport
.
snssai
.
value
=
calloc
(
1
,
nssai_len
);
mm_msg
->
uplink_nas_transport
.
snssai
.
value
[
0
]
=
pdu_req
->
sst
;
if
(
has_nssai_sd
)
INT24_TO_BUFFER
(
pdu_req
->
sd
,
&
mm_msg
->
uplink_nas_transport
.
snssai
.
value
[
1
]);
size
+=
1
+
1
+
nssai_len
;
int
dnnSize
=
strlen
(
nas
->
uicc
->
dnnStr
);
mm_msg
->
uplink_nas_transport
.
dnn
.
value
=
calloc
(
1
,
dnnSize
+
1
);
int
dnnSize
=
strlen
(
nas
->
uicc
->
dnnStr
);
mm_msg
->
uplink_nas_transport
.
dnn
.
value
=
calloc
(
1
,
dnnSize
+
1
);
mm_msg
->
uplink_nas_transport
.
dnn
.
length
=
dnnSize
+
1
;
mm_msg
->
uplink_nas_transport
.
dnn
.
value
[
0
]
=
dnnSize
;
memcpy
(
mm_msg
->
uplink_nas_transport
.
dnn
.
value
+
1
,
nas
->
uicc
->
dnnStr
,
dnnSize
);
size
+=
(
1
+
1
+
dnnSize
+
1
);
size
+=
(
1
+
1
+
dnnSize
+
1
);
// encode the message
initialNasMsg
->
data
=
(
Byte_t
*
)
malloc
(
size
*
sizeof
(
Byte_t
));
int
security_header_len
=
nas_protected_security_header_encode
((
char
*
)(
initialNasMsg
->
data
),
&
(
nas_msg
.
header
),
size
);
int
security_header_len
=
nas_protected_security_header_encode
((
char
*
)(
initialNasMsg
->
data
),
&
(
nas_msg
.
header
),
size
);
initialNasMsg
->
length
=
security_header_len
+
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
+
security_header_len
),
size
-
security_header_len
);
initialNasMsg
->
length
=
security_header_len
+
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
+
security_header_len
),
size
-
security_header_len
);
/* ciphering */
uint8_t
buf
[
initialNasMsg
->
length
-
7
];
stream_cipher
.
context
=
nas
->
security_container
->
ciphering_context
;
stream_cipher
.
context
=
nas
->
security_container
->
ciphering_context
;
AssertFatal
(
nas
->
security
.
nas_count_ul
<=
0xffffff
,
"fatal: NAS COUNT UL too big (todo: fix that)
\n
"
);
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
7
);
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
7
);
/* length in bits */
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
7
)
<<
3
;
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
7
)
<<
3
;
stream_compute_encrypt
(
nas
->
security_container
->
ciphering_algorithm
,
&
stream_cipher
,
buf
);
memcpy
(
stream_cipher
.
message
,
buf
,
initialNasMsg
->
length
-
7
);
/* integrity protection */
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
6
);
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
nas_count_ul
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
stream_cipher
.
message
=
(
unsigned
char
*
)(
initialNasMsg
->
data
+
6
);
/* length in bits */
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
6
)
<<
3
;
stream_cipher
.
blength
=
(
initialNasMsg
->
length
-
6
)
<<
3
;
stream_compute_integrity
(
nas
->
security_container
->
integrity_algorithm
,
&
stream_cipher
,
mac
);
printf
(
"mac %x %x %x %x
\n
"
,
mac
[
0
],
mac
[
1
],
mac
[
2
],
mac
[
3
]);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
initialNasMsg
->
data
[
2
+
i
]
=
mac
[
i
];
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
initialNasMsg
->
data
[
2
+
i
]
=
mac
[
i
];
}
}
static
uint8_t
get_msg_type
(
uint8_t
*
pdu_buffer
,
uint32_t
length
)
{
if
(
pdu_buffer
==
NULL
)
...
...
@@ -1057,22 +1068,22 @@ error:
return
0
;
}
static
void
send_nas_uplink_data_req
(
instance_t
instance
,
const
as_nas_info_t
*
initial_nas_msg
)
static
void
send_nas_uplink_data_req
(
nr_ue_nas_t
*
nas
,
const
as_nas_info_t
*
initial_nas_msg
)
{
MessageDef
*
msg
=
itti_alloc_new_message
(
TASK_NAS_NRUE
,
0
,
NAS_UPLINK_DATA_REQ
);
MessageDef
*
msg
=
itti_alloc_new_message
(
TASK_NAS_NRUE
,
nas
->
UE_id
,
NAS_UPLINK_DATA_REQ
);
ul_info_transfer_req_t
*
req
=
&
NAS_UPLINK_DATA_REQ
(
msg
);
req
->
UEid
=
instance
;
req
->
nasMsg
.
data
=
(
uint8_t
*
)
initial_nas_msg
->
data
;
req
->
UEid
=
nas
->
UE_id
;
req
->
nasMsg
.
data
=
(
uint8_t
*
)
initial_nas_msg
->
data
;
req
->
nasMsg
.
length
=
initial_nas_msg
->
length
;
itti_send_msg_to_task
(
TASK_RRC_NRUE
,
instance
,
msg
);
itti_send_msg_to_task
(
TASK_RRC_NRUE
,
nas
->
UE_id
,
msg
);
}
static
void
send_nas_detach_req
(
instance_t
instance
,
bool
wait_release
)
static
void
send_nas_detach_req
(
nr_ue_nas_t
*
nas
,
bool
wait_release
)
{
MessageDef
*
msg
=
itti_alloc_new_message
(
TASK_NAS_NRUE
,
0
,
NAS_DETACH_REQ
);
MessageDef
*
msg
=
itti_alloc_new_message
(
TASK_NAS_NRUE
,
nas
->
UE_id
,
NAS_DETACH_REQ
);
nas_detach_req_t
*
req
=
&
NAS_DETACH_REQ
(
msg
);
req
->
wait_release
=
wait_release
;
itti_send_msg_to_task
(
TASK_RRC_NRUE
,
instance
,
msg
);
itti_send_msg_to_task
(
TASK_RRC_NRUE
,
nas
->
UE_id
,
msg
);
}
static
void
parse_allowed_nssai
(
nr_nas_msg_snssai_t
nssaiList
[
8
],
const
uint8_t
*
buf
,
const
uint32_t
len
)
...
...
@@ -1171,14 +1182,14 @@ static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_b
}
}
static
void
request_default_pdusession
(
int
instance
,
int
nssai_idx
)
static
void
request_default_pdusession
(
nr_ue_nas_t
*
nas
,
int
nssai_idx
)
{
MessageDef
*
message_p
=
itti_alloc_new_message
(
TASK_NAS_NRUE
,
0
,
NAS_PDU_SESSION_REQ
);
MessageDef
*
message_p
=
itti_alloc_new_message
(
TASK_NAS_NRUE
,
nas
->
UE_id
,
NAS_PDU_SESSION_REQ
);
NAS_PDU_SESSION_REQ
(
message_p
).
pdusession_id
=
10
;
/* first or default pdu session */
NAS_PDU_SESSION_REQ
(
message_p
).
pdusession_type
=
0x91
;
// 0x91 = IPv4, 0x92 = IPv6, 0x93 = IPv4v6
NAS_PDU_SESSION_REQ
(
message_p
).
sst
=
nas_allowed_nssai
[
nssai_idx
].
sst
;
NAS_PDU_SESSION_REQ
(
message_p
).
sd
=
nas_allowed_nssai
[
nssai_idx
].
sd
;
itti_send_msg_to_task
(
TASK_NAS_NRUE
,
instance
,
message_p
);
itti_send_msg_to_task
(
TASK_NAS_NRUE
,
nas
->
UE_id
,
message_p
);
}
static
int
get_user_nssai_idx
(
const
nr_nas_msg_snssai_t
allowed_nssai
[
8
],
const
nr_ue_nas_t
*
nas
)
...
...
@@ -1193,16 +1204,17 @@ static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[8], const
void
*
nas_nrue_task
(
void
*
args_p
)
{
nr_ue_nas
.
uicc
=
checkUicc
(
0
);
for
(
int
UE_id
=
0
;
UE_id
<
NB_UE_INST
;
UE_id
++
)
{
// This sets UE uicc from command line. Needs to be called 2 seconds into nr-ue runtime, otherwise the unused command line
// arguments will be reported as unused and the modem asserts.
(
void
)
get_ue_nas_info
(
UE_id
);
}
while
(
1
)
{
nas_nrue
(
NULL
);
}
}
static
void
handle_registration_accept
(
instance_t
instance
,
nr_ue_nas_t
*
nas
,
const
uint8_t
*
pdu_buffer
,
uint32_t
msg_length
)
static
void
handle_registration_accept
(
nr_ue_nas_t
*
nas
,
const
uint8_t
*
pdu_buffer
,
uint32_t
msg_length
)
{
LOG_I
(
NAS
,
"[UE] Received REGISTRATION ACCEPT message
\n
"
);
decodeRegistrationAccept
(
pdu_buffer
,
msg_length
,
nas
);
...
...
@@ -1211,27 +1223,25 @@ static void handle_registration_accept(instance_t instance,
as_nas_info_t
initialNasMsg
=
{
0
};
generateRegistrationComplete
(
nas
,
&
initialNasMsg
,
NULL
);
if
(
initialNasMsg
.
length
>
0
)
{
send_nas_uplink_data_req
(
instance
,
&
initialNasMsg
);
send_nas_uplink_data_req
(
nas
,
&
initialNasMsg
);
LOG_I
(
NAS
,
"Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)
\n
"
);
}
const
int
nssai_idx
=
get_user_nssai_idx
(
nas_allowed_nssai
,
nas
);
if
(
nssai_idx
<
0
)
{
LOG_E
(
NAS
,
"NSSAI parameters not match with allowed NSSAI. Couldn't request PDU session.
\n
"
);
}
else
{
request_default_pdusession
(
instance
,
nssai_idx
);
request_default_pdusession
(
nas
,
nssai_idx
);
}
}
void
*
nas_nrue
(
void
*
args_p
)
{
// Wait for a message or an event
nr_ue_nas
.
uicc
=
checkUicc
(
0
);
MessageDef
*
msg_p
;
itti_receive_msg
(
TASK_NAS_NRUE
,
&
msg_p
);
if
(
msg_p
!=
NULL
)
{
instance_t
instance
=
msg_p
->
ittiMsgHeader
.
originInstance
;
AssertFatal
(
instance
==
0
,
"cannot handle more than one UE!
\n
"
);
nr_ue_nas_t
*
nas
=
get_ue_nas_info
(
msg_p
->
ittiMsgHeader
.
destinationInstance
);
switch
(
ITTI_MSG_ID
(
msg_p
))
{
case
INITIALIZE_MESSAGE
:
...
...
@@ -1248,7 +1258,7 @@ void *nas_nrue(void *args_p)
case
NAS_CELL_SELECTION_CNF
:
LOG_I
(
NAS
,
"[UE %ld] Received %s: errCode %u, cellID %u, tac %u
\n
"
,
instance
,
nas
->
UE_id
,
ITTI_MSG_NAME
(
msg_p
),
NAS_CELL_SELECTION_CNF
(
msg_p
).
errCode
,
NAS_CELL_SELECTION_CNF
(
msg_p
).
cellID
,
...
...
@@ -1263,7 +1273,7 @@ void *nas_nrue(void *args_p)
case
NAS_CELL_SELECTION_IND
:
LOG_I
(
NAS
,
"[UE %ld] Received %s: cellID %u, tac %u
\n
"
,
instance
,
nas
->
UE_id
,
ITTI_MSG_NAME
(
msg_p
),
NAS_CELL_SELECTION_IND
(
msg_p
).
cellID
,
NAS_CELL_SELECTION_IND
(
msg_p
).
tac
);
...
...
@@ -1272,7 +1282,7 @@ void *nas_nrue(void *args_p)
break
;
case
NAS_PAGING_IND
:
LOG_I
(
NAS
,
"[UE %ld] Received %s: cause %u
\n
"
,
instance
,
ITTI_MSG_NAME
(
msg_p
),
NAS_PAGING_IND
(
msg_p
).
cause
);
LOG_I
(
NAS
,
"[UE %ld] Received %s: cause %u
\n
"
,
nas
->
UE_id
,
ITTI_MSG_NAME
(
msg_p
),
NAS_PAGING_IND
(
msg_p
).
cause
);
/* TODO not processed by NAS currently */
break
;
...
...
@@ -1280,10 +1290,9 @@ void *nas_nrue(void *args_p)
case
NAS_PDU_SESSION_REQ
:
{
as_nas_info_t
pduEstablishMsg
=
{
0
};
nas_pdu_session_req_t
*
pduReq
=
&
NAS_PDU_SESSION_REQ
(
msg_p
);
nr_ue_nas_t
*
nas
=
get_ue_nas_info
(
0
);
generatePduSessionEstablishRequest
(
nas
,
&
pduEstablishMsg
,
pduReq
);
if
(
pduEstablishMsg
.
length
>
0
)
{
send_nas_uplink_data_req
(
instance
,
&
pduEstablishMsg
);
send_nas_uplink_data_req
(
nas
,
&
pduEstablishMsg
);
LOG_I
(
NAS
,
"Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)
\n
"
);
}
break
;
...
...
@@ -1292,7 +1301,7 @@ void *nas_nrue(void *args_p)
case
NAS_CONN_ESTABLI_CNF
:
{
LOG_I
(
NAS
,
"[UE %ld] Received %s: errCode %u, length %u
\n
"
,
instance
,
nas
->
UE_id
,
ITTI_MSG_NAME
(
msg_p
),
NAS_CONN_ESTABLI_CNF
(
msg_p
).
errCode
,
NAS_CONN_ESTABLI_CNF
(
msg_p
).
nasMsg
.
length
);
...
...
@@ -1300,11 +1309,8 @@ void *nas_nrue(void *args_p)
uint8_t
*
pdu_buffer
=
NAS_CONN_ESTABLI_CNF
(
msg_p
).
nasMsg
.
data
;
int
pdu_length
=
NAS_CONN_ESTABLI_CNF
(
msg_p
).
nasMsg
.
length
;
nr_ue_nas_t
*
nas
=
get_ue_nas_info
(
0
);
security_state_t
security_state
=
nas_security_rx_process
(
nas
,
pdu_buffer
,
pdu_length
);
if
(
security_state
!=
NAS_SECURITY_INTEGRITY_PASSED
&&
security_state
!=
NAS_SECURITY_NO_SECURITY_CONTEXT
)
{
if
(
security_state
!=
NAS_SECURITY_INTEGRITY_PASSED
&&
security_state
!=
NAS_SECURITY_NO_SECURITY_CONTEXT
)
{
LOG_E
(
NAS
,
"NAS integrity failed, discard incoming message
\n
"
);
break
;
}
...
...
@@ -1312,7 +1318,7 @@ void *nas_nrue(void *args_p)
int
msg_type
=
get_msg_type
(
pdu_buffer
,
pdu_length
);
if
(
msg_type
==
REGISTRATION_ACCEPT
)
{
handle_registration_accept
(
instance
,
nas
,
pdu_buffer
,
pdu_length
);
handle_registration_accept
(
nas
,
pdu_buffer
,
pdu_length
);
}
else
if
(
msg_type
==
FGS_PDU_SESSION_ESTABLISHMENT_ACC
)
{
capture_pdu_session_establishment_accept_msg
(
pdu_buffer
,
pdu_length
);
}
...
...
@@ -1321,9 +1327,7 @@ void *nas_nrue(void *args_p)
}
case
NR_NAS_CONN_RELEASE_IND
:
LOG_I
(
NAS
,
"[UE %ld] Received %s: cause %u
\n
"
,
instance
,
ITTI_MSG_NAME
(
msg_p
),
NR_NAS_CONN_RELEASE_IND
(
msg_p
).
cause
);
nr_ue_nas_t
*
nas
=
get_ue_nas_info
(
0
);
LOG_I
(
NAS
,
"[UE %ld] Received %s: cause %u
\n
"
,
nas
->
UE_id
,
ITTI_MSG_NAME
(
msg_p
),
NR_NAS_CONN_RELEASE_IND
(
msg_p
).
cause
);
// TODO handle connection release
if
(
nas
->
termination_procedure
)
{
/* the following is not clean, but probably necessary: we need to give
...
...
@@ -1338,7 +1342,7 @@ void *nas_nrue(void *args_p)
case
NAS_UPLINK_DATA_CNF
:
LOG_I
(
NAS
,
"[UE %ld] Received %s: UEid %u, errCode %u
\n
"
,
instance
,
nas
->
UE_id
,
ITTI_MSG_NAME
(
msg_p
),
NAS_UPLINK_DATA_CNF
(
msg_p
).
UEid
,
NAS_UPLINK_DATA_CNF
(
msg_p
).
errCode
);
...
...
@@ -1346,33 +1350,31 @@ void *nas_nrue(void *args_p)
break
;
case
NAS_DEREGISTRATION_REQ
:
{
LOG_I
(
NAS
,
"[UE %ld] Received %s
\n
"
,
instance
,
ITTI_MSG_NAME
(
msg_p
));
nr_ue_nas_t
*
nas
=
get_ue_nas_info
(
0
);
LOG_I
(
NAS
,
"[UE %ld] Received %s
\n
"
,
nas
->
UE_id
,
ITTI_MSG_NAME
(
msg_p
));
nas_deregistration_req_t
*
req
=
&
NAS_DEREGISTRATION_REQ
(
msg_p
);
if
(
nas
->
guti
)
{
if
(
req
->
cause
==
AS_DETACH
)
{
nas
->
termination_procedure
=
true
;
send_nas_detach_req
(
instance
,
true
);
send_nas_detach_req
(
nas
,
true
);
}
as_nas_info_t
initialNasMsg
=
{
0
};
generateDeregistrationRequest
(
nas
,
&
initialNasMsg
,
req
);
send_nas_uplink_data_req
(
instance
,
&
initialNasMsg
);
send_nas_uplink_data_req
(
nas
,
&
initialNasMsg
);
}
else
{
LOG_W
(
NAS
,
"No GUTI, cannot trigger deregistration request.
\n
"
);
if
(
req
->
cause
==
AS_DETACH
)
send_nas_detach_req
(
instance
,
false
);
send_nas_detach_req
(
nas
,
false
);
}
}
break
;
case
NAS_DOWNLINK_DATA_IND
:
{
LOG_I
(
NAS
,
"[UE %ld] Received %s: length %u , buffer %p
\n
"
,
instance
,
nas
->
UE_id
,
ITTI_MSG_NAME
(
msg_p
),
NAS_DOWNLINK_DATA_IND
(
msg_p
).
nasMsg
.
length
,
NAS_DOWNLINK_DATA_IND
(
msg_p
).
nasMsg
.
data
);
as_nas_info_t
initialNasMsg
=
{
0
};
nr_ue_nas_t
*
nas
=
get_ue_nas_info
(
0
);
uint8_t
*
pdu_buffer
=
NAS_DOWNLINK_DATA_IND
(
msg_p
).
nasMsg
.
data
;
int
pdu_length
=
NAS_DOWNLINK_DATA_IND
(
msg_p
).
nasMsg
.
length
;
...
...
@@ -1386,8 +1388,7 @@ void *nas_nrue(void *args_p)
security_state
=
NAS_SECURITY_INTEGRITY_PASSED
;
}
if
(
security_state
!=
NAS_SECURITY_INTEGRITY_PASSED
&&
security_state
!=
NAS_SECURITY_NO_SECURITY_CONTEXT
)
{
if
(
security_state
!=
NAS_SECURITY_INTEGRITY_PASSED
&&
security_state
!=
NAS_SECURITY_NO_SECURITY_CONTEXT
)
{
LOG_E
(
NAS
,
"NAS integrity failed, discard incoming message
\n
"
);
break
;
}
...
...
@@ -1402,13 +1403,13 @@ void *nas_nrue(void *args_p)
generateAuthenticationResp
(
nas
,
&
initialNasMsg
,
pdu_buffer
);
break
;
case
FGS_SECURITY_MODE_COMMAND
:
handle_security_mode_command
(
instance
,
nas
,
&
initialNasMsg
,
pdu_buffer
,
pdu_length
);
handle_security_mode_command
(
nas
,
&
initialNasMsg
,
pdu_buffer
,
pdu_length
);
break
;
case
FGS_DOWNLINK_NAS_TRANSPORT
:
decodeDownlinkNASTransport
(
&
initialNasMsg
,
pdu_buffer
);
break
;
case
REGISTRATION_ACCEPT
:
handle_registration_accept
(
instance
,
nas
,
pdu_buffer
,
pdu_length
);
handle_registration_accept
(
nas
,
pdu_buffer
,
pdu_length
);
break
;
case
FGS_DEREGISTRATION_ACCEPT
:
LOG_I
(
NAS
,
"received deregistration accept
\n
"
);
...
...
@@ -1439,20 +1440,20 @@ void *nas_nrue(void *args_p)
offset
++
;
}
}
break
;
case
FGS_PDU_SESSION_ESTABLISHMENT_REJ
:
LOG_E
(
NAS
,
"Received PDU Session Establishment reject
\n
"
);
break
;
case
FGS_PDU_SESSION_ESTABLISHMENT_REJ
:
LOG_E
(
NAS
,
"Received PDU Session Establishment reject
\n
"
);
break
;
default:
LOG_W
(
NR_RRC
,
"unknown message type %d
\n
"
,
msg_type
);
break
;
}
if
(
initialNasMsg
.
length
>
0
)
send_nas_uplink_data_req
(
instance
,
&
initialNasMsg
);
send_nas_uplink_data_req
(
nas
,
&
initialNasMsg
);
}
break
;
default:
LOG_E
(
NAS
,
"[UE %ld] Received unexpected message %s
\n
"
,
instance
,
ITTI_MSG_NAME
(
msg_p
));
LOG_E
(
NAS
,
"[UE %ld] Received unexpected message %s
\n
"
,
nas
->
UE_id
,
ITTI_MSG_NAME
(
msg_p
));
break
;
}
...
...
openair3/NAS/NR_UE/nr_nas_msg_sim.h
View file @
adc88d3d
...
...
@@ -105,6 +105,7 @@ typedef struct {
bool
termination_procedure
;
uint8_t
*
registration_request_buf
;
uint32_t
registration_request_len
;
instance_t
UE_id
;
}
nr_ue_nas_t
;
typedef
enum
fgs_protocol_discriminator_e
{
...
...
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