mirror of
https://github.com/espressif/openthread.git
synced 2026-09-02 07:10:08 +00:00
[mac] separate aes ccm process from ProcessTransmitSecurity() method (#2810)
Create a new ProcessTransmitAesCcm() method, which is safe to be called in interrupt context.
This commit is contained in:
@@ -109,6 +109,7 @@ typedef struct otRadioFrame
|
||||
uint8_t mMaxTxAttempts; ///< Max number of transmit attempts for an outbound frame.
|
||||
bool mIsARetx : 1; ///< Set to true if this frame is a retransmission. Should be ignored by radio driver.
|
||||
bool mIsCcaEnabled : 1; ///< Set to true if CCA must be enabled for this packet. False otherwise.
|
||||
const uint8_t *mAesKey; ///< The key used for frame encryption and authentication (AES CCM).
|
||||
} mTxInfo;
|
||||
|
||||
struct
|
||||
|
||||
+35
-27
@@ -877,18 +877,36 @@ void Mac::SendBeacon(Frame &aFrame)
|
||||
LogBeacon("Sending", *beaconPayload);
|
||||
}
|
||||
|
||||
void Mac::ProcessTransmitSecurity(Frame &aFrame)
|
||||
void Mac::ProcessTransmitAesCcm(Frame &aFrame, const ExtAddress *aExtAddress)
|
||||
{
|
||||
KeyManager & keyManager = GetNetif().GetKeyManager();
|
||||
uint32_t frameCounter = 0;
|
||||
uint8_t securityLevel;
|
||||
uint32_t frameCounter = 0;
|
||||
uint8_t securityLevel;
|
||||
uint8_t nonce[kNonceSize];
|
||||
uint8_t tagLength;
|
||||
Crypto::AesCcm aesCcm;
|
||||
otError error;
|
||||
|
||||
aFrame.GetSecurityLevel(securityLevel);
|
||||
aFrame.GetFrameCounter(frameCounter);
|
||||
|
||||
GenerateNonce(*aExtAddress, frameCounter, securityLevel, nonce);
|
||||
|
||||
aesCcm.SetKey(aFrame.GetAesKey(), 16);
|
||||
tagLength = aFrame.GetFooterLength() - Frame::kFcsSize;
|
||||
|
||||
error = aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce));
|
||||
assert(error == OT_ERROR_NONE);
|
||||
|
||||
aesCcm.Header(aFrame.GetHeader(), aFrame.GetHeaderLength());
|
||||
aesCcm.Payload(aFrame.GetPayload(), aFrame.GetPayload(), aFrame.GetPayloadLength(), true);
|
||||
aesCcm.Finalize(aFrame.GetFooter(), &tagLength);
|
||||
}
|
||||
|
||||
void Mac::ProcessTransmitSecurity(Frame &aFrame, bool aProcessAesCcm)
|
||||
{
|
||||
KeyManager & keyManager = GetNetif().GetKeyManager();
|
||||
uint8_t keyIdMode;
|
||||
uint8_t nonce[kNonceSize];
|
||||
uint8_t tagLength;
|
||||
Crypto::AesCcm aesCcm;
|
||||
const uint8_t * key = NULL;
|
||||
const ExtAddress *extAddress = NULL;
|
||||
otError error;
|
||||
|
||||
if (aFrame.GetSecurityEnabled() == false)
|
||||
{
|
||||
@@ -900,7 +918,7 @@ void Mac::ProcessTransmitSecurity(Frame &aFrame)
|
||||
switch (keyIdMode)
|
||||
{
|
||||
case Frame::kKeyIdMode0:
|
||||
key = keyManager.GetKek();
|
||||
aFrame.SetAesKey(keyManager.GetKek());
|
||||
extAddress = &mExtAddress;
|
||||
|
||||
if (!aFrame.IsARetransmission())
|
||||
@@ -912,7 +930,7 @@ void Mac::ProcessTransmitSecurity(Frame &aFrame)
|
||||
break;
|
||||
|
||||
case Frame::kKeyIdMode1:
|
||||
key = keyManager.GetCurrentMacKey();
|
||||
aFrame.SetAesKey(keyManager.GetCurrentMacKey());
|
||||
extAddress = &mExtAddress;
|
||||
|
||||
// If the frame is marked as a retransmission, the `Mac::Sender` which
|
||||
@@ -933,7 +951,7 @@ void Mac::ProcessTransmitSecurity(Frame &aFrame)
|
||||
case Frame::kKeyIdMode2:
|
||||
{
|
||||
const uint8_t keySource[] = {0xff, 0xff, 0xff, 0xff};
|
||||
key = sMode2Key;
|
||||
aFrame.SetAesKey(sMode2Key);
|
||||
mKeyIdMode2FrameCounter++;
|
||||
aFrame.SetFrameCounter(mKeyIdMode2FrameCounter);
|
||||
aFrame.SetKeySource(keySource);
|
||||
@@ -947,20 +965,10 @@ void Mac::ProcessTransmitSecurity(Frame &aFrame)
|
||||
break;
|
||||
}
|
||||
|
||||
aFrame.GetSecurityLevel(securityLevel);
|
||||
aFrame.GetFrameCounter(frameCounter);
|
||||
|
||||
GenerateNonce(*extAddress, frameCounter, securityLevel, nonce);
|
||||
|
||||
aesCcm.SetKey(key, 16);
|
||||
tagLength = aFrame.GetFooterLength() - Frame::kFcsSize;
|
||||
|
||||
error = aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce));
|
||||
assert(error == OT_ERROR_NONE);
|
||||
|
||||
aesCcm.Header(aFrame.GetHeader(), aFrame.GetHeaderLength());
|
||||
aesCcm.Payload(aFrame.GetPayload(), aFrame.GetPayload(), aFrame.GetPayloadLength(), true);
|
||||
aesCcm.Finalize(aFrame.GetFooter(), &tagLength);
|
||||
if (aProcessAesCcm)
|
||||
{
|
||||
ProcessTransmitAesCcm(aFrame, extAddress);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
@@ -1135,7 +1143,7 @@ void Mac::BeginTransmit(void)
|
||||
if (applyTransmitSecurity)
|
||||
{
|
||||
// Security Processing
|
||||
ProcessTransmitSecurity(sendFrame);
|
||||
ProcessTransmitSecurity(sendFrame, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+28
-2
@@ -876,6 +876,16 @@ public:
|
||||
*/
|
||||
bool IsEnabled(void) { return mEnabled; }
|
||||
|
||||
/**
|
||||
* This method performs AES CCM on the frame which is going to be sent.
|
||||
*
|
||||
* @param[in] aFrame A reference to the MAC frame buffer that is going to be sent.
|
||||
* @param[in] aExtAddress A pointer to the extended address, which will be used to generate nonce
|
||||
* for AES CCM computation.
|
||||
*
|
||||
*/
|
||||
static void ProcessTransmitAesCcm(Frame &aFrame, const ExtAddress *aExtAddress);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -908,8 +918,24 @@ private:
|
||||
kOperationTransmitOutOfBandFrame,
|
||||
};
|
||||
|
||||
void GenerateNonce(const ExtAddress &aAddress, uint32_t aFrameCounter, uint8_t aSecurityLevel, uint8_t *aNonce);
|
||||
void ProcessTransmitSecurity(Frame &aFrame);
|
||||
/**
|
||||
* This method processes transmit security on the frame which is going to be sent.
|
||||
*
|
||||
* This method prepares the frame, fills Mac auxiliary header, and perform AES CCM immediately in most cases
|
||||
* (depends on @p aProcessAesCcm). If aProcessAesCcm is False, it probably means that some content in the frame
|
||||
* will be updated just before transmission, so AES CCM will be performed after that (before transmission).
|
||||
*
|
||||
* @param[in] aFrame A reference to the MAC frame buffer which is going to be sent.
|
||||
* @param[in] aProcessAesCcm TRUE to perform AES CCM immediately, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
void ProcessTransmitSecurity(Frame &aFrame, bool aProcessAesCcm);
|
||||
|
||||
static void GenerateNonce(const ExtAddress &aAddress,
|
||||
uint32_t aFrameCounter,
|
||||
uint8_t aSecurityLevel,
|
||||
uint8_t * aNonce);
|
||||
|
||||
otError ProcessReceiveSecurity(Frame &aFrame, const Address &aSrcAddr, Neighbor *aNeighbor);
|
||||
void UpdateIdleMode(void);
|
||||
void StartOperation(Operation aOperation);
|
||||
|
||||
@@ -934,6 +934,22 @@ public:
|
||||
*/
|
||||
void SetIsCcaEnabled(bool aIsCcaEnabled) { mInfo.mTxInfo.mIsCcaEnabled = aIsCcaEnabled; }
|
||||
|
||||
/**
|
||||
* This method returns the key used for frame encryption and authentication (AES CCM).
|
||||
*
|
||||
* @returns The pointer to the key.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetAesKey(void) const { return mInfo.mTxInfo.mAesKey; }
|
||||
|
||||
/**
|
||||
* This method sets the key used for frame encryption and authentication (AES CCM).
|
||||
*
|
||||
* @param[in] aAesKey The pointer to the key.
|
||||
*
|
||||
*/
|
||||
void SetAesKey(const uint8_t *aAesKey) { mInfo.mTxInfo.mAesKey = aAesKey; }
|
||||
|
||||
/**
|
||||
* This method returns the IEEE 802.15.4 PSDU length.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user