aboutsummaryrefslogtreecommitdiffstats
path: root/security/tf_driver/tf_util.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /security/tf_driver/tf_util.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'security/tf_driver/tf_util.c')
-rw-r--r--security/tf_driver/tf_util.c1143
1 files changed, 1143 insertions, 0 deletions
diff --git a/security/tf_driver/tf_util.c b/security/tf_driver/tf_util.c
new file mode 100644
index 00000000000..78f90bf677e
--- /dev/null
+++ b/security/tf_driver/tf_util.c
@@ -0,0 +1,1143 @@
1/**
2 * Copyright (c) 2011 Trusted Logic S.A.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#include <linux/mman.h>
21#include "tf_util.h"
22
23/*----------------------------------------------------------------------------
24 * Debug printing routines
25 *----------------------------------------------------------------------------*/
26#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
27
28void tf_trace_array(const char *fun, const char *msg,
29 const void *ptr, size_t len)
30{
31 char hex[511];
32 bool ell = (len > sizeof(hex)/2);
33 unsigned lim = (len > sizeof(hex)/2 ? sizeof(hex)/2 : len);
34 unsigned i;
35 for (i = 0; i < lim; i++)
36 sprintf(hex + 2 * i, "%02x", ((unsigned char *)ptr)[i]);
37 pr_info("%s: %s[%u] = %s%s\n",
38 fun, msg, len, hex, ell ? "..." : "");
39}
40
41void address_cache_property(unsigned long va)
42{
43 unsigned long pa;
44 unsigned long inner;
45 unsigned long outer;
46
47 asm volatile ("mcr p15, 0, %0, c7, c8, 0" : : "r" (va));
48 asm volatile ("mrc p15, 0, %0, c7, c4, 0" : "=r" (pa));
49
50 dprintk(KERN_INFO "VA:%x, PA:%x\n",
51 (unsigned int) va,
52 (unsigned int) pa);
53
54 if (pa & 1) {
55 dprintk(KERN_INFO "Prop Error\n");
56 return;
57 }
58
59 outer = (pa >> 2) & 3;
60 dprintk(KERN_INFO "\touter : %x", (unsigned int) outer);
61
62 switch (outer) {
63 case 3:
64 dprintk(KERN_INFO "Write-Back, no Write-Allocate\n");
65 break;
66 case 2:
67 dprintk(KERN_INFO "Write-Through, no Write-Allocate.\n");
68 break;
69 case 1:
70 dprintk(KERN_INFO "Write-Back, Write-Allocate.\n");
71 break;
72 case 0:
73 dprintk(KERN_INFO "Non-cacheable.\n");
74 break;
75 }
76
77 inner = (pa >> 4) & 7;
78 dprintk(KERN_INFO "\tinner : %x", (unsigned int)inner);
79
80 switch (inner) {
81 case 7:
82 dprintk(KERN_INFO "Write-Back, no Write-Allocate\n");
83 break;
84 case 6:
85 dprintk(KERN_INFO "Write-Through.\n");
86 break;
87 case 5:
88 dprintk(KERN_INFO "Write-Back, Write-Allocate.\n");
89 break;
90 case 3:
91 dprintk(KERN_INFO "Device.\n");
92 break;
93 case 1:
94 dprintk(KERN_INFO "Strongly-ordered.\n");
95 break;
96 case 0:
97 dprintk(KERN_INFO "Non-cacheable.\n");
98 break;
99 }
100
101 if (pa & 0x00000002)
102 dprintk(KERN_INFO "SuperSection.\n");
103 if (pa & 0x00000080)
104 dprintk(KERN_INFO "Memory is shareable.\n");
105 else
106 dprintk(KERN_INFO "Memory is non-shareable.\n");
107
108 if (pa & 0x00000200)
109 dprintk(KERN_INFO "Non-secure.\n");
110}
111
112/*
113 * Dump the L1 shared buffer.
114 */
115void tf_dump_l1_shared_buffer(struct tf_l1_shared_buffer *buffer)
116{
117 dprintk(KERN_INFO
118 "buffer@%p:\n"
119 #ifndef CONFIG_TF_ZEBRA
120 " config_flag_s=%08X\n"
121 #endif
122 " version_description=%64s\n"
123 " status_s=%08X\n"
124 " sync_serial_n=%08X\n"
125 " sync_serial_s=%08X\n"
126 " time_n[0]=%016llX\n"
127 " time_n[1]=%016llX\n"
128 " timeout_s[0]=%016llX\n"
129 " timeout_s[1]=%016llX\n"
130 " first_command=%08X\n"
131 " first_free_command=%08X\n"
132 " first_answer=%08X\n"
133 " first_free_answer=%08X\n\n",
134 buffer,
135 #ifndef CONFIG_TF_ZEBRA
136 buffer->config_flag_s,
137 #endif
138 buffer->version_description,
139 buffer->status_s,
140 buffer->sync_serial_n,
141 buffer->sync_serial_s,
142 buffer->time_n[0],
143 buffer->time_n[1],
144 buffer->timeout_s[0],
145 buffer->timeout_s[1],
146 buffer->first_command,
147 buffer->first_free_command,
148 buffer->first_answer,
149 buffer->first_free_answer);
150}
151
152
153/*
154 * Dump the specified SChannel message using dprintk.
155 */
156void tf_dump_command(union tf_command *command)
157{
158 u32 i;
159
160 dprintk(KERN_INFO "message@%p:\n", command);
161
162 switch (command->header.message_type) {
163 case TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT:
164 dprintk(KERN_INFO
165 " message_size = 0x%02X\n"
166 " message_type = 0x%02X "
167 "TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT\n"
168 " operation_id = 0x%08X\n"
169 " device_context_id = 0x%08X\n",
170 command->header.message_size,
171 command->header.message_type,
172 command->header.operation_id,
173 command->create_device_context.device_context_id
174 );
175 break;
176
177 case TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT:
178 dprintk(KERN_INFO
179 " message_size = 0x%02X\n"
180 " message_type = 0x%02X "
181 "TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT\n"
182 " operation_id = 0x%08X\n"
183 " device_context = 0x%08X\n",
184 command->header.message_size,
185 command->header.message_type,
186 command->header.operation_id,
187 command->destroy_device_context.device_context);
188 break;
189
190 case TF_MESSAGE_TYPE_OPEN_CLIENT_SESSION:
191 dprintk(KERN_INFO
192 " message_size = 0x%02X\n"
193 " message_type = 0x%02X "
194 "TF_MESSAGE_TYPE_OPEN_CLIENT_SESSION\n"
195 " param_types = 0x%04X\n"
196 " operation_id = 0x%08X\n"
197 " device_context = 0x%08X\n"
198 " cancellation_id = 0x%08X\n"
199 " timeout = 0x%016llX\n"
200 " destination_uuid = "
201 "%08X-%04X-%04X-%02X%02X-"
202 "%02X%02X%02X%02X%02X%02X\n",
203 command->header.message_size,
204 command->header.message_type,
205 command->open_client_session.param_types,
206 command->header.operation_id,
207 command->open_client_session.device_context,
208 command->open_client_session.cancellation_id,
209 command->open_client_session.timeout,
210 command->open_client_session.destination_uuid.
211 time_low,
212 command->open_client_session.destination_uuid.
213 time_mid,
214 command->open_client_session.destination_uuid.
215 time_hi_and_version,
216 command->open_client_session.destination_uuid.
217 clock_seq_and_node[0],
218 command->open_client_session.destination_uuid.
219 clock_seq_and_node[1],
220 command->open_client_session.destination_uuid.
221 clock_seq_and_node[2],
222 command->open_client_session.destination_uuid.
223 clock_seq_and_node[3],
224 command->open_client_session.destination_uuid.
225 clock_seq_and_node[4],
226 command->open_client_session.destination_uuid.
227 clock_seq_and_node[5],
228 command->open_client_session.destination_uuid.
229 clock_seq_and_node[6],
230 command->open_client_session.destination_uuid.
231 clock_seq_and_node[7]
232 );
233
234 for (i = 0; i < 4; i++) {
235 uint32_t *param = (uint32_t *) &command->
236 open_client_session.params[i];
237 dprintk(KERN_INFO " params[%d] = "
238 "0x%08X:0x%08X:0x%08X\n",
239 i, param[0], param[1], param[2]);
240 }
241
242 switch (TF_LOGIN_GET_MAIN_TYPE(
243 command->open_client_session.login_type)) {
244 case TF_LOGIN_PUBLIC:
245 dprintk(
246 KERN_INFO " login_type = "
247 "TF_LOGIN_PUBLIC\n");
248 break;
249 case TF_LOGIN_USER:
250 dprintk(
251 KERN_INFO " login_type = "
252 "TF_LOGIN_USER\n");
253 break;
254 case TF_LOGIN_GROUP:
255 dprintk(
256 KERN_INFO " login_type = "
257 "TF_LOGIN_GROUP\n");
258 break;
259 case TF_LOGIN_APPLICATION:
260 dprintk(
261 KERN_INFO " login_type = "
262 "TF_LOGIN_APPLICATION\n");
263 break;
264 case TF_LOGIN_APPLICATION_USER:
265 dprintk(
266 KERN_INFO " login_type = "
267 "TF_LOGIN_APPLICATION_USER\n");
268 break;
269 case TF_LOGIN_APPLICATION_GROUP:
270 dprintk(
271 KERN_INFO " login_type = "
272 "TF_LOGIN_APPLICATION_GROUP\n");
273 break;
274 case TF_LOGIN_AUTHENTICATION:
275 dprintk(
276 KERN_INFO " login_type = "
277 "TF_LOGIN_AUTHENTICATION\n");
278 break;
279 case TF_LOGIN_PRIVILEGED:
280 dprintk(
281 KERN_INFO " login_type = "
282 "TF_LOGIN_PRIVILEGED\n");
283 break;
284 case TF_LOGIN_PRIVILEGED_KERNEL:
285 dprintk(
286 KERN_INFO " login_type = "
287 "TF_LOGIN_PRIVILEGED_KERNEL\n");
288 break;
289 default:
290 dprintk(
291 KERN_ERR " login_type = "
292 "0x%08X (Unknown login type)\n",
293 command->open_client_session.login_type);
294 break;
295 }
296
297 dprintk(
298 KERN_INFO " login_data = ");
299 for (i = 0; i < 20; i++)
300 dprintk(
301 KERN_INFO "%d",
302 command->open_client_session.
303 login_data[i]);
304 dprintk("\n");
305 break;
306
307 case TF_MESSAGE_TYPE_CLOSE_CLIENT_SESSION:
308 dprintk(KERN_INFO
309 " message_size = 0x%02X\n"
310 " message_type = 0x%02X "
311 "TF_MESSAGE_TYPE_CLOSE_CLIENT_SESSION\n"
312 " operation_id = 0x%08X\n"
313 " device_context = 0x%08X\n"
314 " client_session = 0x%08X\n",
315 command->header.message_size,
316 command->header.message_type,
317 command->header.operation_id,
318 command->close_client_session.device_context,
319 command->close_client_session.client_session
320 );
321 break;
322
323 case TF_MESSAGE_TYPE_REGISTER_SHARED_MEMORY:
324 dprintk(KERN_INFO
325 " message_size = 0x%02X\n"
326 " message_type = 0x%02X "
327 "TF_MESSAGE_TYPE_REGISTER_SHARED_MEMORY\n"
328 " memory_flags = 0x%04X\n"
329 " operation_id = 0x%08X\n"
330 " device_context = 0x%08X\n"
331 " block_id = 0x%08X\n"
332 " shared_mem_size = 0x%08X\n"
333 " shared_mem_start_offset = 0x%08X\n"
334 " shared_mem_descriptors[0] = 0x%08X\n"
335 " shared_mem_descriptors[1] = 0x%08X\n"
336 " shared_mem_descriptors[2] = 0x%08X\n"
337 " shared_mem_descriptors[3] = 0x%08X\n"
338 " shared_mem_descriptors[4] = 0x%08X\n"
339 " shared_mem_descriptors[5] = 0x%08X\n"
340 " shared_mem_descriptors[6] = 0x%08X\n"
341 " shared_mem_descriptors[7] = 0x%08X\n",
342 command->header.message_size,
343 command->header.message_type,
344 command->register_shared_memory.memory_flags,
345 command->header.operation_id,
346 command->register_shared_memory.device_context,
347 command->register_shared_memory.block_id,
348 command->register_shared_memory.shared_mem_size,
349 command->register_shared_memory.
350 shared_mem_start_offset,
351 command->register_shared_memory.
352 shared_mem_descriptors[0],
353 command->register_shared_memory.
354 shared_mem_descriptors[1],
355 command->register_shared_memory.
356 shared_mem_descriptors[2],
357 command->register_shared_memory.
358 shared_mem_descriptors[3],
359 command->register_shared_memory.
360 shared_mem_descriptors[4],
361 command->register_shared_memory.
362 shared_mem_descriptors[5],
363 command->register_shared_memory.
364 shared_mem_descriptors[6],
365 command->register_shared_memory.
366 shared_mem_descriptors[7]);
367 break;
368
369 case TF_MESSAGE_TYPE_RELEASE_SHARED_MEMORY:
370 dprintk(KERN_INFO
371 " message_size = 0x%02X\n"
372 " message_type = 0x%02X "
373 "TF_MESSAGE_TYPE_RELEASE_SHARED_MEMORY\n"
374 " operation_id = 0x%08X\n"
375 " device_context = 0x%08X\n"
376 " block = 0x%08X\n",
377 command->header.message_size,
378 command->header.message_type,
379 command->header.operation_id,
380 command->release_shared_memory.device_context,
381 command->release_shared_memory.block);
382 break;
383
384 case TF_MESSAGE_TYPE_INVOKE_CLIENT_COMMAND:
385 dprintk(KERN_INFO
386 " message_size = 0x%02X\n"
387 " message_type = 0x%02X "
388 "TF_MESSAGE_TYPE_INVOKE_CLIENT_COMMAND\n"
389 " param_types = 0x%04X\n"
390 " operation_id = 0x%08X\n"
391 " device_context = 0x%08X\n"
392 " client_session = 0x%08X\n"
393 " timeout = 0x%016llX\n"
394 " cancellation_id = 0x%08X\n"
395 " client_command_identifier = 0x%08X\n",
396 command->header.message_size,
397 command->header.message_type,
398 command->invoke_client_command.param_types,
399 command->header.operation_id,
400 command->invoke_client_command.device_context,
401 command->invoke_client_command.client_session,
402 command->invoke_client_command.timeout,
403 command->invoke_client_command.cancellation_id,
404 command->invoke_client_command.
405 client_command_identifier
406 );
407
408 for (i = 0; i < 4; i++) {
409 uint32_t *param = (uint32_t *) &command->
410 open_client_session.params[i];
411 dprintk(KERN_INFO " params[%d] = "
412 "0x%08X:0x%08X:0x%08X\n", i,
413 param[0], param[1], param[2]);
414 }
415 break;
416
417 case TF_MESSAGE_TYPE_CANCEL_CLIENT_COMMAND:
418 dprintk(KERN_INFO
419 " message_size = 0x%02X\n"
420 " message_type = 0x%02X "
421 "TF_MESSAGE_TYPE_CANCEL_CLIENT_COMMAND\n"
422 " operation_id = 0x%08X\n"
423 " device_context = 0x%08X\n"
424 " client_session = 0x%08X\n",
425 command->header.message_size,
426 command->header.message_type,
427 command->header.operation_id,
428 command->cancel_client_operation.device_context,
429 command->cancel_client_operation.client_session);
430 break;
431
432 case TF_MESSAGE_TYPE_MANAGEMENT:
433 dprintk(KERN_INFO
434 " message_size = 0x%02X\n"
435 " message_type = 0x%02X "
436 "TF_MESSAGE_TYPE_MANAGEMENT\n"
437 " operation_id = 0x%08X\n"
438 " command = 0x%08X\n"
439 " w3b_size = 0x%08X\n"
440 " w3b_start_offset = 0x%08X\n",
441 command->header.message_size,
442 command->header.message_type,
443 command->header.operation_id,
444 command->management.command,
445 command->management.w3b_size,
446 command->management.w3b_start_offset);
447 break;
448
449 default:
450 dprintk(
451 KERN_ERR " message_type = 0x%08X "
452 "(Unknown message type)\n",
453 command->header.message_type);
454 break;
455 }
456}
457
458
459/*
460 * Dump the specified SChannel answer using dprintk.
461 */
462void tf_dump_answer(union tf_answer *answer)
463{
464 u32 i;
465 dprintk(
466 KERN_INFO "answer@%p:\n",
467 answer);
468
469 switch (answer->header.message_type) {
470 case TF_MESSAGE_TYPE_CREATE_DEVICE_CONTEXT:
471 dprintk(KERN_INFO
472 " message_size = 0x%02X\n"
473 " message_type = 0x%02X "
474 "tf_answer_create_device_context\n"
475 " operation_id = 0x%08X\n"
476 " error_code = 0x%08X\n"
477 " device_context = 0x%08X\n",
478 answer->header.message_size,
479 answer->header.message_type,
480 answer->header.operation_id,
481 answer->create_device_context.error_code,
482 answer->create_device_context.device_context);
483 break;
484
485 case TF_MESSAGE_TYPE_DESTROY_DEVICE_CONTEXT:
486 dprintk(KERN_INFO
487 " message_size = 0x%02X\n"
488 " message_type = 0x%02X "
489 "ANSWER_DESTROY_DEVICE_CONTEXT\n"
490 " operation_id = 0x%08X\n"
491 " error_code = 0x%08X\n"
492 " device_context_id = 0x%08X\n",
493 answer->header.message_size,
494 answer->header.message_type,
495 answer->header.operation_id,
496 answer->destroy_device_context.error_code,
497 answer->destroy_device_context.device_context_id);
498 break;
499
500
501 case TF_MESSAGE_TYPE_OPEN_CLIENT_SESSION:
502 dprintk(KERN_INFO
503 " message_size = 0x%02X\n"
504 " message_type = 0x%02X "
505 "tf_answer_open_client_session\n"
506 " error_origin = 0x%02X\n"
507 " operation_id = 0x%08X\n"
508 " error_code = 0x%08X\n"
509 " client_session = 0x%08X\n",
510 answer->header.message_size,
511 answer->header.message_type,
512 answer->open_client_session.error_origin,
513 answer->header.operation_id,
514 answer->open_client_session.error_code,
515 answer->open_client_session.client_session);
516 for (i = 0; i < 4; i++) {
517 dprintk(KERN_INFO " answers[%d]=0x%08X:0x%08X\n",
518 i,
519 answer->open_client_session.answers[i].
520 value.a,
521 answer->open_client_session.answers[i].
522 value.b);
523 }
524 break;
525
526 case TF_MESSAGE_TYPE_CLOSE_CLIENT_SESSION:
527 dprintk(KERN_INFO
528 " message_size = 0x%02X\n"
529 " message_type = 0x%02X "
530 "ANSWER_CLOSE_CLIENT_SESSION\n"
531 " operation_id = 0x%08X\n"
532 " error_code = 0x%08X\n",
533 answer->header.message_size,
534 answer->header.message_type,
535 answer->header.operation_id,
536 answer->close_client_session.error_code);
537 break;
538
539 case TF_MESSAGE_TYPE_REGISTER_SHARED_MEMORY:
540 dprintk(KERN_INFO
541 " message_size = 0x%02X\n"
542 " message_type = 0x%02X "
543 "tf_answer_register_shared_memory\n"
544 " operation_id = 0x%08X\n"
545 " error_code = 0x%08X\n"
546 " block = 0x%08X\n",
547 answer->header.message_size,
548 answer->header.message_type,
549 answer->header.operation_id,
550 answer->register_shared_memory.error_code,
551 answer->register_shared_memory.block);
552 break;
553
554 case TF_MESSAGE_TYPE_RELEASE_SHARED_MEMORY:
555 dprintk(KERN_INFO
556 " message_size = 0x%02X\n"
557 " message_type = 0x%02X "
558 "ANSWER_RELEASE_SHARED_MEMORY\n"
559 " operation_id = 0x%08X\n"
560 " error_code = 0x%08X\n"
561 " block_id = 0x%08X\n",
562 answer->header.message_size,
563 answer->header.message_type,
564 answer->header.operation_id,
565 answer->release_shared_memory.error_code,
566 answer->release_shared_memory.block_id);
567 break;
568
569 case TF_MESSAGE_TYPE_INVOKE_CLIENT_COMMAND:
570 dprintk(KERN_INFO
571 " message_size = 0x%02X\n"
572 " message_type = 0x%02X "
573 "tf_answer_invoke_client_command\n"
574 " error_origin = 0x%02X\n"
575 " operation_id = 0x%08X\n"
576 " error_code = 0x%08X\n",
577 answer->header.message_size,
578 answer->header.message_type,
579 answer->invoke_client_command.error_origin,
580 answer->header.operation_id,
581 answer->invoke_client_command.error_code
582 );
583 for (i = 0; i < 4; i++) {
584 dprintk(KERN_INFO " answers[%d]=0x%08X:0x%08X\n",
585 i,
586 answer->invoke_client_command.answers[i].
587 value.a,
588 answer->invoke_client_command.answers[i].
589 value.b);
590 }
591 break;
592
593 case TF_MESSAGE_TYPE_CANCEL_CLIENT_COMMAND:
594 dprintk(KERN_INFO
595 " message_size = 0x%02X\n"
596 " message_type = 0x%02X "
597 "TF_ANSWER_CANCEL_CLIENT_COMMAND\n"
598 " operation_id = 0x%08X\n"
599 " error_code = 0x%08X\n",
600 answer->header.message_size,
601 answer->header.message_type,
602 answer->header.operation_id,
603 answer->cancel_client_operation.error_code);
604 break;
605
606 case TF_MESSAGE_TYPE_MANAGEMENT:
607 dprintk(KERN_INFO
608 " message_size = 0x%02X\n"
609 " message_type = 0x%02X "
610 "TF_MESSAGE_TYPE_MANAGEMENT\n"
611 " operation_id = 0x%08X\n"
612 " error_code = 0x%08X\n",
613 answer->header.message_size,
614 answer->header.message_type,
615 answer->header.operation_id,
616 answer->header.error_code);
617 break;
618
619 default:
620 dprintk(
621 KERN_ERR " message_type = 0x%02X "
622 "(Unknown message type)\n",
623 answer->header.message_type);
624 break;
625
626 }
627}
628
629#endif /* defined(TF_DRIVER_DEBUG_SUPPORT) */
630
631/*----------------------------------------------------------------------------
632 * SHA-1 implementation
633 * This is taken from the Linux kernel source crypto/sha1.c
634 *----------------------------------------------------------------------------*/
635
636struct sha1_ctx {
637 u64 count;
638 u32 state[5];
639 u8 buffer[64];
640};
641
642static inline u32 rol(u32 value, u32 bits)
643{
644 return ((value) << (bits)) | ((value) >> (32 - (bits)));
645}
646
647/* blk0() and blk() perform the initial expand. */
648/* I got the idea of expanding during the round function from SSLeay */
649#define blk0(i) block32[i]
650
651#define blk(i) (block32[i & 15] = rol( \
652 block32[(i + 13) & 15] ^ block32[(i + 8) & 15] ^ \
653 block32[(i + 2) & 15] ^ block32[i & 15], 1))
654
655/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
656#define R0(v, w, x, y, z, i) do { \
657 z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
658 w = rol(w, 30); } while (0)
659
660#define R1(v, w, x, y, z, i) do { \
661 z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
662 w = rol(w, 30); } while (0)
663
664#define R2(v, w, x, y, z, i) do { \
665 z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
666 w = rol(w, 30); } while (0)
667
668#define R3(v, w, x, y, z, i) do { \
669 z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
670 w = rol(w, 30); } while (0)
671
672#define R4(v, w, x, y, z, i) do { \
673 z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
674 w = rol(w, 30); } while (0)
675
676
677/* Hash a single 512-bit block. This is the core of the algorithm. */
678static void sha1_transform(u32 *state, const u8 *in)
679{
680 u32 a, b, c, d, e;
681 u32 block32[16];
682
683 /* convert/copy data to workspace */
684 for (a = 0; a < sizeof(block32)/sizeof(u32); a++)
685 block32[a] = ((u32) in[4 * a]) << 24 |
686 ((u32) in[4 * a + 1]) << 16 |
687 ((u32) in[4 * a + 2]) << 8 |
688 ((u32) in[4 * a + 3]);
689
690 /* Copy context->state[] to working vars */
691 a = state[0];
692 b = state[1];
693 c = state[2];
694 d = state[3];
695 e = state[4];
696
697 /* 4 rounds of 20 operations each. Loop unrolled. */
698 R0(a, b, c, d, e, 0); R0(e, a, b, c, d, 1);
699 R0(d, e, a, b, c, 2); R0(c, d, e, a, b, 3);
700 R0(b, c, d, e, a, 4); R0(a, b, c, d, e, 5);
701 R0(e, a, b, c, d, 6); R0(d, e, a, b, c, 7);
702 R0(c, d, e, a, b, 8); R0(b, c, d, e, a, 9);
703 R0(a, b, c, d, e, 10); R0(e, a, b, c, d, 11);
704 R0(d, e, a, b, c, 12); R0(c, d, e, a, b, 13);
705 R0(b, c, d, e, a, 14); R0(a, b, c, d, e, 15);
706
707 R1(e, a, b, c, d, 16); R1(d, e, a, b, c, 17);
708 R1(c, d, e, a, b, 18); R1(b, c, d, e, a, 19);
709
710 R2(a, b, c, d, e, 20); R2(e, a, b, c, d, 21);
711 R2(d, e, a, b, c, 22); R2(c, d, e, a, b, 23);
712 R2(b, c, d, e, a, 24); R2(a, b, c, d, e, 25);
713 R2(e, a, b, c, d, 26); R2(d, e, a, b, c, 27);
714 R2(c, d, e, a, b, 28); R2(b, c, d, e, a, 29);
715 R2(a, b, c, d, e, 30); R2(e, a, b, c, d, 31);
716 R2(d, e, a, b, c, 32); R2(c, d, e, a, b, 33);
717 R2(b, c, d, e, a, 34); R2(a, b, c, d, e, 35);
718 R2(e, a, b, c, d, 36); R2(d, e, a, b, c, 37);
719 R2(c, d, e, a, b, 38); R2(b, c, d, e, a, 39);
720
721 R3(a, b, c, d, e, 40); R3(e, a, b, c, d, 41);
722 R3(d, e, a, b, c, 42); R3(c, d, e, a, b, 43);
723 R3(b, c, d, e, a, 44); R3(a, b, c, d, e, 45);
724 R3(e, a, b, c, d, 46); R3(d, e, a, b, c, 47);
725 R3(c, d, e, a, b, 48); R3(b, c, d, e, a, 49);
726 R3(a, b, c, d, e, 50); R3(e, a, b, c, d, 51);
727 R3(d, e, a, b, c, 52); R3(c, d, e, a, b, 53);
728 R3(b, c, d, e, a, 54); R3(a, b, c, d, e, 55);
729 R3(e, a, b, c, d, 56); R3(d, e, a, b, c, 57);
730 R3(c, d, e, a, b, 58); R3(b, c, d, e, a, 59);
731
732 R4(a, b, c, d, e, 60); R4(e, a, b, c, d, 61);
733 R4(d, e, a, b, c, 62); R4(c, d, e, a, b, 63);
734 R4(b, c, d, e, a, 64); R4(a, b, c, d, e, 65);
735 R4(e, a, b, c, d, 66); R4(d, e, a, b, c, 67);
736 R4(c, d, e, a, b, 68); R4(b, c, d, e, a, 69);
737 R4(a, b, c, d, e, 70); R4(e, a, b, c, d, 71);
738 R4(d, e, a, b, c, 72); R4(c, d, e, a, b, 73);
739 R4(b, c, d, e, a, 74); R4(a, b, c, d, e, 75);
740 R4(e, a, b, c, d, 76); R4(d, e, a, b, c, 77);
741 R4(c, d, e, a, b, 78); R4(b, c, d, e, a, 79);
742
743 /* Add the working vars back into context.state[] */
744 state[0] += a;
745 state[1] += b;
746 state[2] += c;
747 state[3] += d;
748 state[4] += e;
749 /* Wipe variables */
750 a = b = c = d = e = 0;
751 memset(block32, 0x00, sizeof(block32));
752}
753
754
755static void sha1_init(void *ctx)
756{
757 struct sha1_ctx *sctx = ctx;
758 static const struct sha1_ctx initstate = {
759 0,
760 { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 },
761 { 0, }
762 };
763
764 *sctx = initstate;
765}
766
767
768static void sha1_update(void *ctx, const u8 *data, unsigned int len)
769{
770 struct sha1_ctx *sctx = ctx;
771 unsigned int i, j;
772
773 j = (sctx->count >> 3) & 0x3f;
774 sctx->count += len << 3;
775
776 if ((j + len) > 63) {
777 memcpy(&sctx->buffer[j], data, (i = 64 - j));
778 sha1_transform(sctx->state, sctx->buffer);
779 for ( ; i + 63 < len; i += 64)
780 sha1_transform(sctx->state, &data[i]);
781 j = 0;
782 } else
783 i = 0;
784 memcpy(&sctx->buffer[j], &data[i], len - i);
785}
786
787
788/* Add padding and return the message digest. */
789static void sha1_final(void *ctx, u8 *out)
790{
791 struct sha1_ctx *sctx = ctx;
792 u32 i, j, index, padlen;
793 u64 t;
794 u8 bits[8] = { 0, };
795 static const u8 padding[64] = { 0x80, };
796
797 t = sctx->count;
798 bits[7] = 0xff & t; t >>= 8;
799 bits[6] = 0xff & t; t >>= 8;
800 bits[5] = 0xff & t; t >>= 8;
801 bits[4] = 0xff & t; t >>= 8;
802 bits[3] = 0xff & t; t >>= 8;
803 bits[2] = 0xff & t; t >>= 8;
804 bits[1] = 0xff & t; t >>= 8;
805 bits[0] = 0xff & t;
806
807 /* Pad out to 56 mod 64 */
808 index = (sctx->count >> 3) & 0x3f;
809 padlen = (index < 56) ? (56 - index) : ((64+56) - index);
810 sha1_update(sctx, padding, padlen);
811
812 /* Append length */
813 sha1_update(sctx, bits, sizeof(bits));
814
815 /* Store state in digest */
816 for (i = j = 0; i < 5; i++, j += 4) {
817 u32 t2 = sctx->state[i];
818 out[j+3] = t2 & 0xff; t2 >>= 8;
819 out[j+2] = t2 & 0xff; t2 >>= 8;
820 out[j+1] = t2 & 0xff; t2 >>= 8;
821 out[j] = t2 & 0xff;
822 }
823
824 /* Wipe context */
825 memset(sctx, 0, sizeof(*sctx));
826}
827
828
829
830
831/*----------------------------------------------------------------------------
832 * Process identification
833 *----------------------------------------------------------------------------*/
834
835/* This function generates a processes hash table for authentication */
836int tf_get_current_process_hash(void *hash)
837{
838 int result = 0;
839 void *buffer;
840 struct mm_struct *mm;
841 struct vm_area_struct *vma;
842
843 buffer = internal_kmalloc(PAGE_SIZE, GFP_KERNEL);
844 if (buffer == NULL) {
845 dprintk(
846 KERN_ERR "tf_get_current_process_hash:"
847 " Out of memory for buffer!\n");
848 return -ENOMEM;
849 }
850
851 mm = current->mm;
852
853 down_read(&(mm->mmap_sem));
854 for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) {
855 if ((vma->vm_flags & VM_EXECUTABLE) != 0 && vma->vm_file
856 != NULL) {
857 struct dentry *dentry;
858 unsigned long start;
859 unsigned long cur;
860 unsigned long end;
861 struct sha1_ctx sha1;
862
863 dentry = dget(vma->vm_file->f_dentry);
864
865 dprintk(
866 KERN_DEBUG "tf_get_current_process_hash: "
867 "Found executable VMA for inode %lu "
868 "(%lu bytes).\n",
869 dentry->d_inode->i_ino,
870 (unsigned long) (dentry->d_inode->
871 i_size));
872
873 start = do_mmap(vma->vm_file, 0,
874 dentry->d_inode->i_size,
875 PROT_READ | PROT_WRITE | PROT_EXEC,
876 MAP_PRIVATE, 0);
877 if (start < 0) {
878 dprintk(
879 KERN_ERR "tf_get_current_process_hash"
880 "Hash: do_mmap failed (error %d)!\n",
881 (int) start);
882 dput(dentry);
883 result = -EFAULT;
884 goto vma_out;
885 }
886
887 end = start + dentry->d_inode->i_size;
888
889 sha1_init(&sha1);
890 cur = start;
891 while (cur < end) {
892 unsigned long chunk;
893
894 chunk = end - cur;
895 if (chunk > PAGE_SIZE)
896 chunk = PAGE_SIZE;
897 if (copy_from_user(buffer, (const void *) cur,
898 chunk) != 0) {
899 dprintk(
900 KERN_ERR "tf_get_current_"
901 "process_hash: copy_from_user "
902 "failed!\n");
903 result = -EINVAL;
904 (void) do_munmap(mm, start,
905 dentry->d_inode->i_size);
906 dput(dentry);
907 goto vma_out;
908 }
909 sha1_update(&sha1, buffer, chunk);
910 cur += chunk;
911 }
912 sha1_final(&sha1, hash);
913 result = 0;
914
915 (void) do_munmap(mm, start, dentry->d_inode->i_size);
916 dput(dentry);
917 break;
918 }
919 }
920vma_out:
921 up_read(&(mm->mmap_sem));
922
923 internal_kfree(buffer);
924
925 if (result == -ENOENT)
926 dprintk(
927 KERN_ERR "tf_get_current_process_hash: "
928 "No executable VMA found for process!\n");
929 return result;
930}
931
932#ifndef CONFIG_ANDROID
933/* This function hashes the path of the current application.
934 * If data = NULL ,nothing else is added to the hash
935 else add data to the hash
936 */
937int tf_hash_application_path_and_data(char *buffer, void *data,
938 u32 data_len)
939{
940 int result = -ENOENT;
941 char *tmp = NULL;
942 struct mm_struct *mm;
943 struct vm_area_struct *vma;
944
945 tmp = internal_kmalloc(PAGE_SIZE, GFP_KERNEL);
946 if (tmp == NULL) {
947 result = -ENOMEM;
948 goto end;
949 }
950
951 mm = current->mm;
952
953 down_read(&(mm->mmap_sem));
954 for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) {
955 if ((vma->vm_flags & VM_EXECUTABLE) != 0
956 && vma->vm_file != NULL) {
957 struct path *path;
958 char *endpath;
959 size_t pathlen;
960 struct sha1_ctx sha1;
961 u8 hash[SHA1_DIGEST_SIZE];
962
963 path = &vma->vm_file->f_path;
964
965 endpath = d_path(path, tmp, PAGE_SIZE);
966 if (IS_ERR(path)) {
967 result = PTR_ERR(endpath);
968 up_read(&(mm->mmap_sem));
969 goto end;
970 }
971 pathlen = (tmp + PAGE_SIZE) - endpath;
972
973#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
974 {
975 char *c;
976 dprintk(KERN_DEBUG "current process path = ");
977 for (c = endpath;
978 c < tmp + PAGE_SIZE;
979 c++)
980 dprintk("%c", *c);
981
982 dprintk(", uid=%d, euid=%d\n", current_uid(),
983 current_euid());
984 }
985#endif /* defined(CONFIG_TF_DRIVER_DEBUG_SUPPORT) */
986
987 sha1_init(&sha1);
988 sha1_update(&sha1, endpath, pathlen);
989 if (data != NULL) {
990 dprintk(KERN_INFO "current process path: "
991 "Hashing additional data\n");
992 sha1_update(&sha1, data, data_len);
993 }
994 sha1_final(&sha1, hash);
995 memcpy(buffer, hash, sizeof(hash));
996
997 result = 0;
998
999 break;
1000 }
1001 }
1002 up_read(&(mm->mmap_sem));
1003
1004end:
1005 if (tmp != NULL)
1006 internal_kfree(tmp);
1007
1008 return result;
1009}
1010#endif /* !CONFIG_ANDROID */
1011
1012void *internal_kmalloc(size_t size, int priority)
1013{
1014 void *ptr;
1015 struct tf_device *dev = tf_get_device();
1016
1017 ptr = kmalloc(size, priority);
1018
1019 if (ptr != NULL)
1020 atomic_inc(
1021 &dev->stats.stat_memories_allocated);
1022
1023 return ptr;
1024}
1025
1026void internal_kfree(void *ptr)
1027{
1028 struct tf_device *dev = tf_get_device();
1029
1030 if (ptr != NULL)
1031 atomic_dec(
1032 &dev->stats.stat_memories_allocated);
1033 return kfree(ptr);
1034}
1035
1036void internal_vunmap(void *ptr)
1037{
1038 struct tf_device *dev = tf_get_device();
1039
1040 if (ptr != NULL)
1041 atomic_dec(
1042 &dev->stats.stat_memories_allocated);
1043
1044 vunmap((void *) (((unsigned int)ptr) & 0xFFFFF000));
1045}
1046
1047void *internal_vmalloc(size_t size)
1048{
1049 void *ptr;
1050 struct tf_device *dev = tf_get_device();
1051
1052 ptr = vmalloc(size);
1053
1054 if (ptr != NULL)
1055 atomic_inc(
1056 &dev->stats.stat_memories_allocated);
1057
1058 return ptr;
1059}
1060
1061void internal_vfree(void *ptr)
1062{
1063 struct tf_device *dev = tf_get_device();
1064
1065 if (ptr != NULL)
1066 atomic_dec(
1067 &dev->stats.stat_memories_allocated);
1068 return vfree(ptr);
1069}
1070
1071unsigned long internal_get_zeroed_page(int priority)
1072{
1073 unsigned long result;
1074 struct tf_device *dev = tf_get_device();
1075
1076 result = get_zeroed_page(priority);
1077
1078 if (result != 0)
1079 atomic_inc(&dev->stats.
1080 stat_pages_allocated);
1081
1082 return result;
1083}
1084
1085void internal_free_page(unsigned long addr)
1086{
1087 struct tf_device *dev = tf_get_device();
1088
1089 if (addr != 0)
1090 atomic_dec(
1091 &dev->stats.stat_pages_allocated);
1092 return free_page(addr);
1093}
1094
1095int internal_get_user_pages(
1096 struct task_struct *tsk,
1097 struct mm_struct *mm,
1098 unsigned long start,
1099 int len,
1100 int write,
1101 int force,
1102 struct page **pages,
1103 struct vm_area_struct **vmas)
1104{
1105 int result;
1106 struct tf_device *dev = tf_get_device();
1107
1108 result = get_user_pages(
1109 tsk,
1110 mm,
1111 start,
1112 len,
1113 write,
1114 force,
1115 pages,
1116 vmas);
1117
1118 if (result > 0)
1119 atomic_add(result,
1120 &dev->stats.stat_pages_locked);
1121
1122 return result;
1123}
1124
1125void internal_get_page(struct page *page)
1126{
1127 struct tf_device *dev = tf_get_device();
1128
1129 atomic_inc(&dev->stats.stat_pages_locked);
1130
1131 get_page(page);
1132}
1133
1134void internal_page_cache_release(struct page *page)
1135{
1136 struct tf_device *dev = tf_get_device();
1137
1138 atomic_dec(&dev->stats.stat_pages_locked);
1139
1140 page_cache_release(page);
1141}
1142
1143