AllWize Library
AllWize_LoRaWAN.cpp
Go to the documentation of this file.
1 /*
2 
3 AllWize LoRaWAN Library
4 
5 This code is based on Adafruit's TinyLora Library and thus
6 
7 Copyright (C) 2015, 2016 Ideetron B.V.
8 Modified by Brent Rubell for Adafruit Industries.
9 Copyright (C) 2018-2021 by AllWize <github@allwize.io>
10 
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU Lesser General Public License for more details.
20 
21 You should have received a copy of the GNU Lesser General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 
24 */
25 
31 #include "AllWize_LoRaWAN.h"
32 
40 bool AllWize_LoRaWAN::joinABP(uint8_t *DevAddr, uint8_t *AppSKey, uint8_t * NwkSKey) {
41 
42  memcpy(_devaddr, DevAddr, 4);
43  memcpy(_appskey, AppSKey, 16);
44  memcpy(_nwkskey, NwkSKey, 16);
45 
46  #if ALLWIZE_LORAWAN_REDUCE_SIZE
48  #endif
49 
50  uint32_t uid = 0;
51  for (uint8_t i=0; i<4; i++) {
52  uid = (uid << 8) + DevAddr[i];
53  }
54  setUID(uid);
55 
56  return true;
57 
58 }
59 
65 
67 
68  // Rebuilds LoRaWAN MAC header and payload from
69  // Wize header info if C-Field matches LORAWAN_C_FIELD_MASK mask
71  uint8_t tmp[RX_BUFFER_SIZE];
72  tmp[0] = (raw.c & 0x0F) << 4;
73  tmp[1] = raw.address[3];
74  tmp[2] = raw.address[2];
75  tmp[3] = raw.address[1];
76  tmp[4] = raw.address[0];
77  tmp[5] = LORAWAN_FRAME_CONTROL;
78  tmp[6] = raw.wize_counter & 0xFF;
79  tmp[7] = raw.wize_counter >> 8;
80  tmp[8] = raw.wize_application;
81  memcpy(&tmp[9], raw.data, raw.len);
82  raw.len += 9;
83  memcpy(raw.data, tmp, raw.len);
84  }
85 
86  return raw;
87 
88 }
89 
97 bool AllWize_LoRaWAN::send(uint8_t *Data, uint8_t Data_Length, uint8_t Frame_Port) {
98 
99  // Define variables
100  uint8_t i;
101  uint8_t LoRaWAN_Data[64] = {0};
102  uint8_t LoRaWAN_Data_Length = 0;
103  uint8_t MIC[4] = {0};
104 
105  // Make a copy of Data
106  uint8_t tmpData[Data_Length];
107  for (int i = 0; i < Data_Length; i++) {
108  tmpData[i] = Data[i];
109  }
110 
111  // Encrypt Data (data argument is overwritten in this function)
112  Encrypt_Payload(tmpData, Data_Length, _counter, LORAWAN_DIRECTION);
113 
114  // MAC Header
115  LoRaWAN_Data[0] = LORAWAN_MAC_HEADER;
116 
117  // MAC Payload - Frame Header
118  LoRaWAN_Data[1] = _devaddr[3];
119  LoRaWAN_Data[2] = _devaddr[2];
120  LoRaWAN_Data[3] = _devaddr[1];
121  LoRaWAN_Data[4] = _devaddr[0];
122  LoRaWAN_Data[5] = LORAWAN_FRAME_CONTROL;
123  LoRaWAN_Data[6] = (_counter & 0x00FF);
124  LoRaWAN_Data[7] = ((_counter >> 8) & 0x00FF);
125 
126  // MAC Payload - Frame Port
127  LoRaWAN_Data[8] = Frame_Port;
128 
129  //Set Current package length
130  LoRaWAN_Data_Length = 9;
131 
132  // MAC Payload - Frame Payload
133  for(i = 0; i < Data_Length; i++) {
134  LoRaWAN_Data[LoRaWAN_Data_Length + i] = tmpData[i];
135  }
136  LoRaWAN_Data_Length += Data_Length;
137 
138  // Calculate MIC
139  Calculate_MIC(LoRaWAN_Data, MIC, LoRaWAN_Data_Length, _counter, LORAWAN_DIRECTION);
140 
141  // Load MIC in package
142  for(i = 0; i < 4; i++) {
143  LoRaWAN_Data[LoRaWAN_Data_Length + i] = MIC[i];
144  }
145  LoRaWAN_Data_Length += 4;
146 
147  #if defined(ALLWIZE_DEBUG_PORT)
148  ALLWIZE_DEBUG_PORT.print("[LORAWAN] PHYPayload: ");
149  char buff[6];
150  for(i = 0; i < LoRaWAN_Data_Length; i++) {
151  snprintf(buff, sizeof(buff), "%02X", LoRaWAN_Data[i]);
152  ALLWIZE_DEBUG_PORT.print(buff);
153  }
154  ALLWIZE_DEBUG_PORT.println();
155  #endif
156 
157  #if ALLWIZE_LORAWAN_REDUCE_SIZE
158  setWizeApplication(Frame_Port);
159  #define ALLWIZE_LORAWAN_SKIP_BYTES 9
160  #else
161  #define ALLWIZE_LORAWAN_SKIP_BYTES 0
162  #endif
163 
164  // Send Package
165  return AllWize::send(&LoRaWAN_Data[ALLWIZE_LORAWAN_SKIP_BYTES], LoRaWAN_Data_Length - ALLWIZE_LORAWAN_SKIP_BYTES);
166 
167 }
168 
169 // ----------------------------------------------------------------------------
170 
179 void AllWize_LoRaWAN::Encrypt_Payload(uint8_t *Data, uint8_t Data_Length, uint16_t Frame_Counter, uint8_t Direction) {
180 
181  uint8_t i = 0x00;
182  uint8_t j;
183  uint8_t Number_of_Blocks = 0x00;
184  uint8_t Incomplete_Block_Size = 0x00;
185 
186  uint8_t Block_A[16];
187 
188  //Calculate number of blocks
189  Number_of_Blocks = Data_Length / 16;
190  Incomplete_Block_Size = Data_Length % 16;
191  if (Incomplete_Block_Size != 0) {
192  Number_of_Blocks++;
193  }
194 
195  for (i = 1; i <= Number_of_Blocks; i++) {
196 
197  Block_A[0] = 0x01;
198  Block_A[1] = 0x00;
199  Block_A[2] = 0x00;
200  Block_A[3] = 0x00;
201  Block_A[4] = 0x00;
202 
203  Block_A[5] = Direction;
204 
205  Block_A[6] = _devaddr[3];
206  Block_A[7] = _devaddr[2];
207  Block_A[8] = _devaddr[1];
208  Block_A[9] = _devaddr[0];
209 
210  Block_A[10] = (Frame_Counter & 0x00FF);
211  Block_A[11] = ((Frame_Counter >> 8) & 0x00FF);
212 
213  Block_A[12] = 0x00; //Frame counter upper Bytes
214  Block_A[13] = 0x00;
215 
216  Block_A[14] = 0x00;
217 
218  Block_A[15] = i;
219 
220  //Calculate S
221  AES_Encrypt(Block_A, _appskey); //original
222 
223  //Check for last block
224  if (i != Number_of_Blocks) {
225  for (j = 0; j < 16; j++) {
226  *Data = *Data ^ Block_A[j];
227  Data++;
228  }
229  } else {
230  if (Incomplete_Block_Size == 0) {
231  Incomplete_Block_Size = 16;
232  }
233  for (j = 0; j < Incomplete_Block_Size; j++) {
234  *Data = *Data ^ Block_A[j];
235  Data++;
236  }
237  }
238  }
239 }
240 
250 void AllWize_LoRaWAN::Calculate_MIC(uint8_t *Data, uint8_t *Final_MIC, uint8_t Data_Length, uint16_t Frame_Counter, uint8_t Direction) {
251 
252  uint8_t i;
253  uint8_t Block_B[16];
254 
255  uint8_t Key_K1[16] = {
256  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
258  };
259  uint8_t Key_K2[16] = {
260  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
262  };
263 
264  //uint8_t Data_Copy[16];
265 
266  uint8_t Old_Data[16] = {
267  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
269  };
270  uint8_t New_Data[16] = {
271  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
273  };
274 
275  uint8_t Number_of_Blocks = 0x00;
276  uint8_t Incomplete_Block_Size = 0x00;
277  uint8_t Block_Counter = 0x01;
278 
279  //Create Block_B
280  Block_B[0] = 0x49;
281  Block_B[1] = 0x00;
282  Block_B[2] = 0x00;
283  Block_B[3] = 0x00;
284  Block_B[4] = 0x00;
285 
286  Block_B[5] = Direction;
287 
288  Block_B[6] = _devaddr[3];
289  Block_B[7] = _devaddr[2];
290  Block_B[8] = _devaddr[1];
291  Block_B[9] = _devaddr[0];
292 
293  Block_B[10] = (Frame_Counter & 0x00FF);
294  Block_B[11] = ((Frame_Counter >> 8) & 0x00FF);
295 
296  Block_B[12] = 0x00; //Frame counter upper bytes
297  Block_B[13] = 0x00;
298 
299  Block_B[14] = 0x00;
300  Block_B[15] = Data_Length;
301 
302  //Calculate number of Blocks and blocksize of last block
303  Number_of_Blocks = Data_Length / 16;
304  Incomplete_Block_Size = Data_Length % 16;
305 
306  if (Incomplete_Block_Size != 0) {
307  Number_of_Blocks++;
308  }
309 
310  Generate_Keys(Key_K1, Key_K2);
311 
312  //Preform Calculation on Block B0
313 
314  //Preform AES encryption
315  AES_Encrypt(Block_B, _nwkskey);
316 
317  //Copy Block_B to Old_Data
318  for (i = 0; i < 16; i++) {
319  Old_Data[i] = Block_B[i];
320  }
321 
322  //Preform full calculating until n-1 messsage blocks
323  while (Block_Counter < Number_of_Blocks) {
324 
325  //Copy data into array
326  for (i = 0; i < 16; i++) {
327  New_Data[i] = *Data;
328  Data++;
329  }
330 
331  //Preform XOR with old data
332  XOR(New_Data, Old_Data);
333 
334  //Preform AES encryption
335  AES_Encrypt(New_Data, _nwkskey);
336 
337  //Copy New_Data to Old_Data
338  for (i = 0; i < 16; i++) {
339  Old_Data[i] = New_Data[i];
340  }
341 
342  //Raise Block counter
343  Block_Counter++;
344 
345  }
346 
347  //Perform calculation on last block
348  //Check if Datalength is a multiple of 16
349  if (Incomplete_Block_Size == 0) {
350 
351  //Copy last data into array
352  for (i = 0; i < 16; i++) {
353  New_Data[i] = *Data;
354  Data++;
355  }
356 
357  //Preform XOR with Key 1
358  XOR(New_Data, Key_K1);
359 
360  //Preform XOR with old data
361  XOR(New_Data, Old_Data);
362 
363  //Preform last AES routine
364  // read _nwkskey from PROGMEM
365  AES_Encrypt(New_Data, _nwkskey);
366 
367  } else {
368 
369  //Copy the remaining data and fill the rest
370  for (i = 0; i < 16; i++) {
371  if (i < Incomplete_Block_Size) {
372  New_Data[i] = *Data;
373  Data++;
374  }
375  if (i == Incomplete_Block_Size) {
376  New_Data[i] = 0x80;
377  }
378  if (i > Incomplete_Block_Size) {
379  New_Data[i] = 0x00;
380  }
381  }
382 
383  //Preform XOR with Key 2
384  XOR(New_Data, Key_K2);
385 
386  //Preform XOR with Old data
387  XOR(New_Data, Old_Data);
388 
389  //Preform last AES routine
390  AES_Encrypt(New_Data, _nwkskey);
391 
392  }
393 
394  Final_MIC[0] = New_Data[0];
395  Final_MIC[1] = New_Data[1];
396  Final_MIC[2] = New_Data[2];
397  Final_MIC[3] = New_Data[3];
398 
399 }
400 
407 void AllWize_LoRaWAN::Generate_Keys(uint8_t *K1, uint8_t *K2) {
408 
409  uint8_t i;
410  uint8_t MSB_Key;
411 
412  //Encrypt the zeros in K1 with the _nwkskey
413  AES_Encrypt(K1, _nwkskey);
414 
415  //Create K1
416  //Check if MSB is 1
417  if ((K1[0] & 0x80) == 0x80) {
418  MSB_Key = 1;
419  } else {
420  MSB_Key = 0;
421  }
422 
423  //Shift K1 one bit left
424  Shift_Left(K1);
425 
426  //if MSB was 1
427  if (MSB_Key == 1) {
428  K1[15] = K1[15] ^ 0x87;
429  }
430 
431  //Copy K1 to K2
432  for (i = 0; i < 16; i++) {
433  K2[i] = K1[i];
434  }
435 
436  //Check if MSB is 1
437  if ((K2[0] & 0x80) == 0x80) {
438  MSB_Key = 1;
439  } else {
440  MSB_Key = 0;
441  }
442 
443  //Shift K2 one bit left
444  Shift_Left(K2);
445 
446  //Check if MSB was 1
447  if (MSB_Key == 1) {
448  K2[15] = K2[15] ^ 0x87;
449  }
450 
451 }
452 
458 void AllWize_LoRaWAN::Shift_Left(uint8_t *Data) {
459 
460  uint8_t i;
461  uint8_t Overflow = 0;
462  //uint8_t High_Byte, Low_Byte;
463 
464  for (i = 0; i < 16; i++) {
465 
466  //Check for overflow on next byte except for the last byte
467  if (i < 15) {
468  //Check if upper bit is one
469  if ((Data[i + 1] & 0x80) == 0x80) {
470  Overflow = 1;
471  } else {
472  Overflow = 0;
473  }
474  } else {
475  Overflow = 0;
476  }
477 
478  //Shift one left
479  Data[i] = (Data[i] << 1) + Overflow;
480 
481  }
482 
483 }
484 
491 void AllWize_LoRaWAN::XOR(uint8_t *New_Data, uint8_t *Old_Data) {
492 
493  uint8_t i;
494  for (i = 0; i < 16; i++) {
495  New_Data[i] = New_Data[i] ^ Old_Data[i];
496  }
497 
498 }
499 
500 //-----------------------------------------------------------------------------
501 // AES Encryption methods
502 //-----------------------------------------------------------------------------
503 
504 /*
505  * Description: S_Table used for AES encription
506  */
507 const uint8_t PROGMEM AllWize_LoRaWAN::S_Table[16][16] = {
508  {0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76},
509  {0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0},
510  {0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15},
511  {0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75},
512  {0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84},
513  {0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF},
514  {0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8},
515  {0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2},
516  {0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73},
517  {0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB},
518  {0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79},
519  {0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08},
520  {0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A},
521  {0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E},
522  {0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF},
523  {0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16}
524  };
525 
532 void AllWize_LoRaWAN::AES_Encrypt(uint8_t *Data, const uint8_t *Key) {
533 
534  uint8_t Row, Column, Round = 0;
535  uint8_t Round_Key[16];
536  uint8_t State[4][4];
537 
538  // Copy input to State arry
539  for (Column = 0; Column < 4; Column++) {
540  for (Row = 0; Row < 4; Row++) {
541  State[Row][Column] = Data[Row + (Column << 2)];
542  }
543  }
544 
545  // Copy key to round key
546  memcpy(&Round_Key[0], &Key[0], 16);
547 
548  // Add round key
549  AES_Add_Round_Key(Round_Key, State);
550 
551  // Preform 9 full rounds with mixed collums
552  for (Round = 1; Round < 10; Round++) {
553 
554  // Perform Byte substitution with S table
555  for (Column = 0; Column < 4; Column++) {
556  for (Row = 0; Row < 4; Row++) {
557  State[Row][Column] = AES_Sub_Byte(State[Row][Column]);
558  }
559  }
560 
561  // Perform Row Shift
562  AES_Shift_Rows(State);
563 
564  // Mix Collums
565  AES_Mix_Collums(State);
566 
567  // Calculate new round key
568  AES_Calculate_Round_Key(Round, Round_Key);
569 
570  // Add the round key to the Round_key
571  AES_Add_Round_Key(Round_Key, State);
572 
573  }
574 
575  // Perform Byte substitution with S table whitout mix collums
576  for (Column = 0; Column < 4; Column++) {
577  for (Row = 0; Row < 4; Row++) {
578  State[Row][Column] = AES_Sub_Byte(State[Row][Column]);
579  }
580  }
581 
582  // Shift rows
583  AES_Shift_Rows(State);
584 
585  // Calculate new round key
586  AES_Calculate_Round_Key(Round, Round_Key);
587 
588  // Add round key
589  AES_Add_Round_Key(Round_Key, State);
590 
591  // Copy the State into the data array
592  for (Column = 0; Column < 4; Column++) {
593  for (Row = 0; Row < 4; Row++) {
594  Data[Row + (Column << 2)] = State[Row][Column];
595  }
596  }
597 
598 }
599 
606 void AllWize_LoRaWAN::AES_Add_Round_Key(uint8_t *Round_Key, uint8_t (*State)[4]) {
607 
608  uint8_t Row, Collum;
609 
610  for (Collum = 0; Collum < 4; Collum++) {
611  for (Row = 0; Row < 4; Row++) {
612  State[Row][Collum] ^= Round_Key[Row + (Collum << 2)];
613  }
614  }
615 
616 }
617 
624 uint8_t AllWize_LoRaWAN::AES_Sub_Byte(uint8_t Byte) {
625 
626  // uint8_t S_Row,S_Collum;
627  // uint8_t S_Byte;
628  //
629  // S_Row = ((Byte >> 4) & 0x0F);
630  // S_Collum = ((Byte >> 0) & 0x0F);
631  // S_Byte = S_Table [S_Row][S_Collum];
632 
633  //return S_Table [ ((Byte >> 4) & 0x0F) ] [ ((Byte >> 0) & 0x0F) ]; // original
634  return pgm_read_byte(&(S_Table[((Byte >> 4) & 0x0F)][((Byte >> 0) & 0x0F)]));
635 
636 }
637 
643 void AllWize_LoRaWAN::AES_Shift_Rows(uint8_t (*State)[4]) {
644 
645  uint8_t Buffer;
646 
647  //Store firt byte in buffer
648  Buffer = State[1][0];
649  //Shift all bytes
650  State[1][0] = State[1][1];
651  State[1][1] = State[1][2];
652  State[1][2] = State[1][3];
653  State[1][3] = Buffer;
654 
655  Buffer = State[2][0];
656  State[2][0] = State[2][2];
657  State[2][2] = Buffer;
658  Buffer = State[2][1];
659  State[2][1] = State[2][3];
660  State[2][3] = Buffer;
661 
662  Buffer = State[3][3];
663  State[3][3] = State[3][2];
664  State[3][2] = State[3][1];
665  State[3][1] = State[3][0];
666  State[3][0] = Buffer;
667 
668 }
669 
675 void AllWize_LoRaWAN::AES_Mix_Collums(uint8_t (*State)[4]) {
676 
677  uint8_t Row, Collum;
678  uint8_t a[4], b[4];
679 
680  for (Collum = 0; Collum < 4; Collum++) {
681  for (Row = 0; Row < 4; Row++) {
682  a[Row] = State[Row][Collum];
683  b[Row] = (State[Row][Collum] << 1);
684 
685  if ((State[Row][Collum] & 0x80) == 0x80) {
686  b[Row] ^= 0x1B;
687  }
688  }
689 
690  State[0][Collum] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3];
691  State[1][Collum] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3];
692  State[2][Collum] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3];
693  State[3][Collum] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3];
694  }
695 
696 }
697 
704 void AllWize_LoRaWAN::AES_Calculate_Round_Key(uint8_t Round, uint8_t *Round_Key) {
705 
706  uint8_t i, j, b, Rcon;
707  uint8_t Temp[4];
708 
709  //Calculate Rcon
710  Rcon = 0x01;
711  while (Round != 1) {
712  b = Rcon & 0x80;
713  Rcon = Rcon << 1;
714 
715  if (b == 0x80) {
716  Rcon ^= 0x1b;
717  }
718  Round--;
719  }
720 
721  // Calculate first Temp
722  // Copy laste byte from previous key and subsitute the byte, but shift the array contents around by 1.
723  Temp[0] = AES_Sub_Byte(Round_Key[12 + 1]);
724  Temp[1] = AES_Sub_Byte(Round_Key[12 + 2]);
725  Temp[2] = AES_Sub_Byte(Round_Key[12 + 3]);
726  Temp[3] = AES_Sub_Byte(Round_Key[12 + 0]);
727 
728  // XOR with Rcon
729  Temp[0] ^= Rcon;
730 
731  // Calculate new key
732  for (i = 0; i < 4; i++) {
733  for (j = 0; j < 4; j++) {
734  Round_Key[j + (i << 2)] ^= Temp[j];
735  Temp[j] = Round_Key[j + (i << 2)];
736  }
737  }
738 
739 }
AllWize::setWizeApplication
void setWizeApplication(uint8_t wize_application)
Sets the wize applicaton field in the transpoprt layer.
Definition: AllWize.cpp:557
AllWize_LoRaWAN::_nwkskey
uint8_t _nwkskey[16]
Definition: AllWize_LoRaWAN.h:86
LORAWAN_FRAME_CONTROL
#define LORAWAN_FRAME_CONTROL
Definition: AllWize_LoRaWAN.h:64
AllWize_LoRaWAN::AES_Sub_Byte
uint8_t AES_Sub_Byte(uint8_t Byte)
Function performs AES SubBytes step.
Definition: AllWize_LoRaWAN.cpp:624
allwize_message_t::wize_counter
uint16_t wize_counter
Definition: AllWize.h:66
AllWize_LoRaWAN::AES_Encrypt
void AES_Encrypt(uint8_t *Data, const uint8_t *Key)
Function used to perform AES encryption.
Definition: AllWize_LoRaWAN.cpp:532
AllWize_LoRaWAN::_devaddr
uint8_t _devaddr[4]
Definition: AllWize_LoRaWAN.h:84
AllWize_LoRaWAN::AES_Calculate_Round_Key
void AES_Calculate_Round_Key(uint8_t Round, uint8_t *Round_Key)
Function performs AES Round Key Calculation.
Definition: AllWize_LoRaWAN.cpp:704
AllWize::setControlField
void setControlField(uint8_t value, bool persist=false)
Sets the control field value.
Definition: AllWize.cpp:838
allwize_message_t
Definition: AllWize.h:54
AllWize_LoRaWAN::S_Table
static const uint8_t S_Table[16][16]
Definition: AllWize_LoRaWAN.h:87
LORAWAN_C_FIELD_MASK
#define LORAWAN_C_FIELD_MASK
Definition: AllWize_LoRaWAN.h:45
AllWize::read
allwize_message_t read()
Returns latest received message.
Definition: AllWize.cpp:505
AllWize_LoRaWAN::Generate_Keys
void Generate_Keys(uint8_t *K1, uint8_t *K2)
Function used to generate keys for the MIC calculation.
Definition: AllWize_LoRaWAN.cpp:407
AllWize_LoRaWAN::Calculate_MIC
void Calculate_MIC(uint8_t *Data, uint8_t *Final_MIC, uint8_t Data_Length, uint16_t Frame_Counter, uint8_t Direction)
Function used to calculate the validity of data messages.
Definition: AllWize_LoRaWAN.cpp:250
AllWize::setUID
bool setUID(uint32_t uid)
Saved the UID into the module memory.
Definition: AllWize.cpp:1072
AllWize_LoRaWAN.h
LORAWAN_DIRECTION
#define LORAWAN_DIRECTION
Definition: AllWize_LoRaWAN.h:56
AllWize_LoRaWAN::Shift_Left
void Shift_Left(uint8_t *Data)
Round-shifts data to the left.
Definition: AllWize_LoRaWAN.cpp:458
AllWize_LoRaWAN::AES_Add_Round_Key
void AES_Add_Round_Key(uint8_t *Round_Key, uint8_t(*State)[4])
Function performs AES AddRoundKey step.
Definition: AllWize_LoRaWAN.cpp:606
AllWize_LoRaWAN::AES_Shift_Rows
void AES_Shift_Rows(uint8_t(*State)[4])
Function performs AES ShiftRows step.
Definition: AllWize_LoRaWAN.cpp:643
AllWize::send
bool send(uint8_t *buffer, uint8_t len)
Sends a byte array.
Definition: AllWize.cpp:366
allwize_message_t::len
uint8_t len
Definition: AllWize.h:61
AllWize_LoRaWAN::read
allwize_message_t read()
Returns latest received message (rebuilds LoRaWan header if necessary)
Definition: AllWize_LoRaWAN.cpp:64
allwize_message_t::wize_application
uint8_t wize_application
Definition: AllWize.h:67
AllWize_LoRaWAN::send
bool send(uint8_t *Data, uint8_t Data_Length, uint8_t Frame_Port=0x01)
Function to assemble and send a LoRaWAN package.
Definition: AllWize_LoRaWAN.cpp:97
AllWize_LoRaWAN::Encrypt_Payload
void Encrypt_Payload(uint8_t *Data, uint8_t Data_Length, uint16_t Frame_Counter, uint8_t Direction)
Function used to encrypt and decrypt the data in a LoRaWAN data packet.
Definition: AllWize_LoRaWAN.cpp:179
ALLWIZE_LORAWAN_SKIP_BYTES
#define ALLWIZE_LORAWAN_SKIP_BYTES
AllWize_LoRaWAN::joinABP
bool joinABP(uint8_t *DevAddr, uint8_t *AppSKey, uint8_t *NwkSKey)
Stores the application and network keys for ABP activation.
Definition: AllWize_LoRaWAN.cpp:40
allwize_message_t::address
uint8_t address[4]
Definition: AllWize.h:60
RX_BUFFER_SIZE
#define RX_BUFFER_SIZE
Definition: AllWize.h:45
allwize_message_t::data
uint8_t data[RX_BUFFER_SIZE]
Definition: AllWize.h:62
AllWize::_counter
uint16_t _counter
Definition: AllWize.h:284
AllWize_LoRaWAN::XOR
void XOR(uint8_t *New_Data, uint8_t *Old_Data)
Function to XOR two character arrays.
Definition: AllWize_LoRaWAN.cpp:491
allwize_message_t::c
uint8_t c
Definition: AllWize.h:55
AllWize_LoRaWAN::AES_Mix_Collums
void AES_Mix_Collums(uint8_t(*State)[4])
Function performs AES MixColumns step.
Definition: AllWize_LoRaWAN.cpp:675
AllWize_LoRaWAN::_appskey
uint8_t _appskey[16]
Definition: AllWize_LoRaWAN.h:85
LORAWAN_MAC_HEADER
#define LORAWAN_MAC_HEADER
Definition: AllWize_LoRaWAN.h:51