From 57b8a244663cd260398bf77abcbfa0738d91b5cc Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Tue, 16 Dec 2014 17:36:38 +0100
Subject: [PATCH] Add a RELIC package and unit test that shows how to use it

Add install of cmake to .travis.yml.

Test-Information:

This has been tested on OS X and on Ubuntu for both the native target
and STM32F4Discovery.
---
 dist/tools/travis-scripts/get-pkg-list.py     |   4 +
 ...fixed-signedness-of-counter-variable.patch | Bin 0 -> 723 bytes
 pkg/relic/0002-don-t-redefine-ALIGN.patch     | Bin 0 -> 1768 bytes
 .../0003-require-only-CMake-version-2.8.patch | Bin 0 -> 581 bytes
 pkg/relic/Makefile                            |  44 ++++++
 pkg/relic/Makefile.include                    |   1 +
 pkg/relic/README.md                           |   9 ++
 pkg/relic/fix-old-style-definitions.sh        |   2 +
 pkg/relic/fix-util_print_wo_args.sh           |   2 +
 pkg/relic/generate-cmake-xcompile.perl        |  29 ++++
 tests/unittests/tests-relic/Makefile          |   6 +
 tests/unittests/tests-relic/Makefile.include  |   8 +
 tests/unittests/tests-relic/tests-relic.c     | 146 ++++++++++++++++++
 13 files changed, 251 insertions(+)
 create mode 100644 pkg/relic/0001-fixed-signedness-of-counter-variable.patch
 create mode 100644 pkg/relic/0002-don-t-redefine-ALIGN.patch
 create mode 100644 pkg/relic/0003-require-only-CMake-version-2.8.patch
 create mode 100644 pkg/relic/Makefile
 create mode 100644 pkg/relic/Makefile.include
 create mode 100644 pkg/relic/README.md
 create mode 100755 pkg/relic/fix-old-style-definitions.sh
 create mode 100755 pkg/relic/fix-util_print_wo_args.sh
 create mode 100755 pkg/relic/generate-cmake-xcompile.perl
 create mode 100644 tests/unittests/tests-relic/Makefile
 create mode 100644 tests/unittests/tests-relic/Makefile.include
 create mode 100644 tests/unittests/tests-relic/tests-relic.c

diff --git a/dist/tools/travis-scripts/get-pkg-list.py b/dist/tools/travis-scripts/get-pkg-list.py
index ecae99d44d..d6babe42d8 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
GIT binary patch
literal 723
zcmZ{hO>f&U42I9qui(*{KO)(Qzp@oM48?$9>mj=vmP|X^9NCcVpzHSIOC?)@9s&pu
zrT67Sk$SYl8H%(m;xtQYmB~yLZMNMNyF5#BOw(PwEre{_SS1p^4F--lg2;gL^12}A
zT(C#Nl<?GJ2Vd&b89oja9!`Ulzkgxhqm2gJJ+RO9j3pfFIe<8a@56<%#STPTa#4yL
zd@eX=$3^}`HJ8xpXKY~7ox#T7G{Mk<8WuC7g-dO9Eqi1v3_}K!RU0*KEcRMeYOG{4
zVx-_NB;fm`3xf3s>QtK!8!8XlOlW64n91|k0T~+X(Ve|;%~+$`7Q(R8Gt`?qaCt{y
z+BEnKDoxT@s3_ufyi00olk;@Db??2)WWMjiUGCukp-6d<f$z2)=t7$r{`Fg-QQkrq
zc{Rg_VWBBI)kRg0CV)nFq-cuVcqkkfxrRRs*gH&v%DY)_kT;~ubVO}#y#Ew?xl&fr
z5c3=W6@J;XaCP+t^nouJfW>L)XZQriAIIwH>z?_m#oYcDv^zQX9V<O><s{0c8ZN4&
WHr{A2;e%Q4sR5cPi=#A(8G8k52;0>F

literal 0
HcmV?d00001

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
GIT binary patch
literal 1768
zcmb7EYfsxi5d6&jiV=KhLSo0~IF1Pw0^0PU0<D^=QiYIpw$F)M$Byg^0@42W?)gF#
z(jXNp&$->bot?RRSCw=011`9G<PNykkA#={N8E||AdVxRiYRi$Fb-m$d$=qMOymN5
z2*(*UFSw4w**hvT!slF0@j=YycwN%Z(^(ls_rGMG%gQdR=?Qx)lpJ9qR2Oc5tMZnz
z`2c({8h9huL&xEc!zRn<r;ODINm;y7sAMA3tdKan`1t;cG0U<TvLeoxiR@J}&*D(s
zFJx`c@EbTn$2>Z!uHxQ2=|#EtC0$xK&u?%?M^PdDFt|vwT-JzZqL|90tJkxlmX*rN
zqHcBCT`HT%T$=w@o3SKIQ&`qCQxLt~%|yF#mKBM-gGgg97&^9{9Ldy6X$X$vd!A<Z
zTt!Ab<GHG*r?5!FF7el2Bo-lhE;KwWi#nSYGC^JzQ}eOR^H3c#;1H9AjI%V0g{FtJ
ztRQj|ek-a>L^K*(2lf~aved|c6L4l7tdwcuvA4GuhC-<-i<U};AzH1+Laj!-cDv0w
z2LKf@iAgKGoV*FYkH4A)tZ=i(<+yd%Mi?eC&THz?R3pp;%e<CNx!qYCjja37xvS)Y
z6eK=Pk$-vg4k70Ybx)ji!`n1>FE<=b(<`R|8<Dh`*_07__|!q$MvZz~$jUWoAR-a;
zZQBcEpL^+3*KFq)zigw8Q-)p6$tlC`kbI(bHRlPhYn2dNdv>w~W`$}%5`Cw9>lrpv
zcvd)TYvLQx&kIIL&Ez`kHus;L`+Wvu&9$q-c#$t_{cbbJJ0+_E`)~H~z%+ZG6Yb8x
zkbk<|2)87%L8yR*tm?85`Stn5*{88P3BQcLPCj3qU7Y{;HlExZlfFIlT{;~219QvN
z;X+hmPA7|5Fg|X<_t0J+##&X&Sdp(E6KX}*BI~T8$w2=VPkTP-jRD<m-=%(M*TIcG
z(wmsNb_vt017EWa+(z;jus+|(+V?hDM=xa^g)d|M7*EtTSo_|;tQ*X*rmK{>wr{(P
F{RPvb1yBG0

literal 0
HcmV?d00001

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
GIT binary patch
literal 581
zcmah_U2EGw5PaWXG33cYk#cvEWmlA<;5ft~j)QGVpcHeGR`xaeNF})>&>!EE8z?k|
za>sEyyF0rx*KJc_DnrfLL@7B<<%clMi()J%LKPWjd7wq4l;R@Iv21E=_!)8nA>z}8
z5<=3orHQdBd5;@?sPM6|-{jDw>FX1hCAWUl?my9$?m5Qx$mfu_;><S7v1N-x70U>&
zkV4Srn117|kMZT<ayz?0a1ne(%ioWtWi)m9irG>>F@A8{8M~13r$nCT(Qo|DbbaUd
zFFk%j!L_hNVM<1J(Dk14VYI0`ZhPB2a-AX0x#UymIYhZB3V7b$^w1ZlQGY1YzW_3I
z&M%m16&0NNzRL7Cm}poXQ5X(ez2hL)b@7fTN#M!zG2G!v62f!a3@(h;^Si|i_B=j1
z<YkprzN<`as$;c#GbJB=p078H)ja}VI^_PR$ol0F2p#vMhxO`qKHKiz2zJZM+tnIp
X;>=e3GrzbW@}bRJX{7wfS46)6q~fYC

literal 0
HcmV?d00001

diff --git a/pkg/relic/Makefile b/pkg/relic/Makefile
new file mode 100644
index 0000000000..54234c534c
--- /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 0000000000..fa0985b127
--- /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 0000000000..aa25d94f01
--- /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 0000000000..36d9f1494c
--- /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 0000000000..91a5b4c6ef
--- /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 0000000000..34bc106ee6
--- /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 0000000000..8f8032c936
--- /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 0000000000..795b814440
--- /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 0000000000..832755b304
--- /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());
+}
-- 
GitLab