def loramac_decrypt(payload_hex, sequence_counter, key, dev_addr, direction=UP_LINK):
key = unhexlify(key)<EOL>dev_addr = unhexlify(dev_addr)<EOL>buffer = bytearray(unhexlify(payload_hex))<EOL>size = len(buffer)<EOL>bufferIndex = <NUM_LIT:0><EOL>ctr = <NUM_LIT:1><EOL>encBuffer = [<NUM_LIT>] * size<EOL>cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())<EOL>def aes_encrypt_block(aBlock):<EOL><INDENT>"""<STR_LIT>"""<EOL>encryptor = cipher.encryptor()<EOL>return bytearray(encryptor.update(to_bytes(aBlock)) + encryptor.finalize())<EOL><DEDENT>aBlock = bytearray(<EOL>[<EOL><NUM_LIT>,  <EOL><NUM_LIT>,  <EOL><NUM_LIT>,  <EOL><NUM_LIT>,  <EOL><NUM_LIT>,  <EOL>direction,  <EOL>dev_addr[<NUM_LIT:3>],  <EOL>dev_addr[<NUM_LIT:2>],  <EOL>dev_addr[<NUM_LIT:1>],  <EOL>dev_addr[<NUM_LIT:0>],  <EOL>sequence_counter & <NUM_LIT>,  <EOL>(sequence_counter >> <NUM_LIT:8>) & <NUM_LIT>,  <EOL>(sequence_counter >> <NUM_LIT:16>) & <NUM_LIT>,  <EOL>(sequence_counter >> <NUM_LIT>) & <NUM_LIT>,  <EOL><NUM_LIT>,  <EOL><NUM_LIT>,  <EOL>]<EOL>)<EOL>while size >= <NUM_LIT:16>:<EOL><INDENT>aBlock[<NUM_LIT:15>] = ctr & <NUM_LIT><EOL>ctr += <NUM_LIT:1><EOL>sBlock = aes_encrypt_block(aBlock)<EOL>for i in range(<NUM_LIT:16>):<EOL><INDENT>encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i]<EOL><DEDENT>size -= <NUM_LIT:16><EOL>bufferIndex += <NUM_LIT:16><EOL><DEDENT>if size > <NUM_LIT:0>:<EOL><INDENT>aBlock[<NUM_LIT:15>] = ctr & <NUM_LIT><EOL>sBlock = aes_encrypt_block(aBlock)<EOL>for i in range(size):<EOL><INDENT>encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i]<EOL><DEDENT><DEDENT>return encBuffer<EOL>
LoraMac decrypt

Which is actually encrypting a predefined 16-byte block (ref LoraWAN
specification 4.3.3.1) and XORing that with each block of data.

payload_hex: hex-encoded payload (FRMPayload)
sequence_counter: integer, sequence counter (FCntUp)
key: 16-byte hex-encoded AES key. (i.e. AABBCCDDEEFFAABBCCDDEEFFAABBCCDD)
dev_addr: 4-byte hex-encoded DevAddr (i.e. AABBCCDD)
direction: 0 for uplink packets, 1 for downlink packets

returns an array of byte values.

This method is based on `void LoRaMacPayloadEncrypt()` in
https://github.com/Lora-net/LoRaMac-node/blob/master/src/mac/LoRaMacCrypto.c#L108