Line data Source code
1 : /*
2 : * Copyright (c) 2021 Intel and/or its affiliates.
3 : * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 :
16 : #include <vnet/crypto/crypto.h>
17 : #include <vnet/tls/tls.h>
18 : #include <picotls/openssl.h>
19 : #include <picotls.h>
20 :
21 : #include <tlspicotls/pico_vpp_crypto.h>
22 : #include <tlspicotls/tls_picotls.h>
23 :
24 : typedef void (*ptls_vpp_do_transform_fn) (ptls_cipher_context_t *, void *,
25 : const void *, size_t);
26 :
27 : vnet_crypto_main_t *cm = &crypto_main;
28 : extern picotls_main_t picotls_main;
29 :
30 : struct cipher_context_t
31 : {
32 : ptls_cipher_context_t super;
33 : vnet_crypto_op_t op;
34 : vnet_crypto_op_id_t id;
35 : u32 key_index;
36 : };
37 :
38 : struct vpp_aead_context_t
39 : {
40 : ptls_aead_context_t super;
41 : EVP_CIPHER_CTX *evp_ctx;
42 : uint8_t static_iv[PTLS_MAX_IV_SIZE];
43 : vnet_crypto_op_t op;
44 : u32 key_index;
45 : vnet_crypto_op_id_t id;
46 : vnet_crypto_op_chunk_t chunks[2];
47 : vnet_crypto_alg_t alg;
48 : u32 chunk_index;
49 : uint8_t iv[PTLS_MAX_IV_SIZE];
50 : };
51 :
52 : static void
53 0 : ptls_vpp_crypto_cipher_do_init (ptls_cipher_context_t * _ctx, const void *iv)
54 : {
55 0 : struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx;
56 :
57 0 : vnet_crypto_op_init (&ctx->op, ctx->id);
58 0 : ctx->op.iv = (u8 *) iv;
59 0 : ctx->op.key_index = ctx->key_index;
60 0 : }
61 :
62 : static void
63 0 : ptls_vpp_crypto_cipher_dispose (ptls_cipher_context_t * _ctx)
64 : {
65 : /* Do nothing */
66 0 : }
67 :
68 : static void
69 0 : ptls_vpp_crypto_cipher_encrypt (ptls_cipher_context_t * _ctx, void *output,
70 : const void *input, size_t _len)
71 : {
72 0 : vlib_main_t *vm = vlib_get_main ();
73 0 : struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx;
74 :
75 0 : ctx->op.src = (u8 *) input;
76 0 : ctx->op.dst = output;
77 0 : ctx->op.len = _len;
78 :
79 0 : vnet_crypto_process_ops (vm, &ctx->op, 1);
80 0 : }
81 :
82 : static int
83 0 : ptls_vpp_crypto_cipher_setup_crypto (ptls_cipher_context_t * _ctx, int is_enc,
84 : const void *key,
85 : const EVP_CIPHER * cipher,
86 : ptls_vpp_do_transform_fn do_transform)
87 : {
88 0 : struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx;
89 :
90 0 : ctx->super.do_dispose = ptls_vpp_crypto_cipher_dispose;
91 0 : ctx->super.do_init = ptls_vpp_crypto_cipher_do_init;
92 0 : ctx->super.do_transform = do_transform;
93 :
94 0 : vlib_main_t *vm = vlib_get_main ();
95 : vnet_crypto_alg_t algo;
96 0 : if (!strcmp (ctx->super.algo->name, "AES128-CTR"))
97 : {
98 0 : algo = VNET_CRYPTO_ALG_AES_128_CTR;
99 0 : ctx->id = is_enc ? VNET_CRYPTO_OP_AES_128_CTR_ENC :
100 : VNET_CRYPTO_OP_AES_128_CTR_DEC;
101 : }
102 0 : else if (!strcmp (ctx->super.algo->name, "AES256-CTR"))
103 : {
104 0 : algo = VNET_CRYPTO_ALG_AES_256_CTR;
105 0 : ctx->id = is_enc ? VNET_CRYPTO_OP_AES_256_CTR_ENC :
106 : VNET_CRYPTO_OP_AES_256_CTR_DEC;
107 : }
108 : else
109 : {
110 : TLS_DBG (1, "%s, Invalid crypto cipher : ", __FUNCTION__,
111 : _ctx->algo->name);
112 0 : assert (0);
113 : }
114 :
115 0 : clib_rwlock_writer_lock (&picotls_main.crypto_keys_rw_lock);
116 0 : ctx->key_index = vnet_crypto_key_add (vm, algo,
117 0 : (u8 *) key, _ctx->algo->key_size);
118 0 : clib_rwlock_writer_unlock (&picotls_main.crypto_keys_rw_lock);
119 :
120 0 : return 0;
121 : }
122 :
123 : size_t
124 0 : ptls_vpp_crypto_aead_decrypt (ptls_aead_context_t *_ctx, void *_output,
125 : const void *input, size_t inlen, uint64_t seq,
126 : const void *aad, size_t aadlen)
127 : {
128 0 : vlib_main_t *vm = vlib_get_main ();
129 0 : struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
130 0 : int tag_size = ctx->super.algo->tag_size;
131 :
132 0 : vnet_crypto_op_init (&ctx->op, ctx->id);
133 0 : ctx->op.aad = (u8 *) aad;
134 0 : ctx->op.aad_len = aadlen;
135 0 : ctx->op.iv = ctx->iv;
136 0 : ptls_aead__build_iv (ctx->super.algo, ctx->op.iv, ctx->static_iv, seq);
137 0 : ctx->op.src = (u8 *) input;
138 0 : ctx->op.dst = _output;
139 0 : ctx->op.key_index = ctx->key_index;
140 0 : ctx->op.len = inlen - tag_size;
141 0 : ctx->op.tag_len = tag_size;
142 0 : ctx->op.tag = ctx->op.src + ctx->op.len;
143 :
144 0 : vnet_crypto_process_ops (vm, &(ctx->op), 1);
145 0 : assert (ctx->op.status == VNET_CRYPTO_OP_STATUS_COMPLETED);
146 :
147 0 : return ctx->op.len;
148 : }
149 :
150 : static void
151 0 : ptls_vpp_crypto_aead_encrypt_init (ptls_aead_context_t *_ctx, uint64_t seq,
152 : const void *aad, size_t aadlen)
153 : {
154 0 : struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
155 :
156 0 : vnet_crypto_op_init (&ctx->op, ctx->id);
157 0 : ctx->op.aad = (void *) aad;
158 0 : ctx->op.aad_len = aadlen;
159 0 : ctx->op.iv = ctx->iv;
160 0 : ptls_aead__build_iv (ctx->super.algo, ctx->op.iv, ctx->static_iv, seq);
161 0 : ctx->op.key_index = ctx->key_index;
162 0 : ctx->op.n_chunks = 2;
163 0 : ctx->op.chunk_index = 0;
164 :
165 0 : ctx->op.flags |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;
166 0 : }
167 :
168 : static size_t
169 0 : ptls_vpp_crypto_aead_encrypt_update (ptls_aead_context_t * _ctx, void *output,
170 : const void *input, size_t inlen)
171 : {
172 0 : struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
173 0 : ctx->chunks[ctx->chunk_index].dst = output;
174 0 : ctx->chunks[ctx->chunk_index].src = (void *) input;
175 0 : ctx->chunks[ctx->chunk_index].len = inlen;
176 :
177 0 : ctx->chunk_index = ctx->chunk_index == 0 ? 1 : 0;
178 :
179 0 : return inlen;
180 : }
181 :
182 : static size_t
183 0 : ptls_vpp_crypto_aead_encrypt_final (ptls_aead_context_t * _ctx, void *_output)
184 : {
185 0 : struct vlib_main_t *vm = vlib_get_main ();
186 0 : struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
187 :
188 0 : ctx->op.tag = _output;
189 0 : ctx->op.tag_len = ctx->super.algo->tag_size;
190 :
191 0 : vnet_crypto_process_chained_ops (vm, &(ctx->op), ctx->chunks, 1);
192 0 : assert (ctx->op.status == VNET_CRYPTO_OP_STATUS_COMPLETED);
193 :
194 0 : return ctx->super.algo->tag_size;
195 : }
196 :
197 : static void
198 0 : ptls_vpp_crypto_aead_dispose_crypto (ptls_aead_context_t * _ctx)
199 : {
200 0 : vlib_main_t *vm = vlib_get_main ();
201 0 : struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
202 :
203 0 : clib_rwlock_writer_lock (&picotls_main.crypto_keys_rw_lock);
204 0 : vnet_crypto_key_del (vm, ctx->key_index);
205 0 : clib_rwlock_writer_unlock (&picotls_main.crypto_keys_rw_lock);
206 0 : }
207 :
208 : static int
209 0 : ptls_vpp_crypto_aead_setup_crypto (ptls_aead_context_t *_ctx, int is_enc,
210 : const void *key, const void *iv,
211 : vnet_crypto_alg_t alg)
212 : {
213 0 : struct vlib_main_t *vm = vlib_get_main ();
214 0 : struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
215 0 : u16 key_len = ctx->super.algo->key_size;
216 :
217 0 : if (alg == VNET_CRYPTO_ALG_AES_128_GCM)
218 : {
219 0 : ctx->id = is_enc ? VNET_CRYPTO_OP_AES_128_GCM_ENC :
220 : VNET_CRYPTO_OP_AES_128_GCM_DEC;
221 : }
222 0 : else if (alg == VNET_CRYPTO_ALG_AES_256_GCM)
223 : {
224 0 : ctx->id = is_enc ? VNET_CRYPTO_OP_AES_256_GCM_ENC :
225 : VNET_CRYPTO_OP_AES_256_GCM_DEC;
226 : }
227 : else
228 : {
229 : TLS_DBG (1, "%s, invalied aead cipher %s", __FUNCTION__,
230 : _ctx->algo->name);
231 0 : return -1;
232 : }
233 :
234 0 : ctx->alg = alg;
235 0 : ctx->chunk_index = 0;
236 0 : clib_memcpy (ctx->static_iv, iv, ctx->super.algo->iv_size);
237 :
238 0 : clib_rwlock_writer_lock (&picotls_main.crypto_keys_rw_lock);
239 0 : ctx->key_index = vnet_crypto_key_add (vm, alg, (void *) key, key_len);
240 0 : clib_rwlock_writer_unlock (&picotls_main.crypto_keys_rw_lock);
241 :
242 0 : if (is_enc)
243 : {
244 0 : ctx->super.do_encrypt_init = ptls_vpp_crypto_aead_encrypt_init;
245 0 : ctx->super.do_encrypt_update = ptls_vpp_crypto_aead_encrypt_update;
246 0 : ctx->super.do_encrypt_final = ptls_vpp_crypto_aead_encrypt_final;
247 : }
248 : else
249 : {
250 0 : ctx->super.do_decrypt = ptls_vpp_crypto_aead_decrypt;
251 : }
252 0 : ctx->super.dispose_crypto = ptls_vpp_crypto_aead_dispose_crypto;
253 :
254 0 : return 0;
255 : }
256 :
257 : static int
258 0 : ptls_vpp_crypto_aes128ctr_setup_crypto (ptls_cipher_context_t * ctx,
259 : int is_enc, const void *key)
260 : {
261 0 : return ptls_vpp_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_128_ctr (),
262 : ptls_vpp_crypto_cipher_encrypt);
263 : }
264 :
265 : static int
266 0 : ptls_vpp_crypto_aes256ctr_setup_crypto (ptls_cipher_context_t * ctx,
267 : int is_enc, const void *key)
268 : {
269 0 : return ptls_vpp_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_256_ctr (),
270 : ptls_vpp_crypto_cipher_encrypt);
271 : }
272 :
273 : static int
274 0 : ptls_vpp_crypto_aead_aes128gcm_setup_crypto (ptls_aead_context_t *ctx,
275 : int is_enc, const void *key,
276 : const void *iv)
277 : {
278 0 : return ptls_vpp_crypto_aead_setup_crypto (ctx, is_enc, key, iv,
279 : VNET_CRYPTO_ALG_AES_128_GCM);
280 : }
281 :
282 : static int
283 0 : ptls_vpp_crypto_aead_aes256gcm_setup_crypto (ptls_aead_context_t *ctx,
284 : int is_enc, const void *key,
285 : const void *iv)
286 : {
287 0 : return ptls_vpp_crypto_aead_setup_crypto (ctx, is_enc, key, iv,
288 : VNET_CRYPTO_ALG_AES_256_GCM);
289 : }
290 :
291 : ptls_cipher_algorithm_t ptls_vpp_crypto_aes128ctr = {
292 : "AES128-CTR",
293 : PTLS_AES128_KEY_SIZE,
294 : 1,
295 : PTLS_AES_IV_SIZE,
296 : sizeof (struct vpp_aead_context_t),
297 : ptls_vpp_crypto_aes128ctr_setup_crypto
298 : };
299 :
300 : ptls_cipher_algorithm_t ptls_vpp_crypto_aes256ctr = {
301 : "AES256-CTR",
302 : PTLS_AES256_KEY_SIZE,
303 : 1 /* block size */,
304 : PTLS_AES_IV_SIZE,
305 : sizeof (struct vpp_aead_context_t),
306 : ptls_vpp_crypto_aes256ctr_setup_crypto
307 : };
308 :
309 : #define PTLS_X86_CACHE_LINE_ALIGN_BITS 6
310 : ptls_aead_algorithm_t ptls_vpp_crypto_aes128gcm = {
311 : "AES128-GCM",
312 : PTLS_AESGCM_CONFIDENTIALITY_LIMIT,
313 : PTLS_AESGCM_INTEGRITY_LIMIT,
314 : &ptls_vpp_crypto_aes128ctr,
315 : NULL,
316 : PTLS_AES128_KEY_SIZE,
317 : PTLS_AESGCM_IV_SIZE,
318 : PTLS_AESGCM_TAG_SIZE,
319 : { PTLS_TLS12_AESGCM_FIXED_IV_SIZE, PTLS_TLS12_AESGCM_RECORD_IV_SIZE },
320 : 1,
321 : PTLS_X86_CACHE_LINE_ALIGN_BITS,
322 : sizeof (struct vpp_aead_context_t),
323 : ptls_vpp_crypto_aead_aes128gcm_setup_crypto
324 : };
325 :
326 : ptls_aead_algorithm_t ptls_vpp_crypto_aes256gcm = {
327 : "AES256-GCM",
328 : PTLS_AESGCM_CONFIDENTIALITY_LIMIT,
329 : PTLS_AESGCM_INTEGRITY_LIMIT,
330 : &ptls_vpp_crypto_aes256ctr,
331 : NULL,
332 : PTLS_AES256_KEY_SIZE,
333 : PTLS_AESGCM_IV_SIZE,
334 : PTLS_AESGCM_TAG_SIZE,
335 : { PTLS_TLS12_AESGCM_FIXED_IV_SIZE, PTLS_TLS12_AESGCM_RECORD_IV_SIZE },
336 : 1,
337 : PTLS_X86_CACHE_LINE_ALIGN_BITS,
338 : sizeof (struct vpp_aead_context_t),
339 : ptls_vpp_crypto_aead_aes256gcm_setup_crypto
340 : };
341 :
342 : ptls_cipher_suite_t ptls_vpp_crypto_aes128gcmsha256 =
343 : { PTLS_CIPHER_SUITE_AES_128_GCM_SHA256,
344 : &ptls_vpp_crypto_aes128gcm,
345 : &ptls_openssl_sha256
346 : };
347 :
348 : ptls_cipher_suite_t ptls_vpp_crypto_aes256gcmsha384 =
349 : { PTLS_CIPHER_SUITE_AES_256_GCM_SHA384,
350 : &ptls_vpp_crypto_aes256gcm,
351 : &ptls_openssl_sha384
352 : };
353 :
354 : ptls_cipher_suite_t *ptls_vpp_crypto_cipher_suites[] =
355 : { &ptls_vpp_crypto_aes256gcmsha384,
356 : &ptls_vpp_crypto_aes128gcmsha256,
357 : NULL
358 : };
359 :
360 : /*
361 : * fd.io coding-style-patch-verification: ON
362 : *
363 : * Local Variables:
364 : * eval: (c-set-style "gnu")
365 : * End:
366 : */
|