Allow encrypted M17 data to be rejected.

This commit is contained in:
Jonathan Naylor 2020-10-26 10:10:31 +00:00
parent d0e8574187
commit 31002c2757
8 changed files with 48 additions and 8 deletions

View file

@ -169,6 +169,7 @@ m_nxdnTXHang(5U),
m_nxdnModeHang(10U),
m_m17Enabled(false),
m_m17SelfOnly(false),
m_m17AllowEncryption(false),
m_m17TXHang(5U),
m_m17ModeHang(10U),
m_pocsagEnabled(false),
@ -706,6 +707,8 @@ bool CConf::read()
m_m17Enabled = ::atoi(value) == 1;
else if (::strcmp(key, "SelfOnly") == 0)
m_m17SelfOnly = ::atoi(value) == 1;
else if (::strcmp(key, "AllowEncryption") == 0)
m_m17AllowEncryption = ::atoi(value) == 1;
else if (::strcmp(key, "TXHang") == 0)
m_m17TXHang = (unsigned int)::atoi(value);
else if (::strcmp(key, "ModeHang") == 0)
@ -1516,6 +1519,11 @@ bool CConf::getM17SelfOnly() const
return m_m17SelfOnly;
}
bool CConf::getM17AllowEncryption() const
{
return m_m17AllowEncryption;
}
unsigned int CConf::getM17TXHang() const
{
return m_m17TXHang;

2
Conf.h
View file

@ -164,6 +164,7 @@ public:
// The M17 section
bool getM17Enabled() const;
bool getM17SelfOnly() const;
bool getM17AllowEncryption() const;
unsigned int getM17TXHang() const;
unsigned int getM17ModeHang() const;
@ -440,6 +441,7 @@ private:
bool m_m17Enabled;
bool m_m17SelfOnly;
bool m_m17AllowEncryption;
unsigned int m_m17TXHang;
unsigned int m_m17ModeHang;

View file

@ -57,9 +57,10 @@ const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04
#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
#define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
CM17Control::CM17Control(const std::string& callsign, bool selfOnly, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper) :
CM17Control::CM17Control(const std::string& callsign, bool selfOnly, bool allowEncryption, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper) :
m_callsign(callsign),
m_selfOnly(selfOnly),
m_allowEncryption(allowEncryption),
m_network(network),
m_display(display),
m_duplex(duplex),
@ -189,6 +190,15 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
}
}
if (!m_allowEncryption) {
bool ret = m_rfLICH.isNONCENull();
if (!ret) {
LogMessage("M17, invalid access attempt from %s to %s", source.c_str(), dest.c_str());
m_rfState = RS_RF_REJECTED;
return false;
}
}
unsigned char dataType = m_rfLICH.getDataType();
switch (dataType) {
case 1U:
@ -531,9 +541,15 @@ void CM17Control::writeNetwork()
m_networkWatchdog.start();
if (m_netState == RS_NET_IDLE) {
m_netLICH.setNetwork(netData);
m_netLICH.setNetwork(netData);
if (!m_allowEncryption) {
bool ret = m_rfLICH.isNONCENull();
if (!ret)
return;
}
if (m_netState == RS_NET_IDLE) {
std::string source = m_netLICH.getSource();
std::string dest = m_netLICH.getDest();

View file

@ -34,7 +34,7 @@
class CM17Control {
public:
CM17Control(const std::string& callsign, bool selfOnly, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper);
CM17Control(const std::string& callsign, bool selfOnly, bool allowEncryption, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper);
~CM17Control();
bool writeModem(unsigned char* data, unsigned int len);
@ -50,6 +50,7 @@ public:
private:
std::string m_callsign;
bool m_selfOnly;
bool m_allowEncryption;
CM17Network* m_network;
CDisplay* m_display;
bool m_duplex;

View file

@ -40,6 +40,10 @@ const unsigned int M17_LICH_FRAGMENT_FEC_LENGTH_BYTES = M17_LICH_FRAGMENT_FEC_LE
const unsigned int M17_PAYLOAD_LENGTH_BITS = 128U;
const unsigned int M17_PAYLOAD_LENGTH_BYTES = M17_PAYLOAD_LENGTH_BITS / 8U;
const unsigned char M17_NULL_NONCE[] = {0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
const unsigned int M17_NONCE_LENGTH_BITS = 112U;
const unsigned int M17_NONCE_LENGTH_BYTES = M17_NONCE_LENGTH_BITS / 8U;
const unsigned int M17_FN_LENGTH_BITS = 16U;
const unsigned int M17_FN_LENGTH_BYTES = M17_FN_LENGTH_BITS / 8U;

View file

@ -89,6 +89,11 @@ void CM17LICH::setDataType(unsigned char type)
m_lich[13U] |= (type << 1) & 0x06U;
}
bool CM17LICH::isNONCENull() const
{
return ::memcmp(m_lich + 14U, M17_NULL_NONCE, M17_NONCE_LENGTH_BYTES) == 0;
}
void CM17LICH::reset()
{
::memset(m_lich, 0x00U, 30U);

View file

@ -38,6 +38,8 @@ public:
unsigned char getDataType() const;
void setDataType(unsigned char type);
bool isNONCENull() const;
void reset();
bool isValid() const;

View file

@ -610,16 +610,18 @@ int CMMDVMHost::run()
}
if (m_m17Enabled) {
bool selfOnly = m_conf.getM17SelfOnly();
unsigned int txHang = m_conf.getM17TXHang();
m_m17RFModeHang = m_conf.getM17ModeHang();
bool selfOnly = m_conf.getM17SelfOnly();
bool allowEncryption = m_conf.getM17AllowEncryption();
unsigned int txHang = m_conf.getM17TXHang();
m_m17RFModeHang = m_conf.getM17ModeHang();
LogInfo("M17 RF Parameters");
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
LogInfo(" Allow Encryption: %s", allowEncryption ? "yes" : "no");
LogInfo(" TX Hang: %us", txHang);
LogInfo(" Mode Hang: %us", m_m17RFModeHang);
m_m17 = new CM17Control(m_callsign, selfOnly, m_m17Network, m_display, m_timeout, m_duplex, rssi);
m_m17 = new CM17Control(m_callsign, selfOnly, allowEncryption, m_m17Network, m_display, m_timeout, m_duplex, rssi);
}
CTimer pocsagTimer(1000U, 30U);