optiga_crypt.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. /**
  2. * MIT License
  3. *
  4. * Copyright (c) 2018 Infineon Technologies AG
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. * SOFTWARE
  23. *
  24. * \file
  25. *
  26. * \brief This file implements the OPTIGA Crypto toolbox APIs.
  27. *
  28. * \addtogroup grOptigaCrypt
  29. * @{
  30. */
  31. #include "optiga/optiga_crypt.h"
  32. #include "optiga/pal/pal_os_lock.h"
  33. optiga_lib_status_t optiga_crypt_random(optiga_rng_types_t rng_type,
  34. uint8_t * random_data,
  35. uint16_t random_data_length)
  36. {
  37. optiga_lib_status_t return_value = OPTIGA_LIB_ERROR;
  38. sRngOptions_d rand_options;
  39. sCmdResponse_d rand_response;
  40. rand_options.eRngType = (eRngType_d)rng_type;
  41. rand_options.wRandomDataLen = random_data_length;
  42. rand_response.prgbBuffer = random_data;
  43. rand_response.wBufferLength = random_data_length;
  44. rand_response.wRespLength = 0;
  45. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  46. return_value = CmdLib_GetRandom(&rand_options,&rand_response);
  47. pal_os_lock_release();
  48. if (CMD_LIB_OK != return_value)
  49. {
  50. return OPTIGA_LIB_ERROR;
  51. }
  52. return OPTIGA_LIB_SUCCESS;
  53. }
  54. optiga_lib_status_t optiga_crypt_hash_start(optiga_hash_context_t * hash_ctx)
  55. {
  56. optiga_lib_status_t return_value;
  57. uint8_t rgbDataStream[1];
  58. sCalcHash_d hash_options;
  59. hash_options.eHashAlg = (eHashAlg_d)(hash_ctx->hash_algo);
  60. hash_options.eHashDataType = eDataStream;
  61. hash_options.eHashSequence = eStartHash;
  62. hash_options.sDataStream.prgbStream = rgbDataStream;
  63. hash_options.sDataStream.wLen =0x00; //No data
  64. hash_options.sContextInfo.pbContextData = hash_ctx->context_buffer;
  65. hash_options.sContextInfo.dwContextLen = hash_ctx->context_buffer_length;
  66. hash_options.sContextInfo.eContextAction = eExport;
  67. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  68. return_value = CmdLib_CalcHash(&hash_options);
  69. pal_os_lock_release();
  70. if (CMD_LIB_OK != return_value)
  71. {
  72. return OPTIGA_LIB_ERROR;
  73. }
  74. return OPTIGA_LIB_SUCCESS;
  75. }
  76. optiga_lib_status_t optiga_crypt_hash_update(optiga_hash_context_t * hash_ctx,
  77. uint8_t source_of_data_to_hash,
  78. void * data_to_hash)
  79. {
  80. optiga_lib_status_t return_value;
  81. sCalcHash_d hash_options;
  82. //To read the maximum communication buffer size.
  83. uint16_t max_comms_buffer;
  84. //To hold the remaining communication buffer size to hold the data
  85. uint16_t remaining_comm_buffer_size = 0;
  86. //Hash the data
  87. //Available_Size = (wMaxCommsBuffer - #CALC_HASH_FIXED_OVERHEAD_SIZE)
  88. uint16_t remaining_comm_bfr_sz_basic;
  89. //Import context to security chip, calculate hash and export hash
  90. //Available_Size = (wMaxCommsBuffer - #CALC_HASH_FIXED_OVERHEAD_SIZE - #CALC_HASH_IMPORT_AND_EXPORT_OVERHEAD_SIZE - #CALC_HASH_SHA256_CONTEXT_SIZE)
  91. uint16_t remaining_comm_bfr_sz_with_import_export;
  92. //Import context to security chip and calculate hash
  93. //Available_Size = (wMaxCommsBuffer - #CALC_HASH_FIXED_OVERHEAD_SIZE - #CALC_HASH_IMPORT_OR_EXPORT_OVERHEAD_SIZE - #CALC_HASH_SHA256_CONTEXT_SIZE)
  94. uint16_t remaining_comm_bfr_sz_with_import;
  95. //Calulate hash and export context out of security chip
  96. //Available_Size = (wMaxCommsBuffer - CALC_HASH_FIXED_OVERHEAD_SIZE - CALC_HASH_IMPORT_OR_EXPORT_OVERHEAD_SIZE)
  97. uint16_t remaining_comm_bfr_sz_with_export;
  98. uint32_t size_of_data_to_hash = 0;
  99. uint8_t chaining = 0;
  100. hash_options.eHashAlg = (eHashAlg_d)(hash_ctx->hash_algo);
  101. hash_options.eHashDataType = source_of_data_to_hash == OPTIGA_CRYPT_HOST_DATA?eDataStream:eOIDData;
  102. hash_options.eHashSequence = eContinueHash;
  103. //Hash context
  104. hash_options.sContextInfo.pbContextData = hash_ctx->context_buffer;
  105. hash_options.sContextInfo.dwContextLen = hash_ctx->context_buffer_length;
  106. hash_options.sContextInfo.eContextAction = eImportExport;
  107. max_comms_buffer = CmdLib_GetMaxCommsBufferSize();
  108. remaining_comm_bfr_sz_basic = max_comms_buffer - CALC_HASH_FIXED_OVERHEAD_SIZE;
  109. remaining_comm_bfr_sz_with_import_export = max_comms_buffer -(CALC_HASH_FIXED_OVERHEAD_SIZE + \
  110. CALC_HASH_IMPORT_AND_EXPORT_OVERHEAD_SIZE + \
  111. CALC_HASH_SHA256_CONTEXT_SIZE);
  112. remaining_comm_bfr_sz_with_import = max_comms_buffer -(CALC_HASH_FIXED_OVERHEAD_SIZE+ \
  113. CALC_HASH_IMPORT_OR_EXPORT_OVERHEAD_SIZE+ \
  114. CALC_HASH_SHA256_CONTEXT_SIZE);
  115. remaining_comm_bfr_sz_with_export = max_comms_buffer -(CALC_HASH_FIXED_OVERHEAD_SIZE + \
  116. CALC_HASH_IMPORT_OR_EXPORT_OVERHEAD_SIZE);
  117. if ((eDataType_d)source_of_data_to_hash == OPTIGA_CRYPT_HOST_DATA)
  118. {
  119. hash_options.sDataStream.prgbStream = (uint8_t *)(((hash_data_from_host_t *)data_to_hash)->buffer);
  120. size_of_data_to_hash = ((hash_data_from_host_t *)data_to_hash)->length;
  121. remaining_comm_buffer_size = size_of_data_to_hash;
  122. //Verify whether (Import & export) + data options can be set in one command or not
  123. if (remaining_comm_bfr_sz_with_import_export<size_of_data_to_hash)
  124. {
  125. chaining = 1;
  126. remaining_comm_buffer_size = remaining_comm_bfr_sz_with_import;
  127. if (remaining_comm_bfr_sz_with_import>size_of_data_to_hash)
  128. {
  129. remaining_comm_buffer_size = size_of_data_to_hash;
  130. }
  131. hash_options.sContextInfo.eContextAction = eImport;
  132. }
  133. hash_options.sDataStream.wLen = remaining_comm_buffer_size;
  134. }
  135. else
  136. {
  137. hash_options.sOIDData.wOID = ((hash_data_in_optiga_t *)data_to_hash)->oid;
  138. hash_options.sOIDData.wOffset = ((hash_data_in_optiga_t *)data_to_hash)->offset;
  139. hash_options.sOIDData.wLength = ((hash_data_in_optiga_t *)data_to_hash)->length;
  140. }
  141. while (1)
  142. {
  143. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  144. return_value = CmdLib_CalcHash(&hash_options);
  145. pal_os_lock_release();
  146. if (CMD_LIB_OK != return_value)
  147. {
  148. break;
  149. }
  150. if (!chaining)
  151. {
  152. return_value = OPTIGA_LIB_SUCCESS;
  153. break;
  154. }
  155. else
  156. {
  157. hash_options.sDataStream.prgbStream += remaining_comm_buffer_size;
  158. size_of_data_to_hash -= remaining_comm_buffer_size;
  159. remaining_comm_buffer_size = size_of_data_to_hash;
  160. hash_options.sContextInfo.eContextAction = eUnused;
  161. //Verify whether export + data options can be set in one command or not
  162. if (remaining_comm_bfr_sz_with_export < size_of_data_to_hash)
  163. {
  164. remaining_comm_buffer_size = remaining_comm_bfr_sz_basic;
  165. if (remaining_comm_bfr_sz_basic > size_of_data_to_hash)
  166. {
  167. remaining_comm_buffer_size = size_of_data_to_hash;
  168. }
  169. }
  170. else
  171. {
  172. hash_options.sContextInfo.eContextAction = eExport;
  173. chaining = 0;
  174. }
  175. hash_options.sDataStream.wLen = remaining_comm_buffer_size;
  176. }
  177. }
  178. return return_value;
  179. }
  180. optiga_lib_status_t optiga_crypt_hash_finalize(optiga_hash_context_t * hash_ctx,
  181. uint8_t * hash_output)
  182. {
  183. optiga_lib_status_t return_value;
  184. uint8_t datastream[1];
  185. sCalcHash_d hash_options;
  186. hash_options.eHashAlg = (eHashAlg_d)hash_ctx->hash_algo;
  187. hash_options.eHashDataType = eDataStream;
  188. hash_options.eHashSequence = eFinalizeHash;
  189. hash_options.sDataStream.prgbStream = datastream;
  190. hash_options.sDataStream.wLen = 0x00; //No data
  191. hash_options.sContextInfo.pbContextData = hash_ctx->context_buffer;
  192. hash_options.sContextInfo.dwContextLen = hash_ctx->context_buffer_length;
  193. hash_options.sContextInfo.eContextAction = eImport;
  194. hash_options.sOutHash.prgbBuffer = hash_output;
  195. if(hash_options.eHashAlg == eSHA256)
  196. {
  197. hash_options.sOutHash.wBufferLength = 32;
  198. }
  199. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  200. return_value = CmdLib_CalcHash(&hash_options);
  201. pal_os_lock_release();
  202. if (CMD_LIB_OK != return_value)
  203. {
  204. return OPTIGA_LIB_ERROR;
  205. }
  206. return OPTIGA_LIB_SUCCESS;
  207. }
  208. optiga_lib_status_t optiga_crypt_ecc_generate_keypair(optiga_ecc_curve_t curve_id,
  209. uint8_t key_usage,
  210. bool_t export_private_key,
  211. void * private_key,
  212. uint8_t * public_key,
  213. uint16_t * public_key_length)
  214. {
  215. optiga_lib_status_t return_value;
  216. sKeyPairOption_d keypair_options;
  217. sOutKeyPair_d public_key_out;
  218. keypair_options.eAlgId = (eAlgId_d)curve_id;
  219. keypair_options.eKeyUsage = (eKeyUsage_d)key_usage;
  220. if (export_private_key)
  221. {
  222. keypair_options.eKeyExport = eExportKeyPair;
  223. public_key_out.sPublicKey.prgbStream = public_key;
  224. public_key_out.sPublicKey.wLen = *public_key_length;
  225. public_key_out.sPrivateKey.prgbStream = private_key;
  226. public_key_out.sPrivateKey.wLen = 0xffff;
  227. }
  228. else
  229. {
  230. keypair_options.eKeyExport = eStorePrivKeyOnly;
  231. keypair_options.wOIDPrivKey = *(uint16_t *)private_key;
  232. public_key_out.sPublicKey.prgbStream = public_key;
  233. public_key_out.sPublicKey.wLen = *public_key_length;
  234. }
  235. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  236. return_value = CmdLib_GenerateKeyPair(&keypair_options,&public_key_out);
  237. pal_os_lock_release();
  238. if (CMD_LIB_OK != return_value)
  239. {
  240. return OPTIGA_LIB_ERROR;
  241. }
  242. //store updated public key length .
  243. *( public_key_length) = public_key_out.sPublicKey.wLen;
  244. return OPTIGA_LIB_SUCCESS;
  245. }
  246. optiga_lib_status_t optiga_crypt_ecdsa_sign (uint8_t * digest,
  247. uint8_t digest_length,
  248. optiga_key_id_t private_key,
  249. uint8_t * signature,
  250. uint16_t * signature_length)
  251. {
  252. optiga_lib_status_t return_value;
  253. sbBlob_d sign;
  254. sCalcSignOptions_d sign_options;
  255. sign_options.eSignScheme = eECDSA_FIPS_186_3_WITHOUT_HASH;
  256. sign_options.wOIDSignKey = private_key;
  257. sign_options.sDigestToSign.prgbStream = digest;
  258. sign_options.sDigestToSign.wLen = digest_length;
  259. sign.prgbStream = signature;
  260. sign.wLen = *signature_length;
  261. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  262. return_value = CmdLib_CalculateSign(&sign_options,&sign);
  263. pal_os_lock_release();
  264. if (CMD_LIB_OK != return_value)
  265. {
  266. return OPTIGA_LIB_ERROR;
  267. }
  268. *signature_length = sign.wLen;
  269. return OPTIGA_LIB_SUCCESS;
  270. }
  271. optiga_lib_status_t optiga_crypt_ecdsa_verify (uint8_t * digest,
  272. uint8_t digest_length,
  273. uint8_t * signature,
  274. uint16_t signature_length,
  275. uint8_t public_key_source_type,
  276. void * public_key)
  277. {
  278. optiga_lib_status_t return_value;
  279. sVerifyOption_d verifysign_options;
  280. sbBlob_d sign, dgst;
  281. verifysign_options.eSignScheme = eECDSA_FIPS_186_3_WITHOUT_HASH;
  282. verifysign_options.sPubKeyInput.eAlgId = (eAlgId_d )(((public_key_from_host_t *)public_key)->curve);
  283. if (public_key_source_type == OPTIGA_CRYPT_HOST_DATA)
  284. {
  285. verifysign_options.eVerifyDataType = eDataStream;
  286. verifysign_options.sPubKeyInput.sDataStream.prgbStream = (uint8_t *)((( public_key_from_host_t *)public_key)->public_key);
  287. verifysign_options.sPubKeyInput.sDataStream.wLen = (((public_key_from_host_t *)public_key)->length);
  288. }
  289. else if (public_key_source_type == OPTIGA_CRYPT_OID_DATA)
  290. {
  291. verifysign_options.eVerifyDataType = eOIDData;
  292. verifysign_options.wOIDPubKey = *((uint16_t *)public_key);
  293. }
  294. dgst.prgbStream = digest;
  295. dgst.wLen = digest_length;
  296. sign.prgbStream = signature;
  297. sign.wLen = signature_length;
  298. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  299. return_value = CmdLib_VerifySign(&verifysign_options, &dgst, &sign);
  300. pal_os_lock_release();
  301. if(CMD_LIB_OK == return_value)
  302. {
  303. return_value = OPTIGA_LIB_SUCCESS;
  304. }
  305. return return_value;
  306. }
  307. optiga_lib_status_t optiga_crypt_ecdh(optiga_key_id_t private_key,
  308. public_key_from_host_t * public_key,
  309. bool_t export_to_host,
  310. uint8_t * shared_secret)
  311. {
  312. optiga_lib_status_t return_value = OPTIGA_LIB_ERROR;
  313. sCalcSSecOptions_d shared_secret_options;
  314. sbBlob_d sharedsecret;
  315. shared_secret_options.eKeyAgreementType = eECDH_NISTSP80056A;
  316. shared_secret_options.wOIDPrivKey = private_key;
  317. public_key->curve == OPTIGA_ECC_NIST_P_256 ? (sharedsecret.wLen = 32) : (sharedsecret.wLen = 64);
  318. shared_secret_options.ePubKeyAlgId = (eAlgId_d)public_key->curve;
  319. shared_secret_options.sPubKey.prgbStream = public_key->public_key;
  320. shared_secret_options.sPubKey.wLen = public_key->length;
  321. if (export_to_host == 1)
  322. {
  323. shared_secret_options.wOIDSharedSecret = 0x0000;
  324. sharedsecret.prgbStream = (uint8_t *)shared_secret;
  325. }
  326. else
  327. {
  328. //shared secret is stored in OID of OPTIGA
  329. shared_secret_options.wOIDSharedSecret = *((uint16_t *)shared_secret);
  330. }
  331. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  332. return_value = CmdLib_CalculateSharedSecret(&shared_secret_options, &sharedsecret);
  333. pal_os_lock_release();
  334. if(CMD_LIB_OK == return_value)
  335. {
  336. return_value = OPTIGA_LIB_SUCCESS;
  337. }
  338. return return_value;
  339. }
  340. optiga_lib_status_t optiga_crypt_tls_prf_sha256(uint16_t secret,
  341. uint8_t * label,
  342. uint16_t label_length,
  343. uint8_t * seed,
  344. uint16_t seed_length,
  345. uint16_t derived_key_length,
  346. bool_t export_to_host,
  347. uint8_t * derived_key)
  348. {
  349. optiga_lib_status_t return_value = OPTIGA_LIB_ERROR;
  350. sDeriveKeyOptions_d derivekey_options;
  351. sbBlob_d derivekey_output_buffer;
  352. derivekey_options.eKDM = eTLS_PRF_SHA256;
  353. derivekey_options.sSeed.prgbStream = seed;
  354. derivekey_options.sSeed.wLen = seed_length;
  355. derivekey_options.wOIDSharedSecret = secret;
  356. if (derived_key_length < 16)
  357. {
  358. derived_key_length += (16 - derived_key_length);
  359. }
  360. derivekey_options.wDerivedKeyLen = derived_key_length;
  361. if (export_to_host == 1)
  362. {
  363. derivekey_options.wOIDDerivedKey = 0x0000;
  364. derivekey_output_buffer.prgbStream = (uint8_t *)derived_key;
  365. derivekey_output_buffer.wLen = derived_key_length;
  366. }
  367. else
  368. {
  369. derivekey_options.wOIDDerivedKey = *((uint16_t *)derived_key);
  370. }
  371. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  372. return_value = CmdLib_DeriveKey(&derivekey_options, &derivekey_output_buffer);
  373. pal_os_lock_release();
  374. if(CMD_LIB_OK == return_value)
  375. {
  376. return_value = OPTIGA_LIB_SUCCESS;
  377. }
  378. return return_value;
  379. }