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