summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJimmy Zhang <jimmzhang@nvidia.com>2015-10-19 16:01:56 -0700
committerStephen Warren <swarren@nvidia.com>2015-10-19 17:33:29 -0600
commitaa869ed597435ec05d5b9f55de64d01a52cc5ea8 (patch)
treeb0877072b080178156aecba4c90857a606d9bfa4
parent3c3b992a68147981792c4f4fe0f3df5633b13076 (diff)
downloadnvidia-cbootimage-aa869ed597435ec05d5b9f55de64d01a52cc5ea8.tar.gz
Add new configuration keyword "RehashBl"
This feature is needed in case an image is updated at later stage after bootimage has been created. How to use: Add keyword "RehashBl" to configuration file, for example, update.cfg: RehashBl; Invoke cbootimage to re-calculate bootloader aes hash, for example, for bootimage bootloader.bin: $ cbootimage -s tegra210 --update update.cfg bootloader.bin bootloader.bin-resigned Where bootloader.bin-resigned is the resigned bootimage bootloader.bin Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
-rw-r--r--samples/update.cfg1
-rw-r--r--src/crypto.c34
-rw-r--r--src/crypto.h7
-rw-r--r--src/data_layout.c51
-rw-r--r--src/data_layout.h2
-rw-r--r--src/parse.c9
-rw-r--r--src/parse.h1
7 files changed, 105 insertions, 0 deletions
diff --git a/samples/update.cfg b/samples/update.cfg
new file mode 100644
index 0000000..c5c741b
--- /dev/null
+++ b/samples/update.cfg
@@ -0,0 +1 @@
+RehashBl;
diff --git a/src/crypto.c b/src/crypto.c
index 039be0a..5438a53 100644
--- a/src/crypto.c
+++ b/src/crypto.c
@@ -326,3 +326,37 @@ reverse_byte_order(
if (size % 2)
out[size / 2] = in[size / 2];
}
+
+int
+sign_bl(build_image_context *context,
+ u_int8_t *bootloader,
+ u_int32_t length,
+ u_int32_t image_instance)
+{
+ int e = 0;
+ u_int8_t *hash_buffer;
+ u_int32_t hash_size;
+
+ g_soc_config->get_value(token_hash_size,
+ &hash_size, context->bct);
+
+ hash_buffer = calloc(1, hash_size);
+ if (hash_buffer == NULL)
+ return -ENOMEM;
+
+ /* Encrypt and compute hash */
+ if ((e = sign_data_block(bootloader,
+ length,
+ hash_buffer)) != 0)
+ goto fail;
+
+ if ((e = g_soc_config->setbl_param(image_instance,
+ token_bl_crypto_hash,
+ (u_int32_t*)hash_buffer,
+ context->bct)) != 0)
+ goto fail;
+
+ fail:
+ free(hash_buffer);
+ return e;
+}
diff --git a/src/crypto.h b/src/crypto.h
index f56b67d..3cd73f2 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -49,4 +49,11 @@ reverse_byte_order(
u_int8_t *out,
const u_int8_t *in,
const u_int32_t size);
+
+int
+sign_bl(build_image_context *context,
+ u_int8_t *bootloader,
+ u_int32_t length,
+ u_int32_t image_instance);
+
#endif /* #ifndef INCLUDED_CRYPTO_H */
diff --git a/src/data_layout.c b/src/data_layout.c
index 0826092..5d3fe10 100644
--- a/src/data_layout.c
+++ b/src/data_layout.c
@@ -1065,3 +1065,54 @@ int get_bct_size_from_image(build_image_context *context)
context->bct = 0;
return bct_size;
}
+
+int resign_bl(build_image_context *context)
+{
+ int ret;
+ u_int8_t *buffer, *image;
+ u_int32_t image_instance = 0; /* support only one instance */
+ u_int32_t image_actual_size; /* In bytes */
+ u_int32_t bl_length;
+ u_int32_t pages_in_image;
+ u_int32_t blk_size, page_size, current_blk, current_page;
+ u_int32_t offset;
+
+ /* read in bl from image */
+ g_soc_config->get_value(token_block_size, &blk_size, context->bct);
+ g_soc_config->get_value(token_page_size, &page_size, context->bct);
+
+ GET_BL_FIELD(image_instance, start_blk, &current_blk);
+ GET_BL_FIELD(image_instance, start_page, &current_page);
+ GET_BL_FIELD(image_instance, length, &bl_length);
+
+ offset = current_blk * blk_size +
+ current_page * page_size;
+
+ if (read_from_image(context->input_image_filename,
+ offset, bl_length,
+ &image, &image_actual_size, file_type_bin)) {
+ printf("Error reading image file %s.\n",
+ context->input_image_filename);
+ return -ENOMEM;
+ }
+
+ pages_in_image = ICEIL(image_actual_size, page_size);
+
+ /* Create a local copy of the bl */
+ if ((buffer = malloc(pages_in_image * page_size)) == NULL) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ memset(buffer, 0, pages_in_image * page_size);
+ memcpy(buffer, image, image_actual_size);
+
+ insert_padding(buffer, image_actual_size);
+
+ /* sign bl */
+ ret = sign_bl(context, buffer, image_actual_size, image_instance);
+ free (buffer);
+ fail:
+ free (image);
+ return ret;
+}
diff --git a/src/data_layout.h b/src/data_layout.h
index c6e53e6..0e6e41f 100644
--- a/src/data_layout.h
+++ b/src/data_layout.h
@@ -64,4 +64,6 @@ get_bct_size_from_image(build_image_context *context);
int
begin_update(build_image_context *context);
+int
+resign_bl(build_image_context *context);
#endif /* #ifndef INCLUDED_DATA_LAYOUT_H */
diff --git a/src/parse.c b/src/parse.c
index 667895c..6f37dad 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -80,6 +80,8 @@ static int
parse_dev_param(build_image_context *context, parse_token token, char *rest);
static int
parse_sdram_param(build_image_context *context, parse_token token, char *rest);
+static int
+parse_sign_bl(build_image_context *context, parse_token token, char *rest);
static int process_statement(build_image_context *context,
char *str,
@@ -121,6 +123,7 @@ static parse_item s_top_level_items[] = {
{ "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 },
+ { "RehashBl", token_sign_bl, parse_sign_bl },
{ NULL, 0, NULL } /* Must be last */
};
@@ -689,6 +692,12 @@ parse_bct_file(build_image_context *context, parse_token token, char *rest)
return 0;
}
+static int
+parse_sign_bl(build_image_context *context, parse_token token, char *rest)
+{
+ return resign_bl(context);
+}
+
static char *
parse_end_state(char *str, char *uname, int chars_remaining)
{
diff --git a/src/parse.h b/src/parse.h
index f2e28b3..191742c 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -117,6 +117,7 @@ typedef enum
token_rsa_key_modulus,
token_rsa_pss_sig_bl,
token_rsa_pss_sig_bct,
+ token_sign_bl,
token_nand_clock_divider,
token_nand_nand_timing,