diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-05-22 11:54:25 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-05-22 23:25:48 +0200 |
commit | af8aa846ae2f664ee30159bfdf9cd4beeb9bebba (patch) | |
tree | a25cb23924f868e9f37a039117e53edb6bdea0aa | |
parent | c2d0881f72cc483e1fc072406a2c8e5df2f17109 (diff) | |
download | gnutls-af8aa846ae2f664ee30159bfdf9cd4beeb9bebba.tar.gz |
crypto: self-tests: enhance to include compatibility APIs
That is, run the compatibility gnutls_cipher_* APIs on self tests
for AEAD ciphers in addition to the AEAD API.
Relates #204
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r-- | lib/crypto-selftests.c | 232 |
1 files changed, 221 insertions, 11 deletions
diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index 63ab44f0b4..b9d14a5538 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -37,7 +37,6 @@ #define V(x) (x), (sizeof(x)/sizeof(x[0])) - /* This does check the AES and SHA implementation against test vectors. * This should not run under valgrind in order to use the native * cpu instructions (AES-NI or padlock). @@ -56,6 +55,7 @@ struct cipher_vectors_st { }; struct cipher_aead_vectors_st { + unsigned compat_apis; const uint8_t *key; unsigned int key_size; @@ -74,6 +74,7 @@ struct cipher_aead_vectors_st { const struct cipher_aead_vectors_st chacha_poly1305_vectors[] = { { + .compat_apis = 1, STR(key, key_size, "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0"), .auth = (void*)"\xf3\x33\x88\x86\x00\x00\x00\x00\x00\x00\x4e\x91", @@ -90,6 +91,7 @@ const struct cipher_aead_vectors_st chacha_poly1305_vectors[] = { const struct cipher_aead_vectors_st aes128_gcm_vectors[] = { { + .compat_apis = 1, STR(key, key_size, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), .auth = NULL, @@ -103,6 +105,7 @@ const struct cipher_aead_vectors_st aes128_gcm_vectors[] = { .tag = (void *) "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45\x5a"}, { + .compat_apis = 1, STR(key, key_size, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), .auth = NULL, @@ -117,6 +120,7 @@ const struct cipher_aead_vectors_st aes128_gcm_vectors[] = { .tag = (void *) "\xab\x6e\x47\xd4\x2c\xec\x13\xbd\xf5\x3a\x67\xb2\x12\x57\xbd\xdf"}, { + .compat_apis = 1, STR(key, key_size, "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08"), .auth = (void *) @@ -135,6 +139,7 @@ const struct cipher_aead_vectors_st aes128_gcm_vectors[] = { const struct cipher_aead_vectors_st aes256_gcm_vectors[] = { { + .compat_apis = 1, STR(key, key_size, "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08"), .auth = NULL, @@ -154,7 +159,9 @@ const struct cipher_aead_vectors_st aes256_gcm_vectors[] = { }; const struct cipher_aead_vectors_st aes256_ccm_vectors[] = { - { STR(key, key_size, + { + .compat_apis = 0, + STR(key, key_size, "\xfb\x76\x15\xb2\x3d\x80\x89\x1d\xd4\x70\x98\x0b\xc7\x95\x84\xc8\xb2\xfb\x64\xce\x60\x97\x8f\x4d\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"), .auth = NULL, .auth_size = 0, @@ -168,6 +175,7 @@ const struct cipher_aead_vectors_st aes256_ccm_vectors[] = { .tag = (void *) "\x34\x72\xe1\x14\x5f\x2c\x0c\xbe\x14\x63\x49\x06\x2c\xf0\xe4\x23"}, { + .compat_apis = 0, STR(key, key_size, "\xfb\x76\x15\xb2\x3d\x80\x89\x1d\xd4\x70\x98\x0b\xc7\x95\x84\xc8\xb2\xfb\x64\xce\x60\x97\x87\x8d\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"), STR(auth, auth_size, "\x36"), @@ -184,6 +192,7 @@ const struct cipher_aead_vectors_st aes256_ccm_vectors[] = { const struct cipher_aead_vectors_st aes128_ccm_vectors[] = { { + .compat_apis = 0, STR(key, key_size, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF"), STR(auth, auth_size, "\x08\xD0\x84\x21\x43\x01\x00\x00\x00\x00\x48\xDE\xAC\x02\x05\x00\x00\x00\x55\xCF\x00\x00\x51\x52\x53\x54"), @@ -195,6 +204,7 @@ const struct cipher_aead_vectors_st aes128_ccm_vectors[] = { .tag = (void *) "\x22\x3B\xC1\xEC\x84\x1A\xB5\x53"}, { + .compat_apis = 0, STR(key, key_size, "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"), STR(auth, auth_size, "\x00\x01\x02\x03\x04\x05\x06\x07"), @@ -209,6 +219,7 @@ const struct cipher_aead_vectors_st aes128_ccm_vectors[] = { "\x4d\xac\x25\x5d"}, /* from rfc3610 */ { + .compat_apis = 0, STR(key, key_size, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF"), STR(auth, auth_size, "\x00\x01\x02\x03\x04\x05\x06\x07"), @@ -222,6 +233,7 @@ const struct cipher_aead_vectors_st aes128_ccm_vectors[] = { .tag = (void *) "\x04\x8C\x56\x60\x2C\x97\xAC\xBB\x74\x90"}, { + .compat_apis = 0, STR(key, key_size, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF"), STR(auth, auth_size, "\x00\x01\x02\x03\x04\x05\x06\x07"), @@ -398,8 +410,6 @@ static int test_cipher(gnutls_cipher_algorithm_t cipher, if (ret < 0) return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); - gnutls_cipher_deinit(hd); - if (memcmp (tmp, vectors[i].ciphertext, vectors[i].plaintext_size) != 0) { @@ -408,6 +418,25 @@ static int test_cipher(gnutls_cipher_algorithm_t cipher, i); return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } + + /* check in-place encryption */ + if (cipher != GNUTLS_CIPHER_ARCFOUR_128) { /* arcfour is stream */ + gnutls_cipher_set_iv(hd, (void*)vectors[i].iv, vectors[i].iv_size); + + memcpy(tmp, vectors[i].plaintext, vectors[i].plaintext_size); + ret = gnutls_cipher_encrypt(hd, tmp, vectors[i].plaintext_size); + if (ret < 0) + return + gnutls_assert_val + (GNUTLS_E_SELF_TEST_ERROR); + + if (memcmp(tmp, vectors[i].ciphertext, vectors[i].plaintext_size) != 0) { + _gnutls_debug_log("%s vector %d in-place encryption failed!\n", gnutls_cipher_get_name(cipher), i); + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + } + + gnutls_cipher_deinit(hd); } iv.size = gnutls_cipher_get_iv_size(cipher); @@ -434,8 +463,6 @@ static int test_cipher(gnutls_cipher_algorithm_t cipher, return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } - gnutls_cipher_deinit(hd); - if (memcmp (tmp, vectors[i].plaintext, vectors[i].plaintext_size) != 0) { @@ -444,6 +471,25 @@ static int test_cipher(gnutls_cipher_algorithm_t cipher, i); return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } + + /* check in-place decryption */ + if (cipher != GNUTLS_CIPHER_ARCFOUR_128) { /* arcfour is stream */ + gnutls_cipher_set_iv(hd, (void*)vectors[i].iv, vectors[i].iv_size); + + memcpy(tmp, vectors[i].ciphertext, vectors[i].plaintext_size); + ret = gnutls_cipher_decrypt(hd, tmp, vectors[i].plaintext_size); + if (ret < 0) + return + gnutls_assert_val + (GNUTLS_E_SELF_TEST_ERROR); + + if (memcmp(tmp, vectors[i].plaintext, vectors[i].plaintext_size) != 0) { + _gnutls_debug_log("%s vector %d in-place decryption failed!\n", gnutls_cipher_get_name(cipher), i); + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + } + + gnutls_cipher_deinit(hd); } _gnutls_debug_log @@ -453,6 +499,169 @@ static int test_cipher(gnutls_cipher_algorithm_t cipher, return 0; } +/* AEAD modes (compat APIs) */ +static int test_cipher_aead_compat(gnutls_cipher_algorithm_t cipher, + const struct cipher_aead_vectors_st *vectors, + size_t vectors_size) +{ + gnutls_cipher_hd_t hd; + int ret; + unsigned int i; + uint8_t tmp[384]; + uint8_t tmp2[384]; + gnutls_datum_t key, iv; + unsigned tag_size; + + _gnutls_debug_log("compat: running tests for: %s\n", + gnutls_cipher_get_name(cipher)); + + for (i = 0; i < vectors_size; i++) { + memset(tmp, 0, sizeof(tmp)); + key.data = (void *) vectors[i].key; + key.size = vectors[i].key_size; + + iv.data = (void *) vectors[i].iv; + iv.size = vectors[i].iv_size; + tag_size = vectors[i].tag_size; + + + if (tag_size > gnutls_cipher_get_tag_size(cipher)) { + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_cipher_init(&hd, cipher, &key, &iv); + if (ret < 0) { + if (vectors[i].compat_apis == 0) { + return 0; /* expected */ + } else { + _gnutls_debug_log("compat: error initializing: %s\n", + gnutls_cipher_get_name(cipher)); + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + } + + if (vectors[i].compat_apis == 0) { + _gnutls_debug_log("compat: initialized but shouldn't: %s\n", + gnutls_cipher_get_name(cipher)); + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + if (vectors[i].auth_size) { + ret = gnutls_cipher_add_auth(hd, vectors[i].auth, vectors[i].auth_size); + if (ret < 0) + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_cipher_encrypt2(hd, vectors[i].plaintext, vectors[i].plaintext_size, + tmp, sizeof(tmp)); + if (ret < 0) + return + gnutls_assert_val + (GNUTLS_E_SELF_TEST_ERROR); + + ret = gnutls_cipher_tag(hd, tmp+vectors[i].plaintext_size, tag_size); + if (ret < 0) + return + gnutls_assert_val + (GNUTLS_E_SELF_TEST_ERROR); + + if (memcmp(tmp+vectors[i].plaintext_size, vectors[i].tag, tag_size) != 0) { + _gnutls_debug_log + ("compat: %s test vector %d failed (tag)!\n", + gnutls_cipher_get_name(cipher), i); + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + if (vectors[i].plaintext_size > 0) { + if (memcmp + (tmp, vectors[i].ciphertext, + vectors[i].plaintext_size) != 0) { + _gnutls_debug_log + ("compat: %s test vector %d failed!\n", + gnutls_cipher_get_name(cipher), i); + + return + gnutls_assert_val + (GNUTLS_E_SELF_TEST_ERROR); + } + } + + /* check inplace encryption */ + if (vectors[i].plaintext_size > 0) { + gnutls_cipher_set_iv(hd, (void*)vectors[i].iv, vectors[i].iv_size); + memcpy(tmp2, vectors[i].plaintext, vectors[i].plaintext_size); + + ret = gnutls_cipher_encrypt(hd, tmp2, vectors[i].plaintext_size); + if (ret < 0) + return + gnutls_assert_val + (GNUTLS_E_SELF_TEST_ERROR); + + if (memcmp(tmp, tmp2, vectors[i].plaintext_size) != 0) { + _gnutls_debug_log("compat: %s vector %d in-place encryption failed!\n", gnutls_cipher_get_name(cipher), i); + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + } + + { + /* check decryption with separate buffers */ + gnutls_cipher_set_iv(hd, (void*)vectors[i].iv, vectors[i].iv_size); + + if (vectors[i].auth_size) { + ret = gnutls_cipher_add_auth(hd, vectors[i].auth, vectors[i].auth_size); + if (ret < 0) + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = + gnutls_cipher_decrypt2(hd, tmp, vectors[i].plaintext_size, + tmp2, sizeof(tmp2)); + if (ret < 0) + return + gnutls_assert_val + (GNUTLS_E_SELF_TEST_ERROR); + + if (memcmp(tmp2, vectors[i].plaintext, vectors[i].plaintext_size) != 0) { + _gnutls_debug_log("compat: %s test vector %d failed (decryption)!\n", + gnutls_cipher_get_name(cipher), i); + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + /* check in-place decryption */ + if (vectors[i].plaintext_size > 0) { + gnutls_cipher_set_iv(hd, (void*)vectors[i].iv, vectors[i].iv_size); + + if (vectors[i].auth_size) { + ret = gnutls_cipher_add_auth(hd, vectors[i].auth, vectors[i].auth_size); + if (ret < 0) + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + memcpy(tmp2, tmp, vectors[i].plaintext_size); + ret = gnutls_cipher_decrypt(hd, tmp2, vectors[i].plaintext_size); + if (ret < 0) + return + gnutls_assert_val + (GNUTLS_E_SELF_TEST_ERROR); + + if (memcmp(tmp2, vectors[i].plaintext, vectors[i].plaintext_size) != 0) { + _gnutls_debug_log("compat: %s vector %d in-place decryption failed!\n", gnutls_cipher_get_name(cipher), i); + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + } + } + + gnutls_cipher_deinit(hd); + } + + _gnutls_debug_log + ("%s compat self check succeeded\n", + gnutls_cipher_get_name(cipher)); + + return 0; + +} + /* AEAD modes */ static int test_cipher_aead(gnutls_cipher_algorithm_t cipher, const struct cipher_aead_vectors_st *vectors, @@ -467,6 +676,9 @@ static int test_cipher_aead(gnutls_cipher_algorithm_t cipher, size_t s, s2; unsigned tag_size; + _gnutls_debug_log("running tests for: %s\n", + gnutls_cipher_get_name(cipher)); + for (i = 0; i < vectors_size; i++) { memset(tmp, 0, sizeof(tmp)); key.data = (void *) vectors[i].key; @@ -489,8 +701,6 @@ static int test_cipher_aead(gnutls_cipher_algorithm_t cipher, gnutls_cipher_get_name(cipher)); return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } - _gnutls_debug_log("initialized: %s\n", - gnutls_cipher_get_name(cipher)); s = sizeof(tmp); @@ -521,7 +731,6 @@ static int test_cipher_aead(gnutls_cipher_algorithm_t cipher, } if (vectors[i].plaintext_size > 0) { - if (memcmp (tmp, vectors[i].ciphertext, vectors[i].plaintext_size) != 0) { @@ -585,10 +794,11 @@ static int test_cipher_aead(gnutls_cipher_algorithm_t cipher, ("%s self check succeeded\n", gnutls_cipher_get_name(cipher)); - return 0; - + /* test the compatibility APIs */ + return test_cipher_aead_compat(cipher, vectors, vectors_size); } + struct hash_vectors_st { const uint8_t *plaintext; unsigned int plaintext_size; |