1 /* $NetBSD: sun8i_crypto.c,v 1.12 2020/02/06 19:52:09 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 2019 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Taylor R. Campbell. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * sun8i_crypto -- Allwinner Crypto Engine driver 34 * 35 * The Crypto Engine is documented in Sec. 3.15 of the Allwinner A64 36 * User Manual v1.1, on pp. 230--241. We only use it for the TRNG at 37 * the moment, but in principle it could be wired up with opencrypto(9) 38 * to compute AES, DES, 3DES, MD5, SHA-1, SHA-224, SHA-256, HMAC-SHA1, 39 * HMAC-HA256, RSA, and an undocumented PRNG. It also seems to support 40 * AES keys in SRAM (for some kind of HDMI HDCP stuff?). 41 * 42 * https://linux-sunxi.org/images/b/b4/Allwinner_A64_User_Manual_V1.1.pdf 43 */ 44 45 #include <sys/cdefs.h> 46 __KERNEL_RCSID(1, "$NetBSD: sun8i_crypto.c,v 1.12 2020/02/06 19:52:09 riastradh Exp $"); 47 48 #include <sys/types.h> 49 #include <sys/param.h> 50 #include <sys/atomic.h> 51 #include <sys/bus.h> 52 #include <sys/callout.h> 53 #include <sys/conf.h> 54 #include <sys/device.h> 55 #include <sys/kernel.h> 56 #include <sys/kmem.h> 57 #include <sys/mutex.h> 58 #include <sys/rndpool.h> 59 #include <sys/rndsource.h> 60 #include <sys/sysctl.h> 61 #include <sys/workqueue.h> 62 63 #include <dev/fdt/fdtvar.h> 64 65 #include <arm/sunxi/sun8i_crypto.h> 66 67 #define SUN8I_CRYPTO_TIMEOUT hz 68 #define SUN8I_CRYPTO_RNGENTROPY 100 /* estimated bits per bit of entropy */ 69 #define SUN8I_CRYPTO_RNGBYTES PAGE_SIZE 70 71 struct sun8i_crypto_task; 72 73 struct sun8i_crypto_buf { 74 bus_dma_segment_t cb_seg[1]; 75 int cb_nsegs; 76 bus_dmamap_t cb_map; 77 void *cb_kva; 78 }; 79 80 struct sun8i_crypto_softc { 81 device_t sc_dev; 82 bus_space_tag_t sc_bst; 83 bus_space_handle_t sc_bsh; 84 bus_dma_tag_t sc_dmat; 85 kmutex_t sc_lock; 86 struct sun8i_crypto_chan { 87 struct sun8i_crypto_task *cc_task; 88 unsigned cc_starttime; 89 } sc_chan[SUN8I_CRYPTO_NCHAN]; 90 struct callout sc_timeout; 91 struct workqueue *sc_wq; 92 struct work sc_work; 93 void *sc_ih; 94 uint32_t sc_done; 95 uint32_t sc_esr; 96 bool sc_work_pending; 97 struct sun8i_crypto_rng { 98 struct sun8i_crypto_buf cr_buf; 99 struct sun8i_crypto_task *cr_task; 100 struct krndsource cr_rndsource; 101 bool cr_pending; 102 } sc_rng; 103 struct sun8i_crypto_selftest { 104 struct sun8i_crypto_buf cs_in; 105 struct sun8i_crypto_buf cs_key; 106 struct sun8i_crypto_buf cs_out; 107 struct sun8i_crypto_task *cs_task; 108 } sc_selftest; 109 struct sun8i_crypto_sysctl { 110 struct sysctllog *cy_log; 111 const struct sysctlnode *cy_root_node; 112 const struct sysctlnode *cy_trng_node; 113 } sc_sysctl; 114 }; 115 116 struct sun8i_crypto_task { 117 struct sun8i_crypto_buf ct_buf; 118 struct sun8i_crypto_taskdesc *ct_desc; 119 void (*ct_callback)(struct sun8i_crypto_softc *, 120 struct sun8i_crypto_task *, void *, int); 121 void *ct_cookie; 122 }; 123 124 /* 125 * Forward declarations 126 */ 127 128 static int sun8i_crypto_match(device_t, cfdata_t, void *); 129 static void sun8i_crypto_attach(device_t, device_t, void *); 130 131 static struct sun8i_crypto_task * 132 sun8i_crypto_task_get(struct sun8i_crypto_softc *, 133 void (*)(struct sun8i_crypto_softc *, 134 struct sun8i_crypto_task *, void *, int), 135 void *); 136 static void sun8i_crypto_task_put(struct sun8i_crypto_softc *, 137 struct sun8i_crypto_task *); 138 static void sun8i_crypto_task_reset(struct sun8i_crypto_task *); 139 140 static void sun8i_crypto_task_set_key(struct sun8i_crypto_task *, 141 bus_dmamap_t); 142 static void sun8i_crypto_task_set_iv(struct sun8i_crypto_task *, 143 bus_dmamap_t); 144 static void sun8i_crypto_task_set_ctr(struct sun8i_crypto_task *, 145 bus_dmamap_t); 146 static void sun8i_crypto_task_set_input(struct sun8i_crypto_task *, 147 bus_dmamap_t); 148 static void sun8i_crypto_task_set_output(struct sun8i_crypto_task *, 149 bus_dmamap_t); 150 151 static void sun8i_crypto_task_scatter(struct sun8i_crypto_adrlen *, 152 bus_dmamap_t); 153 154 static int sun8i_crypto_submit_trng(struct sun8i_crypto_softc *, 155 struct sun8i_crypto_task *, uint32_t); 156 static int sun8i_crypto_submit_aesecb(struct sun8i_crypto_softc *, 157 struct sun8i_crypto_task *, uint32_t, uint32_t, uint32_t); 158 static int sun8i_crypto_submit(struct sun8i_crypto_softc *, 159 struct sun8i_crypto_task *); 160 161 static void sun8i_crypto_timeout(void *); 162 static int sun8i_crypto_intr(void *); 163 static void sun8i_crypto_schedule_worker(struct sun8i_crypto_softc *); 164 static void sun8i_crypto_worker(struct work *, void *); 165 static void sun8i_crypto_chan_done(struct sun8i_crypto_softc *, unsigned, 166 int); 167 168 static int sun8i_crypto_allocbuf(struct sun8i_crypto_softc *, size_t, 169 struct sun8i_crypto_buf *); 170 static void sun8i_crypto_freebuf(struct sun8i_crypto_softc *, size_t, 171 struct sun8i_crypto_buf *); 172 173 static void sun8i_crypto_rng_attach(struct sun8i_crypto_softc *); 174 static void sun8i_crypto_rng_get(size_t, void *); 175 static void sun8i_crypto_rng_done(struct sun8i_crypto_softc *, 176 struct sun8i_crypto_task *, void *, int); 177 178 static void sun8i_crypto_selftest(device_t); 179 static void sun8i_crypto_selftest_done(struct sun8i_crypto_softc *, 180 struct sun8i_crypto_task *, void *, int); 181 182 static void sun8i_crypto_sysctl_attach(struct sun8i_crypto_softc *); 183 static int sun8i_crypto_sysctl_rng(SYSCTLFN_ARGS); 184 static void sun8i_crypto_sysctl_rng_done(struct sun8i_crypto_softc *, 185 struct sun8i_crypto_task *, void *, int); 186 187 /* 188 * Register access 189 */ 190 191 static uint32_t 192 sun8i_crypto_read(struct sun8i_crypto_softc *sc, bus_addr_t reg) 193 { 194 return bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg); 195 } 196 197 static void 198 sun8i_crypto_write(struct sun8i_crypto_softc *sc, bus_addr_t reg, uint32_t v) 199 { 200 bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, v); 201 } 202 203 /* 204 * Autoconf goo 205 */ 206 207 CFATTACH_DECL_NEW(sun8i_crypto, sizeof(struct sun8i_crypto_softc), 208 sun8i_crypto_match, sun8i_crypto_attach, NULL, NULL); 209 210 static const struct of_compat_data compat_data[] = { 211 {"allwinner,sun50i-a64-crypto", 0}, 212 {NULL} 213 }; 214 215 static int 216 sun8i_crypto_match(device_t parent, cfdata_t cf, void *aux) 217 { 218 const struct fdt_attach_args *const faa = aux; 219 220 return of_match_compat_data(faa->faa_phandle, compat_data); 221 } 222 223 static void 224 sun8i_crypto_attach(device_t parent, device_t self, void *aux) 225 { 226 struct sun8i_crypto_softc *const sc = device_private(self); 227 const struct fdt_attach_args *const faa = aux; 228 bus_addr_t addr; 229 bus_size_t size; 230 const int phandle = faa->faa_phandle; 231 char intrstr[128]; 232 struct clk *clk; 233 struct fdtbus_reset *rst; 234 235 sc->sc_dev = self; 236 sc->sc_dmat = faa->faa_dmat; 237 sc->sc_bst = faa->faa_bst; 238 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); 239 callout_init(&sc->sc_timeout, CALLOUT_MPSAFE); 240 callout_setfunc(&sc->sc_timeout, &sun8i_crypto_timeout, sc); 241 if (workqueue_create(&sc->sc_wq, device_xname(self), 242 &sun8i_crypto_worker, sc, PRI_NONE, IPL_VM, WQ_MPSAFE) != 0) { 243 aprint_error(": couldn't create workqueue\n"); 244 return; 245 } 246 247 /* Get and map device registers. */ 248 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 249 aprint_error(": couldn't get registers\n"); 250 return; 251 } 252 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 253 aprint_error(": couldn't map registers\n"); 254 return; 255 } 256 257 /* Get an interrupt handle. */ 258 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 259 aprint_error(": failed to decode interrupt\n"); 260 return; 261 } 262 263 /* Enable the bus clock. */ 264 if (fdtbus_clock_enable(phandle, "bus", true) != 0) { 265 aprint_error(": couldn't enable bus clock\n"); 266 return; 267 } 268 269 /* Get the module clock and set it to 300 MHz. */ 270 if ((clk = fdtbus_clock_get(phandle, "mod")) != NULL) { 271 if (clk_enable(clk) != 0) { 272 aprint_error(": couldn't enable CE clock\n"); 273 return; 274 } 275 if (clk_set_rate(clk, 300*1000*1000) != 0) { 276 aprint_error(": couldn't set CE clock to 300MHz\n"); 277 return; 278 } 279 } 280 281 /* Get a reset handle if we need and try to deassert it. */ 282 if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL) { 283 if (fdtbus_reset_deassert(rst) != 0) { 284 aprint_error(": couldn't de-assert reset\n"); 285 return; 286 } 287 } 288 289 aprint_naive("\n"); 290 aprint_normal(": Crypto Engine\n"); 291 aprint_debug_dev(self, ": clock freq %d\n", clk_get_rate(clk)); 292 293 /* Disable and clear interrupts. */ 294 sun8i_crypto_write(sc, SUN8I_CRYPTO_ICR, 0); 295 sun8i_crypto_write(sc, SUN8I_CRYPTO_ISR, 0); 296 297 /* Establish an interrupt handler. */ 298 sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, FDT_INTR_MPSAFE, 299 &sun8i_crypto_intr, sc); 300 if (sc->sc_ih == NULL) { 301 aprint_error_dev(self, "failed to establish interrupt on %s\n", 302 intrstr); 303 return; 304 } 305 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 306 307 /* Set up the RNG. */ 308 sun8i_crypto_rng_attach(sc); 309 310 /* Attach the sysctl. */ 311 sun8i_crypto_sysctl_attach(sc); 312 313 /* Perform self-tests. */ 314 config_interrupts(self, sun8i_crypto_selftest); 315 } 316 317 /* 318 * Task allocation 319 */ 320 321 static struct sun8i_crypto_task * 322 sun8i_crypto_task_get(struct sun8i_crypto_softc *sc, 323 void (*callback)(struct sun8i_crypto_softc *, struct sun8i_crypto_task *, 324 void *, int), 325 void *cookie) 326 { 327 struct sun8i_crypto_task *task; 328 int error; 329 330 /* Allocate a task. */ 331 task = kmem_zalloc(sizeof(*task), KM_SLEEP); 332 333 /* Allocate a buffer for the descriptor. */ 334 error = sun8i_crypto_allocbuf(sc, sizeof(*task->ct_desc), 335 &task->ct_buf); 336 if (error) 337 goto fail0; 338 339 /* Initialize the task object and return it. */ 340 task->ct_desc = task->ct_buf.cb_kva; 341 task->ct_callback = callback; 342 task->ct_cookie = cookie; 343 return task; 344 345 fail1: __unused 346 sun8i_crypto_freebuf(sc, sizeof(*task->ct_desc), &task->ct_buf); 347 fail0: kmem_free(task, sizeof(*task)); 348 return NULL; 349 } 350 351 static void 352 sun8i_crypto_task_put(struct sun8i_crypto_softc *sc, 353 struct sun8i_crypto_task *task) 354 { 355 356 sun8i_crypto_freebuf(sc, sizeof(*task->ct_desc), &task->ct_buf); 357 kmem_free(task, sizeof(*task)); 358 } 359 360 /* 361 * Task descriptor setup 362 * 363 * WARNING: Task descriptor fields are little-endian, not host-endian. 364 */ 365 366 static void 367 sun8i_crypto_task_reset(struct sun8i_crypto_task *task) 368 { 369 370 memset(task->ct_desc, 0, sizeof(*task->ct_desc)); 371 } 372 373 static void 374 sun8i_crypto_task_set_key(struct sun8i_crypto_task *task, bus_dmamap_t map) 375 { 376 377 KASSERT(map->dm_nsegs == 1); 378 task->ct_desc->td_keydesc = htole32(map->dm_segs[0].ds_addr); 379 } 380 381 static void __unused /* XXX opencrypto(9) */ 382 sun8i_crypto_task_set_iv(struct sun8i_crypto_task *task, bus_dmamap_t map) 383 { 384 385 KASSERT(map->dm_nsegs == 1); 386 task->ct_desc->td_ivdesc = htole32(map->dm_segs[0].ds_addr); 387 } 388 389 static void __unused /* XXX opencrypto(9) */ 390 sun8i_crypto_task_set_ctr(struct sun8i_crypto_task *task, bus_dmamap_t map) 391 { 392 393 KASSERT(map->dm_nsegs == 1); 394 task->ct_desc->td_ctrdesc = htole32(map->dm_segs[0].ds_addr); 395 } 396 397 static void 398 sun8i_crypto_task_set_input(struct sun8i_crypto_task *task, bus_dmamap_t map) 399 { 400 401 sun8i_crypto_task_scatter(task->ct_desc->td_src, map); 402 } 403 404 static void 405 sun8i_crypto_task_set_output(struct sun8i_crypto_task *task, bus_dmamap_t map) 406 { 407 408 sun8i_crypto_task_scatter(task->ct_desc->td_dst, map); 409 } 410 411 static void 412 sun8i_crypto_task_scatter(struct sun8i_crypto_adrlen *adrlen, bus_dmamap_t map) 413 { 414 uint32_t total __diagused = 0; 415 unsigned i; 416 417 KASSERT(map->dm_nsegs <= SUN8I_CRYPTO_MAXSEGS); 418 for (i = 0; i < map->dm_nsegs; i++) { 419 KASSERT((map->dm_segs[i].ds_addr % 4) == 0); 420 KASSERT(map->dm_segs[i].ds_addr <= UINT32_MAX); 421 KASSERT(map->dm_segs[i].ds_len <= UINT32_MAX - total); 422 adrlen[i].adr = htole32(map->dm_segs[i].ds_addr); 423 adrlen[i].len = htole32(map->dm_segs[i].ds_len/4); 424 total += map->dm_segs[i].ds_len; 425 } 426 427 /* Verify the remainder are zero. */ 428 for (; i < SUN8I_CRYPTO_MAXSEGS; i++) { 429 KASSERT(adrlen[i].adr == 0); 430 KASSERT(adrlen[i].len == 0); 431 } 432 433 /* Verify the total size matches the DMA map. */ 434 KASSERT(total == map->dm_mapsize); 435 } 436 437 /* 438 * Task submission 439 * 440 * WARNING: Task descriptor fields are little-endian, not host-endian. 441 */ 442 443 static int 444 sun8i_crypto_submit_trng(struct sun8i_crypto_softc *sc, 445 struct sun8i_crypto_task *task, uint32_t datalen) 446 { 447 struct sun8i_crypto_taskdesc *desc = task->ct_desc; 448 uint32_t tdqc = 0; 449 uint32_t total __diagused; 450 unsigned i __diagused; 451 452 /* Data length must be a multiple of 4 because...reasons. */ 453 KASSERT((datalen % 4) == 0); 454 455 /* All of the sources should be empty. */ 456 for (total = 0, i = 0; i < SUN8I_CRYPTO_MAXSEGS; i++) 457 KASSERT(le32toh(task->ct_desc->td_src[i].len) == 0); 458 459 /* Verify the total output length -- should be datalen/4. */ 460 for (total = 0, i = 0; i < SUN8I_CRYPTO_MAXSEGS; i++) { 461 uint32_t len = le32toh(task->ct_desc->td_dst[i].len); 462 KASSERT(len <= UINT32_MAX - total); 463 total += len; 464 } 465 KASSERT(total == datalen/4); 466 467 /* Verify the key, IV, and CTR are unset. */ 468 KASSERT(desc->td_keydesc == 0); 469 KASSERT(desc->td_ivdesc == 0); 470 KASSERT(desc->td_ctrdesc == 0); 471 472 /* Set up the task descriptor queue control words. */ 473 tdqc |= SUN8I_CRYPTO_TDQC_INTR_EN; 474 tdqc |= __SHIFTIN(SUN8I_CRYPTO_TDQC_METHOD_TRNG, 475 SUN8I_CRYPTO_TDQC_METHOD); 476 desc->td_tdqc = htole32(tdqc); 477 desc->td_tdqs = 0; /* no symmetric crypto */ 478 desc->td_tdqa = 0; /* no asymmetric crypto */ 479 480 /* Set the data length for the output. */ 481 desc->td_datalen = htole32(datalen/4); 482 483 /* Submit! */ 484 return sun8i_crypto_submit(sc, task); 485 } 486 487 static int 488 sun8i_crypto_submit_aesecb(struct sun8i_crypto_softc *sc, 489 struct sun8i_crypto_task *task, 490 uint32_t datalen, uint32_t keysize, uint32_t dir) 491 { 492 struct sun8i_crypto_taskdesc *desc = task->ct_desc; 493 uint32_t tdqc = 0, tdqs = 0; 494 uint32_t total __diagused; 495 unsigned i __diagused; 496 497 /* 498 * Data length must be a multiple of 4 because...reasons. 499 * 500 * WARNING: For `AES-CTS' (maybe that means AES-XTS?), datalen 501 * is in units of bytes, not units of words -- but everything 502 * _else_ is in units of words. This routine applies only to 503 * AES-ECB for the self-test. 504 */ 505 KASSERT((datalen % 4) == 0); 506 507 /* Verify the total input length -- should be datalen/4. */ 508 for (total = 0, i = 0; i < SUN8I_CRYPTO_MAXSEGS; i++) { 509 uint32_t len = le32toh(task->ct_desc->td_src[i].len); 510 KASSERT(len <= UINT32_MAX - total); 511 total += len; 512 } 513 KASSERT(total == datalen/4); 514 515 /* Verify the total output length -- should be datalen/4. */ 516 for (total = 0, i = 0; i < SUN8I_CRYPTO_MAXSEGS; i++) { 517 uint32_t len = le32toh(task->ct_desc->td_dst[i].len); 518 KASSERT(len <= UINT32_MAX - total); 519 total += len; 520 } 521 KASSERT(total == datalen/4); 522 523 /* Set up the task descriptor queue control word. */ 524 tdqc |= SUN8I_CRYPTO_TDQC_INTR_EN; 525 tdqc |= __SHIFTIN(SUN8I_CRYPTO_TDQC_METHOD_AES, 526 SUN8I_CRYPTO_TDQC_METHOD); 527 desc->td_tdqc = htole32(tdqc); 528 529 /* Set up the symmetric control word. */ 530 tdqs |= __SHIFTIN(SUN8I_CRYPTO_TDQS_SKEY_SELECT_SS_KEYx, 531 SUN8I_CRYPTO_TDQS_SKEY_SELECT); 532 tdqs |= __SHIFTIN(SUN8I_CRYPTO_TDQS_OP_MODE_ECB, 533 SUN8I_CRYPTO_TDQS_OP_MODE); 534 tdqs |= __SHIFTIN(SUN8I_CRYPTO_TDQS_AES_KEYSIZE_128, 535 SUN8I_CRYPTO_TDQS_AES_KEYSIZE); 536 desc->td_tdqs = htole32(tdqs); 537 538 desc->td_tdqa = 0; /* no asymmetric crypto */ 539 540 /* Set the data length for the output. */ 541 desc->td_datalen = htole32(datalen/4); 542 543 /* Submit! */ 544 return sun8i_crypto_submit(sc, task); 545 } 546 547 static int 548 sun8i_crypto_submit(struct sun8i_crypto_softc *sc, 549 struct sun8i_crypto_task *task) 550 { 551 unsigned i, retries = 0; 552 uint32_t icr; 553 int error = 0; 554 555 /* One at a time at the device registers, please. */ 556 mutex_enter(&sc->sc_lock); 557 558 /* Find a channel. */ 559 for (i = 0; i < SUN8I_CRYPTO_NCHAN; i++) { 560 if (sc->sc_chan[i].cc_task == NULL) 561 break; 562 } 563 if (i == SUN8I_CRYPTO_NCHAN) { 564 device_printf(sc->sc_dev, "no free channels\n"); 565 error = ERESTART; 566 goto out; 567 } 568 569 /* 570 * Set the channel id. Caller is responsible for setting up 571 * all other parts of the descriptor. 572 */ 573 task->ct_desc->td_cid = htole32(i); 574 575 /* Prepare to send the descriptor to the device by DMA. */ 576 bus_dmamap_sync(sc->sc_dmat, task->ct_buf.cb_map, 0, 577 sizeof(*task->ct_desc), BUS_DMASYNC_PREWRITE); 578 579 /* Confirm we're ready to go. */ 580 if (sun8i_crypto_read(sc, SUN8I_CRYPTO_TLR) & SUN8I_CRYPTO_TLR_LOAD) { 581 device_printf(sc->sc_dev, "TLR not clear\n"); 582 error = EIO; 583 goto out; 584 } 585 586 /* Enable interrupts for this channel. */ 587 icr = sun8i_crypto_read(sc, SUN8I_CRYPTO_ICR); 588 icr |= __SHIFTIN(SUN8I_CRYPTO_ICR_INTR_EN_CHAN(i), 589 SUN8I_CRYPTO_ICR_INTR_EN); 590 sun8i_crypto_write(sc, SUN8I_CRYPTO_ICR, icr); 591 592 /* Set the task descriptor queue address. */ 593 sun8i_crypto_write(sc, SUN8I_CRYPTO_TDQ, 594 task->ct_buf.cb_map->dm_segs[0].ds_addr); 595 596 /* Notify the engine to load it, and wait for acknowledgement. */ 597 sun8i_crypto_write(sc, SUN8I_CRYPTO_TLR, SUN8I_CRYPTO_TLR_LOAD); 598 while (sun8i_crypto_read(sc, SUN8I_CRYPTO_TLR) & SUN8I_CRYPTO_TLR_LOAD) 599 { 600 /* 601 * XXX Timeout pulled from arse. Is it even important 602 * to wait here? 603 */ 604 if (++retries == 1000) { 605 device_printf(sc->sc_dev, "TLR didn't clear: %08x\n", 606 sun8i_crypto_read(sc, SUN8I_CRYPTO_TLR)); 607 /* 608 * Hope it clears eventually; if not, we'll 609 * time out. 610 */ 611 break; 612 } 613 DELAY(1); 614 } 615 616 /* Loaded up and ready to go. Start a timer ticking. */ 617 sc->sc_chan[i].cc_task = task; 618 sc->sc_chan[i].cc_starttime = atomic_load_relaxed(&hardclock_ticks); 619 callout_schedule(&sc->sc_timeout, SUN8I_CRYPTO_TIMEOUT); 620 621 /* XXX Consider polling if cold to get entropy earlier. */ 622 623 out: /* Done! */ 624 mutex_exit(&sc->sc_lock); 625 return error; 626 } 627 628 static void 629 sun8i_crypto_timeout(void *cookie) 630 { 631 struct sun8i_crypto_softc *sc = cookie; 632 unsigned i; 633 634 mutex_enter(&sc->sc_lock); 635 636 /* Check whether there are any tasks pending. */ 637 for (i = 0; i < SUN8I_CRYPTO_NCHAN; i++) { 638 if (sc->sc_chan[i].cc_task) 639 break; 640 } 641 if (i == SUN8I_CRYPTO_NCHAN) 642 /* None pending, so nothing to do. */ 643 goto out; 644 645 /* 646 * Schedule the worker to check for timeouts, and schedule 647 * another timeout in case we need it. 648 */ 649 sun8i_crypto_schedule_worker(sc); 650 callout_schedule(&sc->sc_timeout, SUN8I_CRYPTO_TIMEOUT); 651 652 out: mutex_exit(&sc->sc_lock); 653 } 654 655 static int 656 sun8i_crypto_intr(void *cookie) 657 { 658 struct sun8i_crypto_softc *sc = cookie; 659 uint32_t isr, esr; 660 661 mutex_enter(&sc->sc_lock); 662 663 /* 664 * Get and acknowledge the interrupts and error status. 665 * 666 * XXX Data sheet says the error status register is read-only, 667 * but then advises writing 1 to bit x1xx (keysram access error 668 * for AES, SUN8I_CRYPTO_ESR_KEYSRAMERR) to clear it. What do? 669 */ 670 isr = sun8i_crypto_read(sc, SUN8I_CRYPTO_ISR); 671 esr = sun8i_crypto_read(sc, SUN8I_CRYPTO_ESR); 672 sun8i_crypto_write(sc, SUN8I_CRYPTO_ISR, isr); 673 sun8i_crypto_write(sc, SUN8I_CRYPTO_ESR, esr); 674 675 /* Start the worker if necessary. */ 676 sun8i_crypto_schedule_worker(sc); 677 678 /* Tell the worker what to do. */ 679 sc->sc_done |= __SHIFTOUT(isr, SUN8I_CRYPTO_ISR_DONE); 680 sc->sc_esr |= esr; 681 682 mutex_exit(&sc->sc_lock); 683 684 return __SHIFTOUT(isr, SUN8I_CRYPTO_ISR_DONE) != 0; 685 } 686 687 static void 688 sun8i_crypto_schedule_worker(struct sun8i_crypto_softc *sc) 689 { 690 691 KASSERT(mutex_owned(&sc->sc_lock)); 692 693 /* Start the worker if necessary. */ 694 if (!sc->sc_work_pending) { 695 workqueue_enqueue(sc->sc_wq, &sc->sc_work, NULL); 696 sc->sc_work_pending = true; 697 } 698 } 699 700 static void 701 sun8i_crypto_worker(struct work *wk, void *cookie) 702 { 703 struct sun8i_crypto_softc *sc = cookie; 704 uint32_t done, esr, esr_chan; 705 unsigned i, now; 706 int error; 707 708 /* 709 * Acquire the lock. Note: We will be releasing and 710 * reacquiring it throughout the loop. 711 */ 712 mutex_enter(&sc->sc_lock); 713 714 /* Acknowledge the work. */ 715 KASSERT(sc->sc_work_pending); 716 sc->sc_work_pending = false; 717 718 /* 719 * Claim the done mask and error status once; we will be 720 * releasing and reacquiring the lock for the callbacks, so 721 * they may change. 722 */ 723 done = sc->sc_done; 724 esr = sc->sc_esr; 725 sc->sc_done = 0; 726 sc->sc_esr = 0; 727 728 /* Check the time to determine what's timed out. */ 729 now = atomic_load_relaxed(&hardclock_ticks); 730 731 /* Process the channels. */ 732 for (i = 0; i < SUN8I_CRYPTO_NCHAN; i++) { 733 /* Check whether the channel is done. */ 734 if (!ISSET(done, SUN8I_CRYPTO_ISR_DONE_CHAN(i))) { 735 /* Nope. Do we have a task to time out? */ 736 if ((sc->sc_chan[i].cc_task != NULL) && 737 ((now - sc->sc_chan[i].cc_starttime) >= 738 SUN8I_CRYPTO_TIMEOUT)) 739 sun8i_crypto_chan_done(sc, i, ETIMEDOUT); 740 continue; 741 } 742 743 /* Channel is done. Interpret the error if any. */ 744 esr_chan = __SHIFTOUT(esr, SUN8I_CRYPTO_ESR_CHAN(i)); 745 if (esr_chan & SUN8I_CRYPTO_ESR_CHAN_ALGNOTSUP) { 746 device_printf(sc->sc_dev, "channel %u:" 747 " alg not supported\n", i); 748 error = ENODEV; 749 } else if (esr_chan & SUN8I_CRYPTO_ESR_CHAN_DATALENERR) { 750 device_printf(sc->sc_dev, "channel %u:" 751 " data length error\n", i); 752 error = EIO; /* XXX */ 753 } else if (esr_chan & SUN8I_CRYPTO_ESR_CHAN_KEYSRAMERR) { 754 device_printf(sc->sc_dev, "channel %u:" 755 " key sram error\n", i); 756 error = EIO; /* XXX */ 757 } else if (esr_chan != 0) { 758 error = EIO; /* generic I/O error */ 759 } else { 760 error = 0; 761 } 762 763 /* 764 * Notify the task of completion. May release the lock 765 * to invoke a callback. 766 */ 767 sun8i_crypto_chan_done(sc, i, error); 768 } 769 770 /* All one; release the lock one last time. */ 771 mutex_exit(&sc->sc_lock); 772 } 773 774 static void 775 sun8i_crypto_chan_done(struct sun8i_crypto_softc *sc, unsigned i, int error) 776 { 777 struct sun8i_crypto_task *task; 778 uint32_t icr; 779 780 KASSERT(mutex_owned(&sc->sc_lock)); 781 782 /* Claim the task if there is one; bail if not. */ 783 if ((task = sc->sc_chan[i].cc_task) == NULL) { 784 device_printf(sc->sc_dev, "channel %u: no task but error=%d\n", 785 i, error); 786 return; 787 } 788 sc->sc_chan[i].cc_task = NULL; 789 790 /* Disable interrupts on this channel. */ 791 icr = sun8i_crypto_read(sc, SUN8I_CRYPTO_ICR); 792 icr &= ~__SHIFTIN(SUN8I_CRYPTO_ICR_INTR_EN_CHAN(i), 793 SUN8I_CRYPTO_ICR_INTR_EN); 794 sun8i_crypto_write(sc, SUN8I_CRYPTO_ICR, icr); 795 796 /* Finished sending the descriptor to the device by DMA. */ 797 bus_dmamap_sync(sc->sc_dmat, task->ct_buf.cb_map, 0, 798 sizeof(*task->ct_desc), BUS_DMASYNC_POSTWRITE); 799 800 /* Temporarily release the lock to invoke the callback. */ 801 mutex_exit(&sc->sc_lock); 802 (*task->ct_callback)(sc, task, task->ct_cookie, error); 803 mutex_enter(&sc->sc_lock); 804 } 805 806 /* 807 * DMA buffers 808 */ 809 810 static int 811 sun8i_crypto_allocbuf(struct sun8i_crypto_softc *sc, size_t size, 812 struct sun8i_crypto_buf *buf) 813 { 814 int error; 815 816 /* Allocate a DMA-safe buffer. */ 817 error = bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, buf->cb_seg, 818 __arraycount(buf->cb_seg), &buf->cb_nsegs, BUS_DMA_WAITOK); 819 if (error) 820 goto fail0; 821 822 /* Map the buffer into kernel virtual address space. */ 823 error = bus_dmamem_map(sc->sc_dmat, buf->cb_seg, buf->cb_nsegs, 824 size, &buf->cb_kva, BUS_DMA_WAITOK); 825 if (error) 826 goto fail1; 827 828 /* Create a DMA map for the buffer. */ 829 error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 830 BUS_DMA_WAITOK, &buf->cb_map); 831 if (error) 832 goto fail2; 833 834 /* Load the buffer into the DMA map. */ 835 error = bus_dmamap_load(sc->sc_dmat, buf->cb_map, buf->cb_kva, size, 836 NULL, BUS_DMA_WAITOK); 837 if (error) 838 goto fail3; 839 840 /* Success! */ 841 return 0; 842 843 fail4: __unused 844 bus_dmamap_unload(sc->sc_dmat, buf->cb_map); 845 fail3: bus_dmamap_destroy(sc->sc_dmat, buf->cb_map); 846 fail2: bus_dmamem_unmap(sc->sc_dmat, buf->cb_kva, size); 847 fail1: bus_dmamem_free(sc->sc_dmat, buf->cb_seg, buf->cb_nsegs); 848 fail0: return error; 849 } 850 851 static void 852 sun8i_crypto_freebuf(struct sun8i_crypto_softc *sc, size_t size, 853 struct sun8i_crypto_buf *buf) 854 { 855 856 bus_dmamap_unload(sc->sc_dmat, buf->cb_map); 857 bus_dmamap_destroy(sc->sc_dmat, buf->cb_map); 858 bus_dmamem_unmap(sc->sc_dmat, buf->cb_kva, size); 859 bus_dmamem_free(sc->sc_dmat, buf->cb_seg, buf->cb_nsegs); 860 } 861 862 /* 863 * Crypto Engine - TRNG 864 */ 865 866 static void 867 sun8i_crypto_rng_attach(struct sun8i_crypto_softc *sc) 868 { 869 device_t self = sc->sc_dev; 870 struct sun8i_crypto_rng *rng = &sc->sc_rng; 871 int error; 872 873 /* Preallocate a buffer to reuse. */ 874 error = sun8i_crypto_allocbuf(sc, SUN8I_CRYPTO_RNGBYTES, &rng->cr_buf); 875 if (error) 876 goto fail0; 877 878 /* Create a task to reuse. */ 879 rng->cr_task = sun8i_crypto_task_get(sc, sun8i_crypto_rng_done, rng); 880 if (rng->cr_task == NULL) 881 goto fail1; 882 883 /* 884 * Attach the rndsource. This is _not_ marked as RND_TYPE_RNG 885 * because the output is not uniformly distributed. The bits 886 * are heavily weighted toward 0 or 1, at different times, and 887 * I haven't scienced a satisfactory story out of it yet. 888 */ 889 rndsource_setcb(&rng->cr_rndsource, sun8i_crypto_rng_get, sc); 890 rnd_attach_source(&rng->cr_rndsource, device_xname(self), 891 RND_TYPE_UNKNOWN, 892 RND_FLAG_COLLECT_VALUE|RND_FLAG_ESTIMATE_VALUE|RND_FLAG_HASCB); 893 894 /* Success! */ 895 return; 896 897 fail2: __unused 898 sun8i_crypto_task_put(sc, rng->cr_task); 899 fail1: sun8i_crypto_freebuf(sc, SUN8I_CRYPTO_RNGBYTES, &rng->cr_buf); 900 fail0: aprint_error_dev(self, "failed to set up RNG, error=%d\n", error); 901 } 902 903 static void 904 sun8i_crypto_rng_get(size_t nbytes, void *cookie) 905 { 906 struct sun8i_crypto_softc *sc = cookie; 907 struct sun8i_crypto_rng *rng = &sc->sc_rng; 908 bool pending; 909 int error; 910 911 /* 912 * Test and set the RNG-pending flag. If it's already in 913 * progress, nothing to do here. 914 */ 915 mutex_enter(&sc->sc_lock); 916 pending = rng->cr_pending; 917 rng->cr_pending = true; 918 mutex_exit(&sc->sc_lock); 919 if (pending) 920 return; 921 922 /* Prepare for a DMA read into the buffer. */ 923 bus_dmamap_sync(sc->sc_dmat, rng->cr_buf.cb_map, 924 0, SUN8I_CRYPTO_RNGBYTES, BUS_DMASYNC_PREREAD); 925 926 /* Set the task up for TRNG to our buffer. */ 927 sun8i_crypto_task_reset(rng->cr_task); 928 sun8i_crypto_task_set_output(rng->cr_task, rng->cr_buf.cb_map); 929 930 /* Submit the TRNG task. */ 931 error = sun8i_crypto_submit_trng(sc, rng->cr_task, 932 SUN8I_CRYPTO_RNGBYTES); 933 if (error) 934 goto fail; 935 936 /* All done! */ 937 return; 938 939 fail: mutex_enter(&sc->sc_lock); 940 rng->cr_pending = false; 941 mutex_exit(&sc->sc_lock); 942 } 943 944 static void 945 sun8i_crypto_rng_done(struct sun8i_crypto_softc *sc, 946 struct sun8i_crypto_task *task, void *cookie, int error) 947 { 948 struct sun8i_crypto_rng *rng = cookie; 949 uint8_t *buf = rng->cr_buf.cb_kva; 950 uint32_t entropybits; 951 952 KASSERT(rng == &sc->sc_rng); 953 954 /* Finished the DMA read into the buffer. */ 955 bus_dmamap_sync(sc->sc_dmat, rng->cr_buf.cb_map, 956 0, SUN8I_CRYPTO_RNGBYTES, BUS_DMASYNC_POSTREAD); 957 958 /* If anything went wrong, forget about it. */ 959 if (error) 960 goto out; 961 962 /* 963 * This TRNG has quite low entropy at best. But if it fails a 964 * repeated output test, then assume it's busted. 965 */ 966 CTASSERT(SUN8I_CRYPTO_RNGBYTES <= UINT32_MAX/NBBY); 967 entropybits = (NBBY*SUN8I_CRYPTO_RNGBYTES)/SUN8I_CRYPTO_RNGENTROPY; 968 if (consttime_memequal(buf, buf + SUN8I_CRYPTO_RNGBYTES/2, 969 SUN8I_CRYPTO_RNGBYTES/2)) { 970 device_printf(sc->sc_dev, "failed repeated output test\n"); 971 entropybits = 0; 972 } 973 974 /* 975 * Actually we don't believe in any of the entropy until this 976 * device has had more scrutiny. 977 */ 978 entropybits = 0; 979 980 /* Success! Enter and erase the data. */ 981 rnd_add_data(&rng->cr_rndsource, buf, SUN8I_CRYPTO_RNGBYTES, 982 entropybits); 983 explicit_memset(buf, 0, SUN8I_CRYPTO_RNGBYTES); 984 985 out: /* Done -- clear the RNG-pending flag. */ 986 mutex_enter(&sc->sc_lock); 987 rng->cr_pending = false; 988 mutex_exit(&sc->sc_lock); 989 } 990 991 /* 992 * Self-test 993 */ 994 995 static const uint8_t selftest_input[16]; 996 static const uint8_t selftest_key[16]; 997 static const uint8_t selftest_output[16] = { 998 0x66,0xe9,0x4b,0xd4,0xef,0x8a,0x2c,0x3b, 999 0x88,0x4c,0xfa,0x59,0xca,0x34,0x2b,0x2e, 1000 }; 1001 1002 static void 1003 sun8i_crypto_selftest(device_t self) 1004 { 1005 const size_t datalen = sizeof selftest_input; 1006 struct sun8i_crypto_softc *sc = device_private(self); 1007 struct sun8i_crypto_selftest *selftest = &sc->sc_selftest; 1008 int error; 1009 1010 CTASSERT(sizeof selftest_input == sizeof selftest_output); 1011 1012 /* Allocate an input buffer. */ 1013 error = sun8i_crypto_allocbuf(sc, sizeof selftest_input, 1014 &selftest->cs_in); 1015 if (error) 1016 goto fail0; 1017 1018 /* Allocate a key buffer. */ 1019 error = sun8i_crypto_allocbuf(sc, sizeof selftest_key, 1020 &selftest->cs_key); 1021 if (error) 1022 goto fail1; 1023 1024 /* Allocate an output buffer. */ 1025 error = sun8i_crypto_allocbuf(sc, sizeof selftest_output, 1026 &selftest->cs_out); 1027 if (error) 1028 goto fail2; 1029 1030 /* Allocate a task descriptor. */ 1031 selftest->cs_task = sun8i_crypto_task_get(sc, 1032 sun8i_crypto_selftest_done, selftest); 1033 if (selftest->cs_task == NULL) 1034 goto fail3; 1035 1036 /* Copy the input and key into their buffers. */ 1037 memcpy(selftest->cs_in.cb_kva, selftest_input, sizeof selftest_input); 1038 memcpy(selftest->cs_key.cb_kva, selftest_key, sizeof selftest_key); 1039 1040 /* Prepare for a DMA write from the input and key buffers. */ 1041 bus_dmamap_sync(sc->sc_dmat, selftest->cs_in.cb_map, 0, 1042 sizeof selftest_input, BUS_DMASYNC_PREWRITE); 1043 bus_dmamap_sync(sc->sc_dmat, selftest->cs_key.cb_map, 0, 1044 sizeof selftest_key, BUS_DMASYNC_PREWRITE); 1045 1046 /* Prepare for a DMA read into the output buffer. */ 1047 bus_dmamap_sync(sc->sc_dmat, selftest->cs_out.cb_map, 0, 1048 sizeof selftest_output, BUS_DMASYNC_PREREAD); 1049 1050 /* Set up the task descriptor. */ 1051 sun8i_crypto_task_reset(selftest->cs_task); 1052 sun8i_crypto_task_set_key(selftest->cs_task, selftest->cs_key.cb_map); 1053 sun8i_crypto_task_set_input(selftest->cs_task, selftest->cs_in.cb_map); 1054 sun8i_crypto_task_set_output(selftest->cs_task, 1055 selftest->cs_out.cb_map); 1056 1057 /* Submit the AES-128 ECB task. */ 1058 error = sun8i_crypto_submit_aesecb(sc, selftest->cs_task, datalen, 1059 SUN8I_CRYPTO_TDQS_AES_KEYSIZE_128, SUN8I_CRYPTO_TDQC_OP_DIR_ENC); 1060 if (error) 1061 goto fail4; 1062 1063 device_printf(sc->sc_dev, "AES-128 self-test initiated\n"); 1064 1065 /* Success! */ 1066 return; 1067 1068 fail4: sun8i_crypto_task_put(sc, selftest->cs_task); 1069 fail3: sun8i_crypto_freebuf(sc, sizeof selftest_output, &selftest->cs_out); 1070 fail2: sun8i_crypto_freebuf(sc, sizeof selftest_key, &selftest->cs_key); 1071 fail1: sun8i_crypto_freebuf(sc, sizeof selftest_input, &selftest->cs_in); 1072 fail0: aprint_error_dev(self, "failed to run self-test, error=%d\n", error); 1073 } 1074 1075 static bool 1076 sun8i_crypto_selftest_check(struct sun8i_crypto_softc *sc, const char *title, 1077 size_t n, const void *expected, const void *actual) 1078 { 1079 const uint8_t *e = expected; 1080 const uint8_t *a = actual; 1081 size_t i; 1082 1083 if (memcmp(e, a, n) == 0) 1084 return true; 1085 1086 device_printf(sc->sc_dev, "self-test: %s\n", title); 1087 printf("expected: "); 1088 for (i = 0; i < n; i++) 1089 printf("%02hhx", e[i]); 1090 printf("\n"); 1091 printf("actual: "); 1092 for (i = 0; i < n; i++) 1093 printf("%02hhx", a[i]); 1094 printf("\n"); 1095 return false; 1096 } 1097 1098 static void 1099 sun8i_crypto_selftest_done(struct sun8i_crypto_softc *sc, 1100 struct sun8i_crypto_task *task, void *cookie, int error) 1101 { 1102 struct sun8i_crypto_selftest *selftest = cookie; 1103 bool ok = true; 1104 1105 KASSERT(selftest == &sc->sc_selftest); 1106 1107 /* 1108 * Finished the DMA read into the output buffer, and finished 1109 * the DMA writes from the key buffer and input buffer. 1110 */ 1111 bus_dmamap_sync(sc->sc_dmat, selftest->cs_out.cb_map, 0, 1112 sizeof selftest_output, BUS_DMASYNC_POSTREAD); 1113 bus_dmamap_sync(sc->sc_dmat, selftest->cs_key.cb_map, 0, 1114 sizeof selftest_key, BUS_DMASYNC_POSTWRITE); 1115 bus_dmamap_sync(sc->sc_dmat, selftest->cs_in.cb_map, 0, 1116 sizeof selftest_input, BUS_DMASYNC_POSTWRITE); 1117 1118 /* If anything went wrong, fail now. */ 1119 if (error) { 1120 device_printf(sc->sc_dev, "self-test error=%d\n", error); 1121 goto out; 1122 } 1123 1124 /* 1125 * Verify the input and key weren't clobbered, and verify the 1126 * output matches what we expect. 1127 */ 1128 ok &= sun8i_crypto_selftest_check(sc, "input clobbered", 1129 sizeof selftest_input, selftest_input, selftest->cs_in.cb_kva); 1130 ok &= sun8i_crypto_selftest_check(sc, "key clobbered", 1131 sizeof selftest_key, selftest_key, selftest->cs_key.cb_kva); 1132 ok &= sun8i_crypto_selftest_check(sc, "output mismatch", 1133 sizeof selftest_output, selftest_output, selftest->cs_out.cb_kva); 1134 1135 /* XXX Disable the RNG and other stuff if this fails... */ 1136 if (ok) 1137 device_printf(sc->sc_dev, "AES-128 self-test passed\n"); 1138 1139 out: sun8i_crypto_task_put(sc, task); 1140 sun8i_crypto_freebuf(sc, sizeof selftest_output, &selftest->cs_out); 1141 sun8i_crypto_freebuf(sc, sizeof selftest_key, &selftest->cs_key); 1142 sun8i_crypto_freebuf(sc, sizeof selftest_input, &selftest->cs_in); 1143 } 1144 1145 /* 1146 * Sysctl for testing 1147 */ 1148 1149 struct sun8i_crypto_userreq { 1150 kmutex_t cu_lock; 1151 kcondvar_t cu_cv; 1152 size_t cu_size; 1153 struct sun8i_crypto_buf cu_buf; 1154 struct sun8i_crypto_task *cu_task; 1155 int cu_error; 1156 bool cu_done; 1157 bool cu_cancel; 1158 }; 1159 1160 static void 1161 sun8i_crypto_sysctl_attach(struct sun8i_crypto_softc *sc) 1162 { 1163 struct sun8i_crypto_sysctl *cy = &sc->sc_sysctl; 1164 int error; 1165 1166 /* hw.sun8icryptoN (node) */ 1167 error = sysctl_createv(&cy->cy_log, 0, NULL, &cy->cy_root_node, 1168 CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(sc->sc_dev), 1169 SYSCTL_DESCR("sun8i crypto engine knobs"), 1170 NULL, 0, NULL, 0, 1171 CTL_HW, CTL_CREATE, CTL_EOL); 1172 if (error) { 1173 aprint_error_dev(sc->sc_dev, 1174 "failed to set up sysctl hw.%s: %d\n", 1175 device_xname(sc->sc_dev), error); 1176 return; 1177 } 1178 1179 /* hw.sun8icryptoN.rng (`struct', 4096-byte array) */ 1180 sysctl_createv(&cy->cy_log, 0, &cy->cy_root_node, &cy->cy_trng_node, 1181 CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_PRIVATE, CTLTYPE_STRUCT, 1182 "rng", SYSCTL_DESCR("Read up to 4096 bytes out of the TRNG"), 1183 &sun8i_crypto_sysctl_rng, 0, sc, 0, CTL_CREATE, CTL_EOL); 1184 if (error) { 1185 aprint_error_dev(sc->sc_dev, 1186 "failed to set up sysctl hw.%s.rng: %d\n", 1187 device_xname(sc->sc_dev), error); 1188 return; 1189 } 1190 } 1191 1192 static int 1193 sun8i_crypto_sysctl_rng(SYSCTLFN_ARGS) 1194 { 1195 struct sysctlnode node = *rnode; 1196 struct sun8i_crypto_softc *sc = node.sysctl_data; 1197 struct sun8i_crypto_userreq *req; 1198 size_t size; 1199 int error; 1200 1201 /* If oldp == NULL, the caller wants to learn the size. */ 1202 if (oldp == NULL) { 1203 *oldlenp = 4096; 1204 return 0; 1205 } 1206 1207 /* Verify the output buffer size is reasonable. */ 1208 size = *oldlenp; 1209 if (size > 4096) /* size_t, so never negative */ 1210 return E2BIG; 1211 if (size == 0) 1212 return 0; /* nothing to do */ 1213 1214 /* Allocate a request context. */ 1215 req = kmem_alloc(sizeof(*req), KM_NOSLEEP); 1216 if (req == NULL) 1217 return ENOMEM; 1218 1219 /* Initialize the request context. */ 1220 mutex_init(&req->cu_lock, MUTEX_DEFAULT, IPL_NONE); 1221 cv_init(&req->cu_cv, "sun8isy"); 1222 req->cu_size = size; 1223 req->cu_error = EIO; 1224 req->cu_done = false; 1225 req->cu_cancel = false; 1226 1227 /* Allocate a buffer for the RNG output. */ 1228 error = sun8i_crypto_allocbuf(sc, size, &req->cu_buf); 1229 if (error) 1230 goto out0; 1231 1232 /* Allocate a task. */ 1233 req->cu_task = sun8i_crypto_task_get(sc, sun8i_crypto_sysctl_rng_done, 1234 req); 1235 if (req->cu_task == NULL) 1236 goto out1; 1237 1238 /* Prepare for a DMA read into the buffer. */ 1239 bus_dmamap_sync(sc->sc_dmat, req->cu_buf.cb_map, 0, size, 1240 BUS_DMASYNC_PREREAD); 1241 1242 /* Set the task up for TRNG to our buffer. */ 1243 sun8i_crypto_task_reset(req->cu_task); 1244 sun8i_crypto_task_set_output(req->cu_task, req->cu_buf.cb_map); 1245 1246 /* Submit the TRNG task. */ 1247 error = sun8i_crypto_submit_trng(sc, req->cu_task, size); 1248 if (error) { 1249 if (error == ERESTART) 1250 error = EBUSY; 1251 goto out2; 1252 } 1253 1254 /* Wait for the request to complete. */ 1255 mutex_enter(&req->cu_lock); 1256 while (!req->cu_done) { 1257 error = cv_wait_sig(&req->cu_cv, &req->cu_lock); 1258 if (error) { 1259 /* 1260 * If we finished while waiting to acquire the 1261 * lock, ignore the error and just return now. 1262 * Otherwise, notify the callback that it has 1263 * to clean up after us. 1264 */ 1265 if (req->cu_done) 1266 error = 0; 1267 else 1268 req->cu_cancel = true; 1269 break; 1270 } 1271 } 1272 mutex_exit(&req->cu_lock); 1273 1274 /* 1275 * Return early on error from cv_wait_sig, which means 1276 * interruption; the callback will clean up instead. 1277 */ 1278 if (error) 1279 return error; 1280 1281 /* Check for error from the device. */ 1282 error = req->cu_error; 1283 if (error) 1284 goto out2; 1285 1286 /* Finished the DMA read into the buffer. */ 1287 bus_dmamap_sync(sc->sc_dmat, req->cu_buf.cb_map, 0, req->cu_size, 1288 BUS_DMASYNC_POSTREAD); 1289 1290 /* Copy out the data. */ 1291 node.sysctl_data = req->cu_buf.cb_kva; 1292 node.sysctl_size = size; 1293 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1294 1295 /* Clear the buffer. */ 1296 explicit_memset(req->cu_buf.cb_kva, 0, size); 1297 1298 /* Clean up. */ 1299 out2: sun8i_crypto_task_put(sc, req->cu_task); 1300 out1: sun8i_crypto_freebuf(sc, req->cu_size, &req->cu_buf); 1301 out0: cv_destroy(&req->cu_cv); 1302 mutex_destroy(&req->cu_lock); 1303 kmem_free(req, sizeof(*req)); 1304 return error; 1305 } 1306 1307 static void 1308 sun8i_crypto_sysctl_rng_done(struct sun8i_crypto_softc *sc, 1309 struct sun8i_crypto_task *task, void *cookie, int error) 1310 { 1311 struct sun8i_crypto_userreq *req = cookie; 1312 bool cancel; 1313 1314 /* 1315 * Notify the waiting thread of the error, and find out whether 1316 * that thread cancelled. 1317 */ 1318 mutex_enter(&req->cu_lock); 1319 cancel = req->cu_cancel; 1320 req->cu_error = error; 1321 req->cu_done = true; 1322 cv_broadcast(&req->cu_cv); 1323 mutex_exit(&req->cu_lock); 1324 1325 /* 1326 * If it wasn't cancelled, we're done -- the main thread will 1327 * clean up after itself. 1328 */ 1329 if (!cancel) 1330 return; 1331 1332 /* Clean up after the main thread cancelled. */ 1333 sun8i_crypto_task_put(sc, req->cu_task); 1334 sun8i_crypto_freebuf(sc, req->cu_size, &req->cu_buf); 1335 cv_destroy(&req->cu_cv); 1336 mutex_destroy(&req->cu_lock); 1337 kmem_free(req, sizeof(*req)); 1338 } 1339