Skip to content

Instantly share code, notes, and snippets.

@H0neyBadger
Created April 22, 2020 12:52
Show Gist options
  • Save H0neyBadger/d024bb60e641708acd7d5ce65670099c to your computer and use it in GitHub Desktop.
Save H0neyBadger/d024bb60e641708acd7d5ce65670099c to your computer and use it in GitHub Desktop.
AES GCM tags with MBEDTLS & OpenSSL
#include <mbedtls/gcm.h>
#include <openssl/evp.h>
#include <cstring>
// g++ test_gcm.c -lmbedtls -lmbedx509 -lmbedcrypto /usr/lib64/libcrypto.so
bool print_buffer(const char * text, uint8_t * buf, size_t buf_size){
printf("%s", text);
for(int i=0;i<buf_size;i++){
printf("%.2x ", (uint8_t) *(buf+i));
}
printf("\n");
return true;
}
bool fill_buffer(uint8_t * buf, size_t buf_size){
for(int i=0;i<buf_size;i++){
*(buf+i)= i & 0xff;
}
return true;
}
#define MERROR(err) do{ \
if((err) != 0){ \
printf("MBEDTLS error: %x at line %s", err, __LINE__); \
goto merror; \
} \
} while(0);
#define OERROR(err) do{ \
if(!(err)){ \
printf("OPENSSL error: %x at line %s", err, __LINE__); \
goto oerror; \
} \
} while(0);
#define KEY_SIZE 16
#define IV_SIZE KEY_SIZE
#define TAG_SIZE 16
int main(int argc, char ** argv){
// create fake key
uint8_t key[KEY_SIZE];
fill_buffer(key, sizeof(key));
// create fake IV
uint8_t iv[IV_SIZE];
fill_buffer(iv, sizeof(iv));
// create fake DATA > 128 bits (len > 16)
uint8_t in[16] = {0};
fill_buffer(in, sizeof(in));
// out size == in size
uint8_t out[sizeof(in)] = { 0 };
uint8_t oout[sizeof(in)] = { 0 };
// output gmac tag
uint8_t tag[TAG_SIZE] = { 0 };
uint8_t otag[TAG_SIZE] = { 0 };
// openssl out len
int len;
int ret = 0;
printf("------------ init data ------------\n");
print_buffer("key: ", key, sizeof(key));
print_buffer("iv: ", iv, sizeof(iv));
print_buffer("in: ", in, sizeof(in));
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
mbedtls_gcm_context actx;
printf("------------ MBEDTLS ------------\n");
// MBEDTLS test :
mbedtls_gcm_init(&actx);
// set gmac_key 128 bits key
MERROR(mbedtls_gcm_setkey(&actx, MBEDTLS_CIPHER_ID_AES, key, KEY_SIZE*8));
// encrypt without additional data
MERROR(mbedtls_gcm_starts(&actx, MBEDTLS_GCM_ENCRYPT, iv, IV_SIZE, NULL, 0))
// mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, int mode,
// size_t length, const unsigned char *iv, size_t iv_len,
// const unsigned char *add, size_t add_len,
// const unsigned char *input, unsigned char *output, size_t tag_len,
// unsigned char *tag);
MERROR(mbedtls_gcm_crypt_and_tag(&actx, MBEDTLS_GCM_ENCRYPT,
0, iv, IV_SIZE,
in, sizeof(in), NULL, NULL,
sizeof(tag), tag));
/*
MERROR(mbedtls_gcm_crypt_and_tag(&actx, MBEDTLS_GCM_ENCRYPT,
sizeof(out), iv, IV_SIZE,
NULL, 0, in, out,
sizeof(tag), tag));
*/
mbedtls_gcm_free(&actx);
print_buffer("out: ", out, sizeof(out));
print_buffer("tag: ", tag, sizeof(tag));
printf("------------ OPENSSL ------------\n");
// must match KEYSIZE * 8 == 128 bits key (encryption mode)
OERROR(EVP_CipherInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL, 1))
// init iv len before the iv itself (iv default is 96 bits)
OERROR(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, IV_SIZE, NULL))
// set key and IV to openssl context
OERROR(EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1))
//OERROR(EVP_EncryptUpdate(ctx, oout, &len, in, (int)sizeof(in)))
OERROR(EVP_EncryptUpdate(ctx, NULL, &len, in, (int)sizeof(in)))
printf("Openssl buffer len %d == %d ? \n", len, sizeof(in));
OERROR(EVP_EncryptFinal_ex(ctx, oout, &len))
OERROR(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAG_SIZE, otag))
EVP_CIPHER_CTX_free(ctx);
print_buffer("out: ", oout, sizeof(oout));
print_buffer("tag: ", otag, sizeof(otag));
ret = memcmp(tag, otag, TAG_SIZE);
printf("Test %s !\n", ret ? "FAILED": "ok");
return 1;
oerror:
printf("Openssl Error\n");
EVP_CIPHER_CTX_free(ctx);
return 1;
merror:
printf("mbedtls Error\n");
mbedtls_gcm_free(&actx);
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment