|
12 | 12 | #include <fdt.h> |
13 | 13 |
|
14 | 14 | #define RSIZE 256 |
| 15 | +#define PKCS11_URI_BUFFER_SIZE 511 |
15 | 16 |
|
16 | 17 | uint32_t g_image_offset = 0; |
17 | 18 | unsigned long g_ivt_off_cve = 0x0; |
18 | 19 | unsigned long g_ivt_search_step = 0; |
19 | 20 | int g_last_img_idx = 0; |
| 21 | +int g_pkcs11_token = 0; |
20 | 22 |
|
21 | 23 | typedef struct { |
22 | 24 | int cntr_num; |
@@ -264,13 +266,16 @@ int sign_csf(char *cfgname, char *ofname) |
264 | 266 | ASSERT(ofname, -1); |
265 | 267 |
|
266 | 268 | char sys_cmd[SYS_CMD_LEN] = {0}; |
267 | | - char cst_extra_param[10] = {0}; |
| 269 | + char cst_extra_param[20] = {0}; |
268 | 270 |
|
269 | 271 | /* Add debug info to the tool output */ |
270 | 272 | if (g_debug) { |
271 | 273 | strncpy(cst_extra_param, "--verbose", 10); |
272 | 274 | } |
273 | | - |
| 275 | + /* Add -b pcks11 command*/ |
| 276 | + if(g_pkcs11_token) { |
| 277 | + strncpy(cst_extra_param, "-b pkcs11", 10); |
| 278 | + } |
274 | 279 | /* Find if tool exists and capture path */ |
275 | 280 | if (!find_cst_tool(&sys_cmd[0])) { |
276 | 281 | 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) |
357 | 362 | FCLOSE(fp_ofname); |
358 | 363 | return -E_FAILURE; |
359 | 364 | } |
| 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 | +} |
360 | 428 |
|
| 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 | +} |
361 | 519 | /* |
362 | 520 | * @brief Create CSF source file for IVT type v1 |
363 | 521 | * |
@@ -446,15 +604,30 @@ static int create_csf_file_v1(image_block_t *blocks, int idx, char *ofname) |
446 | 604 | fast_auth = true; |
447 | 605 | /* Install NOCAK */ |
448 | 606 | 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); |
450 | 616 | } else { |
451 | 617 | /* Prepare normal authentication parameters */ |
452 | 618 | /* Install CSFK */ |
453 | 619 | fprintf(fp_csf_file, "[Install CSFK]\n"); |
454 | 620 | cfg_parser(fp_cfg, rvalue, RSIZE, "csfk_file"); |
455 | 621 | if ('\0' == rvalue[0]) |
456 | 622 | 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 */ |
458 | 631 | fprintf(fp_csf_file, "\tFile = \"%s/crts/%s\"\n", g_sig_tool_path, rvalue); |
459 | 632 | } |
460 | 633 |
|
@@ -558,7 +731,14 @@ static int create_csf_file_v1(image_block_t *blocks, int idx, char *ofname) |
558 | 731 | cfg_parser(fp_cfg, rvalue, RSIZE, "img_file"); |
559 | 732 | if ('\0' == rvalue[0]) |
560 | 733 | 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 */ |
562 | 742 | fprintf(fp_csf_file, "\tFile = \"%s/crts/%s\"\n", g_sig_tool_path, rvalue); |
563 | 743 | } |
564 | 744 |
|
@@ -664,7 +844,7 @@ static int create_csf_file_v3(char *csf_filename, char *ifname, csf_params_t *cs |
664 | 844 | if ('\0' == rvalue[0]) |
665 | 845 | fprintf(fp_csf_file, "\tSource = \"%s/crts/SRK1_sha256_prime256v1_v3_ca_crt.pem\"\n", g_sig_tool_path); |
666 | 846 | 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); |
668 | 848 |
|
669 | 849 | cfg_parser(fp_cfg, rvalue, RSIZE, "srk_source_index"); |
670 | 850 | if ('\0' == rvalue[0]) |
|
0 commit comments