aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2013-10-21 23:48:25 -0500
committerPaul Kehrer <paul.l.kehrer@gmail.com>2013-10-21 23:52:13 -0500
commit5399fd087268b671c61ad3710cdec6d540c02f22 (patch)
tree8a6f2297310c1a7bcdc6e9aa444ad6200a1d64fe
parentb59377d9a31d8614e1b883f7523939c8ab271500 (diff)
downloadcryptography-5399fd087268b671c61ad3710cdec6d540c02f22.tar.gz
cryptography-5399fd087268b671c61ad3710cdec6d540c02f22.tar.bz2
cryptography-5399fd087268b671c61ad3710cdec6d540c02f22.zip
Create CipherContext interface & document it
* Rename BlockCipherEncryption/DecryptionContexts to just CipherEncryption/DecryptionContext * Moved register to interfaces.py from modes.py since it is generic and can be used to decorate the _CipherEncryption/DecryptionContexts
-rw-r--r--cryptography/primitives/block/base.py16
-rw-r--r--cryptography/primitives/block/modes.py15
-rw-r--r--cryptography/primitives/interfaces.py21
-rw-r--r--docs/primitives/symmetric-encryption.rst29
4 files changed, 57 insertions, 24 deletions
diff --git a/cryptography/primitives/block/base.py b/cryptography/primitives/block/base.py
index e625dc7c..12b6f626 100644
--- a/cryptography/primitives/block/base.py
+++ b/cryptography/primitives/block/base.py
@@ -13,6 +13,8 @@
from __future__ import absolute_import, division, print_function
+from cryptography.primitives import interfaces
+
class BlockCipher(object):
def __init__(self, cipher, mode, api=None):
@@ -26,15 +28,16 @@ class BlockCipher(object):
self._api = api
def encryptor(self):
- return _BlockCipherEncryptionContext(self.cipher, self.mode, self._api)
+ return _CipherEncryptionContext(self.cipher, self.mode, self._api)
def decryptor(self):
- return _BlockCipherDecryptionContext(self.cipher, self.mode, self._api)
+ return _CipherDecryptionContext(self.cipher, self.mode, self._api)
-class _BlockCipherEncryptionContext(object):
+@interfaces.register(interfaces.CipherContext)
+class _CipherEncryptionContext(object):
def __init__(self, cipher, mode, api):
- super(_BlockCipherEncryptionContext, self).__init__()
+ super(_CipherEncryptionContext, self).__init__()
self._api = api
self._ctx = self._api.create_block_cipher_encrypt_context(cipher, mode)
@@ -51,9 +54,10 @@ class _BlockCipherEncryptionContext(object):
return data
-class _BlockCipherDecryptionContext(object):
+@interfaces.register(interfaces.CipherContext)
+class _CipherDecryptionContext(object):
def __init__(self, cipher, mode, api):
- super(_BlockCipherDecryptionContext, self).__init__()
+ super(_CipherDecryptionContext, self).__init__()
self._api = api
self._ctx = self._api.create_block_cipher_decrypt_context(cipher, mode)
diff --git a/cryptography/primitives/block/modes.py b/cryptography/primitives/block/modes.py
index 43631801..a933c187 100644
--- a/cryptography/primitives/block/modes.py
+++ b/cryptography/primitives/block/modes.py
@@ -16,14 +16,7 @@ from __future__ import absolute_import, division, print_function
from cryptography.primitives import interfaces
-def register(iface):
- def register_decorator(klass):
- iface.register(klass)
- return klass
- return register_decorator
-
-
-@register(interfaces.ModeWithInitializationVector)
+@interfaces.register(interfaces.ModeWithInitializationVector)
class CBC(object):
name = "CBC"
@@ -36,7 +29,7 @@ class ECB(object):
name = "ECB"
-@register(interfaces.ModeWithInitializationVector)
+@interfaces.register(interfaces.ModeWithInitializationVector)
class OFB(object):
name = "OFB"
@@ -45,7 +38,7 @@ class OFB(object):
self.initialization_vector = initialization_vector
-@register(interfaces.ModeWithInitializationVector)
+@interfaces.register(interfaces.ModeWithInitializationVector)
class CFB(object):
name = "CFB"
@@ -54,7 +47,7 @@ class CFB(object):
self.initialization_vector = initialization_vector
-@register(interfaces.ModeWithNonce)
+@interfaces.register(interfaces.ModeWithNonce)
class CTR(object):
name = "CTR"
diff --git a/cryptography/primitives/interfaces.py b/cryptography/primitives/interfaces.py
index c1fc9910..49c19d0e 100644
--- a/cryptography/primitives/interfaces.py
+++ b/cryptography/primitives/interfaces.py
@@ -18,9 +18,30 @@ import abc
import six
+def register(iface):
+ def register_decorator(klass):
+ iface.register(klass)
+ return klass
+ return register_decorator
+
+
class ModeWithInitializationVector(six.with_metaclass(abc.ABCMeta)):
pass
class ModeWithNonce(six.with_metaclass(abc.ABCMeta)):
pass
+
+
+class CipherContext(six.with_metaclass(abc.ABCMeta)):
+ @abc.abstractmethod
+ def update(self, data):
+ """
+ update takes bytes and return bytes
+ """
+
+ @abc.abstractmethod
+ def finalize(self):
+ """
+ finalize return bytes
+ """
diff --git a/docs/primitives/symmetric-encryption.rst b/docs/primitives/symmetric-encryption.rst
index 1ec1ee01..2021356c 100644
--- a/docs/primitives/symmetric-encryption.rst
+++ b/docs/primitives/symmetric-encryption.rst
@@ -15,7 +15,7 @@ where the encrypter and decrypter both use the same key.
Block ciphers work by encrypting content in chunks, often 64- or 128-bits.
They combine an underlying algorithm (such as AES), with a mode (such as
- CBC, CTR, or GCM). A simple example of encrypting (and then decrypting)
+ CBC, CTR, or GCM).A simple example of encrypting (and then decrypting)
content with AES is:
.. doctest::
@@ -31,17 +31,32 @@ where the encrypter and decrypter both use the same key.
:param cipher: One of the ciphers described below.
:param mode: One of the modes described below.
- ``encrypt()`` should be called repeatedly with new plaintext, and once the
- full plaintext is fed in, ``finalize()`` should be called.
+ .. method:: encryptor()
- .. method:: encrypt(plaintext)
+ :return :ref:`CipherContext <ciphercontext>`: encryption instance
- :param bytes plaintext: The text you wish to encrypt.
- :return bytes: Returns the ciphertext that was added.
+ .. method:: decryptor()
+
+ :return :ref:`CipherContext <ciphercontext>`: decryption instance
+
+.. _ciphercontext:
+.. class:: cryptography.primitives.interfaces.CipherContext()
+
+ When calling ``encryptor()`` or ``decryptor()`` on a BlockCipher object you
+ will receive a return object conforming to the CipherContext interface. You
+ can then call ``update(data)`` with data until you have fed everything into
+ the context. Once that is done call ``finalize()`` to finish the operation and
+ obtain the remainder of the data.
+
+
+ .. method:: update(data)
+
+ :param bytes data: The text you wish to pass into the context.
+ :return bytes: Returns the data that was encrypted or decrypted.
.. method:: finalize()
- :return bytes: Returns the remainder of the ciphertext.
+ :return bytes: Returns the remainder of the data.
Ciphers
~~~~~~~