diff mbox

[cbootimage,v1,1/8] Enable --update | -u option support for t210

Message ID 1441228760-26042-2-git-send-email-jimmzhang@nvidia.com
State Superseded, archived
Headers show

Commit Message

jimmzhang Sept. 2, 2015, 9:19 p.m. UTC
Added routines to allow updating pkc pubkey and rsa pss signatures.

Specifically, added following configuration keywords:

   RsaKeyModulus: set pubkey
   RsaPssSigBl:   set bootloader rsa pss signature
   RsaPssSigBct:  set bct rsa pss signature

Sample Configuration file update_bl_sig.cfg
   RsaKeyModulus = pubkey.mod;
   RsaPssSigBl = bl.sig;

Commandline example:
   $ cbootimage -s tegra210 -u update_bl_sig.cfg image.bin image.bin-bl-signed

Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
---
 src/cbootimage.c           |  8 +++++---
 src/cbootimage.h           |  5 +++++
 src/parse.c                | 35 +++++++++++++++++++++++++++++++++++
 src/parse.h                |  4 ++++
 src/set.c                  | 38 ++++++++++++++++++++++++++++++++++++++
 src/set.h                  |  5 +++++
 src/t210/nvbctlib_t210.c   | 20 +++++++++++++++++++-
 src/t210/nvboot_bct_t210.h |  2 --
 8 files changed, 111 insertions(+), 6 deletions(-)

Comments

Stephen Warren Sept. 21, 2015, 7:55 p.m. UTC | #1
On 09/02/2015 03:19 PM, Jimmy Zhang wrote:
> Added routines to allow updating pkc pubkey and rsa pss signatures.

"pkc" and "pss" should be explained.

> Specifically, added following configuration keywords:
>
>     RsaKeyModulus: set pubkey
>     RsaPssSigBl:   set bootloader rsa pss signature
>     RsaPssSigBct:  set bct rsa pss signature
>
> Sample Configuration file update_bl_sig.cfg
>     RsaKeyModulus = pubkey.mod;
>     RsaPssSigBl = bl.sig;

Oh, RsaKeyModulus is a file not an inline value? Better put "File" or 
"Filename" into the keywords then?

How can the user generate the value for RsaPssSigBct if this tool is 
generating the BCT? Why doesn't this tool generate the signatures itself 
internally?

> Commandline example:
>     $ cbootimage -s tegra210 -u update_bl_sig.cfg image.bin image.bin-bl-signed

This commit appears to be two unrelated changes squashed into one. This 
commit description is entirely unrelated to the commit subject for example.

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

>   	printf("    -u|--update           Copy input image data and update bct\n");
>   	printf("                          configs into new image file.\n");
> -	printf("                          This feature is only for tegra114/124.\n");
> +	printf("                          This feature is only for tegra114/124/210.\n");

I assume this feature will be enabled by default going forward. I think 
it'd be better to rephrase that as "This feature is not supported on 
Tegra20/30".

BTW, is there a particular reason the feature won't work there? If not, 
can we simply enable it for all chips?

>   		if (context->boot_data_version != BOOTDATA_VERSION_T114 &&
> -			context->boot_data_version != BOOTDATA_VERSION_T124) {
> -			printf("Update image feature is only for Tegra114 and Tegra124.\n");
> +			context->boot_data_version != BOOTDATA_VERSION_T124 &&
> +			context->boot_data_version != BOOTDATA_VERSION_T210) {
> +			printf("Update image feature is only for Tegra114, Tegra124"
> +				" and Tegra210.\n");
>   			return -EINVAL;

To avoid that if expanding forever, can it not check for == T20/30 
rather than != all other chips?


> diff --git a/src/cbootimage.h b/src/cbootimage.h

> @@ -105,6 +109,7 @@ typedef struct build_image_context_rec
>   	u_int32_t mts_attr;
>
>   	char *bct_filename;
> +	char *rsa_filename;

RSA *what* filename? This patch introduces 3 different RSA-related 
keywords. A more complete variable name would be useful so it's obvious 
which keyword's value is being stored here. Comments would be useful too.

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

> @@ -116,6 +118,9 @@ static parse_item s_top_level_items[] = {
>   	{ "ChipUid=",       token_unique_chip_id,	parse_value_chipuid },
>   	{ "JtagCtrl=",	    token_secure_jtag_control,	parse_value_u32 },
>   	{ "DebugCtrl=",	    token_secure_debug_control,	parse_value_u32 },
> +	{ "RsaKeyModulus=", token_pub_key_modulus,	parse_rsa_param },

Why "RsaKey" in the keyword name but "pub_key" in the enumeration?

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

> +int
> +set_rsa_param(build_image_context *context, parse_token token,
> +		const char *filename)
...
> +	if (result || (actual_size != ARSE_RSA_PARAM_MAX_BYTES)) {
> +		if (result)
> +			printf("Error reading file %s.\n", filename);
> +		else
> +			printf("Error: invalid size, file %s.\n", filename);
> +		exit(1);
> +        }

Since those are two entirely separate error cases, writing two entirely 
separate if conditions would be better:

if (result) {
     printf
     exit
}
if (actual_size != ... {
     printf
     exit
}

> diff --git a/src/t210/nvbctlib_t210.c b/src/t210/nvbctlib_t210.c

> @@ -2198,6 +2201,21 @@ t210_bct_set_value(parse_token id, void *data, u_int8_t *bct)
>   		memcpy(&bct_ptr->unique_chip_id, data, sizeof(nvboot_ecid));
>   		break;
>
> +	case token_pub_key_modulus:
> +		memcpy(&bct_ptr->key, data, sizeof(nvboot_rsa_key_modulus));
> +		break;
> +
> +	case token_rsa_pss_sig_bl:
> +		/* ONLY support one bl */
> +		memcpy(&bct_ptr->bootloader[0].signature.rsa_pss_sig,
> +			data, sizeof(nvboot_rsa_pss_sig));

That comment is unfortunate. Can we not make this keyword an array, so 
that this limitation does not exist? If not, won't this require a 
non-backwards-compatible syntax change when we add support for more than 
one bootloader (which incidentally is a feature I expect will be 
implemented not too far down the road...)
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
jimmzhang Sept. 21, 2015, 11:07 p.m. UTC | #2
> -----Original Message-----
> From: Stephen Warren [mailto:swarren@wwwdotorg.org]
> Sent: Monday, September 21, 2015 12:55 PM
> To: Jimmy Zhang
> Cc: Allen Martin; Stephen Warren; linux-tegra@vger.kernel.org
> Subject: Re: [cbootimage PATCH v1 1/8] Enable --update | -u option support
> for t210
> 
> On 09/02/2015 03:19 PM, Jimmy Zhang wrote:
> > Added routines to allow updating pkc pubkey and rsa pss signatures.
> 
> "pkc" and "pss" should be explained.
Do you mean it should be written like Public-Key Cryptography (pkc) and Probabilistic Signature Scheme (pss)?
> 
> > Specifically, added following configuration keywords:
> >
> >     RsaKeyModulus: set pubkey
> >     RsaPssSigBl:   set bootloader rsa pss signature
> >     RsaPssSigBct:  set bct rsa pss signature
> >
> > Sample Configuration file update_bl_sig.cfg
> >     RsaKeyModulus = pubkey.mod;
> >     RsaPssSigBl = bl.sig;
> 
> Oh, RsaKeyModulus is a file not an inline value? Better put "File" or
> "Filename" into the keywords then?

OK. We use filename inside configuration file for bct and boot loader. For example, use keyword "BootLoader"  to specify boot loader:
BootLoader    = u-boot.bin,0x80108000,0x80108000,Complete;

Should the keywords be changed to:

RsaKeyModulusFile = <...>;
RsaPssSigBlFile = <...>;

> 
> How can the user generate the value for RsaPssSigBct if this tool is generating
> the BCT? Why doesn't this tool generate the signatures itself internally?
>
 
This patch is only about option "--update". Signing function is added in patch 6 and 7.

To test out this patch, I used nv internal tool tegrasign to generate signature files.

> > Commandline example:
> >     $ cbootimage -s tegra210 -u update_bl_sig.cfg image.bin
> > image.bin-bl-signed
> 
> This commit appears to be two unrelated changes squashed into one. This
> commit description is entirely unrelated to the commit subject for example.
> 
> > diff --git a/src/cbootimage.c b/src/cbootimage.c
> 
> >   	printf("    -u|--update           Copy input image data and update
> bct\n");
> >   	printf("                          configs into new image file.\n");
> > -	printf("                          This feature is only for tegra114/124.\n");
> > +	printf("                          This feature is only for tegra114/124/210.\n");
> 
> I assume this feature will be enabled by default going forward. I think it'd be
> better to rephrase that as "This feature is not supported on Tegra20/30".
> 
> BTW, is there a particular reason the feature won't work there? If not, can
> we simply enable it for all chips?
> 
> >   		if (context->boot_data_version !=
> BOOTDATA_VERSION_T114 &&
> > -			context->boot_data_version !=
> BOOTDATA_VERSION_T124) {
> > -			printf("Update image feature is only for Tegra114 and
> Tegra124.\n");
> > +			context->boot_data_version !=
> BOOTDATA_VERSION_T124 &&
> > +			context->boot_data_version !=
> BOOTDATA_VERSION_T210) {
> > +			printf("Update image feature is only for Tegra114,
> Tegra124"
> > +				" and Tegra210.\n");
> >   			return -EINVAL;
> 
> To avoid that if expanding forever, can it not check for == T20/30 rather than
> != all other chips?
> 
> 

I can split this patch into two patches.

"--update | -u" option was added since T114. If there is any needs for T20 and T30, it can be added in.

> > diff --git a/src/cbootimage.h b/src/cbootimage.h
> 
> > @@ -105,6 +109,7 @@ typedef struct build_image_context_rec
> >   	u_int32_t mts_attr;
> >
> >   	char *bct_filename;
> > +	char *rsa_filename;
> 
> RSA *what* filename? This patch introduces 3 different RSA-related
> keywords. A more complete variable name would be useful so it's obvious
> which keyword's value is being stored here. Comments would be useful too.
> 

Agree. In fact, it was replaced by pkckey. I forgot to remove it. 

> > diff --git a/src/parse.c b/src/parse.c
> 
> > @@ -116,6 +118,9 @@ static parse_item s_top_level_items[] = {
> >   	{ "ChipUid=",       token_unique_chip_id,	parse_value_chipuid
> },
> >   	{ "JtagCtrl=",	    token_secure_jtag_control,	parse_value_u32 },
> >   	{ "DebugCtrl=",	    token_secure_debug_control,
> 	parse_value_u32 },
> > +	{ "RsaKeyModulus=", token_pub_key_modulus,
> 	parse_rsa_param },
> 
> Why "RsaKey" in the keyword name but "pub_key" in the enumeration?

Agree. It is a bit confusion. I guess I generally followed what have been used in nv internal tool. RsaKeyModulus is value n, ie p*q. pub_key in RSA scheme is a pair value of (n, e).  Since e is a constant 0x10001, RsaKeyModulus is then simply handled as public key.

I will change pub_key_modulus to rsa_key_modulus.

> 
> > diff --git a/src/set.c b/src/set.c
> 
> > +int
> > +set_rsa_param(build_image_context *context, parse_token token,
> > +		const char *filename)
> ...
> > +	if (result || (actual_size != ARSE_RSA_PARAM_MAX_BYTES)) {
> > +		if (result)
> > +			printf("Error reading file %s.\n", filename);
> > +		else
> > +			printf("Error: invalid size, file %s.\n", filename);
> > +		exit(1);
> > +        }
> 
> Since those are two entirely separate error cases, writing two entirely
> separate if conditions would be better:
> 
> if (result) {
>      printf
>      exit
> }
> if (actual_size != ... {
>      printf
>      exit
> }
> 

OK.

> > diff --git a/src/t210/nvbctlib_t210.c b/src/t210/nvbctlib_t210.c
> 
> > @@ -2198,6 +2201,21 @@ t210_bct_set_value(parse_token id, void *data,
> u_int8_t *bct)
> >   		memcpy(&bct_ptr->unique_chip_id, data,
> sizeof(nvboot_ecid));
> >   		break;
> >
> > +	case token_pub_key_modulus:
> > +		memcpy(&bct_ptr->key, data,
> sizeof(nvboot_rsa_key_modulus));
> > +		break;
> > +
> > +	case token_rsa_pss_sig_bl:
> > +		/* ONLY support one bl */
> > +		memcpy(&bct_ptr->bootloader[0].signature.rsa_pss_sig,
> > +			data, sizeof(nvboot_rsa_pss_sig));
> 
> That comment is unfortunate. Can we not make this keyword an array, so
> that this limitation does not exist? If not, won't this require a
> non-backwards-compatible syntax change when we add support for more
> than
> one bootloader (which incidentally is a feature I expect will be
> implemented not too far down the road...)

Since day one, cbootimage can only support one boot loader. Ie, form a bootable image that contains only one copy of bootloader. This is determined by configuration file key word "BootLoader".  I guess adding multi copies bootloader support propably belongs to another series of patches.

--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/src/cbootimage.c b/src/cbootimage.c
index 1dfb719c819b..9b696519377a 100644
--- a/src/cbootimage.c
+++ b/src/cbootimage.c
@@ -79,7 +79,7 @@  usage(void)
 	printf("                          Default: tegra20.\n");
 	printf("    -u|--update           Copy input image data and update bct\n");
 	printf("                          configs into new image file.\n");
-	printf("                          This feature is only for tegra114/124.\n");
+	printf("                          This feature is only for tegra114/124/210.\n");
 	printf("    configfile            File with configuration information\n");
 	printf("    inputimage            Input image name. This is required\n");
 	printf("                          if -u|--update option is used.\n");
@@ -170,8 +170,10 @@  process_command_line(int argc, char *argv[], build_image_context *context)
 	if (context->update_image)
 	{
 		if (context->boot_data_version != BOOTDATA_VERSION_T114 &&
-			context->boot_data_version != BOOTDATA_VERSION_T124) {
-			printf("Update image feature is only for Tegra114 and Tegra124.\n");
+			context->boot_data_version != BOOTDATA_VERSION_T124 &&
+			context->boot_data_version != BOOTDATA_VERSION_T210) {
+			printf("Update image feature is only for Tegra114, Tegra124"
+				" and Tegra210.\n");
 			return -EINVAL;
 		}
 
diff --git a/src/cbootimage.h b/src/cbootimage.h
index 9706b2c1edb8..2b609eda50f9 100644
--- a/src/cbootimage.h
+++ b/src/cbootimage.h
@@ -49,6 +49,9 @@ 
 
 #define MAX_MTS_SIZE (4 * 1024 * 1024)
 
+#define ARSE_RSA_MAX_MODULUS_SIZE	2048
+#define ARSE_RSA_PARAM_MAX_BYTES	(ARSE_RSA_MAX_MODULUS_SIZE / 8)
+
 #define NVBOOT_CONFIG_TABLE_SIZE_MAX (10 * 1024)
 
 /*
@@ -60,6 +63,7 @@  typedef enum
 	file_type_bl = 0,
 	file_type_bct,
 	file_type_mts,
+	file_type_bin,
 } file_type;
 
 /*
@@ -105,6 +109,7 @@  typedef struct build_image_context_rec
 	u_int32_t mts_attr;
 
 	char *bct_filename;
+	char *rsa_filename;
 	u_int32_t last_blk;
 	u_int32_t bct_size; /* The BCT file size */
 	u_int32_t boot_data_version; /* The boot data version of BCT */
diff --git a/src/parse.c b/src/parse.c
index 8c9824437393..974eec7844ff 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -65,6 +65,8 @@  parse_bootloader(build_image_context *context, parse_token token, char *rest);
 static int
 parse_mts_image(build_image_context *context, parse_token token, char *rest);
 static int
+parse_rsa_param(build_image_context *context, parse_token token, char *rest);
+static int
 parse_value_u32(build_image_context *context, parse_token token, char *rest);
 static int
 parse_value_chipuid(build_image_context *context,
@@ -116,6 +118,9 @@  static parse_item s_top_level_items[] = {
 	{ "ChipUid=",       token_unique_chip_id,	parse_value_chipuid },
 	{ "JtagCtrl=",	    token_secure_jtag_control,	parse_value_u32 },
 	{ "DebugCtrl=",	    token_secure_debug_control,	parse_value_u32 },
+	{ "RsaKeyModulus=", token_pub_key_modulus,	parse_rsa_param },
+	{ "RsaPssSigBl=",   token_rsa_pss_sig_bl,	parse_rsa_param },
+	{ "RsaPssSigBct=",  token_rsa_pss_sig_bct,	parse_rsa_param },
 	{ NULL, 0, NULL } /* Must be last */
 };
 
@@ -480,6 +485,36 @@  static int parse_mts_image(build_image_context *context,
 }
 
 /*
+ * Parse the given rsa modulus/key/signature file name
+ * then call set_rsa_settings to set proper rsa field.
+ *
+ * @param context	The main context pointer
+ * @param token  	The parse token value
+ * @param rest   	String to parse
+ * @return 0 and 1 for success and failure
+ */
+static int parse_rsa_param(build_image_context *context,
+			parse_token token,
+			char *rest)
+{
+	char filename[MAX_BUFFER];
+
+	assert(context != NULL);
+	assert(rest != NULL);
+
+	if (context->generate_bct != 0)
+		return 0;
+
+	/* Parse the file name. */
+	rest = parse_filename(rest, filename, MAX_BUFFER);
+	if (rest == NULL)
+		return 1;
+
+	/* Parsing has finished - set the bootloader */
+	return set_rsa_param(context, token, filename);
+}
+
+/*
  * Parse the given string and find the array items in config file.
  *
  * @param context	The main context pointer
diff --git a/src/parse.h b/src/parse.h
index ce3f21fb8a31..c7035d590ed2 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -114,6 +114,10 @@  typedef enum
 	token_secure_jtag_control,
 	token_secure_debug_control,
 
+	token_pub_key_modulus,
+	token_rsa_pss_sig_bl,
+	token_rsa_pss_sig_bct,
+
 	token_nand_clock_divider,
 	token_nand_nand_timing,
 	token_nand_nand_timing2,
diff --git a/src/set.c b/src/set.c
index 73af52111360..474554b2ed58 100644
--- a/src/set.c
+++ b/src/set.c
@@ -147,6 +147,44 @@  set_mts_image(build_image_context	*context,
 	context->mts_entry_point = entry_point;
 	return update_mts_image(context);
 }
+
+int
+set_rsa_param(build_image_context *context, parse_token token,
+		const char *filename)
+{
+	int	result;
+	u_int8_t *rsa_storage;	/* Holds the rsa param after reading */
+	u_int32_t actual_size;	/* In bytes */
+	file_type rsa_filetype = file_type_bin;
+
+        /* Read the image into memory. */
+	result = read_from_image(filename,
+				0,
+				ARSE_RSA_PARAM_MAX_BYTES,
+				&rsa_storage,
+				&actual_size,
+				rsa_filetype);
+
+	if (result || (actual_size != ARSE_RSA_PARAM_MAX_BYTES)) {
+		if (result)
+			printf("Error reading file %s.\n", filename);
+		else
+			printf("Error: invalid size, file %s.\n", filename);
+		exit(1);
+        }
+
+	if (enable_debug) {
+		printf("Updating token %d with file %s\n", (int)token, filename);
+	}
+
+	/* set to appropriate bct field */
+	result = g_soc_config->set_value(token,
+			rsa_storage, context->bct);
+
+	free(rsa_storage);
+	return result;
+}
+
 #define DEFAULT()                                                     \
 	default:                                                      \
 		printf("Unexpected token %d at line %d\n",            \
diff --git a/src/set.h b/src/set.h
index 8b9a69b2a950..5fc4061b7e4d 100644
--- a/src/set.h
+++ b/src/set.h
@@ -42,6 +42,11 @@  set_mts_image(build_image_context	*context,
 		u_int32_t	entry_point);
 
 int
+set_rsa_param(build_image_context	*context,
+		parse_token	token,
+		const char	*filename);
+
+int
 context_set_value(build_image_context	*context,
 		parse_token	token,
 		void		*value);
diff --git a/src/t210/nvbctlib_t210.c b/src/t210/nvbctlib_t210.c
index 9921bbbe0d2d..f48ff66d4c18 100644
--- a/src/t210/nvbctlib_t210.c
+++ b/src/t210/nvbctlib_t210.c
@@ -113,7 +113,10 @@  parse_token t210_root_token_list[] = {
 	token_crypto_length,
 	token_max_bct_search_blks,
 	token_unique_chip_id,
-	token_secure_debug_control
+	token_secure_debug_control,
+	token_pub_key_modulus,
+	token_rsa_pss_sig_bl,
+	token_rsa_pss_sig_bct
 };
 
 int
@@ -2198,6 +2201,21 @@  t210_bct_set_value(parse_token id, void *data, u_int8_t *bct)
 		memcpy(&bct_ptr->unique_chip_id, data, sizeof(nvboot_ecid));
 		break;
 
+	case token_pub_key_modulus:
+		memcpy(&bct_ptr->key, data, sizeof(nvboot_rsa_key_modulus));
+		break;
+
+	case token_rsa_pss_sig_bl:
+		/* ONLY support one bl */
+		memcpy(&bct_ptr->bootloader[0].signature.rsa_pss_sig,
+			data, sizeof(nvboot_rsa_pss_sig));
+		break;
+
+	case token_rsa_pss_sig_bct:
+		memcpy(&bct_ptr->signature.rsa_pss_sig,
+			data, sizeof(nvboot_rsa_pss_sig));
+		break;
+
 	default:
 		return -ENODATA;
 	}
diff --git a/src/t210/nvboot_bct_t210.h b/src/t210/nvboot_bct_t210.h
index 90841f63feb6..c790ee97106d 100644
--- a/src/t210/nvboot_bct_t210.h
+++ b/src/t210/nvboot_bct_t210.h
@@ -94,8 +94,6 @@ 
  */
 #define NVBOOT_MAX_BCT_SEARCH_BLOCKS	64
 
-#define ARSE_RSA_MAX_MODULUS_SIZE	2048
-
 /**
  * Defines the RSA modulus length in bits and bytes used for PKC secure boot.
  */