From: Nikos Mavrogiannopoulos Date: Wed, 18 Mar 2015 10:46:06 +0000 (+0100) Subject: added test suite for overriden ciphers X-Git-Tag: gnutls_3_4_0~180 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=441325bdf3e33db39d4f833e10102ad48fb0cd4f;p=thirdparty%2Fgnutls.git added test suite for overriden ciphers --- diff --git a/tests/slow/Makefile.am b/tests/slow/Makefile.am index a97aa9032e..be198aeb4b 100644 --- a/tests/slow/Makefile.am +++ b/tests/slow/Makefile.am @@ -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 index 0000000000..a980b8b8a7 --- /dev/null +++ b/tests/slow/cipher-override.c @@ -0,0 +1,250 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef HAVE_LIBNETTLE +int main(int argc, char **argv) +{ + exit(77); +} +#else + +# include +# include +# include + +/* 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 index 0000000000..65fc20b300 --- /dev/null +++ b/tests/slow/override-ciphers @@ -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