|
|
@ -0,0 +1,164 @@ |
|
|
|
#include <stdio.h> |
|
|
|
#include <string.h> |
|
|
|
#include <openssl/conf.h> |
|
|
|
#include <openssl/evp.h> |
|
|
|
#include <openssl/err.h> |
|
|
|
|
|
|
|
static const char HDL_LOGIC_CHAR[] = { 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'}; |
|
|
|
|
|
|
|
enum HDL_LOGIC_STATES { |
|
|
|
HDL_U = 0, |
|
|
|
HDL_X = 1, |
|
|
|
HDL_0 = 2, |
|
|
|
HDL_1 = 3, |
|
|
|
HDL_Z = 4, |
|
|
|
HDL_W = 5, |
|
|
|
HDL_L = 6, |
|
|
|
HDL_H = 7, |
|
|
|
HDL_D = 8, |
|
|
|
}; |
|
|
|
|
|
|
|
EVP_CIPHER_CTX *ctx; |
|
|
|
|
|
|
|
void slv_to_uchar(char* datain, unsigned char* dataout, int bytelen) { |
|
|
|
|
|
|
|
for (int i = 0; i < bytelen; i++) { |
|
|
|
for (int y = 0; y < 8; y++) { |
|
|
|
if (*datain == HDL_1) { |
|
|
|
*dataout |= 1 << y; |
|
|
|
} else if (*datain == HDL_0) { |
|
|
|
*dataout &= ~(1 << y); |
|
|
|
} |
|
|
|
datain++; |
|
|
|
} |
|
|
|
dataout++; |
|
|
|
} |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void slv_to_string(char* datain, char* dataout, int bytelen) { |
|
|
|
|
|
|
|
for (int i = 0; i < bytelen; i++) { |
|
|
|
*dataout = HDL_LOGIC_CHAR[*datain]; |
|
|
|
datain++; |
|
|
|
dataout++; |
|
|
|
} |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void uchar_to_slv(unsigned char* datain, char* dataout, int bytelen) { |
|
|
|
|
|
|
|
for (int i = 0; i < bytelen; i++) { |
|
|
|
for (int y = 0; y < 8; y++) { |
|
|
|
if ((*datain >> y) & 1 == 1) { |
|
|
|
*dataout = HDL_1 ; |
|
|
|
} else { |
|
|
|
*dataout = HDL_0; |
|
|
|
} |
|
|
|
dataout++; |
|
|
|
} |
|
|
|
datain++; |
|
|
|
} |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void handleErrors(void) { |
|
|
|
|
|
|
|
ERR_print_errors_fp(stderr); |
|
|
|
abort(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void init(unsigned char *key, unsigned char *iv) { |
|
|
|
|
|
|
|
// Create and initialise the context |
|
|
|
if(!(ctx = EVP_CIPHER_CTX_new())) |
|
|
|
handleErrors(); |
|
|
|
|
|
|
|
// Initialise the encryption operation, no IV needed in CTR mode |
|
|
|
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ctr(), NULL, key, iv)) |
|
|
|
handleErrors(); |
|
|
|
|
|
|
|
// We don't want padding |
|
|
|
if(1 != EVP_CIPHER_CTX_set_padding(ctx, 0)) |
|
|
|
handleErrors(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int encrypt(unsigned char *plaintext, |
|
|
|
int plaintext_len, |
|
|
|
unsigned char *ciphertext) { |
|
|
|
|
|
|
|
int len = 0; |
|
|
|
|
|
|
|
// Provide the message to be encrypted, and obtain the encrypted output |
|
|
|
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) |
|
|
|
handleErrors(); |
|
|
|
|
|
|
|
return len; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int finalize(void) { |
|
|
|
|
|
|
|
int len = 0; |
|
|
|
unsigned char data[16]; |
|
|
|
|
|
|
|
// Finalise the encryption. No further bytes are written as padding is switched off |
|
|
|
if (1 != EVP_EncryptFinal_ex(ctx, data, &len)) |
|
|
|
handleErrors(); |
|
|
|
|
|
|
|
// Clean up |
|
|
|
EVP_CIPHER_CTX_free(ctx); |
|
|
|
|
|
|
|
return len; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void cryptData(char* datain, char* key, char* iv, char start, char final, char* dataout, int bytelen) { |
|
|
|
|
|
|
|
int crypt_len; |
|
|
|
unsigned char c_din[bytelen]; |
|
|
|
unsigned char c_key[bytelen]; |
|
|
|
unsigned char c_iv[bytelen]; |
|
|
|
unsigned char c_dout[bytelen]; |
|
|
|
|
|
|
|
slv_to_uchar(datain, c_din, bytelen); |
|
|
|
slv_to_uchar(key, c_key, bytelen); |
|
|
|
slv_to_uchar(iv, c_iv, bytelen); |
|
|
|
|
|
|
|
if (start) { |
|
|
|
init(c_key, c_iv); |
|
|
|
} |
|
|
|
|
|
|
|
crypt_len = encrypt(c_din, bytelen, c_dout); |
|
|
|
|
|
|
|
if (crypt_len != bytelen) { |
|
|
|
printf("Warning: encrypt() returned with unexpected length %d\n", crypt_len); |
|
|
|
} |
|
|
|
|
|
|
|
if (final) { |
|
|
|
crypt_len = finalize(); |
|
|
|
if (crypt_len != 0) { |
|
|
|
printf("Warning: finalize() returned with unexpected length %d\n", crypt_len); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
uchar_to_slv(c_dout, dataout, bytelen); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |