Commit 9a36d694 authored by aligungr's avatar aligungr

USIM refactor

parent da1c6910
...@@ -63,20 +63,20 @@ void NasMm::receiveAuthenticationRequestEap(const nas::AuthenticationRequest &ms ...@@ -63,20 +63,20 @@ void NasMm::receiveAuthenticationRequestEap(const nas::AuthenticationRequest &ms
// Log.warning(Tag.CONFIG, "USE_SQN_HACK: %s", USE_SQN_HACK); // Log.warning(Tag.CONFIG, "USE_SQN_HACK: %s", USE_SQN_HACK);
} }
if (USE_SQN_HACK) /*if (USE_SQN_HACK)
{ {
auto ak = calculateMilenage(OctetString::FromSpare(6), receivedRand, false).ak; auto ak = calculateMilenage(OctetString::FromSpare(6), receivedRand, false).ak;
m_usim->m_sqn = OctetString::Xor(receivedAutn.subCopy(0, 6), ak); m_usim->m_sqn = OctetString::Xor(receivedAutn.subCopy(0, 6), ak);
} }*/
auto milenage = calculateMilenage(m_usim->m_sqn, receivedRand, false); auto milenage = calculateMilenage(m_usim->m_sqnMng->getSqn(), receivedRand, false);
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_usim->m_sqn, milenageAk); auto sqnXorAk = OctetString::Xor(m_usim->m_sqnMng->getSqn(), milenageAk);
auto ckPrimeIkPrime = auto ckPrimeIkPrime =
keys::CalculateCkPrimeIkPrime(ck, ik, keys::ConstructServingNetworkName(*m_usim->m_currentPlmn), sqnXorAk); keys::CalculateCkPrimeIkPrime(ck, ik, keys::ConstructServingNetworkName(*m_usim->m_currentPlmn), sqnXorAk);
auto &ckPrime = ckPrimeIkPrime.first; auto &ckPrime = ckPrimeIkPrime.first;
...@@ -289,14 +289,14 @@ void NasMm::receiveAuthenticationRequest5gAka(const nas::AuthenticationRequest & ...@@ -289,14 +289,14 @@ void NasMm::receiveAuthenticationRequest5gAka(const nas::AuthenticationRequest &
auto &rand = msg.authParamRAND->value; auto &rand = msg.authParamRAND->value;
auto &autn = msg.authParamAUTN->value; auto &autn = msg.authParamAUTN->value;
auto milenage = calculateMilenage(m_usim->m_sqn, rand, false); auto milenage = calculateMilenage(m_usim->m_sqnMng->getSqn(), rand, false);
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_usim->m_sqn, milenageAk); auto sqnXorAk = OctetString::Xor(m_usim->m_sqnMng->getSqn(), milenageAk);
auto snn = keys::ConstructServingNetworkName(*m_usim->m_currentPlmn); auto snn = keys::ConstructServingNetworkName(*m_usim->m_currentPlmn);
auto autnCheck = validateAutn(milenageAk, milenageMac, autn); auto autnCheck = validateAutn(milenageAk, milenageMac, autn);
...@@ -329,8 +329,8 @@ void NasMm::receiveAuthenticationRequest5gAka(const nas::AuthenticationRequest & ...@@ -329,8 +329,8 @@ void NasMm::receiveAuthenticationRequest5gAka(const nas::AuthenticationRequest &
} }
else if (autnCheck == EAutnValidationRes::SYNCHRONISATION_FAILURE) else if (autnCheck == EAutnValidationRes::SYNCHRONISATION_FAILURE)
{ {
auto milenageForSync = calculateMilenage(m_usim->m_sqn, rand, true); auto milenageForSync = calculateMilenage(m_usim->m_sqnMng->getSqn(), rand, true);
auto auts = keys::CalculateAuts(m_usim->m_sqn, milenageForSync.ak_r, milenageForSync.mac_s); auto auts = keys::CalculateAuts(m_usim->m_sqnMng->getSqn(), milenageForSync.ak_r, milenageForSync.mac_s);
sendFailure(nas::EMmCause::SYNCH_FAILURE, std::move(auts)); sendFailure(nas::EMmCause::SYNCH_FAILURE, std::move(auts));
} }
else else
...@@ -435,7 +435,7 @@ EAutnValidationRes NasMm::validateAutn(const OctetString &ak, const OctetString ...@@ -435,7 +435,7 @@ EAutnValidationRes NasMm::validateAutn(const OctetString &ak, const OctetString
} }
// Verify that the received sequence number SQN is in the correct range // Verify that the received sequence number SQN is in the correct range
if (!m_usim->checkSqn(receivedSQN)) if (!m_usim->m_sqnMng->checkSqn(receivedSQN))
return EAutnValidationRes::SYNCHRONISATION_FAILURE; return EAutnValidationRes::SYNCHRONISATION_FAILURE;
// Check MAC // Check MAC
......
//
// 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 "sqn_mng.hpp"
#include <stdexcept>
namespace nr::ue
{
SqnManager::SqnManager(uint64_t indBitLen, uint64_t wrappingDelta, uint64_t limit)
: m_indBitLen{indBitLen}, m_wrappingDelta{wrappingDelta}, m_limit{limit}, m_sqnArr(1ull << m_indBitLen)
{
if (m_indBitLen < 2 || m_indBitLen > 16)
throw std::runtime_error("bad indBitLen");
}
uint64_t SqnManager::getSeqFromSqn(uint64_t sqn) const
{
sqn &= ~((1ull << m_indBitLen) - 1ull);
sqn >>= m_indBitLen;
sqn &= (1ull << 48ull) - 1ull;
return sqn;
}
uint64_t SqnManager::getIndFromSqn(uint64_t sqn) const
{
return sqn & ((1ull << m_indBitLen) - 1ull);
}
uint64_t SqnManager::getSeqMs() const
{
return getSeqFromSqn(getSqnUL());
}
uint64_t SqnManager::getSqnUL() const
{
return *std::max_element(m_sqnArr.begin(), m_sqnArr.end());
}
bool SqnManager::checkSqn(uint64_t sqn)
{
uint64_t seq = getSeqFromSqn(sqn);
uint64_t ind = getIndFromSqn(sqn);
if (seq - getSeqMs() > m_wrappingDelta)
return false;
if (getSeqMs() - seq >= m_limit)
return false;
if (seq <= getSeqFromSqn(m_sqnArr[ind]))
return false;
m_sqnArr[ind] = sqn;
return true;
}
bool SqnManager::checkSqn(const OctetString &sqn)
{
OctetString str;
str.appendOctet2(0);
str.append(sqn);
return checkSqn(str.get8UL(0));
}
OctetString SqnManager::getSqn() const
{
return OctetString::FromOctet8(getSqnUL()).subCopy(2);
}
} // namespace nr::ue
//
// 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.
//
#pragma once
#include <algorithm>
#include <cstdint>
#include <vector>
#include <utils/octet_string.hpp>
namespace nr::ue
{
class SqnManager
{
private:
uint64_t m_indBitLen;
uint64_t m_wrappingDelta;
uint64_t m_limit;
std::vector<uint64_t> m_sqnArr;
public:
SqnManager(uint64_t indBitLen, uint64_t wrappingDelta, uint64_t limit);
private:
[[nodiscard]] uint64_t getSeqFromSqn(uint64_t sqn) const;
[[nodiscard]] uint64_t getIndFromSqn(uint64_t sqn) const;
[[nodiscard]] uint64_t getSeqMs() const;
public:
[[nodiscard]] uint64_t getSqnUL() const;
[[nodiscard]] OctetString getSqn() const;
bool checkSqn(uint64_t sqn);
bool checkSqn(const OctetString &sqn);
};
} // namespace nr::ue
...@@ -20,7 +20,7 @@ void ue::Usim::initialize(bool hasSupi, const UeConfig::Initials &initials) ...@@ -20,7 +20,7 @@ void ue::Usim::initialize(bool hasSupi, const UeConfig::Initials &initials)
m_defConfiguredNssai = initials.defaultConfiguredNssai; m_defConfiguredNssai = initials.defaultConfiguredNssai;
m_configuredNssai = initials.configuredNssai; m_configuredNssai = initials.configuredNssai;
m_sqn = OctetString::FromSpare(6); m_sqnMng = std::make_unique<SqnManager>(5ull, 1ull << 28ull, ~0ull);
} }
bool Usim::isValid() bool Usim::isValid()
...@@ -33,10 +33,4 @@ void Usim::invalidate() ...@@ -33,10 +33,4 @@ void Usim::invalidate()
m_isValid = false; m_isValid = false;
} }
bool Usim::checkSqn(const OctetString &sqn)
{
// TODO
return false;
}
} // namespace nr::ue } // namespace nr::ue
...@@ -8,9 +8,12 @@ ...@@ -8,9 +8,12 @@
#pragma once #pragma once
#include <lib/nas/msg.hpp> #include "sqn_mng.hpp"
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <lib/nas/msg.hpp>
#include <ue/types.hpp> #include <ue/types.hpp>
#include <utils/common_types.hpp> #include <utils/common_types.hpp>
#include <utils/octet_string.hpp> #include <utils/octet_string.hpp>
...@@ -49,6 +52,7 @@ class Usim ...@@ -49,6 +52,7 @@ class Usim
OctetString m_rand{}; OctetString m_rand{};
OctetString m_res{}; OctetString m_res{};
OctetString m_resStar{}; OctetString m_resStar{};
std::unique_ptr<SqnManager> m_sqnMng{};
// NSSAI related // NSSAI related
NetworkSlice m_defConfiguredNssai{}; NetworkSlice m_defConfiguredNssai{};
...@@ -67,16 +71,11 @@ class Usim ...@@ -67,16 +71,11 @@ class Usim
// eCall related // eCall related
bool m_isECallOnly{}; bool m_isECallOnly{};
// SQN management
OctetString m_sqn{};
public: public:
void initialize(bool hasSupi, const UeConfig::Initials &initials); void initialize(bool hasSupi, const UeConfig::Initials &initials);
bool isValid(); bool isValid();
void invalidate(); void invalidate();
bool checkSqn(const OctetString &sqn);
}; };
} // namespace nr::ue } // namespace nr::ue
\ No newline at end of file
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