[PATCH v3 10/22] ima: calculate the hash of a buffer using aynchronous hash(ahash)

Dmitry Kasatkin dmitry.kasatkin at gmail.com
Wed Feb 10 11:58:27 PST 2016


On Wed, Feb 3, 2016 at 9:06 PM, Mimi Zohar <zohar at linux.vnet.ibm.com> wrote:
> Setting up ahash has some overhead.  Only use ahash to calculate the
> hash of a buffer, if the buffer is larger than ima_ahash_minsize.
>
> Signed-off-by: Mimi Zohar <zohar at linux.vnet.ibm.com>

Acked-by: Dmitry Kasatkin <dmitry.kasatkin at huawei.com>

> ---
>  security/integrity/ima/ima_crypto.c | 75 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 73 insertions(+), 2 deletions(-)
>
> diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
> index fccb6ce..38f2ed8 100644
> --- a/security/integrity/ima/ima_crypto.c
> +++ b/security/integrity/ima/ima_crypto.c
> @@ -519,6 +519,63 @@ int ima_calc_field_array_hash(struct ima_field_data *field_data,
>         return rc;
>  }
>
> +static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
> +                                 struct ima_digest_data *hash,
> +                                 struct crypto_ahash *tfm)
> +{
> +       struct ahash_request *req;
> +       struct scatterlist sg;
> +       struct ahash_completion res;
> +       int rc, ahash_rc = 0;
> +
> +       hash->length = crypto_ahash_digestsize(tfm);
> +
> +       req = ahash_request_alloc(tfm, GFP_KERNEL);
> +       if (!req)
> +               return -ENOMEM;
> +
> +       init_completion(&res.completion);
> +       ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
> +                                  CRYPTO_TFM_REQ_MAY_SLEEP,
> +                                  ahash_complete, &res);
> +
> +       rc = ahash_wait(crypto_ahash_init(req), &res);
> +       if (rc)
> +               goto out;
> +
> +       sg_init_one(&sg, buf, len);
> +       ahash_request_set_crypt(req, &sg, NULL, len);
> +
> +       ahash_rc = crypto_ahash_update(req);
> +
> +       /* wait for the update request to complete */
> +       rc = ahash_wait(ahash_rc, &res);
> +       if (!rc) {
> +               ahash_request_set_crypt(req, NULL, hash->digest, 0);
> +               rc = ahash_wait(crypto_ahash_final(req), &res);
> +       }
> +out:
> +       ahash_request_free(req);
> +       return rc;
> +}
> +
> +static int calc_buffer_ahash(const void *buf, loff_t len,
> +                            struct ima_digest_data *hash)
> +{
> +       struct crypto_ahash *tfm;
> +       int rc;
> +
> +       tfm = ima_alloc_atfm(hash->algo);
> +       if (IS_ERR(tfm))
> +               return PTR_ERR(tfm);
> +
> +       rc = calc_buffer_ahash_atfm(buf, len, hash, tfm);
> +
> +       ima_free_atfm(tfm);
> +
> +       return rc;
> +}
> +
>  static int calc_buffer_shash_tfm(const void *buf, loff_t size,
>                                 struct ima_digest_data *hash,
>                                 struct crypto_shash *tfm)
> @@ -550,8 +607,8 @@ static int calc_buffer_shash_tfm(const void *buf, loff_t size,
>         return rc;
>  }
>
> -int ima_calc_buffer_hash(const void *buf, loff_t len,
> -                        struct ima_digest_data *hash)
> +static int calc_buffer_shash(const void *buf, loff_t len,
> +                            struct ima_digest_data *hash)
>  {
>         struct crypto_shash *tfm;
>         int rc;
> @@ -566,6 +623,20 @@ int ima_calc_buffer_hash(const void *buf, loff_t len,
>         return rc;
>  }
>
> +int ima_calc_buffer_hash(const void *buf, loff_t len,
> +                        struct ima_digest_data *hash)
> +{
> +       int rc;
> +
> +       if (ima_ahash_minsize && len >= ima_ahash_minsize) {
> +               rc = calc_buffer_ahash(buf, len, hash);
> +               if (!rc)
> +                       return 0;
> +       }
> +
> +       return calc_buffer_shash(buf, len, hash);
> +}
> +
>  static void __init ima_pcrread(int idx, u8 *pcr)
>  {
>         if (!ima_used_chip)
> --
> 2.1.0
>



-- 
Thanks,
Dmitry



More information about the kexec mailing list