?? mac_security.c
字號:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC2430 INTEGRATED 802.15.4 MAC AND PHY *
* *** + + *** MAC Security Support *
* *** +++ *** *
* *** *** *
* ************ *
* ********** *
* *
*******************************************************************************************************
* CONFIDENTIAL *
* The use of this file is restricted by the signed MAC software license agreement. *
* *
* Copyright Chipcon AS, 2005 *
*******************************************************************************************************
* This file implements the MAC security support functions, used internally in the MAC sublayer *
*******************************************************************************************************/
#include <mac_headers.h>
#if (MAC_OPT_SECURITY)
//-------------------------------------------------------------------------------------------------------
// BYTE msecFindSecurityMaterial(BOOL isTX, BYTE addrMode, WORD panId, ADDRESS *pAddr, ...
//
// DESCRIPTION:
// Support function for selecting the correct security material.
// First search the ACL, then default security. If neither is available for this frame,
// return with the value UNAVAILABLE_KEY
// Used ONLY for outgoing packets (incoming packets handled in receive routine)
//
// PARAMETERS:
//
// RETURN VALUE:
// BYTE
// UNAVAILABLE_KEY if no key is available
// securitySuite (0 - 7) otherwise
//-------------------------------------------------------------------------------------------------------
ROOT void msecFindTxSecurityMaterial(MAC_TX_PACKET *pPacket, BOOL securityEnable, BYTE addrMode, WORD panId, ADDRESS *pAddr) {
BYTE n;
BOOL aclFound = FALSE;
BYTE securitySuite;
SECURITY_MATERIAL *pSecurityMaterial;
if (securityEnable) {
securitySuite = UNAVAILABLE_KEY;
pSecurityMaterial = NULL;
// Search through ACL for extended addresses
for (n=0; n<mpib.macACLEntryDescriptorSetSize; n++) {
if (addrMode == AM_EXTENDED_64) {
if (msupCompareAddress(&pAddr->Extended, &mpib.ppMacACLEntryDescriptorSet[n]->extendedAddress)) {
aclFound = TRUE;
break;
}
} else if ((addrMode == AM_SHORT_16) && (panId == mpib.ppMacACLEntryDescriptorSet[n]->panId)) {
if (pAddr->Short == mpib.ppMacACLEntryDescriptorSet[n]->shortAddress) {
aclFound = TRUE;
break;
}
}
}
if (aclFound) {
pSecurityMaterial = &mpib.ppMacACLEntryDescriptorSet[n]->securityMaterial;
securitySuite = mpib.ppMacACLEntryDescriptorSet[n]->securitySuite;
// Is default security available ?
// Default security can only be used in TX (when the 64 bit destination address is equal to
// aExtendedAddress) or in RX when the source address mode is extended.
} else if ((mpib.macSecurityMode == MAC_SECURED_MODE) && (mpib.macDefaultSecurity) && (securityEnable)) {
// Default security enabled
pSecurityMaterial = mpib.pMacDefaultSecurityMaterial;
securitySuite = mpib.macDefaultSecuritySuite;
}
pPacket->pSecurityMaterial = pSecurityMaterial;
pPacket->securitySuite = securitySuite;
} else {
// Security not enabled, no key is necessary
pPacket->securitySuite = MAC_SECURITY_NONE;
}
} // msecFindSecurityMaterial
//-------------------------------------------------------------------------------------------------------
// void msecDecodeSecuritySuite(MSEC_SETUP_INFO *pMSI, BYTE securityMode)
//
// DESCRIPTION:
// Decodes the given security mode, and sets up the MSEC_SETUP_INFO struct with the necessary
// information.
//
// PARAMETERS:
// MSEC_SETUP_INFO *pMSI
// Pointer to the MSEC_SETUP_INFO struct used for RX or TX
//
// BYTE securityMode
// MAC security mode
// (MAC_SECURITY_NONE | MAC_SECURITY_AES_CTR | MAC_SECURITY_AES_CCM128 |
// MAC_SECURITY_AES_CCM64 | MAC_SECURITY_AES_CCM32 | MAC_SECURITY_AES_CBC_MAC128 |
// MAC_SECURITY_AES_CBC_MAC64 | MAC_SECURITY_AES_CBC_MAC32)
//
// RETURN VALUE:
// void
//-------------------------------------------------------------------------------------------------------
ROOT void msecDecodeSecuritySuite(MSEC_SETUP_INFO *pMSI, BYTE securitySuite) {
// Which security mode is used?
switch (securitySuite) {
case MAC_SECURITY_AES_CCM128:
pMSI->secFlags2420 = MAC_CC2420_CCM_FLAGS;
pMSI->secMode2420 = CC2420_SECCTRL0_CCM | (7 << CC2420_SECCTRL0_SEC_M_IDX);
pMSI->micLength = 16;
break;
case MAC_SECURITY_AES_CCM64:
pMSI->secFlags2420 = MAC_CC2420_CCM_FLAGS;
pMSI->secMode2420 = CC2420_SECCTRL0_CCM | (3 << CC2420_SECCTRL0_SEC_M_IDX);
pMSI->micLength = 8;
break;
case MAC_SECURITY_AES_CCM32:
pMSI->secFlags2420 = MAC_CC2420_CCM_FLAGS;
pMSI->secMode2420 = CC2420_SECCTRL0_CCM | (1 << CC2420_SECCTRL0_SEC_M_IDX);
pMSI->micLength = 4;
break;
case MAC_SECURITY_AES_CBC_MAC128:
pMSI->secFlags2420 = 0;
pMSI->secMode2420 = CC2420_SECCTRL0_CBC_MAC | (7 << CC2420_SECCTRL0_SEC_M_IDX);
pMSI->micLength = 16;
pMSI->clearTextLength = 0;
break;
case MAC_SECURITY_AES_CBC_MAC64:
pMSI->secFlags2420 = 0;
pMSI->secMode2420 = CC2420_SECCTRL0_CBC_MAC | (3 << CC2420_SECCTRL0_SEC_M_IDX);
pMSI->micLength = 8;
pMSI->clearTextLength = 0;
break;
case MAC_SECURITY_AES_CBC_MAC32:
pMSI->secFlags2420 = 0;
pMSI->secMode2420 = CC2420_SECCTRL0_CBC_MAC | (1 << CC2420_SECCTRL0_SEC_M_IDX);
pMSI->micLength = 4;
pMSI->clearTextLength = 0;
break;
case MAC_SECURITY_AES_CTR:
pMSI->secFlags2420 = MAC_CC2420_CTR_FLAGS;
pMSI->secMode2420 = CC2420_SECCTRL0_CTR;
pMSI->micLength = 0;
break;
default:
pMSI->secFlags2420 = 0;
pMSI->secMode2420 = 0;
pMSI->micLength = 0;
break;
}
} // msecDecodeSecuritySuite
//-------------------------------------------------------------------------------------------------------
// void msecSetupCC2420KeyAndNonce(BOOL isTx, MSEC_SETUP_INFO *pMSI, KEY pKey, BYTE* pCounters)
//
// DESCRIPTION:
// Sets up CC2420 key and (optionally) nonce in CC2420 before RX / TX security operations
//
// PARAMETERS:
// BOOL isTx
// TRUE for TX (FALSE for RX)
// MSEC_SETUP_INFO *pMSI,
// Pointer to the security setup struct in use
// KEY pKey,
// Pointer to the 16-byte (128 bit) key
// BYTE* pCounters
// Pointer to the Frame Counter (4 bytes) and Key Sequence Counter (1 byte)
//-------------------------------------------------------------------------------------------------------
ROOT void msecSetupCC2420KeyAndNonce(BOOL isTx, MSEC_SETUP_INFO *pMSI, KEY pKey, BYTE* pCounters) {
UINT16 keyAddressCC2420;
UINT8 n;
ADDRESS* pExtendedAddress;
// Write 128-bit key to CC2420 RAM, using KEY0 for TX and KEY1 for RX
if (isTx) {
keyAddressCC2420 = CC2420RAM_KEY0;
} else {
keyAddressCC2420 = CC2420RAM_KEY1;
}
// Write key to CC2420 RAM
msupWriteRam(pKey, keyAddressCC2420, 16, TRUE);
// Write nonce/counter to CC2420 RAM, unless we are in CBC-MAC mode where the nonce/counter value is not used.
if (pMSI->secFlags2420) {
DISABLE_GLOBAL_INT();
SPI_ENABLE();
// RAM address
if (isTx) {
FASTSPI_TX(0x80 | (CC2420RAM_TXNONCE & 0x7F));
FASTSPI_TX((CC2420RAM_TXNONCE >> 1) & 0xC0);
} else {
FASTSPI_TX(0x80 | (CC2420RAM_RXNONCE & 0x7F));
FASTSPI_TX((CC2420RAM_RXNONCE >> 1) & 0xC0);
}
// The 2-byte counter is initialized as 0 in counter mode, 1 in CCM
FASTSPI_TX(pMSI->secFlags2420 == MAC_CC2420_CCM_FLAGS);
FASTSPI_TX(0);
// Key sequence counter (1 byte) and frame counter (4 bytes)
n = 5;
pCounters += 4;
do {
FASTSPI_TX(*(pCounters--));
} while (--n);
if (isTx) {
pExtendedAddress = &aExtendedAddress;
} else {
pExtendedAddress = mrxSecurityInfo.pExtendedAddress;
}
// Extended source address
FASTSPI_TX_MANY((BYTE*) pExtendedAddress, 8);
// Flag byte
FASTSPI_TX(pMSI->secFlags2420);
SPI_DISABLE();
ENABLE_GLOBAL_INT();
}
} // msupSetupCC2420KeyAndNonce
//-------------------------------------------------------------------------------------------------------
// void msecSetupCC2420Regs(MSEC_SETUP_INFO *pMSI)
//
// DESCRIPTION:
// Sets up CC2420 security registers according to the security information struct
//
// PARAMETERS:
// MSEC_SETUP_INFO *pMSI,
// Pointer to the security setup struct in use
//-------------------------------------------------------------------------------------------------------
ROOT void msecSetupCC2420Regs(MSEC_SETUP_INFO *pMSI) {
BYTE cleartextLength;
DISABLE_GLOBAL_INT();
// Configure CC2420 hardware security registers
if (pMSI->secMode2420) {
if (pMSI->secFlags2420) {
cleartextLength = pMSI->clearTextLength;
FASTSPI_SETREG(CC2420_SECCTRL1, ((cleartextLength) << 8) | (cleartextLength));
} else {
// l(a) = 0 for CBC-MAC
FASTSPI_SETREG(CC2420_SECCTRL1, 0);
}
}
// Configure CC2420 hardware security registers
FASTSPI_SETREG(CC2420_SECCTRL0, CC2420_SECCTRL0_RXFIFO_PROTECTION | CC2420_SECCTRL0_SEC_CBC_HEAD | CC2420_SECCTRL0_TXKEYSEL0 | CC2420_SECCTRL0_RXKEYSEL1 | ((WORD) pMSI->secMode2420));
ENABLE_GLOBAL_INT();
} // msecSetupCC2420Regs
//-------------------------------------------------------------------------------------------------------
// UINT8 msecProcessSecurityCounters(MAC_TX_PACKET *pPacket, BYTE *pPayload)
//
// DESCRIPTION:
// Inserts frame counter (4 bytes) and key sequence counter (1 byte) into an outgoing frame,
// if the security suite is CTR or CCM.
// Counters are inserted from the pointer pPayload, and frame counter is incremented.
// pPacket->securitySuite is set to FAILED_SECURITY_CHECK if frame counter overflows.
//
// PARAMETERS:
// MAC_TX_PACKET *pPacket
// Pointer to the outgoing packet in which security is to be inserted
// BYTE *pPayload
// Byte pointer to the location where the pointers should be inserted
//
// RETURN VALUE
// UINT8
// Number of bytes (0 or 5) inserted into the frame
//-------------------------------------------------------------------------------------------------------
ROOT UINT8 msecProcessSecurityCounters(MAC_TX_PACKET *pPacket, BYTE *pPayload) {
BYTE *pSource;
SECURITY_MATERIAL *pSecurityMaterial;
// Only CTR mode and CCM mode have the security flags set,
// and these modes require frame counter / key sequence counter
if (pPacket->securitySetup.secFlags2420) {
// Set up pointer to security material for faster access
pSecurityMaterial = pPacket->pSecurityMaterial;
// Copy the frame counter / key sequence counter into the frame
// with the MOST significant byte being transmitted FIRST
pSource = (BYTE*) &pSecurityMaterial->frameCounter + 3;
*(pPayload++) = *(pSource--);
*(pPayload++) = *(pSource--);
*(pPayload++) = *(pSource--);
*(pPayload++) = *(pSource);
*(pPayload++) = pSecurityMaterial->keySequenceCounter;
if (pSecurityMaterial->frameCounter == 0xFFFF) {
// Frame counter cannot be incremented
pPacket->securitySuite = FAILED_SECURITY_CHECK;
} else {
// Increment frame counter
pSecurityMaterial->frameCounter++;
}
pPacket->securitySetup.clearTextLength += 5;
return 5; // Frame Counter (4 bytes) and Key Sequence Counter (1 byte)
// No frame counter / key sequence counter
} else {
return 0;
}
}
#endif // MAC_OPT_SECURITY
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -