-
Notifications
You must be signed in to change notification settings - Fork 15
SecureShield Programming
A secure-callable API is a set of functions executing in secure mode that can be called from code executing in normal mode. The processor contains a special function call instruction, SJLI, that the compiler uses to implement a secure-mode API. This instruction transfers execution from normal mode to secure mode. Any other call or jump into secure mode from normal mode results in a processor exception.
The GNU tools support a secure-callable API with a two-executable approach:
- One linked executable contains the secure-mode code;
- The second linked executable contains the normal-mode code.
The normal-mode code is compiled normally—no special code is generated for calls to the secure-mode API. However, such calls are resolved by the linker in the normal executable with special function entry points that transfer control to the normal executable using the SJLI instruction. In the secure-mode executable, functions that are designate as belonging to the secure API need an index into the SJLI table. Also the runtime initialization for the secure-mode needs to be carried on by the user.
To indicate to the compiler that a secure-mode function is callable from normal mode, you can use __attribute__((secure_call (IndexNumber))) with secure-callable function. Where IndexNumber is the entry of that particular function into the SJLI table.
Using function pointer of a secure call function is not supported. However, one can make a stub which can be called indirectly, the stub itself calls the secure call normally.
Let us consider the following example:
#include <stdio.h>
extern int foo (int) __attribute__((secure_call(2)));
int bar (void)
{
printf ("%d\n", foo (100));
return 0;
}
int bar2 (void)
{
return foo(100);
}
Where function foo() is an external secure function located at index 2 in the SJLI table.
The result is:
.cpu EM
.section .rodata.str1.4,"aMS",@progbits,1
.align 4
.LC0:
.string "%d\n"
.section .text
.align 4
.global bar
.type bar, @function
bar:
push_s blink
mov_s r0,100 ;3
sjli 2 ; @foo
mov_s r1,r0 ;4
mov_s r0,@.LC0 ;14
bl @printf;1
pop_s blink
j_s.d [blink]
mov_s r0,0 ;3
.size bar, .-bar
.align 4
.global bar2
.type bar2, @function
bar2:
push_s blink
mov_s r0,100 ;3
sjli 2 ; @foo
pop_s blink
j_s [blink]
.size bar2, .-bar2
Where, we can easily spot the call to foo() function via SJLI instruction.