#include
#include
#include
#include
#include "aes.h"
/*!
- CMAC/AES Message Integrity Code (MIC) Block B0 size */ #define LORAMAC_MIC_BLOCK_B0_SIZE 16
/*!
- MIC field computation initial data */ static uint8_t MicBlockB0[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/*!
- Contains the computed MIC field. *
- \remark Only the 4 first bytes are used */ static uint8_t Mic[16];
/*!
- Encryption aBlock and sBlock */ static uint8_t aBlock[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static uint8_t sBlock[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static aes_context AesContext;
#define LORAWAN_NWKSKEY { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
/*!
- AES encryption/decryption cipher application session key */ #define LORAWAN_APPSKEY { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
void LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer )
{
uint16_t i;
uint8_t bufferIndex = 0;
uint16_t ctr = 1;
memset1( AesContext.ksch, '\0', 240 );
aes_set_key( key, 16, &AesContext );
aBlock[5] = dir;
aBlock[6] = ( address ) & 0xFF;
aBlock[7] = ( address >> 8 ) & 0xFF;
aBlock[8] = ( address >> 16 ) & 0xFF;
aBlock[9] = ( address >> 24 ) & 0xFF;
aBlock[10] = ( sequenceCounter ) & 0xFF;
aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF;
aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF;
aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF;
while( size >= 16 )
{
aBlock[15] = ( ( ctr ) & 0xFF );
ctr++;
aes_encrypt( aBlock, sBlock, &AesContext );
for( i = 0; i < 16; i++ )
{
encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
}
size -= 16;
bufferIndex += 16;
}
if( size > 0 )
{
aBlock[15] = ( ( ctr ) & 0xFF );
aes_encrypt( aBlock, sBlock, &AesContext );
for( i = 0; i < size; i++ )
{
encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
}
}
}
void LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer )
{
LoRaMacPayloadEncrypt( buffer, size, key, address, dir, sequenceCounter, decBuffer );
}
uint8_t netkey[16] = LORAWAN_NWKSKEY;
uint8_t appkey[16] = LORAWAN_APPSKEY;
uint8_t buff1[255] = { 0 } ;
unsigned char realkey[16] = { 0 };
unsigned char realkey1[16] = { 0 };
void main(int argc,char *argv[] )
{
if (argc <= 2 ){
printf("I need three parameters.\n1st.Sequence number (frame count)\n2nd.Node mac address in hex format"
"\n13rd.Payload data, string of hex characters with a space in the last. Space in the last is must.\n4th.Payload data size, string in ASCII.\n5th. appkey string of hex\n");
exit(0);
}
uint16_t i ;
char * hello;
char * pEnd;
int sequence= atoi(argv[1]);
uint32_t nodeAddress= (uint32_t) strtol(argv[2], &hello, 16);
uint8_t finalData[248];
char *data=argv[3];
int count=0;
char temp[5];
int realCount=0;
int frame_count= (int) strlen(data);
for (int j = 0; j < frame_count; ++j) {
if(data[j]!=' '){
temp[count++]=data[j];
}else {
finalData[realCount++] = (uint8_t) strtol(temp, &pEnd, 16);
count=0;
}
}
int c2i( char ch )
{
if(isdigit(ch))
return ch-48;
if(ch<'A'||(ch>'F'&&ch<'a')||ch>'z')
return-1;
if(isalpha(ch))
return isupper(ch)?ch-55:ch-87;
return -1;
}
int hex2dec( unsigned char *hex )
{
int len;
int num=0;
int temp;
int bits;
int i;
len=strlen(hex);
for(i=0,temp=0;i<len;i++,temp=0)
{
temp=c2i(*(hex+i));
bits=(len-i-1)*4;
temp=temp<<bits;
num=num|temp;
}
return num;
}
char *temKey = argv[5];
unsigned char mkey[3]={0};
for( char i = 0; i < strlen(temKey); i++ ){
if( i % 2 == 0 ){
mkey[0] = temKey[i];
}else{
mkey[1] = temKey[i];
mkey[2] = '\0';
realkey[i/2] = hex2dec( mkey );
memset( mkey, 0 , sizeof mkey);
}
}
for( char i = 0; i < sizeof realkey; i++ ){
realkey1[i]=realkey[i];
}
//0x0063dfa9
LoRaMacPayloadDecrypt( finalData, atoi(argv[4]), realkey1, nodeAddress , 0, sequence, buff1);
for( i = 0; i < atoi(argv[4]); i++ )
{
printf("%x ", buff1[i] );
}
printf("\n");
}