1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2018, Linaro Limited
4 */
5
6 #include <err.h>
7 #include <inttypes.h>
8 #include <limits.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 /* OP-TEE TEE client API (built by optee_client) */
14 #include <tee_client_api.h>
15
16 /* For the UUID (found in the TA's h-file(s)) */
17 #include <acipher_ta.h>
18
usage(int argc,char * argv[])19 static void usage(int argc, char *argv[])
20 {
21 const char *pname = "acipher";
22
23 if (argc)
24 pname = argv[0];
25
26 fprintf(stderr, "usage: %s <key_size> <string to encrypt>\n", pname);
27 exit(1);
28 }
29
get_args(int argc,char * argv[],size_t * key_size,void ** inbuf,size_t * inbuf_len)30 static void get_args(int argc, char *argv[], size_t *key_size, void **inbuf,
31 size_t *inbuf_len)
32 {
33 char *ep;
34 long ks;
35
36 if (argc != 3) {
37 warnx("Unexpected number of arguments %d (expected 2)",
38 argc - 1);
39 usage(argc, argv);
40 }
41
42 ks = strtol(argv[1], &ep, 0);
43 if (*ep) {
44 warnx("cannot parse key_size \"%s\"", argv[1]);
45 usage(argc, argv);
46 }
47 if (ks < 0 || ks == LONG_MAX) {
48 warnx("bad key_size \"%s\" (%ld)", argv[1], ks);
49 usage(argc, argv);
50 }
51 *key_size = ks;
52
53 *inbuf = argv[2];
54 *inbuf_len = strlen(argv[2]);
55 }
56
teec_err(TEEC_Result res,uint32_t eo,const char * str)57 static void teec_err(TEEC_Result res, uint32_t eo, const char *str)
58 {
59 errx(1, "%s: %#" PRIx32 " (error origin %#" PRIx32 ")", str, res, eo);
60 }
61
main(int argc,char * argv[])62 int main(int argc, char *argv[])
63 {
64 TEEC_Result res;
65 uint32_t eo;
66 TEEC_Context ctx;
67 TEEC_Session sess;
68 TEEC_Operation op;
69 size_t key_size;
70 void *inbuf;
71 size_t inbuf_len;
72 size_t n;
73 const TEEC_UUID uuid = TA_ACIPHER_UUID;
74
75 get_args(argc, argv, &key_size, &inbuf, &inbuf_len);
76
77 res = TEEC_InitializeContext(NULL, &ctx);
78 if (res)
79 errx(1, "TEEC_InitializeContext(NULL, x): %#" PRIx32, res);
80
81 res = TEEC_OpenSession(&ctx, &sess, &uuid, TEEC_LOGIN_PUBLIC, NULL,
82 NULL, &eo);
83 if (res)
84 teec_err(res, eo, "TEEC_OpenSession(TEEC_LOGIN_PUBLIC)");
85
86 memset(&op, 0, sizeof(op));
87 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
88 TEEC_NONE, TEEC_NONE);
89 op.params[0].value.a = key_size;
90
91 res = TEEC_InvokeCommand(&sess, TA_ACIPHER_CMD_GEN_KEY, &op, &eo);
92 if (res)
93 teec_err(res, eo, "TEEC_InvokeCommand(TA_ACIPHER_CMD_GEN_KEY)");
94
95 memset(&op, 0, sizeof(op));
96 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
97 TEEC_MEMREF_TEMP_OUTPUT,
98 TEEC_NONE, TEEC_NONE);
99 op.params[0].tmpref.buffer = inbuf;
100 op.params[0].tmpref.size = inbuf_len;
101
102 res = TEEC_InvokeCommand(&sess, TA_ACIPHER_CMD_ENCRYPT, &op, &eo);
103 if (eo != TEEC_ORIGIN_TRUSTED_APP || res != TEEC_ERROR_SHORT_BUFFER)
104 teec_err(res, eo, "TEEC_InvokeCommand(TA_ACIPHER_CMD_ENCRYPT)");
105
106 op.params[1].tmpref.buffer = malloc(op.params[1].tmpref.size);
107 if (!op.params[1].tmpref.buffer)
108 err(1, "Cannot allocate out buffer of size %zu",
109 op.params[1].tmpref.size);
110
111 res = TEEC_InvokeCommand(&sess, TA_ACIPHER_CMD_ENCRYPT, &op, &eo);
112 if (res)
113 teec_err(res, eo, "TEEC_InvokeCommand(TA_ACIPHER_CMD_ENCRYPT)");
114
115 printf("Encrypted buffer: ");
116 for (n = 0; n < op.params[1].tmpref.size; n++)
117 printf("%02x ", ((uint8_t *)op.params[1].tmpref.buffer)[n]);
118 printf("\n");
119 return 0;
120 }
121