AES128 Decypher - Not able to pass exact char array into uint8_t variable

Hi there, I am working on a EAS128 Cypher-Decypher code and have been struggling with passing a char array into a uint8_t variable.

The uint8_t variable is needed to fill the following "input" variable, which is a uint8_t type.

AES128.runDec(key, 16, input, 16, dec_iv)

I prepared the following brief sketch, which basically copies a string that has been converted into a 32-char array, but when copying it into the uint8_t variable it "arrives" as a 64-char, for it is passed as an HEX byte for each original char.

The code output as follows:

What I need to perform is the filling of the uint8_t variable, with the 32-char array - each char one by one - without changing it from its value to its HEX equivalent.

Any advice or a site to look at for sorting out the issue, or maybe a book, paper or so? THX in advance!

#include <Arduino.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>

//uint8_t arr[16] = {0x65,0xd0,0xf7,0x75,0x8b,0x09,0x41,0x14,0xaf,0xa6,0xd3,0x3a,0x5e,0xa0,0x71,0x6a};
uint8_t arr[16] ;
uint8_t inputt[16] ;
String TestStringinput,TestStringinputMirror;
char charBuf[33];

void setup()
{
   Serial.begin(9600);
   while (!Serial);
   Serial.println("Present Sketch name -> varibleExchange.ino ");
   Serial.println("");

}

void loop()
{

  Serial.print("inputt at the beginning                   ... ");printHex(inputt, 16);Serial.println("");
  Serial.print("arr at the beginning                      ... ");printHex(arr, 16);Serial.println("");

  auto itr = arr;
  auto assign = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01};
  std::copy(assign.begin(), assign.end(), itr);

  Serial.print("arr after Re-assigning                    ... ");printHex(arr, 16);;Serial.println("");
  Serial.println("");

  TestStringinput="65D0F7758B094114AFA6D33A5EA0716A";
  TestStringinputMirror=TestStringinput;
  TestStringinput.toCharArray(charBuf, 33);

  Serial.print("TestStringinput                           ... ");Serial.print(TestStringinput);Serial.println("");
  Serial.print("charBuf as a String                       ... ");Serial.print(String(charBuf));Serial.println("");
  Serial.print("charBuf as a char                         ... ");Serial.print(charBuf);Serial.println("");

  Serial.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");

  Serial.print("inputt variable before copying the string ... ");printHex(inputt, 16);
  Serial.println("");
 
  std::copy(TestStringinput.begin(),TestStringinput.end(), std::begin(arr));
  std::copy(TestStringinputMirror.begin(),TestStringinputMirror.end(), std::begin(inputt));
 
  Serial.print("inputt after copying the string           ... ");printHex(inputt, 32);Serial.println("");
  Serial.print("final arr status                          ... ");printHex(arr, 32);Serial.println("");
  Serial.println("");
 
  while(1);
}

void printHex(uint8_t *text, size_t size) {
  for (byte i = 0; i < size; i = i + 1) {
    if (text[i] < 16) {
      Serial.print("0");
    }
    Serial.print(text[i], HEX);
  }
}

Why do you think it is necessary to distinguish between or work with the two types? uint8_t is the same as unsigned char. Just work with char arrays and you will be fine.

without changing it from its value to its HEX equivalent

Sorry, that makes no sense to me. HEX is a human readable ASCII representation of a binary number.

As for copying char arrays, I suggest to use the C-string routines, or memcpy() for binary data. e.g.

char in[16]={0x65,0xd0,0xf7,0x75,0x8b,0x09,0x41,0x14,0xaf,0xa6,0xd3,0x3a,0x5e,0xa0,0x71,0x6a};
char out[16]={0};
memcpy(out,in,16);

Hi jremington, many thanks for your prompt response!

About my comment " ... without changing it from its value to its HEX equivalent ....", not making sense to you, please consider the following explanation to clear any misunderstandings, produced on my behalf. I am including - at the end - the sketch with the AES128 class where you may check the uint8_t variable needing to receive its content as a collection of bytes ....

EXPLANATION

(1) The following Cyphered TEXT -> 65D0F7758B094114AFA6D33A5EA0716A -> is received as a string in a remote located ARDUINO 33IoT device. However, the Cyphered TEXT originally is a uint8_t [16] variable, therefore the Cyphered TEXT sent as a string, originally is ->

0x65, 0xD0, 0xF7, 0x75, 0x8B, 0x09, 0x41, 0x14, 0xAF, 0xA6, 0xD3, 0x3A, 0x5E, 0xA0, 0x 71, 0x6A

i.e 16 bytes in Length, but sent as a string from a backend to a frontend device

(2) At the frontend side, the Cyphered TEXT is used as an input in the following class ->

    AES128.runDec(key, 16, input, 16, dec_iv);

Where input is a uint8_t variable, within the class AES128 (BTW, there is not much backup info at github, available site for the class AES128)

(3) According to the latter, the original uint8_t 0x65, 0xD0, 0xF7, 0x75, 0x8B, 0x09, 0x41, 0x14, 0xAF, 0xA6, 0xD3, 0x3A, 0x5E, 0xA0, 0x 71, 0x6A, now “received” as a string “65D0F7758B094114AFA6D33A5EA0716A” - NEEDS TO BE CONVERTED back to its original format, i.e. uint8_t; otherwise, it will not fit into the AES128 class “input” variable, for it is defined as a uint8_t type.

(4) input variable needs to “receive” 16 bytes. When copying the string “65D0F7758B094114AFA6D33A5EA0716A”, which contains char – NOT Byte – to any other variable, each char “arrives” as a byte, therefore

“65D0F7758B094114AFA6D33A5EA0716A”
shall be
3635443046373735384230393431313441464136443333413545413037313641

REQUEST
What is finally needed is to pass each char of "65D0F7758B094114AFA6D33A5EA0716A" - as if it is a byte - into the "input" variable of class AES128, e.g. "65" string must arrive as 0x65, "D0" must arrive as 0xD0, and do on till final "6A" having to arrive as 0x6A

I am wrongly copying "65D0F7758B094114AFA6D33A5EA0716A", in such a way that it arrives into the "input" variable of the class AES128 as a BYTE, e.g. 6 arrives as 36; 5 arrives as 35 and so on, completing all original 32 chars in the string, but copied as 64 HEX char.


//Notes for decypher checking
//*********************************************************************************************
//AES128 Decryption of 'F8EC2769085E888FA68FC6309FA0451E' is 0x41726475696E6F41726475696E6F0000 
//IV_Enc               : 65D0F7758B094114AFA6D33A5EA0716A 
//MENSAJE ENCRIPTADO   : F8EC2769085E888FA68FC6309FA0451E
//*********************************************************************************************

//libraries needed to convert char variables into uint8_t
//-------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <string>
using namespace std;
//-------------------------------------------------------

#include <stdlib.h>

#include <ArduinoBearSSL.h>
#include "AES128.h"

// AES128 class declaration
//-------------------------------------------------------
#ifdef ARDUINO_ARCH_MEGAAVR
// Create the object
AES128Class AES128;
#endif

//-------------------------------------------------------

uint8_t key[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02};
uint8_t enc_iv[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01};
//uint8_t dec_iv[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01};
//uint8_t input[16] = "ArduinoArduino"; // {0x41,0x72,0x64,0x75,0x69,0x6E,0x6F,0x41,0x72,0x64,0x75,0x69,0x6E,0x6F,0x00,0x00}

uint8_t dec_iv[16] = {0x65,0xd0,0xf7,0x75,0x8b,0x09,0x41,0x14,0xaf,0xa6,0xd3,0x3a,0x5e,0xa0,0x71,0x6a};
//iv_dec   => 65 D0 F7 75 8B 09 41 14 AF A6 D3 3A 5E A0 71 6A 
uint8_t input[16] = {0xf8,0xec,0x27,0x69,0x08,0x5E,0x88,0x8f,0xa6,0x8f,0xc6,0x30,0x9f,0xa0,0x45,0x1e};
//input   => F8 EC 27 69 08 5E 88 8F A6 8F C6 30 9F A0 45 1E
uint8_t inputRef[16] = {0x41,0x72,0x64,0x75,0x69,0x6E,0x6F,0x41,0x72,0x64,0x75,0x69,0x6E,0x6F,0x00,0x00};

uint8_t inputR[16];
uint8_t dec_ivR[16];
uint8_t arr[16]; // variable to cnevert String into char 
  
char TestCharinput[3]; // Consider deleting

char  charBuf[32];
char* charinput;
          
String EncryptedPost ="65D0F7758B094114AFA6D33A5EA0716AF8EC2769085E888FA68FC6309FA0451E";
//String EncryptedPost ="F8EC2769085E888FA68FC6309FA0451E663B3A72515695AE3748F8A7E08DC6C7";
//String EncryptedPost ="E89D5BE11DFC4295C9E13E2A250F4C85A1F1D8A79256DC6961E96B597DFA6867";
String PostRx="",PostRx_iv="",PostRx_input="";

String str,TestString = "",TestStringinput = "",TestStringoutputI="",TestStringoutput="";

String DECRYPTEDinput = " ";
String DECRYPTEDinputRef = " ";

boolean StatusVector[7]; // starts in 0 and ends in 5
boolean Flag;

void setup() 
{

  Serial.begin(9600);
  while (!Serial);

  //Status Vector initialisation
  //----------------------------
  StatusVector[0]=false;
  StatusVector[1]=false;
  StatusVector[2]=false;
  StatusVector[3]=false;
  StatusVector[4]=false; 
  StatusVector[5]=false; 
  StatusVector[6]=false; 
  //---------------------------

  Serial.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
  Serial.println("64 char length iV+Encrypted POST Decrypting Programme // Test1_AES128_SoloDecV2.1");
  Serial.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
  Serial.println(" ");
  //Serial.println("------------------------------------------------------------------------------");
  Serial.print("Message to decrypt =>  ");Serial.println(EncryptedPost);
  Serial.println(" ");
  Serial.println("-------------------------------------------------------------------------------------------------------------------------------------------");
  
}

void loop() 
{
  PostRx = EncryptedPost;
  PostRx_iv = PostRx.substring(0,32);
  PostRx_input = PostRx.substring(32,64);
  Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
  Serial.print("PostRx_iv    ... CHOPPED //");Serial.print(PostRx_iv);Serial.println("// ");
  Serial.print("PostRx_input ... CHOPPED //");Serial.print(PostRx_input);Serial.println("// ");
  Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

  //Converting a String into a byte array of Char in Hexa
  //-----------------------------------------------------

  //dataString.toCharArray(dataArray, dataString.length()); //  <- EXAMPLE
  PostRx_iv.toCharArray(charBuf, 33);
  
  //TestStringinput="65D0F7758B094114AFA6D33A5EA0716A";     // only for test purposes
  //TestStringinput="FooFooFooFooXxxXF";                    // only for test purposes
 
  //+++++++++++++++++++++++++++++++++++++++++++++
  TestStringinput=PostRx_iv;  // This variable cannot be larger than 16 Char. After char 16 it does not consider it!
  //+++++++++++++++++++++++++++++++++++++++++++++
  
  Serial.print("TestStringinput as String         => ");Serial.print(TestStringinput);Serial.println("");  

  std::copy(TestStringinput.begin(),TestStringinput.end(), std::begin(arr));

  char* input22 = (char *) arr;   
  TestStringoutputI = String(input22); 
  TestStringoutput = TestStringoutputI;    

  Serial.print("arr is TestStringinput as CHAR    => ");printHex(arr,16);Serial.println("");

  if(TestStringoutput.length()>16)
  {
    TestStringoutput = TestStringoutputI.substring(0,TestStringinput.length()); 
    Serial.println("Warning TestStringintput is larger than 16 !");
  }
  
  Serial.print("TestStringoutput                  => ");Serial.print(input22);Serial.println("");
  
  Serial.print("TestStringoutput back to original => ");Serial.print(TestStringoutput);Serial.println("");

  TestStringoutput = "";
  TestStringoutputI = "";
  
  Serial.println("xxxxxxxxxxxxxxxxxxxxxxxx --- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

  Serial.print("charBuf in in CHAR  -----> ");Serial.println(charBuf);
  Serial.print("PostRx_iv in STRING -----> ");Serial.println(PostRx_iv);
 
  //-----------------------------------------------------

  //Serial.println("------------------------------------------------------------------------------");
  
  Serial.print("iV received & BEFORE Decryption //");
  printHex(dec_iv, 16);

  Serial.print("// for the Message  //"); printHex(input, 16);Serial.print("// To be Decrypted ");
  Serial.println(" ");
  Serial.println(" ");
 
  Serial.print("AES128 Decryption of //");
  printHex(input, 16);
  Serial.println("");
  
  Serial.print("// is //0x");
  AES128.runDec(key, 16, input, 16, dec_iv);
  printHex(input, 16);

  //Converting a byte array of Char - in HEX - into String
  //---------------------------------------------------
   char* input2 = (char *) input;
   DECRYPTEDinput = String(input2);     //Actual data
   char* input3 = (char *) inputRef;  
   DECRYPTEDinputRef = String(input3);  //Reference data to test the decrypting METHOD
  //---------------------------------------------------

  Serial.print("// for the original Message => //");Serial.print(DECRYPTEDinput);Serial.print("//");
  Serial.println(" ");
  Serial.println(" ");

  Serial.print("IV_Dec after Decrypted: ");
  printHex(dec_iv, 16);
  Serial.println(" ");
  Serial.print("Key: ");
  printHex(key, 16);
  Serial.println(" ");

if(DECRYPTEDinput == DECRYPTEDinputRef)
{
  Serial.println("");
  Serial.println("B I N G O => Decrypting process Complete & Successfull !");
  Serial.println(""); 
}

   DECRYPTEDinput ="";
   DECRYPTEDinputRef ="";

  // consider deleting when fully operational
  //---------------------------------------------
  StatusVector[0]=true;
  StatusVector[1]=true;
  StatusVector[2]=true;
  StatusVector[3]=true;
  StatusVector[4]=true; 
  StatusVector[5]=true; 
  StatusVector[6]=false; 
  //---------------------------------------------

  Flag =  StatusVector[0] &&  StatusVector[1] &&  StatusVector[2] &&  StatusVector[3] &&  StatusVector[4] &&  StatusVector[5] &&  StatusVector[6]; 
  if(Flag){Serial.println("EXCELLENT HIT !");}
  else {Serial.println("K U A K !");}
   
Serial.println("-------------------------------------------------------------------------------------------------------------------------------------------");
delay(2000);

while(1);

}

void printHex(uint8_t *text, size_t size) {
  for (byte i = 0; i < size; i = i + 1) {
    if (text[i] < 16) {
      Serial.print("0");
    }
    Serial.print(text[i], HEX);
  }
}

Edit: sorry I didn't understand your problem

Hi giux, I'm sending this message after I edited the original one. Perhaps you reached the post while I was still editing it. Any idea you may share is more than welcome. THX in advance!

REQUEST
What is finally needed is to pass each char of "65D0F7758B094114AFA6D33A5EA0716A" - as if it is a byte - into the "input" variable of class AES128, e.g. "65" string must arrive as 0x65, "D0" must arrive as 0xD0, and do on till final "6A" having to arrive as 0x6A

I am wrongly copying "65D0F7758B094114AFA6D33A5EA0716A", in such a way that it arrives into the "input" variable of the class AES128 as a BYTE, e.g. 6 arrives as 36; 5 arrives as 35 and so on, completing all original 32 chars in the string, but copied as 64 HEX char.

Something like this ? w7ViNp - Online C++ Compiler & Debugging Tool - Ideone.com

Many THX - Good Thread!

I think your real problem here.
Why do you sent original uint8_t [16] variable as TEXT? So why do you first convert it to two-char HEX representation so that you forced then convert it back? Why not send this array of bytes as bytes, without converting to a hex string?

It seems to me that you first created a problem for yourself, and now you are trying to solve it.

Good Point - I do not have control over the sender. However, will try to ask the sender to change the type used. Thx!

In the mean time, still needing to copy the sting type into the uint8_t type varibale.
Thx again!

I updated code in the previous link

But I agree with b707, it could be simplified :slight_smile:

Convert the incoming data to binary, and consistently use binary internally.

Indeedd - I was trying to leave this approach till the end ... It seems we have reached "The End"

THX, all very useful comments.Cheers!

That was a mistake. Unfortunately both your explanation of the problem, your attempt to solve the problem and the code are all difficult to understand. Even the post title is confusing, because "uint8_t" IS a char variable type.

No doubt it is difficult. I thought that writing the whole issue would be better, however, it wasn´t. Next time I will only place the request, that in this case was:

REQUEST
Need to pass each char of "65D0F7758B094114AFA6D33A5EA0716A" - as if it is a byte - into the "input" variable of class AES128, e.g. "65" string must arrive as 0x65, "D0" must arrive as 0xD0, and do on till final "6A" having to arrive as 0x6A - How can it be done?

Thanks again,
JP

Treat the string in exactly the same way you would handle binary data.

Each char of the ASCII string "65 ... IS a byte. The value of the first byte, the ASCII character for the decimal digit 6, is in human readable hex representation 0x36.

Doing so doubles the amount of work you have to do to encrypt or decrypt the data, because the data arrays are twice as long.

Hi jremington, still stuck with this issue. I've given a deeper thought to the subject and what I need to sort out is the following:

How to pass a byte into a Uint8_t type variable, e.g.

uint8_t myVar[1] = {0x65};
String myText ="FF";

Begin
"Supose we have a BBox here that places the FF into the myVar"
End

The outputs B E F O R E the black box would be => for myVar .... 65
The output A F T E R the black box would be => for myVar ... FF , but NOT 46 46

I can always place into myVar any byte "by hand" - so to speak - through {0xFF}

so

How can it be done without the "by hand" way. Is there any Re-¨pointing technique?

Please run this code to see what happens ...

#include <Arduino.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>

//uint8_t arr[16] = {0x65,0xd0,0xf7,0x75,0x8b,0x09,0x41,0x14,0xaf,0xa6,0xd3,0x3a,0x5e,0xa0,0x71,0x6a};
uint8_t arr[16] ;
uint8_t inputt[16] ;
String TestStringinput,TestStringinputMirror;
char charBuf[33];

void setup()
{
   Serial.begin(9600);
   while (!Serial);
   Serial.println("Present Sketch name -> varibleExchange.ino ");
   Serial.println("");

}

void loop()
{

  Serial.print("inputt at the beginning                   ... ");printHex(inputt, 16);Serial.println("");
  Serial.print("arr at the beginning                      ... ");printHex(arr, 16);Serial.println("");

  auto itr = arr;
  auto assign = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01};
  std::copy(assign.begin(), assign.end(), itr);

  Serial.print("arr after Re-assigning                    ... ");printHex(arr, 16);;Serial.println("");
  Serial.println("");

  TestStringinput="65D0F7758B094114AFA6D33A5EA0716A";
  TestStringinputMirror=TestStringinput;
  TestStringinput.toCharArray(charBuf, 33);

  Serial.print("TestStringinput                           ... ");Serial.print(TestStringinput);Serial.println("");
  Serial.print("charBuf as a String                       ... ");Serial.print(String(charBuf));Serial.println("");
  Serial.print("charBuf as a char                         ... ");Serial.print(charBuf);Serial.println("");

  Serial.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");

  Serial.print("inputt variable before copying the string ... ");printHex(inputt, 16);
  Serial.println("");
 
  std::copy(TestStringinput.begin(),TestStringinput.end(), std::begin(arr));
  std::copy(TestStringinputMirror.begin(),TestStringinputMirror.end(), std::begin(inputt));
 
  Serial.print("inputt after copying the string           ... ");printHex(inputt, 32);Serial.println("");
  Serial.print("final arr status                          ... ");printHex(arr, 32);Serial.println("");
  Serial.println("");
 
  while(1);
}

void printHex(uint8_t *text, size_t size) {
  for (byte i = 0; i < size; i = i + 1) {
    if (text[i] < 16) {
      Serial.print("0");
    }
    Serial.print(text[i], HEX);
  }
}

Thanks in advance
JP

The String class has no place in your code. Get rid of it and put it out of your mind.

Sorry, I have no idea what you are trying to say. To "pass a byte into a uint8_t variable" use the "=" operator. To copy multiple bytes into an array, use memcpy().

this syntax is fine:

uint8_t myVar= 0x65;

But I suppose it is not what you want....

OK - I think I have seen the light at the end of the tunnel ... Finally I need to convert this char array .... builderBuf = 0xBB into a byte, e.g. BytebuilderBuf = 0xBB.
Any clue or link to look at?

Thanks in advance
JP

To copy one byte from a char array to a uint8_t variable, use "=". For example:

uint8_t var = builderBuf[7];

Please take the time to phrase a sensible question.