1/* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2021 Marvell. 3 */ 4#ifndef __CNXK_IPSEC_H__ 5#define __CNXK_IPSEC_H__ 6 7#include <rte_security.h> 8#include <rte_security_driver.h> 9 10#include "roc_api.h" 11 12extern struct rte_security_ops cnxk_sec_ops; 13 14struct cnxk_cpt_inst_tmpl { 15 uint64_t w2; 16 uint64_t w4; 17 uint64_t w7; 18}; 19 20static inline int 21ipsec_xform_cipher_verify(struct rte_crypto_sym_xform *crypto_xform) 22{ 23 if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_NULL) 24 return 0; 25 26 if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC || 27 crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CTR) { 28 switch (crypto_xform->cipher.key.length) { 29 case 16: 30 case 24: 31 case 32: 32 break; 33 default: 34 return -ENOTSUP; 35 } 36 return 0; 37 } 38 39 if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC && 40 crypto_xform->cipher.key.length == 24) 41 return 0; 42 43 return -ENOTSUP; 44} 45 46static inline int 47ipsec_xform_auth_verify(struct rte_crypto_sym_xform *crypto_xform) 48{ 49 uint16_t keylen = crypto_xform->auth.key.length; 50 51 if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_NULL) 52 return 0; 53 54 if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) { 55 if (keylen >= 20 && keylen <= 64) 56 return 0; 57 } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC) { 58 if (keylen >= 32 && keylen <= 64) 59 return 0; 60 } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA384_HMAC) { 61 if (keylen == 48) 62 return 0; 63 } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA512_HMAC) { 64 if (keylen == 64) 65 return 0; 66 } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { 67 if (keylen >= 16 && keylen <= 32) 68 return 0; 69 } 70 71 if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC && 72 keylen == ROC_CPT_AES_XCBC_KEY_LENGTH) 73 return 0; 74 75 return -ENOTSUP; 76} 77 78static inline int 79ipsec_xform_aead_verify(struct rte_security_ipsec_xform *ipsec_xform, 80 struct rte_crypto_sym_xform *crypto_xform) 81{ 82 if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS && 83 crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT) 84 return -EINVAL; 85 86 if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && 87 crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT) 88 return -EINVAL; 89 90 if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) { 91 switch (crypto_xform->aead.key.length) { 92 case 16: 93 case 24: 94 case 32: 95 break; 96 default: 97 return -EINVAL; 98 } 99 return 0; 100 } 101 102 return -ENOTSUP; 103} 104 105static inline int 106cnxk_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec_xform, 107 struct rte_crypto_sym_xform *crypto_xform) 108{ 109 struct rte_crypto_sym_xform *auth_xform, *cipher_xform; 110 int ret; 111 112 if ((ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && 113 (ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_EGRESS)) 114 return -EINVAL; 115 116 if ((ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_ESP) && 117 (ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_AH)) 118 return -EINVAL; 119 120 if ((ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) && 121 (ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)) 122 return -EINVAL; 123 124 if ((ipsec_xform->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) && 125 (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV4) && 126 (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV6)) 127 return -EINVAL; 128 129 if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) 130 return ipsec_xform_aead_verify(ipsec_xform, crypto_xform); 131 132 if (ipsec_xform->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) { 133 if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { 134 /* Ingress */ 135 auth_xform = crypto_xform; 136 cipher_xform = crypto_xform->next; 137 138 if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH) 139 return -EINVAL; 140 141 if ((cipher_xform != NULL) && ((cipher_xform->type != 142 RTE_CRYPTO_SYM_XFORM_CIPHER) || 143 (cipher_xform->cipher.algo != 144 RTE_CRYPTO_CIPHER_NULL))) 145 return -EINVAL; 146 } else { 147 /* Egress */ 148 if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { 149 cipher_xform = crypto_xform; 150 auth_xform = crypto_xform->next; 151 152 if (auth_xform == NULL || 153 cipher_xform->cipher.algo != 154 RTE_CRYPTO_CIPHER_NULL) 155 return -EINVAL; 156 } else if (crypto_xform->type == 157 RTE_CRYPTO_SYM_XFORM_AUTH) 158 auth_xform = crypto_xform; 159 else 160 return -EINVAL; 161 } 162 } else { 163 if (crypto_xform->next == NULL) 164 return -EINVAL; 165 166 if (ipsec_xform->direction == 167 RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { 168 /* Ingress */ 169 if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH || 170 crypto_xform->next->type != 171 RTE_CRYPTO_SYM_XFORM_CIPHER) 172 return -EINVAL; 173 auth_xform = crypto_xform; 174 cipher_xform = crypto_xform->next; 175 } else { 176 /* Egress */ 177 if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER || 178 crypto_xform->next->type != 179 RTE_CRYPTO_SYM_XFORM_AUTH) 180 return -EINVAL; 181 cipher_xform = crypto_xform; 182 auth_xform = crypto_xform->next; 183 } 184 185 ret = ipsec_xform_cipher_verify(cipher_xform); 186 if (ret) 187 return ret; 188 } 189 190 return ipsec_xform_auth_verify(auth_xform); 191} 192#endif /* __CNXK_IPSEC_H__ */ 193