Reputation: 457
I would like to preface this with, I am new to C and especially using a lib as large as libgcrypt, so if it is something incredibly simple please be understanding.
So, I have been trying to just encrypt some text just to kinda launchpad from and so that way I get some better confidence before going with just encrypting bytes which is one of the end goals of this little app if youd like to call it that. I have been following this, but still am struggling with getting it to work. The part that really confuses me is that I am passing it the out buffer which has been sized to match that of the in text. I do find it weird that this site tells me to make the out buffer the same size as the input even though usually when encrypting with AES the output is large in terms of bytes. Maybe I missed something that someone more experience can help me with, I have read over their code at least 3-4 times now and I feel like it must be something super simple I am missing here.
client.c
#include "client.h"
void printGCRYPTError(gcry_error_t err) {
if (err) {
{
fprintf (stderr, "Failure: %s/%s\n",
gcry_strsource (err),
gcry_strerror (err));
fprintf (stdout, "Failure: %s/%s\n",
gcry_strsource (err),
gcry_strerror (err));
}
}
}
char* Encrypt(char* in, char* key, char* iv){
size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
if(strlen(key) != keyLength) {
printf("Invalid Key Size. Expected %zu got %lu\n", keyLength, strlen(key));
return NULL;
}
if(strlen(iv) != blkLength) {
printf("Invalid BLK/IV Size. Expected %zu got %lu\n", blkLength, strlen(iv));
return NULL;
}
gcry_cipher_hd_t handle;
gcry_error_t err = 0;
size_t inLen = strlen(in)+1;
char * out = malloc(inLen);
// Open
err = gcry_cipher_open(&handle, GCRY_CIPHER, GCRY_C_MODE, 0);
printGCRYPTError(err);
// Set Key
err = gcry_cipher_setkey(handle, key, keyLength);
printGCRYPTError(err);
// Set IV
err = gcry_cipher_setiv(handle, iv, blkLength);
printGCRYPTError(err);
// Enc
printf("Encrypting...\n");
err = gcry_cipher_encrypt(handle, out, inLen, in, inLen);
printGCRYPTError(err);
printf("Encrypted.\n");
gcry_cipher_final(handle);
//Out
printf("Plaintext Message: %s\n", in);
printf("Encrypted Message: ");
int index = 0;
for (index = 0; index<inLen; index++) {
printf("%02X", (unsigned char)out[index]);
}
printf("\n");
// Cleanup!
gcry_cipher_close(handle);
// Return
return out;
}
char* Decrypt(char* in, char* key, char* iv){
size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
if(strlen(key) != keyLength) {
printf("Invalid Key Size. Expected %zu got %lu\n", keyLength, strlen(key));
return NULL;
}
if(strlen(iv) != blkLength) {
printf("Invalid BLK/IV Size. Expected %zu got %lu\n", blkLength, strlen(iv));
return NULL;
}
gcry_cipher_hd_t handle;
gcry_error_t err = 0;
size_t inLen = strlen(in);
char * out = malloc(inLen);
// Open
err = gcry_cipher_open(&handle, GCRY_CIPHER, GCRY_C_MODE, 0);
printGCRYPTError(err);
// Set Key
err = gcry_cipher_setkey(handle, key, keyLength);
printGCRYPTError(err);
// Set IV
err = gcry_cipher_setiv(handle, iv, blkLength);
printGCRYPTError(err);
// Dec
printf("Decrypting...\n");
err = gcry_cipher_decrypt(handle, out, inLen, in, inLen);
printGCRYPTError(err);
printf("Decrypted.\n");
gcry_cipher_final(handle);
//Out
printf("Encrypted Message: ");
int index = 0;
for (index = 0; index<inLen; index++) {
printf("%02X", (unsigned char)out[index]);
}
printf("\n");
printf("Decrypted Message: %s\n", out);
// Cleanup!
gcry_cipher_close(handle);
// Return
return out;
}
int main() {
//aesTest();
char* encrypted = Encrypt("My test message", "sBK0hcXddz6mIKEsBK0hcXddz6mIKEAS", "sBK0uhSAUSUSHKES");
char* decrypted = Decrypt(encrypted, "sBK0hcXddz6mIKEsBK0hcXddz6mIKEAS", "sBK0uhSAUSUSHKES");
}
Console Output
Encrypting...
Encrypted.
Plaintext Message: My test message
Encrypted Message: 153C01DD7821E5113C25D2038F3644F7
Decrypting...
Failure: gcrypt/Invalid length
Failure: gcrypt/Invalid length
Decrypted.
Encrypted Message: 0000000000001000000000000000101400
Decrypted Message:
Thanks for looking!
Upvotes: 2
Views: 331
Reputation: 457
In addition to the key issues, I needed padding to be added to my AES plaintext before encryption.
Upvotes: 0
Reputation: 500
As selbie suggested, checking the error returned by gcry_cipher_encrypt
is useful: it says "Failure: gcrypt/Invalid length."
The root cause appears to be inLen
:
size_t inLen = strlen(in);
...
err = gcry_cipher_encrypt(handle, out, inLen, in, inLen);
printGCRYPTError(err);
gcry_cipher_final(handle);
returns the (expected?) output,
Message: My test message!
Encrypted Message = AEDBBB645CA54F16B5A279D77772A97B
Upvotes: 0
Reputation: 104464
As per the docs for libgcrypt:
Some encryption modes require that gcry_cipher_final is used before the final data chunk is passed to this function.
So I suspect you need to do two things:
Check the error code result from gcry_cipher_encrypt
consistent with how you were doing the prior function calls.
Invoke gcry_cipher_final(handle)
after you call encrypt - presuming you are doing a one-shot encryption of a buffer that is smaller than the block length of your cipher.
Upvotes: 0