1 // SPDX-License-Identifier: GPL-2.0
3 * Turris Mox rWTM firmware driver
5 * Copyright (C) 2019, 2024 Marek BehĂșn <kabel@kernel.org>
8 #include <linux/armada-37xx-rwtm-mailbox.h>
9 #include <linux/completion.h>
10 #include <linux/debugfs.h>
11 #include <linux/dma-mapping.h>
12 #include <linux/hw_random.h>
13 #include <linux/mailbox_client.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
17 #include <linux/platform_device.h>
18 #include <linux/slab.h>
20 #define DRIVER_NAME "turris-mox-rwtm"
23 * The macros and constants below come from Turris Mox's rWTM firmware code.
24 * This firmware is open source and it's sources can be found at
25 * https://gitlab.labs.nic.cz/turris/mox-boot-builder/tree/master/wtmi.
28 #define MBOX_STS_SUCCESS (0 << 30)
29 #define MBOX_STS_FAIL (1 << 30)
30 #define MBOX_STS_BADCMD (2 << 30)
31 #define MBOX_STS_ERROR(s) ((s) & (3 << 30))
32 #define MBOX_STS_VALUE(s) (((s) >> 10) & 0xfffff)
33 #define MBOX_STS_CMD(s) ((s) & 0x3ff)
36 MBOX_CMD_GET_RANDOM
= 1,
37 MBOX_CMD_BOARD_INFO
= 2,
38 MBOX_CMD_ECDSA_PUB_KEY
= 3,
43 MBOX_CMD_OTP_READ
= 7,
44 MBOX_CMD_OTP_WRITE
= 8,
51 struct mbox_client mbox_client
;
52 struct mbox_chan
*mbox
;
53 struct mox_kobject
*kobj
;
56 struct armada_37xx_rwtm_rx_msg reply
;
62 struct completion cmd_done
;
64 /* board information */
67 int board_version
, ram_size
;
68 u8 mac_address1
[6], mac_address2
[6];
70 /* public key burned in eFuse */
74 #ifdef CONFIG_DEBUG_FS
76 * Signature process. This is currently done via debugfs, because it
77 * does not conform to the sysfs standard "one file per attribute".
78 * It should be rewritten via crypto API once akcipher API is available
81 struct dentry
*debugfs_root
;
89 struct mox_rwtm
*rwtm
;
92 static inline struct kobject
*rwtm_to_kobj(struct mox_rwtm
*rwtm
)
94 return &rwtm
->kobj
->kobj
;
97 static inline struct mox_rwtm
*to_rwtm(struct kobject
*kobj
)
99 return container_of(kobj
, struct mox_kobject
, kobj
)->rwtm
;
102 static void mox_kobj_release(struct kobject
*kobj
)
104 kfree(to_rwtm(kobj
)->kobj
);
107 static const struct kobj_type mox_kobj_ktype
= {
108 .release
= mox_kobj_release
,
109 .sysfs_ops
= &kobj_sysfs_ops
,
112 static int mox_kobj_create(struct mox_rwtm
*rwtm
)
114 rwtm
->kobj
= kzalloc(sizeof(*rwtm
->kobj
), GFP_KERNEL
);
118 kobject_init(rwtm_to_kobj(rwtm
), &mox_kobj_ktype
);
119 if (kobject_add(rwtm_to_kobj(rwtm
), firmware_kobj
, "turris-mox-rwtm")) {
120 kobject_put(rwtm_to_kobj(rwtm
));
124 rwtm
->kobj
->rwtm
= rwtm
;
129 #define MOX_ATTR_RO(name, format, cat) \
131 name##_show(struct kobject *kobj, struct kobj_attribute *a, \
134 struct mox_rwtm *rwtm = to_rwtm(kobj); \
135 if (!rwtm->has_##cat) \
137 return sprintf(buf, format, rwtm->name); \
139 static struct kobj_attribute mox_attr_##name = __ATTR_RO(name)
141 MOX_ATTR_RO(serial_number
, "%016llX\n", board_info
);
142 MOX_ATTR_RO(board_version
, "%i\n", board_info
);
143 MOX_ATTR_RO(ram_size
, "%i\n", board_info
);
144 MOX_ATTR_RO(mac_address1
, "%pM\n", board_info
);
145 MOX_ATTR_RO(mac_address2
, "%pM\n", board_info
);
146 MOX_ATTR_RO(pubkey
, "%s\n", pubkey
);
148 static int mox_get_status(enum mbox_cmd cmd
, u32 retval
)
150 if (MBOX_STS_CMD(retval
) != cmd
)
152 else if (MBOX_STS_ERROR(retval
) == MBOX_STS_FAIL
)
153 return -(int)MBOX_STS_VALUE(retval
);
154 else if (MBOX_STS_ERROR(retval
) == MBOX_STS_BADCMD
)
156 else if (MBOX_STS_ERROR(retval
) != MBOX_STS_SUCCESS
)
159 return MBOX_STS_VALUE(retval
);
162 static const struct attribute
*mox_rwtm_attrs
[] = {
163 &mox_attr_serial_number
.attr
,
164 &mox_attr_board_version
.attr
,
165 &mox_attr_ram_size
.attr
,
166 &mox_attr_mac_address1
.attr
,
167 &mox_attr_mac_address2
.attr
,
168 &mox_attr_pubkey
.attr
,
172 static void mox_rwtm_rx_callback(struct mbox_client
*cl
, void *data
)
174 struct mox_rwtm
*rwtm
= dev_get_drvdata(cl
->dev
);
175 struct armada_37xx_rwtm_rx_msg
*msg
= data
;
177 if (completion_done(&rwtm
->cmd_done
))
181 complete(&rwtm
->cmd_done
);
184 static void reply_to_mac_addr(u8
*mac
, u32 t1
, u32 t2
)
194 static int mox_get_board_info(struct mox_rwtm
*rwtm
)
196 struct armada_37xx_rwtm_tx_msg msg
;
197 struct armada_37xx_rwtm_rx_msg
*reply
= &rwtm
->reply
;
200 msg
.command
= MBOX_CMD_BOARD_INFO
;
201 ret
= mbox_send_message(rwtm
->mbox
, &msg
);
205 if (!wait_for_completion_timeout(&rwtm
->cmd_done
, HZ
/ 2))
208 ret
= mox_get_status(MBOX_CMD_BOARD_INFO
, reply
->retval
);
209 if (ret
== -ENODATA
) {
211 "Board does not have manufacturing information burned!\n");
212 } else if (ret
== -ENOSYS
) {
213 dev_notice(rwtm
->dev
,
214 "Firmware does not support the BOARD_INFO command\n");
215 } else if (ret
< 0) {
218 rwtm
->serial_number
= reply
->status
[1];
219 rwtm
->serial_number
<<= 32;
220 rwtm
->serial_number
|= reply
->status
[0];
221 rwtm
->board_version
= reply
->status
[2];
222 rwtm
->ram_size
= reply
->status
[3];
223 reply_to_mac_addr(rwtm
->mac_address1
, reply
->status
[4],
225 reply_to_mac_addr(rwtm
->mac_address2
, reply
->status
[6],
227 rwtm
->has_board_info
= 1;
229 pr_info("Turris Mox serial number %016llX\n",
230 rwtm
->serial_number
);
231 pr_info(" board version %i\n", rwtm
->board_version
);
232 pr_info(" burned RAM size %i MiB\n", rwtm
->ram_size
);
235 msg
.command
= MBOX_CMD_ECDSA_PUB_KEY
;
236 ret
= mbox_send_message(rwtm
->mbox
, &msg
);
240 if (!wait_for_completion_timeout(&rwtm
->cmd_done
, HZ
/ 2))
243 ret
= mox_get_status(MBOX_CMD_ECDSA_PUB_KEY
, reply
->retval
);
244 if (ret
== -ENODATA
) {
245 dev_warn(rwtm
->dev
, "Board has no public key burned!\n");
246 } else if (ret
== -ENOSYS
) {
247 dev_notice(rwtm
->dev
,
248 "Firmware does not support the ECDSA_PUB_KEY command\n");
249 } else if (ret
< 0) {
252 u32
*s
= reply
->status
;
254 rwtm
->has_pubkey
= 1;
255 sprintf(rwtm
->pubkey
,
256 "%06x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
257 ret
, s
[0], s
[1], s
[2], s
[3], s
[4], s
[5], s
[6], s
[7],
258 s
[8], s
[9], s
[10], s
[11], s
[12], s
[13], s
[14], s
[15]);
264 static int check_get_random_support(struct mox_rwtm
*rwtm
)
266 struct armada_37xx_rwtm_tx_msg msg
;
269 msg
.command
= MBOX_CMD_GET_RANDOM
;
271 msg
.args
[1] = rwtm
->buf_phys
;
274 ret
= mbox_send_message(rwtm
->mbox
, &msg
);
278 if (!wait_for_completion_timeout(&rwtm
->cmd_done
, HZ
/ 2))
281 return mox_get_status(MBOX_CMD_GET_RANDOM
, rwtm
->reply
.retval
);
284 static int mox_hwrng_read(struct hwrng
*rng
, void *data
, size_t max
, bool wait
)
286 struct mox_rwtm
*rwtm
= (struct mox_rwtm
*) rng
->priv
;
287 struct armada_37xx_rwtm_tx_msg msg
;
293 msg
.command
= MBOX_CMD_GET_RANDOM
;
295 msg
.args
[1] = rwtm
->buf_phys
;
296 msg
.args
[2] = (max
+ 3) & ~3;
299 if (!mutex_trylock(&rwtm
->busy
))
302 mutex_lock(&rwtm
->busy
);
305 ret
= mbox_send_message(rwtm
->mbox
, &msg
);
309 ret
= wait_for_completion_interruptible(&rwtm
->cmd_done
);
313 ret
= mox_get_status(MBOX_CMD_GET_RANDOM
, rwtm
->reply
.retval
);
317 memcpy(data
, rwtm
->buf
, max
);
321 mutex_unlock(&rwtm
->busy
);
325 #ifdef CONFIG_DEBUG_FS
326 static int rwtm_debug_open(struct inode
*inode
, struct file
*file
)
328 file
->private_data
= inode
->i_private
;
330 return nonseekable_open(inode
, file
);
333 static ssize_t
do_sign_read(struct file
*file
, char __user
*buf
, size_t len
,
336 struct mox_rwtm
*rwtm
= file
->private_data
;
339 /* only allow one read, of 136 bytes, from position 0 */
346 if (!rwtm
->last_sig_done
)
349 /* 2 arrays of 17 32-bit words are 136 bytes */
350 ret
= simple_read_from_buffer(buf
, len
, ppos
, rwtm
->last_sig
, 136);
351 rwtm
->last_sig_done
= 0;
356 static ssize_t
do_sign_write(struct file
*file
, const char __user
*buf
,
357 size_t len
, loff_t
*ppos
)
359 struct mox_rwtm
*rwtm
= file
->private_data
;
360 struct armada_37xx_rwtm_rx_msg
*reply
= &rwtm
->reply
;
361 struct armada_37xx_rwtm_tx_msg msg
;
365 /* the input is a SHA-512 hash, so exactly 64 bytes have to be read */
369 /* if last result is not zero user has not read that information yet */
370 if (rwtm
->last_sig_done
)
373 if (!mutex_trylock(&rwtm
->busy
))
377 * Here we have to send:
378 * 1. Address of the input to sign.
379 * The input is an array of 17 32-bit words, the first (most
380 * significat) is 0, the rest 16 words are copied from the SHA-512
381 * hash given by the user and converted from BE to LE.
382 * 2. Address of the buffer where ECDSA signature value R shall be
383 * stored by the rWTM firmware.
384 * 3. Address of the buffer where ECDSA signature value S shall be
385 * stored by the rWTM firmware.
387 memset(rwtm
->buf
, 0, 4);
388 ret
= simple_write_to_buffer(rwtm
->buf
+ 4, 64, &dummy
, buf
, len
);
391 be32_to_cpu_array(rwtm
->buf
, rwtm
->buf
, 17);
393 msg
.command
= MBOX_CMD_SIGN
;
395 msg
.args
[1] = rwtm
->buf_phys
;
396 msg
.args
[2] = rwtm
->buf_phys
+ 68;
397 msg
.args
[3] = rwtm
->buf_phys
+ 2 * 68;
398 ret
= mbox_send_message(rwtm
->mbox
, &msg
);
402 ret
= wait_for_completion_interruptible(&rwtm
->cmd_done
);
406 ret
= MBOX_STS_VALUE(reply
->retval
);
407 if (MBOX_STS_ERROR(reply
->retval
) != MBOX_STS_SUCCESS
)
411 * Here we read the R and S values of the ECDSA signature
412 * computed by the rWTM firmware and convert their words from
415 memcpy(rwtm
->last_sig
, rwtm
->buf
+ 68, 136);
416 cpu_to_be32_array(rwtm
->last_sig
, rwtm
->last_sig
, 34);
417 rwtm
->last_sig_done
= 1;
419 mutex_unlock(&rwtm
->busy
);
422 mutex_unlock(&rwtm
->busy
);
426 static const struct file_operations do_sign_fops
= {
427 .owner
= THIS_MODULE
,
428 .open
= rwtm_debug_open
,
429 .read
= do_sign_read
,
430 .write
= do_sign_write
,
434 static int rwtm_register_debugfs(struct mox_rwtm
*rwtm
)
436 struct dentry
*root
, *entry
;
438 root
= debugfs_create_dir("turris-mox-rwtm", NULL
);
441 return PTR_ERR(root
);
443 entry
= debugfs_create_file_unsafe("do_sign", 0600, root
, rwtm
,
448 rwtm
->debugfs_root
= root
;
452 debugfs_remove_recursive(root
);
453 return PTR_ERR(entry
);
456 static void rwtm_unregister_debugfs(struct mox_rwtm
*rwtm
)
458 debugfs_remove_recursive(rwtm
->debugfs_root
);
461 static inline int rwtm_register_debugfs(struct mox_rwtm
*rwtm
)
466 static inline void rwtm_unregister_debugfs(struct mox_rwtm
*rwtm
)
471 static int turris_mox_rwtm_probe(struct platform_device
*pdev
)
473 struct mox_rwtm
*rwtm
;
474 struct device
*dev
= &pdev
->dev
;
477 rwtm
= devm_kzalloc(dev
, sizeof(*rwtm
), GFP_KERNEL
);
482 rwtm
->buf
= dmam_alloc_coherent(dev
, PAGE_SIZE
, &rwtm
->buf_phys
,
487 ret
= mox_kobj_create(rwtm
);
489 dev_err(dev
, "Cannot create turris-mox-rwtm kobject!\n");
493 ret
= sysfs_create_files(rwtm_to_kobj(rwtm
), mox_rwtm_attrs
);
495 dev_err(dev
, "Cannot create sysfs files!\n");
499 platform_set_drvdata(pdev
, rwtm
);
501 mutex_init(&rwtm
->busy
);
502 init_completion(&rwtm
->cmd_done
);
504 rwtm
->mbox_client
.dev
= dev
;
505 rwtm
->mbox_client
.rx_callback
= mox_rwtm_rx_callback
;
507 rwtm
->mbox
= mbox_request_channel(&rwtm
->mbox_client
, 0);
508 if (IS_ERR(rwtm
->mbox
)) {
509 ret
= PTR_ERR(rwtm
->mbox
);
510 if (ret
!= -EPROBE_DEFER
)
511 dev_err(dev
, "Cannot request mailbox channel: %i\n",
516 ret
= mox_get_board_info(rwtm
);
518 dev_warn(dev
, "Cannot read board information: %i\n", ret
);
520 ret
= check_get_random_support(rwtm
);
523 "Firmware does not support the GET_RANDOM command\n");
527 rwtm
->hwrng
.name
= DRIVER_NAME
"_hwrng";
528 rwtm
->hwrng
.read
= mox_hwrng_read
;
529 rwtm
->hwrng
.priv
= (unsigned long) rwtm
;
531 ret
= devm_hwrng_register(dev
, &rwtm
->hwrng
);
533 dev_err(dev
, "Cannot register HWRNG: %i\n", ret
);
537 ret
= rwtm_register_debugfs(rwtm
);
539 dev_err(dev
, "Failed creating debugfs entries: %i\n", ret
);
543 dev_info(dev
, "HWRNG successfully registered\n");
548 mbox_free_channel(rwtm
->mbox
);
550 sysfs_remove_files(rwtm_to_kobj(rwtm
), mox_rwtm_attrs
);
552 kobject_put(rwtm_to_kobj(rwtm
));
556 static void turris_mox_rwtm_remove(struct platform_device
*pdev
)
558 struct mox_rwtm
*rwtm
= platform_get_drvdata(pdev
);
560 rwtm_unregister_debugfs(rwtm
);
561 sysfs_remove_files(rwtm_to_kobj(rwtm
), mox_rwtm_attrs
);
562 kobject_put(rwtm_to_kobj(rwtm
));
563 mbox_free_channel(rwtm
->mbox
);
566 static const struct of_device_id turris_mox_rwtm_match
[] = {
567 { .compatible
= "cznic,turris-mox-rwtm", },
568 { .compatible
= "marvell,armada-3700-rwtm-firmware", },
572 MODULE_DEVICE_TABLE(of
, turris_mox_rwtm_match
);
574 static struct platform_driver turris_mox_rwtm_driver
= {
575 .probe
= turris_mox_rwtm_probe
,
576 .remove_new
= turris_mox_rwtm_remove
,
579 .of_match_table
= turris_mox_rwtm_match
,
582 module_platform_driver(turris_mox_rwtm_driver
);
584 MODULE_LICENSE("GPL v2");
585 MODULE_DESCRIPTION("Turris Mox rWTM firmware driver");
586 MODULE_AUTHOR("Marek Behun <kabel@kernel.org>");