examples/ipsec-secgw: add AES-GCM
[dpdk.git] / examples / ipsec-secgw / esp.c
index 21b2f02..7ee53da 100644 (file)
@@ -90,6 +90,8 @@ esp_inbound(struct rte_mbuf *m, struct ipsec_sa *sa,
                sa->iv_len;
        sym_cop->cipher.data.length = payload_len;
 
+       struct cnt_blk *icb;
+       uint8_t *aad;
        uint8_t *iv = RTE_PTR_ADD(ip4, ip_hdr_len + sizeof(struct esp_hdr));
 
        switch (sa->cipher_algo) {
@@ -99,14 +101,41 @@ esp_inbound(struct rte_mbuf *m, struct ipsec_sa *sa,
                sym_cop->cipher.iv.phys_addr = rte_pktmbuf_mtophys_offset(m,
                                 ip_hdr_len + sizeof(struct esp_hdr));
                sym_cop->cipher.iv.length = sa->iv_len;
+               break;
+       case RTE_CRYPTO_CIPHER_AES_GCM:
+               icb = get_cnt_blk(m);
+               icb->salt = sa->salt;
+               memcpy(&icb->iv, iv, 8);
+               icb->cnt = rte_cpu_to_be_32(1);
+               sym_cop->cipher.iv.data = (uint8_t *)icb;
+               sym_cop->cipher.iv.phys_addr = rte_pktmbuf_mtophys_offset(m,
+                        (uint8_t *)icb - rte_pktmbuf_mtod(m, uint8_t *));
+               sym_cop->cipher.iv.length = 16;
+               break;
+       default:
+               RTE_LOG(ERR, IPSEC_ESP, "unsupported cipher algorithm %u\n",
+                               sa->cipher_algo);
+               return -EINVAL;
+       }
 
+       switch (sa->auth_algo) {
+       case RTE_CRYPTO_AUTH_NULL:
+       case RTE_CRYPTO_AUTH_SHA1_HMAC:
                sym_cop->auth.data.offset = ip_hdr_len;
                sym_cop->auth.data.length = sizeof(struct esp_hdr) +
                        sa->iv_len + payload_len;
                break;
+       case RTE_CRYPTO_AUTH_AES_GCM:
+               aad = get_aad(m);
+               memcpy(aad, iv - sizeof(struct esp_hdr), 8);
+               sym_cop->auth.aad.data = aad;
+               sym_cop->auth.aad.phys_addr = rte_pktmbuf_mtophys_offset(m,
+                               aad - rte_pktmbuf_mtod(m, uint8_t *));
+               sym_cop->auth.aad.length = 8;
+               break;
        default:
-               RTE_LOG(ERR, IPSEC_ESP, "unsupported cipher algorithm %u\n",
-                               sa->cipher_algo);
+               RTE_LOG(ERR, IPSEC_ESP, "unsupported auth algorithm %u\n",
+                               sa->auth_algo);
                return -EINVAL;
        }
 
@@ -291,6 +320,12 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
                        sizeof(struct esp_hdr);
                sym_cop->cipher.data.length = pad_payload_len + sa->iv_len;
                break;
+       case RTE_CRYPTO_CIPHER_AES_GCM:
+               *iv = sa->seq;
+               sym_cop->cipher.data.offset = ip_hdr_len +
+                       sizeof(struct esp_hdr) + sa->iv_len;
+               sym_cop->cipher.data.length = pad_payload_len;
+               break;
        default:
                RTE_LOG(ERR, IPSEC_ESP, "unsupported cipher algorithm %u\n",
                                sa->cipher_algo);
@@ -312,16 +347,26 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
                         (uint8_t *)icb - rte_pktmbuf_mtod(m, uint8_t *));
        sym_cop->cipher.iv.length = 16;
 
-       switch (sa->cipher_algo) {
-       case RTE_CRYPTO_CIPHER_NULL:
-       case RTE_CRYPTO_CIPHER_AES_CBC:
+       uint8_t *aad;
+
+       switch (sa->auth_algo) {
+       case RTE_CRYPTO_AUTH_NULL:
+       case RTE_CRYPTO_AUTH_SHA1_HMAC:
                sym_cop->auth.data.offset = ip_hdr_len;
                sym_cop->auth.data.length = sizeof(struct esp_hdr) +
                        sa->iv_len + pad_payload_len;
                break;
+       case RTE_CRYPTO_AUTH_AES_GCM:
+               aad = get_aad(m);
+               memcpy(aad, esp, 8);
+               sym_cop->auth.aad.data = aad;
+               sym_cop->auth.aad.phys_addr = rte_pktmbuf_mtophys_offset(m,
+                               aad - rte_pktmbuf_mtod(m, uint8_t *));
+               sym_cop->auth.aad.length = 8;
+               break;
        default:
-               RTE_LOG(ERR, IPSEC_ESP, "unsupported cipher algorithm %u\n",
-                               sa->cipher_algo);
+               RTE_LOG(ERR, IPSEC_ESP, "unsupported auth algorithm %u\n",
+                               sa->auth_algo);
                return -EINVAL;
        }