cAGE on-target decryption running
This commit is contained in:
parent
4ae75202f4
commit
05c02ab7a7
14 changed files with 337 additions and 216 deletions
20
demo/fw/.gdbinit
Normal file
20
demo/fw/.gdbinit
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
target remote localhost:3333
|
||||
set print pretty on
|
||||
set print elements 512
|
||||
|
||||
# Update GDB's Python paths with the `sys.path` values of the local Python installation,
|
||||
# whether that is brew'ed Python, a virtualenv, or another system python.
|
||||
|
||||
# Convert GDB to interpret in Python
|
||||
python
|
||||
import os,subprocess,sys
|
||||
# Execute a Python using the user's shell and pull out the sys.path (for site-packages)
|
||||
paths = subprocess.check_output('python -c "import os,sys;print(os.linesep.join(sys.path).strip())"',shell=True).decode("utf-8").split()
|
||||
# Extend GDB's Python's search path
|
||||
sys.path.extend(paths)
|
||||
end
|
||||
|
||||
source ../../upstream/PyCortexMDebug/cmdebug/svd_gdb.py
|
||||
svd_load ../../upstream/stm32square/svd/STM32F407.svd
|
||||
|
||||
|
|
@ -19,6 +19,7 @@ C_SOURCES += src/serial.c
|
|||
C_SOURCES += src/spi.c
|
||||
C_SOURCES += src/gpio_helpers.c
|
||||
C_SOURCES += src/dma_util.c
|
||||
C_SOURCES += src/rng.c
|
||||
C_SOURCES += src/cage.c
|
||||
C_SOURCES += src/cage_base64.c
|
||||
C_SOURCES += src/bech32.c
|
||||
|
|
@ -62,7 +63,6 @@ SIZE := $(PREFIX)size
|
|||
NM := $(PREFIX)nm
|
||||
OBJCOPY := $(PREFIX)objcopy
|
||||
OBJDUMP := $(PREFIX)objdump
|
||||
GDB := $(PREFIX)gdb
|
||||
|
||||
HOST_CC ?= $(HOST_PREFIX)gcc
|
||||
HOST_CXX ?= $(HOST_PREFIX)g++
|
||||
|
|
@ -86,11 +86,11 @@ SYSTEM_FLAGS ?= -nostdlib -ffreestanding -nostartfiles
|
|||
|
||||
#CFLAGS += -I$(abspath musl_include_shims)
|
||||
INCLUDES += -I$(CUBE_CMSIS_DIR)/Include -I$(CMSIS_DIR)/CMSIS/Core/Include
|
||||
INCLUDES += -Itinyprintf -I$(MBEDTLS_DIR)/include -I$(TINYALLOC_DIR)
|
||||
INCLUDES += -Itinyprintf -I$(TINYALLOC_DIR) -Iinclude/platform
|
||||
MBEDTLS_CONFIG_INCLUDE := -I$(realpath include) -DMBEDTLS_CONFIG_FILE='<tb_mbedtls_config.h>'
|
||||
COMMON_INCLUDES += -I$(BUILDDIR) -Isrc $(MBEDTLS_CONFIG_INCLUDE)
|
||||
COMMON_INCLUDES += -I$(BUILDDIR) -Isrc $(MBEDTLS_CONFIG_INCLUDE) -I$(MBEDTLS_DIR)/include
|
||||
|
||||
COMMON_CFLAGS += -O0 -std=gnu11 -g -DSTM32F407xx -DSTM32F4 -DDEBUG=$(DEBUG) -DMBEDTLS_ALLOW_PRIVATE_ACCESS
|
||||
COMMON_CFLAGS += -O0 -std=gnu11 -g3 -DSTM32F407xx -DSTM32F4 -DDEBUG=$(DEBUG) -DMBEDTLS_ALLOW_PRIVATE_ACCESS
|
||||
CFLAGS += $(ARCH_FLAGS) $(SYSTEM_FLAGS)
|
||||
#SIM_CFLAGS += -mthumb -mcpu=cortex-m4 -mfloat-abi=soft
|
||||
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
||||
|
|
@ -147,6 +147,15 @@ $(BUILDDIR)/libmbedcrypto.a:
|
|||
make -C $(MBEDTLS_DIR) CC=$(CC) LD=$(LD) CFLAGS="$(CFLAGS) $(COMMON_CFLAGS) $(MBEDTLS_CONFIG_INCLUDE) -w" LDFLAGS="$(LDFLAGS)" lib
|
||||
mv $(MBEDTLS_DIR)/library/libmbedcrypto.a $@
|
||||
|
||||
$(BUILDDIR)/test/libmbedcrypto.a:
|
||||
mkdir -p $(@D)
|
||||
make -C $(MBEDTLS_DIR) clean
|
||||
make -C $(MBEDTLS_DIR) CC=$(HOST_CC) LD=$(HOST_LD) CFLAGS="$(COMMON_CFLAGS) $(MBEDTLS_CONFIG_INCLUDE) -w" LDFLAGS="$(COMMON_LDFLAGS)" lib
|
||||
mv $(MBEDTLS_DIR)/library/libmbedcrypto.a $@
|
||||
|
||||
build/test/cage_test: src/cage.c src/bech32.c src/cage_base64.c $(BUILDDIR)/test/libmbedcrypto.a
|
||||
$(HOST_CC) $(COMMON_CFLAGS) $(COMMON_LDFLAGS) $(COMMON_INCLUDES) -DCAGE_DEBUG -o $@ $^
|
||||
|
||||
build/$(BINARY:.elf=-symbol-sizes.dot): $(ALL_OBJS) $(BUILDDIR)/libmbedcrypto.a
|
||||
$(PYTHON3) tools/linkmem.py $(LINKMEM_FLAGS) $(LD) -T$(LDSCRIPT) $(LDFLAGS) $^ $(LIBS) > $@
|
||||
|
||||
|
|
|
|||
|
|
@ -1,189 +0,0 @@
|
|||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Portions copyright (c) 2018, ARM Limited and Contributors.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef ENDIAN_H
|
||||
#define ENDIAN_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* General byte order swapping functions.
|
||||
*/
|
||||
#define bswap16(x) __bswap16(x)
|
||||
#define bswap32(x) __bswap32(x)
|
||||
#define bswap64(x) __bswap64(x)
|
||||
|
||||
/*
|
||||
* Host to big endian, host to little endian, big endian to host, and little
|
||||
* endian to host byte order functions as detailed in byteorder(9).
|
||||
*/
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define htobe16(x) bswap16((x))
|
||||
#define htobe32(x) bswap32((x))
|
||||
#define htobe64(x) bswap64((x))
|
||||
#define htole16(x) ((uint16_t)(x))
|
||||
#define htole32(x) ((uint32_t)(x))
|
||||
#define htole64(x) ((uint64_t)(x))
|
||||
|
||||
#define be16toh(x) bswap16((x))
|
||||
#define be32toh(x) bswap32((x))
|
||||
#define be64toh(x) bswap64((x))
|
||||
#define le16toh(x) ((uint16_t)(x))
|
||||
#define le32toh(x) ((uint32_t)(x))
|
||||
#define le64toh(x) ((uint64_t)(x))
|
||||
#else /* __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ */
|
||||
#define htobe16(x) ((uint16_t)(x))
|
||||
#define htobe32(x) ((uint32_t)(x))
|
||||
#define htobe64(x) ((uint64_t)(x))
|
||||
#define htole16(x) bswap16((x))
|
||||
#define htole32(x) bswap32((x))
|
||||
#define htole64(x) bswap64((x))
|
||||
|
||||
#define be16toh(x) ((uint16_t)(x))
|
||||
#define be32toh(x) ((uint32_t)(x))
|
||||
#define be64toh(x) ((uint64_t)(x))
|
||||
#define le16toh(x) bswap16((x))
|
||||
#define le32toh(x) bswap32((x))
|
||||
#define le64toh(x) bswap64((x))
|
||||
#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
|
||||
|
||||
/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
|
||||
|
||||
static __inline uint16_t
|
||||
be16dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return ((p[0] << 8) | p[1]);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
be32dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
be64dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4));
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
le16dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return ((p[1] << 8) | p[0]);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
le32dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
le64dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
be16enc(void *pp, uint16_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
p[0] = (u >> 8) & 0xff;
|
||||
p[1] = u & 0xff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
be32enc(void *pp, uint32_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
p[0] = (u >> 24) & 0xff;
|
||||
p[1] = (u >> 16) & 0xff;
|
||||
p[2] = (u >> 8) & 0xff;
|
||||
p[3] = u & 0xff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
be64enc(void *pp, uint64_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
be32enc(p, (uint32_t)(u >> 32));
|
||||
be32enc(p + 4, (uint32_t)(u & 0xffffffffU));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
le16enc(void *pp, uint16_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
p[0] = u & 0xff;
|
||||
p[1] = (u >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
le32enc(void *pp, uint32_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
p[0] = u & 0xff;
|
||||
p[1] = (u >> 8) & 0xff;
|
||||
p[2] = (u >> 16) & 0xff;
|
||||
p[3] = (u >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
le64enc(void *pp, uint64_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
le32enc(p, (uint32_t)(u & 0xffffffffU));
|
||||
le32enc(p + 4, (uint32_t)(u >> 32));
|
||||
}
|
||||
|
||||
#endif /* ENDIAN_H */
|
||||
|
|
@ -11,12 +11,13 @@
|
|||
#include "cage_base64.h"
|
||||
#include "logging.h"
|
||||
#include "bech32.h"
|
||||
#include "rng.h"
|
||||
|
||||
#include "mbedtls/chachapoly.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/hkdf.h"
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/base64.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
|
||||
|
||||
static enum ca_error parse_stanza(struct ca_keystore *ks, const char *stanza_head, size_t len, unsigned char file_key[16]);
|
||||
|
|
@ -46,7 +47,7 @@ enum ca_error ca_keystore_load_x25519_private_key(struct ca_keystore *ks, const
|
|||
/* Reconstruct public key from private key */
|
||||
mbedtls_rc = mbedtls_ecp_mul(&(ks->x25519_kp.grp), &(ks->x25519_kp.Q),
|
||||
&(ks->x25519_kp.d), &(ks->x25519_kp.grp.G),
|
||||
NULL, NULL/* FIXME: DEBUG ONLY!!! */);
|
||||
mbedtls_ctr_drbg_random, g_drbg_ctx);
|
||||
if (mbedtls_rc) {
|
||||
LOG_PRINTF("Error: mbedtls_ecp_read_key: rc=-0x%x\n", -mbedtls_rc);
|
||||
return CA_ERR_MBEDTLS_ERROR;
|
||||
|
|
@ -286,7 +287,7 @@ enum ca_error parse_stanza_x25519(struct ca_keystore *ks, size_t nargs, const ch
|
|||
mbedtls_ecp_point_init(&ecp_dec_res_pt);
|
||||
|
||||
mbedtls_rc = mbedtls_ecp_mul(&x25519_grp, &ecp_dec_res_pt, &(ks->x25519_kp.d), &ecp_ciphertext_pt,
|
||||
NULL, NULL/* FIXME: DEBUG ONLY!!! */);
|
||||
mbedtls_ctr_drbg_random, g_drbg_ctx);
|
||||
if (mbedtls_rc) {
|
||||
LOG_PRINTF("Error: mbedtls_ecp_mul: rc=-0x%x\n", -mbedtls_rc);
|
||||
return CA_ERR_MBEDTLS_ERROR;
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@ const char *base64_decode(unsigned char *dst, size_t dlen, size_t *olen, const c
|
|||
|
||||
|
||||
#ifdef CAGE_DEBUG
|
||||
static void base64_decode_test(void);
|
||||
|
||||
static const char *base64_test_vectors[][2] = {
|
||||
{"", ""},
|
||||
{"f", "Zg=="},
|
||||
|
|
|
|||
|
|
@ -52,3 +52,6 @@ void DMA2_Stream7_IRQHandler(void) {
|
|||
usart_dma_stream_irq(&con_usart);
|
||||
}
|
||||
|
||||
void USART1_IRQHandler(void) {
|
||||
usart_irq(&con_usart);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ extern volatile struct usart_desc con_usart;
|
|||
|
||||
#define con_printf(...) usart_printf(&con_usart, __VA_ARGS__)
|
||||
#define con_printf_blocking(...) usart_printf_blocking(&con_usart, __VA_ARGS__)
|
||||
#define con_read_until(...) usart_read_until(&con_usart, __VA_ARGS__)
|
||||
|
||||
#ifndef CON_USART_BAUDRATE
|
||||
#define CON_USART_BAUDRATE 500000
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2021 jaseg <code@jaseg.de>
|
||||
*
|
||||
*
|
||||
* libusbhost is free software: you can redistribute it and/or modify
|
||||
* tachibana is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
#include "jl_global.h"
|
||||
#include "con_usart.h"
|
||||
#include "spi.h"
|
||||
#include "rng.h"
|
||||
#include "cage.h"
|
||||
#include "bech32.h"
|
||||
|
||||
|
|
@ -45,6 +46,25 @@ unsigned int apb2_timer_speed = 0;
|
|||
struct leds leds;
|
||||
struct spi_fpga_if spif;
|
||||
|
||||
uint8_t cage_startup_test_data[] = {
|
||||
0x61, 0x67, 0x65, 0x2d, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6f,
|
||||
0x72, 0x67, 0x2f, 0x76, 0x31, 0x0a, 0x2d, 0x3e, 0x20, 0x58, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20,
|
||||
0x35, 0x62, 0x6e, 0x32, 0x4d, 0x37, 0x65, 0x4d, 0x78, 0x49, 0x2b, 0x58, 0x4a, 0x30, 0x57, 0x52,
|
||||
0x57, 0x71, 0x2f, 0x35, 0x6c, 0x56, 0x34, 0x2f, 0x42, 0x67, 0x4c, 0x64, 0x2f, 0x52, 0x39, 0x34,
|
||||
0x70, 0x31, 0x58, 0x63, 0x51, 0x52, 0x73, 0x32, 0x42, 0x30, 0x41, 0x0a, 0x72, 0x39, 0x6e, 0x34,
|
||||
0x46, 0x35, 0x61, 0x6a, 0x33, 0x58, 0x74, 0x45, 0x35, 0x2f, 0x30, 0x57, 0x35, 0x5a, 0x68, 0x2b,
|
||||
0x55, 0x46, 0x6e, 0x6a, 0x32, 0x42, 0x53, 0x4b, 0x55, 0x30, 0x47, 0x4c, 0x77, 0x68, 0x31, 0x78,
|
||||
0x70, 0x75, 0x63, 0x4f, 0x68, 0x4d, 0x6f, 0x0a, 0x2d, 0x2d, 0x2d, 0x20, 0x4e, 0x78, 0x72, 0x43,
|
||||
0x6b, 0x35, 0x43, 0x35, 0x39, 0x4c, 0x6a, 0x67, 0x75, 0x2f, 0x71, 0x37, 0x47, 0x4d, 0x7a, 0x68,
|
||||
0x4c, 0x4f, 0x41, 0x66, 0x58, 0x6b, 0x51, 0x49, 0x62, 0x75, 0x50, 0x64, 0x69, 0x68, 0x61, 0x47,
|
||||
0x2f, 0x35, 0x72, 0x72, 0x53, 0x59, 0x77, 0x0a, 0x92, 0x6f, 0xde, 0x4d, 0x73, 0x8c, 0x40, 0xca,
|
||||
0xdb, 0xe8, 0xd1, 0x20, 0x78, 0x71, 0x9b, 0xd7, 0xb4, 0xdb, 0x70, 0x95, 0xec, 0xc5, 0x4a, 0xe1,
|
||||
0xb0, 0x85, 0x34, 0x9b, 0xac, 0xac, 0x8a, 0xd7, 0x4f, 0xe3, 0xd8, 0x63, 0x80, 0x60, 0xc7, 0xb6,
|
||||
0x24, 0xf5, 0x35, 0x9e, 0xc7, 0xaf, 0xd8, 0x4f, 0xc2, 0xa7, 0x5b, 0xab, 0x3e, 0x85, 0x60, 0x0f,
|
||||
0x91, 0x22, 0x5a, 0x5a, 0x9a, 0xf8, 0x37, 0x97, 0x0d, 0x63, 0x23, 0xa2, 0x6a, 0xc0, 0x8e, 0xb8,
|
||||
0x5d, 0x66, 0x00
|
||||
};
|
||||
|
||||
void __libc_init_array(void) { /* we don't need this. */ }
|
||||
void __assert_func (unused_a const char *file, unused_a int line, unused_a const char *function, unused_a const char *expr) {
|
||||
asm volatile ("bkpt");
|
||||
|
|
@ -235,6 +255,9 @@ int main(void)
|
|||
GPIOA->MODER |= (1<<GPIO_MODER_MODER11_Pos) | (1<<GPIO_MODER_MODER12_Pos) | (1<<GPIO_MODER_MODER15_Pos);
|
||||
#endif
|
||||
|
||||
con_printf("Running crypto startup test.\r\n");
|
||||
|
||||
rng_init();
|
||||
ta_init(ta_heap, ta_heap+sizeof(ta_heap), 256, 16, 8);
|
||||
|
||||
/* Begin crypto test */
|
||||
|
|
@ -250,21 +273,21 @@ int main(void)
|
|||
enum ca_error err = ca_keystore_load_x25519_private_key(&ks, private_key);
|
||||
assert (!err);
|
||||
|
||||
size_t bufsize = 16384;
|
||||
char *buf = malloc(bufsize);
|
||||
assert (buf);
|
||||
size_t read_pos = 0;
|
||||
buf[0] = '\0';
|
||||
con_printf("Test private key loaded.\r\n");
|
||||
|
||||
unsigned char file_key[16];
|
||||
err = parse_age_buf(&ks, buf, read_pos+1, file_key);
|
||||
err = parse_age_buf(&ks, cage_startup_test_data, sizeof(cage_startup_test_data), file_key);
|
||||
assert (!err);
|
||||
unsigned char *decrypted = malloc(bufsize);
|
||||
unsigned char *decrypted = malloc(sizeof(cage_startup_test_data));
|
||||
assert (decrypted);
|
||||
|
||||
size_t decrypted_size = 0;
|
||||
err = stream_decrypt(decrypted, bufsize, &decrypted_size, buf, read_pos, file_key);
|
||||
err = stream_decrypt(decrypted, sizeof(cage_startup_test_data), &decrypted_size, cage_startup_test_data, sizeof(cage_startup_test_data)-1, file_key);
|
||||
assert (!err);
|
||||
assert (decrypted_size > 0 && decrypted_size < sizeof(cage_startup_test_data));
|
||||
decrypted[decrypted_size-1] = '\0';
|
||||
|
||||
con_printf("%s\r\n", decrypted);
|
||||
|
||||
/* End crypto test */
|
||||
con_printf("Booted.\r\n");
|
||||
|
|
@ -273,6 +296,14 @@ int main(void)
|
|||
int k = 0;
|
||||
con_printf("loop");
|
||||
while (23) {
|
||||
|
||||
uint8_t rd_buf[128];
|
||||
ssize_t rv = con_read_until(rd_buf, sizeof(rd_buf), '\n');
|
||||
if (rv < 0) {
|
||||
con_printf("USART rx error\r\n");
|
||||
}
|
||||
con_printf("Received %d bytes: %s\r\n", rv, rd_buf);
|
||||
|
||||
con_printf(" #%u", i);
|
||||
if (k == 0)
|
||||
spif_printf(&spif, "\33[1m");
|
||||
|
|
@ -290,7 +321,7 @@ int main(void)
|
|||
if (k == 0) {
|
||||
spif_printf(&spif, "\033[H\033[0m\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\033[H");
|
||||
|
||||
uint8_t buf[128];
|
||||
uint8_t buf[4096];
|
||||
spif_capture_read(&spif, sizeof(buf), buf);
|
||||
con_printf("\r\n");
|
||||
con_printf("\r\n");
|
||||
|
|
|
|||
111
demo/fw/src/rng.c
Normal file
111
demo/fw/src/rng.c
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* This file is part of the tachibana project
|
||||
*
|
||||
* Copyright (C) 2021 jaseg <code@jaseg.de>
|
||||
*
|
||||
*
|
||||
* tachibana is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <stm32f407xx.h>
|
||||
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
|
||||
#include "rng.h"
|
||||
|
||||
|
||||
struct rng_state {
|
||||
bool seed_error;
|
||||
bool clock_error;
|
||||
|
||||
size_t data_available;
|
||||
uint32_t data[MBEDTLS_CTR_DRBG_ENTROPY_LEN];
|
||||
};
|
||||
|
||||
static volatile struct rng_state rng_state;
|
||||
static mbedtls_ctr_drbg_context drbg_ctx;
|
||||
void *g_drbg_ctx = &drbg_ctx;
|
||||
|
||||
static int drbg_f_entropy(void *p, unsigned char *buf, size_t len);
|
||||
|
||||
|
||||
int drbg_f_entropy(void *p, unsigned char *buf, size_t len) {
|
||||
(void) p;
|
||||
|
||||
if (rng_state.seed_error || rng_state.clock_error) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (len > sizeof(rng_state.data)/sizeof(rng_state.data[0])) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
NVIC_EnableIRQ(HASH_RNG_IRQn);
|
||||
size_t it_max = 48000000;
|
||||
while (len > rng_state.data_available * sizeof(rng_state.data[0])) {
|
||||
/* wait for interrupt to fill buffer */
|
||||
if (--it_max == 0) {
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(buf, (void *)rng_state.data, len);
|
||||
rng_state.data_available = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HASH_RNG_IRQHandler(void);
|
||||
void HASH_RNG_IRQHandler() {
|
||||
uint32_t sr = RNG->SR;
|
||||
RNG->SR = 0;
|
||||
|
||||
if (sr & RNG_SR_SEIS) {
|
||||
rng_state.seed_error = true;
|
||||
}
|
||||
|
||||
if (sr & RNG_SR_CEIS) {
|
||||
rng_state.clock_error = true;
|
||||
}
|
||||
|
||||
if (sr & RNG_SR_DRDY) {
|
||||
rng_state.data[rng_state.data_available++] = RNG->DR;
|
||||
if (rng_state.data_available >= sizeof(rng_state.data)/sizeof(rng_state.data[0])) {
|
||||
NVIC_DisableIRQ(HASH_RNG_IRQn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rng_init() {
|
||||
rng_state.seed_error = false;
|
||||
rng_state.clock_error = false;
|
||||
rng_state.data_available = 0;
|
||||
|
||||
RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;
|
||||
RNG->CR = RNG_CR_RNGEN | RNG_CR_IE;
|
||||
|
||||
NVIC_EnableIRQ(HASH_RNG_IRQn);
|
||||
NVIC_SetPriority(HASH_RNG_IRQn, 31);
|
||||
|
||||
mbedtls_ctr_drbg_init(&drbg_ctx);
|
||||
mbedtls_ctr_drbg_seed(&drbg_ctx, drbg_f_entropy, NULL, (const unsigned char *)UID_BASE, 12);
|
||||
}
|
||||
|
||||
29
demo/fw/src/rng.h
Normal file
29
demo/fw/src/rng.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* This file is part of the tachibana project
|
||||
*
|
||||
* Copyright (C) 2021 jaseg <code@jaseg.de>
|
||||
*
|
||||
*
|
||||
* tachibana is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RNG_H__
|
||||
#define __RNG_H__
|
||||
|
||||
extern void *g_drbg_ctx;
|
||||
|
||||
void rng_init(void);
|
||||
|
||||
#endif /* __RNG_H__ */
|
||||
|
|
@ -49,6 +49,8 @@ void usart_dma_reset(volatile struct usart_desc *us) {
|
|||
|
||||
void usart_dma_init(volatile struct usart_desc *us, unsigned int baudrate) {
|
||||
usart_dma_reset(us);
|
||||
us->rx_buf.wr_pos = 0;
|
||||
us->rx_buf.rd_pos = 0;
|
||||
|
||||
/* Configure DMA 1 Channel 2 to handle uart transmission */
|
||||
us->tx_dmas->PAR = (uint32_t)&(us->le_usart->DR);
|
||||
|
|
@ -99,7 +101,7 @@ void usart_schedule_dma(volatile struct usart_desc *us) {
|
|||
} else { /* wraparound */
|
||||
if (xfr_end != 0)
|
||||
buf->wraparound = true;
|
||||
xfr_len = sizeof(us->data) - xfr_start;
|
||||
xfr_len = sizeof(us->tx_data) - xfr_start;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,11 +111,81 @@ void usart_schedule_dma(volatile struct usart_desc *us) {
|
|||
us->comm_led = 100;
|
||||
|
||||
/* initiate transmission of new buffer */
|
||||
us->tx_dmas->M0AR = (uint32_t)(us->data + xfr_start);
|
||||
us->tx_dmas->M0AR = (uint32_t)(us->tx_data + xfr_start);
|
||||
us->tx_dmas->NDTR = xfr_len;
|
||||
us->tx_dmas->CR |= DMA_SxCR_EN;
|
||||
}
|
||||
|
||||
void usart_irq(volatile struct usart_desc *us) {
|
||||
uint32_t sr = us->le_usart->SR;
|
||||
uint8_t c = us->le_usart->DR; /* this read cleas all three flags below */
|
||||
|
||||
if (sr & USART_SR_RXNE) {
|
||||
size_t new_wrpos = us->rx_buf.wr_pos + 1;
|
||||
if (new_wrpos > sizeof(us->rx_data))
|
||||
new_wrpos = 0;
|
||||
|
||||
if (new_wrpos != us->rx_buf.rd_pos) {
|
||||
us->rx_data[us->rx_buf.wr_pos] = c;
|
||||
us->rx_buf.wr_pos = new_wrpos;
|
||||
|
||||
} else {
|
||||
us->rx_buf_overruns ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (sr & USART_SR_FE) {
|
||||
us->rx_framing_errors ++;
|
||||
}
|
||||
|
||||
if (sr & USART_SR_ORE) {
|
||||
us->rx_overruns ++;
|
||||
}
|
||||
}
|
||||
|
||||
int usart_read_char(volatile struct usart_desc *us) {
|
||||
if (us->rx_buf.rd_pos != us->rx_buf.wr_pos) {
|
||||
unsigned char data = us->rx_data[us->rx_buf.rd_pos];
|
||||
size_t new_rdpos = us->rx_buf.rd_pos + 1;
|
||||
if (new_rdpos == sizeof(us->rx_data))
|
||||
new_rdpos = 0;
|
||||
us->rx_buf.rd_pos = new_rdpos;
|
||||
return data;
|
||||
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t usart_read_nonblocking(volatile struct usart_desc *us, uint8_t *buf, size_t size) {
|
||||
for (size_t i=0; i<size; i++) {
|
||||
int val = usart_read_char(us);
|
||||
if (val < 0) {
|
||||
return i;
|
||||
}
|
||||
|
||||
buf[i] = us->rx_data[i];
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
ssize_t usart_read_until(volatile struct usart_desc *us, uint8_t *buf, size_t size, uint8_t sep) {
|
||||
for (size_t i=0; i<size; i++) {
|
||||
int val;
|
||||
do {
|
||||
val = usart_read_char(us);
|
||||
} while (val == -1);
|
||||
|
||||
if (val == sep) {
|
||||
buf[i] = 0;
|
||||
return i;
|
||||
} else {
|
||||
buf[i] = val;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void usart_dma_stream_irq(volatile struct usart_desc *us) {
|
||||
uint8_t iflags = dma_get_isr_and_clear(us->tx_dma, us->tx_dma_sn);
|
||||
|
||||
|
|
@ -136,7 +208,7 @@ int usart_putc_nonblocking(volatile struct usart_desc *us, char c) {
|
|||
}
|
||||
|
||||
buf->data[buf->wr_pos] = c;
|
||||
buf->wr_pos = (buf->wr_pos + 1) % sizeof(us->data);
|
||||
buf->wr_pos = (buf->wr_pos + 1) % sizeof(us->tx_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +219,7 @@ int usart_putc_blocking(volatile struct usart_desc *us, char c) {
|
|||
;
|
||||
|
||||
buf->data[buf->wr_pos] = c;
|
||||
buf->wr_pos = (buf->wr_pos + 1) % sizeof(us->data);
|
||||
buf->wr_pos = (buf->wr_pos + 1) % sizeof(us->tx_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -205,3 +277,4 @@ int usart_printf_blocking(volatile struct usart_desc *us, const char *fmt, ...)
|
|||
return usart_printf_blocking_va(us, fmt, va);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -50,14 +50,29 @@ struct dma_tx_buf {
|
|||
#pragma GCC diagnostic pop
|
||||
};
|
||||
|
||||
struct rx_buf {
|
||||
size_t wr_pos;
|
||||
size_t rd_pos;
|
||||
|
||||
/* Make GCC shut up about the zero-size array member. */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
uint8_t data[0];
|
||||
#pragma GCC diagnostic pop
|
||||
};
|
||||
|
||||
struct usart_desc {
|
||||
struct dma_tx_buf tx_buf;
|
||||
uint8_t data[512];
|
||||
uint8_t tx_data[512];
|
||||
|
||||
volatile struct rx_buf rx_buf;
|
||||
volatile uint8_t rx_data[512];
|
||||
|
||||
uint32_t tx_chunk_overruns, tx_byte_overruns;
|
||||
uint32_t tx_errors;
|
||||
|
||||
volatile uint8_t rx_buf[32];
|
||||
uint32_t rx_framing_errors;
|
||||
uint32_t rx_overruns;
|
||||
uint32_t rx_buf_overruns;
|
||||
|
||||
int comm_led;
|
||||
|
||||
|
|
@ -76,9 +91,14 @@ int usart_putc_nonblocking(volatile struct usart_desc *us, char c);
|
|||
int usart_putc_blocking(volatile struct usart_desc *us, char c);
|
||||
|
||||
void usart_dma_stream_irq(volatile struct usart_desc *us);
|
||||
void usart_irq(volatile struct usart_desc *us);
|
||||
int usart_flush(volatile struct usart_desc *us);
|
||||
int usart_printf(volatile struct usart_desc *us, const char *fmt, ...);
|
||||
int usart_printf_blocking(volatile struct usart_desc *us, const char *fmt, ...);
|
||||
int usart_printf_blocking_va(volatile struct usart_desc *us, const char *fmt, va_list va);
|
||||
|
||||
ssize_t usart_read_until(volatile struct usart_desc *us, uint8_t *buf, size_t size, uint8_t sep);
|
||||
ssize_t usart_read_nonblocking(volatile struct usart_desc *us, uint8_t *buf, size_t size);
|
||||
int usart_read_char(volatile struct usart_desc *us);
|
||||
|
||||
#endif // __SERIAL_H__
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2021 jaseg <code@jaseg.de>
|
||||
*
|
||||
*
|
||||
* libusbhost is free software: you can redistribute it and/or modify
|
||||
* tachibana is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
|
@ -28,6 +28,7 @@ static uint8_t spi_read(struct spi_fpga_if *spif);
|
|||
static void spi_write(struct spi_fpga_if *spif, uint8_t b);
|
||||
static void spi_putc_blocking_tpf(void *spif, char c);
|
||||
|
||||
|
||||
uint8_t spi_xfer(struct spi_fpga_if *spif, uint8_t b) {
|
||||
while (!(spif->spi->SR & SPI_SR_TXE))
|
||||
;
|
||||
|
|
|
|||
13
demo/fw/tools/bin_to_header.py
Normal file
13
demo/fw/tools/bin_to_header.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env python3
|
||||
import click
|
||||
import sys
|
||||
|
||||
@click.command()
|
||||
def convert_to_c_header():
|
||||
data = sys.stdin.buffer.read()
|
||||
|
||||
for i in range(0, len(data), 16):
|
||||
print(', '.join(f'0x{c:02x}' for c in data[i:i+16]) + ',')
|
||||
|
||||
if __name__ == '__main__':
|
||||
convert_to_c_header()
|
||||
Loading…
Add table
Add a link
Reference in a new issue