chkpib2.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  4. *
  5. * All rights reserved.
  6. *
  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. /*====================================================================*
  58. *
  59. * signed lightning_pib_image (void const * memory, size_t extent, char const * filename, flag_t flags);
  60. *
  61. * check memory-resident thunderbolt/lightning PIB image; return 0
  62. * for a good image and -1 for a bad image;
  63. *
  64. * the check performed here is not exhaustive but it is adequate;
  65. *
  66. * Contributor(s):
  67. * Charles Maier <cmaier@qca.qualcomm.com>
  68. *
  69. *--------------------------------------------------------------------*/
  70. static signed lightning_pib_image (void const * memory, size_t extent, char const * filename, flag_t flags)
  71. {
  72. struct simple_pib * simple_pib = (struct simple_pib *) (memory);
  73. uint8_t NID [HPAVKEY_NID_LEN];
  74. if (_anyset (flags, PIB_VERBOSE))
  75. {
  76. printf ("------- %s -------\n", filename);
  77. if (lightning_pib_peek (memory))
  78. {
  79. if (_allclr (flags, PIB_SILENCE))
  80. {
  81. error (0, 0, PIB_BADVERSION, filename);
  82. }
  83. return (- 1);
  84. }
  85. }
  86. if (extent != LE16TOH (simple_pib->PIBLENGTH))
  87. {
  88. if (_allclr (flags, PIB_SILENCE))
  89. {
  90. error (0, 0, PIB_BADLENGTH, filename);
  91. }
  92. return (- 1);
  93. }
  94. if (checksum32 (memory, extent, 0))
  95. {
  96. if (_allclr (flags, PIB_SILENCE))
  97. {
  98. error (0, 0, PIB_BADCHECKSUM, filename);
  99. }
  100. return (- 1);
  101. }
  102. HPAVKeyNID (NID, simple_pib->NMK, simple_pib->PreferredNID [HPAVKEY_NID_LEN - 1] >> 4);
  103. if (memcmp (NID, simple_pib->PreferredNID, sizeof (NID)))
  104. {
  105. if (_allclr (flags, PIB_SILENCE))
  106. {
  107. error (0, 0, PIB_BADNID, filename);
  108. }
  109. return (- 1);
  110. }
  111. return (0);
  112. }
  113. /*====================================================================*
  114. *
  115. * signed panther_pib_image (void const * memory, size_t extent, char const * filename, flag_t flags);
  116. *
  117. * check memory-resident panther/lynx PIB image; return 0 for a
  118. * good image and -1 for an bad image;
  119. *
  120. * the check performed here is not exhaustive but it is adequate;
  121. *
  122. * Contributor(s):
  123. * Charles Maier <cmaier@qca.qualcomm.com>
  124. *
  125. *--------------------------------------------------------------------*/
  126. static signed panther_pib_image (void const * memory, size_t extent, char const * filename, flag_t flags)
  127. {
  128. struct simple_pib * simple_pib = (struct simple_pib *) (memory);
  129. struct pib_header * pib_header = (struct pib_header *) (memory);
  130. uint8_t NID [HPAVKEY_NID_LEN];
  131. if (_anyset (flags, PIB_VERBOSE))
  132. {
  133. pib_header->PIBLENGTH = HTOLE16 (extent);
  134. printf ("------- %s -------\n", filename);
  135. if (panther_pib_peek (memory))
  136. {
  137. if (_allclr (flags, PIB_SILENCE))
  138. {
  139. error (0, 0, PIB_BADVERSION, filename);
  140. }
  141. return (- 1);
  142. }
  143. memset (pib_header, 0, sizeof (* pib_header));
  144. }
  145. HPAVKeyNID (NID, simple_pib->NMK, simple_pib->PreferredNID [HPAVKEY_NID_LEN - 1] >> 4);
  146. if (memcmp (NID, simple_pib->PreferredNID, sizeof (NID)))
  147. {
  148. if (_allclr (flags, PIB_SILENCE))
  149. {
  150. error (0, 0, PIB_BADNID, filename);
  151. }
  152. return (- 1);
  153. }
  154. return (0);
  155. }
  156. /*====================================================================*
  157. *
  158. * signed panther_pib_chain (void const * memory, size_t extent, char const * filename, flag_t flags);
  159. *
  160. * search a panther/lynx image chain looking for PIB images and
  161. * verify each one; return 0 on success or -1 on error; errors
  162. * occur due to an invalid image chain or a bad parameter block;
  163. *
  164. * this implementation reads the parameter block from file into
  165. * into memory and checks it there;
  166. *
  167. *
  168. * Contributor(s):
  169. * Charles Maier <cmaier@qca.qualcomm.com>
  170. *
  171. *--------------------------------------------------------------------*/
  172. static signed panther_pib_chain (void const * memory, size_t extent, char const * filename, flag_t flags)
  173. {
  174. struct panther_nvm_header * header;
  175. uint32_t origin = ~ 0;
  176. uint32_t offset = 0;
  177. unsigned module = 0;
  178. do
  179. {
  180. header = (struct panther_nvm_header *) ((char *) (memory) + offset);
  181. if (LE16TOH (header->MajorVersion) != 1)
  182. {
  183. if (_allclr (flags, NVM_SILENCE))
  184. {
  185. error (0, 0, NVM_HDR_VERSION, filename, module);
  186. }
  187. return (- 1);
  188. }
  189. if (LE16TOH (header->MinorVersion) != 1)
  190. {
  191. if (_allclr (flags, NVM_SILENCE))
  192. {
  193. error (0, 0, NVM_HDR_VERSION, filename, module);
  194. }
  195. return (- 1);
  196. }
  197. if (LE32TOH (header->PrevHeader) != origin)
  198. {
  199. if (_allclr (flags, NVM_SILENCE))
  200. {
  201. error (0, 0, NVM_HDR_LINK, filename, module);
  202. }
  203. return (- 1);
  204. }
  205. if (checksum32 (header, sizeof (* header), 0))
  206. {
  207. if (_allclr (flags, NVM_SILENCE))
  208. {
  209. error (0, 0, NVM_HDR_CHECKSUM, filename, module);
  210. }
  211. return (- 1);
  212. }
  213. origin = offset;
  214. offset += sizeof (* header);
  215. extent -= sizeof (* header);
  216. if (checksum32 ((char *) (memory) + offset, LE32TOH (header->ImageLength), header->ImageChecksum))
  217. {
  218. if (_allclr (flags, NVM_SILENCE))
  219. {
  220. error (0, 0, NVM_IMG_CHECKSUM, filename, module);
  221. }
  222. return (- 1);
  223. }
  224. if (LE32TOH (header->ImageType) == NVM_IMAGE_MANIFEST)
  225. {
  226. if (_anyset (flags, NVM_MANIFEST))
  227. {
  228. printf ("------- %s (%d) -------\n", filename, module);
  229. panther_nvm_manifest ((char *) (memory) + offset, LE32TOH (header->ImageLength));
  230. return (0);
  231. }
  232. if (_anyset (flags, NVM_REVISION))
  233. {
  234. panther_nvm_revision ((char *) (memory) + offset, LE32TOH (header->ImageLength));
  235. return (0);
  236. }
  237. }
  238. else if (LE32TOH (header->ImageType) == NVM_IMAGE_PIB)
  239. {
  240. return (panther_pib_image ((char *) (memory) + offset, LE32TOH (header->ImageLength), filename, flags));
  241. }
  242. offset += LE32TOH (header->ImageLength);
  243. extent -= LE32TOH (header->ImageLength);
  244. module++;
  245. }
  246. while (~ header->NextHeader);
  247. if (extent)
  248. {
  249. if (_allclr (flags, NVM_SILENCE))
  250. {
  251. error (0, errno, NVM_HDR_LINK, filename, module);
  252. }
  253. return (- 1);
  254. }
  255. error (0, 0, "%s has no PIB", filename);
  256. return (- 1);
  257. }
  258. /*====================================================================*
  259. *
  260. * signed chkpib (char const * filename, flag_t flags);
  261. *
  262. *
  263. * Contributor(s):
  264. * Charles Maier <cmaier@qca.qualcomm.com>
  265. *
  266. *--------------------------------------------------------------------*/
  267. static signed chkpib (char const * filename, flag_t flags)
  268. {
  269. void * memory = 0;
  270. signed extent = 0;
  271. signed status;
  272. signed fd;
  273. if ((fd = open (filename, O_BINARY | O_RDONLY)) == - 1)
  274. {
  275. if (_allclr (flags, NVM_SILENCE))
  276. {
  277. error (0, errno, FILE_CANTOPEN, filename);
  278. }
  279. return (- 1);
  280. }
  281. if ((extent = lseek (fd, 0, SEEK_END)) == - 1)
  282. {
  283. if (_allclr (flags, NVM_SILENCE))
  284. {
  285. error (0, errno, FILE_CANTSIZE, filename);
  286. }
  287. return (- 1);
  288. }
  289. if (! (memory = malloc (extent)))
  290. {
  291. if (_allclr (flags, NVM_SILENCE))
  292. {
  293. error (0, errno, FILE_CANTLOAD, filename);
  294. }
  295. return (- 1);
  296. }
  297. if (lseek (fd, 0, SEEK_SET))
  298. {
  299. if (_allclr (flags, NVM_SILENCE))
  300. {
  301. error (0, errno, FILE_CANTHOME, filename);
  302. }
  303. return (- 1);
  304. }
  305. if (read (fd, memory, extent) != extent)
  306. {
  307. if (_allclr (flags, NVM_SILENCE))
  308. {
  309. error (0, errno, FILE_CANTREAD, filename);
  310. }
  311. return (- 1);
  312. }
  313. close (fd);
  314. if (LE32TOH (* (uint32_t *) (memory)) == 0x60000000)
  315. {
  316. if (_allclr (flags, NVM_SILENCE))
  317. {
  318. error (0, 0, FILE_WONTREAD, filename);
  319. }
  320. status = - 1;
  321. }
  322. else if (LE32TOH (* (uint32_t *) (memory)) == 0x00010001)
  323. {
  324. status = panther_pib_chain (memory, extent, filename, flags);
  325. }
  326. else
  327. {
  328. status = lightning_pib_image (memory, extent, filename, flags);
  329. }
  330. free (memory);
  331. return (status);
  332. }
  333. /*====================================================================*
  334. *
  335. * int main (int argc, char const * argv []);
  336. *
  337. *
  338. * Contributor(s):
  339. * Charles Maier <cmaier@qca.qualcomm.com>
  340. *
  341. *--------------------------------------------------------------------*/
  342. int main (int argc, char const * argv [])
  343. {
  344. static char const * optv [] =
  345. {
  346. "mqrv",
  347. "file [file] [...]",
  348. "Qualcomm Atheros PLC Parameter File Inspector",
  349. "m\tdisplay manifest",
  350. "q\tquiet",
  351. "r\tprint firmware revision string",
  352. "v\tverbose messages",
  353. (char const *) (0)
  354. };
  355. flag_t flags = (flag_t) (0);
  356. signed state = 0;
  357. signed c;
  358. optind = 1;
  359. while (~ (c = getoptv (argc, argv, optv)))
  360. {
  361. switch (c)
  362. {
  363. case 'm':
  364. _setbits (flags, PIB_MANIFEST);
  365. break;
  366. case 'q':
  367. _setbits (flags, PIB_SILENCE);
  368. break;
  369. case 'r':
  370. _setbits (flags, PIB_REVISION);
  371. break;
  372. case 'v':
  373. _setbits (flags, PIB_VERBOSE);
  374. break;
  375. default:
  376. break;
  377. }
  378. }
  379. argc -= optind;
  380. argv += optind;
  381. while ((argc) && (* argv))
  382. {
  383. errno = 0;
  384. if (chkpib (* argv, flags))
  385. {
  386. state = 1;
  387. }
  388. else if (_allclr (flags, (PIB_VERBOSE | PIB_SILENCE | PIB_MANIFEST)))
  389. {
  390. printf ("%s looks good\n", * argv);
  391. }
  392. argc--;
  393. argv++;
  394. }
  395. return (state);
  396. }