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