aboutsummaryrefslogtreecommitdiffstats
path: root/cryptography
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2013-10-21 22:06:41 -0500
committerPaul Kehrer <paul.l.kehrer@gmail.com>2013-10-21 22:06:41 -0500
commit9f7ea6e232e5e319a2bfc6bab8d88455947b4901 (patch)
treecddf176070c0a7589c4203eb2a88c47d0b99ea7f /cryptography
parent653463f0e133def71425a26fdd80bfe7c8ad5961 (diff)
parentc160079df8dd021b6b1e8091025ba27ddc6cd6c0 (diff)
downloadcryptography-9f7ea6e232e5e319a2bfc6bab8d88455947b4901.tar.gz
cryptography-9f7ea6e232e5e319a2bfc6bab8d88455947b4901.tar.bz2
cryptography-9f7ea6e232e5e319a2bfc6bab8d88455947b4901.zip
Merge branch 'master' into block-cipher-decrypt
Diffstat (limited to 'cryptography')
-rw-r--r--cryptography/bindings/openssl/api.py58
-rw-r--r--cryptography/bindings/openssl/hmac.py32
-rw-r--r--cryptography/primitives/block/base.py4
3 files changed, 79 insertions, 15 deletions
diff --git a/cryptography/bindings/openssl/api.py b/cryptography/bindings/openssl/api.py
index a3198c1a..67d73afb 100644
--- a/cryptography/bindings/openssl/api.py
+++ b/cryptography/bindings/openssl/api.py
@@ -13,11 +13,23 @@
from __future__ import absolute_import, division, print_function
+import itertools
import sys
import cffi
from cryptography.primitives import interfaces
+from cryptography.primitives.block.ciphers import AES, Camellia
+from cryptography.primitives.block.modes import CBC, CTR, ECB, OFB, CFB
+
+
+class GetCipherByName(object):
+ def __init__(self, fmt):
+ self._fmt = fmt
+
+ def __call__(self, api, cipher, mode):
+ cipher_name = self._fmt.format(cipher=cipher, mode=mode).lower()
+ return api.lib.EVP_get_cipherbyname(cipher_name.encode("ascii"))
class API(object):
@@ -35,6 +47,7 @@ class API(object):
"engine",
"err",
"evp",
+ "hmac",
"nid",
"opensslv",
"pem",
@@ -86,6 +99,9 @@ class API(object):
self.lib.OpenSSL_add_all_algorithms()
self.lib.SSL_load_error_strings()
+ self._cipher_registry = {}
+ self._register_default_ciphers()
+
def openssl_version_text(self):
"""
Friendly string name of linked OpenSSL.
@@ -94,9 +110,31 @@ class API(object):
"""
return self.ffi.string(self.lib.OPENSSL_VERSION_TEXT).decode("ascii")
- def supports_cipher(self, ciphername):
- return (self.ffi.NULL !=
- self.lib.EVP_get_cipherbyname(ciphername.encode("ascii")))
+ def supports_cipher(self, cipher, mode):
+ try:
+ adapter = self._cipher_registry[type(cipher), type(mode)]
+ except KeyError:
+ return False
+ evp_cipher = adapter(self, cipher, mode)
+ return self.ffi.NULL != evp_cipher
+
+ def register_cipher_adapter(self, cipher_cls, mode_cls, adapter):
+ if (cipher_cls, mode_cls) in self._cipher_registry:
+ raise ValueError("Duplicate registration for: {0} {1}".format(
+ cipher_cls, mode_cls)
+ )
+ self._cipher_registry[cipher_cls, mode_cls] = adapter
+
+ def _register_default_ciphers(self):
+ for cipher_cls, mode_cls in itertools.product(
+ [AES, Camellia],
+ [CBC, CTR, ECB, OFB, CFB],
+ ):
+ self.register_cipher_adapter(
+ cipher_cls,
+ mode_cls,
+ GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}")
+ )
def create_block_cipher_encrypt_context(self, cipher, mode):
ctx, evp, iv_nonce = self._create_block_cipher_context(cipher, mode)
@@ -119,15 +157,11 @@ class API(object):
return ctx
def _create_block_cipher_context(self, cipher, mode):
- ctx = self.ffi.new("EVP_CIPHER_CTX *")
- res = self.lib.EVP_CIPHER_CTX_init(ctx)
- assert res != 0
- ctx = self.ffi.gc(ctx, self.lib.EVP_CIPHER_CTX_cleanup)
- # TODO: compute name using a better algorithm
- ciphername = "{0}-{1}-{2}".format(
- cipher.name, cipher.key_size, mode.name
- ).lower()
- evp_cipher = self.lib.EVP_get_cipherbyname(ciphername.encode("ascii"))
+ 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)](
+ self, cipher, mode
+ )
assert evp_cipher != self.ffi.NULL
if isinstance(mode, interfaces.ModeWithInitializationVector):
iv_nonce = mode.initialization_vector
diff --git a/cryptography/bindings/openssl/hmac.py b/cryptography/bindings/openssl/hmac.py
new file mode 100644
index 00000000..e97ac35e
--- /dev/null
+++ b/cryptography/bindings/openssl/hmac.py
@@ -0,0 +1,32 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+INCLUDES = """
+#include <openssl/hmac.h>
+"""
+
+TYPES = """
+typedef struct { ...; } HMAC_CTX;
+"""
+
+FUNCTIONS = """
+void HMAC_CTX_init(HMAC_CTX *);
+void HMAC_CTX_cleanup(HMAC_CTX *);
+int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *);
+int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t);
+int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *);
+int HMAC_CTX_copy(HMAC_CTX *, HMAC_CTX *);
+"""
+
+MACROS = """
+"""
diff --git a/cryptography/primitives/block/base.py b/cryptography/primitives/block/base.py
index 14704ffe..e625dc7c 100644
--- a/cryptography/primitives/block/base.py
+++ b/cryptography/primitives/block/base.py
@@ -13,15 +13,13 @@
from __future__ import absolute_import, division, print_function
-from cryptography.bindings import _default_api
-
class BlockCipher(object):
def __init__(self, cipher, mode, api=None):
super(BlockCipher, self).__init__()
if api is None:
- api = _default_api
+ from cryptography.bindings import _default_api as api
self.cipher = cipher
self.mode = mode