I'm trying to use gcrypt to make a simple cryptography a txt file. When I executes the command gcry_cipher_encrypt
i receive the follow errors:
gcry_strsource => User defined source 1
gcry_strerror => Invalid length
This occurs when I use the content of one txt file, if I hardcode the text content in the code this function works, what is the possible cause?
Text file content
test test test test test
Crypt code:
void myEncrypt::aesEncrypt(char *txtInput, int txtInputSize, char *txtOutput){
gcry_error_t gcryError;
gcry_cipher_hd_t gcryCipherHd;
size_t index;
size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
//char * txtBuffer = "123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ";
char * txtBuffer = txtInput;
size_t txtLength = strlen(txtBuffer)+1; // string plus termination
char * encBuffer = (char *)malloc(txtLength);
char * outBuffer = (char *)malloc(txtLength);
char * aesSymKey = "one test AES key"; // 16 bytes
char * iniVector = "a test ini value"; // 16 bytes
gcryError = gcry_cipher_open(
&gcryCipherHd, // gcry_cipher_hd_t *
GCRY_CIPHER, // int
GCRY_C_MODE, // int
0); // unsigned int
if (gcryError)
{
printf("gcry_cipher_open failed: %s/%s\n",
gcry_strsource(gcryError),
gcry_strerror(gcryError));
return;
}
printf("gcry_cipher_open worked\n");
gcryError = gcry_cipher_setkey(gcryCipherHd, aesSymKey, keyLength);
if (gcryError)
{
printf("gcry_cipher_setkey failed: %s/%s\n",
gcry_strsource(gcryError),
gcry_strerror(gcryError));
return;
}
printf("gcry_cipher_setkey worked\n");
gcryError = gcry_cipher_setiv(gcryCipherHd, iniVector, blkLength);
if (gcryError)
{
printf("gcry_cipher_setiv failed: %s/%s\n",
gcry_strsource(gcryError),
gcry_strerror(gcryError));
return;
}
printf("gcry_cipher_setiv worked\n");
gcryError = gcry_cipher_encrypt(
gcryCipherHd, // gcry_cipher_hd_t
encBuffer, // void *
txtLength, // size_t
txtBuffer, // const void *
txtLength); // size_t
if (gcryError)
{
printf("gcry_cipher_encrypt failed: %s/%s\n",
gcry_strsource(gcryError),
gcry_strerror(gcryError));
return;
}
printf("gcry_cipher_encrypt worked\n");
gcryError = gcry_cipher_setiv(gcryCipherHd, iniVector, blkLength);
if (gcryError)
{
printf("gcry_cipher_setiv failed: %s/%s\n",
gcry_strsource(gcryError),
gcry_strerror(gcryError));
return;
}
printf("gcry_cipher_setiv worked\n");
gcryError = gcry_cipher_decrypt(
gcryCipherHd, // gcry_cipher_hd_t
outBuffer, // void *
txtLength, // size_t
encBuffer, // const void *
txtLength); // size_t
if (gcryError)
{
printf("gcry_cipher_decrypt failed: %s/%s\n",
gcry_strsource(gcryError),
gcry_strerror(gcryError));
return;
}
printf("gcry_cipher_decrypt worked\n");
printf("keyLength = %d\n", keyLength);
printf("blkLength = %d\n", blkLength);
printf("txtLength = %d\n", txtLength);
printf("aesSymKey = %s\n", aesSymKey);
printf("iniVector = %s\n", iniVector);
printf("txtBuffer = %s\n", txtBuffer);
printf("encBuffer = ");
for (index = 0; index<txtLength; index++)
printf("%02X", (unsigned char)encBuffer[index]);
printf("\n");
printf("outBuffer = %s\n", outBuffer);
// clean up after ourselves
gcry_cipher_close(gcryCipherHd);
free(encBuffer);
free(outBuffer);
}
Well... I don't know libgcrypt, but...
In this page, in the description of the gcry_cipher_encrypt()
function, I read
Depending on the selected algorithms and encryption mode, the length of the buffers must be a multiple of the block size.
If I understand well, you're using AES as algorithm so, according various sources (wikipedia, by example), the block size for AES is 16 bytes.
If you look at the original txtBuffer
, you can see that was of 63 bytes (9 numbers, 26+26 letters, 2 spaces), so (adding +1 for the terminal zero) txtLength
was 64, an exact multiple of 16.
Your text is of 25 bytes, so your texLength
if 26, that isn't a multiple of 16.
En passant: you're using C++, so I strongly suggest to avoid malloc()
and use new []
instead; or (better, IMHO) std::string
with reserve()
, c_str()
and data()
.
I suppose you should use txtBuffer
as an intermediate allocated buffer.
Using the new []
solution, I suppose you should modify you code in this way
std::size_t txtLength = strlen(txtInput)+1; // from txtInput, not txtBuffer
if ( 0U != (txtLength & 0xfU) )
txtLength += 0x10U - (txtLength & 0xfU);
char * txtBuffer = new char[txtLength];
char * encBuffer = new char[txtLength];
char * outBuffer = new char[txtLength];
std::strcpy(txtBuffer, txtInput);
p.s.: caution, code not tested.
p.s.2: sorry for my bad English.