From de505128c272e633a66fbcfae277d69d141fcec7 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 23 Oct 2013 22:32:23 -0500 Subject: simplify enc/dec in the OpenSSL backend by using the EVP_Cipher* methods --- cryptography/bindings/openssl/backend.py | 56 +++++++++----------------------- cryptography/bindings/openssl/evp.py | 5 +++ cryptography/primitives/block/base.py | 8 ++--- 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 -- cgit v1.2.3