aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2014-01-11 21:59:08 -0600
committerPaul Kehrer <paul.l.kehrer@gmail.com>2014-01-11 21:59:08 -0600
commit74169660e47b760f82c0653b4210b3bc5d3bf46b (patch)
tree33835b3e733f6b918b56240200e29402092cc384 /docs
parent9ad4d755bb3a2edfb8e46b60f6dfaff6365f0386 (diff)
parent089a860f2d3f0ac923fc3f78190055990a940e2a (diff)
downloadcryptography-74169660e47b760f82c0653b4210b3bc5d3bf46b.tar.gz
cryptography-74169660e47b760f82c0653b4210b3bc5d3bf46b.tar.bz2
cryptography-74169660e47b760f82c0653b4210b3bc5d3bf46b.zip
Merge branch 'master' into urandom-engine
* master: (169 commits) Make just one call to ffi.cdef for most of the definitions Use pytest.fixture for backends drop to >= 0.8 to make pypy happy change to anonymous enum require cffi >= 0.8.1 remove extraneous spaces add hmac to commoncrypto binding bytes byte back add check to confirm we've loaded error strings Bind all the PEM errors Spelling! oops, bytes plz don't leak a context in the test add tests to the openssl backend to verify that we've registered Nonsense I think we need. This is a dep init the ssl library in the backend Actuall install a thing Try to run the spellchecker on travis Use a normal quote here, not sure where the smart quote came from ... Conflicts: cryptography/hazmat/bindings/openssl/binding.py tests/hazmat/backends/test_openssl.py
Diffstat (limited to 'docs')
-rw-r--r--docs/changelog.rst11
-rw-r--r--docs/conf.py12
-rw-r--r--docs/contributing.rst2
-rw-r--r--docs/cryptography-docs.py16
-rw-r--r--docs/doing-a-release.rst37
-rw-r--r--docs/fernet.rst76
-rw-r--r--docs/hazmat/bindings/commoncrypto.rst28
-rw-r--r--docs/hazmat/bindings/index.rst3
-rw-r--r--docs/hazmat/primitives/hmac.rst29
-rw-r--r--docs/hazmat/primitives/interfaces.rst12
-rw-r--r--docs/hazmat/primitives/symmetric-encryption.rst255
-rw-r--r--docs/index.rst8
-rw-r--r--docs/security.rst4
-rw-r--r--docs/spelling_wordlist.txt28
14 files changed, 405 insertions, 116 deletions
diff --git a/docs/changelog.rst b/docs/changelog.rst
new file mode 100644
index 00000000..41db635e
--- /dev/null
+++ b/docs/changelog.rst
@@ -0,0 +1,11 @@
+Changelog
+=========
+0.2 - 2014-XX-XX
+~~~~~~~~~~~~~~~~
+
+* In development.
+
+0.1 - 2014-01-08
+~~~~~~~~~~~~~~~~
+
+* Initial release.
diff --git a/docs/conf.py b/docs/conf.py
index 5dbcdab8..a42dcb22 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -38,6 +38,7 @@ extensions = [
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
'cryptography-docs',
+ 'sphinxcontrib.spelling',
]
# Add any paths that contain templates here, relative to this directory.
@@ -60,10 +61,13 @@ copyright = '2013-2014, Individual Contributors'
# |version| and |release|, also used in various other places throughout the
# built documents.
#
-# The short X.Y version.
-version = '0.1dev'
-# The full version, including alpha/beta/rc tags.
-release = '0.1dev'
+
+base_dir = os.path.join(os.path.dirname(__file__), os.pardir)
+about = {}
+with open(os.path.join(base_dir, "cryptography", "__about__.py")) as f:
+ exec(f.read(), about)
+
+version = release = about["__version__"]
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/contributing.rst b/docs/contributing.rst
index 657c4359..8e32c368 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -29,6 +29,8 @@ devastating, ``cryptography`` has a strict code review policy:
backwards incompatible release of a dependency) no pull requests may be
merged until this is rectified.
* All merged patches must have 100% test coverage.
+* New features and significant bug fixes should be documented in the
+ :doc:`/changelog`.
The purpose of these policies is to minimize the chances we merge a change
which jeopardizes our users' security.
diff --git a/docs/cryptography-docs.py b/docs/cryptography-docs.py
index ea7e8eef..0252d693 100644
--- a/docs/cryptography-docs.py
+++ b/docs/cryptography-docs.py
@@ -6,17 +6,29 @@ from sphinx.util.compat import Directive, make_admonition
DANGER_MESSAGE = """
This is a "Hazardous Materials" module. You should **ONLY** use it if you're
100% absolutely sure that you know what you're doing because this module is
-full of land mines, dragons, and dinosaurs with laser guns. """
+full of land mines, dragons, and dinosaurs with laser guns.
+"""
+
+DANGER_ALTERNATE = """
+
+You may instead be interested in :doc:`{alternate}`.
+"""
class HazmatDirective(Directive):
+ has_content = True
+
def run(self):
+ message = DANGER_MESSAGE
+ if self.content:
+ message += DANGER_ALTERNATE.format(alternate=self.content[0])
+
ad = make_admonition(
Hazmat,
self.name,
[],
self.options,
- nodes.paragraph("", DANGER_MESSAGE),
+ nodes.paragraph("", message),
self.lineno,
self.content_offset,
self.block_text,
diff --git a/docs/doing-a-release.rst b/docs/doing-a-release.rst
new file mode 100644
index 00000000..194e82f4
--- /dev/null
+++ b/docs/doing-a-release.rst
@@ -0,0 +1,37 @@
+Doing a Release
+===============
+
+Doing a release of ``cryptography`` is a two part process.
+
+Bumping the version number
+--------------------------
+
+The first step in doing a release is bumping the version number in the
+software.
+
+* Update the version number in ``cryptography/__about__.py``.
+* Set the release date in the :doc:`/changelog`.
+* Do a commit indicating this.
+* Send a pull request with this.
+* Wait for it to be merged.
+
+Performing the release
+----------------------
+
+The commit which merged the version number bump is now the official release
+commit for this release. You will need to have ``gpg`` installed and a ``gpg``
+key in order to do a release. Once this has happened:
+
+* Run ``invoke release {version}``.
+
+The release should now be available on PyPI and a tag should be available in
+the repository. You should verify that ``pip install cryptography`` works
+correctly:
+
+.. code-block:: pycon
+
+ >>> import cryptography
+ >>> cryptography.__version__
+ '...'
+
+Verify that this is the version you just released.
diff --git a/docs/fernet.rst b/docs/fernet.rst
new file mode 100644
index 00000000..13295c0c
--- /dev/null
+++ b/docs/fernet.rst
@@ -0,0 +1,76 @@
+Fernet (Symmetric encryption)
+=============================
+
+.. currentmodule:: cryptography.fernet
+
+Fernet provides guarantees that a message encrypted using it cannot be
+manipulated or read without the key. `Fernet`_ is an implementation of
+symmetric (also known as "secret key") authenticated cryptography.
+
+.. class:: Fernet(key)
+
+ This class provides both encryption and decryption facilities.
+
+ .. doctest::
+
+ >>> from cryptography.fernet import Fernet
+ >>> key = Fernet.generate_key()
+ >>> f = Fernet(key)
+ >>> token = f.encrypt(b"my deep dark secret")
+ >>> token
+ '...'
+ >>> f.decrypt(token)
+ 'my deep dark secret'
+
+ :param bytes key: A URL-safe base64-encoded 32-byte key. This **must** be
+ kept secret. Anyone with this key is able to create and
+ read messages.
+
+ .. classmethod:: generate_key()
+
+ Generates a fresh fernet key. Keep this some place safe! If you lose it
+ you'll no longer be able to decrypt messages; if anyone else gains
+ access to it, they'll be able to decrypt all of your messages, and
+ they'll also be able forge arbitrary messages which will be
+ authenticated and decrypted.
+
+ .. method:: encrypt(plaintext)
+
+ :param bytes plaintext: The message you would like to encrypt.
+ :returns bytes: A secure message which cannot be read or altered
+ without the key. It is URL-safe base64-encoded. This is
+ referred to as a "Fernet token".
+
+ .. note::
+
+ The encrypted message contains the current time when it was
+ generated in *plaintext*, the time a message was created will
+ therefore be visible to a possible attacker.
+
+ .. method:: decrypt(token, ttl=None)
+
+ :param bytes token: The Fernet token. This is the result of calling
+ :meth:`encrypt`.
+ :param int ttl: Optionally, the number of seconds old a message may be
+ for it to be valid. If the message is older than
+ ``ttl`` seconds (from the time it was originally
+ created) an exception will be raised. If ``ttl`` is not
+ provided (or is ``None``), the age of the message is
+ not considered.
+ :returns bytes: The original plaintext.
+ :raises cryptography.fernet.InvalidToken: If the ``token`` is in any
+ way invalid, this exception
+ is raised. A token may be
+ invalid for a number of
+ reasons: it is older than the
+ ``ttl``, it is malformed, or
+ it does not have a valid
+ signature.
+
+
+.. class:: InvalidToken
+
+ See :meth:`Fernet.decrypt` for more information.
+
+
+.. _`Fernet`: https://github.com/fernet/spec/
diff --git a/docs/hazmat/bindings/commoncrypto.rst b/docs/hazmat/bindings/commoncrypto.rst
new file mode 100644
index 00000000..25535e02
--- /dev/null
+++ b/docs/hazmat/bindings/commoncrypto.rst
@@ -0,0 +1,28 @@
+.. hazmat::
+
+CommonCrypto Binding
+====================
+
+.. currentmodule:: cryptography.hazmat.bindings.commoncrypto.binding
+
+These are `CFFI`_ bindings to the `CommonCrypto`_ C library. It is available on
+Mac OS X.
+
+.. class:: cryptography.hazmat.bindings.commoncrypto.binding.Binding()
+
+ This is the exposed API for the CommonCrypto bindings. It has two public
+ attributes:
+
+ .. attribute:: ffi
+
+ This is a :class:`cffi.FFI` instance. It can be used to allocate and
+ otherwise manipulate CommonCrypto structures.
+
+ .. attribute:: lib
+
+ This is a ``cffi`` library. It can be used to call CommonCrypto
+ functions, and access constants.
+
+
+.. _`CFFI`: https://cffi.readthedocs.org/
+.. _`CommonCrypto`: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/Common%20Crypto.3cc.html#//apple_ref/doc/man/3cc/CommonCrypto
diff --git a/docs/hazmat/bindings/index.rst b/docs/hazmat/bindings/index.rst
index 809eddfc..caab8d6a 100644
--- a/docs/hazmat/bindings/index.rst
+++ b/docs/hazmat/bindings/index.rst
@@ -6,7 +6,7 @@ Bindings
.. currentmodule:: cryptography.hazmat.bindings
``cryptography`` aims to provide low-level CFFI based bindings to multiple
-native C libraries. These provide no automatic initialisation of the library
+native C libraries. These provide no automatic initialization of the library
and may not provide complete wrappers for its API.
Using these functions directly is likely to require you to be careful in
@@ -20,3 +20,4 @@ Individual Bindings
:maxdepth: 1
openssl
+ commoncrypto
diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst
index b8f94fd2..a21799be 100644
--- a/docs/hazmat/primitives/hmac.rst
+++ b/docs/hazmat/primitives/hmac.rst
@@ -37,6 +37,16 @@ message.
If the backend doesn't support the requested ``algorithm`` an
:class:`~cryptography.exceptions.UnsupportedAlgorithm` 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:
+
+ .. code-block:: pycon
+
+ >>> h.verify(b"an incorrect signature")
+ Traceback (most recent call last):
+ ...
+ cryptography.exceptions.InvalidSignature: Signature did not match digest.
+
:param key: Secret key as ``bytes``.
:param algorithm: A
:class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
@@ -61,6 +71,17 @@ message.
and finalized independently of the original instance.
:raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
+ .. method:: verify(signature)
+
+ Finalize the current context and securely compare digest to
+ ``signature``.
+
+ :param bytes signature: The bytes to compare the current digest
+ against.
+ :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
+ :raises cryptography.exceptions.InvalidSignature: If signature does not
+ match digest
+
.. method:: finalize()
Finalize the current context and return the message digest as bytes.
@@ -71,11 +92,3 @@ message.
:return bytes: The message digest as bytes.
:raises cryptography.exceptions.AlreadyFinalized:
-
- .. method:: verify(signature)
-
- Finalize the current context and securely compare digest to ``signature``.
-
- :param bytes signature: The bytes of the HMAC signature recieved.
- :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
- :raises cryptography.exceptions.InvalidSignature: If signature does not match digest
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
index 361b723e..edb24cd9 100644
--- a/docs/hazmat/primitives/interfaces.rst
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -67,6 +67,18 @@ Interfaces used by the symmetric cipher modes described in
The name may be used by a backend to influence the operation of a
cipher in conjunction with the algorithm's name.
+ .. method:: validate_for_algorithm(algorithm)
+
+ :param CipherAlgorithm algorithm:
+
+ Checks that the combination of this mode with the provided algorithm
+ meets any necessary invariants. This should raise an exception if they
+ are not met.
+
+ For example, the :class:`~cryptography.hazmat.primitives.modes.CBC`
+ mode uses this method to check that the provided initialization
+ vector's length matches the block size of the algorithm.
+
.. class:: ModeWithInitializationVector
diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst
index 30896a05..83165690 100644
--- a/docs/hazmat/primitives/symmetric-encryption.rst
+++ b/docs/hazmat/primitives/symmetric-encryption.rst
@@ -1,4 +1,4 @@
-.. hazmat::
+.. hazmat:: /fernet
Symmetric Encryption
@@ -74,79 +74,6 @@ an "encrypt-then-MAC" formulation as `described by Colin Percival`_.
and ``mode`` an :class:`cryptography.exceptions.UnsupportedAlgorithm`
will be raised.
-
-.. currentmodule:: cryptography.hazmat.primitives.interfaces
-
-.. class:: CipherContext
-
- When calling ``encryptor()`` or ``decryptor()`` on a ``Cipher`` object
- you will receive a return object conforming to the ``CipherContext``
- interface. You can then call ``update(data)`` with data until you have fed
- everything into the context. Once that is done call ``finalize()`` to
- finish the operation and obtain the remainder of the data.
-
- Block ciphers require that plaintext or ciphertext always be a multiple of
- their block size, because of that **padding** is often required to make a
- message the correct size. ``CipherContext`` will not automatically apply
- any padding; you'll need to add your own. For block ciphers the recommended
- padding is :class:`cryptography.hazmat.primitives.padding.PKCS7`. If you
- are using a stream cipher mode (such as
- :class:`cryptography.hazmat.primitives.modes.CTR`) you don't have to worry
- about this.
-
- .. method:: update(data)
-
- :param bytes data: The data you wish to pass into the context.
- :return bytes: Returns the data that was encrypted or decrypted.
- :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
-
- When the ``Cipher`` was constructed in a mode that turns it into a
- stream cipher (e.g.
- :class:`cryptography.hazmat.primitives.ciphers.modes.CTR`), this will
- return bytes immediately, however in other modes it will return chunks,
- whose size is determined by the cipher's block size.
-
- .. method:: finalize()
-
- :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.
-
- Once ``finalize`` is called this object can no longer be used and
- :meth:`update` and :meth:`finalize` will raise
- :class:`~cryptography.exceptions.AlreadyFinalized`.
-
-.. class:: AEADCipherContext
-
- When calling ``encryptor()`` or ``decryptor()`` on a ``Cipher`` object
- with an AEAD mode you will receive a return object conforming to the
- ``AEADCipherContext`` interface (in addition to the ``CipherContext``
- interface). If it is an encryption context it will additionally be an
- ``AEADEncryptionContext`` interface. ``AEADCipherContext`` contains an
- additional method ``authenticate_additional_data`` for adding additional
- authenticated but unencrypted data. You should call this before calls to
- ``update``. When you are done call ``finalize()`` to finish the operation.
-
- .. method:: authenticate_additional_data(data)
-
- :param bytes data: The data you wish to authenticate but not encrypt.
- :raises: :class:`~cryptography.exceptions.AlreadyFinalized`
-
-.. class:: AEADEncryptionContext
-
- When creating an encryption context using ``encryptor()`` on a ``Cipher``
- object with an AEAD mode you will receive a return object conforming to the
- ``AEADEncryptionContext`` interface (as well as ``AEADCipherContext``).
- This interface provides one additional attribute ``tag``. ``tag`` can only
- be obtained after ``finalize()``.
-
- .. attribute:: tag
-
- :return bytes: Returns the tag value as bytes.
- :raises: :class:`~cryptography.exceptions.NotYetFinalized` if called
- before the context is finalized.
-
.. _symmetric-encryption-algorithms:
Algorithms
@@ -189,15 +116,6 @@ Algorithms
``56`` bits long), they can simply be concatenated to
produce the full key. This must be kept secret.
-.. class:: CAST5(key)
-
- CAST5 (also known as CAST-128) is a block cipher approved for use in the
- Canadian government by their 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
------------
@@ -251,6 +169,8 @@ Modes
CBC (Cipher block chaining) is a mode of operation for block ciphers. It is
considered cryptographically strong.
+ **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
@@ -293,6 +213,8 @@ Modes
cryptographically strong. It transforms a block cipher into a stream
cipher.
+ **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
@@ -306,6 +228,8 @@ Modes
OFB (Output Feedback) is a mode of operation for block ciphers. It
transforms a block cipher into a stream cipher.
+ **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
@@ -319,6 +243,8 @@ Modes
CFB (Cipher Feedback) is a mode of operation for block ciphers. It
transforms a block cipher into a stream cipher.
+ **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
@@ -343,6 +269,8 @@ Modes
Additional means of verifying integrity (like
:doc:`HMAC </hazmat/primitives/hmac>`) are not necessary.
+ **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
@@ -365,20 +293,70 @@ Modes
:param bytes tag: The tag bytes to verify during decryption. When encrypting
this must be None.
- .. doctest::
+ .. testcode::
- >>> from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
- >>> from cryptography.hazmat.backends import default_backend
- >>> cipher = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend())
- >>> encryptor = cipher.encryptor()
- >>> encryptor.authenticate_additional_data(b"authenticated but not encrypted payload")
- >>> ct = encryptor.update(b"a secret message") + encryptor.finalize()
- >>> tag = encryptor.tag
- >>> cipher = Cipher(algorithms.AES(key), modes.GCM(iv, tag), backend)
- >>> decryptor = cipher.decryptor()
- >>> decryptor.authenticate_additional_data(b"authenticated but not encrypted payload")
- >>> decryptor.update(ct) + decryptor.finalize()
- 'a secret message'
+ import os
+
+ from cryptography.hazmat.primitives.ciphers import (
+ Cipher, algorithms, modes
+ )
+
+ def encrypt(key, plaintext, associated_data):
+ # Generate a random 96-bit IV.
+ iv = os.urandom(12)
+
+ # Construct a AES-GCM Cipher object with the given and our randomly
+ # generated IV.
+ encryptor = Cipher(
+ algorithms.AES(key),
+ modes.GCM(iv),
+ backend=default_backend()
+ ).encryptor()
+
+ # associated_data will be authenticated but not encrypted,
+ # it must also be passed in on decryption.
+ encryptor.authenticate_additional_data(associated_data)
+
+ # Encrypt the plaintext and get the associated ciphertext.
+ # GCM does not require padding.
+ ciphertext = encryptor.update(plaintext) + encryptor.finalize()
+
+ return (iv, ciphertext, encryptor.tag)
+
+ def decrypt(key, associated_data, iv, ciphertext, tag):
+ # Construct a Cipher object, with the key, iv, and additionally the
+ # GCM tag used for authenticating the message.
+ decryptor = Cipher(
+ algorithms.AES(key),
+ modes.GCM(iv, tag),
+ backend=default_backend()
+ ).decryptor()
+
+ # We put associated_data back in or the tag will fail to verify
+ # when we finalize the decryptor.
+ decryptor.authenticate_additional_data(associated_data)
+
+ # Decryption gets us the authenticated plaintext.
+ # If the tag does not match an InvalidTag exception will be raised.
+ return decryptor.update(ciphertext) + decryptor.finalize()
+
+ iv, ciphertext, tag = encrypt(
+ key,
+ b"a secret message!",
+ b"authenticated but not encrypted payload"
+ )
+
+ print(decrypt(
+ key,
+ b"authenticated but not encrypted payload",
+ iv,
+ ciphertext,
+ tag
+ ))
+
+ .. testoutput::
+
+ a secret message!
Insecure Modes
@@ -397,6 +375,91 @@ Insecure Modes
identical plaintext blocks will always result in identical ciphertext
blocks, and thus result in information leakage
+ **Padding is required when using this mode.**
+
+Interfaces
+----------
+
+.. class:: CipherContext
+
+ When calling ``encryptor()`` or ``decryptor()`` on a ``Cipher`` object
+ you will receive a return object conforming to the ``CipherContext``
+ interface. You can then call ``update(data)`` with data until you have fed
+ everything into the context. Once that is done call ``finalize()`` to
+ finish the operation and obtain the remainder of the data.
+
+ Block ciphers require that plaintext or ciphertext always be a multiple of
+ their block size, because of that **padding** is sometimes required to make
+ a message the correct size. ``CipherContext`` will not automatically apply
+ any padding; you'll need to add your own. For block ciphers the recommended
+ padding is :class:`cryptography.hazmat.primitives.padding.PKCS7`. If you
+ are using a stream cipher mode (such as
+ :class:`cryptography.hazmat.primitives.modes.CTR`) you don't have to worry
+ about this.
+
+ .. method:: update(data)
+
+ :param bytes data: The data you wish to pass into the context.
+ :return bytes: Returns the data that was encrypted or decrypted.
+ :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
+
+ When the ``Cipher`` was constructed in a mode that turns it into a
+ stream cipher (e.g.
+ :class:`cryptography.hazmat.primitives.ciphers.modes.CTR`), this will
+ return bytes immediately, however in other modes it will return chunks,
+ whose size is determined by the cipher's block size.
+
+ .. method:: finalize()
+
+ :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.
+
+ Once ``finalize`` is called this object can no longer be used and
+ :meth:`update` and :meth:`finalize` will raise
+ :class:`~cryptography.exceptions.AlreadyFinalized`.
+
+.. class:: AEADCipherContext
+
+ When calling ``encryptor()`` or ``decryptor()`` on a ``Cipher`` object
+ with an AEAD mode (e.g.
+ :class:`~cryptography.hazmat.primitives.ciphers.modes.GCM`) you will receive
+ a return object conforming to the ``AEADCipherContext`` and
+ ``CipherContext`` interfaces. If it is an encryption context it will
+ additionally be an ``AEADEncryptionContext`` interface.
+ ``AEADCipherContext`` contains an additional method
+ ``authenticate_additional_data`` for adding additional authenticated but
+ unencrypted data (see note below). You should call this before calls to
+ ``update``. When you are done call ``finalize()`` to finish the operation.
+
+ .. note::
+
+ In AEAD modes all data passed to ``update()`` will be both encrypted
+ and authenticated. Do not pass encrypted data to the
+ ``authenticate_additional_data()`` method. It is meant solely for
+ additional data you may want to authenticate but leave unencrypted.
+
+ .. method:: authenticate_additional_data(data)
+
+ :param bytes data: Any data you wish to authenticate but not encrypt.
+ :raises: :class:`~cryptography.exceptions.AlreadyFinalized`
+
+.. class:: AEADEncryptionContext
+
+ When creating an encryption context using ``encryptor()`` on a ``Cipher``
+ object with an AEAD mode (e.g.
+ :class:`~cryptography.hazmat.primitives.ciphers.modes.GCM`) you will receive
+ a return object conforming to the ``AEADEncryptionContext`` interface (as
+ well as ``AEADCipherContext``). This interface provides one additional
+ attribute ``tag``. ``tag`` can only be obtained after ``finalize()``.
+
+ .. attribute:: tag
+
+ :return bytes: Returns the tag value as bytes.
+ :raises: :class:`~cryptography.exceptions.NotYetFinalized` if called
+ before the context is finalized.
+
.. _`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
diff --git a/docs/index.rst b/docs/index.rst
index 5eb3de7d..e17b4f9f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -8,12 +8,11 @@ needs in Python.
Installing
----------
-We don't yet have a release on PyPI, for now you can install ``cryptography``
-directly from Github:
+You can install ``cryptography`` with ``pip``:
.. code-block:: console
- $ pip install git+https://github.com/pyca/cryptography
+ $ pip install cryptography
Why a new crypto library for Python?
------------------------------------
@@ -56,6 +55,7 @@ The recipes layer
.. toctree::
:maxdepth: 2
+ fernet
exceptions
glossary
@@ -78,4 +78,6 @@ The ``cryptography`` open source project
contributing
security
api-stability
+ doing-a-release
+ changelog
community
diff --git a/docs/security.rst b/docs/security.rst
index 88959709..4dadc847 100644
--- a/docs/security.rst
+++ b/docs/security.rst
@@ -7,6 +7,6 @@ identified a security issue in it, please report it to
fingerprint ``E27D 4AA0 1651 72CB C5D2 AF2B 125F 5C67 DFE9 4084`` (this public
key is available from most commonly-used key servers).
-Once you’ve submitted an issue via email, you should receive an acknowledgment
+Once you've submitted an issue via email, you should receive an acknowledgment
within 48 hours, and depending on the action to be taken, you may receive
-further followup emails.
+further follow-up emails.
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
new file mode 100644
index 00000000..97356c24
--- /dev/null
+++ b/docs/spelling_wordlist.txt
@@ -0,0 +1,28 @@
+backend
+backends
+boolean
+ciphertext
+committer
+crypto
+cryptographic
+cryptographically
+decrypt
+decrypted
+decrypting
+fernet
+hazmat
+indistinguishability
+introspectability
+invariants
+pickleable
+plaintext
+testability
+unencrypted
+unpadded
+unpadding
+Backends
+Blowfish
+Changelog
+Docstrings
+Fernet
+Schneier