#include <asm/arch-tegra/pmc.h>
#include <asm/arch-tegra/fuse.h>
#include <asm/arch-tegra/warmboot.h>
+#include <asm/arch-tegra/crypto.h>
DECLARE_GLOBAL_DATA_PTR;
return 0;
}
-static void determine_crypto_options(int *is_encrypted, int *is_signed,
- int *use_zero_key)
+static void determine_crypto_options(int *is_encrypted, int *is_signed)
{
switch (tegra_fuse_get_operation_mode()) {
+ case MODE_ODM_PRODUCTION_SECURE:
+ *is_encrypted = 1;
+ *is_signed = 1;
+ break;
+ case MODE_ODM_PRODUCTION_OPEN:
case MODE_PRODUCTION:
*is_encrypted = 0;
*is_signed = 1;
- *use_zero_key = 1;
break;
case MODE_UNDEFINED:
default:
*is_encrypted = 0;
*is_signed = 0;
- *use_zero_key = 0;
break;
}
}
-static int sign_wb_code(u32 start, u32 length, int use_zero_key)
+static int encrypt_wb_code(u8 *source, u8 *destination, u32 length)
+{
+ source += offsetof(struct wb_header, random_aes_block);
+ destination += offsetof(struct wb_header, random_aes_block);
+ length -= offsetof(struct wb_header, random_aes_block);
+
+ return encrypt_data_block(source, destination, length);
+}
+
+static int sign_wb_code(u32 start, u32 length)
{
int err;
u8 *source; /* Pointer to source */
struct wb_header *dst_header; /* Pointer to dest WB header */
int is_encrypted; /* Segment is encrypted */
int is_signed; /* Segment is signed */
- int use_zero_key; /* Use key of all zeros */
/* Determine crypto options. */
- determine_crypto_options(&is_encrypted, &is_signed, &use_zero_key);
+ determine_crypto_options(&is_encrypted, &is_signed);
/* Get the actual code limits. */
length = roundup(((u32)wb_end - (u32)wb_start), 16);
dst_header->entry_point = NV_WB_RUN_ADDRESS;
dst_header->code_length = length;
- if (is_encrypted) {
- printf("!!!! Encryption is not supported !!!!\n");
- dst_header->length_insecure = 0;
- err = -EACCES;
- goto fail;
- } else
- /* copy the wb code directly following dst_header. */
- memcpy((char *)(dst_header+1), (char *)wb_start, length);
+ if (is_encrypted)
+ encrypt_wb_code((u8 *)wb_start, (u8 *)dst_header,
+ length + sizeof(struct wb_header));
+ else
+ /* copy the wb code directly following dst_header */
+ memcpy((char *)(dst_header + 1), (char *)wb_start, length);
if (is_signed)
- err = sign_wb_code(seg_address, dst_header->length_insecure,
- use_zero_key);
+ err = sign_wb_code(seg_address, dst_header->length_insecure);
fail:
if (err)