SecureShield Programming

SecureShield API

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.

Identifying the Secure-Callable APIs

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.

Programming Cautions

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.

Example

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.