pcl_crypto.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright (C) 2011-2018 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #include <openssl/aes.h>
  32. #include <openssl/sha.h>
  33. #include <openssl/modes.h>
  34. #include <sgx_tseal.h>
  35. #include <sgx_tcrypto.h>
  36. #include <pcl_common.h>
  37. #include <pcl_internal.h>
  38. #include <pcl_crypto_internal.h>
  39. /*
  40. * @func pcl_gcm_decrypt applies AES-GCM-128
  41. * @param OUT uint8_t* plaintext, input plain text buffer
  42. * @param IN uint8_t* ciphertext, output cipher text buffer
  43. * @param size_t textlen, size of buffer in bytes
  44. * @param IN uint8_t* aad, aditional authenticated data
  45. * @param size_t aad_len, size of aditional authenticated data
  46. * @param IN uint8_t* key, 16 bytes decryption key
  47. * @param IN uint8_t* iv, 12 bytes IV
  48. * @param IN uint8_t* tag, 16 bytes TAG result
  49. * @return sgx_status_t
  50. * SGX_ERROR_INVALID_PARAMETER if any pointer is NULL except for aad
  51. * SGX_ERROR_UNEXPECTED if any of the following functions fail:
  52. * pcl_vpaes_set_encrypt_key, pcl_CRYPTO_gcm128_aad or pcl_CRYPTO_gcm128_decrypt
  53. * SGX_ERROR_PCL_MAC_MISMATCH if MAC mismatch when calling pcl_CRYPTO_gcm128_finish
  54. * SGX_SUCCESS if successfull
  55. */
  56. sgx_status_t pcl_gcm_decrypt(
  57. OUT uint8_t* plaintext,
  58. IN uint8_t* ciphertext,
  59. size_t textlen,
  60. IN uint8_t* aad,
  61. size_t aad_len,
  62. IN uint8_t* key,
  63. IN uint8_t* iv,
  64. IN uint8_t* tag)
  65. {
  66. sgx_status_t ret_status = SGX_ERROR_INVALID_PARAMETER;
  67. if( NULL == plaintext ||
  68. NULL == ciphertext ||
  69. NULL == key ||
  70. NULL == iv ||
  71. NULL == tag)
  72. {
  73. return SGX_ERROR_INVALID_PARAMETER;
  74. }
  75. AES_KEY wide_key = { 0 };
  76. GCM128_CONTEXT gcm_ctx;
  77. int ret = pcl_vpaes_set_encrypt_key(key, PCL_AES_BLOCK_LEN_BITS, &wide_key);
  78. if(0 != ret)
  79. {
  80. ret_status = SGX_ERROR_UNEXPECTED;
  81. goto Label_zero_wide_key;
  82. }
  83. pcl_CRYPTO_gcm128_init(&gcm_ctx, &wide_key, (block128_f)pcl_vpaes_encrypt);
  84. pcl_CRYPTO_gcm128_setiv(&gcm_ctx, iv, SGX_AESGCM_IV_SIZE);
  85. if(NULL != aad)
  86. {
  87. ret = pcl_CRYPTO_gcm128_aad(&gcm_ctx, aad, aad_len);
  88. if(0 != ret)
  89. {
  90. ret_status = SGX_ERROR_UNEXPECTED;
  91. goto Label_zero_buffers;
  92. }
  93. }
  94. ret = pcl_CRYPTO_gcm128_decrypt(
  95. &gcm_ctx,
  96. ciphertext,
  97. plaintext,
  98. textlen);
  99. if(0 != ret)
  100. {
  101. ret_status = SGX_ERROR_UNEXPECTED;
  102. goto Label_zero_buffers;
  103. }
  104. ret = pcl_CRYPTO_gcm128_finish(&gcm_ctx, tag, SGX_CMAC_MAC_SIZE);
  105. if(0 != ret)
  106. {
  107. ret_status = SGX_ERROR_PCL_MAC_MISMATCH;
  108. goto Label_zero_buffers;
  109. }
  110. ret_status = SGX_SUCCESS;
  111. // Scrab secrets from stack:
  112. Label_zero_buffers:
  113. pcl_volatile_memset((volatile void*)(&gcm_ctx), 0, sizeof(gcm_ctx));
  114. Label_zero_wide_key:
  115. pcl_volatile_memset((volatile void*)(&wide_key), 0, sizeof(wide_key));
  116. return ret_status;
  117. }
  118. /*
  119. * @func pcl_sha256 calculates the payload SHA256
  120. * @param IN uint8_t* buf, payload buffer
  121. * @param size_t buflen, buffer size in bytes
  122. * @param OUT uint8_t* hash, SHA256 result
  123. */
  124. sgx_status_t pcl_sha256(IN uint8_t* buf, size_t buflen, OUT uint8_t* hash)
  125. {
  126. if(NULL == buf || NULL == hash)
  127. {
  128. return SGX_ERROR_INVALID_PARAMETER;
  129. }
  130. SHA256_CTX sha256;
  131. pcl_SHA256_Init(&sha256);
  132. pcl_SHA256_Update(&sha256, buf, buflen);
  133. pcl_SHA256_Final(hash, &sha256);
  134. pcl_volatile_memset((volatile void*)(&sha256), 0, sizeof(SHA256_CTX));
  135. return SGX_SUCCESS;
  136. }
  137. #ifdef SE_SIM
  138. /*
  139. * @func pcl_cmac calcualtes CMAC-128 on payload
  140. * @param IN const sgx_cmac_128bit_key_t *p_key, CMAC key
  141. * @param IN const uint8_t *p_src, input buffer
  142. * @param uint32_t src_len, buffer size in bytes
  143. * @param OUT sgx_cmac_128bit_tag_t *p_mac, 16 bytes resulting MAC
  144. * @return int, -1 if p_key, p_src or p_mac are NULL, 0 if success
  145. */
  146. int pcl_cmac(
  147. const sgx_cmac_128bit_key_t *p_key,
  148. const uint8_t *p_src,
  149. uint32_t src_len,
  150. sgx_cmac_128bit_tag_t *p_mac)
  151. {
  152. if(NULL == p_key || NULL == p_src || NULL == p_mac)
  153. {
  154. return -1;
  155. }
  156. unsigned char iv[PCL_COUNTER_SIZE] = { 0 };
  157. unsigned char aux[PCL_AES_BLOCK_LEN] = { 0 };
  158. unsigned char k1[PCL_AES_BLOCK_LEN] = { 0 };
  159. AES_KEY wide_key;
  160. pcl_vpaes_set_encrypt_key((const unsigned char *)p_key, PCL_AES_BLOCK_LEN_BITS, &wide_key);
  161. // Apply AES-CBC encrypt on input = 0^16 and IV = 0^16:
  162. pcl_vpaes_cbc_encrypt(iv, aux, PCL_AES_BLOCK_LEN, &wide_key, iv, 1);
  163. // Use result to generate K1:
  164. make_kn(k1, aux, PCL_AES_BLOCK_LEN);
  165. // Digest message except for last block:
  166. pcl_memset(iv, 0, PCL_COUNTER_SIZE);
  167. while(src_len > PCL_AES_BLOCK_LEN)
  168. {
  169. pcl_vpaes_cbc_encrypt((uint8_t *)p_src, aux, PCL_AES_BLOCK_LEN, &wide_key, iv, 1);
  170. src_len -= PCL_AES_BLOCK_LEN;
  171. p_src += PCL_AES_BLOCK_LEN;
  172. }
  173. // XOR K1 with last block of message:
  174. for (int i = 0; i < PCL_AES_BLOCK_LEN; i++)aux[i] = p_src[i] ^ k1[i];
  175. // Apply AES-CBC encrypt on result and IV
  176. pcl_vpaes_cbc_encrypt(aux, (uint8_t*)p_mac, PCL_AES_BLOCK_LEN, &wide_key, iv, 1);
  177. return 0;
  178. }
  179. #endif // #ifdef SE_SIM