intel_sdsi.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * sdsi: Intel On Demand (formerly Software Defined Silicon) tool for
  4. * provisioning certificates and activation payloads on supported cpus.
  5. *
  6. * See https://github.com/intel/intel-sdsi/blob/master/os-interface.rst
  7. * for register descriptions.
  8. *
  9. * Copyright (C) 2022 Intel Corporation. All rights reserved.
  10. */
  11. #include <dirent.h>
  12. #include <errno.h>
  13. #include <fcntl.h>
  14. #include <getopt.h>
  15. #include <stdbool.h>
  16. #include <stdio.h>
  17. #include <stdint.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <unistd.h>
  21. #include <sys/types.h>
  22. #ifndef __packed
  23. #define __packed __attribute__((packed))
  24. #endif
  25. #define min(x, y) ({ \
  26. typeof(x) _min1 = (x); \
  27. typeof(y) _min2 = (y); \
  28. (void) (&_min1 == &_min2); \
  29. _min1 < _min2 ? _min1 : _min2; })
  30. #define SDSI_DEV "intel_vsec.sdsi"
  31. #define AUX_DEV_PATH "/sys/bus/auxiliary/devices/"
  32. #define SDSI_PATH (AUX_DEV_DIR SDSI_DEV)
  33. #define GUID_V1 0x6dd191
  34. #define REGS_SIZE_GUID_V1 72
  35. #define GUID_V2 0xF210D9EF
  36. #define REGS_SIZE_GUID_V2 80
  37. #define STATE_CERT_MAX_SIZE 4096
  38. #define METER_CERT_MAX_SIZE 4096
  39. #define STATE_MAX_NUM_LICENSES 16
  40. #define STATE_MAX_NUM_IN_BUNDLE (uint32_t)8
  41. #define FEAT_LEN 5 /* 4 plus NUL terminator */
  42. #define __round_mask(x, y) ((__typeof__(x))((y) - 1))
  43. #define round_up(x, y) ((((x) - 1) | __round_mask(x, y)) + 1)
  44. struct nvram_content_auth_err_sts {
  45. uint64_t reserved:3;
  46. uint64_t sdsi_content_auth_err:1;
  47. uint64_t reserved1:1;
  48. uint64_t sdsi_metering_auth_err:1;
  49. uint64_t reserved2:58;
  50. };
  51. struct enabled_features {
  52. uint64_t reserved:3;
  53. uint64_t sdsi:1;
  54. uint64_t reserved1:8;
  55. uint64_t attestation:1;
  56. uint64_t reserved2:13;
  57. uint64_t metering:1;
  58. uint64_t reserved3:37;
  59. };
  60. struct key_provision_status {
  61. uint64_t reserved:1;
  62. uint64_t license_key_provisioned:1;
  63. uint64_t reserved2:62;
  64. };
  65. struct auth_fail_count {
  66. uint64_t key_failure_count:3;
  67. uint64_t key_failure_threshold:3;
  68. uint64_t auth_failure_count:3;
  69. uint64_t auth_failure_threshold:3;
  70. uint64_t reserved:52;
  71. };
  72. struct availability {
  73. uint64_t reserved:48;
  74. uint64_t available:3;
  75. uint64_t threshold:3;
  76. uint64_t reserved2:10;
  77. };
  78. struct nvram_update_limit {
  79. uint64_t reserved:12;
  80. uint64_t sdsi_50_pct:1;
  81. uint64_t sdsi_75_pct:1;
  82. uint64_t sdsi_90_pct:1;
  83. uint64_t reserved2:49;
  84. };
  85. struct sdsi_regs {
  86. uint64_t ppin;
  87. struct nvram_content_auth_err_sts auth_err_sts;
  88. struct enabled_features en_features;
  89. struct key_provision_status key_prov_sts;
  90. struct auth_fail_count auth_fail_count;
  91. struct availability prov_avail;
  92. struct nvram_update_limit limits;
  93. uint64_t pcu_cr3_capid_cfg;
  94. union {
  95. struct {
  96. uint64_t socket_id;
  97. } v1;
  98. struct {
  99. uint64_t reserved;
  100. uint64_t socket_id;
  101. uint64_t reserved2;
  102. } v2;
  103. } extra;
  104. };
  105. #define CONTENT_TYPE_LK_ENC 0xD
  106. #define CONTENT_TYPE_LK_BLOB_ENC 0xE
  107. struct state_certificate {
  108. uint32_t content_type;
  109. uint32_t region_rev_id;
  110. uint32_t header_size;
  111. uint32_t total_size;
  112. uint32_t key_size;
  113. uint32_t num_licenses;
  114. };
  115. struct license_key_info {
  116. uint32_t key_rev_id;
  117. uint64_t key_image_content[6];
  118. } __packed;
  119. #define LICENSE_BLOB_SIZE(l) (((l) & 0x7fffffff) * 4)
  120. #define LICENSE_VALID(l) (!!((l) & 0x80000000))
  121. // License Group Types
  122. #define LBT_ONE_TIME_UPGRADE 1
  123. #define LBT_METERED_UPGRADE 2
  124. struct license_blob_content {
  125. uint32_t type;
  126. uint64_t id;
  127. uint64_t ppin;
  128. uint64_t previous_ppin;
  129. uint32_t rev_id;
  130. uint32_t num_bundles;
  131. } __packed;
  132. struct bundle_encoding {
  133. uint32_t encoding;
  134. uint32_t encoding_rsvd[7];
  135. };
  136. struct meter_certificate {
  137. uint32_t signature;
  138. uint32_t version;
  139. uint64_t ppin;
  140. uint32_t counter_unit;
  141. uint32_t bundle_length;
  142. uint64_t reserved;
  143. uint32_t mmrc_encoding;
  144. uint32_t mmrc_counter;
  145. };
  146. struct bundle_encoding_counter {
  147. uint32_t encoding;
  148. uint32_t counter;
  149. };
  150. #define METER_BUNDLE_SIZE sizeof(struct bundle_encoding_counter)
  151. #define BUNDLE_COUNT(length) ((length) / METER_BUNDLE_SIZE)
  152. #define METER_MAX_NUM_BUNDLES \
  153. ((METER_CERT_MAX_SIZE - sizeof(struct meter_certificate)) / \
  154. sizeof(struct bundle_encoding_counter))
  155. struct sdsi_dev {
  156. struct sdsi_regs regs;
  157. struct state_certificate sc;
  158. char *dev_name;
  159. char *dev_path;
  160. uint32_t guid;
  161. };
  162. enum command {
  163. CMD_SOCKET_INFO,
  164. CMD_METER_CERT,
  165. CMD_METER_CURRENT_CERT,
  166. CMD_STATE_CERT,
  167. CMD_PROV_AKC,
  168. CMD_PROV_CAP,
  169. };
  170. static void sdsi_list_devices(void)
  171. {
  172. struct dirent *entry;
  173. DIR *aux_dir;
  174. bool found = false;
  175. aux_dir = opendir(AUX_DEV_PATH);
  176. if (!aux_dir) {
  177. fprintf(stderr, "Cannot open directory %s\n", AUX_DEV_PATH);
  178. return;
  179. }
  180. while ((entry = readdir(aux_dir))) {
  181. if (!strncmp(SDSI_DEV, entry->d_name, strlen(SDSI_DEV))) {
  182. found = true;
  183. printf("%s\n", entry->d_name);
  184. }
  185. }
  186. if (!found)
  187. fprintf(stderr, "No On Demand devices found.\n");
  188. }
  189. static int sdsi_update_registers(struct sdsi_dev *s)
  190. {
  191. FILE *regs_ptr;
  192. int ret;
  193. memset(&s->regs, 0, sizeof(s->regs));
  194. /* Open the registers file */
  195. ret = chdir(s->dev_path);
  196. if (ret == -1) {
  197. perror("chdir");
  198. return ret;
  199. }
  200. regs_ptr = fopen("registers", "r");
  201. if (!regs_ptr) {
  202. perror("Could not open 'registers' file");
  203. return -1;
  204. }
  205. if (s->guid != GUID_V1 && s->guid != GUID_V2) {
  206. fprintf(stderr, "Unrecognized guid, 0x%x\n", s->guid);
  207. fclose(regs_ptr);
  208. return -1;
  209. }
  210. /* Update register info for this guid */
  211. ret = fread(&s->regs, sizeof(uint8_t), sizeof(s->regs), regs_ptr);
  212. if ((s->guid == GUID_V1 && ret != REGS_SIZE_GUID_V1) ||
  213. (s->guid == GUID_V2 && ret != REGS_SIZE_GUID_V2)) {
  214. fprintf(stderr, "Could not read 'registers' file\n");
  215. fclose(regs_ptr);
  216. return -1;
  217. }
  218. fclose(regs_ptr);
  219. return 0;
  220. }
  221. static int sdsi_read_reg(struct sdsi_dev *s)
  222. {
  223. int ret;
  224. ret = sdsi_update_registers(s);
  225. if (ret)
  226. return ret;
  227. /* Print register info for this guid */
  228. printf("\n");
  229. printf("Socket information for device %s\n", s->dev_name);
  230. printf("\n");
  231. printf("PPIN: 0x%lx\n", s->regs.ppin);
  232. printf("NVRAM Content Authorization Error Status\n");
  233. printf(" SDSi Auth Err Sts: %s\n", !!s->regs.auth_err_sts.sdsi_content_auth_err ? "Error" : "Okay");
  234. if (!!s->regs.en_features.metering)
  235. printf(" Metering Auth Err Sts: %s\n", !!s->regs.auth_err_sts.sdsi_metering_auth_err ? "Error" : "Okay");
  236. printf("Enabled Features\n");
  237. printf(" On Demand: %s\n", !!s->regs.en_features.sdsi ? "Enabled" : "Disabled");
  238. printf(" Attestation: %s\n", !!s->regs.en_features.attestation ? "Enabled" : "Disabled");
  239. printf(" On Demand: %s\n", !!s->regs.en_features.sdsi ? "Enabled" : "Disabled");
  240. printf(" Metering: %s\n", !!s->regs.en_features.metering ? "Enabled" : "Disabled");
  241. printf("License Key (AKC) Provisioned: %s\n", !!s->regs.key_prov_sts.license_key_provisioned ? "Yes" : "No");
  242. printf("Authorization Failure Count\n");
  243. printf(" AKC Failure Count: %d\n", s->regs.auth_fail_count.key_failure_count);
  244. printf(" AKC Failure Threshold: %d\n", s->regs.auth_fail_count.key_failure_threshold);
  245. printf(" CAP Failure Count: %d\n", s->regs.auth_fail_count.auth_failure_count);
  246. printf(" CAP Failure Threshold: %d\n", s->regs.auth_fail_count.auth_failure_threshold);
  247. printf("Provisioning Availability\n");
  248. printf(" Updates Available: %d\n", s->regs.prov_avail.available);
  249. printf(" Updates Threshold: %d\n", s->regs.prov_avail.threshold);
  250. printf("NVRAM Udate Limit\n");
  251. printf(" 50%% Limit Reached: %s\n", !!s->regs.limits.sdsi_50_pct ? "Yes" : "No");
  252. printf(" 75%% Limit Reached: %s\n", !!s->regs.limits.sdsi_75_pct ? "Yes" : "No");
  253. printf(" 90%% Limit Reached: %s\n", !!s->regs.limits.sdsi_90_pct ? "Yes" : "No");
  254. if (s->guid == GUID_V1)
  255. printf("Socket ID: %ld\n", s->regs.extra.v1.socket_id & 0xF);
  256. else
  257. printf("Socket ID: %ld\n", s->regs.extra.v2.socket_id & 0xF);
  258. return 0;
  259. }
  260. static char *license_blob_type(uint32_t type)
  261. {
  262. switch (type) {
  263. case LBT_ONE_TIME_UPGRADE:
  264. return "One time upgrade";
  265. case LBT_METERED_UPGRADE:
  266. return "Metered upgrade";
  267. default:
  268. return "Unknown license blob type";
  269. }
  270. }
  271. static char *content_type(uint32_t type)
  272. {
  273. switch (type) {
  274. case CONTENT_TYPE_LK_ENC:
  275. return "Licencse key encoding";
  276. case CONTENT_TYPE_LK_BLOB_ENC:
  277. return "License key + Blob encoding";
  278. default:
  279. return "Unknown content type";
  280. }
  281. }
  282. static void get_feature(uint32_t encoding, char feature[5])
  283. {
  284. char *name = (char *)&encoding;
  285. feature[4] = '\0';
  286. feature[3] = name[0];
  287. feature[2] = name[1];
  288. feature[1] = name[2];
  289. feature[0] = name[3];
  290. }
  291. static int sdsi_meter_cert_show(struct sdsi_dev *s, bool show_current)
  292. {
  293. char buf[METER_CERT_MAX_SIZE] = {0};
  294. struct bundle_encoding_counter *bec;
  295. struct meter_certificate *mc;
  296. uint32_t count = 0;
  297. FILE *cert_ptr;
  298. char *cert_fname;
  299. int ret, size;
  300. char name[FEAT_LEN];
  301. ret = sdsi_update_registers(s);
  302. if (ret)
  303. return ret;
  304. if (!s->regs.en_features.sdsi) {
  305. fprintf(stderr, "SDSi feature is present but not enabled.\n");
  306. return -1;
  307. }
  308. if (!s->regs.en_features.metering) {
  309. fprintf(stderr, "Metering not supporting on this socket.\n");
  310. return -1;
  311. }
  312. ret = chdir(s->dev_path);
  313. if (ret == -1) {
  314. perror("chdir");
  315. return ret;
  316. }
  317. cert_fname = show_current ? "meter_current" : "meter_certificate";
  318. cert_ptr = fopen(cert_fname, "r");
  319. if (!cert_ptr) {
  320. fprintf(stderr, "Could not open '%s' file: %s", cert_fname, strerror(errno));
  321. return -1;
  322. }
  323. size = fread(buf, 1, sizeof(buf), cert_ptr);
  324. if (!size) {
  325. fprintf(stderr, "Could not read '%s' file\n", cert_fname);
  326. fclose(cert_ptr);
  327. return -1;
  328. }
  329. fclose(cert_ptr);
  330. mc = (struct meter_certificate *)buf;
  331. printf("\n");
  332. printf("Meter certificate for device %s\n", s->dev_name);
  333. printf("\n");
  334. get_feature(mc->signature, name);
  335. printf("Signature: %s\n", name);
  336. printf("Version: %d\n", mc->version);
  337. printf("Count Unit: %dms\n", mc->counter_unit);
  338. printf("PPIN: 0x%lx\n", mc->ppin);
  339. printf("Feature Bundle Length: %d\n", mc->bundle_length);
  340. get_feature(mc->mmrc_encoding, name);
  341. printf("MMRC encoding: %s\n", name);
  342. printf("MMRC counter: %d\n", mc->mmrc_counter);
  343. if (mc->bundle_length % METER_BUNDLE_SIZE) {
  344. fprintf(stderr, "Invalid bundle length\n");
  345. return -1;
  346. }
  347. if (mc->bundle_length > METER_MAX_NUM_BUNDLES * METER_BUNDLE_SIZE) {
  348. fprintf(stderr, "More than %ld bundles: actual %ld\n",
  349. METER_MAX_NUM_BUNDLES, BUNDLE_COUNT(mc->bundle_length));
  350. return -1;
  351. }
  352. bec = (struct bundle_encoding_counter *)(mc + 1);
  353. printf("Number of Feature Counters: %ld\n", BUNDLE_COUNT(mc->bundle_length));
  354. while (count < BUNDLE_COUNT(mc->bundle_length)) {
  355. char feature[FEAT_LEN];
  356. get_feature(bec[count].encoding, feature);
  357. printf(" %s: %d\n", feature, bec[count].counter);
  358. ++count;
  359. }
  360. return 0;
  361. }
  362. static int sdsi_state_cert_show(struct sdsi_dev *s)
  363. {
  364. char buf[STATE_CERT_MAX_SIZE] = {0};
  365. struct state_certificate *sc;
  366. struct license_key_info *lki;
  367. uint32_t offset = 0;
  368. uint32_t count = 0;
  369. FILE *cert_ptr;
  370. int ret, size;
  371. ret = sdsi_update_registers(s);
  372. if (ret)
  373. return ret;
  374. if (!s->regs.en_features.sdsi) {
  375. fprintf(stderr, "On Demand feature is present but not enabled.");
  376. fprintf(stderr, " Unable to read state certificate");
  377. return -1;
  378. }
  379. ret = chdir(s->dev_path);
  380. if (ret == -1) {
  381. perror("chdir");
  382. return ret;
  383. }
  384. cert_ptr = fopen("state_certificate", "r");
  385. if (!cert_ptr) {
  386. perror("Could not open 'state_certificate' file");
  387. return -1;
  388. }
  389. size = fread(buf, 1, sizeof(buf), cert_ptr);
  390. if (!size) {
  391. fprintf(stderr, "Could not read 'state_certificate' file\n");
  392. fclose(cert_ptr);
  393. return -1;
  394. }
  395. fclose(cert_ptr);
  396. sc = (struct state_certificate *)buf;
  397. /* Print register info for this guid */
  398. printf("\n");
  399. printf("State certificate for device %s\n", s->dev_name);
  400. printf("\n");
  401. printf("Content Type: %s\n", content_type(sc->content_type));
  402. printf("Region Revision ID: %d\n", sc->region_rev_id);
  403. printf("Header Size: %d\n", sc->header_size * 4);
  404. printf("Total Size: %d\n", sc->total_size);
  405. printf("OEM Key Size: %d\n", sc->key_size * 4);
  406. printf("Number of Licenses: %d\n", sc->num_licenses);
  407. /* Skip over the license sizes 4 bytes per license) to get the license key info */
  408. lki = (void *)sc + sizeof(*sc) + (4 * sc->num_licenses);
  409. printf("License blob Info:\n");
  410. printf(" License Key Revision ID: 0x%x\n", lki->key_rev_id);
  411. printf(" License Key Image Content: 0x%lx%lx%lx%lx%lx%lx\n",
  412. lki->key_image_content[5], lki->key_image_content[4],
  413. lki->key_image_content[3], lki->key_image_content[2],
  414. lki->key_image_content[1], lki->key_image_content[0]);
  415. while (count++ < sc->num_licenses) {
  416. uint32_t blob_size_field = *(uint32_t *)(buf + 0x14 + count * 4);
  417. uint32_t blob_size = LICENSE_BLOB_SIZE(blob_size_field);
  418. bool license_valid = LICENSE_VALID(blob_size_field);
  419. struct license_blob_content *lbc =
  420. (void *)(sc) + // start of the state certificate
  421. sizeof(*sc) + // size of the state certificate
  422. (4 * sc->num_licenses) + // total size of the blob size blocks
  423. sizeof(*lki) + // size of the license key info
  424. offset; // offset to this blob content
  425. struct bundle_encoding *bundle = (void *)(lbc) + sizeof(*lbc);
  426. char feature[FEAT_LEN];
  427. uint32_t i;
  428. printf(" Blob %d:\n", count - 1);
  429. printf(" License blob size: %u\n", blob_size);
  430. printf(" License is valid: %s\n", license_valid ? "Yes" : "No");
  431. printf(" License blob type: %s\n", license_blob_type(lbc->type));
  432. printf(" License blob ID: 0x%lx\n", lbc->id);
  433. printf(" PPIN: 0x%lx\n", lbc->ppin);
  434. printf(" Previous PPIN: 0x%lx\n", lbc->previous_ppin);
  435. printf(" Blob revision ID: %u\n", lbc->rev_id);
  436. printf(" Number of Features: %u\n", lbc->num_bundles);
  437. for (i = 0; i < min(lbc->num_bundles, STATE_MAX_NUM_IN_BUNDLE); i++) {
  438. get_feature(bundle[i].encoding, feature);
  439. printf(" Feature %d: %s\n", i, feature);
  440. }
  441. if (lbc->num_bundles > STATE_MAX_NUM_IN_BUNDLE)
  442. fprintf(stderr, " Warning: %d > %d licenses in bundle reported.\n",
  443. lbc->num_bundles, STATE_MAX_NUM_IN_BUNDLE);
  444. offset += blob_size;
  445. };
  446. return 0;
  447. }
  448. static int sdsi_provision(struct sdsi_dev *s, char *bin_file, enum command command)
  449. {
  450. int bin_fd, prov_fd, size, ret;
  451. char buf[STATE_CERT_MAX_SIZE] = { 0 };
  452. char cap[] = "provision_cap";
  453. char akc[] = "provision_akc";
  454. char *prov_file;
  455. if (!bin_file) {
  456. fprintf(stderr, "No binary file provided\n");
  457. return -1;
  458. }
  459. /* Open the binary */
  460. bin_fd = open(bin_file, O_RDONLY);
  461. if (bin_fd == -1) {
  462. fprintf(stderr, "Could not open file %s: %s\n", bin_file, strerror(errno));
  463. return bin_fd;
  464. }
  465. prov_file = (command == CMD_PROV_AKC) ? akc : cap;
  466. ret = chdir(s->dev_path);
  467. if (ret == -1) {
  468. perror("chdir");
  469. close(bin_fd);
  470. return ret;
  471. }
  472. /* Open the provision file */
  473. prov_fd = open(prov_file, O_WRONLY);
  474. if (prov_fd == -1) {
  475. fprintf(stderr, "Could not open file %s: %s\n", prov_file, strerror(errno));
  476. close(bin_fd);
  477. return prov_fd;
  478. }
  479. /* Read the binary file into the buffer */
  480. size = read(bin_fd, buf, STATE_CERT_MAX_SIZE);
  481. if (size == -1) {
  482. close(bin_fd);
  483. close(prov_fd);
  484. return -1;
  485. }
  486. ret = write(prov_fd, buf, size);
  487. if (ret == -1) {
  488. close(bin_fd);
  489. close(prov_fd);
  490. perror("Provisioning failed");
  491. return ret;
  492. }
  493. printf("Provisioned %s file %s successfully\n", prov_file, bin_file);
  494. close(bin_fd);
  495. close(prov_fd);
  496. return 0;
  497. }
  498. static int sdsi_provision_akc(struct sdsi_dev *s, char *bin_file)
  499. {
  500. int ret;
  501. ret = sdsi_update_registers(s);
  502. if (ret)
  503. return ret;
  504. if (!s->regs.en_features.sdsi) {
  505. fprintf(stderr, "On Demand feature is present but not enabled. Unable to provision");
  506. return -1;
  507. }
  508. if (!s->regs.prov_avail.available) {
  509. fprintf(stderr, "Maximum number of updates (%d) has been reached.\n",
  510. s->regs.prov_avail.threshold);
  511. return -1;
  512. }
  513. if (s->regs.auth_fail_count.key_failure_count ==
  514. s->regs.auth_fail_count.key_failure_threshold) {
  515. fprintf(stderr, "Maximum number of AKC provision failures (%d) has been reached.\n",
  516. s->regs.auth_fail_count.key_failure_threshold);
  517. fprintf(stderr, "Power cycle the system to reset the counter\n");
  518. return -1;
  519. }
  520. return sdsi_provision(s, bin_file, CMD_PROV_AKC);
  521. }
  522. static int sdsi_provision_cap(struct sdsi_dev *s, char *bin_file)
  523. {
  524. int ret;
  525. ret = sdsi_update_registers(s);
  526. if (ret)
  527. return ret;
  528. if (!s->regs.en_features.sdsi) {
  529. fprintf(stderr, "On Demand feature is present but not enabled. Unable to provision");
  530. return -1;
  531. }
  532. if (!s->regs.prov_avail.available) {
  533. fprintf(stderr, "Maximum number of updates (%d) has been reached.\n",
  534. s->regs.prov_avail.threshold);
  535. return -1;
  536. }
  537. if (s->regs.auth_fail_count.auth_failure_count ==
  538. s->regs.auth_fail_count.auth_failure_threshold) {
  539. fprintf(stderr, "Maximum number of CAP provision failures (%d) has been reached.\n",
  540. s->regs.auth_fail_count.auth_failure_threshold);
  541. fprintf(stderr, "Power cycle the system to reset the counter\n");
  542. return -1;
  543. }
  544. return sdsi_provision(s, bin_file, CMD_PROV_CAP);
  545. }
  546. static int read_sysfs_data(const char *file, int *value)
  547. {
  548. char buff[16];
  549. FILE *fp;
  550. fp = fopen(file, "r");
  551. if (!fp) {
  552. perror(file);
  553. return -1;
  554. }
  555. if (!fgets(buff, 16, fp)) {
  556. fprintf(stderr, "Failed to read file '%s'", file);
  557. fclose(fp);
  558. return -1;
  559. }
  560. fclose(fp);
  561. *value = strtol(buff, NULL, 0);
  562. return 0;
  563. }
  564. static struct sdsi_dev *sdsi_create_dev(char *dev_no)
  565. {
  566. int dev_name_len = sizeof(SDSI_DEV) + strlen(dev_no) + 1;
  567. struct sdsi_dev *s;
  568. int guid;
  569. DIR *dir;
  570. s = (struct sdsi_dev *)malloc(sizeof(*s));
  571. if (!s) {
  572. perror("malloc");
  573. return NULL;
  574. }
  575. s->dev_name = (char *)malloc(sizeof(SDSI_DEV) + strlen(dev_no) + 1);
  576. if (!s->dev_name) {
  577. perror("malloc");
  578. free(s);
  579. return NULL;
  580. }
  581. snprintf(s->dev_name, dev_name_len, "%s.%s", SDSI_DEV, dev_no);
  582. s->dev_path = (char *)malloc(sizeof(AUX_DEV_PATH) + dev_name_len);
  583. if (!s->dev_path) {
  584. perror("malloc");
  585. free(s->dev_name);
  586. free(s);
  587. return NULL;
  588. }
  589. snprintf(s->dev_path, sizeof(AUX_DEV_PATH) + dev_name_len, "%s%s", AUX_DEV_PATH,
  590. s->dev_name);
  591. dir = opendir(s->dev_path);
  592. if (!dir) {
  593. fprintf(stderr, "Could not open directory '%s': %s\n", s->dev_path,
  594. strerror(errno));
  595. free(s->dev_path);
  596. free(s->dev_name);
  597. free(s);
  598. return NULL;
  599. }
  600. if (chdir(s->dev_path) == -1) {
  601. perror("chdir");
  602. free(s->dev_path);
  603. free(s->dev_name);
  604. free(s);
  605. return NULL;
  606. }
  607. if (read_sysfs_data("guid", &guid)) {
  608. free(s->dev_path);
  609. free(s->dev_name);
  610. free(s);
  611. return NULL;
  612. }
  613. s->guid = guid;
  614. return s;
  615. }
  616. static void sdsi_free_dev(struct sdsi_dev *s)
  617. {
  618. free(s->dev_path);
  619. free(s->dev_name);
  620. free(s);
  621. }
  622. static void usage(char *prog)
  623. {
  624. printf("Usage: %s [-l] [-d DEVNO [-i] [-s] [-m | -C] [-a FILE] [-c FILE]\n", prog);
  625. }
  626. static void show_help(void)
  627. {
  628. printf("Commands:\n");
  629. printf(" %-18s\t%s\n", "-l, --list", "list available On Demand devices");
  630. printf(" %-18s\t%s\n", "-d, --devno DEVNO", "On Demand device number");
  631. printf(" %-18s\t%s\n", "-i, --info", "show socket information");
  632. printf(" %-18s\t%s\n", "-s, --state", "show state certificate data");
  633. printf(" %-18s\t%s\n", "-m, --meter", "show meter certificate data");
  634. printf(" %-18s\t%s\n", "-C, --meter_current", "show live unattested meter data");
  635. printf(" %-18s\t%s\n", "-a, --akc FILE", "provision socket with AKC FILE");
  636. printf(" %-18s\t%s\n", "-c, --cap FILE>", "provision socket with CAP FILE");
  637. }
  638. int main(int argc, char *argv[])
  639. {
  640. char bin_file[PATH_MAX], *dev_no = NULL;
  641. bool device_selected = false;
  642. char *progname;
  643. enum command command = -1;
  644. struct sdsi_dev *s;
  645. int ret = 0, opt;
  646. int option_index = 0;
  647. static struct option long_options[] = {
  648. {"akc", required_argument, 0, 'a'},
  649. {"cap", required_argument, 0, 'c'},
  650. {"devno", required_argument, 0, 'd'},
  651. {"help", no_argument, 0, 'h'},
  652. {"info", no_argument, 0, 'i'},
  653. {"list", no_argument, 0, 'l'},
  654. {"meter", no_argument, 0, 'm'},
  655. {"meter_current", no_argument, 0, 'C'},
  656. {"state", no_argument, 0, 's'},
  657. {0, 0, 0, 0 }
  658. };
  659. progname = argv[0];
  660. while ((opt = getopt_long_only(argc, argv, "+a:c:d:hilmCs", long_options,
  661. &option_index)) != -1) {
  662. switch (opt) {
  663. case 'd':
  664. dev_no = optarg;
  665. device_selected = true;
  666. break;
  667. case 'l':
  668. sdsi_list_devices();
  669. return 0;
  670. case 'i':
  671. command = CMD_SOCKET_INFO;
  672. break;
  673. case 'm':
  674. command = CMD_METER_CERT;
  675. break;
  676. case 'C':
  677. command = CMD_METER_CURRENT_CERT;
  678. break;
  679. case 's':
  680. command = CMD_STATE_CERT;
  681. break;
  682. case 'a':
  683. case 'c':
  684. if (!access(optarg, F_OK) == 0) {
  685. fprintf(stderr, "Could not open file '%s': %s\n", optarg,
  686. strerror(errno));
  687. return -1;
  688. }
  689. if (!realpath(optarg, bin_file)) {
  690. perror("realpath");
  691. return -1;
  692. }
  693. command = (opt == 'a') ? CMD_PROV_AKC : CMD_PROV_CAP;
  694. break;
  695. case 'h':
  696. usage(progname);
  697. show_help();
  698. return 0;
  699. default:
  700. usage(progname);
  701. return -1;
  702. }
  703. }
  704. if (device_selected) {
  705. s = sdsi_create_dev(dev_no);
  706. if (!s)
  707. return -1;
  708. switch (command) {
  709. case CMD_SOCKET_INFO:
  710. ret = sdsi_read_reg(s);
  711. break;
  712. case CMD_METER_CERT:
  713. ret = sdsi_meter_cert_show(s, false);
  714. break;
  715. case CMD_METER_CURRENT_CERT:
  716. ret = sdsi_meter_cert_show(s, true);
  717. break;
  718. case CMD_STATE_CERT:
  719. ret = sdsi_state_cert_show(s);
  720. break;
  721. case CMD_PROV_AKC:
  722. ret = sdsi_provision_akc(s, bin_file);
  723. break;
  724. case CMD_PROV_CAP:
  725. ret = sdsi_provision_cap(s, bin_file);
  726. break;
  727. default:
  728. fprintf(stderr, "No command specified\n");
  729. return -1;
  730. }
  731. sdsi_free_dev(s);
  732. } else {
  733. fprintf(stderr, "No device specified\n");
  734. return -1;
  735. }
  736. return ret;
  737. }