[git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-172-g5e66a4f
by Jussi Kivilinna
cvs at cvs.gnupg.org
Sat Feb 28 18:25:58 CET 2015
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".
The branch, master has been updated
via 5e66a4f8d5a63f58caeee367433dd8dd32346083 (commit)
from 505decf5369970219ddc9e78a20f97c623957b78 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 5e66a4f8d5a63f58caeee367433dd8dd32346083
Author: Jussi Kivilinna <jussi.kivilinna at iki.fi>
Date: Sat Feb 28 18:04:34 2015 +0200
Fix in-place encryption for OCB mode
* cipher/cipher-ocb.c (ocb_checksum): New.
(ocb_crypt): Move checksum calculation outside main crypt loop, do
checksum calculation for encryption before inbuf is overwritten.
* tests/basic.c (check_ocb_cipher): Rename to ...
(do_check_ocb_cipher): ... to this and add argument for testing
in-place encryption/decryption.
(check_ocb_cipher): New.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
diff --git a/cipher/cipher-ocb.c b/cipher/cipher-ocb.c
index 25466f0..652683c 100644
--- a/cipher/cipher-ocb.c
+++ b/cipher/cipher-ocb.c
@@ -299,6 +299,21 @@ _gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf,
}
+/* Checksumming for encrypt and decrypt. */
+static void ocb_checksum(unsigned char *chksum, const unsigned char *plainbuf,
+ size_t nblks)
+{
+ while (nblks > 0)
+ {
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ buf_xor_1(chksum, plainbuf, OCB_BLOCK_LEN);
+
+ plainbuf += OCB_BLOCK_LEN;
+ nblks--;
+ }
+}
+
+
/* Common code for encrypt and decrypt. */
static gcry_err_code_t
ocb_crypt (gcry_cipher_hd_t c, int encrypt,
@@ -308,6 +323,7 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt,
unsigned char l_tmp[OCB_BLOCK_LEN];
unsigned int burn = 0;
unsigned int nburn;
+ size_t nblks = inbuflen / OCB_BLOCK_LEN;
/* Check that a nonce and thus a key has been set and that we are
not yet in end of data state. */
@@ -324,6 +340,12 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt,
else if ((inbuflen % OCB_BLOCK_LEN))
return GPG_ERR_INV_LENGTH; /* We support only full blocks for now. */
+ if (encrypt)
+ {
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ ocb_checksum (c->u_ctr.ctr, inbuf, nblks);
+ }
+
/* Encrypt all full blocks. */
while (inbuflen >= OCB_BLOCK_LEN)
{
@@ -341,15 +363,18 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt,
burn = nburn > burn ? nburn : burn;
buf_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN);
- /* Checksum_i = Checksum_{i-1} xor P_i */
- buf_xor_1 (c->u_ctr.ctr, encrypt? inbuf : outbuf, OCB_BLOCK_LEN);
-
inbuf += OCB_BLOCK_LEN;
inbuflen -= OCB_BLOCK_LEN;
outbuf += OCB_BLOCK_LEN;
outbuflen =- OCB_BLOCK_LEN;
}
+ if (!encrypt)
+ {
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ ocb_checksum (c->u_ctr.ctr, outbuf - nblks * OCB_BLOCK_LEN, nblks);
+ }
+
/* Encrypt final partial block. Note that we expect INBUFLEN to be
shorter than OCB_BLOCK_LEN (see above). */
if (inbuflen)
diff --git a/tests/basic.c b/tests/basic.c
index 869b381..6ebc056 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -2781,7 +2781,7 @@ check_ccm_cipher (void)
static void
-check_ocb_cipher (void)
+do_check_ocb_cipher (int inplace)
{
/* Note that we use hex strings and not binary strings in TV. That
makes it easier to maintain the test vectors. */
@@ -3028,7 +3028,18 @@ check_ocb_cipher (void)
err = gcry_cipher_final (hde);
if (!err)
- err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, plain, plainlen);
+ {
+ if (inplace)
+ {
+ memcpy(out, plain, plainlen);
+ err = gcry_cipher_encrypt (hde, out, plainlen, NULL, 0);
+ }
+ else
+ {
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+ plain, plainlen);
+ }
+ }
if (err)
{
fail ("cipher-ocb, gcry_cipher_encrypt failed (tv %d): %s\n",
@@ -3075,7 +3086,19 @@ check_ocb_cipher (void)
/* Now for the decryption. */
err = gcry_cipher_final (hdd);
if (!err)
- err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0);
+ {
+ if (inplace)
+ {
+ err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0);
+ }
+ else
+ {
+ unsigned char tmp[MAX_DATA_LEN];
+
+ memcpy(tmp, out, plainlen);
+ err = gcry_cipher_decrypt (hdd, out, plainlen, tmp, plainlen);
+ }
+ }
if (err)
{
fail ("cipher-ocb, gcry_cipher_decrypt (tv %d) failed: %s\n",
@@ -3130,6 +3153,18 @@ check_ocb_cipher (void)
static void
+check_ocb_cipher (void)
+{
+ /* Check OCB cipher with separate destination and source buffers for
+ * encryption/decryption. */
+ do_check_ocb_cipher(0);
+
+ /* Check OCB cipher with inplace encrypt/decrypt. */
+ do_check_ocb_cipher(1);
+}
+
+
+static void
check_stream_cipher (void)
{
static const struct tv
-----------------------------------------------------------------------
Summary of changes:
cipher/cipher-ocb.c | 31 ++++++++++++++++++++++++++++---
tests/basic.c | 41 ++++++++++++++++++++++++++++++++++++++---
2 files changed, 66 insertions(+), 6 deletions(-)
hooks/post-receive
--
The GNU crypto library
http://git.gnupg.org
_______________________________________________
Gnupg-commits mailing list
Gnupg-commits at gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-commits
More information about the Gcrypt-devel
mailing list