crypto: coverity issues
[vpp.git] / src / plugins / crypto_ia32 / aesni.h
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2019 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17
18 #ifndef __aesni_h__
19 #define __aesni_h__
20
21 typedef enum
22 {
23   AESNI_KEY_128 = 0,
24   AESNI_KEY_192 = 1,
25   AESNI_KEY_256 = 2,
26 } aesni_key_size_t;
27
28 #define AESNI_KEY_ROUNDS(x)             (10 + x *2)
29 #define AESNI_KEY_BYTES(x)              (16 + x * 8)
30
31
32 /* AES-NI based AES key expansion based on code samples from
33    Intel(r) Advanced Encryption Standard (AES) New Instructions White Paper
34    (323641-001) */
35
36 static_always_inline __m128i
37 aes128_key_assist (__m128i r1, __m128i r2)
38 {
39   r1 ^= _mm_slli_si128 (r1, 4);
40   r1 ^= _mm_slli_si128 (r1, 4);
41   r1 ^= _mm_slli_si128 (r1, 4);
42   return r1 ^ _mm_shuffle_epi32 (r2, 0xff);
43 }
44
45 static_always_inline void
46 aes128_key_expand (__m128i * k, u8 * key)
47 {
48   k[0] = _mm_loadu_si128 ((const __m128i *) key);
49   k[1] = aes128_key_assist (k[0], _mm_aeskeygenassist_si128 (k[0], 0x01));
50   k[2] = aes128_key_assist (k[1], _mm_aeskeygenassist_si128 (k[1], 0x02));
51   k[3] = aes128_key_assist (k[2], _mm_aeskeygenassist_si128 (k[2], 0x04));
52   k[4] = aes128_key_assist (k[3], _mm_aeskeygenassist_si128 (k[3], 0x08));
53   k[5] = aes128_key_assist (k[4], _mm_aeskeygenassist_si128 (k[4], 0x10));
54   k[6] = aes128_key_assist (k[5], _mm_aeskeygenassist_si128 (k[5], 0x20));
55   k[7] = aes128_key_assist (k[6], _mm_aeskeygenassist_si128 (k[6], 0x40));
56   k[8] = aes128_key_assist (k[7], _mm_aeskeygenassist_si128 (k[7], 0x80));
57   k[9] = aes128_key_assist (k[8], _mm_aeskeygenassist_si128 (k[8], 0x1b));
58   k[10] = aes128_key_assist (k[9], _mm_aeskeygenassist_si128 (k[9], 0x36));
59 }
60
61 static_always_inline void
62 aes192_key_assist (__m128i * r1, __m128i * r2, __m128i * r3)
63 {
64   __m128i r;
65   *r1 ^= r = _mm_slli_si128 (*r1, 0x4);
66   *r1 ^= r = _mm_slli_si128 (r, 0x4);
67   *r1 ^= _mm_slli_si128 (r, 0x4);
68   *r1 ^= _mm_shuffle_epi32 (*r2, 0x55);
69   *r3 ^= _mm_slli_si128 (*r3, 0x4);
70   *r3 ^= *r2 = _mm_shuffle_epi32 (*r1, 0xff);
71 }
72
73 static_always_inline void
74 aes192_key_expand (__m128i * k, u8 * key)
75 {
76   __m128i r1, r2, r3;
77
78   k[0] = r1 = _mm_loadu_si128 ((__m128i *) key);
79   r3 = _mm_loadu_si128 ((__m128i *) (key + 16));
80
81   k[1] = r3;
82   r2 = _mm_aeskeygenassist_si128 (r3, 0x1);
83   aes192_key_assist (&r1, &r2, &r3);
84   k[1] = (__m128i) _mm_shuffle_pd ((__m128d) k[1], (__m128d) r1, 0);
85   k[2] = (__m128i) _mm_shuffle_pd ((__m128d) r1, (__m128d) r3, 1);
86   r2 = _mm_aeskeygenassist_si128 (r3, 0x2);
87   aes192_key_assist (&r1, &r2, &r3);
88   k[3] = r1;
89
90   k[4] = r3;
91   r2 = _mm_aeskeygenassist_si128 (r3, 0x4);
92   aes192_key_assist (&r1, &r2, &r3);
93   k[4] = (__m128i) _mm_shuffle_pd ((__m128d) k[4], (__m128d) r1, 0);
94   k[5] = (__m128i) _mm_shuffle_pd ((__m128d) r1, (__m128d) r3, 1);
95   r2 = _mm_aeskeygenassist_si128 (r3, 0x8);
96   aes192_key_assist (&r1, &r2, &r3);
97   k[6] = r1;
98
99   k[7] = r3;
100   r2 = _mm_aeskeygenassist_si128 (r3, 0x10);
101   aes192_key_assist (&r1, &r2, &r3);
102   k[7] = (__m128i) _mm_shuffle_pd ((__m128d) k[7], (__m128d) r1, 0);
103   k[8] = (__m128i) _mm_shuffle_pd ((__m128d) r1, (__m128d) r3, 1);
104   r2 = _mm_aeskeygenassist_si128 (r3, 0x20);
105   aes192_key_assist (&r1, &r2, &r3);
106   k[9] = r1;
107
108   k[10] = r3;
109   r2 = _mm_aeskeygenassist_si128 (r3, 0x40);
110   aes192_key_assist (&r1, &r2, &r3);
111   k[10] = (__m128i) _mm_shuffle_pd ((__m128d) k[10], (__m128d) r1, 0);
112   k[11] = (__m128i) _mm_shuffle_pd ((__m128d) r1, (__m128d) r3, 1);
113   r2 = _mm_aeskeygenassist_si128 (r3, 0x80);
114   aes192_key_assist (&r1, &r2, &r3);
115   k[12] = r1;
116 }
117
118 static_always_inline void
119 aes256_key_assist1 (__m128i * r1, __m128i * r2)
120 {
121   __m128i r;
122   *r1 ^= r = _mm_slli_si128 (*r1, 0x4);
123   *r1 ^= r = _mm_slli_si128 (r, 0x4);
124   *r1 ^= _mm_slli_si128 (r, 0x4);
125   *r1 ^= *r2 = _mm_shuffle_epi32 (*r2, 0xff);
126 }
127
128 static_always_inline void
129 aes256_key_assist2 (__m128i r1, __m128i * r3)
130 {
131   __m128i r;
132   *r3 ^= r = _mm_slli_si128 (*r3, 0x4);
133   *r3 ^= r = _mm_slli_si128 (r, 0x4);
134   *r3 ^= _mm_slli_si128 (r, 0x4);
135   *r3 ^= _mm_shuffle_epi32 (_mm_aeskeygenassist_si128 (r1, 0x0), 0xaa);
136 }
137
138 static_always_inline void
139 aes256_key_expand (__m128i * k, u8 * key)
140 {
141   __m128i r1, r2, r3;
142   k[0] = r1 = _mm_loadu_si128 ((__m128i *) key);
143   k[1] = r3 = _mm_loadu_si128 ((__m128i *) (key + 16));
144   r2 = _mm_aeskeygenassist_si128 (k[1], 0x01);
145   aes256_key_assist1 (&r1, &r2);
146   k[2] = r1;
147   aes256_key_assist2 (r1, &r3);
148   k[3] = r3;
149   r2 = _mm_aeskeygenassist_si128 (r3, 0x02);
150   aes256_key_assist1 (&r1, &r2);
151   k[4] = r1;
152   aes256_key_assist2 (r1, &r3);
153   k[5] = r3;
154   r2 = _mm_aeskeygenassist_si128 (r3, 0x04);
155   aes256_key_assist1 (&r1, &r2);
156   k[6] = r1;
157   aes256_key_assist2 (r1, &r3);
158   k[7] = r3;
159   r2 = _mm_aeskeygenassist_si128 (r3, 0x08);
160   aes256_key_assist1 (&r1, &r2);
161   k[8] = r1;
162   aes256_key_assist2 (r1, &r3);
163   k[9] = r3;
164   r2 = _mm_aeskeygenassist_si128 (r3, 0x10);
165   aes256_key_assist1 (&r1, &r2);
166   k[10] = r1;
167   aes256_key_assist2 (r1, &r3);
168   k[11] = r3;
169   r2 = _mm_aeskeygenassist_si128 (r3, 0x20);
170   aes256_key_assist1 (&r1, &r2);
171   k[12] = r1;
172   aes256_key_assist2 (r1, &r3);
173   k[13] = r3;
174   r2 = _mm_aeskeygenassist_si128 (r3, 0x40);
175   aes256_key_assist1 (&r1, &r2);
176   k[14] = r1;
177 }
178
179 static_always_inline void
180 aes_key_expand (__m128i * k, u8 * key, aesni_key_size_t ks)
181 {
182   switch (ks)
183     {
184     case AESNI_KEY_128:
185       aes128_key_expand (k, key);
186       break;
187     case AESNI_KEY_192:
188       aes192_key_expand (k, key);
189       break;
190     case AESNI_KEY_256:
191       aes256_key_expand (k, key);
192       break;
193     }
194 }
195
196
197 static_always_inline void
198 aes_key_enc_to_dec (__m128i * k, aesni_key_size_t ks)
199 {
200   int rounds = AESNI_KEY_ROUNDS (ks);
201   __m128i r;
202
203   r = k[rounds];
204   k[rounds] = k[0];
205   k[0] = r;
206
207   for (int i = 1; i < (rounds / 2); i++)
208     {
209       r = k[rounds - i];
210       k[rounds - i] = _mm_aesimc_si128 (k[i]);
211       k[i] = _mm_aesimc_si128 (r);
212     }
213
214   k[rounds / 2] = _mm_aesimc_si128 (k[rounds / 2]);
215 }
216
217 #endif /* __aesni_h__ */
218
219 /*
220  * fd.io coding-style-patch-verification: ON
221  *
222  * Local Variables:
223  * eval: (c-set-style "gnu")
224  * End:
225  */