Subversion Repositories pub

Compare Revisions

Ignore whitespace Rev 181 → Rev 182

/relevation/ext/cryptopy-1.2.5.orig/crypto/cipher/base.py
0,0 → 1,140
""" crypto.cipher.base
 
 
Base 'BlockCipher' and Pad classes for cipher instances.
BlockCipher supports automatic padding and type conversion. The BlockCipher
class was written to make the actual algorithm code more readable and
not for performance.
 
Copyright © (c) 2002 by Paul A. Lambert
Read LICENSE.txt for license information.
 
2002-04-25 changed block input
"""
from crypto.errors import DecryptNotBlockAlignedError
from crypto.keyedHash.pbkdf2 import pbkdf2
 
class BlockCipher:
""" Block ciphers """
def __init__(self):
self.reset()
 
def reset(self):
self.resetEncrypt()
self.resetDecrypt()
def resetEncrypt(self):
self.encryptBlockCount = 0
self.bytesToEncrypt = ''
def resetDecrypt(self):
self.decryptBlockCount = 0
self.bytesToDecrypt = ''
 
def setPassphrase(self,passphrase):
""" Use pbkdf2 to hash passphrase into a key """
self.setKey( pbkdf2( passphrase, self.name, 4096, self.keySize) )
 
def encrypt(self, plainText, more = None):
""" Encrypt a string and return a binary string """
self.bytesToEncrypt += plainText # append plainText to any bytes from prior encrypt
numBlocks, numExtraBytes = divmod(len(self.bytesToEncrypt), self.blockSize)
cipherText = ''
for i in range(numBlocks):
bStart = i*self.blockSize
ctBlock = self.encryptBlock(self.bytesToEncrypt[bStart:bStart+self.blockSize])
self.encryptBlockCount += 1
cipherText += ctBlock
if numExtraBytes > 0: # save any bytes that are not block aligned
self.bytesToEncrypt = self.bytesToEncrypt[-numExtraBytes:]
else:
self.bytesToEncrypt = ''
 
if more == None: # no more data expected from caller
finalBytes = self.padding.addPad(self.bytesToEncrypt,self.blockSize)
if len(finalBytes) > 0:
ctBlock = self.encryptBlock(finalBytes)
self.encryptBlockCount += 1
cipherText += ctBlock
self.resetEncrypt()
return cipherText
def decrypt(self, cipherText, more = None):
""" Decrypt a string and return a string """
self.bytesToDecrypt += cipherText # append to any bytes from prior decrypt
 
numBlocks, numExtraBytes = divmod(len(self.bytesToDecrypt), self.blockSize)
if more == None: # no more calls to decrypt, should have all the data
if numExtraBytes != 0:
raise DecryptNotBlockAlignedError, 'Data not block aligned on decrypt'
 
# hold back some bytes in case last decrypt has zero len
if (more != None) and (numExtraBytes == 0) and (numBlocks >0) :
numBlocks -= 1
numExtraBytes = self.blockSize
 
plainText = ''
for i in range(numBlocks):
bStart = i*self.blockSize
ptBlock = self.decryptBlock(self.bytesToDecrypt[bStart : bStart+self.blockSize])
self.decryptBlockCount += 1
plainText += ptBlock
 
if numExtraBytes > 0: # save any bytes that are not block aligned
self.bytesToEncrypt = self.bytesToEncrypt[-numExtraBytes:]
else:
self.bytesToEncrypt = ''
 
if more == None: # last decrypt remove padding
plainText = self.padding.removePad(plainText, self.blockSize)
self.resetDecrypt()
return plainText
 
class BlockCipherWithIntegrity(BlockCipher):
""" Base class for encryption with integrity checking
just a holding place for now ... """
def __init__(self, authData, plainText):
self.reset()
 
class Pad:
def __init__(self):
pass # eventually could put in calculation of min and max size extension
 
class padWithPadLen(Pad):
""" Pad a binary string with the length of the padding """
 
def addPad(self, extraBytes, blockSize):
""" Add padding to a binary string to make it an even multiple
of the block size """
blocks, numExtraBytes = divmod(len(extraBytes), blockSize)
padLength = blockSize - numExtraBytes
return extraBytes + padLength*chr(padLength)
def removePad(self, paddedBinaryString, blockSize):
""" Remove padding from a binary string """
if not(0<len(paddedBinaryString)):
raise DecryptNotBlockAlignedError, 'Expected More Data'
return paddedBinaryString[:-ord(paddedBinaryString[-1])]
 
class noPadding(Pad):
""" No padding. Use this to get ECB behavior from encrypt/decrypt """
 
def addPad(self, extraBytes, blockSize):
""" Add no padding """
return extraBytes
 
def removePad(self, paddedBinaryString, blockSize):
""" Remove no padding """
return paddedBinaryString
 
class padWithZeros(Pad):
""" Zero padding. Used in CBC_MAC processing """
 
def addPad(self, extraBytes, blockSize):
""" Add padding to a binary string to make it an even multiple
of the block size """
blocks, numExtraBytes = divmod(len(extraBytes), blockSize)
padLength = blockSize - numExtraBytes
return extraBytes + padLength*chr(0x00)
 
def removePad(self, paddedBinaryString, blockSize):
""" Remove no padding, you really should, but no way to tell padding size """
return paddedBinaryString