miracl / MIRACL

MIRACL Cryptographic SDK: Multiprecision Integer and Rational Arithmetic Cryptographic Library is a C software library that is widely regarded by developers as the gold standard open source SDK for elliptic curve cryptography (ECC).
https://miracl.com
654 stars 242 forks source link

Suggestion: AES-GCM in-place decryption is not supported, but is very easily implemented (mrgcm.c) #27

Closed erikbs closed 8 years ago

erikbs commented 8 years ago

Hi

I have a suggestion concerning in-place encryption and decryption using the AES-GCM algorithm (mrgcm.c).

The implementation currently supports in-place encryption by passing the same pointer to both the char *plain and char *cipher parameters of gcm_add_cipher, like this: gcm_add_cipher(&g, GCM_ENCRYPTING, BUFFER_NAME, len, BUFFER_NAME);

In-place decryption, however, works only partially. If GCM_DECRYPTING is passed instead of GCM_ENCRYPTING, the message is decrypted correctly, but the tag is computed in the same way as during encryption. This is of course because the if statements on lines 197 and 198 become identical. Consider the following lines in mrgcm.c:

197. if (mode==GCM_ENCRYPTING) cipher[j]=plain[j]^B[i];
198. if (mode==GCM_DECRYPTING) plain[j]=cipher[j]^B[i];
199. g->stateX[i]^=cipher[j++];

If the incrementation is placed on a separate line and the if statements are reordered like this …:

197. if (mode==GCM_ENCRYPTING) cipher[j]=plain[j]^B[i];
198. g->stateX[i]^=cipher[j];
199. if (mode==GCM_DECRYPTING) plain[j]=cipher[j]^B[i];
200. j++;

… then the tag is computed correctly for in-place decryption as well. As far as I can see, it should not cause any problems. Any thought on this idea?

TL;DR: swapping lines 198 and 199 in mrgcm.c, then placing j++ on a separate line, will make in-place decryption work.

mcarrickscott commented 8 years ago

Good idea! We will use that...

Thanks!

Mike

On Tue, Aug 2, 2016 at 10:42 PM, erikbs notifications@github.com wrote:

Hi

I have a suggestion concerning in-place encryption and decryption using the AES-GCM algorithm (mrgcm.c).

The implementation currently supports in-place encryption by passing the same pointer to both the char plain and char cipher parameters of gcm_add_cipher, like this: gcm_add_cipher(&g, GCM_ENCRYPTING, BUFFER_NAME, len, BUFFER_NAME);

In-place decryption, however, works only partially. If GCM_DECRYPTING is passed instead of GCM_ENCRYPTING, the message is decrypted correctly, but the tag is computed in the same way as during encryption. This is of course because the if statements on lines 197 and 198 become identical. Consider the following lines in mrgcm.c:

  1. if (mode==GCM_ENCRYPTING) cipher[j]=plain[j]^B[i];
  2. if (mode==GCM_DECRYPTING) plain[j]=cipher[j]^B[i];
  3. g->stateX[i]^=cipher[j++];

If the incrementation is placed on a separate line and the if statements are reordered like this …:

  1. if (mode==GCM_ENCRYPTING) cipher[j]=plain[j]^B[i];
  2. g->stateX[i]^=cipher[j];
  3. if (mode==GCM_DECRYPTING) plain[j]=cipher[j]^B[i];
  4. j++;

… then the tag is computed correctly for in-place decryption as well. As far as I can see, it should not cause any problems. Any thought on this idea?

TL;DR: swapping lines 198 and 199 in mrgcm.c, then placing j++ on a separate line, will make in-place decryption work.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/miracl/MIRACL/issues/27, or mute the thread https://github.com/notifications/unsubscribe-auth/ACm8jpcfj7Mx6i1NzYDXO78xRJNX4w4jks5qb7mvgaJpZM4JbFI0 .