1 # =============================================================================
2 # Copyright (c) 2008 Christophe Oosterlynck (christophe.oosterlynck@gmail.com)
3 # Philippe Teuwen (philippe.teuwen@nxp.com)
5 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 # of this software and associated documentation files (the "Software"), to deal
7 # in the Software without restriction, including without limitation the rights
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 # copies of the Software, and to permit persons to whom the Software is
10 # furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 # =============================================================================
23 from ..Util
import util
24 from array
import array
25 from ..Util
.padding
import Padding
36 """ Base class for all blockciphers
39 key_error_message
= "Wrong key size" #should be overwritten in child classes
41 def __init__(self
,key
,mode
,IV
,counter
,cipher_module
,args
={}):
42 # Cipher classes inheriting from this one take care of:
50 if 'keylen_valid' in dir(self
): #wrappers for pycrypto functions don't have this function
51 if not self
.keylen_valid(key
) and type(key
) is not tuple:
52 raise ValueError(self
.key_error_message
)
55 self
.cipher
= cipher_module(self
.key
,**args
)
57 self
.chain
= ECB(self
.cipher
, self
.blocksize
)
58 elif mode
== MODE_CBC
:
60 raise Exception,"Provide an IV!"
61 if len(IV
) <> self
.blocksize
:
62 raise Exception,"the IV length should be %i bytes"%self
.blocksize
63 self
.chain
= CBC(self
.cipher
, self
.blocksize
,IV
)
64 elif mode
== MODE_CFB
:
66 raise Exception,"Provide an IV!"
67 if len(IV
) <> self
.blocksize
:
68 raise Exception,"the IV length should be %i bytes"%self
.blocksize
69 self
.chain
= CFB(self
.cipher
, self
.blocksize
,IV
)
70 elif mode
== MODE_OFB
:
72 raise Exception,"Provide an IV!"
73 if len(IV
) <> self
.blocksize
:
74 raise ValueError("the IV length should be %i bytes"%self
.blocksize
)
75 self
.chain
= OFB(self
.cipher
, self
.blocksize
,IV
)
76 elif mode
== MODE_CTR
:
77 if (counter
== None) or not callable(counter
):
78 raise Exception,"Supply a valid counter object for the CTR mode"
79 self
.chain
= CTR(self
.cipher
,self
.blocksize
,counter
)
80 elif mode
== MODE_XTS
:
81 if self
.blocksize
<> 16:
82 raise Exception,'XTS only works with blockcipher that have a 128-bit blocksize'
83 if not(type(key
) == tuple and len(key
) == 2):
84 raise Exception,'Supply two keys as a tuple when using XTS'
85 if 'keylen_valid' in dir(self
): #wrappers for pycrypto functions don't have this function
86 if not self
.keylen_valid(key
[0]) or not self
.keylen_valid(key
[1]):
87 raise ValueError(self
.key_error_message
)
88 self
.cipher
= cipher_module(self
.key
[0],**args
)
89 self
.cipher2
= cipher_module(self
.key
[1],**args
)
90 self
.chain
= XTS(self
.cipher
, self
.cipher2
)
91 elif mode
== MODE_CMAC
:
92 if self
.blocksize
not in (8,16):
93 raise Exception,'CMAC only works with blockcipher that have a 64 or 128-bit blocksize'
94 self
.chain
= CMAC(self
.cipher
,self
.blocksize
)
96 raise Exception,"Unknown chaining mode!"
98 def encrypt(self
,plaintext
,n
=''):
99 """Encrypt some plaintext
101 plaintext = a string of binary data
102 n = the 'tweak' value when the chaining mode is XTS
104 The encrypt function will encrypt the supplied plaintext.
105 The behavior varies slightly depending on the chaining mode.
109 When the supplied plaintext is not a multiple of the blocksize
110 of the cipher, then the remaining plaintext will be cached.
111 The next time the encrypt function is called with some plaintext,
112 the new plaintext will be concatenated to the cache and then
113 cache+plaintext will be encrypted.
117 When the chaining mode allows the cipher to act as a stream cipher,
118 the encrypt function will always encrypt all of the supplied
119 plaintext immediately. No cache will be kept.
123 Because the handling of the last two blocks is linked,
124 it needs the whole block of plaintext to be supplied at once.
125 Every encrypt function called on a XTS cipher will output
126 an encrypted block based on the current supplied plaintext block.
130 Everytime the function is called, the hash from the input data is calculated.
131 No finalizing needed.
132 The hashlength is equal to block size of the used block cipher.
134 #self.ed = 'e' if chain is encrypting, 'd' if decrypting,
135 # None if nothing happened with the chain yet
136 #assert self.ed in ('e',None)
137 # makes sure you don't encrypt with a cipher that has started decrypting
139 if self
.mode
== MODE_XTS
:
140 # data sequence number (or 'tweak') has to be provided when in XTS mode
141 return self
.chain
.update(plaintext
,'e',n
)
143 return self
.chain
.update(plaintext
,'e')
145 def decrypt(self
,ciphertext
,n
=''):
146 """Decrypt some ciphertext
148 ciphertext = a string of binary data
149 n = the 'tweak' value when the chaining mode is XTS
151 The decrypt function will decrypt the supplied ciphertext.
152 The behavior varies slightly depending on the chaining mode.
156 When the supplied ciphertext is not a multiple of the blocksize
157 of the cipher, then the remaining ciphertext will be cached.
158 The next time the decrypt function is called with some ciphertext,
159 the new ciphertext will be concatenated to the cache and then
160 cache+ciphertext will be decrypted.
164 When the chaining mode allows the cipher to act as a stream cipher,
165 the decrypt function will always decrypt all of the supplied
166 ciphertext immediately. No cache will be kept.
170 Because the handling of the last two blocks is linked,
171 it needs the whole block of ciphertext to be supplied at once.
172 Every decrypt function called on a XTS cipher will output
173 a decrypted block based on the current supplied ciphertext block.
177 Mode not supported for decryption as this does not make sense.
179 #self.ed = 'e' if chain is encrypting, 'd' if decrypting,
180 # None if nothing happened with the chain yet
181 #assert self.ed in ('d',None)
182 # makes sure you don't decrypt with a cipher that has started encrypting
184 if self
.mode
== MODE_XTS
:
185 # data sequence number (or 'tweak') has to be provided when in XTS mode
186 return self
.chain
.update(ciphertext
,'d',n
)
188 return self
.chain
.update(ciphertext
,'d')
190 def final(self
,padding
='PKCS7'):
191 # TODO: after calling final, reset the IV? so the cipher is as good as new?
192 """Finalizes the encryption by padding the cache
194 padding = padding function provided as an argument. Possible padding functions:
201 While a cipher object is in encryption mode, the final function will pad the remaining cache and encrypt it.
202 If the cipher has been used for decryption, the final function won't do antyhing. You have to manually unpad if necessary or
203 construct a Padder yourself en use its unpad function.
205 After finalization, the chain can still be used but the IV, counter etc aren't reset but just continu as they were after the last step (finalization step).
207 assert self
.mode
not in (MODE_XTS
, MODE_CMAC
) # finalizing (=padding) doesn't make sense when in XTS or CMAC mode
209 # when the chain is in encryption mode, finalizing will pad the cache and encrypt this last block
210 padder
= Padding(self
.blocksize
)
211 if self
.mode
in (MODE_OFB
,MODE_CFB
,MODE_CTR
):
212 dummy
= '0'*(self
.blocksize
- self
.chain
.keystream
.buffer_info()[1]) # a dummy string that will be used to get a valid padding
214 dummy
= self
.chain
.cache
215 return self
.chain
.update(padder
.pad(dummy
,padding
)[len(dummy
):],'e') # pad the cache and then only supply the padding to the update function
217 # final function doesn't make sense when decrypting => padding should be removed manually
223 def __init__(self
, codebook
, blocksize
):
225 self
.codebook
= codebook
226 self
.blocksize
= blocksize
228 def update(self
, data
, ed
):
229 """Processes the given ciphertext/plaintext
232 data: raw string of any length
233 ed: 'e' for encryption, 'd' for decryption
235 processed raw string block(s), if any
237 When the supplied data is not a multiple of the blocksize
238 of the cipher, then the remaining input data will be cached.
239 The next time the update function is called with some data,
240 the new data will be concatenated to the cache and then
241 cache+data will be processed and full blocks will be outputted.
245 if len(self
.cache
) < self
.blocksize
:
247 for i
in xrange(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
248 #the only difference between encryption/decryption in the chain is the cipher block
250 output_blocks
.append(self
.codebook
.encrypt( self
.cache
[i
:i
+ self
.blocksize
] ))
252 output_blocks
.append(self
.codebook
.decrypt( self
.cache
[i
:i
+ self
.blocksize
] ))
253 self
.cache
= self
.cache
[i
+self
.blocksize
:]
254 return ''.join(output_blocks
)
259 def __init__(self
, codebook
, blocksize
, IV
):
262 self
.codebook
= codebook
263 self
.blocksize
= blocksize
265 def update(self
, data
, ed
):
266 """Processes the given ciphertext/plaintext
269 data: raw string of any length
270 ed: 'e' for encryption, 'd' for decryption
272 processed raw string block(s), if any
274 When the supplied data is not a multiple of the blocksize
275 of the cipher, then the remaining input data will be cached.
276 The next time the update function is called with some data,
277 the new data will be concatenated to the cache and then
278 cache+data will be processed and full blocks will be outputted.
281 encrypted_blocks
= ''
283 if len(self
.cache
) < self
.blocksize
:
285 for i
in xrange(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
286 self
.IV
= self
.codebook
.encrypt(util
.xorstring(self
.cache
[i
:i
+self
.blocksize
],self
.IV
))
287 encrypted_blocks
+= self
.IV
288 self
.cache
= self
.cache
[i
+self
.blocksize
:]
289 return encrypted_blocks
291 decrypted_blocks
= ''
293 if len(self
.cache
) < self
.blocksize
:
295 for i
in xrange(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
296 plaintext
= util
.xorstring(self
.IV
,self
.codebook
.decrypt(self
.cache
[i
:i
+ self
.blocksize
]))
297 self
.IV
= self
.cache
[i
:i
+ self
.blocksize
]
298 decrypted_blocks
+=plaintext
299 self
.cache
= self
.cache
[i
+self
.blocksize
:]
300 return decrypted_blocks
305 Can be accessed as a stream cipher.
308 def __init__(self
, codebook
, blocksize
, IV
):
309 self
.codebook
= codebook
311 self
.blocksize
= blocksize
313 def update(self
, data
, ed
):
314 """Processes the given ciphertext/plaintext
317 data: raw string of any multiple of bytes
318 ed: 'e' for encryption, 'd' for decryption
322 The encrypt/decrypt functions will always process all of the supplied
323 input data immediately. No cache will be kept.
327 for i
in xrange(len(data
)):
329 if len(self
.keystream
) == 0:
330 block
= self
.codebook
.encrypt(self
.IV
)
331 self
.keystream
= list(block
)
333 output
[i
] = chr(ord(output
[i
]) ^
ord(self
.keystream
.pop(0)))
334 self
.IV
+= output
[i
] # the IV for the next block in the chain is being built byte per byte as the ciphertext flows in
336 if len(self
.keystream
) == 0:
337 block
= self
.codebook
.encrypt(self
.IV
)
338 self
.keystream
= list(block
)
341 output
[i
] = chr(ord(output
[i
]) ^
ord(self
.keystream
.pop(0)))
342 return ''.join(output
)
347 Can be accessed as a stream cipher.
349 def __init__(self
, codebook
, blocksize
, IV
):
350 self
.codebook
= codebook
352 self
.blocksize
= blocksize
354 def update(self
, data
, ed
):
355 """Processes the given ciphertext/plaintext
358 data: raw string of any multiple of bytes
359 ed: 'e' for encryption, 'd' for decryption
363 The encrypt/decrypt functions will always process all of the supplied
364 input data immediately. No cache will be kept.
366 #no difference between encryption and decryption mode
368 blocksize
= self
.blocksize
372 if len(self
.keystream
) == 0: #encrypt a new counter block when the current keystream is fully used
373 self
.IV
= self
.codebook
.encrypt(self
.IV
)
374 self
.keystream
= list(self
.IV
)
375 output
[i
] = chr(ord(output
[i
]) ^
ord(self
.keystream
.pop(0))) #as long as an encrypted counter value is available, the output is just "input XOR keystream"
376 return ''.join(output
)
381 Can be accessed as a stream cipher.
383 # initial counter value can be choosen, decryption always starts from beginning
384 # -> you can start from anywhere yourself: just feed the cipher encoded blocks and feed a counter with the corresponding value
385 def __init__(self
, codebook
, blocksize
, counter
):
386 self
.codebook
= codebook
387 self
.counter
= counter
388 self
.blocksize
= blocksize
389 self
.keystream
= [] #holds the output of the current encrypted counter value
391 def update(self
, data
, ed
):
392 """Processes the given ciphertext/plaintext
395 data: raw string of any multiple of bytes
396 ed: 'e' for encryption, 'd' for decryption
400 The encrypt/decrypt functions will always process all of the supplied
401 input data immediately. No cache will be kept.
403 # no need for the encryption/decryption distinction: both are the same
405 blocksize
= self
.blocksize
409 if len(self
.keystream
) == 0: #encrypt a new counter block when the current keystream is fully used
410 block
= self
.codebook
.encrypt(self
.counter())
411 self
.keystream
= list(block
)
412 output
[i
] = chr(ord(output
[i
])^
ord(self
.keystream
.pop(0))) #as long as an encrypted counter value is available, the output is just "input XOR keystream"
413 return ''.join(output
)
418 # TODO: allow other blocksizes besides 16bytes?
419 def __init__(self
,codebook1
, codebook2
):
421 self
.codebook1
= codebook1
422 self
.codebook2
= codebook2
424 def update(self
, data
, ed
,tweak
=''):
425 # supply n as a raw string
426 # tweak = data sequence number
427 """Perform a XTS encrypt/decrypt operation.
429 Because the handling of the last two blocks is linked,
430 it needs the whole block of ciphertext to be supplied at once.
431 Every decrypt function called on a XTS cipher will output
432 a decrypted block based on the current supplied ciphertext block.
435 assert len(data
) > 15, "At least one block of 128 bits needs to be supplied"
436 assert len(data
) < 128*pow(2,20)
439 # e_k2_n = E_K2(tweak)
440 e_k2_n
= self
.codebook2
.encrypt(tweak
+ '\x00' * (16-len(tweak
)))[::-1]
441 self
.T
= util
.string2number(e_k2_n
)
444 while i
< ((len(data
) // 16)-1): #Decrypt all the blocks but one last full block and opt one last partial block
445 # C = E_K1(P xor T) xor T
446 output
+= self
.__xts
_step
(ed
,data
[i
*16:(i
+1)*16],self
.T
)
447 # T = E_K2(n) mul (a pow i)
451 # Check if the data supplied is a multiple of 16 bytes -> one last full block and we're done
452 if len(data
[i
*16:]) == 16:
453 # C = E_K1(P xor T) xor T
454 output
+= self
.__xts
_step
(ed
,data
[i
*16:(i
+1)*16],self
.T
)
455 # T = E_K2(n) mul (a pow i)
460 T_temp
.append(self
.T
)
462 # Permutation of the last two indexes
464 # Decrypt/Encrypt the last two blocks when data is not a multiple of 16 bytes
465 Cm1
= data
[i
*16:(i
+1)*16]
467 PP
= self
.__xts
_step
(ed
,Cm1
,T_temp
[0])
471 Pm1
= self
.__xts
_step
(ed
,CC
,T_temp
[1])
475 def __xts_step(self
,ed
,tocrypt
,T
):
476 T_string
= util
.number2string_N(T
,16)[::-1]
477 # C = E_K1(P xor T) xor T
479 return util
.xorstring(T_string
, self
.codebook1
.decrypt(util
.xorstring(T_string
, tocrypt
)))
481 return util
.xorstring(T_string
, self
.codebook1
.encrypt(util
.xorstring(T_string
, tocrypt
)))
483 def __T_update(self
):
484 # Used for calculating T for a certain step using the T value from the previous step
488 #T[0] ^= GF_128_FDBK;
489 self
.T
= self
.T ^
0x100000000000000000000000000000087L
493 """CMAC chaining mode
495 Supports every cipher with a blocksize available
496 in the list CMAC.supported_blocksizes.
497 The hashlength is equal to block size of the used block cipher.
499 # TODO: move to hash module?
500 # TODO: change update behaviour to .update() and .digest() as for all hash modules?
501 # -> other hash functions in pycrypto: calling update, concatenates current input with previous input and hashes everything
502 __Rb_dictionary
= {64:0x000000000000001b,128:0x00000000000000000000000000000087}
503 supported_blocksizes
= __Rb_dictionary
.keys()
504 def __init__(self
,codebook
,blocksize
):
505 # Purpose of init: calculate Lu & Lu2
506 #blocksize (in bytes): to select the Rb constant in the dictionary
507 #Rb as a dictionary: adding support for other blocksizes is easy
509 self
.blocksize
= blocksize
510 self
.codebook
= codebook
512 #Rb_dictionary: holds values for Rb for different blocksizes
513 # values for 64 and 128 bits found here: http://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html
514 # explanation from: http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf
515 # Rb is a representation of a certain irreducible binary polynomial of degree b, namely,
516 # the lexicographically first among all such polynomials with the minimum possible number of
517 # nonzero terms. If this polynomial is expressed as ub+cb-1ub-1+...+c2u2+c1u+c0, where the
518 # coefficients cb-1, cb-2, ..., c2, c1, c0 are either 0 or 1, then Rb is the bit string cb-1cb-2...c2c1c0.
520 self
.Rb
= self
.__Rb
_dictionary
[blocksize
*8]
522 mask1
= int(('\xff'*blocksize
).encode('hex'),16)
523 mask2
= int(('\x80' + '\x00'*(blocksize
-1) ).encode('hex'),16)
525 L
= int(self
.codebook
.encrypt('\x00'*blocksize
).encode('hex'),16)
528 Lu
= ((L
<< 1) & mask1
) ^ self
.Rb
534 Lu2
= ((Lu
<< 1) & mask1
)^ self
.Rb
539 self
.Lu
=util
.number2string_N(Lu
,self
.blocksize
)
540 self
.Lu2
=util
.number2string_N(Lu2
,self
.blocksize
)
542 def update(self
, data
, ed
):
543 """Processes the given ciphertext/plaintext
546 data: raw string of any length
547 ed: 'e' for encryption, 'd' for decryption
549 hashed data as raw string
551 This is not really an update function:
552 Everytime the function is called, the hash from the input data is calculated.
553 No finalizing needed.
556 blocksize
= self
.blocksize
558 m
= (len(data
)+blocksize
-1)/blocksize
#m = amount of datablocks
562 y
= self
.codebook
.encrypt( util
.xorstring(data
[(i
-1)*blocksize
:(i
)*blocksize
],y
) )
564 if len(data
[(i
)*blocksize
:])==blocksize
:
565 X
= util
.xorstring(util
.xorstring(data
[(i
)*blocksize
:],y
),self
.Lu
)
567 tmp
= data
[(i
)*blocksize
:] + '\x80' + '\x00'*(blocksize
- len(data
[(i
)*blocksize
:])-1)
568 X
= util
.xorstring(util
.xorstring(tmp
,y
),self
.Lu2
)
570 T
= self
.codebook
.encrypt(X
)