summaryrefslogtreecommitdiff
path: root/cipher
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2020-02-02 19:52:08 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2020-02-02 19:52:08 +0200
commit5beadf201312d0c649971b0c1d4c3827b434a0b5 (patch)
tree67d3b937afdc6d3e44e50daa5538d4380888a398 /cipher
parente0898d0628789414da23e0526c87df1885c8b3ae (diff)
downloadlibgcrypt-5beadf201312d0c649971b0c1d4c3827b434a0b5.tar.gz
Add gcry_cipher_ctl command to allow weak keys in testing use-cases
* cipher/cipher-internal.h (gcry_cipher_handle): Add 'marks.allow_weak_key' flag. * cipher/cipher.c (cipher_setkey): Do not handle weak key as error when weak keys are allowed. (cipher_reset): Preserve 'marks.allow_weak_key' flag on object reset. (_gcry_cipher_ctl): Add handling for GCRYCTL_SET_ALLOW_WEAK_KEY. * src/gcrypt.h.in (gcry_ctl_cmds): Add GCRYCTL_SET_ALLOW_WEAK_KEY. * tests/basic.c (check_ecb_cipher): Add tests for weak key errors and for GCRYCTL_SET_ALLOW_WEAK_KEY. -- Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher')
-rw-r--r--cipher/cipher-internal.h1
-rw-r--r--cipher/cipher.c15
2 files changed, 13 insertions, 3 deletions
diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h
index 47b7b6f9..262ca902 100644
--- a/cipher/cipher-internal.h
+++ b/cipher/cipher-internal.h
@@ -207,6 +207,7 @@ struct gcry_cipher_handle
unsigned int iv:1; /* Set to 1 if a IV has been set. */
unsigned int tag:1; /* Set to 1 if a tag is finalized. */
unsigned int finalize:1; /* Next encrypt/decrypt has the final data. */
+ unsigned int allow_weak_key:1; /* Set to 1 if weak keys are allowed. */
} marks;
/* The initialization vector. For best performance we make sure
diff --git a/cipher/cipher.c b/cipher/cipher.c
index bd571367..09b8d829 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -794,7 +794,7 @@ cipher_setkey (gcry_cipher_hd_t c, byte *key, size_t keylen)
}
rc = c->spec->setkey (&c->context.c, key, keylen, c);
- if (!rc)
+ if (!rc || (c->marks.allow_weak_key && rc == GPG_ERR_WEAK_KEY))
{
/* Duplicate initial context. */
memcpy ((void *) ((char *) &c->context.c + c->spec->contextsize),
@@ -828,7 +828,7 @@ cipher_setkey (gcry_cipher_hd_t c, byte *key, size_t keylen)
/* Setup tweak cipher with second part of XTS key. */
rc = c->spec->setkey (c->u_mode.xts.tweak_context, key + keylen,
keylen, c);
- if (!rc)
+ if (!rc || (c->marks.allow_weak_key && rc == GPG_ERR_WEAK_KEY))
{
/* Duplicate initial tweak context. */
memcpy (c->u_mode.xts.tweak_context + c->spec->contextsize,
@@ -889,9 +889,10 @@ cipher_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
static void
cipher_reset (gcry_cipher_hd_t c)
{
- unsigned int marks_key;
+ unsigned int marks_key, marks_allow_weak_key;
marks_key = c->marks.key;
+ marks_allow_weak_key = c->marks.allow_weak_key;
memcpy (&c->context.c,
(char *) &c->context.c + c->spec->contextsize,
@@ -903,6 +904,7 @@ cipher_reset (gcry_cipher_hd_t c)
c->unused = 0;
c->marks.key = marks_key;
+ c->marks.allow_weak_key = marks_allow_weak_key;
switch (c->mode)
{
@@ -1592,6 +1594,13 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
rc = GPG_ERR_NOT_SUPPORTED;
break;
+ case GCRYCTL_SET_ALLOW_WEAK_KEY:
+ /* Expecting BUFFER to be NULL and buflen to be on/off flag (0 or 1). */
+ if (!h || buffer || buflen > 1)
+ return GPG_ERR_CIPHER_ALGO;
+ h->marks.allow_weak_key = buflen ? 1 : 0;
+ break;
+
default:
rc = GPG_ERR_INV_OP;
}