aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2014-02-13 15:44:01 -0600
committerPaul Kehrer <paul.l.kehrer@gmail.com>2014-02-13 15:44:01 -0600
commitba7d5ecd3e34c59ce58a4b1c2f86494602efe9e8 (patch)
treee7e01d828b33e849c0ed84cb006139282504e82f
parentb477b53fc7e8afe64c380315e16eabfeaaaf7847 (diff)
parent43e4d7a1b97d66c6da1f4ce34faaa4ba45937739 (diff)
downloadcryptography-ba7d5ecd3e34c59ce58a4b1c2f86494602efe9e8.tar.gz
cryptography-ba7d5ecd3e34c59ce58a4b1c2f86494602efe9e8.tar.bz2
cryptography-ba7d5ecd3e34c59ce58a4b1c2f86494602efe9e8.zip
Merge branch 'master' into add-crt-coefficients
* master: Also clean up this syntax Fixed a missing word in the RSA docs Fix comments in padding.py to be accurate add versionadded to cast5 A few style nits in the docs add CAST5 support to changelog Changed .... lines to ~~~~ and s/Gnu\/Linux/Linux/ Pypy is not a real word either apparently. Added Pypy note and fixed libffi's "spelling" Added Debian mention, extra missing packages Added a docs section on Linux installation remove some extra linebreaks add cast5 docs Syntax highlight the go code. Be mad Rob Pike. add cbc, cfb, ofb support to CAST5 (aka CAST128) for openssl & cc re-add CAST5 ECB support (OpenSSL & CC backends). fixes #417 Switch this to a warning block Be clear about HKDF's applicability for password storage Conflicts: docs/hazmat/primitives/rsa.rst
-rw-r--r--cryptography/hazmat/backends/commoncrypto/backend.py14
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py8
-rw-r--r--cryptography/hazmat/primitives/ciphers/algorithms.py15
-rw-r--r--cryptography/hazmat/primitives/padding.py6
-rw-r--r--docs/changelog.rst1
-rw-r--r--docs/development/custom-vectors/cast5.rst1
-rw-r--r--docs/hazmat/primitives/key-derivation-functions.rst4
-rw-r--r--docs/hazmat/primitives/rsa.rst22
-rw-r--r--docs/hazmat/primitives/symmetric-encryption.rst13
-rw-r--r--docs/installation.rst25
-rw-r--r--tests/hazmat/primitives/test_cast5.py92
-rw-r--r--tests/hazmat/primitives/test_ciphers.py15
12 files changed, 196 insertions, 20 deletions
diff --git a/cryptography/hazmat/backends/commoncrypto/backend.py b/cryptography/hazmat/backends/commoncrypto/backend.py
index e5d4ee00..5c08a356 100644
--- a/cryptography/hazmat/backends/commoncrypto/backend.py
+++ b/cryptography/hazmat/backends/commoncrypto/backend.py
@@ -25,7 +25,7 @@ from cryptography.hazmat.backends.interfaces import (
from cryptography.hazmat.bindings.commoncrypto.binding import Binding
from cryptography.hazmat.primitives import interfaces, constant_time
from cryptography.hazmat.primitives.ciphers.algorithms import (
- AES, Blowfish, TripleDES, ARC4
+ AES, Blowfish, TripleDES, ARC4, CAST5
)
from cryptography.hazmat.primitives.ciphers.modes import (
CBC, CTR, ECB, OFB, CFB, GCM
@@ -198,6 +198,18 @@ class Backend(object):
mode_cls,
mode_const
)
+ for mode_cls, mode_const in [
+ (CBC, self._lib.kCCModeCBC),
+ (ECB, self._lib.kCCModeECB),
+ (CFB, self._lib.kCCModeCFB),
+ (OFB, self._lib.kCCModeOFB)
+ ]:
+ self._register_cipher_adapter(
+ CAST5,
+ self._lib.kCCAlgorithmCAST,
+ mode_cls,
+ mode_const
+ )
self._register_cipher_adapter(
ARC4,
self._lib.kCCAlgorithmRC4,
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index ce37e5c8..8a4aeac5 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -26,7 +26,7 @@ from cryptography.hazmat.bindings.openssl.binding import Binding
from cryptography.hazmat.primitives import interfaces, hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.ciphers.algorithms import (
- AES, Blowfish, Camellia, TripleDES, ARC4,
+ AES, Blowfish, Camellia, TripleDES, ARC4, CAST5
)
from cryptography.hazmat.primitives.ciphers.modes import (
CBC, CTR, ECB, OFB, CFB, GCM,
@@ -153,6 +153,12 @@ class Backend(object):
mode_cls,
GetCipherByName("bf-{mode.name}")
)
+ for mode_cls in [CBC, CFB, OFB, ECB]:
+ self.register_cipher_adapter(
+ CAST5,
+ mode_cls,
+ GetCipherByName("cast5-{mode.name}")
+ )
self.register_cipher_adapter(
ARC4,
type(None),
diff --git a/cryptography/hazmat/primitives/ciphers/algorithms.py b/cryptography/hazmat/primitives/ciphers/algorithms.py
index 19cf1920..a5cfce92 100644
--- a/cryptography/hazmat/primitives/ciphers/algorithms.py
+++ b/cryptography/hazmat/primitives/ciphers/algorithms.py
@@ -90,6 +90,21 @@ class Blowfish(object):
return len(self.key) * 8
+@utils.register_interface(interfaces.BlockCipherAlgorithm)
+@utils.register_interface(interfaces.CipherAlgorithm)
+class CAST5(object):
+ name = "CAST5"
+ block_size = 64
+ key_sizes = frozenset(range(40, 129, 8))
+
+ def __init__(self, key):
+ self.key = _verify_key_size(self, key)
+
+ @property
+ def key_size(self):
+ return len(self.key) * 8
+
+
@utils.register_interface(interfaces.CipherAlgorithm)
class ARC4(object):
name = "RC4"
diff --git a/cryptography/hazmat/primitives/padding.py b/cryptography/hazmat/primitives/padding.py
index ddb2c63c..1717262c 100644
--- a/cryptography/hazmat/primitives/padding.py
+++ b/cryptography/hazmat/primitives/padding.py
@@ -86,8 +86,7 @@ class PKCS7(object):
class _PKCS7PaddingContext(object):
def __init__(self, block_size):
self.block_size = block_size
- # TODO: O(n ** 2) complexity for repeated concatentation, we should use
- # zero-buffer (#193)
+ # TODO: more copies than necessary, we should use zero-buffer (#193)
self._buffer = b""
def update(self, data):
@@ -120,8 +119,7 @@ class _PKCS7PaddingContext(object):
class _PKCS7UnpaddingContext(object):
def __init__(self, block_size):
self.block_size = block_size
- # TODO: O(n ** 2) complexity for repeated concatentation, we should use
- # zero-buffer (#193)
+ # TODO: more copies than necessary, we should use zero-buffer (#193)
self._buffer = b""
def update(self, data):
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 4d459bd9..cd289b6e 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -18,6 +18,7 @@ Changelog
* Added :class:`~cryptography.hazmat.primitives.kdf.hkdf.HKDF`.
* Added :doc:`/hazmat/backends/multibackend`.
* Set default random for the :doc:`/hazmat/backends/openssl` to the OS random engine.
+* Added :class:`~cryptography.hazmat.primitives.ciphers.algorithms.CAST5` (CAST-128) support.
0.1 - 2014-01-08
~~~~~~~~~~~~~~~~
diff --git a/docs/development/custom-vectors/cast5.rst b/docs/development/custom-vectors/cast5.rst
index 7f1d72c1..09b3bdb1 100644
--- a/docs/development/custom-vectors/cast5.rst
+++ b/docs/development/custom-vectors/cast5.rst
@@ -23,5 +23,6 @@ Verification
The following go code was used to verify the vectors.
.. literalinclude:: /development/custom-vectors/cast5/verify_cast5.go
+ :language: go
Download link: :download:`verify_cast5.go </development/custom-vectors/cast5/verify_cast5.go>`
diff --git a/docs/hazmat/primitives/key-derivation-functions.rst b/docs/hazmat/primitives/key-derivation-functions.rst
index 1937c2ec..d8a0e241 100644
--- a/docs/hazmat/primitives/key-derivation-functions.rst
+++ b/docs/hazmat/primitives/key-derivation-functions.rst
@@ -129,6 +129,10 @@ Different KDFs are suitable for different tasks such as:
`HKDF`_ (HMAC-based Extract-and-Expand Key Derivation Function) is suitable
for deriving keys of a fixed size used for other cryptographic operations.
+ .. warning::
+
+ HKDF should not be used for password storage.
+
.. doctest::
>>> import os
diff --git a/docs/hazmat/primitives/rsa.rst b/docs/hazmat/primitives/rsa.rst
index 4925366a..e7ec4749 100644
--- a/docs/hazmat/primitives/rsa.rst
+++ b/docs/hazmat/primitives/rsa.rst
@@ -20,10 +20,10 @@ RSA
.. warning::
This method only checks a limited set of properties of its arguments.
- Using an RSA that you do not trust or with incorrect parameters may
- lead to insecure operation, crashes, and other undefined behavior. We
- recommend that you only ever load private keys that were generated with
- software you trust.
+ Using an RSA private key that you do not trust or with incorrect
+ parameters may lead to insecure operation, crashes, and other undefined
+ behavior. We recommend that you only ever load private keys that were
+ generated with software you trust.
This class conforms to the
@@ -32,9 +32,10 @@ RSA
:raises TypeError: This is raised when the arguments are not all integers.
- :raises ValueError: This is raised when the values of `p`, `q`,
- `private_exponent`, `public_exponent` or `modulus` do
- not match the bounds specified in `RFC 3447`_.
+ :raises ValueError: This is raised when the values of ``p``, ``q``,
+ ``private_exponent``, ``public_exponent``, or
+ ``modulus`` do not match the bounds specified in
+ :rfc:`3447`.
.. classmethod:: generate(public_exponent, key_size, backend)
@@ -68,12 +69,11 @@ RSA
:raises TypeError: This is raised when the arguments are not all integers.
- :raises ValueError: This is raised when the values of `public_exponent` or
- `modulus` do not match the bounds specified in
- `RFC 3447`_.
+ :raises ValueError: This is raised when the values of ``public_exponent``
+ or ``modulus`` do not match the bounds specified in
+ :rfc:`3447`.
.. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)
.. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography
-.. _`RFC 3447`: https://tools.ietf.org/html/rfc3447
.. _`use 65537`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html
.. _`at least 2048`: http://www.ecrypt.eu.org/documents/D.SPA.20.pdf
diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst
index 85d8e8e3..d91dde9d 100644
--- a/docs/hazmat/primitives/symmetric-encryption.rst
+++ b/docs/hazmat/primitives/symmetric-encryption.rst
@@ -99,7 +99,6 @@ Algorithms
:param bytes key: The secret key, either ``128``, ``192``, or ``256`` bits.
This must be kept secret.
-
.. class:: TripleDES(key)
Triple DES (Data Encryption Standard), sometimes referred to as 3DES, is a
@@ -116,6 +115,17 @@ Algorithms
``56`` bits long), they can simply be concatenated to
produce the full key. This must be kept secret.
+.. class:: CAST5(key)
+
+ .. versionadded:: 0.2
+
+ CAST5 (also known as CAST-128) is a block cipher approved for use in the
+ Canadian government by the `Communications Security Establishment`_. It is
+ a variable key length cipher and supports keys from 40-128 bits in length.
+
+ :param bytes key: The secret key, 40-128 bits in length (in increments of
+ 8). This must be kept secret.
+
Weak Ciphers
------------
@@ -469,3 +479,4 @@ Interfaces
.. _`described by Colin Percival`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html
.. _`recommends 96-bit IV length`: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
.. _`NIST SP-800-38D`: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+.. _`Communications Security Establishment`: http://www.cse-cst.gc.ca
diff --git a/docs/installation.rst b/docs/installation.rst
index 7e7348e2..f9c3574d 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -22,8 +22,31 @@ to include the corresponding locations. For example:
C:\> set INCLUDE=C:\OpenSSL-1.0.1f-64bit\include;%INCLUDE%
C:\> pip install cryptography
+Building cryptography on Linux
+------------------------------
+
+``cryptography`` should build very easily on Linux provided you have a C
+compiler, headers for Python (if you're not using ``pypy``), and headers for
+the OpenSSL and ``libffi`` libraries available on your system.
+
+Debian and Ubuntu systems
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For Debian and Ubuntu, the following command line will ensure the required
+dependencies are installed:
+
+.. code-block:: console
+
+ $ sudo apt-get install build-essential libssl-dev libffi-dev python-dev
+
+You should now be able to build and install cryptography with the usual
+
+.. code-block:: console
+
+ $ pip install cryptography
+
Using your own OpenSSL on Linux
--------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Python links to OpenSSL for its own purposes and this can sometimes cause
problems when you wish to use a different version of OpenSSL with cryptography.
diff --git a/tests/hazmat/primitives/test_cast5.py b/tests/hazmat/primitives/test_cast5.py
new file mode 100644
index 00000000..682b4496
--- /dev/null
+++ b/tests/hazmat/primitives/test_cast5.py
@@ -0,0 +1,92 @@
+# 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.
+
+from __future__ import absolute_import, division, print_function
+
+import binascii
+import os
+
+import pytest
+
+from cryptography.hazmat.primitives.ciphers import algorithms, modes
+
+from .utils import generate_encrypt_test
+from ...utils import load_nist_vectors
+
+
+@pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.CAST5("\x00" * 16), modes.ECB()
+ ),
+ skip_message="Does not support CAST5 ECB",
+)
+@pytest.mark.cipher
+class TestCAST5_ECB(object):
+ test_ECB = generate_encrypt_test(
+ load_nist_vectors,
+ os.path.join("ciphers", "CAST5"),
+ ["cast5-ecb.txt"],
+ lambda key, **kwargs: algorithms.CAST5(binascii.unhexlify((key))),
+ lambda **kwargs: modes.ECB(),
+ )
+
+
+@pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.CAST5("\x00" * 16), modes.CBC("\x00" * 8)
+ ),
+ skip_message="Does not support CAST5 CBC",
+)
+@pytest.mark.cipher
+class TestCAST5_CBC(object):
+ test_CBC = generate_encrypt_test(
+ load_nist_vectors,
+ os.path.join("ciphers", "CAST5"),
+ ["cast5-cbc.txt"],
+ lambda key, **kwargs: algorithms.CAST5(binascii.unhexlify((key))),
+ lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv))
+ )
+
+
+@pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.CAST5("\x00" * 16), modes.OFB("\x00" * 8)
+ ),
+ skip_message="Does not support CAST5 OFB",
+)
+@pytest.mark.cipher
+class TestCAST5_OFB(object):
+ test_OFB = generate_encrypt_test(
+ load_nist_vectors,
+ os.path.join("ciphers", "CAST5"),
+ ["cast5-ofb.txt"],
+ lambda key, **kwargs: algorithms.CAST5(binascii.unhexlify((key))),
+ lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv))
+ )
+
+
+@pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.CAST5("\x00" * 16), modes.CFB("\x00" * 8)
+ ),
+ skip_message="Does not support CAST5 CFB",
+)
+@pytest.mark.cipher
+class TestCAST5_CFB(object):
+ test_CFB = generate_encrypt_test(
+ load_nist_vectors,
+ os.path.join("ciphers", "CAST5"),
+ ["cast5-cfb.txt"],
+ lambda key, **kwargs: algorithms.CAST5(binascii.unhexlify((key))),
+ lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv))
+ )
diff --git a/tests/hazmat/primitives/test_ciphers.py b/tests/hazmat/primitives/test_ciphers.py
index 6a7b2f93..50cadf64 100644
--- a/tests/hazmat/primitives/test_ciphers.py
+++ b/tests/hazmat/primitives/test_ciphers.py
@@ -18,7 +18,7 @@ import binascii
import pytest
from cryptography.hazmat.primitives.ciphers.algorithms import (
- AES, Camellia, TripleDES, Blowfish, ARC4
+ AES, Camellia, TripleDES, Blowfish, ARC4, CAST5
)
@@ -80,6 +80,19 @@ class TestBlowfish(object):
Blowfish(binascii.unhexlify(b"0" * 6))
+class TestCAST5(object):
+ @pytest.mark.parametrize(("key", "keysize"), [
+ (b"0" * (keysize // 4), keysize) for keysize in range(40, 129, 8)
+ ])
+ def test_key_size(self, key, keysize):
+ cipher = CAST5(binascii.unhexlify(key))
+ assert cipher.key_size == keysize
+
+ def test_invalid_key_size(self):
+ with pytest.raises(ValueError):
+ CAST5(binascii.unhexlify(b"0" * 34))
+
+
class TestARC4(object):
@pytest.mark.parametrize(("key", "keysize"), [
(b"0" * 10, 40),