11.11Smrg/* $NetBSD: rk_v1crypto.c,v 1.11 2023/04/24 05:16:01 mrg Exp $ */ 21.1Sriastrad 31.1Sriastrad/*- 41.1Sriastrad * Copyright (c) 2020 The NetBSD Foundation, Inc. 51.1Sriastrad * All rights reserved. 61.1Sriastrad * 71.1Sriastrad * This code is derived from software contributed to The NetBSD Foundation 81.1Sriastrad * by Taylor R. Campbell. 91.1Sriastrad * 101.1Sriastrad * Redistribution and use in source and binary forms, with or without 111.1Sriastrad * modification, are permitted provided that the following conditions 121.1Sriastrad * are met: 131.1Sriastrad * 1. Redistributions of source code must retain the above copyright 141.1Sriastrad * notice, this list of conditions and the following disclaimer. 151.1Sriastrad * 2. Redistributions in binary form must reproduce the above copyright 161.1Sriastrad * notice, this list of conditions and the following disclaimer in the 171.1Sriastrad * documentation and/or other materials provided with the distribution. 181.1Sriastrad * 191.1Sriastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 201.1Sriastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 211.1Sriastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 221.1Sriastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 231.1Sriastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 241.1Sriastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 251.1Sriastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 261.1Sriastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 271.1Sriastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 281.1Sriastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 291.1Sriastrad * POSSIBILITY OF SUCH DAMAGE. 301.1Sriastrad */ 311.1Sriastrad 321.1Sriastrad/* 331.1Sriastrad * rk_v1crypto -- Rockchip crypto v1 driver 341.1Sriastrad * 351.1Sriastrad * This is just the RNG for now. 361.1Sriastrad */ 371.1Sriastrad 381.1Sriastrad#include <sys/cdefs.h> 391.11Smrg__KERNEL_RCSID(1, "$NetBSD: rk_v1crypto.c,v 1.11 2023/04/24 05:16:01 mrg Exp $"); 401.1Sriastrad 411.1Sriastrad#include <sys/types.h> 421.1Sriastrad 431.1Sriastrad#include <sys/bus.h> 441.1Sriastrad#include <sys/device.h> 451.1Sriastrad#include <sys/errno.h> 461.1Sriastrad#include <sys/mutex.h> 471.1Sriastrad#include <sys/rndsource.h> 481.1Sriastrad#include <sys/sysctl.h> 491.1Sriastrad 501.1Sriastrad#include <dev/fdt/fdtvar.h> 511.1Sriastrad 521.1Sriastrad#include <arm/rockchip/rk_v1crypto.h> 531.1Sriastrad 541.1Sriastradstruct rk_v1crypto_softc { 551.1Sriastrad device_t sc_dev; 561.1Sriastrad bus_space_tag_t sc_bst; 571.1Sriastrad bus_space_handle_t sc_bsh; 581.1Sriastrad kmutex_t sc_lock; 591.1Sriastrad struct krndsource sc_rndsource; 601.1Sriastrad struct rk_v1crypto_sysctl { 611.1Sriastrad struct sysctllog *cy_log; 621.1Sriastrad const struct sysctlnode *cy_root_node; 631.1Sriastrad } sc_sysctl; 641.1Sriastrad}; 651.1Sriastrad 661.1Sriastradstatic int rk_v1crypto_match(device_t, cfdata_t, void *); 671.1Sriastradstatic void rk_v1crypto_attach(device_t, device_t, void *); 681.1Sriastradstatic int rk_v1crypto_selftest(struct rk_v1crypto_softc *); 691.1Sriastradstatic void rk_v1crypto_rndsource_attach(struct rk_v1crypto_softc *); 701.1Sriastradstatic void rk_v1crypto_rng_get(size_t, void *); 711.1Sriastradstatic void rk_v1crypto_sysctl_attach(struct rk_v1crypto_softc *); 721.1Sriastradstatic int rk_v1crypto_sysctl_rng(SYSCTLFN_ARGS); 731.1Sriastradstatic int rk_v1crypto_rng(struct rk_v1crypto_softc *, 741.1Sriastrad uint32_t[static RK_V1CRYPTO_TRNG_NOUT]); 751.1Sriastrad 761.1Sriastradstatic uint32_t 771.1SriastradRKC_READ(struct rk_v1crypto_softc *sc, bus_addr_t reg) 781.1Sriastrad{ 791.1Sriastrad return bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg); 801.1Sriastrad} 811.1Sriastrad 821.1Sriastradstatic void 831.1SriastradRKC_WRITE(struct rk_v1crypto_softc *sc, bus_addr_t reg, uint32_t v) 841.1Sriastrad{ 851.3Stnn bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, v); 861.1Sriastrad} 871.1Sriastrad 881.1Sriastradstatic inline void 891.1SriastradRKC_CTRL(struct rk_v1crypto_softc *sc, uint16_t m, uint16_t v) 901.1Sriastrad{ 911.1Sriastrad uint32_t c = 0; 921.1Sriastrad 931.1Sriastrad c |= __SHIFTIN(m, RK_V1CRYPTO_CTRL_MASK); 941.1Sriastrad c |= __SHIFTIN(v, m); 951.1Sriastrad RKC_WRITE(sc, RK_V1CRYPTO_CTRL, c); 961.1Sriastrad} 971.1Sriastrad 981.1SriastradCFATTACH_DECL_NEW(rk_v1crypto, sizeof(struct rk_v1crypto_softc), 991.1Sriastrad rk_v1crypto_match, rk_v1crypto_attach, NULL, NULL); 1001.1Sriastrad 1011.11Smrgstruct rk_v1crypto_data { 1021.11Smrg int num_clks; 1031.11Smrg const char *const clks[]; 1041.11Smrg}; 1051.11Smrg 1061.11Smrgstatic const struct rk_v1crypto_data rk3288_crypto_data = { 1071.11Smrg .num_clks = 4, 1081.11Smrg .clks = {"aclk", "hclk", "sclk", "apb_pclk"}, 1091.11Smrg}; 1101.11Smrg 1111.11Smrgstatic const struct rk_v1crypto_data rk3328_crypto_data = { 1121.11Smrg .num_clks = 3, 1131.11Smrg .clks = {"hclk_master", "hclk_slave", "sclk"}, 1141.11Smrg}; 1151.11Smrg 1161.4Sthorpejstatic const struct device_compatible_entry compat_data[] = { 1171.11Smrg { .compat = "rockchip,rk3288-crypto", .data = &rk3288_crypto_data }, 1181.11Smrg { .compat = "rockchip,rk3328-crypto", .data = &rk3328_crypto_data }, 1191.6Sthorpej DEVICE_COMPAT_EOL 1201.1Sriastrad}; 1211.1Sriastrad 1221.1Sriastradstatic int 1231.1Sriastradrk_v1crypto_match(device_t parent, cfdata_t cf, void *aux) 1241.1Sriastrad{ 1251.1Sriastrad const struct fdt_attach_args *const faa = aux; 1261.1Sriastrad 1271.7Sthorpej return of_compatible_match(faa->faa_phandle, compat_data); 1281.1Sriastrad} 1291.1Sriastrad 1301.1Sriastradstatic void 1311.1Sriastradrk_v1crypto_attach(device_t parent, device_t self, void *aux) 1321.1Sriastrad{ 1331.1Sriastrad struct rk_v1crypto_softc *const sc = device_private(self); 1341.1Sriastrad const struct fdt_attach_args *const faa = aux; 1351.1Sriastrad bus_addr_t addr; 1361.1Sriastrad bus_size_t size; 1371.1Sriastrad const int phandle = faa->faa_phandle; 1381.1Sriastrad struct fdtbus_reset *rst; 1391.1Sriastrad unsigned i; 1401.1Sriastrad uint32_t ctrl; 1411.11Smrg const struct rk_v1crypto_data *config = 1421.11Smrg of_compatible_lookup(phandle, compat_data)->data; 1431.11Smrg const char *const *clks = config->clks; 1441.1Sriastrad 1451.1Sriastrad fdtbus_clock_assign(phandle); 1461.1Sriastrad 1471.1Sriastrad sc->sc_dev = self; 1481.1Sriastrad sc->sc_bst = faa->faa_bst; 1491.8Sriastrad mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTSERIAL); 1501.1Sriastrad 1511.1Sriastrad /* Get and map device registers. */ 1521.1Sriastrad if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 1531.1Sriastrad aprint_error(": couldn't get registers\n"); 1541.1Sriastrad return; 1551.1Sriastrad } 1561.1Sriastrad if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 1571.1Sriastrad aprint_error(": couldn't map registers\n"); 1581.1Sriastrad return; 1591.1Sriastrad } 1601.1Sriastrad 1611.1Sriastrad /* Enable the clocks. */ 1621.11Smrg for (i = 0; i < config->num_clks; i++) { 1631.1Sriastrad if (fdtbus_clock_enable(phandle, clks[i], true) != 0) { 1641.1Sriastrad aprint_error(": couldn't enable %s clock\n", clks[i]); 1651.1Sriastrad return; 1661.1Sriastrad } 1671.1Sriastrad } 1681.1Sriastrad 1691.1Sriastrad /* Get a reset handle if we need and try to deassert it. */ 1701.1Sriastrad if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL) { 1711.1Sriastrad if (fdtbus_reset_deassert(rst) != 0) { 1721.1Sriastrad aprint_error(": couldn't de-assert reset\n"); 1731.1Sriastrad return; 1741.1Sriastrad } 1751.1Sriastrad } 1761.1Sriastrad 1771.1Sriastrad aprint_naive("\n"); 1781.1Sriastrad aprint_normal(": Crypto v1\n"); 1791.1Sriastrad 1801.1Sriastrad /* 1811.1Sriastrad * Enable ring oscillator to start gathering entropy, and set 1821.1Sriastrad * up the crypto clock to sample it once every 100 cycles. 1831.1Sriastrad * 1841.1Sriastrad * The ring oscillator can run even when the clock is gated or 1851.1Sriastrad * flush is asserted, and the longer we run it, the less it 1861.1Sriastrad * will be synchronized with the main clock owing to jitter 1871.1Sriastrad * ideally from unpredictable thermal noise. 1881.1Sriastrad */ 1891.1Sriastrad ctrl = RK_V1CRYPTO_TRNG_CTRL_OSC_ENABLE; 1901.1Sriastrad ctrl |= __SHIFTIN(100, RK_V1CRYPTO_TRNG_CTRL_CYCLES); 1911.1Sriastrad RKC_WRITE(sc, RK_V1CRYPTO_TRNG_CTRL, ctrl); 1921.1Sriastrad 1931.1Sriastrad if (rk_v1crypto_selftest(sc)) 1941.1Sriastrad return; 1951.1Sriastrad rk_v1crypto_rndsource_attach(sc); 1961.1Sriastrad rk_v1crypto_sysctl_attach(sc); 1971.1Sriastrad} 1981.1Sriastrad 1991.1Sriastradstatic int 2001.1Sriastradrk_v1crypto_selftest(struct rk_v1crypto_softc *sc) 2011.1Sriastrad{ 2021.1Sriastrad static const uint32_t key[4] = {0}; 2031.1Sriastrad static const uint32_t input[4] = {0}; 2041.1Sriastrad static const uint32_t expected[4] = { 2051.1Sriastrad 0x66e94bd4, 0xef8a2c3b, 0x884cfa59, 0xca342b2e, 2061.1Sriastrad }; 2071.1Sriastrad uint32_t output[4]; 2081.1Sriastrad uint32_t ctrl; 2091.1Sriastrad unsigned i, timo; 2101.1Sriastrad 2111.1Sriastrad /* Program the key and input block. */ 2121.1Sriastrad for (i = 0; i < 4; i++) 2131.1Sriastrad RKC_WRITE(sc, RK_V1CRYPTO_AES_DIN(i), key[i]); 2141.1Sriastrad for (i = 0; i < 4; i++) 2151.1Sriastrad RKC_WRITE(sc, RK_V1CRYPTO_AES_DIN(i), input[i]); 2161.1Sriastrad 2171.1Sriastrad /* 2181.1Sriastrad * Set up the AES unit to do AES-128 `ECB' (i.e., just the raw 2191.1Sriastrad * AES permutation) in the encryption direction. 2201.1Sriastrad */ 2211.1Sriastrad ctrl = 0; 2221.1Sriastrad ctrl |= RK_V1CRYPTO_AES_CTRL_KEYCHANGE; 2231.1Sriastrad ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_MODE_ECB, 2241.1Sriastrad RK_V1CRYPTO_AES_CTRL_MODE); 2251.1Sriastrad ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_KEYSIZE_128, 2261.1Sriastrad RK_V1CRYPTO_AES_CTRL_KEYSIZE); 2271.1Sriastrad ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_DIR_ENC, 2281.1Sriastrad RK_V1CRYPTO_AES_CTRL_DIR); 2291.1Sriastrad RKC_WRITE(sc, RK_V1CRYPTO_AES_CTRL, ctrl); 2301.1Sriastrad 2311.1Sriastrad /* Kick it off. */ 2321.1Sriastrad RKC_CTRL(sc, RK_V1CRYPTO_CTRL_AES_START, 1); 2331.1Sriastrad 2341.1Sriastrad /* Wait up to 1ms for it to complete. */ 2351.1Sriastrad timo = 1000; 2361.1Sriastrad while (RKC_READ(sc, RK_V1CRYPTO_CTRL) & RK_V1CRYPTO_CTRL_AES_START) { 2371.1Sriastrad if (--timo == 0) { 2381.1Sriastrad device_printf(sc->sc_dev, "AES self-test timed out\n"); 2391.1Sriastrad return -1; 2401.1Sriastrad } 2411.1Sriastrad DELAY(1); 2421.1Sriastrad } 2431.1Sriastrad 2441.1Sriastrad /* Read the output. */ 2451.1Sriastrad for (i = 0; i < 4; i++) 2461.1Sriastrad output[i] = RKC_READ(sc, RK_V1CRYPTO_AES_DOUT(i)); 2471.1Sriastrad 2481.1Sriastrad /* Verify the output. */ 2491.1Sriastrad for (i = 0; i < 4; i++) { 2501.1Sriastrad if (output[i] != expected[i]) { 2511.1Sriastrad device_printf(sc->sc_dev, "AES self-test failed\n"); 2521.1Sriastrad return -1; 2531.1Sriastrad } 2541.1Sriastrad } 2551.1Sriastrad 2561.1Sriastrad /* Success! */ 2571.1Sriastrad return 0; 2581.1Sriastrad} 2591.1Sriastrad 2601.1Sriastradstatic void 2611.1Sriastradrk_v1crypto_rndsource_attach(struct rk_v1crypto_softc *sc) 2621.1Sriastrad{ 2631.1Sriastrad device_t self = sc->sc_dev; 2641.1Sriastrad 2651.1Sriastrad rndsource_setcb(&sc->sc_rndsource, rk_v1crypto_rng_get, sc); 2661.1Sriastrad rnd_attach_source(&sc->sc_rndsource, device_xname(self), 2671.1Sriastrad RND_TYPE_RNG, RND_FLAG_DEFAULT|RND_FLAG_HASCB); 2681.1Sriastrad} 2691.1Sriastrad 2701.1Sriastradstatic void 2711.1Sriastradrk_v1crypto_rng_get(size_t nbytes, void *cookie) 2721.1Sriastrad{ 2731.1Sriastrad struct rk_v1crypto_softc *sc = cookie; 2741.1Sriastrad device_t self = sc->sc_dev; 2751.1Sriastrad uint32_t buf[RK_V1CRYPTO_TRNG_NOUT]; 2761.1Sriastrad uint32_t entropybits = NBBY*sizeof(buf)/2; /* be conservative */ 2771.1Sriastrad unsigned n = RK_V1CRYPTO_TRNG_NOUT; 2781.1Sriastrad int error; 2791.1Sriastrad size_t nbits = NBBY*nbytes; 2801.1Sriastrad 2811.1Sriastrad while (nbits) { 2821.1Sriastrad CTASSERT((RK_V1CRYPTO_TRNG_NOUT % 2) == 0); 2831.1Sriastrad 2841.1Sriastrad error = rk_v1crypto_rng(sc, buf); 2851.1Sriastrad if (error) { 2861.1Sriastrad device_printf(self, "timed out\n"); 2871.1Sriastrad break; 2881.1Sriastrad } 2891.10Sriastrad if (consttime_memequal(buf, buf + n/2, sizeof(buf[0]) * n/2)) { 2901.1Sriastrad device_printf(self, "failed repeated output test\n"); 2911.1Sriastrad break; 2921.1Sriastrad } 2931.2Sriastrad rnd_add_data_sync(&sc->sc_rndsource, buf, sizeof buf, 2941.2Sriastrad entropybits); 2951.1Sriastrad nbits -= MIN(nbits, MAX(1, entropybits)); 2961.1Sriastrad } 2971.1Sriastrad explicit_memset(buf, 0, sizeof buf); 2981.1Sriastrad} 2991.1Sriastrad 3001.1Sriastradstatic void 3011.1Sriastradrk_v1crypto_sysctl_attach(struct rk_v1crypto_softc *sc) 3021.1Sriastrad{ 3031.1Sriastrad device_t self = sc->sc_dev; 3041.1Sriastrad struct rk_v1crypto_sysctl *cy = &sc->sc_sysctl; 3051.1Sriastrad int error; 3061.1Sriastrad 3071.1Sriastrad /* hw.rkv1cryptoN (node) */ 3081.1Sriastrad error = sysctl_createv(&cy->cy_log, 0, NULL, &cy->cy_root_node, 3091.1Sriastrad CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(self), 3101.1Sriastrad SYSCTL_DESCR("rk crypto v1 engine knobs"), 3111.1Sriastrad NULL, 0, NULL, 0, 3121.1Sriastrad CTL_HW, CTL_CREATE, CTL_EOL); 3131.1Sriastrad if (error) { 3141.1Sriastrad aprint_error_dev(self, 3151.1Sriastrad "failed to set up sysctl hw.%s: %d\n", 3161.1Sriastrad device_xname(self), error); 3171.1Sriastrad return; 3181.1Sriastrad } 3191.1Sriastrad 3201.1Sriastrad /* hw.rkv1cryptoN.rng (`struct', 32-byte array) */ 3211.9Sriastrad error = sysctl_createv(&cy->cy_log, 0, &cy->cy_root_node, NULL, 3221.1Sriastrad CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_PRIVATE, CTLTYPE_STRUCT, 3231.1Sriastrad "rng", SYSCTL_DESCR("Read up to 32 bytes out of the TRNG"), 3241.1Sriastrad &rk_v1crypto_sysctl_rng, 0, sc, 0, CTL_CREATE, CTL_EOL); 3251.1Sriastrad if (error) { 3261.1Sriastrad aprint_error_dev(self, 3271.1Sriastrad "failed to set up sysctl hw.%s.rng: %d\n", 3281.1Sriastrad device_xname(self), error); 3291.1Sriastrad return; 3301.1Sriastrad } 3311.1Sriastrad} 3321.1Sriastrad 3331.1Sriastradstatic int 3341.1Sriastradrk_v1crypto_sysctl_rng(SYSCTLFN_ARGS) 3351.1Sriastrad{ 3361.1Sriastrad uint32_t buf[RK_V1CRYPTO_TRNG_NOUT]; 3371.1Sriastrad struct sysctlnode node = *rnode; 3381.1Sriastrad struct rk_v1crypto_softc *sc = node.sysctl_data; 3391.1Sriastrad size_t size; 3401.1Sriastrad int error; 3411.1Sriastrad 3421.1Sriastrad /* If oldp == NULL, the caller wants to learn the size. */ 3431.1Sriastrad if (oldp == NULL) { 3441.1Sriastrad *oldlenp = sizeof buf; 3451.1Sriastrad return 0; 3461.1Sriastrad } 3471.1Sriastrad 3481.1Sriastrad /* Verify the output buffer size is reasonable. */ 3491.1Sriastrad size = *oldlenp; 3501.1Sriastrad if (size > sizeof buf) /* size_t, so never negative */ 3511.1Sriastrad return E2BIG; 3521.1Sriastrad if (size == 0) 3531.1Sriastrad return 0; /* nothing to do */ 3541.1Sriastrad 3551.1Sriastrad /* Generate data. */ 3561.1Sriastrad error = rk_v1crypto_rng(sc, buf); 3571.1Sriastrad if (error) 3581.1Sriastrad return error; 3591.1Sriastrad 3601.1Sriastrad /* Copy out the data. */ 3611.1Sriastrad node.sysctl_data = buf; 3621.1Sriastrad node.sysctl_size = size; 3631.1Sriastrad error = sysctl_lookup(SYSCTLFN_CALL(&node)); 3641.1Sriastrad 3651.1Sriastrad /* Clear the buffer. */ 3661.1Sriastrad explicit_memset(buf, 0, sizeof buf); 3671.1Sriastrad 3681.1Sriastrad /* Return the sysctl_lookup error, if any. */ 3691.1Sriastrad return error; 3701.1Sriastrad} 3711.1Sriastrad 3721.1Sriastradstatic int 3731.1Sriastradrk_v1crypto_rng(struct rk_v1crypto_softc *sc, 3741.1Sriastrad uint32_t buf[static RK_V1CRYPTO_TRNG_NOUT]) 3751.1Sriastrad{ 3761.1Sriastrad unsigned i, timo; 3771.1Sriastrad int error; 3781.1Sriastrad 3791.1Sriastrad /* Acquire lock to serialize access to TRNG. */ 3801.1Sriastrad mutex_enter(&sc->sc_lock); 3811.1Sriastrad 3821.1Sriastrad /* 3831.1Sriastrad * Query TRNG and wait up to 1ms for it to post. Empirically, 3841.1Sriastrad * this takes around 120us. 3851.1Sriastrad */ 3861.1Sriastrad RKC_CTRL(sc, RK_V1CRYPTO_CTRL_TRNG_START, 1); 3871.1Sriastrad timo = 1000; 3881.1Sriastrad while (RKC_READ(sc, RK_V1CRYPTO_CTRL) & RK_V1CRYPTO_CTRL_TRNG_START) { 3891.1Sriastrad if (--timo == 0) { 3901.1Sriastrad error = ETIMEDOUT; 3911.1Sriastrad goto out; 3921.1Sriastrad } 3931.1Sriastrad DELAY(1); 3941.1Sriastrad } 3951.1Sriastrad 3961.1Sriastrad /* Read out the data. */ 3971.1Sriastrad for (i = 0; i < RK_V1CRYPTO_TRNG_NOUT; i++) 3981.1Sriastrad buf[i] = RKC_READ(sc, RK_V1CRYPTO_TRNG_DOUT(i)); 3991.1Sriastrad 4001.1Sriastrad /* Success! */ 4011.1Sriastrad error = 0; 4021.1Sriastradout: mutex_exit(&sc->sc_lock); 4031.1Sriastrad return error; 4041.1Sriastrad} 405