Skip to content

SecureShield Programming

Claudiu Zissulescu edited this page May 9, 2017 · 1 revision

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.