diff --git a/Documentation/components/drivers/character/index.rst b/Documentation/components/drivers/character/index.rst index 8cdcaa5521..f9551389b4 100644 --- a/Documentation/components/drivers/character/index.rst +++ b/Documentation/components/drivers/character/index.rst @@ -66,4 +66,5 @@ Character device drivers have these properties: note.rst foc.rst ws2812.rst + se05x.rst diff --git a/Documentation/components/drivers/character/se05x.rst b/Documentation/components/drivers/character/se05x.rst new file mode 100644 index 0000000000..e064d25aa4 --- /dev/null +++ b/Documentation/components/drivers/character/se05x.rst @@ -0,0 +1,46 @@ +============ +SE05X Driver +============ + +This driver enables access to the NXP SE05X secure element by +using the `NXP plug and trust nano `_. + +.. note:: + Currently this driver has only been tested on SE050. + +API +=== + +The driver supports reading/writing to the SE05X's keystore and additional +features like diffie-hellman key derivation and signing CSR's and verifying +certificates using keys from the keystore. +Refer to ``drivers/crypto/pnt/pnt_se05x_api.h`` for the API functions available +and to ``include/nuttx/crypto/se05x.h`` for the ioctl commands + +These tools make use of the SE05X driver (which can function as a reference project): + +- The ``controlse`` app can be used to control the SE05X from NSH. + +- The ``setest`` app tests all the SE05X ioctl functionality from NSH + +Datasheets are available on the `NXP website `_. + +Configuration +============= + +- ``DEV_SE05X`` Enable support for /dev/se05x secure element provided by NXP SE050 + or SE051 + + - Channel communication interface + + - ``DEV_SE05X_SCP03`` SCP03 secure channel (Not implemented) + + - ``DEV_SE05X_SCP03_KEY_FILE`` Specify file containing the keys needed with + SCP03 channel authentication. + Location may be relative to the NuttX root folder. File should contain + the definitions for SCP03_ENC_KEY, SCP03_MAC_KEY and SCP03_DEK_KEY as + byte array initializers. + + - ``DEV_SE05X_PLAIN`` plain communication + + - ``SE05X_LOG_LEVEL`` The SE05x log is divided into the following levels: ERROR,WARNING,INFO,DEBUG. diff --git a/boards/arm/s32k1xx/ucans32k146/configs/se05x/defconfig b/boards/arm/s32k1xx/ucans32k146/configs/se05x/defconfig new file mode 100644 index 0000000000..a7bafc199c --- /dev/null +++ b/boards/arm/s32k1xx/ucans32k146/configs/se05x/defconfig @@ -0,0 +1,55 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_FPU is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="ucans32k146" +CONFIG_ARCH_BOARD_UCANS32K146=y +CONFIG_ARCH_CHIP="s32k1xx" +CONFIG_ARCH_CHIP_S32K146=y +CONFIG_ARCH_CHIP_S32K14X=y +CONFIG_ARCH_CHIP_S32K1XX=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=6667 +CONFIG_BUILTIN=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_CONTROLSE=y +CONFIG_CRYPTO_CONTROLSE_STACKSIZE=5120 +CONFIG_CRYPTO_MBEDTLS=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEV_SE05X=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_LPUART1_SERIAL_CONSOLE=y +CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=126976 +CONFIG_RAM_START=0x1fff0000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_S32K1XX_LPI2C0=y +CONFIG_S32K1XX_LPUART1=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=9 +CONFIG_START_YEAR=2021 +CONFIG_SYMTAB_ORDEREDBYNAME=y +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_SETEST=y +CONFIG_TESTING_SETEST_STACKSIZE=4096 diff --git a/boards/arm/s32k1xx/ucans32k146/src/Makefile b/boards/arm/s32k1xx/ucans32k146/src/Makefile index 211ea89471..edbb015b4d 100644 --- a/boards/arm/s32k1xx/ucans32k146/src/Makefile +++ b/boards/arm/s32k1xx/ucans32k146/src/Makefile @@ -45,4 +45,8 @@ ifeq ($(CONFIG_S32K1XX_LPSPI),y) CSRCS += s32k1xx_spi.c endif +ifeq ($(CONFIG_DEV_SE05X),y) +CSRCS += s32k1xx_se05x.c +endif + include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/s32k1xx/ucans32k146/src/s32k1xx_bringup.c b/boards/arm/s32k1xx/ucans32k146/src/s32k1xx_bringup.c index ab8d102f6d..3efcab34a9 100644 --- a/boards/arm/s32k1xx/ucans32k146/src/s32k1xx_bringup.c +++ b/boards/arm/s32k1xx/ucans32k146/src/s32k1xx_bringup.c @@ -139,6 +139,17 @@ int s32k1xx_bringup(void) } #endif +#ifdef CONFIG_DEV_SE05X + /* Initialize SE05x driver */ + + ret = s32k1xx_se05x_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: s32k1xx_se05x_initialize() failed: %d\n", + ret); + } +#endif + #ifdef CONFIG_S32K1XX_LPSPI /* Initialize SPI driver */ diff --git a/boards/arm/s32k1xx/ucans32k146/src/s32k1xx_se05x.c b/boards/arm/s32k1xx/ucans32k146/src/s32k1xx_se05x.c new file mode 100644 index 0000000000..a60b64d8ff --- /dev/null +++ b/boards/arm/s32k1xx/ucans32k146/src/s32k1xx_se05x.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * boards/arm/s32k1xx/ucans32k146/src/s32k1xx_se05x.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include + +#include "ucans32k146.h" +#include +#include +#include +#include + +/**************************************************************************** + * Private Functions Prototypes + ****************************************************************************/ + +static bool board_se05x_enable(bool state); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct se05x_config_s se05x_config = +{ + .address = 0x48, + .frequency = 400000, + .set_enable_pin = board_se05x_enable, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static bool board_se05x_enable(bool state) +{ + s32k1xx_gpiowrite(GPIO_SE050_EN, state); + return true; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int weak_function s32k1xx_se05x_initialize() +{ + int ret; + + struct i2c_master_s *lpi2c0 = s32k1xx_i2cbus_initialize(0); + ret = lpi2c0 == NULL ? -EPERM : 0; + + if (ret == 0) + { + ret = se05x_register("/dev/se05x", lpi2c0, &se05x_config); + } + + return ret; +} diff --git a/boards/arm/s32k1xx/ucans32k146/src/ucans32k146.h b/boards/arm/s32k1xx/ucans32k146/src/ucans32k146.h index f33a1af748..968a34586f 100644 --- a/boards/arm/s32k1xx/ucans32k146/src/ucans32k146.h +++ b/boards/arm/s32k1xx/ucans32k146/src/ucans32k146.h @@ -117,5 +117,15 @@ int s32k1xx_i2cdev_initialize(void); int s32k1xx_spidev_initialize(void); +/**************************************************************************** + * Name: s32k1xx_se05x_initialize + * + * Description: + * Initialize SE05x chip and register /dev/se05x + * + ****************************************************************************/ + +int s32k1xx_se05x_initialize(void); + #endif /* __ASSEMBLY__ */ #endif /* __BOARDS_ARM_S32K1XX_UCANS32K146_SRC_UCANS32K146_H */ diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 27aa49ea59..668803e250 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -74,3 +74,60 @@ config DEV_URANDOM_ARCH endchoice # /dev/urandom algorithm endif # DEV_URANDOM + +menuconfig DEV_SE05X + bool "Enable secure element (SE05X)" + depends on I2C + depends on CRYPTO + default n + ---help--- + Enable support for /dev/se05x secure element provided by NXP SE050 + or SE051 + +if DEV_SE05X + +choice + prompt "Channel communication interface" + default DEV_SE05X_PLAIN + ---help--- + Select authentication method + +config DEV_SE05X_SCP03 + bool "SCP03 secure channel (TBI)" + select CRYPTO_RANDOM_POOL + select CRYPTO_AES + +config DEV_SE05X_PLAIN + bool "plain communication" + +endchoice + +config DEV_SE05X_SCP03_KEY_FILE + string "SCP03 keys" + depends on DEV_SE05X_SCP03 + default "/host/path/to/key_file" + ---help--- + Specify file containing the keys needed with SCP03 channel authentication. + Location may be relative to the NuttX root folder. File should contain + the definitions for SCP03_ENC_KEY, SCP03_MAC_KEY and SCP03_DEK_KEY as + byte array initializers. + +choice SE05X_LOG_LEVEL + prompt "SE05x debug log level" + default SE05X_LOG_NONE + ---help--- + The SE05x log is divided into the following levels: ERROR,WARNING,INFO,DEBUG. + + config SE05X_LOG_NONE + bool "No output" + config SE05X_LOG_ERROR + bool "Error" + config SE05X_LOG_WARNING + bool "Warning" + config SE05X_LOG_INFO + bool "Info" + config SE05X_LOG_DEBUG + bool "Debug" +endchoice + +endif #DEV_SE05X diff --git a/drivers/crypto/Make.defs b/drivers/crypto/Make.defs index 9f5a90f77e..dc2039bcda 100644 --- a/drivers/crypto/Make.defs +++ b/drivers/crypto/Make.defs @@ -24,6 +24,11 @@ ifneq ($(CONFIG_DEV_URANDOM_ARCH),y) endif endif +ifeq ($(CONFIG_DEV_SE05X),y) + CSRCS += se05x.c + include crypto/pnt/Make.defs +endif + # Include crypto device driver build support DEPPATH += --dep-path crypto diff --git a/drivers/crypto/pnt/.gitignore b/drivers/crypto/pnt/.gitignore new file mode 100644 index 0000000000..2582672285 --- /dev/null +++ b/drivers/crypto/pnt/.gitignore @@ -0,0 +1,2 @@ +*.zip +nano-package/ diff --git a/drivers/crypto/pnt/0001-fixed-i2c-port-selection.patch b/drivers/crypto/pnt/0001-fixed-i2c-port-selection.patch new file mode 100644 index 0000000000..3d0b3d26ee --- /dev/null +++ b/drivers/crypto/pnt/0001-fixed-i2c-port-selection.patch @@ -0,0 +1,48 @@ +From 9e5764fa78849d7125aa327838cbb8aab9f72a95 Mon Sep 17 00:00:00 2001 +From: Andre Heinemans +Date: Tue, 18 Oct 2022 12:59:38 +0200 +Subject: [PATCH 1/4] fixed i2c port selection + +--- + lib/apdu/se05x_APDU_apis.h | 2 +- + lib/apdu/se05x_APDU_impl.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/apdu/se05x_APDU_apis.h b/lib/apdu/se05x_APDU_apis.h +index 544f065..38cf017 100644 +--- a/lib/apdu/se05x_APDU_apis.h ++++ b/lib/apdu/se05x_APDU_apis.h +@@ -21,7 +21,7 @@ + * + * @return The sm status. + */ +-smStatus_t Se05x_API_SessionOpen(pSe05xSession_t session_ctx); ++smStatus_t Se05x_API_SessionOpen(pSe05xSession_t session_ctx, void *conn_context); + + /** Se05x_API_SessionClose + * +diff --git a/lib/apdu/se05x_APDU_impl.c b/lib/apdu/se05x_APDU_impl.c +index 966aca0..4acfad7 100644 +--- a/lib/apdu/se05x_APDU_impl.c ++++ b/lib/apdu/se05x_APDU_impl.c +@@ -35,7 +35,7 @@ bool Se05x_IsInValidRangeOfUID(uint32_t uid) + return FALSE; + } + +-smStatus_t Se05x_API_SessionOpen(pSe05xSession_t session_ctx) ++smStatus_t Se05x_API_SessionOpen(pSe05xSession_t session_ctx, void *conn_context) + { + size_t buff_len = 0; + size_t tx_len = 0; +@@ -53,7 +53,7 @@ smStatus_t Se05x_API_SessionOpen(pSe05xSession_t session_ctx) + + buff_len = sizeof(session_ctx->apdu_buffer); + +- ret = smComT1oI2C_Init(&session_ctx->conn_context, NULL); ++ ret = smComT1oI2C_Init(&session_ctx->conn_context, conn_context); + ENSURE_OR_GO_CLEANUP(SM_OK == ret); + + if (session_ctx->session_resume == 1) { +-- +2.25.1 + diff --git a/drivers/crypto/pnt/0002-Fixed-memory-management-in-lib-t1oi2c-phNxpEse_Api.c.patch b/drivers/crypto/pnt/0002-Fixed-memory-management-in-lib-t1oi2c-phNxpEse_Api.c.patch new file mode 100644 index 0000000000..32c735cf54 --- /dev/null +++ b/drivers/crypto/pnt/0002-Fixed-memory-management-in-lib-t1oi2c-phNxpEse_Api.c.patch @@ -0,0 +1,335 @@ +From 48fefd7d0b92b852de6250a37b615eb654dffaf7 Mon Sep 17 00:00:00 2001 +From: Andre Heinemans +Date: Wed, 22 Feb 2023 09:52:15 +0100 +Subject: [PATCH 2/4] Fixed memory management in lib/t1oi2c/phNxpEse_Api.c by + not using global memory anymore but take the buffer being allocated as a + precondition + +--- + lib/apdu/smCom.c | 12 ++++- + lib/t1oi2c/phNxpEse_Api.c | 96 +++++++++++----------------------- + lib/t1oi2c/phNxpEse_Api.h | 2 +- + lib/t1oi2c/phNxpEse_Internal.h | 1 + + 4 files changed, 43 insertions(+), 68 deletions(-) + +diff --git a/lib/apdu/smCom.c b/lib/apdu/smCom.c +index 16eca5e..0fea95a 100644 +--- a/lib/apdu/smCom.c ++++ b/lib/apdu/smCom.c +@@ -36,6 +36,10 @@ smStatus_t smComT1oI2C_Close(void *conn_ctx, uint8_t mode) + status = phNxpEse_close(conn_ctx); + ENSURE_OR_RETURN_ON_ERROR((status == ESESTATUS_SUCCESS), SM_NOT_OK); + ++ if (conn_ctx != NULL) { ++ sm_free(conn_ctx); ++ } ++ + SM_MUTEX_DEINIT(g_sm_mutex); + + return SM_OK; +@@ -47,7 +51,13 @@ smStatus_t smComT1oI2C_Init(void **conn_ctx, const char *pConnString) + phNxpEse_initParams initParams; + initParams.initMode = ESE_MODE_NORMAL; + +- status = phNxpEse_open(conn_ctx, initParams, pConnString); ++ if (*conn_ctx != NULL) { ++ // conn_ctx not being NULL could indicate this function is ++ // called 2 times. Return error to prevent leaks ++ return SM_NOT_OK; ++ } ++ *conn_ctx = sm_malloc(sizeof(phNxpEse_Context_t)); ++ status = phNxpEse_open(*conn_ctx, initParams, pConnString); + ENSURE_OR_RETURN_ON_ERROR((status == ESESTATUS_SUCCESS), SM_NOT_OK); + + SM_MUTEX_INIT(g_sm_mutex); +diff --git a/lib/t1oi2c/phNxpEse_Api.c b/lib/t1oi2c/phNxpEse_Api.c +index a4565f3..01a757e 100644 +--- a/lib/t1oi2c/phNxpEse_Api.c ++++ b/lib/t1oi2c/phNxpEse_Api.c +@@ -29,15 +29,6 @@ static int poll_sof_chained_delay = 0; + + /*********************** Global Variables *************************************/ + +-/* ESE Context structure */ +-phNxpEse_Context_t gnxpese_ctxt; +-static uint8_t t10i2c_tempBuf[48] = { +- 0, +-}; +-phNxpEse_data gRsp = { +- 0, +-}; +- + /****************************************************************************** + * Function phNxpEse_init + * +@@ -55,15 +46,15 @@ phNxpEse_data gRsp = { + ESESTATUS phNxpEse_init(void *conn_ctx, phNxpEse_initParams initParams, phNxpEse_data *AtrRsp) + { + ESESTATUS wConfigStatus = ESESTATUS_SUCCESS; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + bool_t status = FALSE; + phNxpEseProto7816InitParam_t protoInitParam; + phNxpEse_memset(&protoInitParam, 0x00, sizeof(phNxpEseProto7816InitParam_t)); + protoInitParam.rnack_retry_limit = MAX_RNACK_RETRY_LIMIT; + protoInitParam.wtx_counter_limit = PH_PROTO_WTX_DEFAULT_COUNT; + +- gRsp.p_data = AtrRsp->p_data; +- gRsp.len = AtrRsp->len; ++ nxpese_ctxt->p_read_buff = AtrRsp->p_data; ++ nxpese_ctxt->read_buff_len = AtrRsp->len; + + if (ESE_MODE_NORMAL == initParams.initMode) /* TZ/Normal wired mode should come here*/ + { +@@ -101,25 +92,21 @@ ESESTATUS phNxpEse_init(void *conn_ctx, phNxpEse_initParams initParams, phNxpEse + * In case of failure returns other failure value. + * + ******************************************************************************/ +-ESESTATUS phNxpEse_open(void **conn_ctx, phNxpEse_initParams initParams, const char *pConnString) ++ESESTATUS phNxpEse_open(void *conn_ctx, phNxpEse_initParams initParams, const char *pConnString) + { + phPalEse_Config_t tPalConfig; +- phNxpEse_Context_t *pnxpese_ctxt = NULL; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + ESESTATUS wConfigStatus = ESESTATUS_SUCCESS; + +- pnxpese_ctxt = &gnxpese_ctxt; +- phNxpEse_memset(pnxpese_ctxt, 0, sizeof(phNxpEse_Context_t)); +- if (conn_ctx != NULL) { +- *conn_ctx = pnxpese_ctxt; +- } ++ phNxpEse_memset(nxpese_ctxt, 0, sizeof(phNxpEse_Context_t)); + + /*When I2C channel is already opened return status as FAILED*/ +- if (pnxpese_ctxt->EseLibStatus != ESE_STATUS_CLOSE) { ++ if (nxpese_ctxt->EseLibStatus != ESE_STATUS_CLOSE) { + T_SMLOG_E(" Session already opened"); + return ESESTATUS_BUSY; + } + +- phNxpEse_memset(pnxpese_ctxt, 0x00, sizeof(phNxpEse_Context_t)); ++ phNxpEse_memset(nxpese_ctxt, 0x00, sizeof(phNxpEse_Context_t)); + phNxpEse_memset(&tPalConfig, 0x00, sizeof(tPalConfig)); + + tPalConfig.pDevName = (int8_t *)pConnString; //"/dev/p73"; /*RFU*/ +@@ -130,18 +117,18 @@ ESESTATUS phNxpEse_open(void **conn_ctx, phNxpEse_initParams initParams, const c + goto clean_and_return; + } + /* Copying device handle to ESE Lib context*/ +- pnxpese_ctxt->pDevHandle = tPalConfig.pDevHandle; ++ nxpese_ctxt->pDevHandle = tPalConfig.pDevHandle; + /* STATUS_OPEN */ +- pnxpese_ctxt->EseLibStatus = ESE_STATUS_OPEN; +- phNxpEse_memcpy(&pnxpese_ctxt->initParams, &initParams, sizeof(phNxpEse_initParams)); ++ nxpese_ctxt->EseLibStatus = ESE_STATUS_OPEN; ++ phNxpEse_memcpy(&nxpese_ctxt->initParams, &initParams, sizeof(phNxpEse_initParams)); + return wConfigStatus; + + clean_and_return: +- if (NULL != pnxpese_ctxt->pDevHandle) { +- phPalEse_i2c_close(pnxpese_ctxt->pDevHandle); +- phNxpEse_memset(pnxpese_ctxt, 0x00, sizeof(phNxpEse_Context_t)); ++ if (NULL != nxpese_ctxt->pDevHandle) { ++ phPalEse_i2c_close(nxpese_ctxt->pDevHandle); ++ phNxpEse_memset(nxpese_ctxt, 0x00, sizeof(phNxpEse_Context_t)); + } +- pnxpese_ctxt->EseLibStatus = ESE_STATUS_CLOSE; ++ nxpese_ctxt->EseLibStatus = ESE_STATUS_CLOSE; + return ESESTATUS_FAILED; + } + +@@ -162,15 +149,12 @@ ESESTATUS phNxpEse_Transceive(void *conn_ctx, phNxpEse_data *pCmd, phNxpEse_data + { + ESESTATUS status = ESESTATUS_FAILED; + bool_t bStatus = FALSE; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + + if ((NULL == pCmd) || (NULL == pRsp)) { + return ESESTATUS_INVALID_PARAMETER; + } + +- gRsp.p_data = pRsp->p_data; +- gRsp.len = pRsp->len; +- + if ((pCmd->len == 0) || pCmd->p_data == NULL) { + T_SMLOG_E(" phNxpEse_Transceive - Invalid Parameter no data"); + return ESESTATUS_INVALID_PARAMETER; +@@ -218,7 +202,7 @@ ESESTATUS phNxpEse_Transceive(void *conn_ctx, phNxpEse_data *pCmd, phNxpEse_data + ESESTATUS phNxpEse_reset(void *conn_ctx) + { + ESESTATUS status = ESESTATUS_FAILED; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + //bool_t bStatus = phNxpEseProto7816_IntfReset(&AtrRsp); + status = phNxpEse_chipReset((void *)nxpese_ctxt); + if (status != ESESTATUS_SUCCESS) { +@@ -241,7 +225,7 @@ ESESTATUS phNxpEse_reset(void *conn_ctx) + ESESTATUS phNxpEse_EndOfApdu(void *conn_ctx) + { + ESESTATUS status = ESESTATUS_SUCCESS; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + bool_t bStatus = phNxpEseProto7816_Close((void *)nxpese_ctxt); + if (!bStatus) { + status = ESESTATUS_FAILED; +@@ -263,7 +247,7 @@ ESESTATUS phNxpEse_chipReset(void *conn_ctx) + { + ESESTATUS status = ESESTATUS_SUCCESS; + bool_t bStatus = FALSE; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + bStatus = phNxpEseProto7816_Reset(); + if (!bStatus) { + status = ESESTATUS_FAILED; +@@ -294,15 +278,11 @@ ESESTATUS phNxpEse_deInit(void *conn_ctx) + { + ESESTATUS status = ESESTATUS_SUCCESS; + //bool_t bStatus = FALSE; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; +- /*bStatus = phNxpEseProto7816_ResetProtoParams(); +- if(!bStatus) +- { +- status = ESESTATUS_FAILED; +- }*/ ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; ++ + phPalEse_i2c_close(nxpese_ctxt->pDevHandle); + phNxpEse_memset(nxpese_ctxt, 0x00, sizeof(*nxpese_ctxt)); +- //status= phNxpEse_close(); ++ + return status; + } + +@@ -320,7 +300,7 @@ ESESTATUS phNxpEse_deInit(void *conn_ctx) + ESESTATUS phNxpEse_close(void *conn_ctx) + { + ESESTATUS status = ESESTATUS_SUCCESS; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + + if ((ESE_STATUS_CLOSE == nxpese_ctxt->EseLibStatus)) { + T_SMLOG_E(" %s ESE Not Initialized previously ", __FUNCTION__); +@@ -328,7 +308,6 @@ ESESTATUS phNxpEse_close(void *conn_ctx) + } + + phPalEse_i2c_close(nxpese_ctxt->pDevHandle); +- phNxpEse_memset(nxpese_ctxt, 0x00, sizeof(*nxpese_ctxt)); + T_SMLOG_D("phNxpEse_close - ESE Context deinit completed"); + /* Return success always */ + return status; +@@ -350,12 +329,11 @@ ESESTATUS phNxpEse_close(void *conn_ctx) + void phNxpEse_clearReadBuffer(void *conn_ctx) + { + int ret = -1; +- uint8_t *readBuf = &t10i2c_tempBuf[0]; //[MAX_APDU_BUFFER]; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + + T_SMLOG_D("%s Enter ..", __FUNCTION__); + +- ret = phPalEse_i2c_read(nxpese_ctxt->pDevHandle, readBuf, sizeof(t10i2c_tempBuf)); ++ ret = phPalEse_i2c_read(nxpese_ctxt->pDevHandle, nxpese_ctxt->p_read_buff, nxpese_ctxt->read_buff_len); + if (ret < 0) { + /* Do nothing as nothing to read*/ + } +@@ -385,21 +363,15 @@ ESESTATUS phNxpEse_read(void *conn_ctx, uint32_t *data_len, uint8_t **pp_data) + ESESTATUS status = ESESTATUS_FAILED; + int ret = -1; + uint8_t rspBufLen = 0; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + + T_SMLOG_D("%s Enter ..", __FUNCTION__); + + ENSURE_OR_GO_EXIT(data_len != NULL); + ENSURE_OR_GO_EXIT(pp_data != NULL); + +- if (gRsp.p_data == NULL || gRsp.len == 0) { +- *pp_data = &t10i2c_tempBuf[0]; +- rspBufLen = sizeof(t10i2c_tempBuf); +- } +- else { +- *pp_data = gRsp.p_data; +- rspBufLen = gRsp.len; +- } ++ *pp_data = nxpese_ctxt->p_read_buff; ++ rspBufLen = nxpese_ctxt->read_buff_len; + + ret = phNxpEse_readPacket((void *)nxpese_ctxt, nxpese_ctxt->pDevHandle, *pp_data, rspBufLen); + if (ret < 0) { +@@ -417,8 +389,6 @@ ESESTATUS phNxpEse_read(void *conn_ctx, uint32_t *data_len, uint8_t **pp_data) + status = ESESTATUS_SUCCESS; + } + exit: +- gRsp.p_data = NULL; +- gRsp.len = 0; + return status; + } + +@@ -442,7 +412,7 @@ static int phNxpEse_readPacket(void *conn_ctx, void *pDevHandle, uint8_t *pBuffe + int ret = -1; + int sof_counter = 0; /* one read may take 1 ms*/ + int total_count = 0, numBytesToRead = 0, headerIndex = 0; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + + ENSURE_OR_GO_EXIT(pBuffer != NULL); + memset(pBuffer, 0, nNbBytesToRead); +@@ -578,7 +548,7 @@ ESESTATUS phNxpEse_WriteFrame(void *conn_ctx, uint32_t data_len, const uint8_t * + { + ESESTATUS status = ESESTATUS_INVALID_PARAMETER; + int32_t dwNoBytesWrRd = 0; +- phNxpEse_Context_t *nxpese_ctxt = (conn_ctx == NULL) ? &gnxpese_ctxt : (phNxpEse_Context_t *)conn_ctx; ++ phNxpEse_Context_t *nxpese_ctxt = (phNxpEse_Context_t *)conn_ctx; + + /* Create local copy of cmd_data */ + T_SMLOG_D("%s Enter ..", __FUNCTION__); +@@ -709,9 +679,6 @@ ESESTATUS phNxpEse_getAtr(void *conn_ctx, phNxpEse_data *pRsp) + { + bool_t status = FALSE; + +- gRsp.p_data = pRsp->p_data; +- gRsp.len = pRsp->len; +- + status = phNxpEseProto7816_GetAtr(conn_ctx, pRsp); + if (status == FALSE) { + T_SMLOG_E("%s Get ATR Failed ", __FUNCTION__); +@@ -736,9 +703,6 @@ ESESTATUS phNxpEse_getCip(void *conn_ctx, phNxpEse_data *pRsp) + { + bool_t status = FALSE; + +- gRsp.p_data = pRsp->p_data; +- gRsp.len = pRsp->len; +- + status = phNxpEseProto7816_GetCip(conn_ctx, pRsp); + if (status == FALSE) { + T_SMLOG_E("%s Get CIP Failed ", __FUNCTION__); +diff --git a/lib/t1oi2c/phNxpEse_Api.h b/lib/t1oi2c/phNxpEse_Api.h +index 3d5224d..688c84b 100644 +--- a/lib/t1oi2c/phNxpEse_Api.h ++++ b/lib/t1oi2c/phNxpEse_Api.h +@@ -52,7 +52,7 @@ typedef struct phNxpEse_initParams + } phNxpEse_initParams; + + ESESTATUS phNxpEse_init(void *conn_ctx, phNxpEse_initParams initParams, phNxpEse_data *AtrRsp); +-ESESTATUS phNxpEse_open(void **conn_ctx, phNxpEse_initParams initParams, const char *pConnString); ++ESESTATUS phNxpEse_open(void *conn_ctx, phNxpEse_initParams initParams, const char *pConnString); + ESESTATUS phNxpEse_Transceive(void *conn_ctx, phNxpEse_data *pCmd, phNxpEse_data *pRsp); + ESESTATUS phNxpEse_deInit(void *conn_ctx); + ESESTATUS phNxpEse_close(void *conn_ctx); +diff --git a/lib/t1oi2c/phNxpEse_Internal.h b/lib/t1oi2c/phNxpEse_Internal.h +index f20d86a..a5e8a36 100644 +--- a/lib/t1oi2c/phNxpEse_Internal.h ++++ b/lib/t1oi2c/phNxpEse_Internal.h +@@ -38,6 +38,7 @@ typedef enum + typedef struct phNxpEse_Context + { + uint8_t *p_read_buff; ++ uint8_t read_buff_len; + uint8_t cmd_len; + uint8_t *p_cmd_data; + phNxpEse_LibStatus EseLibStatus; /* Indicate if Ese Lib is open or closed */ +-- +2.25.1 + diff --git a/drivers/crypto/pnt/0003-Added-Se05x_API_ReadSize-to-API.patch b/drivers/crypto/pnt/0003-Added-Se05x_API_ReadSize-to-API.patch new file mode 100644 index 0000000000..9e4923316f --- /dev/null +++ b/drivers/crypto/pnt/0003-Added-Se05x_API_ReadSize-to-API.patch @@ -0,0 +1,196 @@ +From b88625c69a26cfc178cad2e1430d53c8f01be6b0 Mon Sep 17 00:00:00 2001 +From: Andre Heinemans +Date: Fri, 11 Nov 2022 13:20:53 +0100 +Subject: [PATCH 3/4] Added Se05x_API_ReadSize to API + +--- + lib/apdu/se05x_APDU_apis.h | 71 ++++++++++++++++++++++++++++++++++++++ + lib/apdu/se05x_APDU_impl.c | 39 +++++++++++++++++++++ + lib/apdu/se05x_tlv.c | 26 ++++++++++++++ + lib/apdu/se05x_tlv.h | 1 + + 4 files changed, 137 insertions(+) + +diff --git a/lib/apdu/se05x_APDU_apis.h b/lib/apdu/se05x_APDU_apis.h +index 38cf017..7865c93 100644 +--- a/lib/apdu/se05x_APDU_apis.h ++++ b/lib/apdu/se05x_APDU_apis.h +@@ -113,6 +113,77 @@ smStatus_t Se05x_API_WriteECKey(pSe05xSession_t session_ctx, + const SE05x_INS_t ins_type, + const SE05x_KeyPart_t key_part); + ++/** Se05x_API_ReadSize ++ * ++ * ReadSize ++ * ++ * Get the size of a Secure Object (in bytes): ++ * ++ * * For EC keys: the size of the curve is returned. ++ * ++ * * For RSA keys: the key size is returned. ++ * ++ * * For AES/DES/HMAC keys, the key size is returned. ++ * ++ * * For binary files: the file size is returned ++ * ++ * * For userIDs: nothing is returned (SW_CONDITIONS_NOT_SATISFIED). ++ * ++ * * For counters: the counter length is returned. ++ * ++ * * For PCR: the PCR length is returned. ++ * ++ * # Command to Applet ++ * ++ * @rst ++ * +-------+------------+-----------------------------+ ++ * | Field | Value | Description | ++ * +=======+============+=============================+ ++ * | CLA | 0x80 | | ++ * +-------+------------+-----------------------------+ ++ * | INS | INS_READ | See :cpp:type:`SE05x_INS_t` | ++ * +-------+------------+-----------------------------+ ++ * | P1 | P1_DEFAULT | See :cpp:type:`SE05x_P1_t` | ++ * +-------+------------+-----------------------------+ ++ * | P2 | P2_SIZE | See :cpp:type:`SE05x_P2_t` | ++ * +-------+------------+-----------------------------+ ++ * | Lc | #(Payload) | | ++ * +-------+------------+-----------------------------+ ++ * | | TLV[TAG_1] | 4-byte object identifier. | ++ * +-------+------------+-----------------------------+ ++ * | Le | 0x00 | | ++ * +-------+------------+-----------------------------+ ++ * @endrst ++ * ++ * # R-APDU Body ++ * ++ * @rst ++ * +------------+-----------------------------+ ++ * | Value | Description | ++ * +============+=============================+ ++ * | TLV[TAG_1] | Byte array containing size. | ++ * +------------+-----------------------------+ ++ * @endrst ++ * ++ * # R-APDU Trailer ++ * ++ * @rst ++ * +-------------+--------------------------------+ ++ * | SW | Description | ++ * +=============+================================+ ++ * | SW_NO_ERROR | Data is returned successfully. | ++ * +-------------+--------------------------------+ ++ * @endrst ++ * ++ * ++ * @param[in] session_ctx The session context ++ * @param[in] objectID The object id ++ * @param psize The psize ++ * ++ * @return The sm status. ++ */ ++smStatus_t Se05x_API_ReadSize(pSe05xSession_t session_ctx, uint32_t objectID, uint16_t *psize); ++ + /** Se05x_API_ReadObject + * + * Reads the content of a Secure Object. +diff --git a/lib/apdu/se05x_APDU_impl.c b/lib/apdu/se05x_APDU_impl.c +index 4acfad7..86b0d8f 100644 +--- a/lib/apdu/se05x_APDU_impl.c ++++ b/lib/apdu/se05x_APDU_impl.c +@@ -186,6 +186,45 @@ cleanup: + return retStatus; + } + ++smStatus_t Se05x_API_ReadSize(pSe05xSession_t session_ctx, uint32_t objectID, uint16_t *psize) ++{ ++ smStatus_t retStatus = SM_NOT_OK; ++ tlvHeader_t hdr = {{kSE05x_CLA, kSE05x_INS_READ, kSE05x_P1_DEFAULT, kSE05x_P2_SIZE}}; ++ size_t cmdbufLen = 0; ++ uint8_t *pCmdbuf = NULL; ++ int tlvRet = 0; ++ uint8_t *pRspbuf = NULL; ++ size_t rspbufLen = 0; ++ ++ ENSURE_OR_GO_CLEANUP(session_ctx != NULL); ++ ++ pCmdbuf = &session_ctx->apdu_buffer[0]; ++ pRspbuf = &session_ctx->apdu_buffer[0]; ++ rspbufLen = sizeof(session_ctx->apdu_buffer); ++ ++ SMLOG_D("APDU - ReadSize [] \n"); ++ ++ tlvRet = TLVSET_U32("object id", &pCmdbuf, &cmdbufLen, kSE05x_TAG_1, objectID); ++ if (0 != tlvRet) { ++ goto cleanup; ++ } ++ retStatus = DoAPDUTxRx(session_ctx, &hdr, session_ctx->apdu_buffer, cmdbufLen, pRspbuf, &rspbufLen, 1); ++ if (retStatus == SM_OK) { ++ retStatus = SM_NOT_OK; ++ size_t rspIndex = 0; ++ tlvRet = tlvGet_U16(pRspbuf, &rspIndex, rspbufLen, kSE05x_TAG_1, psize); /* - */ ++ if (0 != tlvRet) { ++ goto cleanup; ++ } ++ if ((rspIndex + 2) == rspbufLen) { ++ retStatus = (smStatus_t)((pRspbuf[rspIndex] << 8) | (pRspbuf[rspIndex + 1])); ++ } ++ } ++ ++cleanup: ++ return retStatus; ++} ++ + smStatus_t Se05x_API_ReadObject( + pSe05xSession_t session_ctx, uint32_t objectID, uint16_t offset, uint16_t length, uint8_t *data, size_t *pdataLen) + { +diff --git a/lib/apdu/se05x_tlv.c b/lib/apdu/se05x_tlv.c +index 4ed996e..71d253a 100644 +--- a/lib/apdu/se05x_tlv.c ++++ b/lib/apdu/se05x_tlv.c +@@ -252,6 +252,32 @@ cleanup: + return retVal; + } + ++int tlvGet_U16(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, uint16_t *pRsp) ++{ ++ int retVal = 1; ++ uint8_t *pBuf = buf + (*pBufIndex); ++ uint8_t got_tag = *pBuf++; ++ size_t rspLen; ++ ++ if ((*pBufIndex) > bufLen) { ++ goto cleanup; ++ } ++ ++ if (got_tag != tag) { ++ goto cleanup; ++ } ++ rspLen = *pBuf++; ++ if (rspLen > 2) { ++ goto cleanup; ++ } ++ *pRsp = (*pBuf++) << 8; ++ *pRsp |= *pBuf++; ++ *pBufIndex += (1 + 1 + (rspLen)); ++ retVal = 0; ++cleanup: ++ return retVal; ++} ++ + int tlvGet_u8buf(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, uint8_t *rsp, size_t *pRspLen) + { + int retVal = 1; +diff --git a/lib/apdu/se05x_tlv.h b/lib/apdu/se05x_tlv.h +index 2fda3e7..ea7bfdf 100644 +--- a/lib/apdu/se05x_tlv.h ++++ b/lib/apdu/se05x_tlv.h +@@ -34,6 +34,7 @@ int tlvSet_ECCurve(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, SE05x_ECCurve + int tlvSet_KeyID(uint8_t **buf, size_t *bufLen, SE05x_TAG_t tag, uint32_t keyID); + int tlvSet_header(uint8_t **buf, size_t *bufLen, tlvHeader_t *hdr); + int tlvGet_U8(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, uint8_t *pRsp); ++int tlvGet_U16(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, uint16_t *pRsp); + int tlvGet_u8buf(uint8_t *buf, size_t *pBufIndex, const size_t bufLen, SE05x_TAG_t tag, uint8_t *rsp, size_t *pRspLen); + int tlvGet_Result(uint8_t *buf, size_t *pBufIndex, size_t bufLen, SE05x_TAG_t tag, SE05x_Result_t *presult); + smStatus_t DoAPDUTx( +-- +2.25.1 + diff --git a/drivers/crypto/pnt/0004-Restored-delay-at-i2c-read-and-write-retries.patch b/drivers/crypto/pnt/0004-Restored-delay-at-i2c-read-and-write-retries.patch new file mode 100644 index 0000000000..0a86a764fb --- /dev/null +++ b/drivers/crypto/pnt/0004-Restored-delay-at-i2c-read-and-write-retries.patch @@ -0,0 +1,36 @@ +From 592b71399937c8a4b30e15c1a3ec15c8b6bb883a Mon Sep 17 00:00:00 2001 +From: Andre Heinemans +Date: Wed, 22 Feb 2023 09:34:38 +0100 +Subject: [PATCH 4/4] Restored delay at i2c read and write retries + +--- + lib/t1oi2c/phNxpEsePal_i2c.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/lib/t1oi2c/phNxpEsePal_i2c.c b/lib/t1oi2c/phNxpEsePal_i2c.c +index 8e4c6bc..4bb4301 100644 +--- a/lib/t1oi2c/phNxpEsePal_i2c.c ++++ b/lib/t1oi2c/phNxpEsePal_i2c.c +@@ -124,8 +124,7 @@ int phPalEse_i2c_read(void *pDevHandle, uint8_t *pBuffer, int nNbBytesToRead) + if ((ret == I2C_NACK_ON_ADDRESS) && (retryCount < MAX_RETRY_COUNT)) { + retryCount++; + /* 1ms delay to give ESE polling delay */ +- /*i2c driver back off delay is providing 1ms wait time so ignoring waiting time at this level*/ +- //sm_sleep(ESE_POLL_DELAY_MS); ++ sm_sleep(ESE_POLL_DELAY_MS); + T_SMLOG_D("_i2c_read() failed. Going to retry, counter:%d !", retryCount); + continue; + } +@@ -167,8 +166,7 @@ int phPalEse_i2c_write(void *pDevHandle, uint8_t *pBuffer, int nNbBytesToWrite) + if ((ret == I2C_NACK_ON_ADDRESS) && (retryCount < MAX_RETRY_COUNT)) { + retryCount++; + /* 1ms delay to give ESE polling delay */ +- /*i2c driver back off delay is providing 1ms wait time so ignoring waiting time at this level*/ +- //sm_sleep(ESE_POLL_DELAY_MS); ++ sm_sleep(ESE_POLL_DELAY_MS); + T_SMLOG_D("_i2c_write() failed. Going to retry, counter:%d !", retryCount); + continue; + } +-- +2.25.1 + diff --git a/drivers/crypto/pnt/Make.defs b/drivers/crypto/pnt/Make.defs new file mode 100644 index 0000000000..8798b65e3c --- /dev/null +++ b/drivers/crypto/pnt/Make.defs @@ -0,0 +1,77 @@ +############################################################################ +# drivers/crypto/pnt/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +PNT_GIT_COMMIT_HASH = d7323c25d967edb0ff1957459586850f447eb8c5 +PNT_DOWNLOAD_URL = https://github.com/NXPPlugNTrust/nano-package/archive/$(PNT_GIT_COMMIT_HASH).zip +PNT_WRAPPER_DIR = crypto/pnt +PNT_NANO_ZIP = $(PNT_WRAPPER_DIR)/pnt_$(PNT_GIT_COMMIT_HASH).zip +PNT_NANO_DIR = $(PNT_WRAPPER_DIR)/nano-package + +PNT_INCDIRS = \ + -I. \ + -I$(PNT_WRAPPER_DIR) \ + -I$(PNT_NANO_DIR)/lib/apdu \ + -I$(PNT_NANO_DIR)/lib/t1oi2c \ + +CSRCS += \ + $(PNT_WRAPPER_DIR)/pnt_se05x_api.c \ + $(PNT_WRAPPER_DIR)/pnt_util.c \ + $(PNT_WRAPPER_DIR)/sm_i2c.c \ + $(PNT_WRAPPER_DIR)/sm_timer.c \ + $(PNT_NANO_DIR)/lib/apdu/smCom.c \ + $(PNT_NANO_DIR)/lib/apdu/se05x_tlv.c \ + $(PNT_NANO_DIR)/lib/apdu/se05x_APDU_impl.c \ + $(PNT_NANO_DIR)/lib/t1oi2c/phNxpEse_Api.c \ + $(PNT_NANO_DIR)/lib/t1oi2c/phNxpEseProto7816_3.c \ + $(PNT_NANO_DIR)/lib/t1oi2c/phNxpEsePal_i2c.c \ + +ifeq ($(CONFIG_DEV_SE05X_SCP03),y) + PNT_INCDIRS += -I$(PNT_NANO_DIR)/lib/apdu/scp03 + CFLAGS += DWITH_PLATFORM_SCP03 + CSRCS += hcrypto.c $(PNT_NANO_DIR)/lib/apdu/scp03/se05x_scp03.c +endif + +CFLAGS += $(PNT_INCDIRS) -DT1oI2C -DT1oI2C_UM11225 -DAX_EMBEDDED=0 + +UNPACK ?= unzip -q -o + +PATCH ?= patch -p1 + +$(PNT_NANO_ZIP): + @echo "Downloading: $(PNT_DOWNLOAD_URL)" + $(Q) curl -o $(PNT_NANO_ZIP) -L $(PNT_DOWNLOAD_URL) + +$(PNT_NANO_DIR): $(PNT_NANO_ZIP) + @echo "Unpacking: $(PNT_NANO_ZIP) -> $(PNT_NANO_DIR)" + $(Q) $(UNPACK) $(PNT_NANO_ZIP) -d $(PNT_WRAPPER_DIR) + $(call DELDIR, $(PNT_NANO_DIR)) + $(Q) mv -T $(PNT_NANO_DIR)-$(PNT_GIT_COMMIT_HASH) $(PNT_NANO_DIR) + $(Q) $(foreach PATCH_FILE, $(sort $(wildcard $(PNT_WRAPPER_DIR)/*.patch)), $(PATCH) -d $(PNT_NANO_DIR) < $(PATCH_FILE);) + +context:: $(PNT_NANO_DIR) + +distclean:: + $(call DELFILE, $(PNT_NANO_ZIP)) + $(call DELDIR, $(PNT_NANO_DIR)) + +# Include crypto device driver build support + +DEPPATH += --dep-path crypto +CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)drivers$(DELIM)crypto$(DELIM)pnt} diff --git a/drivers/crypto/pnt/pnt_se05x_api.c b/drivers/crypto/pnt/pnt_se05x_api.c new file mode 100644 index 0000000000..01823e9150 --- /dev/null +++ b/drivers/crypto/pnt/pnt_se05x_api.c @@ -0,0 +1,344 @@ +/**************************************************************************** + * drivers/crypto/pnt/pnt_se05x_api.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "pnt_se05x_api.h" + +#include "../se05x_internal.h" +#include "pnt_util.h" +#include "scp03_keys.h" +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SCP03_KEY_SIZE 16 +#define DATA_CHUNK_SIZE 100 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct pnt_handle +{ + Se05xSession_t session; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const SE05x_ECSignatureAlgo_t + signature_algorithm_mapping[SE05X_ALGORITHM_SIZE] = +{ + kSE05x_ECSignatureAlgo_NA, kSE05x_ECSignatureAlgo_PLAIN, + kSE05x_ECSignatureAlgo_SHA, kSE05x_ECSignatureAlgo_SHA_224, + kSE05x_ECSignatureAlgo_SHA_256, kSE05x_ECSignatureAlgo_SHA_384, + kSE05x_ECSignatureAlgo_SHA_512 +}; + +static const uint8_t scp03_enc_key[SCP03_KEY_SIZE] = SCP03_ENC_KEY; +static const uint8_t scp03_mac_key[SCP03_KEY_SIZE] = SCP03_MAC_KEY; +static const uint8_t scp03_dek_key[SCP03_KEY_SIZE] = SCP03_DEK_KEY; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static bool set_enable_pin(FAR struct se05x_dev_s *se05x, bool state) +{ + if (se05x->config->set_enable_pin == NULL) + { + return FALSE; + } + + return se05x->config->set_enable_pin(state); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int pnt_se05x_open(FAR struct se05x_dev_s *se05x) +{ + se05x->pnt = kmm_malloc(sizeof(struct pnt_handle)); + int ret = se05x->pnt != NULL ? 0 : -EIO; + + if (ret == 0) + { + memset(&(se05x->pnt->session), 0, sizeof(Se05xSession_t)); + + se05x->pnt->session.pScp03_enc_key = (FAR uint8_t *)scp03_enc_key; + se05x->pnt->session.pScp03_mac_key = (FAR uint8_t *)scp03_mac_key; + se05x->pnt->session.pScp03_dek_key = (FAR uint8_t *)scp03_dek_key; + se05x->pnt->session.scp03_enc_key_len = SCP03_KEY_SIZE; + se05x->pnt->session.scp03_mac_key_len = SCP03_KEY_SIZE; + se05x->pnt->session.scp03_dek_key_len = SCP03_KEY_SIZE; + ret = set_enable_pin(se05x, true) ? 0 : -EIO; + } + + if (ret == 0) + { + se05x->pnt->session.skip_applet_select = 0; + se05x->pnt->session.session_resume = 0; + smStatus_t status = + Se05x_API_SessionOpen(&(se05x->pnt->session), se05x); + ret = status == SM_OK ? 0 : -EIO; + } + + /* if error */ + + if (ret < 0) + { + if (se05x->pnt->session.conn_context != NULL) + { + kmm_free(se05x->pnt->session.conn_context); + } + + if (se05x->pnt != NULL) + { + kmm_free(se05x->pnt); + } + } + + return ret; +} + +void pnt_se05x_close(FAR struct se05x_dev_s *se05x) +{ + Se05x_API_SessionClose(&(se05x->pnt->session)); + (void)set_enable_pin(se05x, FALSE); + kmm_free(se05x->pnt); +} + +int pnt_se05x_get_info(FAR struct se05x_dev_s *se05x, + FAR struct se05x_info_s *se05x_info) +{ + bool result = select_card_manager(&(se05x->pnt->session)); + identify_rsp_t identify_response; + if (result) + { + result = se05x_identify(&(se05x->pnt->session), &identify_response); + } + + if (result) + { + se05x_info->oef_id = (identify_response.configuration_id[2] << 8) + + identify_response.configuration_id[3]; + } + + return result ? 0 : -EIO; +} + +int pnt_se05x_get_uid(FAR struct se05x_dev_s *se05x, + FAR struct se05x_uid_s *uid) +{ + SE05x_Result_t dummy = kSE05x_Result_NA; + size_t uid_size = SE050_MODULE_UNIQUE_ID_LEN; + + smStatus_t status = Se05x_API_CheckObjectExists( + &(se05x->pnt->session), KSE05X_APPLETRESID_UNIQUE_ID, &dummy); + int result = status == SM_OK ? 0 : -ENODATA; + if (result == 0) + { + status = Se05x_API_ReadObject(&(se05x->pnt->session), + KSE05X_APPLETRESID_UNIQUE_ID, 0, + (uint16_t)uid_size, uid->uid, &uid_size); + result = status == SM_OK ? 0 : -EIO; + } + + return result; +} + +int pnt_se05x_generate_keypair( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_generate_keypair_s *generate_keypair_args) +{ + smStatus_t status = Se05x_API_WriteECKey( + &(se05x->pnt->session), NULL, 0, generate_keypair_args->id, + kSE05x_ECCurve_NIST_P256, NULL, 0, NULL, 0, kSE05x_INS_NA, + kSE05x_KeyPart_Pair); + return status == SM_OK ? 0 : -EIO; +} + +int pnt_se05x_set_public_key( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_key_transmission_s *set_publickey_args) +{ + smStatus_t status = Se05x_API_WriteECKey( + &(se05x->pnt->session), NULL, 0, set_publickey_args->entry.id, + kSE05x_ECCurve_NIST_P256, NULL, 0, set_publickey_args->content.buffer, + set_publickey_args->content.buffer_size, kSE05x_INS_NA, + kSE05x_KeyPart_Public); + return status == SM_OK ? 0 : -EIO; +} + +int pnt_se05x_set_data( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_key_transmission_s *set_publickey_args) +{ + size_t remainder = set_publickey_args->content.buffer_size; + smStatus_t status = SM_OK; + uint16_t offset = 0; + bool first_cycle = TRUE; + + while ((remainder > 0) && (status == SM_OK)) + { + size_t chunk_size = + remainder > DATA_CHUNK_SIZE ? DATA_CHUNK_SIZE : remainder; + status = Se05x_API_WriteBinary( + &(se05x->pnt->session), NULL, set_publickey_args->entry.id, offset, + first_cycle ? set_publickey_args->content.buffer_size : 0, + set_publickey_args->content.buffer + offset, chunk_size); + remainder -= chunk_size; + offset += chunk_size; + first_cycle = FALSE; + } + + return status == SM_OK ? 0 : -EIO; +} + +int pnt_se05x_get_key(FAR struct se05x_dev_s *se05x, + FAR struct se05x_key_transmission_s *get_key_args) +{ + get_key_args->content.buffer_content_size = + get_key_args->content.buffer_size; + smStatus_t status = + Se05x_API_ReadObject(&(se05x->pnt->session), get_key_args->entry.id, 0, + 0, get_key_args->content.buffer, + &get_key_args->content.buffer_content_size); + return status == SM_OK ? 0 : -EIO; +} + +int pnt_se05x_get_data(FAR struct se05x_dev_s *se05x, + FAR struct se05x_key_transmission_s *get_key_args) +{ + uint16_t remainder; + smStatus_t status = Se05x_API_ReadSize(&(se05x->pnt->session), + get_key_args->entry.id, &remainder); + + if (remainder > get_key_args->content.buffer_size) + { + status = SM_NOT_OK; + } + + uint16_t offset = 0; + + while ((remainder > 0) && (status == SM_OK)) + { + size_t chunk_size = + remainder > DATA_CHUNK_SIZE ? DATA_CHUNK_SIZE : remainder; + status = Se05x_API_ReadObject( + &(se05x->pnt->session), get_key_args->entry.id, offset, chunk_size, + get_key_args->content.buffer + offset, &chunk_size); + remainder -= chunk_size; + offset += chunk_size; + } + + get_key_args->content.buffer_content_size = offset; + return status == SM_OK ? 0 : -EIO; +} + +int pnt_se05x_delete_key(FAR struct se05x_dev_s *se05x, uint32_t key_id) +{ + smStatus_t status = + Se05x_API_DeleteSecureObject(&(se05x->pnt->session), key_id); + return status == SM_OK ? 0 : -EIO; +} + +int pnt_se05x_derive_key(FAR struct se05x_dev_s *se05x, + FAR struct se05x_derive_key_s *derive_key_args) +{ + uint8_t public_key[65]; + size_t public_key_size = sizeof(public_key); + smStatus_t status = Se05x_API_ReadObject(&(se05x->pnt->session), + derive_key_args->public_key_id, 0, + 0, public_key, &public_key_size); + + if (status == SM_OK) + { + derive_key_args->content.buffer_content_size = + derive_key_args->content.buffer_size; + status = Se05x_API_ECDHGenerateSharedSecret( + &(se05x->pnt->session), derive_key_args->private_key_id, + public_key, public_key_size, derive_key_args->content.buffer, + &derive_key_args->content.buffer_content_size); + } + + return status == SM_OK ? 0 : -EIO; +} + +int pnt_se05x_create_signature( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_signature_s *create_signature_args) +{ + create_signature_args->signature.buffer_content_size = + create_signature_args->signature.buffer_size; + int result = + Se05x_API_ECDSASign( + &(se05x->pnt->session), create_signature_args->key_id, + signature_algorithm_mapping[create_signature_args->algorithm], + create_signature_args->tbs.buffer, + create_signature_args->tbs.buffer_content_size, + create_signature_args->signature.buffer, + &create_signature_args->signature.buffer_content_size) == SM_OK + ? 0 + : -EIO; + + return result; +} + +int pnt_se05x_verify_signature( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_signature_s *verify_signature_args) +{ + SE05x_Result_t se05x_result; + int result = + Se05x_API_ECDSAVerify( + &(se05x->pnt->session), verify_signature_args->key_id, + signature_algorithm_mapping[verify_signature_args->algorithm], + verify_signature_args->tbs.buffer, + verify_signature_args->tbs.buffer_content_size, + verify_signature_args->signature.buffer, + verify_signature_args->signature.buffer_content_size, + &se05x_result) == SM_OK + ? 0 + : -EACCES; + + if ((result == 0) && (se05x_result != kSE05x_Result_SUCCESS)) + { + result = -EIO; + } + + return result; +} diff --git a/drivers/crypto/pnt/pnt_se05x_api.h b/drivers/crypto/pnt/pnt_se05x_api.h new file mode 100644 index 0000000000..b3e8d40450 --- /dev/null +++ b/drivers/crypto/pnt/pnt_se05x_api.h @@ -0,0 +1,299 @@ +/**************************************************************************** + * drivers/crypto/pnt/pnt_se05x_api.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +#ifndef __INCLUDE_NUTTX_CRYPTO_PNT_PNT_API_H_ +#define __INCLUDE_NUTTX_CRYPTO_PNT_PNT_API_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct se05x_dev_s; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int pnt_se05x_open(FAR struct se05x_dev_s *se05x); +void pnt_se05x_close(FAR struct se05x_dev_s *se05x); + +/**************************************************************************** + * Name: pnt_se05x_get_info + * + * Description: + * Get information on the variant of the SE05x + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * se05x_info - Ptr to storage of retrieved SE050 info. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_get_info(FAR struct se05x_dev_s *se05x, + FAR struct se05x_info_s *se05x_info); + +/**************************************************************************** + * Name: pnt_se05x_get_uid + * + * Description: + * Get the unique id of the SE05x + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * se05x_uid - Ptr to storage for the unique id + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_get_uid(FAR struct se05x_dev_s *se05x, + FAR struct se05x_uid_s *uid); + +/**************************************************************************** + * Name: pnt_se05x_generate_keypair + * + * Description: + * Generate a private/public keypair. + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * generate_keypair_args - Ptr to arguments needed to generate keypair + * (input) + * ->id id where to store key + * ->cipher cipher type + * (defaults to se05x_asym_cipher_EC_NIST_P_256) + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_generate_keypair( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_generate_keypair_s *generate_keypair_args); + +/**************************************************************************** + * Name: pnt_se05x_set_public_key + * + * Description: + * Store key into keystore. Key must be in raw format + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * set_publickey_args - Ptr to arguments needed to set public key + * (input) + * ->entry.id id where to store key + * ->entry.cipher cipher type + * (defaults to se05x_asym_cipher_EC_NIST_P_256) + * ->content assign with public key + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_set_public_key( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_key_transmission_s *set_publickey_args); + +/**************************************************************************** + * Name: pnt_se05x_set_data + * + * Description: + * Store data into keystore. + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * set_publickey_args - Ptr to arguments needed to set data + * (input) + * ->entry.id id where to store key + * ->entry.cipher (not used) + * ->content assign with data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_set_data( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_key_transmission_s *set_publickey_args); + +/**************************************************************************** + * Name: pnt_se05x_get_key + * + * Description: + * Get the key from keystore. Key is returned in raw format + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * get_publickey_args - Ptr to arguments needed to get public key + * (input) + * ->entry.id id where to get key + * (output) + * ->entry.type key type + * ->content public key will be copied into + * buffer. Must be allocated! + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_get_key( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_key_transmission_s *get_publickey_args); + +/**************************************************************************** + * Name: pnt_se05x_get_data + * + * Description: + * Get data from keystore. The returned data is raw data + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * get_data_args - Ptr to arguments needed to get public key + * (input) + * ->entry.id id where to get key + * (output) + * ->entry.type key type + * ->content data will be copied into + * buffer. Must be allocated! + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_get_data(FAR struct se05x_dev_s *se05x, + FAR struct se05x_key_transmission_s *get_data_args); + +/**************************************************************************** + * Name: pnt_se05x_delete_key + * + * Description: + * Delete key from keystore + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * key_id - key ID + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_delete_key(FAR struct se05x_dev_s *se05x, uint32_t key_id); + +/**************************************************************************** + * Name: pnt_se05x_derive_key + * + * Description: + * Derive a symmetric key using a private key of an owned keypair and + * a public key that is received from the peer. + * Currently only keys derived from ecdsa keys are supported + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * derive_key_args - Ptr to arguments needed to derive symmetric key + * (input) + * ->private_key_id id of entry in keystore to get private key + * This entry may be a keypair + * ->public_key_id id of entry in keystore to get public key + * (output) + * ->content symmetric key will be copied into + * buffer. Must be allocated! (>= 32 bytes) + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_derive_key(FAR struct se05x_dev_s *se05x, + FAR struct se05x_derive_key_s *derive_key_args); + +/**************************************************************************** + * Name: pnt_se05x_create_signature + * + * Description: + * Create a signature, using a hash value and a private key. + * To create the signature the hash value is encrypted using the private + *key. + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * create_signature_args - Ptr to arguments needed to create signature + * (input) + * ->key_id id where to get private key + * ->algorithm hash algorithm + * ->tbs digest + * (output) + * ->signature the generated signature. Must be allocated! + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_create_signature( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_signature_s *create_signature_args); + +/**************************************************************************** + * Name: pnt_se05x_verify_signature + * + * Description: + * Verify a signature, using a hash value, a signature and a public key. + * To verify the signature, the provided signature is decrypted using the + * public key. The results in the original hash value which should be the + * same as the provided hash value. + * + * Input Parameters: + * se05x - Ptr to se05x device struct + * verify_signature_args - Ptr to arguments needed to create signature + * (input) + * ->key_id id where to get public key + * ->algorithm hash algorithm + * ->tbs digest + * ->signature the signature + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int pnt_se05x_verify_signature( + FAR struct se05x_dev_s *se05x, + FAR struct se05x_signature_s *verify_signature_args); + +#endif /* __INCLUDE_NUTTX_CRYPTO_PNT_PNT_API_H_ */ diff --git a/drivers/crypto/pnt/pnt_util.c b/drivers/crypto/pnt/pnt_util.c new file mode 100644 index 0000000000..4468497e81 --- /dev/null +++ b/drivers/crypto/pnt/pnt_util.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * drivers/crypto/pnt/pnt_util.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "pnt_util.h" +#include "smCom.h" +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static smStatus_t t1oi2c_transceive(pSe05xSession_t session_ctx, + FAR uint8_t *tx, size_t tx_len, + FAR uint8_t *rx, size_t *rx_len) +{ + memcpy(session_ctx->apdu_buffer, tx, tx_len); + smStatus_t status = smComT1oI2C_TransceiveRaw( + session_ctx->conn_context, session_ctx->apdu_buffer, tx_len, + session_ctx->apdu_buffer, rx_len); + + memcpy(rx, session_ctx->apdu_buffer, *rx_len); + return status; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +bool select_card_manager(pSe05xSession_t session_ctx) +{ + uint8_t tx_buf[5]; + + tx_buf[0] = CLA_ISO7816; + tx_buf[1] = INS_GP_SELECT; + tx_buf[2] = 4; + tx_buf[3] = 0; + tx_buf[4] = 0; + + uint8_t response_data[50]; + size_t response_data_size = sizeof(response_data); + smStatus_t status = t1oi2c_transceive(session_ctx, tx_buf, sizeof(tx_buf), + response_data, &response_data_size); + if (status == SM_OK && response_data_size >= 2) + { + uint16_t rv = response_data[response_data_size - 2]; + rv <<= 8; + rv |= response_data[response_data_size - 1]; + status = rv; + } + + return status == SM_OK; +} + +bool se05x_identify(pSe05xSession_t session_ctx, + FAR identify_rsp_t *identify_response) +{ + const uint8_t cmd[] = { + CLA_GP_7816, /* CLA '80' / '00' GlobalPlatform / ISO / IEC */ + INS_GP_GET_DATA, /* INS 'CA' GET DATA(IDENTIFY) */ + 0x00, /* P1 '00' High order tag value */ + 0xfe, /* P2 'FE' Low order tag value - proprietary data */ + 0x02, /* Lc '02' Length of data field */ + 0xdf, + 0x28, /* Data 'DF28' Card identification data */ + 0x00 /* Le '00' Length of response data */ + }; + + size_t identify_response_size = sizeof(identify_rsp_t); + smStatus_t status = t1oi2c_transceive( + session_ctx, (FAR uint8_t *)cmd, sizeof(cmd), + (FAR uint8_t *)identify_response, &identify_response_size); + + return (status == SM_OK) && + (identify_response_size == sizeof(identify_rsp_t)); +} diff --git a/drivers/crypto/pnt/pnt_util.h b/drivers/crypto/pnt/pnt_util.h new file mode 100644 index 0000000000..6ea74ca72e --- /dev/null +++ b/drivers/crypto/pnt/pnt_util.h @@ -0,0 +1,84 @@ +/**************************************************************************** + * drivers/crypto/pnt/pnt_util.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +#ifndef __INCLUDE_NUTTX_CRYPTO_PNT_PNT_UTIL_H_ +#define __INCLUDE_NUTTX_CRYPTO_PNT_PNT_UTIL_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "se05x_types.h" +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SE050_MODULE_UNIQUE_ID_LEN 18 +#define KSE05X_APPLETRESID_UNIQUE_ID 0x7fff0206 +#define CLA_ISO7816 (0x00) /* ISO7816-4 defined CLA byte */ +#define CLA_GP_7816 (0x80) /* GP 7816-4 defined CLA byte */ +#define INS_GP_SELECT (0xa4) /* Global platform defined instruction */ +#define INS_GP_GET_DATA (0xcA) /* Global platform defined instruction */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef struct +{ + uint8_t tag_value_proprietary_data; + uint8_t length_of_following_data; + uint8_t tag_card_identification_data[0x02]; + uint8_t length_of_card_identification_data; + uint8_t tag_configuration_id; + uint8_t length_configuration_id; + uint8_t configuration_id[0x0c]; + uint8_t tag_patch_id; + uint8_t length_patch_id; + uint8_t patch_id[0x08]; + uint8_t tag_platform_build_id1; + uint8_t length_platform_build_id; + uint8_t platform_build_id[0x18]; + uint8_t tag_fips_mode; + uint8_t length_fips_mode; + uint8_t fips_mode; + uint8_t tag_pre_perso_state; + uint8_t length_pre_perso_state; + uint8_t bitmask_of_pre_perso_state; + uint8_t tag_rom_id; + uint8_t length_rom_id; + uint8_t rom_id[0x08]; + uint8_t status_word_sw_[0x02]; +} identify_rsp_t; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +bool select_card_manager(pSe05xSession_t session_ctx); +bool se05x_identify(pSe05xSession_t session_ctx, + FAR identify_rsp_t *response); + +#endif /* __INCLUDE_NUTTX_CRYPTO_PNT_PNT_UTIL_H_ */ diff --git a/drivers/crypto/pnt/scp03_keys.h b/drivers/crypto/pnt/scp03_keys.h new file mode 100644 index 0000000000..0466a5eb06 --- /dev/null +++ b/drivers/crypto/pnt/scp03_keys.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * drivers/crypto/pnt/scp03_keys.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +#ifndef __INCLUDE_NUTTX_CRYPTO_PNT_SCP03_KEYS_H_ +#define __INCLUDE_NUTTX_CRYPTO_PNT_SCP03_KEYS_H_ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SCP03_ENC_KEY \ + {0xbd, 0x1d, 0xe2, 0x0a, 0x81, 0xea, 0xb2, 0xbf, \ + 0x3b, 0x70, 0x9a, 0x9d, 0x69, 0xa3, 0x12, 0x54}; +#define SCP03_MAC_KEY \ + {0x9a, 0x76, 0x1b, 0x8d, 0xba, 0x6b, 0xed, 0xf2, \ + 0x27, 0x41, 0xe4, 0x5d, 0x8d, 0x42, 0x36, 0xf5}; +#define SCP03_DEK_KEY \ + {0x9b, 0x99, 0x3b, 0x60, 0x0f, 0x1c, 0x64, 0xf5, \ + 0xad, 0xc0, 0x63, 0x19, 0x2a, 0x96, 0xc9, 0x47}; + +#endif /* __INCLUDE_NUTTX_CRYPTO_PNT_SCP03_KEYS_H_ */ diff --git a/drivers/crypto/pnt/sm_i2c.c b/drivers/crypto/pnt/sm_i2c.c new file mode 100644 index 0000000000..775ae6c890 --- /dev/null +++ b/drivers/crypto/pnt/sm_i2c.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * drivers/crypto/pnt/sm_i2c.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "sm_i2c.h" +#include "../se05x_internal.h" +#include +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int se05x_i2c_write(FAR struct se05x_dev_s *priv, + FAR const uint8_t *buffer, ssize_t buflen) +{ + struct i2c_msg_s msg; + int ret; + + /* Setup for the transfer */ + + msg.frequency = priv->config->frequency; + msg.addr = priv->config->address; + msg.flags = 0; + msg.buffer = (FAR uint8_t *)buffer; /* Override const */ + msg.length = buflen; + + /* Then perform the transfer. */ + + ret = I2C_TRANSFER(priv->i2c, &msg, 1); + return (ret >= 0) ? OK : ret; +} + +static int se05x_i2c_read(FAR struct se05x_dev_s *priv, FAR uint8_t *buffer, + ssize_t buflen) +{ + struct i2c_msg_s msg; + int ret; + + /* Setup for the transfer */ + + msg.frequency = priv->config->frequency; + msg.addr = priv->config->address; + msg.flags = I2C_M_READ; + msg.buffer = buffer; + msg.length = buflen; + + /* Then perform the transfer. */ + + ret = I2C_TRANSFER(priv->i2c, &msg, 1); + return (ret >= 0) ? OK : ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: axI2CInit + * + * Description: + * Initialize i2c (plug and trust mw hook) + * pDevName should contain the private device struct + * + ****************************************************************************/ + +unsigned int sm_i2c_init(FAR void **conn_ctx, FAR const char *dev_name) +{ + *conn_ctx = (FAR void *)dev_name; + return I2C_OK; +} + +void sm_i2c_term(FAR void *conn_ctx, int mode) +{ + (void)conn_ctx; + (void)mode; +} + +unsigned int sm_i2c_write(FAR void *conn_ctx, unsigned char bus, + unsigned char addr, FAR unsigned char *tx, + unsigned short tx_len) +{ + (void)bus; + int result = se05x_i2c_write(conn_ctx, tx, (ssize_t)tx_len); + return result == OK ? I2C_OK : I2C_FAILED; +} + +unsigned int sm_i2c_read(FAR void *conn_ctx, uint8_t bus, uint8_t addr, + FAR uint8_t *rx, unsigned short rx_len) +{ + (void)bus; + int result = se05x_i2c_read(conn_ctx, rx, (ssize_t)rx_len); + return result == OK ? I2C_OK : I2C_FAILED; +} diff --git a/drivers/crypto/pnt/sm_i2c.h b/drivers/crypto/pnt/sm_i2c.h new file mode 100644 index 0000000000..3566f0f32a --- /dev/null +++ b/drivers/crypto/pnt/sm_i2c.h @@ -0,0 +1,76 @@ +/**************************************************************************** + * drivers/crypto/pnt/sm_i2c.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +#ifndef __INCLUDE_NUTTX_CRYPTO_PNT_SM_I2C_H_ +#define __INCLUDE_NUTTX_CRYPTO_PNT_SM_I2C_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "se05x_types.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define axI2CInit sm_i2c_init +#define axI2CTerm sm_i2c_term +#define axI2CWrite sm_i2c_write +#define axI2CRead sm_i2c_read + +#define I2C_IDLE 0 +#define I2C_STARTED 1 +#define I2C_RESTARTED 2 +#define I2C_REPEATED_START 3 +#define DATA_ACK 4 +#define DATA_NACK 5 +#define I2C_BUSY 6 +#define I2C_NO_DATA 7 +#define I2C_NACK_ON_ADDRESS 8 +#define I2C_NACK_ON_DATA 9 +#define I2C_ARBITRATION_LOST 10 +#define I2C_TIME_OUT 11 +#define I2C_OK 12 +#define I2C_FAILED 13 +#define I2C_BUS_0 (0) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef unsigned int i2c_error_t; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +i2c_error_t sm_i2c_init(FAR void **conn_ctx, FAR const char *dev_name); +void sm_i2c_term(FAR void *conn_ctx, int mode); +i2c_error_t sm_i2c_write(FAR void *conn_ctx, unsigned char bus, + unsigned char addr, FAR unsigned char *tx, + unsigned short tx_len); +i2c_error_t sm_i2c_read(FAR void *conn_ctx, unsigned char bus, + unsigned char addr, FAR unsigned char *rx, + unsigned short rx_len); + +#endif /* __INCLUDE_NUTTX_CRYPTO_PNT_SM_I2C_H_ */ diff --git a/drivers/crypto/pnt/sm_port.h b/drivers/crypto/pnt/sm_port.h new file mode 100644 index 0000000000..54970ff911 --- /dev/null +++ b/drivers/crypto/pnt/sm_port.h @@ -0,0 +1,103 @@ +/**************************************************************************** + * drivers/crypto/pnt/sm_port.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +#ifndef __INCLUDE_NUTTX_CRYPTO_PNT_SM_PORT_H_ +#define __INCLUDE_NUTTX_CRYPTO_PNT_SM_PORT_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_SE05X_LOG_ERROR +#define SE05X_LOG_LEVEL LOG_ERR +#elif defined(CONFIG_SE05X_LOG_WARNING) +#define SE05X_LOG_LEVEL LOG_WARNING +#elif defined(CONFIG_SE05X_LOG_INFO) +#define SE05X_LOG_LEVEL LOG_INFO +#elif defined(CONFIG_SE05X_LOG_DEBUG) +#define SE05X_LOG_LEVEL LOG_DEBUG +#else +#define SE05X_LOG_LEVEL LOG_EMERG +#endif + +#if SE05X_LOG_LEVEL >= LOG_ERR +#define SMLOG_E(...) syslog(LOG_ERR, __VA_ARGS__); +#else +#define SMLOG_E(...) +#endif + +#if SE05X_LOG_LEVEL >= LOG_WARNING +#define SMLOG_W(...) syslog(LOG_WARNING, __VA_ARGS__); +#else +#define SMLOG_W(...) +#endif + +#if SE05X_LOG_LEVEL >= LOG_INFO +#define SMLOG_I(...) syslog(LOG_INFO, __VA_ARGS__); +#else +#define SMLOG_I(...) +#endif + +#if SE05X_LOG_LEVEL >= LOG_DEBUG +#define SMLOG_D(...) syslog(LOG_DEBUG, __VA_ARGS__); +#define SMLOG_AU8_D(BUF, LEN) \ + syslog(LOG_DEBUG, " :"); \ + for (size_t bufIndex = 0; bufIndex < LEN; bufIndex++) \ + { \ + syslog(LOG_DEBUG, "%02x", BUF[bufIndex]); \ + } \ + syslog(LOG_DEBUG, "\n") +#define SMLOG_MAU8_D(MSG, BUF, LEN) \ + syslog(LOG_DEBUG, MSG); \ + syslog(LOG_DEBUG, " :"); \ + for (size_t bufIndex = 0; bufIndex < LEN; bufIndex++) \ + { \ + syslog(LOG_DEBUG, "%02x", BUF[bufIndex]); \ + } \ + syslog(LOG_DEBUG, "\n") +#else +#define SMLOG_D(...) +#define SMLOG_AU8_D(BUF, LEN) +#define SMLOG_MAU8_D(MSG, BUF, LEN) +#endif + +#define sm_malloc kmm_malloc +#define sm_free kmm_free + +#define SM_MUTEX_DEFINE(x) +#define SM_MUTEX_INIT(x) +#define SM_MUTEX_DEINIT(x) +#define SM_MUTEX_LOCK(x) +#define SM_MUTEX_UNLOCK(x) + +#endif /* __INCLUDE_NUTTX_CRYPTO_PNT_SM_PORT_H_ */ diff --git a/drivers/crypto/pnt/sm_timer.c b/drivers/crypto/pnt/sm_timer.c new file mode 100644 index 0000000000..9d64497c05 --- /dev/null +++ b/drivers/crypto/pnt/sm_timer.c @@ -0,0 +1,36 @@ +/**************************************************************************** + * drivers/crypto/pnt/sm_timer.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void sm_sleep(uint32_t msec) +{ + usleep(1000 * msec); +} diff --git a/drivers/crypto/pnt/sm_timer.h b/drivers/crypto/pnt/sm_timer.h new file mode 100644 index 0000000000..e30d8bf1ea --- /dev/null +++ b/drivers/crypto/pnt/sm_timer.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * drivers/crypto/pnt/sm_timer.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +#ifndef __INCLUDE_NUTTX_CRYPTO_PNT_SM_TIMER_H_ +#define __INCLUDE_NUTTX_CRYPTO_PNT_SM_TIMER_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void sm_sleep(uint32_t msec); + +#endif /* __INCLUDE_NUTTX_CRYPTO_PNT_SM_TIMER_H_ */ diff --git a/drivers/crypto/se05x.c b/drivers/crypto/se05x.c new file mode 100644 index 0000000000..f41b0a5fb6 --- /dev/null +++ b/drivers/crypto/se05x.c @@ -0,0 +1,266 @@ +/**************************************************************************** + * drivers/crypto/se05x.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "pnt/pnt_se05x_api.h" +#include "se05x_internal.h" +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_CRYPTO_CONTROLSE +#warning Controlse is not available; This is probably not what you want. +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Character driver methods */ + +static int se05x_open(FAR struct file *filep); +static int se05x_close(FAR struct file *filep); +static ssize_t se05x_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t se05x_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int se05x_ioctl(FAR struct file *filep, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const FAR struct file_operations g_fops = +{ + se05x_open, se05x_close, se05x_read, se05x_write, + NULL, se05x_ioctl, NULL +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int se05x_open(FAR struct file *filep) +{ + /* create se05x session */ + + FAR struct inode *inode = filep->f_inode; + FAR struct se05x_dev_s *priv = inode->i_private; + nxmutex_lock(&priv->mutex); + int res = pnt_se05x_open(priv) == 0 ? OK : ERROR; + if (res == ERROR) + { + nxmutex_unlock(&priv->mutex); + } + + return res; +} + +static int se05x_close(FAR struct file *filep) +{ + /* stop se05x session */ + + FAR struct inode *inode = filep->f_inode; + FAR struct se05x_dev_s *priv = inode->i_private; + pnt_se05x_close(priv); + nxmutex_unlock(&priv->mutex); + return OK; +} + +static ssize_t se05x_read(FAR struct file *filep, char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +static ssize_t se05x_write(FAR struct file *filep, const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +static int se05x_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct se05x_dev_s *priv = inode->i_private; + int ret = -ENOTTY; + + switch (cmd) + { + case SEIOC_GET_INFO: + { + FAR struct se05x_info_s *info = (FAR struct se05x_info_s *)arg; + ret = pnt_se05x_get_info(priv, info); + } + break; + + case SEIOC_GET_UID: + { + FAR struct se05x_uid_s *uid = (FAR struct se05x_uid_s *)arg; + ret = pnt_se05x_get_uid(priv, uid); + } + break; + + case SEIOC_GENERATE_KEYPAIR: + { + FAR struct se05x_generate_keypair_s *generate_keypair_args = + (FAR struct se05x_generate_keypair_s *)arg; + ret = pnt_se05x_generate_keypair(priv, generate_keypair_args); + } + break; + + case SEIOC_SET_KEY: + { + FAR struct se05x_key_transmission_s *set_key_args = + (FAR struct se05x_key_transmission_s *)arg; + ret = pnt_se05x_set_public_key(priv, set_key_args); + } + break; + + case SEIOC_SET_DATA: + { + FAR struct se05x_key_transmission_s *set_key_args = + (FAR struct se05x_key_transmission_s *)arg; + ret = pnt_se05x_set_data(priv, set_key_args); + } + break; + + case SEIOC_GET_KEY: + { + FAR struct se05x_key_transmission_s *get_key_args = + (FAR struct se05x_key_transmission_s *)arg; + ret = pnt_se05x_get_key(priv, get_key_args); + } + break; + + case SEIOC_GET_DATA: + { + FAR struct se05x_key_transmission_s *get_data_args = + (FAR struct se05x_key_transmission_s *)arg; + ret = pnt_se05x_get_data(priv, get_data_args); + } + break; + + case SEIOC_DELETE_KEY: + { + ret = pnt_se05x_delete_key(priv, arg); + } + break; + + case SEIOC_DERIVE_SYMM_KEY: + { + FAR struct se05x_derive_key_s *derive_key_args = + (FAR struct se05x_derive_key_s *)arg; + ret = pnt_se05x_derive_key(priv, derive_key_args); + } + break; + + case SEIOC_CREATE_SIGNATURE: + { + FAR struct se05x_signature_s *create_signature_args = + (FAR struct se05x_signature_s *)arg; + ret = pnt_se05x_create_signature(priv, create_signature_args); + } + break; + + case SEIOC_VERIFY_SIGNATURE: + { + FAR struct se05x_signature_s *verify_signature_args = + (FAR struct se05x_signature_s *)arg; + ret = pnt_se05x_verify_signature(priv, verify_signature_args); + } + break; + + default: + crypterr("ERROR: Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int se05x_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + FAR struct se05x_config_s *config) +{ + int ret; + + FAR struct se05x_dev_s *priv; + + /* Sanity check */ + + DEBUGASSERT(devpath != NULL); + DEBUGASSERT(i2c != NULL); + + /* Initialize the device's structure */ + + priv = (FAR struct se05x_dev_s *)kmm_malloc(sizeof(*priv)); + if (priv == NULL) + { + crypterr("ERROR: Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->config = config; + priv->i2c = i2c; + + /* Check se05x availability */ + + pnt_se05x_open(priv); + struct se05x_uid_s uid; + ret = pnt_se05x_get_uid(priv, &uid); + if (ret < 0) + { + crypterr("ERROR: Failed to register driver: %d\n", ret); + kmm_free(priv); + return -ENODEV; + } + + pnt_se05x_close(priv); + + /* Register driver */ + + ret = register_driver(devpath, &g_fops, 0666, priv); + if (ret < 0) + { + crypterr("ERROR: Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + nxmutex_init(&priv->mutex); + + return ret; +} diff --git a/drivers/crypto/se05x_internal.h b/drivers/crypto/se05x_internal.h new file mode 100644 index 0000000000..7b3ac184de --- /dev/null +++ b/drivers/crypto/se05x_internal.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * drivers/crypto/se05x_internal.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +#ifndef __INCLUDE_NUTTX_DRIVERS_CRYPTO_SE05X_INTERNAL_H_ +#define __INCLUDE_NUTTX_DRIVERS_CRYPTO_SE05X_INTERNAL_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct i2c_master_s; +struct pnt_handle; +struct se05x_config_s; + +struct se05x_dev_s +{ + FAR struct se05x_config_s *config; + FAR struct i2c_master_s *i2c; /* I2C interface */ + FAR struct pnt_handle *pnt; + mutex_t mutex; +}; + +#endif /* __INCLUDE_NUTTX_DRIVERS_CRYPTO_SE05X_INTERNAL_H_ */ diff --git a/include/nuttx/crypto/se05x.h b/include/nuttx/crypto/se05x.h new file mode 100644 index 0000000000..9b82a38341 --- /dev/null +++ b/include/nuttx/crypto/se05x.h @@ -0,0 +1,164 @@ +/**************************************************************************** + * include/nuttx/crypto/se05x.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Copyright 2023 NXP */ + +#ifndef __INCLUDE_NUTTX_CRYPTO_SE05X_H_ +#define __INCLUDE_NUTTX_CRYPTO_SE05X_H_ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include + +#ifdef CONFIG_DEV_SE05X + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SE05X_MODULE_UNIQUE_ID_LEN 18 + +#define SEIOC_GET_INFO _SEIOC(0x0000) /* Arg: se05x_info_s */ +#define SEIOC_GET_UID _SEIOC(0x0001) /* Arg: se05x_uid_s */ +#define SEIOC_GENERATE_KEYPAIR _SEIOC(0x0002) +/* Arg: se05x_key_store_entry_t */ +#define SEIOC_SET_KEY _SEIOC(0x0003) /* Arg: se05x_key_transmission_s */ +#define SEIOC_SET_DATA _SEIOC(0x0004) /* Arg: se05x_key_transmission_s */ +#define SEIOC_GET_KEY _SEIOC(0x0005) /* Arg: se05x_key_transmission_s */ +#define SEIOC_GET_DATA _SEIOC(0x0006) /* Arg: se05x_key_transmission_s */ +#define SEIOC_DELETE_KEY _SEIOC(0x0007) /* Arg: uint32_t key_id */ +#define SEIOC_CREATE_SIGNATURE _SEIOC(0x0008) /* Arg: se05x_signature_s */ +#define SEIOC_VERIFY_SIGNATURE _SEIOC(0x0009) /* Arg: se05x_signature_s */ +#define SEIOC_DERIVE_SYMM_KEY _SEIOC(0x000A) /* Arg: se05x_derive_key_s */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef enum +{ + SE05X_ASYM_CIPHER_EC_NIST_P_256 = 0, +} se05x_asym_cipher_type_e; + +typedef enum +{ + SE05X_ALGORITHM_NA = 0, + SE05X_ALGORITHM_PLAIN, + SE05X_ALGORITHM_SHA, + SE05X_ALGORITHM_SHA224, + SE05X_ALGORITHM_SHA256, + SE05X_ALGORITHM_SHA384, + SE05X_ALGORITHM_SHA512, + SE05X_ALGORITHM_SIZE, +} se05x_algorithm_e; + +struct se05x_info_s +{ + uint16_t oef_id; +}; + +struct se05x_uid_s +{ + uint8_t uid[SE05X_MODULE_UNIQUE_ID_LEN]; +}; + +struct se05x_generate_keypair_s +{ + uint32_t id; + se05x_asym_cipher_type_e cipher; +}; + +struct se05x_key_store_entry_s +{ + uint32_t id; + se05x_asym_cipher_type_e cipher; +}; + +struct se05x_buffer_s +{ + FAR uint8_t *buffer; + size_t buffer_size; + size_t buffer_content_size; +}; + +struct se05x_key_transmission_s +{ + struct se05x_key_store_entry_s entry; + struct se05x_buffer_s content; +}; + +struct se05x_derive_key_s +{ + uint32_t private_key_id; + uint32_t public_key_id; + struct se05x_buffer_s content; +}; + +struct se05x_signature_s +{ + uint32_t key_id; + se05x_algorithm_e algorithm; + struct se05x_buffer_s tbs; + struct se05x_buffer_s signature; +}; + +struct se05x_config_s +{ + uint8_t address; + uint32_t frequency; + + CODE bool (*set_enable_pin)(bool state); +}; + +struct i2c_master_s; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: se05x_register + * + * Description: + * Register the se05x character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, e.g., "/dev/se05x". + * i2c - An I2C driver instance. + * config - Pointer to the se05x configuration + * + * Returned Value: + * se050_status_success (0) on success, + * a negative value on failure + * + ****************************************************************************/ + +int se05x_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + FAR struct se05x_config_s *config); + +#endif /* CONFIG_DEV_SE05X */ + +#endif /* __INCLUDE_NUTTX_CRYPTO_SE05X_H_ */ diff --git a/include/nuttx/fs/ioctl.h b/include/nuttx/fs/ioctl.h index dd70cc634b..3fd1fac623 100644 --- a/include/nuttx/fs/ioctl.h +++ b/include/nuttx/fs/ioctl.h @@ -96,6 +96,7 @@ #define _VIDIOCBASE (0x3700) /* Video device ioctl commands */ #define _CELLIOCBASE (0x3800) /* Cellular device ioctl commands */ #define _MIPIDSIBASE (0x3900) /* Mipidsi device ioctl commands */ +#define _SEIOCBASE (0x3a00) /* Secure element ioctl commands */ #define _SYSLOGBASE (0x3c00) /* Syslog device ioctl commands */ #define _WLIOCBASE (0x8b00) /* Wireless modules ioctl network commands */ @@ -651,6 +652,13 @@ #define _MIPIDSIIOCVALID(c) (_IOC_TYPE(c)==_MIPIDSIBASE) #define _MIPIDSIIOC(nr) _IOC(_MIPIDSIBASE,nr) +/* Secure element ioctl definitions *****************************************/ + +/* (see nuttx/include/crypto/se05x.h */ + +#define _SEIOCVALID(c) (_IOC_TYPE(c)==_SEIOCBASE) +#define _SEIOC(nr) _IOC(_SEIOCBASE,nr) + /* syslog driver ioctl definitions ******************************************/ #define _SYSLOGVALID(c) (_IOC_TYPE(c)==_SYSLOGBASE)