]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
added test suite for overriden ciphers
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Wed, 18 Mar 2015 10:46:06 +0000 (11:46 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Wed, 18 Mar 2015 12:44:14 +0000 (13:44 +0100)
tests/slow/Makefile.am
tests/slow/cipher-override.c [new file with mode: 0644]
tests/slow/override-ciphers [new file with mode: 0755]

index a97aa9032e744a638315a1dac700c4a6f3c11516..be198aeb4b4a55add07008905bd5125b9a19ea0d 100644 (file)
@@ -40,8 +40,8 @@ endif
 
 ctests = gendh keygen
 
-check_PROGRAMS = $(ctests) cipher-test
-TESTS = $(ctests) test-ciphers
+check_PROGRAMS = $(ctests) cipher-test cipher-override
+TESTS = $(ctests) test-ciphers override-ciphers
 
 EXTRA_DIST = README
 
diff --git a/tests/slow/cipher-override.c b/tests/slow/cipher-override.c
new file mode 100644 (file)
index 0000000..a980b8b
--- /dev/null
@@ -0,0 +1,250 @@
+#include <config.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <utils.h>
+#include <stdlib.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+#include <gnutls/self-test.h>
+
+#ifndef HAVE_LIBNETTLE
+int main(int argc, char **argv)
+{
+       exit(77);
+}
+#else
+
+# include <nettle/aes.h>
+# include <nettle/cbc.h>
+# include <nettle/gcm.h>
+
+/* this tests whether the API to override ciphers works sanely.
+ */
+static int used = 0;
+static int aead_used = 0;
+static void tls_log_func(int level, const char *str)
+{
+       fprintf(stderr, "<%d>| %s", level, str);
+}
+
+#ifndef ENABLE_SELF_CHECKS
+# define AVOID_INTERNALS
+# include "../../lib/crypto-selftests.c"
+#endif
+
+struct myaes_ctx {
+       struct aes_ctx aes;
+       unsigned char iv[16];
+       int enc;
+};
+
+static int
+myaes_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, int enc)
+{
+       /* we use key size to distinguish */
+       if (algorithm != GNUTLS_CIPHER_AES_128_CBC
+           && algorithm != GNUTLS_CIPHER_AES_192_CBC
+           && algorithm != GNUTLS_CIPHER_AES_256_CBC)
+               return GNUTLS_E_INVALID_REQUEST;
+
+       *_ctx = calloc(1, sizeof(struct myaes_ctx));
+       if (*_ctx == NULL) {
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       ((struct myaes_ctx *) (*_ctx))->enc = enc;
+
+       return 0;
+}
+
+static int
+myaes_setkey(void *_ctx, const void *userkey, size_t keysize)
+{
+       struct myaes_ctx *ctx = _ctx;
+
+       if (ctx->enc)
+               aes_set_encrypt_key(&ctx->aes, keysize, userkey);
+       else
+               aes_set_decrypt_key(&ctx->aes, keysize, userkey);
+
+       return 0;
+}
+
+static int myaes_setiv(void *_ctx, const void *iv, size_t iv_size)
+{
+       struct myaes_ctx *ctx = _ctx;
+
+       memcpy(ctx->iv, iv, 16);
+       return 0;
+}
+
+static int
+myaes_encrypt(void *_ctx, const void *src, size_t src_size,
+           void *dst, size_t dst_size)
+{
+       struct myaes_ctx *ctx = _ctx;
+
+       used++;
+       cbc_encrypt(&ctx->aes, (nettle_cipher_func*)aes_encrypt, 16, ctx->iv, src_size, dst, src);
+       return 0;
+}
+
+static int
+myaes_decrypt(void *_ctx, const void *src, size_t src_size,
+           void *dst, size_t dst_size)
+{
+       struct myaes_ctx *ctx = _ctx;
+
+       used++;
+       cbc_decrypt(&ctx->aes, (nettle_cipher_func*)aes_decrypt, 16, ctx->iv, src_size, dst, src);
+
+       return 0;
+}
+
+static void myaes_deinit(void *_ctx)
+{
+       free(_ctx);
+}
+
+/* AES-GCM */
+struct myaes_gcm_ctx {
+       struct gcm_aes128_ctx aes;
+};
+
+static int
+myaes_gcm_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, int enc)
+{
+       /* we use key size to distinguish */
+       if (algorithm != GNUTLS_CIPHER_AES_128_GCM
+           && algorithm != GNUTLS_CIPHER_AES_256_GCM)
+               return GNUTLS_E_INVALID_REQUEST;
+
+       *_ctx = calloc(1, sizeof(struct myaes_gcm_ctx));
+       if (*_ctx == NULL) {
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       return 0;
+}
+
+static int
+myaes_gcm_setkey(void *_ctx, const void *userkey, size_t keysize)
+{
+       struct myaes_gcm_ctx *ctx = _ctx;
+
+       gcm_aes128_set_key(&ctx->aes, userkey);
+
+       return 0;
+}
+
+static void myaes_gcm_deinit(void *_ctx)
+{
+       free(_ctx);
+}
+
+static int
+myaes_gcm_encrypt(void *_ctx,
+                       const void *nonce, size_t nonce_size,
+                       const void *auth, size_t auth_size,
+                       size_t tag_size,
+                       const void *plain, size_t plain_size,
+                       void *encr, size_t encr_size)
+{
+       /* proper AEAD cipher */
+       struct myaes_gcm_ctx *ctx = _ctx;
+       if (encr_size < plain_size + tag_size)
+               return GNUTLS_E_SHORT_MEMORY_BUFFER;
+
+       aead_used++;
+       gcm_aes128_set_iv(&ctx->aes, nonce_size, nonce);
+       gcm_aes128_update(&ctx->aes, auth_size, auth);
+
+       gcm_aes128_encrypt(&ctx->aes, plain_size, encr, plain);
+
+       gcm_aes128_digest(&ctx->aes, tag_size, ((uint8_t*)encr) + plain_size);
+       return 0;
+}
+
+static int
+myaes_gcm_decrypt(void *_ctx,
+                       const void *nonce, size_t nonce_size,
+                       const void *auth, size_t auth_size,
+                       size_t tag_size,
+                       const void *encr, size_t encr_size,
+                       void *plain, size_t plain_size)
+{
+       uint8_t tag[16];
+       struct myaes_gcm_ctx *ctx = _ctx;
+
+       if (encr_size < tag_size)
+               return GNUTLS_E_DECRYPTION_FAILED;
+
+       aead_used++;
+       gcm_aes128_set_iv(&ctx->aes, nonce_size, nonce);
+       gcm_aes128_update(&ctx->aes, auth_size, auth);
+
+       encr_size -= tag_size;
+       gcm_aes128_decrypt(&ctx->aes, encr_size, plain, encr);
+
+       gcm_aes128_digest(&ctx->aes, tag_size, tag);
+
+       if (gnutls_memcmp(((uint8_t*)encr)+encr_size, tag, tag_size) != 0)
+               return GNUTLS_E_DECRYPTION_FAILED;
+
+       return 0;
+}
+
+
+
+int main(int argc, char **argv)
+{
+       int ret;
+
+       gnutls_global_set_log_function(tls_log_func);
+       if (argc > 1)
+               gnutls_global_set_log_level(4711);
+
+       ret = gnutls_crypto_register_cipher(GNUTLS_CIPHER_AES_128_CBC, 1,
+               myaes_init,
+               myaes_setkey,
+               myaes_setiv,
+               myaes_encrypt,
+               myaes_decrypt,
+               myaes_deinit);
+       if (ret < 0) {
+               fprintf(stderr, "%d: cannot register cipher\n", __LINE__);
+               exit(1);
+       }
+
+       ret = gnutls_crypto_register_aead_cipher(GNUTLS_CIPHER_AES_128_GCM, 1,
+               myaes_gcm_init,
+               myaes_gcm_setkey,
+               myaes_gcm_encrypt,
+               myaes_gcm_decrypt,
+               myaes_gcm_deinit);
+       if (ret < 0) {
+               fprintf(stderr, "%d: cannot register cipher\n", __LINE__);
+               exit(1);
+       }
+
+       global_init();
+
+       if (gnutls_cipher_self_test(1, 0) < 0)
+               return 1;
+
+       if (used == 0) {
+               fprintf(stderr, "The CBC cipher was not used\n");
+               exit(1);
+       }
+
+       if (aead_used == 0) {
+               fprintf(stderr, "The AEAD cipher was not used\n");
+               exit(1);
+       }
+
+       gnutls_global_deinit();
+       return 0;
+}
+
+#endif
diff --git a/tests/slow/override-ciphers b/tests/slow/override-ciphers
new file mode 100755 (executable)
index 0000000..65fc20b
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# Author: Nikos Mavrogiannopoulos
+#
+# This file is part of GnuTLS.
+#
+# GnuTLS is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# GnuTLS is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GnuTLS; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+srcdir="${srcdir:-.}"
+CLI="${CLI:-../../src/gnutls-cli$EXEEXT}"
+unset RETCODE
+if ! test -z "${VALGRIND}";then
+VALGRIND="${LIBTOOL:-libtool} --mode=execute ${VALGRIND}"
+fi
+
+GNUTLS_NO_EXPLICIT_INIT=1 $VALGRIND ./cipher-override
+if test $? != 0;then
+       echo "overriden cipher tests failed"
+       exit 1
+fi
+
+$VALGRIND ./cipher-override
+if test $? != 0;then
+       echo "overriden cipher tests 2 failed"
+       exit 1
+fi
+
+exit 0