summaryrefslogtreecommitdiffstats
path: root/ssl/ssl_cert.c
AgeCommit message (Expand)Author
2018-12-06Following the license change, modify the boilerplates in ssl/Richard Levitte
2018-11-12Separate ca_names handling for client and serverMatt Caswell
2018-11-10Unbreak SECLEVEL 3 regression causing it to not accept any ciphers.Tomas Mraz
2018-09-03Rename SSL[_CTX]_add1_CA_list -> SSL[_CTX]_add1_to_CA_listRichard Levitte
2018-08-22Allow TLS-1.3 ciphersuites in @SECLEVEL=3 and aboveTomas Mraz
2018-07-18Check that the public key OID matches the sig algMatt Caswell
2018-03-27Allow NULL for some _free routines.Rich Salz
2018-03-27Remove some code for a contributor that we cannot findMatt Caswell
2018-01-09Update copyright years on all files merged since Jan 1st 2018Richard Levitte
2018-01-08Avoid only exact duplicates when creating the accepted CA names listTomas Mraz
2017-12-07Consistent formatting for sizeof(foo)Rich Salz
2017-10-26Simplify the stack reservationPaul Yang
2017-10-20Various clean-upsKaoruToda
2017-10-18Remove parentheses of return.KaoruToda
2017-10-10crypto/x509v3/v3_utl.c, ssl/ssl_cert.c: fix Coverity problems.Andy Polyakov
2017-09-29Remove unnecessary #include <openssl/lhash.h> directives.Pauli
2017-09-28Add stack space reservations.Pauli
2017-08-30Move e_os.h to be the very first include.Pauli
2017-08-30Move the REF_PRINT support from e_os.h to internal/refcount.h.Pauli
2017-08-30e_os.h removal from other headers and source files.Pauli
2017-08-25NO_SYS_TYPES_H isn't defined anywhere, stop using it as a guardRichard Levitte
2017-07-13Move certificate table to header file so it can be tested.Dr. Stephen Henson
2017-07-13Add certificate properties table.Dr. Stephen Henson
2017-06-20Modify Sun copyright to follow OpenSSL styleRich Salz
2017-04-20Ignore dups in X509_STORE_add_*Rich Salz
2017-04-07Implement a new custom extensions APIMatt Caswell
2017-04-03Constify SSL_dup_CA_list()Dr. Stephen Henson
2017-04-03New certificate_authorities functionsDr. Stephen Henson
2017-03-16Remove obsolete version test when returning CA names.Dr. Stephen Henson
2017-02-24Tidy up certificate type handling.Dr. Stephen Henson
2017-02-10Replace SSL_PKEY_RSA_ENC, SSL_PKEY_RSA_SIGNDr. Stephen Henson
2017-01-10Convert Sigalgs processing to use intsMatt Caswell
2017-01-06Create Certificate messages in TLS1.3 formatMatt Caswell
2016-11-17Add support for reference counting using C11 atomicsKurt Roeckx
2016-09-20Style tweaks following review feedbackMatt Caswell
2016-09-20Convert Certificate message construction to WPACKETMatt Caswell
2016-08-18Indent ssl/Emilia Kasper
2016-07-19Change all our uses of CRYPTO_THREAD_run_once to use RUN_ONCE insteadRichard Levitte
2016-07-02Fix broken loading of client CAsAndreas Karlsson
2016-06-23Add checks on sk_TYPE_push() returned resultFdaSilvaYY
2016-05-27Fix ssl_cert_set0_chain invalid pointerTodd Short
2016-05-23Fix some malloc failure crashes on X509_STORE_CTX_set_ex_dataFdaSilvaYY
2016-05-17Copyright consolidation 01/10Rich Salz
2016-05-16Fold threads.h into crypto.h making API publicViktor Dukhovni
2016-04-28various spelling fixesFdaSilvaYY
2016-04-26Ensure we check i2d_X509 return valMatt Caswell
2016-04-15Make many X509_xxx types opaque.Rich Salz
2016-04-04Revert "various spelling fixes"Rich Salz
2016-04-04various spelling fixesFdaSilvaYY
2016-04-03Move peer chain security checks into x509_vfy.cViktor Dukhovni
' href='#n449'>449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2003-2019, Intel Corporation. All rights reserved.
 * Intel Management Engine Interface (Intel MEI) Linux driver
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/pci.h>
#include <linux/poll.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/sched.h>
#include <linux/uuid.h>
#include <linux/compat.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>

#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>

#include <linux/mei.h>

#include "mei_dev.h"
#include "client.h"
#include "hw-me-regs.h"
#include "hw-me.h"

/* mei_pci_tbl - PCI Device ID Table */
static const struct pci_device_id mei_me_pci_tbl[] = {
	{MEI_PCI_DEVICE(MEI_DEV_ID_82946GZ, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_82G35, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_82Q965, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_82G965, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_82GM965, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_82GME965, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82Q35, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82G33, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82Q33, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82X38, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_3200, MEI_ME_ICH_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_6, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_7, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_8, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_9, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_10, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_1, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_2, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_3, MEI_ME_ICH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_4, MEI_ME_ICH_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_1, MEI_ME_ICH10_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_2, MEI_ME_ICH10_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_3, MEI_ME_ICH10_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_4, MEI_ME_ICH10_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_1, MEI_ME_PCH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_2, MEI_ME_PCH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_CPT_1, MEI_ME_PCH_CPT_PBG_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_PBG_1, MEI_ME_PCH_CPT_PBG_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, MEI_ME_PCH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, MEI_ME_PCH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, MEI_ME_PCH_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, MEI_ME_PCH8_SPS_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, MEI_ME_PCH8_SPS_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, MEI_ME_PCH8_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, MEI_ME_PCH8_SPS_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, MEI_ME_PCH8_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, MEI_ME_PCH8_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT, MEI_ME_PCH8_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, MEI_ME_PCH8_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, MEI_ME_PCH8_SPS_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, MEI_ME_PCH8_SPS_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH12_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, MEI_ME_PCH8_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, MEI_ME_PCH8_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_DNV_IE, MEI_ME_PCH8_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_GLK, MEI_ME_PCH8_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_KBP, MEI_ME_PCH8_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, MEI_ME_PCH8_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP, MEI_ME_PCH12_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP_4, MEI_ME_PCH8_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH12_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_4, MEI_ME_PCH8_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)},

	{MEI_PCI_DEVICE(MEI_DEV_ID_MCC, MEI_ME_PCH12_CFG)},
	{MEI_PCI_DEVICE(MEI_DEV_ID_MCC_4, MEI_ME_PCH8_CFG)},

	/* required last entry */
	{0, }
};

MODULE_DEVICE_TABLE(pci, mei_me_pci_tbl);

#ifdef CONFIG_PM
static inline void mei_me_set_pm_domain(struct mei_device *dev);
static inline void mei_me_unset_pm_domain(struct mei_device *dev);
#else
static inline void mei_me_set_pm_domain(struct mei_device *dev) {}
static inline void mei_me_unset_pm_domain(struct mei_device *dev) {}
#endif /* CONFIG_PM */

/**
 * mei_me_quirk_probe - probe for devices that doesn't valid ME interface
 *
 * @pdev: PCI device structure
 * @cfg: per generation config
 *
 * Return: true if ME Interface is valid, false otherwise
 */
static bool mei_me_quirk_probe(struct pci_dev *pdev,
				const struct mei_cfg *cfg)
{
	if (cfg->quirk_probe && cfg->quirk_probe(pdev)) {
		dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
		return false;
	}

	return true;
}

/**
 * mei_me_probe - Device Initialization Routine
 *
 * @pdev: PCI device structure
 * @ent: entry in kcs_pci_tbl
 *
 * Return: 0 on success, <0 on failure.
 */
static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	const struct mei_cfg *cfg;
	struct mei_device *dev;
	struct mei_me_hw *hw;
	unsigned int irqflags;
	int err;

	cfg = mei_me_get_cfg(ent->driver_data);
	if (!cfg)
		return -ENODEV;

	if (!mei_me_quirk_probe(pdev, cfg))
		return -ENODEV;

	/* enable pci dev */
	err = pcim_enable_device(pdev);
	if (err) {
		dev_err(&pdev->dev, "failed to enable pci device.\n");
		goto end;
	}
	/* set PCI host mastering  */
	pci_set_master(pdev);
	/* pci request regions and mapping IO device memory for mei driver */
	err = pcim_iomap_regions(pdev, BIT(0), KBUILD_MODNAME);
	if (err) {
		dev_err(&pdev->dev, "failed to get pci regions.\n");
		goto end;
	}

	if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) ||
	    dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {

		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
		if (err)
			err = dma_set_coherent_mask(&pdev->dev,
						    DMA_BIT_MASK(32));
	}
	if (err) {
		dev_err(&pdev->dev, "No usable DMA configuration, aborting\n");
		goto end;
	}

	/* allocates and initializes the mei dev structure */
	dev = mei_me_dev_init(pdev, cfg);
	if (!dev) {
		err = -ENOMEM;
		goto end;
	}
	hw = to_me_hw(dev);
	hw->mem_addr = pcim_iomap_table(pdev)[0];

	pci_enable_msi(pdev);

	 /* request and enable interrupt */
	irqflags = pci_dev_msi_enabled(pdev) ? IRQF_ONESHOT : IRQF_SHARED;

	err = request_threaded_irq(pdev->irq,
			mei_me_irq_quick_handler,
			mei_me_irq_thread_handler,
			irqflags, KBUILD_MODNAME, dev);
	if (err) {
		dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
		       pdev->irq);
		goto end;
	}

	if (mei_start(dev)) {
		dev_err(&pdev->dev, "init hw failure.\n");
		err = -ENODEV;
		goto release_irq;
	}

	pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_ME_RPM_TIMEOUT);
	pm_runtime_use_autosuspend(&pdev->dev);

	err = mei_register(dev, &pdev->dev);
	if (err)
		goto stop;

	pci_set_drvdata(pdev, dev);

	/*
	 * MEI requires to resume from runtime suspend mode
	 * in order to perform link reset flow upon system suspend.
	 */
	dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP);

	/*
	 * ME maps runtime suspend/resume to D0i states,
	 * hence we need to go around native PCI runtime service which
	 * eventually brings the device into D3cold/hot state,
	 * but the mei device cannot wake up from D3 unlike from D0i3.
	 * To get around the PCI device native runtime pm,
	 * ME uses runtime pm domain handlers which take precedence
	 * over the driver's pm handlers.
	 */
	mei_me_set_pm_domain(dev);

	if (mei_pg_is_enabled(dev)) {
		pm_runtime_put_noidle(&pdev->dev);
		if (hw->d0i3_supported)
			pm_runtime_allow(&pdev->dev);
	}

	dev_dbg(&