Home | History | Annotate | Download | only in utils
      1 # Author: Trevor Perrin
      2 # See the LICENSE file for legal information regarding use of this file.
      3 
      4 """Pure-Python AES implementation."""
      5 
      6 from .cryptomath import *
      7 
      8 from .aes import *
      9 from .rijndael import rijndael
     10 
     11 def new(key, mode, IV):
     12     return Python_AES(key, mode, IV)
     13 
     14 class 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