API change is OK. There's a typo in patch name:

"AES1268-GCM support" should be "AES128-GCM support"

-Petri


> -----Original Message-----
> From: lng-odp [mailto:[email protected]] On Behalf Of
> EXT Nicolas Morey-Chaisemartin
> Sent: Thursday, November 12, 2015 11:25 AM
> To: [email protected]
> Subject: [lng-odp] [API-NEXT PATCH 3/4] api: crypto: Add AES1268-GCM
> support
> 
> Signed-off-by: Nicolas Morey-Chaisemartin <[email protected]>
> ---
>  include/odp/api/crypto.h                           |   4 +
>  .../linux-generic/include/odp_crypto_internal.h    |   3 +
>  platform/linux-generic/odp_crypto.c                | 183
> +++++++++++++++++++++
>  3 files changed, 190 insertions(+)
> 
> diff --git a/include/odp/api/crypto.h b/include/odp/api/crypto.h
> index c62021e..41beedb 100644
> --- a/include/odp/api/crypto.h
> +++ b/include/odp/api/crypto.h
> @@ -70,6 +70,8 @@ typedef enum {
>       ODP_CIPHER_ALG_3DES_CBC,
>       /** AES128 with cipher block chaining */
>       ODP_CIPHER_ALG_AES128_CBC,
> +     /** AES128 in Galois/Counter Mode */
> +     ODP_CIPHER_ALG_AES128_GCM,
>  } odp_cipher_alg_t;
> 
>  /**
> @@ -82,6 +84,8 @@ typedef enum {
>       ODP_AUTH_ALG_MD5_96,
>       /** SHA256 with 128 bit key */
>       ODP_AUTH_ALG_SHA256_128,
> +     /** AES128 in Galois/Counter Mode */
> +     ODP_AUTH_ALG_AES128_GCM,
>  } odp_auth_alg_t;
> 
>  /**
> diff --git a/platform/linux-generic/include/odp_crypto_internal.h
> b/platform/linux-generic/include/odp_crypto_internal.h
> index b9128a4..7b104af 100644
> --- a/platform/linux-generic/include/odp_crypto_internal.h
> +++ b/platform/linux-generic/include/odp_crypto_internal.h
> @@ -50,6 +50,9 @@ struct odp_crypto_generic_session {
>                       struct {
>                               AES_KEY key;
>                       } aes;
> +                     struct {
> +                             EVP_CIPHER_CTX *ctx;
> +                     } aes_gcm;
>               } data;
>               crypto_func_t func;
>       } cipher;
> diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-
> generic/odp_crypto.c
> index 17fced9..65e8503 100644
> --- a/platform/linux-generic/odp_crypto.c
> +++ b/platform/linux-generic/odp_crypto.c
> @@ -292,6 +292,170 @@ int
> process_aes_params(odp_crypto_generic_session_t *session,
>  }
> 
>  static
> +odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_params_t *params,
> +                                  odp_crypto_generic_session_t *session)
> +{
> +     uint8_t *data  = odp_packet_data(params->out_pkt);
> +     uint32_t plain_len   = params->cipher_range.length;
> +     uint8_t *aad_head = data + params->auth_range.offset;
> +     uint8_t *aad_tail = data + params->cipher_range.offset +
> +             params->cipher_range.length;
> +     uint32_t auth_len = params->auth_range.length;
> +     unsigned char iv_enc[AES_BLOCK_SIZE];
> +     void *iv_ptr;
> +     uint8_t *tag = data + params->hash_result_offset;
> +
> +     if (params->override_iv_ptr)
> +             iv_ptr = params->override_iv_ptr;
> +     else if (session->cipher.iv.data)
> +             iv_ptr = session->cipher.iv.data;
> +     else
> +             return ODP_CRYPTO_ALG_ERR_IV_INVALID;
> +
> +     /* All cipher data must be part of the authentication */
> +     if (params->auth_range.offset > params->cipher_range.offset ||
> +         params->auth_range.offset + auth_len <
> +         params->cipher_range.offset + plain_len)
> +             return ODP_CRYPTO_ALG_ERR_DATA_SIZE;
> +
> +     /*
> +      * Create a copy of the IV.  The DES library modifies IV
> +      * and if we are processing packets on parallel threads
> +      * we could get corruption.
> +      */
> +     memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE);
> +
> +     /* Adjust pointer for beginning of area to cipher/auth */
> +     uint8_t *plaindata = data + params->cipher_range.offset;
> +
> +     /* Encrypt it */
> +     EVP_CIPHER_CTX *ctx = session->cipher.data.aes_gcm.ctx;
> +     int cipher_len = 0;
> +
> +     EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_enc);
> +
> +     /* Authenticate header data (if any) without encrypting them */
> +     if (aad_head < plaindata) {
> +             EVP_EncryptUpdate(ctx, NULL, &cipher_len,
> +                               aad_head, plaindata - aad_head);
> +     }
> +
> +     EVP_EncryptUpdate(ctx, plaindata, &cipher_len,
> +                       plaindata, plain_len);
> +     cipher_len = plain_len;
> +
> +     /* Authenticate footer data (if any) without encrypting them */
> +     if (aad_head + auth_len > plaindata + plain_len) {
> +             EVP_EncryptUpdate(ctx, NULL, NULL, aad_tail,
> +                               auth_len - (aad_tail - aad_head));
> +     }
> +
> +     EVP_EncryptFinal_ex(ctx, plaindata + cipher_len, &cipher_len);
> +     EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag);
> +
> +     return ODP_CRYPTO_ALG_ERR_NONE;
> +}
> +
> +static
> +odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_params_t *params,
> +                                  odp_crypto_generic_session_t *session)
> +{
> +     uint8_t *data  = odp_packet_data(params->out_pkt);
> +     uint32_t cipher_len   = params->cipher_range.length;
> +     uint8_t *aad_head = data + params->auth_range.offset;
> +     uint8_t *aad_tail = data + params->cipher_range.offset +
> +             params->cipher_range.length;
> +     uint32_t auth_len = params->auth_range.length;
> +     unsigned char iv_enc[AES_BLOCK_SIZE];
> +     void *iv_ptr;
> +     uint8_t *tag   = data + params->hash_result_offset;
> +
> +     if (params->override_iv_ptr)
> +             iv_ptr = params->override_iv_ptr;
> +     else if (session->cipher.iv.data)
> +             iv_ptr = session->cipher.iv.data;
> +     else
> +             return ODP_CRYPTO_ALG_ERR_IV_INVALID;
> +
> +     /* All cipher data must be part of the authentication */
> +     if (params->auth_range.offset > params->cipher_range.offset ||
> +         params->auth_range.offset + auth_len <
> +         params->cipher_range.offset + cipher_len)
> +             return ODP_CRYPTO_ALG_ERR_DATA_SIZE;
> +
> +     /*
> +      * Create a copy of the IV.  The DES library modifies IV
> +      * and if we are processing packets on parallel threads
> +      * we could get corruption.
> +      */
> +     memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE);
> +
> +     /* Adjust pointer for beginning of area to cipher/auth */
> +     uint8_t *cipherdata = data + params->cipher_range.offset;
> +     /* Encrypt it */
> +     EVP_CIPHER_CTX *ctx = session->cipher.data.aes_gcm.ctx;
> +     int plain_len = 0;
> +
> +     EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_enc);
> +
> +     /* Authenticate header data (if any) without encrypting them */
> +     if (aad_head < cipherdata) {
> +             EVP_DecryptUpdate(ctx, NULL, &plain_len,
> +                               aad_head, cipherdata - aad_head);
> +     }
> +
> +     EVP_DecryptUpdate(ctx, cipherdata, &plain_len,
> +                       cipherdata, cipher_len);
> +     plain_len = cipher_len;
> +
> +     /* Authenticate footer data (if any) without encrypting them */
> +     if (aad_head + auth_len > cipherdata + cipher_len) {
> +             EVP_DecryptUpdate(ctx, NULL, NULL, aad_tail,
> +                               auth_len - (aad_tail - aad_head));
> +     }
> +
> +     EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag);
> +
> +     if (EVP_DecryptFinal_ex(ctx, cipherdata + cipher_len, &plain_len)
> < 0)
> +             return ODP_CRYPTO_ALG_ERR_ICV_CHECK;
> +
> +     return ODP_CRYPTO_ALG_ERR_NONE;
> +}
> +
> +static
> +int process_aes_gcm_params(odp_crypto_generic_session_t *session,
> +                        odp_crypto_session_params_t *params)
> +{
> +     /* Verify Key len is 16 */
> +     if (params->cipher_key.length != 16)
> +             return -1;
> +
> +     /* Set function */
> +     EVP_CIPHER_CTX *ctx =
> +             session->cipher.data.aes_gcm.ctx = EVP_CIPHER_CTX_new();
> +
> +     if (ODP_CRYPTO_OP_ENCODE == params->op) {
> +             session->cipher.func = aes_gcm_encrypt;
> +             EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL,
> NULL);
> +     } else {
> +             session->cipher.func = aes_gcm_decrypt;
> +             EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL,
> NULL);
> +     }
> +
> +     EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN,
> +                         params->iv.length, NULL);
> +     if (ODP_CRYPTO_OP_ENCODE == params->op) {
> +             EVP_EncryptInit_ex(ctx, NULL, NULL,
> +                                params->cipher_key.data, NULL);
> +     } else {
> +             EVP_DecryptInit_ex(ctx, NULL, NULL,
> +                                params->cipher_key.data, NULL);
> +     }
> +
> +     return 0;
> +}
> +
> +static
>  odp_crypto_alg_err_t des_encrypt(odp_crypto_op_params_t *params,
>                                odp_crypto_generic_session_t *session)
>  {
> @@ -479,6 +643,15 @@
> odp_crypto_session_create(odp_crypto_session_params_t *params,
>       case ODP_CIPHER_ALG_AES128_CBC:
>               rc = process_aes_params(session, params);
>               break;
> +     case ODP_CIPHER_ALG_AES128_GCM:
> +             /* AES-GCM requires to do both auth and
> +              * cipher at the same time */
> +             if (params->auth_alg != ODP_AUTH_ALG_AES128_GCM) {
> +                     rc = -1;
> +                     break;
> +             }
> +             rc = process_aes_gcm_params(session, params);
> +             break;
>       default:
>               rc = -1;
>       }
> @@ -501,6 +674,16 @@
> odp_crypto_session_create(odp_crypto_session_params_t *params,
>       case ODP_AUTH_ALG_SHA256_128:
>               rc = process_sha256_params(session, params, 128);
>               break;
> +     case ODP_AUTH_ALG_AES128_GCM:
> +             /* AES-GCM requires to do both auth and
> +              * cipher at the same time */
> +             if (params->cipher_alg != ODP_CIPHER_ALG_AES128_GCM) {
> +                     rc = -1;
> +                     break;
> +             }
> +             session->auth.func = null_crypto_routine;
> +             rc = 0;
> +             break;
>       default:
>               rc = -1;
>       }
> --
> 2.6.2.406.gaaaec35
> 
> 
> _______________________________________________
> lng-odp mailing list
> [email protected]
> https://lists.linaro.org/mailman/listinfo/lng-odp
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to