core:driver implementation NXP CAAM Driver#2962
core:driver implementation NXP CAAM Driver#2962cneveux wants to merge 9 commits intoOP-TEE:masterfrom
Conversation
|
I submitted this patch to integrate the Crypto HASH done by NXP CAAM HW module. The current implementation of the Crypto operation is not fully filling our expectation. Could see the comment of the commit? |
|
Hi @cneveux, Thanks for this pull request. To better understand what's needed I'll need to ask a few questions and probably also propose different solutions.
Each time
That's already possible today for some definition of best. In our case it's preference of mbedtls or libtomcrypt which is the criterion. I assume that libtomcrypt generally gives better performance, but you could prefer mbedtls for other reasons. For instance company policy or plain trust. |
During HW Driver installation, the HW capacity is stored in the driver operation (max_hash) and function of this value, the Hash is computed by HW or SW. This is need in our case because CAAM Hash Limit is not the same function of the CAAM Module version. We don't want to be only focus on the HASH, we will have the same runtime selection for other Crypto Alloc (e.g. AES CCM/GCM/XTS/CTS, ...) Function of the CAAM version some mode are not supported. Other point, when we will perform the crypto performance testing, we may need to add more criteria than the HW support. For example, we may prefer to do operation by SW because of the data size to be handled. Typically, when the amount of data is small, using HW is overloading the system with cache maintenance and buffer re-allocation to be cache line aligned (add memory copy too). In this case, doing the operation by SW is faster.
Are we able to mix the Tomcrypt and mbedTLS? I mean, can I select the HASH384 with tomcrypt and HASH512 with mbedTLS? In fact the alloc_ctx should be upper to the tomcrypt or mbedTLS. May be having weak function. In our vision, is to let end user (product manufacturer) to decide if he want to limit the runtime flexibility or not. This could be benefict for every OPTEE customer. |
How about adding a call to This would mean that
Let's find something we can agree on for hashes first. I agree that it could be an advantage to reuse the pattern, but I guess it also depends on the pattern.
The current API can't handle this. Is this something that can wait?
Not mixing freely, but that could be achieved with more flags.
Sure, we'll accept patches. They should preferably be independent of this PR, I'm trying to limit the scope of this PR. |
| $(call force,CFG_MX6,y) | ||
| $(call force,CFG_MX6ULL,y) | ||
| $(call force,CFG_TEE_CORE_NB_CORE,1) | ||
| $(call force,CFG_NXP_CAAM,n) |
There was a problem hiding this comment.
"NXP" -> "IMX"? or this driver will also support LS chips?
There was a problem hiding this comment.
Yes this driver will support LS chips also.
There was a problem hiding this comment.
@MrVan ,
yes the driver will support LS devices as well.
| else ifneq (,$(filter $(PLATFORM_FLAVOR),$(mx7-flavorlist))) | ||
| $(call force,CFG_MX7,y) | ||
| CFG_TEE_CORE_NB_CORE ?= 2 | ||
| CFG_WITH_HAB ?= y |
There was a problem hiding this comment.
Please at least explain this macro some where, and why default set to y
| $(call force,CFG_MX6,y) | ||
| $(call force,CFG_MX6S,y) | ||
| $(call force,CFG_TEE_CORE_NB_CORE,1) | ||
| $(call force,CFG_NXP_CAAM,n) |
|
|
||
| CFG_PL310_LOCKED ?= y | ||
| CFG_ENABLE_SCTLR_RR ?= y | ||
| CFG_WITH_HAB ?= y |
|
|
||
| # Almost all platforms include CAAM HW Modules, except the | ||
| # one force to be disabled | ||
| CFG_NXP_CAAM ?= y |
There was a problem hiding this comment.
Will this break the image booting using vendor/upstream uboot + vendor/upstream linux? Or please share some public doc somewhere to use the image built out with this "y"
| CFG_NXP_CAAM ?= y | ||
|
|
||
| ifeq ($(CFG_NXP_CAAM),y) | ||
| # currently disable the use of CAAM in OP-TEE |
There was a problem hiding this comment.
Please add a comment about why "currently disable ..." and "TODO:"
| # | ||
| ifeq ($(CFG_CRYPTO_DRIVER), y) | ||
| # | ||
| # Define this variable ifthe system is able to manage the |
| #include "hal_cfg.h" | ||
| #include "hal_clk.h" | ||
| #include "hal_ctrl.h" | ||
|
|
| #include "hal_clk.h" | ||
| #include "hal_ctrl.h" | ||
|
|
||
| #define CTRL_DEBUG |
There was a problem hiding this comment.
rework debug trace in the driver to select the traces function of build CFG_CAAM_DBG 32 bits word
|
How do you propose to solve the problem of the linux clock driver turning of the clocks to the CAAM if it is used within OP-TEE but not enabled in the Linux kernel? |
|
@Emantor If caam clk disabled by Linux, accessing it in OP-TEE, OP-TEE will crash, secure data will not be leaked. So does clk really matters here? |
|
Yes, you won't leak data, but your OP-TEE and thus your device is not usable as well. |
There is no good method to avoid CCM module being hacked in Linux side, unless protect CCM in secure world, but this requires redesign Linux side clock driver... |
Currently, as @MrVan stated, the clk will not be managed by Linux. Off course as you have stated rightfuly it is subject to a DoS attack. Unfortunatly , the TEE is not design fot that. it rather guarantees data integrity, not cpu availability. |
|
Hello @jenswi-linaro ,
This is good alternative, we will look at this option. |
42fbdf6 to
ff16e81
Compare
|
|
||
| #ifdef CFG_DT_MODIFY | ||
| /* Ensure that CAAM Control is secure-status enabled */ | ||
| if (dt_set_secure_status(fdt, node)) { |
There was a problem hiding this comment.
dt_set_secure_status does not exist in this patch set nor in the OP-TEE master.
There was a problem hiding this comment.
Correct. This is why it's built only if the CFG_DT_MODIFY is define. This will require a specific patch to add this function. Do you agree to keep it for now while a new patch is submitterd?
There was a problem hiding this comment.
Either remove this function or add the implementation, this is up to you. However I think most of the dt modification functions contained in the HAL are general enough to be included in the OP-TEE core files instead of the CAAM hal.
9bf6bf4 to
6f9b125
Compare
|
Hello @jenswi-linaro I reworked the patch to add the function drvcrypt_hash_alloc_ctx() at the beginning of crypto_hash_alloc_ctx(). |
1a69871 to
cbf4c86
Compare
cbf4c86 to
7e044b4
Compare
|
Is an implementation of We have an implementation we have been using here which uses the CAAM to generate them, but ideally we would like to move completely to an upstream implementation rather than maintaining our partial CAAM driver. |
|
@jenswi-linaro, @etienne-lms, @jforissier Can I ask you if there is more comments on this PR? Do you approved it? Thanks and Regards, Cedric |
|
@cneveux, I'm not done yet I was just taking a break since @etienne-lms was bombarding you with comments. I'll resume again. By the way, often there's no notification when a PR is just force pushed, a comment is needed to to make sure that it's noticed. |
@jenswi-linaro |
|
@cneveux, thanks for letting me know. I hope you'll have a good vacation. I'll make sure there's some comments waiting for you when you're back. :-) |
9777694 to
1425ada
Compare
jenswi-linaro
left a comment
There was a problem hiding this comment.
Comments for the commit "core: driver: generic resources for crypto device driver"
| struct crypto_hash *hash_src = to_hash_ctx(src_ctx); | ||
| struct crypto_hash *hash_dst = to_hash_ctx(dst_ctx); | ||
|
|
||
| if (hash_src->op) |
There was a problem hiding this comment.
hash_src->op->copy_state isn't checked, does that mean that all the other functions are optional but this is mandatory?
There was a problem hiding this comment.
my mistake I missed it
| struct crypto_hash *hash = to_hash_ctx(ctx); | ||
|
|
||
| /* Check the parameters */ | ||
| if (hash->op) { |
There was a problem hiding this comment.
I'd prefer to write this as:
if (hash->op && hash->op->free_ctx)Do we really need to check these pointers? Aren't they required to be valid and we're just sanity checking here? If it's just sanity check I think an assert() would be more appropriate.
There was a problem hiding this comment.
The free operation in the driver is not mandatory. Hence the check of the pointer is needed to call the driver function.
| static TEE_Result hash_init(struct crypto_hash_ctx *ctx) | ||
| { | ||
| TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED; | ||
|
|
There was a problem hiding this comment.
Empty line not needed, same in hash_update() and hash_final() below.
| struct crypto_hash *hash = to_hash_ctx(ctx); | ||
|
|
||
| /* Check the parameters */ | ||
| if ((!data) && (len != 0)) |
There was a problem hiding this comment.
It's a matter of taste, but I would've written this as
if (!data && len)All the extra () are redundant, and the ones around !data disturbingly so.
| struct crypto_hash *hash = to_hash_ctx(ctx); | ||
|
|
||
| /* Check the parameters */ | ||
| if ((!digest) || (!len)) |
There was a problem hiding this comment.
Please drop the extra () so this becomes
if (!digest || !len)| TEE_Result (*update)(void *ctx, const uint8_t *data, size_t len); | ||
| /* Finalize the hashing operation */ | ||
| TEE_Result (*final)(void *ctx, uint8_t *digest, size_t len); | ||
|
|
There was a problem hiding this comment.
Empty line not needed.
| #include <drvcrypt.h> | ||
| #include <initcall.h> | ||
| #include <trace.h> | ||
|
|
There was a problem hiding this comment.
I'm not sure the interface implemented in this file is needed. It only seems safe to call during early boot, before exiting to normal world the first time. Type safety is lost. The caller of drvcrypt_getmod() must know the type of the point it gets. All this could be replaced by:
const struct drvcrypt_hash *drvcrypt_hash_ops;
const struct drvcrypt_mac *drvcrypt_mac_ops;
const struct drvcrypt_cipher *drvcrypt_cipher_ops;
...with retained type safety. Perhaps I'm missing something.
If you think it's important to keep this, do so. Once all the PRs are merged we can evaluate this again.
There was a problem hiding this comment.
This interface is to register to HW Driver module in the crypt_algo array. The registration is done during the HW Driver initialization function of the HW capabilities. To be generic and to prevent optional compilation per device type, we read HW registers to know if CAAM support or not the algorithm to register. If not, we keep NULL in the crypt_algo and so the HW driver is not called.
For sure you can not see to need with the HASH but for other operation it will be usefull
| /* | ||
| * Copyright 2018-2019 NXP | ||
| * | ||
| * Brief This driver interfaces TEE Internal API by implementing |
There was a problem hiding this comment.
"TEE Internal API" is an unfortunate wording as that's something different for us who have worked a bit with the GP APIs.
| */ | ||
| struct crypto_hash { | ||
| struct crypto_hash_ctx hash_ctx; /* Crypto Hash API context */ | ||
|
|
There was a problem hiding this comment.
Empty line not needed.
| * Format the HASH context to keep the reference to the | ||
| * operation driver | ||
| */ | ||
| struct crypto_hash { |
There was a problem hiding this comment.
Is this wrapper layer really needed? Is anything missing with struct crypto_hash_ctx which is stopping drivers/crypto/caam/hash/caam_hash.c from implementing a struct crypto_hash_ctx instead? Am I missing something?
There was a problem hiding this comment.
For sure, now it's no more needed as we reworked everything and removed the original checks. I can remove it but for the next crypto driver, I'll have the same structure and to be compliant I would prefer to keep this method. Now if you think that it will add complexity and overhead I can rework it to remove the struct drvcrypt_hash.
Please let me know.
There was a problem hiding this comment.
What do you mean by the next crypto driver? Compliant with what, in which context?
If it's only here for historical reasons I'd rather see it removed since it adds another level of indirection and makes it harder to follow the code.
There was a problem hiding this comment.
I mean the implementation for the Symmetric, Asymmetric and key derivation using the HW driver. There is the same wrapping operation structure used to reformat the crypto_xxx parameters in a data structure.
Anyway, for the Hash I'll remove it and we will see after for the others.
There was a problem hiding this comment.
I added a new commit (last one in the list) to the PR implementing this change. I'll squashed files after review and acceptance
jenswi-linaro
left a comment
There was a problem hiding this comment.
Some comments for the commit "core: driver: implementation NXP CAAM Driver"
| /* Return lower 32 bits of physical address */ | ||
| #define PHYS_ADDR_LO(phys_addr) (uint32_t)(((uint64_t)phys_addr) & UINT32_MAX) | ||
|
|
||
| uint32_t desc_get_len(uint32_t *desc) |
There was a problem hiding this comment.
This is a global symbol. I'd prefer if all global symbols had a common prefix, caam_ seems natural.
I think that in a driver it's more important to stick to a common prefix or two than in other places. This is not a big problem in OP-TEE currently, but as more and more drivers are added it could at least get confusing.
There was a problem hiding this comment.
I see your point. I'll add the prefix
| static uint32_t do_jr_dequeue(uint32_t waitJobIds) | ||
| { | ||
| uint32_t retJobId = 0; | ||
|
|
There was a problem hiding this comment.
Empty line not needed.
| #ifndef __CAAM_HAL_CLK_H__ | ||
| #define __CAAM_HAL_CLK_H__ | ||
|
|
||
| #include <stdlib.h> |
There was a problem hiding this comment.
Including <types_ext.h> would be a better choice.
| #ifndef __CAAM_HAL_CTRL_H__ | ||
| #define __CAAM_HAL_CTRL_H__ | ||
|
|
||
| #include <utee_defines.h> |
There was a problem hiding this comment.
Including <types_ext.h> would be a better choice.
| * | ||
| * @time Time in microsecond | ||
| */ | ||
| void caam_udelay(uint32_t time) |
There was a problem hiding this comment.
How about using udelay() instead?
There was a problem hiding this comment.
udelay() currently uses the core internal timer, which is not available on Cortex-A9 cores, i.e. i.MX6Q.
There was a problem hiding this comment.
Aha, missed that. Perhaps the platform should be able to override udelay(). Because this implementation doesn't seem very suitable for generic code.
There was a problem hiding this comment.
As this is specific to NXP CAAM driver I prefer to not change it and it will be reviewed later when we will finish the NXP i.MX implementation support for all device type (MX6/7/8).
|
There's quite a few cases of camel case in especially the commit "core: driver: implementation NXP CAAM Driver". |
|
There's quite a few new checkpatch warnings now that checkpatch is run with |
Add functions sev() and wfe() to implememt assembly instructions WFE/SEV. Signed-off-by: Cedric Neveux <[email protected]> Reviewed-by: Jens Wiklander <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Add registers to handle CAAM clocks Signed-off-by: Cedric Neveux <[email protected]> Acked-by: Jens Wiklander <[email protected]>
Add DT functions: dt_get_irq() get the interrupt number of a node dt_disable_status() disable the 'status' field of node's prop dt_enable_secure_status() set 'secure-status' field of node's prop and disable the 'status' field in the same time Signed-off-by: Cedric Neveux <[email protected]> Acked-by: Jens Wiklander <[email protected]>
This change moves the DT pack operation at the end of the generic boot, in release_external_dt(). This change allows any driver or initialization function to change the DT and get its content repacked before DT is accessed by another boot agent. Signed-off-by: Cedric Neveux <[email protected]> Acked-by: Jens Wiklander <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Add 32 and 64 bits little endian put/get functions Signed-off-by: Cedric Neveux <[email protected]> Reviewed-by: Etienne Carriere <[email protected]>
Add the read_ctr_el0 function in the arm64.h file Signed-off-by: Cedric Neveux <[email protected]> Reviewed-by: Jens Wiklander <[email protected]>
Add a generic cryptographic driver interface connecting TEE Crypto generic APIs to HW driver interface The Generic Crypto Driver interface in the core/driver/crypto/crypto_api is implemented to be able to use a HW driver. Signed-off-by: Cedric Neveux <[email protected]>
1327263 to
2095bff
Compare
Add the NXP CAAM drivers: - Random generator (instantiation and random generation) - Hash Signed-off-by: Cedric Neveux <[email protected]>
Remove the drvcrypt_hash ops structure to implement the crypto_hash_ctx operations into the specific HASH HW driver implementation. Signed-off-by: Cedric Neveux <[email protected]>
etienne-lms
left a comment
There was a problem hiding this comment.
comments for "core: driver: generic resources for crypto device driver".
| { | ||
| struct crypto_hash *hash = to_hash_ctx(ctx); | ||
|
|
||
| /* Check the parameters */ |
There was a problem hiding this comment.
can remove this comment
| * Copy Software Hashing Context | ||
| * | ||
| * @src_ctx Reference the API context source | ||
| * @dst_ctx [out] Reference the API context destination |
There was a problem hiding this comment.
swap lines (effective args ordering)
| TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED; | ||
| struct crypto_hash *hash = to_hash_ctx(ctx); | ||
|
|
||
| /* Check the parameters */ |
There was a problem hiding this comment.
remove comment
same for all /* Check the parameters */ in this file.
| * Finalize the Hash operation | ||
| * | ||
| * @ctx Reference the API context | ||
| * @len Digest buffer length |
There was a problem hiding this comment.
swap the 2 last lines.
| * @algo Algorithm | ||
| * @id [out] Hash Algorithm internal ID | ||
| */ | ||
| static struct drvcrypt_hash *do_check_algo(uint32_t algo, uint8_t *id) |
There was a problem hiding this comment.
suggest to move this below line 178, right above drvcrypt_hash_alloc_ctx().
| /* | ||
| * Cryptographic module registration | ||
| * | ||
| * @algo_id Crypto index in the array |
There was a problem hiding this comment.
could suggest a more agnostic way (I.e. "ID of the registered crypto algorithm")
| * Crypto Library Hash driver operations | ||
| */ | ||
| struct drvcrypt_hash { | ||
| /* Allocates of the Software context */ |
There was a problem hiding this comment.
s/of the/the/
Some suggested rephrasing:
"Allocate operation context"
"Free operation context"
"Initialize operation context"
"Update operation context"
"Finalize operation context"
"Copy operation context"
...or maybe even no inline comment.
| struct crypto_hash_ctx *src_ctx); | ||
| }; | ||
|
|
||
| #ifdef CFG_CRYPTO_DRIVER |
There was a problem hiding this comment.
Should be CFG_CRYPTO_DRV_HASH?
| /* | ||
| * Cryptographic buffer type | ||
| */ | ||
| struct drvcrypt_buf { |
| if (hash->op && hash->op->alloc_ctx) | ||
| ret = hash->op->alloc_ctx(&hash->ctx, hash_id); | ||
|
|
||
| if (ret != TEE_SUCCESS) { |
There was a problem hiding this comment.
If module has no alloc_ctx handler, this will fail with TEE_ERROR_NOT_IMPLEMENTED.
Could default init ret = TEE_SUCCESS;, or change a bit the code.
|
@cneveux, I suggest you create a P-R for the preliminary changes (all already reviewed) so that they can be merged:
Also minor comment regarding commit "core: driver: generic resources for crypto device driver ": |
And for the commits left perhaps also a new PR because it's quite slow to browse this PR now. |
|
As suggested, created a PR #3222 with:
|
Add the NXP CAAM drivers:
- Random generator (instantiation and random generation)
- Hash
Add a generic cryptographic driver interface connecting
TEE Crypto generic APIs to HW driver interface