1 # =============================================================================
2 # Copyright (c) 2008 Christophe Oosterlynck <christophe.oosterlynck_AT_gmail.com>
3 # & NXP ( Philippe Teuwen <philippe.teuwen_AT_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
)
55 self
.IV
= '\x00'*self
.blocksize
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
== None:
71 raise ValueError,"segment size must be defined explicitely for CFB mode"
72 if segment_size
> self
.blocksize
*8 or segment_size
%8 <> 0:
73 # current CFB implementation doesn't support bit level acces => segment_size should be multiple of bytes
74 raise ValueError,"segment size should be a multiple of 8 bits between 8 and %i"%(self
.blocksize
*8)
75 self
.chain
= CFB(self
.cipher
, self
.blocksize
,self
.IV
,segment_size
)
76 elif mode
== MODE_OFB
:
77 if len(self
.IV
) <> self
.blocksize
:
78 raise ValueError("the IV length should be %i bytes"%self
.blocksize
)
79 self
.chain
= OFB(self
.cipher
, self
.blocksize
,self
.IV
)
80 elif mode
== MODE_CTR
:
81 if (counter
== None) or not callable(counter
):
82 raise Exception,"Supply a valid counter object for the CTR mode"
83 self
.chain
= CTR(self
.cipher
,self
.blocksize
,counter
)
84 elif mode
== MODE_XTS
:
85 if self
.blocksize
<> 16:
86 raise Exception,'XTS only works with blockcipher that have a 128-bit blocksize'
87 if not(type(key
) == tuple and len(key
) == 2):
88 raise Exception,'Supply two keys as a tuple when using XTS'
89 if 'keylen_valid' in dir(self
): #wrappers for pycrypto functions don't have this function
90 if not self
.keylen_valid(key
[0]) or not self
.keylen_valid(key
[1]):
91 raise ValueError(self
.key_error_message
)
92 self
.cipher
= cipher_module(self
.key
[0],**args
)
93 self
.cipher2
= cipher_module(self
.key
[1],**args
)
94 self
.chain
= XTS(self
.cipher
, self
.cipher2
)
95 elif mode
== MODE_CMAC
:
96 if self
.blocksize
not in (8,16):
97 raise Exception,'CMAC only works with blockcipher that have a 64 or 128-bit blocksize'
98 self
.chain
= CMAC(self
.cipher
,self
.blocksize
,self
.IV
)
100 raise Exception,"Unknown chaining mode!"
102 def encrypt(self
,plaintext
,n
=''):
103 """Encrypt some plaintext
105 plaintext = a string of binary data
106 n = the 'tweak' value when the chaining mode is XTS
108 The encrypt function will encrypt the supplied plaintext.
109 The behavior varies slightly depending on the chaining mode.
113 When the supplied plaintext is not a multiple of the blocksize
114 of the cipher, then the remaining plaintext will be cached.
115 The next time the encrypt function is called with some plaintext,
116 the new plaintext will be concatenated to the cache and then
117 cache+plaintext will be encrypted.
121 When the chaining mode allows the cipher to act as a stream cipher,
122 the encrypt function will always encrypt all of the supplied
123 plaintext immediately. No cache will be kept.
127 Because the handling of the last two blocks is linked,
128 it needs the whole block of plaintext to be supplied at once.
129 Every encrypt function called on a XTS cipher will output
130 an encrypted block based on the current supplied plaintext block.
134 Everytime the function is called, the hash from the input data is calculated.
135 No finalizing needed.
136 The hashlength is equal to block size of the used block cipher.
138 #self.ed = 'e' if chain is encrypting, 'd' if decrypting,
139 # None if nothing happened with the chain yet
140 #assert self.ed in ('e',None)
141 # makes sure you don't encrypt with a cipher that has started decrypting
143 if self
.mode
== MODE_XTS
:
144 # data sequence number (or 'tweak') has to be provided when in XTS mode
145 return self
.chain
.update(plaintext
,'e',n
)
147 return self
.chain
.update(plaintext
,'e')
149 def decrypt(self
,ciphertext
,n
=''):
150 """Decrypt some ciphertext
152 ciphertext = a string of binary data
153 n = the 'tweak' value when the chaining mode is XTS
155 The decrypt function will decrypt the supplied ciphertext.
156 The behavior varies slightly depending on the chaining mode.
160 When the supplied ciphertext is not a multiple of the blocksize
161 of the cipher, then the remaining ciphertext will be cached.
162 The next time the decrypt function is called with some ciphertext,
163 the new ciphertext will be concatenated to the cache and then
164 cache+ciphertext will be decrypted.
168 When the chaining mode allows the cipher to act as a stream cipher,
169 the decrypt function will always decrypt all of the supplied
170 ciphertext immediately. No cache will be kept.
174 Because the handling of the last two blocks is linked,
175 it needs the whole block of ciphertext to be supplied at once.
176 Every decrypt function called on a XTS cipher will output
177 a decrypted block based on the current supplied ciphertext block.
181 Mode not supported for decryption as this does not make sense.
183 #self.ed = 'e' if chain is encrypting, 'd' if decrypting,
184 # None if nothing happened with the chain yet
185 #assert self.ed in ('d',None)
186 # makes sure you don't decrypt with a cipher that has started encrypting
188 if self
.mode
== MODE_XTS
:
189 # data sequence number (or 'tweak') has to be provided when in XTS mode
190 return self
.chain
.update(ciphertext
,'d',n
)
192 return self
.chain
.update(ciphertext
,'d')
194 def final(self
,padfct
=padding
.PKCS7
):
195 # TODO: after calling final, reset the IV? so the cipher is as good as new?
196 """Finalizes the encryption by padding the cache
198 padfct = padding function
199 import from CryptoPlus.Util.padding
201 For ECB, CBC: the remaining bytes in the cache will be padded and
203 For OFB,CFB, CTR: an encrypted padding will be returned, making the
204 total outputed bytes since construction of the cipher
205 a multiple of the blocksize of that cipher.
207 If the cipher has been used for decryption, the final function won't do
208 anything. You have to manually unpad if necessary.
210 After finalization, the chain can still be used but the IV, counter etc
211 aren't reset but just continue as they were after the last step (finalization step).
213 assert self
.mode
not in (MODE_XTS
, MODE_CMAC
) # finalizing (=padding) doesn't make sense when in XTS or CMAC mode
215 # when the chain is in encryption mode, finalizing will pad the cache and encrypt this last block
216 if self
.mode
in (MODE_OFB
,MODE_CFB
,MODE_CTR
):
217 dummy
= '0'*(self
.chain
.totalbytes
%self
.blocksize
) # a dummy string that will be used to get a valid padding
219 dummy
= self
.chain
.cache
220 pad
= padfct(dummy
,padding
.PAD
,self
.blocksize
)[len(dummy
):] # construct the padding necessary
221 return self
.chain
.update(pad
,'e') # supply the padding to the update function => chain cache will be "cache+padding"
223 # final function doesn't make sense when decrypting => padding should be removed manually
229 def __init__(self
, codebook
, blocksize
):
231 self
.codebook
= codebook
232 self
.blocksize
= blocksize
234 def update(self
, data
, ed
):
235 """Processes the given ciphertext/plaintext
238 data: raw string of any length
239 ed: 'e' for encryption, 'd' for decryption
241 processed raw string block(s), if any
243 When the supplied data is not a multiple of the blocksize
244 of the cipher, then the remaining input data will be cached.
245 The next time the update function is called with some data,
246 the new data will be concatenated to the cache and then
247 cache+data will be processed and full blocks will be outputted.
251 if len(self
.cache
) < self
.blocksize
:
253 for i
in xrange(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
254 #the only difference between encryption/decryption in the chain is the cipher block
256 output_blocks
.append(self
.codebook
.encrypt( self
.cache
[i
:i
+ self
.blocksize
] ))
258 output_blocks
.append(self
.codebook
.decrypt( self
.cache
[i
:i
+ self
.blocksize
] ))
259 self
.cache
= self
.cache
[i
+self
.blocksize
:]
260 return ''.join(output_blocks
)
265 def __init__(self
, codebook
, blocksize
, IV
):
268 self
.codebook
= codebook
269 self
.blocksize
= blocksize
271 def update(self
, data
, ed
):
272 """Processes the given ciphertext/plaintext
275 data: raw string of any length
276 ed: 'e' for encryption, 'd' for decryption
278 processed raw string block(s), if any
280 When the supplied data is not a multiple of the blocksize
281 of the cipher, then the remaining input data will be cached.
282 The next time the update function is called with some data,
283 the new data will be concatenated to the cache and then
284 cache+data will be processed and full blocks will be outputted.
287 encrypted_blocks
= ''
289 if len(self
.cache
) < self
.blocksize
:
291 for i
in xrange(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
292 self
.IV
= self
.codebook
.encrypt(util
.xorstring(self
.cache
[i
:i
+self
.blocksize
],self
.IV
))
293 encrypted_blocks
+= self
.IV
294 self
.cache
= self
.cache
[i
+self
.blocksize
:]
295 return encrypted_blocks
297 decrypted_blocks
= ''
299 if len(self
.cache
) < self
.blocksize
:
301 for i
in xrange(0, len(self
.cache
)-self
.blocksize
+1, self
.blocksize
):
302 plaintext
= util
.xorstring(self
.IV
,self
.codebook
.decrypt(self
.cache
[i
:i
+ self
.blocksize
]))
303 self
.IV
= self
.cache
[i
:i
+ self
.blocksize
]
304 decrypted_blocks
+=plaintext
305 self
.cache
= self
.cache
[i
+self
.blocksize
:]
306 return decrypted_blocks
309 # TODO: bit access instead of only byte level access
312 Can be accessed as a stream cipher.
315 def __init__(self
, codebook
, blocksize
, IV
,segment_size
):
316 self
.codebook
= codebook
318 self
.blocksize
= blocksize
319 self
.segment_size
= segment_size
/8
323 def update(self
, data
, ed
):
324 """Processes the given ciphertext/plaintext
327 data: raw string of any multiple of bytes
328 ed: 'e' for encryption, 'd' for decryption
332 The encrypt/decrypt functions will always process all of the supplied
333 input data immediately. No cache will be kept.
337 for i
in xrange(len(data
)):
339 if len(self
.keystream
) == 0:
340 block
= self
.codebook
.encrypt(self
.IV
)
341 self
.keystream
= list(block
)[:self
.segment_size
] # keystream consists of the s MSB's
342 self
.IV
= self
.IV
[self
.segment_size
:] # keeping (b-s) LSB's
343 output
[i
] = chr(ord(output
[i
]) ^
ord(self
.keystream
.pop(0)))
344 self
.IV
+= output
[i
] # the IV for the next block in the chain is being built byte per byte as the ciphertext flows in
346 if len(self
.keystream
) == 0:
347 block
= self
.codebook
.encrypt(self
.IV
)
348 self
.keystream
= list(block
)[:self
.segment_size
]
349 self
.IV
= self
.IV
[self
.segment_size
:]
351 output
[i
] = chr(ord(output
[i
]) ^
ord(self
.keystream
.pop(0)))
352 self
.totalbytes
+= len(output
)
353 return ''.join(output
)
358 Can be accessed as a stream cipher.
360 def __init__(self
, codebook
, blocksize
, IV
):
361 self
.codebook
= codebook
363 self
.blocksize
= blocksize
367 def update(self
, data
, ed
):
368 """Processes the given ciphertext/plaintext
371 data: raw string of any multiple of bytes
372 ed: 'e' for encryption, 'd' for decryption
376 The encrypt/decrypt functions will always process all of the supplied
377 input data immediately. No cache will be kept.
379 #no difference between encryption and decryption mode
381 blocksize
= self
.blocksize
385 if len(self
.keystream
) == 0: #encrypt a new counter block when the current keystream is fully used
386 self
.IV
= self
.codebook
.encrypt(self
.IV
)
387 self
.keystream
= list(self
.IV
)
388 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"
390 self
.totalbytes
+= len(output
)
391 return ''.join(output
)
396 Can be accessed as a stream cipher.
398 # initial counter value can be choosen, decryption always starts from beginning
399 # -> you can start from anywhere yourself: just feed the cipher encoded blocks and feed a counter with the corresponding value
400 def __init__(self
, codebook
, blocksize
, counter
):
401 self
.codebook
= codebook
402 self
.counter
= counter
403 self
.blocksize
= blocksize
404 self
.keystream
= [] #holds the output of the current encrypted counter value
407 def update(self
, data
, ed
):
408 """Processes the given ciphertext/plaintext
411 data: raw string of any multiple of bytes
412 ed: 'e' for encryption, 'd' for decryption
416 The encrypt/decrypt functions will always process all of the supplied
417 input data immediately. No cache will be kept.
419 # no need for the encryption/decryption distinction: both are the same
421 blocksize
= self
.blocksize
425 if len(self
.keystream
) == 0: #encrypt a new counter block when the current keystream is fully used
426 block
= self
.codebook
.encrypt(self
.counter())
427 self
.keystream
= list(block
)
428 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"
429 self
.totalbytes
+= len(output
)
430 return ''.join(output
)
435 Usable with blockciphers with a 16-byte blocksize
437 # TODO: allow other blocksizes besides 16bytes?
438 def __init__(self
,codebook1
, codebook2
):
440 self
.codebook1
= codebook1
441 self
.codebook2
= codebook2
443 def update(self
, data
, ed
,tweak
=''):
444 # supply n as a raw string
445 # tweak = data sequence number
446 """Perform a XTS encrypt/decrypt operation.
448 Because the handling of the last two blocks is linked,
449 it needs the whole block of ciphertext to be supplied at once.
450 Every decrypt function called on a XTS cipher will output
451 a decrypted block based on the current supplied ciphertext block.
454 assert len(data
) > 15, "At least one block of 128 bits needs to be supplied"
455 assert len(data
) < 128*pow(2,20)
458 # e_k2_n = E_K2(tweak)
459 e_k2_n
= self
.codebook2
.encrypt(tweak
+ '\x00' * (16-len(tweak
)))[::-1]
460 self
.T
= util
.string2number(e_k2_n
)
463 while i
< ((len(data
) // 16)-1): #Decrypt all the blocks but one last full block and opt one last partial block
464 # C = E_K1(P xor T) xor T
465 output
+= self
.__xts
_step
(ed
,data
[i
*16:(i
+1)*16],self
.T
)
466 # T = E_K2(n) mul (a pow i)
470 # Check if the data supplied is a multiple of 16 bytes -> one last full block and we're done
471 if len(data
[i
*16:]) == 16:
472 # C = E_K1(P xor T) xor T
473 output
+= self
.__xts
_step
(ed
,data
[i
*16:(i
+1)*16],self
.T
)
474 # T = E_K2(n) mul (a pow i)
479 T_temp
.append(self
.T
)
481 # Permutation of the last two indexes
483 # Decrypt/Encrypt the last two blocks when data is not a multiple of 16 bytes
484 Cm1
= data
[i
*16:(i
+1)*16]
486 PP
= self
.__xts
_step
(ed
,Cm1
,T_temp
[0])
490 Pm1
= self
.__xts
_step
(ed
,CC
,T_temp
[1])
494 def __xts_step(self
,ed
,tocrypt
,T
):
495 T_string
= util
.number2string_N(T
,16)[::-1]
496 # C = E_K1(P xor T) xor T
498 return util
.xorstring(T_string
, self
.codebook1
.decrypt(util
.xorstring(T_string
, tocrypt
)))
500 return util
.xorstring(T_string
, self
.codebook1
.encrypt(util
.xorstring(T_string
, tocrypt
)))
502 def __T_update(self
):
503 # Used for calculating T for a certain step using the T value from the previous step
507 #T[0] ^= GF_128_FDBK;
508 self
.T
= self
.T ^
0x100000000000000000000000000000087L
512 """CMAC chaining mode
514 Supports every cipher with a blocksize available
515 in the list CMAC.supported_blocksizes.
516 The hashlength is equal to block size of the used block cipher.
518 Usable with blockciphers with a 8 or 16-byte blocksize
520 # TODO: move to hash module?
521 # TODO: change update behaviour to .update() and .digest() as for all hash modules?
522 # -> other hash functions in pycrypto: calling update, concatenates current input with previous input and hashes everything
523 __Rb_dictionary
= {64:0x000000000000001b,128:0x00000000000000000000000000000087}
524 supported_blocksizes
= __Rb_dictionary
.keys()
525 def __init__(self
,codebook
,blocksize
,IV
):
526 # Purpose of init: calculate Lu & Lu2
527 #blocksize (in bytes): to select the Rb constant in the dictionary
528 #Rb as a dictionary: adding support for other blocksizes is easy
530 self
.blocksize
= blocksize
531 self
.codebook
= codebook
534 #Rb_dictionary: holds values for Rb for different blocksizes
535 # values for 64 and 128 bits found here: http://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html
536 # explanation from: http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf
537 # Rb is a representation of a certain irreducible binary polynomial of degree b, namely,
538 # the lexicographically first among all such polynomials with the minimum possible number of
539 # nonzero terms. If this polynomial is expressed as ub+cb-1ub-1+...+c2u2+c1u+c0, where the
540 # coefficients cb-1, cb-2, ..., c2, c1, c0 are either 0 or 1, then Rb is the bit string cb-1cb-2...c2c1c0.
542 self
.Rb
= self
.__Rb
_dictionary
[blocksize
*8]
544 mask1
= int(('\xff'*blocksize
).encode('hex'),16)
545 mask2
= int(('\x80' + '\x00'*(blocksize
-1) ).encode('hex'),16)
547 L
= int(self
.codebook
.encrypt('\x00'*blocksize
).encode('hex'),16)
550 Lu
= ((L
<< 1) & mask1
) ^ self
.Rb
556 Lu2
= ((Lu
<< 1) & mask1
)^ self
.Rb
561 self
.Lu
=util
.number2string_N(Lu
,self
.blocksize
)
562 self
.Lu2
=util
.number2string_N(Lu2
,self
.blocksize
)
564 def update(self
, data
, ed
):
565 """Processes the given ciphertext/plaintext
568 data: raw string of any length
569 ed: 'e' for encryption, 'd' for decryption
571 hashed data as raw string
573 This is not really an update function:
574 Everytime the function is called, the hash from the input data is calculated.
575 No finalizing needed.
578 blocksize
= self
.blocksize
580 m
= (len(data
)+blocksize
-1)/blocksize
#m = amount of datablocks
583 self
.IV
= self
.codebook
.encrypt( util
.xorstring(data
[(i
-1)*blocksize
:(i
)*blocksize
],self
.IV
) )
585 if len(data
[(i
)*blocksize
:])==blocksize
:
586 X
= util
.xorstring(util
.xorstring(data
[(i
)*blocksize
:],self
.IV
),self
.Lu
)
588 tmp
= data
[(i
)*blocksize
:] + '\x80' + '\x00'*(blocksize
- len(data
[(i
)*blocksize
:])-1)
589 X
= util
.xorstring(util
.xorstring(tmp
,self
.IV
),self
.Lu2
)
591 T
= self
.codebook
.encrypt(X
)