mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
mn50: add data signing capability
Add a PERSO_AUTH appid to sign data passed through the AUTH mn50. Add a signer command to start and generate signatures. Clean UART init to avoid spurious nonprinting characters that will contaminate the siugnature. BUG=b:36910757 BRANCH=None TEST=generates signature for uart and spi Signed-off-by: Nick Sanders <nsanders@chromium.org> Change-Id: I5fc3c4ee34898421060b57b774a09734f6a1bae5 Reviewed-on: https://chromium-review.googlesource.com/670984 Reviewed-by: Marius Schilder <mschilder@chromium.org>
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "nvmem_vars.h"
|
||||
#include "registers.h"
|
||||
#include "signed_header.h"
|
||||
#include "signing.h"
|
||||
#include "spi.h"
|
||||
#include "system.h"
|
||||
#include "task.h"
|
||||
@@ -137,9 +138,7 @@ static void board_init(void)
|
||||
/* Enable USB / CCD */
|
||||
usb_release();
|
||||
usb_console_enable(1, 0);
|
||||
usb_spi_enable(&ccd_usb_spi, 1);
|
||||
ccd_phy_init();
|
||||
uartn_enable(UART_AP);
|
||||
|
||||
/* Calibrate INA0 (VBUS) with 1mA/LSB scale */
|
||||
i2cm_init();
|
||||
@@ -258,6 +257,9 @@ void enable_socket(void)
|
||||
|
||||
/* UART */
|
||||
GWRITE(PINMUX, DIOA7_SEL, GC_PINMUX_UART1_TX_SEL);
|
||||
GWRITE(PINMUX, DIOA3_SEL, GC_PINMUX_UART1_RX_SEL);
|
||||
GWRITE_FIELD(PINMUX, DIOA3_CTL, PU, 1);
|
||||
uartn_enable(UART_AP);
|
||||
|
||||
/* Chip select. */
|
||||
GWRITE_FIELD(PINMUX, DIOA5_CTL, PU, 1);
|
||||
@@ -281,7 +283,10 @@ void disable_socket(void)
|
||||
GWRITE(PINMUX, DIOA5_SEL, GC_PINMUX_GPIO0_GPIO10_SEL);
|
||||
|
||||
/* UART */
|
||||
uartn_disable(UART_AP);
|
||||
GWRITE(PINMUX, DIOA7_SEL, 0);
|
||||
GWRITE(PINMUX, DIOA3_SEL, 0);
|
||||
GWRITE_FIELD(PINMUX, DIOA3_CTL, PU, 0);
|
||||
|
||||
/* GPIOs as inputs. */
|
||||
gpio_set_flags(GPIO_DUT_BOOT_CFG, GPIO_INPUT);
|
||||
@@ -319,6 +324,67 @@ DECLARE_SAFE_CONSOLE_COMMAND(socket, command_socket,
|
||||
"[enable|disable]",
|
||||
"Activate and deactivate socket");
|
||||
|
||||
#ifdef CONFIG_STREAM_SIGNATURE
|
||||
/*
|
||||
* This command allows signing the contents of a data stream that passes
|
||||
* through mn50/scribe. This allows critical segments of SPI readouts,
|
||||
* including the haven personalization data to be verified on the server
|
||||
* side as coming from a registered scribe board. (go/haven-registration)
|
||||
*
|
||||
* The actual interface enables capturing data (start command) on a stream
|
||||
* (either SPI or UART), until stopped (sign command), at which point a
|
||||
* signature is printed to the console. An "append" command is available
|
||||
* to manually insert characters for testing, and should be disabled
|
||||
* before release.
|
||||
*/
|
||||
static int command_signer(int argc, char **argv)
|
||||
{
|
||||
static int initted; /* = 0; */
|
||||
char *data;
|
||||
|
||||
if (!initted) {
|
||||
init_signing();
|
||||
initted = 1;
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
enum stream_id id;
|
||||
|
||||
if (!strcasecmp("spi", argv[1]))
|
||||
id = stream_spi;
|
||||
else if (!strcasecmp("uart", argv[1]))
|
||||
id = stream_uart;
|
||||
else
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
if (!strcasecmp("sign", argv[2])) {
|
||||
if (argc == 3)
|
||||
return sig_sign(id);
|
||||
else
|
||||
return EC_ERROR_PARAM3;
|
||||
} else if (!strcasecmp("start", argv[2])) {
|
||||
if (argc == 3)
|
||||
return sig_start(id);
|
||||
else
|
||||
return EC_ERROR_PARAM3;
|
||||
} else if (!strcasecmp("append", argv[2])) {
|
||||
if (argc == 4) {
|
||||
data = argv[3];
|
||||
return sig_append(id, data, strlen(data));
|
||||
} else
|
||||
return EC_ERROR_PARAM3;
|
||||
} else
|
||||
return EC_ERROR_PARAM2;
|
||||
} else
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_SAFE_CONSOLE_COMMAND(signer, command_signer,
|
||||
"[spi|uart] [start|append|sign] data",
|
||||
"Sign data");
|
||||
#endif
|
||||
|
||||
void post_reboot_request(void)
|
||||
{
|
||||
/* This will never return. */
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
#define CONFIG_STREAM_USART
|
||||
#define CONFIG_STREAM_USB
|
||||
#define CONFIG_STREAM_USART1
|
||||
#define CONFIG_STREAM_SIGNATURE
|
||||
|
||||
#define CONFIG_USB_PID 0x502a
|
||||
#define CONFIG_USB_SELF_POWERED
|
||||
|
||||
@@ -27,6 +27,7 @@ dirs-y += chip/$(CHIP)/dcrypto
|
||||
|
||||
# Objects that we need to build
|
||||
board-y = board.o
|
||||
board-${CONFIG_STREAM_SIGNATURE} += signing.o
|
||||
board-${CONFIG_USB_SPI} += usb_spi.o
|
||||
|
||||
INCLUDE_ROOT := $(abspath ./include)
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
*/
|
||||
#define CONFIG_TASK_LIST \
|
||||
TASK_ALWAYS(HOOKS, hook_task, NULL, CONFIG_STACK_SIZE) \
|
||||
TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE)
|
||||
TASK_ALWAYS(CONSOLE, console_task, NULL, 8192)
|
||||
|
||||
201
board/mn50/signing.c
Normal file
201
board/mn50/signing.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/* Copyright 2017 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "dcrypto/dcrypto.h"
|
||||
#include "signing.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "cryptoc/sha.h"
|
||||
|
||||
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
|
||||
#define fail() cprints(CC_SYSTEM, "FAIL: %s:%d", __FILE__, __LINE__)
|
||||
|
||||
static p256_int x, y, d;
|
||||
|
||||
static HASH_CTX sig_sha[stream_count];
|
||||
|
||||
enum signer_states {
|
||||
state_notready = 0,
|
||||
state_ready,
|
||||
state_started,
|
||||
};
|
||||
|
||||
/* Current state of each signer stream. */
|
||||
static int signer_state[stream_count];
|
||||
|
||||
/* Bytes ingested into the hash so far. */
|
||||
static int signer_bytes[stream_count];
|
||||
|
||||
/* Human readable name of each stream. */
|
||||
static const char *signer_name[stream_count] = {
|
||||
"spi", "uart"
|
||||
};
|
||||
|
||||
void init_signing(void)
|
||||
{
|
||||
/* Add this enum to dcrypto.h */
|
||||
enum dcrypto_appid appid = PERSO_AUTH;
|
||||
struct APPKEY_CTX ctx;
|
||||
uint32_t key_bytes[8];
|
||||
const uint32_t PERSO_SALT[8] = {0xd00d1e, 0xba0, 0xc0ffee};
|
||||
|
||||
/*
|
||||
* Initialize signing key
|
||||
*/
|
||||
if (!DCRYPTO_appkey_init(appid, &ctx))
|
||||
fail();
|
||||
if (!DCRYPTO_appkey_derive(appid, PERSO_SALT, key_bytes))
|
||||
fail();
|
||||
if (!DCRYPTO_p256_key_from_bytes(&x, &y, &d,
|
||||
(const uint8_t *)key_bytes))
|
||||
fail();
|
||||
|
||||
/* (x,y) = pubkey, d = privkey */
|
||||
signer_state[stream_uart] = state_ready;
|
||||
signer_state[stream_spi] = state_ready;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start collecting data into a hash to be signed.
|
||||
* stream_id can be either stream_uart or stream_spi.
|
||||
*/
|
||||
int sig_start(enum stream_id id)
|
||||
{
|
||||
if ((id < 0) || (id >= stream_count))
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
if (signer_state[id] != state_ready) {
|
||||
CPRINTS("Signer %d not ready", id);
|
||||
return EC_ERROR_INVAL;
|
||||
}
|
||||
|
||||
/* Zero the hash. */
|
||||
DCRYPTO_SHA256_init(&sig_sha[id], 0);
|
||||
signer_bytes[id] = 0;
|
||||
signer_state[id] = state_started;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append data into this stream's hash for future signing.
|
||||
* This function is called inline with data receive, from the UART rx code
|
||||
* or the SPI rx code.
|
||||
*
|
||||
* This can be called any time, but only hashes data when the stream
|
||||
* capture is started.
|
||||
*/
|
||||
int sig_append(enum stream_id id, const uint8_t *data, size_t data_len)
|
||||
{
|
||||
HASH_CTX *sha = &sig_sha[id];
|
||||
const uint8_t *blob = data;
|
||||
size_t len = data_len;
|
||||
|
||||
if ((id < 0) || (id >= stream_count))
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
if (signer_state[id] != state_started)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
HASH_update(sha, blob, len);
|
||||
signer_bytes[id] += len;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/* Close this stream's capture and print out the signature. */
|
||||
int sig_sign(enum stream_id id)
|
||||
{
|
||||
HASH_CTX *sha = &sig_sha[id];
|
||||
p256_int r, s; /* signature tuple */
|
||||
p256_int digest;
|
||||
struct drbg_ctx drbg;
|
||||
|
||||
if ((id < 0) || (id >= stream_count))
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
if (signer_state[id] != state_started) {
|
||||
CPRINTS("Signer %d not starter", id);
|
||||
return EC_ERROR_INVAL;
|
||||
}
|
||||
|
||||
p256_from_bin(HASH_final(sha), &digest);
|
||||
drbg_rand_init(&drbg);
|
||||
|
||||
if (!dcrypto_p256_ecdsa_sign(&drbg, &d, &digest, &r, &s)) {
|
||||
fail();
|
||||
return EC_ERROR_INVAL;
|
||||
}
|
||||
|
||||
/* Check that the signature was correctly computed */
|
||||
if (!dcrypto_p256_ecdsa_verify(&x, &y, &digest, &r, &s)) {
|
||||
fail();
|
||||
return EC_ERROR_INVAL;
|
||||
}
|
||||
|
||||
/* Serialize r, s into output. */
|
||||
|
||||
CPRINTS("Signed %d bytes from %s.", signer_bytes[id], signer_name[id]);
|
||||
CPRINTS("digest:");
|
||||
CPRINTS("%08x %08x %08x %08x",
|
||||
digest.a[0], digest.a[1], digest.a[2], digest.a[3]);
|
||||
CPRINTS("%08x %08x %08x %08x",
|
||||
digest.a[4], digest.a[5], digest.a[6], digest.a[7]);
|
||||
CPRINTS("r:");
|
||||
CPRINTS("%08x %08x %08x %08x", r.a[0], r.a[1], r.a[2], r.a[3]);
|
||||
CPRINTS("%08x %08x %08x %08x", r.a[4], r.a[5], r.a[6], r.a[7]);
|
||||
CPRINTS("s:");
|
||||
CPRINTS("%08x %08x %08x %08x", s.a[0], s.a[1], s.a[2], s.a[3]);
|
||||
CPRINTS("%08x %08x %08x %08x", s.a[4], s.a[5], s.a[6], s.a[7]);
|
||||
|
||||
signer_state[id] = state_ready;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Intercept UART data between the uart driver and usb bridge.
|
||||
*
|
||||
* This code is called by the ec's queue implementation, and ingests
|
||||
* the UART RX queue, appends the data to the signer, then passes it
|
||||
* on the the USB bridge's TX queue.
|
||||
*/
|
||||
void signer_written(struct consumer const *consumer, size_t count)
|
||||
{
|
||||
struct signer_config const *config =
|
||||
DOWNCAST(consumer, struct signer_config, consumer);
|
||||
struct producer const *producer = &(config->producer);
|
||||
enum stream_id id = config->id;
|
||||
|
||||
/* This queue receives characters from the UART. */
|
||||
struct queue const *sig_in = consumer->queue;
|
||||
|
||||
/*
|
||||
* This enqueues characters into the USB bridge,
|
||||
* once they have been hashed.
|
||||
*/
|
||||
struct queue const *sig_out = producer->queue;
|
||||
char c;
|
||||
|
||||
/* Copy UART rx from queue. */
|
||||
while (queue_count(sig_in) && QUEUE_REMOVE_UNITS(sig_in, &c, 1)) {
|
||||
/* Append this data to the hash. */
|
||||
sig_append(id, &c, 1);
|
||||
/* Pass the data to the USB bridge. */
|
||||
QUEUE_ADD_UNITS(sig_out, &c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct producer_ops const signer_producer_ops = {
|
||||
.read = NULL,
|
||||
};
|
||||
|
||||
struct consumer_ops const signer_consumer_ops = {
|
||||
.written = signer_written,
|
||||
.flush = NULL,
|
||||
};
|
||||
73
board/mn50/signing.h
Normal file
73
board/mn50/signing.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* Copyright 2017 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Add inline signing to verify records pasased through
|
||||
* AUTH haven on Scribe SLT board.
|
||||
*/
|
||||
|
||||
#ifndef __CROS_EC_SIGNER_H
|
||||
#define __CROS_EC_SIGNER_H
|
||||
|
||||
#include "queue.h"
|
||||
#include "queue_policies.h"
|
||||
|
||||
/*
|
||||
* Data signing is supported on the following inputs:
|
||||
* stream_spi: data received on H1's SPI master.
|
||||
* stream_uart: data received on UART1.
|
||||
*
|
||||
* It's possible to hash multiple streams at once.
|
||||
* Currently the hash will print out as console output
|
||||
* in hex format when the stream is stopped.
|
||||
*/
|
||||
enum stream_id {
|
||||
stream_spi = 0,
|
||||
stream_uart = 1,
|
||||
stream_count = 2,
|
||||
};
|
||||
|
||||
/* Init the signing state and derive keys. Must be called before sig_start. */
|
||||
void init_signing(void);
|
||||
|
||||
/* Zero the existing hash and start processing data in the specified stream. */
|
||||
int sig_start(enum stream_id id);
|
||||
|
||||
/* Append data into the specified stream, if started, otherwise do nothing. */
|
||||
int sig_append(enum stream_id id, const uint8_t *data, size_t data_len);
|
||||
|
||||
/* Stop a stream and sign the hash. The signature will print to the console. */
|
||||
int sig_sign(enum stream_id id);
|
||||
|
||||
|
||||
struct signer_config {
|
||||
enum stream_id id;
|
||||
|
||||
struct producer const producer;
|
||||
struct consumer const consumer;
|
||||
};
|
||||
|
||||
extern struct consumer_ops const signer_consumer_ops;
|
||||
extern struct producer_ops const signer_producer_ops;
|
||||
|
||||
void signer_written(struct consumer const *consumer, size_t count);
|
||||
|
||||
/*
|
||||
* Macro to set up inline signer.
|
||||
* Usage: SIGNER_CONFIG(name, stream_id, tx queue, rx queue)
|
||||
*/
|
||||
#define SIGNER_CONFIG(NAME, ID, RX_QUEUE, TX_QUEUE) \
|
||||
struct signer_config const NAME = { \
|
||||
.id = ID, \
|
||||
.consumer = { \
|
||||
.queue = &TX_QUEUE, \
|
||||
.ops = &signer_consumer_ops, \
|
||||
}, \
|
||||
.producer = { \
|
||||
.queue = &RX_QUEUE, \
|
||||
.ops = &signer_producer_ops, \
|
||||
}, \
|
||||
}
|
||||
#endif
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
#include "registers.h"
|
||||
#include "signing.h"
|
||||
#include "spi.h"
|
||||
#include "system.h"
|
||||
#include "timer.h"
|
||||
@@ -67,6 +68,12 @@ int usb_spi_interface(struct usb_spi_config const *config,
|
||||
else
|
||||
disable_socket();
|
||||
break;
|
||||
case USB_SPI_REQ_SIGNING_START:
|
||||
sig_start(stream_spi);
|
||||
break;
|
||||
case USB_SPI_REQ_SIGNING_SIGN:
|
||||
sig_sign(stream_spi);
|
||||
break;
|
||||
case USB_SPI_REQ_ENABLE_AP:
|
||||
case USB_SPI_REQ_ENABLE:
|
||||
CPRINTS("ERROR: Must specify target");
|
||||
|
||||
@@ -49,6 +49,16 @@ const struct {
|
||||
0xcd375bcd, 0x8065e8cc, 0xc892ed69, 0x72436c7d
|
||||
}
|
||||
},
|
||||
#ifdef CONFIG_STREAM_SIGNATURE
|
||||
{
|
||||
/* This key signs data from H1's configured by mn50/scribe. */
|
||||
"PERSO_AUTH",
|
||||
{
|
||||
0x2019da34, 0xf1a01a13, 0x0fb9f73f, 0xf2e85f76,
|
||||
0x5ecb7690, 0x09f732c9, 0xe540bf14, 0xcc46799a
|
||||
}
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
int DCRYPTO_appkey_init(enum dcrypto_appid appid, struct APPKEY_CTX *ctx)
|
||||
|
||||
@@ -271,6 +271,7 @@ enum dcrypto_appid {
|
||||
U2F_ATTEST = 2,
|
||||
U2F_ORIGIN = 3,
|
||||
U2F_WRAP = 4,
|
||||
PERSO_AUTH = 5,
|
||||
/* This enum value should not exceed 7. */
|
||||
};
|
||||
|
||||
|
||||
@@ -8,25 +8,63 @@
|
||||
#include "uartn.h"
|
||||
#include "usart.h"
|
||||
#include "usb-stream.h"
|
||||
#ifdef CONFIG_STREAM_SIGNATURE
|
||||
#include "signing.h"
|
||||
#endif
|
||||
|
||||
#define USE_UART_INTERRUPTS (!(defined(CONFIG_CUSTOMIZED_RO) && \
|
||||
defined(SECTION_IS_RO)))
|
||||
#define QUEUE_SIZE 64
|
||||
|
||||
|
||||
#ifdef CONFIG_STREAM_USART1
|
||||
struct usb_stream_config const ap_usb;
|
||||
struct usart_config const ap_uart;
|
||||
|
||||
static struct queue const ap_uart_to_usb =
|
||||
#ifdef CONFIG_STREAM_SIGNATURE
|
||||
/*
|
||||
* This code adds the ability to capture UART data received, and
|
||||
* sign it with H1's key. This allows the log output to be verified
|
||||
* as actual UART output from this board.
|
||||
*
|
||||
* This functionality is enabled by redirecting the UART receive queue
|
||||
* to feed into the signing module rather than the usb tx. After being
|
||||
* added to the running hash, the data is then pushed by the signer
|
||||
* into the usb tx queue.
|
||||
*/
|
||||
struct signer_config const sig;
|
||||
static struct queue const ap_uart_output =
|
||||
QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ap_uart.producer, sig.consumer);
|
||||
static struct queue const sig_to_usb =
|
||||
QUEUE_DIRECT(QUEUE_SIZE, uint8_t, sig.producer, ap_usb.consumer);
|
||||
|
||||
SIGNER_CONFIG(sig, stream_uart, sig_to_usb, ap_uart_output);
|
||||
|
||||
#else /* Not CONFIG_STREAM_SIGNATURE */
|
||||
static struct queue const ap_uart_output =
|
||||
QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ap_uart.producer, ap_usb.consumer);
|
||||
#endif
|
||||
|
||||
static struct queue const ap_usb_to_uart =
|
||||
QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ap_usb.producer, ap_uart.consumer);
|
||||
|
||||
/*
|
||||
* AP UART data is sent to the ap_uart_output queue, and received from
|
||||
* the ap_usb_to_uart queue. The ap_uart_output queue is received by the
|
||||
* USB bridge, or if a signer is enabled, received by the signer, which then
|
||||
* passes the data to the USB bridge after processing it.
|
||||
*/
|
||||
USART_CONFIG(ap_uart,
|
||||
UART_AP,
|
||||
ap_uart_to_usb,
|
||||
ap_uart_output,
|
||||
ap_usb_to_uart);
|
||||
|
||||
/*
|
||||
* The UART USB bridge receives character data from the UART's queue,
|
||||
* unless signing is enabled, in which case it receives data from the
|
||||
* signer's queue, after the signer has received it from the UART and
|
||||
* processed it.
|
||||
*/
|
||||
USB_STREAM_CONFIG(ap_usb,
|
||||
USB_IFACE_AP,
|
||||
USB_STR_AP_NAME,
|
||||
@@ -34,8 +72,12 @@ USB_STREAM_CONFIG(ap_usb,
|
||||
USB_MAX_PACKET_SIZE,
|
||||
USB_MAX_PACKET_SIZE,
|
||||
ap_usb_to_uart,
|
||||
ap_uart_to_usb)
|
||||
#ifdef CONFIG_STREAM_SIGNATURE
|
||||
sig_to_usb)
|
||||
#else
|
||||
ap_uart_output)
|
||||
#endif
|
||||
#endif /* CONFIG_STREAM_USART1 */
|
||||
|
||||
#ifdef CONFIG_STREAM_USART2
|
||||
struct usb_stream_config const ec_usb;
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#include "usb_spi.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifdef CONFIG_STREAM_SIGNATURE
|
||||
#include "signing.h"
|
||||
#endif
|
||||
|
||||
#define CPUTS(outstr) cputs(CC_USB, outstr)
|
||||
#define CPRINTS(format, args...) cprints(CC_USB, format, ## args)
|
||||
|
||||
@@ -40,6 +44,15 @@ static uint16_t usb_spi_read_packet(struct usb_spi_config const *config)
|
||||
static void usb_spi_write_packet(struct usb_spi_config const *config,
|
||||
uint8_t count)
|
||||
{
|
||||
#ifdef CONFIG_STREAM_SIGNATURE
|
||||
/*
|
||||
* This hook allows mn50 to sign SPI data read from newly
|
||||
* manufactured H1 devieces. The data is added to a running
|
||||
* hash until a completion message is received.
|
||||
*/
|
||||
sig_append(stream_spi, config->buffer, count);
|
||||
#endif
|
||||
|
||||
QUEUE_ADD_UNITS(config->tx_queue, config->buffer, count);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,8 @@ enum usb_spi_request {
|
||||
USB_SPI_REQ_RESET = 0x0005,
|
||||
USB_SPI_REQ_BOOT_CFG = 0x0006,
|
||||
USB_SPI_REQ_SOCKET = 0x0007,
|
||||
USB_SPI_REQ_SIGNING_START = 0x0008,
|
||||
USB_SPI_REQ_SIGNING_SIGN = 0x0009,
|
||||
};
|
||||
|
||||
/* USB SPI device bitmasks */
|
||||
|
||||
@@ -2842,6 +2842,14 @@
|
||||
/* USB Power monitoring interface config */
|
||||
#undef CONFIG_USB_POWER
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* USB stream signing config. This allows data read over UART or SPI
|
||||
* to have a signature generated that can be used to validate the data
|
||||
* offline based on H1's registered key. Used by mn50.
|
||||
*/
|
||||
#undef CONFIG_STREAM_SIGNATURE
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user