Switchtec Userspace PROJECT_NUMBER = 4.4
Loading...
Searching...
No Matches
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
29
45
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
59#include "lib/crc.h"
60#include "config.h"
61
62#ifdef __linux__
63
64#if HAVE_LIBCRYPTO
65#include <openssl/pem.h>
66#endif
67
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
72
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
78
79#define SWITCHTEC_MB_MAX_ENTRIES 16
80#define SWITCHTEC_ACTV_IDX_MAX_ENTRIES 32
81#define SWITCHTEC_ACTV_IDX_SET_ENTRIES 5
82
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
100
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
105
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);
109
110static void get_i2c_operands(enum switchtec_gen gen, uint32_t *addr_shift,
111 uint32_t *map_shift, uint32_t *map_mask)
112{
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;
117 } else {
118 *addr_shift = SWITCHTEC_I2C_ADDR_BITSHIFT;
119 *map_shift = SWITCHTEC_CMD_MAP_BITSHIFT;
120 *map_mask = SWITCHTEC_CMD_MAP_BITMASK;
121 }
122}
123
124static float spi_clk_rate_float[] = {
125 100, 67, 50, 40, 33.33, 28.57, 25, 22.22, 20, 18.18
126};
127
128static float spi_clk_hi_rate_float[] = {
129 120, 80, 60, 48, 40, 34, 30, 26.67, 24, 21.82
130};
131
132struct get_cfgs_reply {
133 uint32_t valid;
134 uint32_t rsvd1;
135 uint64_t cfg;
136 uint32_t public_key_exponent;
137 uint8_t rsvd2;
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];
142 uint8_t rsvd4[32];
143};
144
145struct get_cfgs_reply_gen5 {
146 uint32_t valid0;
147 uint32_t valid1;
148 uint64_t cfg;
149 uint32_t public_key_exponent;
150 uint8_t rsvd2;
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];
157};
158
159typedef struct switchtec_security_cfg_state_gen6 get_cfgs_reply_gen6;
160
161static uint32_t get_dbg_unlock_id(struct switchtec_dev *dev)
162{
163 if (switchtec_is_gen6(dev))
164 return MRPC_DBG_UNLOCK_GEN6;
165 else if (switchtec_is_gen5(dev))
166 return MRPC_DBG_UNLOCK_GEN5;
167 else
168 return MRPC_DBG_UNLOCK;
169}
170
171static int get_configs(struct switchtec_dev *dev,
172 struct get_cfgs_reply *cfgs,
173 int *otp_valid)
174{
175 uint8_t subcmd = 0;
176 int ret;
177
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)
182 return ret;
183
184 if (!ret) {
185 *otp_valid = true;
186 return ret;
187 }
188
189 *otp_valid = false;
190 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET,
191 NULL, 0, cfgs,
192 sizeof(struct get_cfgs_reply));
193
194 return ret;
195}
196
197static int get_configs_gen5(struct switchtec_dev *dev,
198 struct get_cfgs_reply_gen5 *cfgs)
199{
200 uint32_t subcmd = 0;
201
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));
208}
209
210static int get_configs_gen6(struct switchtec_dev *dev,
211 get_cfgs_reply_gen6 *cfgs)
212{
213 uint32_t subcmd = 0;
214
215 return switchtec_mfg_cmd(dev,
216 MRPC_SECURE_CONFIG_GET_GEN6,
217 &subcmd, sizeof(subcmd),
218 cfgs, sizeof(get_cfgs_reply_gen6));
219
220}
221
222int switchtec_security_spi_avail_rate_get(struct switchtec_dev *dev,
224{
225 int ret;
226 struct get_cfgs_reply reply;
227 int otp_valid;
228
229 ret = get_configs(dev, &reply, &otp_valid);
230 if (ret)
231 return ret;
232
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));
237 else
238 memcpy(rates->rates, spi_clk_rate_float,
239 sizeof(spi_clk_rate_float));
240
241 return 0;
242}
243
244static void parse_otp_settings(struct switchtec_security_cfg_otp_region *otp,
245 uint32_t flags)
246{
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));
263}
264
265static void parse_otp_settings_gen5(
267 uint32_t flags0, uint32_t flags1)
268{
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));
317}
318
319static int security_config_get(struct switchtec_dev *dev,
320 struct switchtec_security_cfg_state *state)
321{
322 int ret;
323 uint32_t addr_shift;
324 uint32_t map_shift;
325 uint32_t map_mask;
326 int spi_clk;
327 struct get_cfgs_reply reply;
328 int otp_valid;
329
330 ret = get_configs(dev, &reply, &otp_valid);
331 if (ret)
332 return ret;
333
334 reply.valid = le32toh(reply.valid);
335 reply.cfg = le64toh(reply.cfg);
336 reply.public_key_exponent = le32toh(reply.public_key_exponent);
337
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);
343
344 state->debug_mode_valid = state->basic_setting_valid;
345
346 state->otp_valid = otp_valid;
347 if (otp_valid)
348 parse_otp_settings(&state->otp, reply.valid);
349
350 state->use_otp_ext = false;
351
352 state->debug_mode = reply.cfg & 0x03;
353 state->secure_state = (reply.cfg>>2) & 0x03;
354
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);
359
360 spi_clk = (reply.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) & 0x0f;
361 if (spi_clk == 0) {
362 if (switchtec_gen(dev) == SWITCHTEC_GEN5)
363 spi_clk = 9;
364 else
365 spi_clk = 7;
366 }
367
368 if (reply.spi_core_clk_high)
369 state->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
370 else
371 state->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
372
373 state->i2c_recovery_tmo =
374 (reply.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) & 0x0f;
375 state->i2c_port = (reply.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) & 0xf;
376
377 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
378 &map_mask);
379 state->i2c_addr =
380 (reply.cfg >> addr_shift) & SWITCHTEC_I2C_ADDR_BITMASK;
381 state->i2c_cmd_map = (reply.cfg >> map_shift) & map_mask;
382
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;
386
387 if (state->public_key_num)
388 memcpy(state->public_key, reply.public_key,
389 state->public_key_num * SWITCHTEC_KMSK_LEN);
390
391 state->attn_state.attestation_mode =
392 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED;
393
394 return 0;
395}
396
397static int security_config_get_gen5(struct switchtec_dev *dev,
398 struct switchtec_security_cfg_state *state)
399{
400 int ret;
401 uint32_t addr_shift;
402 uint32_t map_shift;
403 uint32_t map_mask;
404 int spi_clk;
405 struct get_cfgs_reply_gen5 reply;
406 int attn_mode;
407
408 ret = get_configs_gen5(dev, &reply);
409 if (ret)
410 return ret;
411
412 reply.valid0 = le32toh(reply.valid0);
413 reply.valid1 = le32toh(reply.valid1);
414
415 reply.cfg = le64toh(reply.cfg);
416 reply.public_key_exponent = le32toh(reply.public_key_exponent);
417
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);
423
424 state->debug_mode_valid = !!(reply.valid0 & 0x02);
425 state->attn_state.cdi_efuse_inc_mask_valid = !!(reply.valid0 & 0x40);
426
427 state->otp_valid = true;
428 parse_otp_settings_gen5(&state->otp_ext, reply.valid0,
429 reply.valid1);
430
431 state->use_otp_ext = true;
432
433 state->debug_mode = reply.cfg & 0x03;
434 state->secure_state = (reply.cfg>>2) & 0x03;
435
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);
440
441 spi_clk = (reply.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) & 0x0f;
442 if (spi_clk == 0) {
443 if (switchtec_gen(dev) == SWITCHTEC_GEN5)
444 spi_clk = 9;
445 else
446 spi_clk = 7;
447 }
448
449 if (reply.spi_core_clk_high)
450 state->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
451 else
452 state->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
453
454 state->i2c_recovery_tmo =
455 (reply.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) & 0x0f;
456 state->i2c_port = (reply.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) & 0xf;
457
458 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
459 &map_mask);
460 state->i2c_addr =
461 (reply.cfg >> addr_shift) & SWITCHTEC_I2C_ADDR_BITMASK;
462 state->i2c_cmd_map = (reply.cfg >> map_shift) & map_mask;
463
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);
469
470 attn_mode = (reply.cfg >> SWITCHTEC_ATTEST_BITSHIFT) &
471 SWITCHTEC_ATTEST_BITMASK;
472 if (attn_mode == 1)
473 state->attn_state.attestation_mode =
474 SWITCHTEC_ATTESTATION_MODE_DICE;
475 else
476 state->attn_state.attestation_mode =
477 SWITCHTEC_ATTESTATION_MODE_NONE;
478
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);
484
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;
490 else
491 state->attn_state.uds_visible = false;
492
493 if (state->attn_state.uds_visible)
494 memcpy(state->attn_state.uds_data, reply.uds_data, 32);
495
496 return 0;
497}
498
499static int security_config_get_gen6(struct switchtec_dev *dev,
501{
502 int ret;
503 get_cfgs_reply_gen6 reply;
504
505 ret = get_configs_gen6(dev, &reply);
506 if (ret)
507 return ret;
508
509 memcpy(state, &reply, sizeof(reply));
510
511 return 0;
512}
513
520int switchtec_security_config_get(struct switchtec_dev *dev,
521 void *state)
522{
523 if (switchtec_is_gen6(dev))
524 return security_config_get_gen6(dev,
525 (struct switchtec_security_cfg_state_gen6 *)state);
526 if (switchtec_is_gen5(dev))
527 return security_config_get_gen5(dev,
528 (struct switchtec_security_cfg_state *)state);
529 else
530 return security_config_get(dev, state);
531}
532
533static int mailbox_to_file(struct switchtec_dev *dev, int fd)
534{
535 int ret;
536 int num_to_read = htole32(SWITCHTEC_MB_MAX_ENTRIES);
537 struct mb_reply {
538 uint8_t num_returned;
539 uint8_t num_remaining;
540 uint8_t rsvd[2];
541 uint8_t data[SWITCHTEC_MB_MAX_ENTRIES *
542 SWITCHTEC_MB_LOG_LEN];
543 } reply;
544
545 do {
546 ret = switchtec_mfg_cmd(dev, MRPC_MAILBOX_GET, &num_to_read,
547 sizeof(int), &reply, sizeof(reply));
548 if (ret)
549 return ret;
550
551 reply.num_remaining = le32toh(reply.num_remaining);
552 reply.num_returned = le32toh(reply.num_returned);
553
554 ret = write(fd, reply.data,
555 (reply.num_returned) * SWITCHTEC_MB_LOG_LEN);
556 if (ret < 0)
557 return ret;
558 } while (reply.num_remaining > 0);
559
560 return 0;
561}
562
563/*
564 * @brief Get secure boot settings in BL1 for gen6.
565 * Outside of
566 * @param[in] dev Switchtec device handle
567 * @param[out] state Current secure boot settings
568 * @return 0 on success, error code on failure
569 *
570 * Command ID cannot be accessed outside of BL1 phase. Use security_config_get_gen6
571 * to access the secure settings during MainFW phase.
572*/
573int security_settings_get_gen6(struct switchtec_dev *dev,
575{
576 int ret;
577
578 struct sec_cfg_get_struct cmd = {};
579 uint32_t reply_otp[MRPC_MAX_DATA_LEN / sizeof(uint32_t)] = {};
580
581 /* get first 60dwords of OTP content */
582 cmd.subcmd = MRPC_GET_SECURE_OTP;
583 cmd.OTP_dword_offset = 0;
584 cmd.read_dwords = 60;
585
586 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET_GEN6, &cmd, sizeof(cmd),
587 &reply_otp, cmd.read_dwords * sizeof(uint32_t));
588 if (ret)
589 return ret;
590
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;
601
602 /* get 192 dwords of OTP content from offset 656 for keys*/
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);
606
607 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET_GEN6, &cmd, sizeof(cmd),
608 &reply_otp, cmd.read_dwords * sizeof(uint32_t));
609 if (ret)
610 return ret;
611
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));
616 }
617
618 return 0;
619}
620
621static int mailbox_to_file_gen56(struct switchtec_dev *dev, int fd)
622{
623 int ret;
624 struct mb_read {
625 uint32_t subcmd;
626 uint32_t num_to_read;
627 } read;
628 struct mb_reply {
629 uint8_t num_returned;
630 uint8_t num_remaining;
631 uint8_t rsvd[2];
632 uint8_t data[SWITCHTEC_MB_MAX_ENTRIES *
633 SWITCHTEC_MB_LOG_LEN];
634 } reply;
635
636 read.subcmd = 0;
637 read.num_to_read = htole32(SWITCHTEC_MB_MAX_ENTRIES);
638
639 enum mrpc_cmd cmd_id = switchtec_is_gen6(dev) ?
640 MRPC_MAILBOX_GET_GEN6 : MRPC_MAILBOX_GET_GEN5;
641
642 do {
643 ret = switchtec_mfg_cmd(dev, cmd_id,
644 &read, sizeof(read),
645 &reply, sizeof(reply));
646 if (ret)
647 return ret;
648
649 reply.num_remaining = le32toh(reply.num_remaining);
650 reply.num_returned = le32toh(reply.num_returned);
651
652 ret = write(fd, reply.data,
653 (reply.num_returned) * SWITCHTEC_MB_LOG_LEN);
654 if (ret < 0)
655 return ret;
656 } while (reply.num_remaining > 0);
657
658 return 0;
659}
660
667int switchtec_mailbox_to_file(struct switchtec_dev *dev, int fd)
668{
669 if (switchtec_is_gen5(dev) || switchtec_is_gen6(dev))
670 return mailbox_to_file_gen56(dev, fd);
671 else
672 return mailbox_to_file(dev, fd);
673}
674
675static int convert_spi_clk_rate(float clk_float, int hi_rate)
676{
677 int i;
678 float *p;
679
680 if (hi_rate)
681 p = spi_clk_hi_rate_float;
682 else
683 p = spi_clk_rate_float;
684
685 for (i = 0; i < 10; i++)
686 if ((clk_float < p[i] + 0.1) && (clk_float > p[i] - 0.1))
687 return i + 1;
688
689 return -1;
690}
691
692static int security_config_set_gen4(struct switchtec_dev *dev,
693 struct switchtec_security_cfg_set *setting)
694{
695 int ret;
696 struct setting_data {
697 uint64_t cfg;
698 uint32_t pub_key_exponent;
699 uint8_t rsvd[4];
700 } sd;
701 struct get_cfgs_reply reply;
702 uint64_t ldata = 0;
703 uint32_t addr_shift;
704 uint32_t map_shift;
705 uint32_t map_mask;
706 int spi_clk;
707 int otp_valid;
708
709 /* Gen4 device does not support attestation feature */
710 if (setting->attn_set.attestation_mode !=
711 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED)
712 return -EINVAL;
713
714 ret = get_configs(dev, &reply, &otp_valid);
715 if (ret)
716 return ret;
717
718 memset(&sd, 0, sizeof(sd));
719
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;
728
729 spi_clk = convert_spi_clk_rate(setting->spi_clk_rate,
730 reply.spi_core_clk_high);
731 if (spi_clk < 0) {
732 errno = EINVAL;
733 return -1;
734 }
735
736 sd.cfg |= (spi_clk & SWITCHTEC_CLK_RATE_BITMASK) <<
737 SWITCHTEC_CLK_RATE_BITSHIFT;
738
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;
743
744 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
745 &map_mask);
746 sd.cfg |= (setting->i2c_addr & SWITCHTEC_I2C_ADDR_BITMASK) <<
747 addr_shift;
748
749 ldata = setting->i2c_cmd_map & map_mask;
750 ldata <<= map_shift;
751 sd.cfg |= ldata;
752
753 sd.cfg = htole64(sd.cfg);
754
755 sd.pub_key_exponent = htole32(setting->public_key_exponent);
756
757 return switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_SET,
758 &sd, sizeof(sd), NULL, 0);
759}
760
761static int security_config_set_gen5(struct switchtec_dev *dev,
762 struct switchtec_security_cfg_set *setting)
763{
764 int ret;
765 struct setting_data {
766 uint64_t cfg;
767 uint32_t pub_key_exponent;
768 uint8_t uds_valid;
769 uint8_t rsvd[3];
770 uint32_t cdi_efuse_inc_mask;
771 uint8_t uds[32];
772 } sd;
773 struct get_cfgs_reply_gen5 reply;
774 uint64_t ldata = 0;
775 uint32_t addr_shift;
776 uint32_t map_shift;
777 uint32_t map_mask;
778 int spi_clk;
779 uint8_t cmd_buf[64]={};
780
781 ret = get_configs_gen5(dev, &reply);
782 if (ret)
783 return ret;
784
785 memset(&sd, 0, sizeof(sd));
786
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;
795
796 spi_clk = convert_spi_clk_rate(setting->spi_clk_rate,
797 reply.spi_core_clk_high);
798 if (spi_clk < 0) {
799 errno = EINVAL;
800 return -1;
801 }
802
803 sd.cfg |= (spi_clk & SWITCHTEC_CLK_RATE_BITMASK) <<
804 SWITCHTEC_CLK_RATE_BITSHIFT;
805
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;
810
811 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
812 &map_mask);
813 sd.cfg |= (setting->i2c_addr & SWITCHTEC_I2C_ADDR_BITMASK) <<
814 addr_shift;
815
816 ldata = setting->i2c_cmd_map & map_mask;
817 ldata <<= map_shift;
818 sd.cfg |= ldata;
819
820 sd.cfg = htole64(sd.cfg);
821
822 sd.pub_key_exponent = htole32(setting->public_key_exponent);
823
824 if (setting->attn_set.attestation_mode ==
825 SWITCHTEC_ATTESTATION_MODE_DICE) {
826 sd.cfg |= 0x10;
827 sd.cdi_efuse_inc_mask = setting->attn_set.cdi_efuse_inc_mask;
828
829 ldata = setting->attn_set.uds_selfgen? 1 : 0;
830 ldata <<= 44;
831 sd.cfg |= ldata;
832
833 sd.uds_valid = setting->attn_set.uds_valid;
834 if (sd.uds_valid)
835 memcpy(sd.uds, setting->attn_set.uds_data, 32);
836 }
837
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);
841}
842
849int switchtec_security_config_set(struct switchtec_dev *dev,
850 struct switchtec_security_cfg_set *setting)
851{
852 if (switchtec_is_gen5(dev))
853 return security_config_set_gen5(dev, setting);
854 else
855 return security_config_set_gen4(dev, setting);
856}
857
858static int active_image_index_get(struct switchtec_dev *dev,
859 struct switchtec_active_index *index)
860{
861 int ret;
862 struct active_indices {
863 uint8_t index[SWITCHTEC_ACTV_IDX_MAX_ENTRIES];
864 } reply;
865
866 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_GET, NULL,
867 0, &reply, sizeof(reply));
868 if (ret)
869 return ret;
870
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;
876
877 return 0;
878}
879
880static int active_image_index_get_gen5(struct switchtec_dev *dev,
881 struct switchtec_active_index *index)
882{
883 int ret;
884 uint32_t subcmd = 0;
885 struct active_indices {
886 uint8_t index[SWITCHTEC_ACTV_IDX_MAX_ENTRIES];
887 } reply;
888
889 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_GET_GEN5, &subcmd,
890 sizeof(subcmd), &reply, sizeof(reply));
891 if (ret)
892 return ret;
893
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];
899
900 return 0;
901}
902
909int switchtec_active_image_index_get(struct switchtec_dev *dev,
910 struct switchtec_active_index *index)
911{
912 if (switchtec_is_gen5(dev))
913 return active_image_index_get_gen5(dev, index);
914 else
915 return active_image_index_get(dev, index);
916}
917
918static int active_image_index_set(struct switchtec_dev *dev,
919 struct switchtec_active_index *index)
920{
921 int ret;
922 int i = 0;
923 struct active_idx {
924 uint32_t count;
925 struct entry {
926 uint8_t image_id;
927 uint8_t index;
928 } idx[SWITCHTEC_ACTV_IDX_SET_ENTRIES];
929 } set;
930
931 /* RIOT image is not available on Gen4 device */
932 if (index->riot != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
933 errno = EINVAL;
934 return -EINVAL;
935 }
936
937 memset(&set, 0, sizeof(set));
938
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;
942 i++;
943 }
944
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;
948 i++;
949 }
950
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;
954 i++;
955 }
956
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;
960 i++;
961 }
962
963 if (i == 0)
964 return 0;
965
966 set.count = htole32(i);
967
968 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_SET, &set,
969 sizeof(set), NULL, 0);
970 return ret;
971}
972
973static int active_image_index_set_gen5(struct switchtec_dev *dev,
974 struct switchtec_active_index *index)
975{
976 int ret;
977 int i = 0;
978 struct active_idx {
979 uint32_t subcmd;
980 uint32_t count;
981 struct entry {
982 uint8_t image_id;
983 uint8_t index;
984 } idx[SWITCHTEC_ACTV_IDX_SET_ENTRIES];
985 } set = {};
986
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;
990 i++;
991 }
992
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;
996 i++;
997 }
998
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;
1002 i++;
1003 }
1004
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;
1008 i++;
1009 }
1010
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;
1014 i++;
1015 }
1016
1017 if (i == 0)
1018 return 0;
1019
1020 set.count = htole32(i);
1021
1022 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_SET_GEN5, &set,
1023 sizeof(set), NULL, 0);
1024 return ret;
1025}
1026
1033int switchtec_active_image_index_set(struct switchtec_dev *dev,
1034 struct switchtec_active_index *index)
1035{
1036 if (switchtec_is_gen5(dev))
1037 return active_image_index_set_gen5(dev, index);
1038 else
1039 return active_image_index_set(dev, index);
1040}
1041
1048int switchtec_fw_exec(struct switchtec_dev *dev,
1049 enum switchtec_bl2_recovery_mode recovery_mode)
1050{
1051 uint32_t cmd_id = MRPC_FW_TX;
1052 struct fw_exec_struct {
1053 uint8_t subcmd;
1054 uint8_t recovery_mode;
1055 uint8_t rsvd[2];
1056 } cmd;
1057
1058 memset(&cmd, 0, sizeof(cmd));
1059 cmd.subcmd = MRPC_FW_TX_EXEC;
1060 cmd.recovery_mode = recovery_mode;
1061
1062 if (switchtec_is_gen6(dev))
1063 cmd_id = MRPC_FW_TX_GEN6;
1064 if (switchtec_is_gen5(dev))
1065 cmd_id = MRPC_FW_TX_GEN5;
1066
1067 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
1068}
1069
1082int switchtec_boot_resume(struct switchtec_dev *dev)
1083{
1084 uint32_t subcmd = 0;
1085
1086 if (switchtec_is_gen5(dev))
1087 return switchtec_mfg_cmd(dev, MRPC_BOOTUP_RESUME_GEN5,
1088 &subcmd, sizeof(subcmd),
1089 NULL, 0);
1090 else
1091 return switchtec_mfg_cmd(dev, MRPC_BOOTUP_RESUME,
1092 NULL, 0, NULL, 0);
1093}
1094
1095static int secure_state_set(struct switchtec_dev *dev,
1096 enum switchtec_secure_state state)
1097{
1098 uint32_t data;
1099
1100 data = htole32(state);
1101
1102 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET,
1103 &data, sizeof(data), NULL, 0);
1104}
1105
1106static int secure_state_set_gen5(struct switchtec_dev *dev,
1107 enum switchtec_secure_state state)
1108{
1109 struct state_set {
1110 uint32_t subcmd;
1111 uint32_t state;
1112 } data;
1113
1114 data.subcmd = 0;
1115 data.state = htole32(state);
1116
1117 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET_GEN5,
1118 &data, sizeof(data), NULL, 0);
1119}
1120
1121#define GEN6_STATE_SET_SUBCMD_DEBUG_PROTECT 0x0
1122#define GEN6_STATE_SET_SUBCMD_STATE_TRANS 0x1
1123
1124int switchtec_secure_state_set_debug_protect(struct switchtec_dev *dev)
1125{
1126 uint32_t data;
1127
1128 if (!switchtec_is_gen6(dev))
1129 return ERR_SUBCMD_INVALID;
1130
1131 data = htole32(GEN6_STATE_SET_SUBCMD_DEBUG_PROTECT);
1132
1133 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET_GEN6,
1134 &data, sizeof(data), NULL, 0);
1135}
1136
1137int switchtec_secure_state_set_transition(struct switchtec_dev *dev,
1138 enum switchtec_secure_state state)
1139{
1140 uint32_t data;
1141
1142 if (!switchtec_is_gen6(dev))
1143 return ERR_SUBCMD_INVALID;
1144
1145 if ((state != SWITCHTEC_INITIALIZED_UNSECURED)
1146 && (state != SWITCHTEC_INITIALIZED_SECURED)) {
1147 return ERR_PARAM_INVALID;
1148 }
1149
1150 data = htole32(GEN6_STATE_SET_SUBCMD_STATE_TRANS | (state << 8));
1151
1152 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET_GEN6,
1153 &data, sizeof(data), NULL, 0);
1154}
1155
1162int switchtec_secure_state_set(struct switchtec_dev *dev,
1163 enum switchtec_secure_state state)
1164{
1165 if ((state != SWITCHTEC_INITIALIZED_UNSECURED)
1166 && (state != SWITCHTEC_INITIALIZED_SECURED)) {
1167 return ERR_PARAM_INVALID;
1168 }
1169
1170 if (switchtec_is_gen6(dev))
1171 return switchtec_secure_state_set_transition(dev, state);
1172 else if (switchtec_is_gen5(dev))
1173 return secure_state_set_gen5(dev, state);
1174 else
1175 return secure_state_set(dev, state);
1176}
1177
1178static int dbg_unlock_send_pubkey(struct switchtec_dev *dev,
1179 struct switchtec_pubkey *public_key,
1180 uint32_t cmd_id)
1181{
1182 struct public_key_cmd {
1183 uint8_t subcmd;
1184 uint8_t rsvd[3];
1185 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1186 uint32_t pub_key_exp;
1187 } cmd = {};
1188
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);
1192
1193 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
1194}
1195
1196static int dbg_unlock_send_pubkey_gen6(struct switchtec_dev *dev,
1197 struct switchtec_pubkey *public_key,
1198 uint32_t cmd_id)
1199{
1200 struct public_key_cmd_gen6 {
1201 uint8_t subcmd;
1202 uint8_t reserved[3];
1203 uint32_t total_len;
1204 uint32_t total_crc;
1205 uint32_t data_len;
1206 uint32_t offset;
1207 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1208 } cmd = {};
1209
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);
1216
1217 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
1218}
1219
1220static int dbg_unlock_send_sig_gen6(struct switchtec_dev *dev,
1221 struct switchtec_signature *signature,
1222 uint32_t cmd_id)
1223{
1224 struct sig_cmd_gen6 {
1225 uint8_t subcmd;
1226 uint8_t sig_type;
1227 uint8_t reserved[2];
1228 uint32_t total_len;
1229 uint32_t total_crc;
1230 uint32_t data_len;
1231 uint32_t offset;
1232 uint8_t signature[SWITCHTEC_SIG_LEN];
1233 } cmd = {};
1234
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);
1242
1243 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
1244}
1245
1255int switchtec_dbg_unlock(struct switchtec_dev *dev, uint32_t serial,
1256 uint32_t ver_sec_unlock,
1257 struct switchtec_pubkey *public_key,
1258 struct switchtec_signature *signature,
1259 struct switchtec_gen6_token *token)
1260{
1261 int ret;
1262
1263 if (switchtec_is_gen6(dev))
1264 {
1265 struct unlock_cmd_gen6 {
1266 uint8_t subcmd;
1267 uint8_t rsvd[3];
1268 uint8_t token[SWITCHTEC_GEN6_TOKEN_LEN];
1269 } cmd = {};
1270
1271 uint32_t cmd_id;
1272 cmd_id = MRPC_DBG_UNLOCK_GEN6;
1273
1274 ret = dbg_unlock_send_pubkey_gen6(dev, public_key, cmd_id);
1275 if (ret)
1276 return ret;
1277
1278 ret = dbg_unlock_send_sig_gen6(dev, signature, cmd_id);
1279 if (ret)
1280 return ret;
1281
1282 cmd.subcmd = MRPC_GEN6_DBG_UNLOCK_STATIC;
1283 memcpy(cmd.token, token->token, SWITCHTEC_GEN6_TOKEN_LEN);
1284
1285 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
1286 }
1287
1288 struct unlock_cmd {
1289 uint8_t subcmd;
1290 uint8_t rsvd[3];
1291 uint32_t serial;
1292 uint32_t unlock_ver;
1293 uint8_t signature[SWITCHTEC_SIG_LEN];
1294 } cmd = {};
1295 uint32_t cmd_id;
1296
1297 cmd_id = get_dbg_unlock_id(dev);
1298
1299 ret = dbg_unlock_send_pubkey(dev, public_key, cmd_id);
1300 if (ret)
1301 return ret;
1302
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);
1307
1308 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
1309}
1310
1319int switchtec_dbg_unlock_get_token_gen6(struct switchtec_dev *dev,
1320 struct switchtec_gen6_token *token,
1321 int token_type)
1322{
1323 int ret;
1324
1325 struct get_unlock_token_cmd_gen6 {
1326 uint8_t subcmd;
1327 uint8_t token_type;
1328 uint8_t rsvd[2];
1329 } cmd = {};
1330
1331 uint32_t cmd_id;
1332 cmd_id = MRPC_DBG_UNLOCK_GEN6;
1333
1334 struct get_unlock_token_reply_gen6 {
1335 uint8_t token[SWITCHTEC_GEN6_TOKEN_LEN];
1336 } reply;
1337
1338 cmd.subcmd = MRPC_GEN6_DBG_UNLOCK_TOKEN_GET;
1339
1340 if(token_type == GEN6_TOKEN_STATIC)
1341 cmd.token_type = SECURE_TOKEN_GET_TYPE_STATIC;
1342 else
1343 cmd.token_type = SECURE_TOKEN_GET_TYPE_EPHEMERAL;
1344
1345 ret = switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), &reply,
1346 sizeof(reply));
1347 if (ret)
1348 return ret;
1349
1350 memcpy(&token->token, &reply, SWITCHTEC_GEN6_TOKEN_LEN);
1351 return 0;
1352}
1353
1354int switchtec_dbg_unlock_status_get_gen6(struct switchtec_dev *dev,
1355 uint32_t *jtag_status)
1356{
1357 int ret;
1358 struct {
1359 uint8_t subcmd;
1360 uint8_t rsvd[3];
1361 } cmd = {};
1362 struct {
1363 uint32_t jtag_status;
1364 } reply;
1365
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));
1369 if (ret)
1370 return ret;
1371
1372 *jtag_status = le32toh(reply.jtag_status);
1373 return 0;
1374}
1375
1376#define GEN6_STATE_SET_SUBCMD_STATE_GET 0x2
1377
1378int switchtec_secure_state_get_gen6(struct switchtec_dev *dev,
1379 enum switchtec_secure_state_gen6 *state)
1380{
1381 uint32_t data;
1382 uint32_t reply;
1383 int ret;
1384
1385 if (!switchtec_is_gen6(dev))
1386 return -ENOTSUP;
1387
1388 if (!state)
1389 return -EINVAL;
1390
1391 data = htole32(GEN6_STATE_SET_SUBCMD_STATE_GET);
1392
1393 ret = switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET_GEN6,
1394 &data, sizeof(data), &reply, sizeof(reply));
1395 if (ret)
1396 return ret;
1397
1398 *state = (enum switchtec_secure_state_gen6)(le32toh(reply) & 0xFF);
1399 return 0;
1400}
1401
1411int switchtec_dbg_unlock_version_update(struct switchtec_dev *dev,
1412 uint32_t serial,
1413 uint32_t ver_sec_unlock,
1414 struct switchtec_pubkey *public_key,
1415 struct switchtec_signature *signature)
1416{
1417 int ret;
1418 struct update_cmd {
1419 uint8_t subcmd;
1420 uint8_t rsvd[3];
1421 uint32_t serial;
1422 uint32_t unlock_ver;
1423 uint8_t signature[SWITCHTEC_SIG_LEN];
1424 } cmd = {};
1425 uint32_t cmd_id;
1426
1427 cmd_id = get_dbg_unlock_id(dev);
1428
1429 ret = dbg_unlock_send_pubkey(dev, public_key, cmd_id);
1430 if (ret)
1431 return ret;
1432
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);
1437
1438 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
1439}
1440
1441static int check_sec_cfg_header(struct switchtec_dev *dev,
1442 FILE *setting_file)
1443{
1444 ssize_t rlen;
1445 enum switchtec_gen gen;
1446 char magic[4] = {'S', 'S', 'F', 'F'};
1447 uint32_t crc;
1448 struct setting_file_header {
1449 uint8_t magic[4];
1450 uint32_t version;
1451 uint8_t hw_gen;
1452 uint8_t rsvd[3];
1453 uint32_t crc;
1454 } hdr;
1455 int data_len;
1456 uint8_t data[64];
1457
1458 rlen = fread(&hdr, sizeof(hdr), 1, setting_file);
1459
1460 if (rlen != 1)
1461 return -EBADF;
1462
1463 if (memcmp(hdr.magic, magic, sizeof(magic)))
1464 return -EBADF;
1465
1466 switch (hdr.hw_gen) {
1467 case 0:
1468 gen = SWITCHTEC_GEN4;
1469 break;
1470 case 1:
1471 gen = SWITCHTEC_GEN5;
1472 break;
1473 default:
1474 return -EBADF;
1475 }
1476
1477 if (gen != switchtec_gen(dev))
1478 return -ENODEV;
1479
1480 fseek(setting_file, 0, SEEK_END);
1481 data_len = ftell(setting_file) - sizeof(hdr);
1482 fseek(setting_file, sizeof(hdr), SEEK_SET);
1483
1484 rlen = fread(data, 1, data_len, setting_file);
1485 if (rlen < data_len)
1486 return -EBADF;
1487
1488 crc = crc32(data, data_len, 0, 1, 1);
1489 if (crc != le32toh(hdr.crc))
1490 return -EBADF;
1491
1492 fseek(setting_file, sizeof(hdr), SEEK_SET);
1493 return 0;
1494}
1495
1496static int read_sec_cfg_file(struct switchtec_dev *dev,
1497 FILE *setting_file,
1498 struct switchtec_security_cfg_set *set)
1499{
1500 struct setting_file_data {
1501 uint64_t cfg;
1502 uint32_t pub_key_exponent;
1503 uint8_t rsvd[36];
1504 } data;
1505 struct get_cfgs_reply reply;
1506 uint32_t addr_shift;
1507 uint32_t map_shift;
1508 uint32_t map_mask;
1509 int spi_clk;
1510 int ret;
1511 int otp_valid;
1512
1513 ret = get_configs(dev, &reply, &otp_valid);
1514 if (ret)
1515 return ret;
1516
1517 memset(set, 0, sizeof(struct switchtec_security_cfg_set));
1518
1519 ret = fread(&data, sizeof(data), 1, setting_file);
1520
1521 if (ret != 1)
1522 return -EBADF;
1523
1524 data.cfg = le64toh(data.cfg);
1525
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);
1534
1535 spi_clk = (data.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) &
1536 SWITCHTEC_CLK_RATE_BITMASK;
1537
1538 if (spi_clk == 0)
1539 spi_clk = 7;
1540
1541 if (spi_clk > 10)
1542 return -EINVAL;
1543
1544 if (reply.spi_core_clk_high)
1545 set->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
1546 else
1547 set->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
1548
1549 set->i2c_recovery_tmo =
1550 (data.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) &
1551 SWITCHTEC_RC_TMO_BITMASK;
1552 set->i2c_port =
1553 (data.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) &
1554 SWITCHTEC_I2C_PORT_BITMASK;
1555
1556 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
1557 &map_mask);
1558 set->i2c_addr =
1559 (data.cfg >> addr_shift) &
1560 SWITCHTEC_I2C_ADDR_BITMASK;
1561 set->i2c_cmd_map = (data.cfg >> map_shift) & map_mask;
1562
1563 set->public_key_exponent = le32toh(data.pub_key_exponent);
1564
1565 set->attn_set.attestation_mode =
1566 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED;
1567
1568 return 0;
1569}
1570
1571static int read_sec_cfg_file_gen5(struct switchtec_dev *dev,
1572 FILE *setting_file,
1573 struct switchtec_security_cfg_set *set)
1574{
1575 struct setting_data {
1576 uint64_t cfg;
1577 uint32_t pub_key_exponent;
1578 uint8_t rsvd[4];
1579 uint32_t cdi_efuse_inc_mask;
1580 } data;
1581 struct get_cfgs_reply_gen5 reply;
1582 uint32_t addr_shift;
1583 uint32_t map_shift;
1584 uint32_t map_mask;
1585 int spi_clk;
1586 int ret;
1587 int attest_mode;
1588
1589 ret = get_configs_gen5(dev, &reply);
1590 if (ret)
1591 return ret;
1592
1593 memset(set, 0, sizeof(struct switchtec_security_cfg_set));
1594
1595 ret = fread(&data, sizeof(data), 1, setting_file);
1596
1597 if (ret != 1)
1598 return -EBADF;
1599
1600 data.cfg = le64toh(data.cfg);
1601
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);
1610
1611 spi_clk = (data.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) &
1612 SWITCHTEC_CLK_RATE_BITMASK;
1613
1614 if (spi_clk == 0)
1615 spi_clk = 9;
1616
1617 if (spi_clk > 10)
1618 return -EINVAL;
1619
1620 if (reply.spi_core_clk_high)
1621 set->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
1622 else
1623 set->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
1624
1625 set->i2c_recovery_tmo =
1626 (data.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) &
1627 SWITCHTEC_RC_TMO_BITMASK;
1628 set->i2c_port =
1629 (data.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) &
1630 SWITCHTEC_I2C_PORT_BITMASK;
1631
1632 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
1633 &map_mask);
1634 set->i2c_addr =
1635 (data.cfg >> addr_shift) &
1636 SWITCHTEC_I2C_ADDR_BITMASK;
1637 set->i2c_cmd_map = (data.cfg >> map_shift) & map_mask;
1638
1639 set->public_key_exponent = le32toh(data.pub_key_exponent);
1640
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;
1648 } else {
1649 set->attn_set.attestation_mode =
1650 SWITCHTEC_ATTESTATION_MODE_NONE;
1651 }
1652
1653 return 0;
1654}
1655
1663int switchtec_read_sec_cfg_file(struct switchtec_dev *dev,
1664 FILE *setting_file,
1665 struct switchtec_security_cfg_set *set)
1666{
1667 int ret;
1668
1669 ret = check_sec_cfg_header(dev, setting_file);
1670 if (ret)
1671 return ret;
1672
1673 if (switchtec_is_gen4(dev))
1674 return read_sec_cfg_file(dev, setting_file, set);
1675 else
1676 return read_sec_cfg_file_gen5(dev, setting_file, set);
1677}
1678
1679static int kmsk_set_send_pubkey(struct switchtec_dev *dev,
1680 struct switchtec_pubkey *public_key,
1681 uint32_t cmd_id)
1682{
1683 struct kmsk_pubk_cmd {
1684 uint8_t subcmd;
1685 uint8_t reserved[3];
1686 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1687 uint32_t pub_key_exponent;
1688 } cmd = {};
1689
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);
1694
1695 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
1696 sizeof(cmd), NULL, 0);
1697}
1698
1699static int kmsk_set_send_signature(struct switchtec_dev *dev,
1700 struct switchtec_signature *signature,
1701 uint32_t cmd_id)
1702{
1703 struct kmsk_signature_cmd {
1704 uint8_t subcmd;
1705 uint8_t reserved[3];
1706 uint8_t signature[SWITCHTEC_SIG_LEN];
1707 } cmd = {};
1708
1709 cmd.subcmd = MRPC_KMSK_ENTRY_SET_SIG;
1710 memcpy(cmd.signature, signature->signature,
1711 SWITCHTEC_SIG_LEN);
1712
1713 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
1714 sizeof(cmd), NULL, 0);
1715}
1716
1717static int kmsk_set_send_kmsk(struct switchtec_dev *dev,
1718 struct switchtec_kmsk *kmsk,
1719 uint32_t cmd_id)
1720{
1721 struct kmsk_kmsk_cmd {
1722 uint8_t subcmd;
1723 uint8_t num_entries;
1724 uint8_t reserved[2];
1725 uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1726 } cmd = {};
1727
1728 cmd.subcmd = MRPC_KMSK_ENTRY_SET_KMSK;
1729 cmd.num_entries = 1;
1730 memcpy(cmd.kmsk, kmsk->kmsk, SWITCHTEC_KMSK_LEN);
1731
1732 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd),
1733 NULL, 0);
1734}
1735
1748int switchtec_kmsk_set(struct switchtec_dev *dev,
1749 struct switchtec_pubkey *public_key,
1750 struct switchtec_signature *signature,
1751 struct switchtec_kmsk *kmsk)
1752{
1753 int ret;
1754 uint32_t cmd_id;
1755
1756 if (switchtec_is_gen5(dev))
1757 cmd_id = MRPC_KMSK_ENTRY_SET_GEN5;
1758 else
1759 cmd_id = MRPC_KMSK_ENTRY_SET;
1760
1761 if (public_key) {
1762 ret = kmsk_set_send_pubkey(dev, public_key, cmd_id);
1763 if (ret)
1764 return ret;
1765 }
1766
1767 if (signature) {
1768 ret = kmsk_set_send_signature(dev, signature, cmd_id);
1769 if (ret)
1770 return ret;
1771 }
1772
1773 return kmsk_set_send_kmsk(dev, kmsk, cmd_id);
1774}
1775
1776#if HAVE_LIBCRYPTO
1777
1778#ifdef HAVE_DECL_PEM_READ_PUBKEY
1779
1780#include <openssl/core_names.h>
1781
1788int switchtec_read_pubk_file(FILE *pubk_file, struct switchtec_pubkey *pubk)
1789{
1790 BIGNUM *bn_priv = NULL;
1791 uint32_t exponent_tmp;
1792 EVP_PKEY *pkey;
1793
1794 pkey = PEM_read_PUBKEY(pubk_file, NULL, NULL, NULL);
1795 if (!pkey) {
1796 fseek(pubk_file, 0L, SEEK_SET);
1797 pkey = PEM_read_PrivateKey(pubk_file, NULL, NULL, NULL);
1798 if (!pkey)
1799 return -1;
1800 }
1801
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);
1807
1808 EVP_PKEY_free(pkey);
1809 return 0;
1810}
1811
1812#else /* ! HAVE_DECL_PEM_READ_PUBKEY */
1813
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)
1821{
1822 if (n)
1823 *n = r->n;
1824 if (e)
1825 *e = r->e;
1826 if (d)
1827 *d = r->d;
1828}
1829#endif
1830
1837int switchtec_read_pubk_file(FILE *pubk_file, struct switchtec_pubkey *pubk)
1838{
1839 RSA *RSAKey = NULL;
1840 const BIGNUM *modulus_bn;
1841 const BIGNUM *exponent_bn;
1842 uint32_t exponent_tmp = 0;
1843
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);
1848 if (RSAKey == NULL)
1849 return -1;
1850 }
1851
1852 RSA_get0_key(RSAKey, &modulus_bn, &exponent_bn, NULL);
1853
1854 BN_bn2bin(modulus_bn, pubk->pubkey);
1855 BN_bn2bin(exponent_bn, (uint8_t *)&exponent_tmp);
1856
1857 pubk->pubkey_exp = be32toh(exponent_tmp);
1858 RSA_free(RSAKey);
1859
1860 return 0;
1861}
1862
1863#endif /* HAVE_DECL_PEM_READ_PUBKEY */
1864
1865#endif
1866
1873int switchtec_read_kmsk_file(FILE *kmsk_file, struct switchtec_kmsk *kmsk)
1874{
1875 ssize_t rlen;
1876 struct kmsk_struct {
1877 uint8_t magic[4];
1878 uint32_t version;
1879 uint32_t reserved;
1880 uint32_t crc32;
1881 uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1882 } data;
1883
1884 char magic[4] = {'K', 'M', 'S', 'K'};
1885 uint32_t crc;
1886
1887 rlen = fread(&data, 1, sizeof(data), kmsk_file);
1888
1889 if (rlen < sizeof(data))
1890 return -EBADF;
1891
1892 if (memcmp(data.magic, magic, sizeof(magic)))
1893 return -EBADF;
1894
1895 crc = crc32(data.kmsk, SWITCHTEC_KMSK_LEN, 0, 1, 1);
1896 if (crc != le32toh(data.crc32))
1897 return -EBADF;
1898
1899 memcpy(kmsk->kmsk, data.kmsk, SWITCHTEC_KMSK_LEN);
1900
1901 return 0;
1902}
1903
1910int switchtec_read_signature_file(FILE *sig_file,
1911 struct switchtec_signature *signature)
1912{
1913 ssize_t rlen;
1914
1915 rlen = fread(signature->signature, 1, SWITCHTEC_SIG_LEN, sig_file);
1916
1917 if (rlen < SWITCHTEC_SIG_LEN)
1918 return -EBADF;
1919
1920 return 0;
1921}
1922
1929int switchtec_read_token_file(FILE *tkn_file, struct switchtec_gen6_token *token)
1930{
1931 ssize_t rlen;
1932
1933 rlen = fread(token->token, 1, SWITCHTEC_GEN6_TOKEN_LEN, tkn_file);
1934 if (rlen < SWITCHTEC_GEN6_TOKEN_LEN)
1935 return -EBADF;
1936
1937 return 0;
1938}
1939
1946int switchtec_read_uds_file(FILE *uds_file, struct switchtec_uds *uds)
1947{
1948 ssize_t rlen;
1949
1950 rlen = fread(uds->uds, 1, SWITCHTEC_UDS_LEN, uds_file);
1951
1952 if (rlen < SWITCHTEC_UDS_LEN)
1953 return -EBADF;
1954
1955 return 0;
1956}
1957
1968int
1969switchtec_security_state_has_kmsk(struct switchtec_security_cfg_state *state,
1970 struct switchtec_kmsk *kmsk)
1971{
1972 int key_idx;
1973
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)
1977 return 1;
1978 }
1979
1980 return 0;
1981}
1982
1983#endif /* __linux__ */
1984
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)
1988{
1989 if (dev->ops->flags & SWITCHTEC_OPS_FLAG_NO_MFG) {
1990 errno = ERR_UART_NOT_SUPPORTED | SWITCHTEC_ERRNO_MRPC_FLAG_BIT;
1991 return -1;
1992 }
1993
1994 return switchtec_cmd(dev, cmd, payload, payload_len,
1995 resp, resp_len);
1996}
1997
1998static int sn_ver_get_gen4(struct switchtec_dev *dev,
1999 struct switchtec_sn_ver_info *info)
2000{
2001 int ret;
2002 struct reply_t {
2003 uint32_t chip_serial;
2004 uint32_t ver_km;
2005 uint32_t ver_bl2;
2006 uint32_t ver_main;
2007 uint32_t ver_sec_unlock;
2008 } reply;
2009
2010 ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET, NULL, 0,
2011 &reply, sizeof(reply));
2012 if (ret)
2013 return ret;
2014
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;
2021
2022 return 0;
2023}
2024
2025static int sn_ver_get_gen5(struct switchtec_dev *dev,
2026 struct switchtec_sn_ver_info *info)
2027{
2028 int ret;
2029 uint32_t subcmd = 0;
2030 struct reply_t {
2031 uint32_t chip_serial;
2032 uint32_t ver_km;
2033 uint16_t ver_riot;
2034 uint16_t ver_bl2;
2035 uint32_t ver_main;
2036 uint32_t ver_sec_unlock;
2037 } reply;
2038
2039 ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET_GEN5, &subcmd, 4,
2040 &reply, sizeof(reply));
2041 if (ret)
2042 return ret;
2043
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;
2051
2052 return 0;
2053}
2054
2055static int sn_ver_get_gen6(struct switchtec_dev *dev,
2056 struct switchtec_sn_ver_info *info)
2057{
2058 int ret;
2059 uint32_t subcmd = 0;
2060 struct reply_t {
2061 uint32_t UID[16];
2062 uint32_t PSID0[4];
2063 uint32_t PSID_UID_valid_flags;
2064 uint32_t SVNSV_rsvrd;
2065 uint32_t bl2_sec_ver;
2066 uint32_t rsvrd;
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;
2072 } reply;
2073
2074 ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET_GEN6, &subcmd, 4,
2075 &reply, sizeof(reply));
2076 if (ret)
2077 return ret;
2078
2079 info->UID = malloc(sizeof(reply.UID));
2080 if (!info->UID)
2081 return -1;
2082 info->PSID0 = malloc(sizeof(reply.PSID0));
2083 if (!info->PSID0) {
2084 free(info->UID);
2085 info->UID = NULL;
2086 return -1;
2087 }
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;
2095
2096 return 0;
2097}
2098
2105int switchtec_sn_ver_get(struct switchtec_dev *dev,
2106 struct switchtec_sn_ver_info *info)
2107{
2108 if (switchtec_is_gen6(dev))
2109 return sn_ver_get_gen6(dev, info);
2110 else if (switchtec_is_gen5(dev))
2111 return sn_ver_get_gen5(dev, info);
2112 else
2113 return sn_ver_get_gen4(dev, info);
2114}
2115
2116int switchtec_device_config_get(struct switchtec_dev *dev,
2117 struct switchtec_device_config_dev_settings *settings)
2118{
2119 int ret;
2120 uint32_t subcmd = DEVICE_CONFIG_SUB_CMD_GET;
2121
2122 if (!switchtec_is_gen6(dev)) {
2123 errno = ENOTSUP;
2124 return -ENOTSUP;
2125 }
2126
2127 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &subcmd, sizeof(subcmd),
2128 settings, sizeof(*settings));
2129 return ret;
2130}
2131
2132int switchtec_device_config_get_security(struct switchtec_dev *dev,
2133 struct switchtec_device_config_get_sec *config)
2134{
2135 int ret;
2136 uint32_t subcmd = DEVICE_CONFIG_SUB_CMD_GET_SECURITY;
2137
2138 if (!switchtec_is_gen6(dev)) {
2139 errno = ENOTSUP;
2140 return -ENOTSUP;
2141 }
2142
2143 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &subcmd, sizeof(subcmd),
2144 config, sizeof(*config));
2145 return ret;
2146}
2147
2148int switchtec_device_config_get_customer(struct switchtec_dev *dev,
2150{
2151 int ret;
2152 uint32_t subcmd = DEVICE_CONFIG_SUB_CMD_GET_CUSTOMER;
2153
2154 if (!switchtec_is_gen6(dev)) {
2155 errno = ENOTSUP;
2156 return -ENOTSUP;
2157 }
2158
2159 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &subcmd, sizeof(subcmd),
2160 settings, sizeof(*settings));
2161 return ret;
2162}
2163
2164int switchtec_device_config_set_dev(struct switchtec_dev *dev,
2165 struct switchtec_device_config_dev_settings *settings)
2166{
2167 int ret;
2168 struct {
2169 uint8_t subcmd;
2170 uint8_t reserved[3];
2172 } cmd;
2173
2174 if (!switchtec_is_gen6(dev)) {
2175 errno = ENOTSUP;
2176 return -ENOTSUP;
2177 }
2178
2179 memset(&cmd, 0, sizeof(cmd));
2180 cmd.subcmd = DEVICE_CONFIG_SUB_CMD_SET_DEVICE;
2181 memcpy(&cmd.settings, settings, sizeof(*settings));
2182
2183 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &cmd, sizeof(cmd),
2184 NULL, 0);
2185 return ret;
2186}
2187
2188int switchtec_device_config_set_customer(struct switchtec_dev *dev,
2190{
2191 int ret;
2192 struct {
2193 uint8_t subcmd;
2194 uint8_t reserved[3];
2195 struct switchtec_device_config_customer_settings settings;
2196 } cmd;
2197
2198 if (!switchtec_is_gen6(dev)) {
2199 errno = ENOTSUP;
2200 return -ENOTSUP;
2201 }
2202
2203 memset(&cmd, 0, sizeof(cmd));
2204 cmd.subcmd = DEVICE_CONFIG_SUB_CMD_SET_CUSTOMER;
2205 memcpy(&cmd.settings, settings, sizeof(*settings));
2206
2207 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &cmd, sizeof(cmd),
2208 NULL, 0);
2209 return ret;
2210}
2211
2212int switchtec_device_config_set_security(struct switchtec_dev *dev,
2214{
2215 int ret;
2216 struct {
2217 uint8_t subcmd;
2218 uint8_t reserved[3];
2219 struct switchtec_device_config_secure_settings settings;
2220 } cmd;
2221
2222 if (!switchtec_is_gen6(dev)) {
2223 errno = ENOTSUP;
2224 return -ENOTSUP;
2225 }
2226
2227 memset(&cmd, 0, sizeof(cmd));
2228 cmd.subcmd = DEVICE_CONFIG_SUB_CMD_SET_SECURITY;
2229 memcpy(&cmd.settings, settings, sizeof(*settings));
2230
2231 ret = switchtec_mfg_cmd(dev, MRPC_DEVICE_CONFIG, &cmd, sizeof(cmd),
2232 NULL, 0);
2233 return ret;
2234}
2235
2236int switchtec_dok_config_signature(struct switchtec_dev *dev,
2237 struct switchtec_dok_signature *sig)
2238{
2239 int ret;
2240
2241 if (!switchtec_is_gen6(dev)) {
2242 errno = ENOTSUP;
2243 return -ENOTSUP;
2244 }
2245
2246 ret = switchtec_mfg_cmd(dev, MRPC_DOK_CONFIG, sig,
2247 20 + sig->data_len, NULL, 0);
2248 return ret;
2249}
2250
2251int switchtec_dok_config_key_add(struct switchtec_dev *dev,
2252 struct switchtec_dok_key_add *key_add)
2253{
2254 int ret;
2255
2256 if (!switchtec_is_gen6(dev)) {
2257 errno = ENOTSUP;
2258 return -ENOTSUP;
2259 }
2260
2261 ret = switchtec_mfg_cmd(dev, MRPC_DOK_CONFIG, key_add, sizeof(*key_add),
2262 NULL, 0);
2263 return ret;
2264}
2265
2266int switchtec_dok_config_key_revoke(struct switchtec_dev *dev,
2267 struct switchtec_dok_key_revoke *key_revoke)
2268{
2269 int ret;
2270
2271 if (!switchtec_is_gen6(dev)) {
2272 errno = ENOTSUP;
2273 return -ENOTSUP;
2274 }
2275
2276 ret = switchtec_mfg_cmd(dev, MRPC_DOK_CONFIG, key_revoke,
2277 sizeof(*key_revoke), NULL, 0);
2278 return ret;
2279}
2280
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:178
int switchtec_sn_ver_get(struct switchtec_dev *dev, struct switchtec_sn_ver_info *info)
Get serial number and security version.
Definition mfg.c:2105
Main Switchtec header.
switchtec_gen
The PCIe generations.
Definition switchtec.h:94
static int switchtec_is_gen6(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 6 device.
Definition switchtec.h:524
static int switchtec_is_gen4(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 4 device.
Definition switchtec.h:508
static int switchtec_is_gen5(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 5 device.
Definition switchtec.h:516