My goal is to not use the EVP
functions from OpenSSL
. I know this is possible because I basically broke down thousands of lines of C code for the key derivation to a standalone embedded program and it was not easy.
But now I would like to actually encrypt/decrypt data. The two functions are assembly routines found in /crypto/aes/aesni-x86_64.s
, actually. I'm just a bit burned out from reading more code. I'm looking for the direct functions that just do the encryption using the AES_256_CBC
cipher or AES_256_GCM
. I found the aes_gcm_encrypt
in crypto/modes/aesni-gcm-x86_64.s
This code takes the string in in
and encrypts it to tmp
, then decrypts it back to out
but it doesn't actually decrypt correctly. Any ideas? Am I missing other routines before using the actual assembly functions? And if so, can someone just point me to where that is?
#include <stdio.h>
#include <string.h>
#include <openssl/aes.h>
int aesni_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
AES_KEY *key);
void aesni_cbc_encrypt(const unsigned char *in,
unsigned char *out,
size_t length,
const AES_KEY *key, unsigned char *ivec, int enc);
int main()
{
int i;
unsigned char key[] = "\xE0\xE6\x0C\x86\xF1\x10\xF5\x3A\x4E\x65\x88\x79\x74\xB1\x4E\x3D\x06\x22\x9D\xB9\x4E\x26\x25\xBE\xD1\x18\x2B\x56\x73\xAB\x44\xF3";
unsigned char iv[] = "\x06\x22\x9D\xB9\x4E\x26\x25\xBE\xD1\x18\x2B\x56\x73\xAB\x44\xF3";
unsigned char in[] = "\x64\x6f\x20\x77\x68\x61\x74\x63\x68\x61\x20\x68\x61\x66\x74\x61";
unsigned char out[16];
unsigned char tmp[16];
// print plaintext
size_t blksz = 16;
for (i=0;i<blksz;i++)
printf("%02x ", in[i]);
puts("");
AES_KEY ks;
aesni_set_encrypt_key(key, 256, &ks);
aesni_cbc_encrypt(in, tmp, blksz, &ks, iv, 1); // 1 = encrypt
// print ciphertext
for (i=0;i<blksz;i++)
printf("%02x ", tmp[i]);
puts("");
// decrypt
aesni_set_decrypt_key(key, 256, &ks);
aesni_cbc_encrypt(tmp, out, blksz, &ks, iv, 0); // 0 = decrypt
// print decrypted plaintext
for (i=0;i<blksz;i++)
printf("%02x ", out[i]);
puts("");
return 0;
}
I'm going to answer this question using the first comment made by Dave Thompson.
"That function updates the IV (to allow chained operation) so you decrypt with a different=wrong IV giving a wrong result. You need to either reinitialize the IV before decrypting, or use a copy of the IV not the original for your function calls. (PS: the fact the ivec parameter is NOT declared pointer-to-const hints at this.)"