CFB support
This requires a bit of explanation. OpenSSL has methods that implement
standard CFB, 1-bit CFB (cfb1), and 8-bit CFB (cfb8). Unfortunately,
while old (read: 0.9.7) versions of OpenSSL appear to test these
variants, newer versions have a comment stating that cfb{1,8} are
unsupported. Accordingly, I've backed out any support for the variants
for now. We can add it back into the CFB class if and when we gain a
backend that supports arbitrary s for 1 <= s <= block_size
diff --git a/cryptography/primitives/block/modes.py b/cryptography/primitives/block/modes.py
index 62a1c2c..0f17a1a 100644
--- a/cryptography/primitives/block/modes.py
+++ b/cryptography/primitives/block/modes.py
@@ -36,5 +36,14 @@
self.nonce = nonce
+class CFB(object):
+ name = "CFB"
+
+ def __init__(self, initialization_vector):
+ super(CFB, self).__init__()
+ self.initialization_vector = initialization_vector
+
+
interfaces.ModeWithInitializationVector.register(CBC)
interfaces.ModeWithNonce.register(OFB)
+interfaces.ModeWithInitializationVector.register(CFB)
diff --git a/tests/primitives/test_nist.py b/tests/primitives/test_nist.py
index 0e16cc9..1e5d239 100644
--- a/tests/primitives/test_nist.py
+++ b/tests/primitives/test_nist.py
@@ -180,3 +180,50 @@
actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext))
actual_ciphertext += cipher.finalize()
assert binascii.hexlify(actual_ciphertext) == ciphertext
+
+
+class TestAES_CFB(object):
+ @parameterize_encrypt_test(
+ "AES", "KAT",
+ ("key", "iv", "plaintext", "ciphertext"),
+ [
+ "CFB128GFSbox128.rsp",
+ "CFB128GFSbox192.rsp",
+ "CFB128GFSbox256.rsp",
+ "CFB128KeySbox128.rsp",
+ "CFB128KeySbox192.rsp",
+ "CFB128KeySbox256.rsp",
+ "CFB128VarKey128.rsp",
+ "CFB128VarKey192.rsp",
+ "CFB128VarKey256.rsp",
+ "CFB128VarTxt128.rsp",
+ "CFB128VarTxt192.rsp",
+ "CFB128VarTxt256.rsp",
+ ]
+ )
+ def test_KAT(self, key, iv, plaintext, ciphertext):
+ cipher = BlockCipher(
+ ciphers.AES(binascii.unhexlify(key)),
+ modes.CFB(binascii.unhexlify(iv))
+ )
+ actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext))
+ actual_ciphertext += cipher.finalize()
+ assert binascii.hexlify(actual_ciphertext) == ciphertext
+
+ @parameterize_encrypt_test(
+ "AES", "MMT",
+ ("key", "iv", "plaintext", "ciphertext"),
+ [
+ "CFB128MMT128.rsp",
+ "CFB128MMT192.rsp",
+ "CFB128MMT256.rsp",
+ ]
+ )
+ def test_MMT(self, key, iv, plaintext, ciphertext):
+ cipher = BlockCipher(
+ ciphers.AES(binascii.unhexlify(key)),
+ modes.CFB(binascii.unhexlify(iv))
+ )
+ actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext))
+ actual_ciphertext += cipher.finalize()
+ assert binascii.hexlify(actual_ciphertext) == ciphertext