FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
pico_vpp_crypto.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 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 "pico_vpp_crypto.h"
22 
23 typedef void (*ptls_vpp_do_transform_fn) (ptls_cipher_context_t *, void *,
24  const void *, size_t);
25 
27 
28 struct cipher_context_t
29 {
30  ptls_cipher_context_t super;
32  u32 key_index;
33 };
34 
36 {
37  ptls_aead_context_t super;
43 };
44 
45 static void
46 ptls_vpp_crypto_cipher_do_init (ptls_cipher_context_t * _ctx, const void *iv)
47 {
48  struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx;
49 
51  if (!strcmp (ctx->super.algo->name, "AES128-CTR"))
52  {
53  id = VNET_CRYPTO_OP_AES_128_CTR_ENC;
54  }
55  else if (!strcmp (ctx->super.algo->name, "AES256-CTR"))
56  {
57  id = VNET_CRYPTO_OP_AES_256_CTR_ENC;
58  }
59  else
60  {
61  TLS_DBG (1, "%s, Invalid crypto cipher : ", __FUNCTION__,
62  _ctx->algo->name);
63  assert (0);
64  }
65 
66  vnet_crypto_op_init (&ctx->op, id);
67  ctx->op.iv = (u8 *) iv;
68  ctx->op.key_index = ctx->key_index;
69 }
70 
71 static void
72 ptls_vpp_crypto_cipher_dispose (ptls_cipher_context_t * _ctx)
73 {
74  /* Do nothing */
75 }
76 
77 static void
78 ptls_vpp_crypto_cipher_encrypt (ptls_cipher_context_t * _ctx, void *output,
79  const void *input, size_t _len)
80 {
82  struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx;
83 
84  ctx->op.src = (u8 *) input;
85  ctx->op.dst = output;
86  ctx->op.len = _len;
87 
88  vnet_crypto_process_ops (vm, &ctx->op, 1);
89 }
90 
91 static int
92 ptls_vpp_crypto_cipher_setup_crypto (ptls_cipher_context_t * _ctx, int is_enc,
93  const void *key,
94  const EVP_CIPHER * cipher,
95  ptls_vpp_do_transform_fn do_transform)
96 {
97  struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx;
98 
99  ctx->super.do_dispose = ptls_vpp_crypto_cipher_dispose;
100  ctx->super.do_init = ptls_vpp_crypto_cipher_do_init;
101  ctx->super.do_transform = do_transform;
102 
104  vnet_crypto_alg_t algo;
105  if (!strcmp (ctx->super.algo->name, "AES128-CTR"))
106  {
107  algo = VNET_CRYPTO_ALG_AES_128_CTR;
108  }
109  else if (!strcmp (ctx->super.algo->name, "AES256-CTR"))
110  {
111  algo = VNET_CRYPTO_ALG_AES_256_CTR;
112  }
113  else
114  {
115  TLS_DBG (1, "%s, Invalid crypto cipher : ", __FUNCTION__,
116  _ctx->algo->name);
117  assert (0);
118  }
119 
120  ctx->key_index = vnet_crypto_key_add (vm, algo,
121  (u8 *) key, _ctx->algo->key_size);
122 
123  return 0;
124 }
125 
126 size_t
127 ptls_vpp_crypto_aead_decrypt (ptls_aead_context_t * _ctx, void *_output,
128  const void *input, size_t inlen, const void *iv,
129  const void *aad, size_t aadlen)
130 {
132  struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
133  int tag_size = ctx->super.algo->tag_size;
134 
135  ctx->op.dst = _output;
136  ctx->op.src = (void *) input;
137  ctx->op.len = inlen - tag_size;;
138  ctx->op.iv = (void *) iv;
139  ctx->op.aad = (void *) aad;
140  ctx->op.aad_len = aadlen;
141  ctx->op.tag = (void *) input + inlen - tag_size;
142  ctx->op.tag_len = tag_size;
143 
144  vnet_crypto_process_ops (vm, &(ctx->op), 1);
145  assert (ctx->op.status == VNET_CRYPTO_OP_STATUS_COMPLETED);
146 
147  return inlen - tag_size;
148 }
149 
150 static void
151 ptls_vpp_crypto_aead_encrypt_init (ptls_aead_context_t * _ctx, const void *iv,
152  const void *aad, size_t aadlen)
153 {
154  struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
155  ctx->op.iv = (void *) iv;
156  ctx->op.aad = (void *) aad;
157  ctx->op.aad_len = aadlen;
158  ctx->op.n_chunks = 2;
159  ctx->op.chunk_index = 0;
160 
162 }
163 
164 static size_t
165 ptls_vpp_crypto_aead_encrypt_update (ptls_aead_context_t * _ctx, void *output,
166  const void *input, size_t inlen)
167 {
168  struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
169  ctx->chunks[ctx->chunk_index].dst = output;
170  ctx->chunks[ctx->chunk_index].src = (void *) input;
171  ctx->chunks[ctx->chunk_index].len = inlen;
172 
173  ctx->chunk_index = ctx->chunk_index == 0 ? 1 : 0;
174 
175  return inlen;
176 }
177 
178 static size_t
179 ptls_vpp_crypto_aead_encrypt_final (ptls_aead_context_t * _ctx, void *_output)
180 {
181  struct vlib_main_t *vm = vlib_get_main ();
182  struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
183 
184  ctx->op.tag = _output;
185  ctx->op.tag_len = ctx->super.algo->tag_size;
186 
187  vnet_crypto_process_chained_ops (vm, &(ctx->op), ctx->chunks, 1);
188  assert (ctx->op.status == VNET_CRYPTO_OP_STATUS_COMPLETED);
189 
190  return ctx->super.algo->tag_size;
191 }
192 
193 static void
194 ptls_vpp_crypto_aead_dispose_crypto (ptls_aead_context_t * _ctx)
195 {
196  /* Do nothing */
197 }
198 
199 
200 static int
201 ptls_vpp_crypto_aead_setup_crypto (ptls_aead_context_t * _ctx, int is_enc,
202  const void *key, vnet_crypto_alg_t alg)
203 {
204  struct vlib_main_t *vm = vlib_get_main ();
205  struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
206  u16 key_len = ctx->super.algo->key_size;
207 
208  memset (&(ctx->op), 0, sizeof (vnet_crypto_op_t));
209 
210  if (alg == VNET_CRYPTO_ALG_AES_128_GCM)
211  {
212  if (is_enc)
213  vnet_crypto_op_init (&(ctx->op), VNET_CRYPTO_OP_AES_128_GCM_ENC);
214  else
215  vnet_crypto_op_init (&(ctx->op), VNET_CRYPTO_OP_AES_128_GCM_DEC);
216  }
217  else if (alg == VNET_CRYPTO_ALG_AES_256_GCM)
218  {
219  if (is_enc)
220  {
221  vnet_crypto_op_init (&(ctx->op), VNET_CRYPTO_OP_AES_256_GCM_ENC);
222  }
223  else
224  vnet_crypto_op_init (&(ctx->op), VNET_CRYPTO_OP_AES_256_GCM_DEC);
225  }
226  else
227  {
228  TLS_DBG (1, "%s, invalied aead cipher %s", __FUNCTION__,
229  _ctx->algo->name);
230  return -1;
231  }
232 
233  ctx->alg = alg;
234 
235  ctx->op.key_index =
236  vnet_crypto_key_add (vm, ctx->alg, (void *) key, key_len);
237  ctx->chunk_index = 0;
238 
239  ctx->super.do_decrypt = ptls_vpp_crypto_aead_decrypt;
240  ctx->super.do_encrypt_init = ptls_vpp_crypto_aead_encrypt_init;
241  ctx->super.do_encrypt_update = ptls_vpp_crypto_aead_encrypt_update;
242  ctx->super.do_encrypt_final = ptls_vpp_crypto_aead_encrypt_final;
243  ctx->super.dispose_crypto = ptls_vpp_crypto_aead_dispose_crypto;
244 
245  return 0;
246 }
247 
248 static int
250  int is_enc, const void *key)
251 {
252  return ptls_vpp_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_128_ctr (),
254 }
255 
256 static int
258  int is_enc, const void *key)
259 {
260  return ptls_vpp_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_256_ctr (),
262 }
263 
264 static int
266  int is_enc, const void *key)
267 {
268  return ptls_vpp_crypto_aead_setup_crypto (ctx, is_enc, key,
269  VNET_CRYPTO_ALG_AES_128_GCM);
270 }
271 
272 static int
274  int is_enc, const void *key)
275 {
276  return ptls_vpp_crypto_aead_setup_crypto (ctx, is_enc, key,
277  VNET_CRYPTO_ALG_AES_256_GCM);
278 }
279 
280 ptls_cipher_algorithm_t ptls_vpp_crypto_aes128ctr = { "AES128-CTR",
281  PTLS_AES128_KEY_SIZE,
282  1, PTLS_AES_IV_SIZE,
283  sizeof (struct vpp_aead_context_t),
284  ptls_vpp_crypto_aes128ctr_setup_crypto
285 };
286 
287 ptls_cipher_algorithm_t ptls_vpp_crypto_aes256ctr = { "AES256-CTR",
288  PTLS_AES256_KEY_SIZE,
289  1 /* block size */ ,
290  PTLS_AES_IV_SIZE,
291  sizeof (struct vpp_aead_context_t),
292  ptls_vpp_crypto_aes256ctr_setup_crypto
293 };
294 
295 ptls_aead_algorithm_t ptls_vpp_crypto_aes128gcm = { "AES128-GCM",
297  NULL,
298  PTLS_AES128_KEY_SIZE,
299  PTLS_AESGCM_IV_SIZE,
300  PTLS_AESGCM_TAG_SIZE,
301  sizeof (struct vpp_aead_context_t),
302  ptls_vpp_crypto_aead_aes128gcm_setup_crypto
303 };
304 
305 ptls_aead_algorithm_t ptls_vpp_crypto_aes256gcm = { "AES256-GCM",
307  NULL,
308  PTLS_AES256_KEY_SIZE,
309  PTLS_AESGCM_IV_SIZE,
310  PTLS_AESGCM_TAG_SIZE,
311  sizeof (struct vpp_aead_context_t),
312  ptls_vpp_crypto_aead_aes256gcm_setup_crypto
313 };
314 
315 ptls_cipher_suite_t ptls_vpp_crypto_aes128gcmsha256 =
316  { PTLS_CIPHER_SUITE_AES_128_GCM_SHA256,
318  &ptls_openssl_sha256
319 };
320 
321 ptls_cipher_suite_t ptls_vpp_crypto_aes256gcmsha384 =
322  { PTLS_CIPHER_SUITE_AES_256_GCM_SHA384,
324  &ptls_openssl_sha384
325 };
326 
327 ptls_cipher_suite_t *ptls_vpp_crypto_cipher_suites[] =
330  NULL
331 };
332 
333 /*
334  * fd.io coding-style-patch-verification: ON
335  *
336  * Local Variables:
337  * eval: (c-set-style "gnu")
338  * End:
339  */
u32 vnet_crypto_process_ops(vlib_main_t *vm, vnet_crypto_op_t ops[], u32 n_ops)
Definition: crypto.c:99
static size_t ptls_vpp_crypto_aead_encrypt_update(ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen)
ptls_cipher_context_t super
Definition: quic_crypto.c:34
static void ptls_vpp_crypto_aead_dispose_crypto(ptls_aead_context_t *_ctx)
static int ptls_vpp_crypto_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key, vnet_crypto_alg_t alg)
ptls_cipher_suite_t ptls_vpp_crypto_aes128gcmsha256
static void ptls_vpp_crypto_cipher_do_init(ptls_cipher_context_t *_ctx, const void *iv)
#define VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS
Definition: crypto.h:239
u16 key_len
Definition: ikev2_types.api:95
vlib_main_t * vm
Definition: in2out_ed.c:1582
ptls_aead_algorithm_t ptls_vpp_crypto_aes128gcm
ptls_cipher_suite_t ptls_vpp_crypto_aes256gcmsha384
void(* ptls_vpp_do_transform_fn)(ptls_cipher_context_t *, void *, const void *, size_t)
vnet_crypto_alg_t alg
unsigned char u8
Definition: types.h:56
size_t ptls_vpp_crypto_aead_decrypt(ptls_aead_context_t *_ctx, void *_output, const void *input, size_t inlen, const void *iv, const void *aad, size_t aadlen)
u8 id[64]
Definition: dhcp.api:160
#define assert(x)
Definition: dlmalloc.c:31
static int ptls_vpp_crypto_aead_aes256gcm_setup_crypto(ptls_aead_context_t *ctx, int is_enc, const void *key)
static void ptls_vpp_crypto_cipher_dispose(ptls_cipher_context_t *_ctx)
static_always_inline void vnet_crypto_op_init(vnet_crypto_op_t *op, vnet_crypto_op_id_t type)
Definition: crypto.h:496
unsigned int u32
Definition: types.h:88
vnet_crypto_op_t op
Definition: quic_crypto.c:35
static void ptls_vpp_crypto_aead_encrypt_init(ptls_aead_context_t *_ctx, const void *iv, const void *aad, size_t aadlen)
u32 vnet_crypto_key_add(vlib_main_t *vm, vnet_crypto_alg_t alg, u8 *data, u16 length)
Definition: crypto.c:345
vnet_crypto_alg_t
Definition: crypto.h:124
static void ptls_vpp_crypto_cipher_encrypt(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t _len)
static u8 iv[]
Definition: aes_cbc.c:24
long ctx[MAX_CONNS]
Definition: main.c:144
unsigned short u16
Definition: types.h:57
ptls_cipher_algorithm_t ptls_vpp_crypto_aes256ctr
static int ptls_vpp_crypto_cipher_setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key, const EVP_CIPHER *cipher, ptls_vpp_do_transform_fn do_transform)
ptls_cipher_algorithm_t ptls_vpp_crypto_aes128ctr
static int ptls_vpp_crypto_aes128ctr_setup_crypto(ptls_cipher_context_t *ctx, int is_enc, const void *key)
vnet_crypto_op_t op
u32 vnet_crypto_process_chained_ops(vlib_main_t *vm, vnet_crypto_op_t ops[], vnet_crypto_op_chunk_t *chunks, u32 n_ops)
Definition: crypto.c:105
static int ptls_vpp_crypto_aead_aes128gcm_setup_crypto(ptls_aead_context_t *ctx, int is_enc, const void *key)
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
static size_t ptls_vpp_crypto_aead_encrypt_final(ptls_aead_context_t *_ctx, void *_output)
typedef key
Definition: ipsec_types.api:85
ptls_aead_context_t super
ptls_aead_algorithm_t ptls_vpp_crypto_aes256gcm
vnet_crypto_op_chunk_t chunks[2]
vnet_crypto_op_status_t status
Definition: crypto.h:235
vnet_crypto_op_id_t
Definition: crypto.h:196
vnet_crypto_main_t crypto_main
Definition: crypto.c:20
#define TLS_DBG(_lvl, _fmt, _args...)
Definition: tls.h:36
static int ptls_vpp_crypto_aes256ctr_setup_crypto(ptls_cipher_context_t *ctx, int is_enc, const void *key)