1 /* 2 * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <openssl/crypto.h> 11 #include <openssl/aes.h> 12 #include <openssl/rand.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <assert.h> 16 #include "e_os.h" 17 18 #define TEST_SIZE 128 19 #define BIG_TEST_SIZE 10240 20 21 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l) 22 { 23 int n = 0; 24 25 fprintf(f, "%s", title); 26 for (; n < l; ++n) { 27 if ((n % 16) == 0) 28 fprintf(f, "\n%04x", n); 29 fprintf(f, " %02x", s[n]); 30 } 31 fprintf(f, "\n"); 32 } 33 34 #define MAX_VECTOR_SIZE 64 35 36 struct ige_test { 37 const unsigned char key[16]; 38 const unsigned char iv[32]; 39 const unsigned char in[MAX_VECTOR_SIZE]; 40 const unsigned char out[MAX_VECTOR_SIZE]; 41 const size_t length; 42 const int encrypt; 43 }; 44 45 static struct ige_test const ige_test_vectors[] = { 46 {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 47 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key */ 48 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 49 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 50 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 51 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* iv */ 52 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */ 56 {0x1a, 0x85, 0x19, 0xa6, 0x55, 0x7b, 0xe6, 0x52, 57 0xe9, 0xda, 0x8e, 0x43, 0xda, 0x4e, 0xf4, 0x45, 58 0x3c, 0xf4, 0x56, 0xb4, 0xca, 0x48, 0x8a, 0xa3, 59 0x83, 0xc7, 0x9c, 0x98, 0xb3, 0x47, 0x97, 0xcb}, /* out */ 60 32, AES_ENCRYPT}, /* test vector 0 */ 61 62 {{0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 63 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65}, /* key */ 64 {0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 65 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x49, 0x47, 0x45, 66 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f, 67 0x72, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53}, /* iv */ 68 {0x4c, 0x2e, 0x20, 0x4c, 0x65, 0x74, 0x27, 0x73, 69 0x20, 0x68, 0x6f, 0x70, 0x65, 0x20, 0x42, 0x65, 70 0x6e, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x69, 0x74, 71 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x0a}, /* in */ 72 {0x99, 0x70, 0x64, 0x87, 0xa1, 0xcd, 0xe6, 0x13, 73 0xbc, 0x6d, 0xe0, 0xb6, 0xf2, 0x4b, 0x1c, 0x7a, 74 0xa4, 0x48, 0xc8, 0xb9, 0xc3, 0x40, 0x3e, 0x34, 75 0x67, 0xa8, 0xca, 0xd8, 0x93, 0x40, 0xf5, 0x3b}, /* out */ 76 32, AES_DECRYPT}, /* test vector 1 */ 77 }; 78 79 struct bi_ige_test { 80 const unsigned char key1[32]; 81 const unsigned char key2[32]; 82 const unsigned char iv[64]; 83 const unsigned char in[MAX_VECTOR_SIZE]; 84 const unsigned char out[MAX_VECTOR_SIZE]; 85 const size_t keysize; 86 const size_t length; 87 const int encrypt; 88 }; 89 90 static struct bi_ige_test const bi_ige_test_vectors[] = { 91 {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 92 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}, /* key1 */ 93 {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 94 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, /* key2 */ 95 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 96 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 97 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 98 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 99 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 100 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 101 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 102 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}, /* iv */ 103 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* in */ 107 {0x14, 0x40, 0x6f, 0xae, 0xa2, 0x79, 0xf2, 0x56, 108 0x1f, 0x86, 0xeb, 0x3b, 0x7d, 0xff, 0x53, 0xdc, 109 0x4e, 0x27, 0x0c, 0x03, 0xde, 0x7c, 0xe5, 0x16, 110 0x6a, 0x9c, 0x20, 0x33, 0x9d, 0x33, 0xfe, 0x12}, /* out */ 111 16, 32, AES_ENCRYPT}, /* test vector 0 */ 112 {{0x58, 0x0a, 0x06, 0xe9, 0x97, 0x07, 0x59, 0x5c, 113 0x9e, 0x19, 0xd2, 0xa7, 0xbb, 0x40, 0x2b, 0x7a, 114 0xc7, 0xd8, 0x11, 0x9e, 0x4c, 0x51, 0x35, 0x75, 115 0x64, 0x28, 0x0f, 0x23, 0xad, 0x74, 0xac, 0x37}, /* key1 */ 116 {0xd1, 0x80, 0xa0, 0x31, 0x47, 0xa3, 0x11, 0x13, 117 0x86, 0x26, 0x9e, 0x6d, 0xff, 0xaf, 0x72, 0x74, 118 0x5b, 0xa2, 0x35, 0x81, 0xd2, 0xa6, 0x3d, 0x21, 119 0x67, 0x7b, 0x58, 0xa8, 0x18, 0xf9, 0x72, 0xe4}, /* key2 */ 120 {0x80, 0x3d, 0xbd, 0x4c, 0xe6, 0x7b, 0x06, 0xa9, 121 0x53, 0x35, 0xd5, 0x7e, 0x71, 0xc1, 0x70, 0x70, 122 0x74, 0x9a, 0x00, 0x28, 0x0c, 0xbf, 0x6c, 0x42, 123 0x9b, 0xa4, 0xdd, 0x65, 0x11, 0x77, 0x7c, 0x67, 124 0xfe, 0x76, 0x0a, 0xf0, 0xd5, 0xc6, 0x6e, 0x6a, 125 0xe7, 0x5e, 0x4c, 0xf2, 0x7e, 0x9e, 0xf9, 0x20, 126 0x0e, 0x54, 0x6f, 0x2d, 0x8a, 0x8d, 0x7e, 0xbd, 127 0x48, 0x79, 0x37, 0x99, 0xff, 0x27, 0x93, 0xa3}, /* iv */ 128 {0xf1, 0x54, 0x3d, 0xca, 0xfe, 0xb5, 0xef, 0x1c, 129 0x4f, 0xa6, 0x43, 0xf6, 0xe6, 0x48, 0x57, 0xf0, 130 0xee, 0x15, 0x7f, 0xe3, 0xe7, 0x2f, 0xd0, 0x2f, 131 0x11, 0x95, 0x7a, 0x17, 0x00, 0xab, 0xa7, 0x0b, 132 0xbe, 0x44, 0x09, 0x9c, 0xcd, 0xac, 0xa8, 0x52, 133 0xa1, 0x8e, 0x7b, 0x75, 0xbc, 0xa4, 0x92, 0x5a, 134 0xab, 0x46, 0xd3, 0x3a, 0xa0, 0xd5, 0x35, 0x1c, 135 0x55, 0xa4, 0xb3, 0xa8, 0x40, 0x81, 0xa5, 0x0b}, /* in */ 136 {0x42, 0xe5, 0x28, 0x30, 0x31, 0xc2, 0xa0, 0x23, 137 0x68, 0x49, 0x4e, 0xb3, 0x24, 0x59, 0x92, 0x79, 138 0xc1, 0xa5, 0xcc, 0xe6, 0x76, 0x53, 0xb1, 0xcf, 139 0x20, 0x86, 0x23, 0xe8, 0x72, 0x55, 0x99, 0x92, 140 0x0d, 0x16, 0x1c, 0x5a, 0x2f, 0xce, 0xcb, 0x51, 141 0xe2, 0x67, 0xfa, 0x10, 0xec, 0xcd, 0x3d, 0x67, 142 0xa5, 0xe6, 0xf7, 0x31, 0x26, 0xb0, 0x0d, 0x76, 143 0x5e, 0x28, 0xdc, 0x7f, 0x01, 0xc5, 0xa5, 0x4c}, /* out */ 144 32, 64, AES_ENCRYPT}, /* test vector 1 */ 145 146 }; 147 148 static int run_test_vectors(void) 149 { 150 unsigned int n; 151 int errs = 0; 152 153 for (n = 0; n < OSSL_NELEM(ige_test_vectors); ++n) { 154 const struct ige_test *const v = &ige_test_vectors[n]; 155 AES_KEY key; 156 unsigned char buf[MAX_VECTOR_SIZE]; 157 unsigned char iv[AES_BLOCK_SIZE * 2]; 158 159 assert(v->length <= MAX_VECTOR_SIZE); 160 161 if (v->encrypt == AES_ENCRYPT) 162 AES_set_encrypt_key(v->key, 8 * sizeof(v->key), &key); 163 else 164 AES_set_decrypt_key(v->key, 8 * sizeof(v->key), &key); 165 memcpy(iv, v->iv, sizeof(iv)); 166 AES_ige_encrypt(v->in, buf, v->length, &key, iv, v->encrypt); 167 168 if (memcmp(v->out, buf, v->length)) { 169 printf("IGE test vector %d failed\n", n); 170 hexdump(stdout, "key", v->key, sizeof(v->key)); 171 hexdump(stdout, "iv", v->iv, sizeof(v->iv)); 172 hexdump(stdout, "in", v->in, v->length); 173 hexdump(stdout, "expected", v->out, v->length); 174 hexdump(stdout, "got", buf, v->length); 175 176 ++errs; 177 } 178 179 /* try with in == out */ 180 memcpy(iv, v->iv, sizeof(iv)); 181 memcpy(buf, v->in, v->length); 182 AES_ige_encrypt(buf, buf, v->length, &key, iv, v->encrypt); 183 184 if (memcmp(v->out, buf, v->length)) { 185 printf("IGE test vector %d failed (with in == out)\n", n); 186 hexdump(stdout, "key", v->key, sizeof(v->key)); 187 hexdump(stdout, "iv", v->iv, sizeof(v->iv)); 188 hexdump(stdout, "in", v->in, v->length); 189 hexdump(stdout, "expected", v->out, v->length); 190 hexdump(stdout, "got", buf, v->length); 191 192 ++errs; 193 } 194 } 195 196 for (n = 0; n < OSSL_NELEM(bi_ige_test_vectors); ++n) { 197 const struct bi_ige_test *const v = &bi_ige_test_vectors[n]; 198 AES_KEY key1; 199 AES_KEY key2; 200 unsigned char buf[MAX_VECTOR_SIZE]; 201 202 assert(v->length <= MAX_VECTOR_SIZE); 203 204 if (v->encrypt == AES_ENCRYPT) { 205 AES_set_encrypt_key(v->key1, 8 * v->keysize, &key1); 206 AES_set_encrypt_key(v->key2, 8 * v->keysize, &key2); 207 } else { 208 AES_set_decrypt_key(v->key1, 8 * v->keysize, &key1); 209 AES_set_decrypt_key(v->key2, 8 * v->keysize, &key2); 210 } 211 212 AES_bi_ige_encrypt(v->in, buf, v->length, &key1, &key2, v->iv, 213 v->encrypt); 214 215 if (memcmp(v->out, buf, v->length)) { 216 printf("Bidirectional IGE test vector %d failed\n", n); 217 hexdump(stdout, "key 1", v->key1, sizeof(v->key1)); 218 hexdump(stdout, "key 2", v->key2, sizeof(v->key2)); 219 hexdump(stdout, "iv", v->iv, sizeof(v->iv)); 220 hexdump(stdout, "in", v->in, v->length); 221 hexdump(stdout, "expected", v->out, v->length); 222 hexdump(stdout, "got", buf, v->length); 223 224 ++errs; 225 } 226 } 227 228 return errs; 229 } 230 231 int main(int argc, char **argv) 232 { 233 unsigned char rkey[16]; 234 unsigned char rkey2[16]; 235 AES_KEY key; 236 AES_KEY key2; 237 unsigned char plaintext[BIG_TEST_SIZE]; 238 unsigned char ciphertext[BIG_TEST_SIZE]; 239 unsigned char checktext[BIG_TEST_SIZE]; 240 unsigned char iv[AES_BLOCK_SIZE * 4]; 241 unsigned char saved_iv[AES_BLOCK_SIZE * 4]; 242 int err = 0; 243 unsigned int n; 244 unsigned matches; 245 246 assert(BIG_TEST_SIZE >= TEST_SIZE); 247 248 RAND_bytes(rkey, sizeof(rkey)); 249 RAND_bytes(plaintext, sizeof(plaintext)); 250 RAND_bytes(iv, sizeof(iv)); 251 memcpy(saved_iv, iv, sizeof(saved_iv)); 252 253 /* Forward IGE only... */ 254 255 /* Straight encrypt/decrypt */ 256 AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key); 257 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, iv, AES_ENCRYPT); 258 259 AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key); 260 memcpy(iv, saved_iv, sizeof(iv)); 261 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT); 262 263 if (memcmp(checktext, plaintext, TEST_SIZE)) { 264 printf("Encrypt+decrypt doesn't match\n"); 265 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE); 266 hexdump(stdout, "Checktext", checktext, TEST_SIZE); 267 ++err; 268 } 269 270 /* Now check encrypt chaining works */ 271 AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key); 272 memcpy(iv, saved_iv, sizeof(iv)); 273 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv, 274 AES_ENCRYPT); 275 AES_ige_encrypt(plaintext + TEST_SIZE / 2, 276 ciphertext + TEST_SIZE / 2, TEST_SIZE / 2, 277 &key, iv, AES_ENCRYPT); 278 279 AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key); 280 memcpy(iv, saved_iv, sizeof(iv)); 281 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, iv, AES_DECRYPT); 282 283 if (memcmp(checktext, plaintext, TEST_SIZE)) { 284 printf("Chained encrypt+decrypt doesn't match\n"); 285 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE); 286 hexdump(stdout, "Checktext", checktext, TEST_SIZE); 287 ++err; 288 } 289 290 /* And check decrypt chaining */ 291 AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key); 292 memcpy(iv, saved_iv, sizeof(iv)); 293 AES_ige_encrypt(plaintext, ciphertext, TEST_SIZE / 2, &key, iv, 294 AES_ENCRYPT); 295 AES_ige_encrypt(plaintext + TEST_SIZE / 2, 296 ciphertext + TEST_SIZE / 2, TEST_SIZE / 2, 297 &key, iv, AES_ENCRYPT); 298 299 AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key); 300 memcpy(iv, saved_iv, sizeof(iv)); 301 AES_ige_encrypt(ciphertext, checktext, TEST_SIZE / 2, &key, iv, 302 AES_DECRYPT); 303 AES_ige_encrypt(ciphertext + TEST_SIZE / 2, 304 checktext + TEST_SIZE / 2, TEST_SIZE / 2, &key, iv, 305 AES_DECRYPT); 306 307 if (memcmp(checktext, plaintext, TEST_SIZE)) { 308 printf("Chained encrypt+chained decrypt doesn't match\n"); 309 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE); 310 hexdump(stdout, "Checktext", checktext, TEST_SIZE); 311 ++err; 312 } 313 314 /* make sure garble extends forwards only */ 315 AES_set_encrypt_key(rkey, 8 * sizeof(rkey),&key); 316 memcpy(iv, saved_iv, sizeof(iv)); 317 AES_ige_encrypt(plaintext, ciphertext, sizeof(plaintext), &key, iv, 318 AES_ENCRYPT); 319 320 /* corrupt halfway through */ 321 ++ciphertext[sizeof(ciphertext) / 2]; 322 AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key); 323 memcpy(iv, saved_iv, sizeof(iv)); 324 AES_ige_encrypt(ciphertext, checktext, sizeof(checktext), &key, iv, 325 AES_DECRYPT); 326 327 matches = 0; 328 for (n = 0; n < sizeof(checktext); ++n) 329 if (checktext[n] == plaintext[n]) 330 ++matches; 331 332 if (matches > sizeof(checktext) / 2 + sizeof(checktext) / 100) { 333 printf("More than 51%% matches after garbling\n"); 334 ++err; 335 } 336 337 if (matches < sizeof(checktext) / 2) { 338 printf("Garble extends backwards!\n"); 339 ++err; 340 } 341 342 /* Bi-directional IGE */ 343 344 /* 345 * Note that we don't have to recover the IV, because chaining isn't 346 */ 347 /* possible with biIGE, so the IV is not updated. */ 348 349 RAND_bytes(rkey2, sizeof(rkey2)); 350 351 /* Straight encrypt/decrypt */ 352 AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key); 353 AES_set_encrypt_key(rkey2, 8 * sizeof(rkey2), &key2); 354 AES_bi_ige_encrypt(plaintext, ciphertext, TEST_SIZE, &key, &key2, iv, 355 AES_ENCRYPT); 356 357 AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key); 358 AES_set_decrypt_key(rkey2, 8 * sizeof(rkey2), &key2); 359 AES_bi_ige_encrypt(ciphertext, checktext, TEST_SIZE, &key, &key2, iv, 360 AES_DECRYPT); 361 362 if (memcmp(checktext, plaintext, TEST_SIZE)) { 363 printf("Encrypt+decrypt doesn't match\n"); 364 hexdump(stdout, "Plaintext", plaintext, TEST_SIZE); 365 hexdump(stdout, "Checktext", checktext, TEST_SIZE); 366 ++err; 367 } 368 369 /* make sure garble extends both ways */ 370 AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key); 371 AES_set_encrypt_key(rkey2, 8 * sizeof(rkey2), &key2); 372 AES_ige_encrypt(plaintext, ciphertext, sizeof(plaintext), &key, iv, 373 AES_ENCRYPT); 374 375 /* corrupt halfway through */ 376 ++ciphertext[sizeof(ciphertext) / 2]; 377 AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key); 378 AES_set_decrypt_key(rkey2, 8 * sizeof(rkey2), &key2); 379 AES_ige_encrypt(ciphertext, checktext, sizeof(checktext), &key, iv, 380 AES_DECRYPT); 381 382 matches = 0; 383 for (n = 0; n < sizeof(checktext); ++n) 384 if (checktext[n] == plaintext[n]) 385 ++matches; 386 387 if (matches > sizeof(checktext) / 100) { 388 printf("More than 1%% matches after bidirectional garbling\n"); 389 ++err; 390 } 391 392 /* make sure garble extends both ways (2) */ 393 AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key); 394 AES_set_encrypt_key(rkey2, 8 * sizeof(rkey2), &key2); 395 AES_ige_encrypt(plaintext, ciphertext, sizeof(plaintext), &key, iv, 396 AES_ENCRYPT); 397 398 /* corrupt right at the end */ 399 ++ciphertext[sizeof(ciphertext) - 1]; 400 AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key); 401 AES_set_decrypt_key(rkey2, 8 * sizeof(rkey2), &key2); 402 AES_ige_encrypt(ciphertext, checktext, sizeof(checktext), &key, iv, 403 AES_DECRYPT); 404 405 matches = 0; 406 for (n = 0; n < sizeof(checktext); ++n) 407 if (checktext[n] == plaintext[n]) 408 ++matches; 409 410 if (matches > sizeof(checktext) / 100) { 411 printf("More than 1%% matches after bidirectional garbling (2)\n"); 412 ++err; 413 } 414 415 /* make sure garble extends both ways (3) */ 416 AES_set_encrypt_key(rkey, 8 * sizeof(rkey), &key); 417 AES_set_encrypt_key(rkey2, 8 * sizeof(rkey2), &key2); 418 AES_ige_encrypt(plaintext, ciphertext, sizeof(plaintext), &key, iv, 419 AES_ENCRYPT); 420 421 /* corrupt right at the start */ 422 ++ciphertext[0]; 423 AES_set_decrypt_key(rkey, 8 * sizeof(rkey), &key); 424 AES_set_decrypt_key(rkey2, 8 * sizeof(rkey2), &key2); 425 AES_ige_encrypt(ciphertext, checktext, sizeof(checktext), &key, iv, 426 AES_DECRYPT); 427 428 matches = 0; 429 for (n = 0; n < sizeof(checktext); ++n) 430 if (checktext[n] == plaintext[n]) 431 ++matches; 432 433 if (matches > sizeof(checktext) / 100) { 434 printf("More than 1%% matches after bidirectional garbling (3)\n"); 435 ++err; 436 } 437 438 err += run_test_vectors(); 439 440 return err; 441 } 442