optiga_crypt.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  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. return_value = OPTIGA_LIB_ERROR;
  149. break;
  150. }
  151. if (!chaining)
  152. {
  153. return_value = OPTIGA_LIB_SUCCESS;
  154. break;
  155. }
  156. else
  157. {
  158. hash_options.sDataStream.prgbStream += remaining_comm_buffer_size;
  159. size_of_data_to_hash -= remaining_comm_buffer_size;
  160. remaining_comm_buffer_size = size_of_data_to_hash;
  161. hash_options.sContextInfo.eContextAction = eUnused;
  162. //Verify whether export + data options can be set in one command or not
  163. if (remaining_comm_bfr_sz_with_export < size_of_data_to_hash)
  164. {
  165. remaining_comm_buffer_size = remaining_comm_bfr_sz_basic;
  166. if (remaining_comm_bfr_sz_basic > size_of_data_to_hash)
  167. {
  168. remaining_comm_buffer_size = size_of_data_to_hash;
  169. }
  170. }
  171. else
  172. {
  173. hash_options.sContextInfo.eContextAction = eExport;
  174. chaining = 0;
  175. }
  176. hash_options.sDataStream.wLen = remaining_comm_buffer_size;
  177. }
  178. return_value = OPTIGA_LIB_SUCCESS;
  179. }
  180. return return_value;
  181. }
  182. optiga_lib_status_t optiga_crypt_hash_finalize(optiga_hash_context_t * hash_ctx,
  183. uint8_t * hash_output)
  184. {
  185. optiga_lib_status_t return_value;
  186. uint8_t datastream[1];
  187. sCalcHash_d hash_options;
  188. hash_options.eHashAlg = (eHashAlg_d)hash_ctx->hash_algo;
  189. hash_options.eHashDataType = eDataStream;
  190. hash_options.eHashSequence = eFinalizeHash;
  191. hash_options.sDataStream.prgbStream = datastream;
  192. hash_options.sDataStream.wLen = 0x00; //No data
  193. hash_options.sContextInfo.pbContextData = hash_ctx->context_buffer;
  194. hash_options.sContextInfo.dwContextLen = hash_ctx->context_buffer_length;
  195. hash_options.sContextInfo.eContextAction = eImport;
  196. hash_options.sOutHash.prgbBuffer = hash_output;
  197. if(hash_options.eHashAlg == eSHA256)
  198. {
  199. hash_options.sOutHash.wBufferLength = 32;
  200. }
  201. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  202. return_value = CmdLib_CalcHash(&hash_options);
  203. pal_os_lock_release();
  204. if (CMD_LIB_OK != return_value)
  205. {
  206. return OPTIGA_LIB_ERROR;
  207. }
  208. return OPTIGA_LIB_SUCCESS;
  209. }
  210. optiga_lib_status_t optiga_crypt_ecc_generate_keypair(optiga_ecc_curve_t curve_id,
  211. uint8_t key_usage,
  212. bool_t export_private_key,
  213. void * private_key,
  214. uint8_t * public_key,
  215. uint16_t * public_key_length)
  216. {
  217. optiga_lib_status_t return_value;
  218. sKeyPairOption_d keypair_options;
  219. sOutKeyPair_d public_key_out;
  220. keypair_options.eAlgId = (eAlgId_d)curve_id;
  221. keypair_options.eKeyUsage = (eKeyUsage_d)key_usage;
  222. if (export_private_key)
  223. {
  224. keypair_options.eKeyExport = eExportKeyPair;
  225. public_key_out.sPublicKey.prgbStream = public_key;
  226. public_key_out.sPublicKey.wLen = *public_key_length;
  227. public_key_out.sPrivateKey.prgbStream = private_key;
  228. public_key_out.sPrivateKey.wLen = 0xffff;
  229. }
  230. else
  231. {
  232. keypair_options.eKeyExport = eStorePrivKeyOnly;
  233. keypair_options.wOIDPrivKey = *(uint16_t *)private_key;
  234. public_key_out.sPublicKey.prgbStream = public_key;
  235. public_key_out.sPublicKey.wLen = *public_key_length;
  236. }
  237. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  238. return_value = CmdLib_GenerateKeyPair(&keypair_options,&public_key_out);
  239. pal_os_lock_release();
  240. if (CMD_LIB_OK != return_value)
  241. {
  242. return OPTIGA_LIB_ERROR;
  243. }
  244. //store updated public key length .
  245. *( public_key_length) = public_key_out.sPublicKey.wLen;
  246. return OPTIGA_LIB_SUCCESS;
  247. }
  248. optiga_lib_status_t optiga_crypt_ecdsa_sign (uint8_t * digest,
  249. uint8_t digest_length,
  250. optiga_key_id_t private_key,
  251. uint8_t * signature,
  252. uint16_t * signature_length)
  253. {
  254. optiga_lib_status_t return_value;
  255. sbBlob_d sign;
  256. sCalcSignOptions_d sign_options;
  257. sign_options.eSignScheme = eECDSA_FIPS_186_3_WITHOUT_HASH;
  258. sign_options.wOIDSignKey = private_key;
  259. sign_options.sDigestToSign.prgbStream = digest;
  260. sign_options.sDigestToSign.wLen = digest_length;
  261. sign.prgbStream = signature;
  262. sign.wLen = *signature_length;
  263. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  264. return_value = CmdLib_CalculateSign(&sign_options,&sign);
  265. pal_os_lock_release();
  266. if (CMD_LIB_OK != return_value)
  267. {
  268. return OPTIGA_LIB_ERROR;
  269. }
  270. *signature_length = sign.wLen;
  271. return OPTIGA_LIB_SUCCESS;
  272. }
  273. optiga_lib_status_t optiga_crypt_ecdsa_verify (uint8_t * digest,
  274. uint8_t digest_length,
  275. uint8_t * signature,
  276. uint16_t signature_length,
  277. uint8_t public_key_source_type,
  278. void * public_key)
  279. {
  280. optiga_lib_status_t return_value;
  281. sVerifyOption_d verifysign_options;
  282. sbBlob_d sign, dgst;
  283. verifysign_options.eSignScheme = eECDSA_FIPS_186_3_WITHOUT_HASH;
  284. verifysign_options.sPubKeyInput.eAlgId = (eAlgId_d )(((public_key_from_host_t *)public_key)->curve);
  285. if (public_key_source_type == OPTIGA_CRYPT_HOST_DATA)
  286. {
  287. verifysign_options.eVerifyDataType = eDataStream;
  288. verifysign_options.sPubKeyInput.sDataStream.prgbStream = (uint8_t *)((( public_key_from_host_t *)public_key)->public_key);
  289. verifysign_options.sPubKeyInput.sDataStream.wLen = (((public_key_from_host_t *)public_key)->length);
  290. }
  291. else if (public_key_source_type == OPTIGA_CRYPT_OID_DATA)
  292. {
  293. verifysign_options.eVerifyDataType = eOIDData;
  294. verifysign_options.wOIDPubKey = *((uint16_t *)public_key);
  295. }
  296. dgst.prgbStream = digest;
  297. dgst.wLen = digest_length;
  298. sign.prgbStream = signature;
  299. sign.wLen = signature_length;
  300. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  301. return_value = CmdLib_VerifySign(&verifysign_options, &dgst, &sign);
  302. pal_os_lock_release();
  303. if(CMD_LIB_OK != return_value)
  304. {
  305. return OPTIGA_LIB_ERROR;
  306. }
  307. return OPTIGA_LIB_SUCCESS;
  308. }
  309. optiga_lib_status_t optiga_crypt_ecdh(optiga_key_id_t private_key,
  310. public_key_from_host_t * public_key,
  311. bool_t export_to_host,
  312. uint8_t * shared_secret)
  313. {
  314. optiga_lib_status_t return_value = OPTIGA_LIB_ERROR;
  315. sCalcSSecOptions_d shared_secret_options;
  316. sbBlob_d sharedsecret;
  317. shared_secret_options.eKeyAgreementType = eECDH_NISTSP80056A;
  318. shared_secret_options.wOIDPrivKey = private_key;
  319. public_key->curve == OPTIGA_ECC_NIST_P_256 ? (sharedsecret.wLen = 32) : (sharedsecret.wLen = 64);
  320. shared_secret_options.ePubKeyAlgId = (eAlgId_d)public_key->curve;
  321. shared_secret_options.sPubKey.prgbStream = public_key->public_key;
  322. shared_secret_options.sPubKey.wLen = public_key->length;
  323. if (export_to_host == 1)
  324. {
  325. shared_secret_options.wOIDSharedSecret = 0x0000;
  326. sharedsecret.prgbStream = (uint8_t *)shared_secret;
  327. }
  328. else
  329. {
  330. //shared secret is stored in OID of OPTIGA
  331. shared_secret_options.wOIDSharedSecret = *((uint16_t *)shared_secret);
  332. }
  333. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  334. return_value = CmdLib_CalculateSharedSecret(&shared_secret_options, &sharedsecret);
  335. pal_os_lock_release();
  336. if(CMD_LIB_OK != return_value)
  337. {
  338. return_value = OPTIGA_LIB_ERROR;
  339. }
  340. return OPTIGA_LIB_SUCCESS;
  341. }
  342. optiga_lib_status_t optiga_crypt_tls_prf_sha256(uint16_t secret,
  343. uint8_t * label,
  344. uint16_t label_length,
  345. uint8_t * seed,
  346. uint16_t seed_length,
  347. uint16_t derived_key_length,
  348. bool_t export_to_host,
  349. uint8_t * derived_key)
  350. {
  351. optiga_lib_status_t return_value = OPTIGA_LIB_ERROR;
  352. sDeriveKeyOptions_d derivekey_options;
  353. sbBlob_d derivekey_output_buffer;
  354. derivekey_options.eKDM = eTLS_PRF_SHA256;
  355. derivekey_options.sSeed.prgbStream = seed;
  356. derivekey_options.sSeed.wLen = seed_length;
  357. derivekey_options.wOIDSharedSecret = secret;
  358. if (derived_key_length < 16)
  359. {
  360. derived_key_length += (16 - derived_key_length);
  361. }
  362. derivekey_options.wDerivedKeyLen = derived_key_length;
  363. if (export_to_host == 1)
  364. {
  365. derivekey_options.wOIDDerivedKey = 0x0000;
  366. derivekey_output_buffer.prgbStream = (uint8_t *)derived_key;
  367. derivekey_output_buffer.wLen = derived_key_length;
  368. }
  369. else
  370. {
  371. derivekey_options.wOIDDerivedKey = *((uint16_t *)derived_key);
  372. }
  373. while (pal_os_lock_acquire() != OPTIGA_LIB_SUCCESS);
  374. return_value = CmdLib_DeriveKey(&derivekey_options, &derivekey_output_buffer);
  375. pal_os_lock_release();
  376. if(CMD_LIB_OK == return_value)
  377. {
  378. return_value = OPTIGA_LIB_SUCCESS;
  379. }
  380. return OPTIGA_LIB_ERROR;
  381. }