1 module dcrypto.evp; 2 3 public import dcrypto.key; 4 import dcrypto.dcrypto; 5 6 import deimos.openssl.evp; 7 8 import std.string; 9 10 11 class EVPEncryptDecryptBase { 12 public 13 this() { 14 EVP_CIPHER_CTX_init(&_context); 15 } 16 17 this(const ref Key key) { 18 this(); 19 init(key); 20 } 21 22 protected: 23 EVP_CIPHER_CTX _context; 24 25 abstract void init(const ref Key key, const EVP_CIPHER *algorithm); 26 public void init(const ref Key key) { 27 init(key, EVP_aes_256_cbc()); 28 } 29 } 30 31 class EVPEncryptor : EVPEncryptDecryptBase, Encryptor { 32 this() { super(); } 33 this(const ref Key key) { super(key); } 34 35 override string encrypt(const string input) { 36 auto source = representation(input); 37 auto buffer = new ubyte[](source.length + EVP_MAX_BLOCK_LENGTH); 38 int length, lengthFinal; 39 40 EVP_EncryptInit(&_context, null, null, null); 41 EVP_EncryptUpdate(&_context, buffer.ptr, &length, source.ptr, cast(int)source.length); 42 EVP_EncryptFinal_ex(&_context, buffer.ptr + length, &lengthFinal); 43 44 return cast(string)buffer[0..length + lengthFinal]; 45 } 46 47 protected: 48 override void init(const ref Key key, const EVP_CIPHER *algorithm) { 49 EVP_EncryptInit(&_context, algorithm, key.key.ptr, key.iv.ptr); 50 } 51 } 52 53 class EVPDecryptor : EVPEncryptDecryptBase, Decryptor { 54 this() { super(); } 55 this(const ref Key key) { super(key); } 56 57 override string decrypt(const string input) { 58 auto source = representation(input); 59 auto buffer = new ubyte[](source.length + EVP_MAX_BLOCK_LENGTH); 60 int length, lengthFinal; 61 62 EVP_DecryptInit(&_context, null, null, null); 63 EVP_DecryptUpdate(&_context, buffer.ptr, &length, source.ptr, cast(int)source.length); 64 EVP_DecryptFinal_ex(&_context, buffer.ptr + length, &lengthFinal); 65 66 return cast(string)buffer[0..length + lengthFinal]; 67 } 68 protected: 69 override void init(const ref Key key, const EVP_CIPHER *algorithm) { 70 EVP_DecryptInit(&_context, algorithm, key.key.ptr, key.iv.ptr); 71 } 72 } 73 74 unittest { 75 auto key = keyFromSecret("ZYXWVUTSRQPONMLKJIHGFEDCBA", "SALT"); 76 auto encryptor = new EVPEncryptor(key); 77 auto decryptor = new EVPDecryptor(key); 78 79 auto encrypted = encryptor.encrypt("This is a decrypted string"); 80 auto encrypted2 = encryptor.encrypt("This is a second decrypted string"); 81 82 assert(decryptor.decrypt(encrypted2) == "This is a second decrypted string"); 83 assert(decryptor.decrypt(encrypted) == "This is a decrypted string"); 84 assert(decryptor.decrypt(encrypted2) == "This is a second decrypted string"); 85 86 auto key2 = keyFromSecret("ZYXWVUTSRQPONMLKJIHGFEDCBA"); 87 auto decryptor2 = new EVPDecryptor(key2); 88 assert(decryptor2.decrypt(encrypted2) != "This is a second decrypted string"); 89 }