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 <crypto/sha2.h>
9 #include <linux/align.h>
10 #include <linux/armada-37xx-rwtm-mailbox.h>
11 #include <linux/completion.h>
12 #include <linux/container_of.h>
13 #include <linux/debugfs.h>
14 #include <linux/device.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/err.h>
18 #include <linux/hw_random.h>
19 #include <linux/if_ether.h>
20 #include <linux/kobject.h>
21 #include <linux/mailbox_client.h>
22 #include <linux/minmax.h>
23 #include <linux/module.h>
24 #include <linux/mutex.h>
25 #include <linux/platform_device.h>
26 #include <linux/sizes.h>
27 #include <linux/sysfs.h>
28 #include <linux/types.h>
30 #define DRIVER_NAME "turris-mox-rwtm"
32 #define RWTM_DMA_BUFFER_SIZE SZ_4K
35 * The macros and constants below come from Turris Mox's rWTM firmware code.
36 * This firmware is open source and it's sources can be found at
37 * https://gitlab.labs.nic.cz/turris/mox-boot-builder/tree/master/wtmi.
40 #define MOX_ECC_NUMBER_WORDS 17
41 #define MOX_ECC_NUMBER_LEN (MOX_ECC_NUMBER_WORDS * sizeof(u32))
43 #define MOX_ECC_SIGNATURE_WORDS (2 * MOX_ECC_NUMBER_WORDS)
45 #define MBOX_STS_SUCCESS (0 << 30)
46 #define MBOX_STS_FAIL (1 << 30)
47 #define MBOX_STS_BADCMD (2 << 30)
48 #define MBOX_STS_ERROR(s) ((s) & (3 << 30))
49 #define MBOX_STS_VALUE(s) (((s) >> 10) & 0xfffff)
50 #define MBOX_STS_CMD(s) ((s) & 0x3ff)
53 MBOX_CMD_GET_RANDOM
= 1,
54 MBOX_CMD_BOARD_INFO
= 2,
55 MBOX_CMD_ECDSA_PUB_KEY
= 3,
60 MBOX_CMD_OTP_READ
= 7,
61 MBOX_CMD_OTP_WRITE
= 8,
65 * struct mox_rwtm - driver private data structure
66 * @mbox_client: rWTM mailbox client
67 * @mbox: rWTM mailbox channel
68 * @hwrng: RNG driver structure
69 * @reply: last mailbox reply, filled in receive callback
71 * @buf_phys: physical address of the DMA buffer
72 * @busy: mutex to protect mailbox command execution
73 * @cmd_done: command done completion
74 * @has_board_info: whether board information is present
75 * @serial_number: serial number of the device
76 * @board_version: board version / revision of the device
77 * @ram_size: RAM size of the device
78 * @mac_address1: first MAC address of the device
79 * @mac_address2: second MAC address of the device
80 * @has_pubkey: whether board ECDSA public key is present
81 * @pubkey: board ECDSA public key
82 * @last_sig: last ECDSA signature generated with board ECDSA private key
83 * @last_sig_done: whether the last ECDSA signing is complete
86 struct mbox_client mbox_client
;
87 struct mbox_chan
*mbox
;
90 struct armada_37xx_rwtm_rx_msg reply
;
96 struct completion cmd_done
;
100 int board_version
, ram_size
;
101 u8 mac_address1
[ETH_ALEN
], mac_address2
[ETH_ALEN
];
106 #ifdef CONFIG_DEBUG_FS
108 * Signature process. This is currently done via debugfs, because it
109 * does not conform to the sysfs standard "one file per attribute".
110 * It should be rewritten via crypto API once akcipher API is available
113 u32 last_sig
[MOX_ECC_SIGNATURE_WORDS
];
118 static inline struct device
*rwtm_dev(struct mox_rwtm
*rwtm
)
120 return rwtm
->mbox_client
.dev
;
123 #define MOX_ATTR_RO(name, format, cat) \
125 name##_show(struct device *dev, struct device_attribute *a, \
128 struct mox_rwtm *rwtm = dev_get_drvdata(dev); \
129 if (!rwtm->has_##cat) \
131 return sysfs_emit(buf, format, rwtm->name); \
133 static DEVICE_ATTR_RO(name)
135 MOX_ATTR_RO(serial_number
, "%016llX\n", board_info
);
136 MOX_ATTR_RO(board_version
, "%i\n", board_info
);
137 MOX_ATTR_RO(ram_size
, "%i\n", board_info
);
138 MOX_ATTR_RO(mac_address1
, "%pM\n", board_info
);
139 MOX_ATTR_RO(mac_address2
, "%pM\n", board_info
);
140 MOX_ATTR_RO(pubkey
, "%s\n", pubkey
);
142 static struct attribute
*turris_mox_rwtm_attrs
[] = {
143 &dev_attr_serial_number
.attr
,
144 &dev_attr_board_version
.attr
,
145 &dev_attr_ram_size
.attr
,
146 &dev_attr_mac_address1
.attr
,
147 &dev_attr_mac_address2
.attr
,
148 &dev_attr_pubkey
.attr
,
151 ATTRIBUTE_GROUPS(turris_mox_rwtm
);
153 static int mox_get_status(enum mbox_cmd cmd
, u32 retval
)
155 if (MBOX_STS_CMD(retval
) != cmd
)
157 else if (MBOX_STS_ERROR(retval
) == MBOX_STS_FAIL
)
158 return -(int)MBOX_STS_VALUE(retval
);
159 else if (MBOX_STS_ERROR(retval
) == MBOX_STS_BADCMD
)
161 else if (MBOX_STS_ERROR(retval
) != MBOX_STS_SUCCESS
)
164 return MBOX_STS_VALUE(retval
);
167 static void mox_rwtm_rx_callback(struct mbox_client
*cl
, void *data
)
169 struct mox_rwtm
*rwtm
= dev_get_drvdata(cl
->dev
);
170 struct armada_37xx_rwtm_rx_msg
*msg
= data
;
172 if (completion_done(&rwtm
->cmd_done
))
176 complete(&rwtm
->cmd_done
);
179 static int mox_rwtm_exec(struct mox_rwtm
*rwtm
, enum mbox_cmd cmd
,
180 struct armada_37xx_rwtm_tx_msg
*msg
,
183 struct armada_37xx_rwtm_tx_msg _msg
= {};
191 ret
= mbox_send_message(rwtm
->mbox
, msg
);
196 ret
= wait_for_completion_interruptible(&rwtm
->cmd_done
);
200 if (!wait_for_completion_timeout(&rwtm
->cmd_done
, HZ
/ 2))
204 return mox_get_status(cmd
, rwtm
->reply
.retval
);
207 static void reply_to_mac_addr(u8
*mac
, u32 t1
, u32 t2
)
217 static int mox_get_board_info(struct mox_rwtm
*rwtm
)
219 struct device
*dev
= rwtm_dev(rwtm
);
220 struct armada_37xx_rwtm_rx_msg
*reply
= &rwtm
->reply
;
223 ret
= mox_rwtm_exec(rwtm
, MBOX_CMD_BOARD_INFO
, NULL
, false);
224 if (ret
== -ENODATA
) {
226 "Board does not have manufacturing information burned!\n");
227 } else if (ret
== -EOPNOTSUPP
) {
229 "Firmware does not support the BOARD_INFO command\n");
230 } else if (ret
< 0) {
233 rwtm
->serial_number
= reply
->status
[1];
234 rwtm
->serial_number
<<= 32;
235 rwtm
->serial_number
|= reply
->status
[0];
236 rwtm
->board_version
= reply
->status
[2];
237 rwtm
->ram_size
= reply
->status
[3];
238 reply_to_mac_addr(rwtm
->mac_address1
, reply
->status
[4],
240 reply_to_mac_addr(rwtm
->mac_address2
, reply
->status
[6],
242 rwtm
->has_board_info
= true;
244 pr_info("Turris Mox serial number %016llX\n",
245 rwtm
->serial_number
);
246 pr_info(" board version %i\n", rwtm
->board_version
);
247 pr_info(" burned RAM size %i MiB\n", rwtm
->ram_size
);
250 ret
= mox_rwtm_exec(rwtm
, MBOX_CMD_ECDSA_PUB_KEY
, NULL
, false);
251 if (ret
== -ENODATA
) {
252 dev_warn(dev
, "Board has no public key burned!\n");
253 } else if (ret
== -EOPNOTSUPP
) {
255 "Firmware does not support the ECDSA_PUB_KEY command\n");
256 } else if (ret
< 0) {
259 u32
*s
= reply
->status
;
261 rwtm
->has_pubkey
= true;
262 sprintf(rwtm
->pubkey
,
263 "%06x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
264 ret
, s
[0], s
[1], s
[2], s
[3], s
[4], s
[5], s
[6], s
[7],
265 s
[8], s
[9], s
[10], s
[11], s
[12], s
[13], s
[14], s
[15]);
271 static int check_get_random_support(struct mox_rwtm
*rwtm
)
273 struct armada_37xx_rwtm_tx_msg msg
= {
274 .args
= { 1, rwtm
->buf_phys
, 4 },
277 return mox_rwtm_exec(rwtm
, MBOX_CMD_GET_RANDOM
, &msg
, false);
280 static int mox_hwrng_read(struct hwrng
*rng
, void *data
, size_t max
, bool wait
)
282 struct mox_rwtm
*rwtm
= container_of(rng
, struct mox_rwtm
, hwrng
);
283 struct armada_37xx_rwtm_tx_msg msg
= {
284 .args
= { 1, rwtm
->buf_phys
, ALIGN(max
, 4) },
288 max
= min(max
, RWTM_DMA_BUFFER_SIZE
);
291 if (!mutex_trylock(&rwtm
->busy
))
294 mutex_lock(&rwtm
->busy
);
297 ret
= mox_rwtm_exec(rwtm
, MBOX_CMD_GET_RANDOM
, &msg
, true);
301 memcpy(data
, rwtm
->buf
, max
);
305 mutex_unlock(&rwtm
->busy
);
309 #ifdef CONFIG_DEBUG_FS
310 static int rwtm_debug_open(struct inode
*inode
, struct file
*file
)
312 file
->private_data
= inode
->i_private
;
314 return nonseekable_open(inode
, file
);
317 static ssize_t
do_sign_read(struct file
*file
, char __user
*buf
, size_t len
,
320 struct mox_rwtm
*rwtm
= file
->private_data
;
323 /* only allow one read, of whole signature, from position 0 */
327 if (len
< sizeof(rwtm
->last_sig
))
330 if (!rwtm
->last_sig_done
)
333 ret
= simple_read_from_buffer(buf
, len
, ppos
, rwtm
->last_sig
,
334 sizeof(rwtm
->last_sig
));
335 rwtm
->last_sig_done
= false;
340 static ssize_t
do_sign_write(struct file
*file
, const char __user
*buf
,
341 size_t len
, loff_t
*ppos
)
343 struct mox_rwtm
*rwtm
= file
->private_data
;
344 struct armada_37xx_rwtm_tx_msg msg
;
348 if (len
!= SHA512_DIGEST_SIZE
)
351 /* if last result is not zero user has not read that information yet */
352 if (rwtm
->last_sig_done
)
355 if (!mutex_trylock(&rwtm
->busy
))
359 * Here we have to send:
360 * 1. Address of the input to sign.
361 * The input is an array of 17 32-bit words, the first (most
362 * significat) is 0, the rest 16 words are copied from the SHA-512
363 * hash given by the user and converted from BE to LE.
364 * 2. Address of the buffer where ECDSA signature value R shall be
365 * stored by the rWTM firmware.
366 * 3. Address of the buffer where ECDSA signature value S shall be
367 * stored by the rWTM firmware.
369 memset(rwtm
->buf
, 0, sizeof(u32
));
370 ret
= simple_write_to_buffer(rwtm
->buf
+ sizeof(u32
),
371 SHA512_DIGEST_SIZE
, &dummy
, buf
, len
);
374 be32_to_cpu_array(rwtm
->buf
, rwtm
->buf
, MOX_ECC_NUMBER_WORDS
);
377 msg
.args
[1] = rwtm
->buf_phys
;
378 msg
.args
[2] = rwtm
->buf_phys
+ MOX_ECC_NUMBER_LEN
;
379 msg
.args
[3] = rwtm
->buf_phys
+ 2 * MOX_ECC_NUMBER_LEN
;
381 ret
= mox_rwtm_exec(rwtm
, MBOX_CMD_SIGN
, &msg
, true);
386 * Here we read the R and S values of the ECDSA signature
387 * computed by the rWTM firmware and convert their words from
390 memcpy(rwtm
->last_sig
, rwtm
->buf
+ MOX_ECC_NUMBER_LEN
,
391 sizeof(rwtm
->last_sig
));
392 cpu_to_be32_array(rwtm
->last_sig
, rwtm
->last_sig
,
393 MOX_ECC_SIGNATURE_WORDS
);
394 rwtm
->last_sig_done
= true;
396 mutex_unlock(&rwtm
->busy
);
399 mutex_unlock(&rwtm
->busy
);
403 static const struct file_operations do_sign_fops
= {
404 .owner
= THIS_MODULE
,
405 .open
= rwtm_debug_open
,
406 .read
= do_sign_read
,
407 .write
= do_sign_write
,
410 static void rwtm_debugfs_release(void *root
)
412 debugfs_remove_recursive(root
);
415 static void rwtm_register_debugfs(struct mox_rwtm
*rwtm
)
419 root
= debugfs_create_dir("turris-mox-rwtm", NULL
);
421 debugfs_create_file_unsafe("do_sign", 0600, root
, rwtm
, &do_sign_fops
);
423 devm_add_action_or_reset(rwtm_dev(rwtm
), rwtm_debugfs_release
, root
);
426 static inline void rwtm_register_debugfs(struct mox_rwtm
*rwtm
)
431 static void rwtm_devm_mbox_release(void *mbox
)
433 mbox_free_channel(mbox
);
436 static void rwtm_firmware_symlink_drop(void *parent
)
438 sysfs_remove_link(parent
, DRIVER_NAME
);
441 static int turris_mox_rwtm_probe(struct platform_device
*pdev
)
443 struct mox_rwtm
*rwtm
;
444 struct device
*dev
= &pdev
->dev
;
447 rwtm
= devm_kzalloc(dev
, sizeof(*rwtm
), GFP_KERNEL
);
451 rwtm
->buf
= dmam_alloc_coherent(dev
, RWTM_DMA_BUFFER_SIZE
,
452 &rwtm
->buf_phys
, GFP_KERNEL
);
456 platform_set_drvdata(pdev
, rwtm
);
458 ret
= devm_mutex_init(dev
, &rwtm
->busy
);
462 init_completion(&rwtm
->cmd_done
);
464 rwtm
->mbox_client
.dev
= dev
;
465 rwtm
->mbox_client
.rx_callback
= mox_rwtm_rx_callback
;
467 rwtm
->mbox
= mbox_request_channel(&rwtm
->mbox_client
, 0);
468 if (IS_ERR(rwtm
->mbox
))
469 return dev_err_probe(dev
, PTR_ERR(rwtm
->mbox
),
470 "Cannot request mailbox channel!\n");
472 ret
= devm_add_action_or_reset(dev
, rwtm_devm_mbox_release
, rwtm
->mbox
);
476 ret
= mox_get_board_info(rwtm
);
478 dev_warn(dev
, "Cannot read board information: %i\n", ret
);
480 ret
= check_get_random_support(rwtm
);
483 "Firmware does not support the GET_RANDOM command\n");
487 rwtm
->hwrng
.name
= DRIVER_NAME
"_hwrng";
488 rwtm
->hwrng
.read
= mox_hwrng_read
;
490 ret
= devm_hwrng_register(dev
, &rwtm
->hwrng
);
492 return dev_err_probe(dev
, ret
, "Cannot register HWRNG!\n");
494 rwtm_register_debugfs(rwtm
);
496 dev_info(dev
, "HWRNG successfully registered\n");
499 * For sysfs ABI compatibility, create symlink
500 * /sys/firmware/turris-mox-rwtm to this device's sysfs directory.
502 ret
= sysfs_create_link(firmware_kobj
, &dev
->kobj
, DRIVER_NAME
);
504 devm_add_action_or_reset(dev
, rwtm_firmware_symlink_drop
,
510 static const struct of_device_id turris_mox_rwtm_match
[] = {
511 { .compatible
= "cznic,turris-mox-rwtm", },
512 { .compatible
= "marvell,armada-3700-rwtm-firmware", },
516 MODULE_DEVICE_TABLE(of
, turris_mox_rwtm_match
);
518 static struct platform_driver turris_mox_rwtm_driver
= {
519 .probe
= turris_mox_rwtm_probe
,
522 .of_match_table
= turris_mox_rwtm_match
,
523 .dev_groups
= turris_mox_rwtm_groups
,
526 module_platform_driver(turris_mox_rwtm_driver
);
528 MODULE_LICENSE("GPL v2");
529 MODULE_DESCRIPTION("Turris Mox rWTM firmware driver");
530 MODULE_AUTHOR("Marek Behun <kabel@kernel.org>");