2 * init.c : ipsecmb common code
4 * Copyright (c) 2015 Cisco and/or its affiliates.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 #include <sys/types.h>
20 #include <vnet/plugin/plugin.h>
21 #include <vpp/app/version.h>
22 #include <ipsecmb/ipsecmb.h>
23 ipsecmb_main_t ipsecmb_main;
26 sa_expand_keys (u32 sa_index)
28 ipsecmb_main_t *imbm = &ipsecmb_main;
29 ipsec_sa_t *sa = pool_elt_at_index (ipsec_main.sad, sa_index);
30 ipsecmb_sa_t *samb = pool_elt_at_index (imbm->sad, sa_index);
31 if (sa->crypto_key_len > 0)
33 const keyexp_t keyexp_fn = imbm->crypto_algs[sa->crypto_alg].keyexp_fn;
34 keyexp_fn (sa->crypto_key, samb->aes_enc_key_expanded,
35 samb->aes_dec_key_expanded);
37 if (sa->integ_key_len > 0)
39 const u8 block_size = imbm->integ_algs[sa->integ_alg].block_size;
40 const hash_one_block_t hash_one_block_fn =
41 imbm->integ_algs[sa->integ_alg].hash_one_block_fn;
44 if (sa->integ_key_len > block_size)
46 return VNET_API_ERROR_SYSCALL_ERROR_1; // FIXME use correct value
48 memset (buf, 0x36, sizeof (buf));
49 for (i = 0; i < sa->integ_key_len; i++)
51 buf[i] ^= sa->integ_key[i];
53 hash_one_block_fn (buf, samb->ipad_hash);
55 memset (buf, 0x5c, sizeof (buf));
56 for (i = 0; i < sa->integ_key_len; i++)
58 buf[i] ^= sa->integ_key[i];
60 hash_one_block_fn (buf, samb->opad_hash);
66 ipsecmb_add_del_sa_session (u32 sa_index, u8 is_add)
68 ipsecmb_main_t *imbm = &ipsecmb_main;
71 ipsecmb_sa_t *samb = NULL;
72 pool_get (imbm->sad, samb);
73 ASSERT (samb == pool_elt_at_index (imbm->sad, sa_index));
74 sa_expand_keys (sa_index);
78 pool_put_index (imbm->sad, sa_index);
84 ipsecmb_check_esp_support (ipsec_sa_t * sa)
86 switch (sa->crypto_alg)
88 case IPSEC_CRYPTO_ALG_NONE:
90 case IPSEC_CRYPTO_ALG_DES_CBC:
91 case IPSEC_CRYPTO_ALG_3DES_CBC:
92 return clib_error_return (0, "unsupported (3)des crypto-alg");
93 case IPSEC_CRYPTO_ALG_AES_CBC_128:
94 case IPSEC_CRYPTO_ALG_AES_CBC_192:
95 case IPSEC_CRYPTO_ALG_AES_CBC_256:
97 case IPSEC_CRYPTO_ALG_AES_CTR_128:
98 case IPSEC_CRYPTO_ALG_AES_CTR_192:
99 case IPSEC_CRYPTO_ALG_AES_CTR_256:
100 return clib_error_return (0, "unsupported aes-ctr crypto-alg");
101 case IPSEC_CRYPTO_ALG_AES_GCM_128:
102 case IPSEC_CRYPTO_ALG_AES_GCM_192:
103 case IPSEC_CRYPTO_ALG_AES_GCM_256:
104 return clib_error_return (0, "unsupported aes-gcm crypto-alg");
105 case IPSEC_CRYPTO_N_ALG:
106 return clib_error_return (0, "invalid crypto-alg");
109 switch (sa->integ_alg)
111 case IPSEC_INTEG_ALG_NONE:
112 return clib_error_return (0, "unsupported none integ-alg");
113 case IPSEC_INTEG_ALG_MD5_96:
114 return clib_error_return (0, "unsupported md5 integ-alg");
115 case IPSEC_INTEG_ALG_SHA1_96:
116 case IPSEC_INTEG_ALG_SHA_256_96:
117 case IPSEC_INTEG_ALG_SHA_256_128:
118 case IPSEC_INTEG_ALG_SHA_384_192:
119 case IPSEC_INTEG_ALG_SHA_512_256:
121 case IPSEC_INTEG_N_ALG:
122 return clib_error_return (0, "invalid integ-alg");
128 ipsecmb_check_ah_support (ipsec_sa_t * sa)
130 switch (sa->integ_alg)
132 case IPSEC_INTEG_ALG_NONE:
133 return clib_error_return (0, "unsupported none integ-alg");
134 case IPSEC_INTEG_ALG_MD5_96:
135 return clib_error_return (0, "unsupported md5 integ-alg");
136 case IPSEC_INTEG_ALG_SHA1_96:
137 case IPSEC_INTEG_ALG_SHA_256_96:
138 case IPSEC_INTEG_ALG_SHA_256_128:
139 case IPSEC_INTEG_ALG_SHA_384_192:
140 case IPSEC_INTEG_ALG_SHA_512_256:
142 case IPSEC_INTEG_N_ALG:
143 return clib_error_return (0, "invalid integ-alg");
148 static clib_error_t *
149 ipsecmb_init (vlib_main_t * vm)
151 ipsecmb_main_t *imbm = &ipsecmb_main;
152 imbm->dev_urandom_fd = open ("/dev/urandom", O_RDONLY);
153 if (!imbm->dev_urandom_fd)
155 return clib_error_return_unix_fatal (0,
156 "Can't open /dev/urandom for read");
159 vlib_thread_main_t *tm = vlib_get_thread_main ();
161 imbm->crypto_algs = NULL;
162 imbm->integ_algs = NULL;
164 vec_validate (imbm->crypto_algs, IPSEC_CRYPTO_N_ALG - 1);
165 vec_validate (imbm->integ_algs, IPSEC_INTEG_N_ALG - 1);
166 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_128].block_size = 16;
167 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_192].block_size = 16;
168 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_256].block_size = 16;
169 imbm->crypto_algs[IPSEC_CRYPTO_ALG_DES_CBC].block_size = 8;
170 imbm->crypto_algs[IPSEC_CRYPTO_ALG_3DES_CBC].block_size = 8;
171 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_128].iv_size = 16;
172 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_192].iv_size = 16;
173 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_256].iv_size = 16;
174 imbm->crypto_algs[IPSEC_CRYPTO_ALG_DES_CBC].iv_size = 8;
175 imbm->crypto_algs[IPSEC_CRYPTO_ALG_3DES_CBC].iv_size = 8;
176 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_128].cipher_mode = CBC;
177 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_192].cipher_mode = CBC;
178 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_256].cipher_mode = CBC;
180 ipsecmb_integ_alg_t *i;
181 i = &imbm->integ_algs[IPSEC_INTEG_ALG_SHA1_96];
183 i->block_size = SHA1_BLOCK_SIZE;
185 i = &imbm->integ_algs[IPSEC_INTEG_ALG_SHA_256_96];
186 i->hash_alg = SHA_256;
187 i->block_size = SHA_256_BLOCK_SIZE;
189 i = &imbm->integ_algs[IPSEC_INTEG_ALG_SHA_256_128];
190 i->hash_alg = SHA_256;
191 i->block_size = SHA_256_BLOCK_SIZE;
193 i = &imbm->integ_algs[IPSEC_INTEG_ALG_SHA_384_192];
194 i->hash_alg = SHA_384;
195 i->block_size = SHA_384_BLOCK_SIZE;
197 i = &imbm->integ_algs[IPSEC_INTEG_ALG_SHA_512_256];
198 i->hash_alg = SHA_512;
199 i->block_size = SHA_512_BLOCK_SIZE;
201 vec_validate (imbm->mb_mgr, tm->n_vlib_mains - 1);
203 #define __set_funcs(arch) \
206 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_128].keyexp_fn = \
207 aes_keyexp_128_##arch; \
208 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_192].keyexp_fn = \
209 aes_keyexp_192_##arch; \
210 imbm->crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_256].keyexp_fn = \
211 aes_keyexp_256_##arch; \
212 imbm->integ_algs[IPSEC_INTEG_ALG_SHA1_96].hash_one_block_fn = \
213 sha1_one_block_##arch; \
214 imbm->integ_algs[IPSEC_INTEG_ALG_SHA_256_96].hash_one_block_fn = \
215 sha256_one_block_##arch; \
216 imbm->integ_algs[IPSEC_INTEG_ALG_SHA_256_128].hash_one_block_fn = \
217 sha256_one_block_##arch; \
218 imbm->integ_algs[IPSEC_INTEG_ALG_SHA_384_192].hash_one_block_fn = \
219 sha384_one_block_##arch; \
220 imbm->integ_algs[IPSEC_INTEG_ALG_SHA_512_256].hash_one_block_fn = \
221 sha512_one_block_##arch; \
225 if (clib_cpu_supports_avx512f ())
227 __set_funcs (avx512);
228 vec_foreach (mgr, imbm->mb_mgr)
230 *mgr = alloc_mb_mgr (0);
231 init_mb_mgr_avx512 (*mgr);
234 else if (clib_cpu_supports_avx2 ())
237 vec_foreach (mgr, imbm->mb_mgr)
239 *mgr = alloc_mb_mgr (0);
240 init_mb_mgr_avx2 (*mgr);
246 vec_foreach (mgr, imbm->mb_mgr)
248 *mgr = alloc_mb_mgr (0);
249 init_mb_mgr_sse (*mgr);
255 i = &imbm->integ_algs[IPSEC_INTEG_ALG_SHA1_96];
256 i->hash_output_length = 12;
258 i = &imbm->integ_algs[IPSEC_INTEG_ALG_SHA_256_96];
259 i->hash_output_length = 12;
261 i = &imbm->integ_algs[IPSEC_INTEG_ALG_SHA_256_128];
262 i->hash_output_length = 16;
264 i = &imbm->integ_algs[IPSEC_INTEG_ALG_SHA_384_192];
265 i->hash_output_length = 24;
267 i = &imbm->integ_algs[IPSEC_INTEG_ALG_SHA_512_256];
268 i->hash_output_length = 32;
270 vec_validate (imbm->per_thread_data, tm->n_vlib_mains - 1);
275 VLIB_INIT_FUNCTION (ipsecmb_init);
278 ipsecmb_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
280 ipsec_main_t *im = &ipsec_main;
281 ipsec_register_ah_backend (vm, im, "ipsecmb backend",
282 "ah4-encrypt-ipsecmb",
283 "ah4-decrypt-ipsecmb",
284 "ah6-encrypt-ipsecmb",
285 "ah6-decrypt-ipsecmb",
286 ipsecmb_check_ah_support,
287 ipsecmb_add_del_sa_session);
289 ipsec_register_esp_backend (vm, im, "ipsecmb backend",
290 "esp4-encrypt-ipsecmb",
291 "esp4-decrypt-ipsecmb",
292 "esp6-encrypt-ipsecmb",
293 "esp6-decrypt-ipsecmb",
294 ipsecmb_check_esp_support,
295 ipsecmb_add_del_sa_session);
301 VLIB_REGISTER_NODE (ipsecmb_process_node, static) = {
302 .function = ipsecmb_process,
303 .type = VLIB_NODE_TYPE_PROCESS,
304 .name = "ipsecmb-process",
305 .process_log2_n_stack_bytes = 17,
309 VLIB_PLUGIN_REGISTER () = {
310 .version = VPP_BUILD_VER,
311 .description = "IPsecMB plugin",
312 .default_disabled = 1,
317 * fd.io coding-style-patch-verification: ON
320 * eval: (c-set-style "gnu")