Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S967339AbdCXTeJ (ORCPT ); Fri, 24 Mar 2017 15:34:09 -0400 Received: from mail-sn1nam01on0054.outbound.protection.outlook.com ([104.47.32.54]:11399 "EHLO NAM01-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S967046AbdCXT34 (ORCPT ); Fri, 24 Mar 2017 15:29:56 -0400 Authentication-Results: spf=pass (sender IP is 149.199.60.83) smtp.mailfrom=xilinx.com; vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=bestguesspass action=none header.from=xilinx.com; From: Wendy Liang To: CC: , , "Wendy Liang" , Wendy Liang , Michal Simek Subject: [RFC LINUX PATCH 06/19] remoteproc: elf loader: Add get checksum firmware implementation Date: Fri, 24 Mar 2017 12:22:22 -0700 Message-ID: <1490383355-23176-7-git-send-email-jliang@xilinx.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490383355-23176-1-git-send-email-jliang@xilinx.com> References: <1490383355-23176-1-git-send-email-jliang@xilinx.com> X-RCIS-Action: ALLOW X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.1.0.1062-22962.005 X-TM-AS-User-Approved-Sender: Yes;Yes X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:149.199.60.83;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(39450400003)(39840400002)(39410400002)(39860400002)(39850400002)(2980300002)(438002)(199003)(189002)(9170700003)(48376002)(305945005)(356003)(6666003)(189998001)(2950100002)(50466002)(6916009)(5660300001)(2906002)(33646002)(36386004)(8936002)(2351001)(110136004)(8676002)(50986999)(36756003)(81166006)(107886003)(47776003)(50226002)(106466001)(5003940100001)(76176999)(77096006)(38730400002)(9786002)(54906002)(4326008)(107986001)(217873001);DIR:OUT;SFP:1101;SCL:1;SRVR:DM2PR02MB1385;H:xsj-pvapsmtpgw01;FPR:;SPF:Pass;MLV:sfv;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;CY1NAM02FT058;1:11qMb7J+78asuaDTf+Wq6C3J5PU+d9deTXYGVom3GJ5wbIBlFe1XOSohxpshshGGKjQsuu6uf7XLEFhEviv4IKN5+luMD45xVy4busNkfY+g+PACniNJSuOYoqL07cYgy/Yn64egNYb2mFXpwDGEOvHMuisUj3YCS7r+Xic74wlDeLi90MD2DcK1QEIs4UzA3HHxGl4VzoSlZWr4C6aKRvLo4+BnxPi76UOLtefgwSnb2lGXzmu3ohF/WTyNzSTAd94PFQSsbvgzLYVUmeNr7+HimPYbI0udBZcufya8lTC163lEPneiEoNa6qPI+QE7mCDFMazsHUdgskSleL84qQVkIjYVoyVafepUpVDUOUGkgKNcN9vdpT56teBApCZQPvPWADP00/Nwc3QjdxDOXEW5bYeTc3i3Wt1WNs3DqpHLx2GrZYFGud9+wCodjKVXHTm62JmqAjs5jvtMLHOpQxKcr22O5rsOCOm/SNmnfZjCpSTSbBNBBa2lqsPifEWTvTdugRgSU0UKHe9lNWsyFa76FhMBpkLYx+snT5mvYKSXiUTy6toPG0d+tFQZGIxsdftmK/p/B1sY3eADWRK8xw== MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 9b46e47c-7c63-4a4d-c0d1-08d472ec22da X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(8251501002)(2017030254075);SRVR:DM2PR02MB1385; X-Microsoft-Exchange-Diagnostics: 1;DM2PR02MB1385;3:QAbJ7TYvdzdTIbPg6HYLsHoDogx1OupPPVN4N2UlDCR2tXHK1Od8ZfXzgCxjhrcZ5OmRN3tE+j23Gn/jLUnN0pCa9hGxmUkFzKlq5dKpa+q75PGNj+1xGTPGGo4FEymBpEl3RJEZ27m9l+/hBYifFWHtnUudvb05eJE/gjw8xH/hpRagRQvbQ8kC90SbCOY24V8UFaQuSy1dqMgSYwTun2XwWWwWNUyYvBp5fArik7Z7AHKwatsvUwiSHxLQHlWo2oV6SwaJgGxXekYNwYtfXNAFuEMLothJwxqWER7Lf8VV9uUgoh9UAlC/iSzfSJj2axOm5z0Gty501kz3lSXmiJbjMwuQPdmovlu0xF3V8y3/rUa1iRno53RNlQ92VuZ6S0VzTl9/3BFyeNQuJ06KDwKzOPj4v9ZFpttuPx9nMJI=;25:a/9YghHkDv+gmqz5gFQ/BjtMgPNZAHKCWdexRNfNBk5QYGdeZrGwvyCuuBapRn7MIhKvWie5CmYvMKlhMIrXuOH8voJamIMnYzjGALCdUfZeeBJCDqe2THjmPS7OkjdbMdgLiSkriDF8csbK/po40t0hDSG3rboihCGAPD51iQdLDGE+E5jBdKNzOP3ZECzbsR5GubGTKVePQ93Mr5qDcsnoROpkSenR1u1IMN9puH5Mx3BNseAK/hV4KtjY87Lfy/nKQg4IC4+sGlolFn2wcw/ACPqV7Bd11cJzslbXCJ6VQCemRoyZ9BRyvSq+nqg9kGORlLc42ccggApHJ7RK1Tx+cekzjYBnBIsYYIdO836FNjaDJptZrzBI8HchY/EekpVfbKB6hLo+Rsr0n4QAccwqKeEaHPkM3gavLSEnqGgq3xZQgdQwBnT0V/K2AsxxGhEA4kDXXZZssA+uFNS8Gg== X-Microsoft-Exchange-Diagnostics: 1;DM2PR02MB1385;31:tkyVhYTivHEgOu34WVxcl3euYeOjovH+2J2B7oYGF75x39lZZhY2WXm1/nKz2YJXbdnluvyW/FieV2F/ezMAslsqwvWAx9rlujeyNVNBIDGWkbHROUhO/dIfHvMmlMn1Hn57mAv5GAb8muTIxeSUdmYTsb+wtrOQCjxrYtcI4yGYej4+VdiWDlMUEEneEckBXT7hqiS1VJfqucPb8sTxbBG60Dv15NQvgP9RNjw7x7sAgk5tKYrneUm6J9p9QxMiIRfyA9NWRvgL0CJL3RDsJg==;20:ps1TCM9amnEukrNkwZd93gUefmhWAty/kJe+8jwEU0ZiRFMIHKn47YVUcD6GzbvZ3Rr1Ecjkzt8xQ9yAUGIMy9cNVk6/ChMxAiYxAhOe3AUHPT/6Ip81IlsUCdVRqKMscWXHgMLE3EPErv06BTQCyrVqFh/XM88D3VI7f0gxotMK9GKNK7zFSBj+aKeG9s3yXDgAaAeY6AsuLZtXsZT0nfT1qAWA7doSoIDqgvawX5deh3Dr1iS9HqnsJ4f7Xuj4XphVc/Hh8UH0VHzKZN/3Up9q32o6Gbr/mHjOwWBf61h6JftDUW7Bccb5xwZB0jEqJ7SeEAjmWMS6SoGo/L1jH+7VDF+RViMudGb5rfwh2bDNDFvTI18xmGyxOa/7+qC48VI1aqRxZ09rj7OWtpavbO/3GUVn43IbIMfZvQaFjsY5uiy9iqShRn+KiCGO/KSJ3vdzIaXbTsK4NaUUhs27vA+X7c9waJv9VC6ZxxYyyP9GuoVLU/mgo010CxVH6PzL X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(192813158149592); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(13015025)(13024025)(5005006)(13018025)(13023025)(8121501046)(13017025)(10201501046)(3002001)(6055026)(6041248)(20161123564025)(20161123558025)(20161123562025)(20161123560025)(20161123555025)(6072148);SRVR:DM2PR02MB1385;BCL:0;PCL:0;RULEID:;SRVR:DM2PR02MB1385; X-Microsoft-Exchange-Diagnostics: 1;DM2PR02MB1385;4:0Abe2MGIq2TZRqWLT4h3aeaNNvXjTfREHn+a3hY9lY06uKDLjmqHpePID9iQun9KdmXQRSaATvsrdqiCJnWMpQLBDiN4Yf//fYD9zabRHms1bXBuc+zLfNOU6LLCtq2KK9MfxTDVOAbbio9fCLqYcUW5CZvnIaRR0JqOntkhuPZCx3H7XXRz5jpxN5KQSMu5IGWw72orbqP8QBfisM1Li9FO09Tjl8vpr4v8xE0tFsnBCkhWtLEyeCsx3lCKMnfwbYzq6UVP9wflrdRORZIrN8DfZg4PhqEV4VT6oe8zdpe6IHqq62i2Q9PuOuWcRyXjLBPOD78gxmbj1L9v9n6kfT4qJvIS2Z+3244bWk0X/whGSHpeFYqkPCAHcZ5D8U9C6YilJzT51OiSoBLkl6elHSa4AGiqjoVfb04b0aZOBUCJ0bGfX9WP9qDeOr4wkYrIeNA7+xOS1QRFTBShSw9XvwGZ4atJpfR4RzoOCNcTZb0kmWw++3PRzqjV/MVf1sveP/7YlNBXZRijcs6+IHNCzKG281+4v0MEGyobQR2ukK150qlG4WecAw8qQx6w1zbyDZoAv8t7NWcoI71UjSuxbrwxteyWzskiz0iRwBEXSk4au8UAozT8VGnhW6XK0I0xRZYDOzR836RYEwQ2olrgPuRId5EJx/Rd6LPFeaajMZVkdxR1iwUoECSBHsQpvY4EnYT5aYnFtenn4s9mGCOEttZ/wZb7SZhKIerhMzq5kE3F+KNjK7ELobhLWqRh/OE8xDUu9sX18EaEy8pHQpbgRA== X-Forefront-PRVS: 0256C18696 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DM2PR02MB1385;23:3Sgz7cC2krrt+sAUyHoKxNhlsNAjjxhukggt+xrYq?= =?us-ascii?Q?+E9xv7+lzjVLBKQriTimVvAT/TkHcIxown0lFvEap+YRyT78nBgXDibNqEuG?= =?us-ascii?Q?cuSseqAl4PNvIJ3tkk0Fu35Ck1wfdUTKpdkbQC5s+0s0ntegLFw80l7Skozt?= =?us-ascii?Q?xXQWPRlk8aqts0QOUnNoCH8K0O50kQ+yYejeGwGg8+BbOs1uD5UJEAZL5Xvj?= =?us-ascii?Q?WhB/lgVMNvO9bnzn4dOSyPTkZwfNK6OzzL/FyZIVS20Y+oFS5276CR0AFK0r?= =?us-ascii?Q?qxGMQECjD5/aeNW/UIgYD4jrPau+WEvuZkFWixn4oEcWjgRvTMqvoV/vcFnd?= =?us-ascii?Q?zk5JABXa9Pl4HCVHZI13eGN50n0PetGeP0ON9eupv6OUbSSswJj4112sF3gg?= =?us-ascii?Q?KLebQoCwLPu8Gark+n5bkrmJkvJtmVly1G8eQOi5HN1XaGaE086+JFTj0W8+?= =?us-ascii?Q?chr/wedwHXLd7bjZWCGcB5utqr5nCbytont7tFdFlpchv1IYZmOt5Pt/SMx1?= =?us-ascii?Q?nb7dU+Eq+UY3SsGKvP4HKKgOhQZTkx/MMz5KWhXaAUXn6XFxFWrNvNP9eVr0?= =?us-ascii?Q?5JhqkrpaH+FqEPQPLrQmznj+SXsxp8NShyqruDPsUHtUdT86D+8nKNdNka14?= =?us-ascii?Q?NEjV4iDcfYqSgKBXGgoBXYiEEAx7LKdZqAPia/jDwrpsCemcZcxCfoTuSCi+?= =?us-ascii?Q?V3j2Sewby6wVcdf217JzF2eZXW2bgiR31xpNCsXX8KJXma2M5Ikuey0cuyZv?= =?us-ascii?Q?HCen5nZYKWKCLszdW2ea02kW0FFuHQTCWppkBYW1/CAoFPBpV1xEIJKWBHDP?= =?us-ascii?Q?XxV7GwVYOGPCiViuxFSrJwrNkYgKJ0XiyGuYQLdpESsVjUgkUTeujjKKfCYn?= =?us-ascii?Q?Er8jy8VbKuJNQ3UDkkjRYyvO2bdGyibro+GAZEJPTpJwsKZHLPVZnFA8vzJ0?= =?us-ascii?Q?UyQDCqUNxf+gKpxWKy7SZ2TKr7x7Mx8I0Z+f03g1Y8uNX6E5gJaj1eL2/PkF?= =?us-ascii?Q?SHmecZr0VVNjd9BOfvYrF0pqnPQ1YDM65qggll7kXqnafSk2A/XcsemGfN+v?= =?us-ascii?Q?KafUDM6eQ2gQME8VqPFVzwP9XA0?= X-Microsoft-Exchange-Diagnostics: 1;DM2PR02MB1385;6:x4VDoLS+J1XOZUNyvcxesF9/tjpVzRiufa+RCwe9T9GFF+BYVWjauAUvBQM98hkLP89RcYuqZ47lF3q2V+/amG1lm7cByWRxVggzG+RYBIFszViN3iZ6BBy3lXOOqhb6eu0NzPBDXO9cTodnD6yyW2GxAI5cD+9hUznZRLM5eSQO10w8CVjxZ32cBvq0NRgNpvC8xg6nPoUq1ciZl7k2C6ZZiWuJHY07es1cmkNSxxz6k1m6s7LMC+pzWCceZTbC0TWCyrtBGHiG2sFoLlFA0FPvx9tqcLYlf+lqtovGt6reIabLJjl0txXOtYxkrrCqwzRK20eTxl7adizHJMaHOlYXYl7E3Ju1a+inHjTU6S06Makkkkust9PaC3fvHjxodIZmmPDdlOJi5K4TtYz+HeBiw2b8jicHREgIbZ6uimU=;5:x3l6HN1a2FdDqyyL+AN6bBTBqT+IQXU8tNqh7EqsPh9MRpEDxcUg/YoxqsxMXN/hKlKAf+8MBkblx7Y5QsgGGfUkOQ2rS0/1YtLDiF29KO885UjObn7C/McOuUZ04tXOQtj4U58GTqMvzSerldcLXQ==;24:6J03bGxKQDGG4rKqmicATW1wS83xQRmi5gApSJ/SFwit0YJ5ZmKGfv8GNGVHfWuwnUrjj0QpajawC62OmnZMhUb0NSv8IrKMErjiRKLiQG4= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;DM2PR02MB1385;7:DewY9STL1VPThjdeHhXV9lZUrnq4ZH4HEm1Uj/XSYHyYE6FgOod4oL1XXQ4l88uIFNm6DvKc+hQ6VPl11L8do0wLJgZfbB19xMQl1cG+bfHFkfGDTt/v/80RC7Tm5h64sQLxSiei9pV94qBsn9UmYILSO4YMv7XDWLXjT2DAYJ1pxPrXnHXE22WQBsXpL0+B8aBTbF7Mf0WhJchL6LJfx5HFBuZHDch7Y+i731wzJQjGPS3ULPYcSei1frM7I71lbUbvn6N0eK+0mOEd/U+0zcwRfV3yg0uacXQObNExb5rMqEGFyCJ1hf84fL4X7+gNjGV9f7H4/tMNFNIqolvbYA== X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Mar 2017 19:29:48.5411 (UTC) X-MS-Exchange-CrossTenant-Id: 657af505-d5df-48d0-8300-c31994686c5c X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=657af505-d5df-48d0-8300-c31994686c5c;Ip=[149.199.60.83];Helo=[xsj-pvapsmtpgw01] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM2PR02MB1385 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5479 Lines: 179 From: Wendy Liang Add get_chksum() implementation to calculate the checksum of the loadable sections of the firmware. Signed-off-by: Wendy Liang Signed-off-by: Michal Simek --- drivers/remoteproc/Kconfig | 1 + drivers/remoteproc/remoteproc_elf_loader.c | 109 +++++++++++++++++++++++++++++ drivers/remoteproc/remoteproc_internal.h | 3 + 3 files changed, 113 insertions(+) diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 65f86bc..d832f3b 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -7,6 +7,7 @@ config REMOTEPROC select FW_LOADER select VIRTIO select VIRTUALIZATION + select CRYPTO help Support for remote processors (such as DSP coprocessors). These are mainly used on embedded systems. diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c index c523983..f508083 100644 --- a/drivers/remoteproc/remoteproc_elf_loader.c +++ b/drivers/remoteproc/remoteproc_elf_loader.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "remoteproc_internal.h" @@ -328,10 +329,118 @@ u32 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw) return rproc_da_to_va(rproc, shdr->sh_addr, shdr->sh_size); } +/** + * rproc_elf_get_chksum() - calcuate checksum of the loadable section + * @rproc: the rproc handle + * @fw: the ELF firmware image + * @algo: name of the checksum algorithm + * @chksum: checksum + * @output_size: size of the checksum + * + * This function calculate the checksum of the loadable secitons + * of the specified firmware. + * + * Returns 0 for success, negative value for failure. + */ +static int +rproc_elf_get_chksum(struct rproc *rproc, const struct firmware *fw, + char *algo, u8 *chksum, int output_size) +{ + int ret, i; + struct device *dev = &rproc->dev; + struct crypto_shash *tfm; + struct shash_desc *desc; + int algo_len = 0; + struct elf32_hdr *ehdr; + struct elf32_phdr *phdr; + const u8 *elf_data = fw->data; + + memset(chksum, 0, output_size); + /* If no algo is specified, default it to "sha256" */ + if (!strlen(algo)) + sprintf(algo, "sha256"); + ret = crypto_has_alg(algo, 0, 0); + if (!ret) { + dev_err(dev, "failed to find crypto algo: %s.\n", algo); + return -EINVAL; + } + dev_dbg(dev, "firmware checksum algo: %s.\n", algo); + tfm = crypto_alloc_shash(algo, 0, 0); + if (!tfm) { + dev_err(dev, "failed to allocate shash.\n"); + return -ENOMEM; + } + algo_len = crypto_shash_digestsize(tfm); + if (algo_len > output_size) { + dev_err(dev, + "algo digest size %d is larger expected %d.\n", + algo_len, output_size); + return -EINVAL; + } + desc = kzalloc(sizeof(*desc) + algo_len, GFP_KERNEL); + if (!desc) + return -ENOMEM; + desc->tfm = tfm; + ret = crypto_shash_init(desc); + if (ret) { + dev_err(dev, "failed crypto %s initialization.\n", algo); + return ret; + } + + ehdr = (struct elf32_hdr *)elf_data; + phdr = (struct elf32_phdr *)(elf_data + ehdr->e_phoff); + + /* go through the available ELF segments */ + for (i = 0; i < ehdr->e_phnum; i++, phdr++) { + u32 memsz = phdr->p_memsz; + u32 filesz = phdr->p_filesz; + u32 offset = phdr->p_offset; + + if (phdr->p_type != PT_LOAD) + continue; + + if (filesz > memsz) { + dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n", + filesz, memsz); + ret = -EINVAL; + break; + } + + if (offset + filesz > fw->size) { + dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", + offset + filesz, fw->size); + ret = -EINVAL; + break; + } + + /* put the segment where the remote processor expects it */ + if (phdr->p_filesz) { + ret = crypto_shash_update(desc, + elf_data + offset, filesz); + if (ret) { + dev_err(dev, + "Failed to update fw crypto digest state at offset 0x%x, size 0x%x.\n", + offset, filesz); + return ret; + } + } + + } + ret = crypto_shash_final(desc, chksum); + crypto_free_shash(tfm); + kfree(desc); + if (ret) { + dev_err(dev, "failed to finalize checksum of firmware.\n"); + return ret; + } + return ret; +} + const struct rproc_fw_ops rproc_elf_fw_ops = { .load = rproc_elf_load_segments, .find_rsc_table = rproc_elf_find_rsc_table, .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table, .sanity_check = rproc_elf_sanity_check, + .get_chksum = rproc_elf_get_chksum, .get_boot_addr = rproc_elf_get_boot_addr }; diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h index 1e9e5b3..f03e07a 100644 --- a/drivers/remoteproc/remoteproc_internal.h +++ b/drivers/remoteproc/remoteproc_internal.h @@ -33,6 +33,7 @@ * expects to find it * @sanity_check: sanity check the fw image * @get_boot_addr: get boot address to entry point specified in firmware + * @get_chksum: get checksum of the loadable sections of the firmware */ struct rproc_fw_ops { struct resource_table *(*find_rsc_table)(struct rproc *rproc, @@ -43,6 +44,8 @@ struct rproc_fw_ops { int (*load)(struct rproc *rproc, const struct firmware *fw); int (*sanity_check)(struct rproc *rproc, const struct firmware *fw); u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw); + int (*get_chksum)(struct rproc *rproc, const struct firmware *fw, + char *algo, u8 *chksum, int output_size); }; /* from remoteproc_core.c */ -- 1.9.1