aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2019-01-15 22:52:30 -0600
committerAlex Gaynor <alex.gaynor@gmail.com>2019-01-15 23:52:30 -0500
commit82177c2c5ba1f16af2157275108cf7c39d31854a (patch)
tree009a3a609fd7ee0ffae12bece3cd9f24643253ab
parent9c2f3d6a05b117247b37323e1f8ed1cf6fa263d1 (diff)
downloadplatform_external_python_cryptography-82177c2c5ba1f16af2157275108cf7c39d31854a.tar.gz
platform_external_python_cryptography-82177c2c5ba1f16af2157275108cf7c39d31854a.tar.bz2
platform_external_python_cryptography-82177c2c5ba1f16af2157275108cf7c39d31854a.zip
support byteslike in aead for key and nonce (#4695)
-rw-r--r--docs/hazmat/primitives/aead.rst28
-rw-r--r--src/cryptography/hazmat/backends/openssl/aead.py6
-rw-r--r--src/cryptography/hazmat/primitives/ciphers/aead.py12
-rw-r--r--tests/hazmat/primitives/test_aead.py45
4 files changed, 73 insertions, 18 deletions
diff --git a/docs/hazmat/primitives/aead.rst b/docs/hazmat/primitives/aead.rst
index 06fecc5a..d318367b 100644
--- a/docs/hazmat/primitives/aead.rst
+++ b/docs/hazmat/primitives/aead.rst
@@ -18,7 +18,8 @@ also support providing integrity for associated data which is not encrypted.
It is a stream cipher combined with a MAC that offers strong integrity
guarantees.
- :param bytes key: A 32-byte key. This **must** be kept secret.
+ :param key: A 32-byte key. This **must** be kept secret.
+ :type key: :term:`bytes-like`
:raises cryptography.exceptions.UnsupportedAlgorithm: If the version of
OpenSSL does not support ChaCha20Poly1305.
@@ -53,8 +54,8 @@ also support providing integrity for associated data which is not encrypted.
``associated_data``. The output of this can be passed directly
to the ``decrypt`` method.
- :param bytes nonce: A 12 byte value. **NEVER REUSE A NONCE** with a
- key.
+ :param nonce: A 12 byte value. **NEVER REUSE A NONCE** with a key.
+ :type nonce: :term:`bytes-like`
:param bytes data: The data to encrypt.
:param bytes associated_data: Additional data that should be
authenticated with the key, but does not need to be encrypted. Can
@@ -69,8 +70,9 @@ also support providing integrity for associated data which is not encrypted.
called encrypt with ``associated_data`` you must pass the same
``associated_data`` in decrypt or the integrity check will fail.
- :param bytes nonce: A 12 byte value. **NEVER REUSE A NONCE** with a
+ :param nonce: A 12 byte value. **NEVER REUSE A NONCE** with a
key.
+ :type nonce: :term:`bytes-like`
:param bytes data: The data to decrypt (with tag appended).
:param bytes associated_data: Additional data to authenticate. Can be
``None`` if none was passed during encryption.
@@ -88,7 +90,8 @@ also support providing integrity for associated data which is not encrypted.
:class:`~cryptography.hazmat.primitives.ciphers.algorithms.AES` block
cipher utilizing Galois Counter Mode (GCM).
- :param bytes key: A 128, 192, or 256-bit key. This **must** be kept secret.
+ :param key: A 128, 192, or 256-bit key. This **must** be kept secret.
+ :type key: :term:`bytes-like`
.. doctest::
@@ -123,9 +126,10 @@ also support providing integrity for associated data which is not encrypted.
authenticating the ``associated_data``. The output of this can be
passed directly to the ``decrypt`` method.
- :param bytes nonce: NIST `recommends a 96-bit IV length`_ for best
+ :param nonce: NIST `recommends a 96-bit IV length`_ for best
performance but it can be up to 2\ :sup:`64` - 1 :term:`bits`.
**NEVER REUSE A NONCE** with a key.
+ :type nonce: :term:`bytes-like`
:param bytes data: The data to encrypt.
:param bytes associated_data: Additional data that should be
authenticated with the key, but is not encrypted. Can be ``None``.
@@ -139,9 +143,10 @@ also support providing integrity for associated data which is not encrypted.
called encrypt with ``associated_data`` you must pass the same
``associated_data`` in decrypt or the integrity check will fail.
- :param bytes nonce: NIST `recommends a 96-bit IV length`_ for best
+ :param nonce: NIST `recommends a 96-bit IV length`_ for best
performance but it can be up to 2\ :sup:`64` - 1 :term:`bits`.
**NEVER REUSE A NONCE** with a key.
+ :type nonce: :term:`bytes-like`
:param bytes data: The data to decrypt (with tag appended).
:param bytes associated_data: Additional data to authenticate. Can be
``None`` if none was passed during encryption.
@@ -165,7 +170,8 @@ also support providing integrity for associated data which is not encrypted.
:class:`~cryptography.hazmat.primitives.ciphers.algorithms.AES` block
cipher utilizing Counter with CBC-MAC (CCM) (specified in :rfc:`3610`).
- :param bytes key: A 128, 192, or 256-bit key. This **must** be kept secret.
+ :param key: A 128, 192, or 256-bit key. This **must** be kept secret.
+ :type key: :term:`bytes-like`
:param int tag_length: The length of the authentication tag. This
defaults to 16 bytes and it is **strongly** recommended that you
do not make it shorter unless absolutely necessary. Valid tag
@@ -207,11 +213,12 @@ also support providing integrity for associated data which is not encrypted.
authenticating the ``associated_data``. The output of this can be
passed directly to the ``decrypt`` method.
- :param bytes nonce: A value of between 7 and 13 bytes. The maximum
+ :param nonce: A value of between 7 and 13 bytes. The maximum
length is determined by the length of the ciphertext you are
encrypting and must satisfy the condition:
``len(data) < 2 ** (8 * (15 - len(nonce)))``
**NEVER REUSE A NONCE** with a key.
+ :type nonce: :term:`bytes-like`
:param bytes data: The data to encrypt.
:param bytes associated_data: Additional data that should be
authenticated with the key, but is not encrypted. Can be ``None``.
@@ -225,9 +232,10 @@ also support providing integrity for associated data which is not encrypted.
called encrypt with ``associated_data`` you must pass the same
``associated_data`` in decrypt or the integrity check will fail.
- :param bytes nonce: A value of between 7 and 13 bytes. This
+ :param nonce: A value of between 7 and 13 bytes. This
is the same value used when you originally called encrypt.
**NEVER REUSE A NONCE** with a key.
+ :type nonce: :term:`bytes-like`
:param bytes data: The data to decrypt (with tag appended).
:param bytes associated_data: Additional data to authenticate. Can be
``None`` if none was passed during encryption.
diff --git a/src/cryptography/hazmat/backends/openssl/aead.py b/src/cryptography/hazmat/backends/openssl/aead.py
index 9cec3e23..73195ff3 100644
--- a/src/cryptography/hazmat/backends/openssl/aead.py
+++ b/src/cryptography/hazmat/backends/openssl/aead.py
@@ -54,12 +54,14 @@ def _aead_setup(backend, cipher_name, key, nonce, tag, tag_len, operation):
ctx, backend._lib.EVP_CTRL_AEAD_SET_TAG, tag_len, backend._ffi.NULL
)
+ nonce_ptr = backend._ffi.from_buffer(nonce)
+ key_ptr = backend._ffi.from_buffer(key)
res = backend._lib.EVP_CipherInit_ex(
ctx,
backend._ffi.NULL,
backend._ffi.NULL,
- key,
- nonce,
+ key_ptr,
+ nonce_ptr,
int(operation == _ENCRYPT)
)
backend.openssl_assert(res != 0)
diff --git a/src/cryptography/hazmat/primitives/ciphers/aead.py b/src/cryptography/hazmat/primitives/ciphers/aead.py
index 16899d00..42e19adb 100644
--- a/src/cryptography/hazmat/primitives/ciphers/aead.py
+++ b/src/cryptography/hazmat/primitives/ciphers/aead.py
@@ -20,7 +20,7 @@ class ChaCha20Poly1305(object):
"ChaCha20Poly1305 is not supported by this version of OpenSSL",
exceptions._Reasons.UNSUPPORTED_CIPHER
)
- utils._check_bytes("key", key)
+ utils._check_byteslike("key", key)
if len(key) != 32:
raise ValueError("ChaCha20Poly1305 key must be 32 bytes.")
@@ -56,7 +56,7 @@ class ChaCha20Poly1305(object):
)
def _check_params(self, nonce, data, associated_data):
- utils._check_bytes("nonce", nonce)
+ utils._check_byteslike("nonce", nonce)
utils._check_bytes("data", data)
utils._check_bytes("associated_data", associated_data)
if len(nonce) != 12:
@@ -67,7 +67,7 @@ class AESCCM(object):
_MAX_SIZE = 2 ** 32
def __init__(self, key, tag_length=16):
- utils._check_bytes("key", key)
+ utils._check_byteslike("key", key)
if len(key) not in (16, 24, 32):
raise ValueError("AESCCM key must be 128, 192, or 256 bits.")
@@ -129,7 +129,7 @@ class AESCCM(object):
raise ValueError("Nonce too long for data")
def _check_params(self, nonce, data, associated_data):
- utils._check_bytes("nonce", nonce)
+ utils._check_byteslike("nonce", nonce)
utils._check_bytes("data", data)
utils._check_bytes("associated_data", associated_data)
if not 7 <= len(nonce) <= 13:
@@ -140,7 +140,7 @@ class AESGCM(object):
_MAX_SIZE = 2 ** 32
def __init__(self, key):
- utils._check_bytes("key", key)
+ utils._check_byteslike("key", key)
if len(key) not in (16, 24, 32):
raise ValueError("AESGCM key must be 128, 192, or 256 bits.")
@@ -181,7 +181,7 @@ class AESGCM(object):
)
def _check_params(self, nonce, data, associated_data):
- utils._check_bytes("nonce", nonce)
+ utils._check_byteslike("nonce", nonce)
utils._check_bytes("data", data)
utils._check_bytes("associated_data", associated_data)
if len(nonce) == 0:
diff --git a/tests/hazmat/primitives/test_aead.py b/tests/hazmat/primitives/test_aead.py
index 5a518558..e1a17a97 100644
--- a/tests/hazmat/primitives/test_aead.py
+++ b/tests/hazmat/primitives/test_aead.py
@@ -167,6 +167,21 @@ class TestChaCha20Poly1305(object):
computed_ct = chacha.encrypt(nonce, pt, aad)
assert computed_ct == ct + tag
+ def test_buffer_protocol(self, backend):
+ key = ChaCha20Poly1305.generate_key()
+ chacha = ChaCha20Poly1305(key)
+ pt = b"encrypt me"
+ ad = b"additional"
+ nonce = os.urandom(12)
+ ct = chacha.encrypt(nonce, pt, ad)
+ computed_pt = chacha.decrypt(nonce, ct, ad)
+ assert computed_pt == pt
+ chacha2 = ChaCha20Poly1305(bytearray(key))
+ ct2 = chacha2.encrypt(bytearray(nonce), pt, ad)
+ assert ct2 == ct
+ computed_pt2 = chacha2.decrypt(bytearray(nonce), ct2, ad)
+ assert computed_pt2 == pt
+
@pytest.mark.skipif(
_aead_supported(AESCCM),
@@ -317,6 +332,21 @@ class TestAESCCM(object):
with pytest.raises(InvalidTag):
aesccm.decrypt(b"0" * 12, b"0", None)
+ def test_buffer_protocol(self, backend):
+ key = AESCCM.generate_key(128)
+ aesccm = AESCCM(key)
+ pt = b"encrypt me"
+ ad = b"additional"
+ nonce = os.urandom(12)
+ ct = aesccm.encrypt(nonce, pt, ad)
+ computed_pt = aesccm.decrypt(nonce, ct, ad)
+ assert computed_pt == pt
+ aesccm2 = AESCCM(bytearray(key))
+ ct2 = aesccm2.encrypt(bytearray(nonce), pt, ad)
+ assert ct2 == ct
+ computed_pt2 = aesccm2.decrypt(bytearray(nonce), ct2, ad)
+ assert computed_pt2 == pt
+
def _load_gcm_vectors():
vectors = _load_all_params(
@@ -413,3 +443,18 @@ class TestAESGCM(object):
pt1 = aesgcm.decrypt(nonce, ct1, None)
pt2 = aesgcm.decrypt(nonce, ct2, b"")
assert pt1 == pt2
+
+ def test_buffer_protocol(self, backend):
+ key = AESGCM.generate_key(128)
+ aesgcm = AESGCM(key)
+ pt = b"encrypt me"
+ ad = b"additional"
+ nonce = os.urandom(12)
+ ct = aesgcm.encrypt(nonce, pt, ad)
+ computed_pt = aesgcm.decrypt(nonce, ct, ad)
+ assert computed_pt == pt
+ aesgcm2 = AESGCM(bytearray(key))
+ ct2 = aesgcm2.encrypt(bytearray(nonce), pt, ad)
+ assert ct2 == ct
+ computed_pt2 = aesgcm2.decrypt(bytearray(nonce), ct2, ad)
+ assert computed_pt2 == pt