Skip to content

Commit f068650

Browse files
marioicastalutkarshguptanxp
authored andcommitted
Pull request #5: Feature/MICRSE-3703 imx signer add pkcs11 backend for cst hab and spsdk ahab
Merge in IMXS/cst-signer from feature/MICRSE-3703-imx-signer-add-pkcs11-backend-for-cst-hab-and-spsdk-ahab to master * commit '1c477bda6e2625cae88832212a2457868002b6cb': [MICRSE-3703] Create build_pkcs11_uri routine for the pkcs11 string and Support for NOCAK Fast Authentication Applying Suggestion, env_result, replacing conditions about the pkcs11 token Applying suggestion. The parse method is looking for an extact string. Fix format and adding .gitignore [MICRSE-3703] Updating Pull Request Requirements MICRSE-3703: PCKS11 Support for HAB, with/wihtout token and usr pin definition PCKS11 Implementation withe img file. PKCS11 Support for CSF Complete TODO: Working to create a function that implements this routine PCKS11 Implementation defining token in the csf file PKCS11 Token support. - CSF config file is looking for the token in the csfk_file and img_file - Adding -b pkcs11 extra param - TODO Implement a new strncpy and avoid overwrite --verbose command Adding verify routing if there is a Interact Token for the image0
2 parents f300c0c + 1c477bd commit f068650

5 files changed

Lines changed: 241 additions & 11 deletions

File tree

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Compiled object files
2+
src/cst_signer
3+
*.bin
4+
*.o
5+
*.obj
6+
*.out
7+

README.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,28 @@ YAML config file filled with appropriate values based on the setup.
6565
To help start the signing process, sample CSF/YAML configuration files have
6666
been provided as part of this package.
6767

68-
CFG file supporting HAB images: *csf_hab4.cfg.sample*
69-
CFG file supporting AHAB images: *csf_ahab.cfg.sample*, *spsdk_ahab.cfg.sample*
68+
- **CFG file supporting HAB images:** *csf_hab4.cfg.sample* or *csf_hab4_pkcs11.cfg.sample* for PKCS#11 Support
69+
- **CFG file supporting AHAB images:** *csf_ahab.cfg.sample*, *spsdk_ahab.cfg.sample*
70+
71+
**_NOTE_**: Be sure the PKCS#11 support is enabled and Token and USR_PIN environmental variables are defined.
7072

7173
Invoke the *imx_signer* executable as follows (example):
72-
CST Example: `SIG_TOOL_PATH=<cst> SIG_DATA_PATH=<keys/crts folder> ./imx_signer -i flash.bin -c csf.cfg`
73-
SPSDK Example: `SIG_TOOL_PATH=<spsdk> SIG_DATA_PATH=<keys/crts folder> ./imx_signer -i flash.bin -c spsdk.cfg`
74+
```sh
75+
# CST Example:
76+
$ SIG_TOOL_PATH=<cst> SIG_DATA_PATH=<keys/crts folder> ./imx_signer -i flash.bin -c csf.cfg
77+
# SPSDK Example:
78+
$ SIG_TOOL_PATH=<spsdk> SIG_DATA_PATH=<keys/crts folder> ./imx_signer -i flash.bin -c spsdk.cfg
79+
```
7480

75-
---
81+
### PKCS#11 Support HAB
82+
For PKCS#11-based signing with Hardware Security Modules (HSMs), configure your CSF file using the **exact format**:
83+
```sh
84+
csfk_file=pkcs11:token=${PKCS-TOKEN};object=CSF1_1_sha256_2048_65537_v3_usr;type=cert;pin-value=${USR_PIN}
85+
img_file=pkcs11:token=${PKCS-TOKEN};object=IMG1_1_sha256_2048_65537_v3_usr;type=cert;pin-value=${USR_PIN}
86+
```
87+
**_NOTE_**: Be sure the PKCS#11 support is enabled and Token and USR_PIN environmental variables are defined.
7688

89+
---
7790
### Results
7891

7992
This tool generates final signed binary as "**signed-\<input_filename\>**". In

csf_hab4_pkcs11.cfg.sample

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#Header
2+
header_version=4.3
3+
header_eng=ANY
4+
header_eng_config=0
5+
#Install SRK
6+
srktable_file=SRK_1_2_3_4_table_8mini.bin
7+
srk_source_index=0
8+
#Install NOCAK
9+
nocak_file=
10+
#Install CSFK
11+
csfk_file=pkcs11:token=${PKCS-DEMO};object=CSF1_1_sha256_2048_65537_v3_usr;type=cert;pin-value=${USR_PIN}
12+
#Unlock
13+
unlock_engine=
14+
unlock_features=
15+
unlock_uid=
16+
#Install Key
17+
img_verification_index=0
18+
img_target_index=2
19+
img_file=pkcs11:token=${PKCS-DEMO};object=IMG1_1_sha256_2048_65537_v3_usr;type=cert;pin-value=${USR_PIN}
20+
#Authenticate Data
21+
auth_verification_index=2

inc/imx_signer.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ typedef enum SOC_TYPE {
102102
ULP,
103103
} soc_type_t;
104104

105+
typedef enum PKCS_TOKEN {
106+
PCKS11_ENV = 1,
107+
TOKEN_EN = 2,
108+
OBJ_TYPE = 4,
109+
TYPE_CERT = 8,
110+
USRPIN = 16,
111+
COMPLETE_CONF = 31,
112+
} pkcs11token_type_t;
113+
105114
#define E_OK 0
106115
#define E_FAILURE 1
107116

src/imx_signer.c

Lines changed: 186 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
#include <fdt.h>
1313

1414
#define RSIZE 256
15+
#define PKCS11_URI_BUFFER_SIZE 511
1516

1617
uint32_t g_image_offset = 0;
1718
unsigned long g_ivt_off_cve = 0x0;
1819
unsigned long g_ivt_search_step = 0;
1920
int g_last_img_idx = 0;
21+
int g_pkcs11_token = 0;
2022

2123
typedef struct {
2224
int cntr_num;
@@ -264,13 +266,16 @@ int sign_csf(char *cfgname, char *ofname)
264266
ASSERT(ofname, -1);
265267

266268
char sys_cmd[SYS_CMD_LEN] = {0};
267-
char cst_extra_param[10] = {0};
269+
char cst_extra_param[20] = {0};
268270

269271
/* Add debug info to the tool output */
270272
if (g_debug) {
271273
strncpy(cst_extra_param, "--verbose", 10);
272274
}
273-
275+
/* Add -b pcks11 command*/
276+
if(g_pkcs11_token) {
277+
strncpy(cst_extra_param, "-b pkcs11", 10);
278+
}
274279
/* Find if tool exists and capture path */
275280
if (!find_cst_tool(&sys_cmd[0])) {
276281
if (0 > (snprintf(sys_cmd + strlen(sys_cmd), (SYS_CMD_LEN - strlen(sys_cmd)), " %s --i %s --o %s", cst_extra_param, cfgname, ofname))) {
@@ -357,7 +362,160 @@ int copy_files(char *ifname, char *ofname)
357362
FCLOSE(fp_ofname);
358363
return -E_FAILURE;
359364
}
365+
/*
366+
* @brief Extract config value from a string with environment variable handling
367+
*
368+
* @param[in] rvalue : Configuration value string
369+
*
370+
* @retval config_value : Extracted config value with env variable resolved
371+
*/
372+
static char *extract_config_value(const char *rvalue)
373+
{
374+
char *search_equal = strchr(rvalue, '=');
375+
char *config_value = malloc(100);
376+
int skip = 0;
377+
378+
if (search_equal == NULL || config_value == NULL ) {
379+
DEBUG("Search Token Error\n");
380+
DEBUG("Memory allocation failed\n");
381+
return NULL;
382+
}
383+
384+
strncpy(&config_value[0],&search_equal[1],99);
385+
config_value[99]='\0';
386+
strtok(config_value, ";");
387+
if (config_value == NULL) {
388+
FREE(config_value);
389+
return NULL;
390+
}
391+
392+
char *source = &config_value[0];
393+
if (*source == '$') {
394+
skip++;
395+
if (source[1] == '{') {
396+
skip++;
397+
}
398+
}
399+
strncpy(&config_value[0], source + skip,99);
400+
config_value[99]='\0';
401+
strtok(&config_value[0], "}");
402+
403+
return config_value;
404+
}
405+
/*
406+
* @brief Detect and validate PKCS11 Config Param
407+
*
408+
* @param[in] config_value : String with the PKCS11 configuration parameters
409+
*
410+
* @retval flags : PKCS11 configuration validation flags
411+
*/
412+
static int detect_pkcs11_config(const char *config_value) {
413+
if (!config_value)
414+
return 0;
415+
int flags = 0;
416+
if (strstr(config_value, "pkcs11"))
417+
flags |= PCKS11_ENV;
418+
if (strstr(config_value, "token="))
419+
flags |= TOKEN_EN;
420+
if (strstr(config_value, "object="))
421+
flags |= OBJ_TYPE;
422+
if (strstr(config_value, "type=cert"))
423+
flags |= TYPE_CERT;
424+
if (strstr(config_value, "pin-value"))
425+
flags |= USRPIN;
426+
return flags;
427+
}
360428

429+
/*
430+
* @brief Build PKCS11 URI string from configuration value
431+
*
432+
* @param[in] rvalue : Configuration value string containing PKCS11 parameters
433+
*
434+
* @retval pkcs11_uri : Complete PKCS11 URI string, or NULL on failure
435+
* Caller is responsible for freeing the returned string
436+
*/
437+
static char *build_pkcs11_uri(const char *rvalue) {
438+
ASSERT(rvalue, NULL);
439+
440+
char *pkcs11_uri = NULL; /* PKCS11 URI string buffer */
441+
char *env_result = NULL; /* Env result for Token*/
442+
char *config_object = NULL; /* Configuration object identifier */
443+
char *pkcs11_token_pin = NULL; /* Token or Pin values*/
444+
445+
/* Allocate buffer for the complete PKCS11 URI */
446+
pkcs11_uri = calloc(PKCS11_URI_BUFFER_SIZE+1, sizeof(char));
447+
if (NULL == pkcs11_uri) {
448+
DEBUG("ERROR: Error allocating memory for PKCS11 URI\n");
449+
return NULL;
450+
}
451+
452+
/* Check if configuration is complete */
453+
g_pkcs11_token = detect_pkcs11_config(rvalue); /* Set global flag*/
454+
if ( g_pkcs11_token != COMPLETE_CONF) {
455+
DEBUG("ERROR: Invalid PKCS11 configuration \n");
456+
goto err;
457+
}
458+
459+
/* Start building the PKCS11 URI */
460+
strncpy(pkcs11_uri, "\"pkcs11:token=", 15);
461+
462+
/* Extract and process token configuration */
463+
env_result = extract_config_value(rvalue);
464+
if (env_result != NULL) {
465+
pkcs11_token_pin = getenv(env_result);
466+
if (pkcs11_token_pin != NULL) {
467+
DEBUG("Token env variable PKCS11_Token: %s\n", pkcs11_token_pin);
468+
strncat(pkcs11_uri, pkcs11_token_pin, PKCS11_URI_BUFFER_SIZE - strlen(pkcs11_uri));
469+
} else
470+
strncat(pkcs11_uri, env_result, PKCS11_URI_BUFFER_SIZE - strlen(pkcs11_uri));
471+
} else
472+
goto err;
473+
474+
/* Extract and add object configuration */
475+
config_object = extract_config_value(strchr(rvalue, ';'));
476+
if (config_object != NULL) {
477+
strncat(pkcs11_uri, ";object=", PKCS11_URI_BUFFER_SIZE - strlen(pkcs11_uri));
478+
strncat(pkcs11_uri, config_object, PKCS11_URI_BUFFER_SIZE - strlen(pkcs11_uri));
479+
} else
480+
goto err;
481+
482+
pkcs11_token_pin = NULL;
483+
env_result = NULL;
484+
485+
/* Add type=cert */
486+
strncat(pkcs11_uri, ";type=cert", PKCS11_URI_BUFFER_SIZE - strlen(pkcs11_uri));
487+
488+
/* Extract and add PIN configuration */
489+
env_result = extract_config_value(strrchr(rvalue, ';'));
490+
if (env_result != NULL) {
491+
pkcs11_token_pin = getenv(env_result);
492+
DEBUG("USR_PIN environment variable %s and %s\n", env_result, pkcs11_token_pin);
493+
strncat(pkcs11_uri, ";pin-value=", PKCS11_URI_BUFFER_SIZE - strlen(pkcs11_uri));
494+
if (pkcs11_token_pin != NULL)
495+
strncat(pkcs11_uri, pkcs11_token_pin, PKCS11_URI_BUFFER_SIZE - strlen(pkcs11_uri));
496+
else
497+
strncat(pkcs11_uri, env_result, PKCS11_URI_BUFFER_SIZE - strlen(pkcs11_uri));
498+
FREE(env_result);
499+
} else
500+
goto err;
501+
502+
/* Close the URI string */
503+
strncat(pkcs11_uri, "\"", PKCS11_URI_BUFFER_SIZE - strlen(pkcs11_uri));
504+
505+
FREE(pkcs11_token_pin);
506+
FREE(config_object);
507+
FREE(env_result);
508+
FREE(pkcs11_uri);
509+
510+
return pkcs11_uri;
511+
512+
err:
513+
FREE(pkcs11_token_pin);
514+
FREE(config_object);
515+
FREE(env_result);
516+
FREE(pkcs11_uri);
517+
return NULL;
518+
}
361519
/*
362520
* @brief Create CSF source file for IVT type v1
363521
*
@@ -446,15 +604,30 @@ static int create_csf_file_v1(image_block_t *blocks, int idx, char *ofname)
446604
fast_auth = true;
447605
/* Install NOCAK */
448606
fprintf(fp_csf_file, "[Install NOCAK]\n");
449-
fprintf(fp_csf_file, "\tFile = \"%s/crts/%s\"\n", g_sig_tool_path, rvalue);
607+
if (!strncmp (&rvalue[0], "pkcs11",6)) { /* PKCS11 Based Signing */
608+
char *pkcs11_uri = build_pkcs11_uri(rvalue);
609+
if (pkcs11_uri != NULL) {
610+
fprintf(fp_csf_file, "\tFile = %s\n", pkcs11_uri);
611+
FREE(pkcs11_uri);
612+
} else
613+
return -E_FAILURE;
614+
} else
615+
fprintf(fp_csf_file, "\tFile = \"%s/crts/%s\"\n", g_sig_tool_path, rvalue);
450616
} else {
451617
/* Prepare normal authentication parameters */
452618
/* Install CSFK */
453619
fprintf(fp_csf_file, "[Install CSFK]\n");
454620
cfg_parser(fp_cfg, rvalue, RSIZE, "csfk_file");
455621
if ('\0' == rvalue[0])
456622
fprintf(fp_csf_file, "\tFile = \"%s/crts/CSF1_1_sha256_2048_65537_v3_usr_crt.pem\"\n", g_sig_tool_path);
457-
else
623+
else if (!strncmp (&rvalue[0], "pkcs11",6)) { /* PKCS11 Based Signing */
624+
char *pkcs11_uri = build_pkcs11_uri(rvalue);
625+
if (pkcs11_uri != NULL) {
626+
fprintf(fp_csf_file, "\tFile = %s\n", pkcs11_uri);
627+
FREE(pkcs11_uri);
628+
} else
629+
return -E_FAILURE;
630+
} else /* File Based Signing */
458631
fprintf(fp_csf_file, "\tFile = \"%s/crts/%s\"\n", g_sig_tool_path, rvalue);
459632
}
460633

@@ -558,7 +731,14 @@ static int create_csf_file_v1(image_block_t *blocks, int idx, char *ofname)
558731
cfg_parser(fp_cfg, rvalue, RSIZE, "img_file");
559732
if ('\0' == rvalue[0])
560733
fprintf(fp_csf_file, "\tFile = \"%s/crts/IMG1_1_sha256_2048_65537_v3_usr_crt.pem\"\n", g_sig_tool_path);
561-
else
734+
else if (!strncmp (&rvalue[0], "pkcs11",6)) { /* PKCS11 Based Signing */
735+
char *pkcs11_uri = build_pkcs11_uri(rvalue);
736+
if (pkcs11_uri != NULL) {
737+
fprintf(fp_csf_file, "\tFile = %s\n", pkcs11_uri);
738+
FREE(pkcs11_uri);
739+
} else
740+
return -E_FAILURE;
741+
} else /* File Based Signing */
562742
fprintf(fp_csf_file, "\tFile = \"%s/crts/%s\"\n", g_sig_tool_path, rvalue);
563743
}
564744

@@ -664,7 +844,7 @@ static int create_csf_file_v3(char *csf_filename, char *ifname, csf_params_t *cs
664844
if ('\0' == rvalue[0])
665845
fprintf(fp_csf_file, "\tSource = \"%s/crts/SRK1_sha256_prime256v1_v3_ca_crt.pem\"\n", g_sig_tool_path);
666846
else
667-
fprintf(fp_csf_file, "\tSource = \"%s/crts/%s\"\n", g_sig_tool_path, rvalue);
847+
fprintf(fp_csf_file, "\tSource = \"%s/crts/%s\"\n", g_sig_data_path, rvalue);
668848

669849
cfg_parser(fp_cfg, rvalue, RSIZE, "srk_source_index");
670850
if ('\0' == rvalue[0])

0 commit comments

Comments
 (0)