chkpib1.c 11 KB

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