Add flag to toggle key length check for HOTP and TOTP. (#3012)

* Add an enforce_key_length parameter to HOTP and TOTP.

* Document changes in docs.

* Add some words to the wordlist.

* Add versionadded to docs.
diff --git a/docs/hazmat/primitives/twofactor.rst b/docs/hazmat/primitives/twofactor.rst
index 9268f2f..a1391fa 100644
--- a/docs/hazmat/primitives/twofactor.rst
+++ b/docs/hazmat/primitives/twofactor.rst
@@ -18,7 +18,7 @@
 
 .. currentmodule:: cryptography.hazmat.primitives.twofactor.hotp
 
-.. class:: HOTP(key, length, algorithm, backend)
+.. class:: HOTP(key, length, algorithm, backend, enforce_key_length=True)
 
     .. versionadded:: 0.3
 
@@ -50,6 +50,16 @@
     :param backend: A
         :class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
         provider.
+    :param enforce_key_length: A boolean flag defaulting to True that toggles
+        whether a minimum key length of 128 bits is enforced. This exists to
+        work around the fact that as documented in `Issue #2915`, the
+        Google Authenticator PAM module by default generates 80 bit keys. If
+        this flag is set to False, the application develop should implement
+        additional checks of the key length before passing it into
+        :class:`~cryptography.hazmat.primitives.twofactor.hotp.HOTP`.
+
+        .. versionadded:: 1.5
+
     :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
@@ -129,7 +139,7 @@
 
 .. currentmodule:: cryptography.hazmat.primitives.twofactor.totp
 
-.. class:: TOTP(key, length, algorithm, time_step, backend)
+.. class:: TOTP(key, length, algorithm, time_step, backend, enforce_key_length=True)
 
     TOTP objects take a ``key``, ``length``, ``algorithm`` and ``time_step``
     parameter. The ``key`` should be :doc:`randomly generated bytes
@@ -163,6 +173,15 @@
     :param backend: A
         :class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
         provider.
+    :param enforce_key_length: A boolean flag defaulting to True that toggles
+        whether a minimum key length of 128 bits is enforced. This exists to
+        work around the fact that as documented in `Issue #2915`, the
+        Google Authenticator PAM module by default generates 80 bit keys. If
+        this flag is set to False, the application develop should implement
+        additional checks of the key length before passing it into
+        :class:`~cryptography.hazmat.primitives.twofactor.totp.TOTP`.
+
+        .. versionadded:: 1.5
     :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
@@ -222,3 +241,4 @@
 to scan it with Two-Factor authentication applications in their mobile devices.
 
 .. _`spec of Google Authenticator`: https://github.com/google/google-authenticator/wiki/Key-Uri-Format
+.. _`Issue #2915`: https://github.com/pyca/cryptography/issues/2915
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 47415a7..064c738 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -72,3 +72,5 @@
 Verisign
 wildcard
 Xcode
+Google
+Authenticator
diff --git a/src/cryptography/hazmat/primitives/twofactor/hotp.py b/src/cryptography/hazmat/primitives/twofactor/hotp.py
index 12bc766..4ad1bdc 100644
--- a/src/cryptography/hazmat/primitives/twofactor/hotp.py
+++ b/src/cryptography/hazmat/primitives/twofactor/hotp.py
@@ -19,14 +19,15 @@
 
 
 class HOTP(object):
-    def __init__(self, key, length, algorithm, backend):
+    def __init__(self, key, length, algorithm, backend,
+                 enforce_key_length=True):
         if not isinstance(backend, HMACBackend):
             raise UnsupportedAlgorithm(
                 "Backend object does not implement HMACBackend.",
                 _Reasons.BACKEND_MISSING_INTERFACE
             )
 
-        if len(key) < 16:
+        if len(key) < 16 and enforce_key_length is True:
             raise ValueError("Key length has to be at least 128 bits.")
 
         if not isinstance(length, six.integer_types):
diff --git a/src/cryptography/hazmat/primitives/twofactor/totp.py b/src/cryptography/hazmat/primitives/twofactor/totp.py
index 6070590..499f282 100644
--- a/src/cryptography/hazmat/primitives/twofactor/totp.py
+++ b/src/cryptography/hazmat/primitives/twofactor/totp.py
@@ -15,7 +15,8 @@
 
 
 class TOTP(object):
-    def __init__(self, key, length, algorithm, time_step, backend):
+    def __init__(self, key, length, algorithm, time_step, backend,
+                 enforce_key_length=True):
         if not isinstance(backend, HMACBackend):
             raise UnsupportedAlgorithm(
                 "Backend object does not implement HMACBackend.",
@@ -23,7 +24,7 @@
             )
 
         self._time_step = time_step
-        self._hotp = HOTP(key, length, algorithm, backend)
+        self._hotp = HOTP(key, length, algorithm, backend, enforce_key_length)
 
     def generate(self, time):
         counter = int(time / self._time_step)
diff --git a/tests/hazmat/primitives/twofactor/test_hotp.py b/tests/hazmat/primitives/twofactor/test_hotp.py
index ab5f93c..4c561f7 100644
--- a/tests/hazmat/primitives/twofactor/test_hotp.py
+++ b/tests/hazmat/primitives/twofactor/test_hotp.py
@@ -35,6 +35,10 @@
         with pytest.raises(ValueError):
             HOTP(secret, 6, SHA1(), backend)
 
+    def test_unenforced_invalid_kwy_length(self, backend):
+        secret = os.urandom(10)
+        HOTP(secret, 6, SHA1(), backend, enforce_key_length=False)
+
     def test_invalid_hotp_length(self, backend):
         secret = os.urandom(16)