optiga_util.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  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
  27. *
  28. * \addtogroup grOptigaUtil
  29. * @{
  30. */
  31. #include "optiga/optiga_util.h"
  32. #include "optiga/comms/optiga_comms.h"
  33. #include "optiga/cmd/CommandLib.h"
  34. #include "optiga/pal/pal_os_timer.h"
  35. /**
  36. * OPTIGA util module return values
  37. */
  38. ///OPTIGA util API execution is successful
  39. #define OPTIGA_UTIL_SUCCESS (0x0000)
  40. ///OPTIGA util module in busy state
  41. #define OPTIGA_UTIL_BUSY (0x0001)
  42. ///OPTIGA util API failed
  43. #define OPTIGA_UTIL_ERROR (0x0302)
  44. ///OPTIGA util API called with invalid inputs
  45. #define OPTIGA_UTIL_ERROR_INVALID_INPUT (0x0303)
  46. ///OPTIGA util API called with insufficient memory buffer
  47. #define OPTIGA_UTIL_ERROR_MEMORY_INSUFFICIENT (0x0304)
  48. ///OPTIGA util API called when, a request of same instance is already in service
  49. #define OPTIGA_UTIL_ERROR_INSTANCE_IN_USE (0x0305)
  50. ///Requested operation completed without any error
  51. #define INT_LIB_OK 0x75AB1C02
  52. ///Null parameter(s)
  53. #define INT_LIB_NULL_PARAM 0x80002001
  54. ///Invalid data in response
  55. #define INT_LIB_INVALID_RESPONSE (INT_LIB_NULL_PARAM + 1)
  56. ///Invalid access condition
  57. #define INT_LIB_INVALID_AC (INT_LIB_NULL_PARAM + 2)
  58. ///Length of input is zero
  59. #define INT_LIB_ZEROLEN_ERROR (INT_LIB_NULL_PARAM + 3)
  60. ///Invalid or unsupported parameter(s)
  61. #define INT_LIB_INVALID_PARAM (INT_LIB_NULL_PARAM + 4)
  62. ///Invalid Length
  63. #define INT_LIB_INVALID_LENGTH (INT_LIB_NULL_PARAM + 5)
  64. ///Malloc Failures
  65. #define INT_LIB_MALLOC_FAILURE (INT_LIB_NULL_PARAM + 6)
  66. ///General error
  67. #define INT_LIB_ERROR 0xFE5A5502
  68. ///Length of metadata
  69. #define LENGTH_METADATA 0x1C
  70. ///Length of certificate
  71. #define LENGTH_CERTIFICATE 1728
  72. ///Length of R and S vector
  73. #define LENGTH_RS_VECTOR 0x40
  74. ///Length of maximum additional bytes to encode sign in DER
  75. #define MAXLENGTH_SIGN_ENCODE 0x08
  76. ///Length of Signature
  77. #define LENGTH_ASN1_SIGNATURE (LENGTH_RS_VECTOR + MAXLENGTH_SIGN_ENCODE)
  78. ///size of public key for NIST-P256
  79. #define LENGTH_PUB_KEY_NISTP256 0x41
  80. ///Position of data field in metadata
  81. #define METADATA_MAX_LEN 0x001C
  82. ///Offset of Length in the metadata
  83. #define OFFSET_TLV_LENGTH 0x01
  84. ///Size of TLV Format Header
  85. #define TLV_HEADER_SIZE 0x02
  86. ///Length of metadata header
  87. #define METADATA_HEADER_SIZE TLV_HEADER_SIZE
  88. ///Value for parsig failure
  89. #define PARSE_FAILURE 0xFF
  90. ///TLV position for Length
  91. #define POS_LEN 0x01
  92. ///TLV position for Value
  93. #define POS_VAL 0x02
  94. ///Already Found
  95. #define VALUE_TAG_FOUND 0x9B
  96. ///Length of R and S vector
  97. #define VALUE_TAG_NOTFOUND 0x31
  98. ///ASN Tag for sequence
  99. #define ASN_TAG_SEQUENCE 0x30
  100. ///ASN Tag for integer
  101. #define ASN_TAG_INTEGER 0x02
  102. ///msb bit mask
  103. #define MASK_MSB 0x80
  104. ///TLS Identity Tag
  105. #define TLS_TAG 0xC0
  106. /**
  107. * \brief Enumeration to object ids.
  108. */
  109. typedef enum eObjectId_d
  110. {
  111. ///Life Cycle State Global
  112. eLCSG = 0xE0C0,
  113. ///Life Cycle State Application
  114. eLCSA = 0xF1C0
  115. }eObjectId_d;
  116. /**
  117. * \brief Structure to specify general purpose data object parameters for read
  118. */
  119. typedef struct sACVector_d
  120. {
  121. ///OID of data object
  122. uint8_t bLcsA;
  123. uint8_t bLcsG;
  124. uint8_t bLcsO;
  125. sbBlob_d *psMetaData;
  126. }sACVector_d;
  127. /**
  128. * \brief Operators available in simple and complex Access Conditions
  129. */
  130. typedef enum eOperator_d {
  131. /// Equal
  132. eOP_EQUAL = 0xFA,
  133. /// Greater than
  134. eOP_GREATER_THAN = 0xFB,
  135. /// Less than
  136. eOP_LESS_THAN = 0xFC,
  137. /// AND
  138. eOP_AND = 0xFD,
  139. /// OR
  140. eOP_OR = 0xFE
  141. } eOperator_d;
  142. /**
  143. * \brief Meta data tags
  144. */
  145. typedef enum eMetaDataTag_d
  146. {
  147. /// Object Life Cycle
  148. eLCSO = 0xC0,
  149. /// Change AC
  150. eCHANGE_AC = 0xD0,
  151. /// Read AC
  152. eREAD_AC = 0xD1
  153. } eMetaDataTag_d;
  154. /**
  155. * \brief IDs associated with the metadata access condition (simple and complex)
  156. */
  157. typedef enum eAccessConditionID_d
  158. {
  159. /// Always
  160. eACID_ALW = 0x00,
  161. /// Global life cycle status
  162. eACID_LCSG = 0x70,
  163. /// Application specific life cycle status
  164. eACID_LCSA = 0xE0,
  165. /// Data object specific life cycle status
  166. eACID_LCSO = 0xE1,
  167. /// Never
  168. eACID_NEV = 0xFF
  169. } eAccessConditionID_d;
  170. volatile static host_lib_status_t optiga_comms_status;
  171. #ifdef MODULE_ENABLE_READ_WRITE
  172. /**
  173. *
  174. * Implementation to get the metadata tag position.<br>
  175. * Returns error if metadata is not correct<br>
  176. * (if duplication of tag, metadata length / Tag length more than max length of metadata).<br> <br>
  177. *
  178. * PpbPos contains the actual position of the tag if found.<br>
  179. * PpbPos contains 0xFF if tag not found.This is considering that metatdata length is 28 bytes.
  180. * The return value in this case is #INT_LIB_OK.<br>
  181. *
  182. * \param[in] Pprgbmetadata Pointer to the buffer that contains metadata
  183. * \param[in] PbTag Tag type.
  184. * \param[in] PpbPos Pointer to tag position in metadata
  185. *
  186. * \retval #INT_LIB_OK Successful execution
  187. * \retval #INT_LIB_ERROR Failure in execution
  188. *
  189. */
  190. static int32_t __optiga_util_get_tag_position (const uint8_t* Pprgbmetadata, uint8_t PbTag, puint8_t PpbPos)
  191. {
  192. int32_t i4Status = (int32_t)INT_LIB_ERROR;
  193. uint8_t bMetadataSize, bAcLen;
  194. uint8_t bTempPos, bAlreadyFound=VALUE_TAG_NOTFOUND;
  195. do
  196. {
  197. if (NULL == Pprgbmetadata || NULL == PpbPos)
  198. {
  199. break;
  200. }
  201. bMetadataSize = Pprgbmetadata[OFFSET_TLV_LENGTH];
  202. *PpbPos = 0xFF;
  203. if (METADATA_MAX_LEN < (bMetadataSize + METADATA_HEADER_SIZE))
  204. {
  205. //Metadata Corrupted [Length field in Metadata is more than METADATA_MAX_SIZE]
  206. break;
  207. }
  208. bTempPos = METADATA_HEADER_SIZE;
  209. for(;;)
  210. {
  211. if (Pprgbmetadata[bTempPos] == PbTag)
  212. {
  213. if (VALUE_TAG_FOUND == bAlreadyFound)
  214. {
  215. i4Status = (int32_t)INT_LIB_ERROR;
  216. break;
  217. }
  218. i4Status = INT_LIB_OK;
  219. *PpbPos = bTempPos;
  220. bAlreadyFound = VALUE_TAG_FOUND;
  221. }
  222. if(0xFF == Pprgbmetadata[bTempPos])
  223. {
  224. //Length field in Metadata is not correct
  225. break;
  226. }
  227. bAcLen = Pprgbmetadata[bTempPos+1];
  228. //Is metadata Corrupted?
  229. if (METADATA_MAX_LEN <= (bAcLen+bTempPos+1))
  230. {
  231. //Metadata Corrupted
  232. break;
  233. }
  234. bTempPos += (bAcLen+2);
  235. if(bMetadataSize <= (bTempPos-METADATA_HEADER_SIZE))
  236. {
  237. i4Status = INT_LIB_OK;
  238. break;
  239. }
  240. }
  241. } while(0);
  242. return i4Status;
  243. }
  244. /**
  245. *
  246. * Implementation to verify expressions related to LCSA, LCSG, LCSO.<br>
  247. *
  248. * \param[in] PpsACVal Pointer to the access condition vector
  249. * \param[in] PprgbAC Pointer to the AC expression
  250. * \param[in,out] PpwVerifyOver Pointer to verification status
  251. *
  252. * \retval #INT_LIB_OK Successful execution
  253. * \retval #INT_LIB_ERROR Failure in execution
  254. *
  255. */
  256. static int32_t __optiga_util_verify_lcsa_lcsg_lcso(const sACVector_d* PpsACVal, const uint8_t* PprgbAC,puint16_t PpwVerifyOver)
  257. {
  258. int32_t i4Status = (int32_t)INT_LIB_ERROR;
  259. uint8_t bVal, bLcs = 0x00;
  260. eOperator_d eOp ;
  261. // Life cycle state of object
  262. #define LCS_O_VAL (PpsACVal->bLcsO)
  263. // Life cycle state of application
  264. #define LCS_A_VAL (PpsACVal->bLcsA)
  265. // Life cycle state of Global
  266. #define LCS_G_VAL (PpsACVal->bLcsG)
  267. do
  268. {
  269. if((NULL == PpwVerifyOver)
  270. || (NULL == PpsACVal) || (NULL == PprgbAC))
  271. {
  272. break;
  273. }
  274. bLcs = LCS_A_VAL;
  275. if ((uint8_t)eACID_LCSG == *PprgbAC)
  276. {
  277. bLcs = LCS_G_VAL;
  278. }
  279. else if((uint8_t)eACID_LCSO == *PprgbAC)
  280. {
  281. bLcs = LCS_O_VAL;
  282. }
  283. eOp = (eOperator_d)(*(PprgbAC+1));
  284. bVal = *(PprgbAC+2);
  285. if(eOp == eOP_GREATER_THAN)
  286. {
  287. if(bLcs > bVal)
  288. {
  289. i4Status = INT_LIB_OK;
  290. }
  291. }
  292. else if(eOp == eOP_LESS_THAN)
  293. {
  294. if(bLcs < bVal)
  295. {
  296. i4Status = INT_LIB_OK;
  297. }
  298. }
  299. else if(eOp == eOP_EQUAL)
  300. {
  301. if(bLcs == bVal)
  302. {
  303. i4Status = INT_LIB_OK;
  304. }
  305. }
  306. else
  307. {
  308. i4Status = (int32_t)INT_LIB_ERROR;
  309. *PpwVerifyOver = TRUE;
  310. break;
  311. }
  312. } while(0);
  313. return i4Status;
  314. #undef LCS_O_VAL
  315. #undef LCS_A_VAL
  316. #undef LCS_G_VAL
  317. }
  318. /**
  319. *
  320. * Implementation to validate the access conditions.<br>
  321. *
  322. * \param[in] PpsACVal Pointer to the buffer that contains metadata
  323. *
  324. * \retval #INT_LIB_OK Successful execution
  325. * \retval #INT_LIB_ERROR Failure in execution
  326. *
  327. */
  328. static int32_t __optiga_util_check_ac(const sACVector_d *PpsACVal)
  329. {
  330. int32_t i4Status = (int32_t)INT_LIB_ERROR;
  331. int32_t i4StatusCurr = (int32_t)INT_LIB_ERROR;
  332. int32_t i4StatusPrev = (int32_t)INT_LIB_OK;
  333. uint16_t wIndex = 0, wLen, wIDCount = 0;
  334. uint16_t wVerificationOver = 0;
  335. uint8_t bComplexAcOP = 0x00;
  336. puint8_t prgbAccessCode;
  337. // Remaining bytes of the access condition
  338. #define REMAINING_BYTES (wLen - wIndex)
  339. do
  340. {
  341. if((NULL == PpsACVal) || (NULL == PpsACVal->psMetaData)
  342. || (NULL == PpsACVal->psMetaData->prgbStream))
  343. {
  344. break;
  345. }
  346. wLen = PpsACVal->psMetaData->wLen;
  347. prgbAccessCode = PpsACVal->psMetaData->prgbStream;
  348. while(wIndex < wLen)
  349. {
  350. switch((eAccessConditionID_d)*(prgbAccessCode+wIndex))
  351. {
  352. case eACID_ALW:
  353. case eACID_NEV:
  354. if((REMAINING_BYTES > 1) || (wIDCount > 0))
  355. {
  356. wVerificationOver = TRUE;
  357. break;
  358. }
  359. i4StatusCurr = INT_LIB_OK;
  360. if((uint8_t)eACID_NEV == *(prgbAccessCode+wIndex))
  361. {
  362. i4StatusCurr = (int32_t)INT_LIB_ERROR;
  363. }
  364. wIndex++;
  365. wIDCount++;
  366. break;
  367. case eACID_LCSO:
  368. case eACID_LCSA:
  369. case eACID_LCSG:
  370. //including access id
  371. if(REMAINING_BYTES < 3)
  372. {
  373. //because of invalid access coding
  374. wVerificationOver = TRUE;
  375. break;
  376. }
  377. i4StatusCurr = __optiga_util_verify_lcsa_lcsg_lcso(PpsACVal, prgbAccessCode+wIndex, &wVerificationOver);
  378. if(TRUE == wVerificationOver)
  379. {
  380. //because of invalid access coding
  381. break;
  382. }
  383. wIndex+=3;
  384. wIDCount++;
  385. break;
  386. default:
  387. //because of invalid access coding
  388. i4StatusPrev = (int32_t)INT_LIB_ERROR;
  389. i4StatusCurr = (int32_t)INT_LIB_ERROR;
  390. wVerificationOver = TRUE;
  391. break;
  392. }//switch
  393. if(wVerificationOver)
  394. {
  395. break;
  396. }
  397. if(bComplexAcOP == (uint8_t)eOP_AND)
  398. {
  399. if(i4StatusCurr != i4StatusPrev)
  400. {
  401. i4StatusCurr = (int32_t)INT_LIB_ERROR;
  402. }
  403. }
  404. if(wIndex == wLen)
  405. {
  406. break;
  407. }
  408. // for operator
  409. if(REMAINING_BYTES < 3)
  410. {
  411. i4StatusPrev = (int32_t)INT_LIB_ERROR;
  412. i4StatusCurr = (int32_t)INT_LIB_ERROR;
  413. //wVerificationOver = TRUE;
  414. break;
  415. }
  416. bComplexAcOP = *(prgbAccessCode+wIndex);
  417. switch(bComplexAcOP)
  418. {
  419. case eOP_AND:
  420. i4StatusPrev = i4StatusCurr;
  421. i4StatusCurr = (int32_t)INT_LIB_ERROR;
  422. break;
  423. case eOP_OR:
  424. i4StatusPrev = INT_LIB_OK;
  425. if(i4StatusCurr == INT_LIB_OK)
  426. {
  427. //Note: further validation not required
  428. //because the metadata itself is protected by checksum
  429. wVerificationOver = TRUE;
  430. }
  431. break;
  432. default:
  433. //because of invalid access coding
  434. i4StatusPrev = (int32_t)INT_LIB_ERROR;
  435. i4StatusCurr = (int32_t)INT_LIB_ERROR;
  436. wVerificationOver = TRUE;
  437. break;
  438. }//switch
  439. if(wVerificationOver)
  440. {
  441. break;
  442. }
  443. wIndex++;
  444. wIDCount++; //indication of complex AC
  445. }//while
  446. if((i4StatusPrev == INT_LIB_OK) &&
  447. (i4StatusCurr == INT_LIB_OK))
  448. {
  449. i4Status = INT_LIB_OK;
  450. }
  451. }while(0);
  452. return i4Status;
  453. #undef REMAINING_BYTES
  454. }
  455. /**
  456. *
  457. * Reads either LcsA or LcsG based on request.<br>
  458. *
  459. * \param[in] PeLcsType ObjectId of LcsA or LcsG
  460. * \param[in,out] PpbValue Pointer for returning life cycle state.
  461. *
  462. * \retval #INT_LIB_OK Successful execution
  463. * \retval #INT_LIB_ERROR Failure in execution
  464. *
  465. */
  466. static int32_t __optiga_util_read_lcsa_lcsg(eObjectId_d PeLcsType,uint8_t *PpbValue)
  467. {
  468. int32_t i4Status = (int32_t)INT_LIB_ERROR;
  469. sGetData_d sGDVector;
  470. sCmdResponse_d sResponse;
  471. do
  472. {
  473. if(NULL == PpbValue)
  474. {
  475. i4Status = (int32_t)INT_LIB_NULL_PARAM;
  476. break;
  477. }
  478. sGDVector.wOID = (uint16_t)PeLcsType;
  479. sGDVector.wLength = 1;
  480. sGDVector.wOffset = 0;
  481. sGDVector.eDataOrMdata = eDATA;
  482. sResponse.prgbBuffer = PpbValue;
  483. sResponse.wBufferLength = 1;
  484. sResponse.wRespLength = 0;
  485. i4Status = CmdLib_GetDataObject(&sGDVector,&sResponse);
  486. if(CMD_LIB_OK != i4Status)
  487. {
  488. break;
  489. }
  490. //check if the length is 1
  491. if((0x01 != sResponse.wRespLength))
  492. {
  493. i4Status = (int32_t)INT_LIB_INVALID_RESPONSE;
  494. *PpbValue = 0x00;
  495. break;
  496. }
  497. i4Status = INT_LIB_OK;
  498. }while(FALSE);
  499. return i4Status;
  500. }
  501. /**
  502. *
  503. * Verifies the requested access condition in the metadata.<br>
  504. *
  505. * \param[in] PeMetaDataTag Type of access condition
  506. * \param[in] PpsACVal Pointer to metadata.
  507. *
  508. * \retval #INT_LIB_OK Successful execution
  509. * \retval #INT_LIB_ERROR Failure in execution
  510. *
  511. */
  512. static int32_t __optiga_util_verify_ac(eMetaDataTag_d PeMetaDataTag, sACVector_d *PpsACVal)
  513. {
  514. int32_t i4Status = (int32_t)INT_LIB_ERROR;
  515. uint8_t bTagLocation = 0;
  516. do
  517. {
  518. if((NULL == PpsACVal)||(NULL == PpsACVal->psMetaData)||
  519. (NULL == PpsACVal->psMetaData->prgbStream))
  520. {
  521. i4Status = (int32_t)INT_LIB_NULL_PARAM;
  522. break;
  523. }
  524. //get tag position of lcsO and read lcsO.
  525. //LCO may not be found for all object.It is not an error
  526. i4Status = __optiga_util_get_tag_position(PpsACVal->psMetaData->prgbStream,(uint8_t)eLCSO,&bTagLocation);
  527. if(INT_LIB_OK == i4Status && bTagLocation != PARSE_FAILURE)
  528. {
  529. //get the LcsO value from TLV
  530. PpsACVal->bLcsO = (PpsACVal->psMetaData->prgbStream)[bTagLocation+2];
  531. }
  532. else
  533. {
  534. //LcsO not present
  535. PpsACVal->bLcsO = 0x00;
  536. }
  537. //reset tag location
  538. bTagLocation = 0;
  539. //get tag position
  540. i4Status = __optiga_util_get_tag_position(PpsACVal->psMetaData->prgbStream,(uint8_t)PeMetaDataTag,&bTagLocation);
  541. if((INT_LIB_OK != i4Status) || (PARSE_FAILURE == bTagLocation))
  542. {
  543. i4Status = (int32_t)INT_LIB_ERROR;
  544. break;
  545. }
  546. //check access condition
  547. PpsACVal->psMetaData->wLen = *(PpsACVal->psMetaData->prgbStream + (bTagLocation+POS_LEN));
  548. PpsACVal->psMetaData->prgbStream += (bTagLocation+POS_VAL);
  549. i4Status = __optiga_util_check_ac(PpsACVal);
  550. }while(FALSE);
  551. return i4Status;
  552. }
  553. static void __optiga_util_comms_event_handler(void* upper_layer_ctx, host_lib_status_t event)
  554. {
  555. optiga_comms_status = event;
  556. }
  557. optiga_lib_status_t optiga_util_open_application(optiga_comms_t* p_comms)
  558. {
  559. optiga_lib_status_t status = OPTIGA_LIB_ERROR;
  560. sOpenApp_d sOpenApp;
  561. do {
  562. // OPTIGA Initialisation phase
  563. //Invoke optiga_comms_open to initialize the IFX I2C Protocol and security chip
  564. optiga_comms_status = OPTIGA_COMMS_BUSY;
  565. p_comms->upper_layer_handler = __optiga_util_comms_event_handler;
  566. status = optiga_comms_open(p_comms);
  567. if(E_COMMS_SUCCESS != status)
  568. {
  569. status = OPTIGA_LIB_ERROR;
  570. break;
  571. }
  572. //Wait until IFX I2C initialization is complete
  573. while(optiga_comms_status == OPTIGA_COMMS_BUSY)
  574. {
  575. pal_os_timer_delay_in_milliseconds(1);
  576. }
  577. if((OPTIGA_COMMS_SUCCESS != status) || (optiga_comms_status == OPTIGA_COMMS_ERROR))
  578. {
  579. status = OPTIGA_LIB_ERROR;
  580. break;
  581. }
  582. //Set OPTIGA comms context in Command library before invoking the use case APIs or command library APIs
  583. //This context will be used by command libary to communicate with OPTIGA using IFX I2C Protocol.
  584. CmdLib_SetOptigaCommsContext(p_comms);
  585. //Open the application in Security Chip
  586. sOpenApp.eOpenType = eInit;
  587. status = CmdLib_OpenApplication(&sOpenApp);
  588. if(CMD_LIB_OK != status)
  589. {
  590. status = OPTIGA_LIB_ERROR;
  591. }
  592. // OPTIGA ready
  593. status = OPTIGA_LIB_SUCCESS;
  594. } while(FALSE);
  595. return status;
  596. }
  597. optiga_lib_status_t optiga_util_read_data(uint16_t optiga_oid, uint16_t offset,
  598. uint8_t * p_buffer, uint16_t* buffer_size)
  599. {
  600. //lint --e{818} suppress "PpsGPData is out parameter"
  601. int32_t status = (int32_t)OPTIGA_LIB_ERROR;
  602. sGetData_d cmd_params;
  603. sCmdResponse_d cmd_resp;
  604. do
  605. {
  606. if((NULL == p_buffer) || (NULL == buffer_size) || (0 == *buffer_size))
  607. {
  608. status = (int32_t)OPTIGA_LIB_ERROR;
  609. break;
  610. }
  611. //If access condition satisfied, get the data
  612. cmd_params.wOID = optiga_oid;
  613. cmd_params.wLength = *buffer_size;
  614. cmd_params.wOffset = offset;
  615. cmd_params.eDataOrMdata = eDATA;
  616. cmd_resp.prgbBuffer = p_buffer;
  617. cmd_resp.wBufferLength = *buffer_size;
  618. cmd_resp.wRespLength = 0;
  619. status = CmdLib_GetDataObject(&cmd_params,&cmd_resp);
  620. if(CMD_LIB_OK != status)
  621. {
  622. status = (int32_t)OPTIGA_LIB_ERROR;
  623. break;
  624. }
  625. *buffer_size = cmd_resp.wRespLength;
  626. status = OPTIGA_LIB_SUCCESS;
  627. }while(FALSE);
  628. return status;
  629. }
  630. optiga_lib_status_t optiga_util_read_metadata(uint16_t optiga_oid, uint8_t * p_buffer, uint16_t* buffer_size)
  631. {
  632. //lint --e{818} suppress "PpsGPData is out parameter"
  633. int32_t status = (int32_t)OPTIGA_LIB_ERROR;
  634. sGetData_d cmd_params;
  635. sCmdResponse_d cmd_resp;
  636. uint16_t buffer_limit = *buffer_size;
  637. sbBlob_d meta_data = {LENGTH_METADATA, p_buffer};
  638. sACVector_d ac_vector;
  639. do
  640. {
  641. if((NULL == p_buffer) || (NULL == buffer_size) || (0 == *buffer_size))
  642. {
  643. status = (int32_t)OPTIGA_LIB_ERROR;
  644. break;
  645. }
  646. //Read lcsA
  647. status = __optiga_util_read_lcsa_lcsg(eLCSA,&(ac_vector.bLcsA));
  648. if(INT_LIB_OK != status)
  649. {
  650. status = (int32_t)OPTIGA_LIB_ERROR;
  651. break;
  652. }
  653. //Read lcsG
  654. status = __optiga_util_read_lcsa_lcsg(eLCSG,&(ac_vector.bLcsG));
  655. if(INT_LIB_OK != status)
  656. {
  657. status = (int32_t)OPTIGA_LIB_ERROR;
  658. break;
  659. }
  660. //check if OID is for lcsA or lcaG
  661. if((uint16_t)eLCSA == optiga_oid)
  662. {
  663. //return the read value
  664. *p_buffer = ac_vector.bLcsA;
  665. *buffer_size = 0x01;
  666. break;
  667. }
  668. if((uint16_t)eLCSG == optiga_oid)
  669. {
  670. //return the read value
  671. *p_buffer = ac_vector.bLcsG;
  672. *buffer_size = 0x01;
  673. break;
  674. }
  675. //Get metadata of oid
  676. cmd_params.wOID = optiga_oid;
  677. cmd_params.wLength = LENGTH_METADATA;
  678. cmd_params.wOffset = 0;
  679. cmd_params.eDataOrMdata = eMETA_DATA;
  680. cmd_resp.prgbBuffer = p_buffer;
  681. cmd_resp.wBufferLength = buffer_limit;
  682. cmd_resp.wRespLength = 0;
  683. status = CmdLib_GetDataObject(&cmd_params,&cmd_resp);
  684. if(CMD_LIB_OK != status)
  685. {
  686. status = (int32_t)OPTIGA_LIB_ERROR;
  687. break;
  688. }
  689. //Check the length
  690. *buffer_size = *(cmd_resp.prgbBuffer + POS_LEN );
  691. if((*buffer_size != (cmd_resp.wRespLength-POS_VAL)))
  692. {
  693. status = (int32_t)INT_LIB_INVALID_RESPONSE;
  694. break;
  695. }
  696. //Check read access condition
  697. ac_vector.psMetaData = &meta_data;
  698. status = __optiga_util_verify_ac(eREAD_AC,&ac_vector);
  699. if(INT_LIB_OK != status)
  700. {
  701. status = (int32_t)INT_LIB_INVALID_AC;
  702. break;
  703. }
  704. status = OPTIGA_LIB_SUCCESS;
  705. }while(FALSE);
  706. if(status != OPTIGA_LIB_SUCCESS)
  707. {
  708. status = OPTIGA_LIB_ERROR;
  709. }
  710. return status;
  711. }
  712. optiga_lib_status_t optiga_util_write_data(uint16_t optiga_oid, uint8_t write_type, uint16_t offset, uint8_t * p_buffer, uint16_t buffer_size)
  713. {
  714. int32_t status = (int32_t)OPTIGA_LIB_ERROR;
  715. sSetData_d sd_params;
  716. do
  717. {
  718. if((NULL == p_buffer) || (0x00 == buffer_size))
  719. {
  720. break;
  721. }
  722. if ((OPTIGA_UTIL_WRITE_ONLY != write_type) && (OPTIGA_UTIL_ERASE_AND_WRITE != write_type))
  723. {
  724. status = OPTIGA_UTIL_ERROR_INVALID_INPUT;
  725. break;
  726. }
  727. //If access condition satisfied, set the data
  728. sd_params.wOID = optiga_oid;
  729. sd_params.wOffset = offset;
  730. sd_params.eDataOrMdata = eDATA;
  731. if (OPTIGA_UTIL_ERASE_AND_WRITE == write_type)
  732. sd_params.eWriteOption = eERASE_AND_WRITE;
  733. else
  734. sd_params.eWriteOption = eWRITE;
  735. sd_params.prgbData = p_buffer;
  736. sd_params.wLength = buffer_size;
  737. status = CmdLib_SetDataObject(&sd_params);
  738. if(CMD_LIB_OK != status)
  739. {
  740. break;
  741. }
  742. status = OPTIGA_LIB_SUCCESS;
  743. }while(FALSE);
  744. if(status != OPTIGA_LIB_SUCCESS)
  745. {
  746. status = OPTIGA_LIB_ERROR;
  747. }
  748. return status;
  749. }
  750. optiga_lib_status_t optiga_util_write_metadata(uint16_t optiga_oid, uint8_t * p_buffer, uint8_t buffer_size)
  751. {
  752. int32_t status = (int32_t)OPTIGA_LIB_ERROR;
  753. sSetData_d sd_params;
  754. //If access condition satisfied, set the data
  755. sd_params.wOID = optiga_oid;
  756. sd_params.wOffset = 0;
  757. sd_params.eDataOrMdata = eMETA_DATA;
  758. sd_params.eWriteOption = eWRITE;
  759. sd_params.prgbData = p_buffer;
  760. sd_params.wLength = buffer_size;
  761. status = CmdLib_SetDataObject(&sd_params);
  762. if(CMD_LIB_OK != status)
  763. {
  764. return OPTIGA_LIB_ERROR;
  765. }
  766. return OPTIGA_LIB_SUCCESS;
  767. }
  768. #endif // MODULE_ENABLE_READ_WRITE