igetest.c revision 1.1 1 1.1 christos /* test/igetest.c */
2 1.1 christos /* ====================================================================
3 1.1 christos * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
4 1.1 christos *
5 1.1 christos * Redistribution and use in source and binary forms, with or without
6 1.1 christos * modification, are permitted provided that the following conditions
7 1.1 christos * are met:
8 1.1 christos *
9 1.1 christos * 1. Redistributions of source code must retain the above copyright
10 1.1 christos * notice, this list of conditions and the following disclaimer.
11 1.1 christos *
12 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 christos * notice, this list of conditions and the following disclaimer in
14 1.1 christos * the documentation and/or other materials provided with the
15 1.1 christos * distribution.
16 1.1 christos *
17 1.1 christos * 3. All advertising materials mentioning features or use of this
18 1.1 christos * software must display the following acknowledgment:
19 1.1 christos * "This product includes software developed by the OpenSSL Project
20 1.1 christos * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 1.1 christos *
22 1.1 christos * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 1.1 christos * endorse or promote products derived from this software without
24 1.1 christos * prior written permission. For written permission, please contact
25 1.1 christos * openssl-core (at) openssl.org.
26 1.1 christos *
27 1.1 christos * 5. Products derived from this software may not be called "OpenSSL"
28 1.1 christos * nor may "OpenSSL" appear in their names without prior written
29 1.1 christos * permission of the OpenSSL Project.
30 1.1 christos *
31 1.1 christos * 6. Redistributions of any form whatsoever must retain the following
32 1.1 christos * acknowledgment:
33 1.1 christos * "This product includes software developed by the OpenSSL Project
34 1.1 christos * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 1.1 christos *
36 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 1.1 christos * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 1.1 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 1.1 christos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 1.1 christos * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 1.1 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 1.1 christos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 1.1 christos * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 1.1 christos * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 1.1 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 1.1 christos * OF THE POSSIBILITY OF SUCH DAMAGE.
48 1.1 christos * ====================================================================
49 1.1 christos *
50 1.1 christos */
51 1.1 christos
52 1.1 christos #include <openssl/aes.h>
53 1.1 christos #include <openssl/rand.h>
54 1.1 christos #include <stdio.h>
55 1.1 christos #include <string.h>
56 1.1 christos #include <assert.h>
57 1.1 christos
58 1.1 christos #define TEST_SIZE 128
59 1.1 christos #define BIG_TEST_SIZE 10240
60 1.1 christos
61 1.1 christos static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
62 1.1 christos {
63 1.1 christos int n = 0;
64 1.1 christos
65 1.1 christos fprintf(f, "%s", title);
66 1.1 christos for (; n < l; ++n) {
67 1.1 christos if ((n % 16) == 0)
68 1.1 christos fprintf(f, "\n%04x", n);
69 1.1 christos fprintf(f, " %02x", s[n]);
70 1.1 christos }
71 1.1 christos fprintf(f, "\n");
72 1.1 christos }
73 1.1 christos
74 1.1 christos #define MAX_VECTOR_SIZE 64
75 1.1 christos
76 1.1 christos struct ige_test {
77 1.1 christos const unsigned char key[16];
78 1.1 christos const unsigned char iv[32];
79 1.1 christos const unsigned char in[MAX_VECTOR_SIZE];
80 1.1 christos const unsigned char out[MAX_VECTOR_SIZE];
81 1.1 christos const size_t length;
82 1.1 christos const int encrypt;
83 1.1 christos };
84 1.1 christos
85 1.1 christos static struct ige_test const ige_test_vectors[] = {
86 1.1 christos {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
87 1.1 christos 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key */
88 1.1 christos {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
89 1.1 christos 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
90 1.1 christos 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
91 1.1 christos 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* iv */
92 1.1 christos {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 1.1 christos 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 1.1 christos 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 1.1 christos 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
96 1.1 christos {0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52,
97 1.1 christos 0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45,
98 1.1 christos 0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3,
99 1.1 christos 0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb}, /* out */
100 1.1 christos 32, AES_ENCRYPT}, /* test vector 0 */
101 1.1 christos
102 1.1 christos {{0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
103 1.1 christos 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65}, /* key */
104 1.1 christos {0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
105 1.1 christos 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45,
106 1.1 christos 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f,
107 1.1 christos 0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53}, /* iv */
108 1.1 christos {0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73,
109 1.1 christos 0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65,
110 1.1 christos 0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74,
111 1.1 christos 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a}, /* in */
112 1.1 christos {0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13,
113 1.1 christos 0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a,
114 1.1 christos 0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34,
115 1.1 christos 0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b}, /* out */
116 1.1 christos 32, AES_DECRYPT}, /* test vector 1 */
117 1.1 christos };
118 1.1 christos
119 1.1 christos struct bi_ige_test {
120 1.1 christos const unsigned char key1[32];
121 1.1 christos const unsigned char key2[32];
122 1.1 christos const unsigned char iv[64];
123 1.1 christos const unsigned char in[MAX_VECTOR_SIZE];
124 1.1 christos const unsigned char out[MAX_VECTOR_SIZE];
125 1.1 christos const size_t keysize;
126 1.1 christos const size_t length;
127 1.1 christos const int encrypt;
128 1.1 christos };
129 1.1 christos
130 1.1 christos static struct bi_ige_test const bi_ige_test_vectors[] = {
131 1.1 christos {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
132 1.1 christos 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key1 */
133 1.1 christos {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
134 1.1 christos 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* key2 */
135 1.1 christos {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
136 1.1 christos 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
137 1.1 christos 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
138 1.1 christos 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
139 1.1 christos 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
140 1.1 christos 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
141 1.1 christos 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
142 1.1 christos 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}, /* iv */
143 1.1 christos {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 1.1 christos 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 1.1 christos 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 1.1 christos 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */
147 1.1 christos {0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56,
148 1.1 christos 0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc,
149 1.1 christos 0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16,
150 1.1 christos 0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12}, /* out */
151 1.1 christos 16, 32, AES_ENCRYPT}, /* test vector 0 */
152 1.1 christos {{0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c,
153 1.1 christos 0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a,
154 1.1 christos 0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75,
155 1.1 christos 0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37}, /* key1 */
156 1.1 christos {0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13,
157 1.1 christos 0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74,
158 1.1 christos 0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21,
159 1.1 christos 0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4}, /* key2 */
160 1.1 christos {0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9,
161 1.1 christos 0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70,
162 1.1 christos 0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42,
163 1.1 christos 0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67,
164 1.1 christos 0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a,
165 1.1 christos 0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20,
166 1.1 christos 0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd,
167 1.1 christos 0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3}, /* iv */
168 1.1 christos {0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c,
169 1.1 christos 0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0,
170 1.1 christos 0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f,
171 1.1 christos 0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b,
172 1.1 christos 0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52,
173 1.1 christos 0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a,
174 1.1 christos 0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c,
175 1.1 christos 0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */
176 1.1 christos {0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23,
177 1.1 christos 0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79,
178 1.1 christos 0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf,
179 1.1 christos 0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92,
180 1.1 christos 0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51,
181 1.1 christos 0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67,
182 1.1 christos 0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76,
183 1.1 christos 0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */
184 1.1 christos 32, 64, AES_ENCRYPT}, /* test vector 1 */
185 1.1 christos
186 1.1 christos };
187 1.1 christos
188 1.1 christos static int run_test_vectors(void)
189 1.1 christos {
190 1.1 christos unsigned int n;
191 1.1 christos int errs = 0;
192 1.1 christos
193 1.1 christos for (n = 0; n < sizeof(ige_test_vectors) / sizeof(ige_test_vectors[0]);
194 1.1 christos ++n) {
195 1.1 christos const struct ige_test *const v = &ige_test_vectors[n];
196 1.1 christos AES_KEY key;
197 1.1 christos unsigned char buf[MAX_VECTOR_SIZE];
198 1.1 christos unsigned char iv[AES_BLOCK_SIZE * 2];
199 1.1 christos
200 1.1 christos assert(v->length <= MAX_VECTOR_SIZE);
201 1.1 christos
202 1.1 christos if (v->encrypt == AES_ENCRYPT)
203 1.1 christos AES_set_encrypt_key(v->key, 8 * sizeof v->key, &key);
204 1.1 christos else
205 1.1 christos AES_set_decrypt_key(v->key, 8 * sizeof v->key, &key);
206 1.1 christos memcpy(iv, v->iv, sizeof iv);
207 1.1 christos AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt);
208 1.1 christos
209 1.1 christos if (memcmp(v->out, buf, v->length)) {
210 1.1 christos printf("IGE test vector %d failed\n", n);
211 1.1 christos hexdump(stdout, "key", v->key, sizeof v->key);
212 1.1 christos hexdump(stdout, "iv", v->iv, sizeof v->iv);
213 1.1 christos hexdump(stdout, "in", v->in, v->length);
214 1.1 christos hexdump(stdout, "expected", v->out, v->length);
215 1.1 christos hexdump(stdout, "got", buf, v->length);
216 1.1 christos
217 1.1 christos ++errs;
218 1.1 christos }
219 1.1 christos
220 1.1 christos /* try with in == out */
221 1.1 christos memcpy(iv, v->iv, sizeof iv);
222 1.1 christos memcpy(buf, v->in, v->length);
223 1.1 christos AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt);
224 1.1 christos
225 1.1 christos if (memcmp(v->out, buf, v->length)) {
226 1.1 christos printf("IGE test vector %d failed (with in == out)\n", n);
227 1.1 christos hexdump(stdout, "key", v->key, sizeof v->key);
228 1.1 christos hexdump(stdout, "iv", v->iv, sizeof v->iv);
229 1.1 christos hexdump(stdout, "in", v->in, v->length);
230 1.1 christos hexdump(stdout, "expected", v->out, v->length);
231 1.1 christos hexdump(stdout, "got", buf, v->length);
232 1.1 christos
233 1.1 christos ++errs;
234 1.1 christos }
235 1.1 christos }
236 1.1 christos
237 1.1 christos for (n = 0;
238 1.1 christos n < sizeof(bi_ige_test_vectors) / sizeof(bi_ige_test_vectors[0]);
239 1.1 christos ++n) {
240 1.1 christos const struct bi_ige_test *const v = &bi_ige_test_vectors[n];
241 1.1 christos AES_KEY key1;
242 1.1 christos AES_KEY key2;
243 1.1 christos unsigned char buf[MAX_VECTOR_SIZE];
244 1.1 christos
245 1.1 christos assert(v->length <= MAX_VECTOR_SIZE);
246 1.1 christos
247 1.1 christos if (v->encrypt == AES_ENCRYPT) {
248 1.1 christos AES_set_encrypt_key(v->key1, 8 * v->keysize, &key1);
249 1.1 christos AES_set_encrypt_key(v->key2, 8 * v->keysize, &key2);
250 1.1 christos } else {
251 1.1 christos AES_set_decrypt_key(v->key1, 8 * v->keysize, &key1);
252 1.1 christos AES_set_decrypt_key(v->key2, 8 * v->keysize, &key2);
253 1.1 christos }
254 1.1 christos
255 1.1 christos AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv,
256 1.1 christos v->encrypt);
257 1.1 christos
258 1.1 christos if (memcmp(v->out, buf, v->length)) {
259 1.1 christos printf("Bidirectional IGE test vector %d failed\n", n);
260 1.1 christos hexdump(stdout, "key 1", v->key1, sizeof v->key1);
261 1.1 christos hexdump(stdout, "key 2", v->key2, sizeof v->key2);
262 1.1 christos hexdump(stdout, "iv", v->iv, sizeof v->iv);
263 1.1 christos hexdump(stdout, "in", v->in, v->length);
264 1.1 christos hexdump(stdout, "expected", v->out, v->length);
265 1.1 christos hexdump(stdout, "got", buf, v->length);
266 1.1 christos
267 1.1 christos ++errs;
268 1.1 christos }
269 1.1 christos }
270 1.1 christos
271 1.1 christos return errs;
272 1.1 christos }
273 1.1 christos
274 1.1 christos int main(int argc, char **argv)
275 1.1 christos {
276 1.1 christos unsigned char rkey[16];
277 1.1 christos unsigned char rkey2[16];
278 1.1 christos AES_KEY key;
279 1.1 christos AES_KEY key2;
280 1.1 christos unsigned char plaintext[BIG_TEST_SIZE];
281 1.1 christos unsigned char ciphertext[BIG_TEST_SIZE];
282 1.1 christos unsigned char checktext[BIG_TEST_SIZE];
283 1.1 christos unsigned char iv[AES_BLOCK_SIZE * 4];
284 1.1 christos unsigned char saved_iv[AES_BLOCK_SIZE * 4];
285 1.1 christos int err = 0;
286 1.1 christos unsigned int n;
287 1.1 christos unsigned matches;
288 1.1 christos
289 1.1 christos assert(BIG_TEST_SIZE >= TEST_SIZE);
290 1.1 christos
291 1.1 christos RAND_pseudo_bytes(rkey, sizeof rkey);
292 1.1 christos RAND_pseudo_bytes(plaintext, sizeof plaintext);
293 1.1 christos RAND_pseudo_bytes(iv, sizeof iv);
294 1.1 christos memcpy(saved_iv, iv, sizeof saved_iv);
295 1.1 christos
296 1.1 christos /* Forward IGE only... */
297 1.1 christos
298 1.1 christos /* Straight encrypt/decrypt */
299 1.1 christos AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
300 1.1 christos AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv, AES_ENCRYPT);
301 1.1 christos
302 1.1 christos AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
303 1.1 christos memcpy(iv, saved_iv, sizeof iv);
304 1.1 christos AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
305 1.1 christos
306 1.1 christos if (memcmp(checktext, plaintext, TEST_SIZE)) {
307 1.1 christos printf("Encrypt+decrypt doesn't match\n");
308 1.1 christos hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
309 1.1 christos hexdump(stdout, "Checktext", checktext, TEST_SIZE);
310 1.1 christos ++err;
311 1.1 christos }
312 1.1 christos
313 1.1 christos /* Now check encrypt chaining works */
314 1.1 christos AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
315 1.1 christos memcpy(iv, saved_iv, sizeof iv);
316 1.1 christos AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
317 1.1 christos AES_ENCRYPT);
318 1.1 christos AES_ige_encrypt(plaintext + TEST_SIZE / 2,
319 1.1 christos ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
320 1.1 christos &key, iv, AES_ENCRYPT);
321 1.1 christos
322 1.1 christos AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
323 1.1 christos memcpy(iv, saved_iv, sizeof iv);
324 1.1 christos AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT);
325 1.1 christos
326 1.1 christos if (memcmp(checktext, plaintext, TEST_SIZE)) {
327 1.1 christos printf("Chained encrypt+decrypt doesn't match\n");
328 1.1 christos hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
329 1.1 christos hexdump(stdout, "Checktext", checktext, TEST_SIZE);
330 1.1 christos ++err;
331 1.1 christos }
332 1.1 christos
333 1.1 christos /* And check decrypt chaining */
334 1.1 christos AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
335 1.1 christos memcpy(iv, saved_iv, sizeof iv);
336 1.1 christos AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv,
337 1.1 christos AES_ENCRYPT);
338 1.1 christos AES_ige_encrypt(plaintext + TEST_SIZE / 2,
339 1.1 christos ciphertext + TEST_SIZE / 2, TEST_SIZE / 2,
340 1.1 christos &key, iv, AES_ENCRYPT);
341 1.1 christos
342 1.1 christos AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
343 1.1 christos memcpy(iv, saved_iv, sizeof iv);
344 1.1 christos AES_ige_encrypt(ciphertext, checktext, TEST_SIZE / 2, &key, iv,
345 1.1 christos AES_DECRYPT);
346 1.1 christos AES_ige_encrypt(ciphertext + TEST_SIZE / 2,
347 1.1 christos checktext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv,
348 1.1 christos AES_DECRYPT);
349 1.1 christos
350 1.1 christos if (memcmp(checktext, plaintext, TEST_SIZE)) {
351 1.1 christos printf("Chained encrypt+chained decrypt doesn't match\n");
352 1.1 christos hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
353 1.1 christos hexdump(stdout, "Checktext", checktext, TEST_SIZE);
354 1.1 christos ++err;
355 1.1 christos }
356 1.1 christos
357 1.1 christos /* make sure garble extends forwards only */
358 1.1 christos AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
359 1.1 christos memcpy(iv, saved_iv, sizeof iv);
360 1.1 christos AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
361 1.1 christos AES_ENCRYPT);
362 1.1 christos
363 1.1 christos /* corrupt halfway through */
364 1.1 christos ++ciphertext[sizeof ciphertext / 2];
365 1.1 christos AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
366 1.1 christos memcpy(iv, saved_iv, sizeof iv);
367 1.1 christos AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
368 1.1 christos AES_DECRYPT);
369 1.1 christos
370 1.1 christos matches = 0;
371 1.1 christos for (n = 0; n < sizeof checktext; ++n)
372 1.1 christos if (checktext[n] == plaintext[n])
373 1.1 christos ++matches;
374 1.1 christos
375 1.1 christos if (matches > sizeof checktext / 2 + sizeof checktext / 100) {
376 1.1 christos printf("More than 51%% matches after garbling\n");
377 1.1 christos ++err;
378 1.1 christos }
379 1.1 christos
380 1.1 christos if (matches < sizeof checktext / 2) {
381 1.1 christos printf("Garble extends backwards!\n");
382 1.1 christos ++err;
383 1.1 christos }
384 1.1 christos
385 1.1 christos /* Bi-directional IGE */
386 1.1 christos
387 1.1 christos /*
388 1.1 christos * Note that we don't have to recover the IV, because chaining isn't
389 1.1 christos */
390 1.1 christos /* possible with biIGE, so the IV is not updated. */
391 1.1 christos
392 1.1 christos RAND_pseudo_bytes(rkey2, sizeof rkey2);
393 1.1 christos
394 1.1 christos /* Straight encrypt/decrypt */
395 1.1 christos AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
396 1.1 christos AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
397 1.1 christos AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv,
398 1.1 christos AES_ENCRYPT);
399 1.1 christos
400 1.1 christos AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
401 1.1 christos AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
402 1.1 christos AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv,
403 1.1 christos AES_DECRYPT);
404 1.1 christos
405 1.1 christos if (memcmp(checktext, plaintext, TEST_SIZE)) {
406 1.1 christos printf("Encrypt+decrypt doesn't match\n");
407 1.1 christos hexdump(stdout, "Plaintext", plaintext, TEST_SIZE);
408 1.1 christos hexdump(stdout, "Checktext", checktext, TEST_SIZE);
409 1.1 christos ++err;
410 1.1 christos }
411 1.1 christos
412 1.1 christos /* make sure garble extends both ways */
413 1.1 christos AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
414 1.1 christos AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
415 1.1 christos AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
416 1.1 christos AES_ENCRYPT);
417 1.1 christos
418 1.1 christos /* corrupt halfway through */
419 1.1 christos ++ciphertext[sizeof ciphertext / 2];
420 1.1 christos AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
421 1.1 christos AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
422 1.1 christos AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
423 1.1 christos AES_DECRYPT);
424 1.1 christos
425 1.1 christos matches = 0;
426 1.1 christos for (n = 0; n < sizeof checktext; ++n)
427 1.1 christos if (checktext[n] == plaintext[n])
428 1.1 christos ++matches;
429 1.1 christos
430 1.1 christos if (matches > sizeof checktext / 100) {
431 1.1 christos printf("More than 1%% matches after bidirectional garbling\n");
432 1.1 christos ++err;
433 1.1 christos }
434 1.1 christos
435 1.1 christos /* make sure garble extends both ways (2) */
436 1.1 christos AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
437 1.1 christos AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
438 1.1 christos AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
439 1.1 christos AES_ENCRYPT);
440 1.1 christos
441 1.1 christos /* corrupt right at the end */
442 1.1 christos ++ciphertext[sizeof ciphertext - 1];
443 1.1 christos AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
444 1.1 christos AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
445 1.1 christos AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
446 1.1 christos AES_DECRYPT);
447 1.1 christos
448 1.1 christos matches = 0;
449 1.1 christos for (n = 0; n < sizeof checktext; ++n)
450 1.1 christos if (checktext[n] == plaintext[n])
451 1.1 christos ++matches;
452 1.1 christos
453 1.1 christos if (matches > sizeof checktext / 100) {
454 1.1 christos printf("More than 1%% matches after bidirectional garbling (2)\n");
455 1.1 christos ++err;
456 1.1 christos }
457 1.1 christos
458 1.1 christos /* make sure garble extends both ways (3) */
459 1.1 christos AES_set_encrypt_key(rkey, 8 * sizeof rkey, &key);
460 1.1 christos AES_set_encrypt_key(rkey2, 8 * sizeof rkey2, &key2);
461 1.1 christos AES_ige_encrypt(plaintext, ciphertext, sizeof plaintext, &key, iv,
462 1.1 christos AES_ENCRYPT);
463 1.1 christos
464 1.1 christos /* corrupt right at the start */
465 1.1 christos ++ciphertext[0];
466 1.1 christos AES_set_decrypt_key(rkey, 8 * sizeof rkey, &key);
467 1.1 christos AES_set_decrypt_key(rkey2, 8 * sizeof rkey2, &key2);
468 1.1 christos AES_ige_encrypt(ciphertext, checktext, sizeof checktext, &key, iv,
469 1.1 christos AES_DECRYPT);
470 1.1 christos
471 1.1 christos matches = 0;
472 1.1 christos for (n = 0; n < sizeof checktext; ++n)
473 1.1 christos if (checktext[n] == plaintext[n])
474 1.1 christos ++matches;
475 1.1 christos
476 1.1 christos if (matches > sizeof checktext / 100) {
477 1.1 christos printf("More than 1%% matches after bidirectional garbling (3)\n");
478 1.1 christos ++err;
479 1.1 christos }
480 1.1 christos
481 1.1 christos err += run_test_vectors();
482 1.1 christos
483 1.1 christos return err;
484 1.1 christos }
485