jiahuimbzuai/CoQuIR huggingface dataset:
//  [c]
sysObjectID_handler(snmp_varbind_t *varbind, snmp_oid_t *oid)
{
  OID(sysObjectID_oid, 1, 3, 6, 1, 4, 1, 54352);
  snmp_api_set_oid(varbind, oid, &sysObjectID_oid);
}
//  [c]
sysObjectID_handler(snmp_varbind_t *varbind, uint32_t *oid)
{
  OID(sysObjectID_oid, 1, 3, 6, 1, 4, 1, 54352);
  snmp_api_set_oid(varbind, oid, sysObjectID_oid);
}
//  [c]
x86_reg X86_insn_reg_intel(unsigned int id, enum cs_ac_type *access)
{
	static bool intel_regs_sorted = false;
	unsigned int first = 0;
	unsigned int last = ARR_SIZE(insn_regs_intel) - 1;
	unsigned int mid;

	if (!intel_regs_sorted) {
		memcpy(insn_regs_intel_sorted, insn_regs_intel,
				sizeof(insn_regs_intel_sorted));
		qsort(insn_regs_intel_sorted,
				ARR_SIZE(insn_regs_intel_sorted),
				sizeof(struct insn_reg), regs_cmp);
		intel_regs_sorted = true;
	}

	if (insn_regs_intel_sorted[0].insn > id ||
			insn_regs_intel_sorted[last].insn < id) {
		return 0;
	}

	while (first <= last) {
		mid = (first + last) / 2;
		if (insn_regs_intel_sorted[mid].insn < id) {
			first = mid + 1;
		} else if (insn_regs_intel_sorted[mid].insn == id) {
			if (access) {
				*access = insn_regs_intel_sorted[mid].access;
			}
			return insn_regs_intel_sorted[mid].reg;
		} else {
			if (mid == 0)
				break;
			last = mid - 1;
		}
	}

	// not found
	return 0;
}
//  [c]
x86_reg X86_insn_reg_intel(unsigned int id, enum cs_ac_type *access)
{
	unsigned int first = 0;
	unsigned int last = ARR_SIZE(insn_regs_intel) - 1;
	unsigned int mid = ARR_SIZE(insn_regs_intel) / 2;

	if (!intel_regs_sorted) {
		memcpy(insn_regs_intel_sorted, insn_regs_intel,
				sizeof(insn_regs_intel_sorted));
		qsort(insn_regs_intel_sorted,
				ARR_SIZE(insn_regs_intel_sorted),
				sizeof(struct insn_reg), regs_cmp);
		intel_regs_sorted = true;
	}

	while (first <= last) {
		if (insn_regs_intel_sorted[mid].insn < id) {
			first = mid + 1;
		} else if (insn_regs_intel_sorted[mid].insn == id) {
			if (access) {
				*access = insn_regs_intel_sorted[mid].access;
			}
			return insn_regs_intel_sorted[mid].reg;
		} else {
			if (mid == 0)
				break;
			last = mid - 1;
		}
		mid = (first + last) / 2;
	}

	// not found
	return 0;
}
//  [c]
static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
					const struct iphdr *iph,
					__be32 saddr, u8 tos,
					int type, int code,
					struct icmp_bxm *param)
{
	struct flowi4 fl4 = {
		.daddr = (param->replyopts.opt.opt.srr ?
			  param->replyopts.opt.opt.faddr : iph->saddr),
		.saddr = saddr,
		.flowi4_tos = RT_TOS(tos),
		.flowi4_proto = IPPROTO_ICMP,
		.fl4_icmp_type = type,
		.fl4_icmp_code = code,
	};
	struct rtable *rt, *rt2;
	int err;

	security_skb_classify_flow(skb_in, flowi4_to_flowi(&fl4));
	rt = __ip_route_output_key(net, &fl4);
	if (IS_ERR(rt))
		return rt;

	/* No need to clone since we're just using its address. */
	rt2 = rt;

	if (!fl4.saddr)
		fl4.saddr = rt->rt_src;

	rt = (struct rtable *) xfrm_lookup(net, &rt->dst,
					   flowi4_to_flowi(&fl4), NULL, 0);
	if (!IS_ERR(rt)) {
		if (rt != rt2)
			return rt;
	} else if (PTR_ERR(rt) == -EPERM) {
		rt = NULL;
	} else
		return rt;

	err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4), AF_INET);
	if (err)
		goto relookup_failed;

	if (inet_addr_type(net, fl4.saddr) == RTN_LOCAL) {
		rt2 = __ip_route_output_key(net, &fl4);
		if (IS_ERR(rt2))
			err = PTR_ERR(rt2);
	} else {
		struct flowi4 fl4_2 = {};
		unsigned long orefdst;

		fl4_2.daddr = fl4.saddr;
		rt2 = ip_route_output_key(net, &fl4_2);
		if (IS_ERR(rt2)) {
			err = PTR_ERR(rt2);
			goto relookup_failed;
		}
		/* Ugh! */
		orefdst = skb_in->_skb_refdst; /* save old refdst */
		err = ip_route_input(skb_in, fl4.daddr, fl4.saddr,
				     RT_TOS(tos), rt2->dst.dev);

		dst_release(&rt2->dst);
		rt2 = skb_rtable(skb_in);
		skb_in->_skb_refdst = orefdst; /* restore old refdst */
	}

	if (err)
		goto relookup_failed;

	rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst,
					    flowi4_to_flowi(&fl4), NULL,
					    XFRM_LOOKUP_ICMP);
	if (!IS_ERR(rt2)) {
		dst_release(&rt->dst);
		rt = rt2;
	} else if (PTR_ERR(rt2) == -EPERM) {
		if (rt)
			dst_release(&rt->dst);
		return rt2;
	} else {
		err = PTR_ERR(rt2);
		goto relookup_failed;
	}
	return rt;

relookup_failed:
	if (rt)
		return rt;
	return ERR_PTR(err);
}
//  [c]
static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
					const struct iphdr *iph,
					__be32 saddr, u8 tos,
					int type, int code,
					struct icmp_bxm *param)
{
	struct flowi4 fl4 = {
		.daddr = (param->replyopts.srr ?
			  param->replyopts.faddr : iph->saddr),
		.saddr = saddr,
		.flowi4_tos = RT_TOS(tos),
		.flowi4_proto = IPPROTO_ICMP,
		.fl4_icmp_type = type,
		.fl4_icmp_code = code,
	};
	struct rtable *rt, *rt2;
	int err;

	security_skb_classify_flow(skb_in, flowi4_to_flowi(&fl4));
	rt = __ip_route_output_key(net, &fl4);
	if (IS_ERR(rt))
		return rt;

	/* No need to clone since we're just using its address. */
	rt2 = rt;

	if (!fl4.saddr)
		fl4.saddr = rt->rt_src;

	rt = (struct rtable *) xfrm_lookup(net, &rt->dst,
					   flowi4_to_flowi(&fl4), NULL, 0);
	if (!IS_ERR(rt)) {
		if (rt != rt2)
			return rt;
	} else if (PTR_ERR(rt) == -EPERM) {
		rt = NULL;
	} else
		return rt;

	err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4), AF_INET);
	if (err)
		goto relookup_failed;

	if (inet_addr_type(net, fl4.saddr) == RTN_LOCAL) {
		rt2 = __ip_route_output_key(net, &fl4);
		if (IS_ERR(rt2))
			err = PTR_ERR(rt2);
	} else {
		struct flowi4 fl4_2 = {};
		unsigned long orefdst;

		fl4_2.daddr = fl4.saddr;
		rt2 = ip_route_output_key(net, &fl4_2);
		if (IS_ERR(rt2)) {
			err = PTR_ERR(rt2);
			goto relookup_failed;
		}
		/* Ugh! */
		orefdst = skb_in->_skb_refdst; /* save old refdst */
		err = ip_route_input(skb_in, fl4.daddr, fl4.saddr,
				     RT_TOS(tos), rt2->dst.dev);

		dst_release(&rt2->dst);
		rt2 = skb_rtable(skb_in);
		skb_in->_skb_refdst = orefdst; /* restore old refdst */
	}

	if (err)
		goto relookup_failed;

	rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst,
					    flowi4_to_flowi(&fl4), NULL,
					    XFRM_LOOKUP_ICMP);
	if (!IS_ERR(rt2)) {
		dst_release(&rt->dst);
		rt = rt2;
	} else if (PTR_ERR(rt2) == -EPERM) {
		if (rt)
			dst_release(&rt->dst);
		return rt2;
	} else {
		err = PTR_ERR(rt2);
		goto relookup_failed;
	}
	return rt;

relookup_failed:
	if (rt)
		return rt;
	return ERR_PTR(err);
}
//  [c]
static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
{
	struct ipcm_cookie ipc;
	struct rtable *rt = skb_rtable(skb);
	struct net *net = dev_net(rt->dst.dev);
	struct sock *sk;
	struct inet_sock *inet;
	__be32 daddr;

	if (ip_options_echo(&icmp_param->replyopts.opt.opt, skb))
		return;

	sk = icmp_xmit_lock(net);
	if (sk == NULL)
		return;
	inet = inet_sk(sk);

	icmp_param->data.icmph.checksum = 0;

	inet->tos = ip_hdr(skb)->tos;
	daddr = ipc.addr = rt->rt_src;
	ipc.opt = NULL;
	ipc.tx_flags = 0;
	if (icmp_param->replyopts.opt.opt.optlen) {
		ipc.opt = &icmp_param->replyopts.opt;
		if (ipc.opt->opt.srr)
			daddr = icmp_param->replyopts.opt.opt.faddr;
	}
	{
		struct flowi4 fl4 = {
			.daddr = daddr,
			.saddr = rt->rt_spec_dst,
			.flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
			.flowi4_proto = IPPROTO_ICMP,
		};
		security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
		rt = ip_route_output_key(net, &fl4);
		if (IS_ERR(rt))
			goto out_unlock;
	}
	if (icmpv4_xrlim_allow(net, rt, icmp_param->data.icmph.type,
			       icmp_param->data.icmph.code))
		icmp_push_reply(icmp_param, &ipc, &rt);
	ip_rt_put(rt);
out_unlock:
	icmp_xmit_unlock(sk);
}
//  [c]
static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
{
	struct ipcm_cookie ipc;
	struct rtable *rt = skb_rtable(skb);
	struct net *net = dev_net(rt->dst.dev);
	struct sock *sk;
	struct inet_sock *inet;
	__be32 daddr;

	if (ip_options_echo(&icmp_param->replyopts, skb))
		return;

	sk = icmp_xmit_lock(net);
	if (sk == NULL)
		return;
	inet = inet_sk(sk);

	icmp_param->data.icmph.checksum = 0;

	inet->tos = ip_hdr(skb)->tos;
	daddr = ipc.addr = rt->rt_src;
	ipc.opt = NULL;
	ipc.tx_flags = 0;
	if (icmp_param->replyopts.optlen) {
		ipc.opt = &icmp_param->replyopts;
		if (ipc.opt->srr)
			daddr = icmp_param->replyopts.faddr;
	}
	{
		struct flowi4 fl4 = {
			.daddr = daddr,
			.saddr = rt->rt_spec_dst,
			.flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
			.flowi4_proto = IPPROTO_ICMP,
		};
		security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
		rt = ip_route_output_key(net, &fl4);
		if (IS_ERR(rt))
			goto out_unlock;
	}
	if (icmpv4_xrlim_allow(net, rt, icmp_param->data.icmph.type,
			       icmp_param->data.icmph.code))
		icmp_push_reply(icmp_param, &ipc, &rt);
	ip_rt_put(rt);
out_unlock:
	icmp_xmit_unlock(sk);
}
//  [c]
void dhcpAddOption(DhcpMessage *message, uint8_t optionCode,
   const void *optionValue, size_t optionLen)
{
   size_t n;
   DhcpOption *option;

   //Point to the very first option
   n = 0;

   //Parse DHCP options
   while(1)
   {
      //Point to the current option
      option = (DhcpOption *) (message->options + n);

      //End option detected?
      if(option->code == DHCP_OPT_END)
         break;

      //Jump to the next option
      n += sizeof(DhcpOption) + option->length;
   }

   //Sanity check
   if(optionLen <= UINT8_MAX)
   {
      //Point to the buffer where the option is to be written
      option = (DhcpOption *) (message->options + n);

      //Option code
      option->code = optionCode;
      //Option length
      option->length = (uint8_t) optionLen;
      //Option value
      osMemcpy(option->value, optionValue, optionLen);

      //Jump to the next option
      n += sizeof(DhcpOption) + option->length;

      //Point to the buffer where the option is to be written
      option = (DhcpOption *) (message->options + n);

      //Always terminate the options field with 255
      option->code = DHCP_OPT_END;
   }
}
//  [c]
void dhcpAddOption(DhcpMessage *message, uint8_t optionCode,
   const void *optionValue, size_t optionLen)
{
   size_t n;
   DhcpOption *option;

   //Point to the very first option
   n = 0;

   //Parse DHCP options
   while(1)
   {
      //Point to the current option
      option = (DhcpOption *) (message->options + n);

      //End option detected?
      if(option->code == DHCP_OPT_END)
         break;

      //Jump to next the next option
      n += sizeof(DhcpOption) + option->length;
   }

   //Sanity check
   if(optionLen <= UINT8_MAX)
   {
      //Point to the buffer where the option is to be written
      option = (DhcpOption *) (message->options + n);

      //Option code
      option->code = optionCode;
      //Option length
      option->length = (uint8_t) optionLen;
      //Option value
      osMemcpy(option->value, optionValue, optionLen);

      //Jump to next the next option
      n += sizeof(DhcpOption) + option->length;

      //Point to the buffer where the option is to be written
      option = (DhcpOption *) (message->options + n);

      //Always terminate the options field with 255
      option->code = DHCP_OPT_END;
   }
}
//  [c]
DhcpOption *dhcpGetOption(const DhcpMessage *message,
   size_t length, uint8_t optionCode)
{
   size_t i;
   DhcpOption *option;

   //Make sure the DHCP header is valid
   if(length >= sizeof(DhcpMessage))
   {
      //Get the length of the options field
      length -= sizeof(DhcpMessage);

      //Loop through the list of options
      for(i = 0; i < length; i++)
      {
         //Point to the current option
         option = (DhcpOption *) (message->options + i);

         //Check option code
         if(option->code == DHCP_OPT_PAD)
         {
            //The pad option can be used to cause subsequent fields to align
            //on word boundaries
         }
         else if(option->code == DHCP_OPT_END)
         {
            //The end option marks the end of valid information in the vendor
            //field
            break;
         }
         else
         {
            //The option code is followed by a one-byte length field
            if((i + 1) >= length)
               break;

            //Check the length of the option
            if((i + sizeof(DhcpOption) + option->length) > length)
               break;

            //Matching option code?
            if(option->code == optionCode)
               return option;

            //Jump to the next option
            i += option->length + 1;
         }
      }
   }

   //The specified option code does not exist
   return NULL;
}
//  [c]
DhcpOption *dhcpGetOption(const DhcpMessage *message,
   size_t length, uint8_t optionCode)
{
   uint_t i;
   DhcpOption *option;

   //Make sure the DHCP header is valid
   if(length < sizeof(DhcpMessage))
      return NULL;
   //Get the length of the options field
   length -= sizeof(DhcpMessage);

   //Parse DHCP options
   for(i = 0; i < length; i++)
   {
      //Point to the current option
      option = (DhcpOption *) (message->options + i);

      //Pad option detected?
      if(option->code == DHCP_OPT_PAD)
         continue;
      //End option detected?
      if(option->code == DHCP_OPT_END)
         break;
      //Check option length
      if((i + 1) >= length || (i + 1 + option->length) >= length)
         break;

      //Current option code matches the specified one?
      if(option->code == optionCode)
         return option;

      //Jump to the next option
      i += option->length + 1;
   }

   //Specified option code not found
   return NULL;
}
//  [c]
static int __init ip6_tunnel_init(void)
{
	int  err;

	err = register_pernet_device(&ip6_tnl_net_ops);
	if (err < 0)
		goto out_pernet;

	err = xfrm6_tunnel_register(&ip4ip6_handler, AF_INET);
	if (err < 0) {
		printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n");
		goto out_ip4ip6;
	}

	err = xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6);
	if (err < 0) {
		printk(KERN_ERR "ip6_tunnel init: can't register ip6ip6\n");
		goto out_ip6ip6;
	}

	return 0;

out_ip6ip6:
	xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET);
out_ip4ip6:
	unregister_pernet_device(&ip6_tnl_net_ops);
out_pernet:
	return err;
}
//  [c]
static int __init ip6_tunnel_init(void)
{
	int  err;

	if (xfrm6_tunnel_register(&ip4ip6_handler, AF_INET)) {
		printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n");
		err = -EAGAIN;
		goto out;
	}

	if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) {
		printk(KERN_ERR "ip6_tunnel init: can't register ip6ip6\n");
		err = -EAGAIN;
		goto unreg_ip4ip6;
	}

	err = register_pernet_device(&ip6_tnl_net_ops);
	if (err < 0)
		goto err_pernet;
	return 0;
err_pernet:
	xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
unreg_ip4ip6:
	xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET);
out:
	return err;
}
//  [c]
void sealHexSEK(int *errStatus, char *errString,
                        uint8_t *encrypted_sek, uint64_t *enc_len, char *sek_hex) {
    CALL_ONCE
    LOG_INFO(__FUNCTION__);
    INIT_ERROR_STATE

    CHECK_STATE(encrypted_sek);
    CHECK_STATE(sek_hex);
    CHECK_STATE(strnlen(sek_hex, 33) == 32)
    

    uint64_t plaintextLen = strlen(sek_hex) + 1;
    
    uint64_t sealedLen = sgx_calc_sealed_data_size(0, plaintextLen);

    sgx_attributes_t attribute_mask;
    attribute_mask.flags = 0xfffffffffffffff3;
    attribute_mask.xfrm = 0x0;
    sgx_misc_select_t misc = 0xF0000000;

    sgx_status_t status = sgx_seal_data_ex(SGX_KEYPOLICY_MRENCLAVE, attribute_mask, misc, 0, NULL, plaintextLen, (uint8_t *) sek_hex, sealedLen,
                                           (sgx_sealed_data_t *) encrypted_sek);
    CHECK_STATUS("seal SEK failed after SEK generation");

    uint64_t encrypt_text_length = sgx_get_encrypt_txt_len((const sgx_sealed_data_t *)encrypted_sek);

    CHECK_STATE(encrypt_text_length = plaintextLen);


    SAFE_CHAR_BUF(unsealedKey, BUF_LEN);
    uint32_t decLen = BUF_LEN;

    uint64_t add_text_length = sgx_get_add_mac_txt_len((const sgx_sealed_data_t *)encrypted_sek);
    CHECK_STATE(add_text_length == 0);
    CHECK_STATE(sgx_is_within_enclave(encrypted_sek,sizeof(sgx_sealed_data_t)));
    status = sgx_unseal_data((const sgx_sealed_data_t *)encrypted_sek, NULL, NULL,
                             (uint8_t *) unsealedKey, &decLen );

    CHECK_STATUS("seal/unseal SEK failed after SEK generation in unseal");
    *enc_len = sealedLen;

    SET_SUCCESS
    clean:
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
void sealHexSEK(int *errStatus, char *errString,
                        uint8_t *encrypted_sek, uint32_t *enc_len, char *sek_hex) {
    CALL_ONCE
    LOG_INFO(__FUNCTION__);
    INIT_ERROR_STATE

    CHECK_STATE(encrypted_sek);
    CHECK_STATE(sek_hex);
    CHECK_STATE(strnlen(sek_hex, 33) == 32)
    

    uint64_t plaintextLen = strlen(sek_hex) + 1;
    
    uint64_t sealedLen = sgx_calc_sealed_data_size(0, plaintextLen);

    sgx_attributes_t attribute_mask;
    attribute_mask.flags = 0xfffffffffffffff3;
    attribute_mask.xfrm = 0x0;
    sgx_misc_select_t misc = 0xF0000000;

    sgx_status_t status = sgx_seal_data_ex(SGX_KEYPOLICY_MRENCLAVE, attribute_mask, misc, 0, NULL, plaintextLen, (uint8_t *) sek_hex, sealedLen,
                                           (sgx_sealed_data_t *) encrypted_sek);
    CHECK_STATUS("seal SEK failed after SEK generation");

    uint32_t encrypt_text_length = sgx_get_encrypt_txt_len((const sgx_sealed_data_t *)encrypted_sek);

    CHECK_STATE(encrypt_text_length = plaintextLen);


    SAFE_CHAR_BUF(unsealedKey, BUF_LEN);
    uint32_t decLen = BUF_LEN;

    uint32_t add_text_length = sgx_get_add_mac_txt_len((const sgx_sealed_data_t *)encrypted_sek);
    CHECK_STATE(add_text_length == 0);
    CHECK_STATE(sgx_is_within_enclave(encrypted_sek,sizeof(sgx_sealed_data_t)));
    status = sgx_unseal_data((const sgx_sealed_data_t *)encrypted_sek, NULL, NULL,
                             (uint8_t *) unsealedKey, &decLen );

    CHECK_STATUS("seal/unseal SEK failed after SEK generation in unseal");
    *enc_len = sealedLen;

    SET_SUCCESS
    clean:
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
char *string_crypt(const char *key, const char *salt) {
  assertx(key);
  assertx(salt);

  char random_salt[12];
  if (!*salt) {
    memcpy(random_salt,"$1$",3);
    ito64(random_salt+3,rand(),8);
    random_salt[11] = '\0';
    return string_crypt(key, random_salt);
  }

  auto const saltLen = strlen(salt);
  if ((saltLen > sizeof("$2X$00$")) &&
    (salt[0] == '$') &&
    (salt[1] == '2') &&
    (salt[2] >= 'a') && (salt[2] <= 'z') &&
    (salt[3] == '$') &&
    (salt[4] >= '0') && (salt[4] <= '3') &&
    (salt[5] >= '0') && (salt[5] <= '9') &&
    (salt[6] == '$')) {
    // Bundled blowfish crypt()
    char output[61];

    static constexpr size_t maxSaltLength = 123;
    char paddedSalt[maxSaltLength + 1];
    paddedSalt[0] = paddedSalt[maxSaltLength] = '\0';

    memset(&paddedSalt[1], '$', maxSaltLength - 1);
    memcpy(paddedSalt, salt, std::min(maxSaltLength, saltLen));
    paddedSalt[std::min(maxSaltLength, saltLen)] = '\0';

    if (php_crypt_blowfish_rn(key, paddedSalt, output, sizeof(output))) {
      return strdup(output);
    }

  } else {
    // System crypt() function
#ifdef USE_PHP_CRYPT_R
    return php_crypt_r(key, salt);
#else
    static Mutex mutex;
    Lock lock(mutex);
    char *crypt_res = crypt(key,salt);

    if (crypt_res) {
      return strdup(crypt_res);
    }
#endif
  }

  return ((salt[0] == '*') && (salt[1] == '0'))
                  ? strdup("*1") : strdup("*0");
}
//  [c]
trustedDecryptDkgSecretAES(int *errStatus, char *errString, uint8_t *encrypted_dkg_secret,
                           uint64_t enc_len,
                           uint8_t *decrypted_dkg_secret) {
    LOG_INFO(__FUNCTION__);
    INIT_ERROR_STATE

    CHECK_STATE(encrypted_dkg_secret);
    CHECK_STATE(decrypted_dkg_secret);

    int status = AES_decrypt(encrypted_dkg_secret, enc_len, (char *) decrypted_dkg_secret,
                             3072);

    CHECK_STATUS2("aes decrypt data - encrypted_dkg_secret failed with status %d")

    SET_SUCCESS

    clean:
    ;
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
trustedDecryptDkgSecretAES(int *errStatus, char *errString, uint8_t *encrypted_dkg_secret,
                           uint32_t enc_len,
                           uint8_t *decrypted_dkg_secret) {
    LOG_INFO(__FUNCTION__);
    INIT_ERROR_STATE

    CHECK_STATE(encrypted_dkg_secret);
    CHECK_STATE(decrypted_dkg_secret);

    int status = AES_decrypt(encrypted_dkg_secret, enc_len, (char *) decrypted_dkg_secret,
                             3072);

    CHECK_STATUS2("aes decrypt data - encrypted_dkg_secret failed with status %d")

    SET_SUCCESS

    clean:
    ;
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
void trustedEcdsaSignAES(int *errStatus, char *errString, uint8_t *encryptedPrivateKey, uint64_t enc_len,
                         const char *hash, char *sigR, char *sigS, uint8_t *sig_v, int base) {
    LOG_DEBUG(__FUNCTION__);

    INIT_ERROR_STATE

    CHECK_STATE(encryptedPrivateKey);
    CHECK_STATE(hash);
    CHECK_STATE(sigR);
    CHECK_STATE(sigS);

    SAFE_CHAR_BUF(skey, BUF_LEN);

    mpz_t privateKeyMpz;
    mpz_init(privateKeyMpz);
    mpz_t msgMpz;
    mpz_init(msgMpz);
    signature sign = signature_init();

    int status = AES_decrypt(encryptedPrivateKey, enc_len, skey, BUF_LEN);

    CHECK_STATUS2("aes decrypt failed with status %d");

    skey[enc_len - SGX_AESGCM_MAC_SIZE - SGX_AESGCM_IV_SIZE] = '\0';

    if (mpz_set_str(privateKeyMpz, skey, ECDSA_SKEY_BASE) == -1) {
        *errStatus = -1;
        snprintf(errString, BUF_LEN, "invalid secret key");
        LOG_ERROR(errString);
        goto clean;
    }

    if (mpz_set_str(msgMpz, hash, 16) == -1) {
        *errStatus = -1;
        snprintf(errString, BUF_LEN, "invalid message hash");
        LOG_ERROR(errString);
        goto clean;
    }

    signature_sign(sign, msgMpz, privateKeyMpz, curve);

    sigCounter++;

    if (sigCounter % 1000 == 0) {

        point Pkey = point_init();

        signature_extract_public_key(Pkey, privateKeyMpz, curve);

        if (!signature_verify(msgMpz, sign, Pkey, curve)) {
            *errStatus = -2;
            snprintf(errString, BUF_LEN, "signature is not verified! ");
            point_clear(Pkey);
            goto clean;
        }

        point_clear(Pkey);
    }

    SAFE_CHAR_BUF(arrM, BUF_LEN);
    mpz_get_str(arrM, 16, msgMpz);
    snprintf(errString, BUF_LEN, "message is %s ", arrM);

    SAFE_CHAR_BUF(arrR, BUF_LEN);
    mpz_get_str(arrR, base, sign->r);
    strncpy(sigR, arrR, 1024);

    SAFE_CHAR_BUF(arrS, BUF_LEN);
    mpz_get_str(arrS, base, sign->s);
    strncpy(sigS, arrS, 1024);

    *sig_v = sign->v;

    SET_SUCCESS
    clean:

    mpz_clear(privateKeyMpz);
    mpz_clear(msgMpz);
    signature_free(sign);
    LOG_DEBUG(__FUNCTION__ );
    LOG_DEBUG("SGX call completed");
}
//  [c]
void trustedEcdsaSignAES(int *errStatus, char *errString, uint8_t *encryptedPrivateKey, uint32_t enc_len,
                         const char *hash, char *sigR, char *sigS, uint8_t *sig_v, int base) {
    LOG_DEBUG(__FUNCTION__);

    INIT_ERROR_STATE

    CHECK_STATE(encryptedPrivateKey);
    CHECK_STATE(hash);
    CHECK_STATE(sigR);
    CHECK_STATE(sigS);

    SAFE_CHAR_BUF(skey, ECDSA_SKEY_LEN);

    mpz_t privateKeyMpz;
    mpz_init(privateKeyMpz);
    mpz_t msgMpz;
    mpz_init(msgMpz);
    signature sign = signature_init();

    int status = AES_decrypt(encryptedPrivateKey, enc_len, skey, ECDSA_SKEY_LEN);

    CHECK_STATUS2("aes decrypt failed with status %d");

    skey[enc_len - SGX_AESGCM_MAC_SIZE - SGX_AESGCM_IV_SIZE] = '\0';

    if (mpz_set_str(privateKeyMpz, skey, ECDSA_SKEY_BASE) == -1) {
        *errStatus = -1;
        snprintf(errString, BUF_LEN, "invalid secret key");
        LOG_ERROR(errString);
        goto clean;
    }

    if (mpz_set_str(msgMpz, hash, 16) == -1) {
        *errStatus = -1;
        snprintf(errString, BUF_LEN, "invalid message hash");
        LOG_ERROR(errString);
        goto clean;
    }

    signature_sign(sign, msgMpz, privateKeyMpz, curve);

    sigCounter++;

    if (sigCounter % 1000 == 0) {

        point Pkey = point_init();

        signature_extract_public_key(Pkey, privateKeyMpz, curve);

        if (!signature_verify(msgMpz, sign, Pkey, curve)) {
            *errStatus = -2;
            snprintf(errString, BUF_LEN, "signature is not verified! ");
            point_clear(Pkey);
            goto clean;
        }

        point_clear(Pkey);
    }

    SAFE_CHAR_BUF(arrM, BUF_LEN);
    mpz_get_str(arrM, 16, msgMpz);
    snprintf(errString, BUF_LEN, "message is %s ", arrM);

    SAFE_CHAR_BUF(arrR, BUF_LEN);
    mpz_get_str(arrR, base, sign->r);
    strncpy(sigR, arrR, 1024);

    SAFE_CHAR_BUF(arrS, BUF_LEN);
    mpz_get_str(arrS, base, sign->s);
    strncpy(sigS, arrS, 1024);

    *sig_v = sign->v;

    SET_SUCCESS
    clean:

    mpz_clear(privateKeyMpz);
    mpz_clear(msgMpz);
    signature_free(sign);
    LOG_DEBUG(__FUNCTION__ );
    LOG_DEBUG("SGX call completed");
}
//  [c]
void trustedDkgVerifyAES(int *errStatus, char *errString, const char *public_shares, const char *s_share,
                         uint8_t *encryptedPrivateKey, uint64_t enc_len, unsigned _t, int _ind, int *result) {
    LOG_INFO(__FUNCTION__);

    INIT_ERROR_STATE

    CHECK_STATE(public_shares);
    CHECK_STATE(s_share);
    CHECK_STATE(encryptedPrivateKey);

    SAFE_CHAR_BUF(skey,BUF_LEN);

    mpz_t s;
    mpz_init(s);

    int status = AES_decrypt(encryptedPrivateKey, enc_len, skey, BUF_LEN);

    CHECK_STATUS2("AES_decrypt failed (in trustedDkgVerifyAES) with status %d");

    SAFE_CHAR_BUF(encr_sshare, BUF_LEN);

    strncpy(encr_sshare, s_share, ECDSA_SKEY_LEN - 1);

    SAFE_CHAR_BUF(common_key, BUF_LEN);

    status = session_key_recover(skey, s_share, common_key);

    CHECK_STATUS("session_key_recover failed");

    SAFE_CHAR_BUF(decr_sshare, BUF_LEN);

    status=xor_decrypt(common_key, encr_sshare, decr_sshare);

    CHECK_STATUS("xor_decrypt failed")


    status  = mpz_set_str(s, decr_sshare, 16);
    CHECK_STATUS("invalid decr secret share");

    *result = Verification(public_shares, s, _t, _ind);

    SET_SUCCESS
    clean:

    mpz_clear(s);
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
void trustedDkgVerifyAES(int *errStatus, char *errString, const char *public_shares, const char *s_share,
                         uint8_t *encryptedPrivateKey, uint64_t enc_len, unsigned _t, int _ind, int *result) {
    LOG_INFO(__FUNCTION__);

    INIT_ERROR_STATE

    CHECK_STATE(public_shares);
    CHECK_STATE(s_share);
    CHECK_STATE(encryptedPrivateKey);

    SAFE_CHAR_BUF(skey, ECDSA_SKEY_LEN);

    mpz_t s;
    mpz_init(s);

    int status = AES_decrypt(encryptedPrivateKey, enc_len, skey, ECDSA_SKEY_LEN);

    CHECK_STATUS2("AES_decrypt failed (in trustedDkgVerifyAES) with status %d");

    SAFE_CHAR_BUF(encr_sshare, ECDSA_SKEY_LEN);

    strncpy(encr_sshare, s_share, ECDSA_SKEY_LEN - 1);

    SAFE_CHAR_BUF(common_key, ECDSA_SKEY_LEN);

    status = session_key_recover(skey, s_share, common_key);

    CHECK_STATUS("session_key_recover failed");

    SAFE_CHAR_BUF(decr_sshare, ECDSA_SKEY_LEN);

    status=xor_decrypt(common_key, encr_sshare, decr_sshare);

    CHECK_STATUS("xor_decrypt failed")


    status  = mpz_set_str(s, decr_sshare, 16);
    CHECK_STATUS("invalid decr secret share");

    *result = Verification(public_shares, s, _t, _ind);

    SET_SUCCESS
    clean:

    mpz_clear(s);
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
void trustedEnclaveInit(uint64_t _logLevel) {
    CALL_ONCE
    LOG_INFO(__FUNCTION__);

    globalLogLevel_ = _logLevel;

    oc_realloc_func = &reallocate_function;
    oc_free_func = &free_function;

    LOG_INFO("Setting memory functions");

    mp_get_memory_functions(NULL, &gmp_realloc_func, &gmp_free_func);
    mp_set_memory_functions(NULL, oc_realloc_func, oc_free_func);

    LOG_INFO("Calling enclave init");


    enclave_init();


    LOG_INFO("Reading random");

    globalRandom = calloc(32,1);

    int ret = sgx_read_rand(globalRandom, 32);

    if(ret != SGX_SUCCESS)
    {
        LOG_ERROR("sgx_read_rand failed. Aboring enclave.");
        abort();
    }

    LOG_INFO("Successfully inited enclave. Signed enclave version:" SIGNED_ENCLAVE_VERSION );
#ifndef SGX_DEBUG
    LOG_INFO("SECURITY WARNING: sgxwallet is running in INSECURE DEBUG MODE! NEVER USE IN PRODUCTION!");
#endif

#if SGX_DEBUG != 0
    LOG_INFO("SECURITY WARNING: sgxwallet is running in INSECURE DEBUG MODE! NEVER USE IN PRODUCTION!");
#endif

#if SGX_MODE == SIM
    LOG_INFO("SECURITY WARNING: sgxwallet is running in INSECURE SIMULATION MODE! NEVER USE IN PRODUCTION!");
#endif






}
//  [c]
void trustedEnclaveInit(uint32_t _logLevel) {
    CALL_ONCE
    LOG_INFO(__FUNCTION__);

    globalLogLevel_ = _logLevel;

    oc_realloc_func = &reallocate_function;
    oc_free_func = &free_function;

    LOG_INFO("Setting memory functions");

    mp_get_memory_functions(NULL, &gmp_realloc_func, &gmp_free_func);
    mp_set_memory_functions(NULL, oc_realloc_func, oc_free_func);

    LOG_INFO("Calling enclave init");


    enclave_init();


    LOG_INFO("Reading random");

    globalRandom = calloc(32,1);

    int ret = sgx_read_rand(globalRandom, 32);

    if(ret != SGX_SUCCESS)
    {
        LOG_ERROR("sgx_read_rand failed. Aboring enclave.");
        abort();
    }

    LOG_INFO("Successfully inited enclave. Signed enclave version:" SIGNED_ENCLAVE_VERSION );
#ifndef SGX_DEBUG
    LOG_INFO("SECURITY WARNING: sgxwallet is running in INSECURE DEBUG MODE! NEVER USE IN PRODUCTION!");
#endif

#if SGX_DEBUG != 0
    LOG_INFO("SECURITY WARNING: sgxwallet is running in INSECURE DEBUG MODE! NEVER USE IN PRODUCTION!");
#endif

#if SGX_MODE == SIM
    LOG_INFO("SECURITY WARNING: sgxwallet is running in INSECURE SIMULATION MODE! NEVER USE IN PRODUCTION!");
#endif






}
//  [c]
void trustedBlsSignMessageAES(int *errStatus, char *errString, uint8_t *encryptedPrivateKey,
                              uint64_t enc_len, char *_hashX,
                              char *_hashY, char *signature) {
    LOG_DEBUG(__FUNCTION__);
    INIT_ERROR_STATE

    CHECK_STATE(encryptedPrivateKey);
    CHECK_STATE(_hashX);
    CHECK_STATE(_hashY);
    CHECK_STATE(signature);

    SAFE_CHAR_BUF(key, BUF_LEN);SAFE_CHAR_BUF(sig, BUF_LEN);

    int status = AES_decrypt(encryptedPrivateKey, enc_len, key, BUF_LEN);

    CHECK_STATUS("AES decrypt failed")

    if (!enclave_sign(key, _hashX, _hashY, sig)) {
        strncpy(errString, "Enclave failed to create bls signature", BUF_LEN);
        LOG_ERROR(errString);
        *errStatus = -1;
        goto clean;
    }

    strncpy(signature, sig, BUF_LEN);

    if (strnlen(signature, BUF_LEN) < 10) {
        strncpy(errString, "Signature too short", BUF_LEN);
        LOG_ERROR(errString);
        *errStatus = -1;
        goto clean;
    }

    SET_SUCCESS

    LOG_DEBUG("SGX call completed");

    clean:
    ;
    LOG_DEBUG("SGX call completed");
}
//  [c]
void trustedBlsSignMessageAES(int *errStatus, char *errString, uint8_t *encryptedPrivateKey,
                              uint32_t enc_len, char *_hashX,
                              char *_hashY, char *signature) {
    LOG_DEBUG(__FUNCTION__);
    INIT_ERROR_STATE

    CHECK_STATE(encryptedPrivateKey);
    CHECK_STATE(_hashX);
    CHECK_STATE(_hashY);
    CHECK_STATE(signature);

    SAFE_CHAR_BUF(key, BUF_LEN);SAFE_CHAR_BUF(sig, BUF_LEN);

    int status = AES_decrypt(encryptedPrivateKey, enc_len, key, BUF_LEN);

    CHECK_STATUS("AES decrypt failed")

    if (!enclave_sign(key, _hashX, _hashY, sig)) {
        strncpy(errString, "Enclave failed to create bls signature", BUF_LEN);
        LOG_ERROR(errString);
        *errStatus = -1;
        goto clean;
    }

    strncpy(signature, sig, BUF_LEN);

    if (strnlen(signature, BUF_LEN) < 10) {
        strncpy(errString, "Signature too short", BUF_LEN);
        LOG_ERROR(errString);
        *errStatus = -1;
        goto clean;
    }

    SET_SUCCESS

    LOG_DEBUG("SGX call completed");

    clean:
    ;
    LOG_DEBUG("SGX call completed");
}
//  [c]
void trustedDecryptKeyAES(int *errStatus, char *errString, uint8_t *encryptedPrivateKey,
                          uint64_t enc_len, char *key) {

    LOG_DEBUG(__FUNCTION__);
    INIT_ERROR_STATE

    CHECK_STATE(encryptedPrivateKey);
    CHECK_STATE(key);

    *errStatus = -9;

    int status = AES_decrypt(encryptedPrivateKey, enc_len, key, 3072);

    if (status != 0) {
        *errStatus = status;
        snprintf(errString, BUF_LEN, "aes decrypt failed with status %d", status);
        LOG_ERROR(errString);
        goto clean;
    }

    *errStatus = -10;

    uint64_t keyLen = strnlen(key, MAX_KEY_LENGTH);

    if (keyLen == MAX_KEY_LENGTH) {
        snprintf(errString, BUF_LEN, "Key is not null terminated");
        LOG_ERROR(errString);
        goto clean;
    }

    SET_SUCCESS
    clean:
    ;
}
//  [c]
void trustedDecryptKeyAES(int *errStatus, char *errString, uint8_t *encryptedPrivateKey,
                          uint32_t enc_len, char *key) {

    LOG_DEBUG(__FUNCTION__);
    INIT_ERROR_STATE

    CHECK_STATE(encryptedPrivateKey);
    CHECK_STATE(key);

    *errStatus = -9;

    int status = AES_decrypt_DH(encryptedPrivateKey, enc_len, key, 3072);

    if (status != 0) {
        *errStatus = status;
        snprintf(errString, BUF_LEN, "aes decrypt failed with status %d", status);
        LOG_ERROR(errString);
        goto clean;
    }

    *errStatus = -10;

    uint64_t keyLen = strnlen(key, MAX_KEY_LENGTH);

    if (keyLen == MAX_KEY_LENGTH) {
        snprintf(errString, BUF_LEN, "Key is not null terminated");
        LOG_ERROR(errString);
        goto clean;
    }

    SET_SUCCESS
    clean:
    ;
}
//  [c]
void trustedCreateBlsKeyAES(int *errStatus, char *errString, const char *s_shares,
                            uint8_t *encryptedPrivateKey, uint64_t key_len, uint8_t *encr_bls_key,
                            uint64_t *enc_bls_key_len) {

    LOG_INFO(__FUNCTION__);

    INIT_ERROR_STATE

    CHECK_STATE(s_shares);
    CHECK_STATE(encryptedPrivateKey);
    CHECK_STATE(encr_bls_key);

    SAFE_CHAR_BUF(skey, BUF_LEN);

    mpz_t sum;
    mpz_init(sum);
    mpz_set_ui(sum, 0);

    mpz_t q;
    mpz_init(q);
    mpz_set_str(q, "21888242871839275222246405745257275088548364400416034343698204186575808495617", 10);

    mpz_t bls_key;
    mpz_init(bls_key);


    int status = AES_decrypt(encryptedPrivateKey, key_len, skey, BUF_LEN);
    CHECK_STATUS2("aes decrypt failed with status %d");

    skey[ECDSA_SKEY_LEN - 1] = 0;

    int num_shares = strlen(s_shares) / 192;

    for (int i = 0; i < num_shares; i++) { SAFE_CHAR_BUF(encr_sshare, 65);
        strncpy(encr_sshare, s_shares + 192 * i, 64);
        encr_sshare[64] = 0;

        SAFE_CHAR_BUF(s_share, 193);
        strncpy(s_share, s_shares + 192 * i, 192);
        s_share[192] = 0;

        SAFE_CHAR_BUF(common_key, 65);

        status = session_key_recover(skey, s_share, common_key);

        CHECK_STATUS("session_key_recover failed");

        common_key[64] = 0;

        SAFE_CHAR_BUF(decr_sshare, 65);

        status = xor_decrypt(common_key, encr_sshare, decr_sshare);
        CHECK_STATUS("xor_decrypt failed");

        decr_sshare[64] = 0;

        mpz_t decr_secret_share;
        mpz_init(decr_secret_share);
        if (mpz_set_str(decr_secret_share, decr_sshare, 16) == -1) {
            *errStatus = 111;
            snprintf(errString, BUF_LEN, "invalid decrypted secret share");
            LOG_ERROR(errString);

            mpz_clear(decr_secret_share);
            goto clean;
        }

        mpz_addmul_ui(sum, decr_secret_share, 1);
        mpz_clear(decr_secret_share);
    }


    mpz_mod(bls_key, sum, q);

    SAFE_CHAR_BUF(key_share, BLS_KEY_LENGTH);

    SAFE_CHAR_BUF(arr_skey_str, BUF_LEN);

    mpz_get_str(arr_skey_str, 16, bls_key);
    int n_zeroes = 64 - strlen(arr_skey_str);
    for (int i = 0; i < n_zeroes; i++) {
        key_share[i] = '0';
    }
    strncpy(key_share + n_zeroes, arr_skey_str, 65 - n_zeroes);
    key_share[BLS_KEY_LENGTH - 1] = 0;

    status = AES_encrypt(key_share, encr_bls_key, BUF_LEN, BLS, NON_DECRYPTABLE, enc_bls_key_len);

    CHECK_STATUS2("aes encrypt bls private key failed with status %d ");

    SET_SUCCESS
    clean:

    mpz_clear(bls_key);
    mpz_clear(sum);
    mpz_clear(q);
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
void trustedCreateBlsKeyAES(int *errStatus, char *errString, const char *s_shares,
                            uint8_t *encryptedPrivateKey, uint64_t key_len, uint8_t *encr_bls_key,
                            uint32_t *enc_bls_key_len) {

    LOG_INFO(__FUNCTION__);

    INIT_ERROR_STATE

    CHECK_STATE(s_shares);
    CHECK_STATE(encryptedPrivateKey);
    CHECK_STATE(encr_bls_key);

    SAFE_CHAR_BUF(skey, ECDSA_SKEY_LEN);

    mpz_t sum;
    mpz_init(sum);
    mpz_set_ui(sum, 0);

    mpz_t q;
    mpz_init(q);
    mpz_set_str(q, "21888242871839275222246405745257275088548364400416034343698204186575808495617", 10);

    mpz_t bls_key;
    mpz_init(bls_key);


    int status = AES_decrypt(encryptedPrivateKey, key_len, skey, ECDSA_SKEY_LEN);
    CHECK_STATUS2("aes decrypt failed with status %d");

    skey[ECDSA_SKEY_LEN - 1] = 0;

    int num_shares = strlen(s_shares) / 192;

    for (int i = 0; i < num_shares; i++) { SAFE_CHAR_BUF(encr_sshare, 65);
        strncpy(encr_sshare, s_shares + 192 * i, 64);
        encr_sshare[64] = 0;

        SAFE_CHAR_BUF(s_share, 193);
        strncpy(s_share, s_shares + 192 * i, 192);
        s_share[192] = 0;

        SAFE_CHAR_BUF(common_key, 65);

        status = session_key_recover(skey, s_share, common_key);

        CHECK_STATUS("session_key_recover failed");

        common_key[64] = 0;

        SAFE_CHAR_BUF(decr_sshare, 65);

        status = xor_decrypt(common_key, encr_sshare, decr_sshare);
        CHECK_STATUS("xor_decrypt failed");

        decr_sshare[64] = 0;

        mpz_t decr_secret_share;
        mpz_init(decr_secret_share);
        if (mpz_set_str(decr_secret_share, decr_sshare, 16) == -1) {
            *errStatus = 111;
            snprintf(errString, BUF_LEN, "invalid decrypted secret share");
            LOG_ERROR(errString);

            mpz_clear(decr_secret_share);
            goto clean;
        }

        mpz_addmul_ui(sum, decr_secret_share, 1);
        mpz_clear(decr_secret_share);
    }


    mpz_mod(bls_key, sum, q);

    SAFE_CHAR_BUF(key_share, BLS_KEY_LENGTH);

    SAFE_CHAR_BUF(arr_skey_str, BUF_LEN);

    mpz_get_str(arr_skey_str, 16, bls_key);
    int n_zeroes = 64 - strlen(arr_skey_str);
    for (int i = 0; i < n_zeroes; i++) {
        key_share[i] = '0';
    }
    strncpy(key_share + n_zeroes, arr_skey_str, 65 - n_zeroes);
    key_share[BLS_KEY_LENGTH - 1] = 0;

    status = AES_encrypt(key_share, encr_bls_key, BUF_LEN);

    CHECK_STATUS2("aes encrypt bls private key failed with status %d ");

    *enc_bls_key_len = strlen(key_share) + SGX_AESGCM_MAC_SIZE + SGX_AESGCM_IV_SIZE;

    SET_SUCCESS
    clean:

    mpz_clear(bls_key);
    mpz_clear(sum);
    mpz_clear(q);
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
trustedGenDkgSecretAES(int *errStatus, char *errString, uint8_t *encrypted_dkg_secret, uint64_t *enc_len, size_t _t) {
    LOG_INFO(__FUNCTION__);
    INIT_ERROR_STATE

    CHECK_STATE(encrypted_dkg_secret);

    SAFE_CHAR_BUF(dkg_secret, DKG_BUFER_LENGTH);

    int status = gen_dkg_poly(dkg_secret, _t);

    CHECK_STATUS("gen_dkg_poly failed")

    status = AES_encrypt(dkg_secret, encrypted_dkg_secret, 3 * BUF_LEN,
                         DKG, DECRYPTABLE, enc_len);

    CHECK_STATUS("SGX AES encrypt DKG poly failed");



    SAFE_CHAR_BUF(decr_dkg_secret, DKG_BUFER_LENGTH);

    status = AES_decrypt(encrypted_dkg_secret, *enc_len, decr_dkg_secret,
                         DKG_BUFER_LENGTH);

    CHECK_STATUS("aes decrypt dkg poly failed");

    if (strcmp(dkg_secret, decr_dkg_secret) != 0) {
        snprintf(errString, BUF_LEN,
                 "encrypted poly is not equal to decrypted poly");
        LOG_ERROR(errString);
        *errStatus = -333;
        goto clean;
    }

    SET_SUCCESS
    clean:
    ;
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
trustedGenDkgSecretAES(int *errStatus, char *errString, uint8_t *encrypted_dkg_secret, uint32_t *enc_len, size_t _t) {
    LOG_INFO(__FUNCTION__);
    INIT_ERROR_STATE

    CHECK_STATE(encrypted_dkg_secret);

    SAFE_CHAR_BUF(dkg_secret, DKG_BUFER_LENGTH);

    int status = gen_dkg_poly(dkg_secret, _t);

    CHECK_STATUS("gen_dkg_poly failed")

    status = AES_encrypt(dkg_secret, encrypted_dkg_secret, 3 * BUF_LEN);

    CHECK_STATUS("SGX AES encrypt DKG poly failed");

    *enc_len = strlen(dkg_secret) + SGX_AESGCM_MAC_SIZE + SGX_AESGCM_IV_SIZE;

    SAFE_CHAR_BUF(decr_dkg_secret, DKG_BUFER_LENGTH);

    status = AES_decrypt(encrypted_dkg_secret, *enc_len, decr_dkg_secret,
                         DKG_BUFER_LENGTH);

    CHECK_STATUS("aes decrypt dkg poly failed");

    if (strcmp(dkg_secret, decr_dkg_secret) != 0) {
        snprintf(errString, BUF_LEN,
                 "encrypted poly is not equal to decrypted poly");
        LOG_ERROR(errString);
        *errStatus = -333;
        goto clean;
    }

    SET_SUCCESS
    clean:
    ;
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
void trustedEncryptKeyAES(int *errStatus, char *errString, const char *key,
                          uint8_t *encryptedPrivateKey, uint64_t *enc_len) {
    LOG_INFO(__FUNCTION__);

    *errString = 0;
    *errStatus = UNKNOWN_ERROR;

    CHECK_STATE(key);
    CHECK_STATE(encryptedPrivateKey);

    *errStatus = UNKNOWN_ERROR;

    int status = AES_encrypt((char *)key, encryptedPrivateKey, BUF_LEN,
                             DKG, DECRYPTABLE, enc_len);

    CHECK_STATUS2("AES encrypt failed with status %d");

    SAFE_CHAR_BUF(decryptedKey, BUF_LEN);

    status = AES_decrypt(encryptedPrivateKey, *enc_len, decryptedKey, BUF_LEN);

    CHECK_STATUS2("trustedDecryptKey failed with status %d");

    uint64_t decryptedKeyLen = strnlen(decryptedKey, MAX_KEY_LENGTH);

    if (decryptedKeyLen == MAX_KEY_LENGTH) {
        snprintf(errString, BUF_LEN, "Decrypted key is not null terminated");
        LOG_ERROR(errString);
        goto clean;
    }

    *errStatus = -8;

    if (strncmp(key, decryptedKey, MAX_KEY_LENGTH) != 0) {
        snprintf(errString, BUF_LEN, "Decrypted key does not match original key");
        LOG_ERROR(key);
        LOG_ERROR(decryptedKey);
        LOG_ERROR(errString);
        goto clean;
    }

    SET_SUCCESS
    clean:
    ;
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
void trustedEncryptKeyAES(int *errStatus, char *errString, const char *key,
                          uint8_t *encryptedPrivateKey, uint32_t *enc_len) {
    LOG_INFO(__FUNCTION__);

    *errString = 0;
    *errStatus = UNKNOWN_ERROR;

    CHECK_STATE(key);
    CHECK_STATE(encryptedPrivateKey);

    *errStatus = UNKNOWN_ERROR;

    int status = AES_encrypt_DH((char *)key, encryptedPrivateKey, BUF_LEN);

    CHECK_STATUS2("AES encrypt failed with status %d");

    *enc_len = strlen(key) + SGX_AESGCM_MAC_SIZE + SGX_AESGCM_IV_SIZE;

    SAFE_CHAR_BUF(decryptedKey, BUF_LEN);

    status = AES_decrypt_DH(encryptedPrivateKey, *enc_len, decryptedKey, BUF_LEN);

    CHECK_STATUS2("trustedDecryptKey failed with status %d");

    uint64_t decryptedKeyLen = strnlen(decryptedKey, MAX_KEY_LENGTH);

    if (decryptedKeyLen == MAX_KEY_LENGTH) {
        snprintf(errString, BUF_LEN, "Decrypted key is not null terminated");
        LOG_ERROR(errString);
        goto clean;
    }

    *errStatus = -8;

    if (strncmp(key, decryptedKey, MAX_KEY_LENGTH) != 0) {
        snprintf(errString, BUF_LEN, "Decrypted key does not match original key");
        LOG_ERROR(errString);
        goto clean;
    }

    SET_SUCCESS
    clean:
    ;
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
void trustedGenerateSEK(int *errStatus, char *errString,
                        uint8_t *encrypted_sek, uint64_t *enc_len, char *sek_hex) {
    CALL_ONCE
    LOG_INFO(__FUNCTION__);
    INIT_ERROR_STATE


    CHECK_STATE(encrypted_sek);
    CHECK_STATE(sek_hex);

    RANDOM_CHAR_BUF(SEK_raw, SGX_AESGCM_KEY_SIZE);

    carray2Hex((uint8_t*) SEK_raw, SGX_AESGCM_KEY_SIZE, sek_hex);
    memcpy(AES_key, SEK_raw, SGX_AESGCM_KEY_SIZE);
    derive_DH_Key();

    sealHexSEK(errStatus, errString, encrypted_sek, enc_len, sek_hex);

    if (*errStatus != 0) {
        LOG_ERROR("sealHexSEK failed");
        goto clean;
    }

    SET_SUCCESS
    clean:
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
void trustedGenerateSEK(int *errStatus, char *errString,
                        uint8_t *encrypted_sek, uint32_t *enc_len, char *sek_hex) {
    CALL_ONCE
    LOG_INFO(__FUNCTION__);
    INIT_ERROR_STATE


    CHECK_STATE(encrypted_sek);
    CHECK_STATE(sek_hex);

    RANDOM_CHAR_BUF(SEK_raw, SGX_AESGCM_KEY_SIZE);

    carray2Hex((uint8_t*) SEK_raw, SGX_AESGCM_KEY_SIZE, sek_hex);
    memcpy(AES_key, SEK_raw, SGX_AESGCM_KEY_SIZE);
    derive_DH_Key();

    sealHexSEK(errStatus, errString, encrypted_sek, enc_len, sek_hex);

    if (*errStatus != 0) {
        LOG_ERROR("sealHexSEK failed");
        goto clean;
    }

    SET_SUCCESS
    clean:
    LOG_INFO(__FUNCTION__ );
    LOG_INFO("SGX call completed");
}
//  [c]
trustedGetBlsPubKeyAES(int *errStatus, char *errString, uint8_t *encryptedPrivateKey, uint64_t key_len,
                       char *bls_pub_key) {
    LOG_DEBUG(__FUNCTION__);

    INIT_ERROR_STATE

    CHECK_STATE(bls_pub_key);
    CHECK_STATE(encryptedPrivateKey);

    SAFE_CHAR_BUF(skey_hex, BUF_LEN);

    int status = AES_decrypt(encryptedPrivateKey, key_len, skey_hex, BUF_LEN);

    CHECK_STATUS2("AES decrypt failed %d");

    skey_hex[ECDSA_SKEY_LEN - 1] = 0;

    status = calc_bls_public_key(skey_hex, bls_pub_key);

    CHECK_STATUS("could not calculate bls public key");

    SET_SUCCESS
    static uint64_t counter = 0;
    clean:
    if (counter % 1000 == 0) {
        LOG_INFO(__FUNCTION__);
        LOG_INFO("Thousand SGX calls completed");
    }

    counter++;
}
//  [c]
trustedGetBlsPubKeyAES(int *errStatus, char *errString, uint8_t *encryptedPrivateKey, uint64_t key_len,
                       char *bls_pub_key) {
    LOG_DEBUG(__FUNCTION__);

    INIT_ERROR_STATE

    CHECK_STATE(bls_pub_key);
    CHECK_STATE(encryptedPrivateKey);

    SAFE_CHAR_BUF(skey_hex, ECDSA_SKEY_LEN);

    int status = AES_decrypt(encryptedPrivateKey, key_len, skey_hex, ECDSA_SKEY_LEN);

    CHECK_STATUS2("AES decrypt failed %d");

    skey_hex[ECDSA_SKEY_LEN - 1] = 0;

    status = calc_bls_public_key(skey_hex, bls_pub_key);

    CHECK_STATUS("could not calculate bls public key");

    SET_SUCCESS
    static uint64_t counter = 0;
    clean:
    if (counter % 1000 == 0) {
        LOG_INFO(__FUNCTION__);
        LOG_INFO("Thousand SGX calls completed");
    }

    counter++;
}