FD.io VPP  v19.04.2-12-g66b1689
Vector Packet Processing
aesni.h
Go to the documentation of this file.
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 {
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 
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 
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 
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 
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 
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 
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 
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 
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 
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  */
static_always_inline void aes192_key_expand(__m128i *k, u8 *key)
Definition: aesni.h:74
int i
#define AESNI_KEY_ROUNDS(x)
Definition: aesni.h:28
static_always_inline void aes_key_expand(__m128i *k, u8 *key, aesni_key_size_t ks)
Definition: aesni.h:180
unsigned char u8
Definition: types.h:56
static_always_inline __m128i aes128_key_assist(__m128i r1, __m128i r2)
Definition: aesni.h:37
#define static_always_inline
Definition: clib.h:99
aesni_key_size_t
Definition: aesni.h:21
static_always_inline void aes256_key_expand(__m128i *k, u8 *key)
Definition: aesni.h:139
static_always_inline void aes256_key_assist1(__m128i *r1, __m128i *r2)
Definition: aesni.h:119
static_always_inline void aes256_key_assist2(__m128i r1, __m128i *r3)
Definition: aesni.h:129
static_always_inline void aes128_key_expand(__m128i *k, u8 *key)
Definition: aesni.h:46
static_always_inline void aes_key_enc_to_dec(__m128i *k, aesni_key_size_t ks)
Definition: aesni.h:198
typedef key
Definition: ipsec.api:244
static_always_inline void aes192_key_assist(__m128i *r1, __m128i *r2, __m128i *r3)
Definition: aesni.h:62