diff mbox

[cbootimage,v5,1/5] Add support for update pubkey and rsa-pss signatures

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

Commit Message

jimmzhang Oct. 10, 2015, 1:46 a.m. UTC
Create new configuration keywords:
   RsaKeyModulusFile: pubkey modulus
   RsaPssSigBlFile:   bootloader rsa pss signature
   RsaPssSigBctFile:  bct rsa pss signature

Sample Configuration file update_bl_sig.cfg
   RsaKeyModulusFile = pubkey.mod;
   RsaPssSigBlFile = bl.sig;

where pubkey.mod and bl.sig are files that contain the public key
modulus and bootloader's rsa-pss signature respectively.

public key modulus and signature are created through utilities
outside cbootimage.

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

Above three new keywords added in this CL are only implemented support
for T210.

Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
---
 src/cbootimage.h         |  1 +
 src/crypto.c             | 20 ++++++++++++++++++
 src/crypto.h             |  5 +++++
 src/parse.c              | 35 +++++++++++++++++++++++++++++++
 src/parse.h              | 15 ++++++++++++++
 src/set.c                | 49 +++++++++++++++++++++++++++++++++++++++++++
 src/set.h                |  5 +++++
 src/t210/nvbctlib_t210.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++-
 8 files changed, 183 insertions(+), 1 deletion(-)

Comments

Stephen Warren Oct. 12, 2015, 10:49 p.m. UTC | #1
On 10/09/2015 07:46 PM, Jimmy Zhang wrote:
> Create new configuration keywords:
>     RsaKeyModulusFile: pubkey modulus
>     RsaPssSigBlFile:   bootloader rsa pss signature
>     RsaPssSigBctFile:  bct rsa pss signature
>
> Sample Configuration file update_bl_sig.cfg
>     RsaKeyModulusFile = pubkey.mod;
>     RsaPssSigBlFile = bl.sig;
>
> where pubkey.mod and bl.sig are files that contain the public key
> modulus and bootloader's rsa-pss signature respectively.
>
> public key modulus and signature are created through utilities
> outside cbootimage.
>
> Command line example:
>   $ cbootimage -s tegra210 -u update_bl_sig.cfg image.bin image.bin-bl-signed
>
> Above three new keywords added in this CL are only implemented support
> for T210.

I'd like to see a changelog per patch so I don't have to refer back to 
the cover letter each time.

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

> +void
> +swap_endianness(

Nit: It's more like "byte order" (serialization) rather than endianness, 
although they're related concepts.

> +	u_int8_t *out,
> +	u_int8_t *in,

Nit: You could make "in" const to since it's not written.

> +	const u_int32_t size)

... certainly that'd be more useful than making size const.

> +{
> +	u_int32_t i;
> +
> +	for (i = 0; i < size / 2; i++) {
> +		u_int8_t b1 = in[i];
> +		u_int8_t b2 = in[size - 1 - i];
> +		out[i] = b2;
> +		out[size - 1 - i] = b1;

Nit: It'd be nice to put "size - 1 - i" into a variable rather than 
duplicate the calculation.

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

> +int
> +set_rsa_param(build_image_context *context, parse_token token,
> +		char *filename)
> +{
> +	int	result;
> +	u_int8_t *rsa_storage;	/* Holds the rsa param after reading */
> +	u_int32_t size;		/* Bytes to read */
> +	u_int32_t actual_size;	/* In bytes */
> +
> +	if (g_soc_config->get_value_size == NULL) {
> +		printf("Error: get_value_size() is not supported.\n");

I think code that calls that function should be able to assume the 
function pointer is non-NULL. This could be achieved by either having 
each SoC-specific file provide an implementation of that function. For 
the SoCs that don't support this, you could share a common dummy 
implementation that always returns an error.

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

>   	/*
> +	 * Get the size of specified bct field
> +	 *
> +	 * @param id  	The parse token
> +	 * @param data	Return size from bct field
> +	 * @param bct 	Bct pointer
> +	 * @return 0 and -ENODATA for success and failure
> +	 */
> +	int (*get_value_size)(parse_token id,
> +			void *data,
> +			u_int8_t *bct);

The existing get/set functions use a void* since they can operate on 
different fields with different data types. However, the result of 
retrieving a field's size is always a size_t. The "bct" parameter also 
doesn't seem to be used; do you think there could ever be a use for it? 
I think the following prototype should be used so that we can get as 
much type safety as possible:

// Returns >0 for size, -ve for error, never returns 0.
size_t (*get_value_size)(parse_token id);
--
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 Oct. 13, 2015, 2:02 a.m. UTC | #2
> -----Original Message-----
> From: Stephen Warren [mailto:swarren@wwwdotorg.org]
> Sent: Monday, October 12, 2015 3:49 PM
> To: Jimmy Zhang
> Cc: Allen Martin; Stephen Warren; linux-tegra@vger.kernel.org
> Subject: Re: [cbootimage PATCH v5 1/5] Add support for update pubkey and
> rsa-pss signatures
> 
> On 10/09/2015 07:46 PM, Jimmy Zhang wrote:
> > Create new configuration keywords:
> >     RsaKeyModulusFile: pubkey modulus
> >     RsaPssSigBlFile:   bootloader rsa pss signature
> >     RsaPssSigBctFile:  bct rsa pss signature
> >
> > Sample Configuration file update_bl_sig.cfg
> >     RsaKeyModulusFile = pubkey.mod;
> >     RsaPssSigBlFile = bl.sig;
> >
> > where pubkey.mod and bl.sig are files that contain the public key
> > modulus and bootloader's rsa-pss signature respectively.
> >
> > public key modulus and signature are created through utilities outside
> > cbootimage.
> >
> > Command line example:
> >   $ cbootimage -s tegra210 -u update_bl_sig.cfg image.bin
> > image.bin-bl-signed
> >
> > Above three new keywords added in this CL are only implemented support
> > for T210.
> 
> I'd like to see a changelog per patch so I don't have to refer back to the cover
> letter each time.
> 

OK

> > diff --git a/src/crypto.c b/src/crypto.c
> 
> > +void
> > +swap_endianness(
> 
> Nit: It's more like "byte order" (serialization) rather than endianness,
> although they're related concepts.
> 

This is the function name used by tegrasign. I am open if you have a better name. The reason for the swap because the string actually is a 256 byte long number. Tegra soc handles a number by little endian byte order.
 
> > +	u_int8_t *out,
> > +	u_int8_t *in,
> 
> Nit: You could make "in" const to since it's not written.
> 

OK.

> > +	const u_int32_t size)
> 
> ... certainly that'd be more useful than making size const.
> 
> > +{
> > +	u_int32_t i;
> > +
> > +	for (i = 0; i < size / 2; i++) {
> > +		u_int8_t b1 = in[i];
> > +		u_int8_t b2 = in[size - 1 - i];
> > +		out[i] = b2;
> > +		out[size - 1 - i] = b1;
> 
> Nit: It'd be nice to put "size - 1 - i" into a variable rather than duplicate the
> calculation.
> 
> > diff --git a/src/set.c b/src/set.c
> 
> > +int
> > +set_rsa_param(build_image_context *context, parse_token token,
> > +		char *filename)
> > +{
> > +	int	result;
> > +	u_int8_t *rsa_storage;	/* Holds the rsa param after reading */
> > +	u_int32_t size;		/* Bytes to read */
> > +	u_int32_t actual_size;	/* In bytes */
> > +
> > +	if (g_soc_config->get_value_size == NULL) {
> > +		printf("Error: get_value_size() is not supported.\n");
> 
> I think code that calls that function should be able to assume the function
> pointer is non-NULL. This could be achieved by either having each SoC-
> specific file provide an implementation of that function. For the SoCs that
> don't support this, you could share a common dummy implementation that
> always returns an error.
> 

OK

> > diff --git a/src/parse.h b/src/parse.h
> 
> >   	/*
> > +	 * Get the size of specified bct field
> > +	 *
> > +	 * @param id  	The parse token
> > +	 * @param data	Return size from bct field
> > +	 * @param bct 	Bct pointer
> > +	 * @return 0 and -ENODATA for success and failure
> > +	 */
> > +	int (*get_value_size)(parse_token id,
> > +			void *data,
> > +			u_int8_t *bct);
> 
> The existing get/set functions use a void* since they can operate on
> different fields with different data types. However, the result of retrieving a
> field's size is always a size_t. The "bct" parameter also doesn't seem to be
> used; do you think there could ever be a use for it?
> I think the following prototype should be used so that we can get as much
> type safety as possible:
> 
> // Returns >0 for size, -ve for error, never returns 0.
> size_t (*get_value_size)(parse_token id);

OK.
--
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
Stephen Warren Oct. 13, 2015, 4:19 p.m. UTC | #3
On 10/12/2015 08:02 PM, Jimmy Zhang wrote:
>
>
>> -----Original Message-----
>> From: Stephen Warren [mailto:swarren@wwwdotorg.org]
>> Sent: Monday, October 12, 2015 3:49 PM
>> To: Jimmy Zhang
>> Cc: Allen Martin; Stephen Warren; linux-tegra@vger.kernel.org
>> Subject: Re: [cbootimage PATCH v5 1/5] Add support for update pubkey and
>> rsa-pss signatures
>>
>> On 10/09/2015 07:46 PM, Jimmy Zhang wrote:
>>> Create new configuration keywords:
>>>      RsaKeyModulusFile: pubkey modulus
>>>      RsaPssSigBlFile:   bootloader rsa pss signature
>>>      RsaPssSigBctFile:  bct rsa pss signature
>>>
>>> Sample Configuration file update_bl_sig.cfg
>>>      RsaKeyModulusFile = pubkey.mod;
>>>      RsaPssSigBlFile = bl.sig;
>>>
>>> where pubkey.mod and bl.sig are files that contain the public key
>>> modulus and bootloader's rsa-pss signature respectively.
>>>
>>> public key modulus and signature are created through utilities outside
>>> cbootimage.
>>>
>>> Command line example:
>>>    $ cbootimage -s tegra210 -u update_bl_sig.cfg image.bin
>>> image.bin-bl-signed
>>>
>>> Above three new keywords added in this CL are only implemented support
>>> for T210.
>>
>> I'd like to see a changelog per patch so I don't have to refer back to the cover
>> letter each time.
>>
>
> OK
>
>>> diff --git a/src/crypto.c b/src/crypto.c
>>
>>> +void
>>> +swap_endianness(
>>
>> Nit: It's more like "byte order" (serialization) rather than endianness,
>> although they're related concepts.
>
> This is the function name used by tegrasign. I am open if you have a better name. The reason for the swap because the string actually is a 256 byte long number. Tegra soc handles a number by little endian byte order.

reverse_byte_order()?

BTW, does cbootimage operate correctly if run in a big-endian host?
--
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 Oct. 13, 2015, 5:32 p.m. UTC | #4
> -----Original Message-----
> From: Stephen Warren [mailto:swarren@wwwdotorg.org]
> Sent: Tuesday, October 13, 2015 9:19 AM
> To: Jimmy Zhang
> Cc: Allen Martin; Stephen Warren; linux-tegra@vger.kernel.org
> Subject: Re: [cbootimage PATCH v5 1/5] Add support for update pubkey and
> rsa-pss signatures
> 
> On 10/12/2015 08:02 PM, Jimmy Zhang wrote:
> >
> >
> >> -----Original Message-----
> >> From: Stephen Warren [mailto:swarren@wwwdotorg.org]
> >> Sent: Monday, October 12, 2015 3:49 PM
> >> To: Jimmy Zhang
> >> Cc: Allen Martin; Stephen Warren; linux-tegra@vger.kernel.org
> >> Subject: Re: [cbootimage PATCH v5 1/5] Add support for update pubkey
> >> and rsa-pss signatures
> >>
> >> On 10/09/2015 07:46 PM, Jimmy Zhang wrote:
> >>> Create new configuration keywords:
> >>>      RsaKeyModulusFile: pubkey modulus
> >>>      RsaPssSigBlFile:   bootloader rsa pss signature
> >>>      RsaPssSigBctFile:  bct rsa pss signature
> >>>
> >>> Sample Configuration file update_bl_sig.cfg
> >>>      RsaKeyModulusFile = pubkey.mod;
> >>>      RsaPssSigBlFile = bl.sig;
> >>>
> >>> where pubkey.mod and bl.sig are files that contain the public key
> >>> modulus and bootloader's rsa-pss signature respectively.
> >>>
> >>> public key modulus and signature are created through utilities
> >>> outside cbootimage.
> >>>
> >>> Command line example:
> >>>    $ cbootimage -s tegra210 -u update_bl_sig.cfg image.bin
> >>> image.bin-bl-signed
> >>>
> >>> Above three new keywords added in this CL are only implemented
> >>> support for T210.
> >>
> >> I'd like to see a changelog per patch so I don't have to refer back
> >> to the cover letter each time.
> >>
> >
> > OK
> >
> >>> diff --git a/src/crypto.c b/src/crypto.c
> >>
> >>> +void
> >>> +swap_endianness(
> >>
> >> Nit: It's more like "byte order" (serialization) rather than
> >> endianness, although they're related concepts.
> >
> > This is the function name used by tegrasign. I am open if you have a better
> name. The reason for the swap because the string actually is a 256 byte long
> number. Tegra soc handles a number by little endian byte order.
> 
> reverse_byte_order()?
> 
> BTW, does cbootimage operate correctly if run in a big-endian host?


For this function,  it should be no difference.
--
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 Oct. 17, 2015, 12:21 a.m. UTC | #5
> -----Original Message-----
> From: Jimmy Zhang
> Sent: Monday, October 12, 2015 7:02 PM
> To: 'Stephen Warren'
> Cc: Allen Martin; Stephen Warren; linux-tegra@vger.kernel.org
> Subject: RE: [cbootimage PATCH v5 1/5] Add support for update pubkey and
> rsa-pss signatures
> 
> 
> 
> > -----Original Message-----
> > From: Stephen Warren [mailto:swarren@wwwdotorg.org]
> > Sent: Monday, October 12, 2015 3:49 PM
> > To: Jimmy Zhang
> > Cc: Allen Martin; Stephen Warren; linux-tegra@vger.kernel.org
> > Subject: Re: [cbootimage PATCH v5 1/5] Add support for update pubkey
> > and rsa-pss signatures
> >
> > On 10/09/2015 07:46 PM, Jimmy Zhang wrote:
> > > Create new configuration keywords:
> > >     RsaKeyModulusFile: pubkey modulus
> > >     RsaPssSigBlFile:   bootloader rsa pss signature
> > >     RsaPssSigBctFile:  bct rsa pss signature
> > >
> > > Sample Configuration file update_bl_sig.cfg
> > >     RsaKeyModulusFile = pubkey.mod;
> > >     RsaPssSigBlFile = bl.sig;
> > >
> > > where pubkey.mod and bl.sig are files that contain the public key
> > > modulus and bootloader's rsa-pss signature respectively.
> > >
> > > public key modulus and signature are created through utilities
> > > outside cbootimage.
> > >
> > > Command line example:
> > >   $ cbootimage -s tegra210 -u update_bl_sig.cfg image.bin
> > > image.bin-bl-signed
> > >
> > > Above three new keywords added in this CL are only implemented
> > > support for T210.
> >
> > I'd like to see a changelog per patch so I don't have to refer back to
> > the cover letter each time.
> >
> 
> OK
> 
> > > diff --git a/src/crypto.c b/src/crypto.c
> >
> > > +void
> > > +swap_endianness(
> >
> > Nit: It's more like "byte order" (serialization) rather than
> > endianness, although they're related concepts.
> >
> 
> This is the function name used by tegrasign. I am open if you have a better
> name. The reason for the swap because the string actually is a 256 byte long
> number. Tegra soc handles a number by little endian byte order.
> 
> > > +	u_int8_t *out,
> > > +	u_int8_t *in,
> >
> > Nit: You could make "in" const to since it's not written.
> >
> 
> OK.
> 

Actually this function allows output pointing to input, ie, reversing itself in byte order.

> > > +	const u_int32_t size)
> >
> > ... certainly that'd be more useful than making size const.
> >
> > > +{
> > > +	u_int32_t i;
> > > +
> > > +	for (i = 0; i < size / 2; i++) {
> > > +		u_int8_t b1 = in[i];
> > > +		u_int8_t b2 = in[size - 1 - i];
> > > +		out[i] = b2;
> > > +		out[size - 1 - i] = b1;
> >
> > Nit: It'd be nice to put "size - 1 - i" into a variable rather than
> > duplicate the calculation.
> >

OK

> > > diff --git a/src/set.c b/src/set.c
> >
> > > +int
> > > +set_rsa_param(build_image_context *context, parse_token token,
> > > +		char *filename)
> > > +{
> > > +	int	result;
> > > +	u_int8_t *rsa_storage;	/* Holds the rsa param after reading */
> > > +	u_int32_t size;		/* Bytes to read */
> > > +	u_int32_t actual_size;	/* In bytes */
> > > +
> > > +	if (g_soc_config->get_value_size == NULL) {
> > > +		printf("Error: get_value_size() is not supported.\n");
> >
> > I think code that calls that function should be able to assume the
> > function pointer is non-NULL. This could be achieved by either having
> > each SoC- specific file provide an implementation of that function.
> > For the SoCs that don't support this, you could share a common dummy
> > implementation that always returns an error.
> >
> 
> OK
> 
> > > diff --git a/src/parse.h b/src/parse.h
> >
> > >   	/*
> > > +	 * Get the size of specified bct field
> > > +	 *
> > > +	 * @param id  	The parse token
> > > +	 * @param data	Return size from bct field
> > > +	 * @param bct 	Bct pointer
> > > +	 * @return 0 and -ENODATA for success and failure
> > > +	 */
> > > +	int (*get_value_size)(parse_token id,
> > > +			void *data,
> > > +			u_int8_t *bct);
> >
> > The existing get/set functions use a void* since they can operate on
> > different fields with different data types. However, the result of
> > retrieving a field's size is always a size_t. The "bct" parameter also
> > doesn't seem to be used; do you think there could ever be a use for it?
> > I think the following prototype should be used so that we can get as
> > much type safety as possible:
> >
> > // Returns >0 for size, -ve for error, never returns 0.
> > size_t (*get_value_size)(parse_token id);
> 
> OK.
--
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
Stephen Warren Oct. 19, 2015, 4:28 p.m. UTC | #6
On 10/16/2015 06:21 PM, Jimmy Zhang wrote:
> Jimmy Zhang wrote at Monday, October 12, 2015 7:02 PM
>> Stephen Warren wrote at Monday, October 12, 2015 3:49 PM:
>>> On 10/09/2015 07:46 PM, Jimmy Zhang wrote:
>>>> Create new configuration keywords:
>>>>      RsaKeyModulusFile: pubkey modulus
>>>>      RsaPssSigBlFile:   bootloader rsa pss signature
>>>>      RsaPssSigBctFile:  bct rsa pss signature
>>>>
>>>> Sample Configuration file update_bl_sig.cfg
>>>>      RsaKeyModulusFile = pubkey.mod;
>>>>      RsaPssSigBlFile = bl.sig;
>>>>
>>>> where pubkey.mod and bl.sig are files that contain the public key
>>>> modulus and bootloader's rsa-pss signature respectively.
>>>>
>>>> public key modulus and signature are created through utilities
>>>> outside cbootimage.
>>>>
>>>> Command line example:
>>>>    $ cbootimage -s tegra210 -u update_bl_sig.cfg image.bin
>>>> image.bin-bl-signed
>>>>
>>>> Above three new keywords added in this CL are only implemented
>>>> support for T210.

>>>> diff --git a/src/crypto.c b/src/crypto.c
>>>
>>>> +void
>>>> +swap_endianness(
...
>> This is the function name used by tegrasign. I am open if you have a better
>> name. The reason for the swap because the string actually is a 256 byte long
>> number. Tegra soc handles a number by little endian byte order.
>>
>>>> +	u_int8_t *out,
>>>> +	u_int8_t *in,
>>>
>>> Nit: You could make "in" const to since it's not written.
>>>
>>
>> OK.
>
> Actually this function allows output pointing to input, ie, reversing itself in byte order.

Presumably however, the "in" pointer is only used for reads and the 
"out" point is only used for writes, so "in" can still be const?

--
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.h b/src/cbootimage.h
index 9706b2c1edb8..63f0ee97e12e 100644
--- a/src/cbootimage.h
+++ b/src/cbootimage.h
@@ -60,6 +60,7 @@  typedef enum
 	file_type_bl = 0,
 	file_type_bct,
 	file_type_mts,
+	file_type_bin,
 } file_type;
 
 /*
diff --git a/src/crypto.c b/src/crypto.c
index 99e9f085763c..f1710e521c77 100644
--- a/src/crypto.c
+++ b/src/crypto.c
@@ -297,3 +297,23 @@  sign_bct(build_image_context *context,
 	free(hash_buffer);
 	return e;
 }
+
+void
+swap_endianness(
+	u_int8_t *out,
+	u_int8_t *in,
+	const u_int32_t size)
+{
+	u_int32_t i;
+
+	for (i = 0; i < size / 2; i++) {
+		u_int8_t b1 = in[i];
+		u_int8_t b2 = in[size - 1 - i];
+		out[i] = b2;
+		out[size - 1 - i] = b1;
+	}
+
+	/* In case odd number of bytes */
+	if (size % 2)
+		out[size / 2] = in[size / 2];
+}
diff --git a/src/crypto.h b/src/crypto.h
index d7151e0cd191..e9d578e8fa7e 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -44,4 +44,9 @@  sign_data_block(u_int8_t *source,
 		u_int32_t length,
 		u_int8_t *signature);
 
+void
+swap_endianness(
+	u_int8_t *out,
+	u_int8_t *in,
+	const u_int32_t size);
 #endif /* #ifndef INCLUDED_CRYPTO_H */
diff --git a/src/parse.c b/src/parse.c
index 8c9824437393..d2f4016effd8 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 },
+	{ "RsaKeyModulusFile=", token_rsa_key_modulus,	parse_rsa_param },
+	{ "RsaPssSigBlFile=",   token_rsa_pss_sig_bl,	parse_rsa_param },
+	{ "RsaPssSigBctFile=",  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..f6411648f883 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -114,6 +114,10 @@  typedef enum
 	token_secure_jtag_control,
 	token_secure_debug_control,
 
+	token_rsa_key_modulus,
+	token_rsa_pss_sig_bl,
+	token_rsa_pss_sig_bct,
+
 	token_nand_clock_divider,
 	token_nand_nand_timing,
 	token_nand_nand_timing2,
@@ -1109,6 +1113,17 @@  typedef struct cbootimage_soc_config_rec {
 			void *data,
 			u_int8_t *bct);
 	/*
+	 * Get the size of specified bct field
+	 *
+	 * @param id  	The parse token
+	 * @param data	Return size from bct field
+	 * @param bct 	Bct pointer
+	 * @return 0 and -ENODATA for success and failure
+	 */
+	int (*get_value_size)(parse_token id,
+			void *data,
+			u_int8_t *bct);
+	/*
 	 * Set the bct crypto hash data.
 	 *
 	 * @param id    	The parse token value
diff --git a/src/set.c b/src/set.c
index 73af52111360..b6d33189b875 100644
--- a/src/set.c
+++ b/src/set.c
@@ -147,6 +147,55 @@  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,
+		char *filename)
+{
+	int	result;
+	u_int8_t *rsa_storage;	/* Holds the rsa param after reading */
+	u_int32_t size;		/* Bytes to read */
+	u_int32_t actual_size;	/* In bytes */
+
+	if (g_soc_config->get_value_size == NULL) {
+		printf("Error: get_value_size() is not supported.\n");
+		exit(1);
+	}
+
+	if (g_soc_config->get_value_size(token, &size, context->bct)) {
+		printf("Error: Unsupported token %d for value size.\n", token);
+		exit(1);
+	}
+
+	/* Read the image into memory. */
+	result = read_from_image(filename,
+				0,
+				size,
+				&rsa_storage,
+				&actual_size,
+				file_type_bin);
+
+	if (result) {
+		printf("Error reading file %s.\n", filename);
+		exit(1);
+	}
+
+	if (actual_size != size) {
+		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..b38d4cefcb4f 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,
+		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..97985db9db7c 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_rsa_key_modulus,
+	token_rsa_pss_sig_bl,
+	token_rsa_pss_sig_bct
 };
 
 int
@@ -2174,6 +2177,36 @@  t210_bct_get_value(parse_token id, void *data, u_int8_t *bct)
 }
 
 int
+t210_bct_get_value_size(parse_token id, void *data, u_int8_t *bct)
+{
+	nvboot_config_table *bct_ptr = (nvboot_config_table *)bct;
+
+	if (data == NULL)
+		return -ENODATA;
+
+	switch (id) {
+	case token_rsa_key_modulus:
+		*(u_int32_t *)data = sizeof(nvboot_rsa_key_modulus);
+		break;
+
+	case token_rsa_pss_sig_bl:
+		*(u_int32_t *)data = sizeof(nvboot_rsa_pss_sig);
+		break;
+
+	case token_rsa_pss_sig_bct:
+		*(u_int32_t *)data = sizeof(nvboot_rsa_pss_sig);
+		break;
+
+	/*
+	 * Other bct fields can be added in when needed
+	 */
+	default:
+		return -ENODATA;
+	}
+	return 0;
+}
+
+int
 t210_bct_set_value(parse_token id, void *data, u_int8_t *bct)
 {
 	nvboot_config_table *bct_ptr = (nvboot_config_table *)bct;
@@ -2198,6 +2231,24 @@  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_rsa_key_modulus:
+		swap_endianness(&bct_ptr->key, data, sizeof(nvboot_rsa_key_modulus));
+		break;
+
+	case token_rsa_pss_sig_bl:
+		/*
+		 * Update bootloader 0 since there is only one copy
+		 * of bootloader being built in.
+		 */
+		swap_endianness(&bct_ptr->bootloader[0].signature.rsa_pss_sig,
+			data, sizeof(nvboot_rsa_pss_sig));
+		break;
+
+	case token_rsa_pss_sig_bct:
+		swap_endianness(&bct_ptr->signature.rsa_pss_sig,
+			data, sizeof(nvboot_rsa_pss_sig));
+		break;
+
 	default:
 		return -ENODATA;
 	}
@@ -2279,6 +2330,7 @@  cbootimage_soc_config tegra210_config = {
 	.getbl_param				= t210_getbl_param,
 	.set_value					= t210_bct_set_value,
 	.get_value					= t210_bct_get_value,
+	.get_value_size					= t210_bct_get_value_size,
 	.set_data					= t210_bct_set_data,
 	.get_bct_size				= t210_get_bct_size,
 	.token_supported			= t210_bct_token_supported,