Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 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 | { |
Damjan Marion | 7d08e39 | 2020-01-28 09:55:25 +0100 | [diff] [blame] | 23 | AES_KEY_128 = 0, |
| 24 | AES_KEY_192 = 1, |
| 25 | AES_KEY_256 = 2, |
| 26 | } aes_key_size_t; |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 27 | |
Damjan Marion | 7d08e39 | 2020-01-28 09:55:25 +0100 | [diff] [blame] | 28 | #define AES_KEY_ROUNDS(x) (10 + x * 2) |
| 29 | #define AES_KEY_BYTES(x) (16 + x * 8) |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 30 | |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 31 | static_always_inline u8x16 |
| 32 | aes_block_load (u8 * p) |
| 33 | { |
| 34 | return (u8x16) _mm_loadu_si128 ((__m128i *) p); |
| 35 | } |
| 36 | |
| 37 | static_always_inline u8x16 |
| 38 | aes_enc_round (u8x16 a, u8x16 k) |
| 39 | { |
| 40 | return (u8x16) _mm_aesenc_si128 ((__m128i) a, (__m128i) k); |
| 41 | } |
| 42 | |
| 43 | static_always_inline u8x16 |
| 44 | aes_enc_last_round (u8x16 a, u8x16 k) |
| 45 | { |
| 46 | return (u8x16) _mm_aesenclast_si128 ((__m128i) a, (__m128i) k); |
| 47 | } |
| 48 | |
| 49 | static_always_inline u8x16 |
| 50 | aes_dec_round (u8x16 a, u8x16 k) |
| 51 | { |
| 52 | return (u8x16) _mm_aesdec_si128 ((__m128i) a, (__m128i) k); |
| 53 | } |
| 54 | |
| 55 | static_always_inline u8x16 |
| 56 | aes_dec_last_round (u8x16 a, u8x16 k) |
| 57 | { |
| 58 | return (u8x16) _mm_aesdeclast_si128 ((__m128i) a, (__m128i) k); |
| 59 | } |
| 60 | |
| 61 | static_always_inline void |
| 62 | aes_block_store (u8 * p, u8x16 r) |
| 63 | { |
| 64 | _mm_storeu_si128 ((__m128i *) p, (__m128i) r); |
| 65 | } |
| 66 | |
| 67 | static_always_inline u8x16 |
| 68 | aes_inv_mix_column (u8x16 a) |
| 69 | { |
| 70 | return (u8x16) _mm_aesimc_si128 ((__m128i) a); |
| 71 | } |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 72 | |
| 73 | /* AES-NI based AES key expansion based on code samples from |
| 74 | Intel(r) Advanced Encryption Standard (AES) New Instructions White Paper |
| 75 | (323641-001) */ |
| 76 | |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 77 | static_always_inline void |
| 78 | aes128_key_assist (__m128i * k, __m128i r) |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 79 | { |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 80 | __m128i t = k[-1]; |
| 81 | t ^= _mm_slli_si128 (t, 4); |
| 82 | t ^= _mm_slli_si128 (t, 4); |
| 83 | t ^= _mm_slli_si128 (t, 4); |
| 84 | k[0] = t ^ _mm_shuffle_epi32 (r, 0xff); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 85 | } |
| 86 | |
| 87 | static_always_inline void |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 88 | aes128_key_expand (u8x16 * key_schedule, u8 * key) |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 89 | { |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 90 | __m128i *k = (__m128i *) key_schedule; |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 91 | k[0] = _mm_loadu_si128 ((const __m128i *) key); |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 92 | aes128_key_assist (k + 1, _mm_aeskeygenassist_si128 (k[0], 0x01)); |
| 93 | aes128_key_assist (k + 2, _mm_aeskeygenassist_si128 (k[1], 0x02)); |
| 94 | aes128_key_assist (k + 3, _mm_aeskeygenassist_si128 (k[2], 0x04)); |
| 95 | aes128_key_assist (k + 4, _mm_aeskeygenassist_si128 (k[3], 0x08)); |
| 96 | aes128_key_assist (k + 5, _mm_aeskeygenassist_si128 (k[4], 0x10)); |
| 97 | aes128_key_assist (k + 6, _mm_aeskeygenassist_si128 (k[5], 0x20)); |
| 98 | aes128_key_assist (k + 7, _mm_aeskeygenassist_si128 (k[6], 0x40)); |
| 99 | aes128_key_assist (k + 8, _mm_aeskeygenassist_si128 (k[7], 0x80)); |
| 100 | aes128_key_assist (k + 9, _mm_aeskeygenassist_si128 (k[8], 0x1b)); |
| 101 | aes128_key_assist (k + 10, _mm_aeskeygenassist_si128 (k[9], 0x36)); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 102 | } |
| 103 | |
| 104 | static_always_inline void |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 105 | aes192_key_assist (__m128i * r1, __m128i * r2, __m128i key_assist) |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 106 | { |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 107 | __m128i t; |
| 108 | *r1 ^= t = _mm_slli_si128 (*r1, 0x4); |
| 109 | *r1 ^= t = _mm_slli_si128 (t, 0x4); |
| 110 | *r1 ^= _mm_slli_si128 (t, 0x4); |
| 111 | *r1 ^= _mm_shuffle_epi32 (key_assist, 0x55); |
| 112 | *r2 ^= _mm_slli_si128 (*r2, 0x4); |
| 113 | *r2 ^= _mm_shuffle_epi32 (*r1, 0xff); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 114 | } |
| 115 | |
| 116 | static_always_inline void |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 117 | aes192_key_expand (u8x16 * key_schedule, u8 * key) |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 118 | { |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 119 | __m128i r1, r2, *k = (__m128i *) key_schedule; |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 120 | |
| 121 | k[0] = r1 = _mm_loadu_si128 ((__m128i *) key); |
BenoƮt Ganne | 9fb6d40 | 2019-04-15 15:28:21 +0200 | [diff] [blame] | 122 | /* load the 24-bytes key as 2 * 16-bytes (and ignore last 8-bytes) */ |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 123 | k[1] = r2 = CLIB_MEM_OVERFLOW_LOAD (_mm_loadu_si128, (__m128i *) key + 1); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 124 | |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 125 | aes192_key_assist (&r1, &r2, _mm_aeskeygenassist_si128 (r2, 0x1)); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 126 | k[1] = (__m128i) _mm_shuffle_pd ((__m128d) k[1], (__m128d) r1, 0); |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 127 | k[2] = (__m128i) _mm_shuffle_pd ((__m128d) r1, (__m128d) r2, 1); |
| 128 | |
| 129 | aes192_key_assist (&r1, &r2, _mm_aeskeygenassist_si128 (r2, 0x2)); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 130 | k[3] = r1; |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 131 | k[4] = r2; |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 132 | |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 133 | aes192_key_assist (&r1, &r2, _mm_aeskeygenassist_si128 (r2, 0x4)); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 134 | k[4] = (__m128i) _mm_shuffle_pd ((__m128d) k[4], (__m128d) r1, 0); |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 135 | k[5] = (__m128i) _mm_shuffle_pd ((__m128d) r1, (__m128d) r2, 1); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 136 | |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 137 | aes192_key_assist (&r1, &r2, _mm_aeskeygenassist_si128 (r2, 0x8)); |
| 138 | k[6] = r1; |
| 139 | k[7] = r2; |
| 140 | |
| 141 | aes192_key_assist (&r1, &r2, _mm_aeskeygenassist_si128 (r2, 0x10)); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 142 | k[7] = (__m128i) _mm_shuffle_pd ((__m128d) k[7], (__m128d) r1, 0); |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 143 | k[8] = (__m128i) _mm_shuffle_pd ((__m128d) r1, (__m128d) r2, 1); |
| 144 | |
| 145 | aes192_key_assist (&r1, &r2, _mm_aeskeygenassist_si128 (r2, 0x20)); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 146 | k[9] = r1; |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 147 | k[10] = r2; |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 148 | |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 149 | aes192_key_assist (&r1, &r2, _mm_aeskeygenassist_si128 (r2, 0x40)); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 150 | k[10] = (__m128i) _mm_shuffle_pd ((__m128d) k[10], (__m128d) r1, 0); |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 151 | k[11] = (__m128i) _mm_shuffle_pd ((__m128d) r1, (__m128d) r2, 1); |
| 152 | |
| 153 | aes192_key_assist (&r1, &r2, _mm_aeskeygenassist_si128 (r2, 0x80)); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 154 | k[12] = r1; |
| 155 | } |
| 156 | |
| 157 | static_always_inline void |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 158 | aes256_key_assist (__m128i * k, int i, __m128i key_assist) |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 159 | { |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 160 | __m128i r, t; |
| 161 | k += i; |
| 162 | r = k[-2]; |
| 163 | r ^= t = _mm_slli_si128 (r, 0x4); |
| 164 | r ^= t = _mm_slli_si128 (t, 0x4); |
| 165 | r ^= _mm_slli_si128 (t, 0x4); |
| 166 | r ^= _mm_shuffle_epi32 (key_assist, 0xff); |
| 167 | k[0] = r; |
| 168 | |
| 169 | if (i >= 14) |
| 170 | return; |
| 171 | |
| 172 | r = k[-1]; |
| 173 | r ^= t = _mm_slli_si128 (r, 0x4); |
| 174 | r ^= t = _mm_slli_si128 (t, 0x4); |
| 175 | r ^= _mm_slli_si128 (t, 0x4); |
| 176 | r ^= _mm_shuffle_epi32 (_mm_aeskeygenassist_si128 (k[0], 0x0), 0xaa); |
| 177 | k[1] = r; |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 178 | } |
| 179 | |
| 180 | static_always_inline void |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 181 | aes256_key_expand (u8x16 * key_schedule, u8 * key) |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 182 | { |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 183 | __m128i *k = (__m128i *) key_schedule; |
| 184 | k[0] = _mm_loadu_si128 ((__m128i *) key); |
| 185 | k[1] = _mm_loadu_si128 ((__m128i *) (key + 16)); |
| 186 | aes256_key_assist (k, 2, _mm_aeskeygenassist_si128 (k[1], 0x01)); |
| 187 | aes256_key_assist (k, 4, _mm_aeskeygenassist_si128 (k[3], 0x02)); |
| 188 | aes256_key_assist (k, 6, _mm_aeskeygenassist_si128 (k[5], 0x04)); |
| 189 | aes256_key_assist (k, 8, _mm_aeskeygenassist_si128 (k[7], 0x08)); |
| 190 | aes256_key_assist (k, 10, _mm_aeskeygenassist_si128 (k[9], 0x10)); |
| 191 | aes256_key_assist (k, 12, _mm_aeskeygenassist_si128 (k[11], 0x20)); |
| 192 | aes256_key_assist (k, 14, _mm_aeskeygenassist_si128 (k[13], 0x40)); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 193 | } |
| 194 | |
| 195 | static_always_inline void |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 196 | aes_key_expand (u8x16 * key_schedule, u8 * key, aes_key_size_t ks) |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 197 | { |
| 198 | switch (ks) |
| 199 | { |
Damjan Marion | 7d08e39 | 2020-01-28 09:55:25 +0100 | [diff] [blame] | 200 | case AES_KEY_128: |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 201 | aes128_key_expand (key_schedule, key); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 202 | break; |
Damjan Marion | 7d08e39 | 2020-01-28 09:55:25 +0100 | [diff] [blame] | 203 | case AES_KEY_192: |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 204 | aes192_key_expand (key_schedule, key); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 205 | break; |
Damjan Marion | 7d08e39 | 2020-01-28 09:55:25 +0100 | [diff] [blame] | 206 | case AES_KEY_256: |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 207 | aes256_key_expand (key_schedule, key); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 208 | break; |
| 209 | } |
| 210 | } |
| 211 | |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 212 | static_always_inline void |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 213 | aes_key_enc_to_dec (u8x16 * ke, u8x16 * kd, aes_key_size_t ks) |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 214 | { |
Damjan Marion | 7d08e39 | 2020-01-28 09:55:25 +0100 | [diff] [blame] | 215 | int rounds = AES_KEY_ROUNDS (ks); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 216 | |
Damjan Marion | 78b58f6 | 2020-01-29 10:31:26 +0100 | [diff] [blame] | 217 | kd[rounds] = ke[0]; |
| 218 | kd[0] = ke[rounds]; |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 219 | |
| 220 | for (int i = 1; i < (rounds / 2); i++) |
| 221 | { |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 222 | kd[rounds - i] = aes_inv_mix_column (ke[i]); |
| 223 | kd[i] = aes_inv_mix_column (ke[rounds - i]); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 224 | } |
| 225 | |
Damjan Marion | 93975e6 | 2020-01-30 15:46:23 +0100 | [diff] [blame] | 226 | kd[rounds / 2] = aes_inv_mix_column (ke[rounds / 2]); |
Damjan Marion | deb8af6 | 2019-04-02 19:06:50 +0200 | [diff] [blame] | 227 | } |
| 228 | |
| 229 | #endif /* __aesni_h__ */ |
| 230 | |
| 231 | /* |
| 232 | * fd.io coding-style-patch-verification: ON |
| 233 | * |
| 234 | * Local Variables: |
| 235 | * eval: (c-set-style "gnu") |
| 236 | * End: |
| 237 | */ |