Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(C) 2021 Marvell. 3 : : */ 4 : : #ifndef _CNXK_SECURITY_H__ 5 : : #define _CNXK_SECURITY_H__ 6 : : 7 : : #include <errno.h> 8 : : 9 : : #include <rte_crypto.h> 10 : : #include <rte_security.h> 11 : : 12 : : #include "roc_cpt.h" 13 : : #include "roc_ie_on.h" 14 : : #include "roc_ie_ot.h" 15 : : #include "roc_ie_ow.h" 16 : : 17 : : /* Response length calculation data */ 18 : : struct cnxk_ipsec_outb_rlens { 19 : : uint16_t partial_len; 20 : : uint8_t roundup_byte; 21 : : int8_t roundup_len; 22 : : uint16_t max_extended_len; 23 : : }; 24 : : 25 : : int __roc_api 26 : : cnxk_ipsec_outb_rlens_get(struct cnxk_ipsec_outb_rlens *rlens, 27 : : struct rte_security_ipsec_xform *ipsec_xfrm, 28 : : struct rte_crypto_sym_xform *crypto_xfrm); 29 : : uint8_t __roc_api 30 : : cnxk_ipsec_ivlen_get(enum rte_crypto_cipher_algorithm c_algo, 31 : : enum rte_crypto_auth_algorithm a_algo, 32 : : enum rte_crypto_aead_algorithm aead_algo); 33 : : uint8_t __roc_api 34 : : cnxk_ipsec_icvlen_get(enum rte_crypto_cipher_algorithm c_algo, 35 : : enum rte_crypto_auth_algorithm a_algo, 36 : : enum rte_crypto_aead_algorithm aead_algo); 37 : : 38 : : uint8_t __roc_api cnxk_ipsec_outb_roundup_byte(enum rte_crypto_cipher_algorithm c_algo, 39 : : enum rte_crypto_aead_algorithm aead_algo); 40 : : 41 : : /* [CN10K] */ 42 : : int __roc_api cnxk_ot_ipsec_inb_sa_fill(struct roc_ot_ipsec_inb_sa *sa, 43 : : struct rte_security_ipsec_xform *ipsec_xfrm, 44 : : struct rte_crypto_sym_xform *crypto_xfrm, uint8_t ctx_ilen); 45 : : int __roc_api cnxk_ot_ipsec_outb_sa_fill(struct roc_ot_ipsec_outb_sa *sa, 46 : : struct rte_security_ipsec_xform *ipsec_xfrm, 47 : : struct rte_crypto_sym_xform *crypto_xfrm, 48 : : uint8_t ctx_ilen); 49 : : bool __roc_api cnxk_ot_ipsec_inb_sa_valid(struct roc_ot_ipsec_inb_sa *sa); 50 : : bool __roc_api cnxk_ot_ipsec_outb_sa_valid(struct roc_ot_ipsec_outb_sa *sa); 51 : : 52 : : /* [CN9K] */ 53 : : int __roc_api cnxk_on_ipsec_inb_sa_create(struct rte_security_ipsec_xform *ipsec, 54 : : struct rte_crypto_sym_xform *crypto_xform, 55 : : struct roc_ie_on_inb_sa *in_sa); 56 : : 57 : : int __roc_api cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec, 58 : : struct rte_crypto_sym_xform *crypto_xform, 59 : : struct roc_ie_on_outb_sa *out_sa); 60 : : /* [CN20K, .) */ 61 : : int __roc_api cnxk_ow_ipsec_inb_sa_fill(struct roc_ow_ipsec_inb_sa *sa, 62 : : struct rte_security_ipsec_xform *ipsec_xfrm, 63 : : struct rte_crypto_sym_xform *crypto_xfrm, uint8_t ctx_ilen); 64 : : int __roc_api cnxk_ow_ipsec_outb_sa_fill(struct roc_ow_ipsec_outb_sa *sa, 65 : : struct rte_security_ipsec_xform *ipsec_xfrm, 66 : : struct rte_crypto_sym_xform *crypto_xfrm, 67 : : uint8_t ctx_ilen); 68 : : bool __roc_api cnxk_ow_ipsec_inb_sa_valid(struct roc_ow_ipsec_inb_sa *sa); 69 : : bool __roc_api cnxk_ow_ipsec_outb_sa_valid(struct roc_ow_ipsec_outb_sa *sa); 70 : : 71 : : static inline int 72 : 0 : ipsec_xform_cipher_verify(struct rte_crypto_sym_xform *crypto_xform) 73 : : { 74 [ # # ]: 0 : if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_NULL) 75 : : return 0; 76 : : 77 [ # # ]: 0 : if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_DES_CBC && 78 [ # # ]: 0 : crypto_xform->cipher.key.length == 8) 79 : : return 0; 80 : : 81 [ # # ]: 0 : if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC || 82 : : crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CTR) { 83 [ # # ]: 0 : switch (crypto_xform->cipher.key.length) { 84 : : case 16: 85 : : case 24: 86 : : case 32: 87 : : break; 88 : : default: 89 : : return -ENOTSUP; 90 : : } 91 : 0 : return 0; 92 : : } 93 : : 94 [ # # ]: 0 : if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC && 95 [ # # ]: 0 : crypto_xform->cipher.key.length == 24) 96 : 0 : return 0; 97 : : 98 : : return -ENOTSUP; 99 : : } 100 : : 101 : : static inline int 102 : 0 : ipsec_xform_auth_verify(struct rte_crypto_sym_xform *crypto_xform) 103 : : { 104 : 0 : uint16_t keylen = crypto_xform->auth.key.length; 105 : : 106 [ # # ]: 0 : if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_NULL) 107 : : return 0; 108 : : 109 [ # # ]: 0 : if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_MD5_HMAC) { 110 [ # # ]: 0 : if (keylen == 16) 111 : : return 0; 112 : : } 113 : : 114 : : if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) { 115 [ # # ]: 0 : if (keylen >= 20 && keylen <= 64) 116 : : return 0; 117 : : } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC) { 118 [ # # ]: 0 : if (keylen >= 32 && keylen <= 64) 119 : : return 0; 120 : : } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA384_HMAC) { 121 [ # # ]: 0 : if (keylen == 48) 122 : : return 0; 123 : : } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA512_HMAC) { 124 [ # # ]: 0 : if (keylen == 64) 125 : : return 0; 126 : : } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { 127 [ # # ]: 0 : if (keylen >= 16 && keylen <= 32) 128 : : return 0; 129 : : } 130 : : 131 [ # # # # ]: 0 : if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC && 132 : : keylen == ROC_CPT_AES_XCBC_KEY_LENGTH) 133 : 0 : return 0; 134 : : 135 : : return -ENOTSUP; 136 : : } 137 : : 138 : : static inline int 139 : : ipsec_xform_aead_verify(struct rte_security_ipsec_xform *ipsec_xform __rte_unused, 140 : : struct rte_crypto_sym_xform *crypto_xform) 141 : : { 142 [ # # ]: 0 : if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM || 143 : : crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM) { 144 [ # # ]: 0 : switch (crypto_xform->aead.key.length) { 145 : : case 16: 146 : : case 24: 147 : : case 32: 148 : : break; 149 : : default: 150 : : return -EINVAL; 151 : : } 152 : 0 : return 0; 153 : : } 154 : : 155 : : return -ENOTSUP; 156 : : } 157 : : 158 : : static inline int 159 : 0 : cnxk_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec_xform, 160 : : struct rte_crypto_sym_xform *crypto_xform) 161 : : { 162 : : struct rte_crypto_sym_xform *auth_xform, *cipher_xform; 163 : : int ret; 164 : : 165 [ # # ]: 0 : if ((ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && 166 : : (ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_EGRESS)) 167 : : return -EINVAL; 168 : : 169 [ # # ]: 0 : if ((ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_ESP) && 170 : : (ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_AH)) 171 : : return -EINVAL; 172 : : 173 [ # # ]: 0 : if ((ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) && 174 : : (ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)) 175 : : return -EINVAL; 176 : : 177 [ # # ]: 0 : if ((ipsec_xform->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) && 178 [ # # # # ]: 0 : (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV4) && 179 : : (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV6)) 180 : : return -EINVAL; 181 : : 182 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 183 [ # # ]: 0 : if (ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_ESP) 184 : : return -EINVAL; 185 : 0 : return ipsec_xform_aead_verify(ipsec_xform, crypto_xform); 186 : : } 187 : : 188 [ # # ]: 0 : if (ipsec_xform->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) { 189 [ # # ]: 0 : if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { 190 : : /* Ingress */ 191 : : auth_xform = crypto_xform; 192 : 0 : cipher_xform = crypto_xform->next; 193 : : 194 [ # # ]: 0 : if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH) 195 : : return -EINVAL; 196 : : 197 [ # # ]: 0 : if ((cipher_xform != NULL) && 198 [ # # ]: 0 : ((cipher_xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER) || 199 [ # # ]: 0 : (cipher_xform->cipher.algo != RTE_CRYPTO_CIPHER_NULL))) 200 : : return -EINVAL; 201 : : } else { 202 : : /* Egress */ 203 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { 204 : : cipher_xform = crypto_xform; 205 : 0 : auth_xform = crypto_xform->next; 206 : : 207 [ # # ]: 0 : if (auth_xform == NULL || 208 [ # # ]: 0 : cipher_xform->cipher.algo != RTE_CRYPTO_CIPHER_NULL) 209 : : return -EINVAL; 210 [ # # ]: 0 : } else if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) 211 : : auth_xform = crypto_xform; 212 : : else 213 : : return -EINVAL; 214 : : } 215 : : } else { 216 [ # # ]: 0 : if (crypto_xform->next == NULL) 217 : : return -EINVAL; 218 : : 219 [ # # ]: 0 : if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { 220 : : /* Ingress */ 221 [ # # ]: 0 : if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH || 222 [ # # ]: 0 : crypto_xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER) 223 : : return -EINVAL; 224 : : auth_xform = crypto_xform; 225 : : cipher_xform = crypto_xform->next; 226 : : } else { 227 : : /* Egress */ 228 [ # # ]: 0 : if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER || 229 [ # # ]: 0 : crypto_xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH) 230 : : return -EINVAL; 231 : : cipher_xform = crypto_xform; 232 : : auth_xform = crypto_xform->next; 233 : : } 234 : : 235 : 0 : ret = ipsec_xform_cipher_verify(cipher_xform); 236 [ # # ]: 0 : if (ret) 237 : : return ret; 238 : : } 239 : : 240 : 0 : return ipsec_xform_auth_verify(auth_xform); 241 : : } 242 : : 243 : : #endif /* _CNXK_SECURITY_H__ */