brintos

brintos / linux-shallow public Read only

0
0
Text · 14.8 KiB · 7df7aba Raw
692 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2004 IBM Corporation4 * Copyright (C) 2014 Intel Corporation5 *6 * Authors:7 * Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>8 * Leendert van Doorn <leendert@watson.ibm.com>9 * Dave Safford <safford@watson.ibm.com>10 * Reiner Sailer <sailer@watson.ibm.com>11 * Kylene Hall <kjhall@us.ibm.com>12 *13 * Maintained by: <tpmdd-devel@lists.sourceforge.net>14 *15 * TPM chip management routines.16 */17 18#include <linux/poll.h>19#include <linux/slab.h>20#include <linux/mutex.h>21#include <linux/spinlock.h>22#include <linux/freezer.h>23#include <linux/major.h>24#include <linux/tpm_eventlog.h>25#include <linux/hw_random.h>26#include "tpm.h"27 28DEFINE_IDR(dev_nums_idr);29static DEFINE_MUTEX(idr_lock);30 31const struct class tpm_class = {32	.name = "tpm",33	.shutdown_pre = tpm_class_shutdown,34};35const struct class tpmrm_class = {36	.name = "tpmrm",37};38dev_t tpm_devt;39 40static int tpm_request_locality(struct tpm_chip *chip)41{42	int rc;43 44	if (!chip->ops->request_locality)45		return 0;46 47	rc = chip->ops->request_locality(chip, 0);48	if (rc < 0)49		return rc;50 51	chip->locality = rc;52	return 0;53}54 55static void tpm_relinquish_locality(struct tpm_chip *chip)56{57	int rc;58 59	if (!chip->ops->relinquish_locality)60		return;61 62	rc = chip->ops->relinquish_locality(chip, chip->locality);63	if (rc)64		dev_err(&chip->dev, "%s: : error %d\n", __func__, rc);65 66	chip->locality = -1;67}68 69static int tpm_cmd_ready(struct tpm_chip *chip)70{71	if (!chip->ops->cmd_ready)72		return 0;73 74	return chip->ops->cmd_ready(chip);75}76 77static int tpm_go_idle(struct tpm_chip *chip)78{79	if (!chip->ops->go_idle)80		return 0;81 82	return chip->ops->go_idle(chip);83}84 85static void tpm_clk_enable(struct tpm_chip *chip)86{87	if (chip->ops->clk_enable)88		chip->ops->clk_enable(chip, true);89}90 91static void tpm_clk_disable(struct tpm_chip *chip)92{93	if (chip->ops->clk_enable)94		chip->ops->clk_enable(chip, false);95}96 97/**98 * tpm_chip_start() - power on the TPM99 * @chip:	a TPM chip to use100 *101 * Return:102 * * The response length	- OK103 * * -errno			- A system error104 */105int tpm_chip_start(struct tpm_chip *chip)106{107	int ret;108 109	tpm_clk_enable(chip);110 111	if (chip->locality == -1) {112		ret = tpm_request_locality(chip);113		if (ret) {114			tpm_clk_disable(chip);115			return ret;116		}117	}118 119	ret = tpm_cmd_ready(chip);120	if (ret) {121		tpm_relinquish_locality(chip);122		tpm_clk_disable(chip);123		return ret;124	}125 126	return 0;127}128EXPORT_SYMBOL_GPL(tpm_chip_start);129 130/**131 * tpm_chip_stop() - power off the TPM132 * @chip:	a TPM chip to use133 *134 * Return:135 * * The response length	- OK136 * * -errno			- A system error137 */138void tpm_chip_stop(struct tpm_chip *chip)139{140	tpm_go_idle(chip);141	tpm_relinquish_locality(chip);142	tpm_clk_disable(chip);143}144EXPORT_SYMBOL_GPL(tpm_chip_stop);145 146/**147 * tpm_try_get_ops() - Get a ref to the tpm_chip148 * @chip: Chip to ref149 *150 * The caller must already have some kind of locking to ensure that chip is151 * valid. This function will lock the chip so that the ops member can be152 * accessed safely. The locking prevents tpm_chip_unregister from153 * completing, so it should not be held for long periods.154 *155 * Returns -ERRNO if the chip could not be got.156 */157int tpm_try_get_ops(struct tpm_chip *chip)158{159	int rc = -EIO;160 161	if (chip->flags & TPM_CHIP_FLAG_DISABLE)162		return rc;163 164	get_device(&chip->dev);165 166	down_read(&chip->ops_sem);167	if (!chip->ops)168		goto out_ops;169 170	mutex_lock(&chip->tpm_mutex);171	rc = tpm_chip_start(chip);172	if (rc)173		goto out_lock;174 175	return 0;176out_lock:177	mutex_unlock(&chip->tpm_mutex);178out_ops:179	up_read(&chip->ops_sem);180	put_device(&chip->dev);181	return rc;182}183EXPORT_SYMBOL_GPL(tpm_try_get_ops);184 185/**186 * tpm_put_ops() - Release a ref to the tpm_chip187 * @chip: Chip to put188 *189 * This is the opposite pair to tpm_try_get_ops(). After this returns chip may190 * be kfree'd.191 */192void tpm_put_ops(struct tpm_chip *chip)193{194	tpm_chip_stop(chip);195	mutex_unlock(&chip->tpm_mutex);196	up_read(&chip->ops_sem);197	put_device(&chip->dev);198}199EXPORT_SYMBOL_GPL(tpm_put_ops);200 201/**202 * tpm_default_chip() - find a TPM chip and get a reference to it203 */204struct tpm_chip *tpm_default_chip(void)205{206	struct tpm_chip *chip, *res = NULL;207	int chip_num = 0;208	int chip_prev;209 210	mutex_lock(&idr_lock);211 212	do {213		chip_prev = chip_num;214		chip = idr_get_next(&dev_nums_idr, &chip_num);215		if (chip) {216			get_device(&chip->dev);217			res = chip;218			break;219		}220	} while (chip_prev != chip_num);221 222	mutex_unlock(&idr_lock);223 224	return res;225}226EXPORT_SYMBOL_GPL(tpm_default_chip);227 228/**229 * tpm_find_get_ops() - find and reserve a TPM chip230 * @chip:	a &struct tpm_chip instance, %NULL for the default chip231 *232 * Finds a TPM chip and reserves its class device and operations. The chip must233 * be released with tpm_put_ops() after use.234 * This function is for internal use only. It supports existing TPM callers235 * by accepting NULL, but those callers should be converted to pass in a chip236 * directly.237 *238 * Return:239 * A reserved &struct tpm_chip instance.240 * %NULL if a chip is not found.241 * %NULL if the chip is not available.242 */243struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip)244{245	int rc;246 247	if (chip) {248		if (!tpm_try_get_ops(chip))249			return chip;250		return NULL;251	}252 253	chip = tpm_default_chip();254	if (!chip)255		return NULL;256	rc = tpm_try_get_ops(chip);257	/* release additional reference we got from tpm_default_chip() */258	put_device(&chip->dev);259	if (rc)260		return NULL;261	return chip;262}263 264/**265 * tpm_dev_release() - free chip memory and the device number266 * @dev: the character device for the TPM chip267 *268 * This is used as the release function for the character device.269 */270static void tpm_dev_release(struct device *dev)271{272	struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);273 274	mutex_lock(&idr_lock);275	idr_remove(&dev_nums_idr, chip->dev_num);276	mutex_unlock(&idr_lock);277 278	kfree(chip->work_space.context_buf);279	kfree(chip->work_space.session_buf);280	kfree(chip->allocated_banks);281#ifdef CONFIG_TCG_TPM2_HMAC282	kfree(chip->auth);283#endif284	kfree(chip);285}286 287/**288 * tpm_class_shutdown() - prepare the TPM device for loss of power.289 * @dev: device to which the chip is associated.290 *291 * Issues a TPM2_Shutdown command prior to loss of power, as required by the292 * TPM 2.0 spec. Then, calls bus- and device- specific shutdown code.293 *294 * Return: always 0 (i.e. success)295 */296int tpm_class_shutdown(struct device *dev)297{298	struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);299 300	down_write(&chip->ops_sem);301	if (chip->flags & TPM_CHIP_FLAG_TPM2) {302		if (!tpm_chip_start(chip)) {303			tpm2_shutdown(chip, TPM2_SU_CLEAR);304			tpm_chip_stop(chip);305		}306	}307	chip->ops = NULL;308	up_write(&chip->ops_sem);309 310	return 0;311}312 313/**314 * tpm_chip_alloc() - allocate a new struct tpm_chip instance315 * @pdev: device to which the chip is associated316 *        At this point pdev mst be initialized, but does not have to317 *        be registered318 * @ops: struct tpm_class_ops instance319 *320 * Allocates a new struct tpm_chip instance and assigns a free321 * device number for it. Must be paired with put_device(&chip->dev).322 */323struct tpm_chip *tpm_chip_alloc(struct device *pdev,324				const struct tpm_class_ops *ops)325{326	struct tpm_chip *chip;327	int rc;328 329	chip = kzalloc(sizeof(*chip), GFP_KERNEL);330	if (chip == NULL)331		return ERR_PTR(-ENOMEM);332 333	mutex_init(&chip->tpm_mutex);334	init_rwsem(&chip->ops_sem);335 336	chip->ops = ops;337 338	mutex_lock(&idr_lock);339	rc = idr_alloc(&dev_nums_idr, NULL, 0, TPM_NUM_DEVICES, GFP_KERNEL);340	mutex_unlock(&idr_lock);341	if (rc < 0) {342		dev_err(pdev, "No available tpm device numbers\n");343		kfree(chip);344		return ERR_PTR(rc);345	}346	chip->dev_num = rc;347 348	device_initialize(&chip->dev);349 350	chip->dev.class = &tpm_class;351	chip->dev.release = tpm_dev_release;352	chip->dev.parent = pdev;353	chip->dev.groups = chip->groups;354 355	if (chip->dev_num == 0)356		chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);357	else358		chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);359 360	rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);361	if (rc)362		goto out;363 364	if (!pdev)365		chip->flags |= TPM_CHIP_FLAG_VIRTUAL;366 367	cdev_init(&chip->cdev, &tpm_fops);368	chip->cdev.owner = THIS_MODULE;369 370	rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE);371	if (rc) {372		rc = -ENOMEM;373		goto out;374	}375 376	chip->locality = -1;377	return chip;378 379out:380	put_device(&chip->dev);381	return ERR_PTR(rc);382}383EXPORT_SYMBOL_GPL(tpm_chip_alloc);384 385static void tpm_put_device(void *dev)386{387	put_device(dev);388}389 390/**391 * tpmm_chip_alloc() - allocate a new struct tpm_chip instance392 * @pdev: parent device to which the chip is associated393 * @ops: struct tpm_class_ops instance394 *395 * Same as tpm_chip_alloc except devm is used to do the put_device396 */397struct tpm_chip *tpmm_chip_alloc(struct device *pdev,398				 const struct tpm_class_ops *ops)399{400	struct tpm_chip *chip;401	int rc;402 403	chip = tpm_chip_alloc(pdev, ops);404	if (IS_ERR(chip))405		return chip;406 407	rc = devm_add_action_or_reset(pdev,408				      tpm_put_device,409				      &chip->dev);410	if (rc)411		return ERR_PTR(rc);412 413	dev_set_drvdata(pdev, chip);414 415	return chip;416}417EXPORT_SYMBOL_GPL(tpmm_chip_alloc);418 419static int tpm_add_char_device(struct tpm_chip *chip)420{421	int rc;422 423	rc = cdev_device_add(&chip->cdev, &chip->dev);424	if (rc) {425		dev_err(&chip->dev,426			"unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",427			dev_name(&chip->dev), MAJOR(chip->dev.devt),428			MINOR(chip->dev.devt), rc);429		return rc;430	}431 432	if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip)) {433		rc = tpm_devs_add(chip);434		if (rc)435			goto err_del_cdev;436	}437 438	/* Make the chip available. */439	mutex_lock(&idr_lock);440	idr_replace(&dev_nums_idr, chip, chip->dev_num);441	mutex_unlock(&idr_lock);442 443	return 0;444 445err_del_cdev:446	cdev_device_del(&chip->cdev, &chip->dev);447	return rc;448}449 450static void tpm_del_char_device(struct tpm_chip *chip)451{452	cdev_device_del(&chip->cdev, &chip->dev);453 454	/* Make the chip unavailable. */455	mutex_lock(&idr_lock);456	idr_replace(&dev_nums_idr, NULL, chip->dev_num);457	mutex_unlock(&idr_lock);458 459	/* Make the driver uncallable. */460	down_write(&chip->ops_sem);461 462	/*463	 * Check if chip->ops is still valid: In case that the controller464	 * drivers shutdown handler unregisters the controller in its465	 * shutdown handler we are called twice and chip->ops to NULL.466	 */467	if (chip->ops) {468		if (chip->flags & TPM_CHIP_FLAG_TPM2) {469			if (!tpm_chip_start(chip)) {470				tpm2_shutdown(chip, TPM2_SU_CLEAR);471				tpm_chip_stop(chip);472			}473		}474		chip->ops = NULL;475	}476	up_write(&chip->ops_sem);477}478 479static void tpm_del_legacy_sysfs(struct tpm_chip *chip)480{481	struct attribute **i;482 483	if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL) ||484	    tpm_is_firmware_upgrade(chip))485		return;486 487	sysfs_remove_link(&chip->dev.parent->kobj, "ppi");488 489	for (i = chip->groups[0]->attrs; *i != NULL; ++i)490		sysfs_remove_link(&chip->dev.parent->kobj, (*i)->name);491}492 493/* For compatibility with legacy sysfs paths we provide symlinks from the494 * parent dev directory to selected names within the tpm chip directory. Old495 * kernel versions created these files directly under the parent.496 */497static int tpm_add_legacy_sysfs(struct tpm_chip *chip)498{499	struct attribute **i;500	int rc;501 502	if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL) ||503		tpm_is_firmware_upgrade(chip))504		return 0;505 506	rc = compat_only_sysfs_link_entry_to_kobj(507		    &chip->dev.parent->kobj, &chip->dev.kobj, "ppi", NULL);508	if (rc && rc != -ENOENT)509		return rc;510 511	/* All the names from tpm-sysfs */512	for (i = chip->groups[0]->attrs; *i != NULL; ++i) {513		rc = compat_only_sysfs_link_entry_to_kobj(514		    &chip->dev.parent->kobj, &chip->dev.kobj, (*i)->name, NULL);515		if (rc) {516			tpm_del_legacy_sysfs(chip);517			return rc;518		}519	}520 521	return 0;522}523 524static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)525{526	struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng);527 528	return tpm_get_random(chip, data, max);529}530 531static bool tpm_is_hwrng_enabled(struct tpm_chip *chip)532{533	if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM))534		return false;535	if (tpm_is_firmware_upgrade(chip))536		return false;537	if (chip->flags & TPM_CHIP_FLAG_HWRNG_DISABLED)538		return false;539	return true;540}541 542static int tpm_add_hwrng(struct tpm_chip *chip)543{544	if (!tpm_is_hwrng_enabled(chip))545		return 0;546 547	snprintf(chip->hwrng_name, sizeof(chip->hwrng_name),548		 "tpm-rng-%d", chip->dev_num);549	chip->hwrng.name = chip->hwrng_name;550	chip->hwrng.read = tpm_hwrng_read;551	return hwrng_register(&chip->hwrng);552}553 554static int tpm_get_pcr_allocation(struct tpm_chip *chip)555{556	int rc;557 558	if (tpm_is_firmware_upgrade(chip))559		return 0;560 561	rc = (chip->flags & TPM_CHIP_FLAG_TPM2) ?562	     tpm2_get_pcr_allocation(chip) :563	     tpm1_get_pcr_allocation(chip);564 565	if (rc > 0)566		return -ENODEV;567 568	return rc;569}570 571/*572 * tpm_chip_bootstrap() - Boostrap TPM chip after power on573 * @chip: TPM chip to use.574 *575 * Initialize TPM chip after power on. This a one-shot function: subsequent576 * calls will have no effect.577 */578int tpm_chip_bootstrap(struct tpm_chip *chip)579{580	int rc;581 582	if (chip->flags & TPM_CHIP_FLAG_BOOTSTRAPPED)583		return 0;584 585	rc = tpm_chip_start(chip);586	if (rc)587		return rc;588 589	rc = tpm_auto_startup(chip);590	if (rc)591		goto stop;592 593	rc = tpm_get_pcr_allocation(chip);594stop:595	tpm_chip_stop(chip);596 597	/*598	 * Unconditionally set, as driver initialization should cease, when the599	 * boostrapping process fails.600	 */601	chip->flags |= TPM_CHIP_FLAG_BOOTSTRAPPED;602 603	return rc;604}605EXPORT_SYMBOL_GPL(tpm_chip_bootstrap);606 607/*608 * tpm_chip_register() - create a character device for the TPM chip609 * @chip: TPM chip to use.610 *611 * Creates a character device for the TPM chip and adds sysfs attributes for612 * the device. As the last step this function adds the chip to the list of TPM613 * chips available for in-kernel use.614 *615 * This function should be only called after the chip initialization is616 * complete.617 */618int tpm_chip_register(struct tpm_chip *chip)619{620	int rc;621 622	rc = tpm_chip_bootstrap(chip);623	if (rc)624		return rc;625 626	tpm_sysfs_add_device(chip);627 628	tpm_bios_log_setup(chip);629 630	tpm_add_ppi(chip);631 632	rc = tpm_add_hwrng(chip);633	if (rc)634		goto out_ppi;635 636	rc = tpm_add_char_device(chip);637	if (rc)638		goto out_hwrng;639 640	rc = tpm_add_legacy_sysfs(chip);641	if (rc) {642		tpm_chip_unregister(chip);643		return rc;644	}645 646	return 0;647 648out_hwrng:649	if (tpm_is_hwrng_enabled(chip))650		hwrng_unregister(&chip->hwrng);651out_ppi:652	tpm_bios_log_teardown(chip);653 654	return rc;655}656EXPORT_SYMBOL_GPL(tpm_chip_register);657 658/*659 * tpm_chip_unregister() - release the TPM driver660 * @chip: TPM chip to use.661 *662 * Takes the chip first away from the list of available TPM chips and then663 * cleans up all the resources reserved by tpm_chip_register().664 *665 * Once this function returns the driver call backs in 'op's will not be666 * running and will no longer start.667 *668 * NOTE: This function should be only called before deinitializing chip669 * resources.670 */671void tpm_chip_unregister(struct tpm_chip *chip)672{673#ifdef CONFIG_TCG_TPM2_HMAC674	int rc;675 676	rc = tpm_try_get_ops(chip);677	if (!rc) {678		tpm2_end_auth_session(chip);679		tpm_put_ops(chip);680	}681#endif682 683	tpm_del_legacy_sysfs(chip);684	if (tpm_is_hwrng_enabled(chip))685		hwrng_unregister(&chip->hwrng);686	tpm_bios_log_teardown(chip);687	if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip))688		tpm_devs_remove(chip);689	tpm_del_char_device(chip);690}691EXPORT_SYMBOL_GPL(tpm_chip_unregister);692