Implementing a monotonic counter with Intel SGX

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite
1












Here is my program where I create, increase and read a monotonic counter. Because I am new with Intel SGX. ÃŽÂ’elow I show you what I have done until now, because I am not sure if this is the right way to do it. Is that code safe, trusted and isolated? May I have to add something else? Or do I have to do it differently?



How can I use that code? I have made a Java program and with the help of JNI, I call these three functions:



  • create_counter(void)

  • increment_counter(void)

  • read_counter(uint32_t *ctr)

I don't do anything else with that part. Just compile that code and then I run my java program and I call these functions.



Enclave.cpp:



#include "Enclave_t.h"
#include "sgx_tae_service.h"
#include "sgx.h"
#include "sgx_tcrypto.h"
#include <stdio.h>
#include "sgx_trts.h"
#include "Enclave.h"
#include <string.h>
#include <sgx_cpuid.h>
#include <cstring>

// monotonic counter
sgx_mc_uuid_t counter_uuid;
void check_sgx_status(sgx_status_t &ret);

uint32_t latest_counter;

void ecall_sgx_read_rand(unsigned char *ptr, int len)

sgx_status_t ret = sgx_read_rand(ptr, len);
if (ret != SGX_SUCCESS)
abort();


int test_ecc(void)
int i;
sgx_status_t ret;
sgx_ecc_state_handle_t ecc_handle;
sgx_ec256_private_t p_private;
sgx_ec256_public_t p_public;
sgx_ec256_signature_t p_signature;

uint8_t sample_data[8]
= 0x12, 0x13, 0x3f, 0x00,
0x9a, 0x02, 0x10, 0x53;

ret = sgx_ecc256_open_context(&ecc_handle);
if (ret != SGX_SUCCESS)
switch (ret)
case SGX_ERROR_OUT_OF_MEMORY:
ocall_print("SGX_ERROR_OUT_OF_MEMORY");
break;
case SGX_ERROR_UNEXPECTED:
ocall_print("SGX_ERROR_UNEXPECTED");
break;


// create private, public key pair
ret = sgx_ecc256_create_key_pair(&p_private, &p_public, ecc_handle);
ocall_print("ecc private key");
ocall_uint8_t_print(p_private.r, SGX_ECP256_KEY_SIZE);

ocall_print("ecc public key.gx");
ocall_uint8_t_print(p_public.gx, SGX_ECP256_KEY_SIZE);
ocall_print("ecc public key.gy");
ocall_uint8_t_print(p_public.gy, SGX_ECP256_KEY_SIZE);

// create digital signature used ecc
ret = sgx_ecdsa_sign(sample_data,
sizeof(sample_data) / sizeof(sample_data[0]),
&p_private,
&p_signature,
ecc_handle);

ocall_print("ecdsa signature x");
ocall_uint32_t_print(p_signature.x, SGX_NISTP_ECP256_KEY_SIZE);
ocall_print("ecdsa signature y");
ocall_uint32_t_print(p_signature.y, SGX_NISTP_ECP256_KEY_SIZE);

if (ret != SGX_SUCCESS)
ocall_print("ecdsa sign error");


// print p_signature
uint8_t p_result;
ret = sgx_ecdsa_verify(sample_data,
8,
&p_public,
&p_signature,
&p_result,
ecc_handle);
ocall_print("verify result");
ocall_uint8_t_print(&p_result, 1); // 0 on success, 1 on fail

ret = sgx_ecc256_close_context(ecc_handle);
if (ret != SGX_SUCCESS)
ocall_print("ecc256 close fails");


sgx_sha256_hash_t p_hash;
sgx_sha256_msg(sample_data, 8, &p_hash);
ocall_print("sha256");
ocall_uint8_t_print(p_hash, SGX_SHA256_HASH_SIZE);





uint32_t create_counter(void)
sgx_status_t ret;
int busy_retry_times = 2;

do
ret = sgx_create_pse_session();
while (ret == SGX_ERROR_BUSY && busy_retry_times--);
if (ret != SGX_SUCCESS)
return ret;

ret = sgx_create_monotonic_counter(&counter_uuid, &latest_counter);
check_sgx_status(ret);
sgx_close_pse_session();

return latest_counter;


uint32_t increment_counter(void)
sgx_status_t ret;
int busy_retry_times = 2;

do
ret = sgx_create_pse_session();
while (ret == SGX_ERROR_BUSY && busy_retry_times--);
if (ret != SGX_SUCCESS)
return ret;

ret = sgx_increment_monotonic_counter(&counter_uuid, &latest_counter);
check_sgx_status(ret);
sgx_close_pse_session();
return latest_counter;


uint32_t read_counter(uint32_t *ctr)
sgx_status_t ret ;
int busy_retry_times = 2;

do
ret = sgx_create_pse_session();
while (ret == SGX_ERROR_BUSY && busy_retry_times--);
if (ret != SGX_SUCCESS)
return ret;

ret = sgx_read_monotonic_counter(&counter_uuid, &latest_counter);
check_sgx_status(ret);
sgx_close_pse_session();
*ctr = latest_counter;
return latest_counter;


uint32_t destroy_counter(void)
sgx_status_t ret ;
int busy_retry_times = 2;

do
ret = sgx_create_pse_session();
while (ret == SGX_ERROR_BUSY && busy_retry_times--);
if (ret != SGX_SUCCESS)
return ret;

ret = sgx_destroy_monotonic_counter(&counter_uuid);
check_sgx_status(ret);
sgx_close_pse_session();
return latest_counter;


void check_sgx_status(sgx_status_t &ret)
if(ret != SGX_SUCCESS)

switch(ret)

case SGX_ERROR_SERVICE_UNAVAILABLE:
/* Architecture Enclave Service Manager is not installed or not
working properly.*/
break;
case SGX_ERROR_SERVICE_TIMEOUT:
/* retry the operation later*/
break;
case SGX_ERROR_BUSY:
/* retry the operation later*/
break;
case SGX_ERROR_MC_OVER_QUOTA:
/* SGX Platform Service enforces a quota scheme on the Monotonic
Counters a SGX app can maintain. the enclave has reached the
quota.*/
break;
case SGX_ERROR_MC_USED_UP:
/* the Monotonic Counter has been used up and cannot create
Monotonic Counter anymore.*/
break;
default:
/*other errors*/
break;










share|improve this question



























    up vote
    0
    down vote

    favorite
    1












    Here is my program where I create, increase and read a monotonic counter. Because I am new with Intel SGX. ÃŽÂ’elow I show you what I have done until now, because I am not sure if this is the right way to do it. Is that code safe, trusted and isolated? May I have to add something else? Or do I have to do it differently?



    How can I use that code? I have made a Java program and with the help of JNI, I call these three functions:



    • create_counter(void)

    • increment_counter(void)

    • read_counter(uint32_t *ctr)

    I don't do anything else with that part. Just compile that code and then I run my java program and I call these functions.



    Enclave.cpp:



    #include "Enclave_t.h"
    #include "sgx_tae_service.h"
    #include "sgx.h"
    #include "sgx_tcrypto.h"
    #include <stdio.h>
    #include "sgx_trts.h"
    #include "Enclave.h"
    #include <string.h>
    #include <sgx_cpuid.h>
    #include <cstring>

    // monotonic counter
    sgx_mc_uuid_t counter_uuid;
    void check_sgx_status(sgx_status_t &ret);

    uint32_t latest_counter;

    void ecall_sgx_read_rand(unsigned char *ptr, int len)

    sgx_status_t ret = sgx_read_rand(ptr, len);
    if (ret != SGX_SUCCESS)
    abort();


    int test_ecc(void)
    int i;
    sgx_status_t ret;
    sgx_ecc_state_handle_t ecc_handle;
    sgx_ec256_private_t p_private;
    sgx_ec256_public_t p_public;
    sgx_ec256_signature_t p_signature;

    uint8_t sample_data[8]
    = 0x12, 0x13, 0x3f, 0x00,
    0x9a, 0x02, 0x10, 0x53;

    ret = sgx_ecc256_open_context(&ecc_handle);
    if (ret != SGX_SUCCESS)
    switch (ret)
    case SGX_ERROR_OUT_OF_MEMORY:
    ocall_print("SGX_ERROR_OUT_OF_MEMORY");
    break;
    case SGX_ERROR_UNEXPECTED:
    ocall_print("SGX_ERROR_UNEXPECTED");
    break;


    // create private, public key pair
    ret = sgx_ecc256_create_key_pair(&p_private, &p_public, ecc_handle);
    ocall_print("ecc private key");
    ocall_uint8_t_print(p_private.r, SGX_ECP256_KEY_SIZE);

    ocall_print("ecc public key.gx");
    ocall_uint8_t_print(p_public.gx, SGX_ECP256_KEY_SIZE);
    ocall_print("ecc public key.gy");
    ocall_uint8_t_print(p_public.gy, SGX_ECP256_KEY_SIZE);

    // create digital signature used ecc
    ret = sgx_ecdsa_sign(sample_data,
    sizeof(sample_data) / sizeof(sample_data[0]),
    &p_private,
    &p_signature,
    ecc_handle);

    ocall_print("ecdsa signature x");
    ocall_uint32_t_print(p_signature.x, SGX_NISTP_ECP256_KEY_SIZE);
    ocall_print("ecdsa signature y");
    ocall_uint32_t_print(p_signature.y, SGX_NISTP_ECP256_KEY_SIZE);

    if (ret != SGX_SUCCESS)
    ocall_print("ecdsa sign error");


    // print p_signature
    uint8_t p_result;
    ret = sgx_ecdsa_verify(sample_data,
    8,
    &p_public,
    &p_signature,
    &p_result,
    ecc_handle);
    ocall_print("verify result");
    ocall_uint8_t_print(&p_result, 1); // 0 on success, 1 on fail

    ret = sgx_ecc256_close_context(ecc_handle);
    if (ret != SGX_SUCCESS)
    ocall_print("ecc256 close fails");


    sgx_sha256_hash_t p_hash;
    sgx_sha256_msg(sample_data, 8, &p_hash);
    ocall_print("sha256");
    ocall_uint8_t_print(p_hash, SGX_SHA256_HASH_SIZE);





    uint32_t create_counter(void)
    sgx_status_t ret;
    int busy_retry_times = 2;

    do
    ret = sgx_create_pse_session();
    while (ret == SGX_ERROR_BUSY && busy_retry_times--);
    if (ret != SGX_SUCCESS)
    return ret;

    ret = sgx_create_monotonic_counter(&counter_uuid, &latest_counter);
    check_sgx_status(ret);
    sgx_close_pse_session();

    return latest_counter;


    uint32_t increment_counter(void)
    sgx_status_t ret;
    int busy_retry_times = 2;

    do
    ret = sgx_create_pse_session();
    while (ret == SGX_ERROR_BUSY && busy_retry_times--);
    if (ret != SGX_SUCCESS)
    return ret;

    ret = sgx_increment_monotonic_counter(&counter_uuid, &latest_counter);
    check_sgx_status(ret);
    sgx_close_pse_session();
    return latest_counter;


    uint32_t read_counter(uint32_t *ctr)
    sgx_status_t ret ;
    int busy_retry_times = 2;

    do
    ret = sgx_create_pse_session();
    while (ret == SGX_ERROR_BUSY && busy_retry_times--);
    if (ret != SGX_SUCCESS)
    return ret;

    ret = sgx_read_monotonic_counter(&counter_uuid, &latest_counter);
    check_sgx_status(ret);
    sgx_close_pse_session();
    *ctr = latest_counter;
    return latest_counter;


    uint32_t destroy_counter(void)
    sgx_status_t ret ;
    int busy_retry_times = 2;

    do
    ret = sgx_create_pse_session();
    while (ret == SGX_ERROR_BUSY && busy_retry_times--);
    if (ret != SGX_SUCCESS)
    return ret;

    ret = sgx_destroy_monotonic_counter(&counter_uuid);
    check_sgx_status(ret);
    sgx_close_pse_session();
    return latest_counter;


    void check_sgx_status(sgx_status_t &ret)
    if(ret != SGX_SUCCESS)

    switch(ret)

    case SGX_ERROR_SERVICE_UNAVAILABLE:
    /* Architecture Enclave Service Manager is not installed or not
    working properly.*/
    break;
    case SGX_ERROR_SERVICE_TIMEOUT:
    /* retry the operation later*/
    break;
    case SGX_ERROR_BUSY:
    /* retry the operation later*/
    break;
    case SGX_ERROR_MC_OVER_QUOTA:
    /* SGX Platform Service enforces a quota scheme on the Monotonic
    Counters a SGX app can maintain. the enclave has reached the
    quota.*/
    break;
    case SGX_ERROR_MC_USED_UP:
    /* the Monotonic Counter has been used up and cannot create
    Monotonic Counter anymore.*/
    break;
    default:
    /*other errors*/
    break;










    share|improve this question























      up vote
      0
      down vote

      favorite
      1









      up vote
      0
      down vote

      favorite
      1






      1





      Here is my program where I create, increase and read a monotonic counter. Because I am new with Intel SGX. ÃŽÂ’elow I show you what I have done until now, because I am not sure if this is the right way to do it. Is that code safe, trusted and isolated? May I have to add something else? Or do I have to do it differently?



      How can I use that code? I have made a Java program and with the help of JNI, I call these three functions:



      • create_counter(void)

      • increment_counter(void)

      • read_counter(uint32_t *ctr)

      I don't do anything else with that part. Just compile that code and then I run my java program and I call these functions.



      Enclave.cpp:



      #include "Enclave_t.h"
      #include "sgx_tae_service.h"
      #include "sgx.h"
      #include "sgx_tcrypto.h"
      #include <stdio.h>
      #include "sgx_trts.h"
      #include "Enclave.h"
      #include <string.h>
      #include <sgx_cpuid.h>
      #include <cstring>

      // monotonic counter
      sgx_mc_uuid_t counter_uuid;
      void check_sgx_status(sgx_status_t &ret);

      uint32_t latest_counter;

      void ecall_sgx_read_rand(unsigned char *ptr, int len)

      sgx_status_t ret = sgx_read_rand(ptr, len);
      if (ret != SGX_SUCCESS)
      abort();


      int test_ecc(void)
      int i;
      sgx_status_t ret;
      sgx_ecc_state_handle_t ecc_handle;
      sgx_ec256_private_t p_private;
      sgx_ec256_public_t p_public;
      sgx_ec256_signature_t p_signature;

      uint8_t sample_data[8]
      = 0x12, 0x13, 0x3f, 0x00,
      0x9a, 0x02, 0x10, 0x53;

      ret = sgx_ecc256_open_context(&ecc_handle);
      if (ret != SGX_SUCCESS)
      switch (ret)
      case SGX_ERROR_OUT_OF_MEMORY:
      ocall_print("SGX_ERROR_OUT_OF_MEMORY");
      break;
      case SGX_ERROR_UNEXPECTED:
      ocall_print("SGX_ERROR_UNEXPECTED");
      break;


      // create private, public key pair
      ret = sgx_ecc256_create_key_pair(&p_private, &p_public, ecc_handle);
      ocall_print("ecc private key");
      ocall_uint8_t_print(p_private.r, SGX_ECP256_KEY_SIZE);

      ocall_print("ecc public key.gx");
      ocall_uint8_t_print(p_public.gx, SGX_ECP256_KEY_SIZE);
      ocall_print("ecc public key.gy");
      ocall_uint8_t_print(p_public.gy, SGX_ECP256_KEY_SIZE);

      // create digital signature used ecc
      ret = sgx_ecdsa_sign(sample_data,
      sizeof(sample_data) / sizeof(sample_data[0]),
      &p_private,
      &p_signature,
      ecc_handle);

      ocall_print("ecdsa signature x");
      ocall_uint32_t_print(p_signature.x, SGX_NISTP_ECP256_KEY_SIZE);
      ocall_print("ecdsa signature y");
      ocall_uint32_t_print(p_signature.y, SGX_NISTP_ECP256_KEY_SIZE);

      if (ret != SGX_SUCCESS)
      ocall_print("ecdsa sign error");


      // print p_signature
      uint8_t p_result;
      ret = sgx_ecdsa_verify(sample_data,
      8,
      &p_public,
      &p_signature,
      &p_result,
      ecc_handle);
      ocall_print("verify result");
      ocall_uint8_t_print(&p_result, 1); // 0 on success, 1 on fail

      ret = sgx_ecc256_close_context(ecc_handle);
      if (ret != SGX_SUCCESS)
      ocall_print("ecc256 close fails");


      sgx_sha256_hash_t p_hash;
      sgx_sha256_msg(sample_data, 8, &p_hash);
      ocall_print("sha256");
      ocall_uint8_t_print(p_hash, SGX_SHA256_HASH_SIZE);





      uint32_t create_counter(void)
      sgx_status_t ret;
      int busy_retry_times = 2;

      do
      ret = sgx_create_pse_session();
      while (ret == SGX_ERROR_BUSY && busy_retry_times--);
      if (ret != SGX_SUCCESS)
      return ret;

      ret = sgx_create_monotonic_counter(&counter_uuid, &latest_counter);
      check_sgx_status(ret);
      sgx_close_pse_session();

      return latest_counter;


      uint32_t increment_counter(void)
      sgx_status_t ret;
      int busy_retry_times = 2;

      do
      ret = sgx_create_pse_session();
      while (ret == SGX_ERROR_BUSY && busy_retry_times--);
      if (ret != SGX_SUCCESS)
      return ret;

      ret = sgx_increment_monotonic_counter(&counter_uuid, &latest_counter);
      check_sgx_status(ret);
      sgx_close_pse_session();
      return latest_counter;


      uint32_t read_counter(uint32_t *ctr)
      sgx_status_t ret ;
      int busy_retry_times = 2;

      do
      ret = sgx_create_pse_session();
      while (ret == SGX_ERROR_BUSY && busy_retry_times--);
      if (ret != SGX_SUCCESS)
      return ret;

      ret = sgx_read_monotonic_counter(&counter_uuid, &latest_counter);
      check_sgx_status(ret);
      sgx_close_pse_session();
      *ctr = latest_counter;
      return latest_counter;


      uint32_t destroy_counter(void)
      sgx_status_t ret ;
      int busy_retry_times = 2;

      do
      ret = sgx_create_pse_session();
      while (ret == SGX_ERROR_BUSY && busy_retry_times--);
      if (ret != SGX_SUCCESS)
      return ret;

      ret = sgx_destroy_monotonic_counter(&counter_uuid);
      check_sgx_status(ret);
      sgx_close_pse_session();
      return latest_counter;


      void check_sgx_status(sgx_status_t &ret)
      if(ret != SGX_SUCCESS)

      switch(ret)

      case SGX_ERROR_SERVICE_UNAVAILABLE:
      /* Architecture Enclave Service Manager is not installed or not
      working properly.*/
      break;
      case SGX_ERROR_SERVICE_TIMEOUT:
      /* retry the operation later*/
      break;
      case SGX_ERROR_BUSY:
      /* retry the operation later*/
      break;
      case SGX_ERROR_MC_OVER_QUOTA:
      /* SGX Platform Service enforces a quota scheme on the Monotonic
      Counters a SGX app can maintain. the enclave has reached the
      quota.*/
      break;
      case SGX_ERROR_MC_USED_UP:
      /* the Monotonic Counter has been used up and cannot create
      Monotonic Counter anymore.*/
      break;
      default:
      /*other errors*/
      break;










      share|improve this question













      Here is my program where I create, increase and read a monotonic counter. Because I am new with Intel SGX. ÃŽÂ’elow I show you what I have done until now, because I am not sure if this is the right way to do it. Is that code safe, trusted and isolated? May I have to add something else? Or do I have to do it differently?



      How can I use that code? I have made a Java program and with the help of JNI, I call these three functions:



      • create_counter(void)

      • increment_counter(void)

      • read_counter(uint32_t *ctr)

      I don't do anything else with that part. Just compile that code and then I run my java program and I call these functions.



      Enclave.cpp:



      #include "Enclave_t.h"
      #include "sgx_tae_service.h"
      #include "sgx.h"
      #include "sgx_tcrypto.h"
      #include <stdio.h>
      #include "sgx_trts.h"
      #include "Enclave.h"
      #include <string.h>
      #include <sgx_cpuid.h>
      #include <cstring>

      // monotonic counter
      sgx_mc_uuid_t counter_uuid;
      void check_sgx_status(sgx_status_t &ret);

      uint32_t latest_counter;

      void ecall_sgx_read_rand(unsigned char *ptr, int len)

      sgx_status_t ret = sgx_read_rand(ptr, len);
      if (ret != SGX_SUCCESS)
      abort();


      int test_ecc(void)
      int i;
      sgx_status_t ret;
      sgx_ecc_state_handle_t ecc_handle;
      sgx_ec256_private_t p_private;
      sgx_ec256_public_t p_public;
      sgx_ec256_signature_t p_signature;

      uint8_t sample_data[8]
      = 0x12, 0x13, 0x3f, 0x00,
      0x9a, 0x02, 0x10, 0x53;

      ret = sgx_ecc256_open_context(&ecc_handle);
      if (ret != SGX_SUCCESS)
      switch (ret)
      case SGX_ERROR_OUT_OF_MEMORY:
      ocall_print("SGX_ERROR_OUT_OF_MEMORY");
      break;
      case SGX_ERROR_UNEXPECTED:
      ocall_print("SGX_ERROR_UNEXPECTED");
      break;


      // create private, public key pair
      ret = sgx_ecc256_create_key_pair(&p_private, &p_public, ecc_handle);
      ocall_print("ecc private key");
      ocall_uint8_t_print(p_private.r, SGX_ECP256_KEY_SIZE);

      ocall_print("ecc public key.gx");
      ocall_uint8_t_print(p_public.gx, SGX_ECP256_KEY_SIZE);
      ocall_print("ecc public key.gy");
      ocall_uint8_t_print(p_public.gy, SGX_ECP256_KEY_SIZE);

      // create digital signature used ecc
      ret = sgx_ecdsa_sign(sample_data,
      sizeof(sample_data) / sizeof(sample_data[0]),
      &p_private,
      &p_signature,
      ecc_handle);

      ocall_print("ecdsa signature x");
      ocall_uint32_t_print(p_signature.x, SGX_NISTP_ECP256_KEY_SIZE);
      ocall_print("ecdsa signature y");
      ocall_uint32_t_print(p_signature.y, SGX_NISTP_ECP256_KEY_SIZE);

      if (ret != SGX_SUCCESS)
      ocall_print("ecdsa sign error");


      // print p_signature
      uint8_t p_result;
      ret = sgx_ecdsa_verify(sample_data,
      8,
      &p_public,
      &p_signature,
      &p_result,
      ecc_handle);
      ocall_print("verify result");
      ocall_uint8_t_print(&p_result, 1); // 0 on success, 1 on fail

      ret = sgx_ecc256_close_context(ecc_handle);
      if (ret != SGX_SUCCESS)
      ocall_print("ecc256 close fails");


      sgx_sha256_hash_t p_hash;
      sgx_sha256_msg(sample_data, 8, &p_hash);
      ocall_print("sha256");
      ocall_uint8_t_print(p_hash, SGX_SHA256_HASH_SIZE);





      uint32_t create_counter(void)
      sgx_status_t ret;
      int busy_retry_times = 2;

      do
      ret = sgx_create_pse_session();
      while (ret == SGX_ERROR_BUSY && busy_retry_times--);
      if (ret != SGX_SUCCESS)
      return ret;

      ret = sgx_create_monotonic_counter(&counter_uuid, &latest_counter);
      check_sgx_status(ret);
      sgx_close_pse_session();

      return latest_counter;


      uint32_t increment_counter(void)
      sgx_status_t ret;
      int busy_retry_times = 2;

      do
      ret = sgx_create_pse_session();
      while (ret == SGX_ERROR_BUSY && busy_retry_times--);
      if (ret != SGX_SUCCESS)
      return ret;

      ret = sgx_increment_monotonic_counter(&counter_uuid, &latest_counter);
      check_sgx_status(ret);
      sgx_close_pse_session();
      return latest_counter;


      uint32_t read_counter(uint32_t *ctr)
      sgx_status_t ret ;
      int busy_retry_times = 2;

      do
      ret = sgx_create_pse_session();
      while (ret == SGX_ERROR_BUSY && busy_retry_times--);
      if (ret != SGX_SUCCESS)
      return ret;

      ret = sgx_read_monotonic_counter(&counter_uuid, &latest_counter);
      check_sgx_status(ret);
      sgx_close_pse_session();
      *ctr = latest_counter;
      return latest_counter;


      uint32_t destroy_counter(void)
      sgx_status_t ret ;
      int busy_retry_times = 2;

      do
      ret = sgx_create_pse_session();
      while (ret == SGX_ERROR_BUSY && busy_retry_times--);
      if (ret != SGX_SUCCESS)
      return ret;

      ret = sgx_destroy_monotonic_counter(&counter_uuid);
      check_sgx_status(ret);
      sgx_close_pse_session();
      return latest_counter;


      void check_sgx_status(sgx_status_t &ret)
      if(ret != SGX_SUCCESS)

      switch(ret)

      case SGX_ERROR_SERVICE_UNAVAILABLE:
      /* Architecture Enclave Service Manager is not installed or not
      working properly.*/
      break;
      case SGX_ERROR_SERVICE_TIMEOUT:
      /* retry the operation later*/
      break;
      case SGX_ERROR_BUSY:
      /* retry the operation later*/
      break;
      case SGX_ERROR_MC_OVER_QUOTA:
      /* SGX Platform Service enforces a quota scheme on the Monotonic
      Counters a SGX app can maintain. the enclave has reached the
      quota.*/
      break;
      case SGX_ERROR_MC_USED_UP:
      /* the Monotonic Counter has been used up and cannot create
      Monotonic Counter anymore.*/
      break;
      default:
      /*other errors*/
      break;












      share|improve this question












      share|improve this question




      share|improve this question








      edited May 25 at 1:27









      Jamal♦

      30.1k11114225




      30.1k11114225









      asked May 24 at 20:17









      hunter32

      61




      61

























          active

          oldest

          votes











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195116%2fimplementing-a-monotonic-counter-with-intel-sgx%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes










           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195116%2fimplementing-a-monotonic-counter-with-intel-sgx%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation