Merge branch 'master' into arc4-support

* master:
  Typo
  Be really explicit about what's good and bad
  Mention return types.
  Consistently use e.g.
  Module documentation.
  Single space.
  Add a new Mode interface to document mode.name and start on some prose docs for interfaces.
  Proper name for the iv thing.
  Actually note the properties for cipher modes types on their ABCs.

Conflicts:
	docs/hazmat/primitives/symmetric-encryption.rst
diff --git a/cryptography/hazmat/primitives/ciphers/modes.py b/cryptography/hazmat/primitives/ciphers/modes.py
index a60e8a3..e54872a 100644
--- a/cryptography/hazmat/primitives/ciphers/modes.py
+++ b/cryptography/hazmat/primitives/ciphers/modes.py
@@ -16,6 +16,7 @@
 from cryptography.hazmat.primitives import interfaces
 
 
+@interfaces.register(interfaces.Mode)
 @interfaces.register(interfaces.ModeWithInitializationVector)
 class CBC(object):
     name = "CBC"
@@ -25,10 +26,12 @@
         self.initialization_vector = initialization_vector
 
 
+@interfaces.register(interfaces.Mode)
 class ECB(object):
     name = "ECB"
 
 
+@interfaces.register(interfaces.Mode)
 @interfaces.register(interfaces.ModeWithInitializationVector)
 class OFB(object):
     name = "OFB"
@@ -38,6 +41,7 @@
         self.initialization_vector = initialization_vector
 
 
+@interfaces.register(interfaces.Mode)
 @interfaces.register(interfaces.ModeWithInitializationVector)
 class CFB(object):
     name = "CFB"
@@ -47,6 +51,7 @@
         self.initialization_vector = initialization_vector
 
 
+@interfaces.register(interfaces.Mode)
 @interfaces.register(interfaces.ModeWithNonce)
 class CTR(object):
     name = "CTR"
diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py
index ebf5e31..67dbe6f 100644
--- a/cryptography/hazmat/primitives/interfaces.py
+++ b/cryptography/hazmat/primitives/interfaces.py
@@ -25,12 +25,28 @@
     return register_decorator
 
 
+class Mode(six.with_metaclass(abc.ABCMeta)):
+    @abc.abstractproperty
+    def name(self):
+        """
+        A string naming this mode.  (e.g. ECB, CBC)
+        """
+
+
 class ModeWithInitializationVector(six.with_metaclass(abc.ABCMeta)):
-    pass
+    @abc.abstractproperty
+    def initialization_vector(self):
+        """
+        The value of the initialization vector for this mode as bytes.
+        """
 
 
 class ModeWithNonce(six.with_metaclass(abc.ABCMeta)):
-    pass
+    @abc.abstractproperty
+    def nonce(self):
+        """
+        The value of the nonce for this mode as bytes.
+        """
 
 
 class CipherContext(six.with_metaclass(abc.ABCMeta)):
@@ -65,7 +81,7 @@
     @abc.abstractproperty
     def name(self):
         """
-        A string naming this algorithm. (ex. sha256, md5)
+        A string naming this algorithm. (e.g. sha256, md5)
         """
 
     @abc.abstractproperty
diff --git a/docs/hazmat/primitives/index.rst b/docs/hazmat/primitives/index.rst
index c81018a..614c414 100644
--- a/docs/hazmat/primitives/index.rst
+++ b/docs/hazmat/primitives/index.rst
@@ -10,3 +10,4 @@
     hmac
     symmetric-encryption
     padding
+    interfaces
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
new file mode 100644
index 0000000..7068316
--- /dev/null
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -0,0 +1,59 @@
+.. hazmat::
+
+Interfaces
+==========
+
+
+``cryptography`` uses `Abstract Base Classes`_ as interfaces to describe the
+properties and methods of most primitive constructs. Backends may also use
+this information to influence their operation. Interfaces should also be used
+to document argument and return types.
+
+.. _`Abstract Base Classes`: http://docs.python.org/3.2/library/abc.html
+
+
+Cipher Modes
+~~~~~~~~~~~~
+
+.. currentmodule:: cryptography.hazmat.primitives.interfaces
+
+Interfaces used by the symmetric cipher modes described in
+:ref:`Symmetric Encryption Modes <symmetric-encryption-modes>`.
+
+.. class:: Mode
+
+    A named cipher mode.
+
+    .. attribute:: name
+
+        :type: str
+
+        This should be the standard shorthand name for the mode, for example
+        Cipher-Block Chaining mode is "CBC".
+
+        The name may be used by a backend to influence the operation of a
+        cipher in conjunction with the algorithm's name.
+
+
+.. class:: ModeWithInitializationVector
+
+    A cipher mode with an initialization vector.
+
+    .. attribute:: initialization_vector
+
+        :type: bytes
+
+        Exact requirements of the initialization are described by the
+        documentation of individual modes.
+
+
+.. class:: ModeWithNonce
+
+    A cipher mode with a nonce.
+
+    .. attribute:: nonce
+
+        :type: bytes
+
+        Exact requirements of the nonce are described by the documentation of
+        individual modes.
diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst
index 4d0703b..9d18ce5 100644
--- a/docs/hazmat/primitives/symmetric-encryption.rst
+++ b/docs/hazmat/primitives/symmetric-encryption.rst
@@ -159,6 +159,9 @@
                       ``192``, or ``256`` bits in length.  This must be kept
                       secret.
 
+
+.. _symmetric-encryption-modes:
+
 Modes
 ~~~~~
 
@@ -173,9 +176,29 @@
                                         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``.
+                                        ``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:
+
+    .. code-block:: pycon
+
+        >>> import os
+        >>> iv = os.urandom(16)
+        >>> mode = CBC(iv)
+
+    While the following is bad and will leak information:
+
+    .. code-block:: pycon
+
+        >>> iv = "a" * 16
+        >>> mode = CBC(iv)
 
 
 .. class:: CTR(nonce)