xref: /freebsd/sys/crypto/aesni/aesencdec.h (revision 907b59d76938e654f0d040a888e8dfca3de1e222)
1 /*-
2  * Copyright 2013 John-Mark Gurney <jmg@FreeBSD.org>
3  * Copyright 2015 Netflix, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  *
29  */
30 
31 #ifndef _AESENCDEC_H_
32 #define _AESENCDEC_H_
33 
34 #include <crypto/aesni/aesni_os.h>
35 
36 #include <wmmintrin.h>
37 
38 static inline void
39 aesni_enc8(int rounds, const __m128i *keysched, __m128i a,
40     __m128i b, __m128i c, __m128i d, __m128i e, __m128i f, __m128i g,
41     __m128i h, __m128i out[8])
42 {
43 	int i;
44 
45 	a ^= keysched[0];
46 	b ^= keysched[0];
47 	c ^= keysched[0];
48 	d ^= keysched[0];
49 	e ^= keysched[0];
50 	f ^= keysched[0];
51 	g ^= keysched[0];
52 	h ^= keysched[0];
53 
54 	for (i = 0; i < rounds; i++) {
55 		a = _mm_aesenc_si128(a, keysched[i + 1]);
56 		b = _mm_aesenc_si128(b, keysched[i + 1]);
57 		c = _mm_aesenc_si128(c, keysched[i + 1]);
58 		d = _mm_aesenc_si128(d, keysched[i + 1]);
59 		e = _mm_aesenc_si128(e, keysched[i + 1]);
60 		f = _mm_aesenc_si128(f, keysched[i + 1]);
61 		g = _mm_aesenc_si128(g, keysched[i + 1]);
62 		h = _mm_aesenc_si128(h, keysched[i + 1]);
63 	}
64 
65 	out[0] = _mm_aesenclast_si128(a, keysched[i + 1]);
66 	out[1] = _mm_aesenclast_si128(b, keysched[i + 1]);
67 	out[2] = _mm_aesenclast_si128(c, keysched[i + 1]);
68 	out[3] = _mm_aesenclast_si128(d, keysched[i + 1]);
69 	out[4] = _mm_aesenclast_si128(e, keysched[i + 1]);
70 	out[5] = _mm_aesenclast_si128(f, keysched[i + 1]);
71 	out[6] = _mm_aesenclast_si128(g, keysched[i + 1]);
72 	out[7] = _mm_aesenclast_si128(h, keysched[i + 1]);
73 }
74 
75 static inline void
76 aesni_dec8(int rounds, const __m128i *keysched, __m128i a,
77     __m128i b, __m128i c, __m128i d, __m128i e, __m128i f, __m128i g,
78     __m128i h, __m128i out[8])
79 {
80 	int i;
81 
82 	a ^= keysched[0];
83 	b ^= keysched[0];
84 	c ^= keysched[0];
85 	d ^= keysched[0];
86 	e ^= keysched[0];
87 	f ^= keysched[0];
88 	g ^= keysched[0];
89 	h ^= keysched[0];
90 
91 	for (i = 0; i < rounds; i++) {
92 		a = _mm_aesdec_si128(a, keysched[i + 1]);
93 		b = _mm_aesdec_si128(b, keysched[i + 1]);
94 		c = _mm_aesdec_si128(c, keysched[i + 1]);
95 		d = _mm_aesdec_si128(d, keysched[i + 1]);
96 		e = _mm_aesdec_si128(e, keysched[i + 1]);
97 		f = _mm_aesdec_si128(f, keysched[i + 1]);
98 		g = _mm_aesdec_si128(g, keysched[i + 1]);
99 		h = _mm_aesdec_si128(h, keysched[i + 1]);
100 	}
101 
102 	out[0] = _mm_aesdeclast_si128(a, keysched[i + 1]);
103 	out[1] = _mm_aesdeclast_si128(b, keysched[i + 1]);
104 	out[2] = _mm_aesdeclast_si128(c, keysched[i + 1]);
105 	out[3] = _mm_aesdeclast_si128(d, keysched[i + 1]);
106 	out[4] = _mm_aesdeclast_si128(e, keysched[i + 1]);
107 	out[5] = _mm_aesdeclast_si128(f, keysched[i + 1]);
108 	out[6] = _mm_aesdeclast_si128(g, keysched[i + 1]);
109 	out[7] = _mm_aesdeclast_si128(h, keysched[i + 1]);
110 }
111 
112 /* rounds is passed in as rounds - 1 */
113 static inline __m128i
114 aesni_enc(int rounds, const __m128i *keysched, const __m128i from)
115 {
116 	__m128i tmp;
117 	int i;
118 
119 	tmp = from ^ keysched[0];
120 	for (i = 1; i < rounds; i += 2) {
121 		tmp = _mm_aesenc_si128(tmp, keysched[i]);
122 		tmp = _mm_aesenc_si128(tmp, keysched[i + 1]);
123 	}
124 
125 	tmp = _mm_aesenc_si128(tmp, keysched[rounds]);
126 	return _mm_aesenclast_si128(tmp, keysched[rounds + 1]);
127 }
128 
129 static inline __m128i
130 aesni_dec(int rounds, const __m128i *keysched, const __m128i from)
131 {
132 	__m128i tmp;
133 	int i;
134 
135 	tmp = from ^ keysched[0];
136 
137 	for (i = 1; i < rounds; i += 2) {
138 		tmp = _mm_aesdec_si128(tmp, keysched[i]);
139 		tmp = _mm_aesdec_si128(tmp, keysched[i + 1]);
140 	}
141 
142 	tmp = _mm_aesdec_si128(tmp, keysched[rounds]);
143 	return _mm_aesdeclast_si128(tmp, keysched[rounds + 1]);
144 }
145 
146 #endif /* _AESENCDEC_H_ */
147