[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:
Shu Chen
2018-06-21 08:45:19 -07:00
committed by Jonathan Hui
parent 4241b87800
commit 0616997957
4 changed files with 80 additions and 29 deletions
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+16
View File
@@ -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.
*