Initial commit with upstream sources
[platform/core/security/tef-optee_os.git] / core / arch / arm / pta / tee_fs_key_manager_tests.c
1 /*
2  * Copyright (c) 2015, Linaro Limited
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
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.
14  *
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.
26  */
27
28 #include <kernel/pseudo_ta.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <tee/tee_fs_key_manager.h>
33 #include <trace.h>
34
35 #define TA_NAME         "tee_fs_key_manager_tests.ta"
36
37 #define CMD_SELF_TESTS  0
38
39 #define ENC_FS_KEY_MANAGER_TEST_UUID \
40                 { 0x17E5E280, 0xD12E, 0x11E4,  \
41                 { 0xA4, 0x1A, 0x00, 0x02, 0xA5, 0xD5, 0xC5, 0x1B } }
42
43 #define DUMP_BUF_MAX    256
44
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
50 };
51
52 static char *print_buf(char *buf, size_t *remain_size, const char *fmt, ...)
53         __attribute__((__format__(__printf__, 3, 4)));
54
55 static char *print_buf(char *buf, size_t *remain_size, const char *fmt, ...)
56 {
57         va_list ap;
58         size_t len;
59
60         va_start(ap, fmt);
61         len = vsnprintf(buf, *remain_size, fmt, ap);
62         buf += len;
63         *remain_size -= len;
64         va_end(ap);
65         return buf;
66 }
67
68 static void dump_hex(char *buf, size_t *remain_size, uint8_t *input_buf,
69                 size_t input_size)
70 {
71         size_t i;
72
73         for (i = 0; i < input_size; i++)
74                 buf = print_buf(buf, remain_size, "%02X ", input_buf[i]);
75 }
76
77 static void print_hex(uint8_t *input_buf, size_t input_size)
78 {
79         char buf[DUMP_BUF_MAX];
80         size_t remain = sizeof(buf);
81
82         dump_hex(buf, &remain, input_buf, input_size);
83         DMSG("%s", buf);
84 }
85
86 /*
87  * Trusted Application Entry Points
88  */
89
90 static TEE_Result test_file_decrypt_with_invalid_content(void)
91 {
92         TEE_Result res = TEE_SUCCESS;
93         size_t header_size;
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;
98         uint8_t tmp_byte;
99         uint8_t encrypted_fek[TEE_FS_KM_FEK_SIZE];
100
101         DMSG("Start");
102
103         /* data encryption */
104         header_size = tee_fs_get_header_size(META_FILE);
105
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;
111                 goto exit;
112         }
113
114         res = tee_fs_encrypt_file(META_FILE,
115                         test_data, sizeof(test_data),
116                         encrypt_data_out, &encrypt_data_out_size,
117                         encrypted_fek);
118         if (res != TEE_SUCCESS) {
119                 EMSG("file encryption failed");
120                 goto exit;
121         }
122
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;
129                 goto exit;
130         }
131
132         /* case1: data decryption with modified encrypted_key */
133         tmp_byte = *(encrypt_data_out + 4);
134         *(encrypt_data_out + 4) = ~tmp_byte;
135
136         DMSG("case1: decryption with modified encrypted FEK");
137
138         res = tee_fs_decrypt_file(META_FILE,
139                         encrypt_data_out, encrypt_data_out_size,
140                         decrypt_data_out, &decrypt_data_out_size,
141                         encrypted_fek);
142         if (res == TEE_ERROR_MAC_INVALID) {
143                 DMSG("case1: passed, return code=%x", res);
144         } else {
145                 EMSG("case1: failed, return code=%x", res);
146                 res = TEE_ERROR_GENERIC;
147                 goto exit;
148         }
149
150         *(encrypt_data_out + 4) = tmp_byte;
151
152         /* case2: data decryption with modified iv */
153         tmp_byte = *(encrypt_data_out + 20);
154         *(encrypt_data_out + 20) = ~tmp_byte;
155
156         DMSG("case2: decryption with modified IV");
157
158         res = tee_fs_decrypt_file(META_FILE,
159                         encrypt_data_out, encrypt_data_out_size,
160                         decrypt_data_out, &decrypt_data_out_size,
161                         encrypted_fek);
162         if (res == TEE_ERROR_MAC_INVALID) {
163                 DMSG("case2: passed, return code=%x", res);
164         } else {
165                 EMSG("case2: failed, return code=%x", res);
166                 res = TEE_ERROR_GENERIC;
167                 goto exit;
168         }
169
170         *(encrypt_data_out + 20) = tmp_byte;
171
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;
175
176         DMSG("case3: decryption with modified cipher text");
177
178         res = tee_fs_decrypt_file(META_FILE,
179                         encrypt_data_out, encrypt_data_out_size,
180                         decrypt_data_out, &decrypt_data_out_size,
181                         encrypted_fek);
182         if (res == TEE_ERROR_MAC_INVALID) {
183                 DMSG("case3: passed, return code=%x", res);
184         } else {
185                 EMSG("case3: failed, return code=%x", res);
186                 res = TEE_ERROR_GENERIC;
187                 goto exit;
188         }
189
190         *(encrypt_data_out + encrypt_data_out_size - 5) = tmp_byte;
191
192         /* case4: data decryption with shorter cipher text length */
193         DMSG("case4: decryption with shorter cipher text length");
194
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,
198                         encrypted_fek);
199         if (res == TEE_ERROR_MAC_INVALID) {
200                 DMSG("case4: passed, return code=%x", res);
201         } else {
202                 EMSG("case4: failed, return code=%x", res);
203                 res = TEE_ERROR_GENERIC;
204                 goto exit;
205         }
206
207         /* case5: data decryption with shorter plain text buffer */
208         decrypt_data_out_size = sizeof(test_data) - 1;
209
210         DMSG("case5: decryption with shorter plain text buffer");
211
212         res = tee_fs_decrypt_file(META_FILE,
213                         encrypt_data_out, encrypt_data_out_size,
214                         decrypt_data_out, &decrypt_data_out_size,
215                         encrypted_fek);
216         if (res == TEE_ERROR_SHORT_BUFFER) {
217                 DMSG("case5: passed, return code=%x", res);
218         } else {
219                 EMSG("case5: failed, return code=%x", res);
220                 res = TEE_ERROR_GENERIC;
221                 goto exit;
222         }
223
224         decrypt_data_out_size = encrypt_data_out_size;
225
226         /* data decryption with correct encrypted data */
227         DMSG("good path test - decryption with correct data");
228
229         res = tee_fs_decrypt_file(META_FILE,
230                         encrypt_data_out, encrypt_data_out_size,
231                         decrypt_data_out, &decrypt_data_out_size,
232                         encrypted_fek);
233         if (res != TEE_SUCCESS) {
234                 EMSG("failed to decrypted data, return code=%x", res);
235                 goto exit;
236         }
237
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;
242         } else {
243                 DMSG("good path test - passed");
244         }
245
246 exit:
247         if (encrypt_data_out != NULL)
248                 free(encrypt_data_out);
249
250         if (decrypt_data_out != NULL)
251                 free(decrypt_data_out);
252
253         DMSG("Finish");
254
255         return res;
256 }
257
258 static TEE_Result test_file_decrypt_success(void)
259 {
260         TEE_Result res = TEE_SUCCESS;
261         size_t header_size;
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];
267
268         DMSG("Start");
269
270         res = tee_fs_generate_fek(encrypted_fek, TEE_FS_KM_FEK_SIZE);
271         if (res != TEE_SUCCESS)
272                 goto exit;
273
274         /* data encryption */
275         header_size = tee_fs_get_header_size(META_FILE);
276
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;
282                 goto exit;
283         }
284
285         res = tee_fs_encrypt_file(META_FILE,
286                         test_data, sizeof(test_data),
287                         encrypt_data_out, &encrypt_data_out_size,
288                         encrypted_fek);
289         if (res != TEE_SUCCESS) {
290                 EMSG("file encryption failed");
291                 goto exit;
292         }
293
294
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;
301                 goto exit;
302         }
303
304         res = tee_fs_decrypt_file(META_FILE,
305                         encrypt_data_out, encrypt_data_out_size,
306                         decrypt_data_out, &decrypt_data_out_size,
307                         encrypted_fek);
308         if (res != TEE_SUCCESS)
309                 goto exit;
310
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;
315         }
316
317 exit:
318         /* dump data for debug */
319         if (res != TEE_SUCCESS)
320                 DMSG("return code = %x", res);
321         else {
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);
328         }
329
330         if (encrypt_data_out != NULL)
331                 free(encrypt_data_out);
332
333         if (decrypt_data_out != NULL)
334                 free(decrypt_data_out);
335
336         DMSG("Finish");
337
338         return res;
339 }
340
341 static TEE_Result self_tests(
342                         uint32_t nParamTypes __unused,
343                         TEE_Param pParams[TEE_NUM_PARAMS] __unused)
344 {
345         TEE_Result res;
346
347         res = test_file_decrypt_success();
348         if (res != TEE_SUCCESS)
349                 return res;
350
351         res = test_file_decrypt_with_invalid_content();
352         if (res != TEE_SUCCESS)
353                 return res;
354
355         return TEE_SUCCESS;
356 }
357
358 static TEE_Result invoke_command(void *pSessionContext __unused,
359                 uint32_t nCommandID, uint32_t nParamTypes,
360                 TEE_Param pParams[TEE_NUM_PARAMS])
361 {
362         DMSG("command entry point for static ta \"%s\"", TA_NAME);
363
364         switch (nCommandID) {
365         case CMD_SELF_TESTS:
366                 return self_tests(nParamTypes, pParams);
367         default:
368                 break;
369         }
370         return TEE_ERROR_BAD_PARAMETERS;
371 }
372
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);