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