cipher.py
1 """ 2 Symmetric Encryption 3 """ 4 # Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com> 5 # See LICENSE for details. 6 7 from .openssl import OpenSSL 8 9 10 # pylint: disable=redefined-builtin 11 class Cipher(object): 12 """ 13 Main class for encryption 14 15 import pyelliptic 16 iv = pyelliptic.Cipher.gen_IV('aes-256-cfb') 17 ctx = pyelliptic.Cipher("secretkey", iv, 1, ciphername='aes-256-cfb') 18 ciphertext = ctx.update('test1') 19 ciphertext += ctx.update('test2') 20 ciphertext += ctx.final() 21 22 ctx2 = pyelliptic.Cipher("secretkey", iv, 0, ciphername='aes-256-cfb') 23 print ctx2.ciphering(ciphertext) 24 """ 25 def __init__(self, key, iv, do, ciphername='aes-256-cbc'): 26 """ 27 do == 1 => Encrypt; do == 0 => Decrypt 28 """ 29 self.cipher = OpenSSL.get_cipher(ciphername) 30 self.ctx = OpenSSL.EVP_CIPHER_CTX_new() 31 if do == 1 or do == 0: 32 k = OpenSSL.malloc(key, len(key)) 33 IV = OpenSSL.malloc(iv, len(iv)) 34 OpenSSL.EVP_CipherInit_ex( 35 self.ctx, self.cipher.get_pointer(), 0, k, IV, do) 36 else: 37 raise Exception("RTFM ...") 38 39 @staticmethod 40 def get_all_cipher(): 41 """ 42 static method, returns all ciphers available 43 """ 44 return list(OpenSSL.cipher_algo.keys()) 45 46 @staticmethod 47 def get_blocksize(ciphername): 48 """This Method returns cipher blocksize""" 49 cipher = OpenSSL.get_cipher(ciphername) 50 return cipher.get_blocksize() 51 52 @staticmethod 53 def gen_IV(ciphername): 54 """Generate random initialization vector""" 55 cipher = OpenSSL.get_cipher(ciphername) 56 return OpenSSL.rand(cipher.get_blocksize()) 57 58 def update(self, input): 59 """Update result with more data""" 60 i = OpenSSL.c_int(0) 61 buffer = OpenSSL.malloc(b"", len(input) + self.cipher.get_blocksize()) 62 inp = OpenSSL.malloc(input, len(input)) 63 if OpenSSL.EVP_CipherUpdate(self.ctx, OpenSSL.byref(buffer), 64 OpenSSL.byref(i), inp, len(input)) == 0: 65 raise Exception("[OpenSSL] EVP_CipherUpdate FAIL ...") 66 return buffer.raw[0:i.value] # pylint: disable=invalid-slice-index 67 68 def final(self): 69 """Returning the final value""" 70 i = OpenSSL.c_int(0) 71 buffer = OpenSSL.malloc(b"", self.cipher.get_blocksize()) 72 if (OpenSSL.EVP_CipherFinal_ex(self.ctx, OpenSSL.byref(buffer), 73 OpenSSL.byref(i))) == 0: 74 raise Exception("[OpenSSL] EVP_CipherFinal_ex FAIL ...") 75 return buffer.raw[0:i.value] # pylint: disable=invalid-slice-index 76 77 def ciphering(self, input): 78 """ 79 Do update and final in one method 80 """ 81 buff = self.update(input) 82 return buff + self.final() 83 84 def __del__(self): 85 # pylint: disable=protected-access 86 if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL: 87 OpenSSL.EVP_CIPHER_CTX_reset(self.ctx) 88 else: 89 OpenSSL.EVP_CIPHER_CTX_cleanup(self.ctx) 90 OpenSSL.EVP_CIPHER_CTX_free(self.ctx)