Velocity Userspace
mfg.c
Go to the documentation of this file.
1 /*
2  * Microsemi Switchtec(tm) PCIe Management Library
3  * Copyright (c) 2019, Microsemi Corporation
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  */
24 
46 #include "switchtec_priv.h"
47 #include "switchtec/switchtec.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"
53 #include <unistd.h>
54 
55 #include <errno.h>
56 #include <stdio.h>
57 #include <string.h>
58 #include <openssl/sha.h>
59 #include <arpa/inet.h>
60 #include <iconv.h>
61 
62 #include "lib/crc.h"
63 #include "config.h"
64 
65 #ifdef __linux__
66 
67 #if HAVE_LIBCRYPTO
68 #include <openssl/pem.h>
69 #endif
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
74 
75 #define SWITCHTEC_MB_MAX_ENTRIES 16
76 #define SWITCHTEC_ACTV_IDX_MAX_ENTRIES 32
77 #define SWITCHTEC_ACTV_IDX_SET_ENTRIES 4
78 
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
92 
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
97 
98 static int switchtec_mfg_cmd(struct switchtec_dev *dev, uint32_t cmd,
99  const void *payload, size_t payload_len,
100  void *resp, size_t resp_len);
101 
102 #if (HAVE_LIBCRYPTO && !HAVE_DECL_RSA_GET0_KEY)
103 
113 static void RSA_get0_key(const RSA *r, const BIGNUM **n,
114  const BIGNUM **e, const BIGNUM **d)
115 {
116  if (n != NULL)
117  *n = r->n;
118  if (e != NULL)
119  *e = r->e;
120  if (d != NULL)
121  *d = r->d;
122 }
123 #endif
124 
134 static void get_i2c_operands(enum switchtec_gen gen, uint32_t *addr_shift,
135  uint32_t *map_shift, uint32_t *map_mask)
136 {
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;
141  } else {
142  *addr_shift = SWITCHTEC_I2C_ADDR_BITSHIFT;
143  *map_shift = SWITCHTEC_CMD_MAP_BITSHIFT;
144  *map_mask = SWITCHTEC_CMD_MAP_BITMASK;
145  }
146 }
147 
148 static float spi_clk_rate_float[] = {
149  25, 150, 137.5, 125.25, 100, 66.67, 50, 40, 33.33, 28.58
150 };
151 
152 static float spi_clk_hi_rate_float[] = {
153  120, 80, 60, 48, 40, 34, 30, 26.67, 24, 21.82
154 };
155 
156 #pragma pack(push, 1)
157 typedef struct {
158  uint64_t cfg;
159  uint32_t public_key_exponent;
160 }cfg_stmfd;
161 #pragma pack(pop)
162 
164  uint32_t valid;
165  uint32_t rsvd1;
167  uint8_t rsvd2;
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];
172  uint8_t rsvd4[32];
173 };
174 
184 static int get_configs(struct switchtec_dev *dev,
185  struct get_cfgs_reply *cfgs,
186  int *otp_valid)
187 {
188  uint8_t subcmd = 0;
189  int ret;
190 
191  if (switchtec_gen(dev) == SWITCHTEC_GEN5) {
192  subcmd = 1;
193  ret = switchtec_mfg_cmd(dev,
194  MRPC_SECURITY_CONFIG_GET_GEN5,
195  &subcmd, sizeof(subcmd),
196  cfgs, sizeof(struct get_cfgs_reply));
197  if (!ret)
198  *otp_valid = true;
199  } else {
200  ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET_EXT,
201  &subcmd, sizeof(subcmd),
202  cfgs, sizeof(struct get_cfgs_reply));
203  if (ret && ERRNO_MRPC(errno) != ERR_CMD_INVALID)
204  return ret;
205 
206  if (!ret) {
207  *otp_valid = true;
208  return ret;
209  }
210 
211  *otp_valid = false;
212  ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET,
213  NULL, 0, cfgs,
214  sizeof(struct get_cfgs_reply));
215  }
216 
217  return ret;
218 }
219 
228 int switchtec_security_spi_avail_rate_get(struct switchtec_dev *dev,
229  struct switchtec_security_spi_avail_rate *rates)
230 {
231  int ret;
232  struct get_cfgs_reply reply;
233  int otp_valid;
234 
235  ret = get_configs(dev, &reply, &otp_valid);
236  if (ret)
237  return ret;
238 
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));
243  else
244  memcpy(rates->rates, spi_clk_rate_float,
245  sizeof(spi_clk_rate_float));
246 
247  return 0;
248 }
249 
258  uint32_t flags)
259 {
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));
276 }
277 
284 int switchtec_security_config_get(struct switchtec_dev *dev,
285  struct switchtec_security_cfg_state *state)
286 {
287  int ret;
288  uint32_t addr_shift;
289  uint32_t map_shift;
290  uint32_t map_mask;
291  int spi_clk;
292  struct get_cfgs_reply reply;
293  int otp_valid;
294 
295  ret = get_configs(dev, &reply, &otp_valid);
296  if (ret)
297  return ret;
298 
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);
302 
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);
307 
308  state->otp_valid = otp_valid;
309  if (otp_valid)
310  parse_otp_settings(&state->otp, reply.valid);
311 
312  state->secure_state = (reply.cfg_stmfd.cfg) & 0x03;
313 
314  spi_clk = (reply.cfg_stmfd.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) & 0x0f;
315 
316  /* 0 - OTP_SEC_MODE_UNINITIALIZED_UNSECURED - Set the SPI clock freq to default */
317  if(0 == state->secure_state)
318  {
319  if (spi_clk == 0) {
320  if (switchtec_gen(dev) == SWITCHTEC_GEN5)
321  spi_clk = 9;
322  }
323  }
324 
325  if (reply.spi_core_clk_high)
326  state->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
327  else
328  state->spi_clk_rate = spi_clk_rate_float[spi_clk];
329 
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;
333 
334  get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
335  &map_mask);
336  state->i2c_addr =
337  (reply.cfg_stmfd.cfg >> addr_shift) & SWITCHTEC_I2C_ADDR_BITMASK;
338  state->i2c_cmd_map = (reply.cfg_stmfd.cfg >> map_shift) & map_mask;
339 
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);
345 
346  return 0;
347 }
348 
355 int switchtec_mailbox_to_file(struct switchtec_dev *dev, int fd)
356 {
357  int ret;
358  int num_to_read = htole32(SWITCHTEC_MB_MAX_ENTRIES);
359  struct mb_reply {
360  uint8_t num_returned;
361  uint8_t num_remaining;
362  uint8_t rsvd[2];
363  uint8_t data[SWITCHTEC_MB_MAX_ENTRIES *
364  SWITCHTEC_MB_LOG_LEN];
365  } reply;
366 
367  do {
368  ret = switchtec_mfg_cmd(dev, MRPC_MAILBOX_GET, &num_to_read,
369  sizeof(int), &reply, sizeof(reply));
370  if (ret)
371  return ret;
372 
373  reply.num_remaining = le32toh(reply.num_remaining);
374  reply.num_returned = le32toh(reply.num_returned);
375 
376  ret = write(fd, reply.data,
377  (reply.num_returned) * SWITCHTEC_MB_LOG_LEN);
378  if (ret < 0)
379  return ret;
380  } while (reply.num_remaining > 0);
381 
382  return 0;
383 }
384 
396 static int convert_spi_clk_rate(float clk_float, int hi_rate)
397 {
398  int i;
399  int spi_rate_max_val = 10;
400  float *p;
401 
402  if (hi_rate)
403  {
404  p = spi_clk_hi_rate_float;
405  }
406  else
407  {
408  p = spi_clk_rate_float;
409  }
410 
411  for (i = 0; i < spi_rate_max_val; i++)
412  {
413  if ((clk_float < p[i] + 0.1) && (clk_float > p[i] - 0.1))
414  {
415  if (hi_rate)
416  {
417  return i + 1;
418  }
419  else
420  {
421  return i;
422  }
423  }
424  }
425 
426  return -1;
427 }
428 
435 int switchtec_security_config_set(struct switchtec_dev *dev,
436  struct switchtec_security_cfg_set *setting)
437 {
438  int ret;
439  struct setting_data {
440  uint64_t cfg;
441  uint32_t pub_key_exponent;
442  uint8_t rsvd[4];
443  } sd;
444  struct get_cfgs_reply reply;
445  uint64_t ldata = 0;
446  uint32_t addr_shift;
447  uint32_t map_shift;
448  uint32_t map_mask;
449  int spi_clk;
450  uint8_t cmd_buf[20] = {};
451  int otp_valid;
452 
453  ret = get_configs(dev, &reply, &otp_valid);
454  if (ret)
455  return ret;
456 
457  memset(&sd, 0, sizeof(sd));
458 
459  spi_clk = convert_spi_clk_rate(setting->spi_clk_rate,
460  reply.spi_core_clk_high);
461  if (spi_clk < 0) {
462  errno = EINVAL;
463  return -1;
464  }
465 
466  sd.cfg |= (spi_clk & SWITCHTEC_CLK_RATE_BITMASK) <<
467  SWITCHTEC_CLK_RATE_BITSHIFT;
468 
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;
473 
474  get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
475  &map_mask);
476  sd.cfg |= (setting->i2c_addr & SWITCHTEC_I2C_ADDR_BITMASK) <<
477  addr_shift;
478 
479  ldata = setting->i2c_cmd_map & map_mask;
480  ldata <<= map_shift;
481  sd.cfg |= ldata;
482 
483  sd.cfg = htole64(sd.cfg);
484 
485  sd.pub_key_exponent = htole32(setting->public_key_exponent);
486 
487  if (switchtec_gen(dev) == SWITCHTEC_GEN4) {
488  ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_SET,
489  &sd, sizeof(sd), NULL, 0);
490  } else {
491  cmd_buf[0] = 1;
492  memcpy(cmd_buf + 4, &sd, sizeof(sd));
493  ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_SET_GEN5,
494  cmd_buf, sizeof(cmd_buf), NULL, 0);
495  }
496  return ret;
497 }
498 
507 int switchtec_otp_sjtag_mode_set(struct switchtec_dev *dev,
508  uint8_t sjtag_mode)
509 {
510  struct sjtag_mode_cmd {
511  uint8_t subcmd;
512  uint8_t sjtag_mode:2;
513  } cmd = {};
514 
515  cmd.subcmd = MRPC_OTP_SJTAG_MODE_SET;
516  cmd.sjtag_mode = sjtag_mode;
517 
518  return switchtec_mfg_cmd(dev, MRPC_OTP_SJTAG_INFO, &cmd,
519  sizeof(cmd), NULL, 0);
520 }
521 
530 int switchtec_sjtag_hr_send(struct switchtec_dev *dev,
531  uint8_t *sjtag_hr)
532 {
533  struct sjtag_uuid_cmd {
534  uint8_t subcmd;
535  uint8_t reserved[3];
536  uint8_t sjtag_hr[SJTAG_HR_LEN];
537  } cmd = {};
538 
539  cmd.subcmd = MRPC_SJTAG_SET_HOST_RESPONSE;
540 
541  memcpy((void *)cmd.sjtag_hr, (void *)sjtag_hr, SJTAG_HR_LEN);
542 
543  return switchtec_mfg_cmd(dev, MRPC_SJTAG_UNLOCK, &cmd,
544  sizeof(cmd), NULL, 0);
545 }
546 
555 int switchtec_otp_sjtag_uuid_set(struct switchtec_dev *dev,
556  uint8_t *sjtag_uuid)
557 {
558  struct sjtag_uuid_cmd {
559  uint8_t subcmd;
560  uint8_t sjtag_uuid[OTP_SJTAG_UUID_LENGTH];
561  } cmd = {};
562 
563  cmd.subcmd = MRPC_OTP_SJTAG_UUID_SET;
564 
565  memcpy((void *)cmd.sjtag_uuid, (void *)sjtag_uuid, OTP_SJTAG_UUID_LENGTH);
566 
567  return switchtec_mfg_cmd(dev, MRPC_OTP_SJTAG_INFO, &cmd,
568  sizeof(cmd), NULL, 0);
569 }
570 
579 int switchtec_otp_sjtag_key_set(struct switchtec_dev *dev,
580  uint8_t *sjtag_key)
581 {
582  struct sjtag_key_cmd {
583  uint8_t subcmd;
584  uint8_t sjtag_key[OTP_SJTAG_KEY_LENGTH];
585  } cmd = {};
586 
587  cmd.subcmd = MRPC_OTP_SJTAG_KEY_SET;
588 
589  memcpy((void *)cmd.sjtag_key, (void *)sjtag_key, OTP_SJTAG_KEY_LENGTH);
590 
591  return switchtec_mfg_cmd(dev, MRPC_OTP_SJTAG_INFO, &cmd,
592  sizeof(cmd), NULL, 0);
593 }
594 
606 int switchtec_otp_config_prog(struct switchtec_dev *dev,
607  uint16_t config_len,
608  uint8_t *config_data,
609  bool is_firmware_halt)
610 {
611  #pragma pack(push, 1)
612  struct otp_config_cmd {
613  uint8_t subcmd;
614  uint16_t config_len:10;
615  uint16_t reserved:6;
616  uint8_t is_firmware_halt:1;
617  uint8_t reserved1:7;
618  uint8_t config_data[OTP_CONFIG_DATA_MAX_LEN];
619  } cmd = {};
620  #pragma pack(pop)
621 
622  cmd.subcmd = MRPC_OTP_CONFIG_PROG;
623  cmd.config_len = config_len;
624  cmd.is_firmware_halt = is_firmware_halt;
625 
626  memcpy((void *)cmd.config_data, (void *)config_data, OTP_CONFIG_DATA_MAX_LEN);
627 
628  return switchtec_mfg_cmd(dev, MRPC_OTP_PROG_GEN_HDLR, &cmd,
629  sizeof(cmd), NULL, 0);
630 }
631 
643 int switchtec_otp_config_read(struct switchtec_dev *dev,
644  uint16_t config_start_address,
645  int32_t config_length,
646  int out_fd)
647 {
648  int ret = 0;
649 
650  #pragma pack(push, 1)
651  struct otp_config_cmd {
652  uint8_t subcmd;
653  uint16_t config_start_address:14;
654  uint16_t config_length:10;
655  } cmd = {};
656  #pragma pack(pop)
657 
658  struct otp_config_read_reply {
659  uint8_t config_data[OTP_CONFIG_DATA_MAX_LEN];
660  } reply;
661 
662  cmd.subcmd = MRPC_OTP_CONFIG_READ;
663 
664  cmd.config_start_address = config_start_address;
665  while(config_length > 0)
666  {
667  cmd.config_length = (OTP_CONFIG_DATA_MAX_LEN < config_length) ? OTP_CONFIG_DATA_MAX_LEN : config_length;
668  ret = switchtec_mfg_cmd(dev, MRPC_OTP_CONTROL_STATUS_GEN_HDLR, &cmd,
669  sizeof(cmd), &reply, sizeof(reply));
670  if(ret)
671  {
672  return -1;
673  }
674 
675  ret = write(out_fd, reply.config_data, cmd.config_length);
676  if(ret < 0)
677  {
678  return ret;
679  }
680  cmd.config_start_address += OTP_CONFIG_DATA_MAX_LEN;
681  config_length -= OTP_CONFIG_DATA_MAX_LEN;
682  }
683  close(out_fd);
684 
685  return 0;
686 }
687 
697 int switchtec_otp_sjtag_key_verify(struct switchtec_dev *dev,
698  uint8_t *sjtag_key, uint8_t *is_verified)
699 {
700  int ret;
701  struct sjtag_key_cmd {
702  uint8_t subcmd;
703  uint8_t sjtag_key[OTP_SJTAG_KEY_LENGTH];
704  } cmd = {};
705 
706  uint8_t reply = 0;
707 
708  cmd.subcmd = MRPC_OTP_SJTAG_KEY_VERIFY;
709 
710  memcpy((void *)cmd.sjtag_key, (void *)sjtag_key, OTP_SJTAG_KEY_LENGTH);
711 
712  ret = switchtec_mfg_cmd(dev, MRPC_OTP_SJTAG_INFO, &cmd,
713  sizeof(cmd), &reply, sizeof(uint8_t));
714 
715  if(ret)
716  return ret;
717 
718  memcpy((void *)is_verified, (void *)&reply, sizeof(uint8_t));
719  return 0;
720 }
721 
729 int switchtec_otp_sjtag_key_lock(struct switchtec_dev *dev)
730 {
731  struct sjtag_key_cmd {
732  uint8_t subcmd;
733  } cmd = {};
734 
735  cmd.subcmd = MRPC_OTP_SJTAG_KEY_LOCK;
736 
737  return switchtec_mfg_cmd(dev, MRPC_OTP_SJTAG_INFO, &cmd,
738  sizeof(cmd), NULL, 0);
739 }
740 
749 int switchtec_chip_serial_num_prog(struct switchtec_dev *dev,
750  uint32_t chip_serial_num)
751 {
752  struct sku_info_cmd {
753  uint8_t subcmd;
754  uint32_t chip_serial_num;
755  } cmd = {};
756 
757  cmd.subcmd = MRPC_OTP_PROG_CHIP_NUM;
758  cmd.chip_serial_num = chip_serial_num;
759 
760  return switchtec_mfg_cmd(dev, MRPC_OTP_PROG_GEN_HDLR, &cmd,
761  sizeof(cmd), NULL, 0);
762 }
763 
772 int switchtec_otp_sku_info_set(struct switchtec_dev *dev,
773  struct otp_sku_info_set *sku_info_set_str)
774 {
775  struct sku_info_cmd {
776  uint8_t subcmd;
777  uint8_t block_num:2;
778  uint8_t reserved:6;
779  uint8_t sku_info:7;
780  uint8_t reserved1:1;
781  } cmd = {};
782 
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;
786 
787  return switchtec_mfg_cmd(dev, MRPC_OTP_PROG_GEN_HDLR, &cmd,
788  sizeof(cmd), NULL, 0);
789 }
790 
800 int switchtec_sjtag_get_uuid_idcode(struct switchtec_dev *dev,
801  uint8_t *sjtag_uuid_ptr,
802  uint8_t *sjtag_idcode)
803 {
804  int ret;
805  struct sjtag_uuid_idcode {
806  uint8_t uuid[10];
807  uint8_t reserved[2];
808  uint8_t idcode[4];
809  } reply = {};
810 
811  uint8_t sub_cmd = MRPC_SJTAG_GET_UUID_IDCODE;
812 
813  ret = switchtec_mfg_cmd(dev, MRPC_SJTAG_UNLOCK, &sub_cmd,
814  sizeof(sub_cmd), &reply, sizeof(reply));
815 
816  if (ret)
817  return ret;
818 
819  memcpy((void *)sjtag_uuid_ptr, (void *)reply.uuid, SJTAG_UUID_LEN);
820  memcpy((void *)sjtag_idcode, (void *)reply.idcode, SJTAG_IDCODE_LEN);
821 
822  return 0;
823 }
824 
833 int switchtec_sjtag_get_nonce(struct switchtec_dev *dev,
834  struct sjtag_nonce *sjtag_nonce_ptr)
835 {
836  int ret;
837  struct sjtag_nonce {
838  uint32_t data[8];
839  } reply = {};
840 
841  uint8_t sub_cmd = MRPC_SJTAG_GET_NONCE;
842 
843  ret = switchtec_mfg_cmd(dev, MRPC_SJTAG_UNLOCK, &sub_cmd,
844  sizeof(sub_cmd), &reply, sizeof(reply));
845 
846  if (ret)
847  return ret;
848 
849  memcpy((void *)sjtag_nonce_ptr, (void *)&reply, sizeof(reply));
850 
851  return 0;
852 }
853 
854 
864 int switchtec_sjtag_status_get(struct switchtec_dev *dev,
865  struct sjtag_status_get *sjtag_sts_get)
866 {
867  int ret;
868  struct stag_sts_cmd {
869  uint32_t data;
870  } reply = {};
871 
872  uint8_t sub_cmd = MRPC_SJTAG_GET_STATUS;
873 
874  ret = switchtec_mfg_cmd(dev, MRPC_SJTAG_UNLOCK, &sub_cmd,
875  sizeof(sub_cmd), &reply, sizeof(reply));
876 
877  if (ret)
878  return ret;
879 
880  memcpy((void *)sjtag_sts_get, (void *)&reply, sizeof(reply));
881  return 0;
882 }
883 
884 /*******************************************************************************
885 * FUNCTION sjtag_hr_calc()
886 *_______________________________________________________________________________
887 *
888 * DESCRIPTION:
889 * This function calculates the SJTAG Host Response
890 *
891 * @param[in] sjtag_debug_token - Pointer to Debug Token
892 * @param[in] sjtag_nonce - Pointer to Nonce
893 * @param[in] verbose - verbose enable/disable
894 * @param[out] digest - SHA256 Digest
895 *
896 * @return void
897 *
898 ********************************************************************************/
899 void sjtag_hr_calc(uint8_t *sjtag_debug_token, uint8_t *sjtag_nonce, uint8_t *digest, bool verbose)
900 {
901  uint8_t sjtag_sha256_msg[SJTAG_SHA256_MSG_LEN] = {0};
902  SHA256_CTX sha256_algo;
903 
904  if(true == verbose)
905  {
906  printf("Nonce: ");
907  for(int i = 0; i < SJTAG_NONCE_LEN; i++)
908  {
909  printf("%x", sjtag_nonce[31 - i]);
910  }
911  printf("\n");
912  }
913 
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);
916 
917  SHA256_Init(&sha256_algo);
918  SHA256_Update(&sha256_algo, sjtag_sha256_msg, SJTAG_SHA256_MSG_LEN);
919  SHA256_Final(digest, &sha256_algo);
920  if(true == verbose)
921  {
922  printf("Host Response: ");
923  for(int i = 0; i < SJTAG_HR_LEN; i++)
924  {
925  printf("%x", digest[i]);
926  }
927  printf("\n");
928  }
929 }
930 
939 void sjtag_encode_cmd_header(uint8_t *cmd_header, uint8_t cmd)
940 {
941  cmd_header[SJTAG_SERVER_CMD_INDEX] = cmd;
942  cmd_header[SJTAG_SERVER_CMD_RESP_INDICATOR_INDEX] = SJTAG_SERVER_CMD_MSK;
943  cmd_header[2] = 0;
944  cmd_header[3] = 0;
945 }
946 
947 /*******************************************************************************
948 * FUNCTION sjtag_resp_is_success()
949 *_______________________________________________________________________________
950 *
951 * @brief
952 * This function checks for Debug Token generation success from the Response header
953 * received from the server.
954 *
955 * @param resp_header [in] - Response header
956 *
957 * @return
958 * Returns 0 on Success and -1 on Failure
959 *
960 ********************************************************************************/
961 int sjtag_resp_is_success(uint8_t *resp_header)
962 {
963  int ret = -1;
964 
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]))
966  {
967  if(SERVER_STATUS_SUCCESS == resp_header[SJTAG_SERVER_RESPONSE_STATUS_INDEX])
968  {
969  ret = 0;
970  }
971  else if(SERVER_STATUS_INVALID_SJTAGID == resp_header[SJTAG_SERVER_RESPONSE_STATUS_INDEX])
972  {
973  printf("Error in generating debug token generation due to invalid IDCODE!\n");
974  }
975  else if(SERVER_STATUS_INVALID_HEADER == resp_header[SJTAG_SERVER_RESPONSE_STATUS_INDEX])
976  {
977  printf("Error in generating debug token generation due to invalid header!\n");
978  }
979  else if(SERVER_STATUS_DIGEST_COMPUTE_FAIL == resp_header[SJTAG_SERVER_RESPONSE_STATUS_INDEX])
980  {
981  printf("Exception in generating the digest!\n");
982  }
983  else
984  {
985  printf("Invalid response header from SJTAG server!\n");
986  }
987  }
988  return ret;
989 }
990 
1002 int sjtag_debug_token_gen(uint8_t *idcode_ptr, uint8_t *uuid_ptr, uint8_t *suv_ptr, uint8_t *sjtag_debug_token, bool verbose)
1003 {
1004  int ret = 0;
1005  int socket_server;
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];
1013 
1014  do{
1015  /* Create a socket communication */
1016  socket_server = socket(AF_INET, SOCK_STREAM, 0);
1017  if(socket_server < 0)
1018  {
1019  printf("Unable to create socket communication!\n");
1020  ret = -1;
1021  break;
1022  }
1023 
1024  /* Set port and IP */
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);
1028 
1029  /* Send a connection request to Plugin server */
1030  if(connect(socket_server, (struct sockaddr*)&server_address, sizeof(server_address)) < 0)
1031  {
1032  printf("Unable to connect with Plugin server!\n");
1033  ret = -1;
1034  break;
1035  }
1036  printf("Connected with Plugin server successfully!\n");
1037 
1038  sjtag_encode_cmd_header(cmd_header, SJTAG_SERVER_CMD_CHAL_RESP);
1039  /* Send the server header */
1040  if(send(socket_server, cmd_header, SJTAG_SERVER_HEADER_LEN, 0) < 0)
1041  {
1042  printf("Unable to sent the Command Header to the Plugin server!\n");
1043  ret = -1;
1044  break;
1045  }
1046 
1047  if(true == verbose)
1048  printf("IDCODE: ");
1049 
1050  for(int i=0; i<SJTAG_IDCODE_LEN; i++)
1051  {
1052  sjtag_idcode_send[i] = idcode_ptr[3 - i];
1053  if(true == verbose)
1054  {
1055  printf("%x", sjtag_idcode_send[i]);
1056  }
1057  }
1058  if(true == verbose)
1059  printf("\n");
1060 
1061  /* Send the IDCODE to the server */
1062  if(send(socket_server, sjtag_idcode_send, SJTAG_IDCODE_LEN, 0) < 0)
1063  {
1064  printf("Unable to sent the IDCODE to the Plugin server!\n");
1065  ret = -1;
1066  break;
1067  }
1068 
1069  if(true == verbose)
1070  printf("UUID: ");
1071 
1072  for(int i=0; i<SJTAG_UUID_LEN; i++)
1073  {
1074  sjtag_uuid_send[i] = uuid_ptr[9 - i];
1075  if(true == verbose)
1076  {
1077  printf("%x", sjtag_uuid_send[i]);
1078  }
1079  }
1080  if(true == verbose)
1081  printf("\n");
1082 
1083  /* Send the UUID to the server */
1084  if(send(socket_server, sjtag_uuid_send, SJTAG_UUID_LEN, 0) < 0)
1085  {
1086  printf("Unable to send the UUID to the Plugin server!\n");
1087  ret = -1;
1088  break;
1089  }
1090 
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);
1093 
1094  if(true == verbose)
1095  {
1096  printf("SUV: ");
1097  for(int i = 0; i < SUV_LEN; i++)
1098  {
1099  printf("%x", suv_ptr[3 - i]);
1100  }
1101  printf("\n");
1102  }
1103 
1104  /* Send the HMAC message to the server */
1105  if(send(socket_server, sjtag_hmac_msg, SJTAG_HMAC_MSG_LEN, 0) < 0)
1106  {
1107  printf("Unable to send the HMAC message to the Plugin server!\n");
1108  ret = -1;
1109  break;
1110  }
1111 
1112  /* Receive the response header from the Plugin server */
1113  if(recv(socket_server, resp_header, SJTAG_SERVER_HEADER_LEN, 0) < 0)
1114  {
1115  printf("Error while receiving response header from the Plugin server!\n");
1116  ret = -1;
1117  break;
1118  }
1119 
1120  ret = sjtag_resp_is_success(resp_header);
1121  if(0 == ret)
1122  {
1123  /* Receive the Debug Token from the Plugin server */
1124  if(recv(socket_server, sjtag_debug_token, SJTAG_DEBUG_TOKEN_LEN, 0) < 0)
1125  {
1126  printf("Error while receiving Debug Token from the Plugin server!\n");
1127  ret = -1;
1128  break;
1129  }
1130  if(true == verbose)
1131  {
1132  printf("Debug Token: ");
1133  for(int i = 0; i < SJTAG_DEBUG_TOKEN_LEN; i++)
1134  {
1135  printf("%x", sjtag_debug_token[i]);
1136  }
1137  printf("\n");
1138  }
1139  }
1140  }while(false);
1141 
1142  /* Close the socket communication to the Plugin server */
1143  close(socket_server);
1144 
1145  return ret;
1146 }
1155 int switchtec_read_sjtag_debug_token_file(FILE *debug_token_file,
1156  struct sjtag_debug_token *debug_token)
1157 {
1158  ssize_t rlen;
1159 
1160  rlen = fread(debug_token->debug_token, 1, SJTAG_DEBUG_TOKEN_LEN, debug_token_file);
1161 
1162  if (rlen < SJTAG_DEBUG_TOKEN_LEN)
1163  return -EBADF;
1164 
1165  return 0;
1166 }
1167 
1175 int switchtec_otp_regs_write_protect(struct switchtec_dev *dev,
1176  bool sku_info, bool otp_config)
1177 {
1178  #pragma pack(push, 1)
1179  struct otp_write_prot_cmd {
1180  uint8_t subcmd;
1181  bool sku_info:1;
1182  bool otp_config:1;
1183  } cmd={};
1184  #pragma pack(pop)
1185 
1186  cmd.subcmd = MRPC_OTP_REGS_WRITE_PROT;
1187  cmd.sku_info = sku_info;
1188  cmd.otp_config = otp_config;
1189 
1190  return switchtec_mfg_cmd(dev, MRPC_OTP_PROG_GEN_HDLR, &cmd,
1191  sizeof(cmd), NULL, 0);
1192 }
1193 
1200 int switchtec_otp_sku_info_get(struct switchtec_dev *dev,
1201  struct otp_sku_info_get *sku_info_get_str)
1202 {
1203  uint8_t sub_cmd = MRPC_OTP_SKU_INFO_GET;
1204  return switchtec_mfg_cmd(dev, MRPC_OTP_CONTROL_STATUS_GEN_HDLR, &sub_cmd,
1205  sizeof(sub_cmd), sku_info_get_str, sizeof(struct otp_sku_info_get));
1206 }
1207 
1214 int switchtec_otp_self_test_policy_set(struct switchtec_dev *dev,
1215  uint8_t *self_test_policy)
1216 {
1217  struct self_test_policy_cmd {
1218  uint8_t subcmd;
1219  uint8_t self_test_policy[OTP_SELF_TEST_POLICY_LENGTH];
1220  } cmd = {};
1221 
1222  cmd.subcmd = MRPC_OTP_SELF_TEST_POLICY_SET;
1223 
1224  memcpy((void *)cmd.self_test_policy, (void *)self_test_policy, OTP_SELF_TEST_POLICY_LENGTH);
1225 
1226  return switchtec_mfg_cmd(dev, MRPC_OTP_PROG_GEN_HDLR, &cmd,
1227  sizeof(cmd), NULL, 0);
1228 }
1229 
1236 int switchtec_otp_die_trace_prog(struct switchtec_dev *dev,
1237  uint8_t *die_trace)
1238 {
1239  struct otp_die_trace_cmd {
1240  uint32_t subcmd;
1241  uint8_t die_trace[OTP_DIE_TRACE_LENGTH];
1242  } cmd = {};
1243 
1244  cmd.subcmd = MRPC_OTP_PROG_DIE_TRACE;
1245 
1246  memcpy((void *)cmd.die_trace, (void *)die_trace, OTP_DIE_TRACE_LENGTH);
1247 
1248  return switchtec_mfg_cmd(dev, MRPC_OTP_PROG_GEN_HDLR, &cmd,
1249  sizeof(cmd), NULL, 0);
1250 }
1251 
1258 int switchtec_otp_bit_byte_prog_mode_set(struct switchtec_dev *dev,
1259  bool bit_byte_mode)
1260 {
1261 
1262  struct self_test_policy_cmd {
1263  uint8_t subcmd;
1264  bool bit_byte_mode;
1265  } cmd = {};
1266 
1267  cmd.subcmd = MRPC_OTP_BIT_BYTE_MODE_SET;
1268  cmd.bit_byte_mode = bit_byte_mode;
1269  return switchtec_mfg_cmd(dev, MRPC_OTP_CONTROL_STATUS_GEN_HDLR, &cmd,
1270  sizeof(cmd), NULL, 0);
1271 }
1272 
1279 int switchtec_otp_smart_prog_mode_set(struct switchtec_dev *dev,
1280  bool smart_prog_mode)
1281 {
1282  struct self_test_policy_cmd {
1283  uint8_t subcmd;
1284  bool smart_prog_mode;
1285  } cmd = {};
1286 
1287  cmd.subcmd = MRPC_OTP_SMART_PROG_MODE_SET;
1288  cmd.smart_prog_mode = smart_prog_mode;
1289 
1290  return switchtec_mfg_cmd(dev, MRPC_OTP_CONTROL_STATUS_GEN_HDLR, &cmd,
1291  sizeof(cmd), NULL, 0);
1292 }
1293 
1300 int switchtec_otp_mode_status_get(struct switchtec_dev *dev, struct otp_mode_status *otp_mode_status_str)
1301 {
1302  uint8_t subcmd = MRPC_OTP_MODE_STATUS_GET;
1303  return switchtec_mfg_cmd(dev, MRPC_OTP_CONTROL_STATUS_GEN_HDLR, &subcmd,
1304  sizeof(subcmd), otp_mode_status_str, sizeof(struct otp_mode_status));
1305 }
1306 
1313 int switchtec_custid_prog(struct switchtec_dev *dev, uint16_t cust_id)
1314 {
1315  #pragma pack(push, 1)
1316  struct cust_id_cmd {
1317  uint8_t subcmd;
1318  uint16_t cust_id;
1319  } cmd = {};
1320  #pragma pack(pop)
1321 
1322  cmd.subcmd = MRPC_OTP_CUSTID_PROG;
1323  cmd.cust_id = cust_id;
1324 
1325  return switchtec_mfg_cmd(dev, MRPC_OTP_PROG_GEN_HDLR, &cmd,
1326  sizeof(cmd), NULL, 0);
1327 }
1334 int switchtec_active_image_index_get(struct switchtec_dev *dev,
1335  struct switchtec_active_index *index)
1336 {
1337  int ret;
1338  struct active_indices {
1339  uint8_t index[SWITCHTEC_ACTV_IDX_MAX_ENTRIES];
1340  } reply;
1341 
1342  ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_GET, NULL,
1343  0, &reply, sizeof(reply));
1344  if (ret)
1345  return ret;
1346 
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];
1351 
1352  return 0;
1353 }
1354 
1361 int switchtec_active_image_index_set(struct switchtec_dev *dev,
1362  struct switchtec_active_index *index)
1363 {
1364  int ret;
1365  int i = 0;
1366  struct active_idx {
1367  uint32_t count;
1368  struct entry {
1369  uint8_t image_id;
1370  uint8_t index;
1371  } idx[SWITCHTEC_ACTV_IDX_SET_ENTRIES];
1372  } set;
1373 
1374  memset(&set, 0, sizeof(set));
1375 
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;
1379  i++;
1380  }
1381 
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;
1385  i++;
1386  }
1387 
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;
1391  i++;
1392  }
1393 
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;
1397  i++;
1398  }
1399 
1400  if (i == 0)
1401  return 0;
1402 
1403  set.count = htole32(i);
1404 
1405  ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_SET, &set,
1406  sizeof(set), NULL, 0);
1407  return ret;
1408 }
1409 
1416 int switchtec_fw_exec(struct switchtec_dev *dev,
1417  enum switchtec_bl2_recovery_mode recovery_mode)
1418 {
1419  struct fw_exec_struct {
1420  uint8_t subcmd;
1421  uint8_t recovery_mode;
1422  uint8_t rsvd[2];
1423  } cmd;
1424 
1425  memset(&cmd, 0, sizeof(cmd));
1426  cmd.subcmd = MRPC_FW_TX_EXEC;
1427  cmd.recovery_mode = recovery_mode;
1428 
1429  return switchtec_mfg_cmd(dev, MRPC_FW_TX, &cmd, sizeof(cmd), NULL, 0);
1430 }
1431 
1444 int switchtec_boot_resume(struct switchtec_dev *dev)
1445 {
1446  return switchtec_mfg_cmd(dev, MRPC_BOOTUP_RESUME, NULL, 0,
1447  NULL, 0);
1448 }
1449 
1456 int switchtec_secure_state_set(struct switchtec_dev *dev,
1457  enum switchtec_secure_state state)
1458 {
1459  uint32_t data;
1460 
1461  if ((state != SWITCHTEC_INITIALIZED_UNSECURED)
1462  && (state != SWITCHTEC_INITIALIZED_SECURED)) {
1463  return ERR_PARAM_INVALID;
1464  }
1465  data = htole32(state);
1466 
1467  return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET, &data,
1468  sizeof(data), NULL, 0);
1469 }
1470 
1479 static int dbg_unlock_send_pubkey(struct switchtec_dev *dev,
1480  struct switchtec_pubkey *public_key)
1481 {
1482  struct public_key_cmd {
1483  uint8_t subcmd;
1484  uint8_t rsvd[3];
1485  uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1486  uint32_t pub_key_exp;
1487  } cmd = {};
1488 
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);
1492 
1493  return switchtec_mfg_cmd(dev, MRPC_DBG_UNLOCK, &cmd,
1494  sizeof(cmd), NULL, 0);
1495 }
1496 
1506 int switchtec_dbg_unlock(struct switchtec_dev *dev, uint32_t serial,
1507  uint32_t ver_sec_unlock,
1508  struct switchtec_pubkey *public_key,
1509  struct switchtec_signature *signature)
1510 {
1511  int ret;
1512  struct unlock_cmd {
1513  uint8_t subcmd;
1514  uint8_t rsvd[3];
1515  uint32_t serial;
1516  uint32_t unlock_ver;
1517  uint8_t signature[SWITCHTEC_SIG_LEN];
1518  } cmd = {};
1519 
1520  ret = dbg_unlock_send_pubkey(dev, public_key);
1521  if (ret)
1522  return ret;
1523 
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);
1528 
1529  return switchtec_mfg_cmd(dev, MRPC_DBG_UNLOCK, &cmd,
1530  sizeof(cmd), NULL, 0);
1531 }
1532 
1542 int switchtec_dbg_unlock_version_update(struct switchtec_dev *dev,
1543  uint32_t serial,
1544  uint32_t ver_sec_unlock,
1545  struct switchtec_pubkey *public_key,
1546  struct switchtec_signature *signature)
1547 {
1548  int ret;
1549  struct update_cmd {
1550  uint8_t subcmd;
1551  uint8_t rsvd[3];
1552  uint32_t serial;
1553  uint32_t unlock_ver;
1554  uint8_t signature[SWITCHTEC_SIG_LEN];
1555  } cmd = {};
1556 
1557  ret = dbg_unlock_send_pubkey(dev, public_key);
1558  if (ret)
1559  return ret;
1560 
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);
1565 
1566  return switchtec_mfg_cmd(dev, MRPC_DBG_UNLOCK, &cmd, sizeof(cmd),
1567  NULL, 0);
1568 }
1569 
1577 int switchtec_read_sec_cfg_file(struct switchtec_dev *dev,
1578  FILE *setting_file,
1579  struct switchtec_security_cfg_set *set)
1580 {
1581  ssize_t rlen;
1582  char magic[4] = {'S', 'S', 'F', 'F'};
1583  uint32_t crc;
1584  struct setting_file_header {
1585  uint8_t magic[4];
1586  uint32_t version;
1587  uint8_t hw_gen;
1588  uint8_t rsvd[3];
1589  uint32_t crc;
1590  };
1591  struct setting_file_data {
1592  uint64_t cfg;
1593  uint32_t pub_key_exponent;
1594  uint8_t rsvd[36];
1595  };
1596  struct setting_file {
1597  struct setting_file_header header;
1598  struct setting_file_data data;
1599  } file_data;
1600  struct get_cfgs_reply reply;
1601  uint32_t addr_shift;
1602  uint32_t map_shift;
1603  uint32_t map_mask;
1604  enum switchtec_gen gen;
1605  int spi_clk;
1606  int ret;
1607  int otp_valid;
1608 
1609  ret = get_configs(dev, &reply, &otp_valid);
1610  if (ret)
1611  return ret;
1612 
1613  rlen = fread(&file_data, 1, sizeof(file_data), setting_file);
1614 
1615  if (rlen < sizeof(file_data))
1616  return -EBADF;
1617 
1618  if (memcmp(file_data.header.magic, magic, sizeof(magic)))
1619  return -EBADF;
1620 
1621  crc = crc32((uint8_t*)&file_data.data,
1622  sizeof(file_data.data), 0, 1, 1);
1623  if (crc != le32toh(file_data.header.crc))
1624  return -EBADF;
1625  switch (file_data.header.hw_gen) {
1626  case 0:
1627  gen = SWITCHTEC_GEN4;
1628  break;
1629  case 1:
1630  gen = SWITCHTEC_GEN5;
1631  break;
1632  default:
1633  return -EBADF;
1634  }
1635 
1636  if (gen != switchtec_gen(dev))
1637  return -ENODEV;
1638 
1639  memset(set, 0, sizeof(struct switchtec_security_cfg_set));
1640  file_data.data.cfg = le64toh(file_data.data.cfg);
1641 
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];
1646  else
1647  set->spi_clk_rate = spi_clk_rate_float[spi_clk];
1648 
1649  set->i2c_recovery_tmo =
1650  (file_data.data.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) &
1651  SWITCHTEC_RC_TMO_BITMASK;
1652  set->i2c_port =
1653  (file_data.data.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) &
1654  SWITCHTEC_I2C_PORT_BITMASK;
1655 
1656  get_i2c_operands(gen, &addr_shift, &map_shift, &map_mask);
1657  set->i2c_addr =
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;
1661 
1662  set->public_key_exponent = le32toh(file_data.data.pub_key_exponent);
1663 
1664  return 0;
1665 }
1666 
1675 static int kmsk_set_send_pubkey(struct switchtec_dev *dev,
1676  struct switchtec_pubkey *public_key)
1677 {
1678  struct kmsk_pubk_cmd {
1679  uint8_t subcmd;
1680  uint8_t reserved[3];
1681  uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1682  uint32_t pub_key_exponent;
1683  } cmd = {};
1684 
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);
1689 
1690  return switchtec_mfg_cmd(dev, MRPC_KMSK_ENTRY_SET, &cmd,
1691  sizeof(cmd), NULL, 0);
1692 }
1693 
1702 static int kmsk_set_send_signature(struct switchtec_dev *dev,
1703  struct switchtec_signature *signature)
1704 {
1705  struct kmsk_signature_cmd {
1706  uint8_t subcmd;
1707  uint8_t reserved[3];
1708  uint8_t signature[SWITCHTEC_SIG_LEN];
1709  } cmd = {};
1710 
1711  cmd.subcmd = MRPC_KMSK_ENTRY_SET_SIG;
1712  memcpy(cmd.signature, signature->signature,
1713  SWITCHTEC_SIG_LEN);
1714 
1715  return switchtec_mfg_cmd(dev, MRPC_KMSK_ENTRY_SET, &cmd,
1716  sizeof(cmd), NULL, 0);
1717 }
1718 
1727 static int kmsk_set_send_kmsk(struct switchtec_dev *dev,
1728  struct switchtec_kmsk *kmsk)
1729 {
1730  struct kmsk_kmsk_cmd {
1731  uint8_t subcmd;
1732  uint8_t num_entries;
1733  uint8_t reserved[2];
1734  uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1735  } cmd = {};
1736 
1737  cmd.subcmd = MRPC_KMSK_ENTRY_SET_KMSK;
1738  cmd.num_entries = 1;
1739  memcpy(cmd.kmsk, kmsk->kmsk, SWITCHTEC_KMSK_LEN);
1740 
1741  return switchtec_mfg_cmd(dev, MRPC_KMSK_ENTRY_SET, &cmd, sizeof(cmd),
1742  NULL, 0);
1743 }
1744 
1757 int switchtec_kmsk_set(struct switchtec_dev *dev,
1758  struct switchtec_pubkey *public_key,
1759  struct switchtec_signature *signature,
1760  struct switchtec_kmsk *kmsk)
1761 {
1762  int ret;
1763 
1764  if (public_key) {
1765  ret = kmsk_set_send_pubkey(dev, public_key);
1766  if (ret)
1767  return ret;
1768  }
1769 
1770  if (signature) {
1771  ret = kmsk_set_send_signature(dev, signature);
1772  if (ret)
1773  return ret;
1774  }
1775 
1776  return kmsk_set_send_kmsk(dev, kmsk);
1777 }
1778 
1779 #if HAVE_LIBCRYPTO
1780 
1786 int switchtec_read_pubk_file(FILE *pubk_file, struct switchtec_pubkey *pubk)
1787 {
1788  RSA *RSAKey = NULL;
1789  const BIGNUM *modulus_bn;
1790  const BIGNUM *exponent_bn;
1791  uint32_t exponent_tmp = 0;
1792 
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);
1797  if (RSAKey == NULL)
1798  return -1;
1799  }
1800 
1801  RSA_get0_key(RSAKey, &modulus_bn, &exponent_bn, NULL);
1802 
1803  BN_bn2bin(modulus_bn, pubk->pubkey);
1804  BN_bn2bin(exponent_bn, (uint8_t *)&exponent_tmp);
1805 
1806  pubk->pubkey_exp = be32toh(exponent_tmp);
1807  RSA_free(RSAKey);
1808 
1809  return 0;
1810 }
1811 #endif
1812 
1813 
1820 int switchtec_read_kmsk_file(FILE *kmsk_file, struct switchtec_kmsk *kmsk)
1821 {
1822  ssize_t rlen;
1823  struct kmsk_struct {
1824  uint8_t magic[4];
1825  uint32_t version;
1826  uint32_t reserved;
1827  uint32_t crc32;
1828  uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1829  } data;
1830 
1831  char magic[4] = {'K', 'M', 'S', 'K'};
1832  uint32_t crc;
1833 
1834  rlen = fread(&data, 1, sizeof(data), kmsk_file);
1835 
1836  if (rlen < sizeof(data))
1837  return -EBADF;
1838 
1839  if (memcmp(data.magic, magic, sizeof(magic)))
1840  return -EBADF;
1841 
1842  crc = crc32(data.kmsk, SWITCHTEC_KMSK_LEN, 0, 1, 1);
1843  if (crc != le32toh(data.crc32))
1844  return -EBADF;
1845 
1846  memcpy(kmsk->kmsk, data.kmsk, SWITCHTEC_KMSK_LEN);
1847 
1848  return 0;
1849 }
1850 
1858  struct switchtec_signature *signature)
1859 {
1860  ssize_t rlen;
1861 
1862  rlen = fread(signature->signature, 1, SWITCHTEC_SIG_LEN, sig_file);
1863 
1864  if (rlen < SWITCHTEC_SIG_LEN)
1865  return -EBADF;
1866 
1867  return 0;
1868 }
1875 int switchtec_read_uuid_file(FILE *uuid_file,
1876  struct switchtec_uuid *uuid)
1877 {
1878  ssize_t rlen;
1879 
1880  rlen = fread(uuid->uuid_data, 1, OTP_SJTAG_UUID_LENGTH, uuid_file);
1881 
1882  if (rlen < OTP_SJTAG_UUID_LENGTH)
1883  return -EBADF;
1884 
1885  return 0;
1886 }
1887 
1894 int switchtec_read_sjtag_key_file(FILE *sjtag_file,
1895  struct otp_sjtag_key *sjtag_key)
1896 {
1897  ssize_t rlen;
1898 
1899  rlen = fread(sjtag_key->sjtag_key, 1, OTP_SJTAG_KEY_LENGTH, sjtag_file);
1900 
1901  if (rlen < OTP_SJTAG_KEY_LENGTH)
1902  return -EBADF;
1903 
1904  return 0;
1905 }
1906 
1915  struct otp_config_data *config_data,
1916  unsigned short config_len)
1917 {
1918  ssize_t rlen;
1919  rlen = fread((void *)config_data->config_data, 1, config_len, config_file);
1920 
1921  if (rlen < config_len)
1922  return -EBADF;
1923 
1924  return 0;
1925 }
1926 
1933 int switchtec_read_self_test_policy_file(FILE *self_test_file,
1935 {
1936  ssize_t rlen;
1937 
1938  rlen = fread(otp_self_test_policy->otp_self_test_policy, 1, OTP_SELF_TEST_POLICY_LENGTH, self_test_file);
1939 
1940  if (rlen < OTP_SELF_TEST_POLICY_LENGTH)
1941  return -EBADF;
1942 
1943  return 0;
1944 }
1945 
1952 int switchtec_read_die_trace_file(FILE *die_trace_file,
1953  struct otp_die_trace *otp_die_trace_ptr)
1954 {
1955  ssize_t rlen;
1956 
1957  rlen = fread(otp_die_trace_ptr->die_trace, 1, OTP_DIE_TRACE_LENGTH, die_trace_file);
1958 
1959  if (rlen < OTP_DIE_TRACE_LENGTH)
1960  return -EBADF;
1961 
1962  return 0;
1963 }
1964 
1965 
1977  struct switchtec_kmsk *kmsk)
1978 {
1979  int key_idx;
1980 
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)
1984  return 1;
1985  }
1986 
1987  return 0;
1988 }
1989 
1990 #endif /* __linux__ */
1991 
2004 static int switchtec_mfg_cmd(struct switchtec_dev *dev, uint32_t cmd,
2005  const void *payload, size_t payload_len,
2006  void *resp, size_t resp_len)
2007 {
2008  if (dev->ops->flags & SWITCHTEC_OPS_FLAG_NO_MFG) {
2009  errno = ERR_UART_NOT_SUPPORTED | SWITCHTEC_ERRNO_MRPC_FLAG_BIT;
2010  return -1;
2011  }
2012  return switchtec_cmd(dev, cmd, payload, payload_len,
2013  resp, resp_len);
2014 }
2015 
2022 int switchtec_sn_ver_get(struct switchtec_dev *dev,
2023  struct switchtec_sn_ver_info *info)
2024 {
2025  int ret;
2026 
2027  ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET, NULL, 0, info,
2028  sizeof(struct switchtec_sn_ver_info));
2029  if (ret)
2030  return ret;
2031 
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);
2038 
2039  return 0;
2040 }
2041 
2042 
get_configs
static int get_configs(struct switchtec_dev *dev, struct get_cfgs_reply *cfgs, int *otp_valid)
Retrieve configuration settings from the device.
Definition: mfg.c:184
switchtec_read_signature_file
int switchtec_read_signature_file(FILE *sig_file, struct switchtec_signature *signature)
Read signature data from signature file.
Definition: mfg.c:1857
switchtec_sjtag_get_nonce
int switchtec_sjtag_get_nonce(struct switchtec_dev *dev, struct sjtag_nonce *sjtag_nonce_ptr)
Retrieve the SJTAG nonce from the device.
Definition: mfg.c:833
cfg_stmfd
Definition: mfg.c:157
switchtec_otp_config_read
int switchtec_otp_config_read(struct switchtec_dev *dev, uint16_t config_start_address, int32_t config_length, int out_fd)
Reads OTP configuration data from the device.
Definition: mfg.c:643
switchtec_read_sec_cfg_file
int switchtec_read_sec_cfg_file(struct switchtec_dev *dev, FILE *setting_file, struct switchtec_security_cfg_set *set)
Read security settings from config file.
Definition: mfg.c:1577
switchtec_security_cfg_set
Definition: mfg.h:198
switchtec_boot_resume
int switchtec_boot_resume(struct switchtec_dev *dev)
Resume device boot. Note that after calling this function, the current 'dev' pointer is no longer val...
Definition: mfg.c:1444
switchtec_otp_sjtag_key_verify
int switchtec_otp_sjtag_key_verify(struct switchtec_dev *dev, uint8_t *sjtag_key, uint8_t *is_verified)
Verify the SJTAG key in the OTP memory.
Definition: mfg.c:697
switchtec_otp_die_trace_prog
int switchtec_otp_die_trace_prog(struct switchtec_dev *dev, uint8_t *die_trace)
Progrom Die Trace into OTP.
Definition: mfg.c:1236
switchtec_security_spi_avail_rate
Definition: mfg.h:301
switchtec_sjtag_status_get
int switchtec_sjtag_status_get(struct switchtec_dev *dev, struct sjtag_status_get *sjtag_sts_get)
Get the SJTAG status from the switchtec device.
Definition: mfg.c:864
switchtec_otp_sku_info_set
int switchtec_otp_sku_info_set(struct switchtec_dev *dev, struct otp_sku_info_set *sku_info_set_str)
Set the SKU information in the OTP memory of the Switchtec device.
Definition: mfg.c:772
kmsk_set_send_pubkey
static int kmsk_set_send_pubkey(struct switchtec_dev *dev, struct switchtec_pubkey *public_key)
Set and send the public key to the device.
Definition: mfg.c:1675
switchtec_secure_state_set
int switchtec_secure_state_set(struct switchtec_dev *dev, enum switchtec_secure_state state)
Set device secure state.
Definition: mfg.c:1456
otp_sjtag_key
Definition: mfg.h:271
switchtec.h
Main Switchtec header.
switchtec_security_cfg_state
Definition: mfg.h:175
switchtec_custid_prog
int switchtec_custid_prog(struct switchtec_dev *dev, uint16_t cust_id)
Program given customer id into OTP.
Definition: mfg.c:1313
switchtec_sjtag_hr_send
int switchtec_sjtag_hr_send(struct switchtec_dev *dev, uint8_t *sjtag_hr)
Send SJTAG host response to the device.
Definition: mfg.c:530
switchtec_kmsk
Definition: mfg.h:226
otp_config_data
Definition: mfg.h:275
kmsk_set_send_kmsk
static int kmsk_set_send_kmsk(struct switchtec_dev *dev, struct switchtec_kmsk *kmsk)
Set the KMSK (Key Management Security Key) for the device.
Definition: mfg.c:1727
switchtec_otp_bit_byte_prog_mode_set
int switchtec_otp_bit_byte_prog_mode_set(struct switchtec_dev *dev, bool bit_byte_mode)
Set Bit or Byte Mode for OTP.
Definition: mfg.c:1258
otp_sku_info_set
Definition: mfg.h:235
switchtec_security_state_has_kmsk
int switchtec_security_state_has_kmsk(struct switchtec_security_cfg_state *state, struct switchtec_kmsk *kmsk)
Check if secure config already has a KMSK entry KMSK stands for Key Manifest Secure Key....
Definition: mfg.c:1976
sjtag_status_get
Definition: mfg.h:251
switchtec_active_image_index_get
int switchtec_active_image_index_get(struct switchtec_dev *dev, struct switchtec_active_index *index)
Get active image index.
Definition: mfg.c:1334
switchtec_otp_smart_prog_mode_set
int switchtec_otp_smart_prog_mode_set(struct switchtec_dev *dev, bool smart_prog_mode)
Set Smart Programming mode for OTP.
Definition: mfg.c:1279
otp_sku_info_get
Definition: mfg.h:240
switchtec_mfg_cmd
static int switchtec_mfg_cmd(struct switchtec_dev *dev, uint32_t cmd, const void *payload, size_t payload_len, void *resp, size_t resp_len)
Execute a manufacturing command on the Switchtec device.
Definition: mfg.c:2004
get_cfgs_reply
Definition: mfg.c:163
switchtec_otp_sjtag_uuid_set
int switchtec_otp_sjtag_uuid_set(struct switchtec_dev *dev, uint8_t *sjtag_uuid)
Set the SJTAG UUID for a Switchtec device.
Definition: mfg.c:555
switchtec_pubkey
Definition: mfg.h:230
switchtec_mailbox_to_file
int switchtec_mailbox_to_file(struct switchtec_dev *dev, int fd)
Retrieve mailbox entries.
Definition: mfg.c:355
get_i2c_operands
static void get_i2c_operands(enum switchtec_gen gen, uint32_t *addr_shift, uint32_t *map_shift, uint32_t *map_mask)
Get I2C operands based on the Switchtec generation.
Definition: mfg.c:134
switchtec_sn_ver_get
int switchtec_sn_ver_get(struct switchtec_dev *dev, struct switchtec_sn_ver_info *info)
Get serial number and security version.
Definition: mfg.c:2022
switchtec_read_sjtag_debug_token_file
int switchtec_read_sjtag_debug_token_file(FILE *debug_token_file, struct sjtag_debug_token *debug_token)
This function fetches the Debug Token from a bin file.
Definition: mfg.c:1155
switchtec_signature
Definition: mfg.h:297
switchtec_dbg_unlock_version_update
int switchtec_dbg_unlock_version_update(struct switchtec_dev *dev, uint32_t serial, uint32_t ver_sec_unlock, struct switchtec_pubkey *public_key, struct switchtec_signature *signature)
Update firmware debug secure unlock version number.
Definition: mfg.c:1542
sjtag_debug_token_gen
int sjtag_debug_token_gen(uint8_t *idcode_ptr, uint8_t *uuid_ptr, uint8_t *suv_ptr, uint8_t *sjtag_debug_token, bool verbose)
This Generates the Debug Token.
Definition: mfg.c:1002
switchtec_read_sjtag_key_file
int switchtec_read_sjtag_key_file(FILE *sjtag_file, struct otp_sjtag_key *sjtag_key)
Read SJTAG key data from SJTAG file.
Definition: mfg.c:1894
switchtec_otp_config_prog
int switchtec_otp_config_prog(struct switchtec_dev *dev, uint16_t config_len, uint8_t *config_data, bool is_firmware_halt)
Programs the OTP configuration on the Switchtec device.
Definition: mfg.c:606
switchtec_otp_sjtag_key_lock
int switchtec_otp_sjtag_key_lock(struct switchtec_dev *dev)
Locks the SJTAG key on the specified Switchtec device.
Definition: mfg.c:729
switchtec_chip_serial_num_prog
int switchtec_chip_serial_num_prog(struct switchtec_dev *dev, uint32_t chip_serial_num)
Program the chip serial number for a Switchtec device.
Definition: mfg.c:749
sjtag_encode_cmd_header
void sjtag_encode_cmd_header(uint8_t *cmd_header, uint8_t cmd)
This function generates the command header to send to the server.
Definition: mfg.c:939
switchtec_security_config_set
int switchtec_security_config_set(struct switchtec_dev *dev, struct switchtec_security_cfg_set *setting)
Set secure settings.
Definition: mfg.c:435
switchtec_otp_self_test_policy_set
int switchtec_otp_self_test_policy_set(struct switchtec_dev *dev, uint8_t *self_test_policy)
Program Self Test Policy into OTP.
Definition: mfg.c:1214
convert_spi_clk_rate
static int convert_spi_clk_rate(float clk_float, int hi_rate)
Converts SPI clock rate from float to an integer index.
Definition: mfg.c:396
switchtec_security_spi_avail_rate_get
int switchtec_security_spi_avail_rate_get(struct switchtec_dev *dev, struct switchtec_security_spi_avail_rate *rates)
Get the available SPI rates for the Switchtec device.
Definition: mfg.c:228
sjtag_uuid
Definition: mfg.h:255
parse_otp_settings
static void parse_otp_settings(struct switchtec_security_cfg_otp_region *otp, uint32_t flags)
Parse OTP settings from flags.
Definition: mfg.c:257
switchtec_dbg_unlock
int switchtec_dbg_unlock(struct switchtec_dev *dev, uint32_t serial, uint32_t ver_sec_unlock, struct switchtec_pubkey *public_key, struct switchtec_signature *signature)
Unlock firmware debug features.
Definition: mfg.c:1506
switchtec_otp_sjtag_mode_set
int switchtec_otp_sjtag_mode_set(struct switchtec_dev *dev, uint8_t sjtag_mode)
Set the SJTAG mode for the Switchtec device.
Definition: mfg.c:507
switchtec_otp_sku_info_get
int switchtec_otp_sku_info_get(struct switchtec_dev *dev, struct otp_sku_info_get *sku_info_get_str)
Get SKU Information and Write Protected Status.
Definition: mfg.c:1200
switchtec_sn_ver_info
Definition: mfg.h:132
switchtec_read_kmsk_file
int switchtec_read_kmsk_file(FILE *kmsk_file, struct switchtec_kmsk *kmsk)
Read KMSK data from KMSK file.
Definition: mfg.c:1820
switchtec_otp_sjtag_key_set
int switchtec_otp_sjtag_key_set(struct switchtec_dev *dev, uint8_t *sjtag_key)
Set the SJTAG key in the OTP memory of the Switchtec device.
Definition: mfg.c:579
switchtec_sjtag_get_uuid_idcode
int switchtec_sjtag_get_uuid_idcode(struct switchtec_dev *dev, uint8_t *sjtag_uuid_ptr, uint8_t *sjtag_idcode)
Retrieve the UUID and ID code from the switchtec device.
Definition: mfg.c:800
switchtec_otp_regs_write_protect
int switchtec_otp_regs_write_protect(struct switchtec_dev *dev, bool sku_info, bool otp_config)
Write Protect given choice of OTP Regions.
Definition: mfg.c:1175
otp_mode_status
Definition: mfg.h:288
switchtec_read_otp_config_data_file
int switchtec_read_otp_config_data_file(FILE *config_file, struct otp_config_data *config_data, unsigned short config_len)
Read OTP Config data from bin file.
Definition: mfg.c:1914
switchtec_active_index
Definition: mfg.h:213
switchtec_read_uuid_file
int switchtec_read_uuid_file(FILE *uuid_file, struct switchtec_uuid *uuid)
Read UUID data from UUID file.
Definition: mfg.c:1875
switchtec_active_image_index_set
int switchtec_active_image_index_set(struct switchtec_dev *dev, struct switchtec_active_index *index)
Set active image index.
Definition: mfg.c:1361
switchtec_security_config_get
int switchtec_security_config_get(struct switchtec_dev *dev, struct switchtec_security_cfg_state *state)
Get secure boot configurations.
Definition: mfg.c:284
switchtec_fw_exec
int switchtec_fw_exec(struct switchtec_dev *dev, enum switchtec_bl2_recovery_mode recovery_mode)
Execute the transferred firmware.
Definition: mfg.c:1416
dbg_unlock_send_pubkey
static int dbg_unlock_send_pubkey(struct switchtec_dev *dev, struct switchtec_pubkey *public_key)
Send the public key to unlock the device.
Definition: mfg.c:1479
otp_self_test_policy
Definition: mfg.h:279
sjtag_debug_token
Definition: mfg.h:263
switchtec_read_self_test_policy_file
int switchtec_read_self_test_policy_file(FILE *self_test_file, struct otp_self_test_policy *otp_self_test_policy)
Read Self Test Policy from bin file.
Definition: mfg.c:1933
switchtec_gen
switchtec_gen
The PCIe generations.
Definition: switchtec.h:89
kmsk_set_send_signature
static int kmsk_set_send_signature(struct switchtec_dev *dev, struct switchtec_signature *signature)
Set the KMSK send signature.
Definition: mfg.c:1702
switchtec_kmsk_set
int switchtec_kmsk_set(struct switchtec_dev *dev, struct switchtec_pubkey *public_key, struct switchtec_signature *signature, struct switchtec_kmsk *kmsk)
Set KMSK entry KMSK stands for Key Manifest Secure Key. It is a key used to verify Key Manifest parti...
Definition: mfg.c:1757
switchtec_uuid
Definition: mfg.h:267
otp_die_trace
Definition: mfg.h:283
sjtag_nonce
Definition: mfg.h:259
switchtec_cmd
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.
Definition: platform.c:164
switchtec_read_die_trace_file
int switchtec_read_die_trace_file(FILE *die_trace_file, struct otp_die_trace *otp_die_trace_ptr)
Read Die Trace from die trace bin file.
Definition: mfg.c:1952
switchtec_otp_mode_status_get
int switchtec_otp_mode_status_get(struct switchtec_dev *dev, struct otp_mode_status *otp_mode_status_str)
Get Status of Programming Modes in OTP.
Definition: mfg.c:1300
switchtec_security_cfg_otp_region
Definition: mfg.h:162