Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

AES-GCM

1,256 views
Skip to first unread message

Anant Rao

unread,
May 27, 2014, 3:00:43 AM5/27/14
to
Hi,

I have ciphertext encrypted in Java (using BouncyCastle - BC) with "AES/GCM/NoPadding" cipher.

When I tried to decrypt it using OpenSSL in a 'c' program, the last call 'EVP_DecryptFinal_ex' fails. Somehow, ERR_print_errors_fp is not printing anything either.

I do have the IV that is used in the Java's encrypt. However, I don't know where BC stores the tag in the ciphertext. I tried it at the beginning and the end of the ciphertext, but it didn't help.

That is, I tried both of the following in the decrypt:

|IV|TAG|Ciphertext

|IV|Ciphertext|TAG
Both didn't work.

I tried both of the following as well with the same failure:
EVP_aes_256_gcm
EVP_aes_128_gcm

I have run out of ideas what else to try. Any help would be greatly appreciated.
Thanks in advance!


Jens Hiller

unread,
May 27, 2014, 3:33:44 AM5/27/14
to
Have a look at
https://www.openssl.org/docs/crypto/EVP_EncryptInit.html#GCM_Mode
and at the example in 'openssl/demos/evp/aesgcm.c' of the current master
branch (git://git.openssl.org/openssl.git).

Regards
Jens
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org

Jeffrey Walton

unread,
Jun 5, 2014, 11:55:25 PM6/5/14
to
On Tue, May 27, 2014 at 3:00 AM, Anant Rao <ar...@noknok.com> wrote:
> Hi,
>
> I have ciphertext encrypted in Java (using BouncyCastle - BC) with
> "AES/GCM/NoPadding" cipher.
>
> When I tried to decrypt it using OpenSSL in a 'c' program, the last call
> 'EVP_DecryptFinal_ex' fails. Somehow, ERR_print_errors_fp is not printing
> anything either.
>
> ...

I don't know about Bouncy Castle, but I believe Matt Caswell provided
an example of AES/GCM on the OpenSSL wiki at
http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption.

Jeff

Matt Caswell

unread,
Jun 6, 2014, 5:14:38 AM6/6/14
to
On 27 May 2014 08:00, Anant Rao <ar...@noknok.com> wrote:

> When I tried to decrypt it using OpenSSL in a 'c' program, the last call
> 'EVP_DecryptFinal_ex' fails. Somehow, ERR_print_errors_fp is not printing
> anything either.

If EVP_DecryptFinal_ex fails with GCM then this means that the tag has
failed to verify.

>
> I do have the IV that is used in the Java's encrypt. However, I don't know
> where BC stores the tag in the ciphertext. I tried it at the beginning and
> the end of the ciphertext, but it didn't help.
>
> That is, I tried both of the following in the decrypt:
>
> |IV|TAG|Ciphertext
>
> |IV|Ciphertext|TAG
> Both didn't work.

According to the documentation for javax.crypto.Cipher it says:
"Modes such as Authenticated Encryption with Associated Data (AEAD)
provide authenticity assurances for both confidential data and
Additional Associated Data (AAD) that is not encrypted. (Please see
RFC 5116 for more information on AEAD and AEAD algorithms such as
GCM/CCM.) Both confidential and AAD data can be used when calculating
the authentication tag (similar to a Mac). This tag is appended to the
ciphertext during encryption, and is verified on decryption."

>
> I tried both of the following as well with the same failure:
> EVP_aes_256_gcm
> EVP_aes_128_gcm
>
> I have run out of ideas what else to try. Any help would be greatly
> appreciated.

Make sure that the tag length that BouncyCastle is using is the same
as the tag length that openssl is using.

> /* Finalise: note get no output for GCM */
> 63
> <http://git.openssl.org/gitweb/?p=openssl.git;a=blob;f=demos/evp/aesgcm.c;h=324d8a55b1481c507c7754fa7f33c30a02bdb737;hb=HEAD#l63>
> EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
> ...
>
> What does this mean? That we shouldn't expect any output from this call
> and/or that we should ignore it?

The openssl API is designed to work with all types of modes. In some
modes (such as CBC) output is only emitted a whole block at a time.
Therefore sometimes in the call to EVP_EncryptFinal_ex you get some
extra data added to outbuf. In GCM mode this is not the case, so no
additional data will be added to outbuf - but you still need to call
EVP_EncryptFinal_ex.

Matt
Message has been deleted

jef...@janoah.net

unread,
May 31, 2015, 9:53:12 PM5/31/15
to
I'm having the same problem with version 1.0.2a. I wrote a small program to demonstrate the problem (or my mistake). Here is what my program outputs:

return from EVP_DecyrptUpdate: 1
After EVP_decryptFinal_ex
return from EVP_DecryptUpdate_ex: 0
len: 0
plaintext_len = 13
plainText: Hello World!

From my understanding, EVP_DecryptFinal_ex should return 0 on error and 1 on success. And if it does return 0, then you should not trust the decrypted result.

cipher[13] is what I created from the mirror image of the EVP_Encrypt* version of this program. I don't specify any padding which is supposed to default to on which means the EVP_DecryptFinal_ex is not supposed to fail with 0 from my understanding.

The problem is there isn't any data left to decrypt for EVP_DecryptFinal_ex, but I don't necessary know that when I call the EVP_DecryptFinal_ex, which is the whole point: it is supposed to keep track of whether there is left over encryption to finish up and remove any padding "according to the docs". But then I have seen others say GCM doesn't create any padding. (?)

What's the correct way to handle this?

Here is my source code example:

==================== START ====================
#include <stdio.h>
#include <stdlib.h> // EXIT_SUCCESS
#include <unistd.h> // _exit()
#include <openssl/evp.h>
#include <openssl/err.h>

int main(int argc, char *argv[])
{

unsigned char key[32] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x0,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x0 };

unsigned char iv[12] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xa, 0xb, 0xc };

unsigned char cipher[13] = { 0x72, 0x1A, 0xFE, 0x88,
0x6D, 0x5C, 0x3E, 0x36,
0x43, 0xC1, 0x3D, 0x38,
0x9F };

EVP_CIPHER_CTX *ctxDecrypt;
int len;
int plaintext_len;
int ret;
unsigned char plainText[256];
unsigned cipher_len = 13;

if(!(ctxDecrypt = EVP_CIPHER_CTX_new())) {
fprintf(stderr,"EVP_CIPHER_CTX_new() failed.\n");
_exit(EXIT_FAILURE);
}

if(!EVP_DecryptInit_ex(ctxDecrypt, EVP_aes_256_gcm(), NULL, NULL, NULL)) {
fprintf(stderr,"EVP_DecryptInit_ex() failed.\n");
_exit(EXIT_FAILURE);
}

if(!EVP_DecryptInit_ex(ctxDecrypt, NULL, NULL, key, iv)) {
fprintf(stderr,"EVP_EncryptInit_ex() #2 failed.\n");
_exit(EXIT_FAILURE);
}

if (!EVP_CIPHER_CTX_set_key_length(ctxDecrypt, 32)) {
fprintf(stderr, "EVP_CIPHER_CTX_set_key_length failed.\n");
_exit(EXIT_FAILURE);
}

if (!EVP_CIPHER_CTX_ctrl(ctxDecrypt, EVP_CTRL_GCM_SET_IVLEN, 12, NULL)) {
fprintf(stderr, "EVP_CIPHER_CTX_ctrl failed.\n");
_exit(EXIT_FAILURE);
}

ret = EVP_DecryptUpdate(ctxDecrypt, plainText, &len, cipher, cipher_len);
printf("return from EVP_DecyrptUpdate: %d\n", ret);
if(ret != 1) {
fprintf(stderr, "EVP_DecryptUpdate failed.\n");
ERR_print_errors_fp(stderr);
_exit(EXIT_FAILURE);
}

plaintext_len = len;

ret = EVP_DecryptFinal_ex(ctxDecrypt, plainText + len, &len);
printf("After EVP_decryptFinal_ex\n");
printf(" return from EVP_DecryptUpdate_ex: %d\n", ret);
printf(" len: %d\n", len);
printf(" plaintext_len = %d\n", plaintext_len);
printf(" plainText: %s\n", plainText);

EVP_CIPHER_CTX_free(ctxDecrypt);

==================== END ====================
0 new messages