FD.io VPP  v21.06
Vector Packet Processing
pico_vpp_crypto.c
Go to the documentation of this file.
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 
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 
29 
30 struct cipher_context_t
31 {
32  ptls_cipher_context_t super;
34  u32 key_index;
35 };
36 
38 {
39  ptls_aead_context_t super;
45  uint8_t iv[PTLS_MAX_IV_SIZE];
46  uint8_t static_iv[PTLS_MAX_IV_SIZE];
47 };
48 
49 static void
50 ptls_vpp_crypto_cipher_do_init (ptls_cipher_context_t * _ctx, const void *iv)
51 {
52  struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx;
53 
55  if (!strcmp (ctx->super.algo->name, "AES128-CTR"))
56  {
57  id = VNET_CRYPTO_OP_AES_128_CTR_ENC;
58  }
59  else if (!strcmp (ctx->super.algo->name, "AES256-CTR"))
60  {
61  id = VNET_CRYPTO_OP_AES_256_CTR_ENC;
62  }
63  else
64  {
65  TLS_DBG (1, "%s, Invalid crypto cipher : ", __FUNCTION__,
66  _ctx->algo->name);
67  assert (0);
68  }
69 
70  vnet_crypto_op_init (&ctx->op, id);
71  ctx->op.iv = (u8 *) iv;
72  ctx->op.key_index = ctx->key_index;
73 }
74 
75 static void
76 ptls_vpp_crypto_cipher_dispose (ptls_cipher_context_t * _ctx)
77 {
78  /* Do nothing */
79 }
80 
81 static void
82 ptls_vpp_crypto_cipher_encrypt (ptls_cipher_context_t * _ctx, void *output,
83  const void *input, size_t _len)
84 {
86  struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx;
87 
88  ctx->op.src = (u8 *) input;
89  ctx->op.dst = output;
90  ctx->op.len = _len;
91 
92  vnet_crypto_process_ops (vm, &ctx->op, 1);
93 }
94 
95 static int
96 ptls_vpp_crypto_cipher_setup_crypto (ptls_cipher_context_t * _ctx, int is_enc,
97  const void *key,
98  const EVP_CIPHER * cipher,
99  ptls_vpp_do_transform_fn do_transform)
100 {
101  struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx;
102 
103  ctx->super.do_dispose = ptls_vpp_crypto_cipher_dispose;
104  ctx->super.do_init = ptls_vpp_crypto_cipher_do_init;
105  ctx->super.do_transform = do_transform;
106 
108  vnet_crypto_alg_t algo;
109  if (!strcmp (ctx->super.algo->name, "AES128-CTR"))
110  {
111  algo = VNET_CRYPTO_ALG_AES_128_CTR;
112  }
113  else if (!strcmp (ctx->super.algo->name, "AES256-CTR"))
114  {
115  algo = VNET_CRYPTO_ALG_AES_256_CTR;
116  }
117  else
118  {
119  TLS_DBG (1, "%s, Invalid crypto cipher : ", __FUNCTION__,
120  _ctx->algo->name);
121  assert (0);
122  }
123 
125  ctx->key_index = vnet_crypto_key_add (vm, algo,
126  (u8 *) key, _ctx->algo->key_size);
128 
129  return 0;
130 }
131 
132 size_t
133 ptls_vpp_crypto_aead_decrypt (ptls_aead_context_t *_ctx, void *_output,
134  const void *input, size_t inlen, uint64_t seq,
135  const void *aad, size_t aadlen)
136 {
138  struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
139  int tag_size = ctx->super.algo->tag_size;
140 
141  ctx->op.dst = _output;
142  ctx->op.src = (void *) input;
143  ctx->op.len = inlen - tag_size;;
144  ctx->op.iv = ctx->iv;
145  ptls_aead__build_iv (ctx->super.algo, ctx->op.iv, ctx->static_iv, seq);
146  ctx->op.aad = (void *) aad;
147  ctx->op.aad_len = aadlen;
148  ctx->op.tag = (void *) input + inlen - tag_size;
149  ctx->op.tag_len = tag_size;
150 
151  vnet_crypto_process_ops (vm, &(ctx->op), 1);
152  assert (ctx->op.status == VNET_CRYPTO_OP_STATUS_COMPLETED);
153 
154  return inlen - tag_size;
155 }
156 
157 static void
158 ptls_vpp_crypto_aead_encrypt_init (ptls_aead_context_t *_ctx, uint64_t seq,
159  const void *aad, size_t aadlen)
160 {
161  struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
162  ctx->op.iv = ctx->iv;
163  ptls_aead__build_iv (ctx->super.algo, ctx->op.iv, ctx->static_iv, seq);
164  ctx->op.aad = (void *) aad;
165  ctx->op.aad_len = aadlen;
166  ctx->op.n_chunks = 2;
167  ctx->op.chunk_index = 0;
168 
170 }
171 
172 static size_t
173 ptls_vpp_crypto_aead_encrypt_update (ptls_aead_context_t * _ctx, void *output,
174  const void *input, size_t inlen)
175 {
176  struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
177  ctx->chunks[ctx->chunk_index].dst = output;
178  ctx->chunks[ctx->chunk_index].src = (void *) input;
179  ctx->chunks[ctx->chunk_index].len = inlen;
180 
181  ctx->chunk_index = ctx->chunk_index == 0 ? 1 : 0;
182 
183  return inlen;
184 }
185 
186 static size_t
187 ptls_vpp_crypto_aead_encrypt_final (ptls_aead_context_t * _ctx, void *_output)
188 {
189  struct vlib_main_t *vm = vlib_get_main ();
190  struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
191 
192  ctx->op.tag = _output;
193  ctx->op.tag_len = ctx->super.algo->tag_size;
194 
195  vnet_crypto_process_chained_ops (vm, &(ctx->op), ctx->chunks, 1);
196  assert (ctx->op.status == VNET_CRYPTO_OP_STATUS_COMPLETED);
197 
198  return ctx->super.algo->tag_size;
199 }
200 
201 static void
202 ptls_vpp_crypto_aead_dispose_crypto (ptls_aead_context_t * _ctx)
203 {
204  /* Do nothing */
205 }
206 
207 static int
208 ptls_vpp_crypto_aead_setup_crypto (ptls_aead_context_t *_ctx, int is_enc,
209  const void *key, const void *iv,
211 {
212  struct vlib_main_t *vm = vlib_get_main ();
213  struct vpp_aead_context_t *ctx = (struct vpp_aead_context_t *) _ctx;
214  u16 key_len = ctx->super.algo->key_size;
215 
216  memset (&(ctx->op), 0, sizeof (vnet_crypto_op_t));
217 
218  if (alg == VNET_CRYPTO_ALG_AES_128_GCM)
219  {
220  if (is_enc)
221  vnet_crypto_op_init (&(ctx->op), VNET_CRYPTO_OP_AES_128_GCM_ENC);
222  else
223  vnet_crypto_op_init (&(ctx->op), VNET_CRYPTO_OP_AES_128_GCM_DEC);
224  }
225  else if (alg == VNET_CRYPTO_ALG_AES_256_GCM)
226  {
227  if (is_enc)
228  {
229  vnet_crypto_op_init (&(ctx->op), VNET_CRYPTO_OP_AES_256_GCM_ENC);
230  }
231  else
232  vnet_crypto_op_init (&(ctx->op), VNET_CRYPTO_OP_AES_256_GCM_DEC);
233  }
234  else
235  {
236  TLS_DBG (1, "%s, invalied aead cipher %s", __FUNCTION__,
237  _ctx->algo->name);
238  return -1;
239  }
240 
241  ctx->alg = alg;
242 
244  ctx->op.key_index =
245  vnet_crypto_key_add (vm, ctx->alg, (void *) key, key_len);
247  ctx->chunk_index = 0;
248  clib_memcpy (ctx->static_iv, iv, ctx->super.algo->iv_size);
249 
250  ctx->super.do_decrypt = ptls_vpp_crypto_aead_decrypt;
251  ctx->super.do_encrypt_init = ptls_vpp_crypto_aead_encrypt_init;
252  ctx->super.do_encrypt_update = ptls_vpp_crypto_aead_encrypt_update;
253  ctx->super.do_encrypt_final = ptls_vpp_crypto_aead_encrypt_final;
254  ctx->super.dispose_crypto = ptls_vpp_crypto_aead_dispose_crypto;
255 
256  return 0;
257 }
258 
259 static int
261  int is_enc, const void *key)
262 {
263  return ptls_vpp_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_128_ctr (),
265 }
266 
267 static int
269  int is_enc, const void *key)
270 {
271  return ptls_vpp_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_256_ctr (),
273 }
274 
275 static int
277  int is_enc, const void *key,
278  const void *iv)
279 {
280  return ptls_vpp_crypto_aead_setup_crypto (ctx, is_enc, key, iv,
281  VNET_CRYPTO_ALG_AES_128_GCM);
282 }
283 
284 static int
286  int is_enc, const void *key,
287  const void *iv)
288 {
289  return ptls_vpp_crypto_aead_setup_crypto (ctx, is_enc, key, iv,
290  VNET_CRYPTO_ALG_AES_256_GCM);
291 }
292 
293 ptls_cipher_algorithm_t ptls_vpp_crypto_aes128ctr = {
294  "AES128-CTR",
295  PTLS_AES128_KEY_SIZE,
296  1,
297  PTLS_AES_IV_SIZE,
298  sizeof (struct vpp_aead_context_t),
299  ptls_vpp_crypto_aes128ctr_setup_crypto
300 };
301 
302 ptls_cipher_algorithm_t ptls_vpp_crypto_aes256ctr = {
303  "AES256-CTR",
304  PTLS_AES256_KEY_SIZE,
305  1 /* block size */,
306  PTLS_AES_IV_SIZE,
307  sizeof (struct vpp_aead_context_t),
308  ptls_vpp_crypto_aes256ctr_setup_crypto
309 };
310 
311 ptls_aead_algorithm_t ptls_vpp_crypto_aes128gcm = {
312  "AES128-GCM",
313  PTLS_AESGCM_CONFIDENTIALITY_LIMIT,
314  PTLS_AESGCM_INTEGRITY_LIMIT,
316  NULL,
317  PTLS_AES128_KEY_SIZE,
318  PTLS_AESGCM_IV_SIZE,
319  PTLS_AESGCM_TAG_SIZE,
320  sizeof (struct vpp_aead_context_t),
321  ptls_vpp_crypto_aead_aes128gcm_setup_crypto
322 };
323 
324 ptls_aead_algorithm_t ptls_vpp_crypto_aes256gcm = {
325  "AES256-GCM",
326  PTLS_AESGCM_CONFIDENTIALITY_LIMIT,
327  PTLS_AESGCM_INTEGRITY_LIMIT,
329  NULL,
330  PTLS_AES256_KEY_SIZE,
331  PTLS_AESGCM_IV_SIZE,
332  PTLS_AESGCM_TAG_SIZE,
333  sizeof (struct vpp_aead_context_t),
334  ptls_vpp_crypto_aead_aes256gcm_setup_crypto
335 };
336 
337 ptls_cipher_suite_t ptls_vpp_crypto_aes128gcmsha256 =
338  { PTLS_CIPHER_SUITE_AES_128_GCM_SHA256,
340  &ptls_openssl_sha256
341 };
342 
343 ptls_cipher_suite_t ptls_vpp_crypto_aes256gcmsha384 =
344  { PTLS_CIPHER_SUITE_AES_256_GCM_SHA384,
346  &ptls_openssl_sha384
347 };
348 
349 ptls_cipher_suite_t *ptls_vpp_crypto_cipher_suites[] =
352  NULL
353 };
354 
355 /*
356  * fd.io coding-style-patch-verification: ON
357  *
358  * Local Variables:
359  * eval: (c-set-style "gnu")
360  * End:
361  */
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:30
size_t ptls_vpp_crypto_aead_decrypt(ptls_aead_context_t *_ctx, void *_output, const void *input, size_t inlen, uint64_t seq, const void *aad, size_t aadlen)
static void ptls_vpp_crypto_aead_dispose_crypto(ptls_aead_context_t *_ctx)
ptls_cipher_suite_t ptls_vpp_crypto_aes128gcmsha256
static void clib_rwlock_writer_lock(clib_rwlock_t *p)
Definition: lock.h:192
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:264
vnet_crypto_op_id_t id
Definition: quic_crypto.c:32
u16 key_len
Definition: ikev2_types.api:95
static void ptls_vpp_crypto_aead_encrypt_init(ptls_aead_context_t *_ctx, uint64_t seq, const void *aad, size_t aadlen)
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
unsigned int u32
Definition: types.h:88
#define clib_memcpy(d, s, n)
Definition: string.h:197
#define assert(x)
Definition: dlmalloc.c:31
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:528
uint8_t iv[PTLS_MAX_IV_SIZE]
vnet_crypto_op_t op
Definition: quic_crypto.c:31
u32 vnet_crypto_key_add(vlib_main_t *vm, vnet_crypto_alg_t alg, u8 *data, u16 length)
Definition: crypto.c:360
vnet_crypto_alg_t
Definition: crypto.h:145
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
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
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)
static void clib_rwlock_writer_unlock(clib_rwlock_t *p)
Definition: lock.h:206
ptls_cipher_algorithm_t ptls_vpp_crypto_aes128ctr
clib_rwlock_t crypto_keys_rw_lock
Definition: tls_picotls.h:49
static int ptls_vpp_crypto_aes128ctr_setup_crypto(ptls_cipher_context_t *ctx, int is_enc, const void *key)
static int ptls_vpp_crypto_aead_aes256gcm_setup_crypto(ptls_aead_context_t *ctx, int is_enc, const void *key, const void *iv)
vnet_crypto_op_t op
picotls_main_t picotls_main
Definition: tls_picotls.c:7
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, const void *iv)
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
static size_t ptls_vpp_crypto_aead_encrypt_final(ptls_aead_context_t *_ctx, void *_output)
typedef key
Definition: ipsec_types.api:88
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:260
vnet_crypto_op_id_t
Definition: crypto.h:219
uint8_t static_iv[PTLS_MAX_IV_SIZE]
vnet_crypto_main_t crypto_main
Definition: crypto.c:20
static int ptls_vpp_crypto_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key, const void *iv, vnet_crypto_alg_t alg)
#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)