Skip to content

Instantly share code, notes, and snippets.

@jige003
Created April 26, 2019 05:38
Show Gist options
  • Save jige003/500a3e9edb181a65632d128cca5a9390 to your computer and use it in GitHub Desktop.
Save jige003/500a3e9edb181a65632d128cca5a9390 to your computer and use it in GitHub Desktop.
jaes.md
/*************************************************************************
> File Name: aes.c
> Author: jige003
> Created Time: Thu 25 Apr 2019 04:39:32 PM CST
************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include "hex.h"
typedef unsigned char byte;
void hex_debug(const byte *inbuf, size_t inlen, const byte *msg){
byte *enc_buf;
bin2hex(inbuf, inlen, &enc_buf);
printf("%s:%s\n", msg, enc_buf);
free(enc_buf);
}
int aes_encrypt (const char *key, const byte *inbuf, size_t inlen, byte **outbuf, size_t *outlen){
int ret = 0, olen = 0, flen = 0;
const EVP_CIPHER *cipher = EVP_aes_128_cbc();
assert(cipher != NULL);
int cipher_block_size = EVP_CIPHER_block_size(cipher);
int cipher_iv_len = EVP_CIPHER_iv_length(cipher);
char iv[EVP_MAX_IV_LENGTH];
byte * enc_buf = (byte *) malloc( (inlen + cipher_block_size + cipher_iv_len) * sizeof(byte));
/* init evp */
if (!RAND_bytes(iv, sizeof(iv))) {
/* OpenSSL reports a failure, act accordingly */
fprintf(stderr, "ERROR: RAND_bytes error: %s\n", strerror(errno));
ret = errno;
goto cleanup;
}
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
ret = EVP_EncryptInit_ex(&ctx, cipher, NULL, key, iv);
if (ret == 0 ){
fprintf(stderr, "ERROR: EVP_CipherInit_ex failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto cleanup;
}
/* encrypt */
ret = EVP_CipherUpdate(&ctx, enc_buf, &olen, inbuf, inlen);
if( ret == 0) {
fprintf(stderr, "ERROR: EVP_CipherUpdate failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto cleanup;
}
ret = EVP_EncryptFinal_ex(&ctx, enc_buf + olen, &flen);
if ( ret == 0 ){
fprintf(stderr, "ERROR: EVP_CipherFinal_ex failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto cleanup;
}
*outlen = olen + flen;
*outbuf = (byte *) malloc( ((*outlen) + EVP_MAX_IV_LENGTH + 1) * sizeof(byte));
memset((*outbuf), 0 , ((*outlen) + EVP_MAX_IV_LENGTH + 1));
memcpy((*outbuf), iv, EVP_MAX_IV_LENGTH);
memcpy((*outbuf) + EVP_MAX_IV_LENGTH, enc_buf, (*outlen));
(*outlen) += EVP_MAX_IV_LENGTH;
free(enc_buf);
cleanup:
EVP_CIPHER_CTX_cleanup(&ctx);
return ret;
}
int aes_decrypt(const char *key, const byte *inbuf, size_t inlen, byte **outbuf, size_t *outlen){
int ret = 0, olen = 0, flen = 0;
const EVP_CIPHER *cipher = EVP_aes_128_cbc();
assert( cipher != NULL );
int cipher_iv_len = EVP_CIPHER_iv_length(cipher);
char iv[EVP_MAX_IV_LENGTH];
memcpy(iv, inbuf, EVP_MAX_IV_LENGTH);
byte *enc_buf;
enc_buf = (byte *)inbuf + EVP_MAX_IV_LENGTH;
EVP_CIPHER_CTX dctx;
EVP_CIPHER_CTX_init(&dctx);
ret = EVP_DecryptInit_ex(&dctx, cipher, NULL, key, iv);
if (ret == 0 ){
fprintf(stderr, "ERROR: EVP_CipherInit_ex failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto cleanup;
}
*outbuf = (byte *)malloc(inlen * sizeof(byte));
memset((*outbuf), 0 , inlen);
/* decrypt */
ret = EVP_CipherUpdate(&dctx, (*outbuf), &olen, enc_buf, inlen - EVP_MAX_IV_LENGTH);
if( ret == 0) {
fprintf(stderr, "ERROR: EVP_CipherUpdate failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto cleanup;
}
ret = EVP_DecryptFinal_ex(&dctx, ((*outbuf) + olen), &flen);
if ( ret == 0 ){
fprintf(stderr, "ERROR: EVP_CipherFinal_ex failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto cleanup;
}
*outlen = olen + flen;
(*outbuf)[(*outlen)] = '\0';
cleanup:
EVP_CIPHER_CTX_cleanup(&dctx);
return ret;
}
void xfree(void *ptr){
if (ptr != ((void*)0)) free(ptr);
}
int main(void){
char key[] = "this is a key";
byte inbuf[] = "this is a test string by jige003 skeleton encrypt";
size_t inlen = strlen(inbuf);
byte *outbuf ;
size_t outlen;
#ifdef LOOP
while(1){
#endif
aes_encrypt(key, inbuf, inlen, &outbuf, &outlen);
#define P printf
hex_debug(outbuf, outlen, "outbuf");
byte *plainbuf;
size_t plen;
aes_decrypt(key, outbuf, outlen, &plainbuf, &plen);
printf("plainbuf:%s\n", plainbuf);
if ( strcmp(inbuf, plainbuf) == 0 ){
P("aes encrypt/decrypt test success\n");
}else{
P("aes encrypt/decrypt test fail\n");
}
xfree(plainbuf);
xfree(outbuf);
#ifdef LOOP
}
#endif
return 0;
}

aes encrypt/decrypt functions implement by openssl env aes_cbc

api

int aes_encrypt (const char *key, const byte *inbuf, size_t inlen, byte **outbuf, size_t *outlen);

int aes_decrypt(const char *key, const byte *inbuf, size_t inlen, byte **outbuf, size_t *outlen);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment