From patchwork Tue Dec 3 05:46:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver O'Halloran X-Patchwork-Id: 1203530 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47Rrbh057lz9sPJ for ; Tue, 3 Dec 2019 16:47:28 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Cs8zdpy0"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 47Rrbg4bTtzDqPl for ; Tue, 3 Dec 2019 16:47:27 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::443; helo=mail-pf1-x443.google.com; envelope-from=oohall@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Cs8zdpy0"; dkim-atps=neutral Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 47RrZp5k8gzDqN1 for ; Tue, 3 Dec 2019 16:46:42 +1100 (AEDT) Received: by mail-pf1-x443.google.com with SMTP id s18so1274820pfm.4 for ; Mon, 02 Dec 2019 21:46:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1OpY9YmsOMGVd4cjzT7nMtjGosEDPlyY9T+5dziEbp0=; b=Cs8zdpy0UUhi/15+2S1HlH9bS224QMCbeeaN6zHukfTCgFsOyHaSt/2g2yOYOO+yyt IPn+nxpy+1q/guXm2/7hbFFutxQ455GW4cDxtxtSbWonkwqrXDXw7Y6F/iSTVZD9KvmC 50FxWYC/J8blDSMXfYLUiRsszSyeWkQCw5Yp+mcMOZVRYOQgxpSyfVhRnu2W2H4m8j1j iwxLruu/DJIetkxCIsB2mTX8P1l0i9UA3osJM9Qm1LSO227Sp1pTvViWt5CbhFP6OZLi 6tEiLFITTIH0APRWp8bXMih9lKnSEfZx1nNykAJhRNvaMG6W52SzyrxPDl+vPoBKPSmf Rfew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1OpY9YmsOMGVd4cjzT7nMtjGosEDPlyY9T+5dziEbp0=; b=Cn1JX6AoCOB2oTkZwjPjJIHN3se8SBBrhRoaKcjR1KbKB67sWcJRXgW5UaIITgwkTr Zu/X3F7n8tX4hFRNhrtzqiwPYC01CMUb6jE1GaHVfOpotFcBM+r9mPumLitCIarCCEhY y5sjH/TfDSmnfwtoKGdIbaC2J+S5yBTSpJnt1lAEb/MgYQ/vfj5sKEEzOwY0N0Gw1tZQ iZuKoXuJKZ7/E7ZeZPURrSlDgddpnm3RO25bIvbHLwLMZruOOuJr3xmM504LeN0ajh0Y GBHnyFblgwcTQLZsDjC1KHPx/rg1rjS4vrZEPpxjINTPNgnwsUvrewt8XDGs0r14zEHg 6pCQ== X-Gm-Message-State: APjAAAWOQ8heSjfwtOX5SCQllXzcB81RkgZOLjQ4RynhM1QPVANwjGMg Nkj/aCCstJp0gBzcvIzz9HcckvAk X-Google-Smtp-Source: APXvYqz4PjDEDw1hgPGiu7DRBwTH+0jhK/jY4Y6UgOGjtjrYATlvLsQ4HR/2rXmHi2qaSYG1+IcPAA== X-Received: by 2002:a62:154:: with SMTP id 81mr3055073pfb.126.1575351999940; Mon, 02 Dec 2019 21:46:39 -0800 (PST) Received: from wafer.ozlabs.ibm.com ([122.99.82.10]) by smtp.gmail.com with ESMTPSA id i9sm1602365pfk.24.2019.12.02.21.46.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2019 21:46:39 -0800 (PST) From: Oliver O'Halloran To: skiboot@lists.ozlabs.org Date: Tue, 3 Dec 2019 16:46:19 +1100 Message-Id: <20191203054619.20068-3-oohall@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191203054619.20068-1-oohall@gmail.com> References: <20191203054619.20068-1-oohall@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [PATCH 3/3] libstb/tpm: block access to unknown i2c devs on the tpm bus X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Our favourite TPM is capable of listening on multiple I2C bus addresses and although this feature is supposed to be disabled by default we have some systems in the wild where the TPM appears to be listening on these secondary addresses. The secondary addresses are also susceptible to the bus-lockup problem that we see with certain traffic patterns to the "main" TPM address. We don't know what addresses the TPM might be listening on it's best to take a conservitve approach and only allow traffic to I2C bus addresses that we are explicitly told about by firmware. This is only required on the TPM bus, so this patch extends the existing TPM workaround to also check that a DT node exists for any I2C bus address the OS wants to talk to. If there isn't one, we don't forward the I2C request to the bus and return an I2C timeout error to the OS. Signed-off-by: Oliver O'Halloran Acked-by: Stewart Smith --- libstb/drivers/tpm_i2c_nuvoton.c | 47 +++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/libstb/drivers/tpm_i2c_nuvoton.c b/libstb/drivers/tpm_i2c_nuvoton.c index ef32b79fd6f7..83ec1c81e485 100644 --- a/libstb/drivers/tpm_i2c_nuvoton.c +++ b/libstb/drivers/tpm_i2c_nuvoton.c @@ -493,12 +493,46 @@ static struct tpm_driver tpm_i2c_nuvoton_driver = { static int nuvoton_tpm_quirk(void *data, struct i2c_request *req, int *rc) { struct tpm_dev *tpm_device = data; + struct dt_node *dev; + uint16_t addr; + bool found; - /* If we're doing i2cdetect on the TPM, pretent we just NACKed - * it due to errata in nuvoton firmware where if we let this - * request go through, it would steal the bus and you'd end up - * in a nice world of pain. + /* + * The nuvoton TPM firmware has a problem where a single byte read or + * zero byte write to one of its I2C addresses causes the TPM to lock + * up the bus. Once locked up the bus can only be recovered by power + * cycling the TPM. Unfortunately, we don't have the ability to + * power cycle the TPM because allowing it to be reset at runtime + * would undermine the TPM's security model (we can reset it and + * send it whatever measurements we like to unlock it's secrets). + * So the best we can do here is try avoid triggering the problem + * in the first place. + * + * For a bit of added fun the TPM also appears to check for traffic + * on a few different I2C bus addresses. It does this even when not + * configured to respond on those addresses so you can trigger the + * bug by sending traffic... somwhere. To work around this we block + * sending I2C requests on the TPM's bus unless the DT explicitly + * tells us there is a device there. */ + + /* first, check if this a known address */ + addr = req->dev_addr; + found = false; + + dt_for_each_child(req->bus->dt_node, dev) { + if (dt_prop_get_u32(dev, "reg") == addr) { + found = true; + break; + } + } + + if (!found) { + *rc = OPAL_I2C_TIMEOUT; + return 1; + } + + /* second, check if it's a bad transaction to the TPM */ if (tpm_device->bus_id == req->bus->opal_id && tpm_device->i2c_addr == req->dev_addr && ((req->op == I2C_READ && req->rw_len == 1) || @@ -517,6 +551,7 @@ void tpm_i2c_nuvoton_probe(void) struct tpm_dev *tpm_device = NULL; struct dt_node *node = NULL; struct i2c_bus *bus; + const char *name; dt_for_each_compatible(dt_root, node, "nuvoton,npct650") { if (!dt_node_is_enabled(node)) @@ -562,6 +597,10 @@ void tpm_i2c_nuvoton_probe(void) assert(bus->check_quirk == NULL); bus->check_quirk = nuvoton_tpm_quirk; bus->check_quirk_data = tpm_device; + name = dt_prop_get(node, "ibm,port-name"); + + prlog(PR_NOTICE, "NUVOTON: TPM I2C workaround applied to %s\n", + name); /* * Tweak for linux. It doesn't have a driver compatible