aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Reid <dreid@dreid.org>2013-09-11 16:22:26 -0700
committerDavid Reid <dreid@dreid.org>2013-09-11 16:22:26 -0700
commitdd3c783d59010faddb1cbc1d2d16e5792b913ecf (patch)
tree9783c827cefc06e1cf7ea446df7b94deb62e0942
parent9287c2344c6c91ad838a251d3b6fde2a6ea88b56 (diff)
parent4223df72cf3d3566ae8ccbce7d31dbae7ee25cdd (diff)
downloadcryptography-dd3c783d59010faddb1cbc1d2d16e5792b913ecf.tar.gz
cryptography-dd3c783d59010faddb1cbc1d2d16e5792b913ecf.tar.bz2
cryptography-dd3c783d59010faddb1cbc1d2d16e5792b913ecf.zip
Merge pull request #59 from reaperhulk/cfb-support
CFB support
-rw-r--r--cryptography/primitives/block/modes.py9
-rw-r--r--docs/primitives/symmetric-encryption.rst13
-rw-r--r--tests/primitives/test_nist.py47
3 files changed, 69 insertions, 0 deletions
diff --git a/cryptography/primitives/block/modes.py b/cryptography/primitives/block/modes.py
index 62a1c2c9..0f17a1a5 100644
--- a/cryptography/primitives/block/modes.py
+++ b/cryptography/primitives/block/modes.py
@@ -36,5 +36,14 @@ class OFB(object):
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/docs/primitives/symmetric-encryption.rst b/docs/primitives/symmetric-encryption.rst
index c4f78a79..be86229b 100644
--- a/docs/primitives/symmetric-encryption.rst
+++ b/docs/primitives/symmetric-encryption.rst
@@ -79,6 +79,19 @@ Modes
of the cipher. Reuse of a ``nonce`` with a given
``key`` can allow recovery of the original plaintext.
+.. class:: cryptography.primitives.block.modes.CFB(initialization_vector)
+
+ CFB (Cipher Feedback) is a mode of operation for block ciphers. It
+ transforms a block cipher into a stream cipher.
+
+ :param bytes initialization_vector: Must be random bytes. They do not need
+ to be kept secret (they can be included
+ in a transmitted message). Must be the
+ same number of bytes as the
+ ``block_size`` of the cipher. Do not
+ reuse an ``initialization_vector`` with
+ a given ``key``.
+
Insecure Modes
--------------
diff --git a/tests/primitives/test_nist.py b/tests/primitives/test_nist.py
index 0e16cc9c..1e5d2396 100644
--- a/tests/primitives/test_nist.py
+++ b/tests/primitives/test_nist.py
@@ -180,3 +180,50 @@ class TestAES_OFB(object):
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