summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-05-22 11:54:25 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-05-22 23:25:48 +0200
commitaf8aa846ae2f664ee30159bfdf9cd4beeb9bebba (patch)
treea25cb23924f868e9f37a039117e53edb6bdea0aa
parentc2d0881f72cc483e1fc072406a2c8e5df2f17109 (diff)
downloadgnutls-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.c232
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;