How can the HC128 streamcipher be used to decrypt a ciphered message in smaller parts? - encryption

I use the HC128 streamcipher in an application where the sender
applies the HC128 cipher on the message, slices the ciphered data
into (fixed size) smaller parts and sends them to the receiver.
The receiver gets these encrypted data chunks but it cannot wait until all parts
arrive to decrypt the whole message. Instead it should decrypt
the individual message parts and use them before all parts arrive.
I tried to realize this concept but it did not work: when I decrypted
the message parts I did not get the original message. Do I misuse
the HC128 streamcipher or is there a missing step? How can I
achieve the expected behavior?
The HC128 source.
#include <iostream>
#include <ecrypt-sync.h>
int main()
{
ECRYPT_ctx sender_ctx;
ECRYPT_ctx receiver_ctx;
unsigned char key[32];
unsigned char iv[32];
unsigned char plaintext[100];
unsigned char ciphertext[100];
unsigned char plaintext_receiver[100];
// SENDER
// ------
// Key and initial value for the example.
for (int i = 0; i < 16; i++)
key[i] = iv[i] = i;
// Initialize sender's encryptor.
ECRYPT_keysetup(&sender_ctx, key, 128, 128);
ECRYPT_ivsetup(&sender_ctx, iv);
// The message to send.
for (int i = 0; i < 24; i++)
plaintext[i] = i;
// Encrypt the message. The ciphertext will be sent in two parts for this example.
ECRYPT_encrypt_bytes(&sender_ctx, plaintext, ciphertext, 24);
// RECEIVER
// --------
// Initialize receiver's decryptor.
ECRYPT_keysetup(&receiver_ctx, key, 128, 128);
ECRYPT_ivsetup(&receiver_ctx, iv);
// First data chunk has received.
ECRYPT_decrypt_bytes(&receiver_ctx, ciphertext, plaintext_receiver, 12);
// Second data chunk has received.
ECRYPT_decrypt_bytes(&receiver_ctx, ciphertext + 12, plaintext_receiver + 12, 12);
for (int i = 0; i < 24; i += 1)
{
if (plaintext[i] != plaintext_receiver[i])
{
std::cout << "Error at index: " << i << "\n";
return -1;
}
}
std::cout << "Everything OK!" << "\n";
return 0;
}

Related

Send struct with string by LoRa (Arduino)

I'm trying to send some data with LoRa but I only receive single chars (line by line) or float, int, byte...
I want to send "msg" like a string.
I have:
struct DATA {
char msg = "";
int valor;
};
DATA MyData;
.
.
.
void loop() {
if (Serial.available() > 0) {
MyData.msg = Serial.read();
MyData.valor = 10;
Transceiver.SendStruct((uint8_t*) &MyData, (uint8_t) sizeof(MyData));
Serial.print("Sending: "); Serial.println(MyData.msg); Serial.println(MyData.valor);
}
}
it works but if I send: "hello world", I will receive:
h
10
e
10
l
10
.
.
.
So I tried to make an aux variable:
if (Serial.available() > 0) {
char aux = Serial.read();
MyData.msg += aux;
MyData.valor = 10;
Transceiver.SendStruct((uint8_t*) &MyData, (uint8_t) sizeof(MyData));
Serial.print("Sending: "); Serial.println(MyData.msg); Serial.println(MyData.valor);
}
But I receive only unrecognized chars.
PS1: If I change struct char with a String, I receive only unrecognized chars.
PS2: I tried to make a "for" with the sizeof on receive to join the chars to make a string, but it doesn't work either.
Thanks in advance.
Your MyData.msg is defined as a char which is a single character instead of an array[]. You need to define your struct as:
#define MAX_STR_LENGTH 20
typedef struct {
char msg[MAX_STR_LENGTH] = '\0'; // an array of char
int valor = 0;
} Data_t;
Data_t Mydata;
You are sending the struct data each time a char is received instead of of waiting for the whole string is received. Assuming the string you received from Serial is terminated with \n. You can read in the whole string by checking with the received char is an \n and only send the struct then.
void loop() {
static int i = 0;
while (Serial.available() > 0) {
char c = Serial.read();
if (c != '\n') {
MyData.msg[i] = c;
i++;
}
else {
// terminate the array with NULL terminator and send the struct
MyData.msg[i] = '\0';
MyData.valor = 10;
Transceiver.SendStruct((uint8_t*) &MyData, (uint8_t) sizeof(MyData));
Serial.print("Sending: ");
Serial.println(MyData.msg);
Serial.println(MyData.valor);
i = 0;
}
}
}
Further reading:
Array
Nick Gammon on Serial

Arduino - how to concatenate byte arrays to get a final array

I have the following Arduino function:
void SendCommandToDisplay(byte message[], byte size)
{
byte header[] = {0x5A, 0xA5};
byte result[] = {};
memcpy(result, header, sizeof(header));
memcpy(result+sizeof(header), message, size);
for (byte i=0; i<sizeof(result); i++)
{
Serial.print(result[i], HEX);
Serial.print(' ');
}
}
Then I call this function as follows:
byte test[]={0x82, 0x20, 0x10, 0x00, 0x03};
SendCommandToDisplay(test, sizeof(test) / sizeof(byte));
And seems is not working, I'm doing something wrong or maybe I have to do a reference or pointer. Any clue?
You are not allocating memory for the result variable - in your case try this:
void SendCommandToDisplay(byte message[], byte size)
{
byte header[] = {0x5A, 0xA5};
byte result[sizeof(header)+size];
memcpy(result, header, sizeof(header));
memcpy(result+sizeof(header), message, size);
for (byte i=0; i<sizeof(result); i++)
{
Serial.print(result[i], HEX);
Serial.print(' ');
}
}
Once simple approach to inserting the byte count (of message) following header is to change how the header is initialized:
byte header[] = {0x5A, 0xA5, size};
Note: a prior edit added an alternative to use the sizeof(message) but that was incorrect and removed - sizeof(message) where message is a parameter returns the sizeof of a pointer which is 2 on an arduino.

How to write 16bit integer to SRAM via Arduino?

The base of the problem: I have an Arduino Due and a MPU6050 accelerometer and an 23lcv512. MPU gives me 16bit signed integer. I would like to save the datas to the SRAM and after the measurement read them back and via Serial send it to PC. Sending to PC is not a problem. The problem is that this SRAM has 128k pcs 8bit address. My numbers are 16 bit. I can't write them directly. Here is my code. I tested the RAM with this code:
`
void loop() {
int i = 0;
Serial.print("Write Byte: ");
for (i = 0; i < 70000; i++) {
//Serial.print("Write Byte: ");
//Serial.print(i);
//Serial.println();
SRAM.writeByte(START_ADDRESS, i);
START_ADDRESS = START_ADDRESS + 1;
}
Serial.print("Write End");
i = 0;
START_ADDRESS = 0;
for (i = 0; i < 300; i++) {
Serial.print("Read Byte: ");
Serial.print(SRAM.readByte(START_ADDRESS));
Serial.println();
Serial.println();
START_ADDRESS = START_ADDRESS + 1;
delay(100);
}
}`
I added the 23LC library. If it's run reads back the numbers from the RAM but after 255 it starts to read 0 again. I know why does it happen. But I don't know howto solve the problem.
I tried to use the writeBlock command but it only works for me with char variables. Char variable requires more space than integers. I have not too much.
Is there anyone who can write a sample code which can write 16 bit signed integer to sram?
I've commented the most obvious problems in your original code below:
void loop() {
int i = 0;
Serial.print("Write Byte: ");
for (i = 0; i < 70000; i++) { // since i is a 16bit int, 70,000 is out of range.
SRAM.writeByte(START_ADDRESS, i); // cool you wrote 1 byte, where is the other write?
START_ADDRESS = START_ADDRESS + 1; // try to keep all caps names for constants.
// this will make your code easier to read, trust me!
}
Serial.print("Write End");
i = 0;
START_ADDRESS = 0;
for (i = 0; i < 300; i++) {
Serial.print("Read Byte: ");
Serial.print(SRAM.readByte(START_ADDRESS)); // you read 1 byte, you can't expect a 16 bit
// value out of that.
Serial.println();
Serial.println();
START_ADDRESS = START_ADDRESS + 1;
delay(100);
}
}
Here's a more sound approach, it stores unsigned ints, but that can easily be changed to signed ints.
#define SRAM_SIZE (128UL << 10) // we have 128K of SRAM available.
// The U and L make this value an unsigned long.
// ALWAYS use unsigned values for addresses.
void loop()
{
Serial.print(F("Writing sequential numbers into SRAM...")); // _always_ store string constants in flash.
// save your RAM for more interesting stuff.
for (unsigned long i = 0; i < SRAM_SIZE; i += 2) // filling SRAM
{
// this is the (truncated from 0-65535) value we'll write.
unsigned int value = static_cast<unsigned int>(i & 0xFFFF);
SRAM.writeByte(i, value & 0xFF); // write lowest 8 bits
SRAM.writeByte(i + 1, (value >> 8) & 0xFF); // write next 8 bits.
}
Serial.println(F("done."));
// read back
Serial.println(F("SRAM contents (16-bits unsigned values):"));
for (unsigned long i = 0; i < SRAM_SIZE; i += 2) // reading all SRAM in 16-bit chunks.
{
Serial.print(i, HEX);
Serial.print(F(": "));
// read two consecutive bytes and pack them into a 16-bit integer.
unsigned int value = SRAM.readByte(i) + (static_cast<unsigned int>(SRAM.readByte(i+1)) << 8); // the cast is necessary.
Serial.println(value);
}
delay(100);
}

Write String to permanent flash memory of Arduino ESP32

I want to write some text into the flash memory of an Arduino ESP32. It works kinda but not as I want it to.
void writeString(const char* toStore, int startAddr) {
int i = 0;
for (; i < LENGTH(toStore); i++) {
EEPROM.write(startAddr + i, toStore[i]);
}
EEPROM.write(startAddr + i, '\0');
EEPROM.commit();
}
My call
writeString("TEST_STRING_TO_WRITE", 0);
only writes TEST into the memory. I do not understand why. Is that because of the _? Or am I missing something different?
Here is the used LENGTH macro
#define LENGTH(x) (sizeof(x)/sizeof(x[0]))
and the method I use to read the string from the memory again (which seems to work correctly):
String readStringFromFlash(int startAddr) {
char in[128];
char curIn;
int i = 0;
curIn = EEPROM.read(startAddr);
for (; i < 128; i++) {
curIn = EEPROM.read(startAddr + i);
in[i] = curIn;
}
return String(in);
}
Where on earth did you get that LENGTH macro from? It’s surreal.
sizeof will not do what you want here. It’s a compile-time function that computes the storage requirements of its argument. In this case it should return the length in bytes of a character pointer, not the string it points to.
You want to use strlen(), assuming your char* is a properly terminated C string. Add one to make sure the ‘\0’ at the end gets stored, too.
#define LENGTH(x) (strlen(x) + 1)
Below is the code to demonstrate the storing as well as retrieving of the string ssid in the EEPROM (permanent storage).
#include "EEPROM.h"
int addr = 0;
#define EEPROM_SIZE 64
// the sample text which we are storing in EEPROM
char ssid[64] = "CARNIVAL OF RUST";
void setup() {
Serial.begin(115200);
Serial.println("starting now...");
if (!EEPROM.begin(EEPROM_SIZE)) {
Serial.println("failed to init EEPROM");
while(1);
}
// writing byte-by-byte to EEPROM
for (int i = 0; i < EEPROM_SIZE; i++) {
EEPROM.write(addr, ssid[i]);
addr += 1;
}
EEPROM.commit();
// reading byte-by-byte from EEPROM
for (int i = 0; i < EEPROM_SIZE; i++) {
byte readValue = EEPROM.read(i);
if (readValue == 0) {
break;
}
char readValueChar = char(readValue);
Serial.print(readValueChar);
}
}
void loop() {
}

Writing data to the Arduino's onboard EEPROM

I am currently trying to write a function to store data to the EEPROM on my Arduino. So far I am just writing a specified string and then reading it back when the program first runs. I am trying to store the length of the string as the first byte and my code is as follows;
#include <EEPROM.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
char string[] = "Test";
void setup() {
lcd.begin( 16, 2 );
for (int i = 1; i <= EEPROM.read(0); i++){ // Here is my error
lcd.write(EEPROM.read(i));
}
delay(5000);
EEPROM_write(string);
}
void loop() {
}
void EEPROM_write(char data[])
{
lcd.clear();
int length = sizeof(data); // I think my problem originates here!
for (int i = 0; i <= length + 2; i++){
if (i == 0){
EEPROM.write(i, length); // Am I storing the length correctly?
lcd.write(length);
}
else{
byte character = data[i - 1];
EEPROM.write(i, character);
lcd.write(character);
}
}
}
The problem I am having is when I read the first byte of the EEPROM, I get the supposed length value. However, the loop only runs three times. I have commented some points of interest in my code, but where is the error?
You are indeed correct, on many counts, I think. Try this for writing:
// Function takes a void pointer to data, and how much to write (no other way to know)
// Could also take a starting address, and return the size of the reach chunk, to be more generic
void EEPROM_write(void * data, byte datasize) {
int addr = 0;
EEPROM.write(addr++, datasize);
for (int i=0; i<datasize; i++) {
EEPROM.write(addr++, data[i]);
}
}
You would call it like this:
char[] stringToWrite = "Test";
EEPROM_write(stringToWrite, strlen(stringToWrite));
To read then:
int addr = 0;
byte datasize = EEPROM.read(addr++);
char stringToRead[0x20]; // allocate enough space for the string here!
char * readLoc = stringToRead;
for (int i=0;i<datasize; i++) {
readLoc = EEPROM.read(addr++);
readLoc++;
}
Note that this is not using the String class developed for Arduino: reading and writing that would be different. But the above should work for char array strings.
Note however, that while EEPROM_write() looks generic now, it isn't really, since addr is harcoded. It can only write data to the beginning of EEPROM.

Resources