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