examples/ipsec-secgw: support XCBC-MAC/DES-CBC
[dpdk.git] / examples / ipsec-secgw / esp.c
index f11d095..b72a560 100644 (file)
@@ -30,7 +30,8 @@ esp_inbound(struct rte_mbuf *m, struct ipsec_sa *sa,
        int32_t payload_len, ip_hdr_len;
 
        RTE_ASSERT(sa != NULL);
-       if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)
+       if (ipsec_get_action_type(sa) ==
+                       RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)
                return 0;
 
        RTE_ASSERT(m != NULL);
@@ -99,6 +100,7 @@ esp_inbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 
                switch (sa->cipher_algo) {
                case RTE_CRYPTO_CIPHER_NULL:
+               case RTE_CRYPTO_CIPHER_DES_CBC:
                case RTE_CRYPTO_CIPHER_3DES_CBC:
                case RTE_CRYPTO_CIPHER_AES_CBC:
                        /* Copy IV at the end of crypto operation */
@@ -120,6 +122,7 @@ esp_inbound(struct rte_mbuf *m, struct ipsec_sa *sa,
                case RTE_CRYPTO_AUTH_NULL:
                case RTE_CRYPTO_AUTH_SHA1_HMAC:
                case RTE_CRYPTO_AUTH_SHA256_HMAC:
+               case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
                        sym_cop->auth.data.offset = ip_hdr_len;
                        sym_cop->auth.data.length = sizeof(struct rte_esp_hdr) +
                                sa->iv_len + payload_len;
@@ -148,15 +151,18 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
        uint8_t *nexthdr, *pad_len;
        uint8_t *padding;
        uint16_t i;
+       struct rte_ipsec_session *ips;
 
        RTE_ASSERT(m != NULL);
        RTE_ASSERT(sa != NULL);
        RTE_ASSERT(cop != NULL);
 
-       if ((sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
-                       (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
-               if (m->ol_flags & PKT_RX_SEC_OFFLOAD) {
-                       if (m->ol_flags & PKT_RX_SEC_OFFLOAD_FAILED)
+       ips = ipsec_get_primary_session(sa);
+
+       if ((ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
+                       (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
+               if (m->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD) {
+                       if (m->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED)
                                cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
                        else
                                cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
@@ -169,8 +175,8 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
                return -1;
        }
 
-       if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
-           sa->ol_flags & RTE_SECURITY_RX_HW_TRAILER_OFFLOAD) {
+       if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
+               ips->security.ol_flags & RTE_SECURITY_RX_HW_TRAILER_OFFLOAD) {
                nexthdr = &m->inner_esp_next_proto;
        } else {
                nexthdr = rte_pktmbuf_mtod_offset(m, uint8_t*,
@@ -192,7 +198,7 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
                }
        }
 
-       if (unlikely(sa->flags == TRANSPORT)) {
+       if (unlikely(IS_TRANSPORT(sa->flags))) {
                ip = rte_pktmbuf_mtod(m, struct ip *);
                ip4 = (struct ip *)rte_pktmbuf_adj(m,
                                sizeof(struct rte_esp_hdr) + sa->iv_len);
@@ -225,21 +231,23 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
        struct rte_crypto_sym_op *sym_cop;
        int32_t i;
        uint16_t pad_payload_len, pad_len, ip_hdr_len;
+       struct rte_ipsec_session *ips;
 
        RTE_ASSERT(m != NULL);
        RTE_ASSERT(sa != NULL);
 
+       ips = ipsec_get_primary_session(sa);
        ip_hdr_len = 0;
 
        ip4 = rte_pktmbuf_mtod(m, struct ip *);
        if (likely(ip4->ip_v == IPVERSION)) {
-               if (unlikely(sa->flags == TRANSPORT)) {
+               if (unlikely(IS_TRANSPORT(sa->flags))) {
                        ip_hdr_len = ip4->ip_hl * 4;
                        nlp = ip4->ip_p;
                } else
                        nlp = IPPROTO_IPIP;
        } else if (ip4->ip_v == IP6_VERSION) {
-               if (unlikely(sa->flags == TRANSPORT)) {
+               if (unlikely(IS_TRANSPORT(sa->flags))) {
                        /* XXX No option headers supported */
                        ip_hdr_len = sizeof(struct ip6_hdr);
                        ip6 = (struct ip6_hdr *)ip4;
@@ -257,14 +265,13 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
                        ip_hdr_len + 2, sa->block_size);
        pad_len = pad_payload_len + ip_hdr_len - rte_pktmbuf_pkt_len(m);
 
-       RTE_ASSERT(sa->flags == IP4_TUNNEL || sa->flags == IP6_TUNNEL ||
-                       sa->flags == TRANSPORT);
+       RTE_ASSERT(IS_TUNNEL(sa->flags) || IS_TRANSPORT(sa->flags));
 
-       if (likely(sa->flags == IP4_TUNNEL))
+       if (likely(IS_IP4_TUNNEL(sa->flags)))
                ip_hdr_len = sizeof(struct ip);
-       else if (sa->flags == IP6_TUNNEL)
+       else if (IS_IP6_TUNNEL(sa->flags))
                ip_hdr_len = sizeof(struct ip6_hdr);
-       else if (sa->flags != TRANSPORT) {
+       else if (!IS_TRANSPORT(sa->flags)) {
                RTE_LOG(ERR, IPSEC_ESP, "Unsupported SA flags: 0x%x\n",
                                sa->flags);
                return -EINVAL;
@@ -278,9 +285,10 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
        }
 
        /* Add trailer padding if it is not constructed by HW */
-       if (sa->type != RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
-           (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
-            !(sa->ol_flags & RTE_SECURITY_TX_HW_TRAILER_OFFLOAD))) {
+       if (ips->type != RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
+               (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO &&
+                !(ips->security.ol_flags &
+                        RTE_SECURITY_TX_HW_TRAILER_OFFLOAD))) {
                padding = (uint8_t *)rte_pktmbuf_append(m, pad_len +
                                                        sa->digest_len);
                if (unlikely(padding == NULL)) {
@@ -291,7 +299,7 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
                rte_prefetch0(padding);
        }
 
-       switch (sa->flags) {
+       switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
        case IP4_TUNNEL:
                ip4 = ip4ip_outbound(m, sizeof(struct rte_esp_hdr) + sa->iv_len,
                                &sa->src, &sa->dst);
@@ -330,6 +338,7 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
        } else {
                switch (sa->cipher_algo) {
                case RTE_CRYPTO_CIPHER_NULL:
+               case RTE_CRYPTO_CIPHER_DES_CBC:
                case RTE_CRYPTO_CIPHER_3DES_CBC:
                case RTE_CRYPTO_CIPHER_AES_CBC:
                        memset(iv, 0, sa->iv_len);
@@ -345,8 +354,9 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
                }
        }
 
-       if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
-               if (sa->ol_flags & RTE_SECURITY_TX_HW_TRAILER_OFFLOAD) {
+       if (ips->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO) {
+               if (ips->security.ol_flags &
+                               RTE_SECURITY_TX_HW_TRAILER_OFFLOAD) {
                        /* Set the inner esp next protocol for HW trailer */
                        m->inner_esp_next_proto = nlp;
                        m->packet_type |= RTE_PTYPE_TUNNEL_ESP;
@@ -392,6 +402,7 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
        } else {
                switch (sa->cipher_algo) {
                case RTE_CRYPTO_CIPHER_NULL:
+               case RTE_CRYPTO_CIPHER_DES_CBC:
                case RTE_CRYPTO_CIPHER_3DES_CBC:
                case RTE_CRYPTO_CIPHER_AES_CBC:
                        sym_cop->cipher.data.offset = ip_hdr_len +
@@ -424,6 +435,7 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
                case RTE_CRYPTO_AUTH_NULL:
                case RTE_CRYPTO_AUTH_SHA1_HMAC:
                case RTE_CRYPTO_AUTH_SHA256_HMAC:
+               case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
                        sym_cop->auth.data.offset = ip_hdr_len;
                        sym_cop->auth.data.length = sizeof(struct rte_esp_hdr) +
                                sa->iv_len + pad_payload_len;
@@ -449,12 +461,15 @@ esp_outbound_post(struct rte_mbuf *m,
                  struct ipsec_sa *sa,
                  struct rte_crypto_op *cop)
 {
+       enum rte_security_session_action_type type;
        RTE_ASSERT(m != NULL);
        RTE_ASSERT(sa != NULL);
 
-       if ((sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
-                       (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
-               m->ol_flags |= PKT_TX_SEC_OFFLOAD;
+       type = ipsec_get_action_type(sa);
+
+       if ((type == RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) ||
+                       (type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO)) {
+               m->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD;
        } else {
                RTE_ASSERT(cop != NULL);
                if (cop->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {