We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Cryptography 1.2.2 on OS X causing TypeError with AES-GCM cipher
Found this in unit tests we've been working on for our system. Reduced the problem down to the following example code, which causes a TypeError, sometimes 1 in 3 runs cause the failure, sometimes fails every time, you may have to run a few times to hit the problem.

``` python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

cek = [0] * 32
iv = [0] * 12
tag = [0] * 16 

cipher = Cipher(algorithms.AES(cek), modes.GCM(iv, tag), backend=default_backend())
decryptor = cipher.decryptor()
```

as follows:

``` python
Traceback (most recent call last):
  File "fail.py", line 13, in <module>
    decryptor = cipher.decryptor()
  File "/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 115, in decryptor
    self.algorithm, self.mode
  File "/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/multibackend.py", line 59, in create_symmetric_decryption_ctx
    return b.create_symmetric_decryption_ctx(cipher, mode)
  File "/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 875, in create_symmetric_decryption_ctx
    return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT)
  File "/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 86, in __init__
    len(mode.tag), mode.tag
TypeError: initializer for ctype 'void *' must be a cdata pointer, not list
```

I printed the values being passed to "self._backend._lib.EVP_CIPHER_CTX_ctrl()" above on error it gives:

``` python
<cdata 'EVP_CIPHER_CTX *' 0x7fa4fd83d980>, 17, 16, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
```

Note the [0, 0, 0...] is just the tag, changing the value changes this. I've tried this with actual values from our test case which found the problem e.g.

``` python
cek = [177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154, 212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122, 234, 64, 252]
iv  = [227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219]
tag = [92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91, 210, 145]
```

Same result...
- OSX 10.11.2
- Python 3.5.1
- Cryptography 1.2.2

Tried Cryptography 1.1, 1.1.1, 1.1.2, 1.2, 1.2.1, 1.2.2, same problem.

Sometimes get the same error in a different location:

``` python
Traceback (most recent call last):
  File "fail.py", line 13, in <module>
    decryptor = cipher.decryptor()
  File "/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 115, in decryptor
    self.algorithm, self.mode
  File "/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/multibackend.py", line 59, in create_symmetric_decryption_ctx
    return b.create_symmetric_decryption_ctx(cipher, mode)
  File "/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/commoncrypto/backend.py", line 120, in create_symmetric_decryption_ctx
    self, cipher, mode, self._lib.kCCDecrypt
  File "/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/commoncrypto/ciphers.py", line 137, in __init__
    self._backend._ffi.NULL, 0, 0, 0, self._ctx)
TypeError: initializer for ctype 'void *' must be a cdata pointer, not list
```

Looks like something going on in OpenSSL/cffi?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cryptography/hazmat/primitives/ciphers/modes.py`
Content:
```
1 # This file is dual licensed under the terms of the Apache License, Version
2 # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3 # for complete details.
4 
5 from __future__ import absolute_import, division, print_function
6 
7 import abc
8 
9 import six
10 
11 from cryptography import utils
12 
13 
14 @six.add_metaclass(abc.ABCMeta)
15 class Mode(object):
16     @abc.abstractproperty
17     def name(self):
18         """
19         A string naming this mode (e.g. "ECB", "CBC").
20         """
21 
22     @abc.abstractmethod
23     def validate_for_algorithm(self, algorithm):
24         """
25         Checks that all the necessary invariants of this (mode, algorithm)
26         combination are met.
27         """
28 
29 
30 @six.add_metaclass(abc.ABCMeta)
31 class ModeWithInitializationVector(object):
32     @abc.abstractproperty
33     def initialization_vector(self):
34         """
35         The value of the initialization vector for this mode as bytes.
36         """
37 
38 
39 @six.add_metaclass(abc.ABCMeta)
40 class ModeWithNonce(object):
41     @abc.abstractproperty
42     def nonce(self):
43         """
44         The value of the nonce for this mode as bytes.
45         """
46 
47 
48 @six.add_metaclass(abc.ABCMeta)
49 class ModeWithAuthenticationTag(object):
50     @abc.abstractproperty
51     def tag(self):
52         """
53         The value of the tag supplied to the constructor of this mode.
54         """
55 
56 
57 def _check_iv_length(self, algorithm):
58     if len(self.initialization_vector) * 8 != algorithm.block_size:
59         raise ValueError("Invalid IV size ({0}) for {1}.".format(
60             len(self.initialization_vector), self.name
61         ))
62 
63 
64 @utils.register_interface(Mode)
65 @utils.register_interface(ModeWithInitializationVector)
66 class CBC(object):
67     name = "CBC"
68 
69     def __init__(self, initialization_vector):
70         self._initialization_vector = initialization_vector
71 
72     initialization_vector = utils.read_only_property("_initialization_vector")
73     validate_for_algorithm = _check_iv_length
74 
75 
76 @utils.register_interface(Mode)
77 class ECB(object):
78     name = "ECB"
79 
80     def validate_for_algorithm(self, algorithm):
81         pass
82 
83 
84 @utils.register_interface(Mode)
85 @utils.register_interface(ModeWithInitializationVector)
86 class OFB(object):
87     name = "OFB"
88 
89     def __init__(self, initialization_vector):
90         self._initialization_vector = initialization_vector
91 
92     initialization_vector = utils.read_only_property("_initialization_vector")
93     validate_for_algorithm = _check_iv_length
94 
95 
96 @utils.register_interface(Mode)
97 @utils.register_interface(ModeWithInitializationVector)
98 class CFB(object):
99     name = "CFB"
100 
101     def __init__(self, initialization_vector):
102         self._initialization_vector = initialization_vector
103 
104     initialization_vector = utils.read_only_property("_initialization_vector")
105     validate_for_algorithm = _check_iv_length
106 
107 
108 @utils.register_interface(Mode)
109 @utils.register_interface(ModeWithInitializationVector)
110 class CFB8(object):
111     name = "CFB8"
112 
113     def __init__(self, initialization_vector):
114         self._initialization_vector = initialization_vector
115 
116     initialization_vector = utils.read_only_property("_initialization_vector")
117     validate_for_algorithm = _check_iv_length
118 
119 
120 @utils.register_interface(Mode)
121 @utils.register_interface(ModeWithNonce)
122 class CTR(object):
123     name = "CTR"
124 
125     def __init__(self, nonce):
126         self._nonce = nonce
127 
128     nonce = utils.read_only_property("_nonce")
129 
130     def validate_for_algorithm(self, algorithm):
131         if len(self.nonce) * 8 != algorithm.block_size:
132             raise ValueError("Invalid nonce size ({0}) for {1}.".format(
133                 len(self.nonce), self.name
134             ))
135 
136 
137 @utils.register_interface(Mode)
138 @utils.register_interface(ModeWithInitializationVector)
139 @utils.register_interface(ModeWithAuthenticationTag)
140 class GCM(object):
141     name = "GCM"
142     _MAX_ENCRYPTED_BYTES = (2 ** 39 - 256) // 8
143     _MAX_AAD_BYTES = (2 ** 64) // 8
144 
145     def __init__(self, initialization_vector, tag=None, min_tag_length=16):
146         # len(initialization_vector) must in [1, 2 ** 64), but it's impossible
147         # to actually construct a bytes object that large, so we don't check
148         # for it
149         if min_tag_length < 4:
150             raise ValueError("min_tag_length must be >= 4")
151         if tag is not None and len(tag) < min_tag_length:
152             raise ValueError(
153                 "Authentication tag must be {0} bytes or longer.".format(
154                     min_tag_length)
155             )
156 
157         self._initialization_vector = initialization_vector
158         self._tag = tag
159 
160     tag = utils.read_only_property("_tag")
161     initialization_vector = utils.read_only_property("_initialization_vector")
162 
163     def validate_for_algorithm(self, algorithm):
164         pass
165
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/cryptography/hazmat/primitives/ciphers/modes.py b/src/cryptography/hazmat/primitives/ciphers/modes.py
--- a/src/cryptography/hazmat/primitives/ciphers/modes.py
+++ b/src/cryptography/hazmat/primitives/ciphers/modes.py
@@ -67,6 +67,9 @@
     name = "CBC"
 
     def __init__(self, initialization_vector):
+        if not isinstance(initialization_vector, bytes):
+            raise TypeError("initialization_vector must be bytes")
+
         self._initialization_vector = initialization_vector
 
     initialization_vector = utils.read_only_property("_initialization_vector")
@@ -87,6 +90,9 @@
     name = "OFB"
 
     def __init__(self, initialization_vector):
+        if not isinstance(initialization_vector, bytes):
+            raise TypeError("initialization_vector must be bytes")
+
         self._initialization_vector = initialization_vector
 
     initialization_vector = utils.read_only_property("_initialization_vector")
@@ -99,6 +105,9 @@
     name = "CFB"
 
     def __init__(self, initialization_vector):
+        if not isinstance(initialization_vector, bytes):
+            raise TypeError("initialization_vector must be bytes")
+
         self._initialization_vector = initialization_vector
 
     initialization_vector = utils.read_only_property("_initialization_vector")
@@ -111,6 +120,9 @@
     name = "CFB8"
 
     def __init__(self, initialization_vector):
+        if not isinstance(initialization_vector, bytes):
+            raise TypeError("initialization_vector must be bytes")
+
         self._initialization_vector = initialization_vector
 
     initialization_vector = utils.read_only_property("_initialization_vector")
@@ -123,6 +135,9 @@
     name = "CTR"
 
     def __init__(self, nonce):
+        if not isinstance(nonce, bytes):
+            raise TypeError("nonce must be bytes")
+
         self._nonce = nonce
 
     nonce = utils.read_only_property("_nonce")
@@ -154,6 +169,12 @@
                     min_tag_length)
             )
 
+        if not isinstance(initialization_vector, bytes):
+            raise TypeError("initialization_vector must be bytes")
+
+        if tag is not None and not isinstance(tag, bytes):
+            raise TypeError("tag must be bytes or None")
+
         self._initialization_vector = initialization_vector
         self._tag = tag

{"golden_diff": "diff --git a/src/cryptography/hazmat/primitives/ciphers/modes.py b/src/cryptography/hazmat/primitives/ciphers/modes.py\n--- a/src/cryptography/hazmat/primitives/ciphers/modes.py\n+++ b/src/cryptography/hazmat/primitives/ciphers/modes.py\n@@ -67,6 +67,9 @@\n     name = \"CBC\"\n \n     def __init__(self, initialization_vector):\n+        if not isinstance(initialization_vector, bytes):\n+            raise TypeError(\"initialization_vector must be bytes\")\n+\n         self._initialization_vector = initialization_vector\n \n     initialization_vector = utils.read_only_property(\"_initialization_vector\")\n@@ -87,6 +90,9 @@\n     name = \"OFB\"\n \n     def __init__(self, initialization_vector):\n+        if not isinstance(initialization_vector, bytes):\n+            raise TypeError(\"initialization_vector must be bytes\")\n+\n         self._initialization_vector = initialization_vector\n \n     initialization_vector = utils.read_only_property(\"_initialization_vector\")\n@@ -99,6 +105,9 @@\n     name = \"CFB\"\n \n     def __init__(self, initialization_vector):\n+        if not isinstance(initialization_vector, bytes):\n+            raise TypeError(\"initialization_vector must be bytes\")\n+\n         self._initialization_vector = initialization_vector\n \n     initialization_vector = utils.read_only_property(\"_initialization_vector\")\n@@ -111,6 +120,9 @@\n     name = \"CFB8\"\n \n     def __init__(self, initialization_vector):\n+        if not isinstance(initialization_vector, bytes):\n+            raise TypeError(\"initialization_vector must be bytes\")\n+\n         self._initialization_vector = initialization_vector\n \n     initialization_vector = utils.read_only_property(\"_initialization_vector\")\n@@ -123,6 +135,9 @@\n     name = \"CTR\"\n \n     def __init__(self, nonce):\n+        if not isinstance(nonce, bytes):\n+            raise TypeError(\"nonce must be bytes\")\n+\n         self._nonce = nonce\n \n     nonce = utils.read_only_property(\"_nonce\")\n@@ -154,6 +169,12 @@\n                     min_tag_length)\n             )\n \n+        if not isinstance(initialization_vector, bytes):\n+            raise TypeError(\"initialization_vector must be bytes\")\n+\n+        if tag is not None and not isinstance(tag, bytes):\n+            raise TypeError(\"tag must be bytes or None\")\n+\n         self._initialization_vector = initialization_vector\n         self._tag = tag\n", "issue": "Cryptography 1.2.2 on OS X causing TypeError with AES-GCM cipher\nFound this in unit tests we've been working on for our system. Reduced the problem down to the following example code, which causes a TypeError, sometimes 1 in 3 runs cause the failure, sometimes fails every time, you may have to run a few times to hit the problem.\n\n``` python\nfrom cryptography.hazmat.backends import default_backend\nfrom cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes\n\ncek = [0] * 32\niv = [0] * 12\ntag = [0] * 16 \n\ncipher = Cipher(algorithms.AES(cek), modes.GCM(iv, tag), backend=default_backend())\ndecryptor = cipher.decryptor()\n```\n\nas follows:\n\n``` python\nTraceback (most recent call last):\n  File \"fail.py\", line 13, in <module>\n    decryptor = cipher.decryptor()\n  File \"/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/primitives/ciphers/base.py\", line 115, in decryptor\n    self.algorithm, self.mode\n  File \"/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/multibackend.py\", line 59, in create_symmetric_decryption_ctx\n    return b.create_symmetric_decryption_ctx(cipher, mode)\n  File \"/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py\", line 875, in create_symmetric_decryption_ctx\n    return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT)\n  File \"/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/ciphers.py\", line 86, in __init__\n    len(mode.tag), mode.tag\nTypeError: initializer for ctype 'void *' must be a cdata pointer, not list\n```\n\nI printed the values being passed to \"self._backend._lib.EVP_CIPHER_CTX_ctrl()\" above on error it gives:\n\n``` python\n<cdata 'EVP_CIPHER_CTX *' 0x7fa4fd83d980>, 17, 16, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n```\n\nNote the [0, 0, 0...] is just the tag, changing the value changes this. I've tried this with actual values from our test case which found the problem e.g.\n\n``` python\ncek = [177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154, 212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122, 234, 64, 252]\niv  = [227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219]\ntag = [92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91, 210, 145]\n```\n\nSame result...\n- OSX 10.11.2\n- Python 3.5.1\n- Cryptography 1.2.2\n\nTried Cryptography 1.1, 1.1.1, 1.1.2, 1.2, 1.2.1, 1.2.2, same problem.\n\nSometimes get the same error in a different location:\n\n``` python\nTraceback (most recent call last):\n  File \"fail.py\", line 13, in <module>\n    decryptor = cipher.decryptor()\n  File \"/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/primitives/ciphers/base.py\", line 115, in decryptor\n    self.algorithm, self.mode\n  File \"/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/multibackend.py\", line 59, in create_symmetric_decryption_ctx\n    return b.create_symmetric_decryption_ctx(cipher, mode)\n  File \"/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/commoncrypto/backend.py\", line 120, in create_symmetric_decryption_ctx\n    self, cipher, mode, self._lib.kCCDecrypt\n  File \"/Users/collis/.virtualenvs/jwt/lib/python3.5/site-packages/cryptography/hazmat/backends/commoncrypto/ciphers.py\", line 137, in __init__\n    self._backend._ffi.NULL, 0, 0, 0, self._ctx)\nTypeError: initializer for ctype 'void *' must be a cdata pointer, not list\n```\n\nLooks like something going on in OpenSSL/cffi?\n\n", "before_files": [{"content": "# This file is dual licensed under the terms of the Apache License, Version\n# 2.0, and the BSD License. See the LICENSE file in the root of this repository\n# for complete details.\n\nfrom __future__ import absolute_import, division, print_function\n\nimport abc\n\nimport six\n\nfrom cryptography import utils\n\n\n@six.add_metaclass(abc.ABCMeta)\nclass Mode(object):\n    @abc.abstractproperty\n    def name(self):\n        \"\"\"\n        A string naming this mode (e.g. \"ECB\", \"CBC\").\n        \"\"\"\n\n    @abc.abstractmethod\n    def validate_for_algorithm(self, algorithm):\n        \"\"\"\n        Checks that all the necessary invariants of this (mode, algorithm)\n        combination are met.\n        \"\"\"\n\n\n@six.add_metaclass(abc.ABCMeta)\nclass ModeWithInitializationVector(object):\n    @abc.abstractproperty\n    def initialization_vector(self):\n        \"\"\"\n        The value of the initialization vector for this mode as bytes.\n        \"\"\"\n\n\n@six.add_metaclass(abc.ABCMeta)\nclass ModeWithNonce(object):\n    @abc.abstractproperty\n    def nonce(self):\n        \"\"\"\n        The value of the nonce for this mode as bytes.\n        \"\"\"\n\n\n@six.add_metaclass(abc.ABCMeta)\nclass ModeWithAuthenticationTag(object):\n    @abc.abstractproperty\n    def tag(self):\n        \"\"\"\n        The value of the tag supplied to the constructor of this mode.\n        \"\"\"\n\n\ndef _check_iv_length(self, algorithm):\n    if len(self.initialization_vector) * 8 != algorithm.block_size:\n        raise ValueError(\"Invalid IV size ({0}) for {1}.\".format(\n            len(self.initialization_vector), self.name\n        ))\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithInitializationVector)\nclass CBC(object):\n    name = \"CBC\"\n\n    def __init__(self, initialization_vector):\n        self._initialization_vector = initialization_vector\n\n    initialization_vector = utils.read_only_property(\"_initialization_vector\")\n    validate_for_algorithm = _check_iv_length\n\n\n@utils.register_interface(Mode)\nclass ECB(object):\n    name = \"ECB\"\n\n    def validate_for_algorithm(self, algorithm):\n        pass\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithInitializationVector)\nclass OFB(object):\n    name = \"OFB\"\n\n    def __init__(self, initialization_vector):\n        self._initialization_vector = initialization_vector\n\n    initialization_vector = utils.read_only_property(\"_initialization_vector\")\n    validate_for_algorithm = _check_iv_length\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithInitializationVector)\nclass CFB(object):\n    name = \"CFB\"\n\n    def __init__(self, initialization_vector):\n        self._initialization_vector = initialization_vector\n\n    initialization_vector = utils.read_only_property(\"_initialization_vector\")\n    validate_for_algorithm = _check_iv_length\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithInitializationVector)\nclass CFB8(object):\n    name = \"CFB8\"\n\n    def __init__(self, initialization_vector):\n        self._initialization_vector = initialization_vector\n\n    initialization_vector = utils.read_only_property(\"_initialization_vector\")\n    validate_for_algorithm = _check_iv_length\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithNonce)\nclass CTR(object):\n    name = \"CTR\"\n\n    def __init__(self, nonce):\n        self._nonce = nonce\n\n    nonce = utils.read_only_property(\"_nonce\")\n\n    def validate_for_algorithm(self, algorithm):\n        if len(self.nonce) * 8 != algorithm.block_size:\n            raise ValueError(\"Invalid nonce size ({0}) for {1}.\".format(\n                len(self.nonce), self.name\n            ))\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithInitializationVector)\n@utils.register_interface(ModeWithAuthenticationTag)\nclass GCM(object):\n    name = \"GCM\"\n    _MAX_ENCRYPTED_BYTES = (2 ** 39 - 256) // 8\n    _MAX_AAD_BYTES = (2 ** 64) // 8\n\n    def __init__(self, initialization_vector, tag=None, min_tag_length=16):\n        # len(initialization_vector) must in [1, 2 ** 64), but it's impossible\n        # to actually construct a bytes object that large, so we don't check\n        # for it\n        if min_tag_length < 4:\n            raise ValueError(\"min_tag_length must be >= 4\")\n        if tag is not None and len(tag) < min_tag_length:\n            raise ValueError(\n                \"Authentication tag must be {0} bytes or longer.\".format(\n                    min_tag_length)\n            )\n\n        self._initialization_vector = initialization_vector\n        self._tag = tag\n\n    tag = utils.read_only_property(\"_tag\")\n    initialization_vector = utils.read_only_property(\"_initialization_vector\")\n\n    def validate_for_algorithm(self, algorithm):\n        pass\n", "path": "src/cryptography/hazmat/primitives/ciphers/modes.py"}], "after_files": [{"content": "# This file is dual licensed under the terms of the Apache License, Version\n# 2.0, and the BSD License. See the LICENSE file in the root of this repository\n# for complete details.\n\nfrom __future__ import absolute_import, division, print_function\n\nimport abc\n\nimport six\n\nfrom cryptography import utils\n\n\n@six.add_metaclass(abc.ABCMeta)\nclass Mode(object):\n    @abc.abstractproperty\n    def name(self):\n        \"\"\"\n        A string naming this mode (e.g. \"ECB\", \"CBC\").\n        \"\"\"\n\n    @abc.abstractmethod\n    def validate_for_algorithm(self, algorithm):\n        \"\"\"\n        Checks that all the necessary invariants of this (mode, algorithm)\n        combination are met.\n        \"\"\"\n\n\n@six.add_metaclass(abc.ABCMeta)\nclass ModeWithInitializationVector(object):\n    @abc.abstractproperty\n    def initialization_vector(self):\n        \"\"\"\n        The value of the initialization vector for this mode as bytes.\n        \"\"\"\n\n\n@six.add_metaclass(abc.ABCMeta)\nclass ModeWithNonce(object):\n    @abc.abstractproperty\n    def nonce(self):\n        \"\"\"\n        The value of the nonce for this mode as bytes.\n        \"\"\"\n\n\n@six.add_metaclass(abc.ABCMeta)\nclass ModeWithAuthenticationTag(object):\n    @abc.abstractproperty\n    def tag(self):\n        \"\"\"\n        The value of the tag supplied to the constructor of this mode.\n        \"\"\"\n\n\ndef _check_iv_length(self, algorithm):\n    if len(self.initialization_vector) * 8 != algorithm.block_size:\n        raise ValueError(\"Invalid IV size ({0}) for {1}.\".format(\n            len(self.initialization_vector), self.name\n        ))\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithInitializationVector)\nclass CBC(object):\n    name = \"CBC\"\n\n    def __init__(self, initialization_vector):\n        if not isinstance(initialization_vector, bytes):\n            raise TypeError(\"initialization_vector must be bytes\")\n\n        self._initialization_vector = initialization_vector\n\n    initialization_vector = utils.read_only_property(\"_initialization_vector\")\n    validate_for_algorithm = _check_iv_length\n\n\n@utils.register_interface(Mode)\nclass ECB(object):\n    name = \"ECB\"\n\n    def validate_for_algorithm(self, algorithm):\n        pass\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithInitializationVector)\nclass OFB(object):\n    name = \"OFB\"\n\n    def __init__(self, initialization_vector):\n        if not isinstance(initialization_vector, bytes):\n            raise TypeError(\"initialization_vector must be bytes\")\n\n        self._initialization_vector = initialization_vector\n\n    initialization_vector = utils.read_only_property(\"_initialization_vector\")\n    validate_for_algorithm = _check_iv_length\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithInitializationVector)\nclass CFB(object):\n    name = \"CFB\"\n\n    def __init__(self, initialization_vector):\n        if not isinstance(initialization_vector, bytes):\n            raise TypeError(\"initialization_vector must be bytes\")\n\n        self._initialization_vector = initialization_vector\n\n    initialization_vector = utils.read_only_property(\"_initialization_vector\")\n    validate_for_algorithm = _check_iv_length\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithInitializationVector)\nclass CFB8(object):\n    name = \"CFB8\"\n\n    def __init__(self, initialization_vector):\n        if not isinstance(initialization_vector, bytes):\n            raise TypeError(\"initialization_vector must be bytes\")\n\n        self._initialization_vector = initialization_vector\n\n    initialization_vector = utils.read_only_property(\"_initialization_vector\")\n    validate_for_algorithm = _check_iv_length\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithNonce)\nclass CTR(object):\n    name = \"CTR\"\n\n    def __init__(self, nonce):\n        if not isinstance(nonce, bytes):\n            raise TypeError(\"nonce must be bytes\")\n\n        self._nonce = nonce\n\n    nonce = utils.read_only_property(\"_nonce\")\n\n    def validate_for_algorithm(self, algorithm):\n        if len(self.nonce) * 8 != algorithm.block_size:\n            raise ValueError(\"Invalid nonce size ({0}) for {1}.\".format(\n                len(self.nonce), self.name\n            ))\n\n\n@utils.register_interface(Mode)\n@utils.register_interface(ModeWithInitializationVector)\n@utils.register_interface(ModeWithAuthenticationTag)\nclass GCM(object):\n    name = \"GCM\"\n    _MAX_ENCRYPTED_BYTES = (2 ** 39 - 256) // 8\n    _MAX_AAD_BYTES = (2 ** 64) // 8\n\n    def __init__(self, initialization_vector, tag=None, min_tag_length=16):\n        # len(initialization_vector) must in [1, 2 ** 64), but it's impossible\n        # to actually construct a bytes object that large, so we don't check\n        # for it\n        if min_tag_length < 4:\n            raise ValueError(\"min_tag_length must be >= 4\")\n        if tag is not None and len(tag) < min_tag_length:\n            raise ValueError(\n                \"Authentication tag must be {0} bytes or longer.\".format(\n                    min_tag_length)\n            )\n\n        if not isinstance(initialization_vector, bytes):\n            raise TypeError(\"initialization_vector must be bytes\")\n\n        if tag is not None and not isinstance(tag, bytes):\n            raise TypeError(\"tag must be bytes or None\")\n\n        self._initialization_vector = initialization_vector\n        self._tag = tag\n\n    tag = utils.read_only_property(\"_tag\")\n    initialization_vector = utils.read_only_property(\"_initialization_vector\")\n\n    def validate_for_algorithm(self, algorithm):\n        pass\n", "path": "src/cryptography/hazmat/primitives/ciphers/modes.py"}]}