Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: third_party/google-endpoints/Crypto/Cipher/blockalgo.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # -*- coding: utf-8 -*-
2 #
3 # Cipher/blockalgo.py
4 #
5 # ===================================================================
6 # The contents of this file are dedicated to the public domain. To
7 # the extent that dedication to the public domain is not available,
8 # everyone is granted a worldwide, perpetual, royalty-free,
9 # non-exclusive license to exercise all rights associated with the
10 # contents of this file for any purpose whatsoever.
11 # No rights are reserved.
12 #
13 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
17 # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18 # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 # SOFTWARE.
21 # ===================================================================
22 """Module with definitions common to all block ciphers."""
23
24 import sys
25 if sys.version_info[0] == 2 and sys.version_info[1] == 1:
26 from Crypto.Util.py21compat import *
27 from Crypto.Util.py3compat import *
28
29 #: *Electronic Code Book (ECB)*.
30 #: This is the simplest encryption mode. Each of the plaintext blocks
31 #: is directly encrypted into a ciphertext block, independently of
32 #: any other block. This mode exposes frequency of symbols
33 #: in your plaintext. Other modes (e.g. *CBC*) should be used instead.
34 #:
35 #: See `NIST SP800-38A`_ , Section 6.1 .
36 #:
37 #: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp8 00-38a.pdf
38 MODE_ECB = 1
39
40 #: *Cipher-Block Chaining (CBC)*. Each of the ciphertext blocks depends
41 #: on the current and all previous plaintext blocks. An Initialization Vector
42 #: (*IV*) is required.
43 #:
44 #: The *IV* is a data block to be transmitted to the receiver.
45 #: The *IV* can be made public, but it must be authenticated by the receiver and
46 #: it should be picked randomly.
47 #:
48 #: See `NIST SP800-38A`_ , Section 6.2 .
49 #:
50 #: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp8 00-38a.pdf
51 MODE_CBC = 2
52
53 #: *Cipher FeedBack (CFB)*. This mode is similar to CBC, but it transforms
54 #: the underlying block cipher into a stream cipher. Plaintext and ciphertext
55 #: are processed in *segments* of **s** bits. The mode is therefore sometimes
56 #: labelled **s**-bit CFB. An Initialization Vector (*IV*) is required.
57 #:
58 #: When encrypting, each ciphertext segment contributes to the encryption of
59 #: the next plaintext segment.
60 #:
61 #: This *IV* is a data block to be transmitted to the receiver.
62 #: The *IV* can be made public, but it should be picked randomly.
63 #: Reusing the same *IV* for encryptions done with the same key lead to
64 #: catastrophic cryptographic failures.
65 #:
66 #: See `NIST SP800-38A`_ , Section 6.3 .
67 #:
68 #: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp8 00-38a.pdf
69 MODE_CFB = 3
70
71 #: This mode should not be used.
72 MODE_PGP = 4
73
74 #: *Output FeedBack (OFB)*. This mode is very similar to CBC, but it
75 #: transforms the underlying block cipher into a stream cipher.
76 #: The keystream is the iterated block encryption of an Initialization Vector (* IV*).
77 #:
78 #: The *IV* is a data block to be transmitted to the receiver.
79 #: The *IV* can be made public, but it should be picked randomly.
80 #:
81 #: Reusing the same *IV* for encryptions done with the same key lead to
82 #: catastrophic cryptograhic failures.
83 #:
84 #: See `NIST SP800-38A`_ , Section 6.4 .
85 #:
86 #: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp8 00-38a.pdf
87 MODE_OFB = 5
88
89 #: *CounTeR (CTR)*. This mode is very similar to ECB, in that
90 #: encryption of one block is done independently of all other blocks.
91 #: Unlike ECB, the block *position* contributes to the encryption and no
92 #: information leaks about symbol frequency.
93 #:
94 #: Each message block is associated to a *counter* which must be unique
95 #: across all messages that get encrypted with the same key (not just within
96 #: the same message). The counter is as big as the block size.
97 #:
98 #: Counters can be generated in several ways. The most straightword one is
99 #: to choose an *initial counter block* (which can be made public, similarly
100 #: to the *IV* for the other modes) and increment its lowest **m** bits by
101 #: one (modulo *2^m*) for each block. In most cases, **m** is chosen to be half
102 #: the block size.
103 #:
104 #: Reusing the same *initial counter block* for encryptions done with the same
105 #: key lead to catastrophic cryptograhic failures.
106 #:
107 #: See `NIST SP800-38A`_ , Section 6.5 (for the mode) and Appendix B (for how
108 #: to manage the *initial counter block*).
109 #:
110 #: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp8 00-38a.pdf
111 MODE_CTR = 6
112
113 #: OpenPGP. This mode is a variant of CFB, and it is only used in PGP and OpenPG P_ applications.
114 #: An Initialization Vector (*IV*) is required.
115 #:
116 #: Unlike CFB, the IV is not transmitted to the receiver. Instead, the *encrypte d* IV is.
117 #: The IV is a random data block. Two of its bytes are duplicated to act as a ch ecksum
118 #: for the correctness of the key. The encrypted IV is therefore 2 bytes longer than
119 #: the clean IV.
120 #:
121 #: .. _OpenPGP: http://tools.ietf.org/html/rfc4880
122 MODE_OPENPGP = 7
123
124 def _getParameter(name, index, args, kwargs, default=None):
125 """Find a parameter in tuple and dictionary arguments a function receives"""
126 param = kwargs.get(name)
127 if len(args)>index:
128 if param:
129 raise ValueError("Parameter '%s' is specified twice" % name)
130 param = args[index]
131 return param or default
132
133 class BlockAlgo:
134 """Class modelling an abstract block cipher."""
135
136 def __init__(self, factory, key, *args, **kwargs):
137 self.mode = _getParameter('mode', 0, args, kwargs, default=MODE_ECB)
138 self.block_size = factory.block_size
139
140 if self.mode != MODE_OPENPGP:
141 self._cipher = factory.new(key, *args, **kwargs)
142 self.IV = self._cipher.IV
143 else:
144 # OPENPGP mode. For details, see 13.9 in RCC4880.
145 #
146 # A few members are specifically created for this mode:
147 # - _encrypted_iv, set in this constructor
148 # - _done_first_block, set to True after the first encryption
149 # - _done_last_block, set to True after a partial block is processe d
150
151 self._done_first_block = False
152 self._done_last_block = False
153 self.IV = _getParameter('iv', 1, args, kwargs)
154 if not self.IV:
155 raise ValueError("MODE_OPENPGP requires an IV")
156
157 # Instantiate a temporary cipher to process the IV
158 IV_cipher = factory.new(key, MODE_CFB,
159 b('\x00')*self.block_size, # IV for CFB
160 segment_size=self.block_size*8)
161
162 # The cipher will be used for...
163 if len(self.IV) == self.block_size:
164 # ... encryption
165 self._encrypted_IV = IV_cipher.encrypt(
166 self.IV + self.IV[-2:] + # Plaintext
167 b('\x00')*(self.block_size-2) # Padding
168 )[:self.block_size+2]
169 elif len(self.IV) == self.block_size+2:
170 # ... decryption
171 self._encrypted_IV = self.IV
172 self.IV = IV_cipher.decrypt(self.IV + # Ciphertext
173 b('\x00')*(self.block_size-2) # Padding
174 )[:self.block_size+2]
175 if self.IV[-2:] != self.IV[-4:-2]:
176 raise ValueError("Failed integrity check for OPENPGP IV")
177 self.IV = self.IV[:-2]
178 else:
179 raise ValueError("Length of IV must be %d or %d bytes for MODE_O PENPGP"
180 % (self.block_size, self.block_size+2))
181
182 # Instantiate the cipher for the real PGP data
183 self._cipher = factory.new(key, MODE_CFB,
184 self._encrypted_IV[-self.block_size:],
185 segment_size=self.block_size*8)
186
187 def encrypt(self, plaintext):
188 """Encrypt data with the key and the parameters set at initialization.
189
190 The cipher object is stateful; encryption of a long block
191 of data can be broken up in two or more calls to `encrypt()`.
192 That is, the statement:
193
194 >>> c.encrypt(a) + c.encrypt(b)
195
196 is always equivalent to:
197
198 >>> c.encrypt(a+b)
199
200 That also means that you cannot reuse an object for encrypting
201 or decrypting other data with the same key.
202
203 This function does not perform any padding.
204
205 - For `MODE_ECB`, `MODE_CBC`, and `MODE_OFB`, *plaintext* length
206 (in bytes) must be a multiple of *block_size*.
207
208 - For `MODE_CFB`, *plaintext* length (in bytes) must be a multiple
209 of *segment_size*/8.
210
211 - For `MODE_CTR`, *plaintext* can be of any length.
212
213 - For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*,
214 unless it is the last chunk of the message.
215
216 :Parameters:
217 plaintext : byte string
218 The piece of data to encrypt.
219 :Return:
220 the encrypted data, as a byte string. It is as long as
221 *plaintext* with one exception: when encrypting the first message
222 chunk with `MODE_OPENPGP`, the encypted IV is prepended to the
223 returned ciphertext.
224 """
225
226 if self.mode == MODE_OPENPGP:
227 padding_length = (self.block_size - len(plaintext) % self.block_size ) % self.block_size
228 if padding_length>0:
229 # CFB mode requires ciphertext to have length multiple of block size,
230 # but PGP mode allows the last block to be shorter
231 if self._done_last_block:
232 raise ValueError("Only the last chunk is allowed to have len gth not multiple of %d bytes",
233 self.block_size)
234 self._done_last_block = True
235 padded = plaintext + b('\x00')*padding_length
236 res = self._cipher.encrypt(padded)[:len(plaintext)]
237 else:
238 res = self._cipher.encrypt(plaintext)
239 if not self._done_first_block:
240 res = self._encrypted_IV + res
241 self._done_first_block = True
242 return res
243
244 return self._cipher.encrypt(plaintext)
245
246 def decrypt(self, ciphertext):
247 """Decrypt data with the key and the parameters set at initialization.
248
249 The cipher object is stateful; decryption of a long block
250 of data can be broken up in two or more calls to `decrypt()`.
251 That is, the statement:
252
253 >>> c.decrypt(a) + c.decrypt(b)
254
255 is always equivalent to:
256
257 >>> c.decrypt(a+b)
258
259 That also means that you cannot reuse an object for encrypting
260 or decrypting other data with the same key.
261
262 This function does not perform any padding.
263
264 - For `MODE_ECB`, `MODE_CBC`, and `MODE_OFB`, *ciphertext* length
265 (in bytes) must be a multiple of *block_size*.
266
267 - For `MODE_CFB`, *ciphertext* length (in bytes) must be a multiple
268 of *segment_size*/8.
269
270 - For `MODE_CTR`, *ciphertext* can be of any length.
271
272 - For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*,
273 unless it is the last chunk of the message.
274
275 :Parameters:
276 ciphertext : byte string
277 The piece of data to decrypt.
278 :Return: the decrypted data (byte string, as long as *ciphertext*).
279 """
280 if self.mode == MODE_OPENPGP:
281 padding_length = (self.block_size - len(ciphertext) % self.block_siz e) % self.block_size
282 if padding_length>0:
283 # CFB mode requires ciphertext to have length multiple of block size,
284 # but PGP mode allows the last block to be shorter
285 if self._done_last_block:
286 raise ValueError("Only the last chunk is allowed to have len gth not multiple of %d bytes",
287 self.block_size)
288 self._done_last_block = True
289 padded = ciphertext + b('\x00')*padding_length
290 res = self._cipher.decrypt(padded)[:len(ciphertext)]
291 else:
292 res = self._cipher.decrypt(ciphertext)
293 return res
294
295 return self._cipher.decrypt(ciphertext)
296
OLDNEW
« no previous file with comments | « third_party/google-endpoints/Crypto/Cipher/__init__.py ('k') | third_party/google-endpoints/Crypto/Hash/HMAC.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698