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