From patchwork Thu Feb 11 13:50:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulises Cardenas X-Patchwork-Id: 582072 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id EE191140BFC for ; Fri, 12 Feb 2016 10:36:48 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b=S7xVwtpa; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 21DBCA7508; Fri, 12 Feb 2016 00:36:46 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mtyKpCra_pn5; Fri, 12 Feb 2016 00:36:45 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 80943A74F1; Fri, 12 Feb 2016 00:36:45 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id EF394A74EE for ; Thu, 11 Feb 2016 21:49:44 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ZXTXEdXpA7xg for ; Thu, 11 Feb 2016 21:49:44 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from emea01-am1-obe.outbound.protection.outlook.com (mail-am1on0073.outbound.protection.outlook.com [157.56.112.73]) by theia.denx.de (Postfix) with ESMTPS id AE4AEA74DE for ; Thu, 11 Feb 2016 21:49:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=NXP1.onmicrosoft.com; s=selector1-nxp-com; h=From:To:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=RpJlI07yOdrmqxxRIGH9XI2RQ36WcZFDmVQ1BhlKCPg=; b=S7xVwtpaZ8OUz1vXrrghj8gWW+nbsgZ0pYzjL3ldVmd6VN54cjGWG5fMtfFcPAK9xkJo3LN6wKIddUaSqsFp2u13YQO3jJfeQFRMjFDmJzrOHZkiTp9L8fVcXrs4Mz3vMzaTj/hqAcUmBZzxtSr+T7YovgMWQ2YvrE7vD/6iNB8= Authentication-Results: ossystems.com.br; dkim=none (message not signed) header.d=none; ossystems.com.br; dmarc=none action=none header.from=nxp.com; Received: from archy.am.freescale.net (192.88.168.50) by AM2PR04MB0785.eurprd04.prod.outlook.com (2a01:111:e400:840b::25) with Microsoft SMTP Server (TLS) id 15.1.403.16; Thu, 11 Feb 2016 20:49:37 +0000 From: Ulises Cardenas To: Date: Thu, 11 Feb 2016 07:50:05 -0600 Message-ID: <1455198605-17320-1-git-send-email-raul.casas@nxp.com> X-Mailer: git-send-email 2.6.2 MIME-Version: 1.0 X-Originating-IP: [192.88.168.50] X-ClientProxiedBy: SN1PR17CA0006.namprd17.prod.outlook.com (2a01:111:e400:5bbf::16) To AM2PR04MB0785.eurprd04.prod.outlook.com (2a01:111:e400:840b::25) X-Microsoft-Exchange-Diagnostics: 1; AM2PR04MB0785; 2:k7emhGosArzlqPW1FeWtQC7tOOgv9Hy/XJA5TerJRSvhQfdAb/sXgY8m6C0eU/w1RTKRSAWlzV5EfmJpCCuVIT+sqIf7kiCGtzlMjORKLFgMihxGhpfvSl9ycC8vcItuIVVec1SUauIf+5yMK9sUMQ==; 3:KxI4DkMuJaeq34bj8njhIJL+gugfVUMiW0vizK3+2D6kCQk3HVAL+/Ms/xeOdwckPgDtuUsBa9d6pTBfvzc6JVB6l0Adb2q/oMSG+TP3Bn2y8C9zGYLXjRKCry+sYU9j; 25:mj6leqCtQQIIY/kKEX1cRpJwiiS7sPQ5SqP2Y5hkbxDGTXz85D5b9F09nOE8OwfKiwIdbykwIUJOvzClT5veXtEbwHLrHgYWm8fVjcJ8lJUMD8F1u5RPz7f/nQztzhBg1hjoy+3vbt0iilzCuMAfX0QVepeGZO9YfKTDlTLBtjWFbk6vSPHFT1UurdWRlUc9QfKAlHjrcup0AMKIoRO2/vHSLKfwYlbLNMjdYsqQQ1zOSPY6q1ViCzVQKUgdhEEUpsPV7NCWdKZu6Blm/+DL4PwebyFj7IOlEwplcwbwh0dOLzcTpmQorhOOPvpdrp84 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:AM2PR04MB0785; X-MS-Office365-Filtering-Correlation-Id: b8c8d5a7-7ad2-49e3-4873-08d33324dba8 X-Microsoft-Exchange-Diagnostics: 1; AM2PR04MB0785; 20:ztTZObKJpplIDYE0PI94IBpzcahpxDYVqCuZCQAHmE/147AOyRjC3xZpJLOGGDhhWPJzrJKquwOFBTUXZqLz/NY8gIj3FLr1JNIybApfWPw9ll4c/sUwF1svB8gGzqNi6p/0up4W6VCWBu1LJVB5s2TkdoH3GdeO5cKn1d3yXDeEmvcPpb3wcN2Q/qAEoYUqL0fmZMa0t6GVxaY4piE60E/7GZYgngOCBGFljfK++y71c8Glmc/fOnuCRK9kO9LndVr+o1LEs749PNQUEi7ziHTT/uicFmlxg691jN4tDq/CBWYPmpwcJq4RWzQbSPeqAV0yqtA9E4FNTOBh17P9TnF50tiSbWBASX77qZmCQiKMxm4wZuieyjzDdP67BZDIe6EiPAA68MZIDJCUqDCVeoo/EZ6PBulJIfgojGafqJQZXZVfZDOpTQJLD9Gn9wbrFbMkyayEPqRsQqn6/PLr20tJRf7gkWlbclLN2vL90RC51oXLKVVIY4xhunZkc1xR; 4:xiyqEjPmTCHczX1PipNl6WbWfFc4KBikFE2r1J1YANXB/FKEBDRQDGo51zzkDkYDkesrafgXnwVp47lhJryRRiWuFypYUzg5IIyhtBO79WbHn7XqH5zXmNl3+JVwkNpfJfhzotqkSJlJXo0ZstWS+vc3nNeIhPHE+MUe4QClaxahWS5khdt/UNMbXbKDktRSasyVbqi2uq6eFQsGF2o8j0FuRQn6ulp/kpZ2clG2+yU1cwjycaTGnJAWx8RsYIMZK1OsQmbsGOFkRZLyw/zT2Uf0FAY5/v0dQoFICS9s8h3mihx+KhEbNI1JQFMPi3b/JVxH13bemGh4NtqdasUq+xb7CTdekNjhKKCZKtjLrZ6ZGTlA8zUCvTwUkM9cqVEysFj1iqeTQDxbWNtpPYdUfYKrdv4yKhqyLkjomSvqp/4= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001); SRVR:AM2PR04MB0785; BCL:0; PCL:0; RULEID:; SRVR:AM2PR04MB0785; X-Forefront-PRVS: 08497C3D99 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(50986999)(86362001)(42186005)(5001960100002)(19580405001)(5008740100001)(48376002)(47776003)(87976001)(36756003)(33646002)(229853001)(6116002)(3846002)(19580395003)(66066001)(5003940100001)(586003)(2906002)(110136002)(122386002)(40100003)(189998001)(2351001)(92566002)(1096002)(50466002)(5004730100002)(4326007)(50226001)(42262002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM2PR04MB0785; H:archy.am.freescale.net; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; AM2PR04MB0785; 23:+X+N2OL0XKPuPyIktOseBdBjSQAiJP1rZt0ylxUPWdKRj3oIJE4bfS1JIZdFc0bA0b+YlC0xscCXV50F4gltsquIfeqsikULENhjQME2XSIPRoyfyxMVD1NMZL3X7Xhxub/FnexWUZ0V/NeH6fYDijgTFSzT73Z1OlcQVD8NHj/1muCh/6p+TFz3Xrvv67qfXi10W6+WauKmxLamvK/DbiKxH9kQrRb1U2g5TWKO4mMZX8VwKZPLekamu5uaYAiAQHDqOczy3cTaU3PAeOuMfLaKekgLpjNuoUkrqp1eLHlMomdTp/FhuiyWl1oeaDKYFyw6v0ov4f1fEFUnAPQ4pnSsrbpufBNhdEoxzFsZ8gQkmAxfcrhWE6PZ+U1OoIHez/5cGfORyFECxaN+iKGkSRypWSFhxnrx8LJgHKQ/i1Nl6WmIA7QOJa0ZJYq3nI6zMTEe8ngEDyODmY0fOOQTIgSiY0ujZeqsfKB7CXZRbVnKtYgYxJth5/RaU1EjkGAyoMqQpVgLBFqmDGcNFDWTGM2LnxhZDaKobtbU2jtWEfg+RdOHQ/gu4jzGeM8pKaAlphGT/7UPuHfXePnDSVBas53AtEDlAjSRXX4wLCvvEfqpXs0yqvU41MtHUEgJuuu7blXcK1AIeq2ETTMaDgU4VcjKur2vpHTBAgzT1YIKEVIkfSnDFMnK23FoRnVu9cO9gPGR/2ld8U3if+U6pDnCRq94pRoC7/kWAdULxuYp8KmuS3ElmxsPWiZZDSrLXHfdLncJbqsw3kDhHt07EHqCejZHE8VUc4viAizUsoeBC0CWatok0yfBrIQPTDexatJSo1HxXPR895akZy3mV0WFrqr6hlRaDs/BuBIl2WsbuxdZYUzVUlRnpzJnQzdW8NRt X-Microsoft-Exchange-Diagnostics: 1; AM2PR04MB0785; 5:SRXUbIwvI8VB+PEO3x0LhGLMxa4JBYrNM4NQSKzFWQXGV7OJiKnQ9EWuXQJc12ElvOmYvPtwoRYmTz2V1BukJnzRIIWpV+P9ycrpWK0G4ndXJJV3WSAIDjtdo1dWahjESwoaGv53zR2P0WYpBVdIdQ==; 24:+WRFjJT0MnL2ZQQT8zKuzcLX8fevU/d6r3px3bncxvPvOIfu6s+PBKsokk14B3XokoxE1+aXsP6WFga0rIjg9IwQfmPXaMcJ1FSBSJdFCX0= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Feb 2016 20:49:37.0668 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM2PR04MB0785 X-Mailman-Approved-At: Fri, 12 Feb 2016 00:36:43 +0100 Cc: raul.casas@nxp.com, nitin.garg@nxp.com, u-boot@lists.denx.de, dan.douglass@nxp.com, ruchika.gupta@nxp.com, fabio.estevam@nxp.com Subject: [U-Boot] [PATCH v3] imx: imx7 Support for Manufacturing Protection X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" i.MX7 has an a protection feature for Manufacturing process. This feature uses assymetric encryption to sign and verify authenticated software handled between parties. This command enables the use of such feature. The private key is unique and generated once per device. And it is stored in secure memory and only accessible by CAAM. Therefore, the public key generation and signature functions are the only functions available for the user. Command usage: Print the public key for the device. - mfgprot pubk Generates Signature over given data. - mfgprot sign Signed-off-by: Raul Ulises Cardenas --- Changes for v2: - removed genenerate_mppubk and generate_mpsign due to redundancy Changes for v3: - typo correction description - extended mfgprot command from an MPSing function example to a fully functional command, providing the ability of signing given data arch/arm/imx-common/Makefile | 1 + arch/arm/imx-common/cmd_mfgprot.c | 102 ++++++++++++++++ drivers/crypto/fsl/Makefile | 4 + drivers/crypto/fsl/fsl_mfgprot.c | 236 ++++++++++++++++++++++++++++++++++++++ include/fsl_sec.h | 45 +++++++- 5 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 arch/arm/imx-common/cmd_mfgprot.c create mode 100644 drivers/crypto/fsl/fsl_mfgprot.c diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile index e7190c3..8563150 100644 --- a/arch/arm/imx-common/Makefile +++ b/arch/arm/imx-common/Makefile @@ -22,6 +22,7 @@ ifeq ($(SOC),$(filter $(SOC),mx7)) obj-y += cpu.o obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o obj-$(CONFIG_SYSCOUNTER_TIMER) += syscounter.o +obj-$(CONFIG_CMD_MFGPROT) += cmd_mfgprot.o endif ifeq ($(SOC),$(filter $(SOC),mx6 mx7)) obj-y += cache.o init.o diff --git a/arch/arm/imx-common/cmd_mfgprot.c b/arch/arm/imx-common/cmd_mfgprot.c new file mode 100644 index 0000000..3a6e7cb --- /dev/null +++ b/arch/arm/imx-common/cmd_mfgprot.c @@ -0,0 +1,102 @@ +/* + * Copyright 2016 NXP Semiconductors. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Command for manufacturing protection + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/** + * do_mfgprot() - Handle the "mfgprogt" command-line command + * @cmdtp: Command data struct pointer + * @flag: Command flag + * @argc: Command-line argument count + * @argv: Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + */ +static int do_mfgprot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + uint32_t m_addr, dgst_addr, c_addr, d_addr; + u8 *m_ptr, *dgst_ptr, *c_ptr, *d_ptr; + int m_size; + int ret; + char *pubk, *sign, *sel; + + pubk = "pubk"; + sign = "sign"; + sel = argv[1]; + + ret = 0; + + /* Enable HAB clock */ + u32 jr_size = 4; + u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR + 0x102c); + if (out_jr_size != jr_size) { + hab_caam_clock_enable(1); + sec_init(); + } + + if (strcmp(sel, pubk) == 0) { + ret = gen_mppubk(); + } else if (strcmp(sel, sign) == 0) { + if (argc != 7) + return CMD_RET_USAGE; + + m_addr = simple_strtoul(argv[2], NULL, 16); + m_size = simple_strtoul(argv[3], NULL, 10); + dgst_addr = simple_strtoul(argv[4], NULL, 16); + c_addr = simple_strtoul(argv[5], NULL, 16); + d_addr = simple_strtoul(argv[6], NULL, 16); + + + m_ptr = map_physmem(m_addr, m_size, MAP_NOCACHE); + dgst_ptr = map_physmem(dgst_addr, HAB_MES_RESP_DGST_BYTES, + MAP_NOCACHE); + c_ptr = map_physmem(c_addr, HAB_ENG_MFG_PRVK_BYTES, + MAP_NOCACHE); + d_ptr = map_physmem(d_addr, HAB_ENG_MFG_PRVK_BYTES, + MAP_NOCACHE); + + memset(dgst_ptr, 0, HAB_MES_RESP_DGST_BYTES); + memset(c_ptr, 0, HAB_ENG_MFG_PRVK_BYTES); + memset(d_ptr, 0, HAB_ENG_MFG_PRVK_BYTES); + + ret = sign_mppubk(m_ptr, m_size, dgst_ptr, c_ptr, d_ptr); + } else { + return CMD_RET_USAGE; + } + + unmap_sysmem(m_ptr); + unmap_sysmem(dgst_ptr); + unmap_sysmem(c_ptr); + unmap_sysmem(d_ptr); + + return ret; +} + +/***************************************************/ +static char mfgprot_help_text[] = + "Usage:\n" + "Print the public key for Manufacturing Protection\n" + "\tmfgprot pubk\n" + "Generates a Manufacturing Protection signature\n" + "\tmfgprot sign "; + +U_BOOT_CMD( + mfgprot, 7, 1, do_mfgprot, + "Manufacturing Protection\n", + mfgprot_help_text +); diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile index fd736cf..6d6903b 100644 --- a/drivers/crypto/fsl/Makefile +++ b/drivers/crypto/fsl/Makefile @@ -8,3 +8,7 @@ obj-y += sec.o obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o obj-$(CONFIG_CMD_BLOB)$(CONFIG_CMD_DEKBLOB) += fsl_blob.o obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o + +ifdef CONFIG_MX7 +obj-$(CONFIG_CMD_MFGPROT) += fsl_mfgprot.o +endif diff --git a/drivers/crypto/fsl/fsl_mfgprot.c b/drivers/crypto/fsl/fsl_mfgprot.c new file mode 100644 index 0000000..fe89be7 --- /dev/null +++ b/drivers/crypto/fsl/fsl_mfgprot.c @@ -0,0 +1,236 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + */ + +#include +#include +#include +#include +#include "jobdesc.h" +#include "desc.h" +#include "jr.h" + +#define HAB_MASK(LBL) \ + ((((uint32_t)1 << (LBL##_WIDTH)) - 1) << (LBL##_SHIFT)) + +#define HAB_INSERT_BITS(val, LBL) \ + (((uint32_t)(val) << LBL##_SHIFT) & HAB_MASK(LBL)) + +/* Size of MFG descriptor */ +#define MFG_PUBK_DSC_WORDS 4 +#define MFG_SIGN_DSC_WORDS 8 + +/* Size of MFG protocol data block */ +#define MFG_PUBK_PDB_WORDS 2 +#define MFG_SIGN_PDB_WORDS 6 + +void mfg_build_sign_dsc(u32 *dsc_ptr, const u8 *m, int size, + u8 *dgst, u8 *c, u8 *d) +{ + u32 *dsc = dsc_ptr; + *dsc++ = (HAB_ENG_CAAM_CMD_JOBHDR + | HAB_INSERT_BITS( + MFG_SIGN_PDB_WORDS + 1, + HAB_ENG_CAAM_CMD_JOBHDR_START) + | MFG_SIGN_DSC_WORDS); + + /*** MFG PubK PDB ***/ + /* Curve */ + *dsc++ = HAB_INSERT_BITS(HAB_ENG_CAAM_MPPUBK_CSEL_P256, + HAB_ENG_CAAM_MPPUBK_CSEL); + /* Message Pointer */ + *dsc++ = (dma_addr_t)m; + + /* mes-resp Pointer */ + *dsc++ = (dma_addr_t)dgst; + + /* C Pointer */ + *dsc++ = (dma_addr_t)c; + + /* d Pointer */ + *dsc++ = (dma_addr_t)d; + + /* Message Size */ + *dsc++ = size; + + /* MP PubK generate key command */ + *dsc = HAB_ENG_CAAM_CMD_PROTOCOL_MPSIGN; +} + +void mfg_build_pubk_dsc(u32 *dsc_ptr, u8 *dst) +{ + u32 *dsc = dsc_ptr; + *dsc++ = (HAB_ENG_CAAM_CMD_JOBHDR + | HAB_INSERT_BITS( + MFG_PUBK_PDB_WORDS + 1, + HAB_ENG_CAAM_CMD_JOBHDR_START) + | MFG_PUBK_DSC_WORDS); + + /*** MFG PubK PDB ***/ + /* Curve */ + *dsc++ = HAB_INSERT_BITS(HAB_ENG_CAAM_MPPUBK_CSEL_P256, + HAB_ENG_CAAM_MPPUBK_CSEL); + /* Message Pointer */ + *dsc++ = (dma_addr_t)dst; + + /* MP PubK generate key command */ + *dsc = HAB_ENG_CAAM_CMD_PROTOCOL_MPPUBK; +} + +int gen_mppubk(void) +{ + int ret; + int size, i; + + u32 *dsc; + uint32_t dst_addr; + u8 *dst; + + /**************************************************************** + * Allocation & Initialization + ****************************************************************/ + ret = 0; + + /* Memory addresses for output */ + dst_addr = 0x80100000; + dst = map_physmem(dst_addr, HAB_ENG_MFG_PUBK_BYTES, MAP_NOCACHE); + memset(dst, 0, HAB_ENG_MFG_PUBK_BYTES); + + /**************************************************************** + * Job Descriptor initialization + ****************************************************************/ + dsc = memalign(ARCH_DMA_MINALIGN, + sizeof(uint32_t) * MFG_PUBK_DSC_WORDS); + if (!dsc) { + debug("Not enough memory for descriptor allocation\n"); + return -ENOMEM; + } + + mfg_build_pubk_dsc(dsc, dst); + + size = roundup(sizeof(uint32_t) * MFG_PUBK_DSC_WORDS, + ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)dsc, (unsigned long)dsc + size); + + size = roundup(HAB_ENG_MFG_PUBK_BYTES, ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)dst, (unsigned long)dst + size); + + /**************************************************************** + * Execute Job Descriptor + ****************************************************************/ + puts("\nGenerating Manufacturing Protection Public Key\n"); + + ret = run_descriptor_jr(dsc); + if (ret) { + debug("Error in public key generation %d\n", ret); + goto err; + } + + size = roundup(HAB_ENG_MFG_PUBK_BYTES, ARCH_DMA_MINALIGN); + invalidate_dcache_range((unsigned long)dst, (unsigned long)dst+size); + + /**************************************************************** + * Output results + ****************************************************************/ + puts("Public key:\n"); + for (i = 0; i < HAB_ENG_MFG_PUBK_BYTES; i++) + printf("%02X", ((u8 *)dst)[i]); + printf("\n"); + +err: + free(dsc); + unmap_sysmem(dst); + return ret; +} + +int sign_mppubk(const u8 *m, int data_size, u8 *dgst, u8 *c, u8 *d) +{ + int ret; + int size, i; + + u32 *dsc; + + /**************************************************************** + * Allocation & Initialization + ****************************************************************/ + ret = 0; + + memset(dgst, 0, HAB_MES_RESP_DGST_BYTES); + memset(d, 0, HAB_ENG_MFG_PRVK_BYTES); + memset(c, 0, HAB_ENG_MFG_PRVK_BYTES); + + /**************************************************************** + * Job Descriptor initialization + ****************************************************************/ + dsc = memalign(ARCH_DMA_MINALIGN, + sizeof(uint32_t) * MFG_SIGN_DSC_WORDS); + if (!dsc) { + debug("Not enough memory for descriptor allocation\n"); + return -ENOMEM; + } + + mfg_build_sign_dsc(dsc, m, data_size, dgst, c, d); + + size = roundup(sizeof(uint32_t) * MFG_SIGN_DSC_WORDS, + ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)dsc, (unsigned long)dsc + size); + + size = roundup(data_size, ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)m, (unsigned long)m + size); + + size = roundup(HAB_MES_RESP_DGST_BYTES, ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)dgst, (unsigned long)dgst + size); + + size = roundup(HAB_ENG_MFG_PRVK_BYTES, ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)c, (unsigned long)c + size); + flush_dcache_range((unsigned long)d, (unsigned long)d + size); + + /**************************************************************** + * Execute Job Descriptor + ****************************************************************/ + puts("\nSiging message with Manufacturing Protection Public Key\n"); + + ret = run_descriptor_jr(dsc); + if (ret) { + debug("Error in public key generation %d\n", ret); + goto err; + } + + size = roundup(HAB_MES_RESP_DGST_BYTES, ARCH_DMA_MINALIGN); + invalidate_dcache_range((unsigned long)dgst, (unsigned long)dgst+size); + + size = roundup(HAB_ENG_MFG_PRVK_BYTES, ARCH_DMA_MINALIGN); + invalidate_dcache_range((unsigned long)c, (unsigned long)c+size); + invalidate_dcache_range((unsigned long)d, (unsigned long)d+size); + + /**************************************************************** + * Output results + ****************************************************************/ + puts("Message: "); + for (i = 0; i < data_size; i++) + printf("%02X ", ((uint8_t *)m)[i]); + printf("\n"); + + puts("Message Representative Digest(SHA-256):\n"); + for (i = 0; i < HAB_MES_RESP_DGST_BYTES; i++) + printf("%02X", ((uint8_t *)dgst)[i]); + printf("\n"); + + puts("Signature:\n"); + puts("D:\n"); + for (i = 0; i < HAB_ENG_MFG_PRVK_BYTES; i++) + printf("%02X", ((uint8_t *)c)[i]); + printf("\n"); + + puts("d:\n"); + for (i = 0; i < HAB_ENG_MFG_PRVK_BYTES; i++) + printf("%02X", ((uint8_t *)d)[i]); + printf("\n"); + +err: + free(dsc); + return ret; +} diff --git a/include/fsl_sec.h b/include/fsl_sec.h index 2ddced3..6fe02e9 100644 --- a/include/fsl_sec.h +++ b/include/fsl_sec.h @@ -270,9 +270,33 @@ struct sg_entry { #define ERROR_IN_PAGE_ALLOC 1 #define ECONSTRJDESC -1 - #endif +#ifdef CONFIG_MX7 +/* Security level index in #mfg_curve */ +#define MFG_SEC_LVL_256 0 +#define MFG_SEC_LVL_384 1 +#define MFG_SEC_LVL_521 2 + +/* Job Descriptor Header command - add length in words */ +#define HAB_ENG_CAAM_CMD_JOBHDR 0xB0800000UL +#define HAB_ENG_CAAM_CMD_JOBHDR_START_SHIFT 16 /**< START INDEX field */ +#define HAB_ENG_CAAM_CMD_JOBHDR_START_WIDTH 6 /**< START INDEX field */ +#define HAB_ENG_CAAM_MPPUBK_SGF (1UL<<31) /**< Message SG flag */ +#define HAB_ENG_CAAM_MPPUBK_CSEL_SHIFT 17 /**< Curve selection */ +#define HAB_ENG_CAAM_MPPUBK_CSEL_WIDTH 4 /**< Curve selection */ +#define HAB_ENG_CAAM_MPPUBK_CSEL_P256 0x3 /**< P-256 */ +#define HAB_ENG_CAAM_MPPUBK_CSEL_P384 0x4 /**< P-384 */ +#define HAB_ENG_CAAM_MPPUBK_CSEL_P521 0x5 /**< P-521 */ + +/** PROTOCOL MPPubKGen command */ +#define HAB_ENG_CAAM_CMD_PROTOCOL_MPPUBK 0x86140000UL +#define HAB_ENG_CAAM_CMD_PROTOCOL_MPSIGN 0x86150000UL + +#define HAB_ENG_MFG_PUBK_BYTES 64 +#define HAB_ENG_MFG_PRVK_BYTES 32 +#define HAB_MES_RESP_DGST_BYTES 32 +#endif int sec_init(void); /* blob_dek: @@ -284,6 +308,25 @@ int sec_init(void); */ int blob_dek(const u8 *src, u8 *dst, u8 len); +/* + * gen_mpubk: + * Generates example of public key for manufacturing protection + */ +int gen_mppubk(void); + +/* + * sign_mpubk: + * Generates a manufacturing protection signature of the given + * data. + * @m: reference to data be signed + * @data_size: size of data to be signed + * @dgst_addr: address for the digest to be stored + * @c_addr: address for c to be stored + * @d_addr: address for d to be stored + * @return: 0 on success, error otherwise + * + */ +int sign_mppubk(const u8 *m, int data_size, u8 *dgst, u8 *c, u8 *d); #endif #endif /* __FSL_SEC_H */