46 #include "switchtec_priv.h"
48 #include "switchtec/mfg.h"
49 #include "switchtec/errors.h"
50 #include "switchtec/endian.h"
51 #include "switchtec/mrpc.h"
52 #include "switchtec/errors.h"
58 #include <openssl/sha.h>
59 #include <arpa/inet.h>
68 #include <openssl/pem.h>
70 #define SWITCHTEC_ACTV_IMG_ID_KMAN 1
71 #define SWITCHTEC_ACTV_IMG_ID_BL2 2
72 #define SWITCHTEC_ACTV_IMG_ID_CFG 3
73 #define SWITCHTEC_ACTV_IMG_ID_FW 4
75 #define SWITCHTEC_MB_MAX_ENTRIES 16
76 #define SWITCHTEC_ACTV_IDX_MAX_ENTRIES 32
77 #define SWITCHTEC_ACTV_IDX_SET_ENTRIES 4
79 #define SWITCHTEC_CLK_RATE_BITSHIFT 2
80 #define SWITCHTEC_CLK_RATE_BITMASK 0x0f
81 #define SWITCHTEC_RC_TMO_BITSHIFT 6
82 #define SWITCHTEC_RC_TMO_BITMASK 0x0f
83 #define SWITCHTEC_I2C_PORT_BITSHIFT 10
84 #define SWITCHTEC_I2C_PORT_BITMASK 0x0f
85 #define SWITCHTEC_I2C_ADDR_BITSHIFT 14
86 #define SWITCHTEC_I2C_ADDR_BITSHIFT_GEN5 23
87 #define SWITCHTEC_I2C_ADDR_BITMASK 0x7f
88 #define SWITCHTEC_CMD_MAP_BITSHIFT 21
89 #define SWITCHTEC_CMD_MAP_BITSHIFT_GEN5 30
90 #define SWITCHTEC_CMD_MAP_BITMASK 0xffff
91 #define SWITCHTEC_CMD_MAP_BITMASK_GEN5 0x3fff
93 #define SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK 0x40
94 #define SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK 0x80
95 #define SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK 0x0100
96 #define SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK 0x0200
99 const void *payload,
size_t payload_len,
100 void *resp,
size_t resp_len);
102 #if (HAVE_LIBCRYPTO && !HAVE_DECL_RSA_GET0_KEY)
113 static void RSA_get0_key(
const RSA *r,
const BIGNUM **n,
114 const BIGNUM **e,
const BIGNUM **d)
135 uint32_t *map_shift, uint32_t *map_mask)
137 if (gen > SWITCHTEC_GEN4) {
138 *addr_shift = SWITCHTEC_I2C_ADDR_BITSHIFT_GEN5;
139 *map_shift = SWITCHTEC_CMD_MAP_BITSHIFT_GEN5;
140 *map_mask = SWITCHTEC_CMD_MAP_BITMASK_GEN5;
142 *addr_shift = SWITCHTEC_I2C_ADDR_BITSHIFT;
143 *map_shift = SWITCHTEC_CMD_MAP_BITSHIFT;
144 *map_mask = SWITCHTEC_CMD_MAP_BITMASK;
148 static float spi_clk_rate_float[] = {
149 25, 150, 137.5, 125.25, 100, 66.67, 50, 40, 33.33, 28.58
152 static float spi_clk_hi_rate_float[] = {
153 120, 80, 60, 48, 40, 34, 30, 26.67, 24, 21.82
156 #pragma pack(push, 1)
159 uint32_t public_key_exponent;
168 uint8_t public_key_num;
169 uint8_t public_key_ver;
170 uint8_t spi_core_clk_high;
171 uint8_t public_key[SWITCHTEC_KMSK_NUM][SWITCHTEC_KMSK_LEN];
194 MRPC_SECURITY_CONFIG_GET_GEN5,
195 &subcmd,
sizeof(subcmd),
201 &subcmd,
sizeof(subcmd),
203 if (ret && ERRNO_MRPC(errno) != ERR_CMD_INVALID)
239 rates->num_rates = 10;
240 if (reply.spi_core_clk_high)
241 memcpy(rates->rates, spi_clk_hi_rate_float,
242 sizeof(spi_clk_hi_rate_float));
244 memcpy(rates->rates, spi_clk_rate_float,
245 sizeof(spi_clk_rate_float));
260 otp->basic_valid = !!(flags & BIT(7));
261 otp->basic = !!(flags & BIT(8));
262 otp->mixed_ver_valid = !!(flags & BIT(9));
263 otp->mixed_ver = !!(flags & BIT(10));
264 otp->main_fw_ver_valid = !!(flags & BIT(11));
265 otp->main_fw_ver = !!(flags & BIT(12));
266 otp->sec_unlock_ver_valid = !!(flags & BIT(13));
267 otp->sec_unlock_ver = !!(flags & BIT(14));
268 otp->kmsk_valid[0] = !!(flags & BIT(15));
269 otp->kmsk[0] = !!(flags & BIT(16));
270 otp->kmsk_valid[1] = !!(flags & BIT(17));
271 otp->kmsk[1] = !!(flags & BIT(18));
272 otp->kmsk_valid[2] = !!(flags & BIT(19));
273 otp->kmsk[2] = !!(flags & BIT(20));
274 otp->kmsk_valid[3] = !!(flags & BIT(21));
275 otp->kmsk[3] = !!(flags & BIT(22));
299 reply.valid = le32toh(reply.valid);
300 reply.cfg_stmfd.cfg = le64toh(reply.cfg_stmfd.cfg);
301 reply.cfg_stmfd.public_key_exponent = le32toh(reply.cfg_stmfd.public_key_exponent);
303 state->basic_setting_valid = !!(reply.valid & 0x01);
304 state->public_key_num_valid = !!(reply.valid & 0x02);
305 state->public_key_ver_valid = !!(reply.valid & 0x04);
306 state->kmsk_valid = !!(reply.valid & 0x78);
308 state->otp_valid = otp_valid;
312 state->secure_state = (reply.cfg_stmfd.cfg) & 0x03;
314 spi_clk = (reply.cfg_stmfd.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) & 0x0f;
317 if(0 == state->secure_state)
325 if (reply.spi_core_clk_high)
326 state->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
328 state->spi_clk_rate = spi_clk_rate_float[spi_clk];
330 state->i2c_recovery_tmo =
331 (reply.cfg_stmfd.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) & 0x0f;
332 state->i2c_port = (reply.cfg_stmfd.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) & 0xf;
337 (reply.cfg_stmfd.cfg >> addr_shift) & SWITCHTEC_I2C_ADDR_BITMASK;
338 state->i2c_cmd_map = (reply.cfg_stmfd.cfg >> map_shift) & map_mask;
340 state->public_key_exponent = reply.cfg_stmfd.public_key_exponent;
341 state->public_key_num = reply.public_key_num;
342 state->public_key_ver = reply.public_key_ver;
343 memcpy(state->public_key, reply.public_key,
344 SWITCHTEC_KMSK_NUM * SWITCHTEC_KMSK_LEN);
358 int num_to_read = htole32(SWITCHTEC_MB_MAX_ENTRIES);
360 uint8_t num_returned;
361 uint8_t num_remaining;
363 uint8_t data[SWITCHTEC_MB_MAX_ENTRIES *
364 SWITCHTEC_MB_LOG_LEN];
369 sizeof(
int), &reply,
sizeof(reply));
373 reply.num_remaining = le32toh(reply.num_remaining);
374 reply.num_returned = le32toh(reply.num_returned);
376 ret = write(fd, reply.data,
377 (reply.num_returned) * SWITCHTEC_MB_LOG_LEN);
380 }
while (reply.num_remaining > 0);
399 int spi_rate_max_val = 10;
404 p = spi_clk_hi_rate_float;
408 p = spi_clk_rate_float;
411 for (i = 0; i < spi_rate_max_val; i++)
413 if ((clk_float < p[i] + 0.1) && (clk_float > p[i] - 0.1))
439 struct setting_data {
441 uint32_t pub_key_exponent;
450 uint8_t cmd_buf[20] = {};
457 memset(&sd, 0,
sizeof(sd));
460 reply.spi_core_clk_high);
466 sd.cfg |= (spi_clk & SWITCHTEC_CLK_RATE_BITMASK) <<
467 SWITCHTEC_CLK_RATE_BITSHIFT;
469 sd.cfg |= (setting->i2c_recovery_tmo & SWITCHTEC_RC_TMO_BITMASK) <<
470 SWITCHTEC_RC_TMO_BITSHIFT;
471 sd.cfg |= (setting->i2c_port & SWITCHTEC_I2C_PORT_BITMASK) <<
472 SWITCHTEC_I2C_PORT_BITSHIFT;
476 sd.cfg |= (setting->i2c_addr & SWITCHTEC_I2C_ADDR_BITMASK) <<
479 ldata = setting->i2c_cmd_map & map_mask;
483 sd.cfg = htole64(sd.cfg);
485 sd.pub_key_exponent = htole32(setting->public_key_exponent);
489 &sd,
sizeof(sd), NULL, 0);
492 memcpy(cmd_buf + 4, &sd,
sizeof(sd));
494 cmd_buf,
sizeof(cmd_buf), NULL, 0);
510 struct sjtag_mode_cmd {
512 uint8_t sjtag_mode:2;
515 cmd.subcmd = MRPC_OTP_SJTAG_MODE_SET;
516 cmd.sjtag_mode = sjtag_mode;
519 sizeof(cmd), NULL, 0);
533 struct sjtag_uuid_cmd {
536 uint8_t sjtag_hr[SJTAG_HR_LEN];
539 cmd.subcmd = MRPC_SJTAG_SET_HOST_RESPONSE;
541 memcpy((
void *)cmd.sjtag_hr, (
void *)sjtag_hr, SJTAG_HR_LEN);
544 sizeof(cmd), NULL, 0);
558 struct sjtag_uuid_cmd {
563 cmd.subcmd = MRPC_OTP_SJTAG_UUID_SET;
565 memcpy((
void *)cmd.sjtag_uuid, (
void *)
sjtag_uuid, OTP_SJTAG_UUID_LENGTH);
568 sizeof(cmd), NULL, 0);
582 struct sjtag_key_cmd {
584 uint8_t sjtag_key[OTP_SJTAG_KEY_LENGTH];
587 cmd.subcmd = MRPC_OTP_SJTAG_KEY_SET;
589 memcpy((
void *)cmd.sjtag_key, (
void *)sjtag_key, OTP_SJTAG_KEY_LENGTH);
592 sizeof(cmd), NULL, 0);
608 uint8_t *config_data,
609 bool is_firmware_halt)
611 #pragma pack(push, 1)
612 struct otp_config_cmd {
614 uint16_t config_len:10;
616 uint8_t is_firmware_halt:1;
618 uint8_t config_data[OTP_CONFIG_DATA_MAX_LEN];
622 cmd.subcmd = MRPC_OTP_CONFIG_PROG;
623 cmd.config_len = config_len;
624 cmd.is_firmware_halt = is_firmware_halt;
626 memcpy((
void *)cmd.config_data, (
void *)config_data, OTP_CONFIG_DATA_MAX_LEN);
629 sizeof(cmd), NULL, 0);
644 uint16_t config_start_address,
645 int32_t config_length,
650 #pragma pack(push, 1)
651 struct otp_config_cmd {
653 uint16_t config_start_address:14;
654 uint16_t config_length:10;
658 struct otp_config_read_reply {
659 uint8_t config_data[OTP_CONFIG_DATA_MAX_LEN];
662 cmd.subcmd = MRPC_OTP_CONFIG_READ;
664 cmd.config_start_address = config_start_address;
665 while(config_length > 0)
667 cmd.config_length = (OTP_CONFIG_DATA_MAX_LEN < config_length) ? OTP_CONFIG_DATA_MAX_LEN : config_length;
669 sizeof(cmd), &reply,
sizeof(reply));
675 ret = write(out_fd, reply.config_data, cmd.config_length);
680 cmd.config_start_address += OTP_CONFIG_DATA_MAX_LEN;
681 config_length -= OTP_CONFIG_DATA_MAX_LEN;
698 uint8_t *sjtag_key, uint8_t *is_verified)
701 struct sjtag_key_cmd {
703 uint8_t sjtag_key[OTP_SJTAG_KEY_LENGTH];
708 cmd.subcmd = MRPC_OTP_SJTAG_KEY_VERIFY;
710 memcpy((
void *)cmd.sjtag_key, (
void *)sjtag_key, OTP_SJTAG_KEY_LENGTH);
713 sizeof(cmd), &reply,
sizeof(uint8_t));
718 memcpy((
void *)is_verified, (
void *)&reply,
sizeof(uint8_t));
731 struct sjtag_key_cmd {
735 cmd.subcmd = MRPC_OTP_SJTAG_KEY_LOCK;
738 sizeof(cmd), NULL, 0);
750 uint32_t chip_serial_num)
752 struct sku_info_cmd {
754 uint32_t chip_serial_num;
757 cmd.subcmd = MRPC_OTP_PROG_CHIP_NUM;
758 cmd.chip_serial_num = chip_serial_num;
761 sizeof(cmd), NULL, 0);
775 struct sku_info_cmd {
783 cmd.subcmd = MRPC_OTP_SKU_INFO_SET;
784 cmd.block_num = sku_info_set_str->block_num;
785 cmd.sku_info = sku_info_set_str->sku_info;
788 sizeof(cmd), NULL, 0);
801 uint8_t *sjtag_uuid_ptr,
802 uint8_t *sjtag_idcode)
805 struct sjtag_uuid_idcode {
811 uint8_t sub_cmd = MRPC_SJTAG_GET_UUID_IDCODE;
814 sizeof(sub_cmd), &reply,
sizeof(reply));
819 memcpy((
void *)sjtag_uuid_ptr, (
void *)reply.uuid, SJTAG_UUID_LEN);
820 memcpy((
void *)sjtag_idcode, (
void *)reply.idcode, SJTAG_IDCODE_LEN);
841 uint8_t sub_cmd = MRPC_SJTAG_GET_NONCE;
844 sizeof(sub_cmd), &reply,
sizeof(reply));
849 memcpy((
void *)sjtag_nonce_ptr, (
void *)&reply,
sizeof(reply));
868 struct stag_sts_cmd {
872 uint8_t sub_cmd = MRPC_SJTAG_GET_STATUS;
875 sizeof(sub_cmd), &reply,
sizeof(reply));
880 memcpy((
void *)sjtag_sts_get, (
void *)&reply,
sizeof(reply));
901 uint8_t sjtag_sha256_msg[SJTAG_SHA256_MSG_LEN] = {0};
902 SHA256_CTX sha256_algo;
907 for(
int i = 0; i < SJTAG_NONCE_LEN; i++)
914 (void)memcpy((
void*)(sjtag_sha256_msg), (
void*)
sjtag_debug_token, SJTAG_DEBUG_TOKEN_LEN);
915 (void)memcpy((
void*)(&sjtag_sha256_msg[SJTAG_DEBUG_TOKEN_LEN]), (
void*)
sjtag_nonce, SJTAG_NONCE_LEN);
917 SHA256_Init(&sha256_algo);
918 SHA256_Update(&sha256_algo, sjtag_sha256_msg, SJTAG_SHA256_MSG_LEN);
919 SHA256_Final(digest, &sha256_algo);
922 printf(
"Host Response: ");
923 for(
int i = 0; i < SJTAG_HR_LEN; i++)
925 printf(
"%x", digest[i]);
941 cmd_header[SJTAG_SERVER_CMD_INDEX] = cmd;
942 cmd_header[SJTAG_SERVER_CMD_RESP_INDICATOR_INDEX] = SJTAG_SERVER_CMD_MSK;
961 int sjtag_resp_is_success(uint8_t *resp_header)
965 if((SJTAG_SERVER_CMD_CHAL_RESP == resp_header[SJTAG_SERVER_CMD_INDEX]) && (SJTAG_SERVER_RESP_MSK == resp_header[SJTAG_SERVER_CMD_RESP_INDICATOR_INDEX]))
967 if(SERVER_STATUS_SUCCESS == resp_header[SJTAG_SERVER_RESPONSE_STATUS_INDEX])
971 else if(SERVER_STATUS_INVALID_SJTAGID == resp_header[SJTAG_SERVER_RESPONSE_STATUS_INDEX])
973 printf(
"Error in generating debug token generation due to invalid IDCODE!\n");
975 else if(SERVER_STATUS_INVALID_HEADER == resp_header[SJTAG_SERVER_RESPONSE_STATUS_INDEX])
977 printf(
"Error in generating debug token generation due to invalid header!\n");
979 else if(SERVER_STATUS_DIGEST_COMPUTE_FAIL == resp_header[SJTAG_SERVER_RESPONSE_STATUS_INDEX])
981 printf(
"Exception in generating the digest!\n");
985 printf(
"Invalid response header from SJTAG server!\n");
1006 struct sockaddr_in server_address;
1007 uint8_t sjtag_hmac_msg[SJTAG_HMAC_MSG_LEN] = {0};
1008 uint8_t sjtag_uuid_send[SJTAG_UUID_LEN] = {0};
1009 uint8_t sjtag_idcode_send[SJTAG_IDCODE_LEN] = {0};
1010 const uint8_t unlock_str[SJTAG_UNLOCK_STR_LEN] = {
'S',
'T',
'M',
'F',
'D',
'_',
'S',
'J',
'T',
'A',
'G',
'_',
'U',
'N',
'L',
'O',
'C',
'K'};
1011 uint8_t cmd_header[SJTAG_SERVER_HEADER_LEN];
1012 uint8_t resp_header[SJTAG_SERVER_HEADER_LEN];
1016 socket_server = socket(AF_INET, SOCK_STREAM, 0);
1017 if(socket_server < 0)
1019 printf(
"Unable to create socket communication!\n");
1025 server_address.sin_family = AF_INET;
1026 server_address.sin_port = htons(SJTAG_SERVER_PORT);
1027 server_address.sin_addr.s_addr = inet_addr(SJTAG_SERVER_IP);
1030 if(connect(socket_server, (
struct sockaddr*)&server_address,
sizeof(server_address)) < 0)
1032 printf(
"Unable to connect with Plugin server!\n");
1036 printf(
"Connected with Plugin server successfully!\n");
1040 if(send(socket_server, cmd_header, SJTAG_SERVER_HEADER_LEN, 0) < 0)
1042 printf(
"Unable to sent the Command Header to the Plugin server!\n");
1050 for(
int i=0; i<SJTAG_IDCODE_LEN; i++)
1052 sjtag_idcode_send[i] = idcode_ptr[3 - i];
1055 printf(
"%x", sjtag_idcode_send[i]);
1062 if(send(socket_server, sjtag_idcode_send, SJTAG_IDCODE_LEN, 0) < 0)
1064 printf(
"Unable to sent the IDCODE to the Plugin server!\n");
1072 for(
int i=0; i<SJTAG_UUID_LEN; i++)
1074 sjtag_uuid_send[i] = uuid_ptr[9 - i];
1077 printf(
"%x", sjtag_uuid_send[i]);
1084 if(send(socket_server, sjtag_uuid_send, SJTAG_UUID_LEN, 0) < 0)
1086 printf(
"Unable to send the UUID to the Plugin server!\n");
1091 (void)memcpy((
void*)sjtag_hmac_msg, (
void*)suv_ptr, SUV_LEN);
1092 (void)memcpy((
void*)(&sjtag_hmac_msg[SUV_LEN]), (
void*)unlock_str, SJTAG_UNLOCK_STR_LEN);
1097 for(
int i = 0; i < SUV_LEN; i++)
1099 printf(
"%x", suv_ptr[3 - i]);
1105 if(send(socket_server, sjtag_hmac_msg, SJTAG_HMAC_MSG_LEN, 0) < 0)
1107 printf(
"Unable to send the HMAC message to the Plugin server!\n");
1113 if(recv(socket_server, resp_header, SJTAG_SERVER_HEADER_LEN, 0) < 0)
1115 printf(
"Error while receiving response header from the Plugin server!\n");
1120 ret = sjtag_resp_is_success(resp_header);
1126 printf(
"Error while receiving Debug Token from the Plugin server!\n");
1132 printf(
"Debug Token: ");
1133 for(
int i = 0; i < SJTAG_DEBUG_TOKEN_LEN; i++)
1143 close(socket_server);
1160 rlen = fread(debug_token->debug_token, 1, SJTAG_DEBUG_TOKEN_LEN, debug_token_file);
1162 if (rlen < SJTAG_DEBUG_TOKEN_LEN)
1176 bool sku_info,
bool otp_config)
1178 #pragma pack(push, 1)
1179 struct otp_write_prot_cmd {
1186 cmd.subcmd = MRPC_OTP_REGS_WRITE_PROT;
1187 cmd.sku_info = sku_info;
1188 cmd.otp_config = otp_config;
1191 sizeof(cmd), NULL, 0);
1203 uint8_t sub_cmd = MRPC_OTP_SKU_INFO_GET;
1215 uint8_t *self_test_policy)
1217 struct self_test_policy_cmd {
1219 uint8_t self_test_policy[OTP_SELF_TEST_POLICY_LENGTH];
1222 cmd.subcmd = MRPC_OTP_SELF_TEST_POLICY_SET;
1224 memcpy((
void *)cmd.self_test_policy, (
void *)self_test_policy, OTP_SELF_TEST_POLICY_LENGTH);
1227 sizeof(cmd), NULL, 0);
1239 struct otp_die_trace_cmd {
1241 uint8_t die_trace[OTP_DIE_TRACE_LENGTH];
1244 cmd.subcmd = MRPC_OTP_PROG_DIE_TRACE;
1246 memcpy((
void *)cmd.die_trace, (
void *)die_trace, OTP_DIE_TRACE_LENGTH);
1249 sizeof(cmd), NULL, 0);
1262 struct self_test_policy_cmd {
1267 cmd.subcmd = MRPC_OTP_BIT_BYTE_MODE_SET;
1268 cmd.bit_byte_mode = bit_byte_mode;
1270 sizeof(cmd), NULL, 0);
1280 bool smart_prog_mode)
1282 struct self_test_policy_cmd {
1284 bool smart_prog_mode;
1287 cmd.subcmd = MRPC_OTP_SMART_PROG_MODE_SET;
1288 cmd.smart_prog_mode = smart_prog_mode;
1291 sizeof(cmd), NULL, 0);
1302 uint8_t subcmd = MRPC_OTP_MODE_STATUS_GET;
1315 #pragma pack(push, 1)
1316 struct cust_id_cmd {
1322 cmd.subcmd = MRPC_OTP_CUSTID_PROG;
1323 cmd.cust_id = cust_id;
1326 sizeof(cmd), NULL, 0);
1338 struct active_indices {
1339 uint8_t index[SWITCHTEC_ACTV_IDX_MAX_ENTRIES];
1343 0, &reply,
sizeof(reply));
1347 index->keyman = reply.index[SWITCHTEC_ACTV_IMG_ID_KMAN];
1348 index->bl2 = reply.index[SWITCHTEC_ACTV_IMG_ID_BL2];
1349 index->config = reply.index[SWITCHTEC_ACTV_IMG_ID_CFG];
1350 index->firmware = reply.index[SWITCHTEC_ACTV_IMG_ID_FW];
1371 } idx[SWITCHTEC_ACTV_IDX_SET_ENTRIES];
1374 memset(&set, 0,
sizeof(set));
1376 if (index->keyman != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
1377 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_KMAN;
1378 set.idx[i].index = index->keyman;
1382 if (index->bl2 != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
1383 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_BL2;
1384 set.idx[i].index = index->bl2;
1388 if (index->config != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
1389 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_CFG;
1390 set.idx[i].index = index->config;
1394 if (index->firmware != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
1395 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_FW;
1396 set.idx[i].index = index->firmware;
1403 set.count = htole32(i);
1406 sizeof(set), NULL, 0);
1417 enum switchtec_bl2_recovery_mode recovery_mode)
1419 struct fw_exec_struct {
1421 uint8_t recovery_mode;
1425 memset(&cmd, 0,
sizeof(cmd));
1426 cmd.subcmd = MRPC_FW_TX_EXEC;
1427 cmd.recovery_mode = recovery_mode;
1457 enum switchtec_secure_state state)
1461 if ((state != SWITCHTEC_INITIALIZED_UNSECURED)
1462 && (state != SWITCHTEC_INITIALIZED_SECURED)) {
1463 return ERR_PARAM_INVALID;
1465 data = htole32(state);
1468 sizeof(data), NULL, 0);
1482 struct public_key_cmd {
1485 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1486 uint32_t pub_key_exp;
1489 cmd.subcmd = MRPC_DBG_UNLOCK_PKEY;
1490 memcpy(cmd.pub_key, public_key->pubkey, SWITCHTEC_PUB_KEY_LEN);
1491 cmd.pub_key_exp = htole32(public_key->pubkey_exp);
1494 sizeof(cmd), NULL, 0);
1507 uint32_t ver_sec_unlock,
1516 uint32_t unlock_ver;
1517 uint8_t signature[SWITCHTEC_SIG_LEN];
1524 cmd.subcmd = MRPC_DBG_UNLOCK_DATA;
1525 cmd.serial = htole32(serial);
1526 cmd.unlock_ver = htole32(ver_sec_unlock);
1527 memcpy(cmd.signature, signature->signature, SWITCHTEC_SIG_LEN);
1530 sizeof(cmd), NULL, 0);
1544 uint32_t ver_sec_unlock,
1553 uint32_t unlock_ver;
1554 uint8_t signature[SWITCHTEC_SIG_LEN];
1561 cmd.subcmd = MRPC_DBG_UNLOCK_UPDATE;
1562 cmd.serial = htole32(serial);
1563 cmd.unlock_ver = htole32(ver_sec_unlock);
1564 memcpy(cmd.signature, signature->signature, SWITCHTEC_SIG_LEN);
1582 char magic[4] = {
'S',
'S',
'F',
'F'};
1584 struct setting_file_header {
1591 struct setting_file_data {
1593 uint32_t pub_key_exponent;
1596 struct setting_file {
1597 struct setting_file_header header;
1598 struct setting_file_data data;
1601 uint32_t addr_shift;
1613 rlen = fread(&file_data, 1,
sizeof(file_data), setting_file);
1615 if (rlen <
sizeof(file_data))
1618 if (memcmp(file_data.header.magic, magic,
sizeof(magic)))
1621 crc = crc32((uint8_t*)&file_data.data,
1622 sizeof(file_data.data), 0, 1, 1);
1623 if (crc != le32toh(file_data.header.crc))
1625 switch (file_data.header.hw_gen) {
1627 gen = SWITCHTEC_GEN4;
1630 gen = SWITCHTEC_GEN5;
1640 file_data.data.cfg = le64toh(file_data.data.cfg);
1642 spi_clk = (file_data.data.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) &
1643 SWITCHTEC_CLK_RATE_BITMASK;
1644 if (reply.spi_core_clk_high)
1645 set->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
1647 set->spi_clk_rate = spi_clk_rate_float[spi_clk];
1649 set->i2c_recovery_tmo =
1650 (file_data.data.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) &
1651 SWITCHTEC_RC_TMO_BITMASK;
1653 (file_data.data.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) &
1654 SWITCHTEC_I2C_PORT_BITMASK;
1658 (file_data.data.cfg >> addr_shift) &
1659 SWITCHTEC_I2C_ADDR_BITMASK;
1660 set->i2c_cmd_map = (file_data.data.cfg >> map_shift) & map_mask;
1662 set->public_key_exponent = le32toh(file_data.data.pub_key_exponent);
1678 struct kmsk_pubk_cmd {
1680 uint8_t reserved[3];
1681 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1682 uint32_t pub_key_exponent;
1685 cmd.subcmd = MRPC_KMSK_ENTRY_SET_PKEY;
1686 memcpy(cmd.pub_key, public_key->pubkey,
1687 SWITCHTEC_PUB_KEY_LEN);
1688 cmd.pub_key_exponent = htole32(public_key->pubkey_exp);
1691 sizeof(cmd), NULL, 0);
1705 struct kmsk_signature_cmd {
1707 uint8_t reserved[3];
1708 uint8_t signature[SWITCHTEC_SIG_LEN];
1711 cmd.subcmd = MRPC_KMSK_ENTRY_SET_SIG;
1712 memcpy(cmd.signature, signature->signature,
1716 sizeof(cmd), NULL, 0);
1730 struct kmsk_kmsk_cmd {
1732 uint8_t num_entries;
1733 uint8_t reserved[2];
1734 uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1737 cmd.subcmd = MRPC_KMSK_ENTRY_SET_KMSK;
1738 cmd.num_entries = 1;
1739 memcpy(cmd.kmsk, kmsk->kmsk, SWITCHTEC_KMSK_LEN);
1786 int switchtec_read_pubk_file(FILE *pubk_file,
struct switchtec_pubkey *pubk)
1789 const BIGNUM *modulus_bn;
1790 const BIGNUM *exponent_bn;
1791 uint32_t exponent_tmp = 0;
1793 RSAKey = PEM_read_RSA_PUBKEY(pubk_file, NULL, NULL, NULL);
1794 if (RSAKey == NULL) {
1795 fseek(pubk_file, 0L, SEEK_SET);
1796 RSAKey = PEM_read_RSAPrivateKey(pubk_file, NULL, NULL, NULL);
1801 RSA_get0_key(RSAKey, &modulus_bn, &exponent_bn, NULL);
1803 BN_bn2bin(modulus_bn, pubk->pubkey);
1804 BN_bn2bin(exponent_bn, (uint8_t *)&exponent_tmp);
1806 pubk->pubkey_exp = be32toh(exponent_tmp);
1823 struct kmsk_struct {
1828 uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1831 char magic[4] = {
'K',
'M',
'S',
'K'};
1834 rlen = fread(&data, 1,
sizeof(data), kmsk_file);
1836 if (rlen <
sizeof(data))
1839 if (memcmp(data.magic, magic,
sizeof(magic)))
1842 crc = crc32(data.kmsk, SWITCHTEC_KMSK_LEN, 0, 1, 1);
1843 if (crc != le32toh(data.crc32))
1846 memcpy(kmsk->kmsk, data.kmsk, SWITCHTEC_KMSK_LEN);
1862 rlen = fread(signature->signature, 1, SWITCHTEC_SIG_LEN, sig_file);
1864 if (rlen < SWITCHTEC_SIG_LEN)
1880 rlen = fread(uuid->uuid_data, 1, OTP_SJTAG_UUID_LENGTH, uuid_file);
1882 if (rlen < OTP_SJTAG_UUID_LENGTH)
1899 rlen = fread(sjtag_key->sjtag_key, 1, OTP_SJTAG_KEY_LENGTH, sjtag_file);
1901 if (rlen < OTP_SJTAG_KEY_LENGTH)
1916 unsigned short config_len)
1919 rlen = fread((
void *)config_data->config_data, 1, config_len, config_file);
1921 if (rlen < config_len)
1938 rlen = fread(
otp_self_test_policy->otp_self_test_policy, 1, OTP_SELF_TEST_POLICY_LENGTH, self_test_file);
1940 if (rlen < OTP_SELF_TEST_POLICY_LENGTH)
1957 rlen = fread(otp_die_trace_ptr->die_trace, 1, OTP_DIE_TRACE_LENGTH, die_trace_file);
1959 if (rlen < OTP_DIE_TRACE_LENGTH)
1981 for(key_idx = 0; key_idx < state->public_key_num; key_idx++) {
1982 if (memcmp(state->public_key[key_idx], kmsk->kmsk,
1983 SWITCHTEC_KMSK_LEN) == 0)
2005 const void *payload,
size_t payload_len,
2006 void *resp,
size_t resp_len)
2008 if (dev->ops->flags & SWITCHTEC_OPS_FLAG_NO_MFG) {
2009 errno = ERR_UART_NOT_SUPPORTED | SWITCHTEC_ERRNO_MRPC_FLAG_BIT;
2032 info->chip_serial = le32toh(info->chip_serial);
2033 info->ver_bl2 = le32toh(info->ver_bl2);
2034 info->ver_km = le32toh(info->ver_km);
2035 info->ver_main = le32toh(info->ver_main);
2036 info->ver_sec_unlock = le32toh(info->ver_sec_unlock);
2037 info->customer_id = le16toh(info->customer_id);