From patchwork Mon Sep 3 14:47:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 965491 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="H0k1F+j6"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 423tRH1zNyz9s8F for ; Tue, 4 Sep 2018 00:59:39 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id EC560C21E62; Mon, 3 Sep 2018 14:56:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 1ECFCC21F16; Mon, 3 Sep 2018 14:48:10 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 30D87C21EA7; Mon, 3 Sep 2018 14:47:54 +0000 (UTC) Received: from mail-lf1-f68.google.com (mail-lf1-f68.google.com [209.85.167.68]) by lists.denx.de (Postfix) with ESMTPS id 23979C21EF0 for ; Mon, 3 Sep 2018 14:47:45 +0000 (UTC) Received: by mail-lf1-f68.google.com with SMTP id j8-v6so658312lfb.4 for ; Mon, 03 Sep 2018 07:47:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=XTd773w5P/Vj46SmIQFS3d5zP1Ly1I9xPhd1cY5R27M=; b=H0k1F+j6UZKmlcnquFAyZEfoW3mZRuy4fodoIw27XK4KitFaqnn9XE7mZ41YqT2/KZ d8WeItLOD69bym0z2/VhowRTmrRpz/z3JMfoDH5pE0mNAdwNBBn7kz9oXL9WFUSomlvG Hr1BGfdULiQUyRb4afM6St2MMbz/HeAjjUq9Q= 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; bh=XTd773w5P/Vj46SmIQFS3d5zP1Ly1I9xPhd1cY5R27M=; b=r949COjP71RqCOqdneBinsm5Kkpq3+Wk6QejYnCaR8SkMiIiN3qq3S51BAuo6LXSYY +qDpeU5lHUc9oIYQXNkbpfYD/R8eM3zHfydnst3HhU1YVBoS+Uoj/DCE/tP1FjXR1qXa +MsrwIiDBhP0aPJEhlQu3rkVvtlLf7dBjcNHHwwmHlPrZ5eFOl6pwQ827GaVN1D/ISGc qGm/wP0SsG5Ej6zxZyB/isAhQ/ftuRCuZBVGnqwGw75Ezifs9JmQtPcWQZNk4+xnJkPW E+UxRo74Jz/zFuZAjesamM1CFgfswe0Bb2o2S+L4jd7PAZL+FRXzo8sfEVVjMZZK9FPr R/0Q== X-Gm-Message-State: APzg51DPgi1u/06XvoYaaZkK2P/PpiXkVI/MuZwvj27AoOVpCzk8XTLX yOZ5HtqjJ26glVyw0w+/w4C5NSFdqUg= X-Google-Smtp-Source: ANB0VdbsK0kEnw8ffZzliZrGc4gPiZzkOswfDvj0n+9IacVjgq9JgT87sPlQBBohctA+TSQLyLU+rg== X-Received: by 2002:a19:3bd4:: with SMTP id d81-v6mr17052195lfl.96.1535986064258; Mon, 03 Sep 2018 07:47:44 -0700 (PDT) Received: from jax.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id w18-v6sm3343431ljd.73.2018.09.03.07.47.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Sep 2018 07:47:43 -0700 (PDT) From: Jens Wiklander To: u-boot@lists.denx.de Date: Mon, 3 Sep 2018 16:47:08 +0200 Message-Id: <20180903144711.31585-18-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180903144711.31585-1-jens.wiklander@linaro.org> References: <20180903144711.31585-1-jens.wiklander@linaro.org> Cc: Tom Rini , Pierre Aubert Subject: [U-Boot] [PATCH v3 17/20] avb_verify: support using OP-TEE TA AVB X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" With CONFIG_OPTEE_TA_AVB use the trusted application AVB provided by OP-TEE to manage rollback indexes and device lock status. Signed-off-by: Jens Wiklander Reviewed-by: Simon Glass --- common/avb_verify.c | 118 ++++++++++++++++++++++++++++++++++++++++++- doc/README.avb2 | 13 +++++ include/avb_verify.h | 4 ++ 3 files changed, 134 insertions(+), 1 deletion(-) diff --git a/common/avb_verify.c b/common/avb_verify.c index 3a1282a09204..c2248c92514e 100644 --- a/common/avb_verify.c +++ b/common/avb_verify.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include const unsigned char avb_root_pub[1032] = { 0x0, 0x0, 0x10, 0x0, 0x55, 0xd9, 0x4, 0xad, 0xd8, 0x4, @@ -594,6 +596,65 @@ static AvbIOResult validate_vbmeta_public_key(AvbOps *ops, return AVB_IO_RESULT_OK; } +#ifdef CONFIG_OPTEE_TA_AVB +static int get_open_session(struct AvbOpsData *ops_data) +{ + struct udevice *tee = NULL; + + while (!ops_data->tee) { + const struct tee_optee_ta_uuid uuid = TA_AVB_UUID; + struct tee_open_session_arg arg; + int rc; + + tee = tee_find_device(tee, NULL, NULL, NULL); + if (!tee) + return -ENODEV; + + memset(&arg, 0, sizeof(arg)); + tee_optee_ta_uuid_to_octets(arg.uuid, &uuid); + rc = tee_open_session(tee, &arg, 0, NULL); + if (!rc) { + ops_data->tee = tee; + ops_data->session = arg.session; + } + } + + return 0; +} + +static AvbIOResult invoke_func(struct AvbOpsData *ops_data, u32 func, + ulong num_param, struct tee_param *param) +{ + struct tee_invoke_arg arg; + + if (get_open_session(ops_data)) + return AVB_IO_RESULT_ERROR_IO; + + memset(&arg, 0, sizeof(arg)); + arg.func = func; + arg.session = ops_data->session; + + if (tee_invoke_func(ops_data->tee, &arg, num_param, param)) + return AVB_IO_RESULT_ERROR_IO; + switch (arg.ret) { + case TEE_SUCCESS: + return AVB_IO_RESULT_OK; + case TEE_ERROR_OUT_OF_MEMORY: + return AVB_IO_RESULT_ERROR_OOM; + case TEE_ERROR_TARGET_DEAD: + /* + * The TA has paniced, close the session to reload the TA + * for the next request. + */ + tee_close_session(ops_data->tee, ops_data->session); + ops_data->tee = NULL; + return AVB_IO_RESULT_ERROR_IO; + default: + return AVB_IO_RESULT_ERROR_IO; + } +} +#endif + /** * read_rollback_index() - gets the rollback index corresponding to the * location of given by @out_rollback_index. @@ -609,6 +670,7 @@ static AvbIOResult read_rollback_index(AvbOps *ops, size_t rollback_index_slot, u64 *out_rollback_index) { +#ifndef CONFIG_OPTEE_TA_AVB /* For now we always return 0 as the stored rollback index. */ printf("%s not supported yet\n", __func__); @@ -616,6 +678,27 @@ static AvbIOResult read_rollback_index(AvbOps *ops, *out_rollback_index = 0; return AVB_IO_RESULT_OK; +#else + AvbIOResult rc; + struct tee_param param[2]; + + if (rollback_index_slot >= TA_AVB_MAX_ROLLBACK_LOCATIONS) + return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE; + + memset(param, 0, sizeof(param)); + param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; + param[0].u.value.a = rollback_index_slot; + param[1].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT; + + rc = invoke_func(ops->user_data, TA_AVB_CMD_READ_ROLLBACK_INDEX, + ARRAY_SIZE(param), param); + if (rc) + return rc; + + *out_rollback_index = (u64)param[1].u.value.a << 32 | + (u32)param[1].u.value.b; + return AVB_IO_RESULT_OK; +#endif } /** @@ -633,10 +716,27 @@ static AvbIOResult write_rollback_index(AvbOps *ops, size_t rollback_index_slot, u64 rollback_index) { +#ifndef CONFIG_OPTEE_TA_AVB /* For now this is a no-op. */ printf("%s not supported yet\n", __func__); return AVB_IO_RESULT_OK; +#else + struct tee_param param[2]; + + if (rollback_index_slot >= TA_AVB_MAX_ROLLBACK_LOCATIONS) + return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE; + + memset(param, 0, sizeof(param)); + param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; + param[0].u.value.a = rollback_index_slot; + param[1].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; + param[1].u.value.a = (u32)(rollback_index >> 32); + param[1].u.value.b = (u32)rollback_index; + + return invoke_func(ops->user_data, TA_AVB_CMD_WRITE_ROLLBACK_INDEX, + ARRAY_SIZE(param), param); +#endif } /** @@ -652,6 +752,7 @@ static AvbIOResult write_rollback_index(AvbOps *ops, */ static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked) { +#ifndef CONFIG_OPTEE_TA_AVB /* For now we always return that the device is unlocked. */ printf("%s not supported yet\n", __func__); @@ -659,6 +760,16 @@ static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked) *out_is_unlocked = true; return AVB_IO_RESULT_OK; +#else + AvbIOResult rc; + struct tee_param param = { .attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT }; + + rc = invoke_func(ops->user_data, TA_AVB_CMD_READ_LOCK_STATE, 1, ¶m); + if (rc) + return rc; + *out_is_unlocked = !param.u.value.a; + return AVB_IO_RESULT_OK; +#endif } /** @@ -737,6 +848,11 @@ void avb_ops_free(AvbOps *ops) ops_data = ops->user_data; - if (ops_data) + if (ops_data) { +#ifdef CONFIG_OPTEE_TA_AVB + if (ops_data->tee) + tee_close_session(ops_data->tee, ops_data->session); +#endif avb_free(ops_data); + } } diff --git a/doc/README.avb2 b/doc/README.avb2 index 120279fedbe2..a29cee1b6f50 100644 --- a/doc/README.avb2 +++ b/doc/README.avb2 @@ -18,6 +18,13 @@ Integrity of the bootloader (U-boot BLOB and environment) is out of scope. For additional details check: https://android.googlesource.com/platform/external/avb/+/master/README.md +1.1. AVB using OP-TEE (optional) +--------------------------------- +If AVB is configured to use OP-TEE (see 4. below) rollback indexes and +device lock state are stored in RPMB. The RPMB partition is managed by +OP-TEE (https://www.op-tee.org/) which is a secure OS leveraging ARM +TrustZone. + 2. AVB 2.0 U-BOOT SHELL COMMANDS ----------------------------------- @@ -61,6 +68,12 @@ CONFIG_LIBAVB=y CONFIG_AVB_VERIFY=y CONFIG_CMD_AVB=y +In addtion optionally if storing rollback indexes in RPMB with help of +OP-TEE: +CONFIG_TEE=y +CONFIG_OPTEE=y +CONFIG_OPTEE_TA_AVB=y +CONFIG_SUPPORT_EMMC_RPMB=y Then add `avb verify` invocation to your android boot sequence of commands, e.g.: diff --git a/include/avb_verify.h b/include/avb_verify.h index eaa60f5393ef..a532a2331aea 100644 --- a/include/avb_verify.h +++ b/include/avb_verify.h @@ -27,6 +27,10 @@ struct AvbOpsData { struct AvbOps ops; int mmc_dev; enum avb_boot_state boot_state; +#ifdef CONFIG_OPTEE_TA_AVB + struct udevice *tee; + u32 session; +#endif }; struct mmc_part {