From ba809c231ee0a340af7808ee6caf49c0b8baceb7 Mon Sep 17 00:00:00 2001 From: Koen Zandberg <koen@bergzand.net> Date: Mon, 16 Apr 2018 19:02:04 +0200 Subject: [PATCH] pkg/libcose: add simple unittest application --- tests/unittests/Makefile | 1 + tests/unittests/tests-libcose/Makefile | 1 + .../unittests/tests-libcose/Makefile.include | 7 + tests/unittests/tests-libcose/tests-libcose.c | 216 ++++++++++++++++++ tests/unittests/tests-libcose/tests-libcose.h | 37 +++ 5 files changed, 262 insertions(+) create mode 100644 tests/unittests/tests-libcose/Makefile create mode 100644 tests/unittests/tests-libcose/Makefile.include create mode 100644 tests/unittests/tests-libcose/tests-libcose.c create mode 100644 tests/unittests/tests-libcose/tests-libcose.h diff --git a/tests/unittests/Makefile b/tests/unittests/Makefile index a338af3aa6..77e2b74bed 100644 --- a/tests/unittests/Makefile +++ b/tests/unittests/Makefile @@ -215,6 +215,7 @@ ifneq (, $(filter $(AVR_BOARDS), $(BOARD))) endif LARGE_STACK_TESTS += tests-hacl +LARGE_STACK_TESTS += tests-libcose LARGE_STACK_TESTS += tests-tweetnacl ifneq (,$(filter $(LARGE_STACK_TESTS), $(UNIT_TESTS))) CFLAGS += -DTHREAD_STACKSIZE_MAIN=\(4*THREAD_STACKSIZE_DEFAULT+THREAD_EXTRA_STACKSIZE_PRINTF\) diff --git a/tests/unittests/tests-libcose/Makefile b/tests/unittests/tests-libcose/Makefile new file mode 100644 index 0000000000..967631ff5d --- /dev/null +++ b/tests/unittests/tests-libcose/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/tests/unittests/tests-libcose/Makefile.include b/tests/unittests/tests-libcose/Makefile.include new file mode 100644 index 0000000000..8912e9dff4 --- /dev/null +++ b/tests/unittests/tests-libcose/Makefile.include @@ -0,0 +1,7 @@ +CFLAGS +=-DCOSE_SIGNATURES_MAX=2 + +USEPKG += libcose + +USEMODULE += random +USEMODULE += memarray +USEMODULE += libcose_crypt_hacl diff --git a/tests/unittests/tests-libcose/tests-libcose.c b/tests/unittests/tests-libcose/tests-libcose.c new file mode 100644 index 0000000000..ccd989ec96 --- /dev/null +++ b/tests/unittests/tests-libcose/tests-libcose.c @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2018 Freie Universität Berlin + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Unit tests for pkg libcose + * + * @author Koen Zandberg <koen@bergzand.net> + */ + +/* Number of nodes allocated for cn-cbor */ +#define MAX_NUMBER_BLOCKS 32 + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "cn-cbor/cn-cbor.h" +#include "cose.h" +#include "cose/crypto.h" +#include "embUnit.h" +#include "memarray.h" +#include "random.h" + +#include "tests-libcose.h" + +/* Example payload */ +static char payload[] = "Input string"; +/* Key ID's */ +static const char kid[] = "peter@riot-os.org"; +static const char kid2[] = "schmerzl@riot-os.org"; +/* Key pairs */ +static unsigned char pk[COSE_CRYPTO_SIGN_ED25519_PUBLICKEYBYTES]; +static unsigned char sk[COSE_CRYPTO_SIGN_ED25519_SECRETKEYBYTES]; +static unsigned char pk2[COSE_CRYPTO_SIGN_ED25519_PUBLICKEYBYTES]; +static unsigned char sk2[COSE_CRYPTO_SIGN_ED25519_SECRETKEYBYTES]; +static unsigned char symmkey[COSE_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES]; +static uint8_t nonce[COSE_CRYPTO_AEAD_CHACHA20POLY1305_NONCEBYTES] = { 0 }; +/* COSE structs */ +static cose_sign_t sign, verify; +static cose_key_t signer, signer2, symm; +static cose_encrypt_t test_encrypt, test_decrypt; +/* COSE sign buffer */ +static uint8_t buf[1024]; +/*Signature Verification buffer */ +static uint8_t vbuf[1024]; + +static cn_cbor block_storage_data[MAX_NUMBER_BLOCKS]; +static memarray_t storage; + +/* CN_CBOR calloc/free functions */ +static void *cose_calloc(size_t count, size_t size, void *memblock); +static void cose_free(void *ptr, void *memblock); + +/* CN_CBOR block allocator context struct*/ +static cn_cbor_context ct = +{ + .calloc_func = cose_calloc, + .free_func = cose_free, + .context = &storage, +}; + +static void *cose_calloc(size_t count, size_t size, void *memblock) +{ + (void)count; + void *block = memarray_alloc(memblock); + if (block) { + memset(block, 0, size); + } + return block; + +} + +static void cose_free(void *ptr, void *memblock) +{ + memarray_free(memblock, ptr); +} + +static void setUp(void) +{ + /* Initialize */ + random_init(0); + memarray_init(&storage, block_storage_data, sizeof(cn_cbor), + MAX_NUMBER_BLOCKS); + /* Clear buffer */ + memset(buf, 0, sizeof(buf)); + memset(vbuf, 0, sizeof(vbuf)); +} + +static void test_libcose_01(void) +{ + /* Set up first signer */ + cose_key_init(&signer); + cose_key_set_keys(&signer, COSE_EC_CURVE_ED25519, COSE_ALGO_EDDSA, + pk, NULL, sk); + cose_crypto_keypair_ed25519(&signer); + cose_key_set_kid(&signer, (uint8_t *)kid, sizeof(kid) - 1); + + /* Initialize struct */ + cose_sign_init(&sign, COSE_FLAGS_UNTAGGED); + cose_sign_init(&verify, 0); + + /* Add payload */ + cose_sign_set_payload(&sign, payload, sizeof(payload)); + + /* First signer */ + cose_sign_add_signer(&sign, &signer); + + /* Encode COSE sign object */ + uint8_t *out = NULL; + ssize_t encode_size = cose_sign_encode(&sign, buf, sizeof(buf), &out, &ct); + TEST_ASSERT(encode_size > 0); + /* Decode again */ + TEST_ASSERT_EQUAL_INT(cose_sign_decode(&verify, out, encode_size, &ct), 0); + /* Verify with signature slot 0 */ + TEST_ASSERT_EQUAL_INT(cose_sign_verify(&verify, &signer, + 0, vbuf, sizeof(vbuf), &ct), 0); +} + +static void test_libcose_02(void) +{ + /* Set up first signer */ + cose_key_init(&signer); + cose_key_set_keys(&signer, COSE_EC_CURVE_ED25519, COSE_ALGO_EDDSA, + pk, NULL, sk); + cose_crypto_keypair_ed25519(&signer); + cose_key_set_kid(&signer, (uint8_t *)kid, sizeof(kid) - 1); + + /* Second signer */ + cose_key_init(&signer2); + cose_key_set_keys(&signer2, COSE_EC_CURVE_ED25519, COSE_ALGO_EDDSA, + pk2, NULL, sk2); + cose_crypto_keypair_ed25519(&signer2); + cose_key_set_kid(&signer2, (uint8_t *)kid2, sizeof(kid2) - 1); + + /* Initialize struct */ + cose_sign_init(&sign, 0); + cose_sign_init(&verify, 0); + + /* Add payload */ + cose_sign_set_payload(&sign, payload, sizeof(payload)); + + /* Signers */ + cose_sign_add_signer(&sign, &signer); + cose_sign_add_signer(&sign, &signer2); + + uint8_t *out = NULL; + size_t len = cose_sign_encode(&sign, buf, sizeof(buf), &out, &ct); + + TEST_ASSERT(len > 0); + TEST_ASSERT_EQUAL_INT(cose_sign_decode(&verify, out, len, &ct), 0); + + /* Test correct signature with correct signer */ + TEST_ASSERT_EQUAL_INT(cose_sign_verify(&verify, &signer, 0, vbuf, + sizeof(vbuf), &ct), 0); + TEST_ASSERT(cose_sign_verify(&verify, &signer, 1, vbuf, + sizeof(vbuf), &ct) != 0); + TEST_ASSERT(cose_sign_verify(&verify, &signer2, 0, vbuf, + sizeof(vbuf), &ct) != 0); + TEST_ASSERT_EQUAL_INT(cose_sign_verify(&verify, &signer2, 1, vbuf, + sizeof(vbuf), &ct), 0); +} + +static void test_libcose_03(void) +{ + cose_key_init(&symm); + cose_encrypt_init(&test_encrypt); + cose_encrypt_init(&test_decrypt); + + cose_crypto_keygen(symmkey, sizeof(symmkey), COSE_ALGO_CHACHA20POLY1305); + cose_key_set_kid(&symm, (uint8_t *)kid, sizeof(kid) - 1); + cose_key_set_keys(&symm, 0, COSE_ALGO_CHACHA20POLY1305, + NULL, NULL, symmkey); + cose_encrypt_add_recipient(&test_encrypt, &symm); + cose_encrypt_set_algo(&test_encrypt, COSE_ALGO_DIRECT); + + cose_encrypt_set_payload(&test_encrypt, payload, sizeof(payload) - 1); + + uint8_t *out = NULL; + ssize_t len = cose_encrypt_encode(&test_encrypt, buf, sizeof(buf), nonce, &out, &ct); + TEST_ASSERT(len > 0); + TEST_ASSERT_EQUAL_INT(cose_encrypt_decode(&test_decrypt, out, len, &ct), 0); + size_t plaintext_len = 0; + int res = cose_encrypt_decrypt(&test_decrypt, &symm, 0, buf, sizeof(buf), vbuf, + &plaintext_len, &ct); + TEST_ASSERT_EQUAL_INT(res, 0); + TEST_ASSERT_EQUAL_INT(plaintext_len, sizeof(payload) - 1); +} + +Test *tests_libcose_all(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_libcose_01), + new_TestFixture(test_libcose_02), + new_TestFixture(test_libcose_03), + }; + + EMB_UNIT_TESTCALLER(libcose_tests, setUp, NULL, fixtures); + return (Test *)&libcose_tests; +} + +void tests_libcose(void) +{ + printf("Starting libcose test, performing multiple signature operations.\n"); + printf("This can take a while (up to 2 minutes on the samr21-xpro)\n"); + TESTS_RUN(tests_libcose_all()); +} diff --git a/tests/unittests/tests-libcose/tests-libcose.h b/tests/unittests/tests-libcose/tests-libcose.h new file mode 100644 index 0000000000..9051f34762 --- /dev/null +++ b/tests/unittests/tests-libcose/tests-libcose.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 Freie Universität Berlin + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup unittests + * @{ + * + * @file + * @brief Unittests for the libcose package + * + */ +#ifndef TESTS_LIBCOSE_H +#define TESTS_LIBCOSE_H + +#include "embUnit/embUnit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The entry point of this test suite. + */ +void tests_libcose(void); + +#ifdef __cplusplus +} +#endif + +#endif /* TESTS_LIBCOSE_H */ +/** @} */ -- GitLab