[dm-devel] [PATCH v2] dm: switch dm-verity to async hash crypto API
Gilad Ben-Yossef
gilad at benyossef.com
Fri Feb 17 14:52:06 UTC 2017
Hi Milan,
Thank you for the review and testing.
On Fri, Feb 17, 2017 at 3:00 PM, Milan Broz <gmazyland at gmail.com> wrote:
> On 02/06/2017 02:58 PM, Gilad Ben-Yossef wrote:
>> Use of the synchronous digest API limits dm-verity to using pure
>> CPU based algorithm providers and rules out the use of off CPU
>> algorithm providers which are normally asynchronous by nature,
>> potentially freeing CPU cycles.
>>
>> This can reduce performance per Watt in situations such as during
>> boot time when a lot of concurrent file accesses are made to the
>> protected volume.
>>
>> Move DM_VERITY to the asynchronous hash API.
>
> Did you test that async hash completion path?
Yes, I did - with the Arm TrustZone CryptoCell hardware accelerator.
I did not try with cryptd though.
>
> I just tried to force async crypto by replacing "sha256"
> in mapping table with "cryptd(sha256-generic)" and it kills
> kernel immediately.
> https://mbroz.fedorapeople.org/tmp/verity-fail.png
>
> (I hope this trick should cause to use cryptd and use async processing.
> In previous version the parameter is properly rejected, because unsupported
> by shash api.)
>
Thanks for this trick. I was not aware you can invoke cryptd it like that.
I will recreate the issue and fix it.
>
> Some more comments below.
> ...
>
>> -static int verity_hash_update(struct dm_verity *v, struct shash_desc *desc,
>> - const u8 *data, size_t len)
>> +static int verity_hash_update(struct dm_verity *v, struct ahash_request *req,
>> + const u8 *data, size_t len,
>> + struct verity_result *res)
>> {
>> - int r = crypto_shash_update(desc, data, len);
>> + struct scatterlist sg;
>>
>> - if (unlikely(r < 0))
>> - DMERR("crypto_shash_update failed: %d", r);
>> + sg_init_table(&sg, 1);
>> + sg_set_buf(&sg, data, len);
>
> why not use sg_init_one?
No good reason. I will amend it in the next revision.
>
>> + ahash_request_set_crypt(req, &sg, NULL, len);
>> +
>> + return verity_complete_op(res, crypto_ahash_update(req));
>> +}
>
> ...
>
>> -int verity_hash(struct dm_verity *v, struct shash_desc *desc,
>> +int verity_hash(struct dm_verity *v, struct ahash_request *req,
>> const u8 *data, size_t len, u8 *digest)
>> {
>> int r;
>> + struct verity_result res;
>>
>> - r = verity_hash_init(v, desc);
>> + r = verity_hash_init(v, req, &res);
>> if (unlikely(r < 0))
>> - return r;
>> + goto out;
>
> why it is changed to goto? it doesn't simplify anything in this function
>
I generally prefer for a function to have a single return point, if it does
not over complicates things. I find it makes code more readable and easier
to reason about - put debugging log statement for return for example.
>>
>> - r = verity_hash_update(v, desc, data, len);
>> + r = verity_hash_update(v, req, data, len, &res);
>> if (unlikely(r < 0))
>> - return r;
>> + goto out;
>> +
>> + r = verity_hash_final(v, req, digest, &res);
>>
>> - return verity_hash_final(v, desc, digest);
>> +out:
>> + return r;
>> }
I will post a new revision of the patch early next week .
Thanks,
Gilad
--
Gilad Ben-Yossef
Chief Coffee Drinker
"If you take a class in large-scale robotics, can you end up in a
situation where the homework eats your dog?"
-- Jean-Baptiste Queru
More information about the dm-devel
mailing list