This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I'm trying to build my own crypter in c using AES to encrypt the shellcode. Now I've already made a PoC of the crypter in one program which can be found below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* MCrypt API available online:
* http://linux.die.net/man/3/mcrypt
*/
#include <mcrypt.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
int encrypt(
void* buffer,
int buffer_len, /* Because the plaintext could include null bytes*/
char* IV,
char* key,
int key_len
){
MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
int blocksize = mcrypt_enc_get_block_size(td);
if( buffer_len % blocksize != 0 ){return 1;}
mcrypt_generic_init(td, key, key_len, IV);
mcrypt_generic(td, buffer, buffer_len);
mcrypt_generic_deinit (td);
mcrypt_module_close(td);
return 0;
}
int decrypt(
void* buffer,
int buffer_len,
char* IV,
char* key,
int key_len
){
MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
int blocksize = mcrypt_enc_get_block_size(td);
if( buffer_len % blocksize != 0 ){return 1;}
mcrypt_generic_init(td, key, key_len, IV);
mdecrypt_generic(td, buffer, buffer_len);
mcrypt_generic_deinit (td);
mcrypt_module_close(td);
return 0;
}
int main()
{
{
MCRYPT td, td2;
unsigned char * plaintext = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
char* IV = "AAAAAAAAAAAAAAAA";
char *key = "0123456789abcdef";
int keysize = 16; /* 128 bits */
unsigned char buffer[32];
int counter;
int buffer_len = 32;
for ( counter = 0; counter < buffer_len; counter++){
buffer[counter]=0x90;
}
strncpy(buffer, plaintext, buffer_len);
int plain_len = strlen(plaintext);
printf("==Plain Binary==\n");
for ( counter = 0; counter < plain_len; counter++){
printf("%02x",plaintext[counter]);
}
encrypt(buffer, buffer_len, IV, key, keysize);
printf("\n==Encrypted Binary==\n");
for ( counter = 0; counter < buffer_len; counter++){
printf("\\x%02x",buffer[counter]);
}
decrypt(buffer, buffer_len, IV, key, keysize);
printf("\n==decrypted Binary==\n");
for ( counter = 0; counter < buffer_len; counter++){
if (buffer[counter] == 0){
buffer[counter] = 0x90;
}
printf("\\x%02x",buffer[counter]);
}
printf("\n");
printf("Shellcode Length: %d\n", strlen(buffer));
int (*ret)() = (int(*)())buffer;
ret();
return 0;
}
My goal is to take the encrypted shellcode, decrypt it and run it. However it seems I'm getting a segmentation fault when I try to initialize mcrypt with the mcrypt_generic_init(td, key, key_len, IV); function. I'm really unsure what is causing the segmentation fault. If anyone has an idea?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* MCrypt API available online:
* http://linux.die.net/man/3/mcrypt
*/
#include <mcrypt.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
int decrypt(
void* buffer,
int buffer_len,
char* IV,
char* key,
int key_len
){
MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
int blocksize = mcrypt_enc_get_block_size(td);
if( buffer_len % blocksize != 0 ){return 1;}
printf("proceeding to mcrypt\n");
mcrypt_generic_init(td, key, key_len, IV);
printf("initiated mcrypt") ;
mdecrypt_generic(td, buffer, buffer_len);
printf("proceeding to mcrypt\n");
mcrypt_generic_deinit (td);
printf("proceeding to mcrypt\n");
mcrypt_module_close(td);
printf("returning from mcrypt\n");
return 0;
}
int main()
{
MCRYPT td,td2;
char* IV = "AAAAAAAAAAAAAAAA";
char *key = "0123456789abcdef";
int keysize = 16; /* 128 bits */
unsigned char* buffer = "\x5c\xd8\xcf\x9e\x8f\x3a\x9f\x52\x2e\x3d\x51\x06\x00\xde\xa6\x64\x45\x5f\x62\x53\x75\xab\xbd\xe1\x33\xc1\x69\xbf\xed\xc8\x5c\xaa";
int buffer_len = 32;
int counter;
decrypt(buffer, buffer_len, IV, key, keysize);
for ( counter = 0; counter < buffer_len; counter++){
printf("0x%02x",buffer[counter]);
}
printf("\n");
printf("Shellcode Length: %d\n", strlen(buffer));
int (*ret)() = (int(*)())buffer;
ret();
return 0;
}
You are trying to write in a literal string. This is wrong because compilers are allowed to allocate literal strings in read-only memory (and they really do that).
Change this:
char *buffer = "..."
into this:
char buffer[] = "..."
The latter will allocate an array on the stack (hence modifiable) and dynamically fill it with the data from the literal string (done anew each time the function is entered).
Related
I'm trying to write a C program to brute force AES decryption using openssl. However, when I tried to decrypt the message by passing a key attackKey, I got and error printed from the decrypt() function. The error is as follows
There was an error calling the decrypted final object...: Success
The code is given below, I tried reading the book on Openssl for more information but as it is quite outdated it was not helpful. I also googled and barely found any resources on my issue and yes I am well aware of the fact that brute forcing aes_128 is a pipe dream. I am just testing some things with this library to see if the key is only a few combinations ahead, so can I iterate on the attackKey and try to get the decrypted text.
#include <string.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <stdbool.h>
#include <openssl/err.h>
#define BUFFER_SIZE 64
// void addPadding(unsigned char *buff, );
int encrypt(const unsigned char *plaintext, const int plaintext_len, const unsigned char *key, unsigned char *ciphertext);
int decrypt(const unsigned char *ciphertext, const int ciphertext_len, const unsigned char *key, unsigned char *decryptedtext);
void iterateKey(unsigned char *key, const int length);
bool compareKeys(const unsigned char *key1, const unsigned char *key2, const int length);
void *bruteForceAttack(void *arg);
int main(int argc, char *argv[])
{
OpenSSL_add_all_algorithms(); // load all cipher algorithms
ERR_load_crypto_strings(); // load human readable errors
/* A 256 bit key */
unsigned char key[] = "abcdefghijklmnqp"; // 6 + 1 bytes
unsigned char plaintext[] = "Hello, my name is shaheryar ;)."; // 32 + 1 bytes
/* Buffer to store the ciphertext. The size may be different due to padding. */
unsigned char ciphertext[BUFFER_SIZE];
int ciphertext_len = 0;
/* Encryption. */
ciphertext_len = encrypt(plaintext, strlen((char *)plaintext), key, ciphertext);
printf("Length of text:%d, Ciphertext is:\n", ciphertext_len);
BIO_dump_fp(stdout, (const char *)ciphertext, ciphertext_len);
//----------------MAIN DECRYPTION LOGIC
/* Buffer for the decrypted text for verifying decryption. */
unsigned char decryptedtext[BUFFER_SIZE];
int decryptedtext_len = 0;
unsigned char attackKey[] = "abcdefghijklmnop";
const int attackKey_len = 17;
for (int i = 0; i < 10e2; i++)
{
// printf("Key : %s\n", attackKey);
decryptedtext_len = 0;
decryptedtext_len = decrypt(ciphertext, ciphertext_len, attackKey, decryptedtext);
decryptedtext[decryptedtext_len] = '\0';
if (strcmp((const char *)attackKey, (const char *)key) == 0)
{
printf("\nLength of text: %d, Decryptedtext is: %s\n", decryptedtext_len, decryptedtext);
}
iterateKey(attackKey, attackKey_len);
}
//------------END OF DECRYPTION PHASE
if (strncmp((const char *)plaintext, (const char *)decryptedtext, decryptedtext_len))
{
printf("FAIL: enc/dec failed for \"%s\"\n", decryptedtext);
}
else
{
printf("OK: enc/dec ok for \"%s\"\n", plaintext);
}
return 0;
}
int encrypt(const unsigned char *plaintext, const int plaintext_len, const unsigned char *key, unsigned char *ciphertext)
{
/* The following object is used to keep track of the key and internal states*/
EVP_CIPHER_CTX *ctx = NULL;
int len = 0, ciphertext_len = 0;
/* Create and initialize the context and returns a pointer for success and null for failure*/
if (!(ctx = EVP_CIPHER_CTX_new()))
{
printf("There was an error creating the encryption object...");
}
/* Initialize the encryption operation. */
if (!EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
{
printf("There was an error loading the encryption object...");
}
if (plaintext)
{
if (!EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
{
printf("There was an error creating the update the encryption object...");
}
ciphertext_len = len;
}
if (!EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
{
printf("There was an error encrypting the final object...");
}
ciphertext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
}
int decrypt(const unsigned char *ciphertext, const int ciphertext_len, const unsigned char *key, unsigned char *decryptedtext)
{
/* The following object is used to keep track of the key and internal states*/
EVP_CIPHER_CTX *ctx = NULL;
int len = 0, decryptedtext_len = 0;
/* Create and initialize the context and returns a pointer for success and null for failure*/
if (!(ctx = EVP_CIPHER_CTX_new()))
{
printf("There was an error creating the decryption object...");
}
/* Initialize the encryption operation. */
if (!EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
{
printf("There was an error initializing the cipher object...");
}
if (ciphertext)
{
if (!EVP_DecryptUpdate(ctx, decryptedtext, &len, ciphertext, ciphertext_len))
{
printf("There was an error decrypting the cipher text...");
}
decryptedtext_len = len;
}
if (!EVP_DecryptFinal_ex(ctx, decryptedtext + len, &len))
{
printf("There was an error calling the decrypted final object...");
}
decryptedtext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return decryptedtext_len;
}
bool compareKeys(const unsigned char *key1, const unsigned char *key2, const int length)
{
for (int i = 0; i < length; i++)
{
if (key1[i] != key2[i])
{
return false;
}
}
return true;
}
void iterateKey(unsigned char *key, const int length)
{
for (int i = 0; i < (length - 1); i++)
{
if (key[length - 2 - i] == 'z')
{
key[length - 2 - i] = 'a';
}
else
{
key[length - 2 - i]++;
return;
}
}
}
void *bruteForceAttack(void *arg)
{
return NULL;
}
Below are the resources I used for implementing the code:
https://www.cs.ucy.ac.cy/courses/EPL326/labs/lab3/aesimplentation.pdf
https://www.oreilly.com/library/view/network-security-with/059600270X/
I can't figure out where my code is going wrong. I know there is allocation error in my function getit() but I can't figure out why! Any help is appreciated.
What my program does is hash a message into one array. Then, I have a random word generator that makes a string and hashes them. My program will then compare the hashes and keep making words until the hash matches the origional.
#include <stdio.h>
#include <openssl/evp.h>
#include <string.h>
void randString(int length, char* s);
void getit(unsigned char rando[], unsigned char hash[]);
char* mess1 = "Test Message";
unsigned char match[3];
int boolean = 0;
unsigned char orHash[3];
unsigned char raHash[3];
int counter = 0;
int main(int argc, char *argv[])
{
srand(time(NULL));
EVP_MD_CTX *mdctx;
const EVP_MD *md;
unsigned char md_value[EVP_MAX_MD_SIZE];
int md_len, i;
OpenSSL_add_all_digests();
md = EVP_get_digestbyname("SHA256");
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, mess1, strlen(mess1));
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_destroy(mdctx);
strcpy(match,md_value);
strcpy(orHash,match);
printf("Digest is: ");
for (i = 0; i < 3; i++)
printf("%02x", match[i]);
printf("\n");
while(boolean < 3){
char* qt = malloc(strlen(mess1) * sizeof(char));
randString(strlen(mess1),qt);
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, qt, strlen(mess1));
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_destroy(mdctx);
strcpy(raHash,md_value);
getit(raHash, orHash);
}
exit(0);
}
void randString(int length, char* s) {
const char alpha[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < length; i++){
s[i] = alpha[rand()%(int)(sizeof(alpha) -1)];
}
s[length] = '\0';
}
void getit(unsigned char rando[], unsigned char hash[]){
counter += 1;
for (int i = 0; i < 3; i++)
printf("%02x", rando[i]);
for(int i = 0; i < 3; i++){
if (rando[i] != hash[i]){
printf("%d: The hashes don't match\n", counter);
boolean = 0;
break;
}
boolean += 1;
if(boolean == 3){
printf("Match Found!");
}
}
}
The Error I get is as follows:
hash: malloc.c:2392: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
The code breaks at trial 505 everytime (finished comparing trial 504) trying the see if the two arrays match so that might help.
There is no need to dynamic allocation in any of this. The whole point of this exercise it to brute-force generating random, equal-length alpha-numeric strings, digesting them, and stopping when you fine one that matches the first three octets.
No string conversions are required
One like-sized message buffer (matching the size of your test message) can be used.
You can reuse the digest context. No need to keep allocating and destroying it.
getit is ultimately pointless except to tally up a counter.
The result is something like this:
Code
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
void randString(size_t length, char* s);
int main()
{
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned char md_test[EVP_MAX_MD_SIZE];
unsigned int md_len, i;
char msg[] = "Test Message";
srand((unsigned)time(NULL));
OpenSSL_add_all_digests();
const EVP_MD *md = EVP_get_digestbyname("SHA256");
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, msg, sizeof msg-1);
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
printf("Digest is: ");
for (i = 0; i < md_len; i++)
printf("%02x", md_value[i]);
printf("\n");
int counter = 0;
while (1)
{
++counter;
char rand_msg[sizeof msg];
randString(sizeof msg - 1, rand_msg);
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, rand_msg, sizeof rand_msg - 1);
EVP_DigestFinal_ex(mdctx, md_test, &md_len);
if (memcmp(md_test, md_value, 3) == 0)
{
printf("Match found: %s\nAttempts: %d\n", rand_msg, counter);
printf("Digest is: ");
for (i = 0; i < md_len; i++)
printf("%02x", md_test[i]);
printf("\n");
break;
}
}
return 0;
}
Sample Output (varies, obviously)
Digest is: b67d1b3ab0d839eb8bc1156b8717bb441c897fcab323374e2ae530a40632feba
Match found: nPbeGgsZcNoo
Attempts: 9570596
Digest is: b67d1bcdab5d05a8712a8cd4c99b5bf683fdcefcf43fc453f852f4ff14b28a39
Friends I figured it out.
I never used free(qt) so eventually, it ran out of memory to allocate after looping!
I am trying to use the bottom posted code to encrypt using openssl EVP_aes_256_cbc(), I have tested the below code and it is working fine. what I am looking forward to is getting the cipher and then perform base64 encoding and return the same.
I know of the below command:
openssl enc -aes-256-cbc -a -in /u/zsyed10/T.dat -out /u/zsyed10/T_ENC.dat
but not sure if there is any EVP function which would return base64 encoded cipher.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
/**
* Create an 256 bit key and IV using the supplied key_data. salt can be added for taste.
* Fills in the encryption and decryption ctx objects and returns 0 on success
**/
int aes_init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx,
EVP_CIPHER_CTX *d_ctx)
{
int i, nrounds = 5;
unsigned char key[32], iv[32];
/*
* Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material.
* nrounds is the number of times the we hash the material. More rounds are more secure but
* slower.
*/
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv);
if (i != 32) {
printf("Key size is %d bits - should be 256 bits\n", i);
return -1;
}
EVP_CIPHER_CTX_init(e_ctx);
EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_init(d_ctx);
EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv);
return 0;
}
/*
* Encrypt *len bytes of data
* All data going in & out is considered binary (unsigned char[])
*/
unsigned char *aes_encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext, int *len)
{
/* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes */
int c_len = *len + AES_BLOCK_SIZE, f_len = 0;
unsigned char *ciphertext = malloc(c_len);
/* allows reusing of 'e' for multiple encryption cycles */
EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL);
/* update ciphertext, c_len is filled with the length of ciphertext generated,
*len is the size of plaintext in bytes */
EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len);
/* update ciphertext with the final remaining bytes */
EVP_EncryptFinal_ex(e, ciphertext+c_len, &f_len);
*len = c_len + f_len;
return ciphertext;
}
/*
* Decrypt *len bytes of ciphertext
*/
unsigned char *aes_decrypt(EVP_CIPHER_CTX *e, unsigned char *ciphertext, int *len)
{
/* because we have padding ON, we must allocate an extra cipher block size of memory */
int p_len = *len, f_len = 0;
unsigned char *plaintext = malloc(p_len + AES_BLOCK_SIZE);
EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL);
EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len);
EVP_DecryptFinal_ex(e, plaintext+p_len, &f_len);
*len = p_len + f_len;
return plaintext;
}
int main(int argc, char **argv)
{
/* "opaque" encryption, decryption ctx structures that libcrypto uses to record
status of enc/dec operations */
EVP_CIPHER_CTX en, de;
/* 8 bytes to salt the key_data during key generation. This is an example of
compiled in salt. We just read the bit pattern created by these two 4 byte
integers on the stack as 64 bits of contigous salt material -
ofcourse this only works if sizeof(int) >= 4 */
unsigned int salt[] = {12345, 54321};
unsigned char *key_data;
int key_data_len, i;
char *input[] = {"a", "abcd", "this is a test", "this is a bigger test",
"\nWho are you ?\nI am the 'Doctor'.\n'Doctor' who ?\nPrecisely!",
NULL};
/* the key_data is read from the argument list */
key_data = (unsigned char *)argv[1];
key_data_len = strlen(argv[1]);
/* gen key and iv. init the cipher ctx object */
if (aes_init(key_data, key_data_len, (unsigned char *)&salt, &en, &de)) {
printf("Couldn't initialize AES cipher\n");
return -1;
}
/* encrypt and decrypt each input string and compare with the original */
for (i = 0; input[i]; i++) {
char *plaintext;
unsigned char *ciphertext;
int olen, len;
/* The enc/dec functions deal with binary data and not C strings. strlen() will
return length of the string without counting the '\0' string marker. We always
pass in the marker byte to the encrypt/decrypt functions so that after decryption
we end up with a legal C string */
olen = len = strlen(input[i])+1;
ciphertext = aes_encrypt(&en, (unsigned char *)input[i], &len);
plaintext = (char *)aes_decrypt(&de, ciphertext, &len);
if (strncmp(plaintext, input[i], olen))
printf("FAIL: enc/dec failed for \"%s\"\n", input[i]);
else
printf("OK: enc/dec ok for \"%s\"\n", plaintext);
free(ciphertext);
free(plaintext);
}
EVP_CIPHER_CTX_cleanup(&en);
EVP_CIPHER_CTX_cleanup(&de);
return 0;
}
Thanks for the information on BIO filters, etc.
Also could someone please explain the usage of:
EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL);
as it appears before EVP_EncryptUpdate() and after:
EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
Is it not overwriting the key and IV with NULL values rendering the usage of key and IV obsolete.
I understand that it is resetting so that the context could be used again but would have made more sense if it appeared after EVP_EncryptUpdate()
How do I work with msgpack_pack_raw and msgpack_pack_raw_body to send an unsigned char array to more importantly, how to retrieve (unpack) it?
What I have done is as follows:
msgpack_sbuffer* buffer = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
msgpack_sbuffer_clear(buffer);
msgpack_pack_array(pk, 10);
unsigned char a[10] = "0123456789";
msgpack_pack_raw(pk, 10);
msgpack_pack_raw_body(pk,a,10);
and in the receiver part I have:
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
msgpack_unpack_next(&msg, buffer->data, buffer->size, NULL);
msgpack_object obj = msg.data;
msgpack_object* p = obj.via.array.ptr;
int length = (*p).via.raw.size;
IDPRINT(length);
unsigned char* b = (unsigned char*) malloc(length);
memcpy(b,(*p).via.raw.ptr,length);
But it throws seg fault when executing "int length = (*p).via.raw.size;".
Any idea why?
Any idea why?
This is because msgpack_pack_array(pk, 10); is not required here, since you pack your data as a raw buffer of a given size. In other words msgpack_pack_raw and msgpack_pack_raw_body are sufficient.
At unpack time, you must access its fields as follow:
length: obj.via.raw.size
data: obj.via.raw.ptr
see: msgpack_object_raw in object.h.
Here's a recap of how to proceed:
#include <stdio.h>
#include <assert.h>
#include <msgpack.h>
int main(void) {
unsigned char a[10] = "0123456789";
char *buf = NULL;
int size;
/* -- PACK -- */
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pck;
msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write);
msgpack_pack_raw(&pck, 10);
msgpack_pack_raw_body(&pck, a, 10);
size = sbuf.size;
buf = malloc(sbuf.size);
memcpy(buf, sbuf.data, sbuf.size);
msgpack_sbuffer_destroy(&sbuf);
/* -- UNPACK -- */
unsigned char *b = NULL;
int bsize = -1;
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
if (msgpack_unpack_next(&msg, buf, size, NULL)) {
msgpack_object root = msg.data;
if (root.type == MSGPACK_OBJECT_RAW) {
bsize = root.via.raw.size;
b = malloc(bsize);
memcpy(b, root.via.raw.ptr, bsize);
}
}
/* -- CHECK -- */
assert(bsize == 10);
assert(b != NULL);
for (int i = 0; i < bsize; i++)
assert(b[i] == a[i]);
printf("ok\n");
free(buf);
free(b);
return 0;
}
This is my code (the errors checking were deliberately omitted for code readability):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gcrypt.h>
#define GCRYPT_VERSION "1.5.0"
#define GCRY_CIPHER GCRY_CIPHER_AES128
int main(void){
if(!gcry_check_version(GCRYPT_VERSION)){
fputs("libgcrypt version mismatch\n", stderr);
exit(2);
}
gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN);
gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0);
gcry_control(GCRYCTL_RESUME_SECMEM_WARN);
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
int algo = -1;
size_t i;
const char *name = "aes128";
char plain_text[16] = {0x80};
char key[16] = {0};
char iniVector[16] = {0};
size_t txtLenght = strlen(plain_text);
char *encBuffer = malloc(txtLenght);
gcry_cipher_hd_t hd;
algo = gcry_cipher_map_name(name);
size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
gcry_cipher_open(&hd, algo, GCRY_CIPHER_MODE_CBC, 0);
gcry_cipher_setkey(hd, key, keyLength);
gcry_cipher_setiv(hd, iniVector, blkLength);
gcry_cipher_encrypt(hd, encBuffer, txtLenght, plain_text, txtLenght);
printf("encBuffer = ");
for(i = 0; i < txtLenght; i++){
printf("%02x", (unsigned char) encBuffer[i]);
}
printf("\n");
gcry_cipher_close(hd);
free(encBuffer);
return 0;
}
Expected result:
KEY = 00000000000000000000000000000000
IV = 00000000000000000000000000000000
PLAINTEXT = 80000000000000000000000000000000
CIPHERTEXT = 3ad78e726c1ec02b7ebfe92b23d9ec34
My result:
KEY = 00000000000000000000000000000000
IV = 00000000000000000000000000000000
PLAINTEXT = 80000000000000000000000000000000
CIPHERTEXT = 42
Why i got this output? What am I doing wrong?
You are using ASCII values but the AES test vectors are given as hexadecimal values.
Try with hex values instead (the remaining values of the array are initialized by 0 in C):
char plain_text[16] = {0x80};
char key[16] = {0};
char iniVector[16] = {0};
size_t txtLenght = sizeof plain_text;