All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
To: amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org,
	swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org,
	alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Jimmy Zhang <jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Subject: [tegrarcm PATCH v1 2/4] Add option --ml_rcm <rcm_ml_blob>
Date: Fri, 4 Mar 2016 15:44:45 -0800	[thread overview]
Message-ID: <1457135087-967-3-git-send-email-jimmzhang@nvidia.com> (raw)
In-Reply-To: <1457135087-967-1-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

This option along with "--pkc <keyfile>" allows user to generate signed
query version rcm, miniloader rcm and signed bootloader (flasher). With
these signed blob, user will then be able to run tegrarcm on a fused system
without keyfile.

Command syntax:
 $ ./tegrarcm --ml_rcm <ml_rcm_blob> --pkc <keyfile>

Example:
1. connect usb cable to recovery mode usb port
2. put target in recovery mode
3. run command as below:
$ sudo ./tegrarcm --ml_rcm t124_ml_rcm.bin --pkc rsa_priv.der

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

diff --git a/src/main.c b/src/main.c
index fedeab2e1402..8a5a7680837e 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 *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 *keyfile, const char *ml_rcm_file);
+static int initialize_miniloader(uint16_t devid, usb_device_t *usb,
+		char *mlfile, uint32_t mlentry, const char *ml_rcm_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 *ml_rcm_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,7 @@ 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 *keyfile);
 
 enum cmdline_opts {
 	OPT_BCT,
@@ -87,6 +94,7 @@ enum cmdline_opts {
 #ifdef HAVE_USB_PORT_MATCH
 	OPT_USBPORTPATH,
 #endif
+	OPT_CREATE_ML_RCM,
 	OPT_END,
 };
 
@@ -129,7 +137,8 @@ static void usage(char *progname)
 	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, "\t--ml_rcm=ml_rcm_file\n");
+	fprintf(stderr, "\t\tSave rcm message prefixed miniloader\n");
 	fprintf(stderr, "\n");
 }
 
@@ -189,6 +198,7 @@ int main(int argc, char **argv)
 	uint8_t match_ports[PORT_MATCH_MAX_PORTS];
 	int match_ports_len;
 #endif
+	char *ml_rcm_file = NULL;
 
 	static struct option long_options[] = {
 		[OPT_BCT]        = {"bct", 1, 0, 0},
@@ -203,6 +213,7 @@ int main(int argc, char **argv)
 #ifdef HAVE_USB_PORT_MATCH
 		[OPT_USBPORTPATH]  = {"usb-port-path", 1, 0, 0},
 #endif
+		[OPT_CREATE_ML_RCM] = {"ml_rcm", 1, 0, 0},
 		[OPT_END]        = {0, 0, 0, 0}
 	};
 
@@ -249,6 +260,9 @@ int main(int argc, char **argv)
 				match_port = true;
 				break;
 #endif
+			case OPT_CREATE_ML_RCM:
+				ml_rcm_file = optarg;
+				break;
 			case OPT_HELP:
 			default:
 				usage(argv[0]);
@@ -268,29 +282,43 @@ int main(int argc, char **argv)
 		else {
 			fprintf(stderr, "%s: Unknown command line argument: %s\n",
 				argv[0], argv[optind]);
-			usage(argv[0]);
-			exit(EXIT_FAILURE);
+			goto usage_exit;
 		}
 		optind++;
 	}
 
-	if (bctfile == NULL) {
+	/* error check */
+	if (ml_rcm_file) {
+		/* ml_rcm option must also come along with pkc option */
+		if (pkc == NULL) {
+			fprintf(stderr, "PKC key file must be specified\n");
+			goto usage_exit;
+		}
+
+		/* ml_rcm option must also come along with bootloader option */
+		if (blfile == NULL) {
+			fprintf(stderr, "bootloader file must be specified\n");
+			goto usage_exit;
+		}
+	}
+
+	/* specify bct file if no ml_rcm option */
+	if ((bctfile == NULL) && (ml_rcm_file == NULL)) {
 		fprintf(stderr, "BCT file must be specified\n");
-		usage(argv[0]);
-		exit(EXIT_FAILURE);
+		goto usage_exit;
 	}
-	printf("bct file: %s\n", bctfile);
 
-	if (!do_read) {
+	if (bctfile)
+		printf("bct file: %s\n", bctfile);
+
+	if ((ml_rcm_file == NULL) && !do_read) {
 		if (blfile == NULL) {
 			fprintf(stderr, "bootloader file must be specified\n");
-			usage(argv[0]);
-			exit(EXIT_FAILURE);
+			goto usage_exit;
 		}
 		if (loadaddr == 0) {
 			fprintf(stderr, "loadaddr must be specified\n");
-			usage(argv[0]);
-			exit(EXIT_FAILURE);
+			goto usage_exit;
 		}
 		if (entryaddr == 0) {
 			entryaddr = loadaddr;
@@ -320,17 +348,25 @@ int main(int argc, char **argv)
 			error(1, errno, "USB read truncated");
 
 		// initialize rcm
-		ret2 = initialize_rcm(devid, usb, pkc);
+		ret2 = initialize_rcm(devid, usb, pkc, ml_rcm_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,
+						ml_rcm_file);
 		if (ret2)
 			error(1, errno, "error initializing miniloader");
 
+		/* if creating ml_rcm, sign bl as well, then exit */
+		if (ml_rcm_file) {
+			sign_blob(blfile, pkc);
+			goto done;
+		}
+
 		// 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
@@ -384,18 +420,59 @@ int main(int argc, char **argv)
 		error(1, ret, "error downloading bootloader: %s", blfile);
 
 	nv3p_close(h3p);
+done:
 	usb_close(usb);
+	return 0;
+
+usage_exit:
+	usage(argv[0]);
+	exit(EXIT_FAILURE);
+}
 
+static int create_name_string(const char *in, char *out, char *ext)
+{
+	int len = strlen(in);
+
+	if ((len + strlen(ext) + 1) >  FILENAME_MAX_SIZE) {
+		fprintf(stderr, "error: name length %zu bytes exceed "
+				"limits for file %s\n",
+			len + strlen(ext) + 1 - FILENAME_MAX_SIZE, in);
+		return -1;
+	}
+	sprintf(out, "%s%s\n", in, ext);
+	*(out + len + strlen(ext)) = 0x0;
 	return 0;
 }
 
-static int initialize_rcm(uint16_t devid, usb_device_t *usb, const char *keyfile)
+static int save_to_file(const char *filename, const uint8_t *msg_buff,
+			const uint32_t length)
 {
-	int ret;
+	FILE *raw_file;
+
+	printf("Create file %s...\n", filename);
+
+	raw_file = fopen(filename, "wb");
+	if (raw_file == NULL) {
+		fprintf(stderr, "Error opening raw file %s.\n", filename);
+		return -1;
+	}
+
+	fwrite(msg_buff, 1, length, raw_file);
+	fclose(raw_file);
+
+	return 0;
+}
+
+static int initialize_rcm(uint16_t devid, usb_device_t *usb,
+			const char *keyfile, const char *ml_rcm_file)
+{
+	int ret = 0;
 	uint8_t *msg_buff;
 	int msg_len;
 	uint32_t status;
 	int actual_len;
+	#define query_rcm_ext	".qry"
+	char query_filename[FILENAME_MAX_SIZE];
 
 	// initialize RCM
 	if ((devid & 0xff) == USB_DEVID_NVIDIA_TEGRA20 ||
@@ -420,6 +497,18 @@ static int initialize_rcm(uint16_t devid, usb_device_t *usb, const char *keyfile
 	// create query version message
 	rcm_create_msg(RCM_CMD_QUERY_RCM_VERSION, NULL, 0, NULL, 0, &msg_buff);
 
+	/* create query version rcm file */
+	if (ml_rcm_file) {
+		ret = create_name_string(ml_rcm_file, query_filename,
+					query_rcm_ext);
+		if (ret)
+			goto done;
+
+		ret = save_to_file(query_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) {
@@ -429,28 +518,31 @@ static int initialize_rcm(uint16_t devid, usb_device_t *usb, const char *keyfile
 	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 *ml_rcm_file)
 {
 	int fd;
 	struct stat sb;
@@ -504,6 +596,12 @@ static int initialize_miniloader(uint16_t devid, usb_device_t *usb, char *mlfile
 			return ENODEV;
 		}
 	}
+
+	if (ml_rcm_file) {
+		return create_miniloader_rcm(miniloader, miniloader_size,
+				miniloader_entry, ml_rcm_file);
+	}
+
 	printf("downloading miniloader to target at address 0x%x (%d bytes)...\n",
 		miniloader_entry, miniloader_size);
 	ret = download_miniloader(usb, miniloader, miniloader_size,
@@ -629,6 +727,24 @@ fail:
 	return ret;
 }
 
+static int create_miniloader_rcm(uint8_t *miniloader, uint32_t size,
+			uint32_t entry, const char *ml_rcm_file)
+{
+	uint8_t *msg_buff;
+	int ret = 0;
+
+	// create RCM_CMD_DL_MINILOADER blob
+	rcm_create_msg(RCM_CMD_DL_MINILOADER,
+		       (uint8_t *)&entry, sizeof(entry), miniloader, size,
+		       &msg_buff);
+
+	// write to binary file
+	dprintf("Write miniloader rcm to %s\n", ml_rcm_file);
+
+	ret = save_to_file(ml_rcm_file, msg_buff, rcm_get_msg_len(msg_buff));
+	free(msg_buff);
+	return ret;
+}
 
 static int download_miniloader(usb_device_t *usb, uint8_t *miniloader,
 			       uint32_t size, uint32_t entry)
@@ -891,3 +1007,29 @@ static int download_bootloader(nv3p_handle_t h3p, char *filename,
 
 	return 0;
 }
+
+static int sign_blob(const char *blob_filename, const char *keyfile)
+{
+	int ret;
+	uint8_t rsa_pss_sig[2048 / 8];
+
+	#define sign_ext	".sig"
+	char signature_filename[FILENAME_MAX_SIZE];
+
+	ret = rsa_pss_sign_file(keyfile, blob_filename, rsa_pss_sig);
+	if (ret) {
+		fprintf(stderr, "error signing %s with %s\n",
+			blob_filename, keyfile);
+		return ret;
+	}
+
+	/* save signature to blob_filename.sig */
+	ret = create_name_string(blob_filename, signature_filename,
+				sign_ext);
+	if (ret)
+		return ret;
+
+	ret = save_to_file(signature_filename, rsa_pss_sig,
+				sizeof(rsa_pss_sig));
+	return ret;
+}
diff --git a/src/rcm.c b/src/rcm.c
index c7f0f8dddecc..cdf81309ae96 100644
--- a/src/rcm.c
+++ b/src/rcm.c
@@ -202,11 +202,12 @@ 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;
 }
 
@@ -226,11 +227,10 @@ 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;
 }
-- 
1.9.1

  parent reply	other threads:[~2016-03-04 23:44 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-04 23:44 [tegrarcm PATCH v1 0/4] Add flashing support for T124 rsa fused board Jimmy Zhang
     [not found] ` <1457135087-967-1-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-04 23:44   ` [tegrarcm PATCH v1 1/4] Add option "--pkc" Jimmy Zhang
     [not found]     ` <1457135087-967-2-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-05  1:43       ` Allen Martin
2016-03-07 19:55       ` Stephen Warren
     [not found]         ` <56DDDCC8.9090803-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-03-09  0:50           ` Jimmy Zhang
     [not found]             ` <6dc28718c5ec4d4aba4bcafcf36409be-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
2016-03-09 17:32               ` Stephen Warren
2016-03-04 23:44   ` Jimmy Zhang [this message]
     [not found]     ` <1457135087-967-3-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-05  1:25       ` [tegrarcm PATCH v1 2/4] Add option --ml_rcm <rcm_ml_blob> Allen Martin
     [not found]         ` <20160305012506.GA19189-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-05  2:35           ` Jimmy Zhang
     [not found]             ` <b47263cc6b5a412bbbb9cd4a17d223cf-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
2016-03-07  8:54               ` Thierry Reding
2016-03-07 20:15       ` Stephen Warren
     [not found]         ` <56DDE16A.8030809-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-03-09  1:21           ` Jimmy Zhang
     [not found]             ` <efa82104830b489a8ebe29238bb48034-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
2016-03-09 17:35               ` Stephen Warren
2016-03-04 23:44   ` [tegrarcm PATCH v1 3/4] Add option --signed Jimmy Zhang
     [not found]     ` <1457135087-967-4-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-07  8:58       ` Thierry Reding
2016-03-07 20:31       ` Stephen Warren
     [not found]         ` <56DDE53D.4060206-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-03-09  0:36           ` Jimmy Zhang
     [not found]             ` <90950f4d7098476891feda7e5e803cfa-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
2016-03-09 17:29               ` Stephen Warren
     [not found]                 ` <56E05D75.5050707-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-03-09 21:01                   ` Jimmy Zhang
     [not found]                     ` <efdc080b4a0f4bd4a8a736d947417acd-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
2016-03-09 21:03                       ` Stephen Warren
2016-03-04 23:44   ` [tegrarcm PATCH v1 4/4] Increate USB timeout value Jimmy Zhang
     [not found]     ` <1457135087-967-5-git-send-email-jimmzhang-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-05  1:46       ` Allen Martin
     [not found]         ` <20160305014644.GC19189-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-05  2:39           ` Jimmy Zhang
2016-03-07 19:39       ` Stephen Warren
     [not found]         ` <56DDD90B.1040802-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-03-09  1:41           ` Jimmy Zhang
     [not found]             ` <973e4d88a8a24062964655a6ec3b2c71-wO81nVYWzR7YuxH7O460wFaTQe2KTcn/@public.gmane.org>
2016-03-09 17:41               ` Stephen Warren
     [not found]                 ` <56E06042.2060604-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-03-09 19:56                   ` Jimmy Zhang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1457135087-967-3-git-send-email-jimmzhang@nvidia.com \
    --to=jimmzhang-ddmlm1+adcrqt0dzr+alfa@public.gmane.org \
    --cc=alban.bedel-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org \
    --cc=amartin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.