sgx_rsa3072.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  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 "sgx_tcrypto.h"
  32. #include <openssl/bn.h>
  33. #include <openssl/rsa.h>
  34. #include <openssl/evp.h>
  35. #include <openssl/err.h>
  36. #include "se_tcrypto_common.h"
  37. sgx_status_t sgx_rsa3072_sign(const uint8_t * p_data,
  38. uint32_t data_size,
  39. const sgx_rsa3072_key_t * p_key,
  40. sgx_rsa3072_signature_t * p_signature)
  41. {
  42. if ((p_data == NULL) || (data_size < 1) || (p_key == NULL) ||
  43. (p_signature == NULL))
  44. {
  45. return SGX_ERROR_INVALID_PARAMETER;
  46. }
  47. sgx_status_t retval = SGX_ERROR_UNEXPECTED;
  48. RSA *priv_rsa_key = NULL;
  49. EVP_PKEY* priv_pkey = NULL;
  50. BIGNUM *n = NULL;
  51. BIGNUM *d = NULL;
  52. BIGNUM *e = NULL;
  53. EVP_MD_CTX* ctx = NULL;
  54. const EVP_MD* sha256_md = NULL;
  55. size_t siglen = SGX_RSA3072_KEY_SIZE;
  56. int ret = 0;
  57. CLEAR_OPENSSL_ERROR_QUEUE;
  58. do {
  59. // converts the modulus value of rsa key, represented as positive integer in little-endian into a BIGNUM
  60. //
  61. n = BN_lebin2bn((const unsigned char *)p_key->mod, sizeof(p_key->mod), 0);
  62. if (n == NULL) {
  63. break;
  64. }
  65. // converts the private exp value of rsa key, represented as positive integer in little-endian into a BIGNUM
  66. //
  67. d = BN_lebin2bn((const unsigned char *)p_key->d, sizeof(p_key->d), 0);
  68. if (d == NULL) {
  69. break;
  70. }
  71. // converts the public exp value of rsa key, represented as positive integer in little-endian into a BIGNUM
  72. //
  73. e = BN_lebin2bn((const unsigned char *)p_key->e, sizeof(p_key->e), 0);
  74. if (e == NULL) {
  75. break;
  76. }
  77. // allocates and initializes an RSA key structure
  78. //
  79. priv_rsa_key = RSA_new();
  80. if (priv_rsa_key == NULL) {
  81. retval = SGX_ERROR_OUT_OF_MEMORY;
  82. break;
  83. }
  84. // sets the modulus, private exp and public exp values of the RSA key
  85. //
  86. if (RSA_set0_key(priv_rsa_key, n, e, d) != 1) {
  87. BN_clear_free(n);
  88. BN_clear_free(d);
  89. BN_clear_free(e);
  90. break;
  91. }
  92. // allocates an empty EVP_PKEY structure
  93. //
  94. priv_pkey = EVP_PKEY_new();
  95. if (priv_pkey == NULL) {
  96. retval = SGX_ERROR_OUT_OF_MEMORY;
  97. break;
  98. }
  99. // set the referenced key to pub_rsa_key, however these use the supplied key internally and so key will be freed when the parent pkey is freed
  100. //
  101. if (EVP_PKEY_assign_RSA(priv_pkey, priv_rsa_key) != 1) {
  102. RSA_free(priv_rsa_key);
  103. break;
  104. }
  105. // allocates, initializes and returns a digest context
  106. //
  107. ctx = EVP_MD_CTX_new();
  108. if (NULL == ctx) {
  109. retval = SGX_ERROR_OUT_OF_MEMORY;
  110. break;
  111. }
  112. // return EVP_MD structures for SHA256 digest algorithm */
  113. //
  114. sha256_md = EVP_sha256();
  115. if (sha256_md == NULL) {
  116. break;
  117. }
  118. // sets up signing context ctx to use digest type
  119. //
  120. if (EVP_DigestSignInit(ctx, NULL, sha256_md, NULL, priv_pkey) <= 0) {
  121. break;
  122. }
  123. // hashes data_size bytes of data at p_data into the signature context ctx
  124. //
  125. if (EVP_DigestSignUpdate(ctx, (const void *)p_data, data_size) <= 0) {
  126. break;
  127. }
  128. // signs the data in ctx places the signature in p_signature.
  129. //
  130. ret = EVP_DigestSignFinal(ctx, (unsigned char *)p_signature, &siglen);//fails
  131. if (ret <= 0) {
  132. break;
  133. }
  134. // validates the signature size
  135. //
  136. if (SGX_RSA3072_KEY_SIZE != siglen) {
  137. break;
  138. }
  139. retval = SGX_SUCCESS;
  140. } while (0);
  141. if (retval != SGX_SUCCESS) {
  142. GET_LAST_OPENSSL_ERROR;
  143. }
  144. if (ctx)
  145. EVP_MD_CTX_free(ctx);
  146. if (priv_pkey) {
  147. EVP_PKEY_free(priv_pkey);
  148. priv_rsa_key = NULL;
  149. n = NULL;
  150. d = NULL;
  151. e = NULL;
  152. }
  153. if (priv_rsa_key) {
  154. RSA_free(priv_rsa_key);
  155. n = NULL;
  156. d = NULL;
  157. e = NULL;
  158. }
  159. if (n)
  160. BN_clear_free(n);
  161. if (d)
  162. BN_clear_free(d);
  163. if (e)
  164. BN_clear_free(e);
  165. return retval;
  166. }
  167. sgx_status_t sgx_rsa3072_verify(const uint8_t *p_data,
  168. uint32_t data_size,
  169. const sgx_rsa3072_public_key_t *p_public,
  170. const sgx_rsa3072_signature_t *p_signature,
  171. sgx_rsa_result_t *p_result)
  172. {
  173. if ((p_data == NULL) || (data_size < 1) || (p_public == NULL) ||
  174. (p_signature == NULL) || (p_result == NULL))
  175. {
  176. return SGX_ERROR_INVALID_PARAMETER;
  177. }
  178. *p_result = SGX_RSA_INVALID_SIGNATURE;
  179. sgx_status_t retval = SGX_ERROR_UNEXPECTED;
  180. int verified = 0;
  181. RSA *pub_rsa_key = NULL;
  182. EVP_PKEY *pub_pkey = NULL;
  183. BIGNUM *n = NULL;
  184. BIGNUM *e = NULL;
  185. const EVP_MD* sha256_md = NULL;
  186. EVP_MD_CTX *ctx = NULL;
  187. CLEAR_OPENSSL_ERROR_QUEUE;
  188. do {
  189. // converts the modulus value of rsa key, represented as positive integer in little-endian into a BIGNUM
  190. //
  191. n = BN_lebin2bn((const unsigned char *)p_public->mod, sizeof(p_public->mod), 0);
  192. if (n == NULL) {
  193. break;
  194. }
  195. // converts the public exp value of rsa key, represented as positive integer in little-endian into a BIGNUM
  196. //
  197. e = BN_lebin2bn((const unsigned char *)p_public->exp, sizeof(p_public->exp), 0);
  198. if (e == NULL) {
  199. break;
  200. }
  201. // allocates and initializes an RSA key structure
  202. //
  203. pub_rsa_key = RSA_new();
  204. if (pub_rsa_key == NULL) {
  205. retval = SGX_ERROR_OUT_OF_MEMORY;
  206. break;
  207. }
  208. // sets the modulus and public exp values of the RSA key
  209. //
  210. if (RSA_set0_key(pub_rsa_key, n, e, NULL) != 1) {
  211. BN_clear_free(n);
  212. BN_clear_free(e);
  213. break;
  214. }
  215. // allocates an empty EVP_PKEY structure
  216. //
  217. pub_pkey = EVP_PKEY_new();
  218. if (pub_pkey == NULL) {
  219. retval = SGX_ERROR_OUT_OF_MEMORY;
  220. break;
  221. }
  222. // set the referenced key to pub_rsa_key, however these use the supplied key internally and so key will be freed when the parent pkey is freed
  223. //
  224. if (EVP_PKEY_assign_RSA(pub_pkey, pub_rsa_key) != 1) {
  225. RSA_free(pub_rsa_key);
  226. break;
  227. }
  228. // allocates, initializes and returns a digest context
  229. //
  230. ctx = EVP_MD_CTX_new();
  231. if (ctx == NULL) {
  232. retval = SGX_ERROR_OUT_OF_MEMORY;
  233. break;
  234. }
  235. // return EVP_MD structures for SHA256 digest algorithm */
  236. //
  237. sha256_md = EVP_sha256();
  238. if (sha256_md == NULL) {
  239. break;
  240. }
  241. // sets up verification context ctx to use digest type
  242. //
  243. if (EVP_DigestVerifyInit(ctx, NULL, sha256_md, NULL, pub_pkey) <= 0) {
  244. break;
  245. }
  246. // hashes data_size bytes of data at p_data into the verification context ctx.
  247. // this function can be called several times on the same ctx to hash additional data
  248. //
  249. if (EVP_DigestVerifyUpdate(ctx, (const void *)p_data, data_size) <= 0) {
  250. break;
  251. }
  252. // verifies the data in ctx against the signature in p_signature of length SGX_RSA3072_KEY_SIZE
  253. //
  254. verified = EVP_DigestVerifyFinal(ctx, (const unsigned char *)p_signature, SGX_RSA3072_KEY_SIZE);
  255. if (verified) {
  256. *p_result = SGX_RSA_VALID;
  257. }
  258. else if (verified != 0) {
  259. break;
  260. }
  261. retval = SGX_SUCCESS;
  262. } while (0);
  263. if (retval != SGX_SUCCESS) {
  264. GET_LAST_OPENSSL_ERROR;
  265. }
  266. if (ctx)
  267. EVP_MD_CTX_free(ctx);
  268. if (pub_pkey) {
  269. EVP_PKEY_free(pub_pkey);
  270. pub_rsa_key = NULL;
  271. n = NULL;
  272. e = NULL;
  273. }
  274. if (pub_rsa_key) {
  275. RSA_free(pub_rsa_key);
  276. n = NULL;
  277. e = NULL;
  278. }
  279. if (n)
  280. BN_clear_free(n);
  281. if (e)
  282. BN_clear_free(e);
  283. return retval;
  284. }