sgx_rsa_encryption.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  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. /**
  32. * File:
  33. * sgx_rsa_encryption.cpp
  34. * Description:
  35. * Wrapper for rsa operation functions
  36. *
  37. */
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include "sgx_error.h"
  42. #include "sgx_tcrypto.h"
  43. #include "se_tcrypto_common.h"
  44. #include <openssl/bn.h>
  45. #include <openssl/rsa.h>
  46. #include <openssl/evp.h>
  47. #include <openssl/err.h>
  48. #include "ssl_wrapper.h"
  49. sgx_status_t sgx_create_rsa_key_pair(int n_byte_size, int e_byte_size, unsigned char *p_n, unsigned char *p_d, unsigned char *p_e,
  50. unsigned char *p_p, unsigned char *p_q, unsigned char *p_dmp1,
  51. unsigned char *p_dmq1, unsigned char *p_iqmp)
  52. {
  53. if (n_byte_size <= 0 || e_byte_size <= 0 || p_n == NULL || p_d == NULL || p_e == NULL ||
  54. p_p == NULL || p_q == NULL || p_dmp1 == NULL || p_dmq1 == NULL || p_iqmp == NULL) {
  55. return SGX_ERROR_INVALID_PARAMETER;
  56. }
  57. sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
  58. RSA* rsa_ctx = NULL;
  59. BIGNUM* bn_n = NULL;
  60. BIGNUM* bn_e = NULL;
  61. BIGNUM* tmp_bn_e = NULL;
  62. BIGNUM* bn_d = NULL;
  63. BIGNUM* bn_dmp1 = NULL;
  64. BIGNUM* bn_dmq1 = NULL;
  65. BIGNUM* bn_iqmp = NULL;
  66. BIGNUM* bn_q = NULL;
  67. BIGNUM* bn_p = NULL;
  68. do {
  69. //create new rsa ctx
  70. //
  71. rsa_ctx = RSA_new();
  72. if (rsa_ctx == NULL) {
  73. ret_code = SGX_ERROR_OUT_OF_MEMORY;
  74. break;
  75. }
  76. //generate rsa key pair, with n_byte_size*8 mod size and p_e exponent
  77. //
  78. tmp_bn_e = BN_lebin2bn(p_e, e_byte_size, tmp_bn_e);
  79. BN_CHECK_BREAK(tmp_bn_e);
  80. if (RSA_generate_key_ex(rsa_ctx, n_byte_size * 8, tmp_bn_e, NULL) != 1) {
  81. break;
  82. }
  83. //validate RSA key size match input parameter n size
  84. //
  85. int gen_rsa_size = RSA_size(rsa_ctx);
  86. if (gen_rsa_size != n_byte_size) {
  87. break;
  88. }
  89. //get RSA key internal values
  90. //
  91. RSA_get0_key(rsa_ctx, (const BIGNUM**)(&bn_n), (const BIGNUM**)(&bn_e), (const BIGNUM**)(&bn_d));
  92. RSA_get0_factors(rsa_ctx, (const BIGNUM**)(&bn_p), (const BIGNUM**)(&bn_q));
  93. RSA_get0_crt_params(rsa_ctx, (const BIGNUM**)(&bn_dmp1), (const BIGNUM**)(&bn_dmq1), (const BIGNUM**)(&bn_iqmp));
  94. //copy the generated key to input pointers
  95. //
  96. if (!BN_bn2lebinpad(bn_n, p_n, BN_num_bytes(bn_n)) ||
  97. !BN_bn2lebinpad(bn_d, p_d, BN_num_bytes(bn_d)) ||
  98. !BN_bn2lebinpad(bn_e, p_e, BN_num_bytes(bn_e)) ||
  99. !BN_bn2lebinpad(bn_p, p_p, BN_num_bytes(bn_p)) ||
  100. !BN_bn2lebinpad(bn_q, p_q, BN_num_bytes(bn_q)) ||
  101. !BN_bn2lebinpad(bn_dmp1, p_dmp1, BN_num_bytes(bn_dmp1)) ||
  102. !BN_bn2lebinpad(bn_dmq1, p_dmq1, BN_num_bytes(bn_dmq1)) ||
  103. !BN_bn2lebinpad(bn_iqmp, p_iqmp, BN_num_bytes(bn_iqmp))) {
  104. break;
  105. }
  106. ret_code = SGX_SUCCESS;
  107. } while (0);
  108. //free rsa ctx (RSA_free also free related BNs obtained in RSA_get functions)
  109. //
  110. RSA_free(rsa_ctx);
  111. BN_clear_free(tmp_bn_e);
  112. return ret_code;
  113. }
  114. sgx_status_t sgx_create_rsa_priv2_key(int mod_size, int exp_size, const unsigned char *p_rsa_key_e, const unsigned char *p_rsa_key_p, const unsigned char *p_rsa_key_q,
  115. const unsigned char *p_rsa_key_dmp1, const unsigned char *p_rsa_key_dmq1, const unsigned char *p_rsa_key_iqmp,
  116. void **new_pri_key2)
  117. {
  118. if (mod_size <= 0 || exp_size <= 0 || new_pri_key2 == NULL ||
  119. p_rsa_key_e == NULL || p_rsa_key_p == NULL || p_rsa_key_q == NULL || p_rsa_key_dmp1 == NULL ||
  120. p_rsa_key_dmq1 == NULL || p_rsa_key_iqmp == NULL) {
  121. return SGX_ERROR_INVALID_PARAMETER;
  122. }
  123. bool rsa_memory_manager = 0;
  124. EVP_PKEY *rsa_key = NULL;
  125. RSA *rsa_ctx = NULL;
  126. sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
  127. BIGNUM* n = NULL;
  128. BIGNUM* e = NULL;
  129. BIGNUM* d = NULL;
  130. BIGNUM* dmp1 = NULL;
  131. BIGNUM* dmq1 = NULL;
  132. BIGNUM* iqmp = NULL;
  133. BIGNUM* q = NULL;
  134. BIGNUM* p = NULL;
  135. BN_CTX* tmp_ctx = NULL;
  136. do {
  137. tmp_ctx = BN_CTX_new();
  138. NULL_BREAK(tmp_ctx);
  139. n = BN_new();
  140. NULL_BREAK(n);
  141. // convert RSA params, factors to BNs
  142. //
  143. p = BN_lebin2bn(p_rsa_key_p, (mod_size / 2), p);
  144. BN_CHECK_BREAK(p);
  145. q = BN_lebin2bn(p_rsa_key_q, (mod_size / 2), q);
  146. BN_CHECK_BREAK(q);
  147. dmp1 = BN_lebin2bn(p_rsa_key_dmp1, (mod_size / 2), dmp1);
  148. BN_CHECK_BREAK(dmp1);
  149. dmq1 = BN_lebin2bn(p_rsa_key_dmq1, (mod_size / 2), dmq1);
  150. BN_CHECK_BREAK(dmq1);
  151. iqmp = BN_lebin2bn(p_rsa_key_iqmp, (mod_size / 2), iqmp);
  152. BN_CHECK_BREAK(iqmp);
  153. e = BN_lebin2bn(p_rsa_key_e, (exp_size), e);
  154. BN_CHECK_BREAK(e);
  155. // calculate n value
  156. //
  157. if (!BN_mul(n, p, q, tmp_ctx)) {
  158. break;
  159. }
  160. //calculate d value
  161. //ϕ(n)=(p−1)(q−1)
  162. //d=(e^−1) mod ϕ(n)
  163. //
  164. d = BN_dup(n);
  165. NULL_BREAK(d);
  166. if (!BN_sub(d, d, p) || !BN_sub(d, d, q) || !BN_add_word(d, 1) || !BN_mod_inverse(d, e, d, tmp_ctx)) {
  167. break;
  168. }
  169. // allocates and initializes an RSA key structure
  170. //
  171. rsa_ctx = RSA_new();
  172. rsa_key = EVP_PKEY_new();
  173. if (rsa_ctx == NULL || rsa_key == NULL || !EVP_PKEY_assign_RSA(rsa_key, rsa_ctx)) {
  174. RSA_free(rsa_ctx);
  175. rsa_key = NULL;
  176. break;
  177. }
  178. //setup RSA key with input values
  179. //Calling set functions transfers the memory management of the values to the RSA object,
  180. //and therefore the values that have been passed in should not be freed by the caller after these functions has been called.
  181. //
  182. if (!RSA_set0_factors(rsa_ctx, p, q)) {
  183. break;
  184. }
  185. rsa_memory_manager = 1;
  186. if (!RSA_set0_crt_params(rsa_ctx, dmp1, dmq1, iqmp)) {
  187. BN_clear_free(n);
  188. BN_clear_free(e);
  189. BN_clear_free(d);
  190. BN_clear_free(dmp1);
  191. BN_clear_free(dmq1);
  192. BN_clear_free(iqmp);
  193. break;
  194. }
  195. if (!RSA_set0_key(rsa_ctx, n, e, d)) {
  196. BN_clear_free(n);
  197. BN_clear_free(e);
  198. BN_clear_free(d);
  199. break;
  200. }
  201. *new_pri_key2 = rsa_key;
  202. ret_code = SGX_SUCCESS;
  203. } while (0);
  204. BN_CTX_free(tmp_ctx);
  205. //in case of failure, free allocated BNs and RSA struct
  206. //
  207. if (ret_code != SGX_SUCCESS) {
  208. //BNs were not assigned to rsa ctx yet, user code must free allocated BNs
  209. //
  210. if (!rsa_memory_manager) {
  211. BN_clear_free(n);
  212. BN_clear_free(e);
  213. BN_clear_free(d);
  214. BN_clear_free(dmp1);
  215. BN_clear_free(dmq1);
  216. BN_clear_free(iqmp);
  217. BN_clear_free(q);
  218. BN_clear_free(p);
  219. }
  220. EVP_PKEY_free(rsa_key);
  221. }
  222. return ret_code;
  223. }
  224. sgx_status_t sgx_create_rsa_pub1_key(int mod_size, int exp_size, const unsigned char *le_n, const unsigned char *le_e, void **new_pub_key1)
  225. {
  226. if (new_pub_key1 == NULL || mod_size <= 0 || exp_size <= 0 || le_n == NULL || le_e == NULL) {
  227. return SGX_ERROR_INVALID_PARAMETER;
  228. }
  229. EVP_PKEY *rsa_key = NULL;
  230. RSA *rsa_ctx = NULL;
  231. sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
  232. BIGNUM* n = NULL;
  233. BIGNUM* e = NULL;
  234. do {
  235. //convert input buffers to BNs
  236. //
  237. n = BN_lebin2bn(le_n, mod_size, n);
  238. BN_CHECK_BREAK(n);
  239. e = BN_lebin2bn(le_e, exp_size, e);
  240. BN_CHECK_BREAK(e);
  241. // allocates and initializes an RSA key structure
  242. //
  243. rsa_ctx = RSA_new();
  244. rsa_key = EVP_PKEY_new();
  245. if (rsa_ctx == NULL || rsa_key == NULL || !EVP_PKEY_assign_RSA(rsa_key, rsa_ctx)) {
  246. RSA_free(rsa_ctx);
  247. rsa_ctx = NULL;
  248. break;
  249. }
  250. //set n, e values of RSA key
  251. //Calling set functions transfers the memory management of input BNs to the RSA object,
  252. //and therefore the values that have been passed in should not be freed by the caller after these functions has been called.
  253. //
  254. if (!RSA_set0_key(rsa_ctx, n, e, NULL)) {
  255. break;
  256. }
  257. *new_pub_key1 = rsa_key;
  258. ret_code = SGX_SUCCESS;
  259. } while (0);
  260. if (ret_code != SGX_SUCCESS) {
  261. EVP_PKEY_free(rsa_key);
  262. BN_clear_free(n);
  263. BN_clear_free(e);
  264. }
  265. return ret_code;
  266. }
  267. sgx_status_t sgx_rsa_pub_encrypt_sha256(void* rsa_key, unsigned char* pout_data, size_t* pout_len, const unsigned char* pin_data,
  268. const size_t pin_len) {
  269. if (rsa_key == NULL || pout_len == NULL || pin_data == NULL || pin_len < 1 || pin_len >= INT_MAX) {
  270. return SGX_ERROR_INVALID_PARAMETER;
  271. }
  272. EVP_PKEY_CTX *ctx = NULL;
  273. sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
  274. do {
  275. //allocate and init PKEY_CTX
  276. //
  277. ctx = EVP_PKEY_CTX_new((EVP_PKEY*)rsa_key, NULL);
  278. if ((ctx == NULL) || (EVP_PKEY_encrypt_init(ctx) < 1)) {
  279. break;
  280. }
  281. //set the RSA padding mode, init it to use SHA256
  282. //
  283. EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING);
  284. EVP_PKEY_CTX_set_rsa_oaep_md(ctx, EVP_sha256());
  285. if (EVP_PKEY_encrypt(ctx, pout_data, pout_len, pin_data, pin_len) <= 0) {
  286. break;
  287. }
  288. ret_code = SGX_SUCCESS;
  289. } while (0);
  290. EVP_PKEY_CTX_free(ctx);
  291. return ret_code;
  292. }
  293. sgx_status_t sgx_rsa_priv_decrypt_sha256(void* rsa_key, unsigned char* pout_data, size_t* pout_len, const unsigned char* pin_data,
  294. const size_t pin_len) {
  295. if (rsa_key == NULL || pout_len == NULL || pin_data == NULL || pin_len < 1 || pin_len >= INT_MAX) {
  296. return SGX_ERROR_INVALID_PARAMETER;
  297. }
  298. EVP_PKEY_CTX *ctx = NULL;
  299. sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
  300. do {
  301. //allocate and init PKEY_CTX
  302. //
  303. ctx = EVP_PKEY_CTX_new((EVP_PKEY*)rsa_key, NULL);
  304. if ((ctx == NULL) || (EVP_PKEY_decrypt_init(ctx) < 1)) {
  305. break;
  306. }
  307. //set the RSA padding mode, init it to use SHA256
  308. //
  309. EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING);
  310. EVP_PKEY_CTX_set_rsa_oaep_md(ctx, EVP_sha256());
  311. if (EVP_PKEY_decrypt(ctx, pout_data, pout_len, pin_data, pin_len) <= 0) {
  312. break;
  313. }
  314. ret_code = SGX_SUCCESS;
  315. } while (0);
  316. EVP_PKEY_CTX_free(ctx);
  317. return ret_code;
  318. }
  319. sgx_status_t sgx_free_rsa_key(void *p_rsa_key, sgx_rsa_key_type_t key_type, int mod_size, int exp_size) {
  320. (void)(key_type);
  321. (void)(mod_size);
  322. (void)(exp_size);
  323. if (p_rsa_key != NULL) {
  324. EVP_PKEY_free((EVP_PKEY*)p_rsa_key);
  325. }
  326. return SGX_SUCCESS;
  327. }