Commit 2944a009 authored by aligungr's avatar aligungr

Security mode command procedure improvement

parent 1e368383
...@@ -28,6 +28,11 @@ void DeriveNasKeys(NasSecurityContext &securityContext); ...@@ -28,6 +28,11 @@ void DeriveNasKeys(NasSecurityContext &securityContext);
*/ */
std::string ConstructServingNetworkName(const Plmn &plmn); std::string ConstructServingNetworkName(const Plmn &plmn);
/**
* Derives kAMF to kAMF' in mobility 33.501/A.13
*/
OctetString DeriveAmfPrimeInMobility(bool isUplink, const NasCount &count, const OctetString &kAmf);
/** /**
* Calculates K_AUSF for 5G-AKA according to given parameters as specified in 3GPP TS 33.501 Annex A.2 * Calculates K_AUSF for 5G-AKA according to given parameters as specified in 3GPP TS 33.501 Annex A.2
*/ */
......
...@@ -135,6 +135,9 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg) ...@@ -135,6 +135,9 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
// ======================== Check the integrity with new security context ======================== // ======================== Check the integrity with new security context ========================
bool clearNasCount = false; bool clearNasCount = false;
bool horizontalDeriveNeeded =
msg.additional5gSecurityInformation.has_value() &&
msg.additional5gSecurityInformation->hdp == nas::EHorizontalDerivationParameter::REQUIRED;
if (msg.selectedNasSecurityAlgorithms.integrity != nas::ETypeOfIntegrityProtectionAlgorithm::IA0) if (msg.selectedNasSecurityAlgorithms.integrity != nas::ETypeOfIntegrityProtectionAlgorithm::IA0)
{ {
...@@ -142,10 +145,15 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg) ...@@ -142,10 +145,15 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
tmpCtx.integrity = msg.selectedNasSecurityAlgorithms.integrity; tmpCtx.integrity = msg.selectedNasSecurityAlgorithms.integrity;
tmpCtx.ciphering = msg.selectedNasSecurityAlgorithms.ciphering; tmpCtx.ciphering = msg.selectedNasSecurityAlgorithms.ciphering;
// Before deriving the keys for temporary NAS security context, concern the horizontal derivation case
// Because 33.501/6.9.3 says integrity check should be performed with the new key
if (horizontalDeriveNeeded)
tmpCtx.keys.kAmf = keys::DeriveAmfPrimeInMobility(true, tmpCtx.uplinkCount, tmpCtx.keys.kAmf);
keys::DeriveNasKeys(tmpCtx); keys::DeriveNasKeys(tmpCtx);
uint32_t calculatedMac = uint32_t calculatedMac = nas_enc::ComputeMac(tmpCtx.integrity, tmpCtx.downlinkCount, tmpCtx.is3gppAccess, false,
nr::ue::nas_enc::ComputeMac(tmpCtx.integrity, tmpCtx.downlinkCount, tmpCtx.is3gppAccess, false,
tmpCtx.keys.kNasInt, msg._originalPlainNasPdu); tmpCtx.keys.kNasInt, msg._originalPlainNasPdu);
// First check with the last estimated NAS COUNT // First check with the last estimated NAS COUNT
...@@ -156,8 +164,8 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg) ...@@ -156,8 +164,8 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
tmpCtx.downlinkCount = {}; // assign NAS COUNT=0 tmpCtx.downlinkCount = {}; // assign NAS COUNT=0
calculatedMac = nr::ue::nas_enc::ComputeMac(tmpCtx.integrity, tmpCtx.downlinkCount, tmpCtx.is3gppAccess, calculatedMac = nas_enc::ComputeMac(tmpCtx.integrity, tmpCtx.downlinkCount, tmpCtx.is3gppAccess, false,
false, tmpCtx.keys.kNasInt, msg._originalPlainNasPdu); tmpCtx.keys.kNasInt, msg._originalPlainNasPdu);
if (calculatedMac != static_cast<uint32_t>(msg._macForNewSC)) if (calculatedMac != static_cast<uint32_t>(msg._macForNewSC))
{ {
...@@ -189,10 +197,12 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg) ...@@ -189,10 +197,12 @@ void NasMm::receiveSecurityModeCommand(const nas::SecurityModeCommand &msg)
nsCtx->keys.abba = msg.abba->rawData.copy(); nsCtx->keys.abba = msg.abba->rawData.copy();
// Handle horizontal derivation // Handle horizontal derivation
if (msg.additional5gSecurityInformation.has_value() && if (horizontalDeriveNeeded)
msg.additional5gSecurityInformation->hdp == nas::EHorizontalDerivationParameter::REQUIRED)
{ {
// TODO m_logger->debug("Performing kAMF' derivation from kAMF in mobility");
nsCtx->keys.kAmf = keys::DeriveAmfPrimeInMobility(true, nsCtx->uplinkCount, nsCtx->keys.kAmf);
nsCtx->uplinkCount = {};
nsCtx->downlinkCount = {};
} }
// Assign selected algorithms to security context, and derive NAS keys // Assign selected algorithms to security context, and derive NAS keys
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment