Declare an union
between the double
you need to encrypt, and a uint8_t
array of the same size.
To encrypt, fill in the double, encrypt the bytes. To decrypt, decrypt the bytes and read off the double.
This approach can be extended to any non-byte data type, provided the cypher you use outputs same-size messages.
In case of padding, the faster approach of "get a uint8_t *
to whatever your data iswill sometimes work, sometimes not; AES-256 will work with a
doubleof size 8, but block implementations are liable to crash or corrupt data when working with a
floatof size 4 (they will attempt to read 8 bytes, and write 8 bytes; where only four are actually available). Due to platform and compiler quirks, this may *still* work because after the
float` there might be some "memory padding" available.
To be safe, if for example the cypher is padded to 256 bits (32 bytes), you will have to fix the length of the byte array to be likewise padded. One not-so-clean way of doing this is to increase byte count by a whole padding count:
#include <stdio.h>
typedef struct {
double a;
long v;
// Whatever else.
// ...
} payload_t;
union {
payload_t payload;
unsigned char bytes[sizeof(payload_t)+32]; // 256 bits of margin
} data;
int main(void)
{
data.payload.a = 3.14159;
data.payload.v = 123456789;
...
// Encrypt data.bytes, for a length integer multiple of 32 bytes
size_t length = ((sizeof(payload_t)+31)/32)*32;