chkpib.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. /****************************************************************************
  2. Copyright (c) 2013, 2022 Qualcomm Technologies, Inc.
  3. All Rights Reserved.
  4. Confidential and Proprietary - Qualcomm Technologies, Inc.
  5. **********************************************************************
  6. 2013 Qualcomm Atheros, Inc.
  7. ****************************************************************************/
  8. /*====================================================================*
  9. * system header files;
  10. *--------------------------------------------------------------------*/
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <fcntl.h>
  15. #include <errno.h>
  16. /*====================================================================*
  17. * custom header files;
  18. *--------------------------------------------------------------------*/
  19. #include "../tools/getoptv.h"
  20. #include "../tools/flags.h"
  21. #include "../tools/error.h"
  22. #include "../tools/files.h"
  23. #include "../key/HPAVKey.h"
  24. #include "../nvm/nvm.h"
  25. #include "../pib/pib.h"
  26. /*====================================================================*
  27. * custom source files;
  28. *--------------------------------------------------------------------*/
  29. #ifndef MAKEFILE
  30. #include "../tools/getoptv.c"
  31. #include "../tools/putoptv.c"
  32. #include "../tools/version.c"
  33. #include "../tools/checksum32.c"
  34. #include "../tools/fdchecksum32.c"
  35. #include "../tools/checksum32.c"
  36. #include "../tools/hexstring.c"
  37. #include "../tools/hexdecode.c"
  38. #include "../tools/strfbits.c"
  39. #include "../tools/error.c"
  40. #endif
  41. #ifndef MAKEFILE
  42. #include "../key/SHA256Reset.c"
  43. #include "../key/SHA256Block.c"
  44. #include "../key/SHA256Write.c"
  45. #include "../key/SHA256Fetch.c"
  46. #include "../key/HPAVKeyNID.c"
  47. #include "../key/keys.c"
  48. #endif
  49. #ifndef MAKEFILE
  50. #include "../pib/lightning_pib_peek.c"
  51. #include "../pib/panther_pib_peek.c"
  52. #endif
  53. #ifndef MAKEFILE
  54. #include "../nvm/panther_nvm_manifest.c"
  55. #include "../nvm/panther_nvm_revision.c"
  56. #endif
  57. #define PIB_CHIPID_OFFSET 0x127
  58. /*====================================================================*
  59. *
  60. * signed lightning_pib_image (void const * memory, size_t extent, char const * filename, flag_t flags);
  61. *
  62. * check memory-resident thunderbolt/lightning PIB image; return 0
  63. * for a good image and -1 for a bad image;
  64. *
  65. * the check performed here is not exhaustive but it is adequate;
  66. *
  67. * Contributor(s):
  68. * Charles Maier <cmaier@qca.qualcomm.com>
  69. *
  70. *--------------------------------------------------------------------*/
  71. static signed lightning_pib_image (void const * memory, size_t extent, char const * filename, flag_t flags)
  72. {
  73. struct simple_pib * simple_pib = (struct simple_pib *) (memory);
  74. uint8_t NID [HPAVKEY_NID_LEN];
  75. if (_anyset (flags, PIB_VERBOSE))
  76. {
  77. printf ("------- %s -------\n", filename);
  78. if (lightning_pib_peek (memory))
  79. {
  80. if (_allclr (flags, PIB_SILENCE))
  81. {
  82. error (0, 0, PIB_BADVERSION, filename);
  83. }
  84. return (- 1);
  85. }
  86. }
  87. if (extent != LE16TOH (simple_pib->PIBLENGTH))
  88. {
  89. if (_allclr (flags, PIB_SILENCE))
  90. {
  91. error (0, 0, PIB_BADLENGTH, filename);
  92. }
  93. return (- 1);
  94. }
  95. if (checksum32 (memory, extent, 0))
  96. {
  97. if (_allclr (flags, PIB_SILENCE))
  98. {
  99. error (0, 0, PIB_BADCHECKSUM, filename);
  100. }
  101. return (- 1);
  102. }
  103. HPAVKeyNID (NID, simple_pib->NMK, simple_pib->PreferredNID [HPAVKEY_NID_LEN - 1] >> 4);
  104. if (memcmp (NID, simple_pib->PreferredNID, sizeof (NID)))
  105. {
  106. if (_allclr (flags, PIB_SILENCE))
  107. {
  108. error (0, 0, PIB_BADNID, filename);
  109. }
  110. return (- 1);
  111. }
  112. return (0);
  113. }
  114. /*====================================================================*
  115. *
  116. * signed panther_pib_image (void const * memory, size_t extent, char const * filename, flag_t flags);
  117. *
  118. * check memory-resident panther/lynx PIB image; return 0 for a
  119. * good image and -1 for an bad image;
  120. *
  121. * the check performed here is not exhaustive but it is adequate;
  122. *
  123. * Contributor(s):
  124. * Charles Maier <cmaier@qca.qualcomm.com>
  125. *
  126. *--------------------------------------------------------------------*/
  127. static signed panther_pib_image (void const * memory, size_t extent, char const * filename, flag_t flags)
  128. {
  129. struct simple_pib * simple_pib = (struct simple_pib *) (memory);
  130. struct pib_header * pib_header = (struct pib_header *) (memory);
  131. uint8_t NID [HPAVKEY_NID_LEN];
  132. if (_anyset (flags, PIB_VERBOSE))
  133. {
  134. pib_header->PIBLENGTH = HTOLE16 (extent);
  135. printf ("------- %s -------\n", filename);
  136. if (panther_pib_peek (memory))
  137. {
  138. if (_allclr (flags, PIB_SILENCE))
  139. {
  140. error (0, 0, PIB_BADVERSION, filename);
  141. }
  142. return (- 1);
  143. }
  144. memset (pib_header, 0, sizeof (* pib_header));
  145. }
  146. HPAVKeyNID (NID, simple_pib->NMK, simple_pib->PreferredNID [HPAVKEY_NID_LEN - 1] >> 4);
  147. if (memcmp (NID, simple_pib->PreferredNID, sizeof (NID)))
  148. {
  149. if (_allclr (flags, PIB_SILENCE))
  150. {
  151. error (0, 0, PIB_BADNID, filename);
  152. }
  153. return (- 1);
  154. }
  155. return (0);
  156. }
  157. /*====================================================================*
  158. *
  159. * signed panther_pib_chain (void const * memory, size_t extent, char const * filename, flag_t flags);
  160. *
  161. * search a panther/lynx image chain looking for PIB images and
  162. * verify each one; return 0 on success or -1 on error; errors
  163. * occur due to an invalid image chain or a bad parameter block;
  164. *
  165. * this implementation reads the parameter block from file into
  166. * into memory and checks it there;
  167. *
  168. *
  169. * Contributor(s):
  170. * Charles Maier <cmaier@qca.qualcomm.com>
  171. *
  172. *--------------------------------------------------------------------*/
  173. static signed panther_pib_chain (void const * memory, size_t extent, char const * filename, flag_t flags)
  174. {
  175. struct panther_nvm_header * header;
  176. uint32_t origin = ~ 0;
  177. uint32_t offset = 0;
  178. unsigned module = 0;
  179. signed int RetVal = 0;
  180. Revision* PIBRevision = NULL;
  181. bool vFlag = false;
  182. uint8_t *ChipIDFromPIB;
  183. do
  184. {
  185. header = (struct panther_nvm_header *) ((char *) (memory) + offset);
  186. if (LE16TOH (header->MajorVersion) != 1)
  187. {
  188. if (_allclr (flags, NVM_SILENCE))
  189. {
  190. error (0, 0, NVM_HDR_VERSION, filename, module);
  191. }
  192. return (- 1);
  193. }
  194. if (LE16TOH (header->MinorVersion) != 1)
  195. {
  196. if (_allclr (flags, NVM_SILENCE))
  197. {
  198. error (0, 0, NVM_HDR_VERSION, filename, module);
  199. }
  200. return (- 1);
  201. }
  202. if (LE32TOH (header->PrevHeader) != origin)
  203. {
  204. if (_allclr (flags, NVM_SILENCE))
  205. {
  206. error (0, 0, NVM_HDR_LINK, filename, module);
  207. }
  208. return (- 1);
  209. }
  210. if (checksum32 (header, sizeof (* header), 0))
  211. {
  212. if (_allclr (flags, NVM_SILENCE))
  213. {
  214. error (0, 0, NVM_HDR_CHECKSUM, filename, module);
  215. }
  216. return (- 1);
  217. }
  218. origin = offset;
  219. offset += sizeof (* header);
  220. extent -= sizeof (* header);
  221. if (checksum32 ((char *) (memory) + offset, LE32TOH (header->ImageLength), header->ImageChecksum))
  222. {
  223. if (_allclr (flags, NVM_SILENCE))
  224. {
  225. error (0, 0, NVM_IMG_CHECKSUM, filename, module);
  226. }
  227. return (- 1);
  228. }
  229. if (LE32TOH (header->ImageType) == NVM_IMAGE_MANIFEST)
  230. {
  231. if (_anyset (flags, NVM_MANIFEST))
  232. {
  233. printf ("------- %s (%d) -------\n", filename, module);
  234. panther_nvm_manifest ((char *) (memory) + offset, LE32TOH (header->ImageLength));
  235. return (0);
  236. }
  237. if (_anyset (flags, NVM_REVISION))
  238. {
  239. PIBRevision = (Revision*)malloc(sizeof(Revision));
  240. panther_nvm_revision_forChkpib ((char *) (memory) + offset, LE32TOH (header->ImageLength), PIBRevision);
  241. }
  242. }
  243. else if (LE32TOH (header->ImageType) == NVM_IMAGE_PIB)
  244. {
  245. ChipIDFromPIB = (uint8_t*)(((char*)memory) + offset + PIB_CHIPID_OFFSET);
  246. RetVal = (panther_pib_image ((char *) (memory) + offset, LE32TOH (header->ImageLength), filename, flags));
  247. vFlag = true;
  248. break;
  249. }
  250. offset += LE32TOH (header->ImageLength);
  251. extent -= LE32TOH (header->ImageLength);
  252. module++;
  253. }
  254. while (~header->NextHeader);
  255. if (_anyset(flags, NVM_REVISION))
  256. {
  257. printf("QCA");
  258. int i;
  259. for (i = 0; i < 4; i++)
  260. { printf("%c", *(ChipIDFromPIB + i)); }
  261. printf("-%d.", PIBRevision->software[0]);
  262. printf("%d.", PIBRevision->software[1]);
  263. printf("%d.", PIBRevision->software[2]);
  264. printf("%d-", PIBRevision->build);
  265. printf("%02d-", PIBRevision->software[3]);
  266. printf("%08X-", PIBRevision->date);
  267. printf("%s", PIBRevision->type);
  268. PIBRevision ? free(PIBRevision) : 0;
  269. return 0;
  270. }
  271. if(vFlag)
  272. {
  273. PIBRevision ? free(PIBRevision) : 0;
  274. return RetVal;
  275. }
  276. PIBRevision ? free(PIBRevision) : 0;
  277. if (extent)
  278. {
  279. if (_allclr (flags, NVM_SILENCE))
  280. {
  281. error (0, errno, NVM_HDR_LINK, filename, module);
  282. }
  283. return (- 1);
  284. }
  285. error (0, 0, "%s has no PIB", filename);
  286. return (- 1);
  287. }
  288. /*====================================================================*
  289. *
  290. * signed chkpib (char const * filename, flag_t flags);
  291. *
  292. *
  293. * Contributor(s):
  294. * Charles Maier <cmaier@qca.qualcomm.com>
  295. *
  296. *--------------------------------------------------------------------*/
  297. static signed chkpib (char const * filename, flag_t flags)
  298. {
  299. void * memory = 0;
  300. signed extent = 0;
  301. signed status;
  302. signed fd;
  303. if ((fd = open (filename, O_BINARY | O_RDONLY)) == - 1)
  304. {
  305. if (_allclr (flags, NVM_SILENCE))
  306. {
  307. error (0, errno, FILE_CANTOPEN, filename);
  308. }
  309. return (- 1);
  310. }
  311. if ((extent = lseek (fd, 0, SEEK_END)) == - 1)
  312. {
  313. if (_allclr (flags, NVM_SILENCE))
  314. {
  315. error (0, errno, FILE_CANTSIZE, filename);
  316. }
  317. return (- 1);
  318. }
  319. if (! (memory = malloc (extent)))
  320. {
  321. if (_allclr (flags, NVM_SILENCE))
  322. {
  323. error (0, errno, FILE_CANTLOAD, filename);
  324. }
  325. return (- 1);
  326. }
  327. if (lseek (fd, 0, SEEK_SET))
  328. {
  329. if (_allclr (flags, NVM_SILENCE))
  330. {
  331. error (0, errno, FILE_CANTHOME, filename);
  332. }
  333. return (- 1);
  334. }
  335. if (read (fd, memory, extent) != extent)
  336. {
  337. if (_allclr (flags, NVM_SILENCE))
  338. {
  339. error (0, errno, FILE_CANTREAD, filename);
  340. }
  341. return (- 1);
  342. }
  343. close (fd);
  344. if (LE32TOH (* (uint32_t *) (memory)) == 0x60000000)
  345. {
  346. if (_allclr (flags, NVM_SILENCE))
  347. {
  348. error (0, 0, FILE_WONTREAD, filename);
  349. }
  350. status = - 1;
  351. }
  352. else if (LE32TOH (* (uint32_t *) (memory)) == 0x00010001)
  353. {
  354. status = panther_pib_chain (memory, extent, filename, flags);
  355. }
  356. else
  357. {
  358. status = lightning_pib_image (memory, extent, filename, flags);
  359. }
  360. free (memory);
  361. return (status);
  362. }
  363. /*====================================================================*
  364. *
  365. * int main (int argc, char const * argv []);
  366. *
  367. *
  368. * Contributor(s):
  369. * Charles Maier <cmaier@qca.qualcomm.com>
  370. *
  371. *--------------------------------------------------------------------*/
  372. int main (int argc, char const * argv [])
  373. {
  374. static char const * optv [] =
  375. {
  376. "mqrv",
  377. "file [file] [...]",
  378. "Qualcomm Atheros PLC Parameter File Inspector",
  379. "m\tdisplay manifest",
  380. "q\tquiet",
  381. "r\tprint firmware revision string",
  382. "v\tverbose messages",
  383. (char const *) (0)
  384. };
  385. flag_t flags = (flag_t) (0);
  386. signed state = 0;
  387. signed c;
  388. optind = 1;
  389. while (~ (c = getoptv (argc, argv, optv)))
  390. {
  391. switch (c)
  392. {
  393. case 'm':
  394. _setbits (flags, PIB_MANIFEST);
  395. break;
  396. case 'q':
  397. _setbits (flags, PIB_SILENCE);
  398. break;
  399. case 'r':
  400. _setbits (flags, PIB_REVISION);
  401. break;
  402. case 'v':
  403. _setbits (flags, PIB_VERBOSE);
  404. break;
  405. default:
  406. break;
  407. }
  408. }
  409. argc -= optind;
  410. argv += optind;
  411. while ((argc) && (* argv))
  412. {
  413. errno = 0;
  414. if (chkpib (* argv, flags))
  415. {
  416. state = 1;
  417. }
  418. else if (_allclr (flags, (PIB_VERBOSE | PIB_SILENCE | PIB_REVISION | PIB_MANIFEST)))
  419. {
  420. printf ("%s looks good\n", * argv);
  421. }
  422. argc--;
  423. argv++;
  424. }
  425. return (state);
  426. }