Switchtec Userspace PROJECT_NUMBER = 4.2
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
159static int get_configs(struct switchtec_dev *dev,
160 struct get_cfgs_reply *cfgs,
161 int *otp_valid)
162{
163 uint8_t subcmd = 0;
164 int ret;
165
166 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET_EXT,
167 &subcmd, sizeof(subcmd),
168 cfgs, sizeof(struct get_cfgs_reply));
169 if (ret && ERRNO_MRPC(errno) != ERR_CMD_INVALID)
170 return ret;
171
172 if (!ret) {
173 *otp_valid = true;
174 return ret;
175 }
176
177 *otp_valid = false;
178 ret = switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_GET,
179 NULL, 0, cfgs,
180 sizeof(struct get_cfgs_reply));
181
182 return ret;
183}
184
185static int get_configs_gen5(struct switchtec_dev *dev,
186 struct get_cfgs_reply_gen5 *cfgs)
187{
188 uint32_t subcmd = 0;
189
190 return switchtec_mfg_cmd(dev,
191 MRPC_SECURITY_CONFIG_GET_GEN5,
192 &subcmd, sizeof(subcmd),
193 cfgs, sizeof(struct get_cfgs_reply_gen5));
194}
195
196int switchtec_security_spi_avail_rate_get(struct switchtec_dev *dev,
198{
199 int ret;
200 struct get_cfgs_reply reply;
201 int otp_valid;
202
203 ret = get_configs(dev, &reply, &otp_valid);
204 if (ret)
205 return ret;
206
207 rates->num_rates = 10;
208 if (reply.spi_core_clk_high)
209 memcpy(rates->rates, spi_clk_hi_rate_float,
210 sizeof(spi_clk_hi_rate_float));
211 else
212 memcpy(rates->rates, spi_clk_rate_float,
213 sizeof(spi_clk_rate_float));
214
215 return 0;
216}
217
218static void parse_otp_settings(struct switchtec_security_cfg_otp_region *otp,
219 uint32_t flags)
220{
221 otp->basic_valid = !!(flags & BIT(5));
222 otp->basic = !!(flags & BIT(6));
223 otp->mixed_ver_valid = !!(flags & BIT(7));
224 otp->mixed_ver = !!(flags & BIT(8));
225 otp->main_fw_ver_valid = !!(flags & BIT(9));
226 otp->main_fw_ver = !!(flags & BIT(10));
227 otp->sec_unlock_ver_valid = !!(flags & BIT(11));
228 otp->sec_unlock_ver = !!(flags & BIT(12));
229 otp->kmsk_valid[0] = !!(flags & BIT(13));
230 otp->kmsk[0] = !!(flags & BIT(14));
231 otp->kmsk_valid[1] = !!(flags & BIT(15));
232 otp->kmsk[1] = !!(flags & BIT(16));
233 otp->kmsk_valid[2] = !!(flags & BIT(17));
234 otp->kmsk[2] = !!(flags & BIT(18));
235 otp->kmsk_valid[3] = !!(flags & BIT(19));
236 otp->kmsk[3] = !!(flags & BIT(20));
237}
238
239static void parse_otp_settings_gen5(
241 uint32_t flags0, uint32_t flags1)
242{
243 otp->basic_valid = !!(flags0 & BIT(8));
244 otp->basic = !!(flags0 & BIT(9));
245 otp->debug_mode_valid = !!(flags0 & BIT(10));
246 otp->debug_mode = !!(flags0 & BIT(11));
247 otp->key_ver_valid = !!(flags0 & BIT(12));
248 otp->key_ver = !!(flags0 & BIT(13));
249 otp->rc_ver_valid = !!(flags0 & BIT(14));
250 otp->rc_ver = !!(flags0 & BIT(15));
251 otp->bl2_ver_valid = !!(flags0 & BIT(16));
252 otp->bl2_ver = !!(flags0 & BIT(17));
253 otp->main_fw_ver_valid = !!(flags0 & BIT(18));
254 otp->main_fw_ver = !!(flags0 & BIT(19));
255 otp->sec_unlock_ver_valid = !!(flags0 & BIT(20));
256 otp->sec_unlock_ver = !!(flags0 & BIT(21));
257 otp->kmsk_valid[0] = !!(flags0 & BIT(22));
258 otp->kmsk[0] = !!(flags0 & BIT(23));
259 otp->kmsk_valid[1] = !!(flags0 & BIT(24));
260 otp->kmsk[1] = !!(flags0 & BIT(25));
261 otp->kmsk_valid[2] = !!(flags0 & BIT(26));
262 otp->kmsk[2] = !!(flags0 & BIT(27));
263 otp->kmsk_valid[3] = !!(flags0 & BIT(28));
264 otp->kmsk[3] = !!(flags0 & BIT(29));
265 otp->kmsk_valid[4] = !!(flags0 & BIT(30));
266 otp->kmsk[4] = !!(flags0 & BIT(31));
267 otp->kmsk_valid[5] = !!(flags1 & BIT(0));
268 otp->kmsk[5] = !!(flags1 & BIT(1));
269 otp->kmsk_valid[6] = !!(flags1 & BIT(2));
270 otp->kmsk[6] = !!(flags1 & BIT(3));
271 otp->kmsk_valid[7] = !!(flags1 & BIT(4));
272 otp->kmsk[7] = !!(flags1 & BIT(5));
273 otp->kmsk_valid[8] = !!(flags1 & BIT(6));
274 otp->kmsk[8] = !!(flags1 & BIT(7));
275 otp->kmsk_valid[9] = !!(flags1 & BIT(8));
276 otp->kmsk[9] = !!(flags1 & BIT(9));
277 otp->cdi_efuse_inc_mask_valid = !!(flags1 & BIT(10));
278 otp->cdi_efuse_inc_mask = !!(flags1 & BIT(11));
279 otp->uds_valid = !!(flags1 & BIT(12));
280 otp->uds = !!(flags1 & BIT(13));
281 otp->uds_mask_valid = !!(flags1 & BIT(14));
282 otp->uds_mask = !!(flags1 & BIT(15));
283 otp->mchp_uds_valid = !!(flags1 & BIT(16));
284 otp->mchp_uds = !!(flags1 & BIT(17));
285 otp->mchp_uds_mask_valid = !!(flags1 & BIT(18));
286 otp->mchp_uds_mask = !!(flags1 & BIT(19));
287 otp->did_cert0_valid = !!(flags1 & BIT(20));
288 otp->did_cert0 = !!(flags1 & BIT(21));
289 otp->did_cert1_valid = !!(flags1 & BIT(22));
290 otp->did_cert1 = !!(flags1 & BIT(23));
291}
292
293static int security_config_get(struct switchtec_dev *dev,
294 struct switchtec_security_cfg_state *state)
295{
296 int ret;
297 uint32_t addr_shift;
298 uint32_t map_shift;
299 uint32_t map_mask;
300 int spi_clk;
301 struct get_cfgs_reply reply;
302 int otp_valid;
303
304 ret = get_configs(dev, &reply, &otp_valid);
305 if (ret)
306 return ret;
307
308 reply.valid = le32toh(reply.valid);
309 reply.cfg = le64toh(reply.cfg);
310 reply.public_key_exponent = le32toh(reply.public_key_exponent);
311
312 state->basic_setting_valid = !!(reply.valid & 0x01);
313 state->public_key_exp_valid = !!(reply.valid & 0x02);
314 state->public_key_num_valid = !!(reply.valid & 0x04);
315 state->public_key_ver_valid = !!(reply.valid & 0x08);
316 state->public_key_valid = !!(reply.valid & 0x10);
317
318 state->debug_mode_valid = state->basic_setting_valid;
319
320 state->otp_valid = otp_valid;
321 if (otp_valid)
322 parse_otp_settings(&state->otp, reply.valid);
323
324 state->use_otp_ext = false;
325
326 state->debug_mode = reply.cfg & 0x03;
327 state->secure_state = (reply.cfg>>2) & 0x03;
328
329 state->jtag_lock_after_reset = !!(reply.cfg & 0x40);
330 state->jtag_lock_after_bl1 = !!(reply.cfg & 0x80);
331 state->jtag_bl1_unlock_allowed = !!(reply.cfg & 0x0100);
332 state->jtag_post_bl1_unlock_allowed = !!(reply.cfg & 0x0200);
333
334 spi_clk = (reply.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) & 0x0f;
335 if (spi_clk == 0) {
336 if (switchtec_gen(dev) == SWITCHTEC_GEN5)
337 spi_clk = 9;
338 else
339 spi_clk = 7;
340 }
341
342 if (reply.spi_core_clk_high)
343 state->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
344 else
345 state->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
346
347 state->i2c_recovery_tmo =
348 (reply.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) & 0x0f;
349 state->i2c_port = (reply.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) & 0xf;
350
351 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
352 &map_mask);
353 state->i2c_addr =
354 (reply.cfg >> addr_shift) & SWITCHTEC_I2C_ADDR_BITMASK;
355 state->i2c_cmd_map = (reply.cfg >> map_shift) & map_mask;
356
357 state->public_key_exponent = reply.public_key_exponent;
358 state->public_key_num = reply.public_key_num;
359 state->public_key_ver = reply.public_key_ver;
360
361 if (state->public_key_num)
362 memcpy(state->public_key, reply.public_key,
363 state->public_key_num * SWITCHTEC_KMSK_LEN);
364
365 state->attn_state.attestation_mode =
366 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED;
367
368 return 0;
369}
370
371static int security_config_get_gen5(struct switchtec_dev *dev,
372 struct switchtec_security_cfg_state *state)
373{
374 int ret;
375 uint32_t addr_shift;
376 uint32_t map_shift;
377 uint32_t map_mask;
378 int spi_clk;
379 struct get_cfgs_reply_gen5 reply;
380 int attn_mode;
381
382 ret = get_configs_gen5(dev, &reply);
383 if (ret)
384 return ret;
385
386 reply.valid0 = le32toh(reply.valid0);
387 reply.valid1 = le32toh(reply.valid1);
388
389 reply.cfg = le64toh(reply.cfg);
390 reply.public_key_exponent = le32toh(reply.public_key_exponent);
391
392 state->basic_setting_valid = !!(reply.valid0 & 0x01);
393 state->public_key_exp_valid = !!(reply.valid0 & 0x04);
394 state->public_key_num_valid = !!(reply.valid0 & 0x08);
395 state->public_key_ver_valid = !!(reply.valid0 & 0x10);
396 state->public_key_valid = !!(reply.valid0 & 0x20);
397
398 state->debug_mode_valid = !!(reply.valid0 & 0x02);
399 state->attn_state.cdi_efuse_inc_mask_valid = !!(reply.valid0 & 0x40);
400
401 state->otp_valid = true;
402 parse_otp_settings_gen5(&state->otp_ext, reply.valid0,
403 reply.valid1);
404
405 state->use_otp_ext = true;
406
407 state->debug_mode = reply.cfg & 0x03;
408 state->secure_state = (reply.cfg>>2) & 0x03;
409
410 state->jtag_lock_after_reset = !!(reply.cfg & 0x40);
411 state->jtag_lock_after_bl1 = !!(reply.cfg & 0x80);
412 state->jtag_bl1_unlock_allowed = !!(reply.cfg & 0x0100);
413 state->jtag_post_bl1_unlock_allowed = !!(reply.cfg & 0x0200);
414
415 spi_clk = (reply.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) & 0x0f;
416 if (spi_clk == 0) {
417 if (switchtec_gen(dev) == SWITCHTEC_GEN5)
418 spi_clk = 9;
419 else
420 spi_clk = 7;
421 }
422
423 if (reply.spi_core_clk_high)
424 state->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
425 else
426 state->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
427
428 state->i2c_recovery_tmo =
429 (reply.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) & 0x0f;
430 state->i2c_port = (reply.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) & 0xf;
431
432 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
433 &map_mask);
434 state->i2c_addr =
435 (reply.cfg >> addr_shift) & SWITCHTEC_I2C_ADDR_BITMASK;
436 state->i2c_cmd_map = (reply.cfg >> map_shift) & map_mask;
437
438 state->public_key_exponent = reply.public_key_exponent;
439 state->public_key_num = reply.public_key_num;
440 state->public_key_ver = reply.public_key_ver;
441 memcpy(state->public_key, reply.public_key,
442 state->public_key_num * SWITCHTEC_KMSK_LEN);
443
444 attn_mode = (reply.cfg >> SWITCHTEC_ATTEST_BITSHIFT) &
445 SWITCHTEC_ATTEST_BITMASK;
446 if (attn_mode == 1)
447 state->attn_state.attestation_mode =
448 SWITCHTEC_ATTESTATION_MODE_DICE;
449 else
450 state->attn_state.attestation_mode =
451 SWITCHTEC_ATTESTATION_MODE_NONE;
452
453 state->attn_state.uds_selfgen =
454 (reply.cfg >> SWITCHTEC_UDS_SELFGEN_BITSHIFT) &
455 SWITCHTEC_UDS_SELFGEN_BITMASK;
456 state->attn_state.cdi_efuse_inc_mask =
457 le32toh(reply.cdi_efuse_inc_mask);
458
459 if (state->secure_state == SWITCHTEC_UNINITIALIZED_UNSECURED &&
460 state->attn_state.attestation_mode ==
461 SWITCHTEC_ATTESTATION_MODE_DICE &&
462 !state->attn_state.uds_selfgen)
463 state->attn_state.uds_visible = true;
464 else
465 state->attn_state.uds_visible = false;
466
467 if (state->attn_state.uds_visible)
468 memcpy(state->attn_state.uds_data, reply.uds_data, 32);
469
470 return 0;
471}
472
479int switchtec_security_config_get(struct switchtec_dev *dev,
480 struct switchtec_security_cfg_state *state)
481{
482 if (switchtec_is_gen5(dev))
483 return security_config_get_gen5(dev, state);
484 else
485 return security_config_get(dev, state);
486}
487
488static int mailbox_to_file(struct switchtec_dev *dev, int fd)
489{
490 int ret;
491 int num_to_read = htole32(SWITCHTEC_MB_MAX_ENTRIES);
492 struct mb_reply {
493 uint8_t num_returned;
494 uint8_t num_remaining;
495 uint8_t rsvd[2];
496 uint8_t data[SWITCHTEC_MB_MAX_ENTRIES *
497 SWITCHTEC_MB_LOG_LEN];
498 } reply;
499
500 do {
501 ret = switchtec_mfg_cmd(dev, MRPC_MAILBOX_GET, &num_to_read,
502 sizeof(int), &reply, sizeof(reply));
503 if (ret)
504 return ret;
505
506 reply.num_remaining = le32toh(reply.num_remaining);
507 reply.num_returned = le32toh(reply.num_returned);
508
509 ret = write(fd, reply.data,
510 (reply.num_returned) * SWITCHTEC_MB_LOG_LEN);
511 if (ret < 0)
512 return ret;
513 } while (reply.num_remaining > 0);
514
515 return 0;
516}
517
518static int mailbox_to_file_gen5(struct switchtec_dev *dev, int fd)
519{
520 int ret;
521 struct mb_read {
522 uint32_t subcmd;
523 uint32_t num_to_read;
524 } read;
525 struct mb_reply {
526 uint8_t num_returned;
527 uint8_t num_remaining;
528 uint8_t rsvd[2];
529 uint8_t data[SWITCHTEC_MB_MAX_ENTRIES *
530 SWITCHTEC_MB_LOG_LEN];
531 } reply;
532
533 read.subcmd = 0;
534 read.num_to_read = htole32(SWITCHTEC_MB_MAX_ENTRIES);
535
536 do {
537 ret = switchtec_mfg_cmd(dev, MRPC_MAILBOX_GET_GEN5,
538 &read, sizeof(read),
539 &reply, sizeof(reply));
540 if (ret)
541 return ret;
542
543 reply.num_remaining = le32toh(reply.num_remaining);
544 reply.num_returned = le32toh(reply.num_returned);
545
546 ret = write(fd, reply.data,
547 (reply.num_returned) * SWITCHTEC_MB_LOG_LEN);
548 if (ret < 0)
549 return ret;
550 } while (reply.num_remaining > 0);
551
552 return 0;
553}
554
561int switchtec_mailbox_to_file(struct switchtec_dev *dev, int fd)
562{
563 if (switchtec_is_gen5(dev))
564 return mailbox_to_file_gen5(dev, fd);
565 else
566 return mailbox_to_file(dev, fd);
567}
568
569static int convert_spi_clk_rate(float clk_float, int hi_rate)
570{
571 int i;
572 float *p;
573
574 if (hi_rate)
575 p = spi_clk_hi_rate_float;
576 else
577 p = spi_clk_rate_float;
578
579 for (i = 0; i < 10; i++)
580 if ((clk_float < p[i] + 0.1) && (clk_float > p[i] - 0.1))
581 return i + 1;
582
583 return -1;
584}
585
586static int security_config_set_gen4(struct switchtec_dev *dev,
587 struct switchtec_security_cfg_set *setting)
588{
589 int ret;
590 struct setting_data {
591 uint64_t cfg;
592 uint32_t pub_key_exponent;
593 uint8_t rsvd[4];
594 } sd;
595 struct get_cfgs_reply reply;
596 uint64_t ldata = 0;
597 uint32_t addr_shift;
598 uint32_t map_shift;
599 uint32_t map_mask;
600 int spi_clk;
601 int otp_valid;
602
603 /* Gen4 device does not support attestation feature */
604 if (setting->attn_set.attestation_mode !=
605 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED)
606 return -EINVAL;
607
608 ret = get_configs(dev, &reply, &otp_valid);
609 if (ret)
610 return ret;
611
612 memset(&sd, 0, sizeof(sd));
613
614 sd.cfg |= setting->jtag_lock_after_reset?
615 SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK : 0;
616 sd.cfg |= setting->jtag_lock_after_bl1?
617 SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK : 0;
618 sd.cfg |= setting->jtag_bl1_unlock_allowed?
619 SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK : 0;
620 sd.cfg |= setting->jtag_post_bl1_unlock_allowed?
621 SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK : 0;
622
623 spi_clk = convert_spi_clk_rate(setting->spi_clk_rate,
624 reply.spi_core_clk_high);
625 if (spi_clk < 0) {
626 errno = EINVAL;
627 return -1;
628 }
629
630 sd.cfg |= (spi_clk & SWITCHTEC_CLK_RATE_BITMASK) <<
631 SWITCHTEC_CLK_RATE_BITSHIFT;
632
633 sd.cfg |= (setting->i2c_recovery_tmo & SWITCHTEC_RC_TMO_BITMASK) <<
634 SWITCHTEC_RC_TMO_BITSHIFT;
635 sd.cfg |= (setting->i2c_port & SWITCHTEC_I2C_PORT_BITMASK) <<
636 SWITCHTEC_I2C_PORT_BITSHIFT;
637
638 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
639 &map_mask);
640 sd.cfg |= (setting->i2c_addr & SWITCHTEC_I2C_ADDR_BITMASK) <<
641 addr_shift;
642
643 ldata = setting->i2c_cmd_map & map_mask;
644 ldata <<= map_shift;
645 sd.cfg |= ldata;
646
647 sd.cfg = htole64(sd.cfg);
648
649 sd.pub_key_exponent = htole32(setting->public_key_exponent);
650
651 return switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_SET,
652 &sd, sizeof(sd), NULL, 0);
653}
654
655static int security_config_set_gen5(struct switchtec_dev *dev,
656 struct switchtec_security_cfg_set *setting)
657{
658 int ret;
659 struct setting_data {
660 uint64_t cfg;
661 uint32_t pub_key_exponent;
662 uint8_t uds_valid;
663 uint8_t rsvd[3];
664 uint32_t cdi_efuse_inc_mask;
665 uint8_t uds[32];
666 } sd;
667 struct get_cfgs_reply_gen5 reply;
668 uint64_t ldata = 0;
669 uint32_t addr_shift;
670 uint32_t map_shift;
671 uint32_t map_mask;
672 int spi_clk;
673 uint8_t cmd_buf[64]={};
674
675 ret = get_configs_gen5(dev, &reply);
676 if (ret)
677 return ret;
678
679 memset(&sd, 0, sizeof(sd));
680
681 sd.cfg = setting->jtag_lock_after_reset?
682 SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK : 0;
683 sd.cfg |= setting->jtag_lock_after_bl1?
684 SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK : 0;
685 sd.cfg |= setting->jtag_bl1_unlock_allowed?
686 SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK : 0;
687 sd.cfg |= setting->jtag_post_bl1_unlock_allowed?
688 SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK : 0;
689
690 spi_clk = convert_spi_clk_rate(setting->spi_clk_rate,
691 reply.spi_core_clk_high);
692 if (spi_clk < 0) {
693 errno = EINVAL;
694 return -1;
695 }
696
697 sd.cfg |= (spi_clk & SWITCHTEC_CLK_RATE_BITMASK) <<
698 SWITCHTEC_CLK_RATE_BITSHIFT;
699
700 sd.cfg |= (setting->i2c_recovery_tmo & SWITCHTEC_RC_TMO_BITMASK) <<
701 SWITCHTEC_RC_TMO_BITSHIFT;
702 sd.cfg |= (setting->i2c_port & SWITCHTEC_I2C_PORT_BITMASK) <<
703 SWITCHTEC_I2C_PORT_BITSHIFT;
704
705 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
706 &map_mask);
707 sd.cfg |= (setting->i2c_addr & SWITCHTEC_I2C_ADDR_BITMASK) <<
708 addr_shift;
709
710 ldata = setting->i2c_cmd_map & map_mask;
711 ldata <<= map_shift;
712 sd.cfg |= ldata;
713
714 sd.cfg = htole64(sd.cfg);
715
716 sd.pub_key_exponent = htole32(setting->public_key_exponent);
717
718 if (setting->attn_set.attestation_mode ==
719 SWITCHTEC_ATTESTATION_MODE_DICE) {
720 sd.cfg |= 0x10;
721 sd.cdi_efuse_inc_mask = setting->attn_set.cdi_efuse_inc_mask;
722
723 ldata = setting->attn_set.uds_selfgen? 1 : 0;
724 ldata <<= 44;
725 sd.cfg |= ldata;
726
727 sd.uds_valid = setting->attn_set.uds_valid;
728 if (sd.uds_valid)
729 memcpy(sd.uds, setting->attn_set.uds_data, 32);
730 }
731
732 memcpy(cmd_buf + 4, &sd, sizeof(sd));
733 return switchtec_mfg_cmd(dev, MRPC_SECURITY_CONFIG_SET_GEN5,
734 cmd_buf, sizeof(cmd_buf), NULL, 0);
735}
736
743int switchtec_security_config_set(struct switchtec_dev *dev,
744 struct switchtec_security_cfg_set *setting)
745{
746 if (switchtec_is_gen5(dev))
747 return security_config_set_gen5(dev, setting);
748 else
749 return security_config_set_gen4(dev, setting);
750}
751
752static int active_image_index_get(struct switchtec_dev *dev,
753 struct switchtec_active_index *index)
754{
755 int ret;
756 struct active_indices {
757 uint8_t index[SWITCHTEC_ACTV_IDX_MAX_ENTRIES];
758 } reply;
759
760 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_GET, NULL,
761 0, &reply, sizeof(reply));
762 if (ret)
763 return ret;
764
765 index->keyman = reply.index[SWITCHTEC_ACTV_IMG_ID_KMAN];
766 index->bl2 = reply.index[SWITCHTEC_ACTV_IMG_ID_BL2];
767 index->config = reply.index[SWITCHTEC_ACTV_IMG_ID_CFG];
768 index->firmware = reply.index[SWITCHTEC_ACTV_IMG_ID_FW];
769 index->riot = SWITCHTEC_ACTIVE_INDEX_NOT_SET;
770
771 return 0;
772}
773
774static int active_image_index_get_gen5(struct switchtec_dev *dev,
775 struct switchtec_active_index *index)
776{
777 int ret;
778 uint32_t subcmd = 0;
779 struct active_indices {
780 uint8_t index[SWITCHTEC_ACTV_IDX_MAX_ENTRIES];
781 } reply;
782
783 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_GET_GEN5, &subcmd,
784 sizeof(subcmd), &reply, sizeof(reply));
785 if (ret)
786 return ret;
787
788 index->keyman = reply.index[SWITCHTEC_ACTV_IMG_ID_KMAN_GEN5];
789 index->bl2 = reply.index[SWITCHTEC_ACTV_IMG_ID_BL2_GEN5];
790 index->config = reply.index[SWITCHTEC_ACTV_IMG_ID_CFG_GEN5];
791 index->firmware = reply.index[SWITCHTEC_ACTV_IMG_ID_FW_GEN5];
792 index->riot = reply.index[SWITCHTEC_ACTV_IMG_ID_RC_GEN5];
793
794 return 0;
795}
796
803int switchtec_active_image_index_get(struct switchtec_dev *dev,
804 struct switchtec_active_index *index)
805{
806 if (switchtec_is_gen5(dev))
807 return active_image_index_get_gen5(dev, index);
808 else
809 return active_image_index_get(dev, index);
810}
811
812static int active_image_index_set(struct switchtec_dev *dev,
813 struct switchtec_active_index *index)
814{
815 int ret;
816 int i = 0;
817 struct active_idx {
818 uint32_t count;
819 struct entry {
820 uint8_t image_id;
821 uint8_t index;
822 } idx[SWITCHTEC_ACTV_IDX_SET_ENTRIES];
823 } set;
824
825 /* RIOT image is not available on Gen4 device */
826 if (index->riot != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
827 errno = EINVAL;
828 return -EINVAL;
829 }
830
831 memset(&set, 0, sizeof(set));
832
833 if (index->keyman != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
834 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_KMAN;
835 set.idx[i].index = index->keyman;
836 i++;
837 }
838
839 if (index->bl2 != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
840 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_BL2;
841 set.idx[i].index = index->bl2;
842 i++;
843 }
844
845 if (index->config != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
846 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_CFG;
847 set.idx[i].index = index->config;
848 i++;
849 }
850
851 if (index->firmware != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
852 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_FW;
853 set.idx[i].index = index->firmware;
854 i++;
855 }
856
857 if (i == 0)
858 return 0;
859
860 set.count = htole32(i);
861
862 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_SET, &set,
863 sizeof(set), NULL, 0);
864 return ret;
865}
866
867static int active_image_index_set_gen5(struct switchtec_dev *dev,
868 struct switchtec_active_index *index)
869{
870 int ret;
871 int i = 0;
872 struct active_idx {
873 uint32_t subcmd;
874 uint32_t count;
875 struct entry {
876 uint8_t image_id;
877 uint8_t index;
878 } idx[SWITCHTEC_ACTV_IDX_SET_ENTRIES];
879 } set = {};
880
881 if (index->keyman != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
882 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_KMAN_GEN5;
883 set.idx[i].index = index->keyman;
884 i++;
885 }
886
887 if (index->riot != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
888 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_RC_GEN5;
889 set.idx[i].index = index->riot;
890 i++;
891 }
892
893 if (index->bl2 != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
894 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_BL2_GEN5;
895 set.idx[i].index = index->bl2;
896 i++;
897 }
898
899 if (index->config != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
900 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_CFG_GEN5;
901 set.idx[i].index = index->config;
902 i++;
903 }
904
905 if (index->firmware != SWITCHTEC_ACTIVE_INDEX_NOT_SET) {
906 set.idx[i].image_id = SWITCHTEC_ACTV_IMG_ID_FW_GEN5;
907 set.idx[i].index = index->firmware;
908 i++;
909 }
910
911 if (i == 0)
912 return 0;
913
914 set.count = htole32(i);
915
916 ret = switchtec_mfg_cmd(dev, MRPC_ACT_IMG_IDX_SET_GEN5, &set,
917 sizeof(set), NULL, 0);
918 return ret;
919}
920
927int switchtec_active_image_index_set(struct switchtec_dev *dev,
928 struct switchtec_active_index *index)
929{
930 if (switchtec_is_gen5(dev))
931 return active_image_index_set_gen5(dev, index);
932 else
933 return active_image_index_set(dev, index);
934}
935
942int switchtec_fw_exec(struct switchtec_dev *dev,
943 enum switchtec_bl2_recovery_mode recovery_mode)
944{
945 uint32_t cmd_id = MRPC_FW_TX;
946 struct fw_exec_struct {
947 uint8_t subcmd;
948 uint8_t recovery_mode;
949 uint8_t rsvd[2];
950 } cmd;
951
952 memset(&cmd, 0, sizeof(cmd));
953 cmd.subcmd = MRPC_FW_TX_EXEC;
954 cmd.recovery_mode = recovery_mode;
955
956 if (switchtec_is_gen5(dev))
957 cmd_id = MRPC_FW_TX_GEN5;
958
959 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
960}
961
974int switchtec_boot_resume(struct switchtec_dev *dev)
975{
976 uint32_t subcmd = 0;
977
978 if (switchtec_is_gen5(dev))
979 return switchtec_mfg_cmd(dev, MRPC_BOOTUP_RESUME_GEN5,
980 &subcmd, sizeof(subcmd),
981 NULL, 0);
982 else
983 return switchtec_mfg_cmd(dev, MRPC_BOOTUP_RESUME,
984 NULL, 0, NULL, 0);
985}
986
987static int secure_state_set(struct switchtec_dev *dev,
988 enum switchtec_secure_state state)
989{
990 uint32_t data;
991
992 data = htole32(state);
993
994 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET,
995 &data, sizeof(data), NULL, 0);
996}
997
998static int secure_state_set_gen5(struct switchtec_dev *dev,
999 enum switchtec_secure_state state)
1000{
1001 struct state_set {
1002 uint32_t subcmd;
1003 uint32_t state;
1004 } data;
1005
1006 data.subcmd = 0;
1007 data.state = htole32(state);
1008
1009 return switchtec_mfg_cmd(dev, MRPC_SECURE_STATE_SET_GEN5,
1010 &data, sizeof(data), NULL, 0);
1011}
1012
1019int switchtec_secure_state_set(struct switchtec_dev *dev,
1020 enum switchtec_secure_state state)
1021{
1022 if ((state != SWITCHTEC_INITIALIZED_UNSECURED)
1023 && (state != SWITCHTEC_INITIALIZED_SECURED)) {
1024 return ERR_PARAM_INVALID;
1025 }
1026
1027 if (switchtec_is_gen5(dev))
1028 return secure_state_set_gen5(dev, state);
1029 else
1030 return secure_state_set(dev, state);
1031}
1032
1033static int dbg_unlock_send_pubkey(struct switchtec_dev *dev,
1034 struct switchtec_pubkey *public_key,
1035 uint32_t cmd_id)
1036{
1037 struct public_key_cmd {
1038 uint8_t subcmd;
1039 uint8_t rsvd[3];
1040 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1041 uint32_t pub_key_exp;
1042 } cmd = {};
1043
1044 cmd.subcmd = MRPC_DBG_UNLOCK_PKEY;
1045 memcpy(cmd.pub_key, public_key->pubkey, SWITCHTEC_PUB_KEY_LEN);
1046 cmd.pub_key_exp = htole32(public_key->pubkey_exp);
1047
1048 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
1049}
1050
1060int switchtec_dbg_unlock(struct switchtec_dev *dev, uint32_t serial,
1061 uint32_t ver_sec_unlock,
1062 struct switchtec_pubkey *public_key,
1063 struct switchtec_signature *signature)
1064{
1065 int ret;
1066 struct unlock_cmd {
1067 uint8_t subcmd;
1068 uint8_t rsvd[3];
1069 uint32_t serial;
1070 uint32_t unlock_ver;
1071 uint8_t signature[SWITCHTEC_SIG_LEN];
1072 } cmd = {};
1073 uint32_t cmd_id;
1074
1075 if (switchtec_is_gen5(dev))
1076 cmd_id = MRPC_DBG_UNLOCK_GEN5;
1077 else
1078 cmd_id = MRPC_DBG_UNLOCK;
1079
1080 ret = dbg_unlock_send_pubkey(dev, public_key, cmd_id);
1081 if (ret)
1082 return ret;
1083
1084 cmd.subcmd = MRPC_DBG_UNLOCK_DATA;
1085 cmd.serial = htole32(serial);
1086 cmd.unlock_ver = htole32(ver_sec_unlock);
1087 memcpy(cmd.signature, signature->signature, SWITCHTEC_SIG_LEN);
1088
1089 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
1090}
1091
1101int switchtec_dbg_unlock_version_update(struct switchtec_dev *dev,
1102 uint32_t serial,
1103 uint32_t ver_sec_unlock,
1104 struct switchtec_pubkey *public_key,
1105 struct switchtec_signature *signature)
1106{
1107 int ret;
1108 struct update_cmd {
1109 uint8_t subcmd;
1110 uint8_t rsvd[3];
1111 uint32_t serial;
1112 uint32_t unlock_ver;
1113 uint8_t signature[SWITCHTEC_SIG_LEN];
1114 } cmd = {};
1115 uint32_t cmd_id;
1116
1117 if (switchtec_is_gen5(dev))
1118 cmd_id = MRPC_DBG_UNLOCK_GEN5;
1119 else
1120 cmd_id = MRPC_DBG_UNLOCK;
1121
1122 ret = dbg_unlock_send_pubkey(dev, public_key, cmd_id);
1123 if (ret)
1124 return ret;
1125
1126 cmd.subcmd = MRPC_DBG_UNLOCK_UPDATE;
1127 cmd.serial = htole32(serial);
1128 cmd.unlock_ver = htole32(ver_sec_unlock);
1129 memcpy(cmd.signature, signature->signature, SWITCHTEC_SIG_LEN);
1130
1131 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd), NULL, 0);
1132}
1133
1134static int check_sec_cfg_header(struct switchtec_dev *dev,
1135 FILE *setting_file)
1136{
1137 ssize_t rlen;
1138 enum switchtec_gen gen;
1139 char magic[4] = {'S', 'S', 'F', 'F'};
1140 uint32_t crc;
1141 struct setting_file_header {
1142 uint8_t magic[4];
1143 uint32_t version;
1144 uint8_t hw_gen;
1145 uint8_t rsvd[3];
1146 uint32_t crc;
1147 } hdr;
1148 int data_len;
1149 uint8_t data[64];
1150
1151 rlen = fread(&hdr, sizeof(hdr), 1, setting_file);
1152
1153 if (rlen != 1)
1154 return -EBADF;
1155
1156 if (memcmp(hdr.magic, magic, sizeof(magic)))
1157 return -EBADF;
1158
1159 switch (hdr.hw_gen) {
1160 case 0:
1161 gen = SWITCHTEC_GEN4;
1162 break;
1163 case 1:
1164 gen = SWITCHTEC_GEN5;
1165 break;
1166 default:
1167 return -EBADF;
1168 }
1169
1170 if (gen != switchtec_gen(dev))
1171 return -ENODEV;
1172
1173 fseek(setting_file, 0, SEEK_END);
1174 data_len = ftell(setting_file) - sizeof(hdr);
1175 fseek(setting_file, sizeof(hdr), SEEK_SET);
1176
1177 rlen = fread(data, 1, data_len, setting_file);
1178 if (rlen < data_len)
1179 return -EBADF;
1180
1181 crc = crc32(data, data_len, 0, 1, 1);
1182 if (crc != le32toh(hdr.crc))
1183 return -EBADF;
1184
1185 fseek(setting_file, sizeof(hdr), SEEK_SET);
1186 return 0;
1187}
1188
1189static int read_sec_cfg_file(struct switchtec_dev *dev,
1190 FILE *setting_file,
1191 struct switchtec_security_cfg_set *set)
1192{
1193 struct setting_file_data {
1194 uint64_t cfg;
1195 uint32_t pub_key_exponent;
1196 uint8_t rsvd[36];
1197 } data;
1198 struct get_cfgs_reply reply;
1199 uint32_t addr_shift;
1200 uint32_t map_shift;
1201 uint32_t map_mask;
1202 int spi_clk;
1203 int ret;
1204 int otp_valid;
1205
1206 ret = get_configs(dev, &reply, &otp_valid);
1207 if (ret)
1208 return ret;
1209
1210 memset(set, 0, sizeof(struct switchtec_security_cfg_set));
1211
1212 ret = fread(&data, sizeof(data), 1, setting_file);
1213
1214 if (ret != 1)
1215 return -EBADF;
1216
1217 data.cfg = le64toh(data.cfg);
1218
1219 set->jtag_lock_after_reset =
1220 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK);
1221 set->jtag_lock_after_bl1 =
1222 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK);
1223 set->jtag_bl1_unlock_allowed =
1224 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK);
1225 set->jtag_post_bl1_unlock_allowed =
1226 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK);
1227
1228 spi_clk = (data.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) &
1229 SWITCHTEC_CLK_RATE_BITMASK;
1230
1231 if (spi_clk == 0)
1232 spi_clk = 7;
1233
1234 if (spi_clk > 10)
1235 return -EINVAL;
1236
1237 if (reply.spi_core_clk_high)
1238 set->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
1239 else
1240 set->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
1241
1242 set->i2c_recovery_tmo =
1243 (data.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) &
1244 SWITCHTEC_RC_TMO_BITMASK;
1245 set->i2c_port =
1246 (data.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) &
1247 SWITCHTEC_I2C_PORT_BITMASK;
1248
1249 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
1250 &map_mask);
1251 set->i2c_addr =
1252 (data.cfg >> addr_shift) &
1253 SWITCHTEC_I2C_ADDR_BITMASK;
1254 set->i2c_cmd_map = (data.cfg >> map_shift) & map_mask;
1255
1256 set->public_key_exponent = le32toh(data.pub_key_exponent);
1257
1258 set->attn_set.attestation_mode =
1259 SWITCHTEC_ATTESTATION_MODE_NOT_SUPPORTED;
1260
1261 return 0;
1262}
1263
1264static int read_sec_cfg_file_gen5(struct switchtec_dev *dev,
1265 FILE *setting_file,
1266 struct switchtec_security_cfg_set *set)
1267{
1268 struct setting_data {
1269 uint64_t cfg;
1270 uint32_t pub_key_exponent;
1271 uint8_t rsvd[4];
1272 uint32_t cdi_efuse_inc_mask;
1273 } data;
1274 struct get_cfgs_reply_gen5 reply;
1275 uint32_t addr_shift;
1276 uint32_t map_shift;
1277 uint32_t map_mask;
1278 int spi_clk;
1279 int ret;
1280 int attest_mode;
1281
1282 ret = get_configs_gen5(dev, &reply);
1283 if (ret)
1284 return ret;
1285
1286 memset(set, 0, sizeof(struct switchtec_security_cfg_set));
1287
1288 ret = fread(&data, sizeof(data), 1, setting_file);
1289
1290 if (ret != 1)
1291 return -EBADF;
1292
1293 data.cfg = le64toh(data.cfg);
1294
1295 set->jtag_lock_after_reset =
1296 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_RST_BITMASK);
1297 set->jtag_lock_after_bl1 =
1298 !!(data.cfg & SWITCHTEC_JTAG_LOCK_AFT_BL1_BITMASK);
1299 set->jtag_bl1_unlock_allowed =
1300 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_BL1_BITMASK);
1301 set->jtag_post_bl1_unlock_allowed =
1302 !!(data.cfg & SWITCHTEC_JTAG_UNLOCK_AFT_BL1_BITMASK);
1303
1304 spi_clk = (data.cfg >> SWITCHTEC_CLK_RATE_BITSHIFT) &
1305 SWITCHTEC_CLK_RATE_BITMASK;
1306
1307 if (spi_clk == 0)
1308 spi_clk = 9;
1309
1310 if (spi_clk > 10)
1311 return -EINVAL;
1312
1313 if (reply.spi_core_clk_high)
1314 set->spi_clk_rate = spi_clk_hi_rate_float[spi_clk - 1];
1315 else
1316 set->spi_clk_rate = spi_clk_rate_float[spi_clk - 1];
1317
1318 set->i2c_recovery_tmo =
1319 (data.cfg >> SWITCHTEC_RC_TMO_BITSHIFT) &
1320 SWITCHTEC_RC_TMO_BITMASK;
1321 set->i2c_port =
1322 (data.cfg >> SWITCHTEC_I2C_PORT_BITSHIFT) &
1323 SWITCHTEC_I2C_PORT_BITMASK;
1324
1325 get_i2c_operands(switchtec_gen(dev), &addr_shift, &map_shift,
1326 &map_mask);
1327 set->i2c_addr =
1328 (data.cfg >> addr_shift) &
1329 SWITCHTEC_I2C_ADDR_BITMASK;
1330 set->i2c_cmd_map = (data.cfg >> map_shift) & map_mask;
1331
1332 set->public_key_exponent = le32toh(data.pub_key_exponent);
1333
1334 attest_mode = (data.cfg >> SWITCHTEC_ATTEST_BITSHIFT) &
1335 SWITCHTEC_ATTEST_BITMASK;
1336 if (attest_mode == 1) {
1337 set->attn_set.attestation_mode =
1338 SWITCHTEC_ATTESTATION_MODE_DICE;
1339 set->attn_set.cdi_efuse_inc_mask = data.cdi_efuse_inc_mask;
1340 set->attn_set.uds_selfgen = (data.cfg >> 44) & 0x1;
1341 } else {
1342 set->attn_set.attestation_mode =
1343 SWITCHTEC_ATTESTATION_MODE_NONE;
1344 }
1345
1346 return 0;
1347}
1348
1356int switchtec_read_sec_cfg_file(struct switchtec_dev *dev,
1357 FILE *setting_file,
1358 struct switchtec_security_cfg_set *set)
1359{
1360 int ret;
1361
1362 ret = check_sec_cfg_header(dev, setting_file);
1363 if (ret)
1364 return ret;
1365
1366 if (switchtec_is_gen4(dev))
1367 return read_sec_cfg_file(dev, setting_file, set);
1368 else
1369 return read_sec_cfg_file_gen5(dev, setting_file, set);
1370}
1371
1372static int kmsk_set_send_pubkey(struct switchtec_dev *dev,
1373 struct switchtec_pubkey *public_key,
1374 uint32_t cmd_id)
1375{
1376 struct kmsk_pubk_cmd {
1377 uint8_t subcmd;
1378 uint8_t reserved[3];
1379 uint8_t pub_key[SWITCHTEC_PUB_KEY_LEN];
1380 uint32_t pub_key_exponent;
1381 } cmd = {};
1382
1383 cmd.subcmd = MRPC_KMSK_ENTRY_SET_PKEY;
1384 memcpy(cmd.pub_key, public_key->pubkey,
1385 SWITCHTEC_PUB_KEY_LEN);
1386 cmd.pub_key_exponent = htole32(public_key->pubkey_exp);
1387
1388 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
1389 sizeof(cmd), NULL, 0);
1390}
1391
1392static int kmsk_set_send_signature(struct switchtec_dev *dev,
1393 struct switchtec_signature *signature,
1394 uint32_t cmd_id)
1395{
1396 struct kmsk_signature_cmd {
1397 uint8_t subcmd;
1398 uint8_t reserved[3];
1399 uint8_t signature[SWITCHTEC_SIG_LEN];
1400 } cmd = {};
1401
1402 cmd.subcmd = MRPC_KMSK_ENTRY_SET_SIG;
1403 memcpy(cmd.signature, signature->signature,
1404 SWITCHTEC_SIG_LEN);
1405
1406 return switchtec_mfg_cmd(dev, cmd_id, &cmd,
1407 sizeof(cmd), NULL, 0);
1408}
1409
1410static int kmsk_set_send_kmsk(struct switchtec_dev *dev,
1411 struct switchtec_kmsk *kmsk,
1412 uint32_t cmd_id)
1413{
1414 struct kmsk_kmsk_cmd {
1415 uint8_t subcmd;
1416 uint8_t num_entries;
1417 uint8_t reserved[2];
1418 uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1419 } cmd = {};
1420
1421 cmd.subcmd = MRPC_KMSK_ENTRY_SET_KMSK;
1422 cmd.num_entries = 1;
1423 memcpy(cmd.kmsk, kmsk->kmsk, SWITCHTEC_KMSK_LEN);
1424
1425 return switchtec_mfg_cmd(dev, cmd_id, &cmd, sizeof(cmd),
1426 NULL, 0);
1427}
1428
1441int switchtec_kmsk_set(struct switchtec_dev *dev,
1442 struct switchtec_pubkey *public_key,
1443 struct switchtec_signature *signature,
1444 struct switchtec_kmsk *kmsk)
1445{
1446 int ret;
1447 uint32_t cmd_id;
1448
1449 if (switchtec_is_gen5(dev))
1450 cmd_id = MRPC_KMSK_ENTRY_SET_GEN5;
1451 else
1452 cmd_id = MRPC_KMSK_ENTRY_SET;
1453
1454 if (public_key) {
1455 ret = kmsk_set_send_pubkey(dev, public_key, cmd_id);
1456 if (ret)
1457 return ret;
1458 }
1459
1460 if (signature) {
1461 ret = kmsk_set_send_signature(dev, signature, cmd_id);
1462 if (ret)
1463 return ret;
1464 }
1465
1466 return kmsk_set_send_kmsk(dev, kmsk, cmd_id);
1467}
1468
1469#if HAVE_LIBCRYPTO
1470
1471#ifdef HAVE_DECL_PEM_READ_PUBKEY
1472
1473#include <openssl/core_names.h>
1474
1481int switchtec_read_pubk_file(FILE *pubk_file, struct switchtec_pubkey *pubk)
1482{
1483 BIGNUM *bn_priv = NULL;
1484 uint32_t exponent_tmp;
1485 EVP_PKEY *pkey;
1486
1487 pkey = PEM_read_PUBKEY(pubk_file, NULL, NULL, NULL);
1488 if (!pkey) {
1489 fseek(pubk_file, 0L, SEEK_SET);
1490 pkey = PEM_read_PrivateKey(pubk_file, NULL, NULL, NULL);
1491 if (!pkey)
1492 return -1;
1493 }
1494
1495 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bn_priv);
1496 BN_bn2bin(bn_priv, pubk->pubkey);
1497 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bn_priv);
1498 BN_bn2bin(bn_priv, (uint8_t *)&exponent_tmp);
1499 pubk->pubkey_exp = be32toh(exponent_tmp);
1500
1501 EVP_PKEY_free(pkey);
1502 return 0;
1503}
1504
1505#else /* ! HAVE_DECL_PEM_READ_PUBKEY */
1506
1507#if !HAVE_DECL_RSA_GET0_KEY
1512static void RSA_get0_key(const RSA *r, const BIGNUM **n,
1513 const BIGNUM **e, const BIGNUM **d)
1514{
1515 if (n)
1516 *n = r->n;
1517 if (e)
1518 *e = r->e;
1519 if (d)
1520 *d = r->d;
1521}
1522#endif
1523
1530int switchtec_read_pubk_file(FILE *pubk_file, struct switchtec_pubkey *pubk)
1531{
1532 RSA *RSAKey = NULL;
1533 const BIGNUM *modulus_bn;
1534 const BIGNUM *exponent_bn;
1535 uint32_t exponent_tmp = 0;
1536
1537 RSAKey = PEM_read_RSA_PUBKEY(pubk_file, NULL, NULL, NULL);
1538 if (RSAKey == NULL) {
1539 fseek(pubk_file, 0L, SEEK_SET);
1540 RSAKey = PEM_read_RSAPrivateKey(pubk_file, NULL, NULL, NULL);
1541 if (RSAKey == NULL)
1542 return -1;
1543 }
1544
1545 RSA_get0_key(RSAKey, &modulus_bn, &exponent_bn, NULL);
1546
1547 BN_bn2bin(modulus_bn, pubk->pubkey);
1548 BN_bn2bin(exponent_bn, (uint8_t *)&exponent_tmp);
1549
1550 pubk->pubkey_exp = be32toh(exponent_tmp);
1551 RSA_free(RSAKey);
1552
1553 return 0;
1554}
1555
1556#endif /* HAVE_DECL_PEM_READ_PUBKEY */
1557
1558#endif
1559
1566int switchtec_read_kmsk_file(FILE *kmsk_file, struct switchtec_kmsk *kmsk)
1567{
1568 ssize_t rlen;
1569 struct kmsk_struct {
1570 uint8_t magic[4];
1571 uint32_t version;
1572 uint32_t reserved;
1573 uint32_t crc32;
1574 uint8_t kmsk[SWITCHTEC_KMSK_LEN];
1575 } data;
1576
1577 char magic[4] = {'K', 'M', 'S', 'K'};
1578 uint32_t crc;
1579
1580 rlen = fread(&data, 1, sizeof(data), kmsk_file);
1581
1582 if (rlen < sizeof(data))
1583 return -EBADF;
1584
1585 if (memcmp(data.magic, magic, sizeof(magic)))
1586 return -EBADF;
1587
1588 crc = crc32(data.kmsk, SWITCHTEC_KMSK_LEN, 0, 1, 1);
1589 if (crc != le32toh(data.crc32))
1590 return -EBADF;
1591
1592 memcpy(kmsk->kmsk, data.kmsk, SWITCHTEC_KMSK_LEN);
1593
1594 return 0;
1595}
1596
1603int switchtec_read_signature_file(FILE *sig_file,
1604 struct switchtec_signature *signature)
1605{
1606 ssize_t rlen;
1607
1608 rlen = fread(signature->signature, 1, SWITCHTEC_SIG_LEN, sig_file);
1609
1610 if (rlen < SWITCHTEC_SIG_LEN)
1611 return -EBADF;
1612
1613 return 0;
1614}
1615
1622int switchtec_read_uds_file(FILE *uds_file, struct switchtec_uds *uds)
1623{
1624 ssize_t rlen;
1625
1626 rlen = fread(uds->uds, 1, SWITCHTEC_UDS_LEN, uds_file);
1627
1628 if (rlen < SWITCHTEC_UDS_LEN)
1629 return -EBADF;
1630
1631 return 0;
1632}
1633
1644int
1645switchtec_security_state_has_kmsk(struct switchtec_security_cfg_state *state,
1646 struct switchtec_kmsk *kmsk)
1647{
1648 int key_idx;
1649
1650 for(key_idx = 0; key_idx < state->public_key_num; key_idx++) {
1651 if (memcmp(state->public_key[key_idx], kmsk->kmsk,
1652 SWITCHTEC_KMSK_LEN) == 0)
1653 return 1;
1654 }
1655
1656 return 0;
1657}
1658
1659#endif /* __linux__ */
1660
1661static int switchtec_mfg_cmd(struct switchtec_dev *dev, uint32_t cmd,
1662 const void *payload, size_t payload_len,
1663 void *resp, size_t resp_len)
1664{
1665 if (dev->ops->flags & SWITCHTEC_OPS_FLAG_NO_MFG) {
1666 errno = ERR_UART_NOT_SUPPORTED | SWITCHTEC_ERRNO_MRPC_FLAG_BIT;
1667 return -1;
1668 }
1669
1670 return switchtec_cmd(dev, cmd, payload, payload_len,
1671 resp, resp_len);
1672}
1673
1674static int sn_ver_get_gen4(struct switchtec_dev *dev,
1675 struct switchtec_sn_ver_info *info)
1676{
1677 int ret;
1678 struct reply_t {
1679 uint32_t chip_serial;
1680 uint32_t ver_km;
1681 uint32_t ver_bl2;
1682 uint32_t ver_main;
1683 uint32_t ver_sec_unlock;
1684 } reply;
1685
1686 ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET, NULL, 0,
1687 &reply, sizeof(reply));
1688 if (ret)
1689 return ret;
1690
1691 info->chip_serial = reply.chip_serial;
1692 info->ver_bl2 = reply.ver_bl2;
1693 info->ver_km = reply.ver_km;
1694 info->riot_ver_valid = false;
1695 info->ver_sec_unlock = reply.ver_sec_unlock;
1696 info->ver_main = reply.ver_main;
1697
1698 return 0;
1699}
1700
1701static int sn_ver_get_gen5(struct switchtec_dev *dev,
1702 struct switchtec_sn_ver_info *info)
1703{
1704 int ret;
1705 uint32_t subcmd = 0;
1706 struct reply_t {
1707 uint32_t chip_serial;
1708 uint32_t ver_km;
1709 uint16_t ver_riot;
1710 uint16_t ver_bl2;
1711 uint32_t ver_main;
1712 uint32_t ver_sec_unlock;
1713 } reply;
1714
1715 ret = switchtec_mfg_cmd(dev, MRPC_SN_VER_GET_GEN5, &subcmd, 4,
1716 &reply, sizeof(reply));
1717 if (ret)
1718 return ret;
1719
1720 info->chip_serial = reply.chip_serial;
1721 info->ver_bl2 = reply.ver_bl2;
1722 info->ver_km = reply.ver_km;
1723 info->riot_ver_valid = true;
1724 info->ver_riot = reply.ver_riot;
1725 info->ver_sec_unlock = reply.ver_sec_unlock;
1726 info->ver_main = reply.ver_main;
1727
1728 return 0;
1729}
1730
1737int switchtec_sn_ver_get(struct switchtec_dev *dev,
1738 struct switchtec_sn_ver_info *info)
1739{
1740 if (switchtec_is_gen5(dev))
1741 return sn_ver_get_gen5(dev, info);
1742 else
1743 return sn_ver_get_gen4(dev, info);
1744}
1745
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:1737
Main Switchtec header.
switchtec_gen
The PCIe generations.
Definition switchtec.h:91
static int switchtec_is_gen4(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 4 device.
Definition switchtec.h:469
static int switchtec_is_gen5(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 5 device.
Definition switchtec.h:477