sign_csr.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. * Copyright (C) 2011-2017 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 <cstddef>
  32. #include "pse_pr_inc.h"
  33. #include "sign_csr.h"
  34. #include "le2be_macros.h"
  35. #include "sgx_trts.h"
  36. #include <cstring>
  37. #include "ae_ipp.h"
  38. #define BREAK_IF_NULL(a) { if (NULL == (a)) break; }
  39. #define BREAK_IF_IPPERR(a) { if (ippStsNoErr != (a)) break; }
  40. #define LEN_ECDSA_SIG_COMP 32
  41. #include "pse_product_type.hh"
  42. static uint8_t CertificateSigningRequestTemplate[] =
  43. {
  44. /*0000h:*/ 0x30, 0x82, 0x01, 0xB9,
  45. /* BEGIN -- Certificate Request Info (to be signed) */
  46. 0x30, 0x82, 0x01, 0x5E,
  47. 0x02, 0x01, 0x00, 0x30, 0x81, 0xB7, 0x31, 0x0B,
  48. /*0010h:*/ 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x0C, 0x02, 0x55, 0x53, 0x31, 0x0B, 0x30, 0x09, 0x06,
  49. /*0020h:*/ 0x03, 0x55, 0x04, 0x08, 0x0C, 0x02, 0x43, 0x41, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04,
  50. /*0030h:*/ 0x07, 0x0C, 0x0B, 0x53, 0x61, 0x6E, 0x74, 0x61, 0x20, 0x43, 0x6C, 0x61, 0x72, 0x61, 0x31, 0x1A,
  51. /*0040h:*/ 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x11, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x20, 0x43,
  52. /*0050h:*/ 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03,
  53. /*0060h:*/ 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x20, 0x50, 0x53, 0x45, 0x20,
  54. /* BEGIN -- organizationalUnitName GUID */
  55. 0x65,
  56. /*0070h:*/ 0x66, 0x65, 0x66, 0x65, 0x66, 0x65, 0x66, 0x2D, 0x65, 0x66, 0x65, 0x66, 0x2D, 0x65, 0x66, 0x65,
  57. /*0080h:*/ 0x66, 0x2D, 0x65, 0x66, 0x65, 0x66, 0x2D, 0x65, 0x66, 0x65, 0x66, 0x65, 0x66, 0x65, 0x66, 0x65,
  58. /*0090h:*/ 0x66, 0x65, 0x66,
  59. /* END -- organizationalUnitName GUID */
  60. 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0D, 0x77, 0x77,
  61. /*00A0h:*/ 0x77, 0x2E, 0x69, 0x6E, 0x74, 0x65, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x18, 0x30, 0x16, 0x06,
  62. /*00B0h:*/ 0x0A, 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x01, 0x0C, 0x08, 0x46, 0x46, 0x46,
  63. /*00C0h:*/ 0x46, 0x46, 0x46, 0x46, 0x46, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
  64. /*00D0h:*/ 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04,
  65. /* BEGIN -- Public Key (64 bytes) - (public key Px || public key Py) */
  66. /*00E0h:*/ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  67. /*00F0h:*/ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  68. /*0100h:*/ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  69. /*0110h:*/ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  70. /* END -- Public Key (64 bytes) */
  71. /*0120h:*/ 0xA0, 0x44, 0x30, 0x42, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x0E, 0x31,
  72. /*0130h:*/ 0x35, 0x30, 0x33, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03,
  73. /*0140h:*/ 0x02, 0x06, 0xC0, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x02, 0x30,
  74. /*0150h:*/ 0x00, 0x30, 0x13, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF8, 0x4D, 0x01, 0x09, 0x02, 0x01, 0x01,
  75. /*0160h:*/ 0xFF, 0x04, 0x03, 0x0A, 0x01,
  76. #if !defined(PRODUCT_TYPE)
  77. #error PRODUCT_TYPE not #defined
  78. #endif
  79. PRODUCT_TYPE, /* product ID */
  80. /* END -- Certificate Request Info (to be signed) */
  81. /* ecdsaWithSHA256 (1.2.840.10045.4.3.2) */
  82. 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04,
  83. /*0170h:*/ 0x03, 0x02,
  84. /* BEGIN -- Signature data (max 75 bytes) */
  85. /* 0x03 || MM || 0x00 || 0x30 || NN || 0x02 || XX || sigX || 0x02 || YY || sigY */
  86. 0x03, 0x49, 0x00,
  87. 0x30, 0x46,
  88. /* Signature X ( 0x02 || XX || Sx (max 33bytes, See X.690 8.3 Encoding of an integer value) */
  89. 0x02, 0x21,
  90. 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  91. /*0180h:*/ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  92. /*0190h:*/ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  93. /* Signature Y ( 0x02 || YY || Sy (max 33bytes, See X.690 8.3 Encoding of an integer value) */
  94. 0x02, 0x21,
  95. 0x00, 0xaa, 0xaa, 0xaa,
  96. /*01A0h:*/ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  97. /*01B0h:*/ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
  98. /* END -- Signature data */
  99. };
  100. const int nOffset_CSRSize = 0x0002; // Location of CSR length (length excludes 4 bytes header)
  101. //const int nSize_CSRSize = 2;
  102. const int nOffset_CSRInfo = 0x0004; // Offset to start of CSR Info block (Signature is computed using SHA256 Message Digest of CSR Info field)
  103. const int nSize_CSRInfo = 4 + 350; // Length of CSR Info block to sign
  104. const int nOffset_GUID = 0x006F;
  105. const int nSize_GUID = 36; // fefefefe-fefe-fefe-fefe-fefefefefefe (8-4-4-4-12)
  106. const int nOffset_PublicKey = 0x00E0; // Offset to start of Public Key
  107. const int nOffset_SigSize1 = 0x0173; // Offset to length for signature block (1 byte)
  108. const int nOffset_SigSize2 = 0x0176; // Offset to length for signature block (1 byte)
  109. const uint16_t nOffset_SigX = 0x0177; // Offset to start of signature (size will vary from 68 to 70 bytes)
  110. /* Steps:
  111. 1) The public key will be stuffed in the CSR record
  112. 2) A new GUID will be created and placed in the organizationalUnitName field
  113. 2) The CSR record info signature will be computed using the ECDSA private key
  114. 3) The signature will be separated into X and Y components
  115. 4) Prepare X component of signature
  116. if Byte 0 of X component has high bit set then prepare X component
  117. 0x02 || 0x21 || 0x00 || X
  118. else
  119. 0x02 || 0x20 || X
  120. 5) Prepare Y component of signature
  121. if Byte 0 of Y component has high bit set then prepare Y component
  122. 0x02 || 0x21 || 0x00 || Y
  123. else
  124. 0x02 || 0x20 || Y
  125. 6) Update CSR length (307, 308, or 309 bytes)
  126. 7) Update DER signature length (68, 69, or 70 bytes)
  127. 8) Copy prepared signature components immediately after DER signature length byte
  128. 9) Adjust size of CSR reported
  129. */
  130. SignCSR::SignCSR(void)
  131. {
  132. }
  133. SignCSR::~SignCSR(void)
  134. {
  135. }
  136. static inline char ConvertValueToAscii(const uint8_t in)
  137. {
  138. if(in <= 0x09)
  139. {
  140. return (uint8_t)(in + 48);
  141. }
  142. else if(in <= 0x0F)
  143. {
  144. return (uint8_t)(in + 55);
  145. }
  146. return 0;
  147. }
  148. static bool getFormatedGUID(uint8_t* pGUID, uint32_t nGUID)
  149. {
  150. uint32_t i;
  151. uint8_t randBuffer[16];
  152. uint8_t asciiBuffer[32];
  153. if (nGUID < 36)
  154. return false;
  155. if (0 != sgx_read_rand(randBuffer, sizeof(randBuffer)))
  156. return false;
  157. uint8_t* p = randBuffer;
  158. for (i = 0; i < sizeof(asciiBuffer); i += 2)
  159. {
  160. asciiBuffer[i] = ConvertValueToAscii((uint8_t)(*p >> 4));
  161. asciiBuffer[i+1] = ConvertValueToAscii(*p & 0xf);
  162. ++p;
  163. }
  164. // 01234567-9012-4567-9012-546890123456
  165. p = asciiBuffer;
  166. for (i = 0; i < nGUID; i++)
  167. {
  168. if (i == 8 || i == 13 || i == 18 || i == 23)
  169. pGUID[i] = '-';
  170. else
  171. {
  172. pGUID[i] = *p;
  173. ++p;
  174. }
  175. }
  176. return true;
  177. }
  178. size_t SignCSR::GetMaxSize()
  179. {
  180. // May be 2 bytes larger than needed depending on whether X/Y fields of signature need a leading 0x00.
  181. return sizeof(CertificateSigningRequestTemplate);
  182. }
  183. // Note: The keys input are little-endian
  184. ae_error_t SignCSR::GetSignedTemplate(
  185. /*in */ EcDsaPrivKey* pPrivateKey,
  186. /*in */ EcDsaPubKey* pPublicKey,
  187. /*in */ sgx_ecc_state_handle_t csr_ecc_handle,
  188. /*out*/ Ipp8u* pSignedTemplate,
  189. /*i/o*/ uint16_t* pnBytes)
  190. {
  191. ae_error_t aeStatus = PSE_PR_INSUFFICIENT_MEMORY_ERROR;
  192. uint8_t SerializedSignature[64];
  193. if (NULL == pSignedTemplate || NULL == pnBytes ||
  194. NULL == pPrivateKey || NULL == pPublicKey || NULL == csr_ecc_handle)
  195. return PSE_PR_BAD_POINTER_ERROR;
  196. if (GetMaxSize() > *pnBytes)
  197. return PSE_PR_BUFFER_TOO_SMALL_ERROR;
  198. memset_s(pSignedTemplate, *pnBytes, 0, *pnBytes);
  199. memcpy(pSignedTemplate, CertificateSigningRequestTemplate, sizeof(CertificateSigningRequestTemplate));
  200. // Write serialized public key to template (public key Px || public key Py)
  201. memcpy(&pSignedTemplate[nOffset_PublicKey], pPublicKey, sizeof(EcDsaPubKey));
  202. // convert the public key field to big endian
  203. SwapEndian_32B(&pSignedTemplate[nOffset_PublicKey] + 0);
  204. SwapEndian_32B(&pSignedTemplate[nOffset_PublicKey] + 32);
  205. do
  206. {
  207. if (!getFormatedGUID(&pSignedTemplate[nOffset_GUID], nSize_GUID))
  208. {
  209. aeStatus = PSE_PR_INTERNAL_ERROR;
  210. break;
  211. }
  212. if (SGX_SUCCESS == sgx_ecdsa_sign(&pSignedTemplate[nOffset_CSRInfo], nSize_CSRInfo,
  213. (sgx_ec256_private_t *)pPrivateKey,
  214. (sgx_ec256_signature_t *)SerializedSignature,
  215. csr_ecc_handle))
  216. {
  217. /* Convert the signature to big endian format */
  218. SwapEndian_32B(SerializedSignature);
  219. SwapEndian_32B(&(SerializedSignature[32]));
  220. }
  221. else
  222. {
  223. break;
  224. }
  225. // SigBuffer = 0x02 || length of component X || Component X of Sigature || 0x02 || length of component Y || Component Y of Sigature
  226. uint8_t SigBuffer[70] = {0};
  227. uint16_t i = 0;
  228. // Place signature X,Y component into buffer
  229. // SerializedSignature[0]~ is X component and SerializedSignature[32]~ is Y component
  230. for (int offset = 0; offset <= LEN_ECDSA_SIG_COMP; offset += LEN_ECDSA_SIG_COMP)
  231. {
  232. SigBuffer[i++] = 0x02;
  233. if ((SerializedSignature[offset] & 0x80))
  234. {
  235. // Add a leading zero if the bit 8 of the first byte is 1
  236. SigBuffer[i++] = LEN_ECDSA_SIG_COMP + 1;
  237. SigBuffer[i++] = 0x00;
  238. memcpy(&SigBuffer[i], &SerializedSignature[offset], LEN_ECDSA_SIG_COMP);
  239. i += LEN_ECDSA_SIG_COMP;
  240. }
  241. else
  242. {
  243. // The leading j bytes need to be removed if those bytes are all 0s and the bit 8 of the j+1 byte is also 0
  244. int j = 0;
  245. while (j < LEN_ECDSA_SIG_COMP - 1 && SerializedSignature[offset + j] == 0 && (SerializedSignature[offset + j + 1] & 0x80) == 0)
  246. j++;
  247. if (j == LEN_ECDSA_SIG_COMP - 1 && SerializedSignature[offset + j] == 0)
  248. {
  249. // The component buffer is all 0s, which should not happen
  250. aeStatus = PSE_PR_INTERNAL_ERROR;
  251. goto exit;
  252. }
  253. SigBuffer[i++] = LEN_ECDSA_SIG_COMP - j;
  254. memcpy(&SigBuffer[i], &SerializedSignature[offset + j], LEN_ECDSA_SIG_COMP - j);
  255. i += LEN_ECDSA_SIG_COMP - j;
  256. }
  257. }
  258. pSignedTemplate[nOffset_SigSize1] = (Ipp8u)(i + 3);
  259. pSignedTemplate[nOffset_SigSize2] = (Ipp8u)(i);
  260. memcpy(&pSignedTemplate[nOffset_SigX], SigBuffer, i);
  261. *pnBytes = (uint16_t)(nOffset_SigX + i);
  262. uint16_t csrLength = (uint16_t)(*pnBytes - 4);
  263. pSignedTemplate[nOffset_CSRSize+0] = (Ipp8u)(csrLength >> 8);
  264. pSignedTemplate[nOffset_CSRSize+1] = (Ipp8u)(csrLength & 0xff);
  265. aeStatus = AE_SUCCESS;
  266. } while (0);
  267. exit:
  268. // If we weren't successful, don't let any data out
  269. if (AE_FAILED(aeStatus))
  270. {
  271. if (NULL != pSignedTemplate && NULL != pnBytes)
  272. memset_s(pSignedTemplate, *pnBytes, 0, *pnBytes);
  273. aeStatus = PSE_PR_SIGNING_CSR_ERROR;
  274. }
  275. #if 0 //for debugging to verify signature was generated correctly
  276. else
  277. {
  278. uint8_t result;
  279. // Convert the signature back to little endian, for verification API
  280. SwapEndian_32B(SerializedSignature);
  281. SwapEndian_32B(&(SerializedSignature[32]));
  282. if ((SGX_SUCCESS != sgx_ecdsa_verify(&pSignedTemplate[nOffset_CSRInfo], nSize_CSRInfo,
  283. (sgx_ec256_public_t *)pPublicKey, (sgx_ec256_signature_t *)SerializedSignature,
  284. &result, csr_ecc_handle)) || (result != SGX_EC_VALID ))
  285. {
  286. aeStatus = PSE_PR_SIGNING_CSR_ERROR;
  287. }
  288. }
  289. #endif
  290. return aeStatus;
  291. }