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 % METER_BUNDLE_SIZE) { 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 = (struct bundle_encoding_counter *)(mc + 1); 409 410 printf("Number of Feature Counters: %ld\n", BUNDLE_COUNT(mc->bundle_length)); 411 while (count < BUNDLE_COUNT(mc->bundle_length)) { 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 ++count; 418 } 419 420 return 0; 421 } 422 423 static int sdsi_state_cert_show(struct sdsi_dev *s) 424 { 425 char buf[STATE_CERT_MAX_SIZE] = {0}; 426 struct state_certificate *sc; 427 struct license_key_info *lki; 428 uint32_t offset = 0; 429 uint32_t count = 0; 430 FILE *cert_ptr; 431 int ret, size; 432 433 ret = sdsi_update_registers(s); 434 if (ret) 435 return ret; 436 437 if (!s->regs.en_features.sdsi) { 438 fprintf(stderr, "On Demand feature is present but not enabled."); 439 fprintf(stderr, " Unable to read state certificate"); 440 return -1; 441 } 442 443 ret = chdir(s->dev_path); 444 if (ret == -1) { 445 perror("chdir"); 446 return ret; 447 } 448 449 cert_ptr = fopen("state_certificate", "r"); 450 if (!cert_ptr) { 451 perror("Could not open 'state_certificate' file"); 452 return -1; 453 } 454 455 size = fread(buf, 1, sizeof(buf), cert_ptr); 456 if (!size) { 457 fprintf(stderr, "Could not read 'state_certificate' file\n"); 458 fclose(cert_ptr); 459 return -1; 460 } 461 fclose(cert_ptr); 462 463 sc = (struct state_certificate *)buf; 464 465 /* Print register info for this guid */ 466 printf("\n"); 467 printf("State certificate for device %s\n", s->dev_name); 468 printf("\n"); 469 printf("Content Type: %s\n", content_type(sc->content_type)); 470 printf("Region Revision ID: %d\n", sc->region_rev_id); 471 printf("Header Size: %d\n", sc->header_size * 4); 472 printf("Total Size: %d\n", sc->total_size); 473 printf("OEM Key Size: %d\n", sc->key_size * 4); 474 printf("Number of Licenses: %d\n", sc->num_licenses); 475 476 /* Skip over the license sizes 4 bytes per license) to get the license key info */ 477 lki = (void *)sc + sizeof(*sc) + (4 * sc->num_licenses); 478 479 printf("License blob Info:\n"); 480 printf(" License Key Revision ID: 0x%x\n", lki->key_rev_id); 481 printf(" License Key Image Content: 0x%lx%lx%lx%lx%lx%lx\n", 482 lki->key_image_content[5], lki->key_image_content[4], 483 lki->key_image_content[3], lki->key_image_content[2], 484 lki->key_image_content[1], lki->key_image_content[0]); 485 486 while (count++ < sc->num_licenses) { 487 uint32_t blob_size_field = *(uint32_t *)(buf + 0x14 + count * 4); 488 uint32_t blob_size = LICENSE_BLOB_SIZE(blob_size_field); 489 bool license_valid = LICENSE_VALID(blob_size_field); 490 struct license_blob_content *lbc = 491 (void *)(sc) + // start of the state certificate 492 sizeof(*sc) + // size of the state certificate 493 (4 * sc->num_licenses) + // total size of the blob size blocks 494 sizeof(*lki) + // size of the license key info 495 offset; // offset to this blob content 496 struct bundle_encoding *bundle = (void *)(lbc) + sizeof(*lbc); 497 char feature[5]; 498 uint32_t i; 499 500 printf(" Blob %d:\n", count - 1); 501 printf(" License blob size: %u\n", blob_size); 502 printf(" License is valid: %s\n", license_valid ? "Yes" : "No"); 503 printf(" License blob type: %s\n", license_blob_type(lbc->type)); 504 printf(" License blob ID: 0x%lx\n", lbc->id); 505 printf(" PPIN: 0x%lx\n", lbc->ppin); 506 printf(" Previous PPIN: 0x%lx\n", lbc->previous_ppin); 507 printf(" Blob revision ID: %u\n", lbc->rev_id); 508 printf(" Number of Features: %u\n", lbc->num_bundles); 509 510 feature[4] = '\0'; 511 512 for (i = 0; i < min(lbc->num_bundles, STATE_MAX_NUM_IN_BUNDLE); i++) { 513 get_feature(bundle[i].encoding, feature); 514 printf(" Feature %d: %s\n", i, feature); 515 } 516 517 if (lbc->num_bundles > STATE_MAX_NUM_IN_BUNDLE) 518 fprintf(stderr, " Warning: %d > %d licenses in bundle reported.\n", 519 lbc->num_bundles, STATE_MAX_NUM_IN_BUNDLE); 520 521 offset += blob_size; 522 }; 523 524 return 0; 525 } 526 527 static int sdsi_provision(struct sdsi_dev *s, char *bin_file, enum command command) 528 { 529 int bin_fd, prov_fd, size, ret; 530 char buf[STATE_CERT_MAX_SIZE] = { 0 }; 531 char cap[] = "provision_cap"; 532 char akc[] = "provision_akc"; 533 char *prov_file; 534 535 if (!bin_file) { 536 fprintf(stderr, "No binary file provided\n"); 537 return -1; 538 } 539 540 /* Open the binary */ 541 bin_fd = open(bin_file, O_RDONLY); 542 if (bin_fd == -1) { 543 fprintf(stderr, "Could not open file %s: %s\n", bin_file, strerror(errno)); 544 return bin_fd; 545 } 546 547 prov_file = (command == CMD_PROV_AKC) ? akc : cap; 548 549 ret = chdir(s->dev_path); 550 if (ret == -1) { 551 perror("chdir"); 552 close(bin_fd); 553 return ret; 554 } 555 556 /* Open the provision file */ 557 prov_fd = open(prov_file, O_WRONLY); 558 if (prov_fd == -1) { 559 fprintf(stderr, "Could not open file %s: %s\n", prov_file, strerror(errno)); 560 close(bin_fd); 561 return prov_fd; 562 } 563 564 /* Read the binary file into the buffer */ 565 size = read(bin_fd, buf, STATE_CERT_MAX_SIZE); 566 if (size == -1) { 567 close(bin_fd); 568 close(prov_fd); 569 return -1; 570 } 571 572 ret = write(prov_fd, buf, size); 573 if (ret == -1) { 574 close(bin_fd); 575 close(prov_fd); 576 perror("Provisioning failed"); 577 return ret; 578 } 579 580 printf("Provisioned %s file %s successfully\n", prov_file, bin_file); 581 582 close(bin_fd); 583 close(prov_fd); 584 585 return 0; 586 } 587 588 static int sdsi_provision_akc(struct sdsi_dev *s, char *bin_file) 589 { 590 int ret; 591 592 ret = sdsi_update_registers(s); 593 if (ret) 594 return ret; 595 596 if (!s->regs.en_features.sdsi) { 597 fprintf(stderr, "On Demand feature is present but not enabled. Unable to provision"); 598 return -1; 599 } 600 601 if (!s->regs.prov_avail.available) { 602 fprintf(stderr, "Maximum number of updates (%d) has been reached.\n", 603 s->regs.prov_avail.threshold); 604 return -1; 605 } 606 607 if (s->regs.auth_fail_count.key_failure_count == 608 s->regs.auth_fail_count.key_failure_threshold) { 609 fprintf(stderr, "Maximum number of AKC provision failures (%d) has been reached.\n", 610 s->regs.auth_fail_count.key_failure_threshold); 611 fprintf(stderr, "Power cycle the system to reset the counter\n"); 612 return -1; 613 } 614 615 return sdsi_provision(s, bin_file, CMD_PROV_AKC); 616 } 617 618 static int sdsi_provision_cap(struct sdsi_dev *s, char *bin_file) 619 { 620 int ret; 621 622 ret = sdsi_update_registers(s); 623 if (ret) 624 return ret; 625 626 if (!s->regs.en_features.sdsi) { 627 fprintf(stderr, "On Demand feature is present but not enabled. Unable to provision"); 628 return -1; 629 } 630 631 if (!s->regs.prov_avail.available) { 632 fprintf(stderr, "Maximum number of updates (%d) has been reached.\n", 633 s->regs.prov_avail.threshold); 634 return -1; 635 } 636 637 if (s->regs.auth_fail_count.auth_failure_count == 638 s->regs.auth_fail_count.auth_failure_threshold) { 639 fprintf(stderr, "Maximum number of CAP provision failures (%d) has been reached.\n", 640 s->regs.auth_fail_count.auth_failure_threshold); 641 fprintf(stderr, "Power cycle the system to reset the counter\n"); 642 return -1; 643 } 644 645 return sdsi_provision(s, bin_file, CMD_PROV_CAP); 646 } 647 648 static int read_sysfs_data(const char *file, int *value) 649 { 650 char buff[16]; 651 FILE *fp; 652 653 fp = fopen(file, "r"); 654 if (!fp) { 655 perror(file); 656 return -1; 657 } 658 659 if (!fgets(buff, 16, fp)) { 660 fprintf(stderr, "Failed to read file '%s'", file); 661 fclose(fp); 662 return -1; 663 } 664 665 fclose(fp); 666 *value = strtol(buff, NULL, 0); 667 668 return 0; 669 } 670 671 static struct sdsi_dev *sdsi_create_dev(char *dev_no) 672 { 673 int dev_name_len = sizeof(SDSI_DEV) + strlen(dev_no) + 1; 674 struct sdsi_dev *s; 675 int guid; 676 DIR *dir; 677 678 s = (struct sdsi_dev *)malloc(sizeof(*s)); 679 if (!s) { 680 perror("malloc"); 681 return NULL; 682 } 683 684 s->dev_name = (char *)malloc(sizeof(SDSI_DEV) + strlen(dev_no) + 1); 685 if (!s->dev_name) { 686 perror("malloc"); 687 free(s); 688 return NULL; 689 } 690 691 snprintf(s->dev_name, dev_name_len, "%s.%s", SDSI_DEV, dev_no); 692 693 s->dev_path = (char *)malloc(sizeof(AUX_DEV_PATH) + dev_name_len); 694 if (!s->dev_path) { 695 perror("malloc"); 696 free(s->dev_name); 697 free(s); 698 return NULL; 699 } 700 701 snprintf(s->dev_path, sizeof(AUX_DEV_PATH) + dev_name_len, "%s%s", AUX_DEV_PATH, 702 s->dev_name); 703 dir = opendir(s->dev_path); 704 if (!dir) { 705 fprintf(stderr, "Could not open directory '%s': %s\n", s->dev_path, 706 strerror(errno)); 707 free(s->dev_path); 708 free(s->dev_name); 709 free(s); 710 return NULL; 711 } 712 713 if (chdir(s->dev_path) == -1) { 714 perror("chdir"); 715 free(s->dev_path); 716 free(s->dev_name); 717 free(s); 718 return NULL; 719 } 720 721 if (read_sysfs_data("guid", &guid)) { 722 free(s->dev_path); 723 free(s->dev_name); 724 free(s); 725 return NULL; 726 } 727 728 s->guid = guid; 729 730 return s; 731 } 732 733 static void sdsi_free_dev(struct sdsi_dev *s) 734 { 735 free(s->dev_path); 736 free(s->dev_name); 737 free(s); 738 } 739 740 static void usage(char *prog) 741 { 742 printf("Usage: %s [-l] [-d DEVNO [-i] [-s] [-m] [-a FILE] [-c FILE]]\n", prog); 743 } 744 745 static void show_help(void) 746 { 747 printf("Commands:\n"); 748 printf(" %-18s\t%s\n", "-l, --list", "list available On Demand devices"); 749 printf(" %-18s\t%s\n", "-d, --devno DEVNO", "On Demand device number"); 750 printf(" %-18s\t%s\n", "-i, --info", "show socket information"); 751 printf(" %-18s\t%s\n", "-s, --state", "show state certificate"); 752 printf(" %-18s\t%s\n", "-m, --meter", "show meter certificate"); 753 printf(" %-18s\t%s\n", "-a, --akc FILE", "provision socket with AKC FILE"); 754 printf(" %-18s\t%s\n", "-c, --cap FILE>", "provision socket with CAP FILE"); 755 } 756 757 int main(int argc, char *argv[]) 758 { 759 char bin_file[PATH_MAX], *dev_no = NULL; 760 bool device_selected = false; 761 char *progname; 762 enum command command = -1; 763 struct sdsi_dev *s; 764 int ret = 0, opt; 765 int option_index = 0; 766 767 static struct option long_options[] = { 768 {"akc", required_argument, 0, 'a'}, 769 {"cap", required_argument, 0, 'c'}, 770 {"devno", required_argument, 0, 'd'}, 771 {"help", no_argument, 0, 'h'}, 772 {"info", no_argument, 0, 'i'}, 773 {"list", no_argument, 0, 'l'}, 774 {"meter", no_argument, 0, 'm'}, 775 {"state", no_argument, 0, 's'}, 776 {0, 0, 0, 0 } 777 }; 778 779 780 progname = argv[0]; 781 782 while ((opt = getopt_long_only(argc, argv, "+a:c:d:hilms", long_options, 783 &option_index)) != -1) { 784 switch (opt) { 785 case 'd': 786 dev_no = optarg; 787 device_selected = true; 788 break; 789 case 'l': 790 sdsi_list_devices(); 791 return 0; 792 case 'i': 793 command = CMD_SOCKET_INFO; 794 break; 795 case 'm': 796 command = CMD_METER_CERT; 797 break; 798 case 's': 799 command = CMD_STATE_CERT; 800 break; 801 case 'a': 802 case 'c': 803 if (!access(optarg, F_OK) == 0) { 804 fprintf(stderr, "Could not open file '%s': %s\n", optarg, 805 strerror(errno)); 806 return -1; 807 } 808 809 if (!realpath(optarg, bin_file)) { 810 perror("realpath"); 811 return -1; 812 } 813 814 command = (opt == 'a') ? CMD_PROV_AKC : CMD_PROV_CAP; 815 break; 816 case 'h': 817 usage(progname); 818 show_help(); 819 return 0; 820 default: 821 usage(progname); 822 return -1; 823 } 824 } 825 826 if (device_selected) { 827 s = sdsi_create_dev(dev_no); 828 if (!s) 829 return -1; 830 831 switch (command) { 832 case CMD_SOCKET_INFO: 833 ret = sdsi_read_reg(s); 834 break; 835 case CMD_METER_CERT: 836 ret = sdsi_meter_cert_show(s); 837 break; 838 case CMD_STATE_CERT: 839 ret = sdsi_state_cert_show(s); 840 break; 841 case CMD_PROV_AKC: 842 ret = sdsi_provision_akc(s, bin_file); 843 break; 844 case CMD_PROV_CAP: 845 ret = sdsi_provision_cap(s, bin_file); 846 break; 847 default: 848 fprintf(stderr, "No command specified\n"); 849 return -1; 850 } 851 852 sdsi_free_dev(s); 853 854 } else { 855 fprintf(stderr, "No device specified\n"); 856 return -1; 857 } 858 859 return ret; 860 } 861