• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 Freescale Semiconductor, Inc.
3  * Copyright 2017 NXP
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <assert.h>
30 #include <lk/compiler.h>
31 #include <lk/reg.h>
32 #include <malloc.h>
33 #include <openssl/digest.h>
34 #include <openssl/hkdf.h>
35 #include <stddef.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/mman.h>
40 #include <trusty/sys/mman.h>
41 #include <uapi/err.h>
42 
43 #include <imx-regs.h>
44 #include "caam.h"
45 #include "fsl_caam_internal.h"
46 
47 #define TLOG_TAG "caam_drv"
48 #include <trusty_log.h>
49 
50 struct caam_job_rings {
51     uint32_t in[1];  /* single entry input ring */
52     uint32_t out[2]; /* single entry output ring (consists of two words) */
53 };
54 
55 /*
56  * According to CAAM docs max number of descriptors in single sequence is 64
57  * You can chain them though
58  */
59 #define MAX_DSC_NUM 64
60 
61 struct caam_job {
62     uint32_t dsc[MAX_DSC_NUM]; /* job descriptors */
63     uint32_t dsc_used;         /* number of filled entries */
64     uint32_t status;           /* job result */
65 };
66 
67 static struct caam_job_rings* g_rings;
68 static struct caam_job* g_job;
69 
70 const uint32_t rng_inst_dsc[] = {
71         RNG_INST_DESC1, RNG_INST_DESC2, RNG_INST_DESC3,
72         RNG_INST_DESC4, RNG_INST_DESC5, RNG_INST_DESC6,
73         RNG_INST_DESC7, RNG_INST_DESC8, RNG_INST_DESC9};
74 
75 #if WITH_CAAM_SELF_TEST
76 static void caam_test(void);
77 #endif
78 
caam_clk_get(void)79 static void caam_clk_get(void) {
80     uint32_t val;
81 
82     /* make sure clock is on */
83     val = readl(ccm_base + CCM_CAAM_CCGR_OFFSET);
84 #if defined(MACH_IMX6)
85     val |= (3 << 8) | (3 < 10) | (3 << 12);
86 #elif defined(MACH_IMX7)
87     val = (3 << 0); /* Always enabled (for now) */
88 #else
89 #error Unsupported IMX architecture
90 #endif
91     writel(val, ccm_base + CCM_CAAM_CCGR_OFFSET);
92 }
93 
setup_job_rings(void)94 static void setup_job_rings(void) {
95     int rc;
96     struct dma_pmem pmem;
97 
98     /* Initialize job ring addresses */
99     memset(g_rings, 0, sizeof(*g_rings));
100     rc = prepare_dma(g_rings, sizeof(g_rings), DMA_FLAG_TO_DEVICE, &pmem);
101     if (rc != 1) {
102         TLOGE("prepare_dma failed: %d\n", rc);
103         abort();
104     }
105 
106     writel((uint32_t)pmem.paddr + offsetof(struct caam_job_rings, in),
107            CAAM_IRBAR0);  // input ring address
108     writel((uint32_t)pmem.paddr + offsetof(struct caam_job_rings, out),
109            CAAM_ORBAR0);  // output ring address
110 
111     /* Initialize job ring sizes */
112     writel(countof(g_rings->in), CAAM_IRSR0);
113     writel(countof(g_rings->in), CAAM_ORSR0);
114 }
115 
run_job(struct caam_job * job)116 static void run_job(struct caam_job* job) {
117     int ret;
118     uint32_t job_pa;
119     struct dma_pmem pmem;
120 
121     /* prepare dma job */
122     ret = prepare_dma(job->dsc, job->dsc_used * sizeof(uint32_t),
123                       DMA_FLAG_TO_DEVICE, &pmem);
124     assert(ret == 1);
125     job_pa = (uint32_t)pmem.paddr;
126 
127     /* Add job to input ring */
128     g_rings->out[0] = 0;
129     g_rings->out[1] = 0;
130     g_rings->in[0] = job_pa;
131 
132     ret = prepare_dma(g_rings, sizeof(g_rings), DMA_FLAG_TO_DEVICE, &pmem);
133     assert(ret == 1);
134 
135     /* get clock */
136     caam_clk_get();
137 
138     /* start job */
139     writel(1, CAAM_IRJAR0);
140 
141     /* Wait for job ring to complete the job: 1 completed job expected */
142     while (readl(CAAM_ORSFR0) != 1)
143         ;
144 
145     finish_dma(g_rings->out, sizeof(g_rings->out), DMA_FLAG_FROM_DEVICE);
146 
147     /* check that descriptor address is the one expected in the out ring */
148     assert(g_rings->out[0] == job_pa);
149 
150     job->status = g_rings->out[1];
151 
152     /* remove job */
153     writel(1, CAAM_ORJRR0);
154 }
155 
init_caam_env(void)156 int init_caam_env(void) {
157     caam_base = mmap(NULL, CAAM_REG_SIZE, PROT_READ | PROT_WRITE,
158                      MMAP_FLAG_IO_HANDLE, CAAM_MMIO_ID, 0);
159     if (caam_base == MAP_FAILED) {
160         TLOGE("caam base mapping failed!\n");
161         return ERR_GENERIC;
162     }
163 
164     sram_base = mmap(NULL, CAAM_SEC_RAM_SIZE, PROT_READ | PROT_WRITE,
165                      MMAP_FLAG_IO_HANDLE, CAAM_SEC_RAM_MMIO_ID, 0);
166     if (sram_base == MAP_FAILED) {
167         TLOGE("caam secure ram base mapping failed!\n");
168         return ERR_GENERIC;
169     }
170 
171     ccm_base = mmap(NULL, CCM_REG_SIZE, PROT_READ | PROT_WRITE,
172                     MMAP_FLAG_IO_HANDLE, CCM_MMIO_ID, 0);
173     if (ccm_base == MAP_FAILED) {
174         TLOGE("ccm base mapping failed!\n");
175         return ERR_GENERIC;
176     }
177 
178     TLOGD("caam bases: %p, %p, %p\n", caam_base, sram_base, ccm_base);
179 
180     /* allocate rings */
181     assert(sizeof(struct caam_job_rings) <= 16); /* TODO handle alignment */
182     g_rings = memalign(16, sizeof(struct caam_job_rings));
183     if (!g_rings) {
184         TLOGE("out of memory allocating rings\n");
185         return ERR_NO_MEMORY;
186     }
187 
188     /* allocate jobs */
189     g_job = memalign(MAX_DSC_NUM * sizeof(uint32_t), sizeof(struct caam_job));
190     if (!g_job) {
191         TLOGE("out of memory allocating job\n");
192         return ERR_NO_MEMORY;
193     }
194 
195     caam_open();
196 #if WITH_CAAM_SELF_TEST
197     caam_test();
198 #endif
199 
200     return 0;
201 }
202 
caam_open(void)203 void caam_open(void) {
204     uint32_t temp_reg;
205 
206     /* switch on CAAM clock */
207     caam_clk_get();
208 
209     /* Initialize job ring addresses */
210     setup_job_rings();
211 
212     /* HAB disables interrupts for JR0 so do the same here */
213     temp_reg = readl(CAAM_JRCFGR0_LS) | JRCFG_LS_IMSK;
214     writel(temp_reg, CAAM_JRCFGR0_LS);
215 
216     /* if RNG already instantiated then skip it */
217     if ((readl(CAAM_RDSTA) & RDSTA_IF0) != RDSTA_IF0) {
218         /* Enter TRNG Program mode */
219         writel(RTMCTL_PGM, CAAM_RTMCTL);
220 
221         /* Set OSC_DIV field to TRNG */
222         temp_reg = readl(CAAM_RTMCTL) | (RNG_TRIM_OSC_DIV << 2);
223         writel(temp_reg, CAAM_RTMCTL);
224 
225         /* Set delay */
226         writel(((RNG_TRIM_ENT_DLY << 16) | 0x09C4), CAAM_RTSDCTL);
227         writel((RNG_TRIM_ENT_DLY >> 1), CAAM_RTFRQMIN);
228         writel((RNG_TRIM_ENT_DLY << 4), CAAM_RTFRQMAX);
229 
230         /* Resume TRNG Run mode */
231         temp_reg = readl(CAAM_RTMCTL) ^ RTMCTL_PGM;
232         writel(temp_reg, CAAM_RTMCTL);
233 
234         temp_reg = readl(CAAM_RTMCTL) | RTMCTL_ERR;
235         writel(temp_reg, CAAM_RTMCTL);
236 
237         /* init rng job */
238         assert(sizeof(rng_inst_dsc) <= sizeof(g_job->dsc));
239         memcpy(g_job->dsc, rng_inst_dsc, sizeof(rng_inst_dsc));
240         g_job->dsc_used = countof(rng_inst_dsc);
241 
242         run_job(g_job);
243 
244         if (g_job->status & JOB_RING_STS) {
245             TLOGE("job failed (0x%08x)\n", g_job->status);
246             abort();
247         }
248 
249         /* ensure that the RNG was correctly instantiated */
250         temp_reg = readl(CAAM_RDSTA);
251         if (temp_reg != (RDSTA_IF0 | RDSTA_SKVN)) {
252             TLOGE("Bad RNG state 0x%X\n", temp_reg);
253             abort();
254         }
255     }
256 
257     return;
258 }
259 
caam_decap_blob(const uint8_t * kmod,size_t kmod_size,uint8_t * plain,const uint8_t * blob,uint32_t size)260 uint32_t caam_decap_blob(const uint8_t* kmod,
261                          size_t kmod_size,
262                          uint8_t* plain,
263                          const uint8_t* blob,
264                          uint32_t size) {
265     int ret;
266     uint32_t kmod_pa;
267     uint32_t blob_pa;
268     uint32_t plain_pa;
269     struct dma_pmem pmem;
270 
271     assert(size + CAAM_KB_HEADER_LEN < 0xFFFFu);
272     assert(kmod_size == 16);
273 
274     ret = prepare_dma((void*)kmod, kmod_size, DMA_FLAG_TO_DEVICE, &pmem);
275     if (ret != 1) {
276         TLOGE("failed (%d) to prepare dma buffer\n", ret);
277         return CAAM_FAILURE;
278     }
279     kmod_pa = (uint32_t)pmem.paddr;
280 
281     ret = prepare_dma((void*)blob, size + CAAM_KB_HEADER_LEN,
282                       DMA_FLAG_TO_DEVICE, &pmem);
283     if (ret != 1) {
284         TLOGE("failed (%d) to prepare dma buffer\n", ret);
285         return CAAM_FAILURE;
286     }
287     blob_pa = (uint32_t)pmem.paddr;
288 
289     ret = prepare_dma((void*)plain, size, DMA_FLAG_FROM_DEVICE, &pmem);
290     if (ret != 1) {
291         TLOGE("failed (%d) to prepare dma buffer\n", ret);
292         return CAAM_FAILURE;
293     }
294     plain_pa = (uint32_t)pmem.paddr;
295 
296     g_job->dsc[0] = 0xB0800008;
297     g_job->dsc[1] = 0x14400010;
298     g_job->dsc[2] = kmod_pa;
299     g_job->dsc[3] = 0xF0000000 | (0x0000ffff & (size + CAAM_KB_HEADER_LEN));
300     g_job->dsc[4] = blob_pa;
301     g_job->dsc[5] = 0xF8000000 | (0x0000ffff & (size));
302     g_job->dsc[6] = plain_pa;
303     g_job->dsc[7] = 0x860D0000;
304     g_job->dsc_used = 8;
305 
306     run_job(g_job);
307 
308     if (g_job->status & JOB_RING_STS) {
309         TLOGE("job failed (0x%08x)\n", g_job->status);
310         return CAAM_FAILURE;
311     }
312 
313     finish_dma(plain, size, DMA_FLAG_FROM_DEVICE);
314     return CAAM_SUCCESS;
315 }
316 
caam_gen_blob(const uint8_t * kmod,size_t kmod_size,const uint8_t * plain,uint8_t * blob,uint32_t size)317 uint32_t caam_gen_blob(const uint8_t* kmod,
318                        size_t kmod_size,
319                        const uint8_t* plain,
320                        uint8_t* blob,
321                        uint32_t size) {
322     int ret;
323     uint32_t kmod_pa;
324     uint32_t blob_pa;
325     uint32_t plain_pa;
326     struct dma_pmem pmem;
327 
328     assert(size + CAAM_KB_HEADER_LEN < 0xFFFFu);
329     assert(kmod_size == 16);
330 
331     ret = prepare_dma((void*)kmod, kmod_size, DMA_FLAG_TO_DEVICE, &pmem);
332     if (ret != 1) {
333         TLOGE("failed (%d) to prepare dma buffer\n", ret);
334         return CAAM_FAILURE;
335     }
336     kmod_pa = (uint32_t)pmem.paddr;
337 
338     ret = prepare_dma((void*)plain, size, DMA_FLAG_TO_DEVICE, &pmem);
339     if (ret != 1) {
340         TLOGE("failed (%d) to prepare dma buffer\n", ret);
341         return CAAM_FAILURE;
342     }
343     plain_pa = (uint32_t)pmem.paddr;
344 
345     ret = prepare_dma((void*)blob, size + CAAM_KB_HEADER_LEN,
346                       DMA_FLAG_FROM_DEVICE, &pmem);
347     if (ret != 1) {
348         TLOGE("failed (%d) to prepare dma buffer\n", ret);
349         return CAAM_FAILURE;
350     }
351     blob_pa = (uint32_t)pmem.paddr;
352 
353     g_job->dsc[0] = 0xB0800008;
354     g_job->dsc[1] = 0x14400010;
355     g_job->dsc[2] = kmod_pa;
356     g_job->dsc[3] = 0xF0000000 | (0x0000ffff & (size));
357     g_job->dsc[4] = plain_pa;
358     g_job->dsc[5] = 0xF8000000 | (0x0000ffff & (size + CAAM_KB_HEADER_LEN));
359     g_job->dsc[6] = blob_pa;
360     g_job->dsc[7] = 0x870D0000;
361     g_job->dsc_used = 8;
362 
363     run_job(g_job);
364 
365     if (g_job->status & JOB_RING_STS) {
366         TLOGE("job failed (0x%08x)\n", g_job->status);
367         return CAAM_FAILURE;
368     }
369 
370     finish_dma(blob, size + CAAM_KB_HEADER_LEN, DMA_FLAG_FROM_DEVICE);
371     return CAAM_SUCCESS;
372 }
373 
caam_aes_op(const uint8_t * key,size_t key_size,const uint8_t * in,uint8_t * out,size_t len,bool enc)374 uint32_t caam_aes_op(const uint8_t* key,
375                      size_t key_size,
376                      const uint8_t* in,
377                      uint8_t* out,
378                      size_t len,
379                      bool enc) {
380     int ret;
381     uint32_t in_pa;
382     uint32_t out_pa;
383     uint32_t key_pa;
384     struct dma_pmem pmem;
385 
386     assert(key_size == 16);
387     assert(len <= 0xFFFFu);
388     assert(len % 16 == 0);
389 
390     ret = prepare_dma((void*)key, key_size, DMA_FLAG_TO_DEVICE, &pmem);
391     if (ret != 1) {
392         TLOGE("failed (%d) to prepare dma buffer\n", ret);
393         return CAAM_FAILURE;
394     }
395     key_pa = (uint32_t)pmem.paddr;
396 
397     ret = prepare_dma((void*)in, len, DMA_FLAG_TO_DEVICE, &pmem);
398     if (ret != 1) {
399         TLOGE("failed (%d) to prepare dma buffer\n", ret);
400         return CAAM_FAILURE;
401     }
402     in_pa = (uint32_t)pmem.paddr;
403 
404     ret = prepare_dma(out, len, DMA_FLAG_FROM_DEVICE, &pmem);
405     if (ret != 1) {
406         TLOGE("failed (%d) to prepare dma buffer\n", ret);
407         return CAAM_FAILURE;
408     }
409     out_pa = (uint32_t)pmem.paddr;
410 
411     /*
412      * Now AES key use aeskey.
413      * aeskey is derived from the first 16 bytes of RPMB key.
414      */
415     g_job->dsc[0] = 0xb0800008;
416     g_job->dsc[1] = 0x02000010;
417     g_job->dsc[2] = key_pa;
418     g_job->dsc[3] = enc ? 0x8210020D : 0x8210020C;
419     g_job->dsc[4] = 0x22120000 | (0x0000ffff & len);
420     g_job->dsc[5] = in_pa;
421     g_job->dsc[6] = 0x60300000 | (0x0000ffff & len);
422     g_job->dsc[7] = out_pa;
423     g_job->dsc_used = 8;
424 
425     run_job(g_job);
426 
427     if (g_job->status & JOB_RING_STS) {
428         TLOGE("job failed (0x%08x)\n", g_job->status);
429         return CAAM_FAILURE;
430     }
431 
432     finish_dma(out, len, DMA_FLAG_FROM_DEVICE);
433     return CAAM_SUCCESS;
434 }
435 
caam_hwrng(uint8_t * out,size_t len)436 uint32_t caam_hwrng(uint8_t* out, size_t len) {
437     int ret;
438     struct dma_pmem pmem;
439 
440     while (len) {
441         ret = prepare_dma(out, len,
442                           DMA_FLAG_FROM_DEVICE | DMA_FLAG_ALLOW_PARTIAL, &pmem);
443         if (ret != 1) {
444             TLOGE("failed (%d) to prepare dma buffer\n", ret);
445             return CAAM_FAILURE;
446         }
447 
448         g_job->dsc[0] = 0xB0800004;
449         g_job->dsc[1] = 0x82500000;
450         g_job->dsc[2] = 0x60340000 | (0x0000ffff & pmem.size);
451         g_job->dsc[3] = (uint32_t)pmem.paddr;
452         g_job->dsc_used = 4;
453 
454         run_job(g_job);
455 
456         if (g_job->status & JOB_RING_STS) {
457             TLOGE("job failed (0x%08x)\n", g_job->status);
458             return CAAM_FAILURE;
459         }
460 
461         finish_dma(out, pmem.size, DMA_FLAG_FROM_DEVICE);
462 
463         len -= pmem.size;
464         out += pmem.size;
465     }
466 
467     return CAAM_SUCCESS;
468 }
469 
caam_get_keybox(void)470 void* caam_get_keybox(void) {
471     return sram_base;
472 }
473 
caam_hash(uint8_t * in,uint8_t * out,uint32_t len)474 uint32_t caam_hash(uint8_t* in, uint8_t* out, uint32_t len) {
475     int ret;
476     uint32_t in_pa;
477     uint32_t out_pa;
478     struct dma_pmem pmem;
479 
480     assert(len <= 0xFFFFu);
481 
482     ret = prepare_dma((void*)in, len, DMA_FLAG_TO_DEVICE, &pmem);
483     if (ret != 1) {
484         TLOGE("failed (%d) to prepare dma buffer\n", ret);
485         return CAAM_FAILURE;
486     }
487     in_pa = (uint32_t)pmem.paddr;
488 
489     ret = prepare_dma(out, len, DMA_FLAG_FROM_DEVICE, &pmem);
490     if (ret != 1) {
491         TLOGE("failed (%d) to prepare dma buffer\n", ret);
492         return CAAM_FAILURE;
493     }
494     out_pa = (uint32_t)pmem.paddr;
495 
496     g_job->dsc[0] = 0xB0800006;
497     g_job->dsc[1] = 0x8441000D;
498     g_job->dsc[2] = 0x24140000 | (0x0000ffff & len);
499     g_job->dsc[3] = in_pa;
500     g_job->dsc[4] = 0x54200000 | 20;
501     g_job->dsc[5] = out_pa;
502     g_job->dsc_used = 6;
503 
504     run_job(g_job);
505 
506     if (g_job->status & JOB_RING_STS) {
507         TLOGE("job failed (0x%08x)\n", g_job->status);
508         return CAAM_FAILURE;
509     }
510 
511     finish_dma(out, len, DMA_FLAG_FROM_DEVICE);
512     return CAAM_SUCCESS;
513 }
514 
caam_gen_kdfv1_root_key(uint8_t * out,uint32_t size)515 uint32_t caam_gen_kdfv1_root_key(uint8_t* out, uint32_t size) {
516     int ret;
517     uint32_t pa;
518     struct dma_pmem pmem;
519 
520     assert(size == 32);
521 
522     ret = prepare_dma((void*)out, size, DMA_FLAG_FROM_DEVICE, &pmem);
523     if (ret != 1) {
524         TLOGE("failed (%d) to prepare dma buffer\n", ret);
525         return CAAM_FAILURE;
526     }
527     pa = (uint32_t)pmem.paddr;
528 
529     /*
530      * This sequence uses caam blob generation protocol in
531      * master key verification mode to generate unique for device
532      * persistent 256-bit sequence that we will be using a root key
533      * for our key derivation function v1. This is the only known way
534      * on this platform of producing persistent unique device key that
535      * does not require persistent storage. Dsc[2..5] effectively contains
536      * 16 bytes of randomly generated salt that gets mixed (among other
537      * things) with device master key to produce result.
538      */
539     g_job->dsc[0] = 0xB080000B;
540     g_job->dsc[1] = 0x14C00010;
541     g_job->dsc[2] = 0x7083A393; /* salt word 0 */
542     g_job->dsc[3] = 0x2CC0C9F7; /* salt word 1 */
543     g_job->dsc[4] = 0xFC5D2FC0; /* salt word 2 */
544     g_job->dsc[5] = 0x2C4B04E7; /* salt word 3 */
545     g_job->dsc[6] = 0xF0000000;
546     g_job->dsc[7] = 0;
547     g_job->dsc[8] = 0xF8000030;
548     g_job->dsc[9] = pa;
549     g_job->dsc[10] = 0x870D0002;
550     g_job->dsc_used = 11;
551 
552     run_job(g_job);
553 
554     if (g_job->status & JOB_RING_STS) {
555         TLOGE("job failed (0x%08x)\n", g_job->status);
556         return CAAM_FAILURE;
557     }
558 
559     finish_dma(out, size, DMA_FLAG_FROM_DEVICE);
560     return CAAM_SUCCESS;
561 }
562 
563 #if WITH_CAAM_SELF_TEST
564 
565 /*
566  * HWRNG
567  */
caam_hwrng_test(void)568 static void caam_hwrng_test(void) {
569     DECLARE_SG_SAFE_BUF(out1, 32);
570     DECLARE_SG_SAFE_BUF(out2, 32);
571 
572     caam_hwrng(out1, sizeof(out1));
573     caam_hwrng(out2, sizeof(out2));
574 
575     if (memcmp(out1, out2, sizeof(out1)) == 0)
576         TLOGI("caam hwrng test FAILED!!!\n");
577     else
578         TLOGI("caam hwrng test PASS!!!\n");
579 }
580 
581 /*
582  * Blob
583  */
caam_blob_test(void)584 static void caam_blob_test(void) {
585     uint i = 0;
586     DECLARE_SG_SAFE_BUF(keymd, 16);
587     DECLARE_SG_SAFE_BUF(plain, 32);
588     DECLARE_SG_SAFE_BUF(plain_bak, 32);
589     DECLARE_SG_SAFE_BUF(blob, 128);
590 
591     /* generate random key mod */
592     caam_hwrng(keymd, sizeof(keymd));
593 
594     /* build known input */
595     for (i = 0; i < sizeof(plain); i++) {
596         plain[i] = i + '0';
597         plain_bak[i] = plain[i];
598     }
599 
600     /* encap  blob */
601     caam_gen_blob(keymd, 16, plain, blob, sizeof(plain));
602     memset(plain, 0xff, sizeof(plain));
603 
604     /* decap blob */
605     caam_decap_blob(keymd, 16, plain, blob, sizeof(plain));
606 
607     /* compare with original */
608     if (memcmp(plain, plain_bak, sizeof(plain)))
609         TLOGI("caam blob test FAILED!!!\n");
610     else
611         TLOGI("caam blob test PASS!!!\n");
612 }
613 
614 /*
615  *  AES
616  */
caam_aes_test(void)617 static void caam_aes_test(void) {
618     DECLARE_SG_SAFE_BUF(key, 16);
619     DECLARE_SG_SAFE_BUF(buf1, 32);
620     DECLARE_SG_SAFE_BUF(buf2, 32);
621     DECLARE_SG_SAFE_BUF(buf3, 32);
622 
623     /* generate random key */
624     caam_hwrng(key, sizeof(key));
625 
626     /* create input */
627     for (uint i = 0; i < sizeof(buf1); i++) {
628         buf1[i] = i + '0';
629     }
630 
631     /* reset output */
632     memset(buf2, 0x55, sizeof(buf2));
633     memset(buf3, 0xAA, sizeof(buf3));
634 
635     /* encrypt same data twice */
636     caam_aes_op(key, 16, buf1, buf2, sizeof(buf1), true);
637     caam_aes_op(key, 16, buf1, buf3, sizeof(buf1), true);
638 
639     /* compare results */
640     if (memcmp(buf2, buf3, sizeof(buf1)))
641         TLOGI("caam AES enc test FAILED!!!\n");
642     else
643         TLOGI("caam AES enc test PASS!!!\n");
644 
645     /* decrypt res */
646     caam_aes_op(key, 16, buf3, buf2, sizeof(buf3), false);
647 
648     /* compare with original */
649     if (memcmp(buf1, buf2, sizeof(buf1)))
650         TLOGI("caam AES enc test FAILED!!!\n");
651     else
652         TLOGI("caam AES enc test PASS!!!\n");
653 }
654 
655 /*
656  * HASH (SHA-1)
657  */
caam_hash_test(void)658 static void caam_hash_test(void) {
659     DECLARE_SG_SAFE_BUF(in, 32);
660     DECLARE_SG_SAFE_BUF(hash1, 32);
661     DECLARE_SG_SAFE_BUF(hash2, 32);
662 
663     /* generate input */
664     for (uint i = 0; i < sizeof(in); i++) {
665         in[i] = i + '1';
666     }
667 
668     /* reset output */
669     memset(hash1, 0x55, sizeof(hash1));
670     memset(hash2, 0xAA, sizeof(hash2));
671 
672     /* invoke hash twice */
673     caam_hash(in, hash1, sizeof(in));
674     caam_hash(in, hash2, sizeof(in));
675 
676     /* compare results */
677     if (memcmp(hash1, hash2, 20) != 0)
678         TLOGI("caam hash test FAILED!!!\n");
679     else
680         TLOGI("caam hash test PASS!!!\n");
681 }
682 
caam_kdfv1_root_key_test(void)683 static void caam_kdfv1_root_key_test(void) {
684     DECLARE_SG_SAFE_BUF(out1, 32);
685     DECLARE_SG_SAFE_BUF(out2, 32);
686 
687     caam_gen_kdfv1_root_key(out1, 32);
688     caam_gen_kdfv1_root_key(out2, 32);
689 
690     if (memcmp(out1, out2, 32) != 0)
691         TLOGI("caam gen kdf root key test FAILED!!!\n");
692     else
693         TLOGI("caam gen kdf root key test PASS!!!\n");
694 }
695 
caam_test(void)696 static void caam_test(void) {
697     caam_hwrng_test();
698     caam_blob_test();
699     caam_kdfv1_root_key_test();
700     caam_aes_test();
701     caam_hash_test();
702 }
703 
704 #endif /* WITH_CAAM_SELF_TEST */
705