Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
U
UERANSIM
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
Libraries
UERANSIM
Commits
31196a88
Commit
31196a88
authored
Feb 23, 2021
by
aligungr
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Mobile storage refactor
parent
4097d4e6
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
211 additions
and
142 deletions
+211
-142
src/ue/app/cmd_handler.cpp
src/ue/app/cmd_handler.cpp
+5
-5
src/ue/mm/auth.cpp
src/ue/mm/auth.cpp
+41
-40
src/ue/mm/base.cpp
src/ue/mm/base.cpp
+10
-26
src/ue/mm/config.cpp
src/ue/mm/config.cpp
+3
-3
src/ue/mm/dereg.cpp
src/ue/mm/dereg.cpp
+8
-8
src/ue/mm/identity.cpp
src/ue/mm/identity.cpp
+6
-6
src/ue/mm/mm.hpp
src/ue/mm/mm.hpp
+7
-17
src/ue/mm/register.cpp
src/ue/mm/register.cpp
+12
-21
src/ue/mm/security.cpp
src/ue/mm/security.cpp
+10
-10
src/ue/mm/transport.cpp
src/ue/mm/transport.cpp
+7
-6
src/ue/nas/storage.cpp
src/ue/nas/storage.cpp
+14
-0
src/ue/nas/storage.hpp
src/ue/nas/storage.hpp
+88
-0
No files found.
src/ue/app/cmd_handler.cpp
View file @
31196a88
...
@@ -109,9 +109,9 @@ void UeCmdHandler::handleCmdImpl(NwUeCliCommand &msg)
...
@@ -109,9 +109,9 @@ void UeCmdHandler::handleCmdImpl(NwUeCliCommand &msg)
{
"cm-state"
,
ToJson
(
m_base
->
nasTask
->
mm
->
m_cmState
)},
{
"cm-state"
,
ToJson
(
m_base
->
nasTask
->
mm
->
m_cmState
)},
{
"rm-state"
,
ToJson
(
m_base
->
nasTask
->
mm
->
m_rmState
)},
{
"rm-state"
,
ToJson
(
m_base
->
nasTask
->
mm
->
m_rmState
)},
{
"mm-state"
,
ToJson
(
m_base
->
nasTask
->
mm
->
m_mmSubState
)},
{
"mm-state"
,
ToJson
(
m_base
->
nasTask
->
mm
->
m_mmSubState
)},
{
"sim-inserted"
,
m_base
->
nasTask
->
mm
->
m_
validSim
},
{
"sim-inserted"
,
m_base
->
nasTask
->
mm
->
m_
storage
.
isSimValid
()
},
{
"stored-suci"
,
ToJson
(
m_base
->
nasTask
->
mm
->
m_storedSuci
)},
{
"stored-suci"
,
ToJson
(
m_base
->
nasTask
->
mm
->
m_stor
age
.
m_stor
edSuci
)},
{
"stored-guti"
,
ToJson
(
m_base
->
nasTask
->
mm
->
m_storedGuti
)},
{
"stored-guti"
,
ToJson
(
m_base
->
nasTask
->
mm
->
m_stor
age
.
m_stor
edGuti
)},
{
"pdu-sessions"
,
Json
::
Arr
(
std
::
move
(
pduSessions
))},
{
"pdu-sessions"
,
Json
::
Arr
(
std
::
move
(
pduSessions
))},
});
});
sendResult
(
msg
.
address
,
json
.
dumpYaml
());
sendResult
(
msg
.
address
,
json
.
dumpYaml
());
...
@@ -127,8 +127,8 @@ void UeCmdHandler::handleCmdImpl(NwUeCliCommand &msg)
...
@@ -127,8 +127,8 @@ void UeCmdHandler::handleCmdImpl(NwUeCliCommand &msg)
}
}
case
app
:
:
UeCliCommand
::
DE_REGISTER
:
{
case
app
:
:
UeCliCommand
::
DE_REGISTER
:
{
m_base
->
nasTask
->
mm
->
sendDeregistration
(
msg
.
cmd
->
isSwitchOff
?
nas
::
ESwitchOff
::
SWITCH_OFF
m_base
->
nasTask
->
mm
->
sendDeregistration
(
msg
.
cmd
->
isSwitchOff
?
nas
::
ESwitchOff
::
SWITCH_OFF
:
nas
::
ESwitchOff
::
NORMAL_DE_REGISTRATION
,
:
nas
::
ESwitchOff
::
NORMAL_DE_REGISTRATION
,
msg
.
cmd
->
dueToDisable5g
);
msg
.
cmd
->
dueToDisable5g
);
if
(
!
msg
.
cmd
->
isSwitchOff
)
if
(
!
msg
.
cmd
->
isSwitchOff
)
sendResult
(
msg
.
address
,
"De-registration procedure triggered"
);
sendResult
(
msg
.
address
,
"De-registration procedure triggered"
);
else
else
...
...
src/ue/mm/auth.cpp
View file @
31196a88
...
@@ -17,7 +17,7 @@ namespace nr::ue
...
@@ -17,7 +17,7 @@ namespace nr::ue
void
NasMm
::
receiveAuthenticationRequest
(
const
nas
::
AuthenticationRequest
&
msg
)
void
NasMm
::
receiveAuthenticationRequest
(
const
nas
::
AuthenticationRequest
&
msg
)
{
{
if
(
!
m_
validSim
)
if
(
!
m_
storage
.
isSimValid
()
)
{
{
m_logger
->
warn
(
"Authentication request is ignored. USIM is invalid"
);
m_logger
->
warn
(
"Authentication request is ignored. USIM is invalid"
);
return
;
return
;
...
@@ -67,17 +67,17 @@ void NasMm::receiveAuthenticationRequestEap(const nas::AuthenticationRequest &ms
...
@@ -67,17 +67,17 @@ void NasMm::receiveAuthenticationRequestEap(const nas::AuthenticationRequest &ms
if
(
USE_SQN_HACK
)
if
(
USE_SQN_HACK
)
{
{
auto
ak
=
calculateMilenage
(
OctetString
::
FromSpare
(
6
),
receivedRand
).
ak
;
auto
ak
=
calculateMilenage
(
OctetString
::
FromSpare
(
6
),
receivedRand
).
ak
;
m_sqn
=
OctetString
::
Xor
(
receivedAutn
.
subCopy
(
0
,
6
),
ak
);
m_s
torage
.
m_s
qn
=
OctetString
::
Xor
(
receivedAutn
.
subCopy
(
0
,
6
),
ak
);
}
}
auto
milenage
=
calculateMilenage
(
m_sqn
,
receivedRand
);
auto
milenage
=
calculateMilenage
(
m_s
torage
.
m_s
qn
,
receivedRand
);
auto
&
res
=
milenage
.
res
;
auto
&
res
=
milenage
.
res
;
auto
&
ck
=
milenage
.
ck
;
auto
&
ck
=
milenage
.
ck
;
auto
&
ik
=
milenage
.
ik
;
auto
&
ik
=
milenage
.
ik
;
auto
&
milenageAk
=
milenage
.
ak
;
auto
&
milenageAk
=
milenage
.
ak
;
auto
&
milenageMac
=
milenage
.
mac_a
;
auto
&
milenageMac
=
milenage
.
mac_a
;
auto
sqnXorAk
=
OctetString
::
Xor
(
m_sqn
,
milenageAk
);
auto
sqnXorAk
=
OctetString
::
Xor
(
m_s
torage
.
m_s
qn
,
milenageAk
);
auto
ckPrimeIkPrime
=
auto
ckPrimeIkPrime
=
keys
::
CalculateCkPrimeIkPrime
(
ck
,
ik
,
keys
::
ConstructServingNetworkName
(
m_base
->
config
->
plmn
),
sqnXorAk
);
keys
::
CalculateCkPrimeIkPrime
(
ck
,
ik
,
keys
::
ConstructServingNetworkName
(
m_base
->
config
->
plmn
),
sqnXorAk
);
auto
&
ckPrime
=
ckPrimeIkPrime
.
first
;
auto
&
ckPrime
=
ckPrimeIkPrime
.
first
;
...
@@ -92,7 +92,7 @@ void NasMm::receiveAuthenticationRequestEap(const nas::AuthenticationRequest &ms
...
@@ -92,7 +92,7 @@ void NasMm::receiveAuthenticationRequestEap(const nas::AuthenticationRequest &ms
auto
mk
=
keys
::
CalculateMk
(
ckPrime
,
ikPrime
,
m_base
->
config
->
supi
.
value
());
auto
mk
=
keys
::
CalculateMk
(
ckPrime
,
ikPrime
,
m_base
->
config
->
supi
.
value
());
auto
kaut
=
mk
.
subCopy
(
16
,
32
);
auto
kaut
=
mk
.
subCopy
(
16
,
32
);
m_logger
->
debug
(
"ueData.sqn: %s"
,
m_sqn
.
toHexString
().
c_str
());
m_logger
->
debug
(
"ueData.sqn: %s"
,
m_s
torage
.
m_s
qn
.
toHexString
().
c_str
());
m_logger
->
debug
(
"ueData.op(C): %s"
,
m_base
->
config
->
opC
.
toHexString
().
c_str
());
m_logger
->
debug
(
"ueData.op(C): %s"
,
m_base
->
config
->
opC
.
toHexString
().
c_str
());
m_logger
->
debug
(
"ueData.K: %s"
,
m_base
->
config
->
key
.
toHexString
().
c_str
());
m_logger
->
debug
(
"ueData.K: %s"
,
m_base
->
config
->
key
.
toHexString
().
c_str
());
m_logger
->
debug
(
"calculated res: %s"
,
res
.
toHexString
().
c_str
());
m_logger
->
debug
(
"calculated res: %s"
,
res
.
toHexString
().
c_str
());
...
@@ -188,25 +188,25 @@ void NasMm::receiveAuthenticationRequestEap(const nas::AuthenticationRequest &ms
...
@@ -188,25 +188,25 @@ void NasMm::receiveAuthenticationRequestEap(const nas::AuthenticationRequest &ms
auto
kAusf
=
keys
::
CalculateKAusfForEapAkaPrime
(
mk
);
auto
kAusf
=
keys
::
CalculateKAusfForEapAkaPrime
(
mk
);
m_logger
->
debug
(
"kAusf: %s"
,
kAusf
.
toHexString
().
c_str
());
m_logger
->
debug
(
"kAusf: %s"
,
kAusf
.
toHexString
().
c_str
());
m_nonCurrentNsCtx
=
NasSecurityContext
{};
m_
storage
.
m_
nonCurrentNsCtx
=
NasSecurityContext
{};
m_nonCurrentNsCtx
->
tsc
=
msg
.
ngKSI
.
tsc
;
m_
storage
.
m_
nonCurrentNsCtx
->
tsc
=
msg
.
ngKSI
.
tsc
;
m_nonCurrentNsCtx
->
ngKsi
=
msg
.
ngKSI
.
ksi
;
m_
storage
.
m_
nonCurrentNsCtx
->
ngKsi
=
msg
.
ngKSI
.
ksi
;
m_nonCurrentNsCtx
->
keys
.
rand
=
std
::
move
(
receivedRand
);
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
rand
=
std
::
move
(
receivedRand
);
m_nonCurrentNsCtx
->
keys
.
res
=
std
::
move
(
res
);
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
res
=
std
::
move
(
res
);
m_nonCurrentNsCtx
->
keys
.
resStar
=
{};
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
resStar
=
{};
m_nonCurrentNsCtx
->
keys
.
kAusf
=
std
::
move
(
kAusf
);
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
kAusf
=
std
::
move
(
kAusf
);
m_nonCurrentNsCtx
->
keys
.
abba
=
msg
.
abba
.
rawData
.
copy
();
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
abba
=
msg
.
abba
.
rawData
.
copy
();
keys
::
DeriveKeysSeafAmf
(
*
m_base
->
config
,
*
m_nonCurrentNsCtx
);
keys
::
DeriveKeysSeafAmf
(
*
m_base
->
config
,
*
m_
storage
.
m_
nonCurrentNsCtx
);
m_logger
->
debug
(
"kSeaf: %s"
,
m_nonCurrentNsCtx
->
keys
.
kSeaf
.
toHexString
().
c_str
());
m_logger
->
debug
(
"kSeaf: %s"
,
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
kSeaf
.
toHexString
().
c_str
());
m_logger
->
debug
(
"kAmf: %s"
,
m_nonCurrentNsCtx
->
keys
.
kAmf
.
toHexString
().
c_str
());
m_logger
->
debug
(
"kAmf: %s"
,
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
kAmf
.
toHexString
().
c_str
());
// Send Response
// Send Response
{
{
auto
*
akaPrimeResponse
=
auto
*
akaPrimeResponse
=
new
eap
::
EapAkaPrime
(
eap
::
ECode
::
RESPONSE
,
receivedEap
.
id
,
eap
::
ESubType
::
AKA_CHALLENGE
);
new
eap
::
EapAkaPrime
(
eap
::
ECode
::
RESPONSE
,
receivedEap
.
id
,
eap
::
ESubType
::
AKA_CHALLENGE
);
akaPrimeResponse
->
attributes
.
putRes
(
m_nonCurrentNsCtx
->
keys
.
res
);
akaPrimeResponse
->
attributes
.
putRes
(
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
res
);
akaPrimeResponse
->
attributes
.
putMac
(
OctetString
::
FromSpare
(
16
));
// Dummy mac for now
akaPrimeResponse
->
attributes
.
putMac
(
OctetString
::
FromSpare
(
16
));
// Dummy mac for now
akaPrimeResponse
->
attributes
.
putKdf
(
1
);
akaPrimeResponse
->
attributes
.
putKdf
(
1
);
...
@@ -254,48 +254,49 @@ void NasMm::receiveAuthenticationRequest5gAka(const nas::AuthenticationRequest &
...
@@ -254,48 +254,49 @@ void NasMm::receiveAuthenticationRequest5gAka(const nas::AuthenticationRequest &
if
(
USE_SQN_HACK
)
if
(
USE_SQN_HACK
)
{
{
auto
ak
=
calculateMilenage
(
OctetString
::
FromSpare
(
6
),
rand
).
ak
;
auto
ak
=
calculateMilenage
(
OctetString
::
FromSpare
(
6
),
rand
).
ak
;
m_sqn
=
OctetString
::
Xor
(
autn
.
subCopy
(
0
,
6
),
ak
);
m_s
torage
.
m_s
qn
=
OctetString
::
Xor
(
autn
.
subCopy
(
0
,
6
),
ak
);
}
}
auto
milenage
=
calculateMilenage
(
m_sqn
,
rand
);
auto
milenage
=
calculateMilenage
(
m_s
torage
.
m_s
qn
,
rand
);
auto
&
res
=
milenage
.
res
;
auto
&
res
=
milenage
.
res
;
auto
&
ck
=
milenage
.
ck
;
auto
&
ck
=
milenage
.
ck
;
auto
&
ik
=
milenage
.
ik
;
auto
&
ik
=
milenage
.
ik
;
auto
ckIk
=
OctetString
::
Concat
(
ck
,
ik
);
auto
ckIk
=
OctetString
::
Concat
(
ck
,
ik
);
auto
&
milenageAk
=
milenage
.
ak
;
auto
&
milenageAk
=
milenage
.
ak
;
auto
&
milenageMac
=
milenage
.
mac_a
;
auto
&
milenageMac
=
milenage
.
mac_a
;
auto
sqnXorAk
=
OctetString
::
Xor
(
m_sqn
,
milenageAk
);
auto
sqnXorAk
=
OctetString
::
Xor
(
m_s
torage
.
m_s
qn
,
milenageAk
);
auto
snn
=
keys
::
ConstructServingNetworkName
(
m_base
->
config
->
plmn
);
auto
snn
=
keys
::
ConstructServingNetworkName
(
m_base
->
config
->
plmn
);
m_logger
->
debug
(
"Calculated res[%s] ck[%s] ik[%s] ak[%s] mac_a[%s]"
,
res
.
toHexString
().
c_str
(),
m_logger
->
debug
(
"Calculated res[%s] ck[%s] ik[%s] ak[%s] mac_a[%s]"
,
res
.
toHexString
().
c_str
(),
ck
.
toHexString
().
c_str
(),
ik
.
toHexString
().
c_str
(),
milenageAk
.
toHexString
().
c_str
(),
ck
.
toHexString
().
c_str
(),
ik
.
toHexString
().
c_str
(),
milenageAk
.
toHexString
().
c_str
(),
milenageMac
.
toHexString
().
c_str
());
milenageMac
.
toHexString
().
c_str
());
m_logger
->
debug
(
"Used snn[%s] sqn[%s]"
,
snn
.
c_str
(),
m_sqn
.
toHexString
().
c_str
());
m_logger
->
debug
(
"Used snn[%s] sqn[%s]"
,
snn
.
c_str
(),
m_s
torage
.
m_s
qn
.
toHexString
().
c_str
());
auto
autnCheck
=
validateAutn
(
milenageAk
,
milenageMac
,
autn
);
auto
autnCheck
=
validateAutn
(
milenageAk
,
milenageMac
,
autn
);
if
(
IGNORE_CONTROLS_FAILURES
||
autnCheck
==
EAutnValidationRes
::
OK
)
if
(
IGNORE_CONTROLS_FAILURES
||
autnCheck
==
EAutnValidationRes
::
OK
)
{
{
// Create new partial native NAS security context and continue with key derivation
// Create new partial native NAS security context and continue with key derivation
m_nonCurrentNsCtx
=
NasSecurityContext
{};
m_storage
.
m_nonCurrentNsCtx
=
NasSecurityContext
{};
m_nonCurrentNsCtx
->
tsc
=
msg
.
ngKSI
.
tsc
;
m_storage
.
m_nonCurrentNsCtx
->
tsc
=
msg
.
ngKSI
.
tsc
;
m_nonCurrentNsCtx
->
ngKsi
=
msg
.
ngKSI
.
ksi
;
m_storage
.
m_nonCurrentNsCtx
->
ngKsi
=
msg
.
ngKSI
.
ksi
;
m_nonCurrentNsCtx
->
keys
.
rand
=
rand
.
copy
();
m_storage
.
m_nonCurrentNsCtx
->
keys
.
rand
=
rand
.
copy
();
m_nonCurrentNsCtx
->
keys
.
resStar
=
keys
::
CalculateResStar
(
ckIk
,
snn
,
rand
,
res
);
m_storage
.
m_nonCurrentNsCtx
->
keys
.
resStar
=
keys
::
CalculateResStar
(
ckIk
,
snn
,
rand
,
res
);
m_nonCurrentNsCtx
->
keys
.
res
=
std
::
move
(
res
);
m_storage
.
m_nonCurrentNsCtx
->
keys
.
res
=
std
::
move
(
res
);
m_nonCurrentNsCtx
->
keys
.
kAusf
=
keys
::
CalculateKAusfFor5gAka
(
ck
,
ik
,
snn
,
sqnXorAk
);
m_storage
.
m_nonCurrentNsCtx
->
keys
.
kAusf
=
keys
::
CalculateKAusfFor5gAka
(
ck
,
ik
,
snn
,
sqnXorAk
);
m_nonCurrentNsCtx
->
keys
.
abba
=
msg
.
abba
.
rawData
.
copy
();
m_storage
.
m_nonCurrentNsCtx
->
keys
.
abba
=
msg
.
abba
.
rawData
.
copy
();
keys
::
DeriveKeysSeafAmf
(
*
m_base
->
config
,
*
m_nonCurrentNsCtx
);
keys
::
DeriveKeysSeafAmf
(
*
m_base
->
config
,
*
m_storage
.
m_nonCurrentNsCtx
);
m_logger
->
debug
(
"Derived kSeaf[%s] kAusf[%s] kAmf[%s]"
,
m_nonCurrentNsCtx
->
keys
.
kSeaf
.
toHexString
().
c_str
(),
m_logger
->
debug
(
"Derived kSeaf[%s] kAusf[%s] kAmf[%s]"
,
m_nonCurrentNsCtx
->
keys
.
kAusf
.
toHexString
().
c_str
(),
m_storage
.
m_nonCurrentNsCtx
->
keys
.
kSeaf
.
toHexString
().
c_str
(),
m_nonCurrentNsCtx
->
keys
.
kAmf
.
toHexString
().
c_str
());
m_storage
.
m_nonCurrentNsCtx
->
keys
.
kAusf
.
toHexString
().
c_str
(),
m_storage
.
m_nonCurrentNsCtx
->
keys
.
kAmf
.
toHexString
().
c_str
());
// Send response
// Send response
nas
::
AuthenticationResponse
resp
;
nas
::
AuthenticationResponse
resp
;
resp
.
authenticationResponseParameter
=
nas
::
IEAuthenticationResponseParameter
{};
resp
.
authenticationResponseParameter
=
nas
::
IEAuthenticationResponseParameter
{};
resp
.
authenticationResponseParameter
->
rawData
=
m_nonCurrentNsCtx
->
keys
.
resStar
.
copy
();
resp
.
authenticationResponseParameter
->
rawData
=
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
resStar
.
copy
();
sendNasMessage
(
resp
);
sendNasMessage
(
resp
);
}
}
else
if
(
autnCheck
==
EAutnValidationRes
::
MAC_FAILURE
)
else
if
(
autnCheck
==
EAutnValidationRes
::
MAC_FAILURE
)
...
@@ -317,7 +318,7 @@ void NasMm::receiveAuthenticationRequest5gAka(const nas::AuthenticationRequest &
...
@@ -317,7 +318,7 @@ void NasMm::receiveAuthenticationRequest5gAka(const nas::AuthenticationRequest &
void
NasMm
::
receiveAuthenticationResult
(
const
nas
::
AuthenticationResult
&
msg
)
void
NasMm
::
receiveAuthenticationResult
(
const
nas
::
AuthenticationResult
&
msg
)
{
{
if
(
msg
.
abba
.
has_value
())
if
(
msg
.
abba
.
has_value
())
m_nonCurrentNsCtx
->
keys
.
abba
=
msg
.
abba
->
rawData
.
copy
();
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
abba
=
msg
.
abba
->
rawData
.
copy
();
if
(
msg
.
eapMessage
.
eap
->
code
==
eap
::
ECode
::
SUCCESS
)
if
(
msg
.
eapMessage
.
eap
->
code
==
eap
::
ECode
::
SUCCESS
)
receiveEapSuccessMessage
(
*
msg
.
eapMessage
.
eap
);
receiveEapSuccessMessage
(
*
msg
.
eapMessage
.
eap
);
...
@@ -350,9 +351,9 @@ void NasMm::receiveAuthenticationReject(const nas::AuthenticationReject &msg)
...
@@ -350,9 +351,9 @@ void NasMm::receiveAuthenticationReject(const nas::AuthenticationReject &msg)
// The UE shall set the update status to 5U3 ROAMING NOT ALLOWED,
// The UE shall set the update status to 5U3 ROAMING NOT ALLOWED,
switchUState
(
E5UState
::
U3_ROAMING_NOT_ALLOWED
);
switchUState
(
E5UState
::
U3_ROAMING_NOT_ALLOWED
);
// Delete the stored 5G-GUTI, TAI list, last visited registered TAI and ngKSI The USIM shall be considered invalid
// Delete the stored 5G-GUTI, TAI list, last visited registered TAI and ngKSI
.
The USIM shall be considered invalid
// until switching off the UE or the UICC containing the USIM is removed
// until switching off the UE or the UICC containing the USIM is removed
invalidateSim
();
m_storage
.
invalidateSim
();
// The UE shall abort any 5GMM signalling procedure, stop any of the timers T3510, T3516, T3517, T3519 or T3521 (if
// The UE shall abort any 5GMM signalling procedure, stop any of the timers T3510, T3516, T3517, T3519 or T3521 (if
// they were running) ..
// they were running) ..
m_timers
->
t3510
.
stop
();
m_timers
->
t3510
.
stop
();
...
@@ -372,7 +373,7 @@ void NasMm::receiveEapSuccessMessage(const eap::Eap &eap)
...
@@ -372,7 +373,7 @@ void NasMm::receiveEapSuccessMessage(const eap::Eap &eap)
void
NasMm
::
receiveEapFailureMessage
(
const
eap
::
Eap
&
eap
)
void
NasMm
::
receiveEapFailureMessage
(
const
eap
::
Eap
&
eap
)
{
{
m_logger
->
err
(
"EAP failure received. Deleting non-current NAS security context"
);
m_logger
->
err
(
"EAP failure received. Deleting non-current NAS security context"
);
m_nonCurrentNsCtx
=
{};
m_
storage
.
m_
nonCurrentNsCtx
=
{};
}
}
void
NasMm
::
receiveEapResponseMessage
(
const
eap
::
Eap
&
eap
)
void
NasMm
::
receiveEapResponseMessage
(
const
eap
::
Eap
&
eap
)
...
...
src/ue/mm/base.cpp
View file @
31196a88
...
@@ -25,9 +25,9 @@ NasMm::NasMm(TaskBase *base, UeTimers *timers) : m_base{base}, m_timers{timers},
...
@@ -25,9 +25,9 @@ NasMm::NasMm(TaskBase *base, UeTimers *timers) : m_base{base}, m_timers{timers},
m_cmState
=
ECmState
::
CM_IDLE
;
m_cmState
=
ECmState
::
CM_IDLE
;
m_mmState
=
EMmState
::
MM_DEREGISTERED
;
m_mmState
=
EMmState
::
MM_DEREGISTERED
;
m_mmSubState
=
EMmSubState
::
MM_DEREGISTERED_NA
;
m_mmSubState
=
EMmSubState
::
MM_DEREGISTERED_NA
;
m_uState
=
E5UState
::
U1_UPDATED
;
m_
storage
.
m_
uState
=
E5UState
::
U1_UPDATED
;
m_autoBehaviour
=
base
->
config
->
autoBehaviour
;
m_autoBehaviour
=
base
->
config
->
autoBehaviour
;
m_
validSim
=
base
->
config
->
supi
.
has_value
(
);
m_
storage
.
initialize
(
base
->
config
->
supi
.
has_value
()
);
}
}
void
NasMm
::
onStart
(
NasSm
*
sm
)
void
NasMm
::
onStart
(
NasSm
*
sm
)
...
@@ -52,7 +52,7 @@ void NasMm::performMmCycle()
...
@@ -52,7 +52,7 @@ void NasMm::performMmCycle()
if
(
m_mmSubState
==
EMmSubState
::
MM_DEREGISTERED_NA
)
if
(
m_mmSubState
==
EMmSubState
::
MM_DEREGISTERED_NA
)
{
{
if
(
m_
validSim
)
if
(
m_
storage
.
isSimValid
()
)
{
{
if
(
m_cmState
==
ECmState
::
CM_IDLE
)
if
(
m_cmState
==
ECmState
::
CM_IDLE
)
switchMmState
(
EMmState
::
MM_DEREGISTERED
,
EMmSubState
::
MM_DEREGISTERED_PLMN_SEARCH
);
switchMmState
(
EMmState
::
MM_DEREGISTERED
,
EMmSubState
::
MM_DEREGISTERED_PLMN_SEARCH
);
...
@@ -168,15 +168,15 @@ void NasMm::switchCmState(ECmState state)
...
@@ -168,15 +168,15 @@ void NasMm::switchCmState(ECmState state)
void
NasMm
::
switchUState
(
E5UState
state
)
void
NasMm
::
switchUState
(
E5UState
state
)
{
{
E5UState
oldState
=
m_uState
;
E5UState
oldState
=
m_
storage
.
m_
uState
;
m_uState
=
state
;
m_
storage
.
m_
uState
=
state
;
onSwitchUState
(
oldState
,
m_uState
);
onSwitchUState
(
oldState
,
m_
storage
.
m_
uState
);
if
(
m_base
->
nodeListener
)
if
(
m_base
->
nodeListener
)
{
{
m_base
->
nodeListener
->
onSwitch
(
app
::
NodeType
::
UE
,
m_base
->
config
->
getNodeName
(),
app
::
StateType
::
U5
,
m_base
->
nodeListener
->
onSwitch
(
app
::
NodeType
::
UE
,
m_base
->
config
->
getNodeName
(),
app
::
StateType
::
U5
,
ToJson
(
oldState
).
str
(),
ToJson
(
m_uState
).
str
());
ToJson
(
oldState
).
str
(),
ToJson
(
m_
storage
.
m_
uState
).
str
());
}
}
if
(
state
!=
oldState
)
if
(
state
!=
oldState
)
...
@@ -192,12 +192,12 @@ void NasMm::onSwitchMmState(EMmState oldState, EMmState newState, EMmSubState ol
...
@@ -192,12 +192,12 @@ void NasMm::onSwitchMmState(EMmState oldState, EMmState newState, EMmSubState ol
// 5GMM-DEREGISTERED for any other state except 5GMM-NULL.
// 5GMM-DEREGISTERED for any other state except 5GMM-NULL.
if
(
oldState
==
EMmState
::
MM_DEREGISTERED
&&
newState
!=
EMmState
::
MM_DEREGISTERED
&&
newState
!=
EMmState
::
MM_NULL
)
if
(
oldState
==
EMmState
::
MM_DEREGISTERED
&&
newState
!=
EMmState
::
MM_DEREGISTERED
&&
newState
!=
EMmState
::
MM_NULL
)
{
{
if
(
m_
currentNsCtx
.
has_value
()
||
m_nonCurrentNsCtx
.
has_value
())
if
(
m_
storage
.
m_currentNsCtx
.
has_value
()
||
m_storage
.
m_nonCurrentNsCtx
.
has_value
())
{
{
m_logger
->
debug
(
"Deleting NAS security context"
);
m_logger
->
debug
(
"Deleting NAS security context"
);
m_currentNsCtx
=
{};
m_
storage
.
m_
currentNsCtx
=
{};
m_nonCurrentNsCtx
=
{};
m_
storage
.
m_
nonCurrentNsCtx
=
{};
}
}
}
}
}
}
...
@@ -283,20 +283,4 @@ void NasMm::onTimerExpire(nas::NasTimer &timer)
...
@@ -283,20 +283,4 @@ void NasMm::onTimerExpire(nas::NasTimer &timer)
}
}
}
}
void
NasMm
::
invalidateAcquiredParams
()
{
m_storedGuti
=
{};
m_lastVisitedRegisteredTai
=
{};
m_taiList
=
{};
m_currentNsCtx
=
{};
m_nonCurrentNsCtx
=
{};
}
void
NasMm
::
invalidateSim
()
{
m_logger
->
warn
(
"USIM is removed or invalidated"
);
m_validSim
=
false
;
invalidateAcquiredParams
();
}
}
// namespace nr::ue
}
// namespace nr::ue
src/ue/mm/config.cpp
View file @
31196a88
...
@@ -17,13 +17,13 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms
...
@@ -17,13 +17,13 @@ void NasMm::receiveConfigurationUpdate(const nas::ConfigurationUpdateCommand &ms
if
(
msg
.
guti
.
has_value
()
&&
msg
.
guti
->
type
==
nas
::
EIdentityType
::
GUTI
)
if
(
msg
.
guti
.
has_value
()
&&
msg
.
guti
->
type
==
nas
::
EIdentityType
::
GUTI
)
{
{
m_stor
edGuti
=
msg
.
guti
.
value
()
;
m_stor
age
.
m_storedSuci
=
{}
;
m_stor
edSuci
=
{}
;
m_stor
age
.
m_storedGuti
=
*
msg
.
guti
;
m_timers
->
t3519
.
stop
();
m_timers
->
t3519
.
stop
();
}
}
if
(
msg
.
taiList
.
has_value
())
if
(
msg
.
taiList
.
has_value
())
m_taiList
=
msg
.
taiList
.
value
();
m_
storage
.
m_
taiList
=
msg
.
taiList
.
value
();
if
(
msg
.
configurationUpdateIndication
.
has_value
())
if
(
msg
.
configurationUpdateIndication
.
has_value
())
{
{
...
...
src/ue/mm/dereg.cpp
View file @
31196a88
...
@@ -30,10 +30,10 @@ void NasMm::sendDeregistration(nas::ESwitchOff switchOff, bool dueToDisable5g)
...
@@ -30,10 +30,10 @@ void NasMm::sendDeregistration(nas::ESwitchOff switchOff, bool dueToDisable5g)
request
->
deRegistrationType
.
reRegistrationRequired
=
nas
::
EReRegistrationRequired
::
NOT_REQUIRED
;
request
->
deRegistrationType
.
reRegistrationRequired
=
nas
::
EReRegistrationRequired
::
NOT_REQUIRED
;
request
->
deRegistrationType
.
switchOff
=
switchOff
;
request
->
deRegistrationType
.
switchOff
=
switchOff
;
if
(
m_currentNsCtx
.
has_value
())
if
(
m_
storage
.
m_
currentNsCtx
.
has_value
())
{
{
request
->
ngKSI
.
tsc
=
m_currentNsCtx
->
tsc
;
request
->
ngKSI
.
tsc
=
m_
storage
.
m_
currentNsCtx
->
tsc
;
request
->
ngKSI
.
ksi
=
m_currentNsCtx
->
ngKsi
;
request
->
ngKSI
.
ksi
=
m_
storage
.
m_
currentNsCtx
->
ngKsi
;
}
}
else
else
{
{
...
@@ -76,7 +76,7 @@ void NasMm::receiveDeregistrationAccept(const nas::DeRegistrationAcceptUeOrigina
...
@@ -76,7 +76,7 @@ void NasMm::receiveDeregistrationAccept(const nas::DeRegistrationAcceptUeOrigina
m_timers
->
t3521
.
stop
();
m_timers
->
t3521
.
stop
();
m_timers
->
t3519
.
stop
();
m_timers
->
t3519
.
stop
();
m_storedSuci
=
{};
m_stor
age
.
m_stor
edSuci
=
{};
switchRmState
(
ERmState
::
RM_DEREGISTERED
);
switchRmState
(
ERmState
::
RM_DEREGISTERED
);
...
@@ -162,7 +162,7 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
...
@@ -162,7 +162,7 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
case
nas
:
:
EMmCause
::
ILLEGAL_ME
:
case
nas
:
:
EMmCause
::
ILLEGAL_ME
:
case
nas
:
:
EMmCause
::
FIVEG_SERVICES_NOT_ALLOWED
:
{
case
nas
:
:
EMmCause
::
FIVEG_SERVICES_NOT_ALLOWED
:
{
switchUState
(
E5UState
::
U3_ROAMING_NOT_ALLOWED
);
switchUState
(
E5UState
::
U3_ROAMING_NOT_ALLOWED
);
invalidateSim
();
m_storage
.
invalidateSim
();
switchMmState
(
EMmState
::
MM_DEREGISTERED
,
EMmSubState
::
MM_DEREGISTERED_NA
);
switchMmState
(
EMmState
::
MM_DEREGISTERED
,
EMmSubState
::
MM_DEREGISTERED_NA
);
break
;
break
;
}
}
...
@@ -175,13 +175,13 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
...
@@ -175,13 +175,13 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
//}
//}
case
nas
:
:
EMmCause
::
TA_NOT_ALLOWED
:
{
case
nas
:
:
EMmCause
::
TA_NOT_ALLOWED
:
{
switchUState
(
E5UState
::
U3_ROAMING_NOT_ALLOWED
);
switchUState
(
E5UState
::
U3_ROAMING_NOT_ALLOWED
);
invalidateAcquiredParams
();
m_storage
.
discardUsim
();
switchMmState
(
EMmState
::
MM_DEREGISTERED
,
EMmSubState
::
MM_DEREGISTERED_LIMITED_SERVICE
);
switchMmState
(
EMmState
::
MM_DEREGISTERED
,
EMmSubState
::
MM_DEREGISTERED_LIMITED_SERVICE
);
break
;
break
;
}
}
case
nas
:
:
EMmCause
::
N1_MODE_NOT_ALLOWED
:
{
case
nas
:
:
EMmCause
::
N1_MODE_NOT_ALLOWED
:
{
switchUState
(
E5UState
::
U3_ROAMING_NOT_ALLOWED
);
switchUState
(
E5UState
::
U3_ROAMING_NOT_ALLOWED
);
invalidateAcquiredParams
();
m_storage
.
discardUsim
();
switchMmState
(
EMmState
::
MM_NULL
,
EMmSubState
::
MM_NULL_NA
);
switchMmState
(
EMmState
::
MM_NULL
,
EMmSubState
::
MM_NULL_NA
);
break
;
break
;
}
}
...
@@ -198,7 +198,7 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
...
@@ -198,7 +198,7 @@ void NasMm::receiveDeregistrationRequest(const nas::DeRegistrationRequestUeTermi
nas
::
utils
::
EnumToString
(
msg
.
mmCause
->
value
));
nas
::
utils
::
EnumToString
(
msg
.
mmCause
->
value
));
switchUState
(
E5UState
::
U3_ROAMING_NOT_ALLOWED
);
switchUState
(
E5UState
::
U3_ROAMING_NOT_ALLOWED
);
invalidateSim
();
m_storage
.
invalidateSim
();
switchMmState
(
EMmState
::
MM_DEREGISTERED
,
EMmSubState
::
MM_DEREGISTERED_NA
);
switchMmState
(
EMmState
::
MM_DEREGISTERED
,
EMmSubState
::
MM_DEREGISTERED_NA
);
break
;
break
;
}
}
...
...
src/ue/mm/identity.cpp
View file @
31196a88
...
@@ -43,15 +43,15 @@ void NasMm::receiveIdentityRequest(const nas::IdentityRequest &msg)
...
@@ -43,15 +43,15 @@ void NasMm::receiveIdentityRequest(const nas::IdentityRequest &msg)
nas
::
IE5gsMobileIdentity
NasMm
::
getOrGenerateSuci
()
nas
::
IE5gsMobileIdentity
NasMm
::
getOrGenerateSuci
()
{
{
if
(
m_timers
->
t3519
.
isRunning
())
if
(
m_timers
->
t3519
.
isRunning
())
return
m_storedSuci
;
return
m_stor
age
.
m_stor
edSuci
;
m_storedSuci
=
generateSuci
();
m_stor
age
.
m_stor
edSuci
=
generateSuci
();
m_timers
->
t3519
.
start
();
m_timers
->
t3519
.
start
();
if
(
m_storedSuci
.
type
==
nas
::
EIdentityType
::
NO_IDENTITY
)
if
(
m_stor
age
.
m_stor
edSuci
.
type
==
nas
::
EIdentityType
::
NO_IDENTITY
)
return
{};
return
{};
return
m_storedSuci
;
return
m_stor
age
.
m_stor
edSuci
;
}
}
nas
::
IE5gsMobileIdentity
NasMm
::
generateSuci
()
nas
::
IE5gsMobileIdentity
NasMm
::
generateSuci
()
...
@@ -93,8 +93,8 @@ nas::IE5gsMobileIdentity NasMm::generateSuci()
...
@@ -93,8 +93,8 @@ nas::IE5gsMobileIdentity NasMm::generateSuci()
nas
::
IE5gsMobileIdentity
NasMm
::
getOrGeneratePreferredId
()
nas
::
IE5gsMobileIdentity
NasMm
::
getOrGeneratePreferredId
()
{
{
if
(
m_storedGuti
.
type
!=
nas
::
EIdentityType
::
NO_IDENTITY
)
if
(
m_stor
age
.
m_stor
edGuti
.
type
!=
nas
::
EIdentityType
::
NO_IDENTITY
)
return
m_storedGuti
;
return
m_stor
age
.
m_stor
edGuti
;
else
else
{
{
auto
suci
=
getOrGenerateSuci
();
auto
suci
=
getOrGenerateSuci
();
...
...
src/ue/mm/mm.hpp
View file @
31196a88
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
#include <crypt/milenage.hpp>
#include <crypt/milenage.hpp>
#include <nas/nas.hpp>
#include <nas/nas.hpp>
#include <nas/timer.hpp>
#include <nas/timer.hpp>
#include <ue/nas/storage.hpp>
#include <ue/nts.hpp>
#include <ue/nts.hpp>
#include <ue/types.hpp>
#include <ue/types.hpp>
#include <utils/nts.hpp>
#include <utils/nts.hpp>
...
@@ -28,31 +29,22 @@ class NasMm
...
@@ -28,31 +29,22 @@ class NasMm
UeTimers
*
m_timers
;
UeTimers
*
m_timers
;
std
::
unique_ptr
<
Logger
>
m_logger
;
std
::
unique_ptr
<
Logger
>
m_logger
;
NasSm
*
m_sm
;
NasSm
*
m_sm
;
MobileStorage
m_storage
{};
bool
m_autoBehaviour
;
ERmState
m_rmState
;
ERmState
m_rmState
;
ECmState
m_cmState
;
ECmState
m_cmState
;
EMmState
m_mmState
;
EMmState
m_mmState
;
EMmSubState
m_mmSubState
;
EMmSubState
m_mmSubState
;
E5UState
m_uState
;
nas
::
IE5gsMobileIdentity
m_storedSuci
{};
nas
::
IE5gsMobileIdentity
m_storedGuti
{};
// The very last registration request (or null)
std
::
unique_ptr
<
nas
::
RegistrationRequest
>
m_lastRegistrationRequest
{};
std
::
unique_ptr
<
nas
::
RegistrationRequest
>
m_lastRegistrationRequest
{};
// The very last de-registration request (or null)
std
::
unique_ptr
<
nas
::
DeRegistrationRequestUeOriginating
>
m_lastDeregistrationRequest
{};
std
::
unique_ptr
<
nas
::
DeRegistrationRequestUeOriginating
>
m_lastDeregistrationRequest
{};
// Indicates that the last de-registration request is issued due to disable 5G services
bool
m_lastDeregDueToDisable5g
{};
bool
m_lastDeregDueToDisable5g
{};
// Last time PLMN search is triggered
std
::
optional
<
nas
::
IE5gsTrackingAreaIdentity
>
m_lastVisitedRegisteredTai
{};
std
::
optional
<
nas
::
IE5gsTrackingAreaIdentityList
>
m_taiList
{};
std
::
optional
<
NasSecurityContext
>
m_currentNsCtx
;
std
::
optional
<
NasSecurityContext
>
m_nonCurrentNsCtx
;
bool
m_autoBehaviour
;
bool
m_validSim
;
long
m_lastPlmnSearchTrigger
{};
long
m_lastPlmnSearchTrigger
{};
OctetString
m_sqn
{};
friend
class
UeCmdHandler
;
friend
class
UeCmdHandler
;
...
@@ -91,8 +83,6 @@ class NasMm
...
@@ -91,8 +83,6 @@ class NasMm
void
onSwitchRmState
(
ERmState
oldState
,
ERmState
newState
);
void
onSwitchRmState
(
ERmState
oldState
,
ERmState
newState
);
void
onSwitchCmState
(
ECmState
oldState
,
ECmState
newState
);
void
onSwitchCmState
(
ECmState
oldState
,
ECmState
newState
);
void
onSwitchUState
(
E5UState
oldState
,
E5UState
newState
);
void
onSwitchUState
(
E5UState
oldState
,
E5UState
newState
);
void
invalidateAcquiredParams
();
void
invalidateSim
();
/* Transport */
/* Transport */
void
sendMmStatus
(
nas
::
EMmCause
cause
);
void
sendMmStatus
(
nas
::
EMmCause
cause
);
...
...
src/ue/mm/register.cpp
View file @
31196a88
...
@@ -19,19 +19,16 @@ void NasMm::sendRegistration(nas::ERegistrationType registrationType, nas::EFoll
...
@@ -19,19 +19,16 @@ void NasMm::sendRegistration(nas::ERegistrationType registrationType, nas::EFoll
// The UE shall mark the 5G NAS security context on the USIM or in the non-volatile memory as invalid when the UE
// The UE shall mark the 5G NAS security context on the USIM or in the non-volatile memory as invalid when the UE
// initiates an initial registration procedure
// initiates an initial registration procedure
if
(
registrationType
==
nas
::
ERegistrationType
::
INITIAL_REGISTRATION
)
if
(
registrationType
==
nas
::
ERegistrationType
::
INITIAL_REGISTRATION
)
{
m_storage
.
discardCurrentSecurity
();
m_currentNsCtx
=
{};
m_nonCurrentNsCtx
=
{};
}
switchMmState
(
EMmState
::
MM_REGISTERED_INITIATED
,
EMmSubState
::
MM_REGISTERED_INITIATED_NA
);
switchMmState
(
EMmState
::
MM_REGISTERED_INITIATED
,
EMmSubState
::
MM_REGISTERED_INITIATED_NA
);
nas
::
IENasKeySetIdentifier
ngKsi
;
nas
::
IENasKeySetIdentifier
ngKsi
;
if
(
m_currentNsCtx
.
has_value
())
if
(
m_
storage
.
m_
currentNsCtx
.
has_value
())
{
{
ngKsi
.
tsc
=
m_currentNsCtx
->
tsc
;
ngKsi
.
tsc
=
m_
storage
.
m_
currentNsCtx
->
tsc
;
ngKsi
.
ksi
=
m_currentNsCtx
->
ngKsi
;
ngKsi
.
ksi
=
m_
storage
.
m_
currentNsCtx
->
ngKsi
;
}
}
auto
request
=
std
::
make_unique
<
nas
::
RegistrationRequest
>
();
auto
request
=
std
::
make_unique
<
nas
::
RegistrationRequest
>
();
...
@@ -52,8 +49,8 @@ void NasMm::sendRegistration(nas::ERegistrationType registrationType, nas::EFoll
...
@@ -52,8 +49,8 @@ void NasMm::sendRegistration(nas::ERegistrationType registrationType, nas::EFoll
request
->
mobileIdentity
=
getOrGeneratePreferredId
();
request
->
mobileIdentity
=
getOrGeneratePreferredId
();
if
(
m_lastVisitedRegisteredTai
.
has_value
())
if
(
m_
storage
.
m_
lastVisitedRegisteredTai
.
has_value
())
request
->
lastVisitedRegisteredTai
=
m_lastVisitedRegisteredTai
.
value
();
request
->
lastVisitedRegisteredTai
=
m_
storage
.
m_
lastVisitedRegisteredTai
.
value
();
m_timers
->
t3510
.
start
();
m_timers
->
t3510
.
start
();
m_timers
->
t3502
.
stop
();
m_timers
->
t3502
.
stop
();
...
@@ -73,7 +70,7 @@ void NasMm::receiveRegistrationAccept(const nas::RegistrationAccept &msg)
...
@@ -73,7 +70,7 @@ void NasMm::receiveRegistrationAccept(const nas::RegistrationAccept &msg)
bool
sendCompleteMes
=
false
;
bool
sendCompleteMes
=
false
;
m_taiList
=
msg
.
taiList
;
m_
storage
.
m_
taiList
=
msg
.
taiList
;
if
(
msg
.
t3512Value
.
has_value
()
&&
nas
::
utils
::
HasValue
(
msg
.
t3512Value
.
value
()))
if
(
msg
.
t3512Value
.
has_value
()
&&
nas
::
utils
::
HasValue
(
msg
.
t3512Value
.
value
()))
{
{
...
@@ -83,7 +80,7 @@ void NasMm::receiveRegistrationAccept(const nas::RegistrationAccept &msg)
...
@@ -83,7 +80,7 @@ void NasMm::receiveRegistrationAccept(const nas::RegistrationAccept &msg)
if
(
msg
.
mobileIdentity
.
has_value
()
&&
msg
.
mobileIdentity
->
type
==
nas
::
EIdentityType
::
GUTI
)
if
(
msg
.
mobileIdentity
.
has_value
()
&&
msg
.
mobileIdentity
->
type
==
nas
::
EIdentityType
::
GUTI
)
{
{
m_storedGuti
=
msg
.
mobileIdentity
.
value
();
m_stor
age
.
m_stor
edGuti
=
msg
.
mobileIdentity
.
value
();
m_timers
->
t3519
.
stop
();
m_timers
->
t3519
.
stop
();
sendCompleteMes
=
true
;
sendCompleteMes
=
true
;
...
@@ -122,6 +119,8 @@ void NasMm::receiveRegistrationReject(const nas::RegistrationReject &msg)
...
@@ -122,6 +119,8 @@ void NasMm::receiveRegistrationReject(const nas::RegistrationReject &msg)
}
}
auto
unhandledRejectCase
=
[
cause
,
this
]()
{
auto
unhandledRejectCase
=
[
cause
,
this
]()
{
m_storage
.
discardUsim
();
m_logger
->
err
(
"Registration rejected with unhandled MMCause: %s"
,
nas
::
utils
::
EnumToString
(
cause
));
m_logger
->
err
(
"Registration rejected with unhandled MMCause: %s"
,
nas
::
utils
::
EnumToString
(
cause
));
switchMmState
(
EMmState
::
MM_DEREGISTERED
,
EMmSubState
::
MM_DEREGISTERED_NA
);
switchMmState
(
EMmState
::
MM_DEREGISTERED
,
EMmSubState
::
MM_DEREGISTERED_NA
);
switchRmState
(
ERmState
::
RM_DEREGISTERED
);
switchRmState
(
ERmState
::
RM_DEREGISTERED
);
...
@@ -134,11 +133,7 @@ void NasMm::receiveRegistrationReject(const nas::RegistrationReject &msg)
...
@@ -134,11 +133,7 @@ void NasMm::receiveRegistrationReject(const nas::RegistrationReject &msg)
cause
==
nas
::
EMmCause
::
TA_NOT_ALLOWED
||
cause
==
nas
::
EMmCause
::
ROAMING_NOT_ALLOWED_IN_TA
||
cause
==
nas
::
EMmCause
::
TA_NOT_ALLOWED
||
cause
==
nas
::
EMmCause
::
ROAMING_NOT_ALLOWED_IN_TA
||
cause
==
nas
::
EMmCause
::
NO_SUITIBLE_CELLS_IN_TA
)
cause
==
nas
::
EMmCause
::
NO_SUITIBLE_CELLS_IN_TA
)
{
{
m_storedGuti
=
{};
m_storage
.
discardUsim
();
m_lastVisitedRegisteredTai
=
{};
m_taiList
=
{};
m_currentNsCtx
=
{};
m_nonCurrentNsCtx
=
{};
// TODO Normally UE switches to PLMN SEARCH, but this leads to endless registration attempt again and again.
// TODO Normally UE switches to PLMN SEARCH, but this leads to endless registration attempt again and again.
// due to RLS.
// due to RLS.
...
@@ -168,11 +163,7 @@ void NasMm::receiveRegistrationReject(const nas::RegistrationReject &msg)
...
@@ -168,11 +163,7 @@ void NasMm::receiveRegistrationReject(const nas::RegistrationReject &msg)
}
}
else
if
(
cause
==
nas
::
EMmCause
::
N1_MODE_NOT_ALLOWED
)
else
if
(
cause
==
nas
::
EMmCause
::
N1_MODE_NOT_ALLOWED
)
{
{
m_storedGuti
=
{};
m_storage
.
discardUsim
();
m_lastVisitedRegisteredTai
=
{};
m_taiList
=
{};
m_currentNsCtx
=
{};
m_nonCurrentNsCtx
=
{};
switchMmState
(
EMmState
::
MM_NULL
,
EMmSubState
::
MM_NULL_NA
);
switchMmState
(
EMmState
::
MM_NULL
,
EMmSubState
::
MM_NULL_NA
);
switchRmState
(
ERmState
::
RM_DEREGISTERED
);
switchRmState
(
ERmState
::
RM_DEREGISTERED
);
...
...
src/ue/mm/security.cpp
View file @
31196a88
...
@@ -22,7 +22,7 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
...
@@ -22,7 +22,7 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
m_logger
->
err
(
"Rejecting Security Mode Command with cause: %s"
,
nas
::
utils
::
EnumToString
(
cause
));
m_logger
->
err
(
"Rejecting Security Mode Command with cause: %s"
,
nas
::
utils
::
EnumToString
(
cause
));
};
};
if
(
!
m_nonCurrentNsCtx
.
has_value
())
if
(
!
m_
storage
.
m_
nonCurrentNsCtx
.
has_value
())
{
{
reject
(
nas
::
EMmCause
::
MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE
);
reject
(
nas
::
EMmCause
::
MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE
);
return
;
return
;
...
@@ -58,7 +58,7 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
...
@@ -58,7 +58,7 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
// Assign ABBA (if any)
// Assign ABBA (if any)
if
(
msg
.
abba
.
has_value
())
if
(
msg
.
abba
.
has_value
())
m_nonCurrentNsCtx
->
keys
.
abba
=
msg
.
abba
->
rawData
.
copy
();
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
abba
=
msg
.
abba
->
rawData
.
copy
();
// Check selected algorithms
// Check selected algorithms
{
{
...
@@ -68,17 +68,17 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
...
@@ -68,17 +68,17 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
}
}
// Assign selected algorithms to security context, and derive NAS keys
// Assign selected algorithms to security context, and derive NAS keys
m_nonCurrentNsCtx
->
integrity
=
msg
.
selectedNasSecurityAlgorithms
.
integrity
;
m_
storage
.
m_
nonCurrentNsCtx
->
integrity
=
msg
.
selectedNasSecurityAlgorithms
.
integrity
;
m_nonCurrentNsCtx
->
ciphering
=
msg
.
selectedNasSecurityAlgorithms
.
ciphering
;
m_
storage
.
m_
nonCurrentNsCtx
->
ciphering
=
msg
.
selectedNasSecurityAlgorithms
.
ciphering
;
keys
::
DeriveNasKeys
(
*
m_nonCurrentNsCtx
);
keys
::
DeriveNasKeys
(
*
m_
storage
.
m_
nonCurrentNsCtx
);
m_logger
->
debug
(
"Derived kNasEnc[%s] kNasInt[%s]"
,
m_nonCurrentNsCtx
->
keys
.
kNasEnc
.
toHexString
().
c_str
(),
m_logger
->
debug
(
"Derived kNasEnc[%s] kNasInt[%s]"
,
m_
storage
.
m_
nonCurrentNsCtx
->
keys
.
kNasEnc
.
toHexString
().
c_str
(),
m_nonCurrentNsCtx
->
keys
.
kNasInt
.
toHexString
().
c_str
());
m_storage
.
m_nonCurrentNsCtx
->
keys
.
kNasInt
.
toHexString
().
c_str
());
m_logger
->
debug
(
"Selected integrity[%d] ciphering[%d]"
,
(
int
)
m_nonCurrentNsCtx
->
integrity
,
m_logger
->
debug
(
"Selected integrity[%d] ciphering[%d]"
,
(
int
)
m_
storage
.
m_
nonCurrentNsCtx
->
integrity
,
(
int
)
m_nonCurrentNsCtx
->
ciphering
);
(
int
)
m_
storage
.
m_
nonCurrentNsCtx
->
ciphering
);
// Set non-current NAS Security Context as current one.
// Set non-current NAS Security Context as current one.
m_
currentNsCtx
=
m_nonCurrentNsCtx
->
deepCopy
();
m_
storage
.
m_currentNsCtx
=
m_storage
.
m_nonCurrentNsCtx
->
deepCopy
();
// Prepare response
// Prepare response
nas
::
SecurityModeComplete
resp
;
nas
::
SecurityModeComplete
resp
;
...
...
src/ue/mm/transport.cpp
View file @
31196a88
...
@@ -21,10 +21,11 @@ void NasMm::sendNasMessage(const nas::PlainMmMessage &msg)
...
@@ -21,10 +21,11 @@ void NasMm::sendNasMessage(const nas::PlainMmMessage &msg)
// TODO trigger on send
// TODO trigger on send
OctetString
pdu
{};
OctetString
pdu
{};
if
(
m_currentNsCtx
.
has_value
()
&&
(
m_currentNsCtx
->
integrity
!=
nas
::
ETypeOfIntegrityProtectionAlgorithm
::
IA0
||
if
(
m_storage
.
m_currentNsCtx
.
has_value
()
&&
m_currentNsCtx
->
ciphering
!=
nas
::
ETypeOfCipheringAlgorithm
::
EA0
))
(
m_storage
.
m_currentNsCtx
->
integrity
!=
nas
::
ETypeOfIntegrityProtectionAlgorithm
::
IA0
||
m_storage
.
m_currentNsCtx
->
ciphering
!=
nas
::
ETypeOfCipheringAlgorithm
::
EA0
))
{
{
auto
secured
=
nas_enc
::
Encrypt
(
*
m_currentNsCtx
,
msg
);
auto
secured
=
nas_enc
::
Encrypt
(
*
m_
storage
.
m_
currentNsCtx
,
msg
);
nas
::
EncodeNasMessage
(
*
secured
,
pdu
);
nas
::
EncodeNasMessage
(
*
secured
,
pdu
);
}
}
else
else
...
@@ -62,7 +63,7 @@ void NasMm::receiveNasMessage(const nas::NasMessage &msg)
...
@@ -62,7 +63,7 @@ void NasMm::receiveNasMessage(const nas::NasMessage &msg)
{
{
// If any NAS signalling message is received as not integrity protected even though the secure exchange of NAS
// If any NAS signalling message is received as not integrity protected even though the secure exchange of NAS
// messages has been established by the network, then the NAS shall discard this message
// messages has been established by the network, then the NAS shall discard this message
if
(
m_currentNsCtx
.
has_value
())
if
(
m_
storage
.
m_
currentNsCtx
.
has_value
())
{
{
m_logger
->
err
(
m_logger
->
err
(
"Not integrity protected NAS message received after security establishment. Ignoring received "
"Not integrity protected NAS message received after security establishment. Ignoring received "
...
@@ -100,14 +101,14 @@ void NasMm::receiveNasMessage(const nas::NasMessage &msg)
...
@@ -100,14 +101,14 @@ void NasMm::receiveNasMessage(const nas::NasMessage &msg)
return
;
return
;
}
}
if
(
!
m_currentNsCtx
.
has_value
())
if
(
!
m_
storage
.
m_
currentNsCtx
.
has_value
())
{
{
m_logger
->
warn
(
"Secured NAS message received while no security context"
);
m_logger
->
warn
(
"Secured NAS message received while no security context"
);
sendMmStatus
(
nas
::
EMmCause
::
MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE
);
sendMmStatus
(
nas
::
EMmCause
::
MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE
);
return
;
return
;
}
}
auto
decrypted
=
nas_enc
::
Decrypt
(
*
m_currentNsCtx
,
securedMm
);
auto
decrypted
=
nas_enc
::
Decrypt
(
*
m_
storage
.
m_
currentNsCtx
,
securedMm
);
if
(
decrypted
==
nullptr
)
if
(
decrypted
==
nullptr
)
{
{
m_logger
->
err
(
"MAC mismatch in NAS encryption. Ignoring received NAS Message."
);
m_logger
->
err
(
"MAC mismatch in NAS encryption. Ignoring received NAS Message."
);
...
...
src/ue/nas/storage.cpp
0 → 100644
View file @
31196a88
//
// This file is a part of UERANSIM open source project.
// Copyright (c) 2021 ALİ GÜNGÖR.
//
// The software and all associated files are licensed under GPL-3.0
// and subject to the terms and conditions defined in LICENSE file.
//
#include "storage.hpp"
namespace
nr
::
ue
{
}
// namespace nr::ue
src/ue/nas/storage.hpp
0 → 100644
View file @
31196a88
//
// This file is a part of UERANSIM open source project.
// Copyright (c) 2021 ALİ GÜNGÖR.
//
// The software and all associated files are licensed under GPL-3.0
// and subject to the terms and conditions defined in LICENSE file.
//
#include <nas/nas.hpp>
#include <ue/types.hpp>
#pragma once
namespace
nr
::
ue
{
class
MobileStorage
{
private:
bool
m_simIsValid
{};
public:
// Location related
nas
::
IE5gsMobileIdentity
m_storedGuti
{};
std
::
optional
<
nas
::
IE5gsTrackingAreaIdentity
>
m_lastVisitedRegisteredTai
{};
E5UState
m_uState
{};
// Identity related
nas
::
IE5gsMobileIdentity
m_storedSuci
{};
// Plmn related
std
::
optional
<
nas
::
IE5gsTrackingAreaIdentityList
>
m_taiList
{};
// Security related
std
::
optional
<
NasSecurityContext
>
m_currentNsCtx
{};
std
::
optional
<
NasSecurityContext
>
m_nonCurrentNsCtx
{};
OctetString
m_sqn
{};
public:
void
initialize
(
bool
hasSupi
)
{
m_simIsValid
=
hasSupi
;
}
void
discardLocation
()
{
m_storedGuti
=
{};
m_lastVisitedRegisteredTai
=
{};
}
void
discardPlmn
()
{
m_taiList
=
{};
}
void
discardSecurity
()
{
m_currentNsCtx
=
{};
m_nonCurrentNsCtx
=
{};
}
void
discardCurrentSecurity
()
{
m_currentNsCtx
=
{};
// normally NON-current nsCtx is not stored in USIM
}
void
discardUsim
()
{
discardLocation
();
discardPlmn
();
discardSecurity
();
}
void
invalidateSim
()
{
// TODO: log
discardUsim
();
m_simIsValid
=
false
;
}
[[
nodiscard
]]
bool
isSimValid
()
const
{
return
m_simIsValid
;
}
};
}
// namespace nr::ue
\ No newline at end of file
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