// SPDX-License-Identifier: GPL-2.0
/*
 * sdsi: Intel On Demand (formerly Software Defined Silicon) tool for
 * provisioning certificates and activation payloads on supported cpus.
 *
 * See https://github.com/intel/intel-sdsi/blob/master/os-interface.rst
 * for register descriptions.
 *
 * Copyright (C) 2022 Intel Corporation. All rights reserved.
 */

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/types.h>

#ifndef __packed
#define __packed __attribute__((packed))
#endif

#define min(x, y) ({                            \
	typeof(x) _min1 = (x);                  \
	typeof(y) _min2 = (y);                  \
	(void) (&_min1 == &_min2);              \
	_min1 < _min2 ? _min1 : _min2; })

#define SDSI_DEV		"intel_vsec.sdsi"
#define AUX_DEV_PATH		"/sys/bus/auxiliary/devices/"
#define SDSI_PATH		(AUX_DEV_DIR SDSI_DEV)
#define GUID_V1			0x6dd191
#define REGS_SIZE_GUID_V1	72
#define GUID_V2			0xF210D9EF
#define REGS_SIZE_GUID_V2	80
#define STATE_CERT_MAX_SIZE	4096
#define METER_CERT_MAX_SIZE	4096
#define STATE_MAX_NUM_LICENSES	16
#define STATE_MAX_NUM_IN_BUNDLE	(uint32_t)8
#define METER_MAX_NUM_BUNDLES	8

#define __round_mask(x, y) ((__typeof__(x))((y) - 1))
#define round_up(x, y) ((((x) - 1) | __round_mask(x, y)) + 1)

struct nvram_content_auth_err_sts {
	uint64_t reserved:3;
	uint64_t sdsi_content_auth_err:1;
	uint64_t reserved1:1;
	uint64_t sdsi_metering_auth_err:1;
	uint64_t reserved2:58;
};

struct enabled_features {
	uint64_t reserved:3;
	uint64_t sdsi:1;
	uint64_t reserved1:8;
	uint64_t attestation:1;
	uint64_t reserved2:13;
	uint64_t metering:1;
	uint64_t reserved3:37;
};

struct key_provision_status {
	uint64_t reserved:1;
	uint64_t license_key_provisioned:1;
	uint64_t reserved2:62;
};

struct auth_fail_count {
	uint64_t key_failure_count:3;
	uint64_t key_failure_threshold:3;
	uint64_t auth_failure_count:3;
	uint64_t auth_failure_threshold:3;
	uint64_t reserved:52;
};

struct availability {
	uint64_t reserved:48;
	uint64_t available:3;
	uint64_t threshold:3;
	uint64_t reserved2:10;
};

struct nvram_update_limit {
	uint64_t reserved:12;
	uint64_t sdsi_50_pct:1;
	uint64_t sdsi_75_pct:1;
	uint64_t sdsi_90_pct:1;
	uint64_t reserved2:49;
};

struct sdsi_regs {
	uint64_t ppin;
	struct nvram_content_auth_err_sts auth_err_sts;
	struct enabled_features en_features;
	struct key_provision_status key_prov_sts;
	struct auth_fail_count auth_fail_count;
	struct availability prov_avail;
	struct nvram_update_limit limits;
	uint64_t pcu_cr3_capid_cfg;
	union {
		struct {
			uint64_t socket_id;
		} v1;
		struct {
			uint64_t reserved;
			uint64_t socket_id;
			uint64_t reserved2;
		} v2;
	} extra;
};
#define CONTENT_TYPE_LK_ENC		0xD
#define CONTENT_TYPE_LK_BLOB_ENC	0xE

struct state_certificate {
	uint32_t content_type;
	uint32_t region_rev_id;
	uint32_t header_size;
	uint32_t total_size;
	uint32_t key_size;
	uint32_t num_licenses;
};

struct license_key_info {
	uint32_t key_rev_id;
	uint64_t key_image_content[6];
} __packed;

#define LICENSE_BLOB_SIZE(l)	(((l) & 0x7fffffff) * 4)
#define LICENSE_VALID(l)	(!!((l) & 0x80000000))

// License Group Types
#define LBT_ONE_TIME_UPGRADE	1
#define LBT_METERED_UPGRADE	2

struct license_blob_content {
	uint32_t type;
	uint64_t id;
	uint64_t ppin;
	uint64_t previous_ppin;
	uint32_t rev_id;
	uint32_t num_bundles;
} __packed;

struct bundle_encoding {
	uint32_t encoding;
	uint32_t encoding_rsvd[7];
};

struct meter_certificate {
	uint32_t block_signature;
	uint32_t counter_unit;
	uint64_t ppin;
	uint32_t bundle_length;
	uint32_t reserved;
	uint32_t mmrc_encoding;
	uint32_t mmrc_counter;
};

struct bundle_encoding_counter {
	uint32_t encoding;
	uint32_t counter;
};

struct sdsi_dev {
	struct sdsi_regs regs;
	struct state_certificate sc;
	char *dev_name;
	char *dev_path;
	uint32_t guid;
};

enum command {
	CMD_SOCKET_INFO,
	CMD_METER_CERT,
	CMD_STATE_CERT,
	CMD_PROV_AKC,
	CMD_PROV_CAP,
};

static void sdsi_list_devices(void)
{
	struct dirent *entry;
	DIR *aux_dir;
	bool found = false;

	aux_dir = opendir(AUX_DEV_PATH);
	if (!aux_dir) {
		fprintf(stderr, "Cannot open directory %s\n", AUX_DEV_PATH);
		return;
	}

	while ((entry = readdir(aux_dir))) {
		if (!strncmp(SDSI_DEV, entry->d_name, strlen(SDSI_DEV))) {
			found = true;
			printf("%s\n", entry->d_name);
		}
	}

	if (!found)
		fprintf(stderr, "No On Demand devices found.\n");
}

static int sdsi_update_registers(struct sdsi_dev *s)
{
	FILE *regs_ptr;
	int ret;

	memset(&s->regs, 0, sizeof(s->regs));

	/* Open the registers file */
	ret = chdir(s->dev_path);
	if (ret == -1) {
		perror("chdir");
		return ret;
	}

	regs_ptr = fopen("registers", "r");
	if (!regs_ptr) {
		perror("Could not open 'registers' file");
		return -1;
	}

	if (s->guid != GUID_V1 && s->guid != GUID_V2) {
		fprintf(stderr, "Unrecognized guid, 0x%x\n", s->guid);
		fclose(regs_ptr);
		return -1;
	}

	/* Update register info for this guid */
	ret = fread(&s->regs, sizeof(uint8_t), sizeof(s->regs), regs_ptr);
	if ((s->guid == GUID_V1 && ret != REGS_SIZE_GUID_V1) ||
	    (s->guid == GUID_V2 && ret != REGS_SIZE_GUID_V2)) {
		fprintf(stderr, "Could not read 'registers' file\n");
		fclose(regs_ptr);
		return -1;
	}

	fclose(regs_ptr);

	return 0;
}

static int sdsi_read_reg(struct sdsi_dev *s)
{
	int ret;

	ret = sdsi_update_registers(s);
	if (ret)
		return ret;

	/* Print register info for this guid */
	printf("\n");
	printf("Socket information for device %s\n", s->dev_name);
	printf("\n");
	printf("PPIN:                           0x%lx\n", s->regs.ppin);
	printf("NVRAM Content Authorization Error Status\n");
	printf("    SDSi Auth Err Sts:          %s\n", !!s->regs.auth_err_sts.sdsi_content_auth_err ? "Error" : "Okay");

	if (!!s->regs.en_features.metering)
		printf("    Metering Auth Err Sts:      %s\n", !!s->regs.auth_err_sts.sdsi_metering_auth_err ? "Error" : "Okay");

	printf("Enabled Features\n");
	printf("    On Demand:                  %s\n", !!s->regs.en_features.sdsi ? "Enabled" : "Disabled");
	printf("    Attestation:                %s\n", !!s->regs.en_features.attestation ? "Enabled" : "Disabled");
	printf("    On Demand:                  %s\n", !!s->regs.en_features.sdsi ? "Enabled" : "Disabled");
	printf("    Metering:                   %s\n", !!s->regs.en_features.metering ? "Enabled" : "Disabled");
	printf("License Key (AKC) Provisioned:  %s\n", !!s->regs.key_prov_sts.license_key_provisioned ? "Yes" : "No");
	printf("Authorization Failure Count\n");
	printf("    AKC Failure Count:          %d\n", s->regs.auth_fail_count.key_failure_count);
	printf("    AKC Failure Threshold:      %d\n", s->regs.auth_fail_count.key_failure_threshold);
	printf("    CAP Failure Count:          %d\n", s->regs.auth_fail_count.auth_failure_count);
	printf("    CAP Failure Threshold:      %d\n", s->regs.auth_fail_count.auth_failure_threshold);
	printf("Provisioning Availability\n");
	printf("    Updates Available:          %d\n", s->regs.prov_avail.available);
	printf("    Updates Threshold:          %d\n", s->regs.prov_avail.threshold);
	printf("NVRAM Udate Limit\n");
	printf("    50%% Limit Reached:          %s\n", !!s->regs.limits.sdsi_50_pct ? "Yes" : "No");
	printf("    75%% Limit Reached:          %s\n", !!s->regs.limits.sdsi_75_pct ? "Yes" : "No");
	printf("    90%% Limit Reached:          %s\n", !!s->regs.limits.sdsi_90_pct ? "Yes" : "No");
	if (s->guid == GUID_V1)
		printf("Socket ID:                      %ld\n", s->regs.extra.v1.socket_id & 0xF);
	else
		printf("Socket ID:                      %ld\n", s->regs.extra.v2.socket_id & 0xF);

	return 0;
}

static char *license_blob_type(uint32_t type)
{
	switch (type) {
	case LBT_ONE_TIME_UPGRADE:
		return "One time upgrade";
	case LBT_METERED_UPGRADE:
		return "Metered upgrade";
	default:
		return "Unknown license blob type";
	}
}

static char *content_type(uint32_t type)
{
	switch (type) {
	case  CONTENT_TYPE_LK_ENC:
		return "Licencse key encoding";
	case CONTENT_TYPE_LK_BLOB_ENC:
		return "License key + Blob encoding";
	default:
		return "Unknown content type";
	}
}

static void get_feature(uint32_t encoding, char *feature)
{
	char *name = (char *)&encoding;

	feature[3] = name[0];
	feature[2] = name[1];
	feature[1] = name[2];
	feature[0] = name[3];
}

static int sdsi_meter_cert_show(struct sdsi_dev *s)
{
	char buf[METER_CERT_MAX_SIZE] = {0};
	struct bundle_encoding_counter *bec;
	struct meter_certificate *mc;
	uint32_t count = 0;
	FILE *cert_ptr;
	int ret, size;

	ret = sdsi_update_registers(s);
	if (ret)
		return ret;

	if (!s->regs.en_features.sdsi) {
		fprintf(stderr, "SDSi feature is present but not enabled.\n");
		fprintf(stderr, " Unable to read meter certificate\n");
		return -1;
	}

	if (!s->regs.en_features.metering) {
		fprintf(stderr, "Metering not supporting on this socket.\n");
		return -1;
	}

	ret = chdir(s->dev_path);
	if (ret == -1) {
		perror("chdir");
		return ret;
	}

	cert_ptr = fopen("meter_certificate", "r");
	if (!cert_ptr) {
		perror("Could not open 'meter_certificate' file");
		return -1;
	}

	size = fread(buf, 1, sizeof(buf), cert_ptr);
	if (!size) {
		fprintf(stderr, "Could not read 'meter_certificate' file\n");
		fclose(cert_ptr);
		return -1;
	}
	fclose(cert_ptr);

	mc = (struct meter_certificate *)buf;

	printf("\n");
	printf("Meter certificate for device %s\n", s->dev_name);
	printf("\n");
	printf("Block Signature:       0x%x\n", mc->block_signature);
	printf("Count Unit:            %dms\n", mc->counter_unit);
	printf("PPIN:                  0x%lx\n", mc->ppin);
	printf("Feature Bundle Length: %d\n", mc->bundle_length);
	printf("MMRC encoding:         %d\n", mc->mmrc_encoding);
	printf("MMRC counter:          %d\n", mc->mmrc_counter);
	if (mc->bundle_length % 8) {
		fprintf(stderr, "Invalid bundle length\n");
		return -1;
	}

	if (mc->bundle_length > METER_MAX_NUM_BUNDLES * 8)  {
		fprintf(stderr, "More than %d bundles: %d\n",
			METER_MAX_NUM_BUNDLES, mc->bundle_length / 8);
		return -1;
	}

	bec = (void *)(mc) + sizeof(mc);

	printf("Number of Feature Counters:          %d\n", mc->bundle_length / 8);
	while (count++ < mc->bundle_length / 8) {
		char feature[5];

		feature[4] = '\0';
		get_feature(bec[count].encoding, feature);
		printf("    %s:          %d\n", feature, bec[count].counter);
	}

	return 0;
}

static int sdsi_state_cert_show(struct sdsi_dev *s)
{
	char buf[STATE_CERT_MAX_SIZE] = {0};
	struct state_certificate *sc;
	struct license_key_info *lki;
	uint32_t offset = 0;
	uint32_t count = 0;
	FILE *cert_ptr;
	int ret, size;

	ret = sdsi_update_registers(s);
	if (ret)
		return ret;

	if (!s->regs.en_features.sdsi) {
		fprintf(stderr, "On Demand feature is present but not enabled.");
		fprintf(stderr, " Unable to read state certificate");
		return -1;
	}

	ret = chdir(s->dev_path);
	if (ret == -1) {
		perror("chdir");
		return ret;
	}

	cert_ptr = fopen("state_certificate", "r");
	if (!cert_ptr) {
		perror("Could not open 'state_certificate' file");
		return -1;
	}

	size = fread(buf, 1, sizeof(buf), cert_ptr);
	if (!size) {
		fprintf(stderr, "Could not read 'state_certificate' file\n");
		fclose(cert_ptr);
		return -1;
	}
	fclose(cert_ptr);

	sc = (struct state_certificate *)buf;

	/* Print register info for this guid */
	printf("\n");
	printf("State certificate for device %s\n", s->dev_name);
	printf("\n");
	printf("Content Type:          %s\n", content_type(sc->content_type));
	printf("Region Revision ID:    %d\n", sc->region_rev_id);
	printf("Header Size:           %d\n", sc->header_size * 4);
	printf("Total Size:            %d\n", sc->total_size);
	printf("OEM Key Size:          %d\n", sc->key_size * 4);
	printf("Number of Licenses:    %d\n", sc->num_licenses);

	/* Skip over the license sizes 4 bytes per license) to get the license key info */
	lki = (void *)sc + sizeof(*sc) + (4 * sc->num_licenses);

	printf("License blob Info:\n");
	printf("    License Key Revision ID:    0x%x\n", lki->key_rev_id);
	printf("    License Key Image Content:  0x%lx%lx%lx%lx%lx%lx\n",
	       lki->key_image_content[5], lki->key_image_content[4],
	       lki->key_image_content[3], lki->key_image_content[2],
	       lki->key_image_content[1], lki->key_image_content[0]);

	while (count++ < sc->num_licenses) {
		uint32_t blob_size_field = *(uint32_t *)(buf + 0x14 + count * 4);
		uint32_t blob_size = LICENSE_BLOB_SIZE(blob_size_field);
		bool license_valid = LICENSE_VALID(blob_size_field);
		struct license_blob_content *lbc =
			(void *)(sc) +			// start of the state certificate
			sizeof(*sc) +			// size of the state certificate
			(4 * sc->num_licenses) +	// total size of the blob size blocks
			sizeof(*lki) +			// size of the license key info
			offset;				// offset to this blob content
		struct bundle_encoding *bundle = (void *)(lbc) + sizeof(*lbc);
		char feature[5];
		uint32_t i;

		printf("     Blob %d:\n", count - 1);
		printf("        License blob size:          %u\n", blob_size);
		printf("        License is valid:           %s\n", license_valid ? "Yes" : "No");
		printf("        License blob type:          %s\n", license_blob_type(lbc->type));
		printf("        License blob ID:            0x%lx\n", lbc->id);
		printf("        PPIN:                       0x%lx\n", lbc->ppin);
		printf("        Previous PPIN:              0x%lx\n", lbc->previous_ppin);
		printf("        Blob revision ID:           %u\n", lbc->rev_id);
		printf("        Number of Features:         %u\n", lbc->num_bundles);

		feature[4] = '\0';

		for (i = 0; i < min(lbc->num_bundles, STATE_MAX_NUM_IN_BUNDLE); i++) {
			get_feature(bundle[i].encoding, feature);
			printf("                 Feature %d:         %s\n", i, feature);
		}

		if (lbc->num_bundles > STATE_MAX_NUM_IN_BUNDLE)
			fprintf(stderr, "        Warning: %d > %d licenses in bundle reported.\n",
				lbc->num_bundles, STATE_MAX_NUM_IN_BUNDLE);

		offset += blob_size;
	};

	return 0;
}

static int sdsi_provision(struct sdsi_dev *s, char *bin_file, enum command command)
{
	int bin_fd, prov_fd, size, ret;
	char buf[STATE_CERT_MAX_SIZE] = { 0 };
	char cap[] = "provision_cap";
	char akc[] = "provision_akc";
	char *prov_file;

	if (!bin_file) {
		fprintf(stderr, "No binary file provided\n");
		return -1;
	}

	/* Open the binary */
	bin_fd = open(bin_file, O_RDONLY);
	if (bin_fd == -1) {
		fprintf(stderr, "Could not open file %s: %s\n", bin_file, strerror(errno));
		return bin_fd;
	}

	prov_file = (command == CMD_PROV_AKC) ? akc : cap;

	ret = chdir(s->dev_path);
	if (ret == -1) {
		perror("chdir");
		close(bin_fd);
		return ret;
	}

	/* Open the provision file */
	prov_fd = open(prov_file, O_WRONLY);
	if (prov_fd == -1) {
		fprintf(stderr, "Could not open file %s: %s\n", prov_file, strerror(errno));
		close(bin_fd);
		return prov_fd;
	}

	/* Read the binary file into the buffer */
	size = read(bin_fd, buf, STATE_CERT_MAX_SIZE);
	if (size == -1) {
		close(bin_fd);
		close(prov_fd);
		return -1;
	}

	ret = write(prov_fd, buf, size);
	if (ret == -1) {
		close(bin_fd);
		close(prov_fd);
		perror("Provisioning failed");
		return ret;
	}

	printf("Provisioned %s file %s successfully\n", prov_file, bin_file);

	close(bin_fd);
	close(prov_fd);

	return 0;
}

static int sdsi_provision_akc(struct sdsi_dev *s, char *bin_file)
{
	int ret;

	ret = sdsi_update_registers(s);
	if (ret)
		return ret;

	if (!s->regs.en_features.sdsi) {
		fprintf(stderr, "On Demand feature is present but not enabled. Unable to provision");
		return -1;
	}

	if (!s->regs.prov_avail.available) {
		fprintf(stderr, "Maximum number of updates (%d) has been reached.\n",
			s->regs.prov_avail.threshold);
		return -1;
	}

	if (s->regs.auth_fail_count.key_failure_count ==
	    s->regs.auth_fail_count.key_failure_threshold) {
		fprintf(stderr, "Maximum number of AKC provision failures (%d) has been reached.\n",
			s->regs.auth_fail_count.key_failure_threshold);
		fprintf(stderr, "Power cycle the system to reset the counter\n");
		return -1;
	}

	return sdsi_provision(s, bin_file, CMD_PROV_AKC);
}

static int sdsi_provision_cap(struct sdsi_dev *s, char *bin_file)
{
	int ret;

	ret = sdsi_update_registers(s);
	if (ret)
		return ret;

	if (!s->regs.en_features.sdsi) {
		fprintf(stderr, "On Demand feature is present but not enabled. Unable to provision");
		return -1;
	}

	if (!s->regs.prov_avail.available) {
		fprintf(stderr, "Maximum number of updates (%d) has been reached.\n",
			s->regs.prov_avail.threshold);
		return -1;
	}

	if (s->regs.auth_fail_count.auth_failure_count ==
	    s->regs.auth_fail_count.auth_failure_threshold) {
		fprintf(stderr, "Maximum number of CAP provision failures (%d) has been reached.\n",
			s->regs.auth_fail_count.auth_failure_threshold);
		fprintf(stderr, "Power cycle the system to reset the counter\n");
		return -1;
	}

	return sdsi_provision(s, bin_file, CMD_PROV_CAP);
}

static int read_sysfs_data(const char *file, int *value)
{
	char buff[16];
	FILE *fp;

	fp = fopen(file, "r");
	if (!fp) {
		perror(file);
		return -1;
	}

	if (!fgets(buff, 16, fp)) {
		fprintf(stderr, "Failed to read file '%s'", file);
		fclose(fp);
		return -1;
	}

	fclose(fp);
	*value = strtol(buff, NULL, 0);

	return 0;
}

static struct sdsi_dev *sdsi_create_dev(char *dev_no)
{
	int dev_name_len = sizeof(SDSI_DEV) + strlen(dev_no) + 1;
	struct sdsi_dev *s;
	int guid;
	DIR *dir;

	s = (struct sdsi_dev *)malloc(sizeof(*s));
	if (!s) {
		perror("malloc");
		return NULL;
	}

	s->dev_name = (char *)malloc(sizeof(SDSI_DEV) + strlen(dev_no) + 1);
	if (!s->dev_name) {
		perror("malloc");
		free(s);
		return NULL;
	}

	snprintf(s->dev_name, dev_name_len, "%s.%s", SDSI_DEV, dev_no);

	s->dev_path = (char *)malloc(sizeof(AUX_DEV_PATH) + dev_name_len);
	if (!s->dev_path) {
		perror("malloc");
		free(s->dev_name);
		free(s);
		return NULL;
	}

	snprintf(s->dev_path, sizeof(AUX_DEV_PATH) + dev_name_len, "%s%s", AUX_DEV_PATH,
		 s->dev_name);
	dir = opendir(s->dev_path);
	if (!dir) {
		fprintf(stderr, "Could not open directory '%s': %s\n", s->dev_path,
			strerror(errno));
		free(s->dev_path);
		free(s->dev_name);
		free(s);
		return NULL;
	}

	if (chdir(s->dev_path) == -1) {
		perror("chdir");
		free(s->dev_path);
		free(s->dev_name);
		free(s);
		return NULL;
	}

	if (read_sysfs_data("guid", &guid)) {
		free(s->dev_path);
		free(s->dev_name);
		free(s);
		return NULL;
	}

	s->guid = guid;

	return s;
}

static void sdsi_free_dev(struct sdsi_dev *s)
{
	free(s->dev_path);
	free(s->dev_name);
	free(s);
}

static void usage(char *prog)
{
	printf("Usage: %s [-l] [-d DEVNO [-i] [-s] [-m] [-a FILE] [-c FILE]]\n", prog);
}

static void show_help(void)
{
	printf("Commands:\n");
	printf("  %-18s\t%s\n", "-l, --list",           "list available On Demand devices");
	printf("  %-18s\t%s\n", "-d, --devno DEVNO",    "On Demand device number");
	printf("  %-18s\t%s\n", "-i, --info",           "show socket information");
	printf("  %-18s\t%s\n", "-s, --state",          "show state certificate");
	printf("  %-18s\t%s\n", "-m, --meter",          "show meter certificate");
	printf("  %-18s\t%s\n", "-a, --akc FILE",       "provision socket with AKC FILE");
	printf("  %-18s\t%s\n", "-c, --cap FILE>",      "provision socket with CAP FILE");
}

int main(int argc, char *argv[])
{
	char bin_file[PATH_MAX], *dev_no = NULL;
	bool device_selected = false;
	char *progname;
	enum command command = -1;
	struct sdsi_dev *s;
	int ret = 0, opt;
	int option_index = 0;

	static struct option long_options[] = {
		{"akc",		required_argument,	0, 'a'},
		{"cap",		required_argument,	0, 'c'},
		{"devno",	required_argument,	0, 'd'},
		{"help",	no_argument,		0, 'h'},
		{"info",	no_argument,		0, 'i'},
		{"list",	no_argument,		0, 'l'},
		{"meter",	no_argument,		0, 'm'},
		{"state",	no_argument,		0, 's'},
		{0,		0,			0, 0 }
	};


	progname = argv[0];

	while ((opt = getopt_long_only(argc, argv, "+a:c:d:hilms", long_options,
			&option_index)) != -1) {
		switch (opt) {
		case 'd':
			dev_no = optarg;
			device_selected = true;
			break;
		case 'l':
			sdsi_list_devices();
			return 0;
		case 'i':
			command = CMD_SOCKET_INFO;
			break;
		case 'm':
			command = CMD_METER_CERT;
			break;
		case 's':
			command = CMD_STATE_CERT;
			break;
		case 'a':
		case 'c':
			if (!access(optarg, F_OK) == 0) {
				fprintf(stderr, "Could not open file '%s': %s\n", optarg,
					strerror(errno));
				return -1;
			}

			if (!realpath(optarg, bin_file)) {
				perror("realpath");
				return -1;
			}

			command = (opt == 'a') ? CMD_PROV_AKC : CMD_PROV_CAP;
			break;
		case 'h':
			usage(progname);
			show_help();
			return 0;
		default:
			usage(progname);
			return -1;
		}
	}

	if (device_selected) {
		s = sdsi_create_dev(dev_no);
		if (!s)
			return -1;

		switch (command) {
		case CMD_SOCKET_INFO:
			ret = sdsi_read_reg(s);
			break;
		case CMD_METER_CERT:
			ret = sdsi_meter_cert_show(s);
			break;
		case CMD_STATE_CERT:
			ret = sdsi_state_cert_show(s);
			break;
		case CMD_PROV_AKC:
			ret = sdsi_provision_akc(s, bin_file);
			break;
		case CMD_PROV_CAP:
			ret = sdsi_provision_cap(s, bin_file);
			break;
		default:
			fprintf(stderr, "No command specified\n");
			return -1;
		}

		sdsi_free_dev(s);

	} else {
		fprintf(stderr, "No device specified\n");
		return -1;
	}

	return ret;
}
