aboutsummaryrefslogtreecommitdiffstats
path: root/docs/hazmat/primitives
diff options
context:
space:
mode:
Diffstat (limited to 'docs/hazmat/primitives')
-rw-r--r--docs/hazmat/primitives/asymmetric/dsa.rst101
-rw-r--r--docs/hazmat/primitives/asymmetric/ec.rst51
-rw-r--r--docs/hazmat/primitives/asymmetric/index.rst2
-rw-r--r--docs/hazmat/primitives/asymmetric/rsa.rst100
-rw-r--r--docs/hazmat/primitives/asymmetric/serialization.rst100
-rw-r--r--docs/hazmat/primitives/constant-time.rst2
-rw-r--r--docs/hazmat/primitives/cryptographic-hashes.rst1
-rw-r--r--docs/hazmat/primitives/interfaces.rst135
-rw-r--r--docs/hazmat/primitives/key-derivation-functions.rst107
-rw-r--r--docs/hazmat/primitives/mac/cmac.rst13
-rw-r--r--docs/hazmat/primitives/mac/hmac.rst7
-rw-r--r--docs/hazmat/primitives/mac/index.rst8
-rw-r--r--docs/hazmat/primitives/padding.rst1
-rw-r--r--docs/hazmat/primitives/symmetric-encryption.rst23
14 files changed, 596 insertions, 55 deletions
diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst
index 2819bbdb..6848d84c 100644
--- a/docs/hazmat/primitives/asymmetric/dsa.rst
+++ b/docs/hazmat/primitives/asymmetric/dsa.rst
@@ -38,11 +38,11 @@ DSA
Generate a new ``DSAParameters`` instance using ``backend``.
:param int key_size: The length of the modulus in bits. It should be
- either "1024, 2048 or 3072". For keys generated in 2014 this should
- be `at least 2048`_ (See page 41).
- Note that some applications (such as SSH) have not yet gained support
- for larger key sizes specified in FIPS 186-3 and are still restricted
- to only the 1024-bit keys specified in FIPS 186-2.
+ either 1024, 2048 or 3072. For keys generated in 2014 this should
+ be `at least 2048`_ (See page 41). Note that some applications
+ (such as SSH) have not yet gained support for larger key sizes
+ specified in FIPS 186-3 and are still restricted to only the
+ 1024-bit keys specified in FIPS 186-2.
:return: A new instance of ``DSAParameters``
@@ -97,6 +97,48 @@ DSA
or if the OpenSSL version is older than 1.0.0 and the key size is larger than 1024
because older OpenSSL versions don't support a key size larger than 1024.
+ .. method:: signer(algorithm, backend)
+
+ .. versionadded:: 0.4
+
+ Sign data which can be verified later by others using the public key.
+
+ .. doctest::
+
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> from cryptography.hazmat.primitives.asymmetric import dsa
+ >>> parameters = dsa.DSAParameters.generate(
+ ... key_size=1024,
+ ... backend=default_backend()
+ ... )
+ >>> private_key = dsa.DSAPrivateKey.generate(
+ ... parameters=parameters,
+ ... backend=default_backend()
+ ... )
+ >>> signer = private_key.signer(
+ ... hashes.SHA256(),
+ ... default_backend()
+ ... )
+ >>> data = b"this is some data I'd like to sign"
+ >>> signer.update(data)
+ >>> signature = signer.finalize()
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.RSABackend`
+ provider.
+
+ :returns:
+ :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricSignatureContext`
+
+ :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if
+ the provided ``backend`` does not implement
+ :class:`~cryptography.hazmat.backends.interfaces.DSABackend`
+
.. class:: DSAPublicKey(modulus, subgroup_order, generator, y)
@@ -118,6 +160,55 @@ DSA
``subgroup_order``, ``generator``, or ``y``
do not match the bounds specified in `FIPS 186-4`_.
+ .. method:: verifier(signature, algorithm, backend)
+
+ .. versionadded:: 0.4
+
+ Verify data was signed by the private key associated with this public
+ key.
+
+ .. doctest::
+
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> from cryptography.hazmat.primitives.asymmetric import dsa
+ >>> parameters = dsa.DSAParameters.generate(
+ ... key_size=1024,
+ ... backend=default_backend()
+ ... )
+ >>> private_key = dsa.DSAPrivateKey.generate(
+ ... parameters=parameters,
+ ... backend=default_backend()
+ ... )
+ >>> signer = private_key.signer(
+ ... hashes.SHA256(),
+ ... default_backend()
+ ... )
+ >>> data = b"this is some data I'd like to sign"
+ >>> signer.update(data)
+ >>> signature = signer.finalize()
+ >>> public_key = private_key.public_key()
+ >>> verifier = public_key.verifier(
+ ... signature,
+ ... hashes.SHA256(),
+ ... default_backend()
+ ... )
+ >>> verifier.update(data)
+ >>> verifier.verify()
+
+ :param bytes signature: The signature to verify. DER encoded as
+ specified in :rfc:`6979`.
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.DSABackend`
+ provider.
+
+ :returns:
+ :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricVerificationContext`
.. _`DSA`: https://en.wikipedia.org/wiki/Digital_Signature_Algorithm
.. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography
diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst
new file mode 100644
index 00000000..f88b965a
--- /dev/null
+++ b/docs/hazmat/primitives/asymmetric/ec.rst
@@ -0,0 +1,51 @@
+.. hazmat::
+
+Elliptic Curve
+==============
+
+.. currentmodule:: cryptography.hazmat.primitives.asymmetric.ec
+
+
+.. class:: EllipticCurvePrivateNumbers(private_value, public_numbers)
+
+ .. versionadded:: 0.5
+
+ The collection of integers that make up an EC private key.
+
+ .. attribute:: public_numbers
+
+ :type: :class:`~cryptography.hazmat.primitives.ec.EllipticCurvePublicNumbers`
+
+ The :class:`EllipticCurvePublicNumbers` which makes up the EC public
+ key associated with this EC private key.
+
+ .. attribute:: private_value
+
+ :type: int
+
+ The private value.
+
+
+.. class:: EllipticCurvePublicNumbers(x, y, curve)
+
+ .. versionadded:: 0.5
+
+ The collection of integers that make up an EC public key.
+
+ .. attribute:: curve
+
+ :type: :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurve`
+
+ The elliptic curve for this key.
+
+ .. attribute:: x
+
+ :type: int
+
+ The affine x component of the public point used for verifying.
+
+ .. attribute:: y
+
+ :type: int
+
+ The affine y component of the public point used for verifying.
diff --git a/docs/hazmat/primitives/asymmetric/index.rst b/docs/hazmat/primitives/asymmetric/index.rst
index ca048d11..6a5228ba 100644
--- a/docs/hazmat/primitives/asymmetric/index.rst
+++ b/docs/hazmat/primitives/asymmetric/index.rst
@@ -7,5 +7,7 @@ Asymmetric algorithms
:maxdepth: 1
dsa
+ ec
rsa
padding
+ serialization
diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst
index 8c34497e..54839119 100644
--- a/docs/hazmat/primitives/asymmetric/rsa.rst
+++ b/docs/hazmat/primitives/asymmetric/rsa.rst
@@ -85,7 +85,10 @@ RSA
:param padding: An instance of a
:class:`~cryptography.hazmat.primitives.interfaces.AsymmetricPadding`
- provider.
+ provider. Valid values are
+ :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` and
+ :class:`~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15`
+ (``PSS`` is recommended for all new applications).
:param algorithm: An instance of a
:class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
@@ -154,21 +157,39 @@ RSA
:class:`~cryptography.hazmat.primitives.asymmetric.padding.OAEP`
it may also be raised for invalid label values.
- .. code-block:: python
+ .. doctest::
- from cryptography.hazmat.backends import default_backend
- from cryptography.hazmat.primitives import hashes
- from cryptography.hazmat.primitives.asymmetric import padding
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> from cryptography.hazmat.primitives.asymmetric import padding
- plaintext = private_key.decrypt(
- ciphertext,
- padding.OAEP(
- mgf=padding.MGF1(algorithm=hashes.SHA1()),
- algorithm=hashes.SHA1(),
- label=None
- ),
- default_backend()
- )
+ >>> # Generate a key
+ >>> private_key = rsa.RSAPrivateKey.generate(
+ ... public_exponent=65537,
+ ... key_size=2048,
+ ... backend=default_backend()
+ ... )
+ >>> public_key = private_key.public_key()
+ >>> # encrypt some data
+ >>> ciphertext = public_key.encrypt(
+ ... b"encrypted data",
+ ... padding.OAEP(
+ ... mgf=padding.MGF1(algorithm=hashes.SHA1()),
+ ... algorithm=hashes.SHA1(),
+ ... label=None
+ ... ),
+ ... default_backend()
+ ... )
+ >>> # Now do the actual decryption
+ >>> plaintext = private_key.decrypt(
+ ... ciphertext,
+ ... padding.OAEP(
+ ... mgf=padding.MGF1(algorithm=hashes.SHA1()),
+ ... algorithm=hashes.SHA1(),
+ ... label=None
+ ... ),
+ ... default_backend()
+ ... )
.. class:: RSAPublicKey(public_exponent, modulus)
@@ -216,7 +237,7 @@ RSA
... hashes.SHA256(),
... default_backend()
... )
- >>> data= b"this is some data I'd like to sign"
+ >>> data = b"this is some data I'd like to sign"
>>> signer.update(data)
>>> signature = signer.finalize()
>>> public_key = private_key.public_key()
@@ -236,7 +257,10 @@ RSA
:param padding: An instance of a
:class:`~cryptography.hazmat.primitives.interfaces.AsymmetricPadding`
- provider.
+ provider. Valid values are
+ :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` and
+ :class:`~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15`
+ (``PSS`` is recommended for all new applications).
:param algorithm: An instance of a
:class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
@@ -306,27 +330,29 @@ RSA
:class:`~cryptography.hazmat.primitives.asymmetric.padding.OAEP`
it may also be raised for invalid label values.
- .. code-block:: python
-
- from cryptography.hazmat.backends import default_backend
- from cryptography.hazmat.primitives import hashes
- from cryptography.hazmat.primitives.asymmetric import padding, rsa
-
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=2048,
- backend=default_backend()
- )
- public_key = private_key.public_key()
- ciphertext = public_key.encrypt(
- plaintext,
- padding.OAEP(
- mgf=padding.MGF1(algorithm=hashes.SHA1()),
- algorithm=hashes.SHA1(),
- label=None
- ),
- default_backend()
- )
+ .. doctest::
+
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> from cryptography.hazmat.primitives.asymmetric import padding
+
+ >>> # Generate a key
+ >>> private_key = rsa.RSAPrivateKey.generate(
+ ... public_exponent=65537,
+ ... key_size=2048,
+ ... backend=default_backend()
+ ... )
+ >>> public_key = private_key.public_key()
+ >>> # encrypt some data
+ >>> ciphertext = public_key.encrypt(
+ ... b"encrypted data",
+ ... padding.OAEP(
+ ... mgf=padding.MGF1(algorithm=hashes.SHA1()),
+ ... algorithm=hashes.SHA1(),
+ ... label=None
+ ... ),
+ ... default_backend()
+ ... )
.. class:: RSAPublicNumbers(e, n)
diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst
new file mode 100644
index 00000000..2b3eb511
--- /dev/null
+++ b/docs/hazmat/primitives/asymmetric/serialization.rst
@@ -0,0 +1,100 @@
+.. hazmat::
+
+Key Serialization
+=================
+
+.. currentmodule:: cryptography.hazmat.primitives.serialization
+
+There are several common schemes for serializing asymmetric private and public
+keys to bytes. They generally support encryption of private keys and additional
+key metadata.
+
+Many serialization formats support multiple different types of asymmetric keys
+and will return an an instance of the appropriate type. You should check that
+the returned key matches the type your application expects when using these
+methods.
+
+ .. code-block:: pycon
+
+ >>> key = load_pkcs8_private_key(pem_data, None, backend)
+ >>> if isinstance(key, rsa.RSAPrivateKey):
+ >>> signature = sign_with_rsa_key(key, message)
+ >>> elif isinstance(key, dsa.DSAPrivateKey):
+ >>> signature = sign_with_dsa_key(key, message)
+ >>> else:
+ >>> raise TypeError
+
+
+PKCS #8 Format
+~~~~~~~~~~~~~~
+
+PKCS #8 is a serialization format originally standardized by RSA and
+currently maintained by the IETF in :rfc:`5208`. It supports password based
+encryption and additional key metadata attributes.
+
+
+.. function:: load_pkcs8_private_key(data, password, backend)
+
+ .. versionadded:: 0.5
+
+ Deserialize a private key from PEM encoded data to one of the supported
+ asymmetric private key types.
+
+ :param bytes data: The PEM encoded key data.
+
+ :param bytes password: The password to use to decrypt the data. Should
+ be ``None`` if the private key is not encrypted.
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.PKCS8SerializationBackend`
+ provider.
+
+ :returns: A new instance of a private key.
+
+ :raises ValueError: If the PEM data could not be decrypted or if its
+ structure could not be decoded successfully.
+
+ :raises TypeError: If a ``password`` was given and the private key was
+ not encrypted. Or if the key was encrypted but no
+ password was supplied.
+
+ :raises UnsupportedAlgorithm: If the serialized key is of a type that
+ is not supported by the backend or if the key is encrypted with a
+ symmetric cipher that is not supported by the backend.
+
+
+Traditional OpenSSL Format
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The "traditional" PKCS #1 based serialization format used by OpenSSL.
+It supports password based symmetric key encryption. Commonly found in
+OpenSSL based TLS applications. It is usually found in PEM format with a
+header that mentions the type of the serialized key. e.g.
+``-----BEGIN RSA PRIVATE KEY-----``.
+
+.. function:: load_pem_traditional_openssl_private_key(data, password, backend)
+
+ .. versionadded:: 0.5
+
+ Deserialize a private key from PEM encoded data to one of the supported
+ asymmetric private key types.
+
+ :param bytes data: The PEM encoded key data.
+
+ :param bytes password: The password to use to decrypt the data. Should
+ be ``None`` if the private key is not encrypted.
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.TraditionalOpenSSLSerializationBackend`
+ provider.
+
+ :returns: A new instance of a private key.
+
+ :raises ValueError: If the PEM data could not be decrypted or if its
+ structure could not be decoded successfully.
+
+ :raises TypeError: If a ``password`` was given and the private key was
+ not encrypted. Or if the key was encrypted but no
+ password was supplied.
+
+ :raises UnsupportedAlgorithm: If the serialized key is of a type that
+ is not supported by the backend or if the key is encrypted with a
+ symmetric cipher that is not supported by the backend.
diff --git a/docs/hazmat/primitives/constant-time.rst b/docs/hazmat/primitives/constant-time.rst
index c6fcb3a3..1394b6b3 100644
--- a/docs/hazmat/primitives/constant-time.rst
+++ b/docs/hazmat/primitives/constant-time.rst
@@ -36,6 +36,8 @@ about the timing attacks on KeyCzar and Java's ``MessageDigest.isEqual()``.
:param bytes b: The right-hand side.
:returns bool: ``True`` if ``a`` has the same bytes as ``b``, otherwise
``False``.
+ :raises TypeError: This exception is raised if ``a`` or ``b`` is not
+ ``bytes``.
.. _`Coda Hale's blog post`: http://codahale.com/a-lesson-in-timing-attacks/
diff --git a/docs/hazmat/primitives/cryptographic-hashes.rst b/docs/hazmat/primitives/cryptographic-hashes.rst
index 773d97f6..7e5295c4 100644
--- a/docs/hazmat/primitives/cryptographic-hashes.rst
+++ b/docs/hazmat/primitives/cryptographic-hashes.rst
@@ -54,6 +54,7 @@ Message digests
:param bytes data: The bytes to be hashed.
:raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`.
+ :raises TypeError: This exception is raised if ``data`` is not ``bytes``.
.. method:: copy()
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
index c76582c0..b2857f58 100644
--- a/docs/hazmat/primitives/interfaces.rst
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -381,6 +381,23 @@ Asymmetric interfaces
The DSAParameters object associated with this private key.
+ .. method:: signer(algorithm, backend)
+
+ .. versionadded:: 0.4
+
+ Sign data which can be verified later by others using the public key.
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.DSABackend`
+ provider.
+
+ :returns:
+ :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricSignatureContext`
+
.. attribute:: key_size
:type: int
@@ -412,17 +429,129 @@ Asymmetric interfaces
The bit length of the modulus.
+ .. attribute:: y
+
+ :type: int
+
+ The public key.
+
.. method:: parameters()
:return: :class:`~cryptography.hazmat.primitives.interfaces.DSAParameters`
The DSAParameters object associated with this public key.
- .. attribute:: y
+ .. method:: verifier(signature, algorithm, backend)
+
+ .. versionadded:: 0.4
+
+ Verify data was signed by the private key associated with this public
+ key.
+
+ :param bytes signature: The signature to verify. DER encoded as
+ specified in :rfc:`6979`.
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.DSABackend`
+ provider.
+
+ :returns:
+ :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricVerificationContext`
+
+
+.. class:: EllipticCurve
+
+ .. versionadded:: 0.5
+
+ A named elliptic curve.
+
+ .. attribute:: name
+
+ :type: string
+
+ The name of the curve. Usually the name used for the ASN.1 OID such as
+ ``secp256k1``.
+
+ .. attribute:: key_size
:type: int
- The public key.
+ The bit length of the curve's base point.
+
+
+.. class:: EllipticCurveSignatureAlgorithm
+
+ .. versionadded:: 0.5
+
+ A signature algorithm for use with elliptic curve keys.
+
+ .. attribute:: algorithm
+
+ :type: :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+
+ The digest algorithm to be used with the signature scheme.
+
+
+.. class:: EllipticCurvePrivateKey
+
+ .. versionadded:: 0.5
+
+ An elliptic curve private key for use with an algorithm such as `ECDSA`_ or
+ `EdDSA`_.
+
+ .. classmethod:: signer(signature_algorithm)
+
+ Sign data which can be verified later by others using the public key.
+
+ :param signature_algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurveSignatureAlgorithm`
+ provider.
+
+ :returns:
+ :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricSignatureContext`
+
+ .. attribute:: curve
+
+ :type: :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurve`
+
+ The elliptic curve for this key.
+
+ .. method:: public_key()
+
+ :return: :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurvePublicKey`
+
+ The EllipticCurvePublicKey object for this private key.
+
+
+.. class:: EllipticCurvePublicKey
+
+ .. versionadded:: 0.5
+
+ An elliptic curve public key.
+
+ .. classmethod:: verifier(signer, signature_algorithm)
+
+ Verify data was signed by the private key associated with this public
+ key.
+
+ :param bytes signature: The signature to verify.
+
+ :param signature_algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurveSignatureAlgorithm`
+ provider.
+
+ :returns:
+ :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricSignatureContext`
+
+ .. attribute:: curve
+
+ :type: :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurve`
+
+ The elliptic curve for this key.
.. class:: AsymmetricSignatureContext
@@ -574,3 +703,5 @@ Key derivation functions
.. _`Chinese remainder theorem`: https://en.wikipedia.org/wiki/Chinese_remainder_theorem
.. _`DSA`: https://en.wikipedia.org/wiki/Digital_Signature_Algorithm
.. _`CMAC`: https://en.wikipedia.org/wiki/CMAC
+.. _`ECDSA`: http://en.wikipedia.org/wiki/ECDSA
+.. _`EdDSA`: http://en.wikipedia.org/wiki/EdDSA
diff --git a/docs/hazmat/primitives/key-derivation-functions.rst b/docs/hazmat/primitives/key-derivation-functions.rst
index 269f949d..f68b12c1 100644
--- a/docs/hazmat/primitives/key-derivation-functions.rst
+++ b/docs/hazmat/primitives/key-derivation-functions.rst
@@ -88,6 +88,8 @@ Different KDFs are suitable for different tasks such as:
provided ``backend`` does not implement
:class:`~cryptography.hazmat.backends.interfaces.PBKDF2HMACBackend`
+ :raises TypeError: This exception is raised if ``salt`` is not ``bytes``.
+
.. method:: derive(key_material)
:param bytes key_material: The input key material. For PBKDF2 this
@@ -99,6 +101,9 @@ Different KDFs are suitable for different tasks such as:
called more than
once.
+ :raises TypeError: This exception is raised if ``key_material`` is not
+ ``bytes``.
+
This generates and returns a new key from the supplied password.
.. method:: verify(key_material, expected_key)
@@ -191,10 +196,108 @@ Different KDFs are suitable for different tasks such as:
provided ``backend`` does not implement
:class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
+ :raises TypeError: This exception is raised if ``salt`` or ``info`` is not
+ ``bytes``.
+
+ .. method:: derive(key_material)
+
+ :param bytes key_material: The input key material.
+ :return bytes: The derived key.
+ :raises TypeError: This exception is raised if ``key_material`` is not
+ ``bytes``.
+
+ Derives a new key from the input key material by performing both the
+ extract and expand operations.
+
+ .. method:: verify(key_material, expected_key)
+
+ :param key_material bytes: The input key material. This is the same as
+ ``key_material`` in :meth:`derive`.
+ :param expected_key bytes: The expected result of deriving a new key,
+ this is the same as the return value of
+ :meth:`derive`.
+ :raises cryptography.exceptions.InvalidKey: This is raised when the
+ derived key does not match
+ the expected key.
+ :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+ :meth:`derive` or
+ :meth:`verify` is
+ called more than
+ once.
+
+ This checks whether deriving a new key from the supplied
+ ``key_material`` generates the same key as the ``expected_key``, and
+ raises an exception if they do not match.
+
+
+.. class:: HKDFExpand(algorithm, length, info, backend)
+
+ .. versionadded:: 0.5
+
+ HKDF consists of two stages, extract and expand. This class exposes an
+ expand only version of HKDF that is suitable when the key material is
+ already cryptographically strong.
+
+ .. warning::
+
+ HKDFExpand should only be used if the key material is
+ cryptographically strong. You should use
+ :class:`~cryptography.hazmat.primitives.kdf.hkdf.HKDF` if
+ you are unsure.
+
+ .. doctest::
+
+ >>> import os
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> from cryptography.hazmat.primitives.kdf.hkdf import HKDFExpand
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> backend = default_backend()
+ >>> info = b"hkdf-example"
+ >>> key_material = os.urandom(16)
+ >>> hkdf = HKDFExpand(
+ ... algorithm=hashes.SHA256(),
+ ... length=32,
+ ... info=info,
+ ... backend=backend
+ ... )
+ >>> key = hkdf.derive(key_material)
+ >>> hkdf = HKDFExpand(
+ ... algorithm=hashes.SHA256(),
+ ... length=32,
+ ... info=info,
+ ... backend=backend
+ ... )
+ >>> hkdf.verify(key_material, key)
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+
+ :param int length: The desired length of the derived key. Maximum is
+ ``255 * (algorithm.digest_size // 8)``.
+
+ :param bytes info: Application specific context information. If ``None``
+ is explicitly passed an empty byte string will be used.
+
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
+ provider.
+
+ :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the
+ provided ``backend`` does not implement
+ :class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
+ :raises TypeError: This is raised if the provided ``info`` is a unicode object
+ :raises TypeError: This exception is raised if ``info`` is not ``bytes``.
+
.. method:: derive(key_material)
:param bytes key_material: The input key material.
- :retunr bytes: The derived key.
+ :return bytes: The derived key.
+
+ :raises TypeError: This is raised if the provided ``key_material`` is
+ a unicode object
+ :raises TypeError: This exception is raised if ``key_material`` is not
+ ``bytes``.
Derives a new key from the input key material by performing both the
extract and expand operations.
@@ -214,6 +317,8 @@ Different KDFs are suitable for different tasks such as:
:meth:`verify` is
called more than
once.
+ :raises TypeError: This is raised if the provided ``key_material`` is
+ a unicode object
This checks whether deriving a new key from the supplied
``key_material`` generates the same key as the ``expected_key``, and
diff --git a/docs/hazmat/primitives/mac/cmac.rst b/docs/hazmat/primitives/mac/cmac.rst
index a6b048b5..498b8b1e 100644
--- a/docs/hazmat/primitives/mac/cmac.rst
+++ b/docs/hazmat/primitives/mac/cmac.rst
@@ -10,8 +10,8 @@ Cipher-based message authentication code
import binascii
key = binascii.unhexlify(b"0" * 32)
-`Cipher-based message authentication codes`_ (or CMACs) are a tool for calculating
-message authentication codes using a block cipher coupled with a
+`Cipher-based message authentication codes`_ (or CMACs) are a tool for
+calculating message authentication codes using a block cipher coupled with a
secret key. You can use an CMAC to verify both the integrity and authenticity
of a message.
@@ -38,9 +38,9 @@ A subset of CMAC with the AES-128 algorithm is described in :rfc:`4493`.
:class:`~cryptography.exceptions.UnsupportedAlgorithm` exception will be
raised.
- If the `algorithm`` isn't a
- :class:`~cryptography.primitives.interfaces.BlockCipherAlgorithm` provider,
- ``TypeError`` will be raised.
+ If ``algorithm`` isn't a
+ :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm`
+ provider then ``TypeError`` will be raised.
To check that a given signature is correct use the :meth:`verify` method.
You will receive an exception if the signature is wrong:
@@ -68,6 +68,7 @@ A subset of CMAC with the AES-128 algorithm is described in :rfc:`4493`.
:param bytes data: The bytes to hash and authenticate.
:raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
+ :raises TypeError: This exception is raised if ``data`` is not ``bytes``.
.. method:: copy()
@@ -89,6 +90,8 @@ A subset of CMAC with the AES-128 algorithm is described in :rfc:`4493`.
:raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
:raises cryptography.exceptions.InvalidSignature: If signature does not
match digest
+ :raises TypeError: This exception is raised if ``signature`` is not
+ ``bytes``.
.. method:: finalize()
diff --git a/docs/hazmat/primitives/mac/hmac.rst b/docs/hazmat/primitives/mac/hmac.rst
index 11b10735..d56927b9 100644
--- a/docs/hazmat/primitives/mac/hmac.rst
+++ b/docs/hazmat/primitives/mac/hmac.rst
@@ -38,6 +38,10 @@ of a message.
:class:`~cryptography.exceptions.UnsupportedAlgorithm` exception will be
raised.
+ If ``algorithm`` isn't a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm` provider
+ then ``TypeError`` will be raised.
+
To check that a given signature is correct use the :meth:`verify` method.
You will receive an exception if the signature is wrong:
@@ -65,6 +69,7 @@ of a message.
:param bytes msg: The bytes to hash and authenticate.
:raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
+ :raises TypeError: This exception is raised if ``msg`` is not ``bytes``.
.. method:: copy()
@@ -86,6 +91,8 @@ of a message.
:raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
:raises cryptography.exceptions.InvalidSignature: If signature does not
match digest
+ :raises TypeError: This exception is raised if ``signature`` is not
+ ``bytes``.
.. method:: finalize()
diff --git a/docs/hazmat/primitives/mac/index.rst b/docs/hazmat/primitives/mac/index.rst
index 59fb8da2..acfe9bed 100644
--- a/docs/hazmat/primitives/mac/index.rst
+++ b/docs/hazmat/primitives/mac/index.rst
@@ -3,6 +3,14 @@
Message Authentication Codes
============================
+While cryptography supports both the CMAC and HMAC algorithms, we strongly
+recommend that HMAC should be used unless you have a good reason otherwise.
+
+For more information on why HMAC is preferred, see `Use cases for CMAC vs.
+HMAC?`_
+
+.. _`Use cases for CMAC vs. HMAC?`: http://crypto.stackexchange.com/questions/15721/use-cases-for-cmac-vs-hmac
+
.. toctree::
:maxdepth: 1
diff --git a/docs/hazmat/primitives/padding.rst b/docs/hazmat/primitives/padding.rst
index 4092ac00..0322f9d2 100644
--- a/docs/hazmat/primitives/padding.rst
+++ b/docs/hazmat/primitives/padding.rst
@@ -70,6 +70,7 @@ multiple of the block size.
:return bytes: Returns the data that was padded or unpadded.
:raises TypeError: Raised if data is not bytes.
:raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`.
+ :raises TypeError: This exception is raised if ``data`` is not ``bytes``.
.. method:: finalize()
diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst
index c98b3814..bca78354 100644
--- a/docs/hazmat/primitives/symmetric-encryption.rst
+++ b/docs/hazmat/primitives/symmetric-encryption.rst
@@ -20,9 +20,9 @@ provides secrecy but not authenticity. That means an attacker can't see the
message but an attacker can create bogus messages and force the application to
decrypt them.
-For this reason it is *strongly* recommended to combine encryption with a
-message authentication code, such as :doc:`HMAC </hazmat/primitives/mac/hmac>`, in
-an "encrypt-then-MAC" formulation as `described by Colin Percival`_.
+For this reason it is **strongly** recommended to combine encryption with a
+message authentication code, such as :doc:`HMAC </hazmat/primitives/mac/hmac>`,
+in an "encrypt-then-MAC" formulation as `described by Colin Percival`_.
.. class:: Cipher(algorithm, mode, backend)
@@ -134,8 +134,8 @@ Algorithms
.. versionadded:: 0.4
- SEED is a block cipher developed by the Korea Information Security Agency (
- KISA). It is defined in :rfc:`4269` and is used broadly throughout South
+ SEED is a block cipher developed by the Korea Information Security Agency
+ (KISA). It is defined in :rfc:`4269` and is used broadly throughout South
Korean industry, but rarely found elsewhere.
:param bytes key: The secret key. This must be kept secret. ``128`` bits in
@@ -275,6 +275,19 @@ Modes
Must be the same number of bytes as the ``block_size`` of the cipher.
Do not reuse an ``initialization_vector`` with a given ``key``.
+.. class:: CFB8(initialization_vector)
+
+ CFB (Cipher Feedback) is a mode of operation for block ciphers. It
+ transforms a block cipher into a stream cipher. The CFB8 variant uses an
+ 8-bit shift register.
+
+ **This mode does not require padding.**
+
+ :param bytes initialization_vector: Must be random bytes. They do not need
+ to be kept secret and they can be included in a transmitted message.
+ Must be the same number of bytes as the ``block_size`` of the cipher.
+ Do not reuse an ``initialization_vector`` with a given ``key``.
+
.. class:: GCM(initialization_vector, tag=None)
.. danger::