1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

pkg: add cryptoauthlib

This commit is contained in:
Lena Boeckmann 2019-12-18 20:18:50 +01:00 committed by PeterKietzmann
parent a2c257bad2
commit 529f3c8b61
12 changed files with 539 additions and 0 deletions

View File

@ -0,0 +1,61 @@
PKG_NAME=cryptoauthlib
PKG_URL=https://github.com/MicrochipTech/cryptoauthlib
PKG_VERSION=af8187776cd3f3faf8bed412eaf6ff7221862e19
PKG_LICENSE=LGPL-2.1
PKG_TEST_NAME=cryptoauthlib_test
PKG_TESTINCLDIR = $(PKG_BUILDDIR)/test
include $(RIOTBASE)/pkg/pkg.mk
.PHONY: all..cmake_version_supported
CMAKE_MINIMAL_VERSION = 3.6.0
CFLAGS += -Wno-missing-field-initializers -Wno-unused-function
CFLAGS += -Wno-type-limits -Wno-strict-aliasing -Wno-unused-variable -DATCA_HAL_I2C
CFLAGS += -Wno-unused-parameter -Wno-sign-compare -Wno-overflow -Wno-pointer-to-int-cast
TOOLCHAIN_FILE=$(PKG_BUILDDIR)/xcompile-toolchain.cmake
ifneq (,$(filter $(PKG_TEST_NAME),$(USEMODULE)))
all: cryptoauth build_tests
else
all: cryptoauth
endif
cryptoauth: $(PKG_BUILDDIR)/lib/Makefile
$(MAKE) -C $(PKG_BUILDDIR)/lib
cp $(PKG_BUILDDIR)/lib/libcryptoauth.a $(BINDIR)/$(PKG_NAME).a
$(PKG_BUILDDIR)/lib/Makefile: $(TOOLCHAIN_FILE)
cd $(PKG_BUILDDIR)/lib && \
cmake -DCMAKE_TOOLCHAIN_FILE=$(TOOLCHAIN_FILE) \
-Wno-dev \
-DBUILD_TESTS=OFF \
-DATCA_HAL_I2C:BOOL=TRUE .
$(TOOLCHAIN_FILE): git-download
$(RIOTTOOLS)/cmake/generate-xcompile-toolchain.sh > $(TOOLCHAIN_FILE)
build_tests:
cp $(PKG_TESTINCLDIR)/*.c $(PKG_BUILDDIR)
cp $(PKG_TESTINCLDIR)/jwt/*.c $(PKG_BUILDDIR)
cp $(PKG_TESTINCLDIR)/tng/*.c $(PKG_BUILDDIR)
cp $(PKG_TESTINCLDIR)/atcacert/*.c $(PKG_BUILDDIR)
echo "MODULE = $(PKG_TEST_NAME)" > $(PKG_BUILDDIR)/Makefile
echo "include \$$(RIOTBASE)/Makefile.base" >> $(PKG_BUILDDIR)/Makefile
"$(MAKE)" -C $(PKG_BUILDDIR)
git-download: | ..cmake_version_supported
..cmake_version_supported:
@ # Remove '-rcX' from version as they are not well handled
$(Q)\
CMAKE_VERSION=$$(cmake --version | sed -n '1 {s/cmake version //;s/-rc.*//;p;}'); \
$(RIOTTOOLS)/has_minimal_version/has_minimal_version.sh "$${CMAKE_VERSION}" "$(CMAKE_MINIMAL_VERSION)" cmake
clean::
@rm -rf $(BINDIR)/$(PKG_NAME).a
@rm -rf $(BINDIR)/$(PKG_TEST_NAME).a

View File

@ -0,0 +1,3 @@
MODULE = cryptoauthlib
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,4 @@
USEMODULE += xtimer
FEATURES_REQUIRED += periph_i2c
USEMODULE += auto_init_security
USEMODULE += cryptoauthlib_contrib

View File

@ -0,0 +1,20 @@
PKG_BUILDDIR ?= $(PKGDIRBASE)/cryptoauthlib
PKG_TESTINCLDIR = $(PKG_BUILDDIR)/test
INCLUDES += -I$(PKG_BUILDDIR)
INCLUDES += -I$(PKG_BUILDDIR)/lib
INCLUDES += -I$(PKG_BUILDDIR)/app
INCLUDES += -I$(RIOTPKG)/cryptoauthlib/include
DIRS += $(RIOTPKG)/cryptoauthlib/contrib
ifneq (,$(filter cryptoauthlib_test,$(USEMODULE)))
INCLUDES += -I$(PKG_TESTINCLDIR)
INCLUDES += -I$(PKG_TESTINCLDIR)/jwt
INCLUDES += -I$(PKG_TESTINCLDIR)/tng
INCLUDES += -I$(PKG_TESTINCLDIR)/atcacert
endif
ifneq (,$(filter cortex-m%,$(CPU_ARCH)))
TOOLCHAINS_BLACKLIST += llvm
endif

View File

@ -0,0 +1,3 @@
MODULE = cryptoauthlib_contrib
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,217 @@
/*
* Copyright (C) 2019 HAW Hamburg
*
* 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 pkg_cryptoauthlib
* @{
*
* @file
* @brief HAL implementation for the library Microchip CryptoAuth devices
*
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
*
* @}
*/
#include <stdio.h>
#include <stdint.h>
#include "xtimer.h"
#include "periph/i2c.h"
#include "periph/gpio.h"
#include "atca.h"
#include "atca_params.h"
/* Timer functions */
void atca_delay_us(uint32_t delay)
{
xtimer_usleep(delay);
}
void atca_delay_10us(uint32_t delay)
{
xtimer_usleep(delay * 10);
}
void atca_delay_ms(uint32_t delay)
{
xtimer_usleep(delay * 1000);
}
/* Hal I2C implementation */
ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg)
{
(void)hal;
if (cfg->iface_type != ATCA_I2C_IFACE) {
return ATCA_BAD_PARAM;
}
atcab_wakeup();
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_post_init(ATCAIface iface)
{
(void)iface;
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
int ret;
/* The first byte of the command package contains the word address */
txdata[0] = ATCA_DATA_ADDR;
i2c_acquire(cfg->atcai2c.bus);
ret = i2c_write_bytes(cfg->atcai2c.bus, (cfg->atcai2c.slave_address >> 1),
txdata, txlength + 1, 0);
i2c_release(cfg->atcai2c.bus);
if (ret != 0) {
return ATCA_TX_FAIL;
}
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata,
uint16_t *rxlength)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
uint8_t retries = cfg->rx_retries;
uint8_t length_package = 0;
uint8_t bytes_to_read;
int ret = -1;
/* Every command needs some time to be executed. We check whether the device is done
by polling, so we don't have to wait for the max execution time. For that there's
a number of retries (specified in the device descriptor). If polling is not successful
this function returns an error code. */
i2c_acquire(cfg->atcai2c.bus);
while (retries-- > 0 && ret != 0) {
/* read first byte (size of output data) and store it in variable length_package
to check if output will fit into rxdata */
ret = i2c_read_byte(cfg->atcai2c.bus, (cfg->atcai2c.slave_address >> 1),
&length_package, 0);
}
i2c_release(cfg->atcai2c.bus);
if (ret != 0) {
return ATCA_RX_TIMEOUT;
}
bytes_to_read = length_package - 1;
if (bytes_to_read > *rxlength) {
return ATCA_SMALL_BUFFER;
}
/* CRC function calculates value of the whole output package, so to get a correct
result we need to include the length of the package we got before into rxdata as first byte. */
rxdata[0] = length_package;
/* reset ret and retries to read the rest of the output */
ret = -1;
retries = cfg->rx_retries;
/* read rest of output and insert into rxdata array after first byte */
i2c_acquire(cfg->atcai2c.bus);
while (retries-- > 0 && ret != 0) {
ret = i2c_read_bytes(cfg->atcai2c.bus,
(cfg->atcai2c.slave_address >> 1), (rxdata + 1),
bytes_to_read, 0);
}
i2c_release(cfg->atcai2c.bus);
if (ret != 0) {
return ATCA_RX_TIMEOUT;
}
*rxlength = length_package;
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_wake(ATCAIface iface)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
uint8_t data[4] = { 0 };
i2c_acquire(cfg->atcai2c.bus);
i2c_write_byte(cfg->atcai2c.bus, ATCA_WAKE_ADDR, data[0], 0);
i2c_release(cfg->atcai2c.bus);
atca_delay_us(cfg->wake_delay);
uint8_t retries = cfg->rx_retries;
int status = -1;
i2c_acquire(cfg->atcai2c.bus);
while (retries-- > 0 && status != 0) {
status = i2c_read_bytes(cfg->atcai2c.bus,
(cfg->atcai2c.slave_address >> 1),
&data[0], 4, 0);
}
i2c_release(cfg->atcai2c.bus);
if (status != ATCA_SUCCESS) {
return ATCA_COMM_FAIL;
}
return hal_check_wake(data, 4);
}
ATCA_STATUS hal_i2c_idle(ATCAIface iface)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
i2c_acquire(cfg->atcai2c.bus);
i2c_write_byte(cfg->atcai2c.bus, (cfg->atcai2c.slave_address >> 1),
ATCA_IDLE_ADDR, 0);
i2c_release(cfg->atcai2c.bus);
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
i2c_acquire(cfg->atcai2c.bus);
i2c_write_byte(cfg->atcai2c.bus, (cfg->atcai2c.slave_address >> 1),
ATCA_SLEEP_ADDR, 0);
i2c_release(cfg->atcai2c.bus);
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_release(void *hal_data)
{
(void)hal_data;
/* This function is unimplemented, because currently the bus gets acquired
and released before and after each read or write operation. It returns
a success code, in case it gets called somewhere in the library. */
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_discover_buses(int i2c_buses[], int max_buses)
{
(void)i2c_buses;
(void)max_buses;
return ATCA_UNIMPLEMENTED;
}
ATCA_STATUS hal_i2c_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found)
{
(void)bus_num;
(void)cfg;
(void)found;
return ATCA_UNIMPLEMENTED;
}

57
pkg/cryptoauthlib/doc.txt Normal file
View File

@ -0,0 +1,57 @@
/**
* @defgroup pkg_cryptoauthlib Microchip CryptoAuthentication Library
* @ingroup pkg drivers sys_crypto
* @brief Provides the library for Microchip CryptoAuth devices
* @see https://github.com/MicrochipTech/cryptoauthlib
*
* # Introduction
*
* This package provides support for the official library for Microchip CryptoAuth devices.
*
*
* ## Warning
*
* Some functions can only be used, when the data, config and otp zones of the
* device are locked. Locking is permanent and cannot be undone. Be careful if
* you're not sure you've configured everything correctly.
* For more information we refer to the data sheet of the device.
*
*
* ## Usage
*
* Add
* USEPKG += cryptoauthlib
* to your Makefile.
*
*
* ## Implementation status
*
* This implementation was partly tested with ATECC508A and ATECC608A devices.
* We haven't tested the functions that require locking the device, yet. There's
* a wrapper in the cryptoauthlib/contrib folder, which implements most of the
* HAL functions.
* Currently the functions hal_i2c_discover_devices and hal_i2c_discover_buses
* are unimplemented, as well as hal_i2c_post_init.
*
* ### Wake function
*
* The wake function only works when a 0x00 byte is sent on an i2c interface that
* runs with with 133kHz or less.
* Currently RIOT sets the baudrate to the default value of 100 kHz and there's
* no interface to change that. If the default speed ever changes to a value
* higher than 133 kHz the wake function needs to be adapted.
* For more information on how to send a proper wake condition we refer to the
* data sheet of the device.
*
* ## Tests
*
* The library provides unittests for the library functions. There
* is a directory called "pkg_cryptoauthlib_internal_tests" in the RIOT testfolder
* which runs part of the unittests.
* Some of the provided tests can only be run when the config, data and/or otp zones
* of the device are locked. Some tests (but not all) will automatically lock zones
* as needed. We omit those tests at the moment, because zones can only be locked
* permanently. Unlocking is not possible!
* Also there is a test for comparing the runtime of the RIOT software implementation
* and the CryptoAuth hardware implementation for calculating a SHA-256 hash value.
*/

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2019 HAW Hamburg
*
* 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 pkg_cryptoauthlib
* @{
*
* @file
* @brief Default addresses and device descriptor for CryptoAuth devices
*
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
*
*/
#ifndef ATCA_H
#define ATCA_H
#include "periph/i2c.h"
#include "cryptoauthlib.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Default device and word addresses for ATECC508A
*/
#define ATCA_I2C_ADDR (0xC0) /**< Default device address is 0xC0 */
#define ATCA_WAKE_ADDR (0x00) /**< Word address to write 0 to device */
#define ATCA_SLEEP_ADDR (0x01) /**< Word address to write to for sleep mode */
#define ATCA_IDLE_ADDR (0x02) /**< Word address to write to for idle mode */
#define ATCA_DATA_ADDR (0x03) /**< Word address to read and write to data area */
#ifdef __cplusplus
}
#endif
#endif /* ATCA_H */
/** @} */

View File

@ -0,0 +1,79 @@
/*
* Copyright (C) 2019 HAW Hamburg
*
* 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 pkg_cryptoauthlib
* @{
*
* @file
* @brief Default configuration for Microchip CryptoAuth devices
*
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
*
*/
#ifndef ATCA_PARAMS_H
#define ATCA_PARAMS_H
#include "cryptoauthlib.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set default configuration parameters for the ATCA device
*
* The CryptoAuth library defines the data structure ATCAIfaceCfg for
* device initialization. We use this instead of a self defined params
* struct and store it in the params array.
* ATCAIfaceCfg contains a variable for the bus address, which is never
* used by the library. We use it to store RIOT's I2C_DEV.
* We also initialize the baud rate with zero, because RIOT doesn't have
* an API to change baud.
*
* @ingroup config
* @{
*/
#ifndef ATCA_PARAM_I2C
#define ATCA_PARAM_I2C I2C_DEV(0)
#endif
#ifndef ATCA_PARAM_ADDR
#define ATCA_PARAM_ADDR (ATCA_I2C_ADDR)
#endif
#ifndef ATCA_RX_RETRIES
#define ATCA_RX_RETRIES (20)
#endif
#ifndef ATCA_PARAMS
#define ATCA_PARAMS { .iface_type = ATCA_I2C_IFACE, \
.devtype = ATECC508A, \
.atcai2c.slave_address = ATCA_PARAM_ADDR, \
.atcai2c.bus = ATCA_PARAM_I2C, \
.atcai2c.baud = -1, /**< Not used in RIOT */ \
.wake_delay = 1500, \
.rx_retries = ATCA_RX_RETRIES }
#endif
/**@}*/
/**
* @brief Allocation of ATCA device descriptors
*/
static const ATCAIfaceCfg atca_params[] =
{
ATCA_PARAMS
};
#ifdef __cplusplus
}
#endif
#endif /* ATCA_PARAMS_H */
/** @} */

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2019 HAW Hamburg
*
* 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 pkg_cryptoauthlib
* @{
*
* @file
*
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
*
*/
#ifndef CRYPTOAUTHLIB_TEST_H
#define CRYPTOAUTHLIB_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
#include "cryptoauthlib.h"
#include "atca.h"
#include "atca_params.h"
/**
* @brief Helper function to use the library's unittests
* This function is defined in the cryptoauth library via patch.
* It is used to pass commands to run built-in unit tests of the library.
*/
int atca_run_cmd(const char *command);
/**
* @brief Function switches the default cfg in cryptoauthlib test to RIOT cfg
*/
void riot_switch_cfg(ATCAIfaceCfg *cfg)
{
*cfg = atca_params[0];
}
#ifdef __cplusplus
}
#endif
#endif /* CRYPTOAUTHLIB_TEST_H */
/** @} */