1 /* caam_qnx.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <wolfssl/wolfcrypt/settings.h>
27
28 #if defined(__QNX__) || defined(__QNXNTO__)
29
30 #include <wolfssl/wolfcrypt/port/caam/caam_driver.h>
31 #include <wolfssl/version.h>
32
33 #include <errno.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include <pthread.h>
39 #include <sys/iofunc.h>
40 #include <sys/dispatch.h>
41 #include <sys/neutrino.h>
42 #include <sys/resmgr.h>
43 #include <devctl.h>
44
45 /* virtual address for accessing CAAM addresses */
46 uintptr_t virtual_base = 0;
47
48 /* keep track of which ID memory belongs to so it can be free'd up */
49 #define MAX_PART 7
50 pthread_mutex_t sm_mutex;
51 CAAM_ADDRESS sm_ownerId[MAX_PART];
52
53 /* variables for I/O of resource manager */
54 resmgr_connect_funcs_t connect_funcs;
55 resmgr_io_funcs_t io_funcs;
56 dispatch_t *dpp;
57 resmgr_attr_t rattr;
58 dispatch_context_t *ctp;
59 iofunc_attr_t ioattr;
60
61 int io_devctl (resmgr_context_t *ctp, io_devctl_t *msg, iofunc_ocb_t *ocb);
62 int io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle,
63 void *extra);
64 int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb);
65 int io_write(resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb);
66 int io_close_ocb(resmgr_context_t *ctp, void *reserved, RESMGR_OCB_T *ocb);
67
68
69 /* read the contents at offset from BASE address */
CAAM_READ(unsigned int ofst)70 unsigned int CAAM_READ(unsigned int ofst) {
71 return in32(virtual_base + ofst);
72 }
73
74
75 /* takes in offset from BASE address */
CAAM_WRITE(unsigned int ofst,unsigned int in)76 void CAAM_WRITE(unsigned int ofst, unsigned int in)
77 {
78 out32(virtual_base + ofst, in);
79 }
80
81
82 /* Sets the base address to use for read/write
83 * returns 0 on success
84 */
CAAM_SET_BASEADDR()85 int CAAM_SET_BASEADDR()
86 {
87 /* address range for CAAM is CAAM_BASE plus 0x10000 */
88 virtual_base = mmap_device_io(0x00010000, CAAM_BASE);
89 if (virtual_base == (uintptr_t)MAP_FAILED) {
90 WOLFSSL_MSG("Unable to map virtual memory");
91 return -1;
92 }
93 return 0;
94 }
95
96
97 /* cleans up having set the base address */
CAAM_UNSET_BASEADDR()98 void CAAM_UNSET_BASEADDR()
99 {
100 munmap_device_io(virtual_base, 0x00010000);
101 }
102
103 /* convert a virtual address to a physical address
104 * returns the physical address on success
105 */
CAAM_ADR_TO_PHYSICAL(void * in,int inSz)106 CAAM_ADDRESS CAAM_ADR_TO_PHYSICAL(void* in, int inSz)
107 {
108 off64_t ofst = 0;
109 int ret, count = 0;;
110
111 if (in == NULL)
112 return 0;
113
114 if (inSz == 0)
115 inSz = 1;
116
117 do {
118 ret = mem_offset64(in, NOFD, inSz, &ofst, NULL);
119 if (ret != 0) {
120 WOLFSSL_MSG("posix offset failed");
121 #if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
122 perror("posix offset failed : ");
123 #endif
124 }
125 msync(in, inSz, MS_INVALIDATE);
126 count++;
127 } while (ret != 0 && ret == -1 && count < 5);
128
129 return (CAAM_ADDRESS)ofst;
130 }
131
132
133 /* convert a physical address to virtual address
134 * returns the virtual address on success
135 */
CAAM_ADR_TO_VIRTUAL(CAAM_ADDRESS in,int len)136 CAAM_ADDRESS CAAM_ADR_TO_VIRTUAL(CAAM_ADDRESS in, int len)
137 {
138 void* ret;
139 ret = mmap_device_memory(NULL, len, PROT_READ | PROT_WRITE | PROT_NOCACHE,
140 0, in);
141 return (CAAM_ADDRESS)ret;
142 }
143
144
145 /* map a virtual address to a created coherent physical address
146 * returns the mapped address on success
147 */
CAAM_ADR_MAP(unsigned int in,int inSz,unsigned char copy)148 void* CAAM_ADR_MAP(unsigned int in, int inSz, unsigned char copy)
149 {
150 int sz;
151 void *vaddr;
152
153 sz = inSz;
154 if (inSz == 0) {
155 sz = 1;
156 }
157
158 vaddr = mmap(NULL, sz, PROT_READ | PROT_WRITE | PROT_NOCACHE,
159 MAP_PHYS | MAP_SHARED | MAP_ANON, NOFD, 0);
160 if (vaddr == MAP_FAILED) {
161 WOLFSSL_MSG("Failed to map memory");
162 #if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
163 perror("Failed to map memory : ");
164 #endif
165 }
166 else {
167 if (copy && in != 0 && inSz > 0) {
168 memcpy((unsigned char*)vaddr, (unsigned char*)in, inSz);
169 }
170
171 if (msync(vaddr, sz, MS_SYNC) != 0) {
172 WOLFSSL_MSG("Failed to sync memory after copy");
173 }
174 }
175 return vaddr;
176 }
177
178
179 /* un map address, should be called when done with a mapped address */
CAAM_ADR_UNMAP(void * vaddr,unsigned int out,int outSz,unsigned char copy)180 void CAAM_ADR_UNMAP(void* vaddr, unsigned int out, int outSz,
181 unsigned char copy)
182 {
183 int sz;
184
185 sz = outSz;
186 if (outSz == 0)
187 sz = 1;
188
189 if (msync(vaddr, sz, MS_SYNC) != 0) {
190 #if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
191 perror("Failed to sync output");
192 #endif
193 /* even though the address was not synced up still try to copy and
194 unmap it */
195 }
196
197 if (copy && out != 0 && outSz > 0) {
198 memcpy((unsigned char*)out, (unsigned char*)vaddr, outSz);
199 }
200 munmap(vaddr, sz);
201 }
202
203
204 /* synchronize virtual buffer with physical
205 * return 0 on success */
CAAM_ADR_SYNC(void * vaddr,int sz)206 int CAAM_ADR_SYNC(void* vaddr, int sz)
207 {
208 if (msync(vaddr, sz, MS_SYNC) != 0) {
209 #if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
210 perror("address sync failed");
211 #endif
212 return -1;
213 }
214 return 0;
215 }
216
217
218 /* macros for QNX devctl commands */
219 #define WC_TRNG_CMD __DIOTF(_DCMD_ALL, CAAM_ENTROPY, iov_t)
220 #define WC_CAAM_GET_PART __DIOTF(_DCMD_ALL, CAAM_GET_PART, iov_t)
221 #define WC_CAAM_FREE_PART __DIOT(_DCMD_ALL, CAAM_FREE_PART, iov_t)
222 #define WC_CAAM_FIND_PART __DIOTF(_DCMD_ALL, CAAM_FIND_PART, iov_t)
223 #define WC_CAAM_READ_PART __DIOTF(_DCMD_ALL, CAAM_READ_PART, iov_t)
224 #define WC_CAAM_WRITE_PART __DIOT(_DCMD_ALL, CAAM_WRITE_PART, iov_t)
225
226 #define WC_CAAM_ECDSA_KEYPAIR __DIOTF(_DCMD_ALL, CAAM_ECDSA_KEYPAIR, iov_t)
227 #define WC_CAAM_ECDSA_VERIFY __DIOT(_DCMD_ALL, CAAM_ECDSA_VERIFY, iov_t)
228 #define WC_CAAM_ECDSA_SIGN __DIOTF(_DCMD_ALL, CAAM_ECDSA_SIGN, iov_t)
229 #define WC_CAAM_ECDSA_ECDH __DIOTF(_DCMD_ALL, CAAM_ECDSA_ECDH, iov_t)
230
231 #define WC_CAAM_BLOB_ENCAP __DIOTF(_DCMD_ALL, CAAM_BLOB_ENCAP, iov_t)
232 #define WC_CAAM_BLOB_DECAP __DIOTF(_DCMD_ALL, CAAM_BLOB_DECAP, iov_t)
233
234 #define WC_CAAM_CMAC __DIOTF(_DCMD_ALL, CAAM_CMAC, iov_t)
235
236 #define WC_CAAM_FIFO_S __DIOTF(_DCMD_ALL, CAAM_FIFO_S, iov_t)
237
238
239 /* partAddr is virtual address
240 * partSz size expected to access
241 *
242 * returns 0 on ok
243 */
sanityCheckPartitionAddress(CAAM_ADDRESS partAddr,int partSz)244 static int sanityCheckPartitionAddress(CAAM_ADDRESS partAddr, int partSz)
245 {
246 if (partAddr < CAAM_PAGE || partAddr > CAAM_PAGE * MAX_PART ||
247 partSz > 4096) {
248 WOLFSSL_MSG("error in physical address range");
249 return -1;
250 }
251 return 0;
252 }
253
254
255 /* return 0 on success */
getArgs(unsigned int args[4],resmgr_context_t * ctp,io_devctl_t * msg,unsigned int * idx,unsigned int maxIdx)256 static int getArgs(unsigned int args[4], resmgr_context_t *ctp, io_devctl_t *msg,
257 unsigned int *idx, unsigned int maxIdx)
258 {
259 int expectedSz;
260 iov_t in_iov;
261
262 expectedSz = sizeof(unsigned int) * 4;
263 if (*idx + expectedSz > maxIdx) {
264 WOLFSSL_MSG("not enough for arguments");
265 return -1;
266 }
267
268 SETIOV(&in_iov, args, expectedSz);
269 if (resmgr_msgreadv(ctp, &in_iov, 1, *idx) != expectedSz) {
270 WOLFSSL_MSG("unexpected msg size read");
271 return -1;
272 }
273 *idx += expectedSz;
274 return 0;
275 }
276
277
278 /* helper function to setup and run CMAC operation
279 * returns EOK on success
280 */
doCMAC(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx)281 static int doCMAC(resmgr_context_t *ctp, io_devctl_t *msg, unsigned int args[4],
282 unsigned int idx)
283 {
284 DESCSTRUCT desc;
285 CAAM_BUFFER tmp[3];
286 iov_t in_iovs[3], out_iov;
287
288 int msgSz = 0, ret, numBuf, keySz;
289 unsigned char ctx[32]; /* running CMAC context is a constant 32 bytes */
290 unsigned char keybuf[32 + BLACK_KEY_MAC_SZ];/*max AES key size is 32 + MAC*/
291 unsigned char *buf = NULL;
292
293 numBuf = 2; /* start with 2 (key + ctx) for case with no msg input */
294 keySz = args[1];
295 if (args[2] == 1) { /* is it a black key? */
296 keySz = keySz + BLACK_KEY_MAC_SZ;
297 }
298 SETIOV(&in_iovs[0], keybuf, keySz);
299 SETIOV(&in_iovs[1], ctx, sizeof(ctx));
300 msgSz = args[3];
301 if (msgSz < 0) {
302 WOLFSSL_MSG("CMAC msg size was a negative value");
303 return EBADMSG;
304 }
305
306 if (msgSz > 0) {
307 buf = (unsigned char*)CAAM_ADR_MAP(0, msgSz, 0);
308 if (buf == NULL) {
309 return ECANCELED;
310 }
311 SETIOV(&in_iovs[2], buf, msgSz);
312 numBuf = numBuf + 1; /* increase buffer size by one when adding msg */
313 }
314
315 ret = resmgr_msgreadv(ctp, in_iovs, numBuf, idx);
316 if (ret < (msgSz + keySz + sizeof(ctx))) {
317 /* sanity check that enough data was sent */
318 if (buf != NULL)
319 CAAM_ADR_UNMAP(buf, 0, msgSz, 0);
320 return EOVERFLOW;
321 }
322
323 tmp[0].TheAddress = (CAAM_ADDRESS)keybuf;
324 tmp[0].Length = args[1];
325
326 tmp[1].TheAddress = (CAAM_ADDRESS)ctx;
327 tmp[1].Length = sizeof(ctx);
328
329 if (msgSz > 0) {
330 tmp[2].TheAddress = (CAAM_ADDRESS)buf;
331 tmp[2].Length = msgSz;
332 }
333 caamDescInit(&desc, CAAM_CMAC, args, tmp, numBuf);
334 ret = caamAesCmac(&desc, numBuf, args);
335 if (msgSz > 0) {
336 if (buf != NULL)
337 CAAM_ADR_UNMAP(buf, 0, msgSz, 0);
338 }
339
340 if (ret != Success) {
341 return EBADMSG;
342 }
343 SETIOV(&out_iov, ctx, sizeof(ctx));
344
345 /* extra sanity check that out buffer is large enough */
346 if (sizeof(ctx) > msg->o.nbytes) {
347 return EOVERFLOW;
348 }
349 ret = resmgr_msgwritev(ctp, &out_iov, 1, sizeof(msg->o));
350 if (ret < 0) {
351 return ECANCELED;
352 }
353
354 return EOK;
355 }
356
357
358 /* helper function to setup and run TRNG operation
359 * returns EOK on success
360 */
doTRNG(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx)361 static int doTRNG(resmgr_context_t *ctp, io_devctl_t *msg, unsigned int args[4],
362 unsigned int idx)
363 {
364 int length, ret;
365 unsigned char *buf;
366 iov_t out_iov;
367
368 length = args[0];
369
370 /* sanity check that length out is not over the edge */
371 if (length > msg->o.nbytes) {
372 WOLFSSL_MSG("Length too large for TRNG out size available");
373 return EOVERFLOW;
374 }
375
376 if (length > 0) {
377 buf = (unsigned char*)CAAM_ADR_MAP(0, length, 0);
378 if (buf == NULL) {
379 return ECANCELED;
380 }
381
382 ret = caamTRNG(buf, length);
383 if (ret == CAAM_WAITING) {
384 /* waiting for more entropy */
385 CAAM_ADR_UNMAP(buf, 0, length, 0);
386 return EAGAIN;
387 }
388
389 SETIOV(&out_iov, buf, length);
390 ret = resmgr_msgwritev(ctp, &out_iov, 1, sizeof(msg->o));
391 CAAM_ADR_UNMAP(buf, 0, length, 0);
392 if (ret < 0) {
393 return ECANCELED;
394 }
395 }
396 return EOK;
397 }
398
399
400 /* helper function to setup and run BLOB operation
401 * returns EOK on success
402 */
doBLOB(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx)403 static int doBLOB(resmgr_context_t *ctp, io_devctl_t *msg, unsigned int args[4],
404 unsigned int idx)
405 {
406 int WC_CAAM_BLOB_SZ = 48; /* extra blob size from manual */
407 int dir, ret, inSz, outSz;
408 DESCSTRUCT desc;
409 CAAM_BUFFER tmp[3];
410 iov_t in_iovs[2], out_iov;
411
412 unsigned char *inBuf, *outBuf;
413 unsigned char keymod[BLACK_BLOB_KEYMOD_SZ];
414 /* 16 is max size for keymod (8 with red blobs and 16 with black) */
415
416 if (msg->i.dcmd == WC_CAAM_BLOB_ENCAP) {
417 dir = CAAM_BLOB_ENCAP;
418 }
419 else {
420 dir = CAAM_BLOB_DECAP;
421 }
422
423 inSz = args[2];
424 if (inSz < 0) {
425 return EBADMSG;
426 }
427
428 if (args[0] == 1 && dir == CAAM_BLOB_ENCAP) {
429 inSz = inSz + BLACK_KEY_MAC_SZ;
430 }
431
432 SETIOV(&in_iovs[0], keymod, args[3]);
433 if ((inSz + args[3]) > (ctp->size - idx)) {
434 return EOVERFLOW;
435 }
436
437 inBuf = (unsigned char*)CAAM_ADR_MAP(0, inSz, 0);
438 if (inBuf == NULL) {
439 return ECANCELED;
440 }
441 SETIOV(&in_iovs[1], inBuf, inSz);
442 ret = resmgr_msgreadv(ctp, in_iovs, 2, idx);
443 if (ret < inSz + args[3]) {
444 return EBADMSG;
445 }
446
447 /* key mod */
448 tmp[0].TheAddress = (CAAM_ADDRESS)keymod;
449 tmp[0].Length = args[3];
450
451 /* input */
452 tmp[1].TheAddress = (CAAM_ADDRESS)inBuf;
453 tmp[1].Length = args[2];
454
455 /* output */
456 outSz = args[2];
457 if (msg->i.dcmd == WC_CAAM_BLOB_ENCAP) {
458 outSz = outSz + WC_CAAM_BLOB_SZ;
459 }
460 else {
461 outSz = outSz - WC_CAAM_BLOB_SZ;
462 }
463 if (outSz < 0) {
464 return EBADMSG;
465 }
466
467 if (args[0] == 1 && dir == CAAM_BLOB_DECAP) {
468 outBuf = (unsigned char*)CAAM_ADR_MAP(0, outSz + BLACK_KEY_MAC_SZ, 0);
469 }
470 else {
471 outBuf = (unsigned char*)CAAM_ADR_MAP(0, outSz, 0);
472 }
473 if (outBuf == NULL) {
474 CAAM_ADR_UNMAP(inBuf, 0, inSz, 0);
475 return ECANCELED;
476 }
477 tmp[2].TheAddress = (CAAM_ADDRESS)outBuf;
478 tmp[2].Length = outSz;
479
480 caamDescInit(&desc, dir, args, tmp, 3);
481 ret = caamBlob(&desc);
482 CAAM_ADR_UNMAP(inBuf, 0, inSz, 0);
483
484 /* adjust outSz for MAC tag at the end of black key */
485 if (args[0] == 1 && dir == CAAM_BLOB_DECAP) {
486 outSz = outSz + BLACK_KEY_MAC_SZ;
487 }
488
489 if (ret != Success) {
490 CAAM_ADR_UNMAP(outBuf, 0, outSz, 0);
491 return ECANCELED;
492 }
493
494 CAAM_ADR_SYNC(outBuf, outSz);
495 SETIOV(&out_iov, outBuf, outSz);
496 if (outSz > msg->o.nbytes) {
497 CAAM_ADR_UNMAP(outBuf, 0, outSz, 0);
498 return EOVERFLOW;
499 }
500 ret = resmgr_msgwritev(ctp, &out_iov, 1, sizeof(msg->o));
501 CAAM_ADR_UNMAP(outBuf, 0, outSz, 0);
502 if (ret < 0) {
503 return ECANCELED;
504 }
505 return EOK;
506 }
507
508
509 /* helper function to setup and make ECC key
510 * returns EOK on success
511 */
doECDSA_KEYPAIR(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx,iofunc_ocb_t * ocb)512 static int doECDSA_KEYPAIR(resmgr_context_t *ctp, io_devctl_t *msg, unsigned int args[4],
513 unsigned int idx, iofunc_ocb_t *ocb)
514 {
515 int ret;
516 DESCSTRUCT desc;
517 CAAM_BUFFER tmp[2];
518 iov_t in_iovs[2], out_iovs[3];
519
520 SETIOV(&in_iovs[0], &tmp[0], sizeof(CAAM_BUFFER));
521 SETIOV(&in_iovs[1], &tmp[1], sizeof(CAAM_BUFFER));
522 ret = resmgr_msgreadv(ctp, in_iovs, 2, idx);
523
524 caamDescInit(&desc, CAAM_ECDSA_KEYPAIR, args, tmp, 2);
525 ret = caamECDSAMake(&desc, tmp, args);
526 if (ret != Success) {
527 return ECANCELED;
528 }
529
530 SETIOV(&out_iovs[0], &tmp[0], sizeof(CAAM_BUFFER));
531 SETIOV(&out_iovs[1], &tmp[1], sizeof(CAAM_BUFFER));
532 SETIOV(&out_iovs[2], args, sizeof(int) * 4);
533 ret = resmgr_msgwritev(ctp, &out_iovs[0], 3, sizeof(msg->o));
534 if (ret < 0) {
535 return ECANCELED;
536 }
537
538 /* claim ownership of a secure memory location */
539 pthread_mutex_lock(&sm_mutex);
540 sm_ownerId[args[2]] = (CAAM_ADDRESS)ocb;
541 pthread_mutex_unlock(&sm_mutex);
542
543 return EOK;
544 }
545
546
547 /* helper function to setup and do ECC verify
548 * returns EOK on success
549 */
doECDSA_VERIFY(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx)550 static int doECDSA_VERIFY(resmgr_context_t *ctp, io_devctl_t *msg,
551 unsigned int args[4], unsigned int idx)
552 {
553 DESCSTRUCT desc;
554 CAAM_BUFFER tmp[5];
555 iov_t in_iovs[4];
556 int ret, pubSz;
557
558 unsigned char *hash, *pubkey = NULL, *r, *s;
559 CAAM_ADDRESS securePub;
560
561 if (args[0] == 1) {
562 pubSz = sizeof(CAAM_ADDRESS);
563
564 SETIOV(&in_iovs[0], &securePub, sizeof(CAAM_ADDRESS));
565 }
566 else {
567 pubSz = args[3]*2;
568 pubkey = (unsigned char*)CAAM_ADR_MAP(0, pubSz, 0);
569 if (pubkey == NULL) {
570 return ECANCELED;
571 }
572
573 SETIOV(&in_iovs[0], pubkey, args[3]*2);
574 }
575
576 hash = (unsigned char*)CAAM_ADR_MAP(0, args[2], 0);
577 if (hash == NULL) {
578 if (pubkey != NULL)
579 CAAM_ADR_UNMAP(pubkey, 0, pubSz, 0);
580 return ECANCELED;
581 }
582 SETIOV(&in_iovs[1], hash, args[2]);
583
584 r = (unsigned char*)CAAM_ADR_MAP(0, args[3], 0);
585 if (r == NULL) {
586 if (pubkey != NULL)
587 CAAM_ADR_UNMAP(pubkey, 0, pubSz, 0);
588 CAAM_ADR_UNMAP(hash, 0, args[2], 0);
589 return ECANCELED;
590 }
591 SETIOV(&in_iovs[2], r, args[3]);
592
593 s = (unsigned char*)CAAM_ADR_MAP(0, args[3], 0);
594 if (s == NULL) {
595 if (pubkey != NULL)
596 CAAM_ADR_UNMAP(pubkey, 0, pubSz, 0);
597 CAAM_ADR_UNMAP(hash, 0, args[2], 0);
598 CAAM_ADR_UNMAP(r, 0, args[3], 0);
599 return ECANCELED;
600 }
601 SETIOV(&in_iovs[3], s, args[3]);
602
603 ret = resmgr_msgreadv(ctp, in_iovs, 4, idx);
604 if (((args[3] * 2) + args[2] + pubSz) > ret) {
605 if (pubkey != NULL)
606 CAAM_ADR_UNMAP(pubkey, 0, pubSz, 0);
607 CAAM_ADR_UNMAP(hash, 0, args[2], 0);
608 CAAM_ADR_UNMAP(r, 0, args[3], 0);
609 CAAM_ADR_UNMAP(s, 0, args[3], 0);
610 return EOVERFLOW;
611 }
612
613 /* setup CAAM buffers to pass to driver */
614 if (args[0] == 1) {
615 tmp[0].TheAddress = securePub;
616 }
617 else {
618 tmp[0].TheAddress = (CAAM_ADDRESS)pubkey;
619 }
620 tmp[0].Length = args[3]*2;
621
622 tmp[1].TheAddress = (CAAM_ADDRESS)hash;
623 tmp[1].Length = args[2];
624
625 tmp[2].TheAddress = (CAAM_ADDRESS)r;
626 tmp[2].Length = args[3];
627
628 tmp[3].TheAddress = (CAAM_ADDRESS)s;
629 tmp[3].Length = args[3];
630
631 if (pubkey != NULL)
632 CAAM_ADR_SYNC(pubkey, pubSz);
633 CAAM_ADR_SYNC(hash, args[2]);
634 CAAM_ADR_SYNC(r, args[3]);
635 CAAM_ADR_SYNC(s, args[3]);
636 caamDescInit(&desc, CAAM_ECDSA_VERIFY, args, tmp, 4);
637 ret = caamECDSAVerify(&desc, tmp, 4, args);
638
639 /* free all buffers before inspecting the return value */
640 CAAM_ADR_UNMAP(hash, 0, args[2], 0);
641 CAAM_ADR_UNMAP(r, 0, args[3], 0);
642 CAAM_ADR_UNMAP(s, 0, args[3], 0);
643 if (pubkey != NULL)
644 CAAM_ADR_UNMAP(pubkey, 0, pubSz, 0);
645
646 if (ret != Success) {
647 return EBADMSG;
648 }
649 return EOK;
650 }
651
652
653 /* helper function to setup and do ECC sign
654 * returns EOK on success
655 */
doECDSA_SIGN(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx)656 static int doECDSA_SIGN(resmgr_context_t *ctp, io_devctl_t *msg,
657 unsigned int args[4], unsigned int idx)
658 {
659 int ret, keySz;
660 DESCSTRUCT desc;
661 CAAM_BUFFER tmp[4];
662
663 unsigned char *key = NULL, *hash, *r, *s;
664 CAAM_ADDRESS blackKey;
665
666 iov_t in_iovs[2], out_iovs[2];
667
668 if (args[0] == 1) {
669 keySz = sizeof(CAAM_ADDRESS);
670 SETIOV(&in_iovs[0], &blackKey, sizeof(CAAM_ADDRESS));
671 }
672 else {
673 keySz = args[3];
674 key = (unsigned char*)CAAM_ADR_MAP(0, keySz, 0);
675 if (key == NULL) {
676 return ECANCELED;
677 }
678 SETIOV(&in_iovs[0], key, keySz);
679 }
680
681 hash = (unsigned char*)CAAM_ADR_MAP(0, args[2], 0);
682 if (hash == NULL) {
683 if (key != NULL)
684 CAAM_ADR_UNMAP(key, 0, keySz, 0);
685 return ECANCELED;
686 }
687 SETIOV(&in_iovs[1], hash, args[2]);
688 ret = resmgr_msgreadv(ctp, in_iovs, 2, idx);
689 if ((keySz + args[2]) > ret) {
690 CAAM_ADR_UNMAP(hash, 0, args[2], 0);
691 if (key != NULL)
692 CAAM_ADR_UNMAP(key, 0, keySz, 0);
693 return EOVERFLOW;
694 }
695
696
697 /* setup CAAM buffers to pass to driver */
698 if (args[0] == 1) {
699 tmp[0].TheAddress = blackKey;
700 }
701 else {
702 tmp[0].TheAddress = (CAAM_ADDRESS)key;
703 }
704 tmp[0].Length = args[3];
705
706 tmp[1].TheAddress = (CAAM_ADDRESS)hash;
707 tmp[1].Length = args[2];
708
709 r = (unsigned char*)CAAM_ADR_MAP(0, args[3], 0);
710 if (r == NULL) {
711 CAAM_ADR_UNMAP(hash, 0, args[2], 0);
712 if (key != NULL)
713 CAAM_ADR_UNMAP(key, 0, keySz, 0);
714 return ECANCELED;
715 }
716 tmp[2].TheAddress = (CAAM_ADDRESS)r;
717 tmp[2].Length = args[3];
718
719 s = (unsigned char*)CAAM_ADR_MAP(0, args[3], 0);
720 if (s == NULL) {
721 CAAM_ADR_UNMAP(r, 0, args[3], 0);
722 CAAM_ADR_UNMAP(hash, 0, args[2], 0);
723 if (key != NULL)
724 CAAM_ADR_UNMAP(key, 0, keySz, 0);
725 return ECANCELED;
726 }
727 tmp[3].TheAddress = (CAAM_ADDRESS)s;
728 tmp[3].Length = args[3];
729
730 caamDescInit(&desc, CAAM_ECDSA_SIGN, args, tmp, 4);
731 ret = caamECDSASign(&desc, 4, args);
732 CAAM_ADR_UNMAP(hash, 0, args[2], 0);
733 if (key != NULL)
734 CAAM_ADR_UNMAP(key, 0, keySz, 0);
735 if (ret != Success) {
736 CAAM_ADR_UNMAP(s, 0, args[3], 0);
737 CAAM_ADR_UNMAP(r, 0, args[3], 0);
738 return EBADMSG;
739 }
740
741 if ((args[3] * 2) > msg->o.nbytes) {
742 CAAM_ADR_UNMAP(s, 0, args[3], 0);
743 CAAM_ADR_UNMAP(r, 0, args[3], 0);
744 return EOVERFLOW;
745 }
746
747 CAAM_ADR_SYNC(r, args[3]);
748 CAAM_ADR_SYNC(s, args[3]);
749 SETIOV(&out_iovs[0], r, args[3]);
750 SETIOV(&out_iovs[1], s, args[3]);
751
752 ret = resmgr_msgwritev(ctp, &out_iovs[0], 2, sizeof(msg->o));
753 CAAM_ADR_UNMAP(s, 0, args[3], 0);
754 CAAM_ADR_UNMAP(r, 0, args[3], 0);
755 if (ret < 0) {
756 return ECANCELED;
757 }
758 return EOK;
759 }
760
761
762 /* helper function to setup and get an ECC shared secret
763 * returns EOK on success
764 */
doECDSA_ECDH(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx)765 static int doECDSA_ECDH(resmgr_context_t *ctp, io_devctl_t *msg,
766 unsigned int args[4], unsigned int idx)
767 {
768 int ret;
769 DESCSTRUCT desc;
770 CAAM_BUFFER tmp[3];
771 int expectedSz = 0;
772 iov_t in_iovs[2], out_iov;
773
774 unsigned char *pubkey = NULL, *key = NULL, *shared;
775 CAAM_ADDRESS securePub, blackKey;
776
777 /* when using memory in secure partition just send the address */
778 if (args[1] == 1) {
779 SETIOV(&in_iovs[0], &securePub, sizeof(CAAM_ADDRESS));
780 expectedSz += sizeof(CAAM_ADDRESS);
781 }
782 else {
783 pubkey = (unsigned char*)CAAM_ADR_MAP(0, args[3]*2, 0);
784 if (pubkey == NULL) {
785 return ECANCELED;
786 }
787
788 SETIOV(&in_iovs[0], pubkey, args[3]*2);
789 expectedSz += args[3]*2;
790 }
791
792 if (args[0] == 1) {
793 SETIOV(&in_iovs[1], &blackKey, sizeof(CAAM_ADDRESS));
794 expectedSz += sizeof(CAAM_ADDRESS);
795 }
796 else {
797 key = (unsigned char*)CAAM_ADR_MAP(0, args[3], 0);
798 if (key == NULL) {
799 if (pubkey != NULL)
800 CAAM_ADR_UNMAP(pubkey, 0, args[3]*2, 0);
801 return ECANCELED;
802 }
803
804 SETIOV(&in_iovs[1], key, args[3]);
805 expectedSz += args[3];
806 }
807
808 ret = resmgr_msgreadv(ctp, in_iovs, 2, idx);
809 if (expectedSz > ret) {
810 if (pubkey != NULL)
811 CAAM_ADR_UNMAP(pubkey, 0, args[3]*2, 0);
812 if (key != NULL)
813 CAAM_ADR_UNMAP(key, 0, args[3], 0);
814 return ECANCELED;
815 }
816
817 /* setup CAAM buffers to pass to driver */
818 if (args[1] == 1) {
819 tmp[0].TheAddress = securePub;
820 }
821 else {
822 tmp[0].TheAddress = (CAAM_ADDRESS)pubkey;
823 }
824 tmp[0].Length = args[3]*2;
825
826 if (args[0] == 1) {
827 tmp[1].TheAddress = blackKey;
828 }
829 else {
830 tmp[1].TheAddress = (CAAM_ADDRESS)key;
831 }
832 tmp[1].Length = args[3];
833
834 shared = (unsigned char*)CAAM_ADR_MAP(0, args[3], 0);
835 if (shared == NULL) {
836 if (pubkey != NULL)
837 CAAM_ADR_UNMAP(pubkey, 0, args[3]*2, 0);
838 if (key != NULL)
839 CAAM_ADR_UNMAP(key, 0, args[3], 0);
840 return ECANCELED;
841 }
842
843 tmp[2].TheAddress = (CAAM_ADDRESS)shared;
844 tmp[2].Length = args[3];
845 caamDescInit(&desc, CAAM_ECDSA_ECDH, args, tmp, 3);
846 ret = caamECDSA_ECDH(&desc, 3, args);
847 if (pubkey != NULL)
848 CAAM_ADR_UNMAP(pubkey, 0, args[3]*2, 0);
849 if (key != NULL)
850 CAAM_ADR_UNMAP(key, 0, args[3], 0);
851
852 if (ret != Success) {
853 CAAM_ADR_UNMAP(shared, 0, args[3], 0);
854 return EBADMSG;
855 }
856
857 if (args[3] > msg->o.nbytes) {
858 CAAM_ADR_UNMAP(shared, 0, args[3], 0);
859 return EOVERFLOW;
860 }
861 CAAM_ADR_SYNC(shared, args[3]);
862 SETIOV(&out_iov, shared, args[3]);
863 resmgr_msgwritev(ctp, &out_iov, 1, sizeof(msg->o));
864 CAAM_ADR_UNMAP(shared, 0, args[3], 0);
865 return EOK;
866 }
867
868
869 /* helper function to setup and cover data
870 * returns EOK on success
871 */
doFIFO_S(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx)872 static int doFIFO_S(resmgr_context_t *ctp, io_devctl_t *msg,
873 unsigned int args[4], unsigned int idx)
874 {
875 int ret;
876 DESCSTRUCT desc;
877 CAAM_BUFFER tmp[2];
878 iov_t in_iov, out_iov;
879 unsigned char *inBuf, *outBuf;
880
881 inBuf = (unsigned char*)CAAM_ADR_MAP(0, args[1], 0);
882 if (inBuf == NULL) {
883 return ECANCELED;
884 }
885
886 SETIOV(&in_iov, inBuf, args[1]);
887 ret = resmgr_msgreadv(ctp, &in_iov, 1, idx);
888 if (ret < args[1]) {
889 return EBADMSG;
890 }
891
892 outBuf = (unsigned char*)CAAM_ADR_MAP(0, args[1] + BLACK_KEY_MAC_SZ, 0);
893 if (outBuf == NULL) {
894 CAAM_ADR_UNMAP(inBuf, 0, args[1], 0);
895 return ECANCELED;
896 }
897
898 tmp[0].TheAddress = (CAAM_ADDRESS)inBuf;
899 tmp[0].Length = args[1];
900 tmp[1].TheAddress = (CAAM_ADDRESS)outBuf;
901 tmp[1].Length = args[1]; /* tmp1 actually needs an additional 16 bytes
902 * for MAC */
903
904 caamDescInit(&desc, CAAM_FIFO_S, args, tmp, 2);
905 ret = caamKeyCover(&desc, 2, args);
906 CAAM_ADR_UNMAP(inBuf, 0, args[1], 0);
907 if (ret != Success) {
908 CAAM_ADR_UNMAP(outBuf, 0, args[1] + BLACK_KEY_MAC_SZ, 0);
909 return EBADMSG;
910 }
911
912 if (args[1] + BLACK_KEY_MAC_SZ > msg->o.nbytes) {
913 CAAM_ADR_UNMAP(outBuf, 0, args[1] + BLACK_KEY_MAC_SZ, 0);
914 WOLFSSL_MSG("would cause output buffer overflow");
915 return EOVERFLOW;
916 }
917
918 SETIOV(&out_iov, outBuf, args[1] + BLACK_KEY_MAC_SZ);
919 resmgr_msgwritev(ctp, &out_iov, 1, sizeof(msg->o));
920 CAAM_ADR_UNMAP(outBuf, 0, args[1] + BLACK_KEY_MAC_SZ, 0);
921 return EOK;
922 }
923
924
925 /* helper function to get partition
926 * returns EOK on success
927 */
doGET_PART(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx,iofunc_ocb_t * ocb)928 static int doGET_PART(resmgr_context_t *ctp, io_devctl_t *msg,
929 unsigned int args[4], unsigned int idx, iofunc_ocb_t *ocb)
930 {
931 int partNumber;
932 int partSz;
933 CAAM_ADDRESS partAddr;
934 iov_t out_iov;
935
936 partNumber = args[0];
937 partSz = args[1];
938
939 partAddr = caamGetPartition(partNumber, partSz, 0);
940 if (partAddr == 0) {
941 return EBADMSG;
942 }
943
944 SETIOV(&out_iov, &partAddr, sizeof(CAAM_ADDRESS));
945 resmgr_msgwritev(ctp, &out_iov, 1, sizeof(msg->o));
946
947 pthread_mutex_lock(&sm_mutex);
948 sm_ownerId[partNumber] = (CAAM_ADDRESS)ocb;
949 pthread_mutex_unlock(&sm_mutex);
950 return EOK;
951 }
952
953
954 /* helper function to write to a partition
955 * returns EOK on success
956 */
doWRITE_PART(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx)957 static int doWRITE_PART(resmgr_context_t *ctp, io_devctl_t *msg,
958 unsigned int args[4], unsigned int idx)
959 {
960 int partSz, ret;
961 CAAM_ADDRESS partAddr;
962 CAAM_ADDRESS vaddr;
963 unsigned char *buf;
964 iov_t in_iov;
965
966 /* get arguments */
967 partAddr = args[0];
968 partSz = args[1];
969
970 buf = (unsigned char*)CAAM_ADR_MAP(0, partSz, 0);
971 if (buf == NULL) {
972 return ECANCELED;
973 }
974
975 SETIOV(&in_iov, buf, partSz);
976 ret = resmgr_msgreadv(ctp, &in_iov, 1, idx);
977 if (ret != partSz) {
978 CAAM_ADR_UNMAP(buf, 0, partSz, 0);
979 return EBADMSG;
980 }
981
982 /* sanity check on address and length */
983 if (sanityCheckPartitionAddress(partAddr, partSz) != 0) {
984 CAAM_ADR_UNMAP(buf, 0, partSz, 0);
985 return EBADMSG;
986 }
987
988 vaddr = CAAM_ADR_TO_VIRTUAL(partAddr, partSz);
989 if (vaddr == 0) {
990 CAAM_ADR_UNMAP(buf, 0, partSz, 0);
991 return ECANCELED;
992 }
993
994 CAAM_ADR_UNMAP(buf, vaddr, partSz, 1);
995 CAAM_ADR_UNMAP((void*)vaddr, 0, partSz, 0);
996 return EOK;
997 }
998
999
1000 /* helper function to read a partition
1001 * returns EOK on success
1002 */
doREAD_PART(resmgr_context_t * ctp,io_devctl_t * msg,unsigned int args[4],unsigned int idx)1003 static int doREAD_PART(resmgr_context_t *ctp, io_devctl_t *msg,
1004 unsigned int args[4], unsigned int idx)
1005 {
1006 int partSz;
1007 CAAM_ADDRESS partAddr;
1008 CAAM_ADDRESS vaddr;
1009 unsigned char *buf;
1010 iov_t out_iov;
1011
1012 /* get arguments */
1013 partAddr = args[0];
1014 partSz = args[1];
1015
1016 if (partSz > msg->o.nbytes) {
1017 WOLFSSL_MSG("not enough space to store read bytes");
1018 return EOVERFLOW;
1019 }
1020
1021 /* sanity check on address and length */
1022 if (sanityCheckPartitionAddress(partAddr, partSz) != 0) {
1023 return EBADMSG;
1024 }
1025
1026 buf = (unsigned char*)CAAM_ADR_MAP(0, partSz, 0);
1027 if (buf == NULL) {
1028 return ECANCELED;
1029 }
1030
1031 vaddr = CAAM_ADR_TO_VIRTUAL(partAddr, partSz);
1032 if (vaddr == 0) {
1033 CAAM_ADR_UNMAP(buf, 0, partSz, 0);
1034 return ECANCELED;
1035 }
1036
1037 memcpy(buf, (unsigned char*)vaddr, partSz);
1038 SETIOV(&out_iov, buf, partSz);
1039 resmgr_msgwritev(ctp, &out_iov, 1, sizeof(msg->o));
1040 CAAM_ADR_UNMAP(buf, 0, partSz, 0);
1041 CAAM_ADR_UNMAP((void*)vaddr, 0, partSz, 0);
1042 return EOK;
1043 }
1044
1045
io_devctl(resmgr_context_t * ctp,io_devctl_t * msg,iofunc_ocb_t * ocb)1046 int io_devctl (resmgr_context_t *ctp, io_devctl_t *msg, iofunc_ocb_t *ocb)
1047 {
1048 int ret = EBADMSG;
1049 unsigned int idx = sizeof(msg->i);
1050 unsigned int args[4];
1051 iov_t out_iov;
1052
1053 /* check if at least got the msg header */
1054 if( ctp->size < sizeof(msg->i) ) {
1055 return EBADMSG;
1056 }
1057
1058 if ((ret = iofunc_devctl_default (ctp, msg, ocb)) != _RESMGR_DEFAULT) {
1059 return ret;
1060 }
1061
1062 /* check callers access rights for read/write */
1063 if ((ret = iofunc_devctl_verify(ctp, msg, ocb,
1064 _IO_DEVCTL_VERIFY_OCB_READ | _IO_DEVCTL_VERIFY_OCB_WRITE))
1065 != EOK) {
1066 WOLFSSL_MSG("issue verify devctl");
1067 return ret;
1068 }
1069 /* _IO_DEVCTL_VERIFY_PRIV : restrict to root */
1070 /* _IO_DEVCTL_VERIFY_ACC_ISUID : restrict to owner of device */
1071 /* _IO_DEVCTL_VERIFY_ACC_ISGID : restrict to group permissions */
1072
1073 if (getArgs(args, ctp, msg, &idx, ctp->size) != 0) {
1074 WOLFSSL_MSG("issue reading arguments");
1075 return EBADMSG;
1076 }
1077
1078 switch (msg->i.dcmd) {
1079 case WC_CAAM_CMAC:
1080 ret = doCMAC(ctp, msg, args, idx);
1081 break;
1082
1083 case WC_TRNG_CMD:
1084 ret = doTRNG(ctp, msg, args, idx);
1085 break;
1086
1087 case WC_CAAM_BLOB_ENCAP:
1088 case WC_CAAM_BLOB_DECAP:
1089 ret = doBLOB(ctp, msg, args, idx);
1090 break;
1091
1092 case WC_CAAM_ECDSA_KEYPAIR:
1093 ret = doECDSA_KEYPAIR(ctp, msg, args, idx, ocb);
1094 break;
1095
1096 case WC_CAAM_ECDSA_VERIFY:
1097 ret = doECDSA_VERIFY(ctp, msg, args, idx);
1098 break;
1099
1100 case WC_CAAM_ECDSA_SIGN:
1101 ret = doECDSA_SIGN(ctp, msg, args, idx);
1102 break;
1103
1104 case WC_CAAM_ECDSA_ECDH:
1105 ret = doECDSA_ECDH(ctp, msg, args, idx);
1106 break;
1107
1108 case WC_CAAM_FIFO_S:
1109 ret = doFIFO_S(ctp, msg, args, idx);
1110 break;
1111
1112 case WC_CAAM_GET_PART:
1113 ret = doGET_PART(ctp, msg, args, idx, ocb);
1114 break;
1115
1116 case WC_CAAM_FREE_PART:
1117 caamFreePart(args[0]);
1118
1119 pthread_mutex_lock(&sm_mutex);
1120 sm_ownerId[args[0]] = 0;
1121 pthread_mutex_unlock(&sm_mutex);
1122 ret = EOK;
1123 break;
1124
1125 case WC_CAAM_FIND_PART:
1126 ret = caamFindUnusedPartition();
1127 if (ret < 0) {
1128 /* none found, try again later */
1129 return EAGAIN;
1130 }
1131 SETIOV(&out_iov, &ret, sizeof(ret));
1132 resmgr_msgwritev(ctp, &out_iov, 1, sizeof(msg->o));
1133 ret = EOK;
1134 break;
1135
1136 case WC_CAAM_WRITE_PART:
1137 ret = doWRITE_PART(ctp, msg, args, idx);
1138 break;
1139
1140 case WC_CAAM_READ_PART:
1141 ret = doREAD_PART(ctp, msg, args, idx);
1142 break;
1143
1144 default:
1145 WOLFSSL_MSG("unknown option");
1146 return (ENOSYS);
1147 }
1148
1149 return ret;
1150 }
1151
1152
io_open(resmgr_context_t * ctp,io_open_t * msg,RESMGR_HANDLE_T * handle,void * extra)1153 int io_open(resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle,
1154 void *extra)
1155 {
1156 WOLFSSL_MSG("starting up");
1157 return (iofunc_open_default (ctp, msg, handle, extra));
1158 }
1159
1160
io_close_ocb(resmgr_context_t * ctp,void * reserved,RESMGR_OCB_T * ocb)1161 int io_close_ocb(resmgr_context_t *ctp, void *reserved, RESMGR_OCB_T *ocb)
1162 {
1163 int i;
1164
1165 WOLFSSL_MSG("shutting down");
1166
1167 /* free up any dangling owned memory */
1168 pthread_mutex_lock(&sm_mutex);
1169 for (i = 0; i < MAX_PART; i++) {
1170 if (sm_ownerId[i] == (CAAM_ADDRESS)ocb) {
1171 sm_ownerId[i] = 0;
1172 #if defined(WOLFSSL_CAAM_DEBUG) || defined(WOLFSSL_CAAM_PRINT)
1173 printf("found dangiling partition at index %d\n", i);
1174 #endif
1175 caamFreePart(i);
1176 }
1177 }
1178 pthread_mutex_unlock(&sm_mutex);
1179 return iofunc_close_ocb_default(ctp, reserved, ocb);
1180 }
1181
1182
1183 #if 0
1184 static int getSupported(char* in)
1185 {
1186 //printf("CAAM Status [0x%8.8x] = 0x%8.8x\n",
1187 // CAAM_STATUS, WC_CAAM_READ(CAAM_STATUS));
1188 printf("CAAM Version MS Register [0x%8.8x] = 0x%8.8x\n",
1189 CAAM_VERSION_MS, CAAM_READ(CAAM_VERSION_MS));
1190 printf("CAAM Version LS Register [0x%8.8x] = 0x%8.8x\n",
1191 CAAM_VERSION_LS, CAAM_READ(CAAM_VERSION_LS));
1192 printf("CAAM Support MS Register [0x%8.8x] = 0x%8.8x\n",
1193 CAMM_SUPPORT_MS, CAAM_READ(CAMM_SUPPORT_MS));
1194 printf("CAAM Support LS [0x%8.8x] = 0x%8.8x\n",
1195 CAMM_SUPPORT_LS, CAAM_READ(CAMM_SUPPORT_LS));
1196
1197 return strlen(in)+1;
1198 }
1199 #endif
1200
1201 char cannedResponse[] = {
1202 "wolfCrypt QNX CAAM driver version "
1203 LIBWOLFSSL_VERSION_STRING
1204 "\nSupports:\n"
1205 "\tAES-CMAC\n"
1206 "\tECC (sign, verify, ecdh, keygen)\n"
1207 "\tBlobs (black and red)\n"
1208 };
1209
1210 /* read is only used to get banner info of the driver */
io_read(resmgr_context_t * ctp,io_read_t * msg,RESMGR_OCB_T * ocb)1211 int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb)
1212 {
1213 int status;
1214
1215 /* check callers access rights */
1216 if ((status = iofunc_read_verify(ctp, msg, ocb, NULL)) != EOK) {
1217 return (status);
1218 }
1219
1220 /* only support read not pread */
1221 if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE) {
1222 return (ENOSYS);
1223 }
1224
1225 if (ocb->offset == 0) { /* just fill up what can */
1226 int sz = min(msg->i.nbytes, sizeof(cannedResponse));
1227 MsgReply(ctp->rcvid, sz, cannedResponse, sz);
1228 ocb->offset += sz;
1229 }
1230 else {
1231 MsgReply(ctp->rcvid, EOK, NULL, 0);
1232 }
1233
1234 return (_RESMGR_NOREPLY);
1235 }
1236
1237
io_write(resmgr_context_t * ctp,io_write_t * msg,RESMGR_OCB_T * ocb)1238 int io_write(resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb)
1239 {
1240 (void)ctp;
1241 (void)msg;
1242 (void)ocb;
1243
1244 /* write is not supported */
1245 return (ENOSYS);
1246 }
1247
1248
main(int argc,char * argv[])1249 int main(int argc, char *argv[])
1250 {
1251 int name;
1252 int i;
1253
1254 pthread_mutex_init(&sm_mutex, NULL);
1255 for (i = 0; i < MAX_PART; i++) {
1256 sm_ownerId[i] = 0;
1257 }
1258
1259 if (InitCAAM() != 0) {
1260 WOLFSSL_MSG("unable to start up caam driver!");
1261 exit(1);
1262 }
1263
1264 dpp = dispatch_create();
1265 if (dpp == NULL) {
1266 exit (1);
1267 }
1268 memset(&rattr, 0, sizeof(rattr));
1269 iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
1270 _RESMGR_IO_NFUNCS, &io_funcs);
1271
1272 connect_funcs.open = io_open;
1273 io_funcs.close_ocb = io_close_ocb;
1274 io_funcs.read = io_read;
1275 io_funcs.write = io_write;
1276 io_funcs.devctl = io_devctl;
1277
1278 iofunc_attr_init (&ioattr, S_IFCHR | 0666, NULL, NULL);
1279 name = resmgr_attach(dpp, &rattr, "/dev/wolfCrypt",
1280 _FTYPE_ANY, 0, &connect_funcs, &io_funcs, &ioattr);
1281 if (name == -1) {
1282 exit (1);
1283 }
1284
1285 ctp = dispatch_context_alloc(dpp);
1286 while (1) {
1287 ctp = dispatch_block(ctp);
1288 if (ctp == NULL) {
1289 CleanupCAAM();
1290 exit (1);
1291 }
1292 dispatch_handler(ctp);
1293 }
1294
1295 pthread_mutex_destroy(&sm_mutex);
1296 CleanupCAAM();
1297 return 0;
1298 }
1299
1300 #endif /* __QNX__ || __QNXNTO__ */
1301