.. | .. |
---|
1 | | -============= |
---|
2 | | -CRYPTO ENGINE |
---|
| 1 | +.. SPDX-License-Identifier: GPL-2.0 |
---|
| 2 | + |
---|
| 3 | +Crypto Engine |
---|
3 | 4 | ============= |
---|
4 | 5 | |
---|
5 | 6 | Overview |
---|
6 | 7 | -------- |
---|
7 | | -The crypto engine API (CE), is a crypto queue manager. |
---|
| 8 | +The crypto engine (CE) API is a crypto queue manager. |
---|
8 | 9 | |
---|
9 | 10 | Requirement |
---|
10 | 11 | ----------- |
---|
11 | | -You have to put at start of your tfm_ctx the struct crypto_engine_ctx:: |
---|
| 12 | +You must put, at the start of your transform context your_tfm_ctx, the structure |
---|
| 13 | +crypto_engine: |
---|
12 | 14 | |
---|
13 | | - struct your_tfm_ctx { |
---|
14 | | - struct crypto_engine_ctx enginectx; |
---|
15 | | - ... |
---|
16 | | - }; |
---|
| 15 | +:: |
---|
17 | 16 | |
---|
18 | | -Why: Since CE manage only crypto_async_request, it cannot know the underlying |
---|
19 | | -request_type and so have access only on the TFM. |
---|
20 | | -So using container_of for accessing __ctx is impossible. |
---|
21 | | -Furthermore, the crypto engine cannot know the "struct your_tfm_ctx", |
---|
22 | | -so it must assume that crypto_engine_ctx is at start of it. |
---|
| 17 | + struct your_tfm_ctx { |
---|
| 18 | + struct crypto_engine engine; |
---|
| 19 | + ... |
---|
| 20 | + }; |
---|
| 21 | + |
---|
| 22 | +The crypto engine only manages asynchronous requests in the form of |
---|
| 23 | +crypto_async_request. It cannot know the underlying request type and thus only |
---|
| 24 | +has access to the transform structure. It is not possible to access the context |
---|
| 25 | +using container_of. In addition, the engine knows nothing about your |
---|
| 26 | +structure "``struct your_tfm_ctx``". The engine assumes (requires) the placement |
---|
| 27 | +of the known member ``struct crypto_engine`` at the beginning. |
---|
23 | 28 | |
---|
24 | 29 | Order of operations |
---|
25 | 30 | ------------------- |
---|
26 | | -You have to obtain a struct crypto_engine via crypto_engine_alloc_init(). |
---|
27 | | -And start it via crypto_engine_start(). |
---|
| 31 | +You are required to obtain a struct crypto_engine via ``crypto_engine_alloc_init()``. |
---|
| 32 | +Start it via ``crypto_engine_start()``. When finished with your work, shut down the |
---|
| 33 | +engine using ``crypto_engine_stop()`` and destroy the engine with |
---|
| 34 | +``crypto_engine_exit()``. |
---|
28 | 35 | |
---|
29 | | -Before transferring any request, you have to fill the enginectx. |
---|
30 | | -- prepare_request: (taking a function pointer) If you need to do some processing before doing the request |
---|
31 | | -- unprepare_request: (taking a function pointer) Undoing what's done in prepare_request |
---|
32 | | -- do_one_request: (taking a function pointer) Do encryption for current request |
---|
| 36 | +Before transferring any request, you have to fill the context enginectx by |
---|
| 37 | +providing functions for the following: |
---|
33 | 38 | |
---|
34 | | -Note: that those three functions get the crypto_async_request associated with the received request. |
---|
35 | | -So your need to get the original request via container_of(areq, struct yourrequesttype_request, base); |
---|
| 39 | +* ``prepare_crypt_hardware``: Called once before any prepare functions are |
---|
| 40 | + called. |
---|
36 | 41 | |
---|
37 | | -When your driver receive a crypto_request, you have to transfer it to |
---|
38 | | -the cryptoengine via one of: |
---|
39 | | -- crypto_transfer_ablkcipher_request_to_engine() |
---|
40 | | -- crypto_transfer_aead_request_to_engine() |
---|
41 | | -- crypto_transfer_akcipher_request_to_engine() |
---|
42 | | -- crypto_transfer_hash_request_to_engine() |
---|
43 | | -- crypto_transfer_skcipher_request_to_engine() |
---|
| 42 | +* ``unprepare_crypt_hardware``: Called once after all unprepare functions have |
---|
| 43 | + been called. |
---|
44 | 44 | |
---|
45 | | -At the end of the request process, a call to one of the following function is needed: |
---|
46 | | -- crypto_finalize_ablkcipher_request |
---|
47 | | -- crypto_finalize_aead_request |
---|
48 | | -- crypto_finalize_akcipher_request |
---|
49 | | -- crypto_finalize_hash_request |
---|
50 | | -- crypto_finalize_skcipher_request |
---|
| 45 | +* ``prepare_cipher_request``/``prepare_hash_request``: Called before each |
---|
| 46 | + corresponding request is performed. If some processing or other preparatory |
---|
| 47 | + work is required, do it here. |
---|
| 48 | + |
---|
| 49 | +* ``unprepare_cipher_request``/``unprepare_hash_request``: Called after each |
---|
| 50 | + request is handled. Clean up / undo what was done in the prepare function. |
---|
| 51 | + |
---|
| 52 | +* ``cipher_one_request``/``hash_one_request``: Handle the current request by |
---|
| 53 | + performing the operation. |
---|
| 54 | + |
---|
| 55 | +Note that these functions access the crypto_async_request structure |
---|
| 56 | +associated with the received request. You are able to retrieve the original |
---|
| 57 | +request by using: |
---|
| 58 | + |
---|
| 59 | +:: |
---|
| 60 | + |
---|
| 61 | + container_of(areq, struct yourrequesttype_request, base); |
---|
| 62 | + |
---|
| 63 | +When your driver receives a crypto_request, you must to transfer it to |
---|
| 64 | +the crypto engine via one of: |
---|
| 65 | + |
---|
| 66 | +* crypto_transfer_aead_request_to_engine() |
---|
| 67 | + |
---|
| 68 | +* crypto_transfer_akcipher_request_to_engine() |
---|
| 69 | + |
---|
| 70 | +* crypto_transfer_hash_request_to_engine() |
---|
| 71 | + |
---|
| 72 | +* crypto_transfer_skcipher_request_to_engine() |
---|
| 73 | + |
---|
| 74 | +At the end of the request process, a call to one of the following functions is needed: |
---|
| 75 | + |
---|
| 76 | +* crypto_finalize_aead_request() |
---|
| 77 | + |
---|
| 78 | +* crypto_finalize_akcipher_request() |
---|
| 79 | + |
---|
| 80 | +* crypto_finalize_hash_request() |
---|
| 81 | + |
---|
| 82 | +* crypto_finalize_skcipher_request() |
---|