diff options
-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 c722e739..70ef8178 100644 --- a/cryptography/primitives/block/modes.py +++ b/cryptography/primitives/block/modes.py @@ -28,4 +28,13 @@ class ECB(object): name = "ECB" +class OFB(object): + name = "OFB" + + def __init__(self, initialization_vector): + super(OFB, self).__init__() + self.initialization_vector = initialization_vector + + interfaces.ModeWithInitializationVector.register(CBC) +interfaces.ModeWithInitializationVector.register(OFB) diff --git a/docs/primitives/symmetric-encryption.rst b/docs/primitives/symmetric-encryption.rst index d0429d4b..7ec42a30 100644 --- a/docs/primitives/symmetric-encryption.rst +++ b/docs/primitives/symmetric-encryption.rst @@ -68,6 +68,19 @@ Modes reuse an ``initialization_vector`` with a given ``key``. +.. class:: cryptography.primitives.block.modes.OFB(initialization_vector) + + OFB (Output 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 3dc8277a..0e16cc9c 100644 --- a/tests/primitives/test_nist.py +++ b/tests/primitives/test_nist.py @@ -133,3 +133,50 @@ class TestAES_ECB(object): actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) actual_ciphertext += cipher.finalize() assert binascii.hexlify(actual_ciphertext) == ciphertext + + +class TestAES_OFB(object): + @parameterize_encrypt_test( + "AES", "KAT", + ("key", "iv", "plaintext", "ciphertext"), + [ + "OFBGFSbox128.rsp", + "OFBGFSbox192.rsp", + "OFBGFSbox256.rsp", + "OFBKeySbox128.rsp", + "OFBKeySbox192.rsp", + "OFBKeySbox256.rsp", + "OFBVarKey128.rsp", + "OFBVarKey192.rsp", + "OFBVarKey256.rsp", + "OFBVarTxt128.rsp", + "OFBVarTxt192.rsp", + "OFBVarTxt256.rsp", + ] + ) + def test_KAT(self, key, iv, plaintext, ciphertext): + cipher = BlockCipher( + ciphers.AES(binascii.unhexlify(key)), + modes.OFB(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"), + [ + "OFBMMT128.rsp", + "OFBMMT192.rsp", + "OFBMMT256.rsp", + ] + ) + def test_MMT(self, key, iv, plaintext, ciphertext): + cipher = BlockCipher( + ciphers.AES(binascii.unhexlify(key)), + modes.OFB(binascii.unhexlify(iv)) + ) + actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) + actual_ciphertext += cipher.finalize() + assert binascii.hexlify(actual_ciphertext) == ciphertext |