Changeset 76


Ignore:
Timestamp:
03/11/15 14:06:31 (10 years ago)
Author:
tim
Message:

Fixed off-by-one block error in CBC-R code when a partial encryption is provided

Improved debugging/status messages

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/bletchley/CBC/__init__.py

    r69 r76  
    33
    44Copyright (C) 2010 ELOI SANFÈLIX
    5 Copyright (C) 2012-2013 Timothy D. Morgan
     5Copyright (C) 2012-2015 Timothy D. Morgan
    66@author: Eloi Sanfelix < eloi AT limited-entropy.com >
    77@author: Timothy D. Morgan < tmorgan {a} vsecurity . com >
     
    118118    def log_message(self, s):
    119119        if self.log_fh != None:
    120             self.log_fh.write(s+'\n')
     120            self.log_fh.write('BLETCHLEY: %s\n' % s)
    121121
    122122
     
    343343        ptext = self.decrypt_block(b'\x00'*self.block_size, ciphertext, cache=False)
    344344        prior = buffertools.xorBuffers(ptext, plaintext)
    345         self.log_message("Encrypted block: %s to %s with prior %s" % (repr(plaintext), repr(ciphertext), repr(prior)))
     345        self.log_message("Encrypted block: %s to %s with prior %s" % (repr(plaintext),
     346                                                                      repr(bytes(ciphertext)),
     347                                                                      repr(bytes(prior))))
    346348        return prior,ciphertext
    347349   
    348350   
    349     def encrypt(self,plaintext, ciphertext=None):
     351    def encrypt(self, plaintext, ciphertext=None):
    350352        """Encrypts a plaintext value through "CBC-R" style prior-block
    351353        propagation.
     
    364366        blocks = buffertools.splitBuffer(buffertools.pkcs7PadBuffer(plaintext, self.block_size),
    365367                                         self.block_size)
    366         if ciphertext != None:
     368        if ciphertext not in (None, b''):
    367369            if len(ciphertext) % self.block_size != 0:
    368370                raise InvalidBlockError(self.block_size,len(ciphertext))
    369             num_cblocks = (len(ciphertext) // self.block_size) - 1
    370             del blocks[0-num_cblocks:] # we've already encrypted these
    371             prior = ciphertext[0:self.block_size]
     371
     372            cblocks = buffertools.splitBuffer(ciphertext, self.block_size)
     373            prior = cblocks[0]
     374
     375            # remove first block from ciphertext since it'll be re-added later
     376            # after the prior is converted to finished ciphertext.
     377            del cblocks[0]
     378            ciphertext = b''.join(cblocks)
     379
     380            # now remove the plaintext blocks we've already completed
     381            num_finished = len(cblocks)
     382            del blocks[len(blocks)-num_finished:]
     383            self.log_message("Reusing previous decryption of final %d blocks" % num_finished)
    372384           
    373385        elif (len(self.decrypted) >= self.block_size
    374386            and len(self._ciphertext) >= 2*self.block_size):
     387           
     388            self.log_message("Reusing previous decryption of final block")
     389
    375390            # If possible, reuse work from prior decryption efforts on original
    376391            # message for last block
     
    382397            del blocks[-1]
    383398        else:
     399            self.log_message("Starting decryption from scratch with random final block")
     400           
    384401            # Otherwise, select a random last block and generate the prior block
    385402            prior = struct.pack("B"*self.block_size,
     
    387404            ciphertext = b''
    388405
     406        self.log_message("Encrypting %d blocks..." % len(blocks))
    389407        try:
    390408            # Continue generating all prior blocks
Note: See TracChangeset for help on using the changeset viewer.