Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions pkg/cryptoauthlib/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
PKG_NAME=cryptoauthlib
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cgundogan, @leandrolanzieri could you please review this Makefile?

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
Comment thread
leandrolanzieri marked this conversation as resolved.
@rm -rf $(BINDIR)/$(PKG_TEST_NAME).a
3 changes: 3 additions & 0 deletions pkg/cryptoauthlib/Makefile.cryptoauthlib
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MODULE = cryptoauthlib

include $(RIOTBASE)/Makefile.base
4 changes: 4 additions & 0 deletions pkg/cryptoauthlib/Makefile.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
USEMODULE += xtimer
FEATURES_REQUIRED += periph_i2c
USEMODULE += auto_init_security
USEMODULE += cryptoauthlib_contrib
20 changes: 20 additions & 0 deletions pkg/cryptoauthlib/Makefile.include
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
PKG_BUILDDIR ?= $(PKGDIRBASE)/cryptoauthlib
Comment thread
PeterKietzmann marked this conversation as resolved.
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
3 changes: 3 additions & 0 deletions pkg/cryptoauthlib/contrib/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MODULE = cryptoauthlib_contrib

include $(RIOTBASE)/Makefile.base
217 changes: 217 additions & 0 deletions pkg/cryptoauthlib/contrib/atca.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
*
* @}
*/
#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;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please "group" variables of the type?

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 changes: 57 additions & 0 deletions pkg/cryptoauthlib/doc.txt
Original file line number Diff line number Diff line change
@@ -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.
*
*
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be useful if we had a paragraph here that exmpalins about the special wakeup procedure because this eventually affects other devices connected to the same bus.

* ## 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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we omit these tests right? Then, please mention it.

* 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.
*/
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The performance metrics are interesting as part of the discussion (PR description) but please remove them here.

Loading