Mailing List Archive

[PATCH 2/2] cipher: move CBC/CFB/CTR self-tests to tests/basic
* cipher/Makefile.am: Remove 'cipher-selftest.c' and 'cipher-selftest.h'.
* cipher/cipher-selftest.c: Remove (refactor these tests to
tests/basic.c).
* cipher/cipher-selftest.h: Remove.
* cipher/blowfish.c (selftest_ctr, selftest_cbc, selftest_cfb): Remove.
(selftest): Remove CTR/CBC/CFB bulk self-tests.
* cipher/camellia-glue.c (selftest_ctr_128, selftest_cbc_128)
(selftest_cfb_128): Remove.
(selftest): Remove CTR/CBC/CFB bulk self-tests.
* cipher/cast5.c (selftest_ctr, selftest_cbc, selftest_cfb): Remove.
(selftest): Remove CTR/CBC/CFB bulk self-tests.
* cipher/des.c (bulk_selftest_setkey, selftest_ctr, selftest_cbc)
(selftest_cfb): Remove.
(selftest): Remove CTR/CBC/CFB bulk self-tests.
* cipher/rijndael.c (selftest_basic_128, selftest_basic_192)
(selftest_basic_256): Allocate context from stack instead of heap and
handle alignment manually.
(selftest_ctr_128, selftest_cbc_128, selftest_cfb_128): Remove.
(selftest): Remove CTR/CBC/CFB bulk self-tests.
* cipher/serpent.c (selftest_ctr_128, selftest_cbc_128)
(selftest_cfb_128): Remove.
(selftest): Remove CTR/CBC/CFB bulk self-tests.
* cipher/sm4.c (selftest_ctr_128, selftest_cbc_128)
(selftest_cfb_128): Remove.
(selftest): Remove CTR/CBC/CFB bulk self-tests.
* cipher/twofish.c (selftest_ctr, selftest_cbc, selftest_cfb): Remove.
(selftest): Remove CTR/CBC/CFB bulk self-tests.
* tests/basic.c (buf_xor, cipher_cbc_bulk_test, buf_xor_2dst)
(cipher_cfb_bulk_test, cipher_ctr_bulk_test): New.
(check_ciphers): Run cipher_cbc_bulk_test(), cipher_cfb_bulk_test() and
cipher_ctr_bulk_test() for block ciphers.
---

CBC/CFB/CTR bulk self-tests are quite computationally heavy and
slow down use cases where application opens cipher context once,
does processing and exits. Better place for these tests is in
`tests/basic`.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
---
cipher/Makefile.am | 1 -
cipher/blowfish.c | 53 ---
cipher/camellia-glue.c | 49 ---
cipher/cast5.c | 53 ---
cipher/cipher-selftest.c | 512 ----------------------
cipher/cipher-selftest.h | 69 ---
cipher/des.c | 72 ----
cipher/rijndael-aesni.c | 1 -
cipher/rijndael-armv8-ce.c | 1 -
cipher/rijndael-padlock.c | 1 -
cipher/rijndael-ssse3-amd64.c | 1 -
cipher/rijndael-vaes.c | 1 -
cipher/rijndael.c | 92 +---
cipher/serpent.c | 53 ---
cipher/sm4.c | 50 ---
cipher/twofish.c | 49 ---
tests/basic.c | 772 ++++++++++++++++++++++++++++++++++
17 files changed, 780 insertions(+), 1050 deletions(-)
delete mode 100644 cipher/cipher-selftest.c
delete mode 100644 cipher/cipher-selftest.h

diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index a6171bf5..250b229e 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -55,7 +55,6 @@ libcipher_la_SOURCES = \
cipher-eax.c \
cipher-siv.c \
cipher-gcm-siv.c \
- cipher-selftest.c cipher-selftest.h \
pubkey.c pubkey-internal.h pubkey-util.c \
md.c \
mac.c mac-internal.h \
diff --git a/cipher/blowfish.c b/cipher/blowfish.c
index 7b001306..1b11d718 100644
--- a/cipher/blowfish.c
+++ b/cipher/blowfish.c
@@ -38,7 +38,6 @@
#include "cipher.h"
#include "bufhelp.h"
#include "cipher-internal.h"
-#include "cipher-selftest.h"

#define BLOWFISH_BLOCKSIZE 8
#define BLOWFISH_KEY_MIN_BITS 8
@@ -856,48 +855,6 @@ _gcry_blowfish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
}


-/* Run the self-tests for BLOWFISH-CTR, tests IV increment of bulk CTR
- encryption. Returns NULL on success. */
-static const char *
-selftest_ctr (void)
-{
- const int nblocks = 4+1;
- const int blocksize = BLOWFISH_BLOCKSIZE;
- const int context_size = sizeof(BLOWFISH_context);
-
- return _gcry_selftest_helper_ctr("BLOWFISH", &bf_setkey,
- &encrypt_block, nblocks, blocksize, context_size);
-}
-
-
-/* Run the self-tests for BLOWFISH-CBC, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char *
-selftest_cbc (void)
-{
- const int nblocks = 4+2;
- const int blocksize = BLOWFISH_BLOCKSIZE;
- const int context_size = sizeof(BLOWFISH_context);
-
- return _gcry_selftest_helper_cbc("BLOWFISH", &bf_setkey,
- &encrypt_block, nblocks, blocksize, context_size);
-}
-
-
-/* Run the self-tests for BLOWFISH-CFB, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char *
-selftest_cfb (void)
-{
- const int nblocks = 4+2;
- const int blocksize = BLOWFISH_BLOCKSIZE;
- const int context_size = sizeof(BLOWFISH_context);
-
- return _gcry_selftest_helper_cfb("BLOWFISH", &bf_setkey,
- &encrypt_block, nblocks, blocksize, context_size);
-}
-
-
static const char*
selftest(void)
{
@@ -911,7 +868,6 @@ selftest(void)
{ 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
static const byte cipher3[] =
{ 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
- const char *r;

bf_setkey( (void *) &c,
(const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26,
@@ -931,15 +887,6 @@ selftest(void)
if( memcmp( buffer, plain3, 8 ) )
return "Blowfish selftest failed (4).";

- if ( (r = selftest_cbc ()) )
- return r;
-
- if ( (r = selftest_cfb ()) )
- return r;
-
- if ( (r = selftest_ctr ()) )
- return r;
-
return NULL;
}

diff --git a/cipher/camellia-glue.c b/cipher/camellia-glue.c
index a854b82d..c938be71 100644
--- a/cipher/camellia-glue.c
+++ b/cipher/camellia-glue.c
@@ -64,7 +64,6 @@
#include "camellia.h"
#include "bufhelp.h"
#include "cipher-internal.h"
-#include "cipher-selftest.h"
#include "bulkhelp.h"

/* Helper macro to force alignment to 16 bytes. */
@@ -1454,44 +1453,6 @@ _gcry_camellia_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
return nblocks;
}

-/* Run the self-tests for CAMELLIA-CTR-128, tests IV increment of bulk CTR
- encryption. Returns NULL on success. */
-static const char*
-selftest_ctr_128 (void)
-{
- const int nblocks = 64+32+16+1;
- const int blocksize = CAMELLIA_BLOCK_SIZE;
- const int context_size = sizeof(CAMELLIA_context);
-
- return _gcry_selftest_helper_ctr("CAMELLIA", &camellia_setkey,
- &camellia_encrypt, nblocks, blocksize, context_size);
-}
-
-/* Run the self-tests for CAMELLIA-CBC-128, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char*
-selftest_cbc_128 (void)
-{
- const int nblocks = 64+32+16+2;
- const int blocksize = CAMELLIA_BLOCK_SIZE;
- const int context_size = sizeof(CAMELLIA_context);
-
- return _gcry_selftest_helper_cbc("CAMELLIA", &camellia_setkey,
- &camellia_encrypt, nblocks, blocksize, context_size);
-}
-
-/* Run the self-tests for CAMELLIA-CFB-128, tests bulk CFB decryption.
- Returns NULL on success. */
-static const char*
-selftest_cfb_128 (void)
-{
- const int nblocks = 64+32+16+2;
- const int blocksize = CAMELLIA_BLOCK_SIZE;
- const int context_size = sizeof(CAMELLIA_context);
-
- return _gcry_selftest_helper_cfb("CAMELLIA", &camellia_setkey,
- &camellia_encrypt, nblocks, blocksize, context_size);
-}

static const char *
selftest(void)
@@ -1499,7 +1460,6 @@ selftest(void)
CAMELLIA_context ctx;
byte scratch[16];
cipher_bulk_ops_t bulk_ops;
- const char *r;

/* These test vectors are from RFC-3713 */
static const byte plaintext[]=
@@ -1563,15 +1523,6 @@ selftest(void)
if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
return "CAMELLIA-256 test decryption failed.";

- if ( (r = selftest_ctr_128 ()) )
- return r;
-
- if ( (r = selftest_cbc_128 ()) )
- return r;
-
- if ( (r = selftest_cfb_128 ()) )
- return r;
-
return NULL;
}

diff --git a/cipher/cast5.c b/cipher/cast5.c
index 837ea0fe..20bf7479 100644
--- a/cipher/cast5.c
+++ b/cipher/cast5.c
@@ -45,7 +45,6 @@
#include "bithelp.h"
#include "bufhelp.h"
#include "cipher-internal.h"
-#include "cipher-selftest.h"

/* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */
#undef USE_AMD64_ASM
@@ -991,48 +990,6 @@ _gcry_cast5_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
}


-/* Run the self-tests for CAST5-CTR, tests IV increment of bulk CTR
- encryption. Returns NULL on success. */
-static const char *
-selftest_ctr (void)
-{
- const int nblocks = 4+1;
- const int blocksize = CAST5_BLOCKSIZE;
- const int context_size = sizeof(CAST5_context);
-
- return _gcry_selftest_helper_ctr("CAST5", &cast_setkey,
- &encrypt_block, nblocks, blocksize, context_size);
-}
-
-
-/* Run the self-tests for CAST5-CBC, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char *
-selftest_cbc (void)
-{
- const int nblocks = 4+2;
- const int blocksize = CAST5_BLOCKSIZE;
- const int context_size = sizeof(CAST5_context);
-
- return _gcry_selftest_helper_cbc("CAST5", &cast_setkey,
- &encrypt_block, nblocks, blocksize, context_size);
-}
-
-
-/* Run the self-tests for CAST5-CFB, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char *
-selftest_cfb (void)
-{
- const int nblocks = 4+2;
- const int blocksize = CAST5_BLOCKSIZE;
- const int context_size = sizeof(CAST5_context);
-
- return _gcry_selftest_helper_cfb("CAST5", &cast_setkey,
- &encrypt_block, nblocks, blocksize, context_size);
-}
-
-
static const char*
selftest(void)
{
@@ -1046,7 +1003,6 @@ selftest(void)
static const byte cipher[8] =
{ 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
byte buffer[8];
- const char *r;

cast_setkey( &c, key, 16, &bulk_ops );
encrypt_block( &c, buffer, plain );
@@ -1082,15 +1038,6 @@ selftest(void)
}
#endif

- if ( (r = selftest_cbc ()) )
- return r;
-
- if ( (r = selftest_cfb ()) )
- return r;
-
- if ( (r = selftest_ctr ()) )
- return r;
-
return NULL;
}

diff --git a/cipher/cipher-selftest.c b/cipher/cipher-selftest.c
deleted file mode 100644
index d7f38a42..00000000
--- a/cipher/cipher-selftest.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/* cipher-selftest.c - Helper functions for bulk encryption selftests.
- * Copyright (C) 2013,2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#ifdef HAVE_SYSLOG
-# include <syslog.h>
-#endif /*HAVE_SYSLOG*/
-
-#include "types.h"
-#include "g10lib.h"
-#include "cipher.h"
-#include "bufhelp.h"
-#include "cipher-selftest.h"
-#include "cipher-internal.h"
-
-#ifdef HAVE_STDINT_H
-# include <stdint.h> /* uintptr_t */
-#elif defined(HAVE_INTTYPES_H)
-# include <inttypes.h>
-#else
-/* In this case, uintptr_t is provided by config.h. */
-#endif
-
-/* Helper macro to force alignment to 16 bytes. */
-#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
-# define ATTR_ALIGNED_16 __attribute__ ((aligned (16)))
-#else
-# define ATTR_ALIGNED_16
-#endif
-
-
-/* Return an allocated buffers of size CONTEXT_SIZE with an alignment
- of 16. The caller must free that buffer using the address returned
- at R_MEM. Returns NULL and sets ERRNO on failure. */
-void *
-_gcry_cipher_selftest_alloc_ctx (const int context_size, unsigned char **r_mem)
-{
- int offs;
- unsigned int ctx_aligned_size, memsize;
-
- ctx_aligned_size = context_size + 15;
- ctx_aligned_size -= ctx_aligned_size & 0xf;
-
- memsize = ctx_aligned_size + 16;
-
- *r_mem = xtrycalloc (1, memsize);
- if (!*r_mem)
- return NULL;
-
- offs = (16 - ((uintptr_t)*r_mem & 15)) & 15;
- return (void*)(*r_mem + offs);
-}
-
-
-/* Run the self-tests for <block cipher>-CBC-<block size>, tests bulk CBC
- decryption. Returns NULL on success. */
-const char *
-_gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey_func,
- gcry_cipher_encrypt_t encrypt_one,
- const int nblocks, const int blocksize,
- const int context_size)
-{
- cipher_bulk_ops_t bulk_ops = { 0, };
- int i, offs;
- unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem;
- unsigned int ctx_aligned_size, memsize;
-
- static const unsigned char key[16] ATTR_ALIGNED_16 = {
- 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
- 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22
- };
-
- /* Allocate buffers, align first two elements to 16 bytes and latter to
- block size. */
- ctx_aligned_size = context_size + 15;
- ctx_aligned_size -= ctx_aligned_size & 0xf;
-
- memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 3) + 16;
-
- mem = xtrycalloc (1, memsize);
- if (!mem)
- return "failed to allocate memory";
-
- offs = (16 - ((uintptr_t)mem & 15)) & 15;
- ctx = (void*)(mem + offs);
- iv = ctx + ctx_aligned_size;
- iv2 = iv + blocksize;
- plaintext = iv2 + blocksize;
- plaintext2 = plaintext + nblocks * blocksize;
- ciphertext = plaintext2 + nblocks * blocksize;
-
- /* Initialize ctx */
- if (setkey_func (ctx, key, sizeof(key), &bulk_ops) != GPG_ERR_NO_ERROR)
- {
- xfree(mem);
- return "setkey failed";
- }
-
- /* Test single block code path */
- memset (iv, 0x4e, blocksize);
- memset (iv2, 0x4e, blocksize);
- for (i = 0; i < blocksize; i++)
- plaintext[i] = i;
-
- /* CBC manually. */
- buf_xor (ciphertext, iv, plaintext, blocksize);
- encrypt_one (ctx, ciphertext, ciphertext);
- memcpy (iv, ciphertext, blocksize);
-
- /* CBC decrypt. */
- bulk_ops.cbc_dec (ctx, iv2, plaintext2, ciphertext, 1);
- if (memcmp (plaintext2, plaintext, blocksize))
- {
- xfree (mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CBC-%d test failed (plaintext mismatch)", cipher,
- blocksize * 8);
-#else
- (void)cipher; /* Not used. */
-#endif
- return "selftest for CBC failed - see syslog for details";
- }
-
- if (memcmp (iv2, iv, blocksize))
- {
- xfree (mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CBC-%d test failed (IV mismatch)", cipher, blocksize * 8);
-#endif
- return "selftest for CBC failed - see syslog for details";
- }
-
- /* Test parallelized code paths */
- memset (iv, 0x5f, blocksize);
- memset (iv2, 0x5f, blocksize);
-
- for (i = 0; i < nblocks * blocksize; i++)
- plaintext[i] = i;
-
- /* Create CBC ciphertext manually. */
- for (i = 0; i < nblocks * blocksize; i+=blocksize)
- {
- buf_xor (&ciphertext[i], iv, &plaintext[i], blocksize);
- encrypt_one (ctx, &ciphertext[i], &ciphertext[i]);
- memcpy (iv, &ciphertext[i], blocksize);
- }
-
- /* Decrypt using bulk CBC and compare result. */
- bulk_ops.cbc_dec (ctx, iv2, plaintext2, ciphertext, nblocks);
-
- if (memcmp (plaintext2, plaintext, nblocks * blocksize))
- {
- xfree (mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CBC-%d test failed (plaintext mismatch, parallel path)",
- cipher, blocksize * 8);
-#endif
- return "selftest for CBC failed - see syslog for details";
- }
- if (memcmp (iv2, iv, blocksize))
- {
- xfree (mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CBC-%d test failed (IV mismatch, parallel path)",
- cipher, blocksize * 8);
-#endif
- return "selftest for CBC failed - see syslog for details";
- }
-
- xfree (mem);
- return NULL;
-}
-
-/* Run the self-tests for <block cipher>-CFB-<block size>, tests bulk CFB
- decryption. Returns NULL on success. */
-const char *
-_gcry_selftest_helper_cfb (const char *cipher, gcry_cipher_setkey_t setkey_func,
- gcry_cipher_encrypt_t encrypt_one,
- const int nblocks, const int blocksize,
- const int context_size)
-{
- cipher_bulk_ops_t bulk_ops = { 0, };
- int i, offs;
- unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem;
- unsigned int ctx_aligned_size, memsize;
-
- static const unsigned char key[16] ATTR_ALIGNED_16 = {
- 0x11,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
- 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x33
- };
-
- /* Allocate buffers, align first two elements to 16 bytes and latter to
- block size. */
- ctx_aligned_size = context_size + 15;
- ctx_aligned_size -= ctx_aligned_size & 0xf;
-
- memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 3) + 16;
-
- mem = xtrycalloc (1, memsize);
- if (!mem)
- return "failed to allocate memory";
-
- offs = (16 - ((uintptr_t)mem & 15)) & 15;
- ctx = (void*)(mem + offs);
- iv = ctx + ctx_aligned_size;
- iv2 = iv + blocksize;
- plaintext = iv2 + blocksize;
- plaintext2 = plaintext + nblocks * blocksize;
- ciphertext = plaintext2 + nblocks * blocksize;
-
- /* Initialize ctx */
- if (setkey_func (ctx, key, sizeof(key), &bulk_ops) != GPG_ERR_NO_ERROR)
- {
- xfree(mem);
- return "setkey failed";
- }
-
- /* Test single block code path */
- memset(iv, 0xd3, blocksize);
- memset(iv2, 0xd3, blocksize);
- for (i = 0; i < blocksize; i++)
- plaintext[i] = i;
-
- /* CFB manually. */
- encrypt_one (ctx, ciphertext, iv);
- buf_xor_2dst (iv, ciphertext, plaintext, blocksize);
-
- /* CFB decrypt. */
- bulk_ops.cfb_dec (ctx, iv2, plaintext2, ciphertext, 1);
- if (memcmp(plaintext2, plaintext, blocksize))
- {
- xfree(mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CFB-%d test failed (plaintext mismatch)", cipher,
- blocksize * 8);
-#else
- (void)cipher; /* Not used. */
-#endif
- return "selftest for CFB failed - see syslog for details";
- }
-
- if (memcmp(iv2, iv, blocksize))
- {
- xfree(mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CFB-%d test failed (IV mismatch)", cipher, blocksize * 8);
-#endif
- return "selftest for CFB failed - see syslog for details";
- }
-
- /* Test parallelized code paths */
- memset(iv, 0xe6, blocksize);
- memset(iv2, 0xe6, blocksize);
-
- for (i = 0; i < nblocks * blocksize; i++)
- plaintext[i] = i;
-
- /* Create CFB ciphertext manually. */
- for (i = 0; i < nblocks * blocksize; i+=blocksize)
- {
- encrypt_one (ctx, &ciphertext[i], iv);
- buf_xor_2dst (iv, &ciphertext[i], &plaintext[i], blocksize);
- }
-
- /* Decrypt using bulk CBC and compare result. */
- bulk_ops.cfb_dec (ctx, iv2, plaintext2, ciphertext, nblocks);
-
- if (memcmp(plaintext2, plaintext, nblocks * blocksize))
- {
- xfree(mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CFB-%d test failed (plaintext mismatch, parallel path)",
- cipher, blocksize * 8);
-#endif
- return "selftest for CFB failed - see syslog for details";
- }
- if (memcmp(iv2, iv, blocksize))
- {
- xfree(mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CFB-%d test failed (IV mismatch, parallel path)", cipher,
- blocksize * 8);
-#endif
- return "selftest for CFB failed - see syslog for details";
- }
-
- xfree(mem);
- return NULL;
-}
-
-/* Run the self-tests for <block cipher>-CTR-<block size>, tests IV increment
- of bulk CTR encryption. Returns NULL on success. */
-const char *
-_gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
- gcry_cipher_encrypt_t encrypt_one,
- const int nblocks, const int blocksize,
- const int context_size)
-{
- cipher_bulk_ops_t bulk_ops = { 0, };
- int i, j, offs, diff;
- unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *ciphertext2,
- *iv, *iv2, *mem;
- unsigned int ctx_aligned_size, memsize;
-
- static const unsigned char key[16] ATTR_ALIGNED_16 = {
- 0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
- 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21
- };
-
- /* Allocate buffers, align first two elements to 16 bytes and latter to
- block size. */
- ctx_aligned_size = context_size + 15;
- ctx_aligned_size -= ctx_aligned_size & 0xf;
-
- memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 4) + 16;
-
- mem = xtrycalloc (1, memsize);
- if (!mem)
- return "failed to allocate memory";
-
- offs = (16 - ((uintptr_t)mem & 15)) & 15;
- ctx = (void*)(mem + offs);
- iv = ctx + ctx_aligned_size;
- iv2 = iv + blocksize;
- plaintext = iv2 + blocksize;
- plaintext2 = plaintext + nblocks * blocksize;
- ciphertext = plaintext2 + nblocks * blocksize;
- ciphertext2 = ciphertext + nblocks * blocksize;
-
- /* Initialize ctx */
- if (setkey_func (ctx, key, sizeof(key), &bulk_ops) != GPG_ERR_NO_ERROR)
- {
- xfree(mem);
- return "setkey failed";
- }
-
- /* Test single block code path */
- memset (iv, 0xff, blocksize);
- for (i = 0; i < blocksize; i++)
- plaintext[i] = i;
-
- /* CTR manually. */
- encrypt_one (ctx, ciphertext, iv);
- for (i = 0; i < blocksize; i++)
- ciphertext[i] ^= plaintext[i];
- for (i = blocksize; i > 0; i--)
- {
- iv[i-1]++;
- if (iv[i-1])
- break;
- }
-
- memset (iv2, 0xff, blocksize);
- bulk_ops.ctr_enc (ctx, iv2, plaintext2, ciphertext, 1);
-
- if (memcmp (plaintext2, plaintext, blocksize))
- {
- xfree (mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CTR-%d test failed (plaintext mismatch)", cipher,
- blocksize * 8);
-#else
- (void)cipher; /* Not used. */
-#endif
- return "selftest for CTR failed - see syslog for details";
- }
-
- if (memcmp (iv2, iv, blocksize))
- {
- xfree (mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CTR-%d test failed (IV mismatch)", cipher,
- blocksize * 8);
-#endif
- return "selftest for CTR failed - see syslog for details";
- }
-
- /* Test bulk encryption with typical IV. */
- memset(iv, 0x57, blocksize-4);
- iv[blocksize-1] = 1;
- iv[blocksize-2] = 0;
- iv[blocksize-3] = 0;
- iv[blocksize-4] = 0;
- memset(iv2, 0x57, blocksize-4);
- iv2[blocksize-1] = 1;
- iv2[blocksize-2] = 0;
- iv2[blocksize-3] = 0;
- iv2[blocksize-4] = 0;
-
- for (i = 0; i < blocksize * nblocks; i++)
- plaintext2[i] = plaintext[i] = i;
-
- /* Create CTR ciphertext manually. */
- for (i = 0; i < blocksize * nblocks; i+=blocksize)
- {
- encrypt_one (ctx, &ciphertext[i], iv);
- for (j = 0; j < blocksize; j++)
- ciphertext[i+j] ^= plaintext[i+j];
- for (j = blocksize; j > 0; j--)
- {
- iv[j-1]++;
- if (iv[j-1])
- break;
- }
- }
-
- bulk_ops.ctr_enc (ctx, iv2, ciphertext2, plaintext2, nblocks);
-
- if (memcmp (ciphertext2, ciphertext, blocksize * nblocks))
- {
- xfree (mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CTR-%d test failed (ciphertext mismatch, bulk)", cipher,
- blocksize * 8);
-#endif
- return "selftest for CTR failed - see syslog for details";
- }
- if (memcmp(iv2, iv, blocksize))
- {
- xfree (mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CTR-%d test failed (IV mismatch, bulk)", cipher,
- blocksize * 8);
-#endif
- return "selftest for CTR failed - see syslog for details";
- }
-
- /* Test parallelized code paths (check counter overflow handling) */
- for (diff = 0; diff < nblocks; diff++) {
- memset(iv, 0xff, blocksize);
- iv[blocksize-1] -= diff;
- iv[0] = iv[1] = 0;
- iv[2] = 0x07;
-
- for (i = 0; i < blocksize * nblocks; i++)
- plaintext[i] = i;
-
- /* Create CTR ciphertext manually. */
- for (i = 0; i < blocksize * nblocks; i+=blocksize)
- {
- encrypt_one (ctx, &ciphertext[i], iv);
- for (j = 0; j < blocksize; j++)
- ciphertext[i+j] ^= plaintext[i+j];
- for (j = blocksize; j > 0; j--)
- {
- iv[j-1]++;
- if (iv[j-1])
- break;
- }
- }
-
- /* Decrypt using bulk CTR and compare result. */
- memset(iv2, 0xff, blocksize);
- iv2[blocksize-1] -= diff;
- iv2[0] = iv2[1] = 0;
- iv2[2] = 0x07;
-
- bulk_ops.ctr_enc (ctx, iv2, plaintext2, ciphertext, nblocks);
-
- if (memcmp (plaintext2, plaintext, blocksize * nblocks))
- {
- xfree (mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CTR-%d test failed (plaintext mismatch, diff: %d)", cipher,
- blocksize * 8, diff);
-#endif
- return "selftest for CTR failed - see syslog for details";
- }
- if (memcmp(iv2, iv, blocksize))
- {
- xfree (mem);
-#ifdef HAVE_SYSLOG
- syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
- "%s-CTR-%d test failed (IV mismatch, diff: %d)", cipher,
- blocksize * 8, diff);
-#endif
- return "selftest for CTR failed - see syslog for details";
- }
- }
-
- xfree (mem);
- return NULL;
-}
diff --git a/cipher/cipher-selftest.h b/cipher/cipher-selftest.h
deleted file mode 100644
index c3090ad1..00000000
--- a/cipher/cipher-selftest.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* cipher-selftest.h - Helper functions for bulk encryption selftests.
- * Copyright (C) 2013,2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef G10_SELFTEST_HELP_H
-#define G10_SELFTEST_HELP_H
-
-#include <config.h>
-#include "types.h"
-#include "g10lib.h"
-#include "cipher.h"
-
-typedef void (*gcry_cipher_bulk_cbc_dec_t)(void *context, unsigned char *iv,
- void *outbuf_arg,
- const void *inbuf_arg,
- size_t nblocks);
-
-typedef void (*gcry_cipher_bulk_cfb_dec_t)(void *context, unsigned char *iv,
- void *outbuf_arg,
- const void *inbuf_arg,
- size_t nblocks);
-
-typedef void (*gcry_cipher_bulk_ctr_enc_t)(void *context, unsigned char *iv,
- void *outbuf_arg,
- const void *inbuf_arg,
- size_t nblocks);
-
-/* Helper function to allocate an aligned context for selftests. */
-void *_gcry_cipher_selftest_alloc_ctx (const int context_size,
- unsigned char **r_mem);
-
-
-/* Helper function for bulk CBC decryption selftest */
-const char *
-_gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey,
- gcry_cipher_encrypt_t encrypt_one,
- const int nblocks, const int blocksize,
- const int context_size);
-
-/* Helper function for bulk CFB decryption selftest */
-const char *
-_gcry_selftest_helper_cfb (const char *cipher, gcry_cipher_setkey_t setkey,
- gcry_cipher_encrypt_t encrypt_one,
- const int nblocks, const int blocksize,
- const int context_size);
-
-/* Helper function for bulk CTR encryption selftest */
-const char *
-_gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey,
- gcry_cipher_encrypt_t encrypt_one,
- const int nblocks, const int blocksize,
- const int context_size);
-
-#endif /*G10_SELFTEST_HELP_H*/
diff --git a/cipher/des.c b/cipher/des.c
index 51116fcf..7a81697a 100644
--- a/cipher/des.c
+++ b/cipher/des.c
@@ -120,7 +120,6 @@
#include "cipher.h"
#include "bufhelp.h"
#include "cipher-internal.h"
-#include "cipher-selftest.h"


#define DES_BLOCKSIZE 8
@@ -1047,66 +1046,6 @@ is_weak_key ( const byte *key )
}


-/* Alternative setkey for selftests; need larger key than default. */
-static gcry_err_code_t
-bulk_selftest_setkey (void *context, const byte *__key, unsigned __keylen,
- cipher_bulk_ops_t *bulk_ops)
-{
- static const unsigned char key[24] ATTR_ALIGNED_16 = {
- 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
- 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22,
- 0x18,0x2A,0x39,0x47,0x5E,0x6F,0x75,0x82
- };
-
- (void)__key;
- (void)__keylen;
-
- return do_tripledes_setkey(context, key, sizeof(key), bulk_ops);
-}
-
-
-/* Run the self-tests for DES-CTR, tests IV increment of bulk CTR
- encryption. Returns NULL on success. */
-static const char *
-selftest_ctr (void)
-{
- const int nblocks = 3+1;
- const int blocksize = DES_BLOCKSIZE;
- const int context_size = sizeof(struct _tripledes_ctx);
-
- return _gcry_selftest_helper_ctr("3DES", &bulk_selftest_setkey,
- &do_tripledes_encrypt, nblocks, blocksize, context_size);
-}
-
-
-/* Run the self-tests for DES-CBC, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char *
-selftest_cbc (void)
-{
- const int nblocks = 3+2;
- const int blocksize = DES_BLOCKSIZE;
- const int context_size = sizeof(struct _tripledes_ctx);
-
- return _gcry_selftest_helper_cbc("3DES", &bulk_selftest_setkey,
- &do_tripledes_encrypt, nblocks, blocksize, context_size);
-}
-
-
-/* Run the self-tests for DES-CFB, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char *
-selftest_cfb (void)
-{
- const int nblocks = 3+2;
- const int blocksize = DES_BLOCKSIZE;
- const int context_size = sizeof(struct _tripledes_ctx);
-
- return _gcry_selftest_helper_cfb("3DES", &bulk_selftest_setkey,
- &do_tripledes_encrypt, nblocks, blocksize, context_size);
-}
-
-
/*
* Performs a selftest of this DES/Triple-DES implementation.
* Returns an string with the error text on failure.
@@ -1115,8 +1054,6 @@ selftest_cfb (void)
static const char *
selftest (void)
{
- const char *r;
-
/*
* Check if 'u32' is really 32 bits wide. This DES / 3DES implementation
* need this.
@@ -1296,15 +1233,6 @@ selftest (void)
return "DES weak key detection failed";
}

- if ( (r = selftest_cbc ()) )
- return r;
-
- if ( (r = selftest_cfb ()) )
- return r;
-
- if ( (r = selftest_ctr ()) )
- return r;
-
return 0;
}

diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c
index ff6b0b26..156af015 100644
--- a/cipher/rijndael-aesni.c
+++ b/cipher/rijndael-aesni.c
@@ -27,7 +27,6 @@
#include "g10lib.h"
#include "cipher.h"
#include "bufhelp.h"
-#include "cipher-selftest.h"
#include "rijndael-internal.h"
#include "./cipher-internal.h"

diff --git a/cipher/rijndael-armv8-ce.c b/cipher/rijndael-armv8-ce.c
index b24ae3e9..e53c940e 100644
--- a/cipher/rijndael-armv8-ce.c
+++ b/cipher/rijndael-armv8-ce.c
@@ -27,7 +27,6 @@
#include "g10lib.h"
#include "cipher.h"
#include "bufhelp.h"
-#include "cipher-selftest.h"
#include "rijndael-internal.h"
#include "./cipher-internal.h"

diff --git a/cipher/rijndael-padlock.c b/cipher/rijndael-padlock.c
index 3af214d7..2583b834 100644
--- a/cipher/rijndael-padlock.c
+++ b/cipher/rijndael-padlock.c
@@ -27,7 +27,6 @@
#include "g10lib.h"
#include "cipher.h"
#include "bufhelp.h"
-#include "cipher-selftest.h"
#include "rijndael-internal.h"

#ifdef USE_PADLOCK
diff --git a/cipher/rijndael-ssse3-amd64.c b/cipher/rijndael-ssse3-amd64.c
index b0723853..0f0abf62 100644
--- a/cipher/rijndael-ssse3-amd64.c
+++ b/cipher/rijndael-ssse3-amd64.c
@@ -43,7 +43,6 @@
#include "g10lib.h"
#include "cipher.h"
#include "bufhelp.h"
-#include "cipher-selftest.h"
#include "rijndael-internal.h"
#include "./cipher-internal.h"

diff --git a/cipher/rijndael-vaes.c b/cipher/rijndael-vaes.c
index 0d7d1367..dbcf9afa 100644
--- a/cipher/rijndael-vaes.c
+++ b/cipher/rijndael-vaes.c
@@ -26,7 +26,6 @@
#include "g10lib.h"
#include "cipher.h"
#include "bufhelp.h"
-#include "cipher-selftest.h"
#include "rijndael-internal.h"
#include "./cipher-internal.h"

diff --git a/cipher/rijndael.c b/cipher/rijndael.c
index 9b96b616..dddcbc54 100644
--- a/cipher/rijndael.c
+++ b/cipher/rijndael.c
@@ -46,7 +46,6 @@
#include "g10lib.h"
#include "cipher.h"
#include "bufhelp.h"
-#include "cipher-selftest.h"
#include "rijndael-internal.h"
#include "./cipher-internal.h"

@@ -1535,7 +1534,7 @@ static const char*
selftest_basic_128 (void)
{
RIJNDAEL_context *ctx;
- unsigned char *ctxmem;
+ unsigned char ctxmem[sizeof(*ctx) + 16];
unsigned char scratch[16];
cipher_bulk_ops_t bulk_ops;

@@ -1579,21 +1578,15 @@ selftest_basic_128 (void)
};
#endif

- /* Because gcc/ld can only align the CTX struct on 8 bytes on the
- stack, we need to allocate that context on the heap. */
- ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem);
- if (!ctx)
- return "failed to allocate memory";
+ ctx = (void *)(ctxmem + ((16 - ((uintptr_t)ctxmem & 15)) & 15));

rijndael_setkey (ctx, key_128, sizeof (key_128), &bulk_ops);
rijndael_encrypt (ctx, scratch, plaintext_128);
if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128)))
{
- xfree (ctxmem);
return "AES-128 test encryption failed.";
}
rijndael_decrypt (ctx, scratch, scratch);
- xfree (ctxmem);
if (memcmp (scratch, plaintext_128, sizeof (plaintext_128)))
return "AES-128 test decryption failed.";

@@ -1605,7 +1598,7 @@ static const char*
selftest_basic_192 (void)
{
RIJNDAEL_context *ctx;
- unsigned char *ctxmem;
+ unsigned char ctxmem[sizeof(*ctx) + 16];
unsigned char scratch[16];
cipher_bulk_ops_t bulk_ops;

@@ -1626,18 +1619,15 @@ selftest_basic_192 (void)
0x12,0x13,0x1A,0xC7,0xC5,0x47,0x88,0xAA
};

- ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem);
- if (!ctx)
- return "failed to allocate memory";
+ ctx = (void *)(ctxmem + ((16 - ((uintptr_t)ctxmem & 15)) & 15));
+
rijndael_setkey (ctx, key_192, sizeof(key_192), &bulk_ops);
rijndael_encrypt (ctx, scratch, plaintext_192);
if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192)))
{
- xfree (ctxmem);
return "AES-192 test encryption failed.";
}
rijndael_decrypt (ctx, scratch, scratch);
- xfree (ctxmem);
if (memcmp (scratch, plaintext_192, sizeof (plaintext_192)))
return "AES-192 test decryption failed.";

@@ -1650,7 +1640,7 @@ static const char*
selftest_basic_256 (void)
{
RIJNDAEL_context *ctx;
- unsigned char *ctxmem;
+ unsigned char ctxmem[sizeof(*ctx) + 16];
unsigned char scratch[16];
cipher_bulk_ops_t bulk_ops;

@@ -1672,18 +1662,15 @@ selftest_basic_256 (void)
0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3
};

- ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem);
- if (!ctx)
- return "failed to allocate memory";
+ ctx = (void *)(ctxmem + ((16 - ((uintptr_t)ctxmem & 15)) & 15));
+
rijndael_setkey (ctx, key_256, sizeof(key_256), &bulk_ops);
rijndael_encrypt (ctx, scratch, plaintext_256);
if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
{
- xfree (ctxmem);
return "AES-256 test encryption failed.";
}
rijndael_decrypt (ctx, scratch, scratch);
- xfree (ctxmem);
if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
return "AES-256 test decryption failed.";

@@ -1691,60 +1678,6 @@ selftest_basic_256 (void)
}


-/* Run the self-tests for AES-CTR-128, tests IV increment of bulk CTR
- encryption. Returns NULL on success. */
-static const char*
-selftest_ctr_128 (void)
-{
-#ifdef USE_VAES
- const int nblocks = 16+1;
-#else
- const int nblocks = 8+1;
-#endif
- const int blocksize = BLOCKSIZE;
- const int context_size = sizeof(RIJNDAEL_context);
-
- return _gcry_selftest_helper_ctr("AES", &rijndael_setkey,
- &rijndael_encrypt, nblocks, blocksize, context_size);
-}
-
-
-/* Run the self-tests for AES-CBC-128, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char*
-selftest_cbc_128 (void)
-{
-#ifdef USE_VAES
- const int nblocks = 16+2;
-#else
- const int nblocks = 8+2;
-#endif
- const int blocksize = BLOCKSIZE;
- const int context_size = sizeof(RIJNDAEL_context);
-
- return _gcry_selftest_helper_cbc("AES", &rijndael_setkey,
- &rijndael_encrypt, nblocks, blocksize, context_size);
-}
-
-
-/* Run the self-tests for AES-CFB-128, tests bulk CFB decryption.
- Returns NULL on success. */
-static const char*
-selftest_cfb_128 (void)
-{
-#ifdef USE_VAES
- const int nblocks = 16+2;
-#else
- const int nblocks = 8+2;
-#endif
- const int blocksize = BLOCKSIZE;
- const int context_size = sizeof(RIJNDAEL_context);
-
- return _gcry_selftest_helper_cfb("AES", &rijndael_setkey,
- &rijndael_encrypt, nblocks, blocksize, context_size);
-}
-
-
/* Run all the self-tests and return NULL on success. This function
is used for the on-the-fly self-tests. */
static const char *
@@ -1757,15 +1690,6 @@ selftest (void)
|| (r = selftest_basic_256 ()) )
return r;

- if ( (r = selftest_ctr_128 ()) )
- return r;
-
- if ( (r = selftest_cbc_128 ()) )
- return r;
-
- if ( (r = selftest_cfb_128 ()) )
- return r;
-
return r;
}

diff --git a/cipher/serpent.c b/cipher/serpent.c
index dfe5cc28..11eeb079 100644
--- a/cipher/serpent.c
+++ b/cipher/serpent.c
@@ -30,7 +30,6 @@
#include "bithelp.h"
#include "bufhelp.h"
#include "cipher-internal.h"
-#include "cipher-selftest.h"
#include "bulkhelp.h"


@@ -1540,48 +1539,6 @@ _gcry_serpent_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,



-/* Run the self-tests for SERPENT-CTR-128, tests IV increment of bulk CTR
- encryption. Returns NULL on success. */
-static const char*
-selftest_ctr_128 (void)
-{
- const int nblocks = 16+8+1;
- const int blocksize = sizeof(serpent_block_t);
- const int context_size = sizeof(serpent_context_t);
-
- return _gcry_selftest_helper_ctr("SERPENT", &serpent_setkey,
- &serpent_encrypt, nblocks, blocksize, context_size);
-}
-
-
-/* Run the self-tests for SERPENT-CBC-128, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char*
-selftest_cbc_128 (void)
-{
- const int nblocks = 16+8+2;
- const int blocksize = sizeof(serpent_block_t);
- const int context_size = sizeof(serpent_context_t);
-
- return _gcry_selftest_helper_cbc("SERPENT", &serpent_setkey,
- &serpent_encrypt, nblocks, blocksize, context_size);
-}
-
-
-/* Run the self-tests for SERPENT-CBC-128, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char*
-selftest_cfb_128 (void)
-{
- const int nblocks = 16+8+2;
- const int blocksize = sizeof(serpent_block_t);
- const int context_size = sizeof(serpent_context_t);
-
- return _gcry_selftest_helper_cfb("SERPENT", &serpent_setkey,
- &serpent_encrypt, nblocks, blocksize, context_size);
-}
-
-
/* Serpent test. */

static const char *
@@ -1590,7 +1547,6 @@ serpent_test (void)
serpent_context_t context;
unsigned char scratch[16];
unsigned int i;
- const char *r;

static struct test
{
@@ -1662,15 +1618,6 @@ serpent_test (void)
}
}

- if ( (r = selftest_ctr_128 ()) )
- return r;
-
- if ( (r = selftest_cbc_128 ()) )
- return r;
-
- if ( (r = selftest_cfb_128 ()) )
- return r;
-
return NULL;
}

diff --git a/cipher/sm4.c b/cipher/sm4.c
index 7c7bc1ff..5f8bf224 100644
--- a/cipher/sm4.c
+++ b/cipher/sm4.c
@@ -29,7 +29,6 @@
#include "cipher.h"
#include "bufhelp.h"
#include "cipher-internal.h"
-#include "cipher-selftest.h"
#include "bulkhelp.h"

/* Helper macro to force alignment to 64 bytes. */
@@ -1429,51 +1428,11 @@ _gcry_sm4_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks)
return 0;
}

-/* Run the self-tests for SM4-CTR, tests IV increment of bulk CTR
- encryption. Returns NULL on success. */
-static const char*
-selftest_ctr_128 (void)
-{
- const int nblocks = 16 - 1;
- const int blocksize = 16;
- const int context_size = sizeof(SM4_context);
-
- return _gcry_selftest_helper_ctr("SM4", &sm4_setkey,
- &sm4_encrypt, nblocks, blocksize, context_size);
-}
-
-/* Run the self-tests for SM4-CBC, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char*
-selftest_cbc_128 (void)
-{
- const int nblocks = 16 - 1;
- const int blocksize = 16;
- const int context_size = sizeof(SM4_context);
-
- return _gcry_selftest_helper_cbc("SM4", &sm4_setkey,
- &sm4_encrypt, nblocks, blocksize, context_size);
-}
-
-/* Run the self-tests for SM4-CFB, tests bulk CFB decryption.
- Returns NULL on success. */
-static const char*
-selftest_cfb_128 (void)
-{
- const int nblocks = 16 - 1;
- const int blocksize = 16;
- const int context_size = sizeof(SM4_context);
-
- return _gcry_selftest_helper_cfb("SM4", &sm4_setkey,
- &sm4_encrypt, nblocks, blocksize, context_size);
-}
-
static const char *
sm4_selftest (void)
{
SM4_context ctx;
byte scratch[16];
- const char *r;

static const byte plaintext[16] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
@@ -1498,15 +1457,6 @@ sm4_selftest (void)
if (memcmp (scratch, plaintext, sizeof (plaintext)))
return "SM4 test decryption failed.";

- if ( (r = selftest_ctr_128 ()) )
- return r;
-
- if ( (r = selftest_cbc_128 ()) )
- return r;
-
- if ( (r = selftest_cfb_128 ()) )
- return r;
-
return NULL;
}

diff --git a/cipher/twofish.c b/cipher/twofish.c
index 4ae5d5a6..b300715b 100644
--- a/cipher/twofish.c
+++ b/cipher/twofish.c
@@ -46,7 +46,6 @@
#include "cipher.h"
#include "bufhelp.h"
#include "cipher-internal.h"
-#include "cipher-selftest.h"
#include "bulkhelp.h"


@@ -1527,46 +1526,6 @@ _gcry_twofish_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
return nblocks;
}

-
-
-/* Run the self-tests for TWOFISH-CTR, tests IV increment of bulk CTR
- encryption. Returns NULL on success. */
-static const char *
-selftest_ctr (void)
-{
- const int nblocks = 16+1;
- const int blocksize = TWOFISH_BLOCKSIZE;
- const int context_size = sizeof(TWOFISH_context);
-
- return _gcry_selftest_helper_ctr("TWOFISH", &twofish_setkey,
- &twofish_encrypt, nblocks, blocksize, context_size);
-}
-
-/* Run the self-tests for TWOFISH-CBC, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char *
-selftest_cbc (void)
-{
- const int nblocks = 16+2;
- const int blocksize = TWOFISH_BLOCKSIZE;
- const int context_size = sizeof(TWOFISH_context);
-
- return _gcry_selftest_helper_cbc("TWOFISH", &twofish_setkey,
- &twofish_encrypt, nblocks, blocksize, context_size);
-}
-
-/* Run the self-tests for TWOFISH-CFB, tests bulk CBC decryption.
- Returns NULL on success. */
-static const char *
-selftest_cfb (void)
-{
- const int nblocks = 16+2;
- const int blocksize = TWOFISH_BLOCKSIZE;
- const int context_size = sizeof(TWOFISH_context);
-
- return _gcry_selftest_helper_cfb("TWOFISH", &twofish_setkey,
- &twofish_encrypt, nblocks, blocksize, context_size);
-}


/* Test a single encryption and decryption with each key size. */
@@ -1577,7 +1536,6 @@ selftest (void)
TWOFISH_context ctx; /* Expanded key. */
byte scratch[16]; /* Encryption/decryption result buffer. */
cipher_bulk_ops_t bulk_ops;
- const char *r;

/* Test vectors for single encryption/decryption. Note that I am using
* the vectors from the Twofish paper's "known answer test", I=3 for
@@ -1627,13 +1585,6 @@ selftest (void)
if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
return "Twofish-256 test decryption failed.";

- if ((r = selftest_ctr()) != NULL)
- return r;
- if ((r = selftest_cbc()) != NULL)
- return r;
- if ((r = selftest_cfb()) != NULL)
- return r;
-
return NULL;
}

diff --git a/tests/basic.c b/tests/basic.c
index 40a0a474..f5513740 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -27,6 +27,13 @@
#include <string.h>
#include <stdarg.h>
#include <assert.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h> /* uintptr_t */
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#else
+/* In this case, uintptr_t is provided by config.h. */
+#endif

#include "../src/gcrypt-int.h"

@@ -11672,6 +11679,764 @@ out:



+static void buf_xor(void *vdst, const void *vsrc1, const void *vsrc2, size_t len)
+{
+ char *dst = vdst;
+ const char *src1 = vsrc1;
+ const char *src2 = vsrc2;
+
+ while (len)
+ {
+ *(char *)dst = *(char *)src1 ^ *(char *)src2;
+ dst++;
+ src1++;
+ src2++;
+ len--;
+ }
+}
+
+/* Run the tests for <block cipher>-CBC-<block size>, tests bulk CBC
+ decryption. Returns NULL on success. */
+static int
+cipher_cbc_bulk_test (int cipher_algo)
+{
+ const int nblocks = 128 - 1;
+ int i, offs;
+ int blocksize;
+ const char *cipher;
+ gcry_cipher_hd_t hd_one;
+ gcry_cipher_hd_t hd_cbc;
+ gcry_error_t err = 0;
+ unsigned char *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem;
+ unsigned int memsize;
+ unsigned int keylen;
+
+ static const unsigned char key[32] = {
+ 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+ 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22,
+ 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+ 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22
+ };
+
+ if (gcry_cipher_test_algo (cipher_algo))
+ return -1;
+ blocksize = gcry_cipher_get_algo_blklen(cipher_algo);
+ if (blocksize < 8)
+ return -1;
+ cipher = gcry_cipher_algo_name (cipher_algo);
+ keylen = gcry_cipher_get_algo_keylen (cipher_algo);
+ if (keylen > sizeof(key))
+ {
+ fail ("%s-CBC-%d test failed (key too short)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ memsize = (blocksize * 2) + (blocksize * nblocks * 3) + 16;
+
+ mem = xcalloc (1, memsize);
+ if (!mem)
+ return -1;
+
+ offs = (16 - ((uintptr_t)mem & 15)) & 15;
+ iv = (void*)(mem + offs);
+ iv2 = iv + blocksize;
+ plaintext = iv2 + blocksize;
+ plaintext2 = plaintext + nblocks * blocksize;
+ ciphertext = plaintext2 + nblocks * blocksize;
+
+ err = gcry_cipher_open (&hd_one, cipher_algo, GCRY_CIPHER_MODE_ECB, 0);
+ if (err)
+ {
+ xfree(mem);
+ fail ("%s-CBC-%d test failed (cipher open fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ err = gcry_cipher_open (&hd_cbc, cipher_algo, GCRY_CIPHER_MODE_CBC, 0);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ xfree(mem);
+ fail ("%s-CBC-%d test failed (cipher open fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ /* Initialize ctx */
+ if (gcry_cipher_setkey (hd_one, key, keylen) ||
+ gcry_cipher_setkey (hd_cbc, key, keylen))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree(mem);
+ fail ("%s-CBC-%d test failed (setkey fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ /* Test single block code path */
+ memset (iv, 0x4e, blocksize);
+ memset (iv2, 0x4e, blocksize);
+ for (i = 0; i < blocksize; i++)
+ plaintext[i] = i;
+
+ /* CBC manually. */
+ buf_xor (ciphertext, iv, plaintext, blocksize);
+ err = gcry_cipher_encrypt (hd_one, ciphertext, blocksize,
+ ciphertext, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree(mem);
+ fail ("%s-CBC-%d test failed (ECB encrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ memcpy (iv, ciphertext, blocksize);
+
+ /* CBC decrypt. */
+ err = gcry_cipher_setiv (hd_cbc, iv2, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree(mem);
+ fail ("%s-CBC-%d test failed (setiv fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ err = gcry_cipher_decrypt (hd_cbc, plaintext2, blocksize * 1,
+ ciphertext, blocksize * 1);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree(mem);
+ fail ("%s-CBC-%d test failed (CBC decrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ if (memcmp (plaintext2, plaintext, blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree (mem);
+ fail ("%s-CBC-%d test failed (plaintext mismatch)", cipher, blocksize * 8);
+ return -1;
+ }
+
+#if 0 /* missing interface for reading IV */
+ if (memcmp (iv2, iv, blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree (mem);
+ fail ("%s-CBC-%d test failed (IV mismatch)", cipher, blocksize * 8);
+ return -1;
+ }
+#endif
+
+ /* Test parallelized code paths */
+ memset (iv, 0x5f, blocksize);
+ memset (iv2, 0x5f, blocksize);
+
+ for (i = 0; i < nblocks * blocksize; i++)
+ plaintext[i] = i;
+
+ /* Create CBC ciphertext manually. */
+ for (i = 0; i < nblocks * blocksize; i+=blocksize)
+ {
+ buf_xor (&ciphertext[i], iv, &plaintext[i], blocksize);
+ err = gcry_cipher_encrypt (hd_one, &ciphertext[i], blocksize,
+ &ciphertext[i], blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree(mem);
+ fail ("%s-CBC-%d test failed (ECB encrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ memcpy (iv, &ciphertext[i], blocksize);
+ }
+
+ /* Decrypt using bulk CBC and compare result. */
+ err = gcry_cipher_setiv (hd_cbc, iv2, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree(mem);
+ fail ("%s-CBC-%d test failed (setiv fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ err = gcry_cipher_decrypt (hd_cbc, plaintext2, blocksize * nblocks,
+ ciphertext, blocksize * nblocks);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree(mem);
+ fail ("%s-CBC-%d test failed (CBC decrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ if (memcmp (plaintext2, plaintext, nblocks * blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree (mem);
+ fail ("%s-CBC-%d test failed (plaintext mismatch, parallel path)",
+ cipher, blocksize * 8);
+ return -1;
+ }
+#if 0 /* missing interface for reading IV */
+ if (memcmp (iv2, iv, blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree (mem);
+ fail ("%s-CBC-%d test failed (IV mismatch, parallel path)",
+ cipher, blocksize * 8);
+ return -1;
+ }
+#endif
+
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cbc);
+ xfree (mem);
+ return -1;
+}
+
+
+static void
+buf_xor_2dst(void *vdst1, void *vdst2, const void *vsrc, size_t len)
+{
+ byte *dst1 = vdst1;
+ byte *dst2 = vdst2;
+ const byte *src = vsrc;
+
+ for (; len; len--)
+ *dst1++ = (*dst2++ ^= *src++);
+}
+
+/* Run the tests for <block cipher>-CFB-<block size>, tests bulk CFB
+ decryption. Returns NULL on success. */
+static int
+cipher_cfb_bulk_test (int cipher_algo)
+{
+ const int nblocks = 128 - 1;
+ int blocksize;
+ const char *cipher;
+ gcry_cipher_hd_t hd_one;
+ gcry_cipher_hd_t hd_cfb;
+ gcry_error_t err = 0;
+ int i, offs;
+ unsigned char *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem;
+ unsigned int memsize;
+ unsigned int keylen;
+
+ static const unsigned char key[32] = {
+ 0x11,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+ 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x33,
+ 0x11,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+ 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x33
+ };
+
+ if (gcry_cipher_test_algo (cipher_algo))
+ return -1;
+ blocksize = gcry_cipher_get_algo_blklen(cipher_algo);
+ if (blocksize < 8)
+ return -1;
+ cipher = gcry_cipher_algo_name (cipher_algo);
+ keylen = gcry_cipher_get_algo_keylen (cipher_algo);
+ if (keylen > sizeof(key))
+ {
+ fail ("%s-CFB-%d test failed (key too short)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ memsize = (blocksize * 2) + (blocksize * nblocks * 3) + 16;
+
+ mem = xcalloc (1, memsize);
+ if (!mem)
+ return -1;
+
+ offs = (16 - ((uintptr_t)mem & 15)) & 15;
+ iv = (void*)(mem + offs);
+ iv2 = iv + blocksize;
+ plaintext = iv2 + blocksize;
+ plaintext2 = plaintext + nblocks * blocksize;
+ ciphertext = plaintext2 + nblocks * blocksize;
+
+ err = gcry_cipher_open (&hd_one, cipher_algo, GCRY_CIPHER_MODE_ECB, 0);
+ if (err)
+ {
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (cipher open fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ err = gcry_cipher_open (&hd_cfb, cipher_algo, GCRY_CIPHER_MODE_CFB, 0);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (cipher open fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ /* Initialize ctx */
+ if (gcry_cipher_setkey (hd_one, key, keylen) ||
+ gcry_cipher_setkey (hd_cfb, key, keylen))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (setkey fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ /* Test single block code path */
+ memset(iv, 0xd3, blocksize);
+ memset(iv2, 0xd3, blocksize);
+ for (i = 0; i < blocksize; i++)
+ plaintext[i] = i;
+
+ /* CFB manually. */
+ err = gcry_cipher_encrypt (hd_one, ciphertext, blocksize, iv, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (ECB encrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ buf_xor_2dst (iv, ciphertext, plaintext, blocksize);
+
+ /* CFB decrypt. */
+ err = gcry_cipher_setiv (hd_cfb, iv2, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (setiv fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ err = gcry_cipher_decrypt (hd_cfb, plaintext2, blocksize * 1,
+ ciphertext, blocksize * 1);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (CFB decrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ if (memcmp(plaintext2, plaintext, blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (plaintext mismatch)",
+ cipher, blocksize * 8);
+ return -1;
+ }
+
+#if 0
+ if (memcmp(iv2, iv, blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (IV mismatch)",
+ cipher, blocksize * 8);
+ return -1;
+ }
+#endif
+
+ /* Test parallelized code paths */
+ memset(iv, 0xe6, blocksize);
+ memset(iv2, 0xe6, blocksize);
+
+ for (i = 0; i < nblocks * blocksize; i++)
+ plaintext[i] = i;
+
+ /* Create CFB ciphertext manually. */
+ for (i = 0; i < nblocks * blocksize; i+=blocksize)
+ {
+ err = gcry_cipher_encrypt (hd_one, &ciphertext[i], blocksize,
+ iv, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (ECB encrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ buf_xor_2dst (iv, &ciphertext[i], &plaintext[i], blocksize);
+ }
+
+ /* Decrypt using bulk CBC and compare result. */
+ err = gcry_cipher_setiv (hd_cfb, iv2, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (setiv fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ err = gcry_cipher_decrypt (hd_cfb, plaintext2, blocksize * nblocks,
+ ciphertext, blocksize * nblocks);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (CFB decrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ if (memcmp(plaintext2, plaintext, nblocks * blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (plaintext mismatch, parallel path)",
+ cipher, blocksize * 8);
+ return -1;
+ }
+#if 0
+ if (memcmp(iv2, iv, blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ fail ("%s-CFB-%d test failed (IV mismatch, parallel path)",
+ cipher, blocksize * 8);
+ return -1;
+ }
+#endif
+
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_cfb);
+ xfree(mem);
+ return -1;
+}
+
+
+/* Run the tests for <block cipher>-CTR-<block size>, tests IV increment
+ of bulk CTR encryption. Returns NULL on success. */
+static int
+cipher_ctr_bulk_test (int cipher_algo)
+{
+ const int nblocks = 128 - 1;
+ int blocksize;
+ const char *cipher;
+ gcry_cipher_hd_t hd_one;
+ gcry_cipher_hd_t hd_ctr;
+ gcry_error_t err = 0;
+ int i, j, offs, diff;
+ unsigned char *plaintext, *plaintext2, *ciphertext, *ciphertext2,
+ *iv, *iv2, *mem;
+ unsigned int memsize;
+ unsigned int keylen;
+
+ static const unsigned char key[32] = {
+ 0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+ 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21,
+ 0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+ 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21
+ };
+
+ if (gcry_cipher_test_algo (cipher_algo))
+ return -1;
+ blocksize = gcry_cipher_get_algo_blklen(cipher_algo);
+ if (blocksize < 8)
+ return -1;
+ cipher = gcry_cipher_algo_name (cipher_algo);
+ keylen = gcry_cipher_get_algo_keylen (cipher_algo);
+ if (keylen > sizeof(key))
+ {
+ fail ("%s-CTR-%d test failed (key too short)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ memsize = (blocksize * 2) + (blocksize * nblocks * 4) + 16;
+
+ mem = xcalloc (1, memsize);
+ if (!mem)
+ return -1;
+
+ offs = (16 - ((uintptr_t)mem & 15)) & 15;
+ iv = (void*)(mem + offs);
+ iv2 = iv + blocksize;
+ plaintext = iv2 + blocksize;
+ plaintext2 = plaintext + nblocks * blocksize;
+ ciphertext = plaintext2 + nblocks * blocksize;
+ ciphertext2 = ciphertext + nblocks * blocksize;
+
+ err = gcry_cipher_open (&hd_one, cipher_algo, GCRY_CIPHER_MODE_ECB, 0);
+ if (err)
+ {
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (cipher open fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ err = gcry_cipher_open (&hd_ctr, cipher_algo, GCRY_CIPHER_MODE_CTR, 0);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (cipher open fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ /* Initialize ctx */
+ if (gcry_cipher_setkey (hd_one, key, keylen) ||
+ gcry_cipher_setkey (hd_ctr, key, keylen))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (setkey fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ /* Test single block code path */
+ memset (iv, 0xff, blocksize);
+ for (i = 0; i < blocksize; i++)
+ plaintext[i] = i;
+
+ /* CTR manually. */
+ err = gcry_cipher_encrypt (hd_one, ciphertext, blocksize, iv, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (ECB encrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ for (i = 0; i < blocksize; i++)
+ ciphertext[i] ^= plaintext[i];
+ for (i = blocksize; i > 0; i--)
+ {
+ iv[i-1]++;
+ if (iv[i-1])
+ break;
+ }
+
+ memset (iv2, 0xff, blocksize);
+ err = gcry_cipher_setctr (hd_ctr, iv2, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (setiv fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ err = gcry_cipher_encrypt (hd_ctr, plaintext2, blocksize * 1,
+ ciphertext, blocksize * 1);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (CTR encrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ if (memcmp (plaintext2, plaintext, blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (plaintext mismatch)",
+ cipher, blocksize * 8);
+ return -1;
+ }
+
+#if 0
+ if (memcmp (iv2, iv, blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (IV mismatch)", cipher, blocksize * 8);
+ return -1;
+ }
+#endif
+
+ /* Test bulk encryption with typical IV. */
+ memset(iv, 0x57, blocksize-4);
+ iv[blocksize-1] = 1;
+ iv[blocksize-2] = 0;
+ iv[blocksize-3] = 0;
+ iv[blocksize-4] = 0;
+ memset(iv2, 0x57, blocksize-4);
+ iv2[blocksize-1] = 1;
+ iv2[blocksize-2] = 0;
+ iv2[blocksize-3] = 0;
+ iv2[blocksize-4] = 0;
+
+ for (i = 0; i < blocksize * nblocks; i++)
+ plaintext2[i] = plaintext[i] = i;
+
+ /* Create CTR ciphertext manually. */
+ for (i = 0; i < blocksize * nblocks; i+=blocksize)
+ {
+ err = gcry_cipher_encrypt (hd_one, &ciphertext[i], blocksize,
+ iv, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (ECB encrypt fail)",
+ cipher, blocksize * 8);
+ return -1;
+ }
+ for (j = 0; j < blocksize; j++)
+ ciphertext[i+j] ^= plaintext[i+j];
+ for (j = blocksize; j > 0; j--)
+ {
+ iv[j-1]++;
+ if (iv[j-1])
+ break;
+ }
+ }
+
+ err = gcry_cipher_setctr (hd_ctr, iv2, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (setiv fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ err = gcry_cipher_encrypt (hd_ctr, ciphertext2, blocksize * nblocks,
+ plaintext2, blocksize * nblocks);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (CTR encrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ if (memcmp (ciphertext2, ciphertext, blocksize * nblocks))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (ciphertext mismatch, bulk)",
+ cipher, blocksize * 8);
+ return -1;
+ }
+#if 0
+ if (memcmp (iv2, iv, blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (IV mismatch, bulk)", cipher, blocksize * 8);
+ return -1;
+ }
+#endif
+
+ /* Test parallelized code paths (check counter overflow handling) */
+ for (diff = 0; diff < nblocks; diff++) {
+ memset(iv, 0xff, blocksize);
+ iv[blocksize-1] -= diff;
+ iv[0] = iv[1] = 0;
+ iv[2] = 0x07;
+
+ for (i = 0; i < blocksize * nblocks; i++)
+ plaintext[i] = i;
+
+ /* Create CTR ciphertext manually. */
+ for (i = 0; i < blocksize * nblocks; i+=blocksize)
+ {
+ err = gcry_cipher_encrypt (hd_one, &ciphertext[i], blocksize,
+ iv, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (ECB encrypt fail)",
+ cipher, blocksize * 8);
+ return -1;
+ }
+ for (j = 0; j < blocksize; j++)
+ ciphertext[i+j] ^= plaintext[i+j];
+ for (j = blocksize; j > 0; j--)
+ {
+ iv[j-1]++;
+ if (iv[j-1])
+ break;
+ }
+ }
+
+ /* Decrypt using bulk CTR and compare result. */
+ memset(iv2, 0xff, blocksize);
+ iv2[blocksize-1] -= diff;
+ iv2[0] = iv2[1] = 0;
+ iv2[2] = 0x07;
+
+ err = gcry_cipher_setctr (hd_ctr, iv2, blocksize);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (setiv fail)", cipher, blocksize * 8);
+ return -1;
+ }
+ err = gcry_cipher_decrypt (hd_ctr, plaintext2, blocksize * nblocks,
+ ciphertext, blocksize * nblocks);
+ if (err)
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (CTR decrypt fail)", cipher, blocksize * 8);
+ return -1;
+ }
+
+ if (memcmp (plaintext2, plaintext, blocksize * nblocks))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (plaintext mismatch, diff: %d)",
+ cipher, blocksize * 8, diff);
+ return -1;
+ }
+#if 0
+ if (memcmp(iv2, iv, blocksize))
+ {
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ fail ("%s-CTR-%d test failed (IV mismatch, diff: %d)",
+ cipher, blocksize * 8, diff);
+ return -1;
+ }
+#endif
+ }
+
+ gcry_cipher_close (hd_one);
+ gcry_cipher_close (hd_ctr);
+ xfree(mem);
+ return -1;
+}
+
+
+
static void
check_ciphers (void)
{
@@ -11784,6 +12549,13 @@ check_ciphers (void)
check_one_cipher (algos[i], GCRY_CIPHER_MODE_OCB, 0);
if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_XTS_BLOCK_LEN)
check_one_cipher (algos[i], GCRY_CIPHER_MODE_XTS, 0);
+
+ if (gcry_cipher_get_algo_blklen (algos[i]) >= 8)
+ {
+ cipher_cbc_bulk_test (algos[i]);
+ cipher_cfb_bulk_test (algos[i]);
+ cipher_ctr_bulk_test (algos[i]);
+ }
}

for (i = 0; algos2[i]; i++)
--
2.34.1


_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@lists.gnupg.org
https://lists.gnupg.org/mailman/listinfo/gcrypt-devel