41 memcpy(_devaddr, DevAddr, 4);
42 memcpy(_appskey, AppSKey, 16);
43 memcpy(_nwkskey, NwkSKey, 16);
58 uint8_t LoRaWAN_Data[64] = {0};
59 uint8_t LoRaWAN_Data_Length = 0;
63 uint8_t Direction = 0x00;
69 uint8_t Mac_Header = 0x40;
77 uint8_t Frame_Control = 0x00;
80 uint8_t tmpData[Data_Length];
81 for (
int i = 0; i < Data_Length; i++) {
86 Encrypt_Payload(tmpData, Data_Length, _frame_counter, Direction);
89 LoRaWAN_Data[0] = Mac_Header;
92 LoRaWAN_Data[1] = _devaddr[3];
93 LoRaWAN_Data[2] = _devaddr[2];
94 LoRaWAN_Data[3] = _devaddr[1];
95 LoRaWAN_Data[4] = _devaddr[0];
96 LoRaWAN_Data[5] = Frame_Control;
97 LoRaWAN_Data[6] = (_frame_counter & 0x00FF);
98 LoRaWAN_Data[7] = ((_frame_counter >> 8) & 0x00FF);
101 LoRaWAN_Data[8] = Frame_Port;
104 LoRaWAN_Data_Length = 9;
107 for(i = 0; i < Data_Length; i++) {
108 LoRaWAN_Data[LoRaWAN_Data_Length + i] = tmpData[i];
110 LoRaWAN_Data_Length += Data_Length;
113 Calculate_MIC(LoRaWAN_Data, MIC, LoRaWAN_Data_Length, _frame_counter, Direction);
116 for(i = 0; i < 4; i++) {
117 LoRaWAN_Data[i + LoRaWAN_Data_Length] = MIC[i];
119 LoRaWAN_Data_Length += 4;
134 return _frame_counter;
142 _frame_counter = value;
155 void AllWize_LoRaWAN::Encrypt_Payload(uint8_t *Data, uint8_t Data_Length, uint16_t Frame_Counter, uint8_t Direction) {
159 uint8_t Number_of_Blocks = 0x00;
160 uint8_t Incomplete_Block_Size = 0x00;
165 Number_of_Blocks = Data_Length / 16;
166 Incomplete_Block_Size = Data_Length % 16;
167 if (Incomplete_Block_Size != 0) {
171 for (i = 1; i <= Number_of_Blocks; i++) {
178 Block_A[5] = Direction;
180 Block_A[6] = _devaddr[3];
181 Block_A[7] = _devaddr[2];
182 Block_A[8] = _devaddr[1];
183 Block_A[9] = _devaddr[0];
185 Block_A[10] = (Frame_Counter & 0x00FF);
186 Block_A[11] = ((Frame_Counter >> 8) & 0x00FF);
196 AES_Encrypt(Block_A, _appskey);
199 if (i != Number_of_Blocks) {
200 for (j = 0; j < 16; j++) {
201 *Data = *Data ^ Block_A[j];
205 if (Incomplete_Block_Size == 0) {
206 Incomplete_Block_Size = 16;
208 for (j = 0; j < Incomplete_Block_Size; j++) {
209 *Data = *Data ^ Block_A[j];
225 void AllWize_LoRaWAN::Calculate_MIC(uint8_t *Data, uint8_t *Final_MIC, uint8_t Data_Length, uint16_t Frame_Counter, uint8_t Direction) {
230 uint8_t Key_K1[16] = {
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
233 uint8_t Key_K2[16] = {
234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
239 uint8_t Old_Data[16] = {
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
242 uint8_t New_Data[16] = {
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
246 uint8_t Number_of_Blocks = 0x00;
247 uint8_t Incomplete_Block_Size = 0x00;
248 uint8_t Block_Counter = 0x01;
257 Block_B[5] = Direction;
259 Block_B[6] = _devaddr[3];
260 Block_B[7] = _devaddr[2];
261 Block_B[8] = _devaddr[1];
262 Block_B[9] = _devaddr[0];
264 Block_B[10] = (Frame_Counter & 0x00FF);
265 Block_B[11] = ((Frame_Counter >> 8) & 0x00FF);
271 Block_B[15] = Data_Length;
274 Number_of_Blocks = Data_Length / 16;
275 Incomplete_Block_Size = Data_Length % 16;
277 if (Incomplete_Block_Size != 0) {
281 Generate_Keys(Key_K1, Key_K2);
286 AES_Encrypt(Block_B, _nwkskey);
289 for (i = 0; i < 16; i++) {
290 Old_Data[i] = Block_B[i];
294 while (Block_Counter < Number_of_Blocks) {
297 for (i = 0; i < 16; i++) {
303 XOR(New_Data, Old_Data);
306 AES_Encrypt(New_Data, _nwkskey);
309 for (i = 0; i < 16; i++) {
310 Old_Data[i] = New_Data[i];
320 if (Incomplete_Block_Size == 0) {
323 for (i = 0; i < 16; i++) {
329 XOR(New_Data, Key_K1);
332 XOR(New_Data, Old_Data);
336 AES_Encrypt(New_Data, _nwkskey);
341 for (i = 0; i < 16; i++) {
342 if (i < Incomplete_Block_Size) {
346 if (i == Incomplete_Block_Size) {
349 if (i > Incomplete_Block_Size) {
355 XOR(New_Data, Key_K2);
358 XOR(New_Data, Old_Data);
361 AES_Encrypt(New_Data, _nwkskey);
365 Final_MIC[0] = New_Data[0];
366 Final_MIC[1] = New_Data[1];
367 Final_MIC[2] = New_Data[2];
368 Final_MIC[3] = New_Data[3];
378 void AllWize_LoRaWAN::Generate_Keys(uint8_t *K1, uint8_t *K2) {
384 AES_Encrypt(K1, _nwkskey);
388 if ((K1[0] & 0x80) == 0x80) {
399 K1[15] = K1[15] ^ 0x87;
403 for (i = 0; i < 16; i++) {
408 if ((K2[0] & 0x80) == 0x80) {
419 K2[15] = K2[15] ^ 0x87;
429 void AllWize_LoRaWAN::Shift_Left(uint8_t *Data) {
432 uint8_t Overflow = 0;
435 for (i = 0; i < 16; i++) {
440 if ((Data[i + 1] & 0x80) == 0x80) {
450 Data[i] = (Data[i] << 1) + Overflow;
462 void AllWize_LoRaWAN::XOR(uint8_t *New_Data, uint8_t *Old_Data) {
465 for (i = 0; i < 16; i++) {
466 New_Data[i] = New_Data[i] ^ Old_Data[i];
478 const uint8_t PROGMEM AllWize_LoRaWAN::S_Table[16][16] = {
479 {0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76},
480 {0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0},
481 {0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15},
482 {0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75},
483 {0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84},
484 {0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF},
485 {0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8},
486 {0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2},
487 {0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73},
488 {0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB},
489 {0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79},
490 {0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08},
491 {0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A},
492 {0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E},
493 {0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF},
494 {0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16}
503 void AllWize_LoRaWAN::AES_Encrypt(uint8_t *Data,
const uint8_t *Key) {
505 uint8_t Row, Column, Round = 0;
506 uint8_t Round_Key[16];
510 for (Column = 0; Column < 4; Column++) {
511 for (Row = 0; Row < 4; Row++) {
512 State[Row][Column] = Data[Row + (Column << 2)];
517 memcpy(&Round_Key[0], &Key[0], 16);
520 AES_Add_Round_Key(Round_Key, State);
523 for (Round = 1; Round < 10; Round++) {
526 for (Column = 0; Column < 4; Column++) {
527 for (Row = 0; Row < 4; Row++) {
528 State[Row][Column] = AES_Sub_Byte(State[Row][Column]);
533 AES_Shift_Rows(State);
536 AES_Mix_Collums(State);
539 AES_Calculate_Round_Key(Round, Round_Key);
542 AES_Add_Round_Key(Round_Key, State);
547 for (Column = 0; Column < 4; Column++) {
548 for (Row = 0; Row < 4; Row++) {
549 State[Row][Column] = AES_Sub_Byte(State[Row][Column]);
554 AES_Shift_Rows(State);
557 AES_Calculate_Round_Key(Round, Round_Key);
560 AES_Add_Round_Key(Round_Key, State);
563 for (Column = 0; Column < 4; Column++) {
564 for (Row = 0; Row < 4; Row++) {
565 Data[Row + (Column << 2)] = State[Row][Column];
577 void AllWize_LoRaWAN::AES_Add_Round_Key(uint8_t *Round_Key, uint8_t (*State)[4]) {
581 for (Collum = 0; Collum < 4; Collum++) {
582 for (Row = 0; Row < 4; Row++) {
583 State[Row][Collum] ^= Round_Key[Row + (Collum << 2)];
595 uint8_t AllWize_LoRaWAN::AES_Sub_Byte(uint8_t Byte) {
605 return pgm_read_byte(&(S_Table[((Byte >> 4) & 0x0F)][((Byte >> 0) & 0x0F)]));
614 void AllWize_LoRaWAN::AES_Shift_Rows(uint8_t (*State)[4]) {
619 Buffer = State[1][0];
621 State[1][0] = State[1][1];
622 State[1][1] = State[1][2];
623 State[1][2] = State[1][3];
624 State[1][3] = Buffer;
626 Buffer = State[2][0];
627 State[2][0] = State[2][2];
628 State[2][2] = Buffer;
629 Buffer = State[2][1];
630 State[2][1] = State[2][3];
631 State[2][3] = Buffer;
633 Buffer = State[3][3];
634 State[3][3] = State[3][2];
635 State[3][2] = State[3][1];
636 State[3][1] = State[3][0];
637 State[3][0] = Buffer;
646 void AllWize_LoRaWAN::AES_Mix_Collums(uint8_t (*State)[4]) {
651 for (Collum = 0; Collum < 4; Collum++) {
652 for (Row = 0; Row < 4; Row++) {
653 a[Row] = State[Row][Collum];
654 b[Row] = (State[Row][Collum] << 1);
656 if ((State[Row][Collum] & 0x80) == 0x80) {
661 State[0][Collum] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3];
662 State[1][Collum] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3];
663 State[2][Collum] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3];
664 State[3][Collum] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3];
675 void AllWize_LoRaWAN::AES_Calculate_Round_Key(uint8_t Round, uint8_t *Round_Key) {
677 uint8_t i, j, b, Rcon;
694 Temp[0] = AES_Sub_Byte(Round_Key[12 + 1]);
695 Temp[1] = AES_Sub_Byte(Round_Key[12 + 2]);
696 Temp[2] = AES_Sub_Byte(Round_Key[12 + 3]);
697 Temp[3] = AES_Sub_Byte(Round_Key[12 + 0]);
703 for (i = 0; i < 4; i++) {
704 for (j = 0; j < 4; j++) {
705 Round_Key[j + (i << 2)] ^= Temp[j];
706 Temp[j] = Round_Key[j + (i << 2)];
bool send(uint8_t *buffer, uint8_t len)
Sends a byte array.
bool send(uint8_t *Data, uint8_t Data_Length, uint8_t Frame_Port=0x01)
Function to assemble and send a LoRaWAN package.
bool joinABP(uint8_t *DevAddr, uint8_t *AppSKey, uint8_t *NwkSKey)
Stores the application and network keys for ABP activation.
uint16_t getFrameCounter()
Returns current frame counter.
void setFrameCounter(uint16_t value)
Sets new frame counter.