Changeset 38
- Timestamp:
- 02/13/13 21:02:54 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/bletchley/CBC/__init__.py
r37 r38 88 88 previously left off. This argument is assumed to contain the 89 89 final N bytes (for an N-byte argument) of the plaintext; that 90 is, the tail of the plaintext .90 is, the tail of the plaintext including the pad. 91 91 92 92 log_file -- A Python file object where log messages will be … … 99 99 if(iv != None and len(iv)%block_size != 0): 100 100 raise InvalidBlockError(block_size,len(iv)) 101 101 if len(decrypted) > len(ciphertext): 102 raise Exception #XXX: custom exception 103 102 104 self.block_size = block_size 103 105 self.decrypted = decrypted … … 118 120 119 121 120 def probe_padding(self , prior, final):122 def probe_padding(self): 121 123 """Attempts to verify that a CBC padding oracle exists and then determines the 122 124 pad value. … … 125 127 XXX: Currently only works for PKCS 5/7. 126 128 """ 129 130 blocks = buffertools.splitBuffer(self._ciphertext, self.block_size) 131 final = blocks[-1] 132 if len(blocks) == 1: 133 # If only one block present, then try to use IV as prior 134 prior = self._iv 135 else: 136 prior = blocks[-2] 127 137 128 138 ret_val = None … … 157 167 # XXX: Save the decrypted byte for later 158 168 ret_val = buffertools.pkcs7Pad(pad_length) 159 160 if ret_val:161 self.decrypted = ret_val162 169 163 170 return ret_val … … 216 223 if self._thread_result == None: 217 224 self.log_message("Value of a byte could not be determined. Current plaintext suffix: "+ repr(self.decrypted)) 218 raise Exception 225 raise Exception #XXX: custom exception 219 226 220 227 decrypted = struct.pack("B",self._thread_result^base^(numKnownBytes+1)) … … 236 243 237 244 238 # XXX: Add logic to begin where decryption previously left off239 245 def decrypt(self): 240 246 """Decrypts the previously supplied ciphertext. If the IV was … … 243 249 """ 244 250 245 blocks = buffertools.splitBuffer(self._ciphertext, self.block_size)246 247 251 if len(self.decrypted) == 0: 248 249 final = blocks[-1] 250 if len(blocks) == 1: 251 # If only one block present, then try to use IV as prior 252 prior = self._iv 253 else: 254 prior = blocks[-2] 255 256 # Decrypt last block, starting with padding (quicker to decrypt) 257 pad_bytes = self.probe_padding(prior, final) 252 # First decrypt the padding (quick to decrypt and good sanity check) 253 pad_bytes = self.probe_padding() 258 254 if pad_bytes == None: 259 255 # XXX: custom exception 260 256 raise Exception 261 262 decrypted = self.decrypt_block(prior, final, pad_bytes) 263 264 # Now decrypt all other blocks except first block 265 for i in range(len(blocks)-2, 0, -1): 266 decrypted = self.decrypt_block(blocks[i-1], blocks[i]) + decrypted 267 268 # Finally decrypt first block 269 decrypted = self.decrypt_block(self._iv, blocks[0]) + decrypted 270 271 # Start where we left off last 272 # XXX: test this more 273 else: 274 num_partial = len(self.decrypted) % self.block_size 275 finished_blocks = len(self.decrypted) / self.block_size 276 partial = self.decrypted[0:num_partial] 277 decrypted = self.decrypted[num_partial:] 278 279 for i in range(len(blocks)-1-finished_blocks, 0, -1): 280 decrypted = self.decrypt_block(blocks[i-1], blocks[i], partial) + decrypted 281 partial = '' 257 258 self.decrypted = pad_bytes 259 260 261 # Start where we left off last, whether that be with just a pad, 262 # or with additional decrypted blocks. 263 264 # number of bytes in any partially decrypted blocks 265 num_partial = len(self.decrypted) % self.block_size 266 267 # number of blocks fully decrypted 268 finished_blocks = len(self.decrypted) / self.block_size 269 270 # contents of the partial block 271 partial = self.decrypted[0:num_partial] 272 273 # contents of fully decrypted blocks 274 decrypted = self.decrypted[num_partial:] 275 276 blocks = buffertools.splitBuffer(self._ciphertext, self.block_size) 277 278 # Start with the partially decrypted block at the end, and work 279 # our way to the front. Don't decrypt the very first block of 280 # the ciphertext yet. 281 for i in range(len(blocks)-1-finished_blocks, 0, -1): 282 decrypted = self.decrypt_block(blocks[i-1], blocks[i], partial) + decrypted 283 partial = '' 282 284 283 # Finally decrypt first block 284 decrypted = self.decrypt_block(self._iv, blocks[0]) + decrypted 285 285 # Finally decrypt first block 286 decrypted = self.decrypt_block(self._iv, blocks[0], partial) + decrypted 287 288 # Remove the padding and return 286 289 return buffertools.stripPKCS7Pad(decrypted, self.block_size, self.log_fh) 287 290
Note: See TracChangeset
for help on using the changeset viewer.