Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explicit initialization vector to aes_encrypt() #618

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 34 additions & 10 deletions src/dyn_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <openssl/rsa.h>
#include <openssl/ssl.h>
#include <stdio.h>
#include <string.h>

#include "dyn_core.h"
#include "dyn_crypto.h"
Expand Down Expand Up @@ -264,27 +265,47 @@ base64_decode(const char *b64message, const size_t length, unsigned char
}
*/

rstatus_t aes_encrypt(const unsigned char *msg, size_t msg_len,
unsigned char **enc_msg, unsigned char *arg_aes_key) {
rstatus_t aes_encrypt(const unsigned char *original_msg,
size_t original_msg_len, unsigned char **enc_msg,
unsigned char *arg_aes_key) {
int block_len = 0;
int enc_msg_len = 0;

// Create a new plaintext, with an additional block of randomness prepended
// as an explicit initialization vector.
size_t msg_len = original_msg_len + AES_BLOCK_SIZE;
unsigned char *msg = malloc(msg_len);

if (RAND_bytes(msg, AES_BLOCK_SIZE) == 0) {
log_debug(LOG_VERB,
"RAND_bytes failed to generate an explicit iv for : '%.*s':",
original_msg_len,
original_msg);
return DN_ERROR;
}

int i;
for (i = 0; i < original_msg_len; i++) {
msg[i+AES_BLOCK_SIZE] = original_msg[i];
}

// Malloc enough room for the new plaintext and the final block of padding.
*enc_msg = (unsigned char *)malloc(msg_len + AES_BLOCK_SIZE);
if (*enc_msg == NULL) return DN_ERROR;

// if(!EVP_EncryptInit_ex(aes_encrypt_ctx, aes_cipher, NULL, arg_aes_key,
// aes_iv)) {
if (!EVP_EncryptInit_ex(aes_encrypt_ctx, aes_cipher, NULL, arg_aes_key,
arg_aes_key)) {
log_debug(LOG_VERB, "This is bad data in EVP_EncryptInit_ex : '%.*s'",
msg_len, msg);
free(msg);
return DN_ERROR;
}

if (!EVP_EncryptUpdate(aes_encrypt_ctx, *enc_msg, &block_len,
(unsigned char *)msg, (int)msg_len)) {
log_debug(LOG_VERB, "This is bad data in EVP_EncryptUpdate : '%.*s'",
msg_len, msg);
free(msg);
return DN_ERROR;
}
enc_msg_len += block_len;
Expand All @@ -293,9 +314,12 @@ rstatus_t aes_encrypt(const unsigned char *msg, size_t msg_len,
&block_len)) {
log_debug(LOG_VERB, "This is bad data in EVP_EncryptFinal_ex : '%.*s'",
msg_len, msg);
free(msg);
return DN_ERROR;
}

free(msg);

// EVP_CIPHER_CTX_cleanup(aesEncryptCtx);

return enc_msg_len + block_len;
Expand All @@ -308,8 +332,6 @@ rstatus_t dyn_aes_encrypt(const unsigned char *msg, size_t msg_len,

ASSERT(mbuf != NULL && mbuf->last == mbuf->pos);

// if(!EVP_EncryptInit_ex(aes_encrypt_ctx, aes_cipher, NULL, arg_aes_key,
// aes_iv)) {
if (!EVP_EncryptInit_ex(aes_encrypt_ctx, aes_cipher, NULL, arg_aes_key,
arg_aes_key)) {
loga_hexdump(
Expand Down Expand Up @@ -362,8 +384,6 @@ rstatus_t dyn_aes_decrypt(unsigned char *enc_msg, size_t enc_msg_len,

ASSERT(mbuf != NULL && mbuf->start == mbuf->pos);

// if(!EVP_DecryptInit_ex(aes_decrypt_ctx, aes_cipher, NULL, arg_aes_key,
// aes_iv)) {
if (!EVP_DecryptInit_ex(aes_decrypt_ctx, aes_cipher, NULL, arg_aes_key,
arg_aes_key)) {
loga_hexdump(
Expand Down Expand Up @@ -475,8 +495,6 @@ rstatus_t aes_decrypt(unsigned char *enc_msg, size_t enc_msg_len,
*dec_msg = (unsigned char *)malloc(enc_msg_len);
if (*dec_msg == NULL) return DN_ERROR;

// if(!EVP_DecryptInit_ex(aes_decrypt_ctx, aes_cipher, NULL, arg_aes_key,
// aes_iv)) {
if (!EVP_DecryptInit_ex(aes_decrypt_ctx, aes_cipher, NULL, arg_aes_key,
arg_aes_key)) {
log_debug(LOG_VERB, "This is bad data in EVP_DecryptInit_ex : '%.*s'",
Expand All @@ -500,6 +518,12 @@ rstatus_t aes_decrypt(unsigned char *enc_msg, size_t enc_msg_len,
}
dec_len += block_len;

// Drop the first block of random plaintext by shifting dec_msg over
// by one block.
dec_len -= AES_BLOCK_SIZE;
memmove(*dec_msg, *dec_msg + AES_BLOCK_SIZE, dec_len);
(*dec_msg)[dec_len] = '\0';

// EVP_CIPHER_CTX_cleanup(aesDecryptCtx);

return (int)dec_len;
Expand Down
37 changes: 34 additions & 3 deletions src/dyn_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <unistd.h>
Expand Down Expand Up @@ -397,7 +398,9 @@ static rstatus_t aes_test(void) {
}
size_t enc_msg_len = (size_t)ret; /* if success, aes_encrypt returns len */

size_t expected_output_len = 16 * (msg_len / 16 + 1);
// Expected output is 2 blocks larger than the original msg_len, due to the
// explicit initialization vector and padding.
size_t expected_output_len = 16 * (msg_len / 16 + 2);
if (enc_msg_len != expected_output_len) {
log_panic("msg:'%s'\nexpected encrypted len: %lu encrypted len %lu\n\n",
msg, expected_output_len, enc_msg_len);
Expand All @@ -415,15 +418,43 @@ static rstatus_t aes_test(void) {
if (strcmp(msg, dec_msg) != 0) {
loga_hexdump(msg, strlen(msg), "Original Message:");
loga_hexdump(dec_msg, strlen(dec_msg), "Decrypted Message:");
log_panic("encryption/Decryption mismatch");
log_panic("encryption/decryption mismatch");
}

free(enc_msg);
free(dec_msg);
if ((i + 1) % 1000000 == 0) {
if ((i + 1) % (count / 10) == 0) {
loga("Completed Running %lu messages", i + 1);
}
}

loga("Making sure encryption is non-deterministic");
gen_random(msg, rand() % MAX_MSG_LEN);
unsigned int msg_len = strlen(msg) + 1;
unsigned char *enc_msg_1 = NULL;
unsigned char *enc_msg_2 = NULL;

rstatus_t ret_1 =
aes_encrypt((const unsigned char *)msg, msg_len, &enc_msg_1, aes_key);
rstatus_t ret_2 =
aes_encrypt((const unsigned char *)msg, msg_len, &enc_msg_2, aes_key);
if (ret_1 == DN_ERROR || ret_2 == DN_ERROR) {
log_panic("msg:'%s'\nencryption failed aes_key '%s'\n", msg,
aes_key_print);
return DN_ERROR;
}

if ((size_t)ret_1 == (size_t)ret_2 &&
!strncmp(enc_msg_1, enc_msg_2, (size_t)ret_1)) {
loga_hexdump(msg, strlen(msg), "Original Message:");
loga_hexdump(enc_msg_1, (size_t)ret_1, "Encrypted Message #1:");
loga_hexdump(enc_msg_2, (size_t)ret_2, "Encrypted Message #2:");
log_panic("Encryption failed to be non-deterministic");
}

free(enc_msg_1);
free(enc_msg_2);

return DN_OK;
}
/**
Expand Down