diff options
Diffstat (limited to 'src/libstrongswan')
-rw-r--r-- | src/libstrongswan/crypto/crypto_tester.c | 171 | ||||
-rw-r--r-- | src/libstrongswan/crypto/crypto_tester.h | 44 |
2 files changed, 214 insertions, 1 deletions
diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c index a5434cff0..79703830c 100644 --- a/src/libstrongswan/crypto/crypto_tester.c +++ b/src/libstrongswan/crypto/crypto_tester.c @@ -41,6 +41,11 @@ struct private_crypto_tester_t { linked_list_t *crypter; /** + * List of aead test vectors + */ + linked_list_t *aead; + + /** * List of signer test vectors */ linked_list_t *signer; @@ -256,6 +261,162 @@ METHOD(crypto_tester_t, test_crypter, bool, } /** + * Benchmark an aead transform + */ +static u_int bench_aead(private_crypto_tester_t *this, + encryption_algorithm_t alg, aead_constructor_t create) +{ + aead_t *aead; + + aead = create(alg, 0); + if (aead) + { + char iv[aead->get_iv_size(aead)]; + char key[aead->get_key_size(aead)]; + char assoc[4]; + chunk_t buf; + struct timespec start; + u_int runs; + size_t icv; + + memset(iv, 0x56, sizeof(iv)); + memset(key, 0x12, sizeof(key)); + memset(assoc, 0x78, sizeof(assoc)); + aead->set_key(aead, chunk_from_thing(key)); + icv = aead->get_icv_size(aead); + + buf = chunk_alloc(this->bench_size + icv); + memset(buf.ptr, 0x34, buf.len); + buf.len -= icv; + + runs = 0; + start_timing(&start); + while (end_timing(&start) < this->bench_time) + { + aead->encrypt(aead, buf, chunk_from_thing(assoc), + chunk_from_thing(iv), NULL); + aead->decrypt(aead, chunk_create(buf.ptr, buf.len + icv), + chunk_from_thing(assoc), chunk_from_thing(iv), NULL); + runs++; + } + free(buf.ptr); + aead->destroy(aead); + + return runs; + } + return 0; +} + +METHOD(crypto_tester_t, test_aead, bool, + private_crypto_tester_t *this, encryption_algorithm_t alg, size_t key_size, + aead_constructor_t create, u_int *speed) +{ + enumerator_t *enumerator; + aead_test_vector_t *vector; + bool failed = FALSE; + u_int tested = 0; + + enumerator = this->aead->create_enumerator(this->aead); + while (enumerator->enumerate(enumerator, &vector)) + { + aead_t *aead; + chunk_t key, plain, cipher, iv, assoc; + size_t icv; + + if (vector->alg != alg) + { + continue; + } + if (key_size && key_size != vector->key_size) + { /* test only vectors with a specific key size, if key size given */ + continue; + } + aead = create(alg, vector->key_size); + if (!aead) + { /* key size not supported... */ + continue; + } + + failed = FALSE; + tested++; + + key = chunk_create(vector->key, aead->get_key_size(aead)); + aead->set_key(aead, key); + iv = chunk_create(vector->iv, aead->get_iv_size(aead)); + assoc = chunk_create(vector->adata, vector->alen); + icv = aead->get_icv_size(aead); + + /* allocated encryption */ + plain = chunk_create(vector->plain, vector->len); + aead->encrypt(aead, plain, assoc, iv, &cipher); + if (!memeq(vector->cipher, cipher.ptr, cipher.len)) + { + failed = TRUE; + } + /* inline decryption */ + if (!aead->decrypt(aead, cipher, assoc, iv, NULL)) + { + failed = TRUE; + } + if (!memeq(vector->plain, cipher.ptr, cipher.len - icv)) + { + failed = TRUE; + } + free(cipher.ptr); + /* allocated decryption */ + cipher = chunk_create(vector->cipher, vector->len + icv); + if (!aead->decrypt(aead, cipher, assoc, iv, &plain)) + { + plain = chunk_empty; + failed = TRUE; + } + else if (!memeq(vector->plain, plain.ptr, plain.len)) + { + failed = TRUE; + } + plain.ptr = realloc(plain.ptr, plain.len + icv); + /* inline encryption */ + aead->encrypt(aead, plain, assoc, iv, NULL); + if (!memeq(vector->cipher, plain.ptr, plain.len + icv)) + { + failed = TRUE; + } + free(plain.ptr); + + aead->destroy(aead); + if (failed) + { + DBG1(DBG_LIB, "disabled %N: %s test vector failed", + encryption_algorithm_names, alg, get_name(vector)); + break; + } + } + enumerator->destroy(enumerator); + if (!tested) + { + DBG1(DBG_LIB, "%s %N: no test vectors found", + this->required ? "disabled" : "enabled ", + encryption_algorithm_names, alg); + return !this->required; + } + if (!failed) + { + if (speed) + { + *speed = bench_aead(this, alg, create); + DBG1(DBG_LIB, "enabled %N: passed %u test vectors, %d points", + encryption_algorithm_names, alg, tested, *speed); + } + else + { + DBG1(DBG_LIB, "enabled %N: passed %u test vectors", + encryption_algorithm_names, alg, tested); + } + } + return !failed; +} + +/** * Benchmark a signer */ static u_int bench_signer(private_crypto_tester_t *this, @@ -805,6 +966,12 @@ METHOD(crypto_tester_t, add_crypter_vector, void, this->crypter->insert_last(this->crypter, vector); } +METHOD(crypto_tester_t, add_aead_vector, void, + private_crypto_tester_t *this, aead_test_vector_t *vector) +{ + this->aead->insert_last(this->aead, vector); +} + METHOD(crypto_tester_t, add_signer_vector, void, private_crypto_tester_t *this, signer_test_vector_t *vector) { @@ -833,6 +1000,7 @@ METHOD(crypto_tester_t, destroy, void, private_crypto_tester_t *this) { this->crypter->destroy(this->crypter); + this->aead->destroy(this->aead); this->signer->destroy(this->signer); this->hasher->destroy(this->hasher); this->prf->destroy(this->prf); @@ -850,11 +1018,13 @@ crypto_tester_t *crypto_tester_create() INIT(this, .public = { .test_crypter = _test_crypter, + .test_aead = _test_aead, .test_signer = _test_signer, .test_hasher = _test_hasher, .test_prf = _test_prf, .test_rng = _test_rng, .add_crypter_vector = _add_crypter_vector, + .add_aead_vector = _add_aead_vector, .add_signer_vector = _add_signer_vector, .add_hasher_vector = _add_hasher_vector, .add_prf_vector = _add_prf_vector, @@ -862,6 +1032,7 @@ crypto_tester_t *crypto_tester_create() .destroy = _destroy, }, .crypter = linked_list_create(), + .aead = linked_list_create(), .signer = linked_list_create(), .hasher = linked_list_create(), .prf = linked_list_create(), diff --git a/src/libstrongswan/crypto/crypto_tester.h b/src/libstrongswan/crypto/crypto_tester.h index a670931a4..cef0b3c18 100644 --- a/src/libstrongswan/crypto/crypto_tester.h +++ b/src/libstrongswan/crypto/crypto_tester.h @@ -26,6 +26,7 @@ typedef struct crypto_tester_t crypto_tester_t; #include <crypto/crypto_factory.h> typedef struct crypter_test_vector_t crypter_test_vector_t; +typedef struct aead_test_vector_t aead_test_vector_t; typedef struct signer_test_vector_t signer_test_vector_t; typedef struct hasher_test_vector_t hasher_test_vector_t; typedef struct prf_test_vector_t prf_test_vector_t; @@ -48,6 +49,27 @@ struct crypter_test_vector_t { u_char *cipher; }; +struct aead_test_vector_t { + /** encryption algorithm this vector tests */ + encryption_algorithm_t alg; + /** key length to use, in bytes */ + size_t key_size; + /** encryption key of test vector */ + u_char *key; + /** initialization vector, using crypters blocksize bytes */ + u_char *iv; + /** length of associated data */ + size_t alen; + /** associated data */ + u_char *adata; + /** length of plain text */ + size_t len; + /** plain text */ + u_char *plain; + /** cipher text */ + u_char *cipher; +}; + struct signer_test_vector_t { /** signer algorithm this test vector tests */ pseudo_random_function_t alg; @@ -114,7 +136,7 @@ struct crypto_tester_t { * Test a crypter algorithm, optionally using a specified key size. * * @param alg algorithm to test - * @param key_size key size to test, 0 for all + * @param key_size key size to test, 0 for default * @param create constructor function for the crypter * @param speed speed test result, NULL to omit * @return TRUE if test passed @@ -122,6 +144,19 @@ struct crypto_tester_t { bool (*test_crypter)(crypto_tester_t *this, encryption_algorithm_t alg, size_t key_size, crypter_constructor_t create, u_int *speed); + + /** + * Test an aead algorithm, optionally using a specified key size. + * + * @param alg algorithm to test + * @param key_size key size to test, 0 for default + * @param create constructor function for the aead transform + * @param speed speed test result, NULL to omit + * @return TRUE if test passed + */ + bool (*test_aead)(crypto_tester_t *this, encryption_algorithm_t alg, + size_t key_size, aead_constructor_t create, + u_int *speed); /** * Test a signer algorithm. * @@ -170,6 +205,13 @@ struct crypto_tester_t { void (*add_crypter_vector)(crypto_tester_t *this, crypter_test_vector_t *vector); /** + * Add a test vector to test an aead transform. + * + * @param vector pointer to test vector + */ + void (*add_aead_vector)(crypto_tester_t *this, + aead_test_vector_t *vector); + /** * Add a test vector to test a signer. * * @param vector pointer to test vector |