aesm_encode.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * Copyright (C) 2011-2016 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 "aesm_encode.h"
  32. #include "se_memcpy.h"
  33. #include "AEClass.h"
  34. #include "PVEClass.h"
  35. #include "tlv_common.h"
  36. #include <openssl/evp.h>
  37. #include <openssl/bio.h>
  38. #include <openssl/buffer.h>
  39. #include <openssl/x509v3.h>
  40. #include <list>
  41. /**
  42. * Method converts byte containing value from 0x00-0x0F into its corresponding ASCII code,
  43. * e.g. converts 0x00 to '0', 0x0A to 'A'.
  44. * Note: This is mainly a helper method for internal use in byte_array_to_hex_string().
  45. *
  46. * @param in byte to be converted (allowed values: 0x00-0x0F)
  47. *
  48. * @return ASCII code representation of the byte or 0 if method failed (e.g input value was not in provided range).
  49. */
  50. static uint8_t convert_value_to_ascii(uint8_t in)
  51. {
  52. if(in <= 0x09)
  53. {
  54. return (uint8_t)(in + '0');
  55. }
  56. else if(in <= 0x0F)
  57. {
  58. return (uint8_t)(in - 10 + 'A');
  59. }
  60. return 0;
  61. }
  62. /**
  63. * Method converts char containing ASCII code into its corresponding value,
  64. * e.g. converts '0' to 0x00, 'A' to 0x0A.
  65. *
  66. * @param in char containing ASCII code (allowed values: '0-9', 'a-f', 'A-F')
  67. * @param val output parameter containing converted value, if method succeeds.
  68. *
  69. * @return true if conversion succeeds, false otherwise
  70. */
  71. static bool convert_ascii_to_value(uint8_t in, uint8_t& val)
  72. {
  73. if(in >= '0' && in <= '9')
  74. {
  75. val = static_cast<uint8_t>(in - '0');
  76. }
  77. else if(in >= 'A' && in <= 'F')
  78. {
  79. val = static_cast<uint8_t>(in - 'A'+10);
  80. }
  81. else if(in >= 'a' && in <= 'f')
  82. {
  83. val = static_cast<uint8_t>(in - 'a'+10);
  84. }
  85. else
  86. {
  87. return false;
  88. }
  89. return true;
  90. }
  91. //Function to do HEX encoding of array of bytes
  92. //@param in_buf, bytes array whose length is in_size
  93. // out_buf, output the HEX encoding of in_buf on success.
  94. //@return true on success and false on error
  95. //The out_size must always be 2*in_size since each byte into encoded by 2 characters
  96. static bool byte_array_to_hex_string(const uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t out_size)
  97. {
  98. if(in_size>UINT32_MAX/2)return false;
  99. if(in_buf==NULL||out_buf==NULL|| out_size!=in_size*2 )return false;
  100. for(uint32_t i=0; i< in_size; i++)
  101. {
  102. *out_buf++ = convert_value_to_ascii( static_cast<uint8_t>(*in_buf >> 4));
  103. *out_buf++ = convert_value_to_ascii( static_cast<uint8_t>(*in_buf & 0xf));
  104. in_buf++;
  105. }
  106. return true;
  107. }
  108. //Function to do HEX decoding
  109. //@param in_buf, character strings which are HEX encoding of a byte array
  110. // out_buf, output the decode byte array on success
  111. //@return true on success and false on error
  112. //The in_size must be even number and equals 2*out_size
  113. static bool hex_string_to_byte_array(const uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t out_size)
  114. {
  115. if(out_size>UINT32_MAX/2)return false;
  116. if(in_buf==NULL||out_buf==NULL||out_size*2!=in_size)return false;
  117. for(uint32_t i=0;i<out_size;i++)
  118. {
  119. uint8_t value_first, value_second;
  120. if(!convert_ascii_to_value(in_buf[i*2], value_first))
  121. return false;
  122. if(!convert_ascii_to_value(in_buf[i*2+1], value_second))
  123. return false;
  124. out_buf[i] = static_cast<uint8_t>(value_second+ (value_first<<4));
  125. }
  126. return true;
  127. }
  128. //Function to use openssl to do BASE64 encoding
  129. static bool base_64_encode(const uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t *out_size)
  130. {
  131. BIO* bioMem = NULL;
  132. bool ret = false;
  133. BIO *bio64 = NULL;
  134. BIO_METHOD *bm = BIO_f_base64();
  135. if(bm == NULL)
  136. goto ret_point;
  137. bio64 = BIO_new(bm);
  138. if(bio64 == NULL)
  139. goto ret_point;
  140. BIO_set_flags(bio64, BIO_FLAGS_BASE64_NO_NL);
  141. bm = BIO_s_mem();
  142. if(bm == NULL)
  143. goto ret_point;
  144. bioMem = BIO_new(bm);
  145. if(bioMem == NULL)
  146. goto ret_point;
  147. (void)BIO_push(bio64, bioMem);
  148. if(BIO_write(bio64, in_buf, in_size) != (int)in_size){
  149. goto ret_point;
  150. }
  151. (void)BIO_flush(bio64);
  152. BUF_MEM *bptr;
  153. BIO_get_mem_ptr(bio64, &bptr);
  154. if(bptr==NULL){
  155. goto ret_point;
  156. }
  157. if(*out_size < bptr->length){
  158. goto ret_point;
  159. }
  160. if(memcpy_s(out_buf, *out_size,bptr->data, bptr->length)!=0)
  161. goto ret_point;
  162. *out_size = static_cast<uint32_t>(bptr->length);
  163. ret = true;
  164. ret_point:
  165. BIO_free_all(bio64);//we need not free bioMem too because the free_all has free it.
  166. return ret;
  167. }
  168. //Function to use openssl to do BASE64 decoding
  169. static bool base_64_decode(const uint8_t *in_buf, uint32_t in_size, uint8_t *out_buf, uint32_t *out_size)
  170. {
  171. BIO *b64 =NULL, *bmem = NULL;
  172. bool ret = false;
  173. int read=0;
  174. memset(out_buf, 0, *out_size);
  175. BIO_METHOD *bm = BIO_f_base64();
  176. if(bm == NULL)
  177. goto ret_point;
  178. b64 = BIO_new(bm);
  179. if(b64 == NULL)
  180. goto ret_point;
  181. BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
  182. bmem = BIO_new_mem_buf(const_cast<uint8_t *>(in_buf), in_size);
  183. if(bmem == NULL){
  184. goto ret_point;
  185. }
  186. bmem = BIO_push(b64, bmem);
  187. read = BIO_read(bmem, out_buf, *out_size);
  188. if(read < 0)
  189. goto ret_point;
  190. *out_size = read;
  191. ret = true;
  192. ret_point:
  193. BIO_free_all(bmem);
  194. return ret;
  195. }
  196. //Function to give an upper bound of size of data after BASE64 decoding
  197. //@param length: the length in bytes of BASE64 encoded data
  198. //@return an upper bound of length in bytes of decoded data
  199. static uint32_t get_unbase_64_length(uint32_t length)
  200. {
  201. return (length * 3 / 4) + ((length * 3 % 4 > 0) ? 1 : 0 );
  202. }
  203. //Function to give an upper bound of size of data after BASR64 encoding
  204. //@param length: the length in bytes of data to be encoded
  205. //@return an upper bound of length in bytes of data after encoding
  206. static uint32_t get_base_64_length_upbound(uint32_t length)
  207. {
  208. uint32_t extra = (length+9)/10+50;//using enough extra memory
  209. return extra+(length*4+2)/3;
  210. }
  211. uint32_t get_request_encoding_length(const uint8_t *req)
  212. {
  213. //adding 1 extra byte to hold '\0'
  214. return static_cast<uint32_t>(2*PROVISION_REQUEST_HEADER_SIZE+get_base_64_length_upbound(GET_BODY_SIZE_FROM_PROVISION_REQUEST(req))+1);
  215. }
  216. uint32_t get_response_decoding_length(uint32_t buf_len)
  217. {
  218. if(buf_len<2*PROVISION_RESPONSE_HEADER_SIZE)
  219. return 0;
  220. return static_cast<uint32_t>(get_unbase_64_length(buf_len-2*static_cast<uint32_t>(PROVISION_RESPONSE_HEADER_SIZE)) + PROVISION_RESPONSE_HEADER_SIZE);
  221. }
  222. bool encode_request(const uint8_t *req, uint32_t req_len, uint8_t *out_buf, uint32_t *out_len)
  223. {
  224. uint32_t encoded_header_size = static_cast<uint32_t>(2*PROVISION_REQUEST_HEADER_SIZE);
  225. if(*out_len<encoded_header_size)
  226. return false;
  227. if(req_len<PROVISION_REQUEST_HEADER_SIZE)
  228. return false;
  229. if(!byte_array_to_hex_string(req, PROVISION_REQUEST_HEADER_SIZE, out_buf, encoded_header_size))
  230. return false;
  231. uint32_t left_size = *out_len - encoded_header_size;
  232. if(req_len != GET_SIZE_FROM_PROVISION_REQUEST(req))
  233. return false;//error in input message
  234. if(!base_64_encode(req+PROVISION_REQUEST_HEADER_SIZE, GET_BODY_SIZE_FROM_PROVISION_REQUEST(req), out_buf + encoded_header_size, &left_size))
  235. return false;
  236. *out_len = left_size + encoded_header_size;
  237. return true;
  238. }
  239. bool decode_response(const uint8_t *input_buf, uint32_t input_len, uint8_t *resp, uint32_t *out_len)
  240. {
  241. if(input_len < 2*PROVISION_RESPONSE_HEADER_SIZE)
  242. return false;
  243. if(*out_len < PROVISION_RESPONSE_HEADER_SIZE)
  244. return false;
  245. if(!hex_string_to_byte_array(input_buf, static_cast<uint32_t>(2*PROVISION_RESPONSE_HEADER_SIZE), resp, static_cast<uint32_t>(PROVISION_RESPONSE_HEADER_SIZE)))
  246. return false;
  247. if(*out_len<GET_SIZE_FROM_PROVISION_RESPONSE(resp))
  248. return false;
  249. *out_len -= static_cast<uint32_t>(PROVISION_RESPONSE_HEADER_SIZE);
  250. if(!base_64_decode(input_buf+static_cast<uint32_t>(2*PROVISION_RESPONSE_HEADER_SIZE), input_len - static_cast<uint32_t>(2*PROVISION_RESPONSE_HEADER_SIZE),
  251. resp+static_cast<uint32_t>(PROVISION_RESPONSE_HEADER_SIZE), out_len))
  252. return false;
  253. *out_len += static_cast<uint32_t>(PROVISION_RESPONSE_HEADER_SIZE);
  254. if(*out_len != GET_SIZE_FROM_PROVISION_RESPONSE(resp))
  255. return false;
  256. return true;
  257. }