parent
676a112313
commit
ded260216a
@ -0,0 +1,107 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Digital Voice Modem - Common Library
|
||||||
|
* GPLv2 Open Source. Use is subject to license terms.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "Defines.h"
|
||||||
|
#include "p25/P25Defines.h"
|
||||||
|
#include "p25/kmm/KMMFrame.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
using namespace p25;
|
||||||
|
using namespace p25::defines;
|
||||||
|
using namespace p25::kmm;
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Public Class Members
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* Initializes a copy instance of the KMMFrame class. */
|
||||||
|
|
||||||
|
KMMFrame::KMMFrame(const KMMFrame& data) : KMMFrame()
|
||||||
|
{
|
||||||
|
copy(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initializes a new instance of the KMMFrame class. */
|
||||||
|
|
||||||
|
KMMFrame::KMMFrame() :
|
||||||
|
m_messageId(KMM_MessageType::NULL_CMD),
|
||||||
|
m_messageLength(7U),
|
||||||
|
m_respKind(KMM_ResponseKind::NONE),
|
||||||
|
m_complete(true),
|
||||||
|
m_mfMessageNumber(0U),
|
||||||
|
m_mfMac(KMM_MAC::NO_MAC)
|
||||||
|
{
|
||||||
|
/* stub */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finalizes a instance of the KMMFrame class. */
|
||||||
|
|
||||||
|
KMMFrame::~KMMFrame() = default;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Protected Class Members
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* Internal helper to decode a SNDCP header. */
|
||||||
|
|
||||||
|
bool KMMFrame::decodeHeader(const uint8_t* data, bool outbound)
|
||||||
|
{
|
||||||
|
assert(data != nullptr);
|
||||||
|
|
||||||
|
m_messageId = data[0U]; // Message ID
|
||||||
|
m_messageLength = __GET_UINT16B(data, 1U); // Message Length
|
||||||
|
|
||||||
|
m_respKind = (data[2U] >> 6U) & 0x03U; // Response Kind
|
||||||
|
m_mfMessageNumber = (data[2U] >> 4U) & 0x03U; // Message Number
|
||||||
|
m_mfMac = (data[2U] >> 2U) & 0x03U; // MAC
|
||||||
|
|
||||||
|
bool done = (data[2U] & 0x01U) == 0x01U; // Done Flag
|
||||||
|
if (!done)
|
||||||
|
m_complete = true;
|
||||||
|
else
|
||||||
|
m_complete = false;
|
||||||
|
|
||||||
|
m_dstLlId = __GET_UINT16(data, 4U); // Destination RSI
|
||||||
|
m_srcLlId = __GET_UINT16(data, 7U); // Source RSI
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Internal helper to encode a SNDCP header. */
|
||||||
|
|
||||||
|
void KMMFrame::encodeHeader(uint8_t* data, bool outbound)
|
||||||
|
{
|
||||||
|
assert(data != nullptr);
|
||||||
|
|
||||||
|
data[0U] = m_messageId; // Message ID
|
||||||
|
__SET_UINT16B(m_messageLength, data, 2U); // Message Length
|
||||||
|
|
||||||
|
data[2U] = ((m_respKind & 0x03U) << 6U) + // Response Kind
|
||||||
|
((m_mfMessageNumber & 0x03U) << 4U) + // Message Number
|
||||||
|
((m_mfMac & 0x03U) << 2U) + // MAC
|
||||||
|
((!m_complete) ? 0x01U : 0x00U); // Done Flag
|
||||||
|
|
||||||
|
__SET_UINT16(m_dstLlId, data, 4U); // Destination RSI
|
||||||
|
__SET_UINT16(m_srcLlId, data, 7U); // Source RSI
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Internal helper to copy the the class. */
|
||||||
|
|
||||||
|
void KMMFrame::copy(const KMMFrame& data)
|
||||||
|
{
|
||||||
|
m_messageId = data.m_messageId;
|
||||||
|
m_messageLength = data.m_messageLength;
|
||||||
|
m_respKind = data.m_respKind;
|
||||||
|
m_complete = data.m_complete;
|
||||||
|
|
||||||
|
m_mfMessageNumber = data.m_mfMessageNumber;
|
||||||
|
m_mfMac = data.m_mfMac;
|
||||||
|
}
|
||||||
@ -0,0 +1,140 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Digital Voice Modem - Common Library
|
||||||
|
* GPLv2 Open Source. Use is subject to license terms.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup p25_kmm Key Management Message
|
||||||
|
* @brief Implementation for the data handling of the TIA-102.AACA Project 25 standard.
|
||||||
|
* @ingroup p25
|
||||||
|
*
|
||||||
|
* @file KMMFrame.h
|
||||||
|
* @ingroup p25_kmm
|
||||||
|
* @file KMMFrame.cpp
|
||||||
|
* @ingroup p25_kmm
|
||||||
|
*/
|
||||||
|
#if !defined(__P25_KMM__KMM_FRAME_H__)
|
||||||
|
#define __P25_KMM__KMM_FRAME_H__
|
||||||
|
|
||||||
|
#include "common/Defines.h"
|
||||||
|
#include "common/Utils.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace p25
|
||||||
|
{
|
||||||
|
namespace kmm
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Constants
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup p25_kmm
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
const uint32_t KMM_FRAME_LENGTH = 9U;
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Class Declaration
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a KMM frame packet header.
|
||||||
|
* @ingroup p25_kmm
|
||||||
|
*/
|
||||||
|
class HOST_SW_API KMMFrame {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Initializes a copy instance of the KMMFrame class.
|
||||||
|
* @param data Instance of KMMFrame to copy/
|
||||||
|
*/
|
||||||
|
KMMFrame(const KMMFrame& data);
|
||||||
|
/**
|
||||||
|
* @brief Initializes a new instance of the KMMFrame class.
|
||||||
|
*/
|
||||||
|
KMMFrame();
|
||||||
|
/**
|
||||||
|
* @brief Finalizes a instance of the KMMFrame class.
|
||||||
|
*/
|
||||||
|
~KMMFrame();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the byte length of this KMMFrame.
|
||||||
|
* @return uint32_t Length of KMMFrame.
|
||||||
|
*/
|
||||||
|
virtual uint32_t length() const { return KMM_FRAME_LENGTH; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decode a KMM frame.
|
||||||
|
* @param[in] data Buffer containing KMM frame data to decode.
|
||||||
|
* @returns bool True, if decoded, otherwise false.
|
||||||
|
*/
|
||||||
|
virtual bool decode(const uint8_t* data) = 0;
|
||||||
|
/**
|
||||||
|
* @brief Encode a KMM frame.
|
||||||
|
* @param[out] data Buffer to encode KMM frame data to.
|
||||||
|
*/
|
||||||
|
virtual void encode(uint8_t* data) = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Common Data
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROTECTED_PROPERTY(uint8_t, messageId, MessageId);
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROTECTED_PROPERTY(uint16_t, messageLength, MessageLength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROTECTED_PROPERTY(uint8_t, respKind, ResponseKind);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destination Logical link ID.
|
||||||
|
*/
|
||||||
|
__PROTECTED_PROPERTY(uint32_t, dstLlId, DstLLId);
|
||||||
|
/**
|
||||||
|
* @brief Source Logical link ID.
|
||||||
|
*/
|
||||||
|
__PROTECTED_PROPERTY(uint32_t, srcLlId, SrcLLId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROTECTED_PROPERTY(bool, complete, Complete);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint8_t m_mfMessageNumber;
|
||||||
|
uint8_t m_mfMac;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal helper to decode a KMM header.
|
||||||
|
* @param data Buffer containing KMM packet data to decode.
|
||||||
|
* @param outbound Flag indicating whether the packet is inbound or outbound.
|
||||||
|
* @returns bool True, if decoded, otherwise false.
|
||||||
|
*/
|
||||||
|
bool decodeHeader(const uint8_t* data, bool outbound = false);
|
||||||
|
/**
|
||||||
|
* @brief Internal helper to encode a KMM header.
|
||||||
|
* @param data Buffer to encode KMM packet data to.
|
||||||
|
* @param outbound Flag indicating whether the packet is inbound or outbound.
|
||||||
|
*/
|
||||||
|
void encodeHeader(uint8_t* data, bool outbound = false);
|
||||||
|
|
||||||
|
__PROTECTED_COPY(KMMFrame);
|
||||||
|
};
|
||||||
|
} // namespace kmm
|
||||||
|
} // namespace p25
|
||||||
|
|
||||||
|
#endif // __P25_KMM__KMM_FRAME_H__
|
||||||
@ -0,0 +1,171 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Digital Voice Modem - Common Library
|
||||||
|
* GPLv2 Open Source. Use is subject to license terms.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "Defines.h"
|
||||||
|
#include "p25/P25Defines.h"
|
||||||
|
#include "p25/kmm/KMMModifyKey.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
using namespace p25;
|
||||||
|
using namespace p25::defines;
|
||||||
|
using namespace p25::kmm;
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Public Class Members
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* Initializes a new instance of the KMMModifyKey class. */
|
||||||
|
|
||||||
|
KMMModifyKey::KMMModifyKey() : KMMFrame(),
|
||||||
|
m_decryptInfoFmt(KMM_DECRYPT_INSTRUCT_NONE),
|
||||||
|
m_algId(ALGO_UNENCRYPT),
|
||||||
|
m_kId(0U),
|
||||||
|
m_keysetItem(),
|
||||||
|
m_miSet(false),
|
||||||
|
m_mi(nullptr)
|
||||||
|
{
|
||||||
|
m_mi = new uint8_t[MI_LENGTH_BYTES];
|
||||||
|
::memset(m_mi, 0x00U, MI_LENGTH_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finalizes a instance of the KMMModifyKey class. */
|
||||||
|
|
||||||
|
KMMModifyKey::~KMMModifyKey()
|
||||||
|
{
|
||||||
|
if (m_mi != nullptr) {
|
||||||
|
delete[] m_mi;
|
||||||
|
m_mi = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets the byte length of this KMMFrame. */
|
||||||
|
|
||||||
|
uint32_t KMMModifyKey::length() const
|
||||||
|
{
|
||||||
|
uint32_t len = KMM_MODIFY_KEY_LENGTH;
|
||||||
|
if (m_miSet)
|
||||||
|
len += MI_LENGTH_BYTES;
|
||||||
|
len += m_keysetItem.length();
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode a KMM modify key. */
|
||||||
|
|
||||||
|
bool KMMModifyKey::decode(const uint8_t* data)
|
||||||
|
{
|
||||||
|
assert(data != nullptr);
|
||||||
|
|
||||||
|
KMMFrame::decodeHeader(data, false);
|
||||||
|
|
||||||
|
m_decryptInfoFmt = data[10U]; // Decryption Instruction Format
|
||||||
|
m_algId = data[11U]; // Algorithm ID
|
||||||
|
m_kId = data[12U]; // Key ID
|
||||||
|
|
||||||
|
uint16_t offset = 0U;
|
||||||
|
if (m_decryptInfoFmt == KMM_DECRYPT_INSTRUCT_MI) {
|
||||||
|
::memset(m_mi, 0x00U, MI_LENGTH_BYTES);
|
||||||
|
::memcpy(m_mi, data + 13U, MI_LENGTH_BYTES);
|
||||||
|
offset += 9U;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_keysetItem.keysetId(data[13U + offset]);
|
||||||
|
m_keysetItem.algId(data[14U + offset]);
|
||||||
|
m_keysetItem.keyLength(data[15U + offset]);
|
||||||
|
|
||||||
|
uint8_t keyCount = data[16U + offset];
|
||||||
|
for (uint8_t i = 0U; i < keyCount; i++) {
|
||||||
|
KeyItem* key = new KeyItem();
|
||||||
|
|
||||||
|
UInt8Array __keyPayload = std::make_unique<uint8_t[]>(m_keysetItem.keyLength());
|
||||||
|
uint8_t* keyPayload = __keyPayload.get();
|
||||||
|
|
||||||
|
uint8_t keyFormat = data[17U + offset];
|
||||||
|
uint8_t keyNameLen = keyFormat & 0x1FU;
|
||||||
|
|
||||||
|
key->keyFormat(keyFormat & 0xE0U);
|
||||||
|
key->sln(data[18U + offset]);
|
||||||
|
key->kId(data[19U + offset]);
|
||||||
|
|
||||||
|
::memcpy(keyPayload, data + (20U + offset), m_keysetItem.keyLength());
|
||||||
|
key->setKey(keyPayload, m_keysetItem.keyLength());
|
||||||
|
|
||||||
|
m_keysetItem.push_back(key);
|
||||||
|
|
||||||
|
offset += 5U + keyNameLen + m_keysetItem.keyLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encode a KMM modify key. */
|
||||||
|
|
||||||
|
void KMMModifyKey::encode(uint8_t* data)
|
||||||
|
{
|
||||||
|
assert(data != nullptr);
|
||||||
|
|
||||||
|
KMMFrame::encodeHeader(data, true);
|
||||||
|
|
||||||
|
if (!m_miSet && m_decryptInfoFmt == KMM_DECRYPT_INSTRUCT_MI) {
|
||||||
|
m_decryptInfoFmt = KMM_DECRYPT_INSTRUCT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[10U] = m_decryptInfoFmt; // Decryption Instruction Format
|
||||||
|
data[11U] = m_algId; // Algorithm ID
|
||||||
|
data[12U] = m_kId; // Key ID
|
||||||
|
|
||||||
|
uint16_t offset = 0U;
|
||||||
|
if (m_decryptInfoFmt == KMM_DECRYPT_INSTRUCT_MI) {
|
||||||
|
::memcpy(data + 13U, m_mi, MI_LENGTH_BYTES);
|
||||||
|
offset += 9U;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[13U + offset] = m_keysetItem.keysetId();
|
||||||
|
data[14U + offset] = m_keysetItem.algId();
|
||||||
|
data[15U + offset] = m_keysetItem.keyLength();
|
||||||
|
|
||||||
|
uint8_t keyCount = m_keysetItem.keys().size();
|
||||||
|
data[16U + offset] = keyCount;
|
||||||
|
for (auto key : m_keysetItem.keys()) {
|
||||||
|
uint8_t keyNameLen = key->keyFormat() & 0x1FU;
|
||||||
|
data[17U + offset] = key->keyFormat();
|
||||||
|
data[18U + offset] = key->sln();
|
||||||
|
data[19U + offset] = key->kId();
|
||||||
|
|
||||||
|
UInt8Array __keyPayload = std::make_unique<uint8_t[]>(m_keysetItem.keyLength());
|
||||||
|
uint8_t* keyPayload = __keyPayload.get();
|
||||||
|
key->getKey(keyPayload);
|
||||||
|
|
||||||
|
::memcpy(data + (20U + offset), keyPayload, m_keysetItem.keyLength());
|
||||||
|
|
||||||
|
offset += 5U + keyNameLen + m_keysetItem.keyLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Protected Class Members
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* Internal helper to copy the the class. */
|
||||||
|
|
||||||
|
void KMMModifyKey::copy(const KMMModifyKey& data)
|
||||||
|
{
|
||||||
|
m_decryptInfoFmt = data.m_decryptInfoFmt;
|
||||||
|
m_algId = data.m_algId;
|
||||||
|
m_kId = data.m_kId;
|
||||||
|
|
||||||
|
if (data.m_mi != nullptr) {
|
||||||
|
::memset(m_mi, 0x00U, MI_LENGTH_BYTES);
|
||||||
|
::memcpy(m_mi, data.m_mi, MI_LENGTH_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_keysetItem = data.m_keysetItem;
|
||||||
|
}
|
||||||
@ -0,0 +1,119 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Digital Voice Modem - Common Library
|
||||||
|
* GPLv2 Open Source. Use is subject to license terms.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file KMMModifyKey.h
|
||||||
|
* @ingroup p25_kmm
|
||||||
|
* @file KMMModifyKey.cpp
|
||||||
|
* @ingroup p25_kmm
|
||||||
|
*/
|
||||||
|
#if !defined(__P25_KMM__KMM_MODIFY_KEY_H__)
|
||||||
|
#define __P25_KMM__KMM_MODIFY_KEY_H__
|
||||||
|
|
||||||
|
#include "common/Defines.h"
|
||||||
|
#include "common/p25/kmm/KMMFrame.h"
|
||||||
|
#include "common/p25/kmm/KeysetItem.h"
|
||||||
|
#include "common/Utils.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace p25
|
||||||
|
{
|
||||||
|
namespace kmm
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Constants
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup p25_kmm
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
const uint32_t KMM_MODIFY_KEY_LENGTH = KMM_FRAME_LENGTH + 4U;
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Class Declaration
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class HOST_SW_API KMMModifyKey : public KMMFrame {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Initializes a new instance of the KMMModifyKey class.
|
||||||
|
*/
|
||||||
|
KMMModifyKey();
|
||||||
|
/**
|
||||||
|
* @brief Finalizes a instance of the KMMModifyKey class.
|
||||||
|
*/
|
||||||
|
~KMMModifyKey();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the byte length of this KMMFrame.
|
||||||
|
* @return uint32_t Length of KMMFrame.
|
||||||
|
*/
|
||||||
|
uint32_t length() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decode a KMM modify key packet.
|
||||||
|
* @param[in] data Buffer containing KMM packet data to decode.
|
||||||
|
* @returns bool True, if decoded, otherwise false.
|
||||||
|
*/
|
||||||
|
bool decode(const uint8_t* data);
|
||||||
|
/**
|
||||||
|
* @brief Encode a KMM modify key packet.
|
||||||
|
* @param[out] data Buffer to encode KMM packet data to.
|
||||||
|
*/
|
||||||
|
void encode(uint8_t* data);
|
||||||
|
|
||||||
|
/** @name Encryption data */
|
||||||
|
/**
|
||||||
|
* @brief Sets the encryption message indicator.
|
||||||
|
* @param[in] mi Buffer containing the 9-byte Message Indicator.
|
||||||
|
*/
|
||||||
|
void setMI(const uint8_t* mi);
|
||||||
|
/**
|
||||||
|
* @brief Gets the encryption message indicator.
|
||||||
|
* @param[out] mi Buffer containing the 9-byte Message Indicator.
|
||||||
|
*/
|
||||||
|
void getMI(uint8_t* mi) const;
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROPERTY(uint8_t, decryptInfoFmt, DecryptInfoFmt);
|
||||||
|
/**
|
||||||
|
* @brief Encryption algorithm ID.
|
||||||
|
*/
|
||||||
|
__PROPERTY(uint8_t, algId, AlgId);
|
||||||
|
/**
|
||||||
|
* @brief Encryption key ID.
|
||||||
|
*/
|
||||||
|
__PROPERTY(uint32_t, kId, KId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROPERTY(KeysetItem, keysetItem, KeysetItem);
|
||||||
|
|
||||||
|
__COPY(KMMModifyKey);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Encryption data
|
||||||
|
bool m_miSet;
|
||||||
|
uint8_t* m_mi;
|
||||||
|
};
|
||||||
|
} // namespace kmm
|
||||||
|
} // namespace p25
|
||||||
|
|
||||||
|
#endif // __P25_KMM__KMM_MODIFY_KEY_H__
|
||||||
@ -0,0 +1,228 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Digital Voice Modem - Common Library
|
||||||
|
* GPLv2 Open Source. Use is subject to license terms.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file KeysetItem.h
|
||||||
|
* @ingroup p25_kmm
|
||||||
|
*/
|
||||||
|
#if !defined(__P25_KMM__KEYSET_ITEM_H__)
|
||||||
|
#define __P25_KMM__KEYSET_ITEM_H__
|
||||||
|
|
||||||
|
#include "common/Defines.h"
|
||||||
|
#include "common/Utils.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace p25
|
||||||
|
{
|
||||||
|
namespace kmm
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Class Declaration
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a key set item within a KMM frame packet.
|
||||||
|
* @ingroup p25_kmm
|
||||||
|
*/
|
||||||
|
class HOST_SW_API KeyItem {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Initializes a new instance of the KeyItem class.
|
||||||
|
*/
|
||||||
|
KeyItem() :
|
||||||
|
m_keyFormat(0x80U/*P25DEF::KEY_FORMAT_TEK*/),
|
||||||
|
m_sln(0U),
|
||||||
|
m_kId(0U),
|
||||||
|
m_keyLength(0U),
|
||||||
|
m_keyMaterial(nullptr)
|
||||||
|
{
|
||||||
|
/* stub */
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Finalizes a instance of the KeyItem class.
|
||||||
|
*/
|
||||||
|
~KeyItem()
|
||||||
|
{
|
||||||
|
if (m_keyMaterial != nullptr) {
|
||||||
|
delete[] m_keyMaterial;
|
||||||
|
m_keyMaterial = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equals operator. Copies this KeyItem to another KeyItem.
|
||||||
|
* @param data Instance of KeyItem to copy.
|
||||||
|
*/
|
||||||
|
virtual KeyItem& operator= (const KeyItem& data)
|
||||||
|
{
|
||||||
|
if (this != &data) {
|
||||||
|
m_keyFormat = data.m_keyFormat;
|
||||||
|
m_sln = data.m_sln;
|
||||||
|
m_kId = data.m_kId;
|
||||||
|
|
||||||
|
if (data.m_keyLength > 0U) {
|
||||||
|
if (m_keyMaterial != nullptr) {
|
||||||
|
delete[] m_keyMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_keyMaterial = new uint8_t[data.m_keyLength];
|
||||||
|
m_keyLength = data.m_keyLength;
|
||||||
|
::memcpy(m_keyMaterial, data.m_keyMaterial, data.m_keyLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the key material.
|
||||||
|
* @param key
|
||||||
|
* @param keyLength
|
||||||
|
*/
|
||||||
|
void setKey(const uint8_t* key, uint32_t keyLength)
|
||||||
|
{
|
||||||
|
assert(key != nullptr);
|
||||||
|
m_keyLength = keyLength;
|
||||||
|
::memcpy(m_keyMaterial, key, keyLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the key material.
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
void getKey(uint8_t* key) const
|
||||||
|
{
|
||||||
|
assert(key != nullptr);
|
||||||
|
::memcpy(key, m_keyMaterial, m_keyLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROPERTY_PLAIN(uint8_t, keyFormat);
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROPERTY_PLAIN(uint16_t, sln);
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROPERTY_PLAIN(uint16_t, kId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_keyLength;
|
||||||
|
uint8_t* m_keyMaterial;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Class Declaration
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a key set item within a KMM frame packet.
|
||||||
|
* @ingroup p25_kmm
|
||||||
|
*/
|
||||||
|
class HOST_SW_API KeysetItem {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Initializes a new instance of the KeysetItem class.
|
||||||
|
*/
|
||||||
|
KeysetItem() :
|
||||||
|
m_keysetId(0U),
|
||||||
|
m_algId(0U),
|
||||||
|
m_keyLength(0U),
|
||||||
|
m_keys()
|
||||||
|
{
|
||||||
|
/* stub */
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Finalizes a instance of the KeysetItem class.
|
||||||
|
*/
|
||||||
|
~KeysetItem()
|
||||||
|
{
|
||||||
|
for (auto key : m_keys) {
|
||||||
|
delete key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equals operator. Copies this KeysetItem to another KeysetItem.
|
||||||
|
* @param data Instance of KeysetItem to copy.
|
||||||
|
*/
|
||||||
|
virtual KeysetItem& operator= (const KeysetItem& data)
|
||||||
|
{
|
||||||
|
if (this != &data) {
|
||||||
|
m_keysetId = data.m_keysetId;
|
||||||
|
m_algId = data.m_algId;
|
||||||
|
m_keyLength = data.m_keyLength;
|
||||||
|
|
||||||
|
for (auto key : m_keys) {
|
||||||
|
delete key;
|
||||||
|
}
|
||||||
|
m_keys.clear();
|
||||||
|
|
||||||
|
for (auto key : data.m_keys) {
|
||||||
|
KeyItem* copy = key;
|
||||||
|
m_keys.push_back(copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the byte length of this keyset item.
|
||||||
|
* @return uint32_t Length of keyset item.
|
||||||
|
*/
|
||||||
|
uint32_t length() const
|
||||||
|
{
|
||||||
|
uint32_t len = 4U;
|
||||||
|
|
||||||
|
uint32_t keyItemLength = m_keys.size() * 5U;
|
||||||
|
uint32_t combinedKeyLength = m_keys.size() * m_keyLength;
|
||||||
|
len += keyItemLength + combinedKeyLength;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a key to the key list.
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
void push_back(KeyItem* key)
|
||||||
|
{
|
||||||
|
m_keys.push_back(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROPERTY_PLAIN(uint8_t, keysetId);
|
||||||
|
/**
|
||||||
|
* @brief Encryption algorithm ID.
|
||||||
|
*/
|
||||||
|
__PROPERTY_PLAIN(uint8_t, algId);
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
__PROPERTY_PLAIN(uint8_t, keyLength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief List of keys.
|
||||||
|
*/
|
||||||
|
__PROPERTY_PLAIN(std::vector<KeyItem*>, keys);
|
||||||
|
};
|
||||||
|
} // namespace kmm
|
||||||
|
} // namespace p25
|
||||||
|
|
||||||
|
#endif // __P25_KMM__KEYSET_ITEM_H__
|
||||||
Loading…
Reference in new issue