• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5from __future__ import absolute_import, division, print_function
6
7from cryptography import utils
8from cryptography.hazmat.primitives.ciphers import (
9    BlockCipherAlgorithm,
10    CipherAlgorithm,
11)
12from cryptography.hazmat.primitives.ciphers.modes import ModeWithNonce
13
14
15def _verify_key_size(algorithm, key):
16    # Verify that the key is instance of bytes
17    utils._check_byteslike("key", key)
18
19    # Verify that the key size matches the expected key size
20    if len(key) * 8 not in algorithm.key_sizes:
21        raise ValueError(
22            "Invalid key size ({}) for {}.".format(
23                len(key) * 8, algorithm.name
24            )
25        )
26    return key
27
28
29@utils.register_interface(BlockCipherAlgorithm)
30@utils.register_interface(CipherAlgorithm)
31class AES(object):
32    name = "AES"
33    block_size = 128
34    # 512 added to support AES-256-XTS, which uses 512-bit keys
35    key_sizes = frozenset([128, 192, 256, 512])
36
37    def __init__(self, key):
38        self.key = _verify_key_size(self, key)
39
40    @property
41    def key_size(self):
42        return len(self.key) * 8
43
44
45@utils.register_interface(BlockCipherAlgorithm)
46@utils.register_interface(CipherAlgorithm)
47class Camellia(object):
48    name = "camellia"
49    block_size = 128
50    key_sizes = frozenset([128, 192, 256])
51
52    def __init__(self, key):
53        self.key = _verify_key_size(self, key)
54
55    @property
56    def key_size(self):
57        return len(self.key) * 8
58
59
60@utils.register_interface(BlockCipherAlgorithm)
61@utils.register_interface(CipherAlgorithm)
62class TripleDES(object):
63    name = "3DES"
64    block_size = 64
65    key_sizes = frozenset([64, 128, 192])
66
67    def __init__(self, key):
68        if len(key) == 8:
69            key += key + key
70        elif len(key) == 16:
71            key += key[:8]
72        self.key = _verify_key_size(self, key)
73
74    @property
75    def key_size(self):
76        return len(self.key) * 8
77
78
79@utils.register_interface(BlockCipherAlgorithm)
80@utils.register_interface(CipherAlgorithm)
81class Blowfish(object):
82    name = "Blowfish"
83    block_size = 64
84    key_sizes = frozenset(range(32, 449, 8))
85
86    def __init__(self, key):
87        self.key = _verify_key_size(self, key)
88
89    @property
90    def key_size(self):
91        return len(self.key) * 8
92
93
94@utils.register_interface(BlockCipherAlgorithm)
95@utils.register_interface(CipherAlgorithm)
96class CAST5(object):
97    name = "CAST5"
98    block_size = 64
99    key_sizes = frozenset(range(40, 129, 8))
100
101    def __init__(self, key):
102        self.key = _verify_key_size(self, key)
103
104    @property
105    def key_size(self):
106        return len(self.key) * 8
107
108
109@utils.register_interface(CipherAlgorithm)
110class ARC4(object):
111    name = "RC4"
112    key_sizes = frozenset([40, 56, 64, 80, 128, 160, 192, 256])
113
114    def __init__(self, key):
115        self.key = _verify_key_size(self, key)
116
117    @property
118    def key_size(self):
119        return len(self.key) * 8
120
121
122@utils.register_interface(CipherAlgorithm)
123class IDEA(object):
124    name = "IDEA"
125    block_size = 64
126    key_sizes = frozenset([128])
127
128    def __init__(self, key):
129        self.key = _verify_key_size(self, key)
130
131    @property
132    def key_size(self):
133        return len(self.key) * 8
134
135
136@utils.register_interface(BlockCipherAlgorithm)
137@utils.register_interface(CipherAlgorithm)
138class SEED(object):
139    name = "SEED"
140    block_size = 128
141    key_sizes = frozenset([128])
142
143    def __init__(self, key):
144        self.key = _verify_key_size(self, key)
145
146    @property
147    def key_size(self):
148        return len(self.key) * 8
149
150
151@utils.register_interface(CipherAlgorithm)
152@utils.register_interface(ModeWithNonce)
153class ChaCha20(object):
154    name = "ChaCha20"
155    key_sizes = frozenset([256])
156
157    def __init__(self, key, nonce):
158        self.key = _verify_key_size(self, key)
159        utils._check_byteslike("nonce", nonce)
160
161        if len(nonce) != 16:
162            raise ValueError("nonce must be 128-bits (16 bytes)")
163
164        self._nonce = nonce
165
166    nonce = utils.read_only_property("_nonce")
167
168    @property
169    def key_size(self):
170        return len(self.key) * 8
171