Commit a9b7b96c authored by aligungr's avatar aligungr

Protection of initial NAS messages

parent b2f74d6b
...@@ -87,4 +87,13 @@ inline T DeepCopyIe(const T &a) ...@@ -87,4 +87,13 @@ inline T DeepCopyIe(const T &a)
} }
} }
template <typename T>
inline std::unique_ptr<NasMessage> DeepCopyMsg(const T &msg)
{
OctetString stream;
EncodeNasMessage(msg, stream);
return DecodeNasMessage(OctetView{stream});
}
} // namespace nas::utils } // namespace nas::utils
...@@ -34,11 +34,51 @@ static bool IsAcceptedWithoutIntegrity(const nas::PlainMmMessage &msg) ...@@ -34,11 +34,51 @@ static bool IsAcceptedWithoutIntegrity(const nas::PlainMmMessage &msg)
msgType == nas::EMessageType::SERVICE_REJECT; msgType == nas::EMessageType::SERVICE_REJECT;
} }
static bool BypassCiphering(const nas::PlainMmMessage &msg) static bool ShouldBypassCiphering(const nas::PlainMmMessage &msg)
{ {
return IsInitialNasMessage(msg); return IsInitialNasMessage(msg);
} }
static void EncodeNasMessageWithoutCleartext(const nas::PlainMmMessage &msg, OctetString &stream)
{
if (msg.messageType == nas::EMessageType::REGISTRATION_REQUEST)
{
auto copy = nas::utils::DeepCopyMsg(msg);
auto &regReq = (nas::RegistrationRequest &)(*copy);
regReq.nonCurrentNgKsi = std::nullopt;
regReq.micoIndication = std::nullopt;
regReq.networkSlicingIndication = std::nullopt;
regReq.mmCapability = std::nullopt;
regReq.requestedNSSAI = std::nullopt;
regReq.requestedDrxParameters = std::nullopt;
regReq.uesUsageSetting = std::nullopt;
regReq.updateType = std::nullopt;
regReq.uplinkDataStatus = std::nullopt;
regReq.nasMessageContainer = std::nullopt;
regReq.allowedPduSessionStatus = std::nullopt;
regReq.lastVisitedRegisteredTai = std::nullopt;
regReq.s1UeNetworkCapability = std::nullopt;
regReq.pduSessionStatus = std::nullopt;
regReq.payloadContainer = std::nullopt;
regReq.ladnIndication = std::nullopt;
nas::EncodeNasMessage(*copy, stream);
}
else if (msg.messageType == nas::EMessageType::SERVICE_REQUEST)
{
auto copy = nas::utils::DeepCopyMsg(msg);
auto &servReq = (nas::ServiceRequest &)(*copy);
servReq.uplinkDataStatus = std::nullopt;
servReq.pduSessionStatus = std::nullopt;
servReq.allowedPduSessionStatus = std::nullopt;
servReq.nasMessageContainer = std::nullopt;
nas::EncodeNasMessage(*copy, stream);
}
}
void NasMm::sendNasMessage(const nas::PlainMmMessage &msg) void NasMm::sendNasMessage(const nas::PlainMmMessage &msg)
{ {
if (m_cmState == ECmState::CM_IDLE && !IsInitialNasMessage(msg)) if (m_cmState == ECmState::CM_IDLE && !IsInitialNasMessage(msg))
...@@ -49,16 +89,19 @@ void NasMm::sendNasMessage(const nas::PlainMmMessage &msg) ...@@ -49,16 +89,19 @@ void NasMm::sendNasMessage(const nas::PlainMmMessage &msg)
return; return;
} }
OctetString pdu{}; OctetString pdu;
if (m_usim->m_currentNsCtx && (m_usim->m_currentNsCtx->integrity != nas::ETypeOfIntegrityProtectionAlgorithm::IA0 || if (m_usim->m_currentNsCtx && (m_usim->m_currentNsCtx->integrity != nas::ETypeOfIntegrityProtectionAlgorithm::IA0 ||
m_usim->m_currentNsCtx->ciphering != nas::ETypeOfCipheringAlgorithm::EA0)) m_usim->m_currentNsCtx->ciphering != nas::ETypeOfCipheringAlgorithm::EA0))
{ {
auto secured = nas_enc::Encrypt(*m_usim->m_currentNsCtx, msg, BypassCiphering(msg)); auto secured = nas_enc::Encrypt(*m_usim->m_currentNsCtx, msg, ShouldBypassCiphering(msg));
nas::EncodeNasMessage(*secured, pdu); nas::EncodeNasMessage(*secured, pdu);
} }
else else
{ {
nas::EncodeNasMessage(msg, pdu); if (IsInitialNasMessage(msg))
EncodeNasMessageWithoutCleartext(msg, pdu);
else
nas::EncodeNasMessage(msg, pdu);
} }
if (m_cmState == ECmState::CM_IDLE) if (m_cmState == ECmState::CM_IDLE)
......
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