ssize_t tpm_getcap(struct tpm_chip *chip, uint32_t subcap_id, cap_t *cap, const char *desc) { struct tpm_cmd_t tpm_cmd; int rc; tpm_cmd.header.in = tpm_getcap_header; if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) { tpm_cmd.params.getcap_in.cap = subcap_id; /*subcap field not necessary */ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(0); tpm_cmd.header.in.length -= cpu_to_be32(sizeof(uint32_t)); } else { if (subcap_id == TPM_CAP_FLAG_PERM || subcap_id == TPM_CAP_FLAG_VOL) tpm_cmd.params.getcap_in.cap = TPM_CAP_FLAG; else tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); tpm_cmd.params.getcap_in.subcap = subcap_id; } rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc); if (!rc) *cap = tpm_cmd.params.getcap_out.cap; return rc; }
static ssize_t pubek_show(struct device *dev, struct device_attribute *attr, char *buf) { u8 *data; struct tpm_cmd_t tpm_cmd; ssize_t err; int i, rc; char *str = buf; struct tpm_chip *chip = dev_get_drvdata(dev); tpm_cmd.header.in = tpm_readpubek_header; err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, "attempting to read the PUBEK"); if (err) goto out; /* ignore header 10 bytes algorithm 32 bits (1 == RSA ) encscheme 16 bits sigscheme 16 bits parameters (RSA 12->bytes: keybit, #primes, expbit) keylenbytes 32 bits 256 byte modulus ignore checksum 20 bytes */ data = tpm_cmd.params.readpubek_out_buffer; str += sprintf(str, "Algorithm: %02X %02X %02X %02X\n" "Encscheme: %02X %02X\n" "Sigscheme: %02X %02X\n" "Parameters: %02X %02X %02X %02X " "%02X %02X %02X %02X " "%02X %02X %02X %02X\n" "Modulus length: %d\n" "Modulus:\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], be32_to_cpu(*((__be32 *) (data + 24)))); for (i = 0; i < 256; i++) { str += sprintf(str, "%02X ", data[i + 28]); if ((i + 1) % 16 == 0) str += sprintf(str, "\n"); } out: rc = str - buf; return rc; }
void app(const char *address, const char *name) { int sock; char buffer[BUF_SIZE]; fd_set rdfs; strcpy(buffer, "hello"); sock = init_connection(address); write_server(sock, name); while (1) { init_socket(sock, &rdfs); if(select(sock + 1, &rdfs, NULL, NULL, NULL) == -1) { perror("select()"); exit(errno); } if(FD_ISSET(STDIN_FILENO, &rdfs)) { if (read_keyboard(buffer) < 0) continue; transmit_cmd(buffer,sock); } else if(FD_ISSET(sock, &rdfs)) { int n = read_server(sock, &buffer); printf("receive : %s|\n", buffer); if (fgets(buffer, BUF_SIZE - 1, stdin) == NULL) { perror("fgets()"); continue; } printf("receive:%s\n",buffer); /* server down */ if(n == 0) { printf("Server disconnected !\n"); break; } puts(buffer); } } end_connection(sock); }
dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc); return err; } return 0; } void tpm_gen_interrupt(struct tpm_chip *chip) { u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)]; ssize_t rc; memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT; rc = transmit_cmd(chip, data, sizeof(data), "attempting to determine the timeouts"); } EXPORT_SYMBOL_GPL(tpm_gen_interrupt); void tpm_get_timeouts(struct tpm_chip *chip) { u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)]; ssize_t rc; u32 timeout; memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT; rc = transmit_cmd(chip, data, sizeof(data), "attempting to determine the timeouts");
int tpm_get_timeouts(struct tpm_chip *chip) { struct tpm_cmd_t tpm_cmd; struct timeout_t *timeout_cap; struct duration_t *duration_cap; ssize_t rc; uint32_t timeout; unsigned int scale = 1; tpm_cmd.header.in = tpm_getcap_header; tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT; if((rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, "attempting to determine the timeouts")) != 0) { printk("transmit failed %d\n", rc); goto duration; } if(be32_to_cpu(tpm_cmd.header.out.return_code) != 0 || be32_to_cpu(tpm_cmd.header.out.length) != sizeof(tpm_cmd.header.out) + sizeof(uint32_t) + 4 * sizeof(uint32_t)) { return -EINVAL; } timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout; /* Don't overwrite default if value is 0 */ timeout = be32_to_cpu(timeout_cap->a); if(timeout && timeout < 1000) { /* timeouts in msc rather usec */ scale = 1000; } if (timeout) chip->timeout_a = MICROSECS(timeout * scale); /*Convert to msec */ ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_a,MILLISECS(TIS_SHORT_TIMEOUT),'a'); timeout = be32_to_cpu(timeout_cap->b); if (timeout) chip->timeout_b = MICROSECS(timeout * scale); /*Convert to msec */ ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_b,MILLISECS(TIS_LONG_TIMEOUT),'b'); timeout = be32_to_cpu(timeout_cap->c); if (timeout) chip->timeout_c = MICROSECS(timeout * scale); /*Convert to msec */ ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_c,MILLISECS(TIS_SHORT_TIMEOUT),'c'); timeout = be32_to_cpu(timeout_cap->d); if (timeout) chip->timeout_d = MICROSECS(timeout * scale); /*Convert to msec */ ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_d,MILLISECS(TIS_SHORT_TIMEOUT),'d'); duration: tpm_cmd.header.in = tpm_getcap_header; tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION; if((rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, "attempting to determine the durations")) < 0) { return rc; } if(be32_to_cpu(tpm_cmd.header.out.return_code) != 0 || be32_to_cpu(tpm_cmd.header.out.length) != sizeof(tpm_cmd.header.out) + sizeof(uint32_t) + 3 * sizeof(uint32_t)) { return -EINVAL; } duration_cap = &tpm_cmd.params.getcap_out.cap.duration; chip->duration[TPM_SHORT] = MICROSECS(be32_to_cpu(duration_cap->tpm_short)); chip->duration[TPM_MEDIUM] = MICROSECS(be32_to_cpu(duration_cap->tpm_medium)); chip->duration[TPM_LONG] = MICROSECS(be32_to_cpu(duration_cap->tpm_long)); /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above * value wrong and apparently reports msecs rather than usecs. So we * fix up the resulting too-small TPM_SHORT value to make things work. */ if (chip->duration[TPM_SHORT] < MILLISECS(10)) { chip->duration[TPM_SHORT] = SECONDS(1); chip->duration[TPM_MEDIUM] *= 1000; chip->duration[TPM_LONG] *= 1000; printk("Adjusting TPM timeout parameters\n"); } return 0; }