From: Sergio Gonzalez Monroy Date: Thu, 29 Sep 2016 15:44:09 +0000 (+0100) Subject: examples/ipsec-secgw: add AES-GCM X-Git-Tag: spdx-start~5703 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=a9121c4001c1f7003a6c681cfefe77f58e632347;p=dpdk.git examples/ipsec-secgw: add AES-GCM 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 Acked-by: Pablo de Lara --- diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst index ee6728602a..3779f133d7 100644 --- a/doc/guides/rel_notes/release_16_11.rst +++ b/doc/guides/rel_notes/release_16_11.rst @@ -87,6 +87,7 @@ New Features * configuration file * AES CBC IV generation with cipher forward function + * AES GCM mode Resolved Issues diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst index 5cce2fec9a..503f6748a0 100644 --- a/doc/guides/sample_app_ug/ipsec_secgw.rst +++ b/doc/guides/sample_app_ug/ipsec_secgw.rst @@ -79,7 +79,7 @@ Constraints * No IPv6 options headers. * No AH mode. -* Currently only EAS-CBC, HMAC-SHA1 and NULL. +* Supported algorithms: AES-CBC, AES-GCM, HMAC-SHA1 and NULL. * Each SA must be handle by a unique lcore (*1 RX queue per port*). * No chained mbufs. @@ -380,9 +380,6 @@ SA rule syntax The successfully parsed SA rules will be stored in an array table. -All SAs configured with AES-CBC and HMAC-SHA1 share the same values for -cipher block size and key, and authentication digest size and key. - The SA rule syntax is shown as follows: .. code-block:: console @@ -421,6 +418,7 @@ where each options means: * *null*: NULL algorithm * *aes-128-cbc*: AES-CBC 128-bit algorithm + * *aes-128-gcm*: AES-GCM 128-bit algorithm * Syntax: *cipher_algo * @@ -447,10 +445,12 @@ where each options means: * *null*: NULL algorithm * *sha1-hmac*: HMAC SHA1 algorithm + * *aes-128-gcm*: AES-GCM 128-bit algorithm ```` - * Authentication key, NOT available when 'null' algorithm is used + * Authentication key, NOT available when 'null' or 'aes-128-gcm' algorithm + is used. * Optional: No, must followed by option @@ -514,6 +514,10 @@ Example SA rules: src 1111:1111:1111:1111:1111:1111:1111:5555 \ dst 2222:2222:2222:2222:2222:2222:2222:5555 + sa in 105 cipher_algo aes-128-gcm \ + cipher_key de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef \ + auth_algo aes-128-gcm \ + mode ipv4-tunnel src 172.16.2.5 dst 172.16.1.5 Routing rule syntax ^^^^^^^^^^^^^^^^^^^ diff --git a/examples/ipsec-secgw/esp.c b/examples/ipsec-secgw/esp.c index 21b2f02391..7ee53da5b3 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 ad96782cd4..dbc8c2cbed 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) return &priv->buf[0]; } +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_sym_cop(struct rte_crypto_op *cop) { diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index ee88802005..d5ad5af70d 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;