Hello,
i'm trying to implement wireless security into my project based on JN-AN-1180-JN516x-802-15-4-Home-Sensor-Demo.
However i don't want to use different keys based on short addresses. I'd like to avoid a handshake/association. the count of senders and receivers will be fixed. so no handshake is needed.
when sending data, i get an mlme event "MAC_MLME_IND_COMM_STATUS" on receiver side with "MAC_ENUM_FAILED_SECURITY_CHECK"
I modified the code taken from the demo to the following (It's used for both, sender and receiver):
Why does the decryption fail? The Keys are fixed and the same for sender and receiver.
#if (SECURITY_ENABLED)
#define FRAME_TYPE_DATA (1)
#define TOTAL_SEC_ENTRIES (1)
#define TOTAL_SECURITY_KEYS (1)
#define TOTAL_KEY_USAGE_ENTRIES (1)
#define TOTAL_LEVEL_DESCRIPTORS (1)
PRIVATE MAC_KeyDescriptor_s asKeyDescriptor[TOTAL_SECURITY_KEYS];
PRIVATE MAC_KeyIdLookupDescriptor_s asKeyIdLookupDescriptor[TOTAL_SECURITY_KEYS];
PRIVATE MAC_KeyUsageDescriptor_s asKeyUsageNwk[TOTAL_KEY_USAGE_ENTRIES];
PRIVATE MAC_DeviceDescriptor_s asDeviceDescriptor[TOTAL_SEC_ENTRIES];
PRIVATE MAC_KeyDeviceDescriptor_s asKeyDeviceList[TOTAL_SEC_ENTRIES];
PRIVATE MAC_SecurityLevelDescriptor_s asSecurityLevelDescriptor[TOTAL_LEVEL_DESCRIPTORS];
PRIVATE const uint8 au8DefaultKeySource[8] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 };
#endif
#if (SECURITY_ENABLED)
asSecurityLevelDescriptor[0].u8FrameType = FRAME_TYPE_DATA;
asSecurityLevelDescriptor[0].u8MinimumSecurity = 5;
asSecurityLevelDescriptor[0].bOverideSecurityMinimum = FALSE;
/* Key Usage Descriptor list */
asKeyUsageNwk[0].u8FrameType = FRAME_TYPE_DATA;
/* Set up Key ID Lookup table. All key lookups are configured as the
default key source plus a byte for a unique index (to be determined
after association); 9 bytes in total. The lookup data size is set as
1, which means 9(!) */
memcpy(asKeyIdLookupDescriptor[0].au8LookupData, au8DefaultKeySource, 8);
asKeyIdLookupDescriptor[0].au8LookupData[8] = 0; /* Key index */
asKeyIdLookupDescriptor[0].u8LookupDataSize = MAC_SECURITY_KEYID_LENGTH_MODE_1;
/* Key Device Descriptor. Note that as u32DeviceDescriptorHandle is
index into the asDeviceDescriptor array */
asKeyDeviceList[0].u32DeviceDescriptorHandle = 0;
asKeyDeviceList[0].bUniqueDevice = FALSE;
asKeyDeviceList[0].bBlacklisted = FALSE;
/* Key descriptors: for each key, Device list (Key Device Descriptor)
is a list of one, unique to the key. Same for the Key ID Lookup
Descriptor. All keys share the same Key Usage Descriptor
(list of frame types). Each key is unique, but in this example the
value is based on the key number for simplicity */
asKeyDescriptor[0].psKeyDeviceList = &asKeyDeviceList[0];
asKeyDescriptor[0].u8KeyDeviceListEntries = 1;
asKeyDescriptor[0].psKeyIdLookupDescriptor = &asKeyIdLookupDescriptor[0];
asKeyDescriptor[0].u8KeyIdLookupEntries = 1;
asKeyDescriptor[0].psKeyUsageList = asKeyUsageNwk;
asKeyDescriptor[0].u8KeyUsageListEntries = TOTAL_KEY_USAGE_ENTRIES;
asKeyDescriptor[0].au32SymmetricKey[0] = 0x01020304;
asKeyDescriptor[0].au32SymmetricKey[1] = 0x05060708;
asKeyDescriptor[0].au32SymmetricKey[2] = 0x090a0b0c;
asKeyDescriptor[0].au32SymmetricKey[3] = 0x0d0e0f00;
/* Device Descriptor table is mostly concerned with addresses. These
will be filled in properly when each device joins */
#if defined(RECEIVER)
asDeviceDescriptor[0].u16PanId = PAN_ID;
asDeviceDescriptor[0].u16Short = ADDR_SENDER;
asDeviceDescriptor[0].u32FrameCounter = 0;
asDeviceDescriptor[0].bExempt = FALSE;
#elif defined(SENDER)
asDeviceDescriptor[0].u16PanId = PAN_ID;
asDeviceDescriptor[0].u16Short = ADDR_RECEIVER;
asDeviceDescriptor[0].u32FrameCounter = 0;
asDeviceDescriptor[0].bExempt = FALSE;
#endif
/* Configure the MAC... enable security... */
vAppApiSetSecurityMode(MAC_SECURITY_2006);
s_psMacPib->bMacSecurityEnabled = TRUE;
/* ... set the default lookup key (same as the value in the Key ID Lookup
Descriptors) ... */
memcpy(s_psMacPib->au8MacDefaultKeySource, au8DefaultKeySource, 8);
/* ... set the Key Descriptor table... */
s_psMacPib->psMacKeyTable = asKeyDescriptor;
s_psMacPib->u8MacKeyTableEntries = TOTAL_SECURITY_KEYS;
/* ... set the Security Level Descriptor table... */
s_psMacPib->psMacSecurityLevelTable = asSecurityLevelDescriptor;
s_psMacPib->u8MacSecuirtyLevelTableEntries = TOTAL_LEVEL_DESCRIPTORS;
/* ... and set the Device Descriptor table */
s_psMacPib->psMacDeviceTable = asDeviceDescriptor;
s_psMacPib->u8MacDeviceTableEntries = TOTAL_SEC_ENTRIES;
#endif
when sending data:
#if (SECURITY_ENABLED)
/* Specify security information. Key ID is mode 1 (Key determined by 1 octet key index and macDefaultKeySource) */
sMcpsReqRsp.uParam.sReqData.sFrame.sSecurityData.u8SecurityLevel = 5;
sMcpsReqRsp.uParam.sReqData.sFrame.sSecurityData.u8KeyIdMode = MAC_SECURITY_KEYID_MODE_1;
sMcpsReqRsp.uParam.sReqData.sFrame.sSecurityData.u8KeyIndex = 0;
#else
sMcpsReqRsp.uParam.sReqData.sFrame.sSecurityData.u8SecurityLevel = 0;
#endif
no one any idea?
Hi Mohammeds,
The 802.15.4-2006 security algorithm uses the extended source address of the originator of the frame during the frame encryption and decryption – it forms part of the nonce (see section 7.6.3.2 of the 802.15.4-2006 specification). In fact, the 2003 specification used it as well.
The frame originator obviously knows its own extended address, but the recipient must obtain it either from the frame itself (not possible in this case as they are using short addresses) or from the device descriptor information.
As you are using a pre-configured system and a single key, they are not actually going to end up with a particularly secure system: it will deter a snooper but not a committed hacker. As such, it is probably acceptable to ‘cheat’ by giving each device an extended address based on its short address: the function MAC_vSetExtAddr can be used to override the original extended address on a device, so it can be set to anything. It will then be possible to set the extended address fields in the MAC_DeviceDescriptor_s table in each device, again based on the short addresses, so everything will then match at both ends of the connection.
Best Regards,
Mario