1 /******************************************************************************* 2 3 libgcrypt with algorithm AES (Rijndael) with a 128 bit key. 4 5 Requires linking with libgcrypt: 6 -L -lgcrypt 7 8 See_Also: 9 http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf 10 11 Copyright: 12 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 13 All rights reserved. 14 15 License: 16 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 17 Alternatively, this file may be distributed under the terms of the Tango 18 3-Clause BSD License (see LICENSE_BSD.txt for details). 19 20 *******************************************************************************/ 21 22 module ocean.util.cipher.gcrypt.AES; 23 24 import ocean.meta.types.Qualifiers; 25 import ocean.util.cipher.gcrypt.core.Gcrypt; 26 27 28 /******************************************************************************* 29 30 Gcrypt with AES with mode ECB. 31 32 See usage example in unittest below. 33 34 *******************************************************************************/ 35 36 public alias GcryptNoIV!(Algorithm.GCRY_CIPHER_AES, Mode.GCRY_CIPHER_MODE_ECB) AES128; 37 38 /// Usage example of AES with 128-bit keys 39 unittest 40 { 41 // AES128 requires a key of length 16 bytes. 42 static immutable KEY = "asdfghjklqwertyu"; 43 44 testAES!(AES128, KEY)(); 45 } 46 47 public alias GcryptNoIV!(Algorithm.GCRY_CIPHER_AES192, Mode.GCRY_CIPHER_MODE_ECB) AES192; 48 49 /// Usage example of AES with 192-bit keys 50 unittest 51 { 52 // AES192 requires a key of length 24 bytes. 53 static immutable KEY = "abcdefghijklmnopqrstuvwx"; 54 55 testAES!(AES192, KEY); 56 } 57 58 public alias GcryptNoIV!(Algorithm.GCRY_CIPHER_AES256, Mode.GCRY_CIPHER_MODE_ECB) AES256; 59 60 /// Usage example of AES with 256-bit keys 61 unittest 62 { 63 // AES256 requires a key of length 32 bytes. 64 static immutable KEY = "abcdefghijklmnopqrstuvwxyz012345"; 65 66 testAES!(AES256, KEY); 67 } 68 69 /******************************************************************************* 70 71 Gcrypt with AES with mode CBC. 72 73 See usage example in unittest below. 74 75 *******************************************************************************/ 76 77 public alias GcryptWithIV!(Algorithm.GCRY_CIPHER_AES, Mode.GCRY_CIPHER_MODE_CBC) AES128_CBC; 78 79 /// Usage example of AES-CBC with 128-bit keys 80 unittest 81 { 82 // AES128-CBC requires a key of length 16 bytes. 83 static immutable KEY = "asdfghjklqwertyu"; 84 85 // AES128-CBC requires an IV of length 16 bytes. 86 static immutable IV = "0123456789ABCDEF"; 87 88 testAES_IV!(AES128_CBC, KEY, IV); 89 } 90 91 public alias GcryptWithIV!(Algorithm.GCRY_CIPHER_AES192, Mode.GCRY_CIPHER_MODE_CBC) AES192_CBC; 92 93 /// Usage example of AES-CBC with 192-bit keys 94 unittest 95 { 96 // AES192-CBC requires a key of length 24 bytes. 97 static immutable KEY = "abcdefghijklmnopqrstuvwx"; 98 99 // AES192-CBC requires an IV of length 16 bytes. 100 static immutable IV = "0123456789ABCDEF"; 101 102 testAES_IV!(AES192_CBC, KEY, IV); 103 } 104 105 public alias GcryptWithIV!(Algorithm.GCRY_CIPHER_AES256, Mode.GCRY_CIPHER_MODE_CBC) AES256_CBC; 106 107 /// Usage example of AES-CBC with 256-bit keys 108 unittest 109 { 110 // AES256-CBC requires a key of length 32 bytes. 111 static immutable KEY = "abcdefghijklmnopqrstuvwxyz012345"; 112 113 // AES256-CBC requires an IV of length 16 bytes. 114 static immutable IV = "0123456789ABCDEF"; 115 116 testAES_IV!(AES256_CBC, KEY, IV); 117 } 118 119 version (unittest) 120 { 121 import ocean.core.Test; 122 123 void testAES ( Cipher, istring str_key ) ( ) 124 { 125 auto key = cast(immutable(ubyte)[])str_key; 126 127 // Test that only keys of the provided length are allowed 128 Cipher.testFixedKeyLength(key); 129 130 // AES operates on 16-byte blocks. 131 istring text = "Length divide 16"; 132 mstring encrypted_text, decrypted_text; 133 134 // Create the class. 135 auto cipher = new Cipher(key); 136 137 // encryption/decryption is done in place so first copy the plain text 138 // to a buffer. 139 encrypted_text ~= text; 140 141 // The actual encryption 142 cipher.encrypt(encrypted_text); 143 144 // Since decryption is done in place we copy the decrypted string to a 145 // new buffer. 146 decrypted_text ~= encrypted_text; 147 148 // The decryption call. 149 cipher.decrypt(decrypted_text); 150 151 // We have now successfully encrypted and decrypted a string. 152 test!("==")(text, decrypted_text); 153 } 154 155 void testAES_IV ( Cipher, istring str_key, istring str_iv ) ( ) 156 { 157 auto key = cast(immutable(ubyte)[])str_key; 158 auto iv = cast(immutable(ubyte)[])str_iv; 159 160 // Test that only keys of the provided length are allowed 161 Cipher.testFixedKeyLength(key); 162 163 // AES operates on 16-byte blocks; 164 istring text = "Length divide 16"; 165 mstring encrypted_text, decrypted_text; 166 167 // Create the class. 168 auto cipher = new Cipher(key); 169 170 // encryption/decryption is done in place so first copy the plain text 171 // to a buffer 172 encrypted_text ~= text; 173 174 // The actual encryption 175 cipher.encrypt(encrypted_text, iv); 176 177 // Since decryption is done in place we copy the decrypted string to a 178 // new buffer. 179 decrypted_text ~= encrypted_text; 180 181 // The decryption call. 182 cipher.decrypt(decrypted_text, iv); 183 184 // We have now successfully encrypted and decrypted a string. 185 test!("==")(text, decrypted_text); 186 } 187 }