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