mirror of https://github.com/wolfSSL/wolfBoot.git
commit
2aef0ed77b
|
|
@ -8,7 +8,7 @@ jobs:
|
|||
trustzone-emulator-tests:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/danielinux/m33mu-ci:1.5
|
||||
image: ghcr.io/wolfssl/m33mu-ci:1.9
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
|
@ -27,6 +27,56 @@ jobs:
|
|||
run: |
|
||||
./test.sh
|
||||
|
||||
- name: Clean build tree for PKCS11 test (stm32h5)
|
||||
run: |
|
||||
make clean distclean
|
||||
|
||||
- name: Configure PKCS11 test (stm32h5)
|
||||
run: |
|
||||
cp config/examples/stm32h5-tz.config .config
|
||||
|
||||
- name: Build persistent PKCS11 test app (stm32h5)
|
||||
run: |
|
||||
make PKCS11_TESTAPP=1
|
||||
|
||||
- name: Prepare PKCS11 persistence directory
|
||||
run: |
|
||||
rm -rf /tmp/m33mu-pkcs11-persist
|
||||
mkdir -p /tmp/m33mu-pkcs11-persist
|
||||
rm -f /tmp/m33mu-pkcs11-first.log /tmp/m33mu-pkcs11-second.log
|
||||
|
||||
- name: Run PKCS11 first boot (stm32h5)
|
||||
run: |
|
||||
cd /tmp/m33mu-pkcs11-persist
|
||||
m33mu "$GITHUB_WORKSPACE/wolfboot.bin" \
|
||||
"$GITHUB_WORKSPACE/test-app/image_v1_signed.bin:0x60000" \
|
||||
--persist --uart-stdout --timeout 120 --expect-bkpt 0x7d \
|
||||
| tee /tmp/m33mu-pkcs11-first.log
|
||||
|
||||
- name: Verify PKCS11 first boot (stm32h5)
|
||||
run: |
|
||||
grep -q "pkcs11: first boot path, creating persistent objects" /tmp/m33mu-pkcs11-first.log
|
||||
grep -q "pkcs11: created persistent PKCS11 objects" /tmp/m33mu-pkcs11-first.log
|
||||
grep -q "pkcs11: success" /tmp/m33mu-pkcs11-first.log
|
||||
grep -q "\\[BKPT\\] imm=0x7d" /tmp/m33mu-pkcs11-first.log
|
||||
grep -q "\\[EXPECT BKPT\\] Success" /tmp/m33mu-pkcs11-first.log
|
||||
|
||||
- name: Run PKCS11 second boot (stm32h5)
|
||||
run: |
|
||||
cd /tmp/m33mu-pkcs11-persist
|
||||
m33mu "$GITHUB_WORKSPACE/wolfboot.bin" \
|
||||
"$GITHUB_WORKSPACE/test-app/image_v1_signed.bin:0x60000" \
|
||||
--persist --uart-stdout --timeout 120 --expect-bkpt 0x7f \
|
||||
| tee /tmp/m33mu-pkcs11-second.log
|
||||
|
||||
- name: Verify PKCS11 second boot (stm32h5)
|
||||
run: |
|
||||
grep -q "pkcs11: second boot path, restoring persistent objects" /tmp/m33mu-pkcs11-second.log
|
||||
grep -q "pkcs11: restored persistent PKCS11 objects" /tmp/m33mu-pkcs11-second.log
|
||||
grep -q "pkcs11: success" /tmp/m33mu-pkcs11-second.log
|
||||
grep -q "\\[BKPT\\] imm=0x7f" /tmp/m33mu-pkcs11-second.log
|
||||
grep -q "\\[EXPECT BKPT\\] Success" /tmp/m33mu-pkcs11-second.log
|
||||
|
||||
- name: Clean and build stm32u5 (TZ + wolfcrypt)
|
||||
run: |
|
||||
make clean distclean
|
||||
|
|
@ -44,7 +94,7 @@ jobs:
|
|||
cp config/examples/stm32l5-wolfcrypt-tz.config .config
|
||||
make wolfboot.bin
|
||||
|
||||
- name: Run emu test (stm32u5)
|
||||
- name: Run emu test (stm32l5)
|
||||
working-directory: test-app/emu-test-apps
|
||||
run: |
|
||||
TARGET=stm32l5 ./test.sh
|
||||
|
|
|
|||
|
|
@ -32,23 +32,23 @@ PKA?=1
|
|||
WOLFBOOT_SECTOR_SIZE?=0x2000
|
||||
|
||||
# Default configuration
|
||||
# 40KB boot, no keyvault, 8KB NSC, 64KB partitions, 8KB swap
|
||||
# 40KB boot, no keyvault, 8KB NSC, 72KB partitions, 8KB swap
|
||||
WOLFBOOT_KEYVAULT_ADDRESS?=0xA000
|
||||
WOLFBOOT_KEYVAULT_SIZE?=0
|
||||
WOLFBOOT_NSC_ADDRESS?=0xA000
|
||||
WOLFBOOT_NSC_SIZE?=0x2000
|
||||
WOLFBOOT_PARTITION_SIZE?=0x10000
|
||||
WOLFBOOT_PARTITION_SIZE?=0x12000
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xC000
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x1C000
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x2C000
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x1E000
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x30000
|
||||
|
||||
# Alternate larger configuration for debugging or ARMASM
|
||||
# 128KB boot, no keyvault, 8KB NSC, 64KB partitions, 8KB swap
|
||||
# 128KB boot, no keyvault, 8KB NSC, 72KB partitions, 8KB swap
|
||||
#WOLFBOOT_KEYVAULT_ADDRESS?=0x20000
|
||||
#WOLFBOOT_KEYVAULT_SIZE?=0
|
||||
#WOLFBOOT_NSC_ADDRESS?=0x20000
|
||||
#WOLFBOOT_NSC_SIZE?=0x2000
|
||||
#WOLFBOOT_PARTITION_SIZE?=0x10000
|
||||
#WOLFBOOT_PARTITION_SIZE?=0x12000
|
||||
#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x22000
|
||||
#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x32000
|
||||
#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x42000
|
||||
#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x34000
|
||||
#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x46000
|
||||
|
|
|
|||
|
|
@ -34,23 +34,23 @@ WOLFCRYPT_TZ_PKCS11?=1
|
|||
WOLFBOOT_SECTOR_SIZE?=0x2000
|
||||
|
||||
# Default configuration
|
||||
# 192KB boot, 96KB keyvault, 8KB NSC, 64KB partitions, 8KB swap
|
||||
# 192KB boot, 96KB keyvault, 8KB NSC, 72KB partitions, 8KB swap
|
||||
WOLFBOOT_KEYVAULT_ADDRESS?=0x30000
|
||||
WOLFBOOT_KEYVAULT_SIZE?=0x18000
|
||||
WOLFBOOT_NSC_ADDRESS?=0x48000
|
||||
WOLFBOOT_NSC_SIZE?=0x2000
|
||||
WOLFBOOT_PARTITION_SIZE?=0x10000
|
||||
WOLFBOOT_PARTITION_SIZE?=0x12000
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x4A000
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x5A000
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x6A000
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x5C000
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x6E000
|
||||
|
||||
# Alternate larger configuration for debugging or ARMASM
|
||||
# 320KB boot, 96KB keyvault, 8KB NSC, 64KB partitions, 8KB swap
|
||||
# 320KB boot, 96KB keyvault, 8KB NSC, 72KB partitions, 8KB swap
|
||||
#WOLFBOOT_KEYVAULT_ADDRESS?=0x50000
|
||||
#WOLFBOOT_KEYVAULT_SIZE?=0x18000
|
||||
#WOLFBOOT_NSC_ADDRESS?=0x68000
|
||||
#WOLFBOOT_NSC_SIZE?=0x2000
|
||||
#WOLFBOOT_PARTITION_SIZE?=0x10000
|
||||
#WOLFBOOT_PARTITION_SIZE?=0x12000
|
||||
#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x6A000
|
||||
#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x7A000
|
||||
#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x8A000
|
||||
#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x7C000
|
||||
#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x8E000
|
||||
|
|
|
|||
|
|
@ -400,11 +400,17 @@ static void clock_pll_on(int powersave)
|
|||
#if TZ_SECURE()
|
||||
static void periph_unsecure()
|
||||
{
|
||||
volatile uint32_t reg;
|
||||
|
||||
/*Enable clock for User LED GPIOs */
|
||||
RCC_AHB2_CLOCK_ER|= LED_AHB2_ENABLE;
|
||||
|
||||
/* Enable clock for LPUART1 */
|
||||
RCC_APB1_CLOCK_ER |= UART1_APB1_CLOCK_ER_VAL;
|
||||
/* Enable clock for USART3 used by emu-test-apps on PD8/PD9 */
|
||||
RCC_APB1_CLOCK_ER |= UART3_APB1_CLOCK_ER_VAL;
|
||||
/* Enable clock for GPIO D (USART3 pins) */
|
||||
RCC_AHB2_CLOCK_ER |= GPIOD_AHB2_CLOCK_ER;
|
||||
|
||||
|
||||
PWR_CR2 |= PWR_CR2_IOSV;
|
||||
|
|
@ -423,6 +429,16 @@ static void periph_unsecure()
|
|||
GPIO_SECCFGR(GPIOG_BASE) &= ~(1<<UART1_TX_PIN);
|
||||
GPIO_SECCFGR(GPIOG_BASE) &= ~(1<<UART1_RX_PIN);
|
||||
|
||||
/* Unsecure USART3 and its pins for the STM32L5 emulator app path. */
|
||||
reg = TZSC_SECCFGR1;
|
||||
if (reg & TZSC_SECCFGR1_USART3SEC) {
|
||||
reg &= ~TZSC_SECCFGR1_USART3SEC;
|
||||
DMB();
|
||||
TZSC_SECCFGR1 = reg;
|
||||
}
|
||||
GPIO_SECCFGR(GPIOD_BASE) &= ~(1u << 8);
|
||||
GPIO_SECCFGR(GPIOD_BASE) &= ~(1u << 9);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -181,8 +181,10 @@
|
|||
#define FLASH_NS_SR (*(volatile uint32_t *)(FLASH_NS_BASE + 0x20))
|
||||
#define FLASH_NS_CR (*(volatile uint32_t *)(FLASH_NS_BASE + 0x28))
|
||||
|
||||
#define TZSC_PRIVCFGR1 *((uint32_t *)(0x50032420))
|
||||
#define TZSC_PRIVCFG1_LPUARTPRIV (1 << 21)
|
||||
#define TZSC_PRIVCFGR1 (*(volatile uint32_t *)(0x50032420))
|
||||
#define TZSC_PRIVCFG1_LPUARTPRIV (1u << 21)
|
||||
#define TZSC_SECCFGR1 (*(volatile uint32_t *)(0x50032410))
|
||||
#define TZSC_SECCFGR1_USART3SEC (1u << 11)
|
||||
|
||||
|
||||
#else
|
||||
|
|
@ -257,6 +259,7 @@
|
|||
|
||||
#define RCC_APB1_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0x5C ))
|
||||
#define UART1_APB1_CLOCK_ER_VAL (1 << 0)
|
||||
#define UART3_APB1_CLOCK_ER_VAL (1 << 18)
|
||||
|
||||
#define UART1_PIN_AF 8
|
||||
#define UART1_RX_PIN 8
|
||||
|
|
|
|||
|
|
@ -122,6 +122,9 @@ endif()
|
|||
|
||||
if(BUILD_TEST_APPS)
|
||||
message(STATUS "Building wolfBoot test apps")
|
||||
if(WOLFCRYPT_TZ_PKCS11 AND NOT TZEN)
|
||||
message(FATAL_ERROR "WOLFCRYPT_TZ_PKCS11 requires TZEN=ON for test-app builds")
|
||||
endif()
|
||||
add_executable(image)
|
||||
|
||||
target_sources(image PRIVATE ${APP_SOURCES})
|
||||
|
|
@ -176,7 +179,7 @@ if(BUILD_TEST_APPS)
|
|||
target_include_directories(image PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/wcs)
|
||||
endif()
|
||||
|
||||
if(WOLFCRYPT_TZ_PKCS11)
|
||||
if(TZEN AND WOLFCRYPT_TZ_PKCS11)
|
||||
target_include_directories(image PRIVATE ../lib/wolfPKCS11)
|
||||
endif()
|
||||
|
||||
|
|
@ -204,11 +207,18 @@ if(BUILD_TEST_APPS)
|
|||
list(APPEND TEST_APP_COMPILE_DEFINITIONS WOLFBOOT_SECURE_CALLS)
|
||||
endif()
|
||||
|
||||
if(WOLFCRYPT_TZ_PKCS11)
|
||||
list(APPEND TEST_APP_COMPILE_DEFINITIONS WOLFBOOT_PKCS11_APP SECURE_PKCS11 WOLFPKCS11_USER_SETTINGS)
|
||||
if(TZEN AND WOLFCRYPT_TZ_PKCS11)
|
||||
list(APPEND TEST_APP_COMPILE_DEFINITIONS
|
||||
WOLFBOOT_PKCS11_APP
|
||||
SECURE_PKCS11
|
||||
WOLFBOOT_TZ_PKCS11
|
||||
WOLFPKCS11_USER_SETTINGS)
|
||||
if(PKCS11_TESTAPP)
|
||||
list(APPEND TEST_APP_COMPILE_DEFINITIONS WOLFBOOT_PKCS11_TESTAPP)
|
||||
endif()
|
||||
set(WOLFSSL_PKCS11_SOURCES
|
||||
test_pkcs11.c
|
||||
wcs/pkcs11_stub.c
|
||||
wcs/pkcs11_test_ecc.c
|
||||
../lib/wolfssl/wolfcrypt/src/ecc.c
|
||||
../lib/wolfssl/wolfcrypt/src/rsa.c
|
||||
../lib/wolfssl/wolfcrypt/src/asn.c
|
||||
|
|
|
|||
|
|
@ -247,8 +247,11 @@ ifeq ($(TZEN),1)
|
|||
ifeq ($(WOLFCRYPT_TZ_PKCS11),1)
|
||||
CFLAGS+=-DWOLFSSL_USER_SETTINGS -DWOLFTPM_USER_SETTINGS
|
||||
CFLAGS+=-DWOLFBOOT_PKCS11_APP -DSECURE_PKCS11 -DWOLFBOOT_TZ_PKCS11
|
||||
ifeq ($(PKCS11_TESTAPP),1)
|
||||
CFLAGS+=-DWOLFBOOT_PKCS11_TESTAPP
|
||||
endif
|
||||
CFLAGS+=-I"$(WOLFBOOT_LIB_WOLFPKCS11)"
|
||||
APP_OBJS+=./wcs/pkcs11_test_ecc.o
|
||||
APP_OBJS+=./test_pkcs11.o
|
||||
APP_OBJS+=./wcs/pkcs11_stub.o
|
||||
APP_OBJS+=./wcs/ecc.o
|
||||
APP_OBJS+=./wcs/rsa.o
|
||||
|
|
|
|||
|
|
@ -41,12 +41,7 @@
|
|||
#endif
|
||||
|
||||
#ifdef WOLFBOOT_TZ_PKCS11
|
||||
#include "wcs/user_settings.h"
|
||||
#include "wolfssl/wolfcrypt/settings.h"
|
||||
#include "wolfssl/wolfcrypt/wc_pkcs11.h"
|
||||
#include "wolfssl/wolfcrypt/random.h"
|
||||
extern const char pkcs11_library_name[];
|
||||
extern const CK_FUNCTION_LIST wolfpkcs11nsFunctionList;
|
||||
#include "test_pkcs11.h"
|
||||
#endif
|
||||
|
||||
#ifdef WOLFCRYPT_SECURE_MODE
|
||||
|
|
@ -192,8 +187,6 @@ void extra_led_off(void)
|
|||
GPIOF_BSRR |= (1 << (LED_EXTRA_PIN + 16));
|
||||
}
|
||||
|
||||
extern int ecdsa_sign_verify(int devId);
|
||||
|
||||
/* Command line commands */
|
||||
static int cmd_help(const char *args);
|
||||
static int cmd_info(const char *args);
|
||||
|
|
@ -837,98 +830,8 @@ static int run_psa_boot_attestation(void)
|
|||
#ifdef WOLFBOOT_TZ_PKCS11
|
||||
static int cmd_login_pkcs11(const char *args)
|
||||
{
|
||||
int ret = -1;
|
||||
unsigned int devId = 0;
|
||||
Pkcs11Token token;
|
||||
Pkcs11Dev PKCS11_d;
|
||||
unsigned long session;
|
||||
char TokenPin[] = "0123456789ABCDEF";
|
||||
char UserPin[] = "ABCDEF0123456789";
|
||||
char SoPinName[] = "SO-PIN";
|
||||
static int pkcs11_initialized = 0;
|
||||
|
||||
if (pkcs11_initialized) {
|
||||
printf("PKCS11 already initialized.\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("PKCS11 Login\r\n");
|
||||
|
||||
printf("Initializing wolfCrypt...");
|
||||
fflush(stdout);
|
||||
wolfCrypt_Init();
|
||||
printf("Done.\r\n");
|
||||
|
||||
PKCS11_d.heap = NULL,
|
||||
PKCS11_d.func = (CK_FUNCTION_LIST *)&wolfpkcs11nsFunctionList;
|
||||
|
||||
printf("Initializing EccKey token...");
|
||||
fflush(stdout);
|
||||
ret = wc_Pkcs11Token_Init(&token, &PKCS11_d, 1, "EccKey",
|
||||
(const byte*)TokenPin, strlen(TokenPin));
|
||||
|
||||
if (ret == 0) {
|
||||
printf("Done.\r\n");
|
||||
printf("Initializing token...");
|
||||
fflush(stdout);
|
||||
ret = wolfpkcs11nsFunctionList.C_InitToken(1,
|
||||
(byte *)TokenPin, strlen(TokenPin), (byte *)SoPinName);
|
||||
}
|
||||
if (ret == 0) {
|
||||
printf("Done.\r\n");
|
||||
printf("Opening session...");
|
||||
fflush(stdout);
|
||||
ret = wolfpkcs11nsFunctionList.C_OpenSession(1,
|
||||
CKF_SERIAL_SESSION | CKF_RW_SESSION,
|
||||
NULL, NULL, &session);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
printf("Done.\r\n");
|
||||
printf("Logging in as SO...");
|
||||
ret = wolfpkcs11nsFunctionList.C_Login(session, CKU_SO,
|
||||
(byte *)TokenPin,
|
||||
strlen(TokenPin));
|
||||
}
|
||||
if (ret == 0) {
|
||||
extra_led_on();
|
||||
printf("Done.\r\n");
|
||||
printf("Setting PIN...");
|
||||
ret = wolfpkcs11nsFunctionList.C_InitPIN(session,
|
||||
(byte *)TokenPin,
|
||||
strlen(TokenPin));
|
||||
}
|
||||
if (ret == 0) {
|
||||
printf("Done.\r\n");
|
||||
printf("Logging out...");
|
||||
ret = wolfpkcs11nsFunctionList.C_Logout(session);
|
||||
}
|
||||
if (ret == 0) {
|
||||
printf("Done.\r\n");
|
||||
printf("Registering crypto calls with wolfCrypt...");
|
||||
ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb,
|
||||
&token);
|
||||
}
|
||||
if (ret == 0) {
|
||||
printf("Done.\r\n");
|
||||
#ifdef HAVE_ECC
|
||||
printf("Testing ECC...");
|
||||
ret = ecdsa_sign_verify(devId);
|
||||
if (ret != 0) {
|
||||
ret = -1;
|
||||
printf("Failed.\r\n");
|
||||
}
|
||||
else {
|
||||
usr_led_on();
|
||||
printf("Done.\r\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (ret == 0) {
|
||||
printf("PKCS11 initialization completed successfully.\r\n");
|
||||
pkcs11_initialized = 1;
|
||||
}
|
||||
return ret;
|
||||
(void)args;
|
||||
return test_pkcs11_start();
|
||||
}
|
||||
#endif /* WOLFBOOT_TZ_PKCS11 */
|
||||
|
||||
|
|
@ -1377,6 +1280,16 @@ void main(void)
|
|||
(void)run_psa_boot_attestation();
|
||||
#endif
|
||||
|
||||
#ifdef WOLFBOOT_PKCS11_TESTAPP
|
||||
ret = test_pkcs11_start();
|
||||
if (ret == PKCS11_TEST_FIRST_BOOT_OK)
|
||||
asm volatile ("bkpt #0x7d");
|
||||
else if (ret == PKCS11_TEST_SECOND_BOOT_OK)
|
||||
asm volatile ("bkpt #0x7f");
|
||||
else
|
||||
asm volatile ("bkpt #0x7e");
|
||||
#endif
|
||||
|
||||
console_loop();
|
||||
|
||||
while(1)
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "system.h"
|
||||
#include "hal.h"
|
||||
#include "uart_drv.h"
|
||||
|
|
@ -33,12 +30,9 @@
|
|||
#include "target.h"
|
||||
|
||||
#ifdef SECURE_PKCS11
|
||||
#include "test_pkcs11.h"
|
||||
#include "wcs/user_settings.h"
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/wc_pkcs11.h>
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
extern const char pkcs11_library_name[];
|
||||
extern const CK_FUNCTION_LIST wolfpkcs11nsFunctionList;
|
||||
#endif
|
||||
|
||||
#define LED_BOOT_PIN (9) /* PA9 - Nucleo - Red Led */
|
||||
|
|
@ -134,84 +128,15 @@ void extra_led_off(void)
|
|||
GPIOB_BSRR |= (1 << (LED_EXTRA_PIN + 16));
|
||||
}
|
||||
|
||||
|
||||
extern int ecdsa_sign_verify(int devId);
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int ret;
|
||||
uint32_t rand;
|
||||
uint32_t i;
|
||||
uint32_t klen = 200;
|
||||
int otherkey_slot;
|
||||
unsigned int devId = 0;
|
||||
|
||||
#ifdef SECURE_PKCS11
|
||||
WC_RNG rng;
|
||||
Pkcs11Token token;
|
||||
Pkcs11Dev PKCS11_d;
|
||||
unsigned long session;
|
||||
char TokenPin[] = "0123456789ABCDEF";
|
||||
char UserPin[] = "ABCDEF0123456789";
|
||||
char SoPinName[] = "SO-PIN";
|
||||
int ret;
|
||||
|
||||
boot_led_on();
|
||||
|
||||
wolfCrypt_Init();
|
||||
|
||||
PKCS11_d.heap = NULL,
|
||||
PKCS11_d.func = (CK_FUNCTION_LIST *)&wolfpkcs11nsFunctionList;
|
||||
|
||||
ret = wc_Pkcs11Token_Init(&token, &PKCS11_d, 1, "EccKey",
|
||||
(const byte*)TokenPin, strlen(TokenPin));
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wolfpkcs11nsFunctionList.C_OpenSession(1,
|
||||
CKF_SERIAL_SESSION | CKF_RW_SESSION,
|
||||
NULL, NULL, &session);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wolfpkcs11nsFunctionList.C_InitToken(1,
|
||||
(byte *)TokenPin, strlen(TokenPin), (byte *)SoPinName);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
extra_led_on();
|
||||
ret = wolfpkcs11nsFunctionList.C_Login(session, CKU_SO,
|
||||
(byte *)TokenPin,
|
||||
strlen(TokenPin));
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wolfpkcs11nsFunctionList.C_InitPIN(session,
|
||||
(byte *)TokenPin,
|
||||
strlen(TokenPin));
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wolfpkcs11nsFunctionList.C_Logout(session);
|
||||
}
|
||||
if (ret != 0) {
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb,
|
||||
&token);
|
||||
if (ret != 0) {
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
if (ret == 0) {
|
||||
#ifdef HAVE_ECC
|
||||
ret = ecdsa_sign_verify(devId);
|
||||
if (ret != 0)
|
||||
ret = 1;
|
||||
else
|
||||
usr_led_on();
|
||||
#endif
|
||||
}
|
||||
wc_Pkcs11Token_Final(&token);
|
||||
}
|
||||
ret = test_pkcs11_start();
|
||||
if (ret != PKCS11_TEST_FAIL)
|
||||
usr_led_on();
|
||||
#endif
|
||||
while(1)
|
||||
;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,600 @@
|
|||
/* test_pkcs11.c
|
||||
*
|
||||
* Reusable PKCS11 secure-world integration demo for wolfBoot test apps.
|
||||
*
|
||||
* The demo is intentionally verbose and linear so it doubles as a reference
|
||||
* for TEE integrations:
|
||||
* 1. initialize or restore a token
|
||||
* 2. create/find persistent key objects
|
||||
* 3. sign a payload with the private key
|
||||
* 4. persist application data as a PKCS11 data object
|
||||
* 5. restore objects on the next boot and verify the signature
|
||||
*/
|
||||
|
||||
#include "user_settings.h"
|
||||
|
||||
#ifdef WOLFBOOT_TZ_PKCS11
|
||||
|
||||
#include "test_pkcs11.h"
|
||||
|
||||
#include "wolfpkcs11/pkcs11.h"
|
||||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/wc_port.h>
|
||||
#include <wolfssl/wolfcrypt/wc_pkcs11.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern const char pkcs11_library_name[];
|
||||
extern const CK_FUNCTION_LIST wolfpkcs11nsFunctionList;
|
||||
|
||||
static const CK_BYTE test_token_label[32] = {
|
||||
'E','c','c','K','e','y',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '
|
||||
};
|
||||
static const char test_token_name[] = "EccKey";
|
||||
static const CK_BYTE test_so_pin[] = "0123456789ABCDEF";
|
||||
static const CK_BYTE test_user_pin[] = "0123456789ABCDEF";
|
||||
static const CK_BYTE test_so_pin_label[] = "SO-PIN";
|
||||
static const CK_BYTE test_key_id[] = { 0x57, 0x42, 0x50, 0x31 };
|
||||
static const CK_BYTE test_pub_label[] = "wolfBoot PKCS11 demo pub";
|
||||
static const CK_BYTE test_priv_label[] = "wolfBoot PKCS11 demo priv";
|
||||
static const CK_BYTE test_data_label[] = "wolfBoot PKCS11 demo blob";
|
||||
static const CK_BYTE test_application[] = "wolfBoot PKCS11 demo";
|
||||
static const CK_BYTE test_object_id[] = { 0x50, 0x4B, 0x43, 0x53, 0x31, 0x31 };
|
||||
static const CK_BYTE test_payload[] = "wolfBoot PKCS11 persistent signing demo";
|
||||
|
||||
/* ASN.1 DER object identifier for secp256r1 / prime256v1. */
|
||||
static const CK_BYTE test_ecc_p256_params[] = {
|
||||
0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07
|
||||
};
|
||||
|
||||
struct test_pkcs11_blob {
|
||||
uint32_t magic;
|
||||
uint16_t version;
|
||||
uint16_t reserved;
|
||||
uint32_t payload_len;
|
||||
uint32_t sig_len;
|
||||
CK_BYTE data[512];
|
||||
};
|
||||
|
||||
#define TEST_PKCS11_BLOB_MAGIC 0x314B5057UL
|
||||
#define TEST_PKCS11_BLOB_VERSION 1U
|
||||
#define TEST_PKCS11_SLOT_ID 1UL
|
||||
|
||||
static void test_pkcs11_dump_rv(const char *label, CK_RV rv)
|
||||
{
|
||||
printf("pkcs11: %s rv=0x%08lx\r\n", label, (unsigned long)rv);
|
||||
}
|
||||
|
||||
static int test_pkcs11_ck_ok(const char *label, CK_RV rv)
|
||||
{
|
||||
if (rv != CKR_OK) {
|
||||
test_pkcs11_dump_rv(label, rv);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_pkcs11_log_blob_checksum(const struct test_pkcs11_blob *blob,
|
||||
const char *prefix)
|
||||
{
|
||||
byte digest[WC_SHA256_DIGEST_SIZE];
|
||||
word32 blob_len = (word32)(blob->payload_len + blob->sig_len);
|
||||
word32 i;
|
||||
|
||||
if (wc_Sha256Hash(blob->data, blob_len, digest) != 0)
|
||||
return;
|
||||
|
||||
printf("pkcs11: %s blob_sha256=", prefix);
|
||||
for (i = 0; i < (word32)sizeof(digest); i++)
|
||||
printf("%02x", digest[i]);
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
static int test_pkcs11_find_one(CK_SESSION_HANDLE session,
|
||||
CK_ATTRIBUTE_PTR tmpl, CK_ULONG tmpl_count, CK_OBJECT_HANDLE *obj)
|
||||
{
|
||||
CK_RV rv;
|
||||
CK_ULONG count = 0;
|
||||
|
||||
*obj = CK_INVALID_HANDLE;
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_FindObjectsInit(session, tmpl, tmpl_count);
|
||||
if (test_pkcs11_ck_ok("C_FindObjectsInit", rv) < 0)
|
||||
return -1;
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_FindObjects(session, obj, 1, &count);
|
||||
if (rv != CKR_OK) {
|
||||
(void)wolfpkcs11nsFunctionList.C_FindObjectsFinal(session);
|
||||
test_pkcs11_dump_rv("C_FindObjects", rv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_FindObjectsFinal(session);
|
||||
if (test_pkcs11_ck_ok("C_FindObjectsFinal", rv) < 0)
|
||||
return -1;
|
||||
|
||||
if (count != 1 || *obj == CK_INVALID_HANDLE)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_pkcs11_get_attr(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj,
|
||||
CK_ATTRIBUTE_TYPE type, CK_BYTE *buf, CK_ULONG *len)
|
||||
{
|
||||
CK_ATTRIBUTE attr = { type, NULL, 0 };
|
||||
CK_RV rv;
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_GetAttributeValue(session, obj, &attr, 1);
|
||||
if (rv != CKR_OK || attr.ulValueLen == (CK_ULONG)-1)
|
||||
return -1;
|
||||
if (buf == NULL) {
|
||||
*len = attr.ulValueLen;
|
||||
return 0;
|
||||
}
|
||||
if (*len < attr.ulValueLen)
|
||||
return -1;
|
||||
|
||||
attr.pValue = buf;
|
||||
rv = wolfpkcs11nsFunctionList.C_GetAttributeValue(session, obj, &attr, 1);
|
||||
if (rv != CKR_OK || attr.ulValueLen == (CK_ULONG)-1)
|
||||
return -1;
|
||||
|
||||
*len = attr.ulValueLen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_pkcs11_log_obj_attr(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj,
|
||||
const char *prefix, CK_ATTRIBUTE_TYPE type)
|
||||
{
|
||||
CK_BYTE buf[160];
|
||||
CK_ULONG len = sizeof(buf);
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
ret = test_pkcs11_get_attr(session, obj, type, buf, &len);
|
||||
if (ret < 0) {
|
||||
printf("pkcs11: %s attr 0x%08lx unavailable\r\n",
|
||||
prefix, (unsigned long)type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
printf("pkcs11: %s attr 0x%08lx len=%lu",
|
||||
prefix, (unsigned long)type, (unsigned long)len);
|
||||
if (type == CKA_LABEL || type == CKA_ID || type == CKA_OBJECT_ID ||
|
||||
type == CKA_APPLICATION) {
|
||||
printf(" value=");
|
||||
for (i = 0; i < len; i++) {
|
||||
CK_BYTE ch = buf[i];
|
||||
if (ch >= 32 && ch < 127)
|
||||
printf("%c", ch);
|
||||
else
|
||||
printf("\\x%02x", ch);
|
||||
}
|
||||
}
|
||||
printf("\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_pkcs11_provision_token(void)
|
||||
{
|
||||
int ret;
|
||||
CK_RV rv;
|
||||
CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
|
||||
Pkcs11Token token;
|
||||
Pkcs11Dev dev;
|
||||
|
||||
printf("pkcs11: provisioning token\r\n");
|
||||
|
||||
dev.heap = NULL;
|
||||
dev.func = (CK_FUNCTION_LIST *)&wolfpkcs11nsFunctionList;
|
||||
|
||||
ret = wc_Pkcs11Token_Init(&token, &dev, (int)TEST_PKCS11_SLOT_ID,
|
||||
test_token_name, test_user_pin, (int)(sizeof(test_user_pin) - 1));
|
||||
if (ret != 0) {
|
||||
printf("pkcs11: wc_Pkcs11Token_Init ret=%d\r\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_InitToken(TEST_PKCS11_SLOT_ID,
|
||||
(CK_UTF8CHAR_PTR)test_so_pin, (CK_ULONG)(sizeof(test_so_pin) - 1),
|
||||
(CK_UTF8CHAR_PTR)test_token_label);
|
||||
if (test_pkcs11_ck_ok("C_InitToken", rv) < 0) {
|
||||
wc_Pkcs11Token_Final(&token);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_OpenSession(TEST_PKCS11_SLOT_ID,
|
||||
CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session);
|
||||
if (test_pkcs11_ck_ok("C_OpenSession(SO)", rv) < 0) {
|
||||
wc_Pkcs11Token_Final(&token);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_Login(session, CKU_SO,
|
||||
(CK_UTF8CHAR_PTR)test_so_pin, (CK_ULONG)(sizeof(test_so_pin) - 1));
|
||||
if (test_pkcs11_ck_ok("C_Login(SO)", rv) < 0) {
|
||||
(void)wolfpkcs11nsFunctionList.C_CloseSession(session);
|
||||
wc_Pkcs11Token_Final(&token);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_InitPIN(session,
|
||||
(CK_UTF8CHAR_PTR)test_user_pin, (CK_ULONG)(sizeof(test_user_pin) - 1));
|
||||
if (test_pkcs11_ck_ok("C_InitPIN", rv) < 0) {
|
||||
(void)wolfpkcs11nsFunctionList.C_Logout(session);
|
||||
(void)wolfpkcs11nsFunctionList.C_CloseSession(session);
|
||||
wc_Pkcs11Token_Final(&token);
|
||||
return -1;
|
||||
}
|
||||
|
||||
(void)wolfpkcs11nsFunctionList.C_Logout(session);
|
||||
(void)wolfpkcs11nsFunctionList.C_CloseSession(session);
|
||||
wc_Pkcs11Token_Final(&token);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_pkcs11_open_user_session(CK_SESSION_HANDLE *session)
|
||||
{
|
||||
CK_RV rv;
|
||||
|
||||
*session = CK_INVALID_HANDLE;
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_OpenSession(TEST_PKCS11_SLOT_ID,
|
||||
CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, session);
|
||||
if (test_pkcs11_ck_ok("C_OpenSession(USER)", rv) < 0)
|
||||
return -1;
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_Login(*session, CKU_USER,
|
||||
(CK_UTF8CHAR_PTR)test_user_pin, (CK_ULONG)(sizeof(test_user_pin) - 1));
|
||||
if (rv == CKR_OK)
|
||||
return 0;
|
||||
|
||||
if (rv == CKR_USER_PIN_NOT_INITIALIZED) {
|
||||
(void)wolfpkcs11nsFunctionList.C_CloseSession(*session);
|
||||
*session = CK_INVALID_HANDLE;
|
||||
return -2;
|
||||
}
|
||||
|
||||
test_pkcs11_dump_rv("C_Login(USER)", rv);
|
||||
(void)wolfpkcs11nsFunctionList.C_CloseSession(*session);
|
||||
*session = CK_INVALID_HANDLE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int test_pkcs11_find_keypair(CK_SESSION_HANDLE session,
|
||||
CK_OBJECT_HANDLE *pub_obj, CK_OBJECT_HANDLE *priv_obj)
|
||||
{
|
||||
CK_OBJECT_CLASS pub_class = CKO_PUBLIC_KEY;
|
||||
CK_OBJECT_CLASS priv_class = CKO_PRIVATE_KEY;
|
||||
CK_ATTRIBUTE pub_tmpl[] = {
|
||||
{ CKA_CLASS, &pub_class, sizeof(pub_class) },
|
||||
{ CKA_ID, (CK_VOID_PTR)test_key_id, sizeof(test_key_id) },
|
||||
{ CKA_LABEL, (CK_VOID_PTR)test_pub_label, sizeof(test_pub_label) - 1 }
|
||||
};
|
||||
CK_ATTRIBUTE priv_tmpl[] = {
|
||||
{ CKA_CLASS, &priv_class, sizeof(priv_class) },
|
||||
{ CKA_ID, (CK_VOID_PTR)test_key_id, sizeof(test_key_id) },
|
||||
{ CKA_LABEL, (CK_VOID_PTR)test_priv_label, sizeof(test_priv_label) - 1 }
|
||||
};
|
||||
int ret_pub;
|
||||
int ret_priv;
|
||||
|
||||
ret_pub = test_pkcs11_find_one(session, pub_tmpl,
|
||||
(CK_ULONG)(sizeof(pub_tmpl) / sizeof(pub_tmpl[0])), pub_obj);
|
||||
ret_priv = test_pkcs11_find_one(session, priv_tmpl,
|
||||
(CK_ULONG)(sizeof(priv_tmpl) / sizeof(priv_tmpl[0])), priv_obj);
|
||||
|
||||
if (ret_pub == 1 && ret_priv == 1)
|
||||
return 1;
|
||||
if (ret_pub != 0 || ret_priv != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_pkcs11_find_data_obj(CK_SESSION_HANDLE session,
|
||||
CK_OBJECT_HANDLE *data_obj)
|
||||
{
|
||||
CK_OBJECT_CLASS data_class = CKO_DATA;
|
||||
CK_ATTRIBUTE data_tmpl[] = {
|
||||
{ CKA_CLASS, &data_class, sizeof(data_class) },
|
||||
{ CKA_LABEL, (CK_VOID_PTR)test_data_label, sizeof(test_data_label) - 1 },
|
||||
{ CKA_OBJECT_ID, (CK_VOID_PTR)test_object_id, sizeof(test_object_id) }
|
||||
};
|
||||
|
||||
return test_pkcs11_find_one(session, data_tmpl,
|
||||
(CK_ULONG)(sizeof(data_tmpl) / sizeof(data_tmpl[0])), data_obj);
|
||||
}
|
||||
|
||||
static int test_pkcs11_generate_keypair(CK_SESSION_HANDLE session,
|
||||
CK_OBJECT_HANDLE *pub_obj, CK_OBJECT_HANDLE *priv_obj)
|
||||
{
|
||||
CK_RV rv;
|
||||
CK_MECHANISM mech;
|
||||
CK_BBOOL ck_true = CK_TRUE;
|
||||
CK_ATTRIBUTE pub_tmpl[] = {
|
||||
{ CKA_EC_PARAMS, (CK_VOID_PTR)test_ecc_p256_params, sizeof(test_ecc_p256_params) },
|
||||
{ CKA_VERIFY, &ck_true, sizeof(ck_true) },
|
||||
{ CKA_TOKEN, &ck_true, sizeof(ck_true) },
|
||||
{ CKA_ID, (CK_VOID_PTR)test_key_id, sizeof(test_key_id) },
|
||||
{ CKA_LABEL, (CK_VOID_PTR)test_pub_label, sizeof(test_pub_label) - 1 }
|
||||
};
|
||||
CK_ATTRIBUTE priv_tmpl[] = {
|
||||
{ CKA_EC_PARAMS, (CK_VOID_PTR)test_ecc_p256_params, sizeof(test_ecc_p256_params) },
|
||||
{ CKA_SIGN, &ck_true, sizeof(ck_true) },
|
||||
{ CKA_TOKEN, &ck_true, sizeof(ck_true) },
|
||||
{ CKA_PRIVATE, &ck_true, sizeof(ck_true) },
|
||||
{ CKA_ID, (CK_VOID_PTR)test_key_id, sizeof(test_key_id) },
|
||||
{ CKA_LABEL, (CK_VOID_PTR)test_priv_label, sizeof(test_priv_label) - 1 }
|
||||
};
|
||||
|
||||
mech.mechanism = CKM_EC_KEY_PAIR_GEN;
|
||||
mech.pParameter = NULL;
|
||||
mech.ulParameterLen = 0;
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_GenerateKeyPair(session, &mech,
|
||||
pub_tmpl, (CK_ULONG)(sizeof(pub_tmpl) / sizeof(pub_tmpl[0])),
|
||||
priv_tmpl, (CK_ULONG)(sizeof(priv_tmpl) / sizeof(priv_tmpl[0])),
|
||||
pub_obj, priv_obj);
|
||||
return test_pkcs11_ck_ok("C_GenerateKeyPair", rv);
|
||||
}
|
||||
|
||||
static int test_pkcs11_sign_payload(CK_SESSION_HANDLE session,
|
||||
CK_OBJECT_HANDLE priv_obj, struct test_pkcs11_blob *blob)
|
||||
{
|
||||
CK_RV rv;
|
||||
CK_MECHANISM mech;
|
||||
CK_ULONG payload_len = (CK_ULONG)(sizeof(test_payload) - 1);
|
||||
CK_ULONG sig_len = (CK_ULONG)(sizeof(blob->data) - payload_len);
|
||||
|
||||
mech.mechanism = CKM_ECDSA_SHA256;
|
||||
mech.pParameter = NULL;
|
||||
mech.ulParameterLen = 0;
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_SignInit(session, &mech, priv_obj);
|
||||
if (test_pkcs11_ck_ok("C_SignInit", rv) < 0)
|
||||
return -1;
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_Sign(session,
|
||||
(CK_BYTE_PTR)test_payload, payload_len,
|
||||
blob->data + payload_len, &sig_len);
|
||||
if (test_pkcs11_ck_ok("C_Sign", rv) < 0)
|
||||
return -1;
|
||||
|
||||
memcpy(blob->data, test_payload, (size_t)payload_len);
|
||||
blob->magic = TEST_PKCS11_BLOB_MAGIC;
|
||||
blob->version = TEST_PKCS11_BLOB_VERSION;
|
||||
blob->reserved = 0;
|
||||
blob->payload_len = (uint32_t)payload_len;
|
||||
blob->sig_len = (uint32_t)sig_len;
|
||||
|
||||
printf("pkcs11: signed payload len=%lu sig_len=%lu\r\n",
|
||||
(unsigned long)blob->payload_len, (unsigned long)blob->sig_len);
|
||||
test_pkcs11_log_blob_checksum(blob, "created");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_pkcs11_store_blob(CK_SESSION_HANDLE session,
|
||||
const struct test_pkcs11_blob *blob, CK_OBJECT_HANDLE *data_obj)
|
||||
{
|
||||
CK_RV rv;
|
||||
CK_OBJECT_CLASS data_class = CKO_DATA;
|
||||
CK_BBOOL ck_true = CK_TRUE;
|
||||
CK_ATTRIBUTE tmpl[] = {
|
||||
{ CKA_CLASS, &data_class, sizeof(data_class) },
|
||||
{ CKA_TOKEN, &ck_true, sizeof(ck_true) },
|
||||
{ CKA_APPLICATION, (CK_VOID_PTR)test_application, sizeof(test_application) - 1 },
|
||||
{ CKA_LABEL, (CK_VOID_PTR)test_data_label, sizeof(test_data_label) - 1 },
|
||||
{ CKA_OBJECT_ID, (CK_VOID_PTR)test_object_id, sizeof(test_object_id) },
|
||||
{ CKA_VALUE, (CK_VOID_PTR)blob, (CK_ULONG)(sizeof(*blob) - sizeof(blob->data) + blob->payload_len + blob->sig_len) }
|
||||
};
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_CreateObject(session, tmpl,
|
||||
(CK_ULONG)(sizeof(tmpl) / sizeof(tmpl[0])), data_obj);
|
||||
return test_pkcs11_ck_ok("C_CreateObject(data)", rv);
|
||||
}
|
||||
|
||||
static int test_pkcs11_load_blob(CK_SESSION_HANDLE session,
|
||||
CK_OBJECT_HANDLE data_obj, struct test_pkcs11_blob *blob)
|
||||
{
|
||||
CK_ULONG len = sizeof(*blob);
|
||||
CK_ULONG expected_len;
|
||||
int ret;
|
||||
|
||||
ret = test_pkcs11_get_attr(session, data_obj, CKA_VALUE, (CK_BYTE *)blob, &len);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
if (blob->magic != TEST_PKCS11_BLOB_MAGIC ||
|
||||
blob->version != TEST_PKCS11_BLOB_VERSION)
|
||||
return -1;
|
||||
if (blob->payload_len > sizeof(blob->data) ||
|
||||
blob->sig_len > sizeof(blob->data) ||
|
||||
blob->payload_len + blob->sig_len > sizeof(blob->data))
|
||||
return -1;
|
||||
|
||||
expected_len = (CK_ULONG)(sizeof(*blob) - sizeof(blob->data) +
|
||||
blob->payload_len + blob->sig_len);
|
||||
if (len < expected_len)
|
||||
return -1;
|
||||
|
||||
printf("pkcs11: restored blob payload_len=%lu sig_len=%lu\r\n",
|
||||
(unsigned long)blob->payload_len, (unsigned long)blob->sig_len);
|
||||
test_pkcs11_log_blob_checksum(blob, "restored");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_pkcs11_verify_blob(CK_SESSION_HANDLE session,
|
||||
CK_OBJECT_HANDLE pub_obj, const struct test_pkcs11_blob *blob)
|
||||
{
|
||||
CK_RV rv;
|
||||
CK_MECHANISM mech;
|
||||
|
||||
mech.mechanism = CKM_ECDSA_SHA256;
|
||||
mech.pParameter = NULL;
|
||||
mech.ulParameterLen = 0;
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_VerifyInit(session, &mech, pub_obj);
|
||||
if (test_pkcs11_ck_ok("C_VerifyInit", rv) < 0)
|
||||
return -1;
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_Verify(session,
|
||||
(CK_BYTE_PTR)blob->data, (CK_ULONG)blob->payload_len,
|
||||
(CK_BYTE_PTR)(blob->data + blob->payload_len), (CK_ULONG)blob->sig_len);
|
||||
return test_pkcs11_ck_ok("C_Verify", rv);
|
||||
}
|
||||
|
||||
static int test_pkcs11_log_key_attrs(CK_SESSION_HANDLE session,
|
||||
CK_OBJECT_HANDLE pub_obj, CK_OBJECT_HANDLE priv_obj)
|
||||
{
|
||||
CK_BYTE ec_point[160];
|
||||
CK_ULONG ec_point_len = sizeof(ec_point);
|
||||
|
||||
if (test_pkcs11_log_obj_attr(session, pub_obj, "public", CKA_LABEL) < 0)
|
||||
return -1;
|
||||
if (test_pkcs11_log_obj_attr(session, pub_obj, "public", CKA_ID) < 0)
|
||||
return -1;
|
||||
if (test_pkcs11_log_obj_attr(session, priv_obj, "private", CKA_LABEL) < 0)
|
||||
return -1;
|
||||
if (test_pkcs11_log_obj_attr(session, priv_obj, "private", CKA_ID) < 0)
|
||||
return -1;
|
||||
if (test_pkcs11_get_attr(session, pub_obj, CKA_EC_POINT, ec_point, &ec_point_len) == 0)
|
||||
printf("pkcs11: public attr 0x%08lx len=%lu\r\n",
|
||||
(unsigned long)CKA_EC_POINT, (unsigned long)ec_point_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_pkcs11_start(void)
|
||||
{
|
||||
int wc_ret;
|
||||
CK_RV rv;
|
||||
CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
|
||||
CK_OBJECT_HANDLE pub_obj = CK_INVALID_HANDLE;
|
||||
CK_OBJECT_HANDLE priv_obj = CK_INVALID_HANDLE;
|
||||
CK_OBJECT_HANDLE data_obj = CK_INVALID_HANDLE;
|
||||
struct test_pkcs11_blob blob;
|
||||
int ret;
|
||||
int key_state;
|
||||
int data_state;
|
||||
int result = PKCS11_TEST_FAIL;
|
||||
int session_logged_in = 0;
|
||||
|
||||
memset(&blob, 0, sizeof(blob));
|
||||
|
||||
printf("pkcs11: start\r\n");
|
||||
printf("pkcs11: secure provider=%s\r\n", pkcs11_library_name);
|
||||
|
||||
wc_ret = wolfCrypt_Init();
|
||||
if (wc_ret != 0) {
|
||||
printf("pkcs11: wolfCrypt_Init ret=%d\r\n", wc_ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = wolfpkcs11nsFunctionList.C_Initialize(NULL);
|
||||
if (test_pkcs11_ck_ok("C_Initialize", rv) < 0) {
|
||||
wolfCrypt_Cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = test_pkcs11_open_user_session(&session);
|
||||
if (ret == -2) {
|
||||
printf("pkcs11: first boot path, provisioning token\r\n");
|
||||
if (test_pkcs11_provision_token() < 0) {
|
||||
(void)wolfpkcs11nsFunctionList.C_Finalize(NULL);
|
||||
wolfCrypt_Cleanup();
|
||||
return -1;
|
||||
}
|
||||
ret = test_pkcs11_open_user_session(&session);
|
||||
}
|
||||
if (ret < 0) {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
session_logged_in = 1;
|
||||
|
||||
key_state = test_pkcs11_find_keypair(session, &pub_obj, &priv_obj);
|
||||
if (key_state < 0) {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
data_state = test_pkcs11_find_data_obj(session, &data_obj);
|
||||
if (data_state < 0) {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (key_state == 1 && data_state == 1) {
|
||||
printf("pkcs11: first boot path, creating persistent objects\r\n");
|
||||
if (test_pkcs11_generate_keypair(session, &pub_obj, &priv_obj) < 0)
|
||||
ret = -1;
|
||||
else
|
||||
ret = 0;
|
||||
if (ret == 0)
|
||||
ret = test_pkcs11_sign_payload(session, priv_obj, &blob);
|
||||
if (ret == 0)
|
||||
ret = test_pkcs11_verify_blob(session, pub_obj, &blob);
|
||||
if (ret == 0)
|
||||
ret = test_pkcs11_store_blob(session, &blob, &data_obj);
|
||||
if (ret == 0)
|
||||
ret = test_pkcs11_log_key_attrs(session, pub_obj, priv_obj);
|
||||
if (ret == 0)
|
||||
ret = test_pkcs11_log_obj_attr(session, data_obj, "data", CKA_LABEL);
|
||||
if (ret == 0)
|
||||
ret = test_pkcs11_log_obj_attr(session, data_obj, "data", CKA_OBJECT_ID);
|
||||
if (ret == 0)
|
||||
printf("pkcs11: created persistent PKCS11 objects\r\n");
|
||||
if (ret == 0)
|
||||
result = PKCS11_TEST_FIRST_BOOT_OK;
|
||||
}
|
||||
else if (key_state == 0 && data_state == 0) {
|
||||
printf("pkcs11: second boot path, restoring persistent objects\r\n");
|
||||
ret = test_pkcs11_load_blob(session, data_obj, &blob);
|
||||
if (ret == 0)
|
||||
ret = test_pkcs11_log_key_attrs(session, pub_obj, priv_obj);
|
||||
if (ret == 0)
|
||||
ret = test_pkcs11_log_obj_attr(session, data_obj, "data", CKA_APPLICATION);
|
||||
if (ret == 0)
|
||||
ret = test_pkcs11_verify_blob(session, pub_obj, &blob);
|
||||
if (ret == 0)
|
||||
printf("pkcs11: restored persistent PKCS11 objects\r\n");
|
||||
if (ret == 0)
|
||||
result = PKCS11_TEST_SECOND_BOOT_OK;
|
||||
}
|
||||
else {
|
||||
printf("pkcs11: inconsistent persistent state key_state=%d data_state=%d\r\n",
|
||||
key_state, data_state);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (session != CK_INVALID_HANDLE) {
|
||||
if (session_logged_in)
|
||||
(void)wolfpkcs11nsFunctionList.C_Logout(session);
|
||||
(void)wolfpkcs11nsFunctionList.C_CloseSession(session);
|
||||
}
|
||||
(void)wolfpkcs11nsFunctionList.C_Finalize(NULL);
|
||||
(void)wolfCrypt_Cleanup();
|
||||
|
||||
if (ret == 0)
|
||||
printf("pkcs11: success\r\n");
|
||||
else
|
||||
printf("pkcs11: failure\r\n");
|
||||
|
||||
return (ret == 0) ? result : PKCS11_TEST_FAIL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "test_pkcs11.h"
|
||||
|
||||
int test_pkcs11_start(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* WOLFBOOT_TZ_PKCS11 */
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef WOLFBOOT_TEST_PKCS11_H
|
||||
#define WOLFBOOT_TEST_PKCS11_H
|
||||
|
||||
enum test_pkcs11_result {
|
||||
PKCS11_TEST_FAIL = -1,
|
||||
PKCS11_TEST_FIRST_BOOT_OK = 1,
|
||||
PKCS11_TEST_SECOND_BOOT_OK = 2
|
||||
};
|
||||
|
||||
int test_pkcs11_start(void);
|
||||
|
||||
#endif /* WOLFBOOT_TEST_PKCS11_H */
|
||||
Loading…
Reference in New Issue