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
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
,segment_size
,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
)
60 self
.cipher
= cipher_module(self
.key
,**args
)
62 self
.chain
= ECB(self
.cipher
, self
.blocksize
)
63 elif mode
== MODE_CBC
:
64 if len(self
.IV
) <> self
.blocksize
:
65 raise Exception,"the IV length should be %i bytes"%self
.blocksize
66 self
.chain
= CBC(self
.cipher
, self
.blocksize
,self
.IV
)
67 elif mode
== MODE_CFB
:
68 if len(self
.IV
) <> self
.blocksize
:
69 raise Exception,"the IV length should be %i bytes"%self
.blocksize
70 if segment_size
> self
.blocksize
*8 or segment_size
%8 <> 0:
71 # current CFB implementation doesn't support bit level acces => segment_size should be multiple of bytes
72 raise ValueError,"segment size should be a multiple of 8 bits between 1 and %i"%(self
.blocksize
*8)
73 self
.chain
= CFB(self
.cipher
, self
.blocksize
,self
.IV
,segment_size
)
74 elif mode
== MODE_OFB
:
75 if len(self
.IV
) <> self
.blocksize
:
76 raise ValueError("the IV length should be %i bytes"%self
.blocksize
)
77 self
.chain
= OFB(self
.cipher
, self
.blocksize
,self
.IV
)
78 elif mode
== MODE_CTR
:
79 if (counter
== None) or not callable(counter
):
80 raise Exception,"Supply a valid counter object for the CTR mode"
81 self
.chain
= CTR(self
.cipher
,self
.blocksize
,counter
)
82 elif mode
== MODE_XTS
:
83 if self
.blocksize
<> 16:
84 raise Exception,'XTS only works with blockcipher that have a 128-bit blocksize'
85 if not(type(key
) == tuple and len(key
) == 2):
86 raise Exception,'Supply two keys as a tuple when using XTS'
87 if 'keylen_valid' in dir(self
): #wrappers for pycrypto functions don't have this function
88 if not self
.keylen_valid(key
[0]) or not self
.keylen_valid(key
[1]):
89 raise ValueError(self
.key_error_message
)
90 self
.cipher
= cipher_module(self
.key
[0],**args
)
91 self
.cipher2
= cipher_module(self
.key
[1],**args
)
92 self
.chain
= XTS(self
.cipher
, self
.cipher2
)
93 elif mode
== MODE_CMAC
:
94 if self
.blocksize
not in (8,16):
95 raise Exception,'CMAC only works with blockcipher that have a 64 or 128-bit blocksize'
96 self
.chain
= CMAC(self
.cipher
,self
.blocksize
)
98 raise Exception,"Unknown chaining mode!"
100 def encrypt(self
,plaintext
,n
=''):
101 """Encrypt some plaintext
103 plaintext = a string of binary data
104 n = the 'tweak' value when the chaining mode is XTS
106 The encrypt function will encrypt the supplied plaintext.
107 The behavior varies slightly depending on the chaining mode.
111 When the supplied plaintext is not a multiple of the blocksize
112 of the cipher, then the remaining plaintext will be cached.
113 The next time the encrypt function is called with some plaintext,
114 the new plaintext will be concatenated to the cache and then
115 cache+plaintext will be encrypted.
119 When the chaining mode allows the cipher to act as a stream cipher,
120 the encrypt function will always encrypt all of the supplied
121 plaintext immediately. No cache will be kept.
125 Because the handling of the last two blocks is linked,
126 it needs the whole block of plaintext to be supplied at once.
127 Every encrypt function called on a XTS cipher will output
128 an encrypted block based on the current supplied plaintext block.
132 Everytime the function is called, the hash from the input data is calculated.
133 No finalizing needed.
134 The hashlength is equal to block size of the used block cipher.
136 #self.ed = 'e' if chain is encrypting, 'd' if decrypting,
137 # None if nothing happened with the chain yet
138 #assert self.ed in ('e',None)
139 # makes sure you don't encrypt with a cipher that has started decrypting
141 if self
.mode
== MODE_XTS
:
142 # data sequence number (or 'tweak') has to be provided when in XTS mode
143 return self
.chain
.update(plaintext
,'e',n
)
145 return self
.chain
.update(plaintext
,'e')
147 def decrypt(self
,ciphertext
,n
=''):
148 """Decrypt some ciphertext
150 ciphertext = a string of binary data
151 n = the 'tweak' value when the chaining mode is XTS
153 The decrypt function will decrypt the supplied ciphertext.
154 The behavior varies slightly depending on the chaining mode.
158 When the supplied ciphertext is not a multiple of the blocksize
159 of the cipher, then the remaining ciphertext will be cached.
160 The next time the decrypt function is called with some ciphertext,
161 the new ciphertext will be concatenated to the cache and then
162 cache+ciphertext will be decrypted.
166 When the chaining mode allows the cipher to act as a stream cipher,
167 the decrypt function will always decrypt all of the supplied
168 ciphertext immediately. No cache will be kept.
172 Because the handling of the last two blocks is linked,
173 it needs the whole block of ciphertext to be supplied at once.
174 Every decrypt function called on a XTS cipher will output
175 a decrypted block based on the current supplied ciphertext block.
179 Mode not supported for decryption as this does not make sense.
181 #self.ed = 'e' if chain is encrypting, 'd' if decrypting,
182 # None if nothing happened with the chain yet
183 #assert self.ed in ('d',None)
184 # makes sure you don't decrypt with a cipher that has started encrypting
186 if self
.mode
== MODE_XTS
:
187 # data sequence number (or 'tweak') has to be provided when in XTS mode
188 return self
.chain
.update(ciphertext
,'d',n
)
190 return self
.chain
.update(ciphertext
,'d')
192 def final(self
,padfct
=padding
.PKCS7
):
193 # TODO: after calling final, reset the IV? so the cipher is as good as new?
194 """Finalizes the encryption by padding the cache
196 padfct = padding function
197 import from CryptoPlus.Util.padding
199 For ECB, CBC: the remaining bytes in the cache will be padded and
201 For OFB,CFB, CTR: an encrypted padding will be returned, making the
202 total outputed bytes since construction of the cipher
203 a multiple of the blocksize of that cipher.
205 If the cipher has been used for decryption, the final function won't do
206 antyhing. You have to manually unpad if necessary.
208 After finalization, the chain can still be used but the IV, counter etc
209 aren't reset but just continu as they were after the last step (finalization step).
211 assert self
.mode
not in (MODE_XTS
, MODE_CMAC
) # finalizing (=padding) doesn't make sense when in XTS or CMAC mode
213 # when the chain is in encryption mode, finalizing will pad the cache and encrypt this last block
214 if self
.mode
in (MODE_OFB
,MODE_CFB
,MODE_CTR
):
215 dummy
= '0'*(self
.blocksize
- self
.chain
.keystream
.buffer_info()[1]) # a dummy string that will be used to get a valid padding
217 dummy
= self
.chain
.cache
218 return self
.chain
.update(padfct(dummy
,padding
.PAD
,self
.blocksize
)[len(dummy
):],'e') # pad the cache and then only supply the padding to the update function
220 # final function doesn't make sense when decrypting => padding should be removed manually
226 def __init__(self
, codebook
, blocksize
):
228 self
.codebook
= codebook
229 self
.blocksize
= blocksize
231 def update(self
, data
, ed
):
232 """Processes the given ciphertext/plaintext
235 data: raw string of any length
236 ed: 'e' for encryption, 'd' for decryption
238 processed raw string block(s), if any
240 When the supplied data is not a multiple of the blocksize
241 of the cipher, then the remaining input data will be cached.
242 The next time the update function is called with some data,
243 the new data will be concatenated to the cache and then
244 cache+data will be processed and full blocks will be outputted.
248 if len(self
.cache
) < self
.blocksize
:
250 for i
in xrange(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
251 #the only difference between encryption/decryption in the chain is the cipher block
253 output_blocks
.append(self
.codebook
.encrypt( self
.cache
[i
:i
+ self
.blocksize
] ))
255 output_blocks
.append(self
.codebook
.decrypt( self
.cache
[i
:i
+ self
.blocksize
] ))
256 self
.cache
= self
.cache
[i
+self
.blocksize
:]
257 return ''.join(output_blocks
)
262 def __init__(self
, codebook
, blocksize
, IV
):
265 self
.codebook
= codebook
266 self
.blocksize
= blocksize
268 def update(self
, data
, ed
):
269 """Processes the given ciphertext/plaintext
272 data: raw string of any length
273 ed: 'e' for encryption, 'd' for decryption
275 processed raw string block(s), if any
277 When the supplied data is not a multiple of the blocksize
278 of the cipher, then the remaining input data will be cached.
279 The next time the update function is called with some data,
280 the new data will be concatenated to the cache and then
281 cache+data will be processed and full blocks will be outputted.
284 encrypted_blocks
= ''
286 if len(self
.cache
) < self
.blocksize
:
288 for i
in xrange(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
289 self
.IV
= self
.codebook
.encrypt(util
.xorstring(self
.cache
[i
:i
+self
.blocksize
],self
.IV
))
290 encrypted_blocks
+= self
.IV
291 self
.cache
= self
.cache
[i
+self
.blocksize
:]
292 return encrypted_blocks
294 decrypted_blocks
= ''
296 if len(self
.cache
) < self
.blocksize
:
298 for i
in xrange(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
299 plaintext
= util
.xorstring(self
.IV
,self
.codebook
.decrypt(self
.cache
[i
:i
+ self
.blocksize
]))
300 self
.IV
= self
.cache
[i
:i
+ self
.blocksize
]
301 decrypted_blocks
+=plaintext
302 self
.cache
= self
.cache
[i
+self
.blocksize
:]
303 return decrypted_blocks
306 # TODO: bit access instead of only byte level access
309 Can be accessed as a stream cipher.
312 def __init__(self
, codebook
, blocksize
, IV
,segment_size
):
313 self
.codebook
= codebook
315 self
.blocksize
= blocksize
316 self
.segment_size
= segment_size
/8
319 def update(self
, data
, ed
):
320 """Processes the given ciphertext/plaintext
323 data: raw string of any multiple of bytes
324 ed: 'e' for encryption, 'd' for decryption
328 The encrypt/decrypt functions will always process all of the supplied
329 input data immediately. No cache will be kept.
333 for i
in xrange(len(data
)):
335 if len(self
.keystream
) == 0:
336 block
= self
.codebook
.encrypt(self
.IV
)
337 self
.keystream
= list(block
)[:self
.segment_size
] # keystream consists of the s MSB's
338 self
.IV
= self
.IV
[self
.segment_size
:] # keeping (b-s) LSB's
339 output
[i
] = chr(ord(output
[i
]) ^
ord(self
.keystream
.pop(0)))
340 self
.IV
+= output
[i
] # the IV for the next block in the chain is being built byte per byte as the ciphertext flows in
342 if len(self
.keystream
) == 0:
343 block
= self
.codebook
.encrypt(self
.IV
)
344 self
.keystream
= list(block
)[:self
.segment_size
]
345 self
.IV
= self
.IV
[self
.segment_size
:]
347 output
[i
] = chr(ord(output
[i
]) ^
ord(self
.keystream
.pop(0)))
348 return ''.join(output
)
353 Can be accessed as a stream cipher.
355 def __init__(self
, codebook
, blocksize
, IV
):
356 self
.codebook
= codebook
358 self
.blocksize
= blocksize
360 def update(self
, data
, ed
):
361 """Processes the given ciphertext/plaintext
364 data: raw string of any multiple of bytes
365 ed: 'e' for encryption, 'd' for decryption
369 The encrypt/decrypt functions will always process all of the supplied
370 input data immediately. No cache will be kept.
372 #no difference between encryption and decryption mode
374 blocksize
= self
.blocksize
378 if len(self
.keystream
) == 0: #encrypt a new counter block when the current keystream is fully used
379 self
.IV
= self
.codebook
.encrypt(self
.IV
)
380 self
.keystream
= list(self
.IV
)
381 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"
382 return ''.join(output
)
387 Can be accessed as a stream cipher.
389 # initial counter value can be choosen, decryption always starts from beginning
390 # -> you can start from anywhere yourself: just feed the cipher encoded blocks and feed a counter with the corresponding value
391 def __init__(self
, codebook
, blocksize
, counter
):
392 self
.codebook
= codebook
393 self
.counter
= counter
394 self
.blocksize
= blocksize
395 self
.keystream
= [] #holds the output of the current encrypted counter value
397 def update(self
, data
, ed
):
398 """Processes the given ciphertext/plaintext
401 data: raw string of any multiple of bytes
402 ed: 'e' for encryption, 'd' for decryption
406 The encrypt/decrypt functions will always process all of the supplied
407 input data immediately. No cache will be kept.
409 # no need for the encryption/decryption distinction: both are the same
411 blocksize
= self
.blocksize
415 if len(self
.keystream
) == 0: #encrypt a new counter block when the current keystream is fully used
416 block
= self
.codebook
.encrypt(self
.counter())
417 self
.keystream
= list(block
)
418 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"
419 return ''.join(output
)
424 # TODO: allow other blocksizes besides 16bytes?
425 def __init__(self
,codebook1
, codebook2
):
427 self
.codebook1
= codebook1
428 self
.codebook2
= codebook2
430 def update(self
, data
, ed
,tweak
=''):
431 # supply n as a raw string
432 # tweak = data sequence number
433 """Perform a XTS encrypt/decrypt operation.
435 Because the handling of the last two blocks is linked,
436 it needs the whole block of ciphertext to be supplied at once.
437 Every decrypt function called on a XTS cipher will output
438 a decrypted block based on the current supplied ciphertext block.
441 assert len(data
) > 15, "At least one block of 128 bits needs to be supplied"
442 assert len(data
) < 128*pow(2,20)
445 # e_k2_n = E_K2(tweak)
446 e_k2_n
= self
.codebook2
.encrypt(tweak
+ '\x00' * (16-len(tweak
)))[::-1]
447 self
.T
= util
.string2number(e_k2_n
)
450 while i
< ((len(data
) // 16)-1): #Decrypt all the blocks but one last full block and opt one last partial block
451 # C = E_K1(P xor T) xor T
452 output
+= self
.__xts
_step
(ed
,data
[i
*16:(i
+1)*16],self
.T
)
453 # T = E_K2(n) mul (a pow i)
457 # Check if the data supplied is a multiple of 16 bytes -> one last full block and we're done
458 if len(data
[i
*16:]) == 16:
459 # C = E_K1(P xor T) xor T
460 output
+= self
.__xts
_step
(ed
,data
[i
*16:(i
+1)*16],self
.T
)
461 # T = E_K2(n) mul (a pow i)
466 T_temp
.append(self
.T
)
468 # Permutation of the last two indexes
470 # Decrypt/Encrypt the last two blocks when data is not a multiple of 16 bytes
471 Cm1
= data
[i
*16:(i
+1)*16]
473 PP
= self
.__xts
_step
(ed
,Cm1
,T_temp
[0])
477 Pm1
= self
.__xts
_step
(ed
,CC
,T_temp
[1])
481 def __xts_step(self
,ed
,tocrypt
,T
):
482 T_string
= util
.number2string_N(T
,16)[::-1]
483 # C = E_K1(P xor T) xor T
485 return util
.xorstring(T_string
, self
.codebook1
.decrypt(util
.xorstring(T_string
, tocrypt
)))
487 return util
.xorstring(T_string
, self
.codebook1
.encrypt(util
.xorstring(T_string
, tocrypt
)))
489 def __T_update(self
):
490 # Used for calculating T for a certain step using the T value from the previous step
494 #T[0] ^= GF_128_FDBK;
495 self
.T
= self
.T ^
0x100000000000000000000000000000087L
499 """CMAC chaining mode
501 Supports every cipher with a blocksize available
502 in the list CMAC.supported_blocksizes.
503 The hashlength is equal to block size of the used block cipher.
505 # TODO: move to hash module?
506 # TODO: change update behaviour to .update() and .digest() as for all hash modules?
507 # -> other hash functions in pycrypto: calling update, concatenates current input with previous input and hashes everything
508 __Rb_dictionary
= {64:0x000000000000001b,128:0x00000000000000000000000000000087}
509 supported_blocksizes
= __Rb_dictionary
.keys()
510 def __init__(self
,codebook
,blocksize
):
511 # Purpose of init: calculate Lu & Lu2
512 #blocksize (in bytes): to select the Rb constant in the dictionary
513 #Rb as a dictionary: adding support for other blocksizes is easy
515 self
.blocksize
= blocksize
516 self
.codebook
= codebook
518 #Rb_dictionary: holds values for Rb for different blocksizes
519 # values for 64 and 128 bits found here: http://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html
520 # explanation from: http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf
521 # Rb is a representation of a certain irreducible binary polynomial of degree b, namely,
522 # the lexicographically first among all such polynomials with the minimum possible number of
523 # nonzero terms. If this polynomial is expressed as ub+cb-1ub-1+...+c2u2+c1u+c0, where the
524 # coefficients cb-1, cb-2, ..., c2, c1, c0 are either 0 or 1, then Rb is the bit string cb-1cb-2...c2c1c0.
526 self
.Rb
= self
.__Rb
_dictionary
[blocksize
*8]
528 mask1
= int(('\xff'*blocksize
).encode('hex'),16)
529 mask2
= int(('\x80' + '\x00'*(blocksize
-1) ).encode('hex'),16)
531 L
= int(self
.codebook
.encrypt('\x00'*blocksize
).encode('hex'),16)
534 Lu
= ((L
<< 1) & mask1
) ^ self
.Rb
540 Lu2
= ((Lu
<< 1) & mask1
)^ self
.Rb
545 self
.Lu
=util
.number2string_N(Lu
,self
.blocksize
)
546 self
.Lu2
=util
.number2string_N(Lu2
,self
.blocksize
)
548 def update(self
, data
, ed
):
549 """Processes the given ciphertext/plaintext
552 data: raw string of any length
553 ed: 'e' for encryption, 'd' for decryption
555 hashed data as raw string
557 This is not really an update function:
558 Everytime the function is called, the hash from the input data is calculated.
559 No finalizing needed.
562 blocksize
= self
.blocksize
564 m
= (len(data
)+blocksize
-1)/blocksize
#m = amount of datablocks
568 y
= self
.codebook
.encrypt( util
.xorstring(data
[(i
-1)*blocksize
:(i
)*blocksize
],y
) )
570 if len(data
[(i
)*blocksize
:])==blocksize
:
571 X
= util
.xorstring(util
.xorstring(data
[(i
)*blocksize
:],y
),self
.Lu
)
573 tmp
= data
[(i
)*blocksize
:] + '\x80' + '\x00'*(blocksize
- len(data
[(i
)*blocksize
:])-1)
574 X
= util
.xorstring(util
.xorstring(tmp
,y
),self
.Lu2
)
576 T
= self
.codebook
.encrypt(X
)