From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sergio Gonzalez Monroy Subject: [PATCH v2 3/7] examples/ipsec-secgw: add AES-GCM support Date: Fri, 23 Sep 2016 08:45:29 +0100 Message-ID: <1474616734-118291-4-git-send-email-sergio.gonzalez.monroy@intel.com> References: <1471971574-108998-1-git-send-email-sergio.gonzalez.monroy@intel.com> <1474616734-118291-1-git-send-email-sergio.gonzalez.monroy@intel.com> To: dev@dpdk.org, pablo.de.lara.guarch@intel.com Return-path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id A390768F2 for ; Fri, 23 Sep 2016 09:45:39 +0200 (CEST) In-Reply-To: <1474616734-118291-1-git-send-email-sergio.gonzalez.monroy@intel.com> List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add support for AES-GCM (Galois-Counter Mode). RFC4106: The Use of Galois-Counter Mode (GCM) in IPSec ESP. Signed-off-by: Sergio Gonzalez Monroy --- examples/ipsec-secgw/esp.c | 59 ++++++++++++++++++++++++++++++++++++++------ examples/ipsec-secgw/ipsec.h | 9 +++++++ examples/ipsec-secgw/sa.c | 36 +++++++++++++++++++++------ 3 files changed, 90 insertions(+), 14 deletions(-) diff --git a/examples/ipsec-secgw/esp.c b/examples/ipsec-secgw/esp.c index 21b2f02..7ee53da 100644 --- a/examples/ipsec-secgw/esp.c +++ b/examples/ipsec-secgw/esp.c @@ -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; } diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h index 665c2c8..bf72110 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -113,6 +113,7 @@ struct ipsec_sa { uint16_t cipher_key_len; uint8_t auth_key[MAX_KEY_SIZE]; uint16_t auth_key_len; + uint16_t aad_len; struct rte_crypto_sym_xform *xforms; } __rte_cache_aligned; @@ -194,6 +195,14 @@ get_cnt_blk(struct rte_mbuf *m) } static inline void * +get_aad(struct rte_mbuf *m) +{ + struct ipsec_mbuf_metadata *priv = get_priv(m); + + return &priv->buf[16]; +} + +static inline void * get_cop(struct rte_mbuf *m) { struct ipsec_mbuf_metadata *priv = get_priv(m); diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index ee88802..d5ad5af 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -63,6 +63,8 @@ struct supported_auth_algo { enum rte_crypto_auth_algorithm algo; uint16_t digest_len; uint16_t key_len; + uint8_t aad_len; + uint8_t key_not_req; }; const struct supported_cipher_algo cipher_algos[] = { @@ -79,6 +81,13 @@ const struct supported_cipher_algo cipher_algos[] = { .iv_len = 16, .block_size = 16, .key_len = 16 + }, + { + .keyword = "aes-128-gcm", + .algo = RTE_CRYPTO_CIPHER_AES_GCM, + .iv_len = 8, + .block_size = 4, + .key_len = 16 } }; @@ -87,13 +96,22 @@ const struct supported_auth_algo auth_algos[] = { .keyword = "null", .algo = RTE_CRYPTO_AUTH_NULL, .digest_len = 0, - .key_len = 0 + .key_len = 0, + .key_not_req = 1 }, { .keyword = "sha1-hmac", .algo = RTE_CRYPTO_AUTH_SHA1_HMAC, .digest_len = 12, .key_len = 20 + }, + { + .keyword = "aes-128-gcm", + .algo = RTE_CRYPTO_AUTH_AES_GCM, + .digest_len = 16, + .key_len = 16, + .aad_len = 8, + .key_not_req = 1 } }; @@ -255,8 +273,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, rule->iv_len = algo->iv_len; rule->cipher_key_len = algo->key_len; - /* for NULL algorithm, no cipher key should - * exist */ + /* for NULL algorithm, no cipher key required */ if (rule->cipher_algo == RTE_CRYPTO_CIPHER_NULL) { cipher_algo_p = 1; continue; @@ -307,9 +324,12 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, rule->auth_algo = algo->algo; rule->auth_key_len = algo->key_len; rule->digest_len = algo->digest_len; + rule->aad_len = algo->key_len; - /* for NULL algorithm, no auth key should exist */ - if (rule->auth_algo == RTE_CRYPTO_AUTH_NULL) { + /* NULL algorithm and combined algos do not + * require auth key + */ + if (algo->key_not_req) { auth_algo_p = 1; continue; } @@ -572,7 +592,8 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_AUTH; sa_ctx->xf[idx].a.auth.algo = sa->auth_algo; - sa_ctx->xf[idx].a.auth.add_auth_data_length = 0; + sa_ctx->xf[idx].a.auth.add_auth_data_length = + sa->aad_len; sa_ctx->xf[idx].a.auth.key.data = sa->auth_key; sa_ctx->xf[idx].a.auth.key.length = sa->auth_key_len; @@ -593,7 +614,8 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], sa_ctx->xf[idx].b.type = RTE_CRYPTO_SYM_XFORM_AUTH; sa_ctx->xf[idx].b.auth.algo = sa->auth_algo; - sa_ctx->xf[idx].b.auth.add_auth_data_length = 0; + sa_ctx->xf[idx].b.auth.add_auth_data_length = + sa->aad_len; sa_ctx->xf[idx].b.auth.key.data = sa->auth_key; sa_ctx->xf[idx].b.auth.key.length = sa->auth_key_len; -- 2.5.5