Skip to content

Intregate Relic (a library for cryptography) into RIOT

Blanloeil Maxime edited this page Jul 11, 2014 · 6 revisions

Introduction

This tutorial will describe how to integrate the Relic library into RIOT. The integration of Relic will be firstly explained on the native, and secondly on the stm32f4discovery board. The Relic library is available on Relic website. Please download it from the Source tab on the website via the svn command.

Prerequisites

Before we start it is assumed that:

  • the OS used for development is equipped with a working and somehow current GCC toolchain (native)
  • the OS used for development is equipped with the recommended or somehow current gcc-arm-none-eabi cross toolchain (stm32f4discovery)
  • the RIOT GIT-repository has been cloned, (head over to the getting started guide if you're uncertain how to obtain the RIOT source)
Please note, for this tutorial:
  • we use the hello-world example
  • we cloned the relic directory into the hello-world project
  • we use the Linaro Toolchain Binaries GCC in version 4.8 for ARM cross compillation

A) Integration on the native

1) Configuring our project

Please take a look at the Build Instructions of Relic website before. We will basically follow theses instructions.

  1. We copy the RIOT/examples/hello-world/ directory to work safely, go to RIOT/examples and :
  • cp -R hello-world/ relic_project/
  1. We work in RIOT/examples/relic_project/ : cd relic_project/
  2. We clone the library with svn: svn checkout http://relic-toolkit.googlecode.com/svn/trunk/ relic
  3. We create a folder that will then welcome the executable files: mkdir relic-build
  4. Run cmake inside the target directory
  • cd relic-build
  • instead of the original cmake command, we need to add some Build Options. Not to make it repetitive, we write a small script named build.sh in the relic-build directory, copy and paste in this file the following commands:
#!/bin/bash
ls |grep -v build.sh |xargs rm -r
COMP="-g -m32" LINK="-m32" cmake -DARCH=X86 -DSEED=ZERO -DWORD=32 -DWITH="DV;MD;BN;CP" -DCMAKE_INSTALL_PREFIX:PATH=*Your_path*/RIOT/examples/relic_project/bin/native/usr/local ../relic

Please complete the beginning of the DCMAKE_INSTALL_PREFIX path with your own one. And note that we use only the "DV;MD;BN;CP" options, please read the Build Options if you need some more.

  • We make this script executable with chmod +x build.sh
  • We run it then ./build.sh
  1. We compile the library:
  • make
  • make install
  1. We compile the riot project outside:
  • cd ..
  • Before compiling, we need to edit the Makefile, to link our project with the Relic library, we add this at the end of the Makefile:
CFLAGS += -I/**Your_own_path**/RIOT/examples/relic_project/bin/native/usr/local/include
LINKFLAGS += -L/**Your_own_path**/RIOT/examples/relic_project/bin/native/usr/local/lib -lrelic_s
  • We can now compile our relic_project project: make

2) Testing with some Relic functions

To check if Relic is really enable on native, let's test it.

  1. First open the main.c file in our project
  2. Then we copy some code from relic, we open ./relic/test/test_bn.c for example (because 'BN 'is one of the building option we selected):
  • We go to the line number 352, we select and copy the whole code of the subtraction function:
static int subtraction(void) {
  int code = STS_ERR;
  int s;
  bn_t a, b, c, d;

  bn_null(a);
  bn_null(b);
  bn_null(c);
  bn_null(d);

  TRY {
  	bn_new(a);
  	bn_new(b);
  	bn_new(c);
  	bn_new(d);

  	TEST_BEGIN("subtraction is anti-commutative") {
  		bn_rand(a, BN_POS, BN_BITS);
  		bn_rand(b, BN_POS, BN_BITS);
  		bn_sub(c, a, b);
  		bn_sub(d, b, a);
  		TEST_ASSERT(bn_cmp_abs(c, d) == CMP_EQ, end);
  		if (!bn_is_zero(c)) {
  			s = bn_sign(d);
  			TEST_ASSERT(bn_sign(c) != s, end);
  		}
  	}
  	TEST_END;

  	TEST_BEGIN("subtraction has identity") {
  		bn_rand(a, BN_POS, BN_BITS);
  		bn_zero(c);
  		bn_sub(d, a, c);
  		TEST_ASSERT(bn_cmp(d, a) == CMP_EQ, end);
  	}
  	TEST_END;

  	TEST_BEGIN("subtraction has inverse") {
  		bn_rand(a, BN_POS, BN_BITS);
  		bn_sub(c, a, a);
  		TEST_ASSERT(bn_is_zero(c), end);
  	}
  	TEST_END;
  }
  CATCH_ANY {
  	ERROR(end);
  }
  code = STS_OK;
end:
  bn_free(a);
  bn_free(b);
  bn_free(c);
  bn_free(d);
  return code;
}
  • We paste it in our main.c file, outside the void main(void) function
  • We now have to modify a little this function, we need to remove everything that is written in capital letters and change TEST_ASSERT in assert and remove the third argument ("end") of this function. Finally this is the code we get:
static int subtraction(void) {
int code = STS_ERR;
int s;
bn_t a, b, c, d;

bn_null(a);
bn_null(b);
bn_null(c);
bn_null(d);


bn_new(a);
bn_new(b);
bn_new(c);
bn_new(d);

bn_rand(a, BN_POS, BN_BITS);
bn_rand(b, BN_POS, BN_BITS);
bn_sub(c, a, b);
bn_sub(d, b, a);
assert(bn_cmp_abs(c, d) == CMP_EQ);
if (!bn_is_zero(c)) {
  s = bn_sign(d);
  assert(bn_sign(c) != s);
}
bn_rand(a, BN_POS, BN_BITS);
bn_zero(c);
bn_sub(d, a, c);
assert(bn_cmp(d, a) == CMP_EQ);

bn_rand(a, BN_POS, BN_BITS);
bn_sub(c, a, a);
assert(bn_is_zero(c));

code = STS_OK;

bn_free(a);
bn_free(b);
bn_free(c);
bn_free(d);
return code;
}

Please note that I provide here the result code, but if you want to copy some other function of Relic you will have to do the modifications by your-self.

  1. We include the headers in our main.c:
#include <assert.h>
#include "relic/relic.h"
  1. We integrate the function we copied (subtraction()) in our void main(void) function, with the "init function" (core_init()) of Relic functions:
  int main(void)
  {      
      core_init();
      subtraction();
      puts("Hello World!");
      return 0;
  }
  1. We can now compile our project again with some code implemented inside:
  • make
  1. Finally we run our project:
  • ./bin/native/hello-world.elf
We get the expected result Hello World!, our program does not complain about the use of the Relic function so that confirms Relic has been well implemented in our RIOT project.

B) Integration on the STM32F4DISCOVERY board

1) Configuring our project

Please integrate on the native before, it eases to understand because it is a bit more complex on the STM32F4DISCOVERY board. We will now start again our relic_project but with this specific board. Do not forget to use gcc-arm-none-eabi cross toolchain.

  1. We remove the relic_project directory, we go to RIOT/examples and :
  • rm -R relic_project/
  1. We copy the RIOT/examples/hello-world/ directory again, to start from the beginning:
  • cp -R hello-world/ relic_project/
  1. We work in RIOT/examples/relic_project/ : cd relic_project/
  2. We clone the library with svn: svn checkout http://relic-toolkit.googlecode.com/svn/trunk/ relic
  3. We create a folder that will then welcome the executable files: mkdir relic-build
  4. Run cmake inside the target directory
  • cd relic-build
  • we need to set some flags to configure cmake for this remote board so we create a file in relic-build named stm32.cmake. Copy and paste in this file the following code:
INCLUDE(CMakeForceCompiler)


SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)

#specify the cross compiler
SET(PREFIX "arm-none-eabi-")

SET(CMAKE_C_COMPILER "${PREFIX}gcc" CACHE STRING "")
SET(CMAKE_CXX_COMPILER "${PREFIX}g++" CACHE STRING "")
SET(CMAKE_RANLIB "${PREFIX}ranlib" CACHE STRING "")
SET(CMAKE_AR "${PREFIX}ar" CACHE STRING "")

# specify the cross compiler
CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)
CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-g++ GNU)
SET(CMAKE_LINKER "${PREFIX}ar" CACHE STRING "")

SET(CPU_USAGE "-mcpu=cortex-m4")
SET(FPU_USAGE "-mfloat-abi=hard -mfpu=fpv4-sp-d16")
SET(CMAKE_C_FLAGS "-g3 -std=gnu99 -Os -Wall -Wstrict-prototypes ${CPU_USAGE} ${FPU_USAGE} -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -DREENTRANT_SYSCALLS_PROVIDED -flto -ffunction-sections -fdata-sections -fno-builtin -B**Your_own_path**/gcc-arm-none-eabi-4_8-2014q2/lib/gcc/arm-none-eabi/4.8.4 -B**Your_own_path**/gcc-arm-none-eabi-4_8-2014q2/arm-none-eabi/lib -Wl,--unresolved-symbols=ignore-all" CACHE STRING "")

SET(CMAKE_STATIC_LINKER_FLAGS "-g3 -std=gnu99 ${CPU_USAGE} ${FPU_USAGE} -mlittle-endian -static -lgcc -mthumb -mthumb-interwork -nostartfiles ")
# -ggdb
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS)
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--unresolved-symbols=ignore-all ${FPU_USAGE}")

# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Please do not forget to replace your path in the parts of this code that needs to be changed.

  • instead of the original cmake command, we need to add some Build Options. Not to make it repetitive, we write a small script named build.sh in the relic-build directory, copy and paste in this file the following commands:
#!/bin/bash
rm CMakeCache.txt
rm -r CMakeFiles
export COMP="-g3 -std=gnu99 -Os -Wall -Wstrict-prototypes -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -DREENTRANT_SYSCALLS_PROVIDED -flto -ffunction-sections -fdata-sections -fno-builtin -B**Your_own_path**/gcc-arm-none-eabi-4_8-2014q2/lib/gcc/arm-none-eabi/4.8.4 -B**Your_own_path**/gcc-arm-none-eabi-4_8-2014q2/arm-none-eabi/lib -Wl,--unresolved-symbols=ignore-all"
export LINK="-Wl,--gc-sections"
cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=stm32.cmake -DSEED=ZERO -DQUIET=ON -DARCH="NONE" -DCHECK=OFF -DSTRIP=ON -DTESTS=1 -DBENCH=0 -DWORD=32 -DWITH="FP;EP;EC;DV;CP;MD;BN" -DFP_METHD="BASIC;COMBA;COMBA;QUICK;LOWER;BASIC" -DCMAKE_INSTALL_PREFIX:PATH=/**Your_own_path**/RIOT/examples/relic_project/bin/stm32f4discovery/usr/local ../relic

Please complete the beginning of the DCMAKE_INSTALL_PREFIX path with your own one and in the other parts where it is necessary. And note that we use only the "FP;EP;EC;DV;CP;MD;BN" options, please read the Build Options if you need some more.

  • We make this script executable with chmod +x build.sh
  • We run it then ./build.sh
  1. We compile the library:
  • ninja install
  1. We edit a file that defines the _kill_r function, which is already defined by Relic:
  • gedit ../../../cpu/stm32f4/syscalls.c
  • go to the line number 114 and comment the function
  1. We compile the riot outside:
  • cd ..
  • Before compiling, we need to edit the Makefile, to link our project with the Relic library, we add this at the end of the Makefile:
CFLAGS += -I**Your_own_path**/RIOT/examples/relic_project/bin/stm32f4discovery/usr/local/include
LINKFLAGS += -L**Your_own_path**/RIOT/examples/relic_project/bin/stm32f4discovery/usr/local/lib -lrelic_s

Please do not forget to set your own path in the CFLAGS and the LINKFLAGS

  • We can now compile our relic_project project: make BOARD=stm32f4discovery

2) Testing with some Relic functions

To check if Relic is really enable on the stm32f4discovery board, let's test it.

  1. First open the main.c file in our project
  2. Then we copy some code from relic, we open ./relic/test/test_bn.c for example (because 'BN 'is one of the building option we selected) :
  • We go to the line number 352, we select and copy the whole code of the subtraction function:
static int subtraction(void) {
  int code = STS_ERR;
  int s;
  bn_t a, b, c, d;

  bn_null(a);
  bn_null(b);
  bn_null(c);
  bn_null(d);

  TRY {
  	bn_new(a);
  	bn_new(b);
  	bn_new(c);
  	bn_new(d);

  	TEST_BEGIN("subtraction is anti-commutative") {
  		bn_rand(a, BN_POS, BN_BITS);
  		bn_rand(b, BN_POS, BN_BITS);
  		bn_sub(c, a, b);
  		bn_sub(d, b, a);
  		TEST_ASSERT(bn_cmp_abs(c, d) == CMP_EQ, end);
  		if (!bn_is_zero(c)) {
  			s = bn_sign(d);
  			TEST_ASSERT(bn_sign(c) != s, end);
  		}
  	}
  	TEST_END;

  	TEST_BEGIN("subtraction has identity") {
  		bn_rand(a, BN_POS, BN_BITS);
  		bn_zero(c);
  		bn_sub(d, a, c);
  		TEST_ASSERT(bn_cmp(d, a) == CMP_EQ, end);
  	}
  	TEST_END;

  	TEST_BEGIN("subtraction has inverse") {
  		bn_rand(a, BN_POS, BN_BITS);
  		bn_sub(c, a, a);
  		TEST_ASSERT(bn_is_zero(c), end);
  	}
  	TEST_END;
  }
  CATCH_ANY {
  	ERROR(end);
  }
  code = STS_OK;
end:
  bn_free(a);
  bn_free(b);
  bn_free(c);
  bn_free(d);
  return code;
}
  • We paste it in our main.c file, outside the void main(void) function
  • We now have to modify a little this function, we need to remove everything that is written in capital letters and change TEST_ASSERT in assert and remove the third argument ("end") of this function. Finally this is the code we get:
static int subtraction(void) {
int code = STS_ERR;
int s;
bn_t a, b, c, d;

bn_null(a);
bn_null(b);
bn_null(c);
bn_null(d);


bn_new(a);
bn_new(b);
bn_new(c);
bn_new(d);

bn_rand(a, BN_POS, BN_BITS);
bn_rand(b, BN_POS, BN_BITS);
bn_sub(c, a, b);
bn_sub(d, b, a);
assert(bn_cmp_abs(c, d) == CMP_EQ);
if (!bn_is_zero(c)) {
  s = bn_sign(d);
  assert(bn_sign(c) != s);
}
bn_rand(a, BN_POS, BN_BITS);
bn_zero(c);
bn_sub(d, a, c);
assert(bn_cmp(d, a) == CMP_EQ);

bn_rand(a, BN_POS, BN_BITS);
bn_sub(c, a, a);
assert(bn_is_zero(c));

code = STS_OK;

bn_free(a);
bn_free(b);
bn_free(c);
bn_free(d);
return code;
}

Please note that I provide here the result code, but if you want to copy some other function of Relic you will have to do the modifications by your-self.

  1. We include the headers in our main.c:
#include <assert.h>
#include "relic/relic.h"
  1. We integrate the function we copied (subtraction()) in our void main(void) function, with the "init function" (core_init()) of Relic functions:
  int main(void)
  {      
      core_init();
      subtraction();
      puts("Hello World!");
      return 0;
  }
  1. We can now compile our project again with some code implemented inside:
  • make BOARD=stm32f4discovery
  1. Finally we run our project:
  • sudo st-flash write bin/stm32f4discovery/hello-world.hex 0x8000000 to flash it on the stm32 board
  • sudo ../../dist/tools/pyterm/pyterm.py /dev/ttyUSB0
  • we press the black button on the board to launch our program
We get the expected result Hello World!, our program does not complain about the use of the Relic function so that confirms Relic has been well implemented in our RIOT project.

This tutorial ends here for now. I hope it was somehow helpful. You should be able to use any Relic functions in RIOT now !

Clone this wiki locally