1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
11 #include <dm/device.h>
12 #include <dm/uclass.h>
16 * STM32MP15x: bit 6 of OPT0
17 * STM32MP13x: 0b111111 = 0x3F for OTP_SECURED closed device
19 #define STM32_OTP_CLOSE_ID 0
20 #define STM32_OTP_STM32MP13x_CLOSE_MASK 0x3F
21 #define STM32_OTP_STM32MP15x_CLOSE_MASK BIT(6)
23 /* PKH is the first element of the key list */
24 #define STM32KEY_PKH 0
33 const struct stm32key stm32mp13_list[] = {
36 .desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm)",
42 .desc = "Encryption/Decryption Master Key",
48 const struct stm32key stm32mp15_list[] = {
51 .desc = "Hash of the ECC Public Key (ECDSA is the authentication algorithm)",
57 /* index of current selected key in stm32key list, 0 = PKH by default */
58 static u8 stm32key_index;
60 static u8 get_key_nb(void)
62 if (IS_ENABLED(CONFIG_STM32MP13x))
63 return ARRAY_SIZE(stm32mp13_list);
65 if (IS_ENABLED(CONFIG_STM32MP15x))
66 return ARRAY_SIZE(stm32mp15_list);
69 static const struct stm32key *get_key(u8 index)
71 if (IS_ENABLED(CONFIG_STM32MP13x))
72 return &stm32mp13_list[index];
74 if (IS_ENABLED(CONFIG_STM32MP15x))
75 return &stm32mp15_list[index];
78 static u32 get_otp_close_mask(void)
80 if (IS_ENABLED(CONFIG_STM32MP13x))
81 return STM32_OTP_STM32MP13x_CLOSE_MASK;
83 if (IS_ENABLED(CONFIG_STM32MP15x))
84 return STM32_OTP_STM32MP15x_CLOSE_MASK;
87 #define BSEC_LOCK_ERROR (-1)
88 #define BSEC_LOCK_PERM BIT(0)
90 static int get_misc_dev(struct udevice **dev)
94 ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(stm32mp_bsec), dev);
96 log_err("Can't find stm32mp_bsec driver\n");
101 static void read_key_value(const struct stm32key *key, u32 addr)
105 for (i = 0; i < key->size; i++) {
106 printf("%s OTP %i: [%08x] %08x\n", key->name, key->start + i,
107 addr, __be32_to_cpu(*(u32 *)addr));
112 static int read_key_otp(struct udevice *dev, const struct stm32key *key, bool print, bool *locked)
115 int nb_invalid = 0, nb_zero = 0, nb_lock = 0, nb_lock_err = 0;
119 for (i = 0, word = key->start; i < key->size; i++, word++) {
120 ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4);
123 ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4);
125 lock = BSEC_LOCK_ERROR;
127 printf("%s OTP %i: %08x lock : %08x\n", key->name, word, val, lock);
132 if (lock & BSEC_LOCK_PERM)
134 if (lock & BSEC_LOCK_ERROR)
138 status = nb_lock_err || (nb_lock == key->size);
141 if (nb_lock_err && print)
142 printf("%s lock is invalid!\n", key->name);
143 else if (!status && print)
144 printf("%s is not locked!\n", key->name);
146 if (nb_invalid == key->size) {
148 printf("%s is invalid!\n", key->name);
151 if (nb_zero == key->size) {
153 printf("%s is free!\n", key->name);
160 static int read_close_status(struct udevice *dev, bool print, bool *closed)
162 int word, ret, result;
167 word = STM32_OTP_CLOSE_ID;
168 ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4);
174 ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4);
178 lock = BSEC_LOCK_ERROR;
180 mask = get_otp_close_mask();
181 status = (val & mask) == mask;
185 printf("OTP %d: closed status: %d lock : %08x\n", word, status, lock);
190 static int fuse_key_value(struct udevice *dev, const struct stm32key *key, u32 addr, bool print)
195 for (i = 0, word = key->start; i < key->size; i++, word++, addr += 4) {
196 val = __be32_to_cpu(*(u32 *)addr);
198 printf("Fuse %s OTP %i : %08x\n", key->name, word, val);
200 ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4);
202 log_err("Fuse %s OTP %i failed\n", key->name, word);
205 /* on success, lock the OTP for the key */
206 val = BSEC_LOCK_PERM;
207 ret = misc_write(dev, STM32_BSEC_LOCK(word), &val, 4);
209 log_err("Lock %s OTP %i failed\n", key->name, word);
217 static int confirm_prog(void)
219 puts("Warning: Programming fuses is an irreversible operation!\n"
220 " This may brick your system.\n"
221 " Use this command only if you are sure of what you are doing!\n"
222 "\nReally perform this fuse programming? <y/N>\n");
227 puts("Fuse programming aborted\n");
231 static void display_key_info(const struct stm32key *key)
233 printf("%s : %s\n", key->name, key->desc);
234 printf("\tOTP%d..%d\n", key->start, key->start + key->size);
237 static int do_stm32key_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
241 for (i = 0; i < get_key_nb(); i++)
242 display_key_info(get_key(i));
244 return CMD_RET_SUCCESS;
247 static int do_stm32key_select(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
249 const struct stm32key *key;
253 printf("Selected key:\n");
254 key = get_key(stm32key_index);
255 display_key_info(key);
256 return CMD_RET_SUCCESS;
259 for (i = 0; i < get_key_nb(); i++) {
261 if (!strcmp(key->name, argv[1])) {
262 printf("%s selected\n", key->name);
264 return CMD_RET_SUCCESS;
268 printf("Unknown key %s\n", argv[1]);
270 return CMD_RET_FAILURE;
273 static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
275 const struct stm32key *key;
281 ret = get_misc_dev(&dev);
285 return CMD_RET_FAILURE;
286 key = get_key(stm32key_index);
287 ret = read_key_otp(dev, key, true, NULL);
289 return CMD_RET_FAILURE;
290 return CMD_RET_SUCCESS;
293 if (!strcmp("-a", argv[1])) {
295 return CMD_RET_FAILURE;
296 result = CMD_RET_SUCCESS;
297 for (i = 0; i < get_key_nb(); i++) {
299 ret = read_key_otp(dev, key, true, NULL);
301 result = CMD_RET_FAILURE;
303 ret = read_close_status(dev, true, NULL);
305 result = CMD_RET_FAILURE;
310 addr = hextoul(argv[1], NULL);
312 return CMD_RET_USAGE;
314 key = get_key(stm32key_index);
315 printf("Read %s at 0x%08x\n", key->name, addr);
316 read_key_value(key, addr);
318 return CMD_RET_SUCCESS;
321 static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
323 const struct stm32key *key = get_key(stm32key_index);
327 bool yes = false, lock;
330 return CMD_RET_USAGE;
333 if (strcmp(argv[1], "-y"))
334 return CMD_RET_USAGE;
338 addr = hextoul(argv[argc - 1], NULL);
340 return CMD_RET_USAGE;
342 ret = get_misc_dev(&dev);
344 return CMD_RET_FAILURE;
346 if (read_key_otp(dev, key, !yes, &lock) != -ENOENT) {
347 printf("Error: can't fuse again the OTP\n");
348 return CMD_RET_FAILURE;
351 printf("Error: %s is locked\n", key->name);
352 return CMD_RET_FAILURE;
356 printf("Writing %s with\n", key->name);
357 read_key_value(key, addr);
360 if (!yes && !confirm_prog())
361 return CMD_RET_FAILURE;
363 if (fuse_key_value(dev, key, addr, !yes))
364 return CMD_RET_FAILURE;
366 printf("%s updated !\n", key->name);
368 return CMD_RET_SUCCESS;
371 static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
373 const struct stm32key *key;
374 bool yes, lock, closed;
381 if (strcmp(argv[1], "-y"))
382 return CMD_RET_USAGE;
386 ret = get_misc_dev(&dev);
388 return CMD_RET_FAILURE;
390 if (read_close_status(dev, !yes, &closed))
391 return CMD_RET_FAILURE;
394 printf("Error: already closed!\n");
395 return CMD_RET_FAILURE;
398 /* check PKH status before to close */
399 key = get_key(STM32KEY_PKH);
400 ret = read_key_otp(dev, key, !yes, &lock);
403 printf("Error: %s not programmed!\n", key->name);
404 return CMD_RET_FAILURE;
407 printf("Warning: %s not locked!\n", key->name);
409 if (!yes && !confirm_prog())
410 return CMD_RET_FAILURE;
412 val = get_otp_close_mask();
413 ret = misc_write(dev, STM32_BSEC_OTP(STM32_OTP_CLOSE_ID), &val, 4);
415 printf("Error: can't update OTP %d\n", STM32_OTP_CLOSE_ID);
416 return CMD_RET_FAILURE;
419 printf("Device is closed !\n");
421 return CMD_RET_SUCCESS;
424 static char stm32key_help_text[] =
425 "list : list the supported key with description\n"
426 "stm32key select [<key>] : Select the key identified by <key> or display the key used for read/fuse command\n"
427 "stm32key read [<addr> | -a ] : Read the curent key at <addr> or current / all (-a) key in OTP\n"
428 "stm32key fuse [-y] <addr> : Fuse the current key at addr in OTP\n"
429 "stm32key close [-y] : Close the device\n";
431 U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Manage key on STM32", stm32key_help_text,
432 U_BOOT_SUBCMD_MKENT(list, 1, 0, do_stm32key_list),
433 U_BOOT_SUBCMD_MKENT(select, 2, 0, do_stm32key_select),
434 U_BOOT_SUBCMD_MKENT(read, 2, 0, do_stm32key_read),
435 U_BOOT_SUBCMD_MKENT(fuse, 3, 0, do_stm32key_fuse),
436 U_BOOT_SUBCMD_MKENT(close, 2, 0, do_stm32key_close));