FD.io VPP  v19.04.4-rc0-5-ge88582fac
Vector Packet Processing
esp.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco 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 #ifndef __ESP_H__
16 #define __ESP_H__
17 
18 #include <vnet/ip/ip.h>
19 #include <vnet/crypto/crypto.h>
20 #include <vnet/ipsec/ipsec.h>
21 
22 typedef struct
23 {
26  u8 data[0];
27 } esp_header_t;
28 
29 typedef struct
30 {
33 } esp_footer_t;
34 
35 /* *INDENT-OFF* */
36 typedef CLIB_PACKED (struct {
37  ip4_header_t ip4;
38  esp_header_t esp;
39 }) ip4_and_esp_header_t;
40 /* *INDENT-ON* */
41 
42 /* *INDENT-OFF* */
43 typedef CLIB_PACKED (struct {
44  ip4_header_t ip4;
45  udp_header_t udp;
46  esp_header_t esp;
47 }) ip4_and_udp_and_esp_header_t;
48 /* *INDENT-ON* */
49 
50 /* *INDENT-OFF* */
51 typedef CLIB_PACKED (struct {
52  ip6_header_t ip6;
53  esp_header_t esp;
54 }) ip6_and_esp_header_t;
55 /* *INDENT-ON* */
56 
57 /**
58  * AES GCM Additional Authentication data
59  */
60 typedef struct esp_aead_t_
61 {
62  /**
63  * for GCM: when using ESN it's:
64  * SPI, seq-hi, seg-low
65  * else
66  * SPI, seq-low
67  */
68  u32 data[3];
69 } __clib_packed esp_aead_t;
70 
71 #define ESP_SEQ_MAX (4294967295UL)
72 #define ESP_MAX_BLOCK_SIZE (16)
73 #define ESP_MAX_IV_SIZE (16)
74 #define ESP_MAX_ICV_SIZE (32)
75 
76 u8 *format_esp_header (u8 * s, va_list * args);
77 
78 /* TODO seq increment should be atomic to be accessed by multiple workers */
79 always_inline int
81 {
82  if (PREDICT_TRUE (ipsec_sa_is_set_USE_ESN (sa)))
83  {
84  if (PREDICT_FALSE (sa->seq == ESP_SEQ_MAX))
85  {
86  if (PREDICT_FALSE (ipsec_sa_is_set_USE_ANTI_REPLAY (sa) &&
87  sa->seq_hi == ESP_SEQ_MAX))
88  return 1;
89  sa->seq_hi++;
90  }
91  sa->seq++;
92  }
93  else
94  {
95  if (PREDICT_FALSE (ipsec_sa_is_set_USE_ANTI_REPLAY (sa) &&
96  sa->seq == ESP_SEQ_MAX))
97  return 1;
98  sa->seq++;
99  }
100 
101  return 0;
102 }
103 
104 
105 always_inline unsigned int
106 hmac_calc (vlib_main_t * vm, ipsec_sa_t * sa, u8 * data, int data_len,
107  u8 * signature)
108 {
109  vnet_crypto_op_t _op, *op = &_op;
110 
111  if (PREDICT_FALSE (sa->integ_op_id == 0))
112  return 0;
113 
115  op->key = sa->integ_key.data;
116  op->key_len = sa->integ_key.len;
117  op->src = data;
118  op->len = data_len;
119  op->digest = signature;
120  op->digest_len = sa->integ_icv_size;
121 
122  if (ipsec_sa_is_set_USE_ESN (sa))
123  {
124  u32 seq_hi = clib_host_to_net_u32 (sa->seq_hi);
125 
126  op->len += 4;
127  clib_memcpy (data + data_len, &seq_hi, 4);
128  }
129 
130  vnet_crypto_process_ops (vm, op, 1);
131  return sa->integ_icv_size;
132 }
133 
134 always_inline void
136  const esp_header_t * esp, const ipsec_sa_t * sa)
137 {
138  esp_aead_t *aad;
139 
140  aad = (esp_aead_t *) op->aad;
141  clib_memcpy_fast (aad, esp, 8);
142 
143  if (ipsec_sa_is_set_USE_ESN (sa))
144  {
145  /* SPI, seq-hi, seq-low */
146  aad->data[2] = aad->data[1];
147  aad->data[1] = clib_host_to_net_u32 (sa->seq_hi);
148  op->aad_len = 12;
149  }
150  else
151  /* SPI, seq-low */
152  op->aad_len = 8;
153 }
154 #endif /* __ESP_H__ */
155 
156 /*
157  * fd.io coding-style-patch-verification: ON
158  *
159  * Local Variables:
160  * eval: (c-set-style "gnu")
161  * End:
162  */
u32 vnet_crypto_process_ops(vlib_main_t *vm, vnet_crypto_op_t ops[], u32 n_ops)
Definition: crypto.c:46
#define PREDICT_TRUE(x)
Definition: clib.h:112
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
struct esp_aead_t_ esp_aead_t
AES GCM Additional Authentication data.
AES GCM Additional Authentication data.
Definition: esp.h:60
u8 data[128]
Definition: ipsec.api:248
vnet_crypto_op_id_t integ_op_id
Definition: ipsec_sa.h:130
unsigned char u8
Definition: types.h:56
u32 seq_hi
Definition: ipsec_sa.h:123
#define clib_memcpy(d, s, n)
Definition: string.h:180
static int esp_seq_advance(ipsec_sa_t *sa)
Definition: esp.h:80
#define always_inline
Definition: clib.h:98
u32 data[3]
for GCM: when using ESN it&#39;s: SPI, seq-hi, seg-low else SPI, seq-low
Definition: esp.h:68
static_always_inline void vnet_crypto_op_init(vnet_crypto_op_t *op, vnet_crypto_op_id_t type)
Definition: crypto.h:190
unsigned int u32
Definition: types.h:88
static void esp_aad_fill(vnet_crypto_op_t *op, const esp_header_t *esp, const ipsec_sa_t *sa)
Definition: esp.h:135
static unsigned int hmac_calc(vlib_main_t *vm, ipsec_sa_t *sa, u8 *data, int data_len, u8 *signature)
Definition: esp.h:106
typedef CLIB_PACKED(struct { ip4_header_t ip4;esp_header_t esp;}) ip4_and_esp_header_t
#define PREDICT_FALSE(x)
Definition: clib.h:111
vlib_main_t * vm
Definition: buffer.c:312
u8 * format_esp_header(u8 *s, va_list *args)
Definition: esp_format.c:23
u8 data[IPSEC_KEY_MAX_LEN]
Definition: ipsec_sa.h:80
u32 seq
Definition: esp.h:25
#define ESP_SEQ_MAX
Definition: esp.h:71
u32 spi
Definition: esp.h:24
ipsec_key_t integ_key
Definition: ipsec_sa.h:154
u8 integ_icv_size
Definition: ipsec_sa.h:120