core:driver implementation NXP CAAM Driver - RNG/HASH#3228
core:driver implementation NXP CAAM Driver - RNG/HASH#3228cneveux wants to merge 3 commits intoOP-TEE:masterfrom
Conversation
jenswi-linaro
left a comment
There was a problem hiding this comment.
Comments for the commit "core: driver: generic resources for crypto device driver"
With comment addressed:
Reviewed-by: Jens Wiklander <[email protected]>
| @@ -0,0 +1,47 @@ | |||
| // SPDX-License-Identifier: BSD-2-Clause | |||
There was a problem hiding this comment.
A separate directory for this file seems a bit too much. How about putting this file directly below crypto_api?
There was a problem hiding this comment.
May be but I'll classified all algorithms in a specific directory. For 2 raisons:
- it is easier to find files associated to the algorithms.
- it facilitate the build by including of not the directory.
At the end we will have following directories (at least):
- acipher (ECC/DH/RSA/DSA)
- cipher (AES/DES/DES3)
- hash (HASH)
- mac (HMAC/Cipher MAC/CMAC)
etienne-lms
left a comment
There was a problem hiding this comment.
some minor comments for "core: driver: generic resources for crypto device driver"
|
|
||
| /* | ||
| * Table of Cryptographic modules | ||
| */ |
There was a problem hiding this comment.
minor: remove the comment and init value { 0 } for crypt_algo[], implicit.
|
|
||
| CRYPTO_TRACE("hash alloc_ctx algo 0x%" PRIX32, algo); | ||
|
|
||
| /* Check the parameters */ |
| algo_id = TEE_ALG_GET_MAIN_ALG(algo); | ||
|
|
||
| if (algo_op == TEE_OPERATION_DIGEST && | ||
| (algo_id >= TEE_MAIN_ALGO_MD5 && algo_id <= TEE_MAIN_ALGO_SHA512)) |
There was a problem hiding this comment.
that's strange. in drvcrypt_hash_alloc_ctx() we do expect to handle a hashing operations, hence call the expected allocation handler. Why test here the algo/op?
| TEE_Result crypto_aes_gcm_alloc_ctx(struct crypto_authenc_ctx **ctx); | ||
|
|
||
| #ifdef CFG_CRYPTO_DRV_HASH | ||
| /* Cryptographic HASH driver context allocation */ |
| $(call force, CFG_JR_BLOCK_SIZE,0x1000) | ||
|
|
||
| $(call force, CFG_JR_INDEX,0) # Default JR index used | ||
| $(call force, CFG_JR_IRQ,137) # Default JR IT Number (105 + 32) = 137 |
There was a problem hiding this comment.
Since it's sometimes IRQ and sometimes FIQ in secure world I'd prefer calling it interrupt when being unspecific. When being more specific are secure interrupts called native interrupts and non-secure interrupts called foreign interrupts.
What's interesting from OP-TEE point of view is if OP-TEE itself will handle the interrupt or if it's to be forwarded.
There was a problem hiding this comment.
ok, as you want, renamed to CFG_JR_INT.
Point of view functional and security, we have to ensure that the Job Ring used into Secure side is not caught by Non-secure side. For that, as all secure interrupts on ARM are Secure FIQ, we configure the Job Ring interrupt to be secured FIQ. That way the non-secure can not enable/disable it and neither intercept it.
In case this interrupt is handled in the Non-secure, the crypto operation can be disturbed or hacked.
| { | ||
| TEE_Result retresult = TEE_ERROR_GENERIC; | ||
| enum CAAM_Status retstatus = CAAM_FAILURE; | ||
| struct caam_jrcfg jrcfg = { 0 }; |
There was a problem hiding this comment.
Structs are normally zero initialized as { }.
There was a problem hiding this comment.
It doesn't cost anything to write it { 0 } and it's more friendly to read ;)
| itr_disable(handler->it); | ||
|
|
||
| /* Send a signal to exit WFE loop */ | ||
| sev(); |
There was a problem hiding this comment.
the enqueue loop do_jr_enqueue.
The justification to switch the CPU in WFE is to reduce power consumption and to not overload HW by pulling register
| uint32_t *job_id) | ||
| { | ||
| enum CAAM_Status retstatus = CAAM_BUSY; | ||
|
|
There was a problem hiding this comment.
Empty line not needed.
| * also touching it | ||
| */ | ||
| cpu_spin_lock(&jr_privdata->callers_lock); | ||
| for ((idx_jr = 0), (found = false); |
There was a problem hiding this comment.
All these redundant () are a bit annoying, how about writing it as (relying on found already being false):
for (idx_jr = 0; idx_jr < jr_privdata->nb_jobs && !found; idx_jr++) {| * @job_ids Job Ids Mask | ||
| * @timeout_ms Timeout in millisecond | ||
| */ | ||
| enum CAAM_Status caam_jr_dequeue(uint32_t job_ids, uint32_t timeout_ms); |
There was a problem hiding this comment.
Could some other type than a fixed width type be used for timeout_ms, the 32-bit width seems rather arbitrary.
There was a problem hiding this comment.
Using a 8, 16 or 32 bits value will not change anything. At compilation the ARM register R1 (32 bits) will be used. Then as it's internal to the CAAM driver, the person calling this function is supposed to know what to do.
There was a problem hiding this comment.
Yes, but that's not the point, by the way there's 64-bit platforms to consider too.
With fixed width types you signal that you care about the specific properties of that type, how it overflows etc. At certain places it will stand out a bit.
You can keep it as it is if you think it's important.
There was a problem hiding this comment.
ok so is unsigned int timeout_ms better?
| * | ||
| * @nbentries Number of descriptor entries | ||
| */ | ||
| uint32_t *caam_alloc_desc(uint8_t nbentries); |
There was a problem hiding this comment.
Why the uint8_t type?
There was a problem hiding this comment.
The number of entry in a descriptor is limited to 64. Using 8 bits will limit the allocation buffer to 256 * 4 bytes even if it's too much.
There was a problem hiding this comment.
So if this function is called as caam_alloc_desc(258), it's OK to get a smaller allocation than expected? This doesn't seem right to me. Using size_t instead would be more robust.
There was a problem hiding this comment.
I would agree with you if the function was called dynamically and outside the CAAM driver which is not the case.
Here if the descriptor allocated is too small, the cryptographic operation is failing because the CAAM HW is not getting the correct descriptor and in plus there will be a buffer overflow because the driver filling the descriptor will write somewhere not allocated to it.
If such error raised after release it means that the developer didn't validate the work done which is a big fault.
Then size_t is really too big data variable in this particular case (size_t is generally a long int), don't you think?
If we want to be stronger, we have to add in any internal function parameters check which will be a mess.
| * Recalculate the pointer p address to start on a align modulus | ||
| * The p address is round up to the next offset (align modulus) | ||
| */ | ||
| static inline vaddr_t align_ptr(vaddr_t p, uint32_t align) |
There was a problem hiding this comment.
How about using ROUNDUP() instead?
| int caam_realloc_align(void *orig, struct caambuf *dst, size_t size) | ||
| { | ||
| enum teecore_memtypes mtype = MEM_AREA_MAXTYPE; | ||
| uint32_t isCached = false; |
There was a problem hiding this comment.
Please drop the camel case.
| */ | ||
| void caam_cache_op_sgt(enum utee_cache_operation op, struct caamsgtbuf *insgt) | ||
| { | ||
| uint8_t idx; |
There was a problem hiding this comment.
How about using unsigned int instead of a fixed width type?
Please initialize
c0791a7 to
ecd1e96
Compare
jenswi-linaro
left a comment
There was a problem hiding this comment.
More comments for the commit "core: driver: implementation NXP CAAM Driver"
| */ | ||
| uint32_t *caam_alloc_desc(uint8_t nbentries) | ||
| { | ||
| return mem_alloc(DESC_SZBYTES(nbentries), |
There was a problem hiding this comment.
Checking for overflow would be nice. It can't happen with a uint8_t, but with a size_t instead it would be possible to catch it.
There was a problem hiding this comment.
As explain I don't want to add the overflow check for this particular function which is intern to the NXP CAAM driver. Overflow must not raised because driver has to be validated before released and this function is not called with dynamic size.
|
|
||
| if (type & MEM_TYPE_ALIGN) { | ||
| cacheline_size = read_cacheline_size(); | ||
| alloc_size += ROUNDUP(alloc_size, cacheline_size); |
There was a problem hiding this comment.
alloc_size = ...
I think we should check for overflow also.
| * | Buffer | | ||
| * -------------- | ||
| */ | ||
| alloc_size = size + MEM_INFO_SIZE; |
There was a problem hiding this comment.
Check for overflow, with ADD_OVERFLOW() it would become:
if (ADD_OVERFLOW(size, MEM_INFO_SIZE, &alloc_res))
return NULL;| if (type & MEM_TYPE_ALIGN) { | ||
| /* | ||
| * In case of the buffer must be aligned on a cache | ||
| * ligne, ensure that the size is aligned on a cache line |
| * otherwise the total buffer size will be too small | ||
| */ | ||
| cacheline_size = read_cacheline_size(); | ||
| alloc_size += |
There was a problem hiding this comment.
I'd prefer avoiding the ternary operator here and use a classic if statement instead.
Need to check for overflow.
| cacheline_size = read_cacheline_size(); | ||
| alloc_size += | ||
| (alloc_size == cacheline_size) ? cacheline_size : 0; | ||
| alloc_size += ROUNDUP(alloc_size, cacheline_size); |
There was a problem hiding this comment.
alloc_size = ...
Need to check for overflow.
| * 1 if reallocation of the buffer | ||
| * (-1) if allocation error | ||
| */ | ||
| int caam_realloc_align(void *orig, struct caambuf *dst, size_t size) |
There was a problem hiding this comment.
The name of this function is a bit unfortunate, the "realloc" tricked me into thinking that it behaved somewhat like realloc(). How about "caam_init_or_alloc_align" or something like that instead.
There was a problem hiding this comment.
or rename to caam_set_or_alloc_align_buf
| uint8_t *data; /* Data buffer */ | ||
| paddr_t paddr; /* Physical address of the buffer */ | ||
| size_t length; /* Number of bytes in the data buffer */ | ||
| uint8_t nocache; /* =1 if buffer is not cacheable */ |
There was a problem hiding this comment.
Negative logic usually make it harder to understand the code. I'd prefer bool cached. Keep it as it is if you think it's important.
There was a problem hiding this comment.
Yes but I'll keep it as is for the simple reason that be default with the variable initialization at 0's the default nocache is as expected without adding a new code line to set the value.
4ee903e to
64ad3db
Compare
|
There's a bunch of comment under "hidden conversions" when I'm viewing this PR which seem to have been missed as they are not address or answered. |
etienne-lms
left a comment
There was a problem hiding this comment.
mainly minor comments
| TEE_Result drvcrypt_register(enum drvcrypt_algo_id algo_id, void *ops) | ||
| { | ||
| if (!crypt_algo[algo_id]) { | ||
| CRYPTO_TRACE("Registering module id %d with 0x%" PRIxPTR, |
There was a problem hiding this comment.
minor: replace "... %0x" PRIxPTR, ..., (uinptr_t)ops)
with "... %p", ..., ops)
Same at line 28, 41.
| /* | ||
| * Allocates the Software Hashing Context function of the algorithm | ||
| * and if the HW handles it. Else return on error and let the | ||
| * global cryptographic core module to call SW library enabled. |
There was a problem hiding this comment.
could simplify: "Allocate context for hashing operation if a drvcrypt hash driver if registered."
| * Modify the Cryptographic algorithm in the table of module | ||
| * | ||
| * @algo_id ID of the Cryptographic module | ||
| * @ops Reference to the cryptographic module |
There was a problem hiding this comment.
prefer use the same description as for drvcrypt_register().
| TEE_Result drvcrypt_register(enum drvcrypt_algo_id algo_id, void *ops); | ||
|
|
||
| /* | ||
| * Modify the Cryptographic algorithm in the table of module |
| CFG_MMAP_REGIONS ?= 24 | ||
|
|
||
| # Almost all platforms include CAAM HW Modules, except the | ||
| # one forced to be disabled |
| int caam_set_or_alloc_align_buf(void *orig, struct caambuf *dst, size_t size) | ||
| { | ||
| enum teecore_memtypes mtype = MEM_AREA_MAXTYPE; | ||
| uint32_t is_cached = false; |
| enum CAAM_Status caam_cpy_block_src(struct caamblock *block, | ||
| struct caambuf *src, size_t offset) | ||
| { | ||
| enum CAAM_Status ret; |
There was a problem hiding this comment.
default init value missing
| block->max); | ||
|
|
||
| cpy_size = block->max - block->filled; | ||
| cpy_size = MIN(cpy_size, (src->length - offset)); |
There was a problem hiding this comment.
minor: remove inner parentheses.
| unsigned int idx = 0; | ||
|
|
||
| cache_operation(TEE_CACHECLEAN, (void *)insgt->sgt, | ||
| (insgt->number * sizeof(struct caamsgt))); |
There was a problem hiding this comment.
minor: remove parentheses.
| TEE_Result job_status_to_tee_result(uint32_t status) | ||
| { | ||
| /* | ||
| * Add all status code that can be translate |
There was a problem hiding this comment.
s/translate/translated/
f5fca66 to
c4a2a1c
Compare
|
|
||
| #define MEM_TYPE_ZEROED BIT(0) | ||
| #define MEM_TYPE_NORMAL BIT(1) | ||
| #define MEM_TYPE_ALIGN BIT(2) |
There was a problem hiding this comment.
MEM_TYPE_NORMAL seems useless, or aybe lacks a description.
MEM_TYPE_ALIGN should be named MEM_TYPE_CACHE_ALIGN. (or maybe add an inline description comment stating it's about cache line alignment)
| * Crypto Library Algorithm enumeration | ||
| */ | ||
| enum drvcrypt_algo_id { | ||
| CRYPTO_HASH = 0, /* HASH driver */ |
| { | ||
| struct crypto_hash *hash = NULL; | ||
| struct hashdata *hashdata = NULL; | ||
| uint8_t algo = (hash_id - TEE_MAIN_ALGO_MD5); |
There was a problem hiding this comment.
minor: as Jens pointed, using uint8_t adds nothing but maybe few instructions to handle the single-byte format of the data. Suggest to replace with unsigned int.
Can remove parentheses.
| if (do_rng_read(&data, 1)) | ||
| return data; | ||
|
|
||
| return 0; |
There was a problem hiding this comment.
hazardous to return a deterministic value here. Suggest panic();
| * Allocate internal driver buffer aligned with a cache line | ||
| * | ||
| * @size size in bytes of the memory to allocate | ||
| * @buf [out] buffer allocated |
| * Allocate internal driver buffer and initialize it with 0s | ||
| * | ||
| * @size size in bytes of the memory to allocate | ||
| * @buf [out] buffer allocated |
| static inline void dump_desc(uint32_t *desc) | ||
| { | ||
| size_t idx; | ||
| size_t len; |
| #define CLASS_DECO 0x3 | ||
|
|
||
| #define CMD_SGT BIT32(24) | ||
| #define CMD_IMM BIT32(23) |
There was a problem hiding this comment.
prefer a space instead of 1st tab
| } | ||
|
|
||
| /* | ||
| * Registration of the HASH Driver |
There was a problem hiding this comment.
s/HASH Driver/hash driver/
Few other occurrences of HASH to lowercase in inline comments.
c4a2a1c to
63a3a41
Compare
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]> Reviewed-by: Jens Wiklander <[email protected]>
c73e55a to
947fbf3
Compare
|
All this force pushing and rebasing makes it harder than necessary to follow the changes you make. Unless rebasing and squashing in changes are needed to get a better view it should normally be avoided during the review. Instead you can push incremental changes which later are squashed in when the review is done. I'm sure you've noticed that pattern in other reviews we've done. I don't think I can help improving the commit "core: driver: implementation NXP CAAM Driver" much more now so please apply: |
947fbf3 to
a41d3b1
Compare
Add the NXP CAAM drivers: - Random generator (instantiation and random generation) - Hash Signed-off-by: Cedric Neveux <[email protected]> Acked-by: Jens Wiklander <[email protected]>
| #include <libfdt.h> | ||
|
|
||
| static const char *dt_ctrl_match_table = { | ||
| "fsl,sec-v4.0-ctrl", |
There was a problem hiding this comment.
This node is not found in any upstream device tree, breaking boot on any board with a mainline kernel and dt:
I/TC: OP-TEE version: 3.6.0-141-ga41d3b18 (gcc version 8.2.1 20181130 (OSELAS.Toolchain-2018.12.0 8-20181130)) #1 Fri Sep 6 07:31:41 UTC 2019 arm
D/TC:0 0 check_ta_store:638 TA store: "early TA"
D/TC:0 0 check_ta_store:638 TA store: "Secure Storage TA"
D/TC:0 0 check_ta_store:638 TA store: "REE [buffered]"
D/TC:0 0 early_ta_init:255 Early TA bc50d971-d4c9-42c4-82cb-343fb7f37896 size 632165 (compressed, uncompressed 1037980)
D/TC:0 0 mobj_mapped_shm_init:447 Shared memory address range: 4e400000, 50400000
E/TC:0 0 plat_rng_init:354 Warning: seeding RNG with zeroes
D/TC:0 0 imx_wdog_base:142 path: /soc/aips-bus@2000000/wdog@20bc000
E/TC:0 0 caam_hal_cfg_get_conf:79 Caam Node not found err = 0xFFFFFFFF
E/TC:0 0 crypto_driver_init:79 CAAM Driver initialization (0xffff000a)
E/TC:0 0 Panic at core/drivers/crypto/caam/caam_ctrl.c:80 <crypto_driver_init>
E/TC:0 0 Call stack:
E/TC:0 0 0x4e0056fd print_kernel_stack at /ptx/work/WORK_BEEMI/rcz/backup/git/trees/optee/imx6q/core/arch/arm/kernel/unwind_arm32.c:450
There was a problem hiding this comment.
You can find the linux version in Code Aurora
There was a problem hiding this comment.
My expectation was that an upstream OP-TEE works with an upstream kernel and does not require device-tree properties not documented anywhere.
There was a problem hiding this comment.
ok, I have to think how to deal with. I'll submit a new commit (thru a new PR) for that.
There was a problem hiding this comment.
IMO this is not the way forward here. Working platforms should still work after the PR is merged, so the necessary change should be included with the commit which introduces the dependency on the device tree node.
There was a problem hiding this comment.
I tend to agree with @Emantor on this, we should be very careful with DT bindings and specs, otherwise things will become unmanageable (I mean difficult to use and possibly inconsistent).
ff you could get the DT stuff and linux drivers to be accepted into upstream Linux at about the same time we accept the secure drivers here, that would be great.
Reminds me of how we dealt with the secure console binding (/secure-chosen/stdout-path). I first created a PR here, then proposed the binding to Linux. Rob H. made some suggestions and accepted the binding as long as I showed it was about to be used by OP-TEE and we were done.
|
@cneveux, I have gone again through the whole P-R, ending around 40 minor comments, hence at least a bunch of cleanup stuff, that actually could be postponed.
All in one, nothing harmful. I won't push straight these additional comments right now, not to put noise in this review. I understood you have other CAAM features waiting for this initial P-R to land. |
rework the hal_cfg.c and hal_cfg_dt.c file to ensure that either DTB configuration is used if defined or Hard coded configuration is used Signed-off-by: Cedric Neveux <[email protected]>
etienne-lms
left a comment
There was a problem hiding this comment.
Specifically for commit "[rework] CAAM Configuration with/without DTB file"
| return TEE_ERROR_NOT_IMPLEMENTED; | ||
| /* | ||
| * If a Cryptographic driver is supported, call first | ||
| * the driver's allocation function. If return no success |
There was a problem hiding this comment.
You should replace "no success" with something else.
I would propose to shorten the description: Use default crypto implement if no matching drvcrypt device.
I guess such comment illustrates why inline comment should be used only when implementation is not self sufficient.
| * | ||
| * @algo_id ID of the Cryptographic module | ||
| */ | ||
| void *drvcrypt_getmod(enum drvcrypt_algo_id algo_id) |
There was a problem hiding this comment.
suggest to rename drvcrypt_get_ops(). As per description referring to a operation ref.
(if agree, better do it now than once merged)
| typedef TEE_Result (*hw_hash_allocate)(struct crypto_hash_ctx **ctx, | ||
| uint8_t hash_id); | ||
|
|
||
| static inline TEE_Result drvcrypt_register_hash(hw_hash_allocate allocate) |
There was a problem hiding this comment.
Add description, as this a formal API of drvcrypt:
/*
* Register a hash processing driver in the crypto API
*
* @allocate - Callback for driver context allocation in the crypto layer
*/| * Crypto Library Hash driver allocation function prototype | ||
| */ | ||
| typedef TEE_Result (*hw_hash_allocate)(struct crypto_hash_ctx **ctx, | ||
| uint8_t hash_id); |
There was a problem hiding this comment.
I though hash_id here is not very explicit. Actually, you should move to there description from next commit in the series 947fbf3#diff-ceb9dd6899902415c951f995eddc5ce1R570.
I think the API should receive the full algo, not only the main algorithm. There is no strong reason the filter info. I guess other drvcrypt drivers will also get the full 32bit Algorithm Identifier.
|
|
||
| reg = io_caam_read32(baseaddr + RNG_STA); | ||
|
|
||
| return (((reg & RNG_STA_SKVN) == RNG_STA_SKVN) ? true : false); |
There was a problem hiding this comment.
return io_caam_read32(baseaddr + RNG_STA) & RNG_STA_SKVN: straight
| caam_hal_cfg_get_jobring_dt(void *fdt __unused, | ||
| struct caam_jrcfg *jrcfg __unused) | ||
| { | ||
| } |
There was a problem hiding this comment.
suggest memset(jrcfg, 0, sizeof(*jrcfg));
There was a problem hiding this comment.
only offset and it_num will be set to 0. one of the field (base) is already set.
| void caam_hal_cfg_get_jobring_dt(void *fdt, struct caam_jrcfg *jrcfg); | ||
|
|
||
| /* | ||
| * Disable the Job Ring used for the Secure environment into the DTB |
There was a problem hiding this comment.
maybe Disable the DT node related to the Job Ring used by secure world
Note this description comment is both in the .c and .h files, which is not convenient for maintenance.
| /* | ||
| * Returns the Job Ring configuration to be used by the TEE | ||
| * Finds the CAAM Controller definition in the DTB. | ||
| * If found, ensures it reserved for the Secure OS and disabled for the RichOS. |
There was a problem hiding this comment.
s/it/it is/
s/reserved/enabled/
There was a problem hiding this comment.
function will be removed
| /* | ||
| * Node is defined, check if the CAAM Controller is defined. If not | ||
| * use HW hard coded value | ||
| */ |
There was a problem hiding this comment.
I think this comment does not belong to this function.
There was a problem hiding this comment.
function will be removed
|
|
||
| /* | ||
| * Returns the Job Ring configuration to be used by the TEE | ||
| * Finds the CAAM Controller definition in the DTB. |
There was a problem hiding this comment.
prefer: Return the CAAM controller node found in the DTB.
There was a problem hiding this comment.
function will be removed
|
ooh! sorry. Pushing comments for "Specifically for commit "[rework] CAAM Configuration with/without DTB file" also pushed all my pending comments. Well... I guess it's a bit late now. Sorry for the noise. |
|
@cneveux, I suggest you push a P-R for the 1st commit: generic drvcrypt only. Should land quick. |
| ({ \ | ||
| __typeof__(size) _size = (size); \ | ||
| __typeof__(size) _sizeup = 0; \ | ||
| _sizeup = ROUNDUP(_size, align); \ |
There was a problem hiding this comment.
Please add a empty escaped line here:
__typeof__(size) _size = (size); \
__typeof__(size) _sizeup = 0; \
+ \
_sizeup = ROUNDUP(_size, align); \
|
|
||
| /* | ||
| * Allocate normal memory. | ||
| * Depending on the MEM_TYPE_DEFAULT value initialized it to 0's. |
There was a problem hiding this comment.
Well, that make sure not to change the API there caller really expects 0 init buffer.
|
|
||
| if ((size_topost) && (data)) { | ||
| struct caambuf indata = { .data = (uint8_t *)data, | ||
| .length = inlen }; |
| ({ \ | ||
| __typeof__(buf) _buf = (buf); \ | ||
| __typeof__(len) _len = (len); \ | ||
| DRV_TRACE("%s @0x%" PRIxPTR ": %zu", title, (uintptr_t)_buf, \ |
There was a problem hiding this comment.
coding style: add an empty escaped line between variable definition and instructions:
({ \
__typeof__(buf) _buf = (buf); \
__typeof__(len) _len = (len); \
+ \
DRV_TRACE("%s @0x%" PRIxPTR ": %zu", title, (uintptr_t)_buf, \|
Replace with PR #3259 |
Add the NXP CAAM drivers:
Add a generic cryptographic driver interface connecting
TEE Crypto generic APIs to HW driver interface