⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac_security.c

📁 zigbee location examples
💻 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 + -