aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2013-10-23 20:50:22 -0700
committerAlex Gaynor <alex.gaynor@gmail.com>2013-10-23 20:50:22 -0700
commitf9d838c988bb4a35d58182fd3d331877f8e6ab00 (patch)
treeb165a1f7d7076b4ed7dc89d9cc499d8462e36b47
parent6deb472b88d18b2b982d5e252a8cc7eb114324d7 (diff)
parentde505128c272e633a66fbcfae277d69d141fcec7 (diff)
downloadcryptography-f9d838c988bb4a35d58182fd3d331877f8e6ab00.tar.gz
cryptography-f9d838c988bb4a35d58182fd3d331877f8e6ab00.tar.bz2
cryptography-f9d838c988bb4a35d58182fd3d331877f8e6ab00.zip
Merge pull request #175 from reaperhulk/evp-cipher-methods
[WIP] Simplify Cipher Encryption/Decryption Interfaces in OpenSSL
-rw-r--r--cryptography/bindings/openssl/backend.py56
-rw-r--r--cryptography/bindings/openssl/evp.py5
-rw-r--r--cryptography/primitives/block/base.py8
3 files changed, 25 insertions, 44 deletions
diff --git a/cryptography/bindings/openssl/backend.py b/cryptography/bindings/openssl/backend.py
index 9c80be66..08ff6ba4 100644
--- a/cryptography/bindings/openssl/backend.py
+++ b/cryptography/bindings/openssl/backend.py
@@ -112,6 +112,9 @@ class GetCipherByName(object):
class Ciphers(object):
+ OPENSSL_ENCRYPT = 1
+ OPENSSL_DECRYPT = 0
+
def __init__(self, ffi, lib):
super(Ciphers, self).__init__()
self.ffi = ffi
@@ -152,26 +155,12 @@ class Ciphers(object):
)
def create_encrypt_ctx(self, cipher, mode):
- ctx, evp, iv_nonce = self._create_ctx(cipher, mode)
- res = self.lib.EVP_EncryptInit_ex(ctx, evp, self.ffi.NULL, cipher.key,
- iv_nonce)
- assert res != 0
- # We purposely disable padding here as it's handled higher up in the
- # API.
- self.lib.EVP_CIPHER_CTX_set_padding(ctx, 0)
- return ctx
+ return self._create_ctx(cipher, mode, self.OPENSSL_ENCRYPT)
def create_decrypt_ctx(self, cipher, mode):
- ctx, evp, iv_nonce = self._create_ctx(cipher, mode)
- res = self.lib.EVP_DecryptInit_ex(ctx, evp, self.ffi.NULL, cipher.key,
- iv_nonce)
- assert res != 0
- # We purposely disable padding here as it's handled higher up in the
- # API.
- self.lib.EVP_CIPHER_CTX_set_padding(ctx, 0)
- return ctx
+ return self._create_ctx(cipher, mode, self.OPENSSL_DECRYPT)
- def _create_ctx(self, cipher, mode):
+ def _create_ctx(self, cipher, mode, enc):
ctx = self.lib.EVP_CIPHER_CTX_new()
ctx = self.ffi.gc(ctx, self.lib.EVP_CIPHER_CTX_free)
evp_cipher = self._cipher_registry[type(cipher), type(mode)](
@@ -184,40 +173,27 @@ class Ciphers(object):
iv_nonce = mode.nonce
else:
iv_nonce = self.ffi.NULL
-
- return (ctx, evp_cipher, iv_nonce)
-
- def update_encrypt_ctx(self, ctx, data):
- block_size = self.lib.EVP_CIPHER_CTX_block_size(ctx)
- buf = self.ffi.new("unsigned char[]", len(data) + block_size - 1)
- outlen = self.ffi.new("int *")
- res = self.lib.EVP_EncryptUpdate(ctx, buf, outlen, data, len(data))
+ res = self.lib.EVP_CipherInit_ex(ctx, evp_cipher, self.ffi.NULL,
+ cipher.key, iv_nonce, enc)
assert res != 0
- return self.ffi.buffer(buf)[:outlen[0]]
+ # We purposely disable padding here as it's handled higher up in the
+ # API.
+ self.lib.EVP_CIPHER_CTX_set_padding(ctx, 0)
+ return ctx
- def update_decrypt_ctx(self, ctx, data):
+ def update_ctx(self, ctx, data):
block_size = self.lib.EVP_CIPHER_CTX_block_size(ctx)
buf = self.ffi.new("unsigned char[]", len(data) + block_size - 1)
outlen = self.ffi.new("int *")
- res = self.lib.EVP_DecryptUpdate(ctx, buf, outlen, data, len(data))
+ res = self.lib.EVP_CipherUpdate(ctx, buf, outlen, data, len(data))
assert res != 0
return self.ffi.buffer(buf)[:outlen[0]]
- def finalize_encrypt_ctx(self, ctx):
- block_size = self.lib.EVP_CIPHER_CTX_block_size(ctx)
- buf = self.ffi.new("unsigned char[]", block_size)
- outlen = self.ffi.new("int *")
- res = self.lib.EVP_EncryptFinal_ex(ctx, buf, outlen)
- assert res != 0
- res = self.lib.EVP_CIPHER_CTX_cleanup(ctx)
- assert res == 1
- return self.ffi.buffer(buf)[:outlen[0]]
-
- def finalize_decrypt_ctx(self, ctx):
+ def finalize_ctx(self, ctx):
block_size = self.lib.EVP_CIPHER_CTX_block_size(ctx)
buf = self.ffi.new("unsigned char[]", block_size)
outlen = self.ffi.new("int *")
- res = self.lib.EVP_DecryptFinal_ex(ctx, buf, outlen)
+ res = self.lib.EVP_CipherFinal_ex(ctx, buf, outlen)
assert res != 0
res = self.lib.EVP_CIPHER_CTX_cleanup(ctx)
assert res == 1
diff --git a/cryptography/bindings/openssl/evp.py b/cryptography/bindings/openssl/evp.py
index 80980c6e..a5a97a50 100644
--- a/cryptography/bindings/openssl/evp.py
+++ b/cryptography/bindings/openssl/evp.py
@@ -49,6 +49,11 @@ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *, const EVP_CIPHER *, ENGINE *,
int EVP_DecryptUpdate(EVP_CIPHER_CTX *, unsigned char *, int *,
const unsigned char *, int);
int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *, unsigned char *, int *);
+int EVP_CipherInit_ex(EVP_CIPHER_CTX *, const EVP_CIPHER *, ENGINE *,
+ const unsigned char *, const unsigned char *, int);
+int EVP_CipherUpdate(EVP_CIPHER_CTX *, unsigned char *, int *,
+ const unsigned char *, int);
+int EVP_CipherFinal_ex(EVP_CIPHER_CTX *, unsigned char *, int *);
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *);
const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *);
int EVP_CIPHER_block_size(const EVP_CIPHER *);
diff --git a/cryptography/primitives/block/base.py b/cryptography/primitives/block/base.py
index e9b949c0..2d4623a8 100644
--- a/cryptography/primitives/block/base.py
+++ b/cryptography/primitives/block/base.py
@@ -44,12 +44,12 @@ class _CipherEncryptionContext(object):
def update(self, data):
if self._ctx is None:
raise ValueError("Context was already finalized")
- return self._backend.ciphers.update_encrypt_ctx(self._ctx, data)
+ return self._backend.ciphers.update_ctx(self._ctx, data)
def finalize(self):
if self._ctx is None:
raise ValueError("Context was already finalized")
- data = self._backend.ciphers.finalize_encrypt_ctx(self._ctx)
+ data = self._backend.ciphers.finalize_ctx(self._ctx)
self._ctx = None
return data
@@ -64,11 +64,11 @@ class _CipherDecryptionContext(object):
def update(self, data):
if self._ctx is None:
raise ValueError("Context was already finalized")
- return self._backend.ciphers.update_decrypt_ctx(self._ctx, data)
+ return self._backend.ciphers.update_ctx(self._ctx, data)
def finalize(self):
if self._ctx is None:
raise ValueError("Context was already finalized")
- data = self._backend.ciphers.finalize_decrypt_ctx(self._ctx)
+ data = self._backend.ciphers.finalize_ctx(self._ctx)
self._ctx = None
return data