Pagefault when using cryptographic crates in TEE

Hi there,

I'm not sure if my question is a perfect match for this category since it does not relate to an embedded target but instead relates to an bare metal target riscv64gc-unknown-none-elf targeting the Keystone TEE (think Intel SGX). Within this enclave I've configured an memory region of 32MiB which should fit the binary as well as stack & heap quite easily, the stack is configured to start at 0x0000000040000000 and to grow downward to 1MB in size. So far so good, originally I've started to encounter an page fault when using the sha2 create via ed25519-dalek however the problem also occurs when trying to encrypt some test data using chacha20 which leads me to believe the problem isn't specific to sha2.

I've also tested my code(as far as possible without the TEE specific apis) on x86_64-linux as well as riscv64-linux, the tests complete on those platforms without any issues, even with an stack as small as 64k. Which leads me to the conclusion that stack space is not the problem.

Minimal example:

/// #define EAPP_ENTRY __attribute__((__section__(".text._start")))
  #[cfg(keystone)]
  #[no_mangle]
  #[link_section = ".text._start"]
  pub extern "C" fn _start() {
      use sha2::{Digest, Sha512};

      {
          let mut hasher = Sha512::new();
          hasher.update(b"Test");
          let hash512 = hasher.finalize(); // page fault here
          unsafe { core::ptr::read_volatile(&hash512); }
      }
      main();
  }

Would it be possible that the stack within the TEE is setup incorrectly? The rust binary is called by an loader written in C which calls the _start function in the TEE app binary.

Are sure that you handle all sections properly? For example, statics may be stored in the rodata section, which is separate from the text section holding executable code.

You need to minimize your example further. Start with calling the compress512 function directly. If it still fails, copy its source code and continue to cut stuff to find what exactly causes the issue.

1 Like

Got one step further, statics were not the problem, it rather was an misaligned stack. Sha512 works with an fixed stack pointer

fn sp() -> usize {
    let sp: usize;
    unsafe {
        core::arch::asm!("mv {}, sp", out(reg) sp);
    }
    sp
}


    let align = (sp() % 16) as isize * -1;
    unsafe {
        core::arch::asm!(
            "add sp, sp, {x}",
            x = in(reg) align
        )
    };

However loading an DER encoded ed25519 private key still page faults deep in the der crate.

How big is the stack you are running on?

1M, the fault occurs right at the end of the stack

If you get a stack overflow as seems to be the case here, you will need to increase the size of the stack.

Thats not the issue, the code runs on Linux using 64k of stack, there is no way it needs more than one Meg in the TEE. My guess would be another alignment issue