diff options
| author | David Reid <dreid@dreid.org> | 2013-09-11 16:22:26 -0700 | 
|---|---|---|
| committer | David Reid <dreid@dreid.org> | 2013-09-11 16:22:26 -0700 | 
| commit | dd3c783d59010faddb1cbc1d2d16e5792b913ecf (patch) | |
| tree | 9783c827cefc06e1cf7ea446df7b94deb62e0942 | |
| parent | 9287c2344c6c91ad838a251d3b6fde2a6ea88b56 (diff) | |
| parent | 4223df72cf3d3566ae8ccbce7d31dbae7ee25cdd (diff) | |
| download | cryptography-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.py | 9 | ||||
| -rw-r--r-- | docs/primitives/symmetric-encryption.rst | 13 | ||||
| -rw-r--r-- | tests/primitives/test_nist.py | 47 | 
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 | 
