0

I am using AES/GCM, but the following is a general question for other modes, like AES/CBC. I have the following call into libgcrypt:

#define COUNTOF(x) ( sizeof(x) / sizeof(x[0]) )
#define ROUNDUP(x, b) ( (x) ? (((x) + (b - 1)) / b) * b : b)

const byte cipher[] =  { 0xD0,0x6D,0x69,0x0F ... };
byte recovered[ ROUNDUP(COUNTOF(cipher), 16) ];
...

err = gcry_cipher_decrypt(
    handle,             // gcry_cipher_hd_t
    recovered,          // void *
    COUNTOF(recovered), // size_t
    cipher,             // const void *
    COUNTOF(cipher));   // size_t

I cannot figure out how to determine what the size of the resulting recovered text is. I've checked the Working with cipher handles reference, and its not discussed (and there are 0 hits for 'pad). I also checked the libgrcrypt self tests in tests/basic.c and tests/fipsdrv.c, but they use the same oversized buffer and never prune the buffer to the actual size.

How do I determine the size of the data returned to me in the recovered buffer?

jww
  • 97,681
  • 90
  • 411
  • 885
  • Which cipher are you using? – Collin Dauphinee Mar 04 '15 at 01:50
  • @Collin - I tried to avoid that because the particular instance of the coding problem uses AES/GCM ([Steps to decrypt encrypted data in Crypto++ in libgcrypt](http://stackoverflow.com/a/28843458)). But in general terms for modes like CBC, I need to know what the size of the recovered text is. – jww Mar 04 '15 at 01:53

1 Answers1

2

You need to apply a padding scheme to your input, and remove the padding after the decrypt. gcrypt doesn't handle it for you.

The most common choice is PKCS#7. A high level overview is that you fill the unused bytes in your final block with the number of padded bytes (block_size - used_bytes). If your input length is a multiple of the block size, you follow it with a block filled with block_size bytes.

For example, with 8-byte blocks and 4 bytes of input, your raw input would look like:

AB CD EF FF 04 04 04 04

When you do the decrypt, you take the value of the last byte of the last block, and remove that many bytes from the end.

Community
  • 1
  • 1
Collin Dauphinee
  • 13,664
  • 1
  • 40
  • 71
  • *"You need to apply a padding scheme to your input, and remove the padding after the decrypt. gcrypt normally doesn't handle it for you"* - oh, my bad. I thought the library did it. Of all the crypto libraries I work with, that is a first (OpenSSL, Crypto++, and occasionly Cryptlib and Botan). I guess my next question is, what are the library function to apply and remove the pad? Padding is not discussed in [Working with cipher handles](https://www.gnupg.org/documentation/manuals/gcrypt/Working-with-cipher-handles.html) (there are 0 hits on the page). – jww Mar 04 '15 at 02:00
  • I'm not very familiar with gcrypt, but I don't think it provides any facility to deal with padding. – Collin Dauphinee Mar 04 '15 at 02:01
  • The manual says the output buffer has to be a multiple of the block cipher's size (hence the reason for `ROUNDUP` in the code above). So I create an oversized buffer for even AES/GCM mode. In this case, there's no padding to remove, and no way to get it from the library. It appears to make it impossible to write generic code... – jww Mar 04 '15 at 02:10
  • I don't think you can generalize this; if you're using GCM, it's up to you to pass along the plain text size as part of the additional data. – Collin Dauphinee Mar 04 '15 at 02:26