From: Dmitry Eremin-Solenikov <dmitry.ereminsoleni...@linaro.org>

Separate handling of authentication IV data.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsoleni...@linaro.org>
Reviewed-by: Bill Fischofer <bill.fischo...@linaro.org>
Reviewed-by: Petri Savolainen <petri.savolai...@linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org>
---
/** Email created from pull request 413 (SonicwallYhe:api-next)
 ** https://github.com/Linaro/odp/pull/413
 ** Patch: https://github.com/Linaro/odp/pull/413.patch
 ** Base sha: 5a4502fc6bc53e6503169da3028f456b64811a0b
 ** Merge commit sha: 6669be7b55ab094f9e27d2101a6bb005ca87e405
 **/
 platform/linux-generic/odp_crypto.c    | 35 ++++++++++++++++++++++------------
 platform/linux-generic/odp_ipsec.c     |  6 ++++--
 platform/linux-generic/odp_ipsec_sad.c |  2 +-
 3 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/platform/linux-generic/odp_crypto.c 
b/platform/linux-generic/odp_crypto.c
index 35a83ce0f..b7065e73c 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -36,9 +36,7 @@
  * Keep sorted: first by key length, then by IV length
  */
 static const odp_crypto_cipher_capability_t cipher_capa_null[] = {
-{.key_len = 0, .iv_len = 0},
-/* Special case for GMAC */
-{.key_len = 0, .iv_len = 12} };
+{.key_len = 0, .iv_len = 0} };
 
 static const odp_crypto_cipher_capability_t cipher_capa_trides_cbc[] = {
 {.key_len = 24, .iv_len = 8} };
@@ -86,7 +84,8 @@ static const odp_crypto_auth_capability_t auth_capa_aes_gcm[] 
= {
 {.digest_len = 16, .key_len = 0, .aad_len = {.min = 8, .max = 12, .inc = 4} } 
};
 
 static const odp_crypto_auth_capability_t auth_capa_aes_gmac[] = {
-{.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} } 
};
+{.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0},
+       .iv_len = 12 } };
 
 /** Forward declaration of session structure */
 typedef struct odp_crypto_generic_session_t odp_crypto_generic_session_t;
@@ -121,6 +120,7 @@ struct odp_crypto_generic_session_t {
 
        struct {
                uint8_t  key[EVP_MAX_KEY_LENGTH];
+               uint8_t  iv_data[EVP_MAX_IV_LENGTH];
                uint32_t key_length;
                uint32_t bytes;
                union {
@@ -641,10 +641,10 @@ odp_crypto_alg_err_t aes_gmac_gen(odp_packet_t pkt,
        uint8_t block[EVP_MAX_MD_SIZE];
        int ret;
 
-       if (param->cipher_iv_ptr)
-               iv_ptr = param->cipher_iv_ptr;
-       else if (session->p.cipher_iv.data)
-               iv_ptr = session->cipher.iv_data;
+       if (param->auth_iv_ptr)
+               iv_ptr = param->auth_iv_ptr;
+       else if (session->p.auth_iv.data)
+               iv_ptr = session->auth.iv_data;
        else
                return ODP_CRYPTO_ALG_ERR_IV_INVALID;
 
@@ -680,10 +680,10 @@ odp_crypto_alg_err_t aes_gmac_check(odp_packet_t pkt,
        uint8_t block[EVP_MAX_MD_SIZE];
        int ret;
 
-       if (param->cipher_iv_ptr)
-               iv_ptr = param->cipher_iv_ptr;
-       else if (session->p.cipher_iv.data)
-               iv_ptr = session->cipher.iv_data;
+       if (param->auth_iv_ptr)
+               iv_ptr = param->auth_iv_ptr;
+       else if (session->p.auth_iv.data)
+               iv_ptr = session->auth.iv_data;
        else
                return ODP_CRYPTO_ALG_ERR_IV_INVALID;
 
@@ -909,11 +909,21 @@ odp_crypto_session_create(odp_crypto_session_param_t 
*param,
                goto err;
        }
 
+       if (session->p.auth_iv.length > EVP_MAX_IV_LENGTH) {
+               ODP_DBG("Maximum auth IV length exceeded\n");
+               *status = ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER;
+               goto err;
+       }
+
        /* Copy IV data */
        if (session->p.cipher_iv.data)
                memcpy(session->cipher.iv_data, session->p.cipher_iv.data,
                       session->p.cipher_iv.length);
 
+       if (session->p.auth_iv.data)
+               memcpy(session->auth.iv_data, session->p.auth_iv.data,
+                      session->p.auth_iv.length);
+
        /* Derive order */
        if (ODP_CRYPTO_OP_ENCODE == param->op)
                session->do_cipher_first =  param->auth_cipher_text;
@@ -1102,6 +1112,7 @@ odp_crypto_operation(odp_crypto_op_param_t *param,
 
        packet_param.session = param->session;
        packet_param.cipher_iv_ptr = param->cipher_iv_ptr;
+       packet_param.auth_iv_ptr = param->auth_iv_ptr;
        packet_param.hash_result_offset = param->hash_result_offset;
        packet_param.aad_ptr = param->aad_ptr;
        packet_param.cipher_range = param->cipher_range;
diff --git a/platform/linux-generic/odp_ipsec.c 
b/platform/linux-generic/odp_ipsec.c
index ab4fb5543..e19907a5f 100644
--- a/platform/linux-generic/odp_ipsec.c
+++ b/platform/linux-generic/odp_ipsec.c
@@ -478,6 +478,7 @@ static int ipsec_in_esp(odp_packet_t *pkt,
                                    state->in.hdr_len -
                                    ipsec_sa->icv_len;
        param->cipher_iv_ptr = state->iv;
+       param->auth_iv_ptr = state->iv;
 
        state->esp.aad.spi = esp.spi;
        state->esp.aad.seq_no = esp.seq_no;
@@ -560,7 +561,7 @@ static int ipsec_in_ah(odp_packet_t *pkt,
                return -1;
        }
 
-       param->cipher_iv_ptr = state->iv;
+       param->auth_iv_ptr = state->iv;
 
        state->in.hdr_len = (ah.ah_len + 2) * 4;
        state->in.trl_len = 0;
@@ -1080,6 +1081,7 @@ static int ipsec_out_esp(odp_packet_t *pkt,
        }
 
        param->cipher_iv_ptr = state->iv;
+       param->auth_iv_ptr = state->iv;
 
        memset(&esp, 0, sizeof(esp));
        esp.spi = odp_cpu_to_be_32(ipsec_sa->spi);
@@ -1229,7 +1231,7 @@ static int ipsec_out_ah(odp_packet_t *pkt,
                return -1;
        }
 
-       param->cipher_iv_ptr = state->iv;
+       param->auth_iv_ptr = state->iv;
 
        if (odp_packet_extend_head(pkt, hdr_len, NULL, NULL) < 0) {
                status->error.alg = 1;
diff --git a/platform/linux-generic/odp_ipsec_sad.c 
b/platform/linux-generic/odp_ipsec_sad.c
index 11227a5fc..38cf77557 100644
--- a/platform/linux-generic/odp_ipsec_sad.c
+++ b/platform/linux-generic/odp_ipsec_sad.c
@@ -409,7 +409,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const 
odp_ipsec_sa_param_t *param)
                ipsec_sa->use_counter_iv = 1;
                ipsec_sa->esp_iv_len = 8;
                ipsec_sa->esp_block_len = 16;
-               crypto_param.cipher_iv.length = 12;
+               crypto_param.auth_iv.length = 12;
                break;
        default:
                break;

Reply via email to