1# Author: Trevor Perrin 2# See the LICENSE file for legal information regarding use of this file. 3 4"""Pure-Python AES implementation.""" 5 6from .cryptomath import * 7 8from .aes import * 9from .rijndael import rijndael 10 11def new(key, mode, IV): 12 return Python_AES(key, mode, IV) 13 14class Python_AES(AES): 15 def __init__(self, key, mode, IV): 16 AES.__init__(self, key, mode, IV, "python") 17 self.rijndael = rijndael(key, 16) 18 self.IV = IV 19 20 def encrypt(self, plaintext): 21 AES.encrypt(self, plaintext) 22 23 plaintextBytes = plaintext[:] 24 chainBytes = self.IV[:] 25 26 #CBC Mode: For each block... 27 for x in range(len(plaintextBytes)//16): 28 29 #XOR with the chaining block 30 blockBytes = plaintextBytes[x*16 : (x*16)+16] 31 for y in range(16): 32 blockBytes[y] ^= chainBytes[y] 33 34 #Encrypt it 35 encryptedBytes = self.rijndael.encrypt(blockBytes) 36 37 #Overwrite the input with the output 38 for y in range(16): 39 plaintextBytes[(x*16)+y] = encryptedBytes[y] 40 41 #Set the next chaining block 42 chainBytes = encryptedBytes 43 44 self.IV = chainBytes[:] 45 return plaintextBytes 46 47 def decrypt(self, ciphertext): 48 AES.decrypt(self, ciphertext) 49 50 ciphertextBytes = ciphertext[:] 51 chainBytes = self.IV[:] 52 53 #CBC Mode: For each block... 54 for x in range(len(ciphertextBytes)//16): 55 56 #Decrypt it 57 blockBytes = ciphertextBytes[x*16 : (x*16)+16] 58 decryptedBytes = self.rijndael.decrypt(blockBytes) 59 60 #XOR with the chaining block and overwrite the input with output 61 for y in range(16): 62 decryptedBytes[y] ^= chainBytes[y] 63 ciphertextBytes[(x*16)+y] = decryptedBytes[y] 64 65 #Set the next chaining block 66 chainBytes = blockBytes 67 68 self.IV = chainBytes[:] 69 return ciphertextBytes 70