aes_sse2_impl.c revision 1.2 1 /* $NetBSD: aes_sse2_impl.c,v 1.2 2020/06/29 23:50:05 riastradh 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/cdefs.h>
30 __KERNEL_RCSID(1, "$NetBSD: aes_sse2_impl.c,v 1.2 2020/06/29 23:50:05 riastradh Exp $");
31
32 #include <sys/types.h>
33 #include <sys/endian.h>
34
35 #include <crypto/aes/aes.h>
36 #include <crypto/aes/arch/x86/aes_sse2.h>
37
38 #include <x86/cpu.h>
39 #include <x86/cpuvar.h>
40 #include <x86/fpu.h>
41 #include <x86/specialreg.h>
42
43 static void
44 aes_sse2_setenckey_impl(struct aesenc *enc, const uint8_t *key,
45 uint32_t nrounds)
46 {
47
48 fpu_kern_enter();
49 aes_sse2_setkey(enc->aese_aes.aes_rk64, key, nrounds);
50 fpu_kern_leave();
51 }
52
53 static void
54 aes_sse2_setdeckey_impl(struct aesdec *dec, const uint8_t *key,
55 uint32_t nrounds)
56 {
57
58 fpu_kern_enter();
59 /*
60 * BearSSL computes InvMixColumns on the fly -- no need for
61 * distinct decryption round keys.
62 */
63 aes_sse2_setkey(dec->aesd_aes.aes_rk64, key, nrounds);
64 fpu_kern_leave();
65 }
66
67 static void
68 aes_sse2_enc_impl(const struct aesenc *enc, const uint8_t in[static 16],
69 uint8_t out[static 16], uint32_t nrounds)
70 {
71
72 fpu_kern_enter();
73 aes_sse2_enc(enc, in, out, nrounds);
74 fpu_kern_leave();
75 }
76
77 static void
78 aes_sse2_dec_impl(const struct aesdec *dec, const uint8_t in[static 16],
79 uint8_t out[static 16], uint32_t nrounds)
80 {
81
82 fpu_kern_enter();
83 aes_sse2_dec(dec, in, out, nrounds);
84 fpu_kern_leave();
85 }
86
87 static void
88 aes_sse2_cbc_enc_impl(const struct aesenc *enc, const uint8_t in[static 16],
89 uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
90 uint32_t nrounds)
91 {
92
93 if (nbytes == 0)
94 return;
95 fpu_kern_enter();
96 aes_sse2_cbc_enc(enc, in, out, nbytes, iv, nrounds);
97 fpu_kern_leave();
98 }
99
100 static void
101 aes_sse2_cbc_dec_impl(const struct aesdec *dec, const uint8_t in[static 16],
102 uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
103 uint32_t nrounds)
104 {
105
106 if (nbytes == 0)
107 return;
108 fpu_kern_enter();
109 aes_sse2_cbc_dec(dec, in, out, nbytes, iv, nrounds);
110 fpu_kern_leave();
111 }
112
113 static void
114 aes_sse2_xts_enc_impl(const struct aesenc *enc, const uint8_t in[static 16],
115 uint8_t out[static 16], size_t nbytes, uint8_t tweak[static 16],
116 uint32_t nrounds)
117 {
118
119 if (nbytes == 0)
120 return;
121 fpu_kern_enter();
122 aes_sse2_xts_enc(enc, in, out, nbytes, tweak, nrounds);
123 fpu_kern_leave();
124 }
125
126 static void
127 aes_sse2_xts_dec_impl(const struct aesdec *dec, const uint8_t in[static 16],
128 uint8_t out[static 16], size_t nbytes, uint8_t tweak[static 16],
129 uint32_t nrounds)
130 {
131
132 if (nbytes == 0)
133 return;
134 fpu_kern_enter();
135 aes_sse2_xts_dec(dec, in, out, nbytes, tweak, nrounds);
136 fpu_kern_leave();
137 }
138
139 static int
140 aes_sse2_probe(void)
141 {
142 int result = 0;
143
144 /* Verify that the CPU supports SSE and SSE2. */
145 if (!i386_has_sse)
146 return -1;
147 if (!i386_has_sse2)
148 return -1;
149
150 fpu_kern_enter();
151 result = aes_sse2_selftest();
152 fpu_kern_leave();
153
154 return result;
155 }
156
157 struct aes_impl aes_sse2_impl = {
158 .ai_name = "Intel SSE2 bitsliced",
159 .ai_probe = aes_sse2_probe,
160 .ai_setenckey = aes_sse2_setenckey_impl,
161 .ai_setdeckey = aes_sse2_setdeckey_impl,
162 .ai_enc = aes_sse2_enc_impl,
163 .ai_dec = aes_sse2_dec_impl,
164 .ai_cbc_enc = aes_sse2_cbc_enc_impl,
165 .ai_cbc_dec = aes_sse2_cbc_dec_impl,
166 .ai_xts_enc = aes_sse2_xts_enc_impl,
167 .ai_xts_dec = aes_sse2_xts_dec_impl,
168 };
169