summaryrefslogtreecommitdiff
path: root/cipher/cipher.c
diff options
context:
space:
mode:
Diffstat (limited to 'cipher/cipher.c')
-rw-r--r--cipher/cipher.c15
1 files changed, 12 insertions, 3 deletions
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;
}