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