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"
65#include <openssl/pem.h>
68#define SWITCHTEC_ACTV_IMG_ID_KMAN 1
69#define SWITCHTEC_ACTV_IMG_ID_BL2 2
70#define SWITCHTEC_ACTV_IMG_ID_CFG 3
71#define SWITCHTEC_ACTV_IMG_ID_FW 4
73#define SWITCHTEC_ACTV_IMG_ID_KMAN_GEN5 1
74#define SWITCHTEC_ACTV_IMG_ID_RC_GEN5 2
75#define SWITCHTEC_ACTV_IMG_ID_BL2_GEN5 3
76#define SWITCHTEC_ACTV_IMG_ID_CFG_GEN5 4
77#define SWITCHTEC_ACTV_IMG_ID_FW_GEN5 5
79#define SWITCHTEC_MB_MAX_ENTRIES 16
80#define SWITCHTEC_ACTV_IDX_MAX_ENTRIES 32
81#define SWITCHTEC_ACTV_IDX_SET_ENTRIES 5
83#define SWITCHTEC_ATTEST_BITSHIFT 4
84#define SWITCHTEC_ATTEST_BITMASK 0x03
85#define SWITCHTEC_CLK_RATE_BITSHIFT 10
86#define SWITCHTEC_CLK_RATE_BITMASK 0x0f
87#define SWITCHTEC_RC_TMO_BITSHIFT 14
88#define SWITCHTEC_RC_TMO_BITMASK 0x0f
89#define SWITCHTEC_I2C_PORT_BITSHIFT 18
90#define SWITCHTEC_I2C_PORT_BITMASK 0x0f
91#define SWITCHTEC_I2C_ADDR_BITSHIFT 22
92#define SWITCHTEC_I2C_ADDR_BITSHIFT_GEN5 23
93#define SWITCHTEC_I2C_ADDR_BITMASK 0x7f
94#define SWITCHTEC_CMD_MAP_BITSHIFT 29
95#define SWITCHTEC_CMD_MAP_BITSHIFT_GEN5 30
96#define SWITCHTEC_CMD_MAP_BITMASK 0xfff
97#define SWITCHTEC_CMD_MAP_BITMASK_GEN5 0x3fff
98#define SWITCHTEC_UDS_SELFGEN_BITSHIFT 44
99#define SWITCHTEC_UDS_SELFGEN_BITMASK 0x01
101#define SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK 0x40
102#define SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK 0x80
103#define SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK 0x0100
104#define SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK 0x0200
106static int switchtec_mfg_cmd(
struct switchtec_dev *dev, uint32_t cmd,
107 const void *payload,
size_t payload_len,
108 void *resp,
size_t resp_len);
110static void get_i2c_operands(
enum switchtec_gen gen, uint32_t *addr_shift,
111 uint32_t *map_shift, uint32_t *map_mask)
113 if (gen > SWITCHTEC_GEN4) {
114 *addr_shift = SWITCHTEC_I2C_ADDR_BITSHIFT_GEN5;
115 *map_shift = SWITCHTEC_CMD_MAP_BITSHIFT_GEN5;
116 *map_mask = SWITCHTEC_CMD_MAP_BITMASK_GEN5;
118 *addr_shift = SWITCHTEC_I2C_ADDR_BITSHIFT;
119 *map_shift = SWITCHTEC_CMD_MAP_BITSHIFT;
120 *map_mask = SWITCHTEC_CMD_MAP_BITMASK;
124static float spi_clk_rate_float[] = {
125 100, 67, 50, 40, 33.33, 28.57, 25, 22.22, 20, 18.18
128static float spi_clk_hi_rate_float[] = {
129 120, 80, 60, 48, 40, 34, 30, 26.67, 24, 21.82
132struct get_cfgs_reply {
136 uint32_t public_key_exponent;
138 uint8_t public_key_num;
139 uint8_t public_key_ver;
140 uint8_t spi_core_clk_high;
141 uint8_t public_key[4][SWITCHTEC_KMSK_LEN];
145struct get_cfgs_reply_gen5 {
149 uint32_t public_key_exponent;
151 uint8_t public_key_num;
152 uint8_t public_key_ver;
153 uint8_t spi_core_clk_high;
154 uint8_t public_key[10][SWITCHTEC_KMSK_LEN];
155 uint32_t cdi_efuse_inc_mask;
156 uint8_t uds_data[32];
161static uint32_t get_dbg_unlock_id(
struct switchtec_dev *dev)
164 return MRPC_DBG_UNLOCK_GEN6;
166 return MRPC_DBG_UNLOCK_GEN5;
168 return MRPC_DBG_UNLOCK;
171static int get_configs(
struct switchtec_dev *dev,
172 struct get_cfgs_reply *cfgs,
178 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET_EXT,
179 &subcmd,
sizeof(subcmd),
180 cfgs,
sizeof(
struct get_cfgs_reply));
181 if (ret && ERRNO_MRPC(errno) != ERR_CMD_INVALID)
190 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET,
192 sizeof(
struct get_cfgs_reply));
197static int get_configs_gen5(
struct switchtec_dev *dev,
198 struct get_cfgs_reply_gen5 *cfgs)
202 return switchtec_mfg_cmd(dev,
204 ? MRPC_SECURITY_CONFIG_GET_GEN6 :
205 MRPC_SECURITY_CONFIG_GET_GEN5,
206 &subcmd,
sizeof(subcmd),
207 cfgs,
sizeof(
struct get_cfgs_reply_gen5));
210static int get_configs_gen6(
struct switchtec_dev *dev,
211 get_cfgs_reply_gen6 *cfgs)
215 return switchtec_mfg_cmd(dev,
216 MRPC_SECURE_CONFIG_GET_GEN6,
217 &subcmd,
sizeof(subcmd),
218 cfgs,
sizeof(get_cfgs_reply_gen6));
222int switchtec_security_spi_avail_rate_get(
struct switchtec_dev *dev,
226 struct get_cfgs_reply reply;
229 ret = get_configs(dev, &reply, &otp_valid);
233 rates->num_rates = 10;
234 if (reply.spi_core_clk_high)
235 memcpy(rates->rates, spi_clk_hi_rate_float,
236 sizeof(spi_clk_hi_rate_float));
238 memcpy(rates->rates, spi_clk_rate_float,
239 sizeof(spi_clk_rate_float));
247 otp->basic_valid = !!(flags & BIT(5));
248 otp->basic = !!(flags & BIT(6));
249 otp->mixed_ver_valid = !!(flags & BIT(7));
250 otp->mixed_ver = !!(flags & BIT(8));
251 otp->main_fw_ver_valid = !!(flags & BIT(9));
252 otp->main_fw_ver = !!(flags & BIT(10));
253 otp->sec_unlock_ver_valid = !!(flags & BIT(11));
254 otp->sec_unlock_ver = !!(flags & BIT(12));
255 otp->kmsk_valid[0] = !!(flags & BIT(13));
256 otp->kmsk[0] = !!(flags & BIT(14));
257 otp->kmsk_valid[1] = !!(flags & BIT(15));
258 otp->kmsk[1] = !!(flags & BIT(16));
259 otp->kmsk_valid[2] = !!(flags & BIT(17));
260 otp->kmsk[2] = !!(flags & BIT(18));
261 otp->kmsk_valid[3] = !!(flags & BIT(19));
262 otp->kmsk[3] = !!(flags & BIT(20));
265static void parse_otp_settings_gen5(
267 uint32_t flags0, uint32_t flags1)
269 otp->basic_valid = !!(flags0 & BIT(8));
270 otp->basic = !!(flags0 & BIT(9));
271 otp->debug_mode_valid = !!(flags0 & BIT(10));
272 otp->debug_mode = !!(flags0 & BIT(11));
273 otp->key_ver_valid = !!(flags0 & BIT(12));
274 otp->key_ver = !!(flags0 & BIT(13));
275 otp->rc_ver_valid = !!(flags0 & BIT(14));
276 otp->rc_ver = !!(flags0 & BIT(15));
277 otp->bl2_ver_valid = !!(flags0 & BIT(16));
278 otp->bl2_ver = !!(flags0 & BIT(17));
279 otp->main_fw_ver_valid = !!(flags0 & BIT(18));
280 otp->main_fw_ver = !!(flags0 & BIT(19));
281 otp->sec_unlock_ver_valid = !!(flags0 & BIT(20));
282 otp->sec_unlock_ver = !!(flags0 & BIT(21));
283 otp->kmsk_valid[0] = !!(flags0 & BIT(22));
284 otp->kmsk[0] = !!(flags0 & BIT(23));
285 otp->kmsk_valid[1] = !!(flags0 & BIT(24));
286 otp->kmsk[1] = !!(flags0 & BIT(25));
287 otp->kmsk_valid[2] = !!(flags0 & BIT(26));
288 otp->kmsk[2] = !!(flags0 & BIT(27));
289 otp->kmsk_valid[3] = !!(flags0 & BIT(28));
290 otp->kmsk[3] = !!(flags0 & BIT(29));
291 otp->kmsk_valid[4] = !!(flags0 & BIT(30));
292 otp->kmsk[4] = !!(flags0 & BIT(31));
293 otp->kmsk_valid[5] = !!(flags1 & BIT(0));
294 otp->kmsk[5] = !!(flags1 & BIT(1));
295 otp->kmsk_valid[6] = !!(flags1 & BIT(2));
296 otp->kmsk[6] = !!(flags1 & BIT(3));
297 otp->kmsk_valid[7] = !!(flags1 & BIT(4));
298 otp->kmsk[7] = !!(flags1 & BIT(5));
299 otp->kmsk_valid[8] = !!(flags1 & BIT(6));
300 otp->kmsk[8] = !!(flags1 & BIT(7));
301 otp->kmsk_valid[9] = !!(flags1 & BIT(8));
302 otp->kmsk[9] = !!(flags1 & BIT(9));
303 otp->cdi_efuse_inc_mask_valid = !!(flags1 & BIT(10));
304 otp->cdi_efuse_inc_mask = !!(flags1 & BIT(11));
305 otp->uds_valid = !!(flags1 & BIT(12));
306 otp->uds = !!(flags1 & BIT(13));
307 otp->uds_mask_valid = !!(flags1 & BIT(14));
308 otp->uds_mask = !!(flags1 & BIT(15));
309 otp->mchp_uds_valid = !!(flags1 & BIT(16));
310 otp->mchp_uds = !!(flags1 & BIT(17));
311 otp->mchp_uds_mask_valid = !!(flags1 & BIT(18));
312 otp->mchp_uds_mask = !!(flags1 & BIT(19));
313 otp->did_cert0_valid = !!(flags1 & BIT(20));
314 otp->did_cert0 = !!(flags1 & BIT(21));
315 otp->did_cert1_valid = !!(flags1 & BIT(22));
316 otp->did_cert1 = !!(flags1 & BIT(23));
319static int security_config_get(
struct switchtec_dev *dev,
327 struct get_cfgs_reply reply;
330 ret = get_configs(dev, &reply, &otp_valid);
334 reply.valid = le32toh(reply.valid);
335 reply.cfg = le64toh(reply.cfg);
336 reply.public_key_exponent = le32toh(reply.public_key_exponent);
338 state->basic_setting_valid = !!(reply.valid & 0x01);
339 state->public_key_exp_valid = !!(reply.valid & 0x02);
340 state->public_key_num_valid = !!(reply.valid & 0x04);
341 state->public_key_ver_valid = !!(reply.valid & 0x08);
342 state->public_key_valid = !!(reply.valid & 0x10);
344 state->debug_mode_valid = state->basic_setting_valid;
346 state->otp_valid = otp_valid;
348 parse_otp_settings(&state->otp, reply.valid);
350 state->use_otp_ext =
false;
352 state->debug_mode = reply.cfg & 0x03;
353 state->secure_state = (reply.cfg>>2) & 0x03;
355 state->jtag_lock_after_reset = !!(reply.cfg & 0x40);
356 state->jtag_lock_after_bl1 = !!(reply.cfg & 0x80);
357 state->jtag_bl1_unlock_allowed = !!(reply.cfg & 0x0100);
358 state->jtag_post_bl1_unlock_allowed = !!(reply.cfg & 0x0200);
360 spi_clk = (reply.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) & 0x0f;
368 if (reply.spi_core_clk_high)
369 state->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
371 state->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
373 state->i2c_recovery_tmo =
374 (reply.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) & 0x0f;
375 state->i2c_port = (reply.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) & 0xf;
377 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
380 (reply.cfg >> addr_shift) & SWITCHTEC_I2C_ADDR_BITMASK;
381 state->i2c_cmd_map = (reply.cfg >> map_shift) & map_mask;
383 state->public_key_exponent = reply.public_key_exponent;
384 state->public_key_num = reply.public_key_num;
385 state->public_key_ver = reply.public_key_ver;
387 if (state->public_key_num)
388 memcpy(state->public_key, reply.public_key,
389 state->public_key_num * SWITCHTEC_KMSK_LEN);
391 state->attn_state.attestation_mode =
392 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED;
397static int security_config_get_gen5(
struct switchtec_dev *dev,
405 struct get_cfgs_reply_gen5 reply;
408 ret = get_configs_gen5(dev, &reply);
412 reply.valid0 = le32toh(reply.valid0);
413 reply.valid1 = le32toh(reply.valid1);
415 reply.cfg = le64toh(reply.cfg);
416 reply.public_key_exponent = le32toh(reply.public_key_exponent);
418 state->basic_setting_valid = !!(reply.valid0 & 0x01);
419 state->public_key_exp_valid = !!(reply.valid0 & 0x04);
420 state->public_key_num_valid = !!(reply.valid0 & 0x08);
421 state->public_key_ver_valid = !!(reply.valid0 & 0x10);
422 state->public_key_valid = !!(reply.valid0 & 0x20);
424 state->debug_mode_valid = !!(reply.valid0 & 0x02);
425 state->attn_state.cdi_efuse_inc_mask_valid = !!(reply.valid0 & 0x40);
427 state->otp_valid =
true;
428 parse_otp_settings_gen5(&state->otp_ext, reply.valid0,
431 state->use_otp_ext =
true;
433 state->debug_mode = reply.cfg & 0x03;
434 state->secure_state = (reply.cfg>>2) & 0x03;
436 state->jtag_lock_after_reset = !!(reply.cfg & 0x40);
437 state->jtag_lock_after_bl1 = !!(reply.cfg & 0x80);
438 state->jtag_bl1_unlock_allowed = !!(reply.cfg & 0x0100);
439 state->jtag_post_bl1_unlock_allowed = !!(reply.cfg & 0x0200);
441 spi_clk = (reply.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) & 0x0f;
449 if (reply.spi_core_clk_high)
450 state->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
452 state->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
454 state->i2c_recovery_tmo =
455 (reply.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) & 0x0f;
456 state->i2c_port = (reply.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) & 0xf;
458 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
461 (reply.cfg >> addr_shift) & SWITCHTEC_I2C_ADDR_BITMASK;
462 state->i2c_cmd_map = (reply.cfg >> map_shift) & map_mask;
464 state->public_key_exponent = reply.public_key_exponent;
465 state->public_key_num = reply.public_key_num;
466 state->public_key_ver = reply.public_key_ver;
467 memcpy(state->public_key, reply.public_key,
468 state->public_key_num * SWITCHTEC_KMSK_LEN);
470 attn_mode = (reply.cfg >> SWITCHTEC_ATTEST_BITSHIFT) &
471 SWITCHTEC_ATTEST_BITMASK;
473 state->attn_state.attestation_mode =
474 SWITCHTEC_ATTESTATION_MODE_DICE;
476 state->attn_state.attestation_mode =
477 SWITCHTEC_ATTESTATION_MODE_NONE;
479 state->attn_state.uds_selfgen =
480 (reply.cfg >> SWITCHTEC_UDS_SELFGEN_BITSHIFT) &
481 SWITCHTEC_UDS_SELFGEN_BITMASK;
482 state->attn_state.cdi_efuse_inc_mask =
483 le32toh(reply.cdi_efuse_inc_mask);
485 if (state->secure_state == SWITCHTEC_UNINITIALIZED_UNSECURED &&
486 state->attn_state.attestation_mode ==
487 SWITCHTEC_ATTESTATION_MODE_DICE &&
488 !state->attn_state.uds_selfgen)
489 state->attn_state.uds_visible =
true;
491 state->attn_state.uds_visible =
false;
493 if (state->attn_state.uds_visible)
494 memcpy(state->attn_state.uds_data, reply.uds_data, 32);
499static int security_config_get_gen6(
struct switchtec_dev *dev,
503 get_cfgs_reply_gen6 reply;
505 ret = get_configs_gen6(dev, &reply);
509 memcpy(state, &reply,
sizeof(reply));
520int switchtec_security_config_get(
struct switchtec_dev *dev,
524 return security_config_get_gen6(dev,
527 return security_config_get_gen5(dev,
530 return security_config_get(dev, state);
533static int mailbox_to_file(
struct switchtec_dev *dev,
int fd)
536 int num_to_read = htole32(SWITCHTEC_MB_MAX_ENTRIES);
538 uint8_t num_returned;
539 uint8_t num_remaining;
541 uint8_t data[SWITCHTEC_MB_MAX_ENTRIES *
542 SWITCHTEC_MB_LOG_LEN];
546 ret = switchtec_mfg_cmd(dev, MRPC_MAILBOX_GET, &num_to_read,
547 sizeof(
int), &reply,
sizeof(reply));
551 reply.num_remaining = le32toh(reply.num_remaining);
552 reply.num_returned = le32toh(reply.num_returned);
554 ret = write(fd, reply.data,
555 (reply.num_returned) * SWITCHTEC_MB_LOG_LEN);
558 }
while (reply.num_remaining > 0);
573int security_settings_get_gen6(
struct switchtec_dev *dev,
579 uint32_t reply_otp[MRPC_MAX_DATA_LEN /
sizeof(uint32_t)] = {};
582 cmd.subcmd = MRPC_GET_SECURE_OTP;
583 cmd.OTP_dword_offset = 0;
584 cmd.read_dwords = 60;
586 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET_GEN6, &cmd,
sizeof(cmd),
587 &reply_otp, cmd.read_dwords *
sizeof(uint32_t));
591 state->twi_rcvry_address_mrpc = (reply_otp[OTP_DWORD_10] & OTP_DWORD_10_SMBUS_SMBRMRPCADDR_MSK)
592 >> OTP_DWORD_10_SMBUS_SMBRMRPCADDR_LSB;
593 state->twi_rcvry_bus = (reply_otp[OTP_DWORD_10] & OTP_DWORD_10_SMBUS_SMBRIF_MSK)
594 >> OTP_DWORD_10_SMBUS_SMBRIF_LSB;
595 state->twi_address_type = (reply_otp[OTP_DWORD_10] & OTP_DWORD_10_SMBUS_SMBRATYPE_MSK)
596 >> OTP_DWORD_10_SMBUS_SMBRATYPE_LSB;
597 state->twi_rcvry_address_ocp = (reply_otp[OTP_DWORD_10] & OTP_DWORD_10_SMBUS_SMBROCPADDR_MSK)
598 >> OTP_DWORD_10_SMBUS_SMBROCPADDR_LSB;
599 state->secsc = (reply_otp[OTP_DWORD_0] & OTP_DWORD_0_PRODUCT_SECSC_MSK)
600 >> OTP_DWORD_0_PRODUCT_SECSC_LSB;
603 cmd.subcmd = MRPC_GET_SECURE_OTP;
604 cmd.OTP_dword_offset = OTP_MULTI_DWORD_IMAGE_BIAK0;
605 cmd.read_dwords = (SWITCHTEC_KMSK_NUM_GEN6 * SWITCHTEC_KMSK_LEN_DWORDS);
607 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET_GEN6, &cmd,
sizeof(cmd),
608 &reply_otp, cmd.read_dwords *
sizeof(uint32_t));
612 for (
int i = 0; i < SWITCHTEC_KMSK_NUM_GEN6; i++) {
613 memcpy(state->otp_key_hash[i],
614 &reply_otp[i * SWITCHTEC_KMSK_LEN_DWORDS],
615 SWITCHTEC_KMSK_LEN_DWORDS *
sizeof(uint32_t));
621static int mailbox_to_file_gen56(
struct switchtec_dev *dev,
int fd)
626 uint32_t num_to_read;
629 uint8_t num_returned;
630 uint8_t num_remaining;
632 uint8_t data[SWITCHTEC_MB_MAX_ENTRIES *
633 SWITCHTEC_MB_LOG_LEN];
637 read.num_to_read = htole32(SWITCHTEC_MB_MAX_ENTRIES);
640 MRPC_MAILBOX_GET_GEN6 : MRPC_MAILBOX_GET_GEN5;
643 ret = switchtec_mfg_cmd(dev, cmd_id,
645 &reply,
sizeof(reply));
649 reply.num_remaining = le32toh(reply.num_remaining);
650 reply.num_returned = le32toh(reply.num_returned);
652 ret = write(fd, reply.data,
653 (reply.num_returned) * SWITCHTEC_MB_LOG_LEN);
656 }
while (reply.num_remaining > 0);
667int switchtec_mailbox_to_file(
struct switchtec_dev *dev,
int fd)
670 return mailbox_to_file_gen56(dev, fd);
672 return mailbox_to_file(dev, fd);
675static int convert_spi_clk_rate(
float clk_float,
int hi_rate)
681 p = spi_clk_hi_rate_float;
683 p = spi_clk_rate_float;
685 for (i = 0; i < 10; i++)
686 if ((clk_float < p[i] + 0.1) && (clk_float > p[i] - 0.1))
692static int security_config_set_gen4(
struct switchtec_dev *dev,
696 struct setting_data {
698 uint32_t pub_key_exponent;
701 struct get_cfgs_reply reply;
710 if (setting->attn_set.attestation_mode !=
711 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED)
714 ret = get_configs(dev, &reply, &otp_valid);
718 memset(&sd, 0,
sizeof(sd));
720 sd.cfg |= setting->jtag_lock_after_reset?
721 SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK : 0;
722 sd.cfg |= setting->jtag_lock_after_bl1?
723 SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK : 0;
724 sd.cfg |= setting->jtag_bl1_unlock_allowed?
725 SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK : 0;
726 sd.cfg |= setting->jtag_post_bl1_unlock_allowed?
727 SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK : 0;
729 spi_clk = convert_spi_clk_rate(setting->spi_clk_rate,
730 reply.spi_core_clk_high);
736 sd.cfg |= (spi_clk & SWITCHTEC_CLK_RATE_BITMASK) <<
737 SWITCHTEC_CLK_RATE_BITSHIFT;
739 sd.cfg |= (setting->i2c_recovery_tmo & SWITCHTEC_RC_TMO_BITMASK) <<
740 SWITCHTEC_RC_TMO_BITSHIFT;
741 sd.cfg |= (setting->i2c_port & SWITCHTEC_I2C_PORT_BITMASK) <<
742 SWITCHTEC_I2C_PORT_BITSHIFT;
744 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
746 sd.cfg |= (setting->i2c_addr & SWITCHTEC_I2C_ADDR_BITMASK) <<
749 ldata = setting->i2c_cmd_map & map_mask;
753 sd.cfg = htole64(sd.cfg);
755 sd.pub_key_exponent = htole32(setting->public_key_exponent);
757 return switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_SET,
758 &sd,
sizeof(sd), NULL, 0);
761static int security_config_set_gen5(
struct switchtec_dev *dev,
765 struct setting_data {
767 uint32_t pub_key_exponent;
770 uint32_t cdi_efuse_inc_mask;
773 struct get_cfgs_reply_gen5 reply;
779 uint8_t cmd_buf[64]={};
781 ret = get_configs_gen5(dev, &reply);
785 memset(&sd, 0,
sizeof(sd));
787 sd.cfg = setting->jtag_lock_after_reset?
788 SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK : 0;
789 sd.cfg |= setting->jtag_lock_after_bl1?
790 SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK : 0;
791 sd.cfg |= setting->jtag_bl1_unlock_allowed?
792 SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK : 0;
793 sd.cfg |= setting->jtag_post_bl1_unlock_allowed?
794 SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK : 0;
796 spi_clk = convert_spi_clk_rate(setting->spi_clk_rate,
797 reply.spi_core_clk_high);
803 sd.cfg |= (spi_clk & SWITCHTEC_CLK_RATE_BITMASK) <<
804 SWITCHTEC_CLK_RATE_BITSHIFT;
806 sd.cfg |= (setting->i2c_recovery_tmo & SWITCHTEC_RC_TMO_BITMASK) <<
807 SWITCHTEC_RC_TMO_BITSHIFT;
808 sd.cfg |= (setting->i2c_port & SWITCHTEC_I2C_PORT_BITMASK) <<
809 SWITCHTEC_I2C_PORT_BITSHIFT;
811 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
813 sd.cfg |= (setting->i2c_addr & SWITCHTEC_I2C_ADDR_BITMASK) <<
816 ldata = setting->i2c_cmd_map & map_mask;
820 sd.cfg = htole64(sd.cfg);
822 sd.pub_key_exponent = htole32(setting->public_key_exponent);
824 if (setting->attn_set.attestation_mode ==
825 SWITCHTEC_ATTESTATION_MODE_DICE) {
827 sd.cdi_efuse_inc_mask = setting->attn_set.cdi_efuse_inc_mask;
829 ldata = setting->attn_set.uds_selfgen? 1 : 0;
833 sd.uds_valid = setting->attn_set.uds_valid;
835 memcpy(sd.uds, setting->attn_set.uds_data, 32);
838 memcpy(cmd_buf + 4, &sd,
sizeof(sd));
839 return switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_SET_GEN5,
840 cmd_buf,
sizeof(cmd_buf), NULL, 0);
849int switchtec_security_config_set(
struct switchtec_dev *dev,
853 return security_config_set_gen5(dev, setting);
855 return security_config_set_gen4(dev, setting);
858static int active_image_index_get(
struct switchtec_dev *dev,
862 struct active_indices {
863 uint8_t index[SWITCHTEC_ACTV_IDX_MAX_ENTRIES];
866 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_GET, NULL,
867 0, &reply,
sizeof(reply));
871 index->keyman = reply.index[SWITCHTEC_ACTV_IMG_ID_KMAN];
872 index->bl2 = reply.index[SWITCHTEC_ACTV_IMG_ID_BL2];
873 index->config = reply.index[SWITCHTEC_ACTV_IMG_ID_CFG];
874 index->firmware = reply.index[SWITCHTEC_ACTV_IMG_ID_FW];
875 index->riot = SWITCHTEC_ACTIVE_INDEX_NOT_SET;
880static int active_image_index_get_gen5(
struct switchtec_dev *dev,
885 struct active_indices {
886 uint8_t index[SWITCHTEC_ACTV_IDX_MAX_ENTRIES];
889 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_GET_GEN5, &subcmd,
890 sizeof(subcmd), &reply,
sizeof(reply));
894 index->keyman = reply.index[SWITCHTEC_ACTV_IMG_ID_KMAN_GEN5];
895 index->bl2 = reply.index[SWITCHTEC_ACTV_IMG_ID_BL2_GEN5];
896 index->config = reply.index[SWITCHTEC_ACTV_IMG_ID_CFG_GEN5];
897 index->firmware = reply.index[SWITCHTEC_ACTV_IMG_ID_FW_GEN5];
898 index->riot = reply.index[SWITCHTEC_ACTV_IMG_ID_RC_GEN5];
909int switchtec_active_image_index_get(
struct switchtec_dev *dev,
913 return active_image_index_get_gen5(dev, index);
915 return active_image_index_get(dev, index);
918static int active_image_index_set(
struct switchtec_dev *dev,
928 } idx[SWITCHTEC_ACTV_IDX_SET_ENTRIES];
932 if (index->riot != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
937 memset(&set, 0,
sizeof(set));
939 if (index->keyman != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
940 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_KMAN;
941 set.idx[i].index = index->keyman;
945 if (index->bl2 != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
946 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_BL2;
947 set.idx[i].index = index->bl2;
951 if (index->config != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
952 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_CFG;
953 set.idx[i].index = index->config;
957 if (index->firmware != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
958 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_FW;
959 set.idx[i].index = index->firmware;
966 set.count = htole32(i);
968 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_SET, &set,
969 sizeof(set), NULL, 0);
973static int active_image_index_set_gen5(
struct switchtec_dev *dev,
984 } idx[SWITCHTEC_ACTV_IDX_SET_ENTRIES];
987 if (index->keyman != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
988 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_KMAN_GEN5;
989 set.idx[i].index = index->keyman;
993 if (index->riot != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
994 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_RC_GEN5;
995 set.idx[i].index = index->riot;
999 if (index->bl2 != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
1000 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_BL2_GEN5;
1001 set.idx[i].index = index->bl2;
1005 if (index->config != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
1006 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_CFG_GEN5;
1007 set.idx[i].index = index->config;
1011 if (index->firmware != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
1012 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_FW_GEN5;
1013 set.idx[i].index = index->firmware;
1020 set.count = htole32(i);
1022 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_SET_GEN5, &set,
1023 sizeof(set), NULL, 0);
1033int switchtec_active_image_index_set(
struct switchtec_dev *dev,
1037 return active_image_index_set_gen5(dev, index);
1039 return active_image_index_set(dev, index);
1048int switchtec_fw_exec(
struct switchtec_dev *dev,
1049 enum switchtec_bl2_recovery_mode recovery_mode)
1051 uint32_t cmd_id = MRPC_FW_TX;
1052 struct fw_exec_struct {
1054 uint8_t recovery_mode;
1058 memset(&cmd, 0,
sizeof(cmd));
1059 cmd.subcmd = MRPC_FW_TX_EXEC;
1060 cmd.recovery_mode = recovery_mode;
1063 cmd_id = MRPC_FW_TX_GEN6;
1065 cmd_id = MRPC_FW_TX_GEN5;
1067 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
1082int switchtec_boot_resume(
struct switchtec_dev *dev)
1084 uint32_t subcmd = 0;
1087 return switchtec_mfg_cmd(dev, MRPC_BOOTUP_RESUME_GEN5,
1088 &subcmd,
sizeof(subcmd),
1091 return switchtec_mfg_cmd(dev, MRPC_BOOTUP_RESUME,
1095static int secure_state_set(
struct switchtec_dev *dev,
1096 enum switchtec_secure_state state)
1100 data = htole32(state);
1102 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET,
1103 &data,
sizeof(data), NULL, 0);
1106static int secure_state_set_gen5(
struct switchtec_dev *dev,
1107 enum switchtec_secure_state state)
1115 data.state = htole32(state);
1117 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET_GEN5,
1118 &data,
sizeof(data), NULL, 0);
1121#define GEN6_STATE_SET_SUBCMD_DEBUG_PROTECT 0x0
1122#define GEN6_STATE_SET_SUBCMD_STATE_TRANS 0x1
1124int switchtec_secure_state_set_debug_protect(
struct switchtec_dev *dev)
1129 return ERR_SUBCMD_INVALID;
1131 data = htole32(GEN6_STATE_SET_SUBCMD_DEBUG_PROTECT);
1133 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET_GEN6,
1134 &data,
sizeof(data), NULL, 0);
1137int switchtec_secure_state_set_transition(
struct switchtec_dev *dev,
1138 enum switchtec_secure_state state)
1143 return ERR_SUBCMD_INVALID;
1145 if ((state != SWITCHTEC_INITIALIZED_UNSECURED)
1146 && (state != SWITCHTEC_INITIALIZED_SECURED)) {
1147 return ERR_PARAM_INVALID;
1150 data = htole32(GEN6_STATE_SET_SUBCMD_STATE_TRANS | (state << 8));
1152 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET_GEN6,
1153 &data,
sizeof(data), NULL, 0);
1162int switchtec_secure_state_set(
struct switchtec_dev *dev,
1163 enum switchtec_secure_state state)
1165 if ((state != SWITCHTEC_INITIALIZED_UNSECURED)
1166 && (state != SWITCHTEC_INITIALIZED_SECURED)) {
1167 return ERR_PARAM_INVALID;
1171 return switchtec_secure_state_set_transition(dev, state);
1173 return secure_state_set_gen5(dev, state);
1175 return secure_state_set(dev, state);
1178static int dbg_unlock_send_pubkey(
struct switchtec_dev *dev,
1182 struct public_key_cmd {
1185 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1186 uint32_t pub_key_exp;
1189 cmd.subcmd = MRPC_DBG_UNLOCK_PKEY;
1190 memcpy(cmd.pub_key, public_key->pubkey, SWITCHTEC_PUB_KEY_LEN);
1191 cmd.pub_key_exp = htole32(public_key->pubkey_exp);
1193 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
1196static int dbg_unlock_send_pubkey_gen6(
struct switchtec_dev *dev,
1200 struct public_key_cmd_gen6 {
1202 uint8_t reserved[3];
1207 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1210 cmd.subcmd = MRPC_GEN6_DBG_UNLOCK_PKEY;
1211 memcpy(cmd.pub_key, public_key->pubkey, SWITCHTEC_PUB_KEY_LEN);
1212 cmd.total_len = htole32(SWITCHTEC_PUB_KEY_LEN);
1213 cmd.total_crc = htole32(crc32(cmd.pub_key, SWITCHTEC_PUB_KEY_LEN, 0, 1, 1));
1214 cmd.data_len = htole32(SWITCHTEC_PUB_KEY_LEN);
1215 cmd.offset = htole32(0);
1217 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
1220static int dbg_unlock_send_sig_gen6(
struct switchtec_dev *dev,
1224 struct sig_cmd_gen6 {
1227 uint8_t reserved[2];
1232 uint8_t signature[SWITCHTEC_SIG_LEN];
1235 cmd.subcmd = MRPC_GEN6_DBG_UNLOCK_SIG;
1236 cmd.sig_type = KMT_SIG_FORMAT_RSA4KSHA2;
1237 memcpy(cmd.signature, signature->signature, SWITCHTEC_SIG_LEN);
1238 cmd.total_len = htole32(SWITCHTEC_SIG_LEN);
1239 cmd.total_crc = htole32(crc32(cmd.signature, SWITCHTEC_SIG_LEN, 0, 1, 1));
1240 cmd.data_len = htole32(SWITCHTEC_SIG_LEN);
1241 cmd.offset = htole32(0);
1243 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
1255int switchtec_dbg_unlock(
struct switchtec_dev *dev, uint32_t serial,
1256 uint32_t ver_sec_unlock,
1265 struct unlock_cmd_gen6 {
1268 uint8_t token[SWITCHTEC_GEN6_TOKEN_LEN];
1272 cmd_id = MRPC_DBG_UNLOCK_GEN6;
1274 ret = dbg_unlock_send_pubkey_gen6(dev, public_key, cmd_id);
1278 ret = dbg_unlock_send_sig_gen6(dev, signature, cmd_id);
1282 cmd.subcmd = MRPC_GEN6_DBG_UNLOCK_STATIC;
1283 memcpy(cmd.token, token->token, SWITCHTEC_GEN6_TOKEN_LEN);
1285 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
1292 uint32_t unlock_ver;
1293 uint8_t signature[SWITCHTEC_SIG_LEN];
1297 cmd_id = get_dbg_unlock_id(dev);
1299 ret = dbg_unlock_send_pubkey(dev, public_key, cmd_id);
1303 cmd.subcmd = MRPC_DBG_UNLOCK_DATA;
1304 cmd.serial = htole32(serial);
1305 cmd.unlock_ver = htole32(ver_sec_unlock);
1306 memcpy(cmd.signature, signature->signature, SWITCHTEC_SIG_LEN);
1308 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
1319int switchtec_dbg_unlock_get_token_gen6(
struct switchtec_dev *dev,
1325 struct get_unlock_token_cmd_gen6 {
1332 cmd_id = MRPC_DBG_UNLOCK_GEN6;
1334 struct get_unlock_token_reply_gen6 {
1335 uint8_t token[SWITCHTEC_GEN6_TOKEN_LEN];
1338 cmd.subcmd = MRPC_GEN6_DBG_UNLOCK_TOKEN_GET;
1340 if(token_type == GEN6_TOKEN_STATIC)
1341 cmd.token_type = SECURE_TOKEN_GET_TYPE_STATIC;
1343 cmd.token_type = SECURE_TOKEN_GET_TYPE_EPHEMERAL;
1345 ret = switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), &reply,
1350 memcpy(&token->token, &reply, SWITCHTEC_GEN6_TOKEN_LEN);
1354int switchtec_dbg_unlock_status_get_gen6(
struct switchtec_dev *dev,
1355 uint32_t *jtag_status)
1363 uint32_t jtag_status;
1366 cmd.subcmd = MRPC_GEN6_DBG_UNLOCK_STATUS_GET;
1367 ret = switchtec_mfg_cmd(dev, MRPC_DBG_UNLOCK_GEN6,
1368 &cmd,
sizeof(cmd), &reply,
sizeof(reply));
1372 *jtag_status = le32toh(reply.jtag_status);
1376#define GEN6_STATE_SET_SUBCMD_STATE_GET 0x2
1378int switchtec_secure_state_get_gen6(
struct switchtec_dev *dev,
1379 enum switchtec_secure_state_gen6 *state)
1391 data = htole32(GEN6_STATE_SET_SUBCMD_STATE_GET);
1393 ret = switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET_GEN6,
1394 &data,
sizeof(data), &reply,
sizeof(reply));
1398 *state = (
enum switchtec_secure_state_gen6)(le32toh(reply) & 0xFF);
1411int switchtec_dbg_unlock_version_update(
struct switchtec_dev *dev,
1413 uint32_t ver_sec_unlock,
1422 uint32_t unlock_ver;
1423 uint8_t signature[SWITCHTEC_SIG_LEN];
1427 cmd_id = get_dbg_unlock_id(dev);
1429 ret = dbg_unlock_send_pubkey(dev, public_key, cmd_id);
1433 cmd.subcmd = MRPC_DBG_UNLOCK_UPDATE;
1434 cmd.serial = htole32(serial);
1435 cmd.unlock_ver = htole32(ver_sec_unlock);
1436 memcpy(cmd.signature, signature->signature, SWITCHTEC_SIG_LEN);
1438 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
1441static int check_sec_cfg_header(
struct switchtec_dev *dev,
1446 char magic[4] = {
'S',
'S',
'F',
'F'};
1448 struct setting_file_header {
1458 rlen = fread(&hdr,
sizeof(hdr), 1, setting_file);
1463 if (memcmp(hdr.magic, magic,
sizeof(magic)))
1466 switch (hdr.hw_gen) {
1468 gen = SWITCHTEC_GEN4;
1471 gen = SWITCHTEC_GEN5;
1480 fseek(setting_file, 0, SEEK_END);
1481 data_len = ftell(setting_file) -
sizeof(hdr);
1482 fseek(setting_file,
sizeof(hdr), SEEK_SET);
1484 rlen = fread(data, 1, data_len, setting_file);
1485 if (rlen < data_len)
1488 crc = crc32(data, data_len, 0, 1, 1);
1489 if (crc != le32toh(hdr.crc))
1492 fseek(setting_file,
sizeof(hdr), SEEK_SET);
1496static int read_sec_cfg_file(
struct switchtec_dev *dev,
1500 struct setting_file_data {
1502 uint32_t pub_key_exponent;
1505 struct get_cfgs_reply reply;
1506 uint32_t addr_shift;
1513 ret = get_configs(dev, &reply, &otp_valid);
1519 ret = fread(&data,
sizeof(data), 1, setting_file);
1524 data.cfg = le64toh(data.cfg);
1526 set->jtag_lock_after_reset =
1527 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK);
1528 set->jtag_lock_after_bl1 =
1529 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK);
1530 set->jtag_bl1_unlock_allowed =
1531 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK);
1532 set->jtag_post_bl1_unlock_allowed =
1533 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK);
1535 spi_clk = (data.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) &
1536 SWITCHTEC_CLK_RATE_BITMASK;
1544 if (reply.spi_core_clk_high)
1545 set->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
1547 set->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
1549 set->i2c_recovery_tmo =
1550 (data.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) &
1551 SWITCHTEC_RC_TMO_BITMASK;
1553 (data.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) &
1554 SWITCHTEC_I2C_PORT_BITMASK;
1556 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
1559 (data.cfg >> addr_shift) &
1560 SWITCHTEC_I2C_ADDR_BITMASK;
1561 set->i2c_cmd_map = (data.cfg >> map_shift) & map_mask;
1563 set->public_key_exponent = le32toh(data.pub_key_exponent);
1565 set->attn_set.attestation_mode =
1566 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED;
1571static int read_sec_cfg_file_gen5(
struct switchtec_dev *dev,
1575 struct setting_data {
1577 uint32_t pub_key_exponent;
1579 uint32_t cdi_efuse_inc_mask;
1581 struct get_cfgs_reply_gen5 reply;
1582 uint32_t addr_shift;
1589 ret = get_configs_gen5(dev, &reply);
1595 ret = fread(&data,
sizeof(data), 1, setting_file);
1600 data.cfg = le64toh(data.cfg);
1602 set->jtag_lock_after_reset =
1603 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK);
1604 set->jtag_lock_after_bl1 =
1605 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK);
1606 set->jtag_bl1_unlock_allowed =
1607 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK);
1608 set->jtag_post_bl1_unlock_allowed =
1609 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK);
1611 spi_clk = (data.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) &
1612 SWITCHTEC_CLK_RATE_BITMASK;
1620 if (reply.spi_core_clk_high)
1621 set->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
1623 set->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
1625 set->i2c_recovery_tmo =
1626 (data.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) &
1627 SWITCHTEC_RC_TMO_BITMASK;
1629 (data.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) &
1630 SWITCHTEC_I2C_PORT_BITMASK;
1632 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
1635 (data.cfg >> addr_shift) &
1636 SWITCHTEC_I2C_ADDR_BITMASK;
1637 set->i2c_cmd_map = (data.cfg >> map_shift) & map_mask;
1639 set->public_key_exponent = le32toh(data.pub_key_exponent);
1641 attest_mode = (data.cfg >> SWITCHTEC_ATTEST_BITSHIFT) &
1642 SWITCHTEC_ATTEST_BITMASK;
1643 if (attest_mode == 1) {
1644 set->attn_set.attestation_mode =
1645 SWITCHTEC_ATTESTATION_MODE_DICE;
1646 set->attn_set.cdi_efuse_inc_mask = data.cdi_efuse_inc_mask;
1647 set->attn_set.uds_selfgen = (data.cfg >> 44) & 0x1;
1649 set->attn_set.attestation_mode =
1650 SWITCHTEC_ATTESTATION_MODE_NONE;
1663int switchtec_read_sec_cfg_file(
struct switchtec_dev *dev,
1669 ret = check_sec_cfg_header(dev, setting_file);
1674 return read_sec_cfg_file(dev, setting_file, set);
1676 return read_sec_cfg_file_gen5(dev, setting_file, set);
1679static int kmsk_set_send_pubkey(
struct switchtec_dev *dev,
1683 struct kmsk_pubk_cmd {
1685 uint8_t reserved[3];
1686 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1687 uint32_t pub_key_exponent;
1690 cmd.subcmd = MRPC_KMSK_ENTRY_SET_PKEY;
1691 memcpy(cmd.pub_key, public_key->pubkey,
1692 SWITCHTEC_PUB_KEY_LEN);
1693 cmd.pub_key_exponent = htole32(public_key->pubkey_exp);
1695 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
1696 sizeof(cmd), NULL, 0);
1699static int kmsk_set_send_signature(
struct switchtec_dev *dev,
1703 struct kmsk_signature_cmd {
1705 uint8_t reserved[3];
1706 uint8_t signature[SWITCHTEC_SIG_LEN];
1709 cmd.subcmd = MRPC_KMSK_ENTRY_SET_SIG;
1710 memcpy(cmd.signature, signature->signature,
1713 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
1714 sizeof(cmd), NULL, 0);
1717static int kmsk_set_send_kmsk(
struct switchtec_dev *dev,
1721 struct kmsk_kmsk_cmd {
1723 uint8_t num_entries;
1724 uint8_t reserved[2];
1725 uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1728 cmd.subcmd = MRPC_KMSK_ENTRY_SET_KMSK;
1729 cmd.num_entries = 1;
1730 memcpy(cmd.kmsk, kmsk->kmsk, SWITCHTEC_KMSK_LEN);
1732 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd),
1748int switchtec_kmsk_set(
struct switchtec_dev *dev,
1757 cmd_id = MRPC_KMSK_ENTRY_SET_GEN5;
1759 cmd_id = MRPC_KMSK_ENTRY_SET;
1762 ret = kmsk_set_send_pubkey(dev, public_key, cmd_id);
1768 ret = kmsk_set_send_signature(dev, signature, cmd_id);
1773 return kmsk_set_send_kmsk(dev, kmsk, cmd_id);
1778#ifdef HAVE_DECL_PEM_READ_PUBKEY
1780#include <openssl/core_names.h>
1788int switchtec_read_pubk_file(FILE *pubk_file,
struct switchtec_pubkey *pubk)
1790 BIGNUM *bn_priv = NULL;
1791 uint32_t exponent_tmp;
1794 pkey = PEM_read_PUBKEY(pubk_file, NULL, NULL, NULL);
1796 fseek(pubk_file, 0L, SEEK_SET);
1797 pkey = PEM_read_PrivateKey(pubk_file, NULL, NULL, NULL);
1802 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bn_priv);
1803 BN_bn2bin(bn_priv, pubk->pubkey);
1804 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bn_priv);
1805 BN_bn2bin(bn_priv, (uint8_t *)&exponent_tmp);
1806 pubk->pubkey_exp = be32toh(exponent_tmp);
1808 EVP_PKEY_free(pkey);
1814#if !HAVE_DECL_RSA_GET0_KEY
1819static void RSA_get0_key(
const RSA *r,
const BIGNUM **n,
1820 const BIGNUM **e,
const BIGNUM **d)
1837int switchtec_read_pubk_file(FILE *pubk_file,
struct switchtec_pubkey *pubk)
1840 const BIGNUM *modulus_bn;
1841 const BIGNUM *exponent_bn;
1842 uint32_t exponent_tmp = 0;
1844 RSAKey = PEM_read_RSA_PUBKEY(pubk_file, NULL, NULL, NULL);
1845 if (RSAKey == NULL) {
1846 fseek(pubk_file, 0L, SEEK_SET);
1847 RSAKey = PEM_read_RSAPrivateKey(pubk_file, NULL, NULL, NULL);
1852 RSA_get0_key(RSAKey, &modulus_bn, &exponent_bn, NULL);
1854 BN_bn2bin(modulus_bn, pubk->pubkey);
1855 BN_bn2bin(exponent_bn, (uint8_t *)&exponent_tmp);
1857 pubk->pubkey_exp = be32toh(exponent_tmp);
1873int switchtec_read_kmsk_file(FILE *kmsk_file,
struct switchtec_kmsk *kmsk)
1876 struct kmsk_struct {
1881 uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1884 char magic[4] = {
'K',
'M',
'S',
'K'};
1887 rlen = fread(&data, 1,
sizeof(data), kmsk_file);
1889 if (rlen <
sizeof(data))
1892 if (memcmp(data.magic, magic,
sizeof(magic)))
1895 crc = crc32(data.kmsk, SWITCHTEC_KMSK_LEN, 0, 1, 1);
1896 if (crc != le32toh(data.crc32))
1899 memcpy(kmsk->kmsk, data.kmsk, SWITCHTEC_KMSK_LEN);
1910int switchtec_read_signature_file(FILE *sig_file,
1915 rlen = fread(signature->signature, 1, SWITCHTEC_SIG_LEN, sig_file);
1917 if (rlen < SWITCHTEC_SIG_LEN)
1933 rlen = fread(token->token, 1, SWITCHTEC_GEN6_TOKEN_LEN, tkn_file);
1934 if (rlen < SWITCHTEC_GEN6_TOKEN_LEN)
1946int switchtec_read_uds_file(FILE *uds_file,
struct switchtec_uds *uds)
1950 rlen = fread(uds->uds, 1, SWITCHTEC_UDS_LEN, uds_file);
1952 if (rlen < SWITCHTEC_UDS_LEN)
1974 for (key_idx = 0; key_idx < state->public_key_num; key_idx++) {
1975 if (memcmp(state->public_key[key_idx], kmsk->kmsk,
1976 SWITCHTEC_KMSK_LEN) == 0)
1985static int switchtec_mfg_cmd(
struct switchtec_dev *dev, uint32_t cmd,
1986 const void *payload,
size_t payload_len,
1987 void *resp,
size_t resp_len)
1989 if (dev->ops->flags & SWITCHTEC_OPS_FLAG_NO_MFG) {
1990 errno = ERR_UART_NOT_SUPPORTED | SWITCHTEC_ERRNO_MRPC_FLAG_BIT;
1998static int sn_ver_get_gen4(
struct switchtec_dev *dev,
2003 uint32_t chip_serial;
2007 uint32_t ver_sec_unlock;
2010 ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET, NULL, 0,
2011 &reply,
sizeof(reply));
2015 info->chip_serial = reply.chip_serial;
2016 info->ver_bl2 = reply.ver_bl2;
2017 info->ver_km = reply.ver_km;
2018 info->riot_ver_valid =
false;
2019 info->ver_sec_unlock = reply.ver_sec_unlock;
2020 info->ver_main = reply.ver_main;
2025static int sn_ver_get_gen5(
struct switchtec_dev *dev,
2029 uint32_t subcmd = 0;
2031 uint32_t chip_serial;
2036 uint32_t ver_sec_unlock;
2039 ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET_GEN5, &subcmd, 4,
2040 &reply,
sizeof(reply));
2044 info->chip_serial = reply.chip_serial;
2045 info->ver_bl2 = reply.ver_bl2;
2046 info->ver_km = reply.ver_km;
2047 info->riot_ver_valid =
true;
2048 info->ver_riot = reply.ver_riot;
2049 info->ver_sec_unlock = reply.ver_sec_unlock;
2050 info->ver_main = reply.ver_main;
2055static int sn_ver_get_gen6(
struct switchtec_dev *dev,
2059 uint32_t subcmd = 0;
2063 uint32_t PSID_UID_valid_flags;
2064 uint32_t SVNSV_rsvrd;
2065 uint32_t bl2_sec_ver;
2067 uint32_t mainfw_sec_ver;
2068 uint32_t svl1_rsvrd;
2069 uint32_t svl2_rsvrd;
2070 uint32_t dbg_tok_sec_ver_rsvrd;
2071 uint32_t kmt_sec_ver_rsvrd;
2074 ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET_GEN6, &subcmd, 4,
2075 &reply,
sizeof(reply));
2079 info->UID = malloc(
sizeof(reply.UID));
2082 info->PSID0 = malloc(
sizeof(reply.PSID0));
2088 memcpy(info->UID, reply.UID,
sizeof(reply.UID));
2089 memcpy(info->PSID0, reply.PSID0,
sizeof(reply.PSID0));
2090 info->PSID_UID_valid_flags = reply.PSID_UID_valid_flags;
2091 info->ver_bl2 = reply.bl2_sec_ver;
2092 info->ver_main = reply.mainfw_sec_ver;
2093 info->dbg_tok_sec_ver_rsvrd = reply.dbg_tok_sec_ver_rsvrd;
2094 info->kmt_sec_ver_rsvrd = reply.kmt_sec_ver_rsvrd;
2109 return sn_ver_get_gen6(dev, info);
2111 return sn_ver_get_gen5(dev, info);
2113 return sn_ver_get_gen4(dev, info);
2116int switchtec_device_config_get(
struct switchtec_dev *dev,
2120 uint32_t subcmd = DEVICE_CONFIG_SUB_CMD_GET;
2127 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &subcmd,
sizeof(subcmd),
2128 settings,
sizeof(*settings));
2132int switchtec_device_config_get_security(
struct switchtec_dev *dev,
2136 uint32_t subcmd = DEVICE_CONFIG_SUB_CMD_GET_SECURITY;
2143 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &subcmd,
sizeof(subcmd),
2144 config,
sizeof(*config));
2148int switchtec_device_config_get_customer(
struct switchtec_dev *dev,
2152 uint32_t subcmd = DEVICE_CONFIG_SUB_CMD_GET_CUSTOMER;
2159 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &subcmd,
sizeof(subcmd),
2160 settings,
sizeof(*settings));
2164int switchtec_device_config_set_dev(
struct switchtec_dev *dev,
2170 uint8_t reserved[3];
2179 memset(&cmd, 0,
sizeof(cmd));
2180 cmd.subcmd = DEVICE_CONFIG_SUB_CMD_SET_DEVICE;
2181 memcpy(&cmd.settings, settings,
sizeof(*settings));
2183 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &cmd,
sizeof(cmd),
2188int switchtec_device_config_set_customer(
struct switchtec_dev *dev,
2194 uint8_t reserved[3];
2195 struct switchtec_device_config_customer_settings settings;
2203 memset(&cmd, 0,
sizeof(cmd));
2204 cmd.subcmd = DEVICE_CONFIG_SUB_CMD_SET_CUSTOMER;
2205 memcpy(&cmd.settings, settings,
sizeof(*settings));
2207 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &cmd,
sizeof(cmd),
2212int switchtec_device_config_set_security(
struct switchtec_dev *dev,
2218 uint8_t reserved[3];
2219 struct switchtec_device_config_secure_settings settings;
2227 memset(&cmd, 0,
sizeof(cmd));
2228 cmd.subcmd = DEVICE_CONFIG_SUB_CMD_SET_SECURITY;
2229 memcpy(&cmd.settings, settings,
sizeof(*settings));
2231 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &cmd,
sizeof(cmd),
2236int switchtec_dok_config_signature(
struct switchtec_dev *dev,
2246 ret = switchtec_mfg_cmd(dev, MRPC_DOK_CONFIG, sig,
2247 20 + sig->data_len, NULL, 0);
2251int switchtec_dok_config_key_add(
struct switchtec_dev *dev,
2261 ret = switchtec_mfg_cmd(dev, MRPC_DOK_CONFIG, key_add,
sizeof(*key_add),
2266int switchtec_dok_config_key_revoke(
struct switchtec_dev *dev,
2276 ret = switchtec_mfg_cmd(dev, MRPC_DOK_CONFIG, key_revoke,
2277 sizeof(*key_revoke), NULL, 0);
int switchtec_cmd(struct switchtec_dev *dev, uint32_t cmd, const void *payload, size_t payload_len, void *resp, size_t resp_len)
Execute an MRPC command.
int switchtec_sn_ver_get(struct switchtec_dev *dev, struct switchtec_sn_ver_info *info)
Get serial number and security version.
switchtec_gen
The PCIe generations.
static int switchtec_is_gen6(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 6 device.
static int switchtec_is_gen4(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 4 device.
static int switchtec_is_gen5(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 5 device.