aboutsummaryrefslogtreecommitdiffstats
path: root/docs/hazmat/primitives
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2014-03-08 11:09:49 -0400
committerPaul Kehrer <paul.l.kehrer@gmail.com>2014-03-08 11:09:49 -0400
commitbf2a9d9545f39ad0dd9b9c9c4aa2f7f2b5669f0f (patch)
tree083cc465c6fabdb61ff69aadc33b31e8617f2136 /docs/hazmat/primitives
parentdee5c25d35c53885698bca42015c9f7bbfb27baa (diff)
parent78c2f2d2c0a40d20edcaf37c33e91224af3ecbb6 (diff)
downloadcryptography-bf2a9d9545f39ad0dd9b9c9c4aa2f7f2b5669f0f.tar.gz
cryptography-bf2a9d9545f39ad0dd9b9c9c4aa2f7f2b5669f0f.tar.bz2
cryptography-bf2a9d9545f39ad0dd9b9c9c4aa2f7f2b5669f0f.zip
Merge branch 'master' into idea-bespoke-vectors
* master: (246 commits) Fixed python3 incompatibility Removed dependency on setuptools for version check don't need to move these definitions conditional NIDs for 0.9.8e x509 changes for 0.9.8e support more changes for 0.9.8e support, this time in the ssl.h headers macro switches in evp for 0.9.8e bind some error constants conditionally for 0.9.8e support BIO macro switch for 0.9.8e support move some nids conditionally bind AES_wrap/unwrap for 0.9.8e support Add GPG key fingerprint for lvh change comparison to be easier to read ridiculous workaround time whoops Missing imports Convert stuff Add binding for DSA_new Fix drop in coverage levels by removing branches Added check to turn of CC backend for OS X version < 10.8 ... Conflicts: docs/development/test-vectors.rst
Diffstat (limited to 'docs/hazmat/primitives')
-rw-r--r--docs/hazmat/primitives/asymmetric/index.rst10
-rw-r--r--docs/hazmat/primitives/asymmetric/padding.rst20
-rw-r--r--docs/hazmat/primitives/asymmetric/rsa.rst160
-rw-r--r--docs/hazmat/primitives/cryptographic-hashes.rst2
-rw-r--r--docs/hazmat/primitives/hmac.rst2
-rw-r--r--docs/hazmat/primitives/index.rst3
-rw-r--r--docs/hazmat/primitives/interfaces.rst141
-rw-r--r--docs/hazmat/primitives/key-derivation-functions.rst2
-rw-r--r--docs/hazmat/primitives/rsa.rst79
-rw-r--r--docs/hazmat/primitives/symmetric-encryption.rst92
-rw-r--r--docs/hazmat/primitives/twofactor.rst162
11 files changed, 535 insertions, 138 deletions
diff --git a/docs/hazmat/primitives/asymmetric/index.rst b/docs/hazmat/primitives/asymmetric/index.rst
new file mode 100644
index 00000000..10319fad
--- /dev/null
+++ b/docs/hazmat/primitives/asymmetric/index.rst
@@ -0,0 +1,10 @@
+.. hazmat::
+
+Asymmetric Algorithms
+=====================
+
+.. toctree::
+ :maxdepth: 1
+
+ rsa
+ padding
diff --git a/docs/hazmat/primitives/asymmetric/padding.rst b/docs/hazmat/primitives/asymmetric/padding.rst
new file mode 100644
index 00000000..7aec3bd3
--- /dev/null
+++ b/docs/hazmat/primitives/asymmetric/padding.rst
@@ -0,0 +1,20 @@
+.. hazmat::
+
+Padding
+=======
+
+.. currentmodule:: cryptography.hazmat.primitives.asymmetric.padding
+
+.. warning::
+ `Padding is critical`_ when signing or encrypting data using RSA. Without
+ correct padding signatures can be forged, messages decrypted, and private
+ keys compromised.
+
+.. class:: PKCS1v15()
+
+ .. versionadded:: 0.3
+
+ PKCS1 v1.5 (also known as simply PKCS1) is a simple padding scheme
+ developed for use with RSA keys. It is defined in :rfc:`3447`.
+
+.. _`Padding is critical`: http://rdist.root.org/2009/10/06/why-rsa-encryption-padding-is-critical/
diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst
new file mode 100644
index 00000000..7943981e
--- /dev/null
+++ b/docs/hazmat/primitives/asymmetric/rsa.rst
@@ -0,0 +1,160 @@
+.. hazmat::
+
+RSA
+===
+
+.. currentmodule:: cryptography.hazmat.primitives.asymmetric.rsa
+
+`RSA`_ is a `public-key`_ algorithm for encrypting and signing messages.
+
+.. class:: RSAPrivateKey(p, q, private_exponent, dmp1, dmq1, iqmp, public_exponent, modulus)
+
+ .. versionadded:: 0.2
+
+ An RSA private key is required for decryption and signing of messages.
+
+ You should use :meth:`~generate` to generate new keys.
+
+ .. warning::
+ This method only checks a limited set of properties of its arguments.
+ 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
+ :class:`~cryptography.hazmat.primitives.interfaces.RSAPrivateKey`
+ interface.
+
+ :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`.
+
+ .. classmethod:: generate(public_exponent, key_size, backend)
+
+ Generate a new ``RSAPrivateKey`` instance using ``backend``.
+
+ :param int public_exponent: The public exponent of the new key.
+ Usually one of the small Fermat primes 3, 5, 17, 257, 65537. If in
+ doubt you should `use 65537`_.
+ :param int key_size: The length of the modulus in bits. For keys
+ generated in 2014 this should be `at least 2048`_. (See page 41.)
+ Must be at least 512. Some backends may have additional
+ limitations.
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.RSABackend`
+ provider.
+ :return: A new instance of ``RSAPrivateKey``.
+
+ .. method:: signer(padding, algorithm, backend)
+
+ .. versionadded:: 0.3
+
+ 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 rsa, padding
+ >>> private_key = rsa.RSAPrivateKey.generate(
+ ... public_exponent=65537,
+ ... key_size=2048,
+ ... backend=default_backend()
+ ... )
+ >>> signer = private_key.signer(
+ ... padding.PKCS1v15(),
+ ... hashes.SHA256(),
+ ... default_backend()
+ ... )
+ >>> signer.update(b"this is some data I'd like")
+ >>> signer.update(b" to sign")
+ >>> signature = signer.finalize()
+
+ :param padding: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricPadding`
+ provider.
+
+ :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`
+
+
+.. class:: RSAPublicKey(public_exponent, modulus)
+
+ .. versionadded:: 0.2
+
+ An RSA public key is required for encryption and verification of messages.
+
+ Normally you do not need to directly construct public keys because you'll
+ be loading them from a file, generating them automatically or receiving
+ them from a 3rd party.
+
+ This class conforms to the
+ :class:`~cryptography.hazmat.primitives.interfaces.RSAPublicKey`
+ interface.
+
+ :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`.
+
+ .. method:: verifier(signature, padding, algorithm, backend)
+
+ .. versionadded:: 0.3
+
+ 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 rsa, padding
+ >>> private_key = rsa.RSAPrivateKey.generate(
+ ... public_exponent=65537,
+ ... key_size=2048,
+ ... backend=default_backend()
+ ... )
+ >>> signer = private_key.signer(padding.PKCS1v15(), 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, padding.PKCS1v15(), hashes.SHA256(), default_backend())
+ >>> verifier.update(data)
+ >>> verifier.verify()
+
+ :param bytes signature: The signature to verify.
+
+ :param padding: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricPadding`
+ provider.
+
+ :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.AsymmetricVerificationContext`
+
+.. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)
+.. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography
+.. _`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/cryptographic-hashes.rst b/docs/hazmat/primitives/cryptographic-hashes.rst
index 6c56acad..86b85852 100644
--- a/docs/hazmat/primitives/cryptographic-hashes.rst
+++ b/docs/hazmat/primitives/cryptographic-hashes.rst
@@ -29,7 +29,7 @@ Message Digests
'l\xa1=R\xcap\xc8\x83\xe0\xf0\xbb\x10\x1eBZ\x89\xe8bM\xe5\x1d\xb2\xd29%\x93\xafj\x84\x11\x80\x90'
If the backend doesn't support the requested ``algorithm`` an
- :class:`~cryptography.exceptions.UnsupportedAlgorithm` will be raised.
+ :class:`~cryptography.exceptions.UnsupportedHash` will be raised.
Keep in mind that attacks against cryptographic hashes only get stronger
with time, and that often algorithms that were once thought to be strong,
diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst
index 0118be78..1a2838f7 100644
--- a/docs/hazmat/primitives/hmac.rst
+++ b/docs/hazmat/primitives/hmac.rst
@@ -35,7 +35,7 @@ message.
'#F\xdaI\x8b"e\xc4\xf1\xbb\x9a\x8fc\xff\xf5\xdex.\xbc\xcd/+\x8a\x86\x1d\x84\'\xc3\xa6\x1d\xd8J'
If the backend doesn't support the requested ``algorithm`` an
- :class:`~cryptography.exceptions.UnsupportedAlgorithm` will be raised.
+ :class:`~cryptography.exceptions.UnsupportedHash` 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:
diff --git a/docs/hazmat/primitives/index.rst b/docs/hazmat/primitives/index.rst
index 38ed24c9..90deec8b 100644
--- a/docs/hazmat/primitives/index.rst
+++ b/docs/hazmat/primitives/index.rst
@@ -11,6 +11,7 @@ Primitives
symmetric-encryption
padding
key-derivation-functions
- rsa
+ asymmetric/index
constant-time
interfaces
+ twofactor
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
index df17e59d..cc2a3000 100644
--- a/docs/hazmat/primitives/interfaces.rst
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -231,6 +231,146 @@ Asymmetric Interfaces
The public exponent. Alias for :attr:`public_exponent`.
+.. class:: DSAParameters
+
+ .. versionadded:: 0.3
+
+ `DSA`_ parameters.
+
+ .. attribute:: modulus
+
+ :type: int
+
+ The prime modulus that is used in generating the DSA key pair and used
+ in the DSA signing and verification processes.
+
+ .. attribute:: subgroup_order
+
+ :type: int
+
+ The subgroup order that is used in generating the DSA key pair
+ by the generator and used in the DSA signing and verification
+ processes.
+
+ .. attribute:: generator
+
+ :type: int
+
+ The generator that is used in generating the DSA key pair and used
+ in the DSA signing and verification processes.
+
+ .. attribute:: p
+
+ :type: int
+
+ The prime modulus that is used in generating the DSA key pair and used
+ in the DSA signing and verification processes. Alias for :attr:`modulus`.
+
+ .. attribute:: q
+
+ :type: int
+
+ The subgroup order that is used in generating the DSA key pair
+ by the generator and used in the DSA signing and verification
+ processes. Alias for :attr:`subgroup_order`.
+
+ .. attribute:: g
+
+ :type: int
+
+ The generator that is used in generating the DSA key pair and used
+ in the DSA signing and verification processes. Alias for :attr:`generator`.
+
+
+.. class:: DSAPrivateKey
+
+ .. versionadded:: 0.3
+
+ A `DSA`_ private key.
+
+ .. method:: public_key()
+
+ :return: :class:`~cryptography.hazmat.primitives.interfaces.DSAPublicKey`
+
+ An DSA public key object corresponding to the values of the private key.
+
+ .. method:: parameters()
+
+ :return: :class:`~cryptography.hazmat.primitives.interfaces.DSAParameters`
+
+ The DSAParameters object associated with this private key.
+
+ .. attribute:: key_size
+
+ :type: int
+
+ The bit length of the modulus.
+
+ .. attribute:: x
+
+ :type: int
+
+ The private key.
+
+ .. attribute:: y
+
+ :type: int
+
+ The public key.
+
+
+.. class:: DSAPublicKey
+
+ .. versionadded:: 0.3
+
+ A `DSA`_ private key.
+
+ .. method:: parameters()
+
+ :return: :class:`~cryptography.hazmat.primitives.interfaces.DSAParameters`
+
+ The DSAParameters object associated with this public key.
+
+ .. attribute:: y
+
+ :type: int
+
+ The public key.
+
+
+.. class:: AsymmetricSignatureContext
+
+ .. versionadded:: 0.2
+
+ .. method:: update(data)
+
+ :param bytes data: The data you want to sign.
+
+ .. method:: finalize()
+
+ :return bytes signature: The signature.
+
+
+.. class:: AsymmetricVerificationContext
+
+ .. versionadded:: 0.2
+
+ .. method:: update(data)
+
+ :param bytes data: The data you wish to verify using the signature.
+
+ .. method:: verify()
+
+ :raises cryptography.exceptions.InvalidSignature: If the signature does
+ not validate.
+
+
+.. class:: AsymmetricPadding
+
+ .. versionadded:: 0.2
+
+ .. attribute:: name
+
Hash Algorithms
~~~~~~~~~~~~~~~
@@ -302,3 +442,4 @@ Key Derivation Functions
.. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)
.. _`Chinese remainder theorem`: https://en.wikipedia.org/wiki/Chinese_remainder_theorem
+.. _`DSA`: https://en.wikipedia.org/wiki/Digital_Signature_Algorithm
diff --git a/docs/hazmat/primitives/key-derivation-functions.rst b/docs/hazmat/primitives/key-derivation-functions.rst
index d8a0e241..851dbb0b 100644
--- a/docs/hazmat/primitives/key-derivation-functions.rst
+++ b/docs/hazmat/primitives/key-derivation-functions.rst
@@ -179,7 +179,7 @@ Different KDFs are suitable for different tasks such as:
:param bytes info: Application specific context information. If ``None``
is explicitly passed an empty byte string will be used.
- :params backend: A
+ :param backend: A
:class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
provider.
diff --git a/docs/hazmat/primitives/rsa.rst b/docs/hazmat/primitives/rsa.rst
deleted file mode 100644
index e7ec4749..00000000
--- a/docs/hazmat/primitives/rsa.rst
+++ /dev/null
@@ -1,79 +0,0 @@
-.. hazmat::
-
-RSA
-===
-
-.. currentmodule:: cryptography.hazmat.primitives.asymmetric.rsa
-
-`RSA`_ is a `public-key`_ algorithm for encrypting and signing messages.
-
-.. class:: RSAPrivateKey(p, q, private_exponent, dmp1, dmq1, iqmp,
- public_exponent, modulus)
-
- .. versionadded:: 0.2
-
- An RSA private key is required for decryption and signing of messages.
-
- You should use
- :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.generate`
- to generate new keys.
-
- .. warning::
- This method only checks a limited set of properties of its arguments.
- 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
- :class:`~cryptography.hazmat.primitives.interfaces.RSAPrivateKey`
- interface.
-
- :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`.
-
- .. classmethod:: generate(public_exponent, key_size, backend)
-
- Generate a new ``RSAPrivateKey`` instance using ``backend``.
-
- :param int public_exponent: The public exponent of the new key.
- Usually one of the small Fermat primes 3, 5, 17, 257, 65537. If in
- doubt you should `use 65537`_.
- :param int key_size: The length of the modulus in bits. For keys
- generated in 2014 this should be `at least 2048`_. (See page 41.)
- Must be at least 512. Some backends may have additional
- limitations.
- :param backend: A
- :class:`~cryptography.hazmat.backends.interfaces.RSABackend`
- provider.
- :return: A new instance of ``RSAPrivateKey``.
-
-.. class:: RSAPublicKey(public_exponent, modulus)
-
- .. versionadded:: 0.2
-
- An RSA public key is required for encryption and verification of messages.
-
- Normally you do not need to directly construct public keys because you'll
- be loading them from a file, generating them automatically or receiving
- them from a 3rd party.
-
- This class conforms to the
- :class:`~cryptography.hazmat.primitives.interfaces.RSAPublicKey`
- interface.
-
- :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`.
-
-.. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)
-.. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography
-.. _`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 d91dde9d..2bc25c50 100644
--- a/docs/hazmat/primitives/symmetric-encryption.rst
+++ b/docs/hazmat/primitives/symmetric-encryption.rst
@@ -61,7 +61,7 @@ an "encrypt-then-MAC" formulation as `described by Colin Percival`_.
provider.
If the backend doesn't support the requested combination of ``cipher``
- and ``mode`` an :class:`~cryptography.exceptions.UnsupportedAlgorithm`
+ and ``mode`` an :class:`~cryptography.exceptions.UnsupportedCipher`
will be raised.
.. method:: decryptor()
@@ -71,7 +71,7 @@ an "encrypt-then-MAC" formulation as `described by Colin Percival`_.
provider.
If the backend doesn't support the requested combination of ``cipher``
- and ``mode`` an :class:`cryptography.exceptions.UnsupportedAlgorithm`
+ and ``mode`` an :class:`cryptography.exceptions.UnsupportedCipher`
will be raised.
.. _symmetric-encryption-algorithms:
@@ -88,7 +88,7 @@ Algorithms
choice for encryption.
:param bytes key: The secret key, either ``128``, ``192``, or ``256`` bits.
- This must be kept secret.
+ This must be kept secret.
.. class:: Camellia(key)
@@ -97,7 +97,7 @@ Algorithms
is not as widely studied or deployed.
:param bytes key: The secret key, either ``128``, ``192``, or ``256`` bits.
- This must be kept secret.
+ This must be kept secret.
.. class:: TripleDES(key)
@@ -108,12 +108,11 @@ Algorithms
is incredibly slow; old applications should consider moving away from it.
:param bytes key: The secret key, either ``64``, ``128``, or ``192`` bits
- (note that DES functionally uses ``56``, ``112``, or
- ``168`` bits of the key, there is a parity byte in each
- component of the key), in some materials these are
- referred to as being up to three separate keys (each
- ``56`` bits long), they can simply be concatenated to
- produce the full key. This must be kept secret.
+ (note that DES functionally uses ``56``, ``112``, or ``168`` bits of
+ the key, there is a parity byte in each component of the key), in some
+ materials these are referred to as being up to three separate keys
+ (each ``56`` bits long), they can simply be concatenated to produce the
+ full key. This must be kept secret.
.. class:: CAST5(key)
@@ -124,7 +123,7 @@ Algorithms
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.
+ 8). This must be kept secret.
Weak Ciphers
------------
@@ -142,7 +141,7 @@ Weak Ciphers
that users of Blowfish move to newer algorithms, such as :class:`AES`.
:param bytes key: The secret key, 32-448 bits in length (in increments of
- 8). This must be kept secret.
+ 8). This must be kept secret.
.. class:: ARC4(key)
@@ -151,8 +150,7 @@ Weak Ciphers
mode constructions.
:param bytes key: The secret key, ``40``, ``56``, ``64``, ``80``, ``128``,
- ``192``, or ``256`` bits in length. This must be kept
- secret.
+ ``192``, or ``256`` bits in length. This must be kept secret.
.. doctest::
@@ -182,17 +180,12 @@ Modes
**Padding is required when using this mode.**
:param bytes initialization_vector: Must be random bytes. They do not need
- to be kept secret (they can be included
- in a transmitted message). Must be the
- same number of bytes as the
- ``block_size`` of the cipher. Each time
- something is encrypted a new
- ``initialization_vector`` should be
- generated. Do not reuse an
- ``initialization_vector`` with
- a given ``key``, and particularly do
- not use a constant
- ``initialization_vector``.
+ to be kept secret (they can be included in a transmitted message). Must
+ be the same number of bytes as the ``block_size`` of the cipher. Each
+ time something is encrypted a new ``initialization_vector`` should be
+ generated. Do not reuse an ``initialization_vector`` with a given
+ ``key``, and particularly do not use a constant
+ ``initialization_vector``.
A good construction looks like:
@@ -226,12 +219,11 @@ Modes
**This mode does not require padding.**
:param bytes nonce: Should be random bytes. It is critical to never reuse a
- ``nonce`` with a given key. Any reuse of a nonce
- with the same key compromises the security of every
- message encrypted with that key. Must be the same
- number of bytes as the ``block_size`` of the cipher
- with a given key. The nonce does not need to be kept
- secret and may be included alongside the ciphertext.
+ ``nonce`` with a given key. Any reuse of a nonce with the same key
+ compromises the security of every message encrypted with that key. Must
+ be the same number of bytes as the ``block_size`` of the cipher with a
+ given key. The nonce does not need to be kept secret and may be
+ included alongside the ciphertext.
.. class:: OFB(initialization_vector)
@@ -241,12 +233,9 @@ Modes
**This mode does not require padding.**
:param bytes initialization_vector: Must be random bytes. They do not need
- to be kept secret (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``.
+ to be kept secret (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:: CFB(initialization_vector)
@@ -256,12 +245,9 @@ Modes
**This mode does not require padding.**
:param bytes initialization_vector: Must be random bytes. They do not need
- to be kept secret (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``.
+ to be kept secret (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)
@@ -282,13 +268,10 @@ Modes
**This mode does not require padding.**
:param bytes initialization_vector: Must be random bytes. They do not need
- to be kept secret (they can be included
- in a transmitted message). NIST
- `recommends 96-bit IV length`_ for
- performance critical situations, but it
- can be up to 2\ :sup:`64` - 1 bits.
- Do not reuse an ``initialization_vector``
- with a given ``key``.
+ to be kept secret (they can be included in a transmitted message). NIST
+ `recommends 96-bit IV length`_ for performance critical situations, but
+ it can be up to 2\ :sup:`64` - 1 bits. Do not reuse an
+ ``initialization_vector`` with a given ``key``.
.. note::
@@ -300,8 +283,8 @@ Modes
(32-bits). Applications **must** verify the tag is the expected length
to guarantee the expected security margin.
- :param bytes tag: The tag bytes to verify during decryption. When encrypting
- this must be None.
+ :param bytes tag: The tag bytes to verify during decryption. When
+ encrypting this must be ``None``.
.. testcode::
@@ -428,8 +411,7 @@ Interfaces
:return bytes: Returns the remainder of the data.
:raises ValueError: This is raised when the data provided isn't
- correctly padded to be a multiple of the
- algorithm's block size.
+ correctly padded to be a multiple of the algorithm's block size.
Once ``finalize`` is called this object can no longer be used and
:meth:`update` and :meth:`finalize` will raise
@@ -473,7 +455,7 @@ Interfaces
:return bytes: Returns the tag value as bytes.
:raises: :class:`~cryptography.exceptions.NotYetFinalized` if called
- before the context is finalized.
+ before the context is finalized.
.. _`described by Colin Percival`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html
diff --git a/docs/hazmat/primitives/twofactor.rst b/docs/hazmat/primitives/twofactor.rst
new file mode 100644
index 00000000..3912d483
--- /dev/null
+++ b/docs/hazmat/primitives/twofactor.rst
@@ -0,0 +1,162 @@
+.. hazmat::
+
+Two-factor Authentication
+=========================
+
+.. currentmodule:: cryptography.hazmat.primitives.twofactor
+
+This module contains algorithms related to two-factor authentication.
+
+Currently, it contains an algorithm for generating and verifying
+one time password values based on Hash-based message authentication
+codes (HMAC).
+
+.. currentmodule:: cryptography.hazmat.primitives.twofactor.hotp
+
+.. class:: HOTP(key, length, algorithm, backend)
+
+ .. versionadded:: 0.3
+
+ HOTP objects take a ``key``, ``length`` and ``algorithm`` parameter. The
+ ``key`` should be randomly generated bytes and is recommended to be 160
+ bits in length. The ``length`` parameter controls the length of the
+ generated one time password and must be >= 6 and <= 8.
+
+ This is an implementation of :rfc:`4226`.
+
+ .. doctest::
+
+ >>> import os
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> from cryptography.hazmat.primitives.twofactor.hotp import HOTP
+ >>> from cryptography.hazmat.primitives.hashes import SHA1
+ >>> key = os.urandom(16)
+ >>> hotp = HOTP(key, 6, SHA1(), backend=default_backend())
+ >>> hotp_value = hotp.generate(0)
+ >>> hotp.verify(hotp_value, 0)
+
+ :param bytes key: Per-user secret key. This value must be kept secret
+ and be at least 128 bits. It is recommended that the
+ key be 160 bits.
+ :param int length: Length of generated one time password as ``int``.
+ :param HashAlgorithm algorithm: A
+ :class:`~cryptography.hazmat.primitives.hashes`
+ provider.
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
+ provider.
+ :raises ValueError: This is raised if the provided ``key`` is shorter than
+ 128 bits or if the ``length`` parameter is not 6, 7 or 8.
+ :raises TypeError: This is raised if the provided ``algorithm`` is not
+ :class:`~cryptography.hazmat.primitives.hashes.SHA1()`,
+ :class:`~cryptography.hazmat.primitives.hashes.SHA256()` or
+ :class:`~cryptography.hazmat.primitives.hashes.SHA512()` or if the
+ ``length`` parameter is not an integer.
+
+ .. method:: generate(counter)
+
+ :param int counter: The counter value used to generate the one time
+ password.
+ :return bytes: A one time password value.
+
+ .. method:: verify(hotp, counter)
+
+ :param bytes hotp: The one time password value to validate.
+ :param int counter: The counter value to validate against.
+ :raises cryptography.exceptions.InvalidToken: This is raised when the
+ supplied HOTP does not match the expected HOTP.
+
+Throttling
+~~~~~~~~~~
+
+Due to the fact that the HOTP algorithm generates rather short tokens that are
+6 - 8 digits long, brute force attacks are possible. It is highly recommended
+that the server that validates the token implement a throttling scheme that
+locks out the account for a period of time after a number of failed attempts.
+The number of allowed attempts should be as low as possible while still
+ensuring that usability is not significantly impacted.
+
+Re-synchronization of the Counter
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The server's counter value should only be incremented on a successful HOTP
+authentication. However, the counter on the client is incremented every time a
+new HOTP value is requested. This can lead to the counter value being out of
+synchronization between the client and server.
+
+Due to this, it is highly recommended that the server sets a look-ahead window
+that allows the server to calculate the next ``x`` HOTP values and check them
+against the supplied HOTP value. This can be accomplished with something
+similar to the following code.
+
+.. code-block:: python
+
+ def verify(hotp, counter, look_ahead):
+ assert look_ahead >= 0
+ correct_counter = None
+
+ otp = HOTP(key, 6, default_backend())
+ for count in range(counter, counter + look_ahead):
+ try:
+ otp.verify(hotp, count)
+ correct_counter = count
+ except InvalidToken:
+ pass
+
+ return correct_counter
+
+.. currentmodule:: cryptography.hazmat.primitives.twofactor.totp
+
+.. class:: TOTP(key, length, algorithm, time_step, backend)
+
+ TOTP objects take a ``key``, ``length``, ``algorithm`` and ``time_step``
+ parameter. The ``key`` should be randomly generated bytes and is recommended
+ to be as long as your hash function's output (e.g 256-bit for SHA256).
+ The ``length`` parameter controls the length of the generated one time
+ password and must be >= 6 and <= 8.
+
+ This is an implementation of :rfc:`6238`.
+
+ .. doctest::
+
+ >>> import os
+ >>> import time
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> from cryptography.hazmat.primitives.twofactor.totp import TOTP
+ >>> from cryptography.hazmat.primitives.hashes import SHA1
+ >>> key = os.urandom(16)
+ >>> totp = TOTP(key, 8, SHA1(), 30, backend=default_backend())
+ >>> time_value = time.time()
+ >>> totp_value = totp.generate(time_value)
+ >>> totp.verify(totp_value, time_value)
+
+ :param bytes key: Per-user secret key. This value must be kept secret
+ and be at least 128 bits. It is recommended that the
+ key be 160 bits.
+ :param int length: Length of generated one time password as ``int``.
+ :param HashAlgorithm algorithm: A
+ :class:`~cryptography.hazmat.primitives.hashes`
+ provider.
+ :param int time_step: The time step size. The recommended size is 30.
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
+ provider.
+ :raises ValueError: This is raised if the provided ``key`` is shorter than
+ 128 bits or if the ``length`` parameter is not 6, 7 or 8.
+ :raises TypeError: This is raised if the provided ``algorithm`` is not
+ :class:`~cryptography.hazmat.primitives.hashes.SHA1()`,
+ :class:`~cryptography.hazmat.primitives.hashes.SHA256()` or
+ :class:`~cryptography.hazmat.primitives.hashes.SHA512()` or if the
+ ``length`` parameter is not an integer.
+
+ .. method:: generate(time)
+
+ :param int time: The time value used to generate the one time password.
+ :return bytes: A one time password value.
+
+ .. method:: verify(totp, time)
+
+ :param bytes totp: The one time password value to validate.
+ :param int time: The time value to validate against.
+ :raises cryptography.exceptions.InvalidToken: This is raised when the
+ supplied TOTP does not match the expected TOTP.