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 moduleocean.util.cipher.gcrypt.AES;
23 24 importocean.util.cipher.gcrypt.core.Gcrypt;
25 importocean.transition;
26 27 28 /*******************************************************************************
29 30 Gcrypt with AES with mode ECB.
31 32 See usage example in unittest below.
33 34 *******************************************************************************/35 36 publicaliasGcryptNoIV!(Algorithm.GCRY_CIPHER_AES, Mode.GCRY_CIPHER_MODE_ECB) AES128;
37 38 /// Usage example of AES with 128-bit keys39 unittest40 {
41 // AES128 requires a key of length 16 bytes.42 staticimmutableKEY = "asdfghjklqwertyu";
43 44 testAES!(AES128, KEY)();
45 }
46 47 publicaliasGcryptNoIV!(Algorithm.GCRY_CIPHER_AES192, Mode.GCRY_CIPHER_MODE_ECB) AES192;
48 49 /// Usage example of AES with 192-bit keys50 unittest51 {
52 // AES192 requires a key of length 24 bytes.53 staticimmutableKEY = "abcdefghijklmnopqrstuvwx";
54 55 testAES!(AES192, KEY);
56 }
57 58 publicaliasGcryptNoIV!(Algorithm.GCRY_CIPHER_AES256, Mode.GCRY_CIPHER_MODE_ECB) AES256;
59 60 /// Usage example of AES with 256-bit keys61 unittest62 {
63 // AES256 requires a key of length 32 bytes.64 staticimmutableKEY = "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 publicaliasGcryptWithIV!(Algorithm.GCRY_CIPHER_AES, Mode.GCRY_CIPHER_MODE_CBC) AES128_CBC;
78 79 /// Usage example of AES-CBC with 128-bit keys80 unittest81 {
82 // AES128-CBC requires a key of length 16 bytes.83 staticimmutableKEY = "asdfghjklqwertyu";
84 85 // AES128-CBC requires an IV of length 16 bytes.86 staticimmutableIV = "0123456789ABCDEF";
87 88 testAES_IV!(AES128_CBC, KEY, IV);
89 }
90 91 publicaliasGcryptWithIV!(Algorithm.GCRY_CIPHER_AES192, Mode.GCRY_CIPHER_MODE_CBC) AES192_CBC;
92 93 /// Usage example of AES-CBC with 192-bit keys94 unittest95 {
96 // AES192-CBC requires a key of length 24 bytes.97 staticimmutableKEY = "abcdefghijklmnopqrstuvwx";
98 99 // AES192-CBC requires an IV of length 16 bytes.100 staticimmutableIV = "0123456789ABCDEF";
101 102 testAES_IV!(AES192_CBC, KEY, IV);
103 }
104 105 publicaliasGcryptWithIV!(Algorithm.GCRY_CIPHER_AES256, Mode.GCRY_CIPHER_MODE_CBC) AES256_CBC;
106 107 /// Usage example of AES-CBC with 256-bit keys108 unittest109 {
110 // AES256-CBC requires a key of length 32 bytes.111 staticimmutableKEY = "abcdefghijklmnopqrstuvwxyz012345";
112 113 // AES256-CBC requires an IV of length 16 bytes.114 staticimmutableIV = "0123456789ABCDEF";
115 116 testAES_IV!(AES256_CBC, KEY, IV);
117 }
118 119 version ( UnitTest )
120 {
121 importocean.core.Test;
122 123 voidtestAES ( Cipher, istringstr_key ) ( )
124 {
125 autokey = cast(Immut!(ubyte)[])str_key;
126 127 // Test that only keys of the provided length are allowed128 Cipher.testFixedKeyLength(key);
129 130 // AES operates on 16-byte blocks.131 istringtext = "Length divide 16";
132 mstringencrypted_text, decrypted_text;
133 134 // Create the class.135 autocipher = newCipher(key);
136 137 // encryption/decryption is done in place so first copy the plain text138 // to a buffer.139 encrypted_text ~= text;
140 141 // The actual encryption142 cipher.encrypt(encrypted_text);
143 144 // Since decryption is done in place we copy the decrypted string to a145 // 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 voidtestAES_IV ( Cipher, istringstr_key, istringstr_iv ) ( )
156 {
157 autokey = cast(Immut!(ubyte)[])str_key;
158 autoiv = cast(Immut!(ubyte)[])str_iv;
159 160 // Test that only keys of the provided length are allowed161 Cipher.testFixedKeyLength(key);
162 163 // AES operates on 16-byte blocks;164 istringtext = "Length divide 16";
165 mstringencrypted_text, decrypted_text;
166 167 // Create the class.168 autocipher = newCipher(key);
169 170 // encryption/decryption is done in place so first copy the plain text171 // to a buffer172 encrypted_text ~= text;
173 174 // The actual encryption175 cipher.encrypt(encrypted_text, iv);
176 177 // Since decryption is done in place we copy the decrypted string to a178 // 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 }