Skip to content

Instantly share code, notes, and snippets.

@dvtalk
Last active May 24, 2024 20:58
Show Gist options
  • Save dvtalk/edca1d9753503cd03f04b495b040f0e3 to your computer and use it in GitHub Desktop.
Save dvtalk/edca1d9753503cd03f04b495b040f0e3 to your computer and use it in GitHub Desktop.
AES encryption/decryption using OpenSSL Library
// https://dvtalk.me/2021/08/29/systemverilog-dpi-example-with-aes-openssl-cmodel/
#ifndef __AES_C__
#define __AES_C__
#include "aes.h"
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void handleErrors(void) {
ERR_print_errors_fp(stderr);
abort();
}
int aes_encrypt(enum AES_OP_MODE aes_mode,
unsigned char *plaintext,
int plaintext_len,
unsigned char *key,
int key_len,
unsigned char *ivec,
unsigned char *ciphertext) {
/* Initialise the library */
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
EVP_CIPHER_CTX *ctx;
int len;
int ciphertext_len;
/* Create and initialise the context */
if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
/* Initialise the encryption operation. */
switch (aes_mode) {
case AES_OP_MODE_ECB:
if (key_len == 128){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL)) handleErrors();};
if (key_len == 192){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_192_ecb(), NULL, key, NULL)) handleErrors();};
if (key_len == 256){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL)) handleErrors();};
break;
case AES_OP_MODE_CBC:
if (key_len == 128){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, ivec)) handleErrors();};
if (key_len == 192){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_192_cbc(), NULL, key, ivec)) handleErrors();};
if (key_len == 256){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, ivec)) handleErrors();}
break;
case AES_OP_MODE_CFB:
if (key_len == 128){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cfb(), NULL, key, ivec)) handleErrors();};
if (key_len == 192){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_192_cfb(), NULL, key, ivec)) handleErrors();};
if (key_len == 256){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cfb(), NULL, key, ivec)) handleErrors();}
break;
case AES_OP_MODE_XTS:
if (key_len == 128){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_xts(), NULL, key, ivec)) handleErrors();};
//if (key_len == 192){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_192_xts(), NULL, key, ivec)) handleErrors();};
if (key_len == 256){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_xts(), NULL, key, ivec)) handleErrors();};
break;
case AES_OP_MODE_OFB:
if (key_len == 128){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ofb(), NULL, key, ivec)) handleErrors();};
if (key_len == 192){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_192_ofb(), NULL, key, ivec)) handleErrors();};
if (key_len == 256){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ofb(), NULL, key, ivec)) handleErrors();}
break;
case AES_OP_MODE_CTR:
if (key_len == 128){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ctr(), NULL, key, ivec)) handleErrors();};
if (key_len == 192){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_192_ctr(), NULL, key, ivec)) handleErrors();};
if (key_len == 256){ if( 1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, ivec)) handleErrors();}
break;
}
/* Disable padding */
EVP_CIPHER_CTX_set_padding(ctx, 0);
/* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) handleErrors();
ciphertext_len = len;
/* Finalise the encryption. Further ciphertext bytes may be written at this stage. */
if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
ciphertext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
/* Some printing */
printf("\nEncypt key is : \n");
BIO_dump_fp (stdout, (const char *)key, key_len/8);
printf("\nEncypt ivec is:\n");
BIO_dump_fp (stdout, (const char *)ivec, 16 ); //16 bytes
printf("\nPlain text is:\n");
BIO_dump_fp (stdout, (const char *)plaintext, plaintext_len);
printf("\nCiphertext is:\n");
BIO_dump_fp (stdout, (const char *)ciphertext, ciphertext_len);
return ciphertext_len;
}
/* Turn "aabbcc22" to an array of 0xaa, 0xbb, 0xcc, 0x22*/
unsigned int hexstring2hexarray(const unsigned char *inputstring, unsigned char *outputstring) {
int inputstrsize = (int) strlen((char *)inputstring);
for(int i =0; i < inputstrsize; i+=2) {
unsigned char hexstr[2];
hexstr[0] = inputstring[i];
hexstr[1] = inputstring[i+1];
int num = (int) strtol((char*)hexstr, NULL, 16);
outputstring[i/2] = num;
}
return inputstrsize/2;
}
/* Implement main() for debugging */
int main (void) {
unsigned char plaintext[4096], key[4096], ivec[4096], decryptedtext[4096], ciphertext[4096];
unsigned int plaintext_len, key_len, ivec_len, decryptedtext_len, ciphertext_len;
/* Test with NIST KAT CBC GFSbox 192 COUNT=1*/
plaintext_len = hexstring2hexarray((unsigned char *)"00000000000000000000000000000000" , plaintext);
key_len = hexstring2hexarray((unsigned char *)"000000000000000000000000000000000000000000000000" , key);
ivec_len = hexstring2hexarray((unsigned char *)"9c2d8842e5f48f57648205d39a239af1" , ivec);
/* Encrypt the plaintext */
ciphertext_len = aes_encrypt( AES_OP_MODE_CBC,
plaintext,
plaintext_len,
key,
key_len*8,
ivec,
ciphertext);
/* Clean up */
EVP_cleanup();
ERR_free_strings();
return 0;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment