diff --git a/cli/mfg.c b/cli/mfg.c index ee41e11..ab65c8e 100755 --- a/cli/mfg.c +++ b/cli/mfg.c @@ -58,6 +58,8 @@ #define PING_SPI_CLK_SEL_MASK 0x30000 #define PING_SPI_CLK_SEL_OFFSET 16 #define PING_SPI_BUS_RATE_MASK 0xFFFF +#define MIN_PORT 1 +#define MAX_PORT 65535 static const struct argconfig_choice recovery_mode_choices[] = { {"I2C", SWITCHTEC_BL2_RECOVERY_I2C, "I2C"}, @@ -2307,33 +2309,67 @@ static int sjtag_unlock(int argc, char **argv) struct switchtec_sn_ver_info sn_info = {}; uint8_t sjtag_hr[SJTAG_HR_LEN]; struct sjtag_debug_token debug_token; - FILE *debug_token_bin_file; - char dir_path[1024]; + const char *port_str; + unsigned long temp; + char *endptr = NULL; int ret; static struct { struct switchtec_dev *dev; FILE *sjtag_debug_token; const char *sjtag_debug_token_file; + int out_fd; + const char *out_filename; + const char *sjtag_server_ip; + uint16_t sjtag_server_port; bool verbose; bool force_hr; } cfg = { - .verbose = false, - .force_hr = false}; + .out_fd = -1, + .sjtag_server_ip = NULL, + .sjtag_server_port = 0, + .verbose = false, + .force_hr = false}; const struct argconfig_options opts[] = { DEVICE_OPTION_MFG, - {"sjtag_debug_token_file", - .cfg_type=CFG_FILE_R, - .value_addr=&cfg.sjtag_debug_token, - .argument_type=optional_positional, - .help="Optional Argument. If not provided, the Debug Token will be generated\n"\ - "SJTAG Debug Token File(.bin)\n" \ - "Generated by the HSM Server\n"}, - {"verbose", 'v', "", CFG_NONE, &cfg.verbose, no_argument, - "print additional sjtag-unlock information"}, - {"force_hr", 'f', "", CFG_NONE, &cfg.force_hr, no_argument, - "send HR for all SJTAG mode"}, + { + "debug_token_input_file", 'i', + .cfg_type=CFG_FILE_R, + .value_addr=&cfg.sjtag_debug_token, + .argument_type=required_argument, + .help="Optional Argument. If provided the input debug token file will be used for SJTAG Unlocking. If not provided, HSM server will be used for SJTAG Unlocking and the Debug Token (.bin) will be generated\n" \ + "Note: When both -i and -o are provided, -i overides -o\n" + }, + { + "debug_token_output_file", 'o', + .cfg_type=CFG_FD_WR, + .value_addr=&cfg.out_fd, + .argument_type=required_argument, + .help="Optional Argument. If not provided, the HSM generated Debug Token File will be named sjtag_debug_token.bin\n" + }, + { + "sjtag_server_ip", 's', + .cfg_type=CFG_STRING, + .value_addr=&cfg.sjtag_server_ip, + .argument_type=required_argument, + .help="SJTAG HSM Server IP. Can also set via HSM_SERVER_IP environment variable." + }, + { + "sjtag_server_port", 'p', + .cfg_type=CFG_SHORT, + .value_addr=&cfg.sjtag_server_port, + .argument_type=required_argument, + .help="SJTAG HSM Server Port. Can also set via HSM_SERVER_PORT environment variable." + }, + { + "verbose", 'v', "", CFG_NONE, &cfg.verbose, no_argument, + "print additional sjtag-unlock information" + }, + { + "force_hr", 'f', "", CFG_NONE, &cfg.force_hr, no_argument, + "send HR for all SJTAG mode" + }, {NULL} }; @@ -2349,7 +2385,7 @@ static int sjtag_unlock(int argc, char **argv) break; } - if(true == cfg.verbose) + if (true == cfg.verbose) { printf("SJTAG Mode: %x\n", (status.data & 0x03)); } @@ -2365,8 +2401,22 @@ static int sjtag_unlock(int argc, char **argv) } else { + /* Open default output file only if no input file is provided */ + if (!cfg.sjtag_debug_token_file && cfg.out_fd < 0) + { + cfg.out_filename = "sjtag_debug_token.bin"; + cfg.out_fd = open(cfg.out_filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (cfg.out_fd < 0) + { + perror("Failed to open default output file"); + ret = -1; + break; + } + } + if (cfg.sjtag_debug_token_file) { + printf("HSM not used for Debug Token Generation. Using provided Debug Token(-i) for Unlocking.\n"); ret = switchtec_read_sjtag_debug_token_file(cfg.sjtag_debug_token, &debug_token); fclose(cfg.sjtag_debug_token); if (ret) @@ -2378,11 +2428,56 @@ static int sjtag_unlock(int argc, char **argv) } else { + /* If SJTAG IP and Port are not provided fetch it from environment variables*/ + if (cfg.sjtag_server_ip == NULL) + { + cfg.sjtag_server_ip = getenv("HSM_SERVER_IP"); + } + + if (cfg.sjtag_server_port == 0) + { + /* Environment variables are always strings. convert the string to integer */ + port_str = getenv("HSM_SERVER_PORT"); + if (port_str != NULL) + { + errno = 0; + temp = strtoul(port_str, &endptr, 10); + + if ((errno != 0) || temp > MAX_PORT || temp < MIN_PORT || endptr == port_str || *endptr != '\0') + { + fprintf(stderr, "Error: Invalid port number in HSM_SERVER_PORT environment variable\n"); + ret = -1; + if (cfg.out_fd > 0) + { + close(cfg.out_fd); + } + break; + } + cfg.sjtag_server_port = (uint16_t)temp; + } + } + + /* Check for Invalid IP and Port */ + if((cfg.sjtag_server_ip == NULL) || (cfg.sjtag_server_port == 0)) + { + fprintf(stderr, "Error: SJTAG server IP and Port are required when generating token from HSM server.\n"); + ret = -1; + if (cfg.out_fd > 0) + { + close(cfg.out_fd); + } + break; + } + ret = switchtec_sjtag_get_uuid_idcode(cfg.dev, uuid.uuid, sjtag_unlock.idcode); if (ret) { switchtec_perror("Failed to retrive the UUID/IDCODE from the device"); ret = -1; + if (cfg.out_fd > 0) + { + close(cfg.out_fd); + } break; } @@ -2391,28 +2486,51 @@ static int sjtag_unlock(int argc, char **argv) { switchtec_perror("Failed to retrive the SUV from the device"); ret = -1; + if (cfg.out_fd > 0) + { + close(cfg.out_fd); + } break; } - ret = sjtag_debug_token_gen(sjtag_unlock.idcode, uuid.uuid, (uint8_t *)&sn_info.ver_sec_unlock, debug_token.debug_token, cfg.verbose); + ret = sjtag_debug_token_gen(sjtag_unlock.idcode, + uuid.uuid, + (uint8_t *)&sn_info.ver_sec_unlock, + debug_token.debug_token, + cfg.sjtag_server_ip, + cfg.sjtag_server_port, + cfg.verbose); + if(ret) { ret = -1; + if (cfg.out_fd > 0) + { + close(cfg.out_fd); + } break; } - debug_token_bin_file = fopen("sjtag_debug_token.bin", "wb"); - if (NULL == debug_token_bin_file) + /* Save the generated Debug Token as a binary */ + ret = write(cfg.out_fd, debug_token.debug_token, SJTAG_DEBUG_TOKEN_LEN); + + close(cfg.out_fd); + + if (ret != SJTAG_DEBUG_TOKEN_LEN) { - switchtec_perror("Error opening file"); + if (ret < 0) + { + perror("Error saving the Debug token"); + } + else + { + perror("Error: Incomplete Debug Token"); + } ret = -1; break; - } + } - fwrite(debug_token.debug_token, sizeof(uint8_t), SJTAG_DEBUG_TOKEN_LEN, debug_token_bin_file); - fclose(debug_token_bin_file); - getcwd(dir_path, sizeof(dir_path)); - printf("Generated SJTAG Debug Token Path: %s/sjtag_debug_token.bin\n", dir_path); + fprintf(stdout, "\nGenerated SJTAG Debug token saved to %s\n", cfg.out_filename); } ret = switchtec_sjtag_get_nonce(cfg.dev, &nonce); @@ -2437,6 +2555,7 @@ static int sjtag_unlock(int argc, char **argv) } } }while(false); + return ret; } /* sjtag_unlock() */ diff --git a/inc/switchtec/mfg.h b/inc/switchtec/mfg.h index a92d660..88d8320 100755 --- a/inc/switchtec/mfg.h +++ b/inc/switchtec/mfg.h @@ -60,8 +60,6 @@ #define SKU_NO_OF_BLOCKS 4 -#define SJTAG_SERVER_IP "10.40.56.34" -#define SJTAG_SERVER_PORT (5001) #define SJTAG_SERVER_HEADER_LEN (4) #define SJTAG_IDCODE_LEN (4) #define SJTAG_HR_LEN (32) @@ -394,7 +392,7 @@ int switchtec_sjtag_hr_send(struct switchtec_dev *dev, int switchtec_read_sjtag_debug_token_file(FILE *debug_token_file, struct sjtag_debug_token *debug_token); void sjtag_hr_calc(uint8_t *sjtag_debug_token, uint8_t *sjtag_nonce, uint8_t *digest, bool verbose); -int sjtag_debug_token_gen(uint8_t *idcode_ptr, uint8_t *uuid_ptr, uint8_t *suv_ptr, uint8_t *sjtag_debug_token, bool verbose); +int sjtag_debug_token_gen(uint8_t *idcode_ptr, uint8_t *uuid_ptr, uint8_t *suv_ptr, uint8_t *sjtag_debug_token, const char *server_ip, uint16_t server_port, bool verbose); void sjtag_hr_compute(uint8_t *sjtag_uuid, uint8_t *sjtag_suv, uint8_t *sjtag_nonce, uint8_t *sjtag_hr); diff --git a/lib/mfg.c b/lib/mfg.c index a1ab756..d2e2c40 100755 --- a/lib/mfg.c +++ b/lib/mfg.c @@ -1001,7 +1001,7 @@ int sjtag_resp_is_success(uint8_t *resp_header) * * @return Returns 0 on Success and -1 on Failure */ -int sjtag_debug_token_gen(uint8_t *idcode_ptr, uint8_t *uuid_ptr, uint8_t *suv_ptr, uint8_t *sjtag_debug_token, bool verbose) +int sjtag_debug_token_gen(uint8_t *idcode_ptr, uint8_t *uuid_ptr, uint8_t *suv_ptr, uint8_t *sjtag_debug_token, const char *server_ip, uint16_t server_port, bool verbose) { int ret = 0; int socket_server; @@ -1024,8 +1024,8 @@ int sjtag_debug_token_gen(uint8_t *idcode_ptr, uint8_t *uuid_ptr, uint8_t *suv_p /* Set port and IP */ server_address.sin_family = AF_INET; - server_address.sin_port = htons(SJTAG_SERVER_PORT); - server_address.sin_addr.s_addr = inet_addr(SJTAG_SERVER_IP); + server_address.sin_port = htons(server_port); + server_address.sin_addr.s_addr = inet_addr(server_ip); /* Send a connection request to Plugin server */ if(connect(socket_server, (struct sockaddr*)&server_address, sizeof(server_address)) < 0)