2017-09-24 15:48 GMT+03:00 Niels Möller nisse@lysator.liu.se:
What use cases do you have? CFB has been requested earlier (see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=721187), motivated by openpgp.
My primary usecase is PKCS7/PBES2 encryption with GOST28147 cipher in CFB mode. I will check how to add support for OpenPGP way.
If I've understod things correctly, one traditional usecase of CFB is for encrypting messages smaller than the block size, one at a time (and that's how CFB is defined in Handbook of Applied Cryptography). While your implementation works similarly to the CTR implementation.
Yes, I modelled CFB after CTR, as both of them are stream modes of operation. Should we also add CTR interface supporting stream of short messages?
Dmitry Eremin-Solenikov dbaryshkov@gmail.com writes:
--- /dev/null +++ b/cfb.c @@ -0,0 +1,176 @@
[...]
if (length)
{
TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
TMP_ALLOC(buffer, block_size);
f(ctx, block_size, buffer, iv);
memxor3(dst, buffer, src, length);
memcpy(iv, dst, length);
Is this intended only for the last block of a message, or more generally? I don't quite understand the update of the iv; from HoAC it seems the IV should be shifted, and I think NIST SP800-38A agrees? If this can be supported without a lot of difficulty, that would be nice. And we don't have to do it now, if it could be added later, if we can arrange now that it's possible without redesigning of the itnerface.
--- a/nettle.texinfo +++ b/nettle.texinfo
[...]
+Cipher Feedback mode (@acronym{CFB}) being a close relative to both +@acronym{CBC} mode and @acronym{CTR} mode transforms block cipher into a +stream cipher.
+The message is divided into @code{n} blocks @code{M_1},@dots{} +@code{M_n}, where @code{M_n} is of size @code{m} which may be smaller +than the block size. Except for the last block, all the message blocks +must be of size equal to the cipher's block size.
So a sequence of short messages isn't supported?
Yes, as I wrote, this was modelled against CTR.
+@deftypefun {void} cbc_encrypt (const void *@var{ctx}, nettle_cipher_func *@var{f}, size_t @var{block_size}, uint8_t *@var{iv}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx {void} cbc_decrypt (const void *@var{ctx}, nettle_cipher_func *@var{f}, size_t @var{block_size}, uint8_t *@var{iv}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
+Applies the encryption or decryption function @var{f} in @acronym{CBC} +mode. The final ciphertext block processed is copied into @var{iv} +before returning, so that a large message can be processed by a sequence of +calls to @code{cfb_encrypt}. Note that for @acronym{CFB} mode internally +uses encryption only function and hence @var{f} should always be the +encryption function for the underlying block cipher.
Some copy-paste errors here, should be cfb, not cbc.
Ugh, sorry.
--- /dev/null +++ b/testsuite/cfb-test.c
[...]
+void +test_main(void) +{
- /* From NIST spec 800-38a on AES modes.
- F.3 CFB Example Vectors
- F.3.13 CFB128-AES128.Encrypt
- */
Seems there are testvectors also for shorter messages, e.g., F.3.7, CFB8.
CFB8 is not for 'shorter messages', but for shorter segments of CFB. I targeted mode where s == b (in terms of 800-38a).
So, to sum up, would you like the following to be implemented:
- real stream-like API, where one can call encrypt/decrypt multiple times, not necessaryly starting/ending on segment boundary? This should probably together with updated CTR/GCM API, implementing possibility to store interim block state and continue xor'ing from the point we left
- support for shorter segments (then which segment lengths would you like to see?) Would s=b and s=8 bit be enough from your POV?