All of lore.kernel.org
 help / color / mirror / Atom feed
* [tegrarcm PATCH v2] Add support for production devices secured with PKC
@ 2016-02-29 17:49 Alban Bedel
       [not found] ` <1456768181-12983-1-git-send-email-alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Alban Bedel @ 2016-02-29 17:49 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA; +Cc: Alban Bedel

Add the support code needed to sign the RCM messages with RSA-PSS as
needed to communicate with secured production devices. This mode is
enabled by passing a key via the --pkc command line argument. If such
a key is set the RCM messages will be signed with it as well as the
bootloader.

Signed-off-by: Alban Bedel <alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
--
Changelog:
v2: * Added the missing bootloader signature
    * Added the ODM secure PKC mode to the supported operating modes
    * Renamed the --key option to --pkc to avoid potential ambiguities
      if SKB mode is ever supported.
    * Added a copyright header to the new files
---
 src/Makefile.am |   2 +
 src/main.c      |  51 ++++++++++++++++----
 src/rcm.c       |  20 ++++++--
 src/rcm.h       |   3 +-
 src/rsa-pss.cpp | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/rsa-pss.h   |  46 ++++++++++++++++++
 6 files changed, 256 insertions(+), 13 deletions(-)
 create mode 100644 src/rsa-pss.cpp
 create mode 100644 src/rsa-pss.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 4b54885..3dad0e6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,6 +8,8 @@ tegrarcm_SOURCES = \
 	nv3p.c \
 	debug.c \
 	rcm.c \
+	rsa-pss.cpp \
+	rsa-pss.h \
 	aes-cmac.cpp \
 	aes-cmac.h \
 	debug.h \
diff --git a/src/main.c b/src/main.c
index 3db0ed8..fedeab2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -44,6 +44,7 @@
 #include "nv3p.h"
 #include "nv3p_status.h"
 #include "aes-cmac.h"
+#include "rsa-pss.h"
 #include "rcm.h"
 #include "debug.h"
 #include "config.h"
@@ -60,7 +61,7 @@
 // tegra124 miniloader
 #include "miniloader/tegra124-miniloader.h"
 
-static int initialize_rcm(uint16_t devid, usb_device_t *usb);
+static int initialize_rcm(uint16_t devid, usb_device_t *usb, const char *keyfile);
 static int initialize_miniloader(uint16_t devid, usb_device_t *usb, char *mlfile, uint32_t mlentry);
 static int wait_status(nv3p_handle_t h3p);
 static int send_file(nv3p_handle_t h3p, const char *filename);
@@ -69,7 +70,8 @@ static int download_miniloader(usb_device_t *usb, uint8_t *miniloader,
 static void dump_platform_info(nv3p_platform_info_t *info);
 static int download_bct(nv3p_handle_t h3p, char *filename);
 static int download_bootloader(nv3p_handle_t h3p, char *filename,
-			       uint32_t entry, uint32_t loadaddr);
+			       uint32_t entry, uint32_t loadaddr,
+			       const char *pkc_keyfile);
 static int read_bct(nv3p_handle_t h3p, char *filename);
 
 enum cmdline_opts {
@@ -81,6 +83,7 @@ enum cmdline_opts {
 	OPT_VERSION,
 	OPT_MINILOADER,
 	OPT_MINIENTRY,
+	OPT_PKC,
 #ifdef HAVE_USB_PORT_MATCH
 	OPT_USBPORTPATH,
 #endif
@@ -123,6 +126,10 @@ static void usage(char *progname)
 	fprintf(stderr, "\t\tminiloader\n");
 	fprintf(stderr, "\t--miniloader_entry=<mlentry>\n");
 	fprintf(stderr, "\t\tSpecify the entry point for the miniloader\n");
+	fprintf(stderr, "\t--pkc=<key.ber>\n");
+	fprintf(stderr, "\t\tSpecify the key file for secured devices. The key should be\n");
+	fprintf(stderr, "\t\tin DER format\n");
+
 	fprintf(stderr, "\n");
 }
 
@@ -175,6 +182,7 @@ int main(int argc, char **argv)
 	int do_read = 0;
 	char *mlfile = NULL;
 	uint32_t mlentry = 0;
+	char *pkc = NULL;
 #ifdef HAVE_USB_PORT_MATCH
 	bool match_port = false;
 	uint8_t match_bus;
@@ -191,6 +199,7 @@ int main(int argc, char **argv)
 		[OPT_VERSION]    = {"version", 0, 0, 0},
 		[OPT_MINILOADER] = {"miniloader", 1, 0, 0},
 		[OPT_MINIENTRY]  = {"miniloader_entry", 1, 0, 0},
+		[OPT_PKC]        = {"pkc", 1, 0, 0},
 #ifdef HAVE_USB_PORT_MATCH
 		[OPT_USBPORTPATH]  = {"usb-port-path", 1, 0, 0},
 #endif
@@ -229,6 +238,9 @@ int main(int argc, char **argv)
 			case OPT_MINIENTRY:
 				mlentry = strtoul(optarg, NULL, 0);
 				break;
+			case OPT_PKC:
+				pkc = optarg;
+				break;
 #ifdef HAVE_USB_PORT_MATCH
 			case OPT_USBPORTPATH:
 				parse_usb_port_path(argv[0], optarg,
@@ -308,7 +320,7 @@ int main(int argc, char **argv)
 			error(1, errno, "USB read truncated");
 
 		// initialize rcm
-		ret2 = initialize_rcm(devid, usb);
+		ret2 = initialize_rcm(devid, usb, pkc);
 		if (ret2)
 			error(1, errno, "error initializing RCM protocol");
 
@@ -355,6 +367,7 @@ int main(int argc, char **argv)
 	if (info.op_mode != RCM_OP_MODE_DEVEL &&
 	    info.op_mode != RCM_OP_MODE_ODM_OPEN &&
 	    info.op_mode != RCM_OP_MODE_ODM_SECURE &&
+	    info.op_mode != RCM_OP_MODE_ODM_SECURE_PKC &&
 	    info.op_mode != RCM_OP_MODE_PRE_PRODUCTION)
 		error(1, ENODEV, "device is not in developer, open, secure, "
 		      "or pre-production mode, cannot flash");
@@ -366,7 +379,7 @@ int main(int argc, char **argv)
 	}
 
 	// download the bootloader
-	ret = download_bootloader(h3p, blfile, entryaddr, loadaddr);
+	ret = download_bootloader(h3p, blfile, entryaddr, loadaddr, pkc);
 	if (ret)
 		error(1, ret, "error downloading bootloader: %s", blfile);
 
@@ -376,7 +389,7 @@ int main(int argc, char **argv)
 	return 0;
 }
 
-static int initialize_rcm(uint16_t devid, usb_device_t *usb)
+static int initialize_rcm(uint16_t devid, usb_device_t *usb, const char *keyfile)
 {
 	int ret;
 	uint8_t *msg_buff;
@@ -388,13 +401,13 @@ static int initialize_rcm(uint16_t devid, usb_device_t *usb)
 	if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA20 ||
 	    (devid & 0xff) == USB_DEVID_NVIDIA_TEGRA30) {
 		dprintf("initializing RCM version 1\n");
-		ret = rcm_init(RCM_VERSION_1);
+		ret = rcm_init(RCM_VERSION_1, keyfile);
 	} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA114) {
 		dprintf("initializing RCM version 35\n");
-		ret = rcm_init(RCM_VERSION_35);
+		ret = rcm_init(RCM_VERSION_35, keyfile);
 	} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA124) {
 		dprintf("initializing RCM version 40\n");
-		ret = rcm_init(RCM_VERSION_40);
+		ret = rcm_init(RCM_VERSION_40, keyfile);
 	} else {
 		fprintf(stderr, "unknown tegra device: 0x%x\n", devid);
 		return errno;
@@ -720,6 +733,7 @@ static void dump_platform_info(nv3p_platform_info_t *info)
 	case RCM_OP_MODE_DEVEL:             op_mode = "developer mode"; break;
 	case RCM_OP_MODE_ODM_OPEN:          op_mode = "odm open mode"; break;
 	case RCM_OP_MODE_ODM_SECURE:        op_mode = "odm secure mode"; break;
+	case RCM_OP_MODE_ODM_SECURE_PKC:    op_mode = "odm secure mode with PKC"; break;
 	default:                            op_mode = "unknown"; break;
 	}
 	printf(" (%s)\n", op_mode);
@@ -813,7 +827,8 @@ out:
 }
 
 static int download_bootloader(nv3p_handle_t h3p, char *filename,
-			       uint32_t entry, uint32_t loadaddr)
+			       uint32_t entry, uint32_t loadaddr,
+			       const char *pkc_keyfile)
 {
 	int ret;
 	nv3p_cmd_dl_bl_t arg;
@@ -849,6 +864,24 @@ static int download_bootloader(nv3p_handle_t h3p, char *filename,
 		return ret;
 	}
 
+	// When using PKC the bootloader hash must be sent first
+	if (pkc_keyfile) {
+		uint8_t rsa_pss_sig[2048 / 8];
+
+		ret = rsa_pss_sign_file(pkc_keyfile, filename, rsa_pss_sig);
+		if (ret) {
+			dprintf("error signing %s with %s\n",
+				filename, pkc_keyfile);
+			return ret;
+		}
+
+		ret = nv3p_data_send(h3p, rsa_pss_sig, sizeof(rsa_pss_sig));
+		if (ret) {
+			dprintf("error sending bootloader signature\n");
+			return ret;
+		}
+	}
+
 	// send the bootloader file
 	ret = send_file(h3p, filename);
 	if (ret) {
diff --git a/src/rcm.c b/src/rcm.c
index cb53d8f..c7f0f8d 100644
--- a/src/rcm.c
+++ b/src/rcm.c
@@ -32,6 +32,7 @@
 #include <errno.h>
 #include "rcm.h"
 #include "aes-cmac.h"
+#include "rsa-pss.h"
 
 static int rcm_sign_msg(uint8_t *buf);
 static int rcm1_sign_msg(uint8_t *buf);
@@ -72,8 +73,9 @@ static uint32_t rcm_get_msg_buf_len(uint32_t payload_len);
 
 static uint32_t rcm_version = 0;
 static uint32_t message_size = 0;
+static const char *rcm_keyfile = NULL;
 
-int rcm_init(uint32_t version)
+int rcm_init(uint32_t version, const char *keyfile)
 {
 	int ret = -EINVAL;
 
@@ -92,6 +94,9 @@ int rcm_init(uint32_t version)
 		message_size = sizeof(rcm40_msg_t);
 		ret = 0;
 	}
+
+	rcm_keyfile = keyfile;
+
 	return ret;
 }
 
@@ -197,7 +202,11 @@ static int rcm35_sign_msg(uint8_t *buf)
 		return -EMSGSIZE;
 	}
 
-	cmac_hash(msg->reserved, crypto_len, msg->object_sig.cmac_hash);
+	if (rcm_keyfile)
+		rsa_pss_sign(rcm_keyfile, msg->reserved, crypto_len,
+			msg->object_sig.rsa_pss_sig, msg->modulus);
+	else
+		cmac_hash(msg->reserved, crypto_len, msg->object_sig.cmac_hash);
 	return 0;
 }
 
@@ -217,7 +226,12 @@ static int rcm40_sign_msg(uint8_t *buf)
 		return -EMSGSIZE;
 	}
 
-	cmac_hash(msg->reserved, crypto_len, msg->object_sig.cmac_hash);
+	if (rcm_keyfile)
+		rsa_pss_sign(rcm_keyfile, msg->reserved, crypto_len,
+			msg->object_sig.rsa_pss_sig, msg->modulus);
+	else
+		cmac_hash(msg->reserved, crypto_len, msg->object_sig.cmac_hash);
+
 	return 0;
 }
 
diff --git a/src/rcm.h b/src/rcm.h
index ab4bea2..fb371b3 100644
--- a/src/rcm.h
+++ b/src/rcm.h
@@ -109,8 +109,9 @@ typedef struct {
 #define RCM_OP_MODE_DEVEL           0x3
 #define RCM_OP_MODE_ODM_SECURE      0x4
 #define RCM_OP_MODE_ODM_OPEN        0x5
+#define RCM_OP_MODE_ODM_SECURE_PKC  0x6
 
-int rcm_init(uint32_t version);
+int rcm_init(uint32_t version, const char *keyfile);
 uint32_t rcm_get_msg_len(uint8_t *msg);
 int rcm_create_msg(
 	uint32_t opcode,
diff --git a/src/rsa-pss.cpp b/src/rsa-pss.cpp
new file mode 100644
index 0000000..d9aa8c6
--- /dev/null
+++ b/src/rsa-pss.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2015-1016, Avionic Design GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  * Neither the name of Avionic Design GmbH nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <iostream>
+using std::cout;
+using std::cerr;
+using std::endl;
+
+#include <iomanip>
+using std::hex;
+
+#include <string>
+using std::string;
+
+#include <cstdlib>
+using std::exit;
+
+#include "cryptlib.h"
+using CryptoPP::Exception;
+
+#include "integer.h"
+using CryptoPP::Integer;
+
+#include "files.h"
+using CryptoPP::FileSource;
+
+#include "filters.h"
+using CryptoPP::StringSink;
+using CryptoPP::SignerFilter;
+
+#include "queue.h"
+using CryptoPP::ByteQueue;
+
+#include "rsa.h"
+using CryptoPP::RSA;
+using CryptoPP::RSASS;
+
+#include "pssr.h"
+using CryptoPP::PSS;
+
+#include "sha.h"
+using CryptoPP::SHA256;
+
+#include "secblock.h"
+using CryptoPP::SecByteBlock;
+
+#include "osrng.h"
+using CryptoPP::AutoSeededRandomPool;
+
+#include "rsa-pss.h"
+
+extern "C" int rsa_pss_sign(const char *key_file, const unsigned char *msg,
+			int len, unsigned char *sig_buf, unsigned char *modulus_buf)
+{
+	try {
+		AutoSeededRandomPool rng;
+		FileSource file(key_file, true);
+		RSA::PrivateKey key;
+		ByteQueue bq;
+
+		// Load the key
+		file.TransferTo(bq);
+		bq.MessageEnd();
+		key.BERDecodePrivateKey(bq, false, bq.MaxRetrievable());
+
+		// Write the modulus
+		Integer mod = key.GetModulus();
+		for (int i = 0; i < mod.ByteCount(); i++)
+			modulus_buf[i] = mod.GetByte(i);
+
+		// Sign the message
+		RSASS<PSS, SHA256>::Signer signer(key);
+		size_t length = signer.MaxSignatureLength();
+		SecByteBlock signature(length);
+
+		length = signer.SignMessage(rng, msg, len, signature);
+
+		// Copy in reverse order
+		for (int i = 0; i < length; i++)
+			sig_buf[length - i - 1] = signature[i];
+	}
+	catch(const CryptoPP::Exception& e) {
+		cerr << e.what() << endl;
+		return 1;
+	}
+
+	return 0;
+}
+
+extern "C" int rsa_pss_sign_file(const char *key_file, const char *msg_file,
+			unsigned char *sig_buf)
+{
+	try {
+		AutoSeededRandomPool rng;
+		FileSource file(key_file, true);
+		RSA::PrivateKey key;
+		ByteQueue bq;
+
+		// Load the key
+		file.TransferTo(bq);
+		bq.MessageEnd();
+		key.BERDecodePrivateKey(bq, false, bq.MaxRetrievable());
+
+		// Sign the message
+		RSASS<PSS, SHA256>::Signer signer(key);
+		string signature;
+		FileSource src(msg_file, true,
+			new SignerFilter(rng, signer,
+					new StringSink(signature)));
+		int length = signature.length();
+
+		// Copy in reverse order
+		for (int i = 0; i < length; i++)
+			sig_buf[length - i - 1] = signature[i];
+	}
+	catch(const CryptoPP::Exception& e) {
+		cerr << e.what() << endl;
+		return 1;
+	}
+
+	return 0;
+}
diff --git a/src/rsa-pss.h b/src/rsa-pss.h
new file mode 100644
index 0000000..39e88c0
--- /dev/null
+++ b/src/rsa-pss.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015-1016, Avionic Design GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  * Neither the name of Avionic Design GmbH nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _RSA_PSS_H
+#define _RSA_PSS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int rsa_pss_sign(const char *key_file, const unsigned char *msg,
+		int len, unsigned char *sig_buf, unsigned char *modulus_buf);
+
+int rsa_pss_sign_file(const char *key_file, const char *msg_file,
+		unsigned char *sig_buf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _RSA_PSS_H
-- 
2.7.2

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: [tegrarcm PATCH v2] Add support for production devices secured with PKC
       [not found] ` <1456768181-12983-1-git-send-email-alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
@ 2016-02-29 23:03   ` Jimmy Zhang
       [not found]     ` <fbd256251e014b23a189337a7d251da0-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Jimmy Zhang @ 2016-02-29 23:03 UTC (permalink / raw)
  To: Alban Bedel, linux-tegra-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 19614 bytes --]

Alban,

First of all, I believe the code your added here should and will work. However, it is probably purely coincident that I was adding similar functions as requested by Avionic Design (AD) in the last a few weeks. I think we could merge both approaches and result in one best solution. 

The main differences between your and mine are:
1. When to sign.
    My solution is to separate signing and flashing. Ie, signing can be done at a secure server and flashing at non-secure factory. During flashing, only signed RCM messages and bootloader are needed. No pkc private key file is required to be present at factory. This private key management feature is also requested by AD. Your solution requires the rsa key file being present when downloading flasher.

    I will send you my complete solution in another email thread.  

2. How to sign
    When I was adding rsa signing supporting functions into cbootimage for t210, the consensus is not adding rsa signing code into cbootimage. Instead, we should utilize openssl.  So, we ended up a shell script that calls openssl, cbootimage and other utilities to sign a given bootimage. What was added into cbootimage are some new configuration options that take rsa key's modulus and signatures as file and embed them into bootimage. I saw you have expanded rsa supporting to T124. With TOT cbootimage, I can run the attached script to sign T124 bootimage.

    So, the solution I provided has no any rsa signing functions added into tegrarcm. Instead, use shell script to call openssl and modified tegrarcm to support for rsa signing.

     If my understanding is correct, the rsa signing functions you added here are only APIs. The actually signing are actually done by cryptlib. So, it is kind of in the middle. If everyone agrees, I am fine with it.


> -----Original Message-----
> From: linux-tegra-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org [mailto:linux-tegra-
> owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org] On Behalf Of Alban Bedel
> Sent: Monday, February 29, 2016 9:50 AM
> To: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: Alban Bedel
> Subject: [tegrarcm PATCH v2] Add support for production devices secured
> with PKC
> 
> Add the support code needed to sign the RCM messages with RSA-PSS as
> needed to communicate with secured production devices. This mode is
> enabled by passing a key via the --pkc command line argument. If such a key
> is set the RCM messages will be signed with it as well as the bootloader.
> 
> Signed-off-by: Alban Bedel <alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
> --
> Changelog:
> v2: * Added the missing bootloader signature
>     * Added the ODM secure PKC mode to the supported operating modes
>     * Renamed the --key option to --pkc to avoid potential ambiguities
>       if SKB mode is ever supported.
>     * Added a copyright header to the new files
> ---
>  src/Makefile.am |   2 +
>  src/main.c      |  51 ++++++++++++++++----
>  src/rcm.c       |  20 ++++++--
>  src/rcm.h       |   3 +-
>  src/rsa-pss.cpp | 147
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/rsa-pss.h   |  46 ++++++++++++++++++
>  6 files changed, 256 insertions(+), 13 deletions(-)  create mode 100644
> src/rsa-pss.cpp  create mode 100644 src/rsa-pss.h
> 
> diff --git a/src/Makefile.am b/src/Makefile.am index 4b54885..3dad0e6
> 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -8,6 +8,8 @@ tegrarcm_SOURCES = \
>  	nv3p.c \
>  	debug.c \
>  	rcm.c \
> +	rsa-pss.cpp \
> +	rsa-pss.h \
>  	aes-cmac.cpp \
>  	aes-cmac.h \
>  	debug.h \
> diff --git a/src/main.c b/src/main.c
> index 3db0ed8..fedeab2 100644
> --- a/src/main.c
> +++ b/src/main.c
> @@ -44,6 +44,7 @@
>  #include "nv3p.h"
>  #include "nv3p_status.h"
>  #include "aes-cmac.h"
> +#include "rsa-pss.h"
>  #include "rcm.h"
>  #include "debug.h"
>  #include "config.h"
> @@ -60,7 +61,7 @@
>  // tegra124 miniloader
>  #include "miniloader/tegra124-miniloader.h"
> 
> -static int initialize_rcm(uint16_t devid, usb_device_t *usb);
> +static int initialize_rcm(uint16_t devid, usb_device_t *usb, const char
> +*keyfile);
>  static int initialize_miniloader(uint16_t devid, usb_device_t *usb, char
> *mlfile, uint32_t mlentry);  static int wait_status(nv3p_handle_t h3p);  static
> int send_file(nv3p_handle_t h3p, const char *filename); @@ -69,7 +70,8 @@
> static int download_miniloader(usb_device_t *usb, uint8_t *miniloader,
> static void dump_platform_info(nv3p_platform_info_t *info);  static int
> download_bct(nv3p_handle_t h3p, char *filename);  static int
> download_bootloader(nv3p_handle_t h3p, char *filename,
> -			       uint32_t entry, uint32_t loadaddr);
> +			       uint32_t entry, uint32_t loadaddr,
> +			       const char *pkc_keyfile);
>  static int read_bct(nv3p_handle_t h3p, char *filename);
> 
>  enum cmdline_opts {
> @@ -81,6 +83,7 @@ enum cmdline_opts {
>  	OPT_VERSION,
>  	OPT_MINILOADER,
>  	OPT_MINIENTRY,
> +	OPT_PKC,
>  #ifdef HAVE_USB_PORT_MATCH
>  	OPT_USBPORTPATH,
>  #endif
> @@ -123,6 +126,10 @@ static void usage(char *progname)
>  	fprintf(stderr, "\t\tminiloader\n");
>  	fprintf(stderr, "\t--miniloader_entry=<mlentry>\n");
>  	fprintf(stderr, "\t\tSpecify the entry point for the miniloader\n");
> +	fprintf(stderr, "\t--pkc=<key.ber>\n");
> +	fprintf(stderr, "\t\tSpecify the key file for secured devices. The key
> should be\n");
> +	fprintf(stderr, "\t\tin DER format\n");
> +
>  	fprintf(stderr, "\n");
>  }
> 
> @@ -175,6 +182,7 @@ int main(int argc, char **argv)
>  	int do_read = 0;
>  	char *mlfile = NULL;
>  	uint32_t mlentry = 0;
> +	char *pkc = NULL;
>  #ifdef HAVE_USB_PORT_MATCH
>  	bool match_port = false;
>  	uint8_t match_bus;
> @@ -191,6 +199,7 @@ int main(int argc, char **argv)
>  		[OPT_VERSION]    = {"version", 0, 0, 0},
>  		[OPT_MINILOADER] = {"miniloader", 1, 0, 0},
>  		[OPT_MINIENTRY]  = {"miniloader_entry", 1, 0, 0},
> +		[OPT_PKC]        = {"pkc", 1, 0, 0},
>  #ifdef HAVE_USB_PORT_MATCH
>  		[OPT_USBPORTPATH]  = {"usb-port-path", 1, 0, 0},  #endif
> @@ -229,6 +238,9 @@ int main(int argc, char **argv)
>  			case OPT_MINIENTRY:
>  				mlentry = strtoul(optarg, NULL, 0);
>  				break;
> +			case OPT_PKC:
> +				pkc = optarg;
> +				break;
>  #ifdef HAVE_USB_PORT_MATCH
>  			case OPT_USBPORTPATH:
>  				parse_usb_port_path(argv[0], optarg, @@ -
> 308,7 +320,7 @@ int main(int argc, char **argv)
>  			error(1, errno, "USB read truncated");
> 
>  		// initialize rcm
> -		ret2 = initialize_rcm(devid, usb);
> +		ret2 = initialize_rcm(devid, usb, pkc);
>  		if (ret2)
>  			error(1, errno, "error initializing RCM protocol");
> 
> @@ -355,6 +367,7 @@ int main(int argc, char **argv)
>  	if (info.op_mode != RCM_OP_MODE_DEVEL &&
>  	    info.op_mode != RCM_OP_MODE_ODM_OPEN &&
>  	    info.op_mode != RCM_OP_MODE_ODM_SECURE &&
> +	    info.op_mode != RCM_OP_MODE_ODM_SECURE_PKC &&
>  	    info.op_mode != RCM_OP_MODE_PRE_PRODUCTION)
>  		error(1, ENODEV, "device is not in developer, open, secure, "
>  		      "or pre-production mode, cannot flash"); @@ -366,7
> +379,7 @@ int main(int argc, char **argv)
>  	}
> 
>  	// download the bootloader
> -	ret = download_bootloader(h3p, blfile, entryaddr, loadaddr);
> +	ret = download_bootloader(h3p, blfile, entryaddr, loadaddr, pkc);
>  	if (ret)
>  		error(1, ret, "error downloading bootloader: %s", blfile);
> 
> @@ -376,7 +389,7 @@ int main(int argc, char **argv)
>  	return 0;
>  }
> 
> -static int initialize_rcm(uint16_t devid, usb_device_t *usb)
> +static int initialize_rcm(uint16_t devid, usb_device_t *usb, const char
> +*keyfile)
>  {
>  	int ret;
>  	uint8_t *msg_buff;
> @@ -388,13 +401,13 @@ static int initialize_rcm(uint16_t devid,
> usb_device_t *usb)
>  	if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA20 ||
>  	    (devid & 0xff) == USB_DEVID_NVIDIA_TEGRA30) {
>  		dprintf("initializing RCM version 1\n");
> -		ret = rcm_init(RCM_VERSION_1);
> +		ret = rcm_init(RCM_VERSION_1, keyfile);
>  	} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA114) {
>  		dprintf("initializing RCM version 35\n");
> -		ret = rcm_init(RCM_VERSION_35);
> +		ret = rcm_init(RCM_VERSION_35, keyfile);
>  	} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA124) {
>  		dprintf("initializing RCM version 40\n");
> -		ret = rcm_init(RCM_VERSION_40);
> +		ret = rcm_init(RCM_VERSION_40, keyfile);
>  	} else {
>  		fprintf(stderr, "unknown tegra device: 0x%x\n", devid);
>  		return errno;
> @@ -720,6 +733,7 @@ static void
> dump_platform_info(nv3p_platform_info_t *info)
>  	case RCM_OP_MODE_DEVEL:             op_mode = "developer mode";
> break;
>  	case RCM_OP_MODE_ODM_OPEN:          op_mode = "odm open
> mode"; break;
>  	case RCM_OP_MODE_ODM_SECURE:        op_mode = "odm secure
> mode"; break;
> +	case RCM_OP_MODE_ODM_SECURE_PKC:    op_mode = "odm
> secure mode with PKC"; break;
>  	default:                            op_mode = "unknown"; break;
>  	}
>  	printf(" (%s)\n", op_mode);
> @@ -813,7 +827,8 @@ out:
>  }
> 
>  static int download_bootloader(nv3p_handle_t h3p, char *filename,
> -			       uint32_t entry, uint32_t loadaddr)
> +			       uint32_t entry, uint32_t loadaddr,
> +			       const char *pkc_keyfile)
>  {
>  	int ret;
>  	nv3p_cmd_dl_bl_t arg;
> @@ -849,6 +864,24 @@ static int download_bootloader(nv3p_handle_t h3p,
> char *filename,
>  		return ret;
>  	}
> 
> +	// When using PKC the bootloader hash must be sent first
> +	if (pkc_keyfile) {
> +		uint8_t rsa_pss_sig[2048 / 8];
> +
> +		ret = rsa_pss_sign_file(pkc_keyfile, filename, rsa_pss_sig);
> +		if (ret) {
> +			dprintf("error signing %s with %s\n",
> +				filename, pkc_keyfile);
> +			return ret;
> +		}
> +
> +		ret = nv3p_data_send(h3p, rsa_pss_sig, sizeof(rsa_pss_sig));
> +		if (ret) {
> +			dprintf("error sending bootloader signature\n");
> +			return ret;
> +		}
> +	}
> +
>  	// send the bootloader file
>  	ret = send_file(h3p, filename);
>  	if (ret) {
> diff --git a/src/rcm.c b/src/rcm.c
> index cb53d8f..c7f0f8d 100644
> --- a/src/rcm.c
> +++ b/src/rcm.c
> @@ -32,6 +32,7 @@
>  #include <errno.h>
>  #include "rcm.h"
>  #include "aes-cmac.h"
> +#include "rsa-pss.h"
> 
>  static int rcm_sign_msg(uint8_t *buf);
>  static int rcm1_sign_msg(uint8_t *buf); @@ -72,8 +73,9 @@ static uint32_t
> rcm_get_msg_buf_len(uint32_t payload_len);
> 
>  static uint32_t rcm_version = 0;
>  static uint32_t message_size = 0;
> +static const char *rcm_keyfile = NULL;
> 
> -int rcm_init(uint32_t version)
> +int rcm_init(uint32_t version, const char *keyfile)
>  {
>  	int ret = -EINVAL;
> 
> @@ -92,6 +94,9 @@ int rcm_init(uint32_t version)
>  		message_size = sizeof(rcm40_msg_t);
>  		ret = 0;
>  	}
> +
> +	rcm_keyfile = keyfile;
> +
>  	return ret;
>  }
> 
> @@ -197,7 +202,11 @@ static int rcm35_sign_msg(uint8_t *buf)
>  		return -EMSGSIZE;
>  	}
> 
> -	cmac_hash(msg->reserved, crypto_len, msg-
> >object_sig.cmac_hash);
> +	if (rcm_keyfile)
> +		rsa_pss_sign(rcm_keyfile, msg->reserved, crypto_len,
> +			msg->object_sig.rsa_pss_sig, msg->modulus);
> +	else
> +		cmac_hash(msg->reserved, crypto_len, msg-
> >object_sig.cmac_hash);
>  	return 0;
>  }
> 
> @@ -217,7 +226,12 @@ static int rcm40_sign_msg(uint8_t *buf)
>  		return -EMSGSIZE;
>  	}
> 
> -	cmac_hash(msg->reserved, crypto_len, msg-
> >object_sig.cmac_hash);
> +	if (rcm_keyfile)
> +		rsa_pss_sign(rcm_keyfile, msg->reserved, crypto_len,
> +			msg->object_sig.rsa_pss_sig, msg->modulus);
> +	else
> +		cmac_hash(msg->reserved, crypto_len, msg-
> >object_sig.cmac_hash);
> +
>  	return 0;
>  }
> 
> diff --git a/src/rcm.h b/src/rcm.h
> index ab4bea2..fb371b3 100644
> --- a/src/rcm.h
> +++ b/src/rcm.h
> @@ -109,8 +109,9 @@ typedef struct {
>  #define RCM_OP_MODE_DEVEL           0x3
>  #define RCM_OP_MODE_ODM_SECURE      0x4
>  #define RCM_OP_MODE_ODM_OPEN        0x5
> +#define RCM_OP_MODE_ODM_SECURE_PKC  0x6
> 
> -int rcm_init(uint32_t version);
> +int rcm_init(uint32_t version, const char *keyfile);
>  uint32_t rcm_get_msg_len(uint8_t *msg);  int rcm_create_msg(
>  	uint32_t opcode,
> diff --git a/src/rsa-pss.cpp b/src/rsa-pss.cpp new file mode 100644 index
> 0000000..d9aa8c6
> --- /dev/null
> +++ b/src/rsa-pss.cpp
> @@ -0,0 +1,147 @@
> +/*
> + * Copyright (c) 2015-1016, Avionic Design GmbH
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *  * Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *  * Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *  * Neither the name of Avionic Design GmbH nor the names of its
> + *    contributors may be used to endorse or promote products derived
> + *    from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND
> ANY
> + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> PARTICULAR
> + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
> OR
> + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> +SPECIAL,
> + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> LIMITED TO,
> + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> DATA, OR
> + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> THEORY
> + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE
> +USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> DAMAGE.
> + */
> +#include <iostream>
> +using std::cout;
> +using std::cerr;
> +using std::endl;
> +
> +#include <iomanip>
> +using std::hex;
> +
> +#include <string>
> +using std::string;
> +
> +#include <cstdlib>
> +using std::exit;
> +
> +#include "cryptlib.h"
> +using CryptoPP::Exception;
> +
> +#include "integer.h"
> +using CryptoPP::Integer;
> +
> +#include "files.h"
> +using CryptoPP::FileSource;
> +
> +#include "filters.h"
> +using CryptoPP::StringSink;
> +using CryptoPP::SignerFilter;
> +
> +#include "queue.h"
> +using CryptoPP::ByteQueue;
> +
> +#include "rsa.h"
> +using CryptoPP::RSA;
> +using CryptoPP::RSASS;
> +
> +#include "pssr.h"
> +using CryptoPP::PSS;
> +
> +#include "sha.h"
> +using CryptoPP::SHA256;
> +
> +#include "secblock.h"
> +using CryptoPP::SecByteBlock;
> +
> +#include "osrng.h"
> +using CryptoPP::AutoSeededRandomPool;
> +
> +#include "rsa-pss.h"
> +
> +extern "C" int rsa_pss_sign(const char *key_file, const unsigned char *msg,
> +			int len, unsigned char *sig_buf, unsigned char
> *modulus_buf) {
> +	try {
> +		AutoSeededRandomPool rng;
> +		FileSource file(key_file, true);
> +		RSA::PrivateKey key;
> +		ByteQueue bq;
> +
> +		// Load the key
> +		file.TransferTo(bq);
> +		bq.MessageEnd();
> +		key.BERDecodePrivateKey(bq, false, bq.MaxRetrievable());
> +
> +		// Write the modulus
> +		Integer mod = key.GetModulus();
> +		for (int i = 0; i < mod.ByteCount(); i++)
> +			modulus_buf[i] = mod.GetByte(i);
> +
> +		// Sign the message
> +		RSASS<PSS, SHA256>::Signer signer(key);
> +		size_t length = signer.MaxSignatureLength();
> +		SecByteBlock signature(length);
> +
> +		length = signer.SignMessage(rng, msg, len, signature);
> +
> +		// Copy in reverse order
> +		for (int i = 0; i < length; i++)
> +			sig_buf[length - i - 1] = signature[i];
> +	}
> +	catch(const CryptoPP::Exception& e) {
> +		cerr << e.what() << endl;
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> +
> +extern "C" int rsa_pss_sign_file(const char *key_file, const char *msg_file,
> +			unsigned char *sig_buf)
> +{
> +	try {
> +		AutoSeededRandomPool rng;
> +		FileSource file(key_file, true);
> +		RSA::PrivateKey key;
> +		ByteQueue bq;
> +
> +		// Load the key
> +		file.TransferTo(bq);
> +		bq.MessageEnd();
> +		key.BERDecodePrivateKey(bq, false, bq.MaxRetrievable());
> +
> +		// Sign the message
> +		RSASS<PSS, SHA256>::Signer signer(key);
> +		string signature;
> +		FileSource src(msg_file, true,
> +			new SignerFilter(rng, signer,
> +					new StringSink(signature)));
> +		int length = signature.length();
> +
> +		// Copy in reverse order
> +		for (int i = 0; i < length; i++)
> +			sig_buf[length - i - 1] = signature[i];
> +	}
> +	catch(const CryptoPP::Exception& e) {
> +		cerr << e.what() << endl;
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> diff --git a/src/rsa-pss.h b/src/rsa-pss.h new file mode 100644 index
> 0000000..39e88c0
> --- /dev/null
> +++ b/src/rsa-pss.h
> @@ -0,0 +1,46 @@
> +/*
> + * Copyright (c) 2015-1016, Avionic Design GmbH
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *  * Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *  * Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *  * Neither the name of Avionic Design GmbH nor the names of its
> + *    contributors may be used to endorse or promote products derived
> + *    from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND
> ANY
> + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> PARTICULAR
> + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
> OR
> + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> +SPECIAL,
> + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> LIMITED TO,
> + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> DATA, OR
> + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> THEORY
> + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE
> +USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> DAMAGE.
> + */
> +#ifndef _RSA_PSS_H
> +#define _RSA_PSS_H
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +int rsa_pss_sign(const char *key_file, const unsigned char *msg,
> +		int len, unsigned char *sig_buf, unsigned char
> *modulus_buf);
> +
> +int rsa_pss_sign_file(const char *key_file, const char *msg_file,
> +		unsigned char *sig_buf);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif // _RSA_PSS_H
> --
> 2.7.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the
> body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: sign-t124-bl.sh --]
[-- Type: application/octet-stream, Size: 2692 bytes --]

#!/bin/bash
#
# Copyright (c) 2015, NVIDIA CORPORATION.  All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# See file CREDITS for list of people who contributed to this
# project.
#
set -e
IMAGE_FILE=$1
KEY_FILE=$2
TARGET_IMAGE=$IMAGE_FILE
CONFIG_FILE=config.tmp

CBOOTIMAGE=./cbootimage
BCT_DUMP=./bct_dump
OBJCOPY=objcopy
OPENSSL=openssl
DD=dd
RM=rm
MV=mv
XXD=xxd
CUT=cut

echo "Get bl length "
BL_LENGTH=`$BCT_DUMP $IMAGE_FILE | grep "Bootloader\[0\].Length"\
 | awk -F ' ' '{print $4}' | awk -F ';' '{print $1}'`

echo "Extract bootloader to $IMAGE_FILE.bl.tosig, length $BL_LENGTH"
$DD bs=1 skip=16384 if=$IMAGE_FILE of=$IMAGE_FILE.bl.tosig count=$BL_LENGTH

echo "Calculate rsa signature for bootloader and save to $IMAGE_FILE.bl.sig"
$OPENSSL dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 \
 -sign $KEY_FILE -out $IMAGE_FILE.bl.sig $IMAGE_FILE.bl.tosig

echo "Update bootloader's rsa signature, aes hash and bct's aes hash"
echo "RsaPssSigBlFile = $IMAGE_FILE.bl.sig;" > $CONFIG_FILE
echo "RehashBl;" >> $CONFIG_FILE
$CBOOTIMAGE -s tegra124 -u $CONFIG_FILE $IMAGE_FILE $IMAGE_FILE.tmp

echo "Extract the part of bct which needs to be rsa signed"
$DD bs=1 if=$IMAGE_FILE.tmp of=$IMAGE_FILE.bct.tosig count=6480 skip=1712

echo "Calculate rsa signature for bct and save to $IMAGE_FILE.bct.sig"
$OPENSSL dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 \
 -sign $KEY_FILE -out $IMAGE_FILE.bct.sig $IMAGE_FILE.bct.tosig

echo "Create public key modulus from key file $KEY_FILE and save to $KEY_FILE.mod"
$OPENSSL rsa -in $KEY_FILE -noout -modulus -out $KEY_FILE.mod
# remove prefix
$CUT -d= -f2 < $KEY_FILE.mod > $KEY_FILE.mod.tmp

# convert from hexdecimal to binary
$XXD -r -p -l 256 $KEY_FILE.mod.tmp $KEY_FILE.mod.bin

echo "Update bct's rsa signature and modulus"
echo "RsaPssSigBctFile = $IMAGE_FILE.bct.sig;" > $CONFIG_FILE
echo "RsaKeyModulusFile = $KEY_FILE.mod.bin;" >> $CONFIG_FILE
$CBOOTIMAGE -s tegra124 -u $CONFIG_FILE $IMAGE_FILE.tmp $TARGET_IMAGE

# echo "Get rid of all temporary files: *.sig, *.tosig, *.tmp, *.mod, *.mod.bin"
$RM -f *.sig *.tosig *.tmp *.mod *.mod.bin


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [tegrarcm PATCH v2] Add support for production devices secured with PKC
       [not found]     ` <fbd256251e014b23a189337a7d251da0-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
@ 2016-03-01 11:12       ` Alban Bedel
  2016-03-01 17:32         ` Stephen Warren
  0 siblings, 1 reply; 6+ messages in thread
From: Alban Bedel @ 2016-03-01 11:12 UTC (permalink / raw)
  To: Jimmy Zhang; +Cc: Alban Bedel, linux-tegra-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 3389 bytes --]

On Mon, 29 Feb 2016 23:03:01 +0000
Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:

> Alban,
> 
> First of all, I believe the code your added here should and will work.
> However, it is probably purely coincident that I was adding similar
> functions as requested by Avionic Design (AD) in the last a few weeks.
> I think we could merge both approaches and result in one best
> solution. 

Up to yesterday what I did was only based on guess work, it was enough
to use RCM, but loading the bootloader failed. Now we finally got access
to (part of) the miniloader source and I was able to pin point the
missing piece to start the bootloader. The miniloader need the
bootloader signature before the bootloader binary when in PKC mode.
I added that and I was finally able to bootstrap my fused board.

> The main differences between your and mine are:
> 1. When to sign.
>     My solution is to separate signing and flashing. Ie, signing can be
> done at a secure server and flashing at non-secure factory. During
> flashing, only signed RCM messages and bootloader are needed. No pkc
> private key file is required to be present at factory. This private
> key management feature is also requested by AD. Your solution requires
> the rsa key file being present when downloading flasher.

Yes, this is currently not suited for production. But I first wanted to
have a tool that allow me to recover fused boards. We expected to be
able to use the "official" nvidia tooling (nvflash) for production.
However there are still problems with nvflash, so we might need a
"production ready" tegrarcm in the future.

>     I will send you my complete solution in another email thread.  

That would be nice.

> 2. How to sign
>     When I was adding rsa signing supporting functions into cbootimage
> for t210, the consensus is not adding rsa signing code into
> cbootimage. Instead, we should utilize openssl.  So, we ended up a
> shell script that calls openssl, cbootimage and other utilities to
> sign a given bootimage. What was added into cbootimage are some new
> configuration options that take rsa key's modulus and signatures as
> file and embed them into bootimage. I saw you have expanded rsa
> supporting to T124. With TOT cbootimage, I can run the attached script
> to sign T124 bootimage.
>
>     So, the solution I provided has no any rsa signing functions added
> into tegrarcm. Instead, use shell script to call openssl and modified
> tegrarcm to support for rsa signing.
> 
>      If my understanding is correct, the rsa signing functions you added
> here are only APIs. The actually signing are actually done by
> cryptlib. So, it is kind of in the middle. If everyone agrees, I am
> fine with it.

tegrarcm already make use of crypto++ for the AES-CMAC, so that seemed
logical to use that for the RSA-PSS signing too. To be honest I'm not
too keen on relying on external scripts for these kind of things.
I find the current solution for cbootimage quiet horrible TBH. It do
works, but it is too complex to use and error prone.

Now for tegrarcm the idea I had for production would be to allow
it to record and replay the USB command sequence. That way one could
generate a file containing the signed programming sequence that could
then be used in factories without needing the key.

Alban

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [tegrarcm PATCH v2] Add support for production devices secured with PKC
  2016-03-01 11:12       ` Alban Bedel
@ 2016-03-01 17:32         ` Stephen Warren
       [not found]           ` <56D5D245.3000204-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Stephen Warren @ 2016-03-01 17:32 UTC (permalink / raw)
  To: Alban Bedel, Jimmy Zhang; +Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 03/01/2016 04:12 AM, Alban Bedel wrote:
> On Mon, 29 Feb 2016 23:03:01 +0000
> Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
>
>> Alban,
>>
>> First of all, I believe the code your added here should and will work.
>> However, it is probably purely coincident that I was adding similar
>> functions as requested by Avionic Design (AD) in the last a few weeks.
>> I think we could merge both approaches and result in one best
>> solution.
>
> Up to yesterday what I did was only based on guess work, it was enough
> to use RCM, but loading the bootloader failed. Now we finally got access
> to (part of) the miniloader source and I was able to pin point the
> missing piece to start the bootloader. The miniloader need the
> bootloader signature before the bootloader binary when in PKC mode.
> I added that and I was finally able to bootstrap my fused board.
>
>> The main differences between your and mine are:
>> 1. When to sign.
>>      My solution is to separate signing and flashing. Ie, signing can be
>> done at a secure server and flashing at non-secure factory. During
>> flashing, only signed RCM messages and bootloader are needed. No pkc
>> private key file is required to be present at factory. This private
>> key management feature is also requested by AD. Your solution requires
>> the rsa key file being present when downloading flasher.
>
> Yes, this is currently not suited for production.

Given that, I think I'll ignore this patch series for now. It's typical 
to mark such patches "RFC" in the email subject to indicate that they 
shouldn't be applied. Hopefully you and Jimmy can work together to 
combine your work and post a production-ready patch set?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [tegrarcm PATCH v2] Add support for production devices secured with PKC
       [not found]           ` <56D5D245.3000204-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2016-03-01 18:26             ` Jimmy Zhang
  2016-03-02 10:41             ` Alban Bedel
  1 sibling, 0 replies; 6+ messages in thread
From: Jimmy Zhang @ 2016-03-01 18:26 UTC (permalink / raw)
  To: Stephen Warren, Alban Bedel; +Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA



> -----Original Message-----
> From: Stephen Warren [mailto:swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org]
> Sent: Tuesday, March 01, 2016 9:33 AM
> To: Alban Bedel; Jimmy Zhang
> Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Subject: Re: [tegrarcm PATCH v2] Add support for production devices
> secured with PKC
> 
> On 03/01/2016 04:12 AM, Alban Bedel wrote:
> > On Mon, 29 Feb 2016 23:03:01 +0000
> > Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> >
> >> Alban,
> >>
> >> First of all, I believe the code your added here should and will work.
> >> However, it is probably purely coincident that I was adding similar
> >> functions as requested by Avionic Design (AD) in the last a few weeks.
> >> I think we could merge both approaches and result in one best
> >> solution.
> >
> > Up to yesterday what I did was only based on guess work, it was enough
> > to use RCM, but loading the bootloader failed. Now we finally got
> > access to (part of) the miniloader source and I was able to pin point
> > the missing piece to start the bootloader. The miniloader need the
> > bootloader signature before the bootloader binary when in PKC mode.
> > I added that and I was finally able to bootstrap my fused board.
> >
> >> The main differences between your and mine are:
> >> 1. When to sign.
> >>      My solution is to separate signing and flashing. Ie, signing can
> >> be done at a secure server and flashing at non-secure factory. During
> >> flashing, only signed RCM messages and bootloader are needed. No pkc
> >> private key file is required to be present at factory. This private
> >> key management feature is also requested by AD. Your solution
> >> requires the rsa key file being present when downloading flasher.
> >
> > Yes, this is currently not suited for production.
> 
> Given that, I think I'll ignore this patch series for now. It's typical to mark such
> patches "RFC" in the email subject to indicate that they shouldn't be applied.
> Hopefully you and Jimmy can work together to combine your work and post
> a production-ready patch set?

I have sent my patches and total solution to Alban last night. Seems it was missed.

I will send out again. 
 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [tegrarcm PATCH v2] Add support for production devices secured with PKC
       [not found]           ` <56D5D245.3000204-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  2016-03-01 18:26             ` Jimmy Zhang
@ 2016-03-02 10:41             ` Alban Bedel
  1 sibling, 0 replies; 6+ messages in thread
From: Alban Bedel @ 2016-03-02 10:41 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Alban Bedel, Jimmy Zhang, linux-tegra-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 2337 bytes --]

On Tue, 1 Mar 2016 10:32:53 -0700
Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> wrote:

> On 03/01/2016 04:12 AM, Alban Bedel wrote:
> > On Mon, 29 Feb 2016 23:03:01 +0000
> > Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> >
> >> Alban,
> >>
> >> First of all, I believe the code your added here should and will work.
> >> However, it is probably purely coincident that I was adding similar
> >> functions as requested by Avionic Design (AD) in the last a few weeks.
> >> I think we could merge both approaches and result in one best
> >> solution.
> >
> > Up to yesterday what I did was only based on guess work, it was enough
> > to use RCM, but loading the bootloader failed. Now we finally got access
> > to (part of) the miniloader source and I was able to pin point the
> > missing piece to start the bootloader. The miniloader need the
> > bootloader signature before the bootloader binary when in PKC mode.
> > I added that and I was finally able to bootstrap my fused board.
> >
> >> The main differences between your and mine are:
> >> 1. When to sign.
> >>      My solution is to separate signing and flashing. Ie, signing can be
> >> done at a secure server and flashing at non-secure factory. During
> >> flashing, only signed RCM messages and bootloader are needed. No pkc
> >> private key file is required to be present at factory. This private
> >> key management feature is also requested by AD. Your solution requires
> >> the rsa key file being present when downloading flasher.
> >
> > Yes, this is currently not suited for production.
> 
> Given that, I think I'll ignore this patch series for now. It's typical 
> to mark such patches "RFC" in the email subject to indicate that they 
> shouldn't be applied.

Sorry, this was misleading, with production I meant a factory producing
some K1 based hardware. What this patch implement works properly, but it
is only useful for developers as you need the private key. It does not
provide a solution for programming/recovering locked devices at an
untrusted factory. However I didn't intended to cover this case with
this patch.

> Hopefully you and Jimmy can work together to 
> combine your work and post a production-ready patch set?

I'll look at Jimmy's patches.

Alban

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-03-02 10:41 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-29 17:49 [tegrarcm PATCH v2] Add support for production devices secured with PKC Alban Bedel
     [not found] ` <1456768181-12983-1-git-send-email-alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2016-02-29 23:03   ` Jimmy Zhang
     [not found]     ` <fbd256251e014b23a189337a7d251da0-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
2016-03-01 11:12       ` Alban Bedel
2016-03-01 17:32         ` Stephen Warren
     [not found]           ` <56D5D245.3000204-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-03-01 18:26             ` Jimmy Zhang
2016-03-02 10:41             ` Alban Bedel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.