1 1.4 jmcneill /* $NetBSD: chacha_impl.c,v 1.4 2022/11/05 17:36:33 jmcneill Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /*- 4 1.1 riastrad * Copyright (c) 2020 The NetBSD Foundation, Inc. 5 1.1 riastrad * All rights reserved. 6 1.1 riastrad * 7 1.1 riastrad * Redistribution and use in source and binary forms, with or without 8 1.1 riastrad * modification, are permitted provided that the following conditions 9 1.1 riastrad * are met: 10 1.1 riastrad * 1. Redistributions of source code must retain the above copyright 11 1.1 riastrad * notice, this list of conditions and the following disclaimer. 12 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 riastrad * notice, this list of conditions and the following disclaimer in the 14 1.1 riastrad * documentation and/or other materials provided with the distribution. 15 1.1 riastrad * 16 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 1.1 riastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 1.1 riastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 1.1 riastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 1.1 riastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.1 riastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.1 riastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.1 riastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.1 riastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.1 riastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.1 riastrad * POSSIBILITY OF SUCH DAMAGE. 27 1.1 riastrad */ 28 1.1 riastrad 29 1.1 riastrad #include <sys/types.h> 30 1.1 riastrad #include <sys/cdefs.h> 31 1.1 riastrad #include <sys/errno.h> 32 1.1 riastrad #include <sys/module.h> 33 1.1 riastrad #include <sys/once.h> 34 1.1 riastrad #include <sys/sysctl.h> 35 1.1 riastrad 36 1.1 riastrad #include <lib/libkern/libkern.h> 37 1.1 riastrad 38 1.1 riastrad #include "chacha.h" 39 1.1 riastrad #include "chacha_ref.h" 40 1.1 riastrad 41 1.3 riastrad static const struct chacha_impl *chacha_md_impl __read_mostly; 42 1.3 riastrad static const struct chacha_impl *chacha_impl __read_mostly = &chacha_ref_impl; 43 1.1 riastrad 44 1.1 riastrad static int 45 1.2 riastrad sysctl_kern_crypto_chacha_selected(SYSCTLFN_ARGS) 46 1.1 riastrad { 47 1.1 riastrad struct sysctlnode node; 48 1.1 riastrad 49 1.1 riastrad node = *rnode; 50 1.1 riastrad node.sysctl_data = __UNCONST(chacha_impl->ci_name); 51 1.1 riastrad node.sysctl_size = strlen(chacha_impl->ci_name) + 1; 52 1.1 riastrad return sysctl_lookup(SYSCTLFN_CALL(&node)); 53 1.1 riastrad } 54 1.1 riastrad 55 1.2 riastrad SYSCTL_SETUP(sysctl_kern_crypto_chacha_setup, "sysctl kern.crypto.chacha setup") 56 1.1 riastrad { 57 1.2 riastrad const struct sysctlnode *cnode; 58 1.2 riastrad const struct sysctlnode *chacha_node; 59 1.1 riastrad 60 1.2 riastrad sysctl_createv(clog, 0, NULL, &cnode, 0, CTLTYPE_NODE, "crypto", 61 1.2 riastrad SYSCTL_DESCR("Kernel cryptography"), 62 1.2 riastrad NULL, 0, NULL, 0, 63 1.2 riastrad CTL_KERN, CTL_CREATE, CTL_EOL); 64 1.2 riastrad sysctl_createv(clog, 0, &cnode, &chacha_node, 0, CTLTYPE_NODE, "chacha", 65 1.2 riastrad SYSCTL_DESCR("ChaCha"), 66 1.2 riastrad NULL, 0, NULL, 0, 67 1.2 riastrad CTL_CREATE, CTL_EOL); 68 1.2 riastrad sysctl_createv(clog, 0, &chacha_node, NULL, 69 1.2 riastrad CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_STRING, "selected", 70 1.1 riastrad SYSCTL_DESCR("Selected ChaCha implementation"), 71 1.2 riastrad sysctl_kern_crypto_chacha_selected, 0, NULL, 0, 72 1.2 riastrad CTL_CREATE, CTL_EOL); 73 1.1 riastrad } 74 1.1 riastrad 75 1.1 riastrad static int 76 1.1 riastrad chacha_select(void) 77 1.1 riastrad { 78 1.1 riastrad 79 1.1 riastrad if (chacha_md_impl) { 80 1.1 riastrad if (chacha_selftest(chacha_md_impl)) 81 1.1 riastrad aprint_error("chacha: self-test failed: %s\n", 82 1.1 riastrad chacha_md_impl->ci_name); 83 1.1 riastrad else 84 1.1 riastrad chacha_impl = chacha_md_impl; 85 1.1 riastrad } 86 1.1 riastrad 87 1.4 jmcneill aprint_debug("chacha: %s\n", chacha_impl->ci_name); 88 1.1 riastrad return 0; 89 1.1 riastrad } 90 1.1 riastrad 91 1.1 riastrad MODULE(MODULE_CLASS_MISC, chacha, NULL); 92 1.1 riastrad 93 1.1 riastrad static int 94 1.1 riastrad chacha_modcmd(modcmd_t cmd, void *opaque) 95 1.1 riastrad { 96 1.1 riastrad 97 1.1 riastrad switch (cmd) { 98 1.1 riastrad case MODULE_CMD_INIT: 99 1.1 riastrad return chacha_select(); 100 1.1 riastrad case MODULE_CMD_FINI: 101 1.1 riastrad return 0; 102 1.1 riastrad default: 103 1.1 riastrad return ENOTTY; 104 1.1 riastrad } 105 1.1 riastrad } 106 1.1 riastrad 107 1.1 riastrad void 108 1.1 riastrad chacha_md_init(const struct chacha_impl *impl) 109 1.1 riastrad { 110 1.1 riastrad 111 1.1 riastrad KASSERT(cold); 112 1.1 riastrad KASSERTMSG(chacha_md_impl == NULL, 113 1.1 riastrad "ChaCha implementation `%s' already offered, can't offer `%s'", 114 1.1 riastrad chacha_md_impl->ci_name, impl->ci_name); 115 1.1 riastrad 116 1.1 riastrad chacha_md_impl = impl; 117 1.1 riastrad } 118 1.1 riastrad 119 1.1 riastrad void 120 1.1 riastrad chacha_core(uint8_t out[restrict static CHACHA_CORE_OUTBYTES], 121 1.1 riastrad const uint8_t in[static CHACHA_CORE_INBYTES], 122 1.1 riastrad const uint8_t k[static CHACHA_CORE_KEYBYTES], 123 1.1 riastrad const uint8_t c[static CHACHA_CORE_CONSTBYTES], 124 1.1 riastrad unsigned nr) 125 1.1 riastrad { 126 1.1 riastrad 127 1.1 riastrad (*chacha_impl->ci_chacha_core)(out, in, k, c, nr); 128 1.1 riastrad } 129 1.1 riastrad 130 1.1 riastrad void 131 1.1 riastrad hchacha(uint8_t out[restrict static HCHACHA_OUTBYTES], 132 1.1 riastrad const uint8_t in[static HCHACHA_INBYTES], 133 1.1 riastrad const uint8_t k[static HCHACHA_KEYBYTES], 134 1.1 riastrad const uint8_t c[static HCHACHA_CONSTBYTES], 135 1.1 riastrad unsigned nr) 136 1.1 riastrad { 137 1.1 riastrad 138 1.1 riastrad (*chacha_impl->ci_hchacha)(out, in, k, c, nr); 139 1.1 riastrad } 140 1.1 riastrad 141 1.1 riastrad void 142 1.1 riastrad chacha_stream(uint8_t *restrict s, size_t nbytes, uint32_t blkno, 143 1.1 riastrad const uint8_t nonce[static CHACHA_STREAM_NONCEBYTES], 144 1.1 riastrad const uint8_t key[static CHACHA_STREAM_KEYBYTES], 145 1.1 riastrad unsigned nr) 146 1.1 riastrad { 147 1.1 riastrad 148 1.1 riastrad (*chacha_impl->ci_chacha_stream)(s, nbytes, blkno, nonce, key, nr); 149 1.1 riastrad } 150 1.1 riastrad 151 1.1 riastrad void 152 1.1 riastrad chacha_stream_xor(uint8_t *c, const uint8_t *p, size_t nbytes, uint32_t blkno, 153 1.1 riastrad const uint8_t nonce[static CHACHA_STREAM_NONCEBYTES], 154 1.1 riastrad const uint8_t key[static CHACHA_STREAM_KEYBYTES], 155 1.1 riastrad unsigned nr) 156 1.1 riastrad { 157 1.1 riastrad 158 1.1 riastrad (*chacha_impl->ci_chacha_stream_xor)(c, p, nbytes, blkno, nonce, key, 159 1.1 riastrad nr); 160 1.1 riastrad } 161 1.1 riastrad 162 1.1 riastrad void 163 1.1 riastrad xchacha_stream(uint8_t *restrict s, size_t nbytes, uint32_t blkno, 164 1.1 riastrad const uint8_t nonce[static XCHACHA_STREAM_NONCEBYTES], 165 1.1 riastrad const uint8_t key[static XCHACHA_STREAM_KEYBYTES], 166 1.1 riastrad unsigned nr) 167 1.1 riastrad { 168 1.1 riastrad 169 1.1 riastrad (*chacha_impl->ci_xchacha_stream)(s, nbytes, blkno, nonce, key, nr); 170 1.1 riastrad } 171 1.1 riastrad 172 1.1 riastrad void 173 1.1 riastrad xchacha_stream_xor(uint8_t *c, const uint8_t *p, size_t nbytes, uint32_t blkno, 174 1.1 riastrad const uint8_t nonce[static XCHACHA_STREAM_NONCEBYTES], 175 1.1 riastrad const uint8_t key[static XCHACHA_STREAM_KEYBYTES], 176 1.1 riastrad unsigned nr) 177 1.1 riastrad { 178 1.1 riastrad 179 1.1 riastrad (*chacha_impl->ci_xchacha_stream_xor)(c, p, nbytes, blkno, nonce, key, 180 1.1 riastrad nr); 181 1.1 riastrad } 182