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
next prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox