From 27b271614938ca85c3c0867e0b2f46c6483f800d Mon Sep 17 00:00:00 2001
From: trgv <trgv@tavrida.com>
Date: Tue, 7 Jun 2022 15:09:49 +0300
Subject: [PATCH] Fix uninitialized local variables.

Causes wrong encryption/decryption.
---
 development/src/GXCipher.cpp | 91 ++++++++++++++++++------------------
 1 file changed, 46 insertions(+), 45 deletions(-)

diff --git a/development/src/GXCipher.cpp b/development/src/GXCipher.cpp
index b345258..3521981 100644
--- a/development/src/GXCipher.cpp
+++ b/development/src/GXCipher.cpp
@@ -229,8 +229,7 @@ int CGXCipher::Int(uint32_t* rk,
     const unsigned char* cipherKey,
     unsigned short keyBits)
 {
-    unsigned long i;
-    unsigned long temp;
+    unsigned long temp = 0;
 
     rk[0] = GETU32(cipherKey);
     rk[1] = GETU32(cipherKey + 4);
@@ -239,7 +238,7 @@ int CGXCipher::Int(uint32_t* rk,
 
     if (keyBits == 128)
     {
-        for (i = 0; i < 10; i++)
+        for (int i = 0; i < 10; i++)
         {
             temp = rk[3];
             rk[4] = rk[0] ^ TE421(temp) ^ TE432(temp) ^
@@ -259,7 +258,7 @@ int CGXCipher::Int(uint32_t* rk,
 
     if (keyBits == 192)
     {
-        for (i = 0; i < 8; i++)
+        for (int i = 0; i < 8; i++)
         {
             temp = rk[5];
             rk[6] = rk[0] ^ TE421(temp) ^ TE432(temp) ^
@@ -280,7 +279,7 @@ int CGXCipher::Int(uint32_t* rk,
 
     if (keyBits == 256)
     {
-        for (i = 0; i < 7; i++)
+        for (int i = 0; i < 7; i++)
         {
             temp = rk[7];
             rk[8] = rk[0] ^ TE421(temp) ^ TE432(temp) ^
@@ -308,8 +307,8 @@ void CGXCipher::AesEncrypt(
     const unsigned char* pt,
     unsigned char* ct)
 {
-    unsigned long s0, s1, s2, s3, t0, t1, t2, t3;
-    int r;
+    unsigned long s0 = 0, s1 = 0, s2 = 0, s3 = 0, t0 = 0, t1 = 0, t2 = 0, t3 = 0;
+    int r = 0;
     s0 = GETU32(pt) ^ rk[0];
     s1 = GETU32(pt + 4) ^ rk[1];
     s2 = GETU32(pt + 8) ^ rk[2];
@@ -348,12 +347,16 @@ void CGXCipher::Xor(
     unsigned char* dst,
     const unsigned char* src)
 {
+  for (int pos = 0; pos != 16; ++pos)
+    dst[pos] ^= src[pos];
+  /*
     uint32_t* d = (uint32_t*)dst;
     uint32_t* s = (uint32_t*)src;
     *d++ ^= *s++;
     *d++ ^= *s++;
     *d++ ^= *s++;
     *d++ ^= *s++;
+  */
 }
 
 void CGXCipher::shift_right_block(unsigned char* v)
@@ -385,15 +388,14 @@ void CGXCipher::shift_right_block(unsigned char* v)
 
 void CGXCipher::MultiplyH(const unsigned char* x, const unsigned char* y, unsigned char* z)
 {
-    unsigned char tmp[16];
-    int i, j;
+    unsigned char tmp[16] = { 0 };
 
     memset(z, 0, 16);
     memcpy(tmp, y, 16);
 
-    for (i = 0; i < 16; i++)
+    for (int i = 0; i < 16; i++)
     {
-        for (j = 0; j < 8; j++)
+        for (int j = 0; j < 8; j++)
         {
             if (x[i] & 1 << (7 - j))
             {
@@ -419,11 +421,11 @@ void CGXCipher::GetGHash(
     int xlen,
     unsigned char* y)
 {
-    int m, i;
+    int m = xlen / 16;
     const unsigned char* xpos = x;
-    unsigned char tmp[16];
-    m = xlen / 16;
-    for (i = 0; i < m; i++)
+    unsigned char tmp[16] = { 0 };
+
+    for (int i = 0; i < m; i++)
     {
         Xor(y, xpos);
         xpos += 16;
@@ -449,7 +451,7 @@ void CGXCipher::Init_j0(
     const unsigned char* H,
     unsigned char* J0)
 {
-    unsigned char tmp[16];
+    unsigned char tmp[16] = {0};
     //IV length.
     if (len == 12)
     {
@@ -473,16 +475,15 @@ void CGXCipher::Init_j0(
 
 void CGXCipher::Inc32(unsigned char* block)
 {
-    unsigned long val;
-    val = GETU32(block + 16 - 4);
+    unsigned long val = GETU32(block + 16 - 4);
     val++;
     PUT32(block + 16 - 4, val);
 }
 
 void CGXCipher::Gctr(unsigned int* aes, const unsigned char* icb, unsigned char* in, int len, unsigned char* out)
 {
-    size_t i, n, last;
-    unsigned char cb[16], tmp[16] = { 0 };
+    size_t n = 0, last = 0;
+    unsigned char cb[16] = { 0 }, tmp[16] = { 0 };
     unsigned char* pin = in;
     unsigned char* pout = out;
     if (len == 0)
@@ -493,7 +494,7 @@ void CGXCipher::Gctr(unsigned int* aes, const unsigned char* icb, unsigned char*
     memcpy(cb, icb, 16);
 
     //Full blocks.
-    for (i = 0; i < n; i++)
+    for (size_t i = 0; i < n; i++)
     {
 
         if (out == NULL)
@@ -515,7 +516,7 @@ void CGXCipher::Gctr(unsigned int* aes, const unsigned char* icb, unsigned char*
     if (last)
     {
         AesEncrypt(aes, aes[60], cb, tmp);
-        for (i = 0; i < last; i++)
+        for (size_t i = 0; i < last; i++)
         {
             if (out == NULL)
             {
@@ -533,7 +534,7 @@ void CGXCipher::Gctr(unsigned int* aes, const unsigned char* icb, unsigned char*
 
 void CGXCipher::AesGcmGctr(unsigned int* aes, const unsigned char* J0, unsigned char* in, int len, unsigned char* out)
 {
-    unsigned char J0inc[16];
+    unsigned char J0inc[16] = { 0 };
     if (len == 0)
     {
         return;
@@ -547,7 +548,7 @@ void CGXCipher::AesGcmGctr(unsigned int* aes, const unsigned char* J0, unsigned
 void CGXCipher::AesGcmGhash(const unsigned char* H, const unsigned char* aad, int aad_len,
     const unsigned char* crypt, int crypt_len, unsigned char* S)
 {
-    unsigned char len_buf[16];
+    unsigned char len_buf[16] = { 0 };
     GetGHash(H, aad, aad_len, S);
     GetGHash(H, crypt, crypt_len, S);
     //Here is expected that data is newer longger than 32 bit.
@@ -574,7 +575,7 @@ int CGXCipher::Encrypt(
     //    printf("key: %s\r\n", key.ToHexString().c_str());
     //    printf("Authentication Key: %s\r\n", m_AuthenticationKey.ToHexString().c_str());
 #endif //defined(_WIN32) || defined(_WIN64) || defined(__linux__)//If Windows or Linux
-    int ret;
+    int ret = DLMS_ERROR_CODE_OK;
     uint32_t aes[61] = { 0 };
     unsigned char H[16] = { 0 };
     unsigned char J0[16] = { 0 };
@@ -707,11 +708,11 @@ int CGXCipher::Decrypt(
     DLMS_SECURITY_SUITE& suite,
     uint64_t& InvocationCounter)
 {
-    unsigned long length;
-    int ret;
-    unsigned char ch;
-    unsigned long frameCounter;
-    DLMS_COMMAND cmd;
+    unsigned long length = 0;
+    int ret = DLMS_ERROR_CODE_OK;
+    unsigned char ch = 0;
+    unsigned long frameCounter = 0;
+    DLMS_COMMAND cmd = DLMS_COMMAND_NONE;
     CGXByteBuffer* pTitle = &title;
     CGXByteBuffer systemTitle, countTag;
     if (data.GetSize() - data.GetPosition() < 2)
@@ -820,12 +821,12 @@ int CGXCipher::Aes1Encrypt(
     unsigned short offset,
     CGXByteBuffer& secret)
 {
-    unsigned char buf1, buf2, buf3, buf4, round, i;
+    unsigned char buf1 = 0, buf2 = 0, buf3 = 0, buf4 = 0;
     unsigned char* key = secret.m_Data;
     unsigned char* data = buff.m_Data;
-    for (round = 0; round < 10; ++round)
+    for (int round = 0; round < 10; ++round)
     {
-        for (i = 0; i < 16; ++i)
+        for (int i = 0; i < 16; ++i)
         {
             data[i + offset] = S_BOX[(data[i + offset] ^ key[i]) & 0xFF];
         }
@@ -851,7 +852,7 @@ int CGXCipher::Aes1Encrypt(
 
         if (round < 9)
         {
-            for (i = 0; i < 4; i++)
+            for (int i = 0; i < 4; i++)
             {
                 buf4 = (i << 2);
                 buf1 = (data[buf4 + offset] ^ data[buf4 + 1 + offset]
@@ -882,13 +883,13 @@ int CGXCipher::Aes1Encrypt(
         key[1] = (S_BOX[key[14] & 0xFF] ^ key[1]);
         key[2] = (S_BOX[key[15] & 0xFF] ^ key[2]);
         key[3] = (S_BOX[key[12] & 0xFF] ^ key[3]);
-        for (i = 4; i < 16; i++)
+        for (int i = 4; i < 16; i++)
         {
             key[i] = (key[i] ^ key[i - 4]);
         }
     }
 
-    for (i = 0; i < 16; i++)
+    for (int i = 0; i < 16; i++)
     {
         data[i + offset] = (data[i + offset] ^ key[i]);
     }
@@ -899,28 +900,28 @@ int CGXCipher::Aes1Decrypt(
     CGXByteBuffer& buff,
     CGXByteBuffer& secret)
 {
-    unsigned char buf1, buf2, buf3, round, i;
-    int buf4;
+    unsigned char buf1 = 0, buf2 = 0, buf3 = 0;
+    int buf4 = 0;
     CGXByteBuffer key2;
     key2.Set(&secret, 0, secret.GetSize());
     unsigned char* data = buff.GetData();
     unsigned char* key = key2.GetData();
-    for (round = 0; round < 10; round++) {
+    for (int round = 0; round < 10; round++) {
         key[0] = (S_BOX[key[13] & 0xFF] ^ key[0] ^ R_CON[round]);
         key[1] = (S_BOX[key[14] & 0xFF] ^ key[1]);
         key[2] = (S_BOX[key[15] & 0xFF] ^ key[2]);
         key[3] = (S_BOX[key[12] & 0xFF] ^ key[3]);
-        for (i = 4; i < 16; i++) {
+        for (int i = 4; i < 16; i++) {
             key[i] = (key[i] ^ key[i - 4]);
         }
     }
 
-    for (i = 0; i < 16; i++) {
+    for (int i = 0; i < 16; i++) {
         data[i] = (data[i] ^ key[i]);
     }
 
-    for (round = 0; round < 10; ++round) {
-        for (i = 15; i > 3; --i) {
+    for (int round = 0; round < 10; ++round) {
+        for (int i = 15; i > 3; --i) {
             key[i] = (key[i] ^ key[i - 4]);
         }
         key[0] = (S_BOX[key[13] & 0xFF] ^ key[0] ^ R_CON[9 - round]);
@@ -929,7 +930,7 @@ int CGXCipher::Aes1Decrypt(
         key[3] = (S_BOX[key[12] & 0xFF] ^ key[3]);
 
         if (round > 0) {
-            for (i = 0; i < 4; i++) {
+            for (int i = 0; i < 4; i++) {
                 buf4 = (i << 2) & 0xFF;
 
                 buf1 = GaloisMultiply(
@@ -977,7 +978,7 @@ int CGXCipher::Aes1Decrypt(
         data[11] = data[15];
         data[15] = buf1;
 
-        for (i = 0; i < 16; i++) {
+        for (int i = 0; i < 16; i++) {
             data[i] = (S_BOX_REVERSED[data[i] & 0xFF] ^ key[i]);
         }
     }
-- 
2.36.1.windows.1

