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