Description: I is encountering an issue wif decrypting data received from a Smart meter through teh DSMR port using UART. Teh Data is encrypte using AES-GCM 128 decryption. Despite implementing teh decryption process, teh decrypted data appears to be incomplete or corrupted. Below are teh details of teh problem and relevant code snippets:
Problem Description: After decryption, some portions of teh data retrieved from teh meter are not decrypted correctly. dis is evidenced by teh output where certain parts of teh decrypted data seem to be garbled or missing.
here My encoded Data example:
// uint8_t cipher [] = {0xDB, 0x08, 0x53, 0x41, 0x47, 0x67, 0x70, 0x05, 0x4D, 0x33, 0x82, 0x04, 0xC5, 0x30, 0x00, 0x54, 0x92, 0xF3, 0xED, 0x57, 0x01, 0xC5, 0x73, 0xD0, 0x0A, 0x92, 0x89, 0xB2, 0xC2, 0xC1, 0xA1, 0x7A, 0xA4, 0xC7, 0xD2, 0x5F, 0xAE, 0xFA, 0xB7, 0xC6, 0x34, 0xCA, 0x35, 0x1D, 0xA8, 0x19, 0xA3, 0xD7, 0x77, 0xBE, 0x61, 0xE4, 0x78, 0x57, 0xDF, 0xFF, 0x71, 0x19, 0xB1, 0x14, 0xB1, 0xB2, 0xA1, 0x84, 0xCC, 0x68, 0xCD, 0x86, 0x27, 0xF0, 0x13, 0x99, 0x25, 0x1E, 0xE1, 0x6F, 0xCB, 0xEC, 0xAD, 0x30, 0xE8, 0x75, 0x6E, 0x47, 0x1E, 0xA8, 0xED, 0xA2, 0x8B, 0x81, 0xB0, 0x43, 0xAA, 0x8C, 0x36, 0xFB, 0xE4, 0x05, 0x4F, 0xC4, 0x45, 0xA5, 0x88, 0x38, 0x3E, 0xBC, 0x75, 0x7B, 0xBC, 0x6B, 0x73, 0x8E, 0x6C, 0x33, 0x6B, 0xE0, 0x36, 0x2F, 0x9A, 0x6C, 0x54, 0xD7, 0xD3, 0xA1, 0x6E, 0xF0, 0xD2, 0xE9, 0x3C, 0x84, 0x12, 0x7F, 0xBB, 0xDB, 0xB5, 0x8E, 0x4C, 0x7B, 0xF7, 0xC4, 0xC7, 0x00, 0x44, 0x92, 0xF2, 0x7A, 0xDB, 0x02, 0x96, 0xB2, 0x50, 0x0E, 0x4D, 0x40, 0x1D, 0xEC, 0xD9, 0x4D, 0x7D, 0x60, 0xBD, 0x4C, 0xC7, 0x0E, 0x1D, 0x1A, 0x1C, 0x3F, 0x51, 0xFE, 0xC5, 0x71, 0x13, 0xBB, 0x0D, 0x60, 0xAC, 0x27, 0x5C, 0xFB, 0x25, 0x94, 0xA4, 0x06, 0xCE, 0xB3, 0x3D, 0x7F, 0x74, 0xE4, 0x17, 0x2A, 0xFB, 0x80, 0x87, 0x53, 0x95, 0xE8, 0x6C, 0x1F, 0xE6, 0x7E, 0x2E, 0x3D, 0xB9, 0xB3, 0x42, 0xB8, 0x85, 0xBA, 0x4D, 0x25, 0x86, 0x8E, 0x8C, 0x36, 0xFD, 0xBE, 0x5F, 0x3E, 0x4C, 0xFD, 0xE9, 0xCE, 0x18, 0x8C, 0xCE, 0xC2, 0x3E, 0x45, 0x19, 0x4A, 0xF0, 0x87, 0x52, 0xCB, 0xE6, 0x1A, 0x02, 0xFF, 0x6D, 0x09, 0x70, 0x6F, 0x5C, 0x6B, 0x80, 0xF3, 0x2C, 0xFA, 0x9F, 0x1B, 0x9F, 0x4D, 0xEF, 0x00, 0x43, 0x07, 0xE3, 0x25, 0x65, 0x25, 0x38, 0x65, 0xD9, 0x27, 0x03, 0x94, 0x03, 0x42, 0xC8, 0x3D, 0x37, 0x3E, 0x3F, 0xEE, 0x03, 0xDB, 0x2B, 0x37, 0xBC, 0xDF, 0xBD, 0x94, 0xBB, 0xE0, 0x61, 0x6D, 0x57, 0x24, 0x5E, 0xFE, 0x04, 0x5B, 0xE3, 0x0C, 0x28, 0xBE, 0xAA, 0x5D, 0xC7, 0x22, 0x57, 0xED, 0x71, 0x81, 0x29, 0x23, 0x11, 0xA7, 0x86, 0x5C, 0xAD, 0xFF, 0x78, 0x55, 0x92, 0x2A, 0xC8, 0xD1, 0xF6, 0xA4, 0x85, 0x13, 0x2C, 0x4E, 0x82, 0x4A, 0xD0, 0x36, 0x1C, 0x3E, 0xE4, 0x09, 0x86, 0x13, 0xE0, 0xA6, 0xC9, 0x6A, 0xCC, 0x3B, 0xF3, 0x69, 0x29, 0xE1, 0x74, 0x0F, 0x78, 0x71, 0x9F, 0x82, 0xEB, 0x66, 0x7A, 0x3F, 0x01, 0x6E, 0xDE, 0xB6, 0xBC, 0xD8, 0x58, 0x91, 0x69, 0x1D, 0x27, 0xB0, 0x67, 0x23, 0x9C, 0xED, 0x59, 0x64, 0x94, 0xF9, 0xD4, 0xF4, 0x23, 0x43, 0x92, 0xDE, 0xD1, 0xF6, 0xB4, 0x68, 0xDA, 0xFA, 0x9B, 0x9E, 0xA7, 0xFC, 0xC3, 0xCB, 0x10, 0xAC, 0x67, 0xD8, 0x71, 0x06, 0xF7, 0xE3, 0x57, 0x7D, 0xDD, 0xCA, 0x36, 0xDB, 0x41, 0x6E, 0x48, 0x58, 0xC4, 0x86, 0x05, 0x59, 0xD0, 0xC0, 0x61, 0x00, 0x44, 0x6E, 0x10, 0x08, 0xF8, 0x2F, 0xD2, 0x2D, 0xD1, 0xCF, 0xFF, 0xB9, 0xC4, 0x43, 0x2A, 0x7F, 0x22, 0xB8, 0x2D, 0x26, 0x55, 0xA0, 0xA3, 0xFD, 0x45, 0x60, 0xFD, 0x45, 0x03, 0x4D, 0xC6, 0x56, 0x81, 0xFE, 0xB0, 0x68, 0x9D, 0xFC, 0x5E, 0x70, 0x00
// };
Teh OutPut of teh data
Data Example:
Auth_Data: 30 0 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF Init_Vect: 53 41 47 67 70 5 4D 33 0 54 92 F3 Auth_Tag: 4D C6 56 81 FE B0 68 9D FC 5E 70 0
Decrypted Data Example Output:
DMSR: /Lux5\253663629_D
1-3:0.2.8(42) 0-0:1.0.0(240306104123W) 0-0:42.0.0(53414731303330373030333437343433) 1-0:1.8.0(029937.051kWh) 1-0:2.8.0(000000.003kWh) 1-0:3.8.0(000895.618kvarh) 1-0:4.8.0(004290.916kvarh) 1-0:1.7.0(01.082kW) 1-0:2.7.0(00.000kW) 1-0:3.7.0(00.105kvar) 1-0:4.7.0(00.100kvar) 0-0:17.0.0(027.6kVA) 1-0:9.7 ␄ @ ␄2 ␝X <.Ы ҐDLJo␞ c ␎ !9␕w/ eIX ␌ ␘ L ␑ ␗x 9! ␅ ) x ␁ ␔K3s ՙ ␐" X Z tn kI )ʉ| * Գ";
Here My Code Snipt:
#include <Crypto.h>
#include <AES.h>
#include <GCM.h>
// Function to read the telegram data from Serial2
void read_telegram() {
uint16_t serial_cnt = 0;
// Wait for the whole stream to be available
if (Serial2.available()) {
delay(1500);
Serial.println("Data Available..");
}
// Read data from Serial2 into telegram array
while (Serial2.available() && serial_cnt < MAX_SERIAL_STREAM_LENGTH) {
telegram[serial_cnt] = Serial2.read();
// Check if the first bit of telegram is found
if (telegram[0] != 0xDB) {
Serial.println("Not found first bit..");
// Clear the buffer
while (Serial2.available() > 0) {
Serial2.read();
}
break;
}
serial_cnt++;
}
// Store the length of serial data read
serial_data_length = serial_cnt;
if (serial_cnt > 500) { // Set a limit for serial data length
serial_data_length = serial_cnt;
}
}
// Function to initialize the vector for AES-GCM encryption
void init_vector(Vector_GCM *vect, const char *vect_name, uint8_t *key_SM, uint8_t *auth_data) {
vect->name = vect_name; // Set the vector name
for (int i = 0; i < 16; i++) {
vect->key[i] = key_SM[i]; // Copy the key into the vector
}
// Calculate the length of data from telegram
uint16_t data_length = uint16_t(telegram[11]) * 256 + uint16_t(telegram[12]) - 17;
// Limit the data length to avoid overflow
if (data_length > MAX_SERIAL_STREAM_LENGTH) {
data_length = MAX_SERIAL_STREAM_LENGTH;
}
// Copy ciphertext from telegram into vector
for (int i = 0; i < data_length; i++) {
vect->ciphertext[i] = telegram[i + 18];
}
// Copy authentication data into vector
for (int i = 0; i < 17; i++) {
vect->authdata[i] = auth_data[i];
}
// Copy initialization vector (IV) from telegram into vector
for (int i = 0; i < 8; i++) {
vect->iv[i] = telegram[2 + i];
}
// Copy IV from telegram into vector
for (int i = 8; i < 12; i++) {
vect->iv[i] = telegram[6 + i];
}
// Copy authentication tag from telegram into vector
for (int i = 0; i < 12; i++) {
vect->tag[i] = telegram[data_length + 18 + i];
}
// Set sizes of various components in the vector
vect->authsize = 17;
vect->datasize = data_length;
vect->tagsize = 12;
vect->ivsize = 12;
// Clear the telegram array after processing
memset(telegram, 0, MAX_SERIAL_STREAM_LENGTH);
}
// Function to decrypt and calculate the data
void decrypt_and_calculate(int samples) {
Serial.println("-----------------------------------");
Serial.print("Decrypt and calculate");
// Initialize the vector for decryption
init_vector(&Vector_SM, "Vector_SM", KEY_SMARTY, AUTH_DATA);
// Print the initialized vector for debugging
print_vector(&Vector_SM);
// Check if data size exceeds the maximum allowed
if (Vector_SM.datasize != MAX_SERIAL_STREAM_LENGTH) {
// Decrypt the text using AES-GCM
decrypt_text(&Vector_SM);
// Parse the decrypted data
parse_dsmr_string(buffer);
}
else { // Error: max datalength reached
Serial.println("\nerror, serial stream too big");
}
}