summaryrefslogtreecommitdiff
path: root/cipher
diff options
context:
space:
mode:
authorMathias L. Baumann <mathias.baumann_at_sociomantic.com>2017-02-04 13:30:41 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2017-02-04 13:31:02 +0200
commitd1ee9a660571ce4a998c9ab2299d4f2419f99127 (patch)
treeb327acebfeb639a838b0558088bccf7ae8f2ec80 /cipher
parent80bd6195c794a7900791a88b943f371dc480cf07 (diff)
downloadlibgcrypt-d1ee9a660571ce4a998c9ab2299d4f2419f99127.tar.gz
Implement CFB with 8-bit mode
* cipher/cipher-cfb.c (_gcry_cipher_cfb8_encrypt) (_gcry_cipher_cfg8_decrypt): Add 8-bit variants of decrypt/encrypt functions. * cipher/cipher-internal.h (_gcry_cipher_cfb8_encrypt) (_gcry_cipher_cfg8_decrypt): Ditto. * cipher/cipher.c: Adjust code flow to work with GCRY_CIPHER_MODE_CFB8. * tests/basic.c: Add tests for cfb8 with AES and 3DES. -- Signed-off-by: Mathias L. Baumann <mathias.baumann at sociomantic.com> [JK: edit changelog, fix email malformed patch] Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher')
-rw-r--r--cipher/cipher-cfb.c86
-rw-r--r--cipher/cipher-internal.h8
-rw-r--r--cipher/cipher.c9
3 files changed, 103 insertions, 0 deletions
diff --git a/cipher/cipher-cfb.c b/cipher/cipher-cfb.c
index 21c81ca2..cca5c1fb 100644
--- a/cipher/cipher-cfb.c
+++ b/cipher/cipher-cfb.c
@@ -233,3 +233,89 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c,
return 0;
}
+
+
+gcry_err_code_t
+_gcry_cipher_cfb8_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ size_t blocksize = c->spec->blocksize;
+ unsigned int burn, nburn;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ burn = 0;
+
+ while ( inbuflen > 0)
+ {
+ /* Encrypt the IV. */
+ nburn = enc_fn ( &c->context.c, c->lastiv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+
+ outbuf[0] = c->lastiv[0] ^ inbuf[0];
+
+ /* Bitshift iv by 8 bit to the left */
+ for (int i = 0; i < blocksize-1; i++)
+ c->u_iv.iv[i] = c->u_iv.iv[i+1];
+
+ /* append cipher text to iv */
+ c->u_iv.iv[blocksize-1] = outbuf[0];
+
+ outbuf += 1;
+ inbuf += 1;
+ inbuflen -= 1;
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cfb8_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ size_t blocksize = c->spec->blocksize;
+ unsigned int burn, nburn;
+ unsigned char appendee;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ burn = 0;
+
+ while (inbuflen > 0)
+ {
+ /* Encrypt the IV. */
+ nburn = enc_fn ( &c->context.c, c->lastiv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+
+ /* inbuf might == outbuf, make sure we keep the value
+ so we can append it later */
+ appendee = inbuf[0];
+
+ outbuf[0] = inbuf[0] ^ c->lastiv[0];
+
+ /* Bitshift iv by 8 bit to the left */
+ for (int i = 0; i < blocksize-1; i++)
+ c->u_iv.iv[i] = c->u_iv.iv[i+1];
+
+ c->u_iv.iv[blocksize-1] = appendee;
+
+ outbuf += 1;
+ inbuf += 1;
+ inbuflen -= 1;
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h
index 33d0629c..ea9c33d3 100644
--- a/cipher/cipher-internal.h
+++ b/cipher/cipher-internal.h
@@ -348,6 +348,14 @@ gcry_err_code_t _gcry_cipher_cfb_decrypt
/* */ (gcry_cipher_hd_t c,
unsigned char *outbuf, size_t outbuflen,
const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_cfb8_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_cfb8_decrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
/*-- cipher-ofb.c --*/
diff --git a/cipher/cipher.c b/cipher/cipher.c
index 06ce1dad..124700e9 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -415,6 +415,7 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
case GCRY_CIPHER_MODE_ECB:
case GCRY_CIPHER_MODE_CBC:
case GCRY_CIPHER_MODE_CFB:
+ case GCRY_CIPHER_MODE_CFB8:
case GCRY_CIPHER_MODE_OFB:
case GCRY_CIPHER_MODE_CTR:
case GCRY_CIPHER_MODE_AESWRAP:
@@ -902,6 +903,10 @@ cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen,
rc = _gcry_cipher_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
+ case GCRY_CIPHER_MODE_CFB8:
+ rc = _gcry_cipher_cfb8_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
case GCRY_CIPHER_MODE_OFB:
rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
@@ -1029,6 +1034,10 @@ cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen,
rc = _gcry_cipher_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
+ case GCRY_CIPHER_MODE_CFB8:
+ rc = _gcry_cipher_cfb8_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
case GCRY_CIPHER_MODE_OFB:
rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;