I already have an AES-CCM implementation and tested it with the test vectors for ZigBee Green Power from the ZigBee Pro Specification. The problem is that the result I get isn't correct (it's not the same as in the specification).
I also tried to verify my implementation with other test vectors (non-GP ones) from the specification and the result was correct. So, my algorithm seems to be correct.
Is there a difference in calculating the GP MIC code to the normal ZigBee MIC?? Maybe someone has another implementation which is working for ZigBee GP??
Additional information:
The ZigBee specification I used is available here: http://www.zigbee.org/zigbee-for-develo ... zigbeepro/#
The test vectors which are working are in Annex C.3 of the above document.
The test vectors for the Green Power version are in Annex H.2. For the sake of completeness, the parameters are as follows (Annex H.2.3):
Code: Select all
Key: 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCa, 0xCb, 0xCc, 0xCd, 0xCe, 0xCf
NWK Frame Control: 0x8C
GPD Src ID: 0x87654321
Security Frame Counter: 0x00000002
GPD Command ID: 0x02
No data Payload
Code: Select all
Nonce: SRC ID || SRC ID || Frame Counter || 0x05
Nonce: 0x21 0x43 0x65 0x87 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00 0x05
Code: Select all
a = Header || Payload
Header = NWK FC || NWK Ext FC || SRC ID || Frame Counter
Header = 0x8C 0x10 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00
Payload = GPD Command ID = 0x20
a = 0x8C 0x10 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00 0x20
Code: Select all
length(a) = 0x0B
L(a) = 0x00 0x0B (big endian encoding of length(a))
AddAuthData = L(a) || a || padding
AddAuthData = 0x00 0x0B 0x8C 0x10 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00 0x20 0x00 0x00 0x00
Flags = 0x49
B0 = Flags || Nonce || padding
B0 = 0x49 0x21 0x43 0x65 0x87 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00 0x05 0x00 0x00
Code: Select all
B1 = AddAuthData
B1 = 0x00 0x0B 0x8C 0x10 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00 0x20 0x00 0x00 0x00
The result of the AES calculation is a 16 byte value. But only the 4 leftmost bytes are used. And the expected result is:
Code: Select all
U = 0xCF 0x78 0x7E 0x72
Code: Select all
X2 = 02 1C 9F 9C 40 3A 27 B4 9A 31 64 EA 17 CF 69 D3
U = 0x02 0x1C 0x9F 0x9C