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 mbox_client mbox_client
;
66 struct mbox_chan
*mbox
;
69 struct armada_37xx_rwtm_rx_msg reply
;
75 struct completion cmd_done
;
77 /* board information */
80 int board_version
, ram_size
;
81 u8 mac_address1
[ETH_ALEN
], mac_address2
[ETH_ALEN
];
83 /* public key burned in eFuse */
87 #ifdef CONFIG_DEBUG_FS
89 * Signature process. This is currently done via debugfs, because it
90 * does not conform to the sysfs standard "one file per attribute".
91 * It should be rewritten via crypto API once akcipher API is available
94 u32 last_sig
[MOX_ECC_SIGNATURE_WORDS
];
99 static inline struct device
*rwtm_dev(struct mox_rwtm
*rwtm
)
101 return rwtm
->mbox_client
.dev
;
104 #define MOX_ATTR_RO(name, format, cat) \
106 name##_show(struct device *dev, struct device_attribute *a, \
109 struct mox_rwtm *rwtm = dev_get_drvdata(dev); \
110 if (!rwtm->has_##cat) \
112 return sysfs_emit(buf, format, rwtm->name); \
114 static DEVICE_ATTR_RO(name)
116 MOX_ATTR_RO(serial_number
, "%016llX\n", board_info
);
117 MOX_ATTR_RO(board_version
, "%i\n", board_info
);
118 MOX_ATTR_RO(ram_size
, "%i\n", board_info
);
119 MOX_ATTR_RO(mac_address1
, "%pM\n", board_info
);
120 MOX_ATTR_RO(mac_address2
, "%pM\n", board_info
);
121 MOX_ATTR_RO(pubkey
, "%s\n", pubkey
);
123 static struct attribute
*turris_mox_rwtm_attrs
[] = {
124 &dev_attr_serial_number
.attr
,
125 &dev_attr_board_version
.attr
,
126 &dev_attr_ram_size
.attr
,
127 &dev_attr_mac_address1
.attr
,
128 &dev_attr_mac_address2
.attr
,
129 &dev_attr_pubkey
.attr
,
132 ATTRIBUTE_GROUPS(turris_mox_rwtm
);
134 static int mox_get_status(enum mbox_cmd cmd
, u32 retval
)
136 if (MBOX_STS_CMD(retval
) != cmd
)
138 else if (MBOX_STS_ERROR(retval
) == MBOX_STS_FAIL
)
139 return -(int)MBOX_STS_VALUE(retval
);
140 else if (MBOX_STS_ERROR(retval
) == MBOX_STS_BADCMD
)
142 else if (MBOX_STS_ERROR(retval
) != MBOX_STS_SUCCESS
)
145 return MBOX_STS_VALUE(retval
);
148 static void mox_rwtm_rx_callback(struct mbox_client
*cl
, void *data
)
150 struct mox_rwtm
*rwtm
= dev_get_drvdata(cl
->dev
);
151 struct armada_37xx_rwtm_rx_msg
*msg
= data
;
153 if (completion_done(&rwtm
->cmd_done
))
157 complete(&rwtm
->cmd_done
);
160 static int mox_rwtm_exec(struct mox_rwtm
*rwtm
, enum mbox_cmd cmd
,
161 struct armada_37xx_rwtm_tx_msg
*msg
,
164 struct armada_37xx_rwtm_tx_msg _msg
= {};
172 ret
= mbox_send_message(rwtm
->mbox
, msg
);
177 ret
= wait_for_completion_interruptible(&rwtm
->cmd_done
);
181 if (!wait_for_completion_timeout(&rwtm
->cmd_done
, HZ
/ 2))
185 return mox_get_status(cmd
, rwtm
->reply
.retval
);
188 static void reply_to_mac_addr(u8
*mac
, u32 t1
, u32 t2
)
198 static int mox_get_board_info(struct mox_rwtm
*rwtm
)
200 struct device
*dev
= rwtm_dev(rwtm
);
201 struct armada_37xx_rwtm_rx_msg
*reply
= &rwtm
->reply
;
204 ret
= mox_rwtm_exec(rwtm
, MBOX_CMD_BOARD_INFO
, NULL
, false);
205 if (ret
== -ENODATA
) {
207 "Board does not have manufacturing information burned!\n");
208 } else if (ret
== -EOPNOTSUPP
) {
210 "Firmware does not support the BOARD_INFO command\n");
211 } else if (ret
< 0) {
214 rwtm
->serial_number
= reply
->status
[1];
215 rwtm
->serial_number
<<= 32;
216 rwtm
->serial_number
|= reply
->status
[0];
217 rwtm
->board_version
= reply
->status
[2];
218 rwtm
->ram_size
= reply
->status
[3];
219 reply_to_mac_addr(rwtm
->mac_address1
, reply
->status
[4],
221 reply_to_mac_addr(rwtm
->mac_address2
, reply
->status
[6],
223 rwtm
->has_board_info
= true;
225 pr_info("Turris Mox serial number %016llX\n",
226 rwtm
->serial_number
);
227 pr_info(" board version %i\n", rwtm
->board_version
);
228 pr_info(" burned RAM size %i MiB\n", rwtm
->ram_size
);
231 ret
= mox_rwtm_exec(rwtm
, MBOX_CMD_ECDSA_PUB_KEY
, NULL
, false);
232 if (ret
== -ENODATA
) {
233 dev_warn(dev
, "Board has no public key burned!\n");
234 } else if (ret
== -EOPNOTSUPP
) {
236 "Firmware does not support the ECDSA_PUB_KEY command\n");
237 } else if (ret
< 0) {
240 u32
*s
= reply
->status
;
242 rwtm
->has_pubkey
= true;
243 sprintf(rwtm
->pubkey
,
244 "%06x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
245 ret
, s
[0], s
[1], s
[2], s
[3], s
[4], s
[5], s
[6], s
[7],
246 s
[8], s
[9], s
[10], s
[11], s
[12], s
[13], s
[14], s
[15]);
252 static int check_get_random_support(struct mox_rwtm
*rwtm
)
254 struct armada_37xx_rwtm_tx_msg msg
= {
255 .args
= { 1, rwtm
->buf_phys
, 4 },
258 return mox_rwtm_exec(rwtm
, MBOX_CMD_GET_RANDOM
, &msg
, false);
261 static int mox_hwrng_read(struct hwrng
*rng
, void *data
, size_t max
, bool wait
)
263 struct mox_rwtm
*rwtm
= container_of(rng
, struct mox_rwtm
, hwrng
);
264 struct armada_37xx_rwtm_tx_msg msg
= {
265 .args
= { 1, rwtm
->buf_phys
, ALIGN(max
, 4) },
269 max
= min(max
, RWTM_DMA_BUFFER_SIZE
);
272 if (!mutex_trylock(&rwtm
->busy
))
275 mutex_lock(&rwtm
->busy
);
278 ret
= mox_rwtm_exec(rwtm
, MBOX_CMD_GET_RANDOM
, &msg
, true);
282 memcpy(data
, rwtm
->buf
, max
);
286 mutex_unlock(&rwtm
->busy
);
290 #ifdef CONFIG_DEBUG_FS
291 static int rwtm_debug_open(struct inode
*inode
, struct file
*file
)
293 file
->private_data
= inode
->i_private
;
295 return nonseekable_open(inode
, file
);
298 static ssize_t
do_sign_read(struct file
*file
, char __user
*buf
, size_t len
,
301 struct mox_rwtm
*rwtm
= file
->private_data
;
304 /* only allow one read, of whole signature, from position 0 */
308 if (len
< sizeof(rwtm
->last_sig
))
311 if (!rwtm
->last_sig_done
)
314 ret
= simple_read_from_buffer(buf
, len
, ppos
, rwtm
->last_sig
,
315 sizeof(rwtm
->last_sig
));
316 rwtm
->last_sig_done
= false;
321 static ssize_t
do_sign_write(struct file
*file
, const char __user
*buf
,
322 size_t len
, loff_t
*ppos
)
324 struct mox_rwtm
*rwtm
= file
->private_data
;
325 struct armada_37xx_rwtm_tx_msg msg
;
329 if (len
!= SHA512_DIGEST_SIZE
)
332 /* if last result is not zero user has not read that information yet */
333 if (rwtm
->last_sig_done
)
336 if (!mutex_trylock(&rwtm
->busy
))
340 * Here we have to send:
341 * 1. Address of the input to sign.
342 * The input is an array of 17 32-bit words, the first (most
343 * significat) is 0, the rest 16 words are copied from the SHA-512
344 * hash given by the user and converted from BE to LE.
345 * 2. Address of the buffer where ECDSA signature value R shall be
346 * stored by the rWTM firmware.
347 * 3. Address of the buffer where ECDSA signature value S shall be
348 * stored by the rWTM firmware.
350 memset(rwtm
->buf
, 0, sizeof(u32
));
351 ret
= simple_write_to_buffer(rwtm
->buf
+ sizeof(u32
),
352 SHA512_DIGEST_SIZE
, &dummy
, buf
, len
);
355 be32_to_cpu_array(rwtm
->buf
, rwtm
->buf
, MOX_ECC_NUMBER_WORDS
);
358 msg
.args
[1] = rwtm
->buf_phys
;
359 msg
.args
[2] = rwtm
->buf_phys
+ MOX_ECC_NUMBER_LEN
;
360 msg
.args
[3] = rwtm
->buf_phys
+ 2 * MOX_ECC_NUMBER_LEN
;
362 ret
= mox_rwtm_exec(rwtm
, MBOX_CMD_SIGN
, &msg
, true);
367 * Here we read the R and S values of the ECDSA signature
368 * computed by the rWTM firmware and convert their words from
371 memcpy(rwtm
->last_sig
, rwtm
->buf
+ MOX_ECC_NUMBER_LEN
,
372 sizeof(rwtm
->last_sig
));
373 cpu_to_be32_array(rwtm
->last_sig
, rwtm
->last_sig
,
374 MOX_ECC_SIGNATURE_WORDS
);
375 rwtm
->last_sig_done
= true;
377 mutex_unlock(&rwtm
->busy
);
380 mutex_unlock(&rwtm
->busy
);
384 static const struct file_operations do_sign_fops
= {
385 .owner
= THIS_MODULE
,
386 .open
= rwtm_debug_open
,
387 .read
= do_sign_read
,
388 .write
= do_sign_write
,
391 static void rwtm_debugfs_release(void *root
)
393 debugfs_remove_recursive(root
);
396 static void rwtm_register_debugfs(struct mox_rwtm
*rwtm
)
400 root
= debugfs_create_dir("turris-mox-rwtm", NULL
);
402 debugfs_create_file_unsafe("do_sign", 0600, root
, rwtm
, &do_sign_fops
);
404 devm_add_action_or_reset(rwtm_dev(rwtm
), rwtm_debugfs_release
, root
);
407 static inline void rwtm_register_debugfs(struct mox_rwtm
*rwtm
)
412 static void rwtm_devm_mbox_release(void *mbox
)
414 mbox_free_channel(mbox
);
417 static void rwtm_firmware_symlink_drop(void *parent
)
419 sysfs_remove_link(parent
, DRIVER_NAME
);
422 static int turris_mox_rwtm_probe(struct platform_device
*pdev
)
424 struct mox_rwtm
*rwtm
;
425 struct device
*dev
= &pdev
->dev
;
428 rwtm
= devm_kzalloc(dev
, sizeof(*rwtm
), GFP_KERNEL
);
432 rwtm
->buf
= dmam_alloc_coherent(dev
, RWTM_DMA_BUFFER_SIZE
,
433 &rwtm
->buf_phys
, GFP_KERNEL
);
437 platform_set_drvdata(pdev
, rwtm
);
439 ret
= devm_mutex_init(dev
, &rwtm
->busy
);
443 init_completion(&rwtm
->cmd_done
);
445 rwtm
->mbox_client
.dev
= dev
;
446 rwtm
->mbox_client
.rx_callback
= mox_rwtm_rx_callback
;
448 rwtm
->mbox
= mbox_request_channel(&rwtm
->mbox_client
, 0);
449 if (IS_ERR(rwtm
->mbox
))
450 return dev_err_probe(dev
, PTR_ERR(rwtm
->mbox
),
451 "Cannot request mailbox channel!\n");
453 ret
= devm_add_action_or_reset(dev
, rwtm_devm_mbox_release
, rwtm
->mbox
);
457 ret
= mox_get_board_info(rwtm
);
459 dev_warn(dev
, "Cannot read board information: %i\n", ret
);
461 ret
= check_get_random_support(rwtm
);
464 "Firmware does not support the GET_RANDOM command\n");
468 rwtm
->hwrng
.name
= DRIVER_NAME
"_hwrng";
469 rwtm
->hwrng
.read
= mox_hwrng_read
;
471 ret
= devm_hwrng_register(dev
, &rwtm
->hwrng
);
473 return dev_err_probe(dev
, ret
, "Cannot register HWRNG!\n");
475 rwtm_register_debugfs(rwtm
);
477 dev_info(dev
, "HWRNG successfully registered\n");
480 * For sysfs ABI compatibility, create symlink
481 * /sys/firmware/turris-mox-rwtm to this device's sysfs directory.
483 ret
= sysfs_create_link(firmware_kobj
, &dev
->kobj
, DRIVER_NAME
);
485 devm_add_action_or_reset(dev
, rwtm_firmware_symlink_drop
,
491 static const struct of_device_id turris_mox_rwtm_match
[] = {
492 { .compatible
= "cznic,turris-mox-rwtm", },
493 { .compatible
= "marvell,armada-3700-rwtm-firmware", },
497 MODULE_DEVICE_TABLE(of
, turris_mox_rwtm_match
);
499 static struct platform_driver turris_mox_rwtm_driver
= {
500 .probe
= turris_mox_rwtm_probe
,
503 .of_match_table
= turris_mox_rwtm_match
,
504 .dev_groups
= turris_mox_rwtm_groups
,
507 module_platform_driver(turris_mox_rwtm_driver
);
509 MODULE_LICENSE("GPL v2");
510 MODULE_DESCRIPTION("Turris Mox rWTM firmware driver");
511 MODULE_AUTHOR("Marek Behun <kabel@kernel.org>");