Skip to content

Commit

Permalink
Merge pull request sancus-tee#37 from gianlu33/sancus-untag
Browse files Browse the repository at this point in the history
Add `sancus_untag` functions and fix `sancus_unwrap_with_key`
  • Loading branch information
jovanbulck authored and gianlu33 committed Nov 4, 2021
1 parent db4f05a commit 4e7c9a8
Showing 1 changed file with 91 additions and 20 deletions.
111 changes: 91 additions & 20 deletions src/sancus_support/sm_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ always_inline int is_buffer_outside_region(void *start_p, void *end_p,
uintptr_t end = (uintptr_t) end_p;
uintptr_t buf = (uintptr_t) buf_p;
uintptr_t buf_end;

// make sure start < end, otherwise return false
if (start >= end) {
return 0;
Expand All @@ -332,16 +332,55 @@ always_inline int is_buffer_outside_region(void *start_p, void *end_p,
buf_end = buf;
}

/* check for int overflow and finally validate `buf` falls outside */
/* check for int overflow and finally validate `buf` falls outside */
if( (buf <= buf_end) && ((end <= buf) || (start > buf_end))) {
return 1;
}

return 0;
}

/**
* Performs constant time comparison between to buffers
* Returns 0 if the first `n` bytes of the two buffers are equal, -1 otherwise
* NOTE: Function copied from NaCL's libsodium, re-use allowed under ISC license.
*/
always_inline int constant_time_cmp(const unsigned char *x_,
const unsigned char *y_,
const unsigned int n)
{
const volatile unsigned char *volatile x =
(const volatile unsigned char *volatile) x_;
const volatile unsigned char *volatile y =
(const volatile unsigned char *volatile) y_;
volatile unsigned int d = 0U;
int i;

for (i = 0; i < n; i++) {
d |= x[i] ^ y[i];
}

return (1 & ((d - 1) >> 8)) - 1;
}

/**
* Disable the protection of the calling module.
* DANGEROUS: Disable the protection of the calling module.
*
* NOTE: On Sancus cores that support interruptible enclaves, the
* compiler/runtime does _not_ transparently take care of atomicity concerns
* when disabling enclaves, i.e., secure linking is currently not meant to be
* interrupt-safe. If this SM is being called by another one, the other SM may
* be interrupted between the sm_verify check and the actual call into the
* function. If sancus_disable is executed in this window, an attacker could
* fully control the SM call and the return to the other SM.
* Thus, for callee SMs that may disable themselves, local attestation through
* sancus_verify and jumping to callee SM entry point needs to happen
* atomically. This concern is left to the application developer, e.g., SMs
* should not call sancus_disable when they might still be called by a
* trusted caller SM (and the caller SM can verify this is indeed not the case
* by local attestation of the callee SM code section).
*/
always_inline void sancus_disable(void *continuation)
{
Expand Down Expand Up @@ -492,6 +531,51 @@ always_inline int sancus_wrap(const void* ad, size_t ad_len,
return sancus_wrap_with_key(NULL, ad, ad_len, body, body_len, cipher, tag);
}

/**
* The same as sancus_wrap_with_key() but only produces the MAC of the message.
*/
always_inline int sancus_tag_with_key(const void* key,
const void* body, size_t body_len,
void* tag)
{
return sancus_wrap_with_key(key, body, body_len, NULL, 0, NULL, tag);
}

/**
* The same as sancus_wrap() but only produces the MAC of the message.
*/
always_inline int sancus_tag(const void* body, size_t body_len, void* tag)
{
return sancus_wrap(body, body_len, NULL, 0, NULL, tag);
}

/**
* Verify if the MAC computed over `body` matches with the content of `tag`
*/
always_inline int sancus_untag_with_key(const void* key, const void* body,
size_t body_len, const void* tag)
{
unsigned char computed_tag[SANCUS_TAG_SIZE];

// compute MAC over `body`
if ( !sancus_tag_with_key(key, body, body_len, computed_tag) ) {
return 0;
}

// compare MAC with provided reference `tag`
return (constant_time_cmp(tag, computed_tag, SANCUS_TAG_SIZE) == 0);
}

/**
* Verify if the MAC computed over `body` matches with the content of `tag`
*
* This is the same as sancus_untag_with_key using the key of the caller module.
*/
always_inline int sancus_untag(const void* body, size_t body_len, const void* tag)
{
return sancus_untag_with_key(NULL, body, body_len, tag);
}

/**
* Unwrap a message using the Sancus authenticated encryption features.
*
Expand All @@ -503,6 +587,11 @@ always_inline int sancus_unwrap_with_key(const void* key,
size_t cipher_len,
const void* tag, void* body)
{
// fix: if cipher_len is zero, just compare the MACs using sancus_untag
if(cipher_len == 0) {
return sancus_untag_with_key(key, ad, ad_len, tag);
}

void* ad_end = (char*)ad + ad_len;
void* cipher_end = (char*)cipher + cipher_len;
int ret;
Expand Down Expand Up @@ -542,24 +631,6 @@ always_inline int sancus_unwrap(const void* ad, size_t ad_len,
tag, body);
}

/**
* The same as sancus_wrap() but only produces the MAC of the message.
*/
always_inline int sancus_tag(const void* body, size_t body_len, void* tag)
{
return sancus_wrap(body, body_len, NULL, 0, NULL, tag);
}

/**
* The same as sancus_wrap_with_key() but only produces the MAC of the message.
*/
always_inline int sancus_tag_with_key(const void* key,
const void* body, size_t body_len,
void* tag)
{
return sancus_wrap_with_key(key, body, body_len, NULL, 0, NULL, tag);
}

/**
* Get the Sancus ID of the module loaded at @p addr.
*/
Expand Down

0 comments on commit 4e7c9a8

Please sign in to comment.