aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm/tpm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tpm/tpm.c')
-rw-r--r--drivers/char/tpm/tpm.c74
1 files changed, 64 insertions, 10 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 3af9f4d1a23f..f26afdb1a702 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -30,12 +30,7 @@
30#include <linux/freezer.h> 30#include <linux/freezer.h>
31 31
32#include "tpm.h" 32#include "tpm.h"
33 33#include "tpm_eventlog.h"
34enum tpm_const {
35 TPM_MINOR = 224, /* officially assigned */
36 TPM_BUFSIZE = 4096,
37 TPM_NUM_DEVICES = 256,
38};
39 34
40enum tpm_duration { 35enum tpm_duration {
41 TPM_SHORT = 0, 36 TPM_SHORT = 0,
@@ -482,6 +477,7 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
482#define TPM_INTERNAL_RESULT_SIZE 200 477#define TPM_INTERNAL_RESULT_SIZE 200
483#define TPM_TAG_RQU_COMMAND cpu_to_be16(193) 478#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
484#define TPM_ORD_GET_CAP cpu_to_be32(101) 479#define TPM_ORD_GET_CAP cpu_to_be32(101)
480#define TPM_ORD_GET_RANDOM cpu_to_be32(70)
485 481
486static const struct tpm_input_header tpm_getcap_header = { 482static const struct tpm_input_header tpm_getcap_header = {
487 .tag = TPM_TAG_RQU_COMMAND, 483 .tag = TPM_TAG_RQU_COMMAND,
@@ -919,7 +915,7 @@ EXPORT_SYMBOL_GPL(tpm_show_pcrs);
919 915
920#define READ_PUBEK_RESULT_SIZE 314 916#define READ_PUBEK_RESULT_SIZE 314
921#define TPM_ORD_READPUBEK cpu_to_be32(124) 917#define TPM_ORD_READPUBEK cpu_to_be32(124)
922struct tpm_input_header tpm_readpubek_header = { 918static struct tpm_input_header tpm_readpubek_header = {
923 .tag = TPM_TAG_RQU_COMMAND, 919 .tag = TPM_TAG_RQU_COMMAND,
924 .length = cpu_to_be32(30), 920 .length = cpu_to_be32(30),
925 .ordinal = TPM_ORD_READPUBEK 921 .ordinal = TPM_ORD_READPUBEK
@@ -1175,7 +1171,7 @@ int tpm_release(struct inode *inode, struct file *file)
1175 flush_work(&chip->work); 1171 flush_work(&chip->work);
1176 file->private_data = NULL; 1172 file->private_data = NULL;
1177 atomic_set(&chip->data_pending, 0); 1173 atomic_set(&chip->data_pending, 0);
1178 kfree(chip->data_buffer); 1174 kzfree(chip->data_buffer);
1179 clear_bit(0, &chip->is_open); 1175 clear_bit(0, &chip->is_open);
1180 put_device(chip->dev); 1176 put_device(chip->dev);
1181 return 0; 1177 return 0;
@@ -1227,7 +1223,6 @@ ssize_t tpm_read(struct file *file, char __user *buf,
1227 del_singleshot_timer_sync(&chip->user_read_timer); 1223 del_singleshot_timer_sync(&chip->user_read_timer);
1228 flush_work(&chip->work); 1224 flush_work(&chip->work);
1229 ret_size = atomic_read(&chip->data_pending); 1225 ret_size = atomic_read(&chip->data_pending);
1230 atomic_set(&chip->data_pending, 0);
1231 if (ret_size > 0) { /* relay data */ 1226 if (ret_size > 0) { /* relay data */
1232 ssize_t orig_ret_size = ret_size; 1227 ssize_t orig_ret_size = ret_size;
1233 if (size < ret_size) 1228 if (size < ret_size)
@@ -1242,6 +1237,8 @@ ssize_t tpm_read(struct file *file, char __user *buf,
1242 mutex_unlock(&chip->buffer_mutex); 1237 mutex_unlock(&chip->buffer_mutex);
1243 } 1238 }
1244 1239
1240 atomic_set(&chip->data_pending, 0);
1241
1245 return ret_size; 1242 return ret_size;
1246} 1243}
1247EXPORT_SYMBOL_GPL(tpm_read); 1244EXPORT_SYMBOL_GPL(tpm_read);
@@ -1326,6 +1323,58 @@ int tpm_pm_resume(struct device *dev)
1326} 1323}
1327EXPORT_SYMBOL_GPL(tpm_pm_resume); 1324EXPORT_SYMBOL_GPL(tpm_pm_resume);
1328 1325
1326#define TPM_GETRANDOM_RESULT_SIZE 18
1327static struct tpm_input_header tpm_getrandom_header = {
1328 .tag = TPM_TAG_RQU_COMMAND,
1329 .length = cpu_to_be32(14),
1330 .ordinal = TPM_ORD_GET_RANDOM
1331};
1332
1333/**
1334 * tpm_get_random() - Get random bytes from the tpm's RNG
1335 * @chip_num: A specific chip number for the request or TPM_ANY_NUM
1336 * @out: destination buffer for the random bytes
1337 * @max: the max number of bytes to write to @out
1338 *
1339 * Returns < 0 on error and the number of bytes read on success
1340 */
1341int tpm_get_random(u32 chip_num, u8 *out, size_t max)
1342{
1343 struct tpm_chip *chip;
1344 struct tpm_cmd_t tpm_cmd;
1345 u32 recd, num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA);
1346 int err, total = 0, retries = 5;
1347 u8 *dest = out;
1348
1349 chip = tpm_chip_find_get(chip_num);
1350 if (chip == NULL)
1351 return -ENODEV;
1352
1353 if (!out || !num_bytes || max > TPM_MAX_RNG_DATA)
1354 return -EINVAL;
1355
1356 do {
1357 tpm_cmd.header.in = tpm_getrandom_header;
1358 tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
1359
1360 err = transmit_cmd(chip, &tpm_cmd,
1361 TPM_GETRANDOM_RESULT_SIZE + num_bytes,
1362 "attempting get random");
1363 if (err)
1364 break;
1365
1366 recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
1367 memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd);
1368
1369 dest += recd;
1370 total += recd;
1371 num_bytes -= recd;
1372 } while (retries-- && total < max);
1373
1374 return total ? total : -EIO;
1375}
1376EXPORT_SYMBOL_GPL(tpm_get_random);
1377
1329/* In case vendor provided release function, call it too.*/ 1378/* In case vendor provided release function, call it too.*/
1330 1379
1331void tpm_dev_vendor_release(struct tpm_chip *chip) 1380void tpm_dev_vendor_release(struct tpm_chip *chip)
@@ -1346,7 +1395,7 @@ EXPORT_SYMBOL_GPL(tpm_dev_vendor_release);
1346 * Once all references to platform device are down to 0, 1395 * Once all references to platform device are down to 0,
1347 * release all allocated structures. 1396 * release all allocated structures.
1348 */ 1397 */
1349void tpm_dev_release(struct device *dev) 1398static void tpm_dev_release(struct device *dev)
1350{ 1399{
1351 struct tpm_chip *chip = dev_get_drvdata(dev); 1400 struct tpm_chip *chip = dev_get_drvdata(dev);
1352 1401
@@ -1427,6 +1476,11 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
1427 goto put_device; 1476 goto put_device;
1428 } 1477 }
1429 1478
1479 if (sys_add_ppi(&dev->kobj)) {
1480 misc_deregister(&chip->vendor.miscdev);
1481 goto put_device;
1482 }
1483
1430 chip->bios_dir = tpm_bios_log_setup(devname); 1484 chip->bios_dir = tpm_bios_log_setup(devname);
1431 1485
1432 /* Make chip available */ 1486 /* Make chip available */