diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2020-02-02 19:52:08 +0200 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2020-02-02 19:52:08 +0200 |
commit | 5beadf201312d0c649971b0c1d4c3827b434a0b5 (patch) | |
tree | 67d3b937afdc6d3e44e50daa5538d4380888a398 /cipher | |
parent | e0898d0628789414da23e0526c87df1885c8b3ae (diff) | |
download | libgcrypt-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.h | 1 | ||||
-rw-r--r-- | cipher/cipher.c | 15 |
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; } |