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);
110#if (HAVE_LIBCRYPTO && !HAVE_DECL_RSA_GET0_KEY)
115static void RSA_get0_key(
const RSA *r,
const BIGNUM **n,
116 const BIGNUM **e,
const BIGNUM **d)
127static void get_i2c_operands(
enum switchtec_gen gen, uint32_t *addr_shift,
128 uint32_t *map_shift, uint32_t *map_mask)
130 if (gen > SWITCHTEC_GEN4) {
131 *addr_shift = SWITCHTEC_I2C_ADDR_BITSHIFT_GEN5;
132 *map_shift = SWITCHTEC_CMD_MAP_BITSHIFT_GEN5;
133 *map_mask = SWITCHTEC_CMD_MAP_BITMASK_GEN5;
135 *addr_shift = SWITCHTEC_I2C_ADDR_BITSHIFT;
136 *map_shift = SWITCHTEC_CMD_MAP_BITSHIFT;
137 *map_mask = SWITCHTEC_CMD_MAP_BITMASK;
141static float spi_clk_rate_float[] = {
142 100, 67, 50, 40, 33.33, 28.57, 25, 22.22, 20, 18.18
145static float spi_clk_hi_rate_float[] = {
146 120, 80, 60, 48, 40, 34, 30, 26.67, 24, 21.82
149struct get_cfgs_reply {
153 uint32_t public_key_exponent;
155 uint8_t public_key_num;
156 uint8_t public_key_ver;
157 uint8_t spi_core_clk_high;
158 uint8_t public_key[4][SWITCHTEC_KMSK_LEN];
162struct get_cfgs_reply_gen5 {
166 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[10][SWITCHTEC_KMSK_LEN];
172 uint32_t cdi_efuse_inc_mask;
173 uint8_t uds_data[32];
176static int get_configs(
struct switchtec_dev *dev,
177 struct get_cfgs_reply *cfgs,
183 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET_EXT,
184 &subcmd,
sizeof(subcmd),
185 cfgs,
sizeof(
struct get_cfgs_reply));
186 if (ret && ERRNO_MRPC(errno) != ERR_CMD_INVALID)
195 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET,
197 sizeof(
struct get_cfgs_reply));
202static int get_configs_gen5(
struct switchtec_dev *dev,
203 struct get_cfgs_reply_gen5 *cfgs)
207 return switchtec_mfg_cmd(dev,
208 MRPC_SECURITY_CONFIG_GET_GEN5,
209 &subcmd,
sizeof(subcmd),
210 cfgs,
sizeof(
struct get_cfgs_reply_gen5));
213int switchtec_security_spi_avail_rate_get(
struct switchtec_dev *dev,
217 struct get_cfgs_reply reply;
220 ret = get_configs(dev, &reply, &otp_valid);
224 rates->num_rates = 10;
225 if (reply.spi_core_clk_high)
226 memcpy(rates->rates, spi_clk_hi_rate_float,
227 sizeof(spi_clk_hi_rate_float));
229 memcpy(rates->rates, spi_clk_rate_float,
230 sizeof(spi_clk_rate_float));
238 otp->basic_valid = !!(flags & BIT(5));
239 otp->basic = !!(flags & BIT(6));
240 otp->mixed_ver_valid = !!(flags & BIT(7));
241 otp->mixed_ver = !!(flags & BIT(8));
242 otp->main_fw_ver_valid = !!(flags & BIT(9));
243 otp->main_fw_ver = !!(flags & BIT(10));
244 otp->sec_unlock_ver_valid = !!(flags & BIT(11));
245 otp->sec_unlock_ver = !!(flags & BIT(12));
246 otp->kmsk_valid[0] = !!(flags & BIT(13));
247 otp->kmsk[0] = !!(flags & BIT(14));
248 otp->kmsk_valid[1] = !!(flags & BIT(15));
249 otp->kmsk[1] = !!(flags & BIT(16));
250 otp->kmsk_valid[2] = !!(flags & BIT(17));
251 otp->kmsk[2] = !!(flags & BIT(18));
252 otp->kmsk_valid[3] = !!(flags & BIT(19));
253 otp->kmsk[3] = !!(flags & BIT(20));
256static void parse_otp_settings_gen5(
258 uint32_t flags0, uint32_t flags1)
260 otp->basic_valid = !!(flags0 & BIT(8));
261 otp->basic = !!(flags0 & BIT(9));
262 otp->debug_mode_valid = !!(flags0 & BIT(10));
263 otp->debug_mode = !!(flags0 & BIT(11));
264 otp->key_ver_valid = !!(flags0 & BIT(12));
265 otp->key_ver = !!(flags0 & BIT(13));
266 otp->rc_ver_valid = !!(flags0 & BIT(14));
267 otp->rc_ver = !!(flags0 & BIT(15));
268 otp->bl2_ver_valid = !!(flags0 & BIT(16));
269 otp->bl2_ver = !!(flags0 & BIT(17));
270 otp->main_fw_ver_valid = !!(flags0 & BIT(18));
271 otp->main_fw_ver = !!(flags0 & BIT(19));
272 otp->sec_unlock_ver_valid = !!(flags0 & BIT(20));
273 otp->sec_unlock_ver = !!(flags0 & BIT(21));
274 otp->kmsk_valid[0] = !!(flags0 & BIT(22));
275 otp->kmsk[0] = !!(flags0 & BIT(23));
276 otp->kmsk_valid[1] = !!(flags0 & BIT(24));
277 otp->kmsk[1] = !!(flags0 & BIT(25));
278 otp->kmsk_valid[2] = !!(flags0 & BIT(26));
279 otp->kmsk[2] = !!(flags0 & BIT(27));
280 otp->kmsk_valid[3] = !!(flags0 & BIT(28));
281 otp->kmsk[3] = !!(flags0 & BIT(29));
282 otp->kmsk_valid[4] = !!(flags0 & BIT(30));
283 otp->kmsk[4] = !!(flags0 & BIT(31));
284 otp->kmsk_valid[5] = !!(flags1 & BIT(0));
285 otp->kmsk[5] = !!(flags1 & BIT(1));
286 otp->kmsk_valid[6] = !!(flags1 & BIT(2));
287 otp->kmsk[6] = !!(flags1 & BIT(3));
288 otp->kmsk_valid[7] = !!(flags1 & BIT(4));
289 otp->kmsk[7] = !!(flags1 & BIT(5));
290 otp->kmsk_valid[8] = !!(flags1 & BIT(6));
291 otp->kmsk[8] = !!(flags1 & BIT(7));
292 otp->kmsk_valid[9] = !!(flags1 & BIT(8));
293 otp->kmsk[9] = !!(flags1 & BIT(9));
294 otp->cdi_efuse_inc_mask_valid = !!(flags1 & BIT(10));
295 otp->cdi_efuse_inc_mask = !!(flags1 & BIT(11));
296 otp->uds_valid = !!(flags1 & BIT(12));
297 otp->uds = !!(flags1 & BIT(13));
298 otp->uds_mask_valid = !!(flags1 & BIT(14));
299 otp->uds_mask = !!(flags1 & BIT(15));
300 otp->mchp_uds_valid = !!(flags1 & BIT(16));
301 otp->mchp_uds = !!(flags1 & BIT(17));
302 otp->mchp_uds_mask_valid = !!(flags1 & BIT(18));
303 otp->mchp_uds_mask = !!(flags1 & BIT(19));
304 otp->did_cert0_valid = !!(flags1 & BIT(20));
305 otp->did_cert0 = !!(flags1 & BIT(21));
306 otp->did_cert1_valid = !!(flags1 & BIT(22));
307 otp->did_cert1 = !!(flags1 & BIT(23));
310static int security_config_get(
struct switchtec_dev *dev,
318 struct get_cfgs_reply reply;
321 ret = get_configs(dev, &reply, &otp_valid);
325 reply.valid = le32toh(reply.valid);
326 reply.cfg = le64toh(reply.cfg);
327 reply.public_key_exponent = le32toh(reply.public_key_exponent);
329 state->basic_setting_valid = !!(reply.valid & 0x01);
330 state->public_key_exp_valid = !!(reply.valid & 0x02);
331 state->public_key_num_valid = !!(reply.valid & 0x04);
332 state->public_key_ver_valid = !!(reply.valid & 0x08);
333 state->public_key_valid = !!(reply.valid & 0x10);
335 state->debug_mode_valid = state->basic_setting_valid;
337 state->otp_valid = otp_valid;
339 parse_otp_settings(&state->otp, reply.valid);
341 state->use_otp_ext =
false;
343 state->debug_mode = reply.cfg & 0x03;
344 state->secure_state = (reply.cfg>>2) & 0x03;
346 state->jtag_lock_after_reset = !!(reply.cfg & 0x40);
347 state->jtag_lock_after_bl1 = !!(reply.cfg & 0x80);
348 state->jtag_bl1_unlock_allowed = !!(reply.cfg & 0x0100);
349 state->jtag_post_bl1_unlock_allowed = !!(reply.cfg & 0x0200);
351 spi_clk = (reply.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) & 0x0f;
359 if (reply.spi_core_clk_high)
360 state->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
362 state->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
364 state->i2c_recovery_tmo =
365 (reply.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) & 0x0f;
366 state->i2c_port = (reply.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) & 0xf;
368 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
371 (reply.cfg >> addr_shift) & SWITCHTEC_I2C_ADDR_BITMASK;
372 state->i2c_cmd_map = (reply.cfg >> map_shift) & map_mask;
374 state->public_key_exponent = reply.public_key_exponent;
375 state->public_key_num = reply.public_key_num;
376 state->public_key_ver = reply.public_key_ver;
378 if (state->public_key_num)
379 memcpy(state->public_key, reply.public_key,
380 state->public_key_num * SWITCHTEC_KMSK_LEN);
382 state->attn_state.attestation_mode =
383 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED;
388static int security_config_get_gen5(
struct switchtec_dev *dev,
396 struct get_cfgs_reply_gen5 reply;
399 ret = get_configs_gen5(dev, &reply);
403 reply.valid0 = le32toh(reply.valid0);
404 reply.valid1 = le32toh(reply.valid1);
406 reply.cfg = le64toh(reply.cfg);
407 reply.public_key_exponent = le32toh(reply.public_key_exponent);
409 state->basic_setting_valid = !!(reply.valid0 & 0x01);
410 state->public_key_exp_valid = !!(reply.valid0 & 0x04);
411 state->public_key_num_valid = !!(reply.valid0 & 0x08);
412 state->public_key_ver_valid = !!(reply.valid0 & 0x10);
413 state->public_key_valid = !!(reply.valid0 & 0x20);
415 state->debug_mode_valid = !!(reply.valid0 & 0x02);
416 state->attn_state.cdi_efuse_inc_mask_valid = !!(reply.valid0 & 0x40);
418 state->otp_valid =
true;
419 parse_otp_settings_gen5(&state->otp_ext, reply.valid0,
422 state->use_otp_ext =
true;
424 state->debug_mode = reply.cfg & 0x03;
425 state->secure_state = (reply.cfg>>2) & 0x03;
427 state->jtag_lock_after_reset = !!(reply.cfg & 0x40);
428 state->jtag_lock_after_bl1 = !!(reply.cfg & 0x80);
429 state->jtag_bl1_unlock_allowed = !!(reply.cfg & 0x0100);
430 state->jtag_post_bl1_unlock_allowed = !!(reply.cfg & 0x0200);
432 spi_clk = (reply.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) & 0x0f;
440 if (reply.spi_core_clk_high)
441 state->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
443 state->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
445 state->i2c_recovery_tmo =
446 (reply.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) & 0x0f;
447 state->i2c_port = (reply.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) & 0xf;
449 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
452 (reply.cfg >> addr_shift) & SWITCHTEC_I2C_ADDR_BITMASK;
453 state->i2c_cmd_map = (reply.cfg >> map_shift) & map_mask;
455 state->public_key_exponent = reply.public_key_exponent;
456 state->public_key_num = reply.public_key_num;
457 state->public_key_ver = reply.public_key_ver;
458 memcpy(state->public_key, reply.public_key,
459 state->public_key_num * SWITCHTEC_KMSK_LEN);
461 attn_mode = (reply.cfg >> SWITCHTEC_ATTEST_BITSHIFT) &
462 SWITCHTEC_ATTEST_BITMASK;
464 state->attn_state.attestation_mode =
465 SWITCHTEC_ATTESTATION_MODE_DICE;
467 state->attn_state.attestation_mode =
468 SWITCHTEC_ATTESTATION_MODE_NONE;
470 state->attn_state.uds_selfgen =
471 (reply.cfg >> SWITCHTEC_UDS_SELFGEN_BITSHIFT) &
472 SWITCHTEC_UDS_SELFGEN_BITMASK;
473 state->attn_state.cdi_efuse_inc_mask =
474 le32toh(reply.cdi_efuse_inc_mask);
476 if (state->secure_state == SWITCHTEC_UNINITIALIZED_UNSECURED &&
477 state->attn_state.attestation_mode ==
478 SWITCHTEC_ATTESTATION_MODE_DICE &&
479 !state->attn_state.uds_selfgen)
480 state->attn_state.uds_visible =
true;
482 state->attn_state.uds_visible =
false;
484 if (state->attn_state.uds_visible)
485 memcpy(state->attn_state.uds_data, reply.uds_data, 32);
496int switchtec_security_config_get(
struct switchtec_dev *dev,
500 return security_config_get_gen5(dev, state);
502 return security_config_get(dev, state);
505static int mailbox_to_file(
struct switchtec_dev *dev,
int fd)
508 int num_to_read = htole32(SWITCHTEC_MB_MAX_ENTRIES);
510 uint8_t num_returned;
511 uint8_t num_remaining;
513 uint8_t data[SWITCHTEC_MB_MAX_ENTRIES *
514 SWITCHTEC_MB_LOG_LEN];
518 ret = switchtec_mfg_cmd(dev, MRPC_MAILBOX_GET, &num_to_read,
519 sizeof(
int), &reply,
sizeof(reply));
523 reply.num_remaining = le32toh(reply.num_remaining);
524 reply.num_returned = le32toh(reply.num_returned);
526 ret = write(fd, reply.data,
527 (reply.num_returned) * SWITCHTEC_MB_LOG_LEN);
530 }
while (reply.num_remaining > 0);
535static int mailbox_to_file_gen5(
struct switchtec_dev *dev,
int fd)
540 uint32_t num_to_read;
543 uint8_t num_returned;
544 uint8_t num_remaining;
546 uint8_t data[SWITCHTEC_MB_MAX_ENTRIES *
547 SWITCHTEC_MB_LOG_LEN];
551 read.num_to_read = htole32(SWITCHTEC_MB_MAX_ENTRIES);
554 ret = switchtec_mfg_cmd(dev, MRPC_MAILBOX_GET_GEN5,
556 &reply,
sizeof(reply));
560 reply.num_remaining = le32toh(reply.num_remaining);
561 reply.num_returned = le32toh(reply.num_returned);
563 ret = write(fd, reply.data,
564 (reply.num_returned) * SWITCHTEC_MB_LOG_LEN);
567 }
while (reply.num_remaining > 0);
578int switchtec_mailbox_to_file(
struct switchtec_dev *dev,
int fd)
581 return mailbox_to_file_gen5(dev, fd);
583 return mailbox_to_file(dev, fd);
586static int convert_spi_clk_rate(
float clk_float,
int hi_rate)
592 p = spi_clk_hi_rate_float;
594 p = spi_clk_rate_float;
596 for (i = 0; i < 10; i++)
597 if ((clk_float < p[i] + 0.1) && (clk_float > p[i] - 0.1))
603static int security_config_set_gen4(
struct switchtec_dev *dev,
607 struct setting_data {
609 uint32_t pub_key_exponent;
612 struct get_cfgs_reply reply;
621 if (setting->attn_set.attestation_mode !=
622 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED)
625 ret = get_configs(dev, &reply, &otp_valid);
629 memset(&sd, 0,
sizeof(sd));
631 sd.cfg |= setting->jtag_lock_after_reset?
632 SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK : 0;
633 sd.cfg |= setting->jtag_lock_after_bl1?
634 SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK : 0;
635 sd.cfg |= setting->jtag_bl1_unlock_allowed?
636 SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK : 0;
637 sd.cfg |= setting->jtag_post_bl1_unlock_allowed?
638 SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK : 0;
640 spi_clk = convert_spi_clk_rate(setting->spi_clk_rate,
641 reply.spi_core_clk_high);
647 sd.cfg |= (spi_clk & SWITCHTEC_CLK_RATE_BITMASK) <<
648 SWITCHTEC_CLK_RATE_BITSHIFT;
650 sd.cfg |= (setting->i2c_recovery_tmo & SWITCHTEC_RC_TMO_BITMASK) <<
651 SWITCHTEC_RC_TMO_BITSHIFT;
652 sd.cfg |= (setting->i2c_port & SWITCHTEC_I2C_PORT_BITMASK) <<
653 SWITCHTEC_I2C_PORT_BITSHIFT;
655 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
657 sd.cfg |= (setting->i2c_addr & SWITCHTEC_I2C_ADDR_BITMASK) <<
660 ldata = setting->i2c_cmd_map & map_mask;
664 sd.cfg = htole64(sd.cfg);
666 sd.pub_key_exponent = htole32(setting->public_key_exponent);
668 return switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_SET,
669 &sd,
sizeof(sd), NULL, 0);
672static int security_config_set_gen5(
struct switchtec_dev *dev,
676 struct setting_data {
678 uint32_t pub_key_exponent;
681 uint32_t cdi_efuse_inc_mask;
684 struct get_cfgs_reply_gen5 reply;
690 uint8_t cmd_buf[64]={};
692 ret = get_configs_gen5(dev, &reply);
696 memset(&sd, 0,
sizeof(sd));
698 sd.cfg = setting->jtag_lock_after_reset?
699 SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK : 0;
700 sd.cfg |= setting->jtag_lock_after_bl1?
701 SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK : 0;
702 sd.cfg |= setting->jtag_bl1_unlock_allowed?
703 SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK : 0;
704 sd.cfg |= setting->jtag_post_bl1_unlock_allowed?
705 SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK : 0;
707 spi_clk = convert_spi_clk_rate(setting->spi_clk_rate,
708 reply.spi_core_clk_high);
714 sd.cfg |= (spi_clk & SWITCHTEC_CLK_RATE_BITMASK) <<
715 SWITCHTEC_CLK_RATE_BITSHIFT;
717 sd.cfg |= (setting->i2c_recovery_tmo & SWITCHTEC_RC_TMO_BITMASK) <<
718 SWITCHTEC_RC_TMO_BITSHIFT;
719 sd.cfg |= (setting->i2c_port & SWITCHTEC_I2C_PORT_BITMASK) <<
720 SWITCHTEC_I2C_PORT_BITSHIFT;
722 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
724 sd.cfg |= (setting->i2c_addr & SWITCHTEC_I2C_ADDR_BITMASK) <<
727 ldata = setting->i2c_cmd_map & map_mask;
731 sd.cfg = htole64(sd.cfg);
733 sd.pub_key_exponent = htole32(setting->public_key_exponent);
735 if (setting->attn_set.attestation_mode ==
736 SWITCHTEC_ATTESTATION_MODE_DICE) {
738 sd.cdi_efuse_inc_mask = setting->attn_set.cdi_efuse_inc_mask;
740 ldata = setting->attn_set.uds_selfgen? 1 : 0;
744 sd.uds_valid = setting->attn_set.uds_valid;
746 memcpy(sd.uds, setting->attn_set.uds_data, 32);
749 memcpy(cmd_buf + 4, &sd,
sizeof(sd));
750 return switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_SET_GEN5,
751 cmd_buf,
sizeof(cmd_buf), NULL, 0);
760int switchtec_security_config_set(
struct switchtec_dev *dev,
764 return security_config_set_gen5(dev, setting);
766 return security_config_set_gen4(dev, setting);
769static int active_image_index_get(
struct switchtec_dev *dev,
773 struct active_indices {
774 uint8_t index[SWITCHTEC_ACTV_IDX_MAX_ENTRIES];
777 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_GET, NULL,
778 0, &reply,
sizeof(reply));
782 index->keyman = reply.index[SWITCHTEC_ACTV_IMG_ID_KMAN];
783 index->bl2 = reply.index[SWITCHTEC_ACTV_IMG_ID_BL2];
784 index->config = reply.index[SWITCHTEC_ACTV_IMG_ID_CFG];
785 index->firmware = reply.index[SWITCHTEC_ACTV_IMG_ID_FW];
786 index->riot = SWITCHTEC_ACTIVE_INDEX_NOT_SET;
791static int active_image_index_get_gen5(
struct switchtec_dev *dev,
796 struct active_indices {
797 uint8_t index[SWITCHTEC_ACTV_IDX_MAX_ENTRIES];
800 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_GET_GEN5, &subcmd,
801 sizeof(subcmd), &reply,
sizeof(reply));
805 index->keyman = reply.index[SWITCHTEC_ACTV_IMG_ID_KMAN_GEN5];
806 index->bl2 = reply.index[SWITCHTEC_ACTV_IMG_ID_BL2_GEN5];
807 index->config = reply.index[SWITCHTEC_ACTV_IMG_ID_CFG_GEN5];
808 index->firmware = reply.index[SWITCHTEC_ACTV_IMG_ID_FW_GEN5];
809 index->riot = reply.index[SWITCHTEC_ACTV_IMG_ID_RC_GEN5];
820int switchtec_active_image_index_get(
struct switchtec_dev *dev,
824 return active_image_index_get_gen5(dev, index);
826 return active_image_index_get(dev, index);
829static int active_image_index_set(
struct switchtec_dev *dev,
839 } idx[SWITCHTEC_ACTV_IDX_SET_ENTRIES];
843 if (index->riot != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
848 memset(&set, 0,
sizeof(set));
850 if (index->keyman != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
851 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_KMAN;
852 set.idx[i].index = index->keyman;
856 if (index->bl2 != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
857 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_BL2;
858 set.idx[i].index = index->bl2;
862 if (index->config != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
863 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_CFG;
864 set.idx[i].index = index->config;
868 if (index->firmware != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
869 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_FW;
870 set.idx[i].index = index->firmware;
877 set.count = htole32(i);
879 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_SET, &set,
880 sizeof(set), NULL, 0);
884static int active_image_index_set_gen5(
struct switchtec_dev *dev,
895 } idx[SWITCHTEC_ACTV_IDX_SET_ENTRIES];
898 if (index->keyman != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
899 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_KMAN_GEN5;
900 set.idx[i].index = index->keyman;
904 if (index->riot != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
905 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_RC_GEN5;
906 set.idx[i].index = index->riot;
910 if (index->bl2 != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
911 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_BL2_GEN5;
912 set.idx[i].index = index->bl2;
916 if (index->config != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
917 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_CFG_GEN5;
918 set.idx[i].index = index->config;
922 if (index->firmware != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
923 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_FW_GEN5;
924 set.idx[i].index = index->firmware;
931 set.count = htole32(i);
933 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_SET_GEN5, &set,
934 sizeof(set), NULL, 0);
944int switchtec_active_image_index_set(
struct switchtec_dev *dev,
948 return active_image_index_set_gen5(dev, index);
950 return active_image_index_set(dev, index);
959int switchtec_fw_exec(
struct switchtec_dev *dev,
960 enum switchtec_bl2_recovery_mode recovery_mode)
962 uint32_t cmd_id = MRPC_FW_TX;
963 struct fw_exec_struct {
965 uint8_t recovery_mode;
969 memset(&cmd, 0,
sizeof(cmd));
970 cmd.subcmd = MRPC_FW_TX_EXEC;
971 cmd.recovery_mode = recovery_mode;
974 cmd_id = MRPC_FW_TX_GEN5;
976 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
991int switchtec_boot_resume(
struct switchtec_dev *dev)
996 return switchtec_mfg_cmd(dev, MRPC_BOOTUP_RESUME_GEN5,
997 &subcmd,
sizeof(subcmd),
1000 return switchtec_mfg_cmd(dev, MRPC_BOOTUP_RESUME,
1004static int secure_state_set(
struct switchtec_dev *dev,
1005 enum switchtec_secure_state state)
1009 data = htole32(state);
1011 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET,
1012 &data,
sizeof(data), NULL, 0);
1015static int secure_state_set_gen5(
struct switchtec_dev *dev,
1016 enum switchtec_secure_state state)
1024 data.state = htole32(state);
1026 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET_GEN5,
1027 &data,
sizeof(data), NULL, 0);
1036int switchtec_secure_state_set(
struct switchtec_dev *dev,
1037 enum switchtec_secure_state state)
1039 if ((state != SWITCHTEC_INITIALIZED_UNSECURED)
1040 && (state != SWITCHTEC_INITIALIZED_SECURED)) {
1041 return ERR_PARAM_INVALID;
1045 return secure_state_set_gen5(dev, state);
1047 return secure_state_set(dev, state);
1050static int dbg_unlock_send_pubkey(
struct switchtec_dev *dev,
1054 struct public_key_cmd {
1057 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1058 uint32_t pub_key_exp;
1061 cmd.subcmd = MRPC_DBG_UNLOCK_PKEY;
1062 memcpy(cmd.pub_key, public_key->pubkey, SWITCHTEC_PUB_KEY_LEN);
1063 cmd.pub_key_exp = htole32(public_key->pubkey_exp);
1065 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
1077int switchtec_dbg_unlock(
struct switchtec_dev *dev, uint32_t serial,
1078 uint32_t ver_sec_unlock,
1087 uint32_t unlock_ver;
1088 uint8_t signature[SWITCHTEC_SIG_LEN];
1093 cmd_id = MRPC_DBG_UNLOCK_GEN5;
1095 cmd_id = MRPC_DBG_UNLOCK;
1097 ret = dbg_unlock_send_pubkey(dev, public_key, cmd_id);
1101 cmd.subcmd = MRPC_DBG_UNLOCK_DATA;
1102 cmd.serial = htole32(serial);
1103 cmd.unlock_ver = htole32(ver_sec_unlock);
1104 memcpy(cmd.signature, signature->signature, SWITCHTEC_SIG_LEN);
1106 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
1118int switchtec_dbg_unlock_version_update(
struct switchtec_dev *dev,
1120 uint32_t ver_sec_unlock,
1129 uint32_t unlock_ver;
1130 uint8_t signature[SWITCHTEC_SIG_LEN];
1135 cmd_id = MRPC_DBG_UNLOCK_GEN5;
1137 cmd_id = MRPC_DBG_UNLOCK;
1139 ret = dbg_unlock_send_pubkey(dev, public_key, cmd_id);
1143 cmd.subcmd = MRPC_DBG_UNLOCK_UPDATE;
1144 cmd.serial = htole32(serial);
1145 cmd.unlock_ver = htole32(ver_sec_unlock);
1146 memcpy(cmd.signature, signature->signature, SWITCHTEC_SIG_LEN);
1148 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd), NULL, 0);
1151static int check_sec_cfg_header(
struct switchtec_dev *dev,
1156 char magic[4] = {
'S',
'S',
'F',
'F'};
1158 struct setting_file_header {
1168 rlen = fread(&hdr,
sizeof(hdr), 1, setting_file);
1173 if (memcmp(hdr.magic, magic,
sizeof(magic)))
1176 switch (hdr.hw_gen) {
1178 gen = SWITCHTEC_GEN4;
1181 gen = SWITCHTEC_GEN5;
1190 fseek(setting_file, 0, SEEK_END);
1191 data_len = ftell(setting_file) -
sizeof(hdr);
1192 fseek(setting_file,
sizeof(hdr), SEEK_SET);
1194 rlen = fread(data, 1, data_len, setting_file);
1195 if (rlen < data_len)
1198 crc = crc32(data, data_len, 0, 1, 1);
1199 if (crc != le32toh(hdr.crc))
1202 fseek(setting_file,
sizeof(hdr), SEEK_SET);
1206static int read_sec_cfg_file(
struct switchtec_dev *dev,
1210 struct setting_file_data {
1212 uint32_t pub_key_exponent;
1215 struct get_cfgs_reply reply;
1216 uint32_t addr_shift;
1223 ret = get_configs(dev, &reply, &otp_valid);
1229 ret = fread(&data,
sizeof(data), 1, setting_file);
1234 data.cfg = le64toh(data.cfg);
1236 set->jtag_lock_after_reset =
1237 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK);
1238 set->jtag_lock_after_bl1 =
1239 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK);
1240 set->jtag_bl1_unlock_allowed =
1241 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK);
1242 set->jtag_post_bl1_unlock_allowed =
1243 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK);
1245 spi_clk = (data.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) &
1246 SWITCHTEC_CLK_RATE_BITMASK;
1247 if (reply.spi_core_clk_high)
1248 set->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
1250 set->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
1252 set->i2c_recovery_tmo =
1253 (data.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) &
1254 SWITCHTEC_RC_TMO_BITMASK;
1256 (data.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) &
1257 SWITCHTEC_I2C_PORT_BITMASK;
1259 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
1262 (data.cfg >> addr_shift) &
1263 SWITCHTEC_I2C_ADDR_BITMASK;
1264 set->i2c_cmd_map = (data.cfg >> map_shift) & map_mask;
1266 set->public_key_exponent = le32toh(data.pub_key_exponent);
1268 set->attn_set.attestation_mode =
1269 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED;
1274static int read_sec_cfg_file_gen5(
struct switchtec_dev *dev,
1278 struct setting_data {
1280 uint32_t pub_key_exponent;
1282 uint32_t cdi_efuse_inc_mask;
1284 struct get_cfgs_reply_gen5 reply;
1285 uint32_t addr_shift;
1292 ret = get_configs_gen5(dev, &reply);
1298 ret = fread(&data,
sizeof(data), 1, setting_file);
1303 data.cfg = le64toh(data.cfg);
1305 set->jtag_lock_after_reset =
1306 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK);
1307 set->jtag_lock_after_bl1 =
1308 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK);
1309 set->jtag_bl1_unlock_allowed =
1310 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK);
1311 set->jtag_post_bl1_unlock_allowed =
1312 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK);
1314 spi_clk = (data.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) &
1315 SWITCHTEC_CLK_RATE_BITMASK;
1316 if (reply.spi_core_clk_high)
1317 set->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
1319 set->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
1321 set->i2c_recovery_tmo =
1322 (data.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) &
1323 SWITCHTEC_RC_TMO_BITMASK;
1325 (data.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) &
1326 SWITCHTEC_I2C_PORT_BITMASK;
1328 get_i2c_operands(
switchtec_gen(dev), &addr_shift, &map_shift,
1331 (data.cfg >> addr_shift) &
1332 SWITCHTEC_I2C_ADDR_BITMASK;
1333 set->i2c_cmd_map = (data.cfg >> map_shift) & map_mask;
1335 set->public_key_exponent = le32toh(data.pub_key_exponent);
1337 attest_mode = (data.cfg >> SWITCHTEC_ATTEST_BITSHIFT) &
1338 SWITCHTEC_ATTEST_BITMASK;
1339 if (attest_mode == 1) {
1340 set->attn_set.attestation_mode =
1341 SWITCHTEC_ATTESTATION_MODE_DICE;
1342 set->attn_set.cdi_efuse_inc_mask = data.cdi_efuse_inc_mask;
1343 set->attn_set.uds_selfgen = (data.cfg >> 44) & 0x1;
1345 set->attn_set.attestation_mode =
1346 SWITCHTEC_ATTESTATION_MODE_NONE;
1359int switchtec_read_sec_cfg_file(
struct switchtec_dev *dev,
1365 ret = check_sec_cfg_header(dev, setting_file);
1370 return read_sec_cfg_file(dev, setting_file, set);
1372 return read_sec_cfg_file_gen5(dev, setting_file, set);
1375static int kmsk_set_send_pubkey(
struct switchtec_dev *dev,
1379 struct kmsk_pubk_cmd {
1381 uint8_t reserved[3];
1382 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1383 uint32_t pub_key_exponent;
1386 cmd.subcmd = MRPC_KMSK_ENTRY_SET_PKEY;
1387 memcpy(cmd.pub_key, public_key->pubkey,
1388 SWITCHTEC_PUB_KEY_LEN);
1389 cmd.pub_key_exponent = htole32(public_key->pubkey_exp);
1391 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
1392 sizeof(cmd), NULL, 0);
1395static int kmsk_set_send_signature(
struct switchtec_dev *dev,
1399 struct kmsk_signature_cmd {
1401 uint8_t reserved[3];
1402 uint8_t signature[SWITCHTEC_SIG_LEN];
1405 cmd.subcmd = MRPC_KMSK_ENTRY_SET_SIG;
1406 memcpy(cmd.signature, signature->signature,
1409 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
1410 sizeof(cmd), NULL, 0);
1413static int kmsk_set_send_kmsk(
struct switchtec_dev *dev,
1417 struct kmsk_kmsk_cmd {
1419 uint8_t num_entries;
1420 uint8_t reserved[2];
1421 uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1424 cmd.subcmd = MRPC_KMSK_ENTRY_SET_KMSK;
1425 cmd.num_entries = 1;
1426 memcpy(cmd.kmsk, kmsk->kmsk, SWITCHTEC_KMSK_LEN);
1428 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
sizeof(cmd),
1444int switchtec_kmsk_set(
struct switchtec_dev *dev,
1453 cmd_id = MRPC_KMSK_ENTRY_SET_GEN5;
1455 cmd_id = MRPC_KMSK_ENTRY_SET;
1458 ret = kmsk_set_send_pubkey(dev, public_key, cmd_id);
1464 ret = kmsk_set_send_signature(dev, signature, cmd_id);
1469 return kmsk_set_send_kmsk(dev, kmsk, cmd_id);
1479int switchtec_read_pubk_file(FILE *pubk_file,
struct switchtec_pubkey *pubk)
1482 const BIGNUM *modulus_bn;
1483 const BIGNUM *exponent_bn;
1484 uint32_t exponent_tmp = 0;
1486 RSAKey = PEM_read_RSA_PUBKEY(pubk_file, NULL, NULL, NULL);
1487 if (RSAKey == NULL) {
1488 fseek(pubk_file, 0L, SEEK_SET);
1489 RSAKey = PEM_read_RSAPrivateKey(pubk_file, NULL, NULL, NULL);
1494 RSA_get0_key(RSAKey, &modulus_bn, &exponent_bn, NULL);
1496 BN_bn2bin(modulus_bn, pubk->pubkey);
1497 BN_bn2bin(exponent_bn, (uint8_t *)&exponent_tmp);
1499 pubk->pubkey_exp = be32toh(exponent_tmp);
1512int switchtec_read_kmsk_file(FILE *kmsk_file,
struct switchtec_kmsk *kmsk)
1515 struct kmsk_struct {
1520 uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1523 char magic[4] = {
'K',
'M',
'S',
'K'};
1526 rlen = fread(&data, 1,
sizeof(data), kmsk_file);
1528 if (rlen <
sizeof(data))
1531 if (memcmp(data.magic, magic,
sizeof(magic)))
1534 crc = crc32(data.kmsk, SWITCHTEC_KMSK_LEN, 0, 1, 1);
1535 if (crc != le32toh(data.crc32))
1538 memcpy(kmsk->kmsk, data.kmsk, SWITCHTEC_KMSK_LEN);
1549int switchtec_read_signature_file(FILE *sig_file,
1554 rlen = fread(signature->signature, 1, SWITCHTEC_SIG_LEN, sig_file);
1556 if (rlen < SWITCHTEC_SIG_LEN)
1568int switchtec_read_uds_file(FILE *uds_file,
struct switchtec_uds *uds)
1572 rlen = fread(uds->uds, 1, SWITCHTEC_UDS_LEN, uds_file);
1574 if (rlen < SWITCHTEC_UDS_LEN)
1596 for(key_idx = 0; key_idx < state->public_key_num; key_idx++) {
1597 if (memcmp(state->public_key[key_idx], kmsk->kmsk,
1598 SWITCHTEC_KMSK_LEN) == 0)
1607static int switchtec_mfg_cmd(
struct switchtec_dev *dev, uint32_t cmd,
1608 const void *payload,
size_t payload_len,
1609 void *resp,
size_t resp_len)
1611 if (dev->ops->flags & SWITCHTEC_OPS_FLAG_NO_MFG) {
1612 errno = ERR_UART_NOT_SUPPORTED | SWITCHTEC_ERRNO_MRPC_FLAG_BIT;
1620static int sn_ver_get_gen4(
struct switchtec_dev *dev,
1625 uint32_t chip_serial;
1629 uint32_t ver_sec_unlock;
1632 ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET, NULL, 0,
1633 &reply,
sizeof(reply));
1637 info->chip_serial = reply.chip_serial;
1638 info->ver_bl2 = reply.ver_bl2;
1639 info->ver_km = reply.ver_km;
1640 info->riot_ver_valid =
false;
1641 info->ver_sec_unlock = reply.ver_sec_unlock;
1642 info->ver_main = reply.ver_main;
1647static int sn_ver_get_gen5(
struct switchtec_dev *dev,
1651 uint32_t subcmd = 0;
1653 uint32_t chip_serial;
1658 uint32_t ver_sec_unlock;
1661 ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET_GEN5, &subcmd, 4,
1662 &reply,
sizeof(reply));
1666 info->chip_serial = reply.chip_serial;
1667 info->ver_bl2 = reply.ver_bl2;
1668 info->ver_km = reply.ver_km;
1669 info->riot_ver_valid =
true;
1670 info->ver_riot = reply.ver_riot;
1671 info->ver_sec_unlock = reply.ver_sec_unlock;
1672 info->ver_main = reply.ver_main;
1687 return sn_ver_get_gen5(dev, info);
1689 return sn_ver_get_gen4(dev, info);
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_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.