ipsec: fix build with gcc 6
[dpdk.git] / lib / librte_ipsec / crypto.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4
5 #ifndef _CRYPTO_H_
6 #define _CRYPTO_H_
7
8 /**
9  * @file crypto.h
10  * Contains crypto specific functions/structures/macros used internally
11  * by ipsec library.
12  */
13
14  /*
15   * AES-GCM devices have some specific requirements for IV and AAD formats.
16   * Ideally that to be done by the driver itself.
17   */
18
19 struct aead_gcm_iv {
20         uint32_t salt;
21         uint64_t iv;
22         uint32_t cnt;
23 } __attribute__((packed));
24
25 struct aead_gcm_aad {
26         uint32_t spi;
27         /*
28          * RFC 4106, section 5:
29          * Two formats of the AAD are defined:
30          * one for 32-bit sequence numbers, and one for 64-bit ESN.
31          */
32         union {
33                 uint32_t u32[2];
34                 uint64_t u64;
35         } sqn;
36         uint32_t align0; /* align to 16B boundary */
37 } __attribute__((packed));
38
39 struct gcm_esph_iv {
40         struct esp_hdr esph;
41         uint64_t iv;
42 } __attribute__((packed));
43
44
45 static inline void
46 aead_gcm_iv_fill(struct aead_gcm_iv *gcm, uint64_t iv, uint32_t salt)
47 {
48         gcm->salt = salt;
49         gcm->iv = iv;
50         gcm->cnt = rte_cpu_to_be_32(1);
51 }
52
53 /*
54  * RFC 4106, 5 AAD Construction
55  * spi and sqn should already be converted into network byte order.
56  * Make sure that not used bytes are zeroed.
57  */
58 static inline void
59 aead_gcm_aad_fill(struct aead_gcm_aad *aad, rte_be32_t spi, rte_be64_t sqn,
60         int esn)
61 {
62         aad->spi = spi;
63         if (esn)
64                 aad->sqn.u64 = sqn;
65         else {
66                 aad->sqn.u32[0] = sqn_low32(sqn);
67                 aad->sqn.u32[1] = 0;
68         }
69         aad->align0 = 0;
70 }
71
72 static inline void
73 gen_iv(uint64_t iv[IPSEC_MAX_IV_QWORD], rte_be64_t sqn)
74 {
75         iv[0] = sqn;
76         iv[1] = 0;
77 }
78
79 /*
80  * Helper routine to copy IV
81  * Righ now we support only algorithms with IV length equals 0/8/16 bytes.
82  */
83 static inline void
84 copy_iv(uint64_t dst[IPSEC_MAX_IV_QWORD],
85         const uint64_t src[IPSEC_MAX_IV_QWORD], uint32_t len)
86 {
87         RTE_BUILD_BUG_ON(IPSEC_MAX_IV_SIZE != 2 * sizeof(uint64_t));
88
89         switch (len) {
90         case IPSEC_MAX_IV_SIZE:
91                 dst[1] = src[1];
92                 /* fallthrough */
93         case sizeof(uint64_t):
94                 dst[0] = src[0];
95                 /* fallthrough */
96         case 0:
97                 break;
98         default:
99                 /* should never happen */
100                 RTE_ASSERT(NULL);
101         }
102 }
103
104 /*
105  * from RFC 4303 3.3.2.1.4:
106  * If the ESN option is enabled for the SA, the high-order 32
107  * bits of the sequence number are appended after the Next Header field
108  * for purposes of this computation, but are not transmitted.
109  */
110
111 /*
112  * Helper function that moves ICV by 4B below, and inserts SQN.hibits.
113  * icv parameter points to the new start of ICV.
114  */
115 static inline void
116 insert_sqh(uint32_t sqh, void *picv, uint32_t icv_len)
117 {
118         uint32_t *icv;
119         int32_t i;
120
121         RTE_ASSERT(icv_len % sizeof(uint32_t) == 0);
122
123         icv = picv;
124         icv_len = icv_len / sizeof(uint32_t);
125         for (i = icv_len; i-- != 0; icv[i] = icv[i - 1])
126                 ;
127
128         icv[i] = sqh;
129 }
130
131 /*
132  * Helper function that moves ICV by 4B up, and removes SQN.hibits.
133  * icv parameter points to the new start of ICV.
134  */
135 static inline void
136 remove_sqh(void *picv, uint32_t icv_len)
137 {
138         uint32_t i, *icv;
139
140         RTE_ASSERT(icv_len % sizeof(uint32_t) == 0);
141
142         icv = picv;
143         icv_len = icv_len / sizeof(uint32_t);
144         for (i = 0; i != icv_len; i++)
145                 icv[i] = icv[i + 1];
146 }
147
148 #endif /* _CRYPTO_H_ */