2 * Copyright (c) 2015, Linaro Limited
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
28 #include <kernel/pseudo_ta.h>
32 #include <tee/tee_fs_key_manager.h>
35 #define TA_NAME "tee_fs_key_manager_tests.ta"
37 #define CMD_SELF_TESTS 0
39 #define ENC_FS_KEY_MANAGER_TEST_UUID \
40 { 0x17E5E280, 0xD12E, 0x11E4, \
41 { 0xA4, 0x1A, 0x00, 0x02, 0xA5, 0xD5, 0xC5, 0x1B } }
43 #define DUMP_BUF_MAX 256
45 static uint8_t test_data[] = {
46 0x00, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
47 0x00, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
48 0x00, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
49 0x00, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x00
52 static char *print_buf(char *buf, size_t *remain_size, const char *fmt, ...)
53 __attribute__((__format__(__printf__, 3, 4)));
55 static char *print_buf(char *buf, size_t *remain_size, const char *fmt, ...)
61 len = vsnprintf(buf, *remain_size, fmt, ap);
68 static void dump_hex(char *buf, size_t *remain_size, uint8_t *input_buf,
73 for (i = 0; i < input_size; i++)
74 buf = print_buf(buf, remain_size, "%02X ", input_buf[i]);
77 static void print_hex(uint8_t *input_buf, size_t input_size)
79 char buf[DUMP_BUF_MAX];
80 size_t remain = sizeof(buf);
82 dump_hex(buf, &remain, input_buf, input_size);
87 * Trusted Application Entry Points
90 static TEE_Result test_file_decrypt_with_invalid_content(void)
92 TEE_Result res = TEE_SUCCESS;
94 size_t encrypt_data_out_size;
95 uint8_t *encrypt_data_out = NULL;
96 size_t decrypt_data_out_size;
97 uint8_t *decrypt_data_out = NULL;
99 uint8_t encrypted_fek[TEE_FS_KM_FEK_SIZE];
103 /* data encryption */
104 header_size = tee_fs_get_header_size(META_FILE);
106 encrypt_data_out_size = header_size + sizeof(test_data);
107 encrypt_data_out = malloc(encrypt_data_out_size);
108 if (!encrypt_data_out) {
109 EMSG("malloc for encrypt data buffer failed");
110 res = TEE_ERROR_OUT_OF_MEMORY;
114 res = tee_fs_encrypt_file(META_FILE,
115 test_data, sizeof(test_data),
116 encrypt_data_out, &encrypt_data_out_size,
118 if (res != TEE_SUCCESS) {
119 EMSG("file encryption failed");
123 /* data decryption */
124 decrypt_data_out_size = sizeof(test_data);
125 decrypt_data_out = malloc(decrypt_data_out_size);
126 if (!decrypt_data_out) {
127 EMSG("malloc for decrypt data buffer failed");
128 res = TEE_ERROR_OUT_OF_MEMORY;
132 /* case1: data decryption with modified encrypted_key */
133 tmp_byte = *(encrypt_data_out + 4);
134 *(encrypt_data_out + 4) = ~tmp_byte;
136 DMSG("case1: decryption with modified encrypted FEK");
138 res = tee_fs_decrypt_file(META_FILE,
139 encrypt_data_out, encrypt_data_out_size,
140 decrypt_data_out, &decrypt_data_out_size,
142 if (res == TEE_ERROR_MAC_INVALID) {
143 DMSG("case1: passed, return code=%x", res);
145 EMSG("case1: failed, return code=%x", res);
146 res = TEE_ERROR_GENERIC;
150 *(encrypt_data_out + 4) = tmp_byte;
152 /* case2: data decryption with modified iv */
153 tmp_byte = *(encrypt_data_out + 20);
154 *(encrypt_data_out + 20) = ~tmp_byte;
156 DMSG("case2: decryption with modified IV");
158 res = tee_fs_decrypt_file(META_FILE,
159 encrypt_data_out, encrypt_data_out_size,
160 decrypt_data_out, &decrypt_data_out_size,
162 if (res == TEE_ERROR_MAC_INVALID) {
163 DMSG("case2: passed, return code=%x", res);
165 EMSG("case2: failed, return code=%x", res);
166 res = TEE_ERROR_GENERIC;
170 *(encrypt_data_out + 20) = tmp_byte;
172 /* case3: data decryption with modified cipher text */
173 tmp_byte = *(encrypt_data_out + encrypt_data_out_size - 5);
174 *(encrypt_data_out + encrypt_data_out_size - 5) = ~tmp_byte;
176 DMSG("case3: decryption with modified cipher text");
178 res = tee_fs_decrypt_file(META_FILE,
179 encrypt_data_out, encrypt_data_out_size,
180 decrypt_data_out, &decrypt_data_out_size,
182 if (res == TEE_ERROR_MAC_INVALID) {
183 DMSG("case3: passed, return code=%x", res);
185 EMSG("case3: failed, return code=%x", res);
186 res = TEE_ERROR_GENERIC;
190 *(encrypt_data_out + encrypt_data_out_size - 5) = tmp_byte;
192 /* case4: data decryption with shorter cipher text length */
193 DMSG("case4: decryption with shorter cipher text length");
195 res = tee_fs_decrypt_file(META_FILE,
196 encrypt_data_out, encrypt_data_out_size - 1,
197 decrypt_data_out, &decrypt_data_out_size,
199 if (res == TEE_ERROR_MAC_INVALID) {
200 DMSG("case4: passed, return code=%x", res);
202 EMSG("case4: failed, return code=%x", res);
203 res = TEE_ERROR_GENERIC;
207 /* case5: data decryption with shorter plain text buffer */
208 decrypt_data_out_size = sizeof(test_data) - 1;
210 DMSG("case5: decryption with shorter plain text buffer");
212 res = tee_fs_decrypt_file(META_FILE,
213 encrypt_data_out, encrypt_data_out_size,
214 decrypt_data_out, &decrypt_data_out_size,
216 if (res == TEE_ERROR_SHORT_BUFFER) {
217 DMSG("case5: passed, return code=%x", res);
219 EMSG("case5: failed, return code=%x", res);
220 res = TEE_ERROR_GENERIC;
224 decrypt_data_out_size = encrypt_data_out_size;
226 /* data decryption with correct encrypted data */
227 DMSG("good path test - decryption with correct data");
229 res = tee_fs_decrypt_file(META_FILE,
230 encrypt_data_out, encrypt_data_out_size,
231 decrypt_data_out, &decrypt_data_out_size,
233 if (res != TEE_SUCCESS) {
234 EMSG("failed to decrypted data, return code=%x", res);
238 /* data comparison */
239 if (memcmp(test_data, decrypt_data_out, sizeof(test_data)) != 0) {
240 EMSG("decrypted data doest not correct");
241 res = TEE_ERROR_GENERIC;
243 DMSG("good path test - passed");
247 if (encrypt_data_out != NULL)
248 free(encrypt_data_out);
250 if (decrypt_data_out != NULL)
251 free(decrypt_data_out);
258 static TEE_Result test_file_decrypt_success(void)
260 TEE_Result res = TEE_SUCCESS;
262 size_t encrypt_data_out_size;
263 uint8_t *encrypt_data_out = NULL;
264 size_t decrypt_data_out_size;
265 uint8_t *decrypt_data_out = NULL;
266 uint8_t encrypted_fek[TEE_FS_KM_FEK_SIZE];
270 res = tee_fs_generate_fek(encrypted_fek, TEE_FS_KM_FEK_SIZE);
271 if (res != TEE_SUCCESS)
274 /* data encryption */
275 header_size = tee_fs_get_header_size(META_FILE);
277 encrypt_data_out_size = header_size + sizeof(test_data);
278 encrypt_data_out = malloc(encrypt_data_out_size);
279 if (!encrypt_data_out) {
280 EMSG("malloc for encrypt data buffer failed");
281 res = TEE_ERROR_OUT_OF_MEMORY;
285 res = tee_fs_encrypt_file(META_FILE,
286 test_data, sizeof(test_data),
287 encrypt_data_out, &encrypt_data_out_size,
289 if (res != TEE_SUCCESS) {
290 EMSG("file encryption failed");
295 /* data decryption */
296 decrypt_data_out_size = sizeof(test_data);
297 decrypt_data_out = malloc(decrypt_data_out_size);
298 if (!decrypt_data_out) {
299 EMSG("malloc for decrypt data buffer failed");
300 res = TEE_ERROR_OUT_OF_MEMORY;
304 res = tee_fs_decrypt_file(META_FILE,
305 encrypt_data_out, encrypt_data_out_size,
306 decrypt_data_out, &decrypt_data_out_size,
308 if (res != TEE_SUCCESS)
311 /* data comparison */
312 if (memcmp(test_data, decrypt_data_out, sizeof(test_data)) != 0) {
313 EMSG("Data compare failed");
314 res = TEE_ERROR_GENERIC;
318 /* dump data for debug */
319 if (res != TEE_SUCCESS)
320 DMSG("return code = %x", res);
322 DMSG("Test Data (%zu bytes)", sizeof(test_data));
323 print_hex(test_data, sizeof(test_data));
324 DMSG("Encrypted Data (%zu bytes)", encrypt_data_out_size);
325 print_hex(encrypt_data_out, encrypt_data_out_size);
326 DMSG("Decrypted Data (%zu bytes)", decrypt_data_out_size);
327 print_hex(decrypt_data_out, decrypt_data_out_size);
330 if (encrypt_data_out != NULL)
331 free(encrypt_data_out);
333 if (decrypt_data_out != NULL)
334 free(decrypt_data_out);
341 static TEE_Result self_tests(
342 uint32_t nParamTypes __unused,
343 TEE_Param pParams[TEE_NUM_PARAMS] __unused)
347 res = test_file_decrypt_success();
348 if (res != TEE_SUCCESS)
351 res = test_file_decrypt_with_invalid_content();
352 if (res != TEE_SUCCESS)
358 static TEE_Result invoke_command(void *pSessionContext __unused,
359 uint32_t nCommandID, uint32_t nParamTypes,
360 TEE_Param pParams[TEE_NUM_PARAMS])
362 DMSG("command entry point for static ta \"%s\"", TA_NAME);
364 switch (nCommandID) {
366 return self_tests(nParamTypes, pParams);
370 return TEE_ERROR_BAD_PARAMETERS;
373 pseudo_ta_register(.uuid = ENC_FS_KEY_MANAGER_TEST_UUID, .name = TA_NAME,
374 .flags = PTA_DEFAULT_FLAGS,
375 .invoke_command_entry_point = invoke_command);