All of lore.kernel.org
 help / color / mirror / Atom feed
* [tegrarcm PATCH V2 0/4] Add support for flashing PKC secured board
@ 2016-03-12  1:02 Jimmy Zhang
       [not found] ` <1457744552-30966-1-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Jimmy Zhang @ 2016-03-12  1:02 UTC (permalink / raw)
  To: amartin-DDmLM1+adcrQT0dZR+AlfA, swarren-DDmLM1+adcrQT0dZR+AlfA,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jimmy Zhang

V2:
1. Redefined sign and download command line parameters as below:
    generate signed messages: --gen-signed-msgs --signed-msgs-file <msgs.bin>
    download signed messages: --download-signed-msgs --signed-msgs-file <msgs.bin>
2. Added option --soc=<soc#> to specify tegra soc model number so that generating
   signed messages can be proceeded without accessing hardware.
3. Re-enabled cmac_hash when generating signed messages so that signed messages
   can also run on an unsecured board.
4. Download bootloader's pkc signature only when the board is in secured pkc mode.
5. Added error check on key length.
6. Added option --usb-timeout to allow user to specify usb transfer timeout value.

V1:
1. Use option "--pkc" to sign and download bootloader. This option is
   designed for developer. Patch 0001-Add-option-pkc.patch was originally
   submitted by Alban Bedel.
2. Use option "--ml_rcm" and "--pkc" to sign rcm messages and bootloader.
   This signing only feature is intended for production where signging
   is done at secured server and flashing can be done at different stage and
   site without requiring keyfile being present. 
3. Use option "--signed" to specify and download signed rcm messages.
   This option is used for flashing on fused board. ie, a system with
   security mode enabled.

Alban Bedel (1):
  Add support for production devices secured with PKC

Jimmy Zhang (3):
  Add option --gen-signed-msgs and --signed-msgs-file to generate signed
    blobs
  Add option --download-signed-msgs to download signed blobs
  Add option --usb-timeout=<value>

 src/Makefile.am |   2 +
 src/main.c      | 535 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 src/rcm.c       |  16 +-
 src/rcm.h       |  13 +-
 src/rsa-pss.cpp | 163 +++++++++++++++++
 src/rsa-pss.h   |  46 +++++
 src/usb.c       |   5 +-
 7 files changed, 713 insertions(+), 67 deletions(-)
 create mode 100644 src/rsa-pss.cpp
 create mode 100644 src/rsa-pss.h

-- 
1.9.1

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

* [tegrarcm PATCH V2 1/4] Add support for production devices secured with PKC
       [not found] ` <1457744552-30966-1-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2016-03-12  1:02   ` Jimmy Zhang
       [not found]     ` <1457744552-30966-2-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2016-03-12  1:02   ` [tegrarcm PATCH V2 2/4] Add option --gen-signed-msgs and --signed-msgs-file to generate signed blobs Jimmy Zhang
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Jimmy Zhang @ 2016-03-12  1:02 UTC (permalink / raw)
  To: amartin-DDmLM1+adcrQT0dZR+AlfA, swarren-DDmLM1+adcrQT0dZR+AlfA,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jimmy Zhang

From: Alban Bedel <alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>

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>
Signed-off-by: Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

--
Changelog:
V3: * Download bl sig only when op_mode is SECURE_PKC
    * Generate cmac_hash even when --pkc option is present so that
      an unfused board can still run with --pkc option.
    * Added Error Check on key length
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      |  79 +++++++++++++++++++++++----
 src/rcm.c       |  16 +++++-
 src/rcm.h       |  13 +++--
 src/rsa-pss.cpp | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/rsa-pss.h   |  46 ++++++++++++++++
 6 files changed, 304 insertions(+), 15 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 4b548859e075..3dad0e6d5e72 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 3db0ed8be506..cbf400d565a9 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 *pkc_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,9 +70,15 @@ 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);
 
+static void set_platform_info(nv3p_platform_info_t *info);
+static uint32_t get_op_mode(void);
+
+static nv3p_platform_info_t *g_platform_info = NULL;
+
 enum cmdline_opts {
 	OPT_BCT,
 	OPT_BOOTLOADER,
@@ -81,6 +88,7 @@ enum cmdline_opts {
 	OPT_VERSION,
 	OPT_MINILOADER,
 	OPT_MINIENTRY,
+	OPT_PKC,
 #ifdef HAVE_USB_PORT_MATCH
 	OPT_USBPORTPATH,
 #endif
@@ -123,6 +131,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 private key should be\n");
+	fprintf(stderr, "\t\tin DER format\n");
+
 	fprintf(stderr, "\n");
 }
 
@@ -175,6 +187,7 @@ int main(int argc, char **argv)
 	int do_read = 0;
 	char *mlfile = NULL;
 	uint32_t mlentry = 0;
+	char *pkc_keyfile = NULL;
 #ifdef HAVE_USB_PORT_MATCH
 	bool match_port = false;
 	uint8_t match_bus;
@@ -191,6 +204,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 +243,9 @@ int main(int argc, char **argv)
 			case OPT_MINIENTRY:
 				mlentry = strtoul(optarg, NULL, 0);
 				break;
+			case OPT_PKC:
+				pkc_keyfile = optarg;
+				break;
 #ifdef HAVE_USB_PORT_MATCH
 			case OPT_USBPORTPATH:
 				parse_usb_port_path(argv[0], optarg,
@@ -308,7 +325,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_keyfile);
 		if (ret2)
 			error(1, errno, "error initializing RCM protocol");
 
@@ -351,10 +368,12 @@ int main(int argc, char **argv)
 	if (ret)
 		error(1, errno, "wait status after platform info");
 	dump_platform_info(&info);
+	set_platform_info(&info);
 
 	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 +385,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_keyfile);
 	if (ret)
 		error(1, ret, "error downloading bootloader: %s", blfile);
 
@@ -376,7 +395,8 @@ 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 *pkc_keyfile)
 {
 	int ret;
 	uint8_t *msg_buff;
@@ -388,13 +408,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, pkc_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, pkc_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, pkc_keyfile);
 	} else {
 		fprintf(stderr, "unknown tegra device: 0x%x\n", devid);
 		return errno;
@@ -720,6 +740,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 +834,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 +871,31 @@ static int download_bootloader(nv3p_handle_t h3p, char *filename,
 		return ret;
 	}
 
+	// For fused board, the bootloader hash must be sent first
+	if (get_op_mode() == RCM_OP_MODE_ODM_SECURE_PKC) {
+		/* sign and download */
+		if (pkc_keyfile)  {
+			uint8_t rsa_pss_sig[RCM_RSA_SIG_SIZE];
+
+			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;
+			}
+		} else {
+			fprintf(stderr, "Error: missing pkc keyfile to sign"
+				" bootloader\n");
+			return -1;
+		}
+	}
+
 	// send the bootloader file
 	ret = send_file(h3p, filename);
 	if (ret) {
@@ -858,3 +905,17 @@ static int download_bootloader(nv3p_handle_t h3p, char *filename,
 
 	return 0;
 }
+
+static void set_platform_info(nv3p_platform_info_t *info)
+{
+	g_platform_info = info;
+}
+
+static uint32_t get_op_mode(void)
+{
+	if (g_platform_info)
+		return g_platform_info->op_mode;
+
+	fprintf(stderr, "Error: No platform info has been retrieved\n");
+	return 0;
+}
diff --git a/src/rcm.c b/src/rcm.c
index cb53d8f4f56d..cdf81309ae96 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;
 }
 
@@ -198,6 +203,11 @@ static int rcm35_sign_msg(uint8_t *buf)
 	}
 
 	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);
+
 	return 0;
 }
 
@@ -218,6 +228,10 @@ static int rcm40_sign_msg(uint8_t *buf)
 	}
 
 	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);
+
 	return 0;
 }
 
diff --git a/src/rcm.h b/src/rcm.h
index ab4bea2d8752..0185f6439f94 100644
--- a/src/rcm.h
+++ b/src/rcm.h
@@ -50,6 +50,8 @@
 
 // AES block size in bytes
 #define RCM_AES_BLOCK_SIZE      (128 / 8)
+#define RCM_RSA_MODULUS_SIZE	(2048 / 8)
+#define RCM_RSA_SIG_SIZE	RCM_RSA_MODULUS_SIZE
 
 /*
  * Defines the header for RCM messages from the host.
@@ -72,10 +74,10 @@ typedef struct {
 
 typedef struct {
 	uint32_t len_insecure;		// 000-003
-	uint8_t modulus[2048 / 8];	// 004-103
+	uint8_t modulus[RCM_RSA_MODULUS_SIZE];	// 004-103
 	union {
 		uint8_t cmac_hash[RCM_AES_BLOCK_SIZE];
-		uint8_t rsa_pss_sig[2048 / 8];
+		uint8_t rsa_pss_sig[RCM_RSA_SIG_SIZE];
 	} object_sig;			// 104-203
 	uint8_t reserved[16];		// 204-213
 	uint32_t ecid[4];		// 214-223
@@ -89,10 +91,10 @@ typedef struct {
 
 typedef struct {
 	uint32_t len_insecure;		// 000-003
-	uint8_t modulus[2048 / 8];	// 004-103
+	uint8_t modulus[RCM_RSA_MODULUS_SIZE];	// 004-103
 	struct {
 		uint8_t cmac_hash[RCM_AES_BLOCK_SIZE];
-		uint8_t rsa_pss_sig[2048 / 8];
+		uint8_t rsa_pss_sig[RCM_RSA_SIG_SIZE];
 	} object_sig;			// 104-213
 	uint8_t reserved[16];		// 214-223
 	uint32_t ecid[4];		// 224-233
@@ -109,8 +111,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 000000000000..ab0a680af206
--- /dev/null
+++ b/src/rsa-pss.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2015-2016, 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"
+#include <stdexcept>
+#include "rcm.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();
+		// error check
+		if (mod.ByteCount() != RCM_RSA_MODULUS_SIZE)
+			throw std::length_error("incorrect rsa key modulus length");
+		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;
+	}
+	catch(std::length_error& le) {
+		cerr << "Error: " << le.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();
+		// error check
+		if (length != RCM_RSA_SIG_SIZE)
+			throw std::length_error("incorrect rsa key 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;
+	}
+	catch(std::length_error& le) {
+		cerr << "Error: " << le.what() << endl;
+		return 1;
+	}
+
+	return 0;
+}
diff --git a/src/rsa-pss.h b/src/rsa-pss.h
new file mode 100644
index 000000000000..39e88c0f12a8
--- /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
-- 
1.9.1

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

* [tegrarcm PATCH V2 2/4] Add option --gen-signed-msgs and --signed-msgs-file to generate signed blobs
       [not found] ` <1457744552-30966-1-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2016-03-12  1:02   ` [tegrarcm PATCH V2 1/4] Add support for production devices secured with PKC Jimmy Zhang
@ 2016-03-12  1:02   ` Jimmy Zhang
       [not found]     ` <1457744552-30966-3-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2016-03-12  1:02   ` [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to download " Jimmy Zhang
  2016-03-12  1:02   ` [tegrarcm PATCH V2 4/4] Add option --usb-timeout=<value> Jimmy Zhang
  3 siblings, 1 reply; 14+ messages in thread
From: Jimmy Zhang @ 2016-03-12  1:02 UTC (permalink / raw)
  To: amartin-DDmLM1+adcrQT0dZR+AlfA, swarren-DDmLM1+adcrQT0dZR+AlfA,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jimmy Zhang

This feature allows generation of signed blobs that can later be used
to communicate with a PKC-enabled Tegra device without access to the
PKC. Option --bootloader, --soc and --pkc are also required when generating
the blob.

Example:
tegrarcm --gen-signed-msgs --signed-msgs-file rel_1001.bin \
        --bootloader u-boot.bin --loadaddr 0x83d88000 --soc 124 \
        --pkc rsa_priv.der

Where generated signed message files are:

a) rel_1001.bin.qry
b) rel_1001.bin.ml
c) rel_1001.bin.bl

Signed-off-by: Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 src/main.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 242 insertions(+), 19 deletions(-)

diff --git a/src/main.c b/src/main.c
index cbf400d565a9..17046e1efd6a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -61,10 +61,16 @@
 // tegra124 miniloader
 #include "miniloader/tegra124-miniloader.h"
 
-static int initialize_rcm(uint16_t devid, usb_device_t *usb, const char *pkc_keyfile);
-static int initialize_miniloader(uint16_t devid, usb_device_t *usb, char *mlfile, uint32_t mlentry);
+#define FILENAME_MAX_SIZE 256
+
+static int initialize_rcm(uint16_t devid, usb_device_t *usb,
+		 const char *pkc_keyfile, const char *signed_msgs_file);
+static int initialize_miniloader(uint16_t devid, usb_device_t *usb,
+		char *mlfile, uint32_t mlentry, const char *signed_msgs_file);
 static int wait_status(nv3p_handle_t h3p);
 static int send_file(nv3p_handle_t h3p, const char *filename);
+static int create_miniloader_rcm(uint8_t *miniloader, uint32_t size,
+			uint32_t entry, const char *signed_msgs_file);
 static int download_miniloader(usb_device_t *usb, uint8_t *miniloader,
 			       uint32_t size, uint32_t entry);
 static void dump_platform_info(nv3p_platform_info_t *info);
@@ -73,6 +79,8 @@ static int download_bootloader(nv3p_handle_t h3p, char *filename,
 			       uint32_t entry, uint32_t loadaddr,
 			       const char *pkc_keyfile);
 static int read_bct(nv3p_handle_t h3p, char *filename);
+static int sign_blob(const char *blob_filename, const char *pkc_keyfile,
+				const char *signed_msgs_file);
 
 static void set_platform_info(nv3p_platform_info_t *info);
 static uint32_t get_op_mode(void);
@@ -92,6 +100,9 @@ enum cmdline_opts {
 #ifdef HAVE_USB_PORT_MATCH
 	OPT_USBPORTPATH,
 #endif
+	OPT_SIGN_MSGS,
+	OPT_SIGNED_MSGS_FILE,
+	OPT_SOC,
 	OPT_END,
 };
 
@@ -134,7 +145,12 @@ static void usage(char *progname)
 	fprintf(stderr, "\t--pkc=<key.ber>\n");
 	fprintf(stderr, "\t\tSpecify the key file for secured devices. The private key should be\n");
 	fprintf(stderr, "\t\tin DER format\n");
-
+	fprintf(stderr, "\t--gen-signed-msgs\n");
+	fprintf(stderr, "\t\tGenerate signed messages for pkc secured devices\n");
+	fprintf(stderr, "\t--signed-msgs-file=<msg_file_prefix>\n");
+	fprintf(stderr, "\t\tSpecify message files prefix\n");
+	fprintf(stderr, "\t--soc=<tegra soc #>\n");
+	fprintf(stderr, "\t\tSpecify Tegra SoC chip model number, ie, 124.\n");
 	fprintf(stderr, "\n");
 }
 
@@ -168,6 +184,29 @@ static void parse_usb_port_path(char *argv0, char *path, uint8_t *match_bus,
 }
 #endif
 
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+static bool is_supported_soc(uint32_t soc, uint16_t *devid)
+{
+	struct _soc_to_devid {
+		uint32_t soc;
+		uint16_t usb_devid;
+	} soc_to_devid[] = {
+		{114,	USB_DEVID_NVIDIA_TEGRA114},
+		{124,	USB_DEVID_NVIDIA_TEGRA124},
+	};
+
+	uint32_t i;
+
+	for (i = 0; i < ARRAY_SIZE(soc_to_devid); ++i) {
+		if (soc_to_devid[i].soc == soc) {
+			*devid = soc_to_devid[i].usb_devid;
+			return true;
+		}
+	}
+
+	return false;
+}
+
 int main(int argc, char **argv)
 {
 	// discover devices
@@ -194,6 +233,9 @@ int main(int argc, char **argv)
 	uint8_t match_ports[PORT_MATCH_MAX_PORTS];
 	int match_ports_len;
 #endif
+	bool sign_msgs = false;
+	char *signed_msgs_file = NULL;
+	uint32_t soc = 0;
 
 	static struct option long_options[] = {
 		[OPT_BCT]        = {"bct", 1, 0, 0},
@@ -208,9 +250,11 @@ int main(int argc, char **argv)
 #ifdef HAVE_USB_PORT_MATCH
 		[OPT_USBPORTPATH]  = {"usb-port-path", 1, 0, 0},
 #endif
+		[OPT_SIGN_MSGS] = {"gen-signed-msgs", 0, 0, 0},
+		[OPT_SIGNED_MSGS_FILE] = {"signed-msgs-file", 1, 0, 0},
+		[OPT_SOC]        = {"soc", 1, 0, 0},
 		[OPT_END]        = {0, 0, 0, 0}
 	};
-
 	// parse command line args
 	while (1) {
 		c = getopt_long(argc, argv, "h0",
@@ -254,6 +298,15 @@ int main(int argc, char **argv)
 				match_port = true;
 				break;
 #endif
+			case OPT_SIGN_MSGS:
+				sign_msgs = true;
+				break;
+			case OPT_SIGNED_MSGS_FILE:
+				signed_msgs_file = optarg;
+				break;
+			case OPT_SOC:
+				soc = strtoul(optarg, NULL, 0);
+				break;
 			case OPT_HELP:
 			default:
 				usage(argv[0]);
@@ -279,12 +332,47 @@ int main(int argc, char **argv)
 		optind++;
 	}
 
-	if (bctfile == NULL) {
+	/* error check */
+	if (sign_msgs == true) {
+		/* must have pkc option */
+		if (pkc_keyfile == NULL) {
+			fprintf(stderr, "PKC key file must be specified\n");
+			goto usage_exit;
+		}
+
+		/* must have signed_msgs_file option */
+		if (signed_msgs_file == NULL) {
+			fprintf(stderr, "signed msgs filename must be"
+				" specified\n");
+			goto usage_exit;
+		}
+
+		/* must have --soc option */
+		if (soc == 0) {
+			fprintf(stderr, "soc model number must be"
+				" specified\n");
+			goto usage_exit;
+		}
+	}
+
+	/*
+	 * option --signed-msgs-file needs to work with option
+	 *  --gen-signed-msgs
+	 */
+	if (signed_msgs_file && (sign_msgs == false)) {
+		fprintf(stderr, "missing option --gen-signed-msgs\n");
+		goto usage_exit;
+	}
+
+	/* specify bct file if no sign_msgs option */
+	if ((bctfile == NULL) && (sign_msgs == false)) {
 		fprintf(stderr, "BCT file must be specified\n");
 		usage(argv[0]);
 		exit(EXIT_FAILURE);
 	}
-	printf("bct file: %s\n", bctfile);
+
+	if (bctfile)
+		printf("bct file: %s\n", bctfile);
 
 	if (!do_read) {
 		if (blfile == NULL) {
@@ -305,6 +393,33 @@ int main(int argc, char **argv)
 		printf("entry addr 0x%x\n", entryaddr);
 	}
 
+	/* if sign_msgs, generate signed msgs, then exit */
+	if (sign_msgs == true) {
+		/*
+		 * validate SoC value
+		 *  currently only verified soc is T124
+		 */
+		if (!is_supported_soc(soc, &devid)) {
+			fprintf(stderr, "Unrecognized soc: %u\n", soc);
+			goto usage_exit;
+		}
+
+		// init and create signed query version rcm
+		if (initialize_rcm(devid, NULL, pkc_keyfile, signed_msgs_file))
+			error(1, errno, "error initializing RCM protocol");
+
+		// create signed download miniloader rcm
+		if (initialize_miniloader(devid, NULL, mlfile, mlentry,
+					signed_msgs_file))
+			error(1, errno, "error initializing miniloader");
+
+		// create bl signature
+		sign_blob(blfile, pkc_keyfile, signed_msgs_file);
+
+		exit(0);
+	}
+
+	/* start nv3p protocol */
 	usb = usb_open(USB_VENID_NVIDIA, &devid
 #ifdef HAVE_USB_PORT_MATCH
 		, &match_port, &match_bus, match_ports, &match_ports_len
@@ -325,17 +440,20 @@ int main(int argc, char **argv)
 			error(1, errno, "USB read truncated");
 
 		// initialize rcm
-		ret2 = initialize_rcm(devid, usb, pkc_keyfile);
+		ret2 = initialize_rcm(devid, usb, pkc_keyfile,
+					signed_msgs_file);
 		if (ret2)
 			error(1, errno, "error initializing RCM protocol");
 
-		// download the miniloader to start nv3p
-		ret2 = initialize_miniloader(devid, usb, mlfile, mlentry);
+		// download the miniloader to start nv3p or create ml rcm file
+		ret2 = initialize_miniloader(devid, usb, mlfile, mlentry,
+						signed_msgs_file);
 		if (ret2)
 			error(1, errno, "error initializing miniloader");
 
 		// device may have re-enumerated, so reopen USB
 		usb_close(usb);
+
 		usb = usb_open(USB_VENID_NVIDIA, &devid
 #ifdef HAVE_USB_PORT_MATCH
 		, &match_port, &match_bus, match_ports, &match_ports_len
@@ -391,18 +509,53 @@ int main(int argc, char **argv)
 
 	nv3p_close(h3p);
 	usb_close(usb);
+	return 0;
+
+usage_exit:
+	usage(argv[0]);
+	exit(EXIT_FAILURE);
+}
+
+static int create_name_string(char *out, const char *in, const char *ext)
+{
+	if ((strlen(in) + strlen(ext) + 1) > FILENAME_MAX_SIZE) {
+		fprintf(stderr, "error: name length %zu bytes exceed "
+				"limits for file %s\n",
+			strlen(in) + strlen(ext) + 1 - FILENAME_MAX_SIZE, in);
+		return -1;
+	}
+	snprintf(out, FILENAME_MAX_SIZE, "%s%s", in, ext);
+	return 0;
+}
+
+static int save_to_file(const char *filename, const uint8_t *msg_buff,
+			const uint32_t length)
+{
+	FILE *fp;
+
+	printf("Create file %s...\n", filename);
+
+	fp = fopen(filename, "wb");
+	if (fp == NULL) {
+		fprintf(stderr, "Error opening raw file %s.\n", filename);
+		return -1;
+	}
+
+	fwrite(msg_buff, 1, length, fp);
+	fclose(fp);
 
 	return 0;
 }
 
 static int initialize_rcm(uint16_t devid, usb_device_t *usb,
-			const char *pkc_keyfile)
+			const char *pkc_keyfile, const char *signed_msgs_file)
 {
-	int ret;
+	int ret = 0;
 	uint8_t *msg_buff;
 	int msg_len;
 	uint32_t status;
 	int actual_len;
+	char query_version_rcm_filename[FILENAME_MAX_SIZE];
 
 	// initialize RCM
 	if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA20 ||
@@ -427,6 +580,18 @@ static int initialize_rcm(uint16_t devid, usb_device_t *usb,
 	// create query version message
 	rcm_create_msg(RCM_CMD_QUERY_RCM_VERSION, NULL, 0, NULL, 0, &msg_buff);
 
+	/* save query version rcm blob */
+	if (signed_msgs_file) {
+		ret = create_name_string(query_version_rcm_filename,
+					signed_msgs_file, ".qry");
+		if (ret)
+			goto done;
+
+		ret = save_to_file(query_version_rcm_filename, msg_buff,
+					rcm_get_msg_len(msg_buff));
+		goto done;
+	}
+
 	// write query version message to device
 	msg_len = rcm_get_msg_len(msg_buff);
 	if (msg_len == 0) {
@@ -436,28 +601,31 @@ static int initialize_rcm(uint16_t devid, usb_device_t *usb,
 	ret = usb_write(usb, msg_buff, msg_len);
 	if (ret) {
 		fprintf(stderr, "write RCM query version: USB transfer failure\n");
-		return ret;
+		goto done;
 	}
-	free(msg_buff);
-	msg_buff = NULL;
 
 	// read response
 	ret = usb_read(usb, (uint8_t *)&status, sizeof(status), &actual_len);
 	if (ret) {
 		fprintf(stderr, "read RCM query version: USB transfer failure\n");
-		return ret;
+		goto done;
 	}
 	if (actual_len < sizeof(status)) {
 		fprintf(stderr, "read RCM query version: USB read truncated\n");
-		return EIO;
+		ret = EIO;
+		goto done;
 	}
 	printf("RCM version: %d.%d\n", RCM_VERSION_MAJOR(status),
 	       RCM_VERSION_MINOR(status));
 
-	return 0;
+done:
+	if (msg_buff)
+		free(msg_buff);
+	return ret;
 }
 
-static int initialize_miniloader(uint16_t devid, usb_device_t *usb, char *mlfile, uint32_t mlentry)
+static int initialize_miniloader(uint16_t devid, usb_device_t *usb,
+		 char *mlfile, uint32_t mlentry, const char *signed_msgs_file)
 {
 	int fd;
 	struct stat sb;
@@ -466,7 +634,7 @@ static int initialize_miniloader(uint16_t devid, usb_device_t *usb, char *mlfile
 	uint32_t miniloader_size;
 	uint32_t miniloader_entry;
 
-	// use prebuilt miniloader if not loading from a file
+	// if using miniloader from an exteranl file
 	if (mlfile) {
 		fd = open(mlfile, O_RDONLY, 0);
 		if (fd < 0) {
@@ -511,6 +679,12 @@ static int initialize_miniloader(uint16_t devid, usb_device_t *usb, char *mlfile
 			return ENODEV;
 		}
 	}
+
+	if (signed_msgs_file) {
+		return create_miniloader_rcm(miniloader, miniloader_size,
+				miniloader_entry, signed_msgs_file);
+	}
+
 	printf("downloading miniloader to target at address 0x%x (%d bytes)...\n",
 		miniloader_entry, miniloader_size);
 	ret = download_miniloader(usb, miniloader, miniloader_size,
@@ -636,6 +810,30 @@ fail:
 	return ret;
 }
 
+static int create_miniloader_rcm(uint8_t *miniloader, uint32_t size,
+			uint32_t entry, const char *signed_msgs_file)
+{
+	uint8_t *msg_buff;
+	int ret = 0;
+	char ml_rcm_filename[FILENAME_MAX_SIZE];
+
+	// create RCM_CMD_DL_MINILOADER blob
+	rcm_create_msg(RCM_CMD_DL_MINILOADER, (uint8_t *)&entry, sizeof(entry),
+		       miniloader, size, &msg_buff);
+
+	ret = create_name_string(ml_rcm_filename, signed_msgs_file, ".ml");
+	if (ret)
+		goto done;
+
+	// write to binary file
+	dprintf("Write miniloader rcm to %s\n", ml_rcm_filename);
+
+	ret = save_to_file(ml_rcm_filename, msg_buff,
+				rcm_get_msg_len(msg_buff));
+done:
+	free(msg_buff);
+	return ret;
+}
 
 static int download_miniloader(usb_device_t *usb, uint8_t *miniloader,
 			       uint32_t size, uint32_t entry)
@@ -906,6 +1104,31 @@ static int download_bootloader(nv3p_handle_t h3p, char *filename,
 	return 0;
 }
 
+static int sign_blob(const char *blob_filename, const char *pkc_keyfile,
+			const char *signed_msgs_file)
+{
+	int ret;
+	uint8_t rsa_pss_sig[RCM_RSA_SIG_SIZE];
+
+	char signature_filename[FILENAME_MAX_SIZE];
+
+	ret = rsa_pss_sign_file(pkc_keyfile, blob_filename, rsa_pss_sig);
+	if (ret) {
+		fprintf(stderr, "error signing %s with %s\n",
+			blob_filename, pkc_keyfile);
+		return ret;
+	}
+
+	/* save signature to signed_msgs_file.bl */
+	ret = create_name_string(signature_filename, signed_msgs_file, ".bl");
+	if (ret)
+		return ret;
+
+	ret = save_to_file(signature_filename, rsa_pss_sig,
+				sizeof(rsa_pss_sig));
+	return ret;
+}
+
 static void set_platform_info(nv3p_platform_info_t *info)
 {
 	g_platform_info = info;
-- 
1.9.1

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

* [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to download signed blobs
       [not found] ` <1457744552-30966-1-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2016-03-12  1:02   ` [tegrarcm PATCH V2 1/4] Add support for production devices secured with PKC Jimmy Zhang
  2016-03-12  1:02   ` [tegrarcm PATCH V2 2/4] Add option --gen-signed-msgs and --signed-msgs-file to generate signed blobs Jimmy Zhang
@ 2016-03-12  1:02   ` Jimmy Zhang
       [not found]     ` <1457744552-30966-4-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2016-03-12  1:02   ` [tegrarcm PATCH V2 4/4] Add option --usb-timeout=<value> Jimmy Zhang
  3 siblings, 1 reply; 14+ messages in thread
From: Jimmy Zhang @ 2016-03-12  1:02 UTC (permalink / raw)
  To: amartin-DDmLM1+adcrQT0dZR+AlfA, swarren-DDmLM1+adcrQT0dZR+AlfA,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jimmy Zhang

This feature allows user to download signed messages to devices
secured with PKC.

Example:
tegrarcm --download-signed-msgs --signed-msgs-file rel_1001.bin \
   --bct=jetson-tk1-bct.bct --bootloader=u-boot.bin --loadaddr=0x83d88000

Where the following blob files are downloaded to device sequentially:

a) rel_1001.bin.qry
b) rel_1001.bin.ml
c) rel_1001.bin.bl

Signed-off-by: Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 src/main.c | 257 +++++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 191 insertions(+), 66 deletions(-)

diff --git a/src/main.c b/src/main.c
index 17046e1efd6a..cb12138ae66c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -64,20 +64,23 @@
 #define FILENAME_MAX_SIZE 256
 
 static int initialize_rcm(uint16_t devid, usb_device_t *usb,
-		 const char *pkc_keyfile, const char *signed_msgs_file);
+		const char *pkc_keyfile, const char *signed_msgs_file,
+		bool download_signed_msgs);
 static int initialize_miniloader(uint16_t devid, usb_device_t *usb,
-		char *mlfile, uint32_t mlentry, const char *signed_msgs_file);
+		char *mlfile, uint32_t mlentry, const char *signed_msgs_file,
+		bool download_signed_msgs);
 static int wait_status(nv3p_handle_t h3p);
 static int send_file(nv3p_handle_t h3p, const char *filename);
 static int create_miniloader_rcm(uint8_t *miniloader, uint32_t size,
 			uint32_t entry, const char *signed_msgs_file);
 static int download_miniloader(usb_device_t *usb, uint8_t *miniloader,
-			       uint32_t size, uint32_t entry);
+				uint32_t size, uint32_t entry,
+				bool download_signed_msgs);
 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,
-			       const char *pkc_keyfile);
+			uint32_t entry, uint32_t loadaddr,
+			const char *pkc_keyfile, const char *signed_msgs_file);
 static int read_bct(nv3p_handle_t h3p, char *filename);
 static int sign_blob(const char *blob_filename, const char *pkc_keyfile,
 				const char *signed_msgs_file);
@@ -103,6 +106,7 @@ enum cmdline_opts {
 	OPT_SIGN_MSGS,
 	OPT_SIGNED_MSGS_FILE,
 	OPT_SOC,
+	OPT_DOWNLOAD_SIGNED_MSGS,
 	OPT_END,
 };
 
@@ -151,6 +155,8 @@ static void usage(char *progname)
 	fprintf(stderr, "\t\tSpecify message files prefix\n");
 	fprintf(stderr, "\t--soc=<tegra soc #>\n");
 	fprintf(stderr, "\t\tSpecify Tegra SoC chip model number, ie, 124.\n");
+	fprintf(stderr, "\t--download-signed-msgs\n");
+	fprintf(stderr, "\t\tDownload signed messages\n");
 	fprintf(stderr, "\n");
 }
 
@@ -236,6 +242,7 @@ int main(int argc, char **argv)
 	bool sign_msgs = false;
 	char *signed_msgs_file = NULL;
 	uint32_t soc = 0;
+	bool download_signed_msgs = false;
 
 	static struct option long_options[] = {
 		[OPT_BCT]        = {"bct", 1, 0, 0},
@@ -253,6 +260,7 @@ int main(int argc, char **argv)
 		[OPT_SIGN_MSGS] = {"gen-signed-msgs", 0, 0, 0},
 		[OPT_SIGNED_MSGS_FILE] = {"signed-msgs-file", 1, 0, 0},
 		[OPT_SOC]        = {"soc", 1, 0, 0},
+		[OPT_DOWNLOAD_SIGNED_MSGS] = {"download-signed-msgs", 0, 0, 0},
 		[OPT_END]        = {0, 0, 0, 0}
 	};
 	// parse command line args
@@ -307,6 +315,9 @@ int main(int argc, char **argv)
 			case OPT_SOC:
 				soc = strtoul(optarg, NULL, 0);
 				break;
+			case OPT_DOWNLOAD_SIGNED_MSGS:
+				download_signed_msgs = true;
+				break;
 			case OPT_HELP:
 			default:
 				usage(argv[0]);
@@ -355,12 +366,36 @@ int main(int argc, char **argv)
 		}
 	}
 
+	/* error check */
+	if (download_signed_msgs == true) {
+		/* must have signed_msgs_file option */
+		if (signed_msgs_file == NULL) {
+			fprintf(stderr, "signed msgs filename must be"
+					" specified\n");
+			goto usage_exit;
+		}
+
+		/* can not have pkc keyfile */
+		if (pkc_keyfile) {
+			fprintf(stderr, "No pkc keyfile is needed\n");
+			goto usage_exit;
+		}
+
+		/* can not load in unsigned ml */
+		if (mlfile) {
+			fprintf(stderr, "can not have option --miniloader\n");
+			goto usage_exit;
+		}
+	}
+
 	/*
 	 * option --signed-msgs-file needs to work with option
-	 *  --gen-signed-msgs
+	 *   either --gen-signed-msgs or --download-signed-msgs
 	 */
-	if (signed_msgs_file && (sign_msgs == false)) {
-		fprintf(stderr, "missing option --gen-signed-msgs\n");
+	if (signed_msgs_file && (sign_msgs == false) &&
+			(download_signed_msgs == false)) {
+		fprintf(stderr, "missing option either --gen-signed-msgs or"
+				" --download-signed-msgs\n");
 		goto usage_exit;
 	}
 
@@ -405,12 +440,13 @@ int main(int argc, char **argv)
 		}
 
 		// init and create signed query version rcm
-		if (initialize_rcm(devid, NULL, pkc_keyfile, signed_msgs_file))
+		if (initialize_rcm(devid, NULL, pkc_keyfile, signed_msgs_file,
+					download_signed_msgs))
 			error(1, errno, "error initializing RCM protocol");
 
 		// create signed download miniloader rcm
 		if (initialize_miniloader(devid, NULL, mlfile, mlentry,
-					signed_msgs_file))
+				signed_msgs_file, download_signed_msgs))
 			error(1, errno, "error initializing miniloader");
 
 		// create bl signature
@@ -441,13 +477,13 @@ int main(int argc, char **argv)
 
 		// initialize rcm
 		ret2 = initialize_rcm(devid, usb, pkc_keyfile,
-					signed_msgs_file);
+					signed_msgs_file, download_signed_msgs);
 		if (ret2)
 			error(1, errno, "error initializing RCM protocol");
 
 		// download the miniloader to start nv3p or create ml rcm file
 		ret2 = initialize_miniloader(devid, usb, mlfile, mlentry,
-						signed_msgs_file);
+					signed_msgs_file, download_signed_msgs);
 		if (ret2)
 			error(1, errno, "error initializing miniloader");
 
@@ -503,7 +539,8 @@ int main(int argc, char **argv)
 	}
 
 	// download the bootloader
-	ret = download_bootloader(h3p, blfile, entryaddr, loadaddr, pkc_keyfile);
+	ret = download_bootloader(h3p, blfile, entryaddr, loadaddr,
+				pkc_keyfile, signed_msgs_file);
 	if (ret)
 		error(1, ret, "error downloading bootloader: %s", blfile);
 
@@ -548,7 +585,8 @@ static int save_to_file(const char *filename, const uint8_t *msg_buff,
 }
 
 static int initialize_rcm(uint16_t devid, usb_device_t *usb,
-			const char *pkc_keyfile, const char *signed_msgs_file)
+			const char *pkc_keyfile, const char *signed_msgs_file,
+			bool download_signed_msgs)
 {
 	int ret = 0;
 	uint8_t *msg_buff;
@@ -580,16 +618,55 @@ static int initialize_rcm(uint16_t devid, usb_device_t *usb,
 	// create query version message
 	rcm_create_msg(RCM_CMD_QUERY_RCM_VERSION, NULL, 0, NULL, 0, &msg_buff);
 
-	/* save query version rcm blob */
+	/* if signed_msgs_file is given */
 	if (signed_msgs_file) {
+		int fd;
+		struct stat sb;
+
 		ret = create_name_string(query_version_rcm_filename,
 					signed_msgs_file, ".qry");
 		if (ret)
 			goto done;
 
-		ret = save_to_file(query_version_rcm_filename, msg_buff,
+		/* either save query version rcm blob */
+		if (download_signed_msgs == false) {
+			ret = save_to_file(query_version_rcm_filename, msg_buff,
 					rcm_get_msg_len(msg_buff));
-		goto done;
+			goto done;
+		}
+
+		/* or download signed query version rcm blob */
+		printf("download signed query version rcm from file %s\n",
+			 query_version_rcm_filename);
+
+		free(msg_buff); // release memory allocated by rcm_create_msg
+		msg_buff = NULL;
+
+		fd = open(query_version_rcm_filename, O_RDONLY, 0);
+		if (fd < 0) {
+			fprintf(stderr, "error opening %s\n",
+				query_version_rcm_filename);
+			return errno;
+		}
+
+		ret = fstat(fd, &sb);
+		if (ret) {
+			fprintf(stderr, "error on fstat of %s\n",
+				query_version_rcm_filename);
+			return ret;
+		}
+		msg_buff = (uint8_t *)malloc(sb.st_size);
+		if (!msg_buff) {
+			fprintf(stderr, "error allocating %zd bytes for query"
+				" rcm\n", sb.st_size);
+			return errno;
+		}
+		if (read(fd, msg_buff, sb.st_size) != sb.st_size) {
+			fprintf(stderr,"error reading from %s\n",
+				query_version_rcm_filename);
+			free(msg_buff);
+			return errno;
+		}
 	}
 
 	// write query version message to device
@@ -625,25 +702,68 @@ done:
 }
 
 static int initialize_miniloader(uint16_t devid, usb_device_t *usb,
-		 char *mlfile, uint32_t mlentry, const char *signed_msgs_file)
+		char *mlfile, uint32_t mlentry, const char *signed_msgs_file,
+		bool download_signed_msgs)
 {
 	int fd;
 	struct stat sb;
 	int ret;
-	uint8_t *miniloader;
+	uint8_t *miniloader = NULL;
+	bool ml_buffer_alloc = false;
 	uint32_t miniloader_size;
 	uint32_t miniloader_entry;
+	char ml_rcm_filename[FILENAME_MAX_SIZE];
+	char *filename = NULL;
+
+	// use prebuilt miniloader if not loading from a file
+	if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA20) {
+		miniloader = miniloader_tegra20;
+		miniloader_size = sizeof(miniloader_tegra20);
+		miniloader_entry = TEGRA20_MINILOADER_ENTRY;
+	} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA30) {
+		miniloader = miniloader_tegra30;
+		miniloader_size = sizeof(miniloader_tegra30);
+		miniloader_entry = TEGRA30_MINILOADER_ENTRY;
+	} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA114) {
+		miniloader = miniloader_tegra114;
+		miniloader_size = sizeof(miniloader_tegra114);
+		miniloader_entry = TEGRA114_MINILOADER_ENTRY;
+	} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA124) {
+		miniloader = miniloader_tegra124;
+		miniloader_size = sizeof(miniloader_tegra124);
+		miniloader_entry = TEGRA124_MINILOADER_ENTRY;
+	} else {
+		fprintf(stderr, "unknown tegra device: 0x%x\n", devid);
+		return ENODEV;
+	}
+
+	// if loading unsigned ml from a file
+	if (mlfile)
+		filename = mlfile;
+
+	// if loading signed ml rcm file
+	if (signed_msgs_file && (download_signed_msgs == true)) {
+		filename = ml_rcm_filename;
+		ret = create_name_string(ml_rcm_filename, signed_msgs_file,
+					".ml");
+		if (ret)
+			goto done;
+
+		/* download signed ml rcm blob */
+		printf("download signed miniloader rcm from file %s\n",
+			 ml_rcm_filename);
+	}
 
-	// if using miniloader from an exteranl file
-	if (mlfile) {
-		fd = open(mlfile, O_RDONLY, 0);
+	// loading ml or signed ml rcm from a file
+	if (filename) {
+		fd = open(filename, O_RDONLY, 0);
 		if (fd < 0) {
-			dprintf("error opening %s for reading\n", mlfile);
+			dprintf("error opening %s\n", filename);
 			return errno;
 		}
 		ret = fstat(fd, &sb);
 		if (ret) {
-			dprintf("error on fstat of %s\n", mlfile);
+			dprintf("error on fstat of %s\n", filename);
 			return ret;
 		}
 		miniloader_size = sb.st_size;
@@ -652,50 +772,37 @@ static int initialize_miniloader(uint16_t devid, usb_device_t *usb,
 			dprintf("error allocating %d bytes for miniloader\n", miniloader_size);
 			return errno;
 		}
+		ml_buffer_alloc = true;
 		if (read(fd, miniloader, miniloader_size) != miniloader_size) {
 			dprintf("error reading from miniloader file");
 			return errno;
 		}
-		miniloader_entry = mlentry;
-	} else {
-		if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA20) {
-			miniloader = miniloader_tegra20;
-			miniloader_size = sizeof(miniloader_tegra20);
-			miniloader_entry = TEGRA20_MINILOADER_ENTRY;
-		} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA30) {
-			miniloader = miniloader_tegra30;
-			miniloader_size = sizeof(miniloader_tegra30);
-			miniloader_entry = TEGRA30_MINILOADER_ENTRY;
-		} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA114) {
-			miniloader = miniloader_tegra114;
-			miniloader_size = sizeof(miniloader_tegra114);
-			miniloader_entry = TEGRA114_MINILOADER_ENTRY;
-		} else if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA124) {
-			miniloader = miniloader_tegra124;
-			miniloader_size = sizeof(miniloader_tegra124);
-			miniloader_entry = TEGRA124_MINILOADER_ENTRY;
-		} else {
-			fprintf(stderr, "unknown tegra device: 0x%x\n", devid);
-			return ENODEV;
-		}
 	}
 
-	if (signed_msgs_file) {
-		return create_miniloader_rcm(miniloader, miniloader_size,
+	// if entry is specified
+	if (mlentry)
+		miniloader_entry = mlentry;
+
+	// if generating ml rcm file
+	if (signed_msgs_file && (download_signed_msgs == false)) {
+		ret = create_miniloader_rcm(miniloader, miniloader_size,
 				miniloader_entry, signed_msgs_file);
+		goto done;
 	}
 
 	printf("downloading miniloader to target at address 0x%x (%d bytes)...\n",
 		miniloader_entry, miniloader_size);
 	ret = download_miniloader(usb, miniloader, miniloader_size,
-				  miniloader_entry);
+				  miniloader_entry, download_signed_msgs);
 	if (ret) {
 		fprintf(stderr, "Error downloading miniloader\n");
 		return ret;
 	}
 	printf("miniloader downloaded successfully\n");
-
-	return 0;
+done:
+	if ((ml_buffer_alloc == true) && miniloader)
+		free(miniloader);
+	return ret;
 }
 
 static int wait_status(nv3p_handle_t h3p)
@@ -836,17 +943,24 @@ done:
 }
 
 static int download_miniloader(usb_device_t *usb, uint8_t *miniloader,
-			       uint32_t size, uint32_t entry)
+				uint32_t size, uint32_t entry,
+				bool download_signed_msgs)
 {
-	uint8_t *msg_buff;
+	uint8_t *msg_buff = NULL;
+	bool msg_buff_alloc = false;
 	int ret;
 	uint32_t status;
 	int actual_len;
 
 	// download the miniloader to the bootrom
-	rcm_create_msg(RCM_CMD_DL_MINILOADER,
-		       (uint8_t *)&entry, sizeof(entry), miniloader, size,
-		       &msg_buff);
+	if (download_signed_msgs == true)	/* signed ml with rcm header */
+		msg_buff = miniloader;
+	else {
+		rcm_create_msg(RCM_CMD_DL_MINILOADER, (uint8_t *)&entry,
+				sizeof(entry), miniloader, size, &msg_buff);
+		msg_buff_alloc = true;
+	}
+
 	ret = usb_write(usb, msg_buff, rcm_get_msg_len(msg_buff));
 	if (ret)
 		goto fail;
@@ -864,7 +978,8 @@ static int download_miniloader(usb_device_t *usb, uint8_t *miniloader,
 
 	ret = 0;
 fail:
-	free(msg_buff);
+	if ((msg_buff_alloc == true) && msg_buff)
+		free(msg_buff);
 	return ret;
 }
 
@@ -1032,8 +1147,8 @@ out:
 }
 
 static int download_bootloader(nv3p_handle_t h3p, char *filename,
-			       uint32_t entry, uint32_t loadaddr,
-			       const char *pkc_keyfile)
+			uint32_t entry, uint32_t loadaddr,
+			const char *pkc_keyfile, const char *signed_msgs_file)
 {
 	int ret;
 	nv3p_cmd_dl_bl_t arg;
@@ -1083,14 +1198,24 @@ static int download_bootloader(nv3p_handle_t h3p, char *filename,
 			}
 
 			ret = nv3p_data_send(h3p, rsa_pss_sig, sizeof(rsa_pss_sig));
-			if (ret) {
-				dprintf("error sending bootloader signature\n");
+		}
+
+		/* download bl's rsa_pss_sig */
+		if (signed_msgs_file) {
+			char signature_filename[FILENAME_MAX_SIZE];
+
+			ret = create_name_string(signature_filename,
+						signed_msgs_file, ".bl");
+			if (ret)
 				return ret;
-			}
-		} else {
-			fprintf(stderr, "Error: missing pkc keyfile to sign"
-				" bootloader\n");
-			return -1;
+
+			// send the bootloader file
+			ret = send_file(h3p, signature_filename);
+		}
+
+		if (ret) {
+			dprintf("error sending bootloader signature\n");
+			return ret;
 		}
 	}
 
-- 
1.9.1

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

* [tegrarcm PATCH V2 4/4] Add option --usb-timeout=<value>
       [not found] ` <1457744552-30966-1-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (2 preceding siblings ...)
  2016-03-12  1:02   ` [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to download " Jimmy Zhang
@ 2016-03-12  1:02   ` Jimmy Zhang
       [not found]     ` <1457744552-30966-5-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  3 siblings, 1 reply; 14+ messages in thread
From: Jimmy Zhang @ 2016-03-12  1:02 UTC (permalink / raw)
  To: amartin-DDmLM1+adcrQT0dZR+AlfA, swarren-DDmLM1+adcrQT0dZR+AlfA,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jimmy Zhang

RCM communication sometimes fails if the USB timeout is short. The default
timeout is 1000ms. Increase the timeout value to avoid this issue. The exact
cause is not yet diagnosed.

Signed-off-by: Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 src/main.c | 8 ++++++++
 src/usb.c  | 5 +++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/main.c b/src/main.c
index cb12138ae66c..acda0b1b607f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -89,6 +89,7 @@ static void set_platform_info(nv3p_platform_info_t *info);
 static uint32_t get_op_mode(void);
 
 static nv3p_platform_info_t *g_platform_info = NULL;
+extern uint32_t usb_timeout;
 
 enum cmdline_opts {
 	OPT_BCT,
@@ -107,6 +108,7 @@ enum cmdline_opts {
 	OPT_SIGNED_MSGS_FILE,
 	OPT_SOC,
 	OPT_DOWNLOAD_SIGNED_MSGS,
+	OPT_USB_TIMEOUT,
 	OPT_END,
 };
 
@@ -157,6 +159,8 @@ static void usage(char *progname)
 	fprintf(stderr, "\t\tSpecify Tegra SoC chip model number, ie, 124.\n");
 	fprintf(stderr, "\t--download-signed-msgs\n");
 	fprintf(stderr, "\t\tDownload signed messages\n");
+	fprintf(stderr, "\t--usb-timeout=<timeout_ms>\n");
+	fprintf(stderr, "\t\tSpecify usb transfer timeout value in ms, 0 for unlimited timeout\n");
 	fprintf(stderr, "\n");
 }
 
@@ -261,6 +265,7 @@ int main(int argc, char **argv)
 		[OPT_SIGNED_MSGS_FILE] = {"signed-msgs-file", 1, 0, 0},
 		[OPT_SOC]        = {"soc", 1, 0, 0},
 		[OPT_DOWNLOAD_SIGNED_MSGS] = {"download-signed-msgs", 0, 0, 0},
+		[OPT_USB_TIMEOUT] = {"usb-timeout", 1, 0, 0},
 		[OPT_END]        = {0, 0, 0, 0}
 	};
 	// parse command line args
@@ -318,6 +323,9 @@ int main(int argc, char **argv)
 			case OPT_DOWNLOAD_SIGNED_MSGS:
 				download_signed_msgs = true;
 				break;
+			case OPT_USB_TIMEOUT:
+				usb_timeout = strtoul(optarg, NULL, 0);
+				break;
 			case OPT_HELP:
 			default:
 				usage(argv[0]);
diff --git a/src/usb.c b/src/usb.c
index 8a367426b29c..fbce09f94da9 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -39,6 +39,7 @@
 
 #define USB_XFER_MAX 4096
 
+uint32_t usb_timeout = USB_TIMEOUT;
 //
 // returns 1 if the specified usb device matches the vendor id
 //
@@ -307,7 +308,7 @@ int usb_write(usb_device_t *usb, uint8_t *buf, int len)
 	while (len) {
 		chunk_size = MIN(len, USB_XFER_MAX);
 		ret = libusb_bulk_transfer(usb->handle, usb->endpt_out, buf,
-					   chunk_size, &actual_chunk, USB_TIMEOUT);
+					   chunk_size, &actual_chunk, usb_timeout);
 		if (ret != LIBUSB_SUCCESS) {
 			dprintf("libusb write failure: %d: %s\n", ret, libusb_error_name(ret));
 			return EIO;
@@ -334,7 +335,7 @@ int usb_read(usb_device_t *usb, uint8_t *buf, int len, int *actual_len)
 	while (len) {
 		chunk_size = MIN(len, USB_XFER_MAX);
 		ret = libusb_bulk_transfer(usb->handle, usb->endpt_in, buf,
-					   chunk_size, &actual_chunk, USB_TIMEOUT);
+					   chunk_size, &actual_chunk, usb_timeout);
 		if (ret != LIBUSB_SUCCESS) {
 			dprintf("libusb read failure: %d: %s\n", ret, libusb_error_name(ret));
 			return EIO;
-- 
1.9.1

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

* Re: [tegrarcm PATCH V2 4/4] Add option --usb-timeout=<value>
       [not found]     ` <1457744552-30966-5-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2016-03-14 18:31       ` Stephen Warren
  0 siblings, 0 replies; 14+ messages in thread
From: Stephen Warren @ 2016-03-14 18:31 UTC (permalink / raw)
  To: Jimmy Zhang
  Cc: amartin-DDmLM1+adcrQT0dZR+AlfA, swarren-DDmLM1+adcrQT0dZR+AlfA,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 03/11/2016 06:02 PM, Jimmy Zhang wrote:
> RCM communication sometimes fails if the USB timeout is short. The default
> timeout is 1000ms. Increase the timeout value to avoid this issue. The exact
> cause is not yet diagnosed.

This patch has been modified to add a cmdline option to specify the 
timeout, rather than increasing the default timeout, so the commit 
description needs to be updated.

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

* Re: [tegrarcm PATCH V2 1/4] Add support for production devices secured with PKC
       [not found]     ` <1457744552-30966-2-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2016-03-14 18:39       ` Stephen Warren
       [not found]         ` <56E70576.3050000-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Stephen Warren @ 2016-03-14 18:39 UTC (permalink / raw)
  To: Jimmy Zhang
  Cc: amartin-DDmLM1+adcrQT0dZR+AlfA, swarren-DDmLM1+adcrQT0dZR+AlfA,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 03/11/2016 06:02 PM, Jimmy Zhang wrote:
> From: Alban Bedel <alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
>
> 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>
> Signed-off-by: Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>
> --

Nit: That needs to be --- not -- for git to recognize it as the end of 
the commit description.

> Changelog:
> V3: * Download bl sig only when op_mode is SECURE_PKC
>      * Generate cmac_hash even when --pkc option is present so that
>        an unfused board can still run with --pkc option.
>      * Added Error Check on key length

Nit: The message subject says "V2".

In all the patches in this series, please make sure that all the files 
you edit contain an NVIDIA copyright message which references the year 
2016. If not, please add/update the message.

> diff --git a/src/rsa-pss.cpp b/src/rsa-pss.cpp

> +extern "C" int rsa_pss_sign_file(const char *key_file, const char *msg_file,
> +			unsigned char *sig_buf)

> +		int length = signature.length();
> +		// error check
> +		if (length != RCM_RSA_SIG_SIZE)
> +			throw std::length_error("incorrect rsa key length");

I think that check is required in rsa_pss_sign() too.

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

* Re: [tegrarcm PATCH V2 2/4] Add option --gen-signed-msgs and --signed-msgs-file to generate signed blobs
       [not found]     ` <1457744552-30966-3-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2016-03-14 18:58       ` Stephen Warren
  0 siblings, 0 replies; 14+ messages in thread
From: Stephen Warren @ 2016-03-14 18:58 UTC (permalink / raw)
  To: Jimmy Zhang
  Cc: amartin-DDmLM1+adcrQT0dZR+AlfA, swarren-DDmLM1+adcrQT0dZR+AlfA,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 03/11/2016 06:02 PM, Jimmy Zhang wrote:
> This feature allows generation of signed blobs that can later be used
> to communicate with a PKC-enabled Tegra device without access to the
> PKC. Option --bootloader, --soc and --pkc are also required when generating
> the blob.
>
> Example:
> tegrarcm --gen-signed-msgs --signed-msgs-file rel_1001.bin \
>          --bootloader u-boot.bin --loadaddr 0x83d88000 --soc 124 \
>          --pkc rsa_priv.der
>
> Where generated signed message files are:
>
> a) rel_1001.bin.qry
> b) rel_1001.bin.ml
> c) rel_1001.bin.bl

> diff --git a/src/main.c b/src/main.c

> +#define FILENAME_MAX_SIZE 256

Why not use the standard PATH_MAX define?

> +static bool is_supported_soc(uint32_t soc, uint16_t *devid)
> +{
> +	struct _soc_to_devid {

You can simply write "struct {" there.

> +		uint32_t soc;
> +		uint16_t usb_devid;
> +	} soc_to_devid[] = {
> +		{114,	USB_DEVID_NVIDIA_TEGRA114},
> +		{124,	USB_DEVID_NVIDIA_TEGRA124},
> +	};

More SoCs are supported than that; the function name seems a bit 
generic. Perhaps is_soc_supported_for_signed_msgs()?

>   static int initialize_rcm(uint16_t devid, usb_device_t *usb,
> -			const char *pkc_keyfile)
> +			const char *pkc_keyfile, const char *signed_msgs_file)

> +	char query_version_rcm_filename[FILENAME_MAX_SIZE];

You can probably move that inside the "if (signed_msgs_file)" block to 
reduce the scope. But ignore this comment if it would complicate the 
next patch since the variable is used in more code there (I haven't 
looked at that patch yet).

> @@ -466,7 +634,7 @@ static int initialize_miniloader(uint16_t devid, usb_device_t *usb, char *mlfile
>   	uint32_t miniloader_size;
>   	uint32_t miniloader_entry;
>
> -	// use prebuilt miniloader if not loading from a file
> +	// if using miniloader from an exteranl file

Nit: external

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

* Re: [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to download signed blobs
       [not found]     ` <1457744552-30966-4-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2016-03-14 19:17       ` Stephen Warren
       [not found]         ` <56E70E4F.80307-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Stephen Warren @ 2016-03-14 19:17 UTC (permalink / raw)
  To: Jimmy Zhang
  Cc: amartin-DDmLM1+adcrQT0dZR+AlfA, swarren-DDmLM1+adcrQT0dZR+AlfA,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 03/11/2016 06:02 PM, Jimmy Zhang wrote:
> This feature allows user to download signed messages to devices
> secured with PKC.
>
> Example:
> tegrarcm --download-signed-msgs --signed-msgs-file rel_1001.bin \
>     --bct=jetson-tk1-bct.bct --bootloader=u-boot.bin --loadaddr=0x83d88000
>
> Where the following blob files are downloaded to device sequentially:
>
> a) rel_1001.bin.qry
> b) rel_1001.bin.ml
> c) rel_1001.bin.bl

> @@ -1083,14 +1198,24 @@ static int download_bootloader(nv3p_handle_t h3p, char *filename,
>   			}
>
>   			ret = nv3p_data_send(h3p, rsa_pss_sig, sizeof(rsa_pss_sig));
> -			if (ret) {
> -				dprintf("error sending bootloader signature\n");
> +		}

Doesn't this change (moving that error dprintf later) mean that any 
error there potentially won't be reported, since the code below can 
overwrite "ret" before the moved copy of that check? I'm not convinced 
the code should be moved.

> +		/* download bl's rsa_pss_sig */
> +		if (signed_msgs_file) {
> +			char signature_filename[FILENAME_MAX_SIZE];
> +
> +			ret = create_name_string(signature_filename,
> +						signed_msgs_file, ".bl");
> +			if (ret)
>   				return ret;
> +
> +			// send the bootloader file
> +			ret = send_file(h3p, signature_filename);
> +		}
> +
> +		if (ret) {
> +			dprintf("error sending bootloader signature\n");
> +			return ret;
>   		}
>   	}

The resultant logic here seems to do the following for chips in 
SECURE_PKC mode:

a) Always calculate and send the PKC.
b) if (signed_msgs_file), send the content of that file
c) continue to send the bootloader

I would have expected either (a) or (b) to happen, but never both.

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

* RE: [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to download signed blobs
       [not found]         ` <56E70E4F.80307-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2016-03-14 20:01           ` Jimmy Zhang
       [not found]             ` <41214cca62234ce1b7f238fa8fcb71aa-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Jimmy Zhang @ 2016-03-14 20:01 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Allen Martin, Stephen Warren,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA



> -----Original Message-----
> From: Stephen Warren [mailto:swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org]
> Sent: Monday, March 14, 2016 12:18 PM
> To: Jimmy Zhang
> Cc: Allen Martin; Stephen Warren; alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org; linux-
> tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Subject: Re: [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to
> download signed blobs
> 
> On 03/11/2016 06:02 PM, Jimmy Zhang wrote:
> > This feature allows user to download signed messages to devices
> > secured with PKC.
> >
> > Example:
> > tegrarcm --download-signed-msgs --signed-msgs-file rel_1001.bin \
> >     --bct=jetson-tk1-bct.bct --bootloader=u-boot.bin
> > --loadaddr=0x83d88000
> >
> > Where the following blob files are downloaded to device sequentially:
> >
> > a) rel_1001.bin.qry
> > b) rel_1001.bin.ml
> > c) rel_1001.bin.bl
> 
> > @@ -1083,14 +1198,24 @@ static int download_bootloader(nv3p_handle_t
> h3p, char *filename,
> >   			}
> >
> >   			ret = nv3p_data_send(h3p, rsa_pss_sig,
> sizeof(rsa_pss_sig));
> > -			if (ret) {
> > -				dprintf("error sending bootloader
> signature\n");
> > +		}
> 
> Doesn't this change (moving that error dprintf later) mean that any error
> there potentially won't be reported, since the code below can overwrite
> "ret" before the moved copy of that check? I'm not convinced the code
> should be moved.
> 

No. This is because only one can be true between pkc_keyfile and signed_msgs_file. Ie, either when signing on fly or signed without keyfile option. This logic is ensured in main when checking command line options.
  
> > +		/* download bl's rsa_pss_sig */
> > +		if (signed_msgs_file) {
> > +			char signature_filename[FILENAME_MAX_SIZE];
> > +
> > +			ret = create_name_string(signature_filename,
> > +						signed_msgs_file, ".bl");
> > +			if (ret)
> >   				return ret;
> > +
> > +			// send the bootloader file

The comment will be changed to "send the bootloader's signature file"
 
> > +			ret = send_file(h3p, signature_filename);
> > +		}
> > +
> > +		if (ret) {
> > +			dprintf("error sending bootloader signature\n");
> > +			return ret;
> >   		}
> >   	}
> 
> The resultant logic here seems to do the following for chips in SECURE_PKC
> mode:
> 
> a) Always calculate and send the PKC.
> b) if (signed_msgs_file), send the content of that file
> c) continue to send the bootloader
> 
> I would have expected either (a) or (b) to happen, but never both.

It is true. The answer is the same as above. Only one can be true between pkc_keyfile and signed_msgs_file.

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

* Re: [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to download signed blobs
       [not found]             ` <41214cca62234ce1b7f238fa8fcb71aa-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
@ 2016-03-14 20:16               ` Stephen Warren
       [not found]                 ` <56E71C30.7030503-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Stephen Warren @ 2016-03-14 20:16 UTC (permalink / raw)
  To: Jimmy Zhang
  Cc: Allen Martin, Stephen Warren,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 03/14/2016 02:01 PM, Jimmy Zhang wrote:
>
>
>> -----Original Message-----
>> From: Stephen Warren [mailto:swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org]
>> Sent: Monday, March 14, 2016 12:18 PM
>> To: Jimmy Zhang
>> Cc: Allen Martin; Stephen Warren; alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org; linux-
>> tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Subject: Re: [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to
>> download signed blobs
>>
>> On 03/11/2016 06:02 PM, Jimmy Zhang wrote:
>>> This feature allows user to download signed messages to devices
>>> secured with PKC.
>>>
>>> Example:
>>> tegrarcm --download-signed-msgs --signed-msgs-file rel_1001.bin \
>>>      --bct=jetson-tk1-bct.bct --bootloader=u-boot.bin
>>> --loadaddr=0x83d88000
>>>
>>> Where the following blob files are downloaded to device sequentially:
>>>
>>> a) rel_1001.bin.qry
>>> b) rel_1001.bin.ml
>>> c) rel_1001.bin.bl
>>
>>> @@ -1083,14 +1198,24 @@ static int download_bootloader(nv3p_handle_t
>> h3p, char *filename,
>>>    			}
>>>
>>>    			ret = nv3p_data_send(h3p, rsa_pss_sig,
>> sizeof(rsa_pss_sig));
>>> -			if (ret) {
>>> -				dprintf("error sending bootloader
>> signature\n");
>>> +		}
>>
>> Doesn't this change (moving that error dprintf later) mean that any error
>> there potentially won't be reported, since the code below can overwrite
>> "ret" before the moved copy of that check? I'm not convinced the code
>> should be moved.
>>
>
> No. This is because only one can be true between pkc_keyfile and signed_msgs_file. Ie, either when signing on fly or signed without keyfile option. This logic is ensured in main when checking command line options.

Ah, I guess that makes sense. Reading the diff is a bit more confusing 
than the resultant code. So, this patch,

Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

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

* RE: [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to download signed blobs
       [not found]                 ` <56E71C30.7030503-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2016-03-14 20:24                   ` Jimmy Zhang
  0 siblings, 0 replies; 14+ messages in thread
From: Jimmy Zhang @ 2016-03-14 20:24 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Allen Martin, Stephen Warren,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA



> -----Original Message-----
> From: Stephen Warren [mailto:swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org]
> Sent: Monday, March 14, 2016 1:17 PM
> To: Jimmy Zhang
> Cc: Allen Martin; Stephen Warren; alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org; linux-
> tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Subject: Re: [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to
> download signed blobs
> 
> On 03/14/2016 02:01 PM, Jimmy Zhang wrote:
> >
> >
> >> -----Original Message-----
> >> From: Stephen Warren [mailto:swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org]
> >> Sent: Monday, March 14, 2016 12:18 PM
> >> To: Jimmy Zhang
> >> Cc: Allen Martin; Stephen Warren; alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org;
> >> linux- tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> >> Subject: Re: [tegrarcm PATCH V2 3/4] Add option
> >> --download-signed-msgs to download signed blobs
> >>
> >> On 03/11/2016 06:02 PM, Jimmy Zhang wrote:
> >>> This feature allows user to download signed messages to devices
> >>> secured with PKC.
> >>>
> >>> Example:
> >>> tegrarcm --download-signed-msgs --signed-msgs-file rel_1001.bin \
> >>>      --bct=jetson-tk1-bct.bct --bootloader=u-boot.bin
> >>> --loadaddr=0x83d88000
> >>>
> >>> Where the following blob files are downloaded to device sequentially:
> >>>
> >>> a) rel_1001.bin.qry
> >>> b) rel_1001.bin.ml
> >>> c) rel_1001.bin.bl
> >>
> >>> @@ -1083,14 +1198,24 @@ static int
> download_bootloader(nv3p_handle_t
> >> h3p, char *filename,
> >>>    			}
> >>>
> >>>    			ret = nv3p_data_send(h3p, rsa_pss_sig,
> >> sizeof(rsa_pss_sig));
> >>> -			if (ret) {
> >>> -				dprintf("error sending bootloader
> >> signature\n");
> >>> +		}
> >>
> >> Doesn't this change (moving that error dprintf later) mean that any
> >> error there potentially won't be reported, since the code below can
> >> overwrite "ret" before the moved copy of that check? I'm not
> >> convinced the code should be moved.
> >>
> >
> > No. This is because only one can be true between pkc_keyfile and
> signed_msgs_file. Ie, either when signing on fly or signed without keyfile
> option. This logic is ensured in main when checking command line options.
> 
> Ah, I guess that makes sense. Reading the diff is a bit more confusing than
> the resultant code. So, this patch,
> 

OK. I think I should add some comments here. Also, add error case if neither conditions are true.

> Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

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

* RE: [tegrarcm PATCH V2 1/4] Add support for production devices secured with PKC
       [not found]         ` <56E70576.3050000-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2016-03-15  0:51           ` Jimmy Zhang
       [not found]             ` <f0f79d636da2412f8dad980e4114a4c8-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Jimmy Zhang @ 2016-03-15  0:51 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Allen Martin, Stephen Warren,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA



> -----Original Message-----
> From: Stephen Warren [mailto:swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org]
> Sent: Monday, March 14, 2016 11:40 AM
> To: Jimmy Zhang
> Cc: Allen Martin; Stephen Warren; alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org; linux-
> tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Subject: Re: [tegrarcm PATCH V2 1/4] Add support for production devices
> secured with PKC
> 
> On 03/11/2016 06:02 PM, Jimmy Zhang wrote:
> > From: Alban Bedel <alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
> >
> > 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>
> > Signed-off-by: Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> >
> > --
> 
> Nit: That needs to be --- not -- for git to recognize it as the end of the commit
> description.
> 
> > Changelog:
> > V3: * Download bl sig only when op_mode is SECURE_PKC
> >      * Generate cmac_hash even when --pkc option is present so that
> >        an unfused board can still run with --pkc option.
> >      * Added Error Check on key length
> 
> Nit: The message subject says "V2".
> 
> In all the patches in this series, please make sure that all the files you edit
> contain an NVIDIA copyright message which references the year 2016. If not,
> please add/update the message.
> 
> > diff --git a/src/rsa-pss.cpp b/src/rsa-pss.cpp
> 
> > +extern "C" int rsa_pss_sign_file(const char *key_file, const char
> *msg_file,
> > +			unsigned char *sig_buf)
> 
> > +		int length = signature.length();
> > +		// error check
> > +		if (length != RCM_RSA_SIG_SIZE)
> > +			throw std::length_error("incorrect rsa key length");
> 
> I think that check is required in rsa_pss_sign() too.

I checked key's modulus length there. Once it passes, key's length should be correct.

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

* Re: [tegrarcm PATCH V2 1/4] Add support for production devices secured with PKC
       [not found]             ` <f0f79d636da2412f8dad980e4114a4c8-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
@ 2016-03-15 16:20               ` Stephen Warren
  0 siblings, 0 replies; 14+ messages in thread
From: Stephen Warren @ 2016-03-15 16:20 UTC (permalink / raw)
  To: Jimmy Zhang
  Cc: Allen Martin, Stephen Warren,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 03/14/2016 06:51 PM, Jimmy Zhang wrote:
> Stephen Warren wrote atMonday, March 14, 2016 11:40 AM:
>> On 03/11/2016 06:02 PM, Jimmy Zhang wrote:
>>> From: Alban Bedel <alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
>>>
>>> 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.

>>> diff --git a/src/rsa-pss.cpp b/src/rsa-pss.cpp
>>
>>> +extern "C" int rsa_pss_sign_file(const char *key_file, const char
>> *msg_file,
>>> +			unsigned char *sig_buf)
>>
>>> +		int length = signature.length();
>>> +		// error check
>>> +		if (length != RCM_RSA_SIG_SIZE)
>>> +			throw std::length_error("incorrect rsa key length");
>>
>> I think that check is required in rsa_pss_sign() too.
>
> I checked key's modulus length there. Once it passes, key's length should be correct.

Aren't the two functions essentially identical, the only difference 
being that one signs an in-memory buffer and the other signs data read 
from a file. As such, I don't see why they would be coded any 
differently, apart from the file IO portion (and indeed, why doesn't 
rsa_pss_sign_file() simply read file data into memory, then call the 
other function?

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

end of thread, other threads:[~2016-03-15 16:20 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-12  1:02 [tegrarcm PATCH V2 0/4] Add support for flashing PKC secured board Jimmy Zhang
     [not found] ` <1457744552-30966-1-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-12  1:02   ` [tegrarcm PATCH V2 1/4] Add support for production devices secured with PKC Jimmy Zhang
     [not found]     ` <1457744552-30966-2-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-14 18:39       ` Stephen Warren
     [not found]         ` <56E70576.3050000-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-03-15  0:51           ` Jimmy Zhang
     [not found]             ` <f0f79d636da2412f8dad980e4114a4c8-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
2016-03-15 16:20               ` Stephen Warren
2016-03-12  1:02   ` [tegrarcm PATCH V2 2/4] Add option --gen-signed-msgs and --signed-msgs-file to generate signed blobs Jimmy Zhang
     [not found]     ` <1457744552-30966-3-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-14 18:58       ` Stephen Warren
2016-03-12  1:02   ` [tegrarcm PATCH V2 3/4] Add option --download-signed-msgs to download " Jimmy Zhang
     [not found]     ` <1457744552-30966-4-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-14 19:17       ` Stephen Warren
     [not found]         ` <56E70E4F.80307-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-03-14 20:01           ` Jimmy Zhang
     [not found]             ` <41214cca62234ce1b7f238fa8fcb71aa-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
2016-03-14 20:16               ` Stephen Warren
     [not found]                 ` <56E71C30.7030503-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-03-14 20:24                   ` Jimmy Zhang
2016-03-12  1:02   ` [tegrarcm PATCH V2 4/4] Add option --usb-timeout=<value> Jimmy Zhang
     [not found]     ` <1457744552-30966-5-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-14 18:31       ` Stephen Warren

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.