1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Turris Mox rWTM firmware driver 4 * 5 * Copyright (C) 2019, 2024, 2025 Marek Behún <kabel@kernel.org> 6 */ 7 8 #include <crypto/sha2.h> 9 #include <linux/align.h> 10 #include <linux/armada-37xx-rwtm-mailbox.h> 11 #include <linux/cleanup.h> 12 #include <linux/completion.h> 13 #include <linux/container_of.h> 14 #include <linux/device.h> 15 #include <linux/dma-mapping.h> 16 #include <linux/err.h> 17 #include <linux/hw_random.h> 18 #include <linux/if_ether.h> 19 #include <linux/key.h> 20 #include <linux/kobject.h> 21 #include <linux/mailbox_client.h> 22 #include <linux/math.h> 23 #include <linux/minmax.h> 24 #include <linux/module.h> 25 #include <linux/mutex.h> 26 #include <linux/platform_device.h> 27 #include <linux/sizes.h> 28 #include <linux/sysfs.h> 29 #include <linux/turris-signing-key.h> 30 #include <linux/types.h> 31 32 #define DRIVER_NAME "turris-mox-rwtm" 33 34 #define RWTM_DMA_BUFFER_SIZE SZ_4K 35 36 /* 37 * The macros and constants below come from Turris Mox's rWTM firmware code. 38 * This firmware is open source and it's sources can be found at 39 * https://gitlab.labs.nic.cz/turris/mox-boot-builder/tree/master/wtmi. 40 */ 41 42 enum { 43 MOX_ECC_NUM_BITS = 521, 44 MOX_ECC_NUM_LEN = DIV_ROUND_UP(MOX_ECC_NUM_BITS, 8), 45 MOX_ECC_NUM_WORDS = DIV_ROUND_UP(MOX_ECC_NUM_BITS, 32), 46 MOX_ECC_SIG_LEN = 2 * MOX_ECC_NUM_LEN, 47 MOX_ECC_PUBKEY_LEN = 1 + MOX_ECC_NUM_LEN, 48 }; 49 50 #define MBOX_STS_SUCCESS (0 << 30) 51 #define MBOX_STS_FAIL (1 << 30) 52 #define MBOX_STS_BADCMD (2 << 30) 53 #define MBOX_STS_ERROR(s) ((s) & (3 << 30)) 54 #define MBOX_STS_VALUE(s) (((s) >> 10) & 0xfffff) 55 #define MBOX_STS_CMD(s) ((s) & 0x3ff) 56 57 enum mbox_cmd { 58 MBOX_CMD_GET_RANDOM = 1, 59 MBOX_CMD_BOARD_INFO = 2, 60 MBOX_CMD_ECDSA_PUB_KEY = 3, 61 MBOX_CMD_HASH = 4, 62 MBOX_CMD_SIGN = 5, 63 MBOX_CMD_VERIFY = 6, 64 65 MBOX_CMD_OTP_READ = 7, 66 MBOX_CMD_OTP_WRITE = 8, 67 }; 68 69 /** 70 * struct mox_rwtm - driver private data structure 71 * @mbox_client: rWTM mailbox client 72 * @mbox: rWTM mailbox channel 73 * @hwrng: RNG driver structure 74 * @reply: last mailbox reply, filled in receive callback 75 * @buf: DMA buffer 76 * @buf_phys: physical address of the DMA buffer 77 * @busy: mutex to protect mailbox command execution 78 * @cmd_done: command done completion 79 * @has_board_info: whether board information is present 80 * @serial_number: serial number of the device 81 * @board_version: board version / revision of the device 82 * @ram_size: RAM size of the device 83 * @mac_address1: first MAC address of the device 84 * @mac_address2: second MAC address of the device 85 * @pubkey: board ECDSA public key 86 */ 87 struct mox_rwtm { 88 struct mbox_client mbox_client; 89 struct mbox_chan *mbox; 90 struct hwrng hwrng; 91 92 struct armada_37xx_rwtm_rx_msg reply; 93 94 void *buf; 95 dma_addr_t buf_phys; 96 97 struct mutex busy; 98 struct completion cmd_done; 99 100 bool has_board_info; 101 u64 serial_number; 102 int board_version, ram_size; 103 u8 mac_address1[ETH_ALEN], mac_address2[ETH_ALEN]; 104 105 #ifdef CONFIG_TURRIS_MOX_RWTM_KEYCTL 106 u8 pubkey[MOX_ECC_PUBKEY_LEN]; 107 #endif 108 }; 109 110 static inline struct device *rwtm_dev(struct mox_rwtm *rwtm) 111 { 112 return rwtm->mbox_client.dev; 113 } 114 115 #define MOX_ATTR_RO(name, format) \ 116 static ssize_t \ 117 name##_show(struct device *dev, struct device_attribute *a, \ 118 char *buf) \ 119 { \ 120 struct mox_rwtm *rwtm = dev_get_drvdata(dev); \ 121 if (!rwtm->has_board_info) \ 122 return -ENODATA; \ 123 return sysfs_emit(buf, format, rwtm->name); \ 124 } \ 125 static DEVICE_ATTR_RO(name) 126 127 MOX_ATTR_RO(serial_number, "%016llX\n"); 128 MOX_ATTR_RO(board_version, "%i\n"); 129 MOX_ATTR_RO(ram_size, "%i\n"); 130 MOX_ATTR_RO(mac_address1, "%pM\n"); 131 MOX_ATTR_RO(mac_address2, "%pM\n"); 132 133 static struct attribute *turris_mox_rwtm_attrs[] = { 134 &dev_attr_serial_number.attr, 135 &dev_attr_board_version.attr, 136 &dev_attr_ram_size.attr, 137 &dev_attr_mac_address1.attr, 138 &dev_attr_mac_address2.attr, 139 NULL 140 }; 141 ATTRIBUTE_GROUPS(turris_mox_rwtm); 142 143 static int mox_get_status(enum mbox_cmd cmd, u32 retval) 144 { 145 if (MBOX_STS_CMD(retval) != cmd) 146 return -EIO; 147 else if (MBOX_STS_ERROR(retval) == MBOX_STS_FAIL) 148 return -(int)MBOX_STS_VALUE(retval); 149 else if (MBOX_STS_ERROR(retval) == MBOX_STS_BADCMD) 150 return -EOPNOTSUPP; 151 else if (MBOX_STS_ERROR(retval) != MBOX_STS_SUCCESS) 152 return -EIO; 153 else 154 return MBOX_STS_VALUE(retval); 155 } 156 157 static void mox_rwtm_rx_callback(struct mbox_client *cl, void *data) 158 { 159 struct mox_rwtm *rwtm = dev_get_drvdata(cl->dev); 160 struct armada_37xx_rwtm_rx_msg *msg = data; 161 162 if (completion_done(&rwtm->cmd_done)) 163 return; 164 165 rwtm->reply = *msg; 166 complete(&rwtm->cmd_done); 167 } 168 169 static int mox_rwtm_exec(struct mox_rwtm *rwtm, enum mbox_cmd cmd, 170 struct armada_37xx_rwtm_tx_msg *msg, 171 bool interruptible) 172 { 173 struct armada_37xx_rwtm_tx_msg _msg = {}; 174 int ret; 175 176 if (!msg) 177 msg = &_msg; 178 179 msg->command = cmd; 180 181 ret = mbox_send_message(rwtm->mbox, msg); 182 if (ret < 0) 183 return ret; 184 185 if (interruptible) { 186 ret = wait_for_completion_interruptible(&rwtm->cmd_done); 187 if (ret < 0) 188 return ret; 189 } else { 190 if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2)) 191 return -ETIMEDOUT; 192 } 193 194 return mox_get_status(cmd, rwtm->reply.retval); 195 } 196 197 static void reply_to_mac_addr(u8 *mac, u32 t1, u32 t2) 198 { 199 mac[0] = t1 >> 8; 200 mac[1] = t1; 201 mac[2] = t2 >> 24; 202 mac[3] = t2 >> 16; 203 mac[4] = t2 >> 8; 204 mac[5] = t2; 205 } 206 207 static int mox_get_board_info(struct mox_rwtm *rwtm) 208 { 209 struct device *dev = rwtm_dev(rwtm); 210 struct armada_37xx_rwtm_rx_msg *reply = &rwtm->reply; 211 int ret; 212 213 ret = mox_rwtm_exec(rwtm, MBOX_CMD_BOARD_INFO, NULL, false); 214 if (ret == -ENODATA) { 215 dev_warn(dev, 216 "Board does not have manufacturing information burned!\n"); 217 } else if (ret == -EOPNOTSUPP) { 218 dev_notice(dev, 219 "Firmware does not support the BOARD_INFO command\n"); 220 } else if (ret < 0) { 221 return ret; 222 } else { 223 rwtm->serial_number = reply->status[1]; 224 rwtm->serial_number <<= 32; 225 rwtm->serial_number |= reply->status[0]; 226 rwtm->board_version = reply->status[2]; 227 rwtm->ram_size = reply->status[3]; 228 reply_to_mac_addr(rwtm->mac_address1, reply->status[4], 229 reply->status[5]); 230 reply_to_mac_addr(rwtm->mac_address2, reply->status[6], 231 reply->status[7]); 232 rwtm->has_board_info = true; 233 234 pr_info("Turris Mox serial number %016llX\n", 235 rwtm->serial_number); 236 pr_info(" board version %i\n", rwtm->board_version); 237 pr_info(" burned RAM size %i MiB\n", rwtm->ram_size); 238 } 239 240 return 0; 241 } 242 243 static int check_get_random_support(struct mox_rwtm *rwtm) 244 { 245 struct armada_37xx_rwtm_tx_msg msg = { 246 .args = { 1, rwtm->buf_phys, 4 }, 247 }; 248 249 return mox_rwtm_exec(rwtm, MBOX_CMD_GET_RANDOM, &msg, false); 250 } 251 252 static int mox_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) 253 { 254 struct mox_rwtm *rwtm = container_of(rng, struct mox_rwtm, hwrng); 255 struct armada_37xx_rwtm_tx_msg msg = { 256 .args = { 1, rwtm->buf_phys, ALIGN(max, 4) }, 257 }; 258 int ret; 259 260 max = min(max, RWTM_DMA_BUFFER_SIZE); 261 262 if (!wait) { 263 if (!mutex_trylock(&rwtm->busy)) 264 return -EBUSY; 265 } else { 266 mutex_lock(&rwtm->busy); 267 } 268 269 ret = mox_rwtm_exec(rwtm, MBOX_CMD_GET_RANDOM, &msg, true); 270 if (ret < 0) 271 goto unlock_mutex; 272 273 memcpy(data, rwtm->buf, max); 274 ret = max; 275 276 unlock_mutex: 277 mutex_unlock(&rwtm->busy); 278 return ret; 279 } 280 281 #ifdef CONFIG_TURRIS_MOX_RWTM_KEYCTL 282 283 static void mox_ecc_number_to_bin(void *dst, const u32 *src) 284 { 285 __be32 tmp[MOX_ECC_NUM_WORDS]; 286 287 cpu_to_be32_array(tmp, src, MOX_ECC_NUM_WORDS); 288 289 memcpy(dst, (void *)tmp + 2, MOX_ECC_NUM_LEN); 290 } 291 292 static void mox_ecc_public_key_to_bin(void *dst, u32 src_first, 293 const u32 *src_rest) 294 { 295 __be32 tmp[MOX_ECC_NUM_WORDS - 1]; 296 u8 *p = dst; 297 298 /* take 3 bytes from the first word */ 299 *p++ = src_first >> 16; 300 *p++ = src_first >> 8; 301 *p++ = src_first; 302 303 /* take the rest of the words */ 304 cpu_to_be32_array(tmp, src_rest, MOX_ECC_NUM_WORDS - 1); 305 memcpy(p, tmp, sizeof(tmp)); 306 } 307 308 static int mox_rwtm_sign(const struct key *key, const void *data, void *signature) 309 { 310 struct mox_rwtm *rwtm = dev_get_drvdata(turris_signing_key_get_dev(key)); 311 struct armada_37xx_rwtm_tx_msg msg = {}; 312 u32 offset_r, offset_s; 313 int ret; 314 315 guard(mutex)(&rwtm->busy); 316 317 /* 318 * For MBOX_CMD_SIGN command: 319 * args[0] - must be 1 320 * args[1] - address of message M to sign; message is a 521-bit number 321 * args[2] - address where the R part of the signature will be stored 322 * args[3] - address where the S part of the signature will be stored 323 * 324 * M, R and S are 521-bit numbers encoded as seventeen 32-bit words, 325 * most significat word first. 326 * Since the message in @data is a sha512 digest, the most significat 327 * word is always zero. 328 */ 329 330 offset_r = MOX_ECC_NUM_WORDS * sizeof(u32); 331 offset_s = 2 * MOX_ECC_NUM_WORDS * sizeof(u32); 332 333 memset(rwtm->buf, 0, sizeof(u32)); 334 memcpy(rwtm->buf + sizeof(u32), data, SHA512_DIGEST_SIZE); 335 be32_to_cpu_array(rwtm->buf, rwtm->buf, MOX_ECC_NUM_WORDS); 336 337 msg.args[0] = 1; 338 msg.args[1] = rwtm->buf_phys; 339 msg.args[2] = rwtm->buf_phys + offset_r; 340 msg.args[3] = rwtm->buf_phys + offset_s; 341 342 ret = mox_rwtm_exec(rwtm, MBOX_CMD_SIGN, &msg, true); 343 if (ret < 0) 344 return ret; 345 346 /* convert R and S parts of the signature */ 347 mox_ecc_number_to_bin(signature, rwtm->buf + offset_r); 348 mox_ecc_number_to_bin(signature + MOX_ECC_NUM_LEN, rwtm->buf + offset_s); 349 350 return 0; 351 } 352 353 static const void *mox_rwtm_get_public_key(const struct key *key) 354 { 355 struct mox_rwtm *rwtm = dev_get_drvdata(turris_signing_key_get_dev(key)); 356 357 return rwtm->pubkey; 358 } 359 360 static const struct turris_signing_key_subtype mox_signing_key_subtype = { 361 .key_size = MOX_ECC_NUM_BITS, 362 .data_size = SHA512_DIGEST_SIZE, 363 .sig_size = MOX_ECC_SIG_LEN, 364 .public_key_size = MOX_ECC_PUBKEY_LEN, 365 .hash_algo = "sha512", 366 .get_public_key = mox_rwtm_get_public_key, 367 .sign = mox_rwtm_sign, 368 }; 369 370 static int mox_register_signing_key(struct mox_rwtm *rwtm) 371 { 372 struct armada_37xx_rwtm_rx_msg *reply = &rwtm->reply; 373 struct device *dev = rwtm_dev(rwtm); 374 int ret; 375 376 ret = mox_rwtm_exec(rwtm, MBOX_CMD_ECDSA_PUB_KEY, NULL, false); 377 if (ret == -ENODATA) { 378 dev_warn(dev, "Board has no public key burned!\n"); 379 } else if (ret == -EOPNOTSUPP) { 380 dev_notice(dev, 381 "Firmware does not support the ECDSA_PUB_KEY command\n"); 382 } else if (ret < 0) { 383 return ret; 384 } else { 385 char sn[17] = "unknown"; 386 char desc[46]; 387 388 if (rwtm->has_board_info) 389 sprintf(sn, "%016llX", rwtm->serial_number); 390 391 sprintf(desc, "Turris MOX SN %s rWTM ECDSA key", sn); 392 393 mox_ecc_public_key_to_bin(rwtm->pubkey, ret, reply->status); 394 395 ret = devm_turris_signing_key_create(dev, 396 &mox_signing_key_subtype, 397 desc); 398 if (ret) 399 return dev_err_probe(dev, ret, 400 "Cannot create signing key\n"); 401 } 402 403 return 0; 404 } 405 406 #else /* CONFIG_TURRIS_MOX_RWTM_KEYCTL */ 407 408 static inline int mox_register_signing_key(struct mox_rwtm *rwtm) 409 { 410 return 0; 411 } 412 413 #endif /* !CONFIG_TURRIS_MOX_RWTM_KEYCTL */ 414 415 static void rwtm_devm_mbox_release(void *mbox) 416 { 417 mbox_free_channel(mbox); 418 } 419 420 static void rwtm_firmware_symlink_drop(void *parent) 421 { 422 sysfs_remove_link(parent, DRIVER_NAME); 423 } 424 425 static int turris_mox_rwtm_probe(struct platform_device *pdev) 426 { 427 struct mox_rwtm *rwtm; 428 struct device *dev = &pdev->dev; 429 int ret; 430 431 rwtm = devm_kzalloc(dev, sizeof(*rwtm), GFP_KERNEL); 432 if (!rwtm) 433 return -ENOMEM; 434 435 rwtm->buf = dmam_alloc_coherent(dev, RWTM_DMA_BUFFER_SIZE, 436 &rwtm->buf_phys, GFP_KERNEL); 437 if (!rwtm->buf) 438 return -ENOMEM; 439 440 platform_set_drvdata(pdev, rwtm); 441 442 ret = devm_mutex_init(dev, &rwtm->busy); 443 if (ret) 444 return ret; 445 446 init_completion(&rwtm->cmd_done); 447 448 rwtm->mbox_client.dev = dev; 449 rwtm->mbox_client.rx_callback = mox_rwtm_rx_callback; 450 451 rwtm->mbox = mbox_request_channel(&rwtm->mbox_client, 0); 452 if (IS_ERR(rwtm->mbox)) 453 return dev_err_probe(dev, PTR_ERR(rwtm->mbox), 454 "Cannot request mailbox channel!\n"); 455 456 ret = devm_add_action_or_reset(dev, rwtm_devm_mbox_release, rwtm->mbox); 457 if (ret) 458 return ret; 459 460 ret = mox_get_board_info(rwtm); 461 if (ret < 0) 462 dev_warn(dev, "Cannot read board information: %i\n", ret); 463 464 ret = mox_register_signing_key(rwtm); 465 if (ret < 0) 466 return ret; 467 468 ret = check_get_random_support(rwtm); 469 if (ret < 0) { 470 dev_notice(dev, 471 "Firmware does not support the GET_RANDOM command\n"); 472 return ret; 473 } 474 475 rwtm->hwrng.name = DRIVER_NAME "_hwrng"; 476 rwtm->hwrng.read = mox_hwrng_read; 477 478 ret = devm_hwrng_register(dev, &rwtm->hwrng); 479 if (ret) 480 return dev_err_probe(dev, ret, "Cannot register HWRNG!\n"); 481 482 dev_info(dev, "HWRNG successfully registered\n"); 483 484 /* 485 * For sysfs ABI compatibility, create symlink 486 * /sys/firmware/turris-mox-rwtm to this device's sysfs directory. 487 */ 488 ret = sysfs_create_link(firmware_kobj, &dev->kobj, DRIVER_NAME); 489 if (!ret) 490 devm_add_action_or_reset(dev, rwtm_firmware_symlink_drop, 491 firmware_kobj); 492 493 return 0; 494 } 495 496 static const struct of_device_id turris_mox_rwtm_match[] = { 497 { .compatible = "cznic,turris-mox-rwtm", }, 498 { .compatible = "marvell,armada-3700-rwtm-firmware", }, 499 { }, 500 }; 501 502 MODULE_DEVICE_TABLE(of, turris_mox_rwtm_match); 503 504 static struct platform_driver turris_mox_rwtm_driver = { 505 .probe = turris_mox_rwtm_probe, 506 .driver = { 507 .name = DRIVER_NAME, 508 .of_match_table = turris_mox_rwtm_match, 509 .dev_groups = turris_mox_rwtm_groups, 510 }, 511 }; 512 module_platform_driver(turris_mox_rwtm_driver); 513 514 MODULE_LICENSE("GPL v2"); 515 MODULE_DESCRIPTION("Turris Mox rWTM firmware driver"); 516 MODULE_AUTHOR("Marek Behun <kabel@kernel.org>"); 517