From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 412023792 for ; Tue, 23 Aug 2016 18:59:38 +0200 (CEST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP; 23 Aug 2016 09:59:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,567,1464678000"; d="scan'208";a="159905581" Received: from silpixa00397517.ir.intel.com ([10.237.222.54]) by fmsmga004.fm.intel.com with ESMTP; 23 Aug 2016 09:59:36 -0700 From: Sergio Gonzalez Monroy To: dev@dpdk.org Date: Tue, 23 Aug 2016 17:59:34 +0100 Message-Id: <1471971574-108998-4-git-send-email-sergio.gonzalez.monroy@intel.com> X-Mailer: git-send-email 2.4.11 In-Reply-To: <1471971574-108998-1-git-send-email-sergio.gonzalez.monroy@intel.com> References: <1471971574-108998-1-git-send-email-sergio.gonzalez.monroy@intel.com> Subject: [dpdk-dev] [PATCH 3/3] examples/ipsec-secgw: add AES-GCM support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Aug 2016 16:59:39 -0000 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 d640ab2..3852c7e 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 *nonce; + 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: + nonce = get_cnt_blk(m); + nonce->salt = sa->salt; + memcpy(&nonce->iv, iv, 8); + sym_cop->cipher.iv.data = (uint8_t *)nonce; + sym_cop->cipher.iv.phys_addr = rte_pktmbuf_mtophys_offset(m, + (uint8_t *)nonce - rte_pktmbuf_mtod(m, uint8_t *)); + /* FIXME should be 12 for GCM, but API needs 16 */ + 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, /* FIXME should be 12 for GCM, but API needs 16 */ 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 d950df3..4db6691 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; @@ -193,6 +194,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 54b5b19..67d39c9 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