diff --git a/dist/tools/travis-scripts/get-pkg-list.py b/dist/tools/travis-scripts/get-pkg-list.py index ecae99d44dce8343378b5d77fbdbbeff744f783b..d6babe42d8d0aa76ddaf76d8bfd6fdf2d943e393 100755 --- a/dist/tools/travis-scripts/get-pkg-list.py +++ b/dist/tools/travis-scripts/get-pkg-list.py @@ -30,6 +30,10 @@ known_mcu_groups = arm_mcu_groups + msp_mcu_groups + x86_mcu_groups + \ avr8_mcu_groups + static_tests_groups common_pkgs = ["pcregrep", "libpcre3", "python3"] + +# testing the relic pkg and its RIOT specific unit test requires cmake +common_pkgs = common_pkgs + ["cmake"] + arm_pkgs = ["gcc-arm-none-eabi"] msp_pkgs = ["gcc-msp430"] x86_pkgs = ["qemu-system-x86", "g++-multilib", "gcc-multilib", diff --git a/pkg/relic/0001-fixed-signedness-of-counter-variable.patch b/pkg/relic/0001-fixed-signedness-of-counter-variable.patch new file mode 100644 index 0000000000000000000000000000000000000000..c4dbd2917536703295e4af8c5a5c6610c19b7467 Binary files /dev/null and b/pkg/relic/0001-fixed-signedness-of-counter-variable.patch differ diff --git a/pkg/relic/0002-don-t-redefine-ALIGN.patch b/pkg/relic/0002-don-t-redefine-ALIGN.patch new file mode 100644 index 0000000000000000000000000000000000000000..9cbc90ca040a4e24e47c9030c2745719cef4f61e Binary files /dev/null and b/pkg/relic/0002-don-t-redefine-ALIGN.patch differ diff --git a/pkg/relic/0003-require-only-CMake-version-2.8.patch b/pkg/relic/0003-require-only-CMake-version-2.8.patch new file mode 100644 index 0000000000000000000000000000000000000000..d8be0d262f24a6946fd6583f37a60d9610345ae7 Binary files /dev/null and b/pkg/relic/0003-require-only-CMake-version-2.8.patch differ diff --git a/pkg/relic/Makefile b/pkg/relic/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..54234c534c3663e8a046a61fe47010bed42ffee5 --- /dev/null +++ b/pkg/relic/Makefile @@ -0,0 +1,44 @@ +RELIC_URL=http://github.com/relic-toolkit/relic.git +RELIC_BRANCH=master + +PKG_NAME=relic +PKG_URL=$(RELIC_URL) +PKG_VERSION=$(RELIC_BRANCH) +PKG_DIR=$(CURDIR)/$(PKG_NAME) + +ifneq ($(RIOTBOARD),) +include $(RIOTBOARD)/$(BOARD)/Makefile.include +endif + +ifneq ($(RIOTBASE),) +INCLUDES += -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/sys/net/include \ + -I$(RIOTBASE)/sys/posix/include -I$(RIOTBASE)/sys/posix/pnet/include +endif + +.PHONY: all clean reset + +all: $(PKG_DIR)/Makefile + "$(MAKE)" -C $(PKG_DIR) && \ + cp $(PKG_DIR)/lib/librelic_s.a $(BINDIR)$(PKG_NAME).a + +$(PKG_DIR)/comp-options.cmake: $(PKG_DIR)/.git/config + cd "$(PKG_DIR)" && perl ../generate-cmake-xcompile.perl > comp-options.cmake + +$(PKG_DIR)/Makefile: $(PKG_DIR)/comp-options.cmake + cd "$(PKG_DIR)" && COMP="$(filter-out -Werror=old-style-definition -Werror=strict-prototypes, $(CFLAGS) ) " cmake -DCMAKE_TOOLCHAIN_FILE=comp-options.cmake -DCHECK=off -DTESTS=0 -DBENCH=0 -DSHLIB=off -Wno-dev $(RELIC_CONFIG_FLAGS) . +$(PKG_DIR)/.git/config: + test -d "$(PKG_DIR)" || git clone "$(PKG_URL)" "$(PKG_DIR)"; \ + cd "$(PKG_DIR)" && git checkout -f "$(PKG_VERSION)" + cd "$(PKG_DIR)" && git am --ignore-whitespace $(CURDIR)/*.patch + ./fix-util_print_wo_args.sh . + ./fix-old-style-definitions.sh . + +clean:: + @echo "Cleaning up relic package..." + rm -rf "$(PKG_DIR)" + +distclean:: + rm -rf "$(PKG_DIR)" + +Makefile.include: + @true diff --git a/pkg/relic/Makefile.include b/pkg/relic/Makefile.include new file mode 100644 index 0000000000000000000000000000000000000000..fa0985b127c8601eb4f64ff4874810d4fd462d14 --- /dev/null +++ b/pkg/relic/Makefile.include @@ -0,0 +1 @@ +INCLUDES += -I$(RIOTBASE)/pkg/relic/relic/include diff --git a/pkg/relic/README.md b/pkg/relic/README.md new file mode 100644 index 0000000000000000000000000000000000000000..aa25d94f0148260334d886130edd570b832f1501 --- /dev/null +++ b/pkg/relic/README.md @@ -0,0 +1,9 @@ +# Configuration Options +You can pass along configuration flags for RELIC from your project makefile via: + +```export RELIC_CONFIG_FLAGS=-DARCH=NONE -DQUIET=off -DWORD=32 -DFP_PRIME=255 -DWITH="BN;MD;DV;FP;EP;CP;BC;EC" -DSEED=ZERO``` + +This should happen before the ```USEPKG``` line. + +# Usage +Just put ```USEPKG += relic``` in your Makefile and ```#include <relic.h>```. \ No newline at end of file diff --git a/pkg/relic/fix-old-style-definitions.sh b/pkg/relic/fix-old-style-definitions.sh new file mode 100755 index 0000000000000000000000000000000000000000..36d9f1494cb400b5a295234198804c45ce5e5a9b --- /dev/null +++ b/pkg/relic/fix-old-style-definitions.sh @@ -0,0 +1,2 @@ +#!/bin/sh +find ${1} -name "*.[ch]" | xargs sed -i 's/() {/(void) {/' diff --git a/pkg/relic/fix-util_print_wo_args.sh b/pkg/relic/fix-util_print_wo_args.sh new file mode 100755 index 0000000000000000000000000000000000000000..91a5b4c6ef25e17208e6b5f45a93f82158f90d22 --- /dev/null +++ b/pkg/relic/fix-util_print_wo_args.sh @@ -0,0 +1,2 @@ +#!/bin/sh +find ${1} -name "*.[ch]" | xargs sed -i 's/util_print("\(.*\)")/util_print("\1", NULL)/g' diff --git a/pkg/relic/generate-cmake-xcompile.perl b/pkg/relic/generate-cmake-xcompile.perl new file mode 100755 index 0000000000000000000000000000000000000000..34bc106ee6f07d6b0e5cf8fcb7f5f11152ccc21b --- /dev/null +++ b/pkg/relic/generate-cmake-xcompile.perl @@ -0,0 +1,29 @@ +#!/usr/bin/env perl +print "INCLUDE(CMakeForceCompiler)\n"; +print "\n"; +print "\n"; +print "SET(CMAKE_SYSTEM_NAME Generic)\n"; +print "SET(CMAKE_SYSTEM_VERSION 1)\n"; +print "\n"; +print "SET(CMAKE_C_COMPILER \"$ENV{CC}\" CACHE STRING \"\")\n"; +print "SET(CMAKE_CXX_COMPILER \"$ENV{CXX}\" CACHE STRING \"\")\n"; +print "SET(CMAKE_RANLIB \"echo\" CACHE STRING \"\")\n"; + +print "\n"; +print "# specify the cross compiler\n"; +print "CMAKE_FORCE_C_COMPILER(\${CMAKE_C_COMPILER} GNU)\n"; +print "CMAKE_FORCE_CXX_COMPILER(\${CMAKE_CXX_COMPILER} GNU)\n"; +print "SET(CMAKE_LINKER \"$ENV{LINK}\" CACHE STRING \"\")\n"; +print "\n"; +my $esc_c_flags = "$ENV{CFLAGS}"; +$esc_c_flags =~ s/"/\\"/g; +print "SET(CMAKE_C_FLAGS \"$esc_c_flags\" CACHE STRING \"\")\n"; +print "\n"; +print "SET(CMAKE_EXE_LINKER_FLAGS \"$ENV{LINKFLAGS}\" CACHE STRING \"\")\n"; + +print "\n"; +print "# search for programs in the build host directories\n"; +print "SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\n"; +print "# for libraries and headers in the target directories\n"; +print "SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)\n"; +print "SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)\n"; diff --git a/tests/unittests/tests-relic/Makefile b/tests/unittests/tests-relic/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8f8032c93677f0d26fa6c1fe08ae9b0a9586cda4 --- /dev/null +++ b/tests/unittests/tests-relic/Makefile @@ -0,0 +1,6 @@ +MODULE = tests-relic + +# The following boards are known to fail or have not been tested. +BOARD_BLACKLIST := arduino-mega2560 chronos f4vi1 msb-430 msb-430h msbiot qemu-i386 redbee-econotag stm32f0discovery stm32f3discovery telosb wsn430-v1_3b wsn430-v1_4 z1 + +include $(RIOTBASE)/Makefile.base diff --git a/tests/unittests/tests-relic/Makefile.include b/tests/unittests/tests-relic/Makefile.include new file mode 100644 index 0000000000000000000000000000000000000000..795b81444006876c1ffeb46da9f7ab8d76e7f830 --- /dev/null +++ b/tests/unittests/tests-relic/Makefile.include @@ -0,0 +1,8 @@ +USEPKG += relic + +# -DWORD=32 : Specifies the word width of the target system. This is +# currently not automatically detected so adjusted to your target +# platform. + +# The rest of the parameters are configuration parameters for RELIC described in its documentation. +export RELIC_CONFIG_FLAGS=-DARCH=NONE -DOPSYS=NONE -DQUIET=off -DWORD=32 -DFP_PRIME=255 -DWITH="BN;MD;DV;FP;EP;CP;BC;EC" -DSEED=ZERO diff --git a/tests/unittests/tests-relic/tests-relic.c b/tests/unittests/tests-relic/tests-relic.c new file mode 100644 index 0000000000000000000000000000000000000000..832755b304357c3c858f9c8484796e892541b59c --- /dev/null +++ b/tests/unittests/tests-relic/tests-relic.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2014 Tobias Markmann <tm@ayena.de> + * + * 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. + */ + + +#define TEST_RELIC_SHOW_OUTPUT (0) /**< set if encoded/decoded string is displayed */ + +#if (TEST_RELIC_SHOW_OUTPUT == 1) +#include <stdio.h> +#endif +#include <assert.h> +#include <stdlib.h> + +#include "relic.h" +#include "embUnit.h" + +void print_mem(void *mem, int len) { + int i; + unsigned char *p = (unsigned char *)mem; + for (i=0;i<len;i++) { + printf("0x%02x ", p[i]); + } + printf("\n"); +} + +static void setUp(void) +{ + /* Initialize RELIC */ + TEST_ASSERT_EQUAL_INT(STS_OK, core_init()); +} + +static void tearDown(void) +{ + /* Finalize RELIC */ + core_clean(); +} + +static void tests_relic_ecdh(void) +{ + /* The following is an example for doing an elliptic-curve Diffie-Hellman + key exchange. + */ + + /* Select an elliptic curve configuration */ + if (ec_param_set_any() == STS_OK) { +#if (TEST_RELIC_SHOW_OUTPUT == 1) + ec_param_print(); +#endif + + bn_t privateA; + ec_t publicA; + uint8_t sharedKeyA[MD_LEN]; + + bn_t privateB; + ec_t publicB; + uint8_t sharedKeyB[MD_LEN]; + + bn_null(privateA); + ec_null(publicA); + + bn_new(privateA); + ec_new(publicA); + + bn_null(privateB); + ec_null(publicB); + + bn_new(privateB); + ec_new(publicB); + + /* User A generates private/public key pair */ + TEST_ASSERT_EQUAL_INT(STS_OK, cp_ecdh_gen(privateA, publicA)); + +#if (TEST_RELIC_SHOW_OUTPUT == 1) + printf("User A\n"); + printf("======\n"); + printf("private key: "); + bn_print(privateA); + printf("\npublic key: "); + ec_print(publicA); + printf("\n"); +#endif + + /* User B generates private/public key pair */ + TEST_ASSERT_EQUAL_INT(STS_OK, cp_ecdh_gen(privateB, publicB)); + +#if (TEST_RELIC_SHOW_OUTPUT == 1) + printf("User B\n"); + printf("======\n"); + printf("private key: "); + bn_print(privateB); + printf("\npublic key: "); + ec_print(publicB); + printf("\n"); +#endif + + /* In a protocol you would exchange the public keys now */ + + /* User A calculates shared secret */ + TEST_ASSERT_EQUAL_INT(STS_OK, cp_ecdh_key(sharedKeyA, MD_LEN, privateA, publicB)); + +#if (TEST_RELIC_SHOW_OUTPUT == 1) + printf("\nshared key computed by user A: "); + print_mem(sharedKeyA, MD_LEN); +#endif + + /* User B calculates shared secret */ + TEST_ASSERT_EQUAL_INT(STS_OK, cp_ecdh_key(sharedKeyB, MD_LEN, privateB, publicA)); + +#if (TEST_RELIC_SHOW_OUTPUT == 1) + printf("\nshared key computed by user B: "); + print_mem(sharedKeyB, MD_LEN); +#endif + + /* The secrets should be the same now */ + TEST_ASSERT_EQUAL_INT(CMP_EQ, util_cmp_const(sharedKeyA, sharedKeyB, MD_LEN)); + + bn_free(privateA); + ec_free(publicA); + + bn_free(privateB); + ec_free(publicB); +#if (TEST_RELIC_SHOW_OUTPUT == 1) + printf("\nRELIC EC-DH test successful\n"); +#endif + } + +} + +TestRef tests_relic_all(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(tests_relic_ecdh) + }; + + EMB_UNIT_TESTCALLER(RELICTest, setUp, tearDown, fixtures); + return (TestRef)&RELICTest; +} + +void tests_relic(void) +{ + TESTS_RUN(tests_relic_all()); +}