blob: 41fea52f021ac98f154b68c26e693e545b914f68 [file] [log] [blame]
/*
* Copyright 2016 Freescale Semiconductor, Inc.
* Copyright 2017 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*
* These commands enable the use of the CAAM MPPubK-generation and MPSign
* functions in supported i.MX devices.
*/
#include <asm/byteorder.h>
#include <asm/arch/clock.h>
#include <linux/compiler.h>
#include <command.h>
#include <common.h>
#include <environment.h>
#include <fsl_sec.h>
#include <mapmem.h>
#include <memalign.h>
DECLARE_GLOBAL_DATA_PTR;
/**
* do_mfgprot() - Handle the "mfgprot" command-line command
* @cmdtp: Command data struct pointer
* @flag: Command flag
* @argc: Command-line argument count
* @argv: Array of command-line arguments
*
* Returns zero on success, CMD_RET_USAGE in case of misuse and negative
* on error.
*/
static int do_mfgprot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
u8 *m_ptr, *dgst_ptr, *c_ptr, *d_ptr, *dst_ptr;
char *pubk, *sign, *sel;
int m_size, i, ret;
u32 m_addr;
pubk = "pubk";
sign = "sign";
sel = argv[1];
/* Enable HAB clock */
u32 jr_size = 4;
u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR + 0x102c);
if (out_jr_size != jr_size) {
hab_caam_clock_enable(1);
sec_init();
}
if (strcmp(sel, pubk) == 0) {
dst_ptr = malloc_cache_aligned(FSL_CAAM_MP_PUBK_BYTES);
if (!dst_ptr)
return -ENOMEM;
ret = gen_mppubk(dst_ptr);
if (ret) {
free(dst_ptr);
return ret;
}
/* Output results */
puts("Public key:\n");
for (i = 0; i < FSL_CAAM_MP_PUBK_BYTES; i++)
printf("%02X", (dst_ptr)[i]);
puts("\n");
free(dst_ptr);
} else if (strcmp(sel, sign) == 0) {
if (argc != 4)
return CMD_RET_USAGE;
m_addr = simple_strtoul(argv[2], NULL, 16);
m_size = simple_strtoul(argv[3], NULL, 10);
m_ptr = map_physmem(m_addr, m_size, MAP_NOCACHE);
if (!m_ptr)
return -ENOMEM;
dgst_ptr = malloc_cache_aligned(FSL_CAAM_MP_MES_DGST_BYTES);
if (!dgst_ptr) {
ret = -ENOMEM;
goto free_m;
}
c_ptr = malloc_cache_aligned(FSL_CAAM_MP_PRVK_BYTES);
if (!c_ptr) {
ret = -ENOMEM;
goto free_dgst;
}
d_ptr = malloc_cache_aligned(FSL_CAAM_MP_PRVK_BYTES);
if (!d_ptr) {
ret = -ENOMEM;
goto free_c;
}
ret = sign_mppubk(m_ptr, m_size, dgst_ptr, c_ptr, d_ptr);
if (ret)
goto free_d;
/* Output results */
puts("Message: ");
for (i = 0; i < m_size; i++)
printf("%02X ", (m_ptr)[i]);
puts("\n");
puts("Message Representative Digest(SHA-256):\n");
for (i = 0; i < FSL_CAAM_MP_MES_DGST_BYTES; i++)
printf("%02X", (dgst_ptr)[i]);
puts("\n");
puts("Signature:\n");
puts("C:\n");
for (i = 0; i < FSL_CAAM_MP_PRVK_BYTES; i++)
printf("%02X", (c_ptr)[i]);
puts("\n");
puts("d:\n");
for (i = 0; i < FSL_CAAM_MP_PRVK_BYTES; i++)
printf("%02X", (d_ptr)[i]);
puts("\n");
free_d:
free(d_ptr);
free_c:
free(c_ptr);
free_dgst:
free(dgst_ptr);
free_m:
unmap_sysmem(m_ptr);
} else {
return CMD_RET_USAGE;
}
return ret;
}
/***************************************************/
static char mfgprot_help_text[] =
"Usage:\n"
"Print the public key for Manufacturing Protection\n"
"\tmfgprot pubk\n"
"Generates a Manufacturing Protection signature\n"
"\tmfgprot sign <data_addr> <size>";
U_BOOT_CMD(
mfgprot, 4, 1, do_mfgprot,
"Manufacturing Protection\n",
mfgprot_help_text
);