mirror of
https://github.com/u-boot/u-boot.git
synced 2024-12-26 05:03:30 +08:00
Merge branch '2020-07-08-misc-features-and-fixes'
- mem cmd improvements - TPM fixes - SPL/NAND/FIT fixes - RSA improvements
This commit is contained in:
commit
61608f395e
2
Kconfig
2
Kconfig
@ -509,6 +509,8 @@ config SPL_FIT_SIGNATURE
|
||||
bool "Enable signature verification of FIT firmware within SPL"
|
||||
depends on SPL_DM
|
||||
select SPL_FIT
|
||||
select SPL_CRYPTO_SUPPORT
|
||||
select SPL_HASH_SUPPORT
|
||||
select SPL_RSA
|
||||
select SPL_RSA_VERIFY
|
||||
select SPL_IMAGE_SIGN_INFO
|
||||
|
10
README
10
README
@ -3237,6 +3237,7 @@ md - memory display
|
||||
mm - memory modify (auto-incrementing)
|
||||
nm - memory modify (constant address)
|
||||
mw - memory write (fill)
|
||||
ms - memory search
|
||||
cp - memory copy
|
||||
cmp - memory compare
|
||||
crc32 - checksum calculation
|
||||
@ -3482,6 +3483,15 @@ List of environment variables (most likely not complete):
|
||||
CONFIG_NET_RETRY_COUNT, if defined. This value has
|
||||
precedence over the valu based on CONFIG_NET_RETRY_COUNT.
|
||||
|
||||
memmatches - Number of matches found by the last 'ms' command, in hex
|
||||
|
||||
memaddr - Address of the last match found by the 'ms' command, in hex,
|
||||
or 0 if none
|
||||
|
||||
mempos - Index position of the last match found by the 'ms' command,
|
||||
in units of the size (.b, .w, .l) of the search
|
||||
|
||||
|
||||
The following image location variables contain the location of images
|
||||
used in booting. The "Image" column gives the role of the image and is
|
||||
not an environment variable name. The other columns are environment
|
||||
|
14
cmd/Kconfig
14
cmd/Kconfig
@ -718,6 +718,20 @@ config CMD_MEMORY
|
||||
base - print or set address offset
|
||||
loop - initialize loop on address range
|
||||
|
||||
config MEM_SEARCH
|
||||
bool "ms - Memory search"
|
||||
help
|
||||
Memory-search command
|
||||
|
||||
This allows searching through a region of memory looking for hex
|
||||
data (byte, 16-bit word, 32-bit long, also 64-bit on machines that
|
||||
support it). It is also possible to search for a string. The
|
||||
command accepts a memory range and a list of values to search for.
|
||||
The values need to appear in memory in the same order they are given
|
||||
in the command. At most 10 matches can be returned at a time, but
|
||||
pressing return will show the next 10 matches. Environment variables
|
||||
are set for use with scripting (memmatches, memaddr, mempos).
|
||||
|
||||
config CMD_MX_CYCLIC
|
||||
bool "Enable cyclic md/mw commands"
|
||||
depends on CMD_MEMORY
|
||||
|
@ -8,6 +8,7 @@ ifndef CONFIG_SPL_BUILD
|
||||
obj-y += boot.o
|
||||
obj-$(CONFIG_CMD_BOOTM) += bootm.o
|
||||
obj-y += help.o
|
||||
obj-y += panic.o
|
||||
obj-y += version.o
|
||||
|
||||
# command
|
||||
|
334
cmd/mem.c
334
cmd/mem.c
@ -25,6 +25,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
@ -33,6 +34,15 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
#define CONFIG_SYS_MEMTEST_SCRATCH 0
|
||||
#endif
|
||||
|
||||
/* Create a compile-time value */
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
#define SUPPORT_64BIT_DATA 1
|
||||
#define HELP_Q ", .q"
|
||||
#else
|
||||
#define SUPPORT_64BIT_DATA 0
|
||||
#define HELP_Q ""
|
||||
#endif
|
||||
|
||||
static int mod_mem(struct cmd_tbl *, int, int, int, char * const []);
|
||||
|
||||
/* Display values from last command.
|
||||
@ -43,6 +53,10 @@ static ulong dp_last_length = 0x40;
|
||||
static ulong mm_last_addr, mm_last_size;
|
||||
|
||||
static ulong base_address = 0;
|
||||
#ifdef CONFIG_MEM_SEARCH
|
||||
static u8 search_buf[64];
|
||||
static uint search_len;
|
||||
#endif
|
||||
|
||||
/* Memory Display
|
||||
*
|
||||
@ -116,11 +130,7 @@ static int do_mem_nm(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
u64 writeval;
|
||||
#else
|
||||
ulong writeval;
|
||||
#endif
|
||||
ulong writeval; /* 64-bit if SUPPORT_64BIT_DATA */
|
||||
ulong addr, count;
|
||||
int size;
|
||||
void *buf, *start;
|
||||
@ -141,11 +151,10 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
|
||||
/* Get the value to write.
|
||||
*/
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
writeval = simple_strtoull(argv[2], NULL, 16);
|
||||
#else
|
||||
writeval = simple_strtoul(argv[2], NULL, 16);
|
||||
#endif
|
||||
if (SUPPORT_64BIT_DATA)
|
||||
writeval = simple_strtoull(argv[2], NULL, 16);
|
||||
else
|
||||
writeval = simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
/* Count ? */
|
||||
if (argc == 4) {
|
||||
@ -160,10 +169,8 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
while (count-- > 0) {
|
||||
if (size == 4)
|
||||
*((u32 *)buf) = (u32)writeval;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
else if (size == 8)
|
||||
*((u64 *)buf) = (u64)writeval;
|
||||
#endif
|
||||
else if (SUPPORT_64BIT_DATA && size == 8)
|
||||
*((ulong *)buf) = writeval;
|
||||
else if (size == 2)
|
||||
*((u16 *)buf) = (u16)writeval;
|
||||
else
|
||||
@ -240,11 +247,7 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
int rcode = 0;
|
||||
const char *type;
|
||||
const void *buf1, *buf2, *base;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
u64 word1, word2;
|
||||
#else
|
||||
ulong word1, word2;
|
||||
#endif
|
||||
ulong word1, word2; /* 64-bit if SUPPORT_64BIT_DATA */
|
||||
|
||||
if (argc != 4)
|
||||
return CMD_RET_USAGE;
|
||||
@ -272,11 +275,9 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
if (size == 4) {
|
||||
word1 = *(u32 *)buf1;
|
||||
word2 = *(u32 *)buf2;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
} else if (size == 8) {
|
||||
word1 = *(u64 *)buf1;
|
||||
word2 = *(u64 *)buf2;
|
||||
#endif
|
||||
} else if (SUPPORT_64BIT_DATA && size == 8) {
|
||||
word1 = *(ulong *)buf1;
|
||||
word2 = *(ulong *)buf2;
|
||||
} else if (size == 2) {
|
||||
word1 = *(u16 *)buf1;
|
||||
word2 = *(u16 *)buf2;
|
||||
@ -286,15 +287,9 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
}
|
||||
if (word1 != word2) {
|
||||
ulong offset = buf1 - base;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
printf("%s at 0x%p (%#0*llx) != %s at 0x%p (%#0*llx)\n",
|
||||
type, (void *)(addr1 + offset), size, word1,
|
||||
type, (void *)(addr2 + offset), size, word2);
|
||||
#else
|
||||
printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n",
|
||||
type, (ulong)(addr1 + offset), size, word1,
|
||||
type, (ulong)(addr2 + offset), size, word2);
|
||||
#endif
|
||||
rcode = 1;
|
||||
break;
|
||||
}
|
||||
@ -372,6 +367,142 @@ static int do_mem_cp(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEM_SEARCH
|
||||
static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
ulong addr, length, bytes, offset;
|
||||
u8 *ptr, *end, *buf;
|
||||
bool quiet = false;
|
||||
ulong last_pos; /* Offset of last match in 'size' units*/
|
||||
ulong last_addr; /* Address of last displayed line */
|
||||
int limit = 10;
|
||||
int count;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
/* We use the last specified parameters, unless new ones are entered */
|
||||
addr = dp_last_addr;
|
||||
size = dp_last_size;
|
||||
length = dp_last_length;
|
||||
|
||||
if (argc < 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if ((!flag & CMD_FLAG_REPEAT)) {
|
||||
/*
|
||||
* Check for a size specification.
|
||||
* Defaults to long if no or incorrect specification.
|
||||
*/
|
||||
size = cmd_get_data_size(argv[0], 4);
|
||||
if (size < 0 && size != -2 /* string */)
|
||||
return 1;
|
||||
|
||||
argc--; argv++;
|
||||
while (argc && *argv[0] == '-') {
|
||||
int ch = argv[0][1];
|
||||
|
||||
if (ch == 'q')
|
||||
quiet = true;
|
||||
else if (ch == 'l' && isxdigit(argv[0][2]))
|
||||
limit = simple_strtoul(argv[0] + 2, NULL, 16);
|
||||
else
|
||||
return CMD_RET_USAGE;
|
||||
argc--; argv++;
|
||||
}
|
||||
|
||||
/* Address is specified since argc > 1 */
|
||||
addr = simple_strtoul(argv[0], NULL, 16);
|
||||
addr += base_address;
|
||||
|
||||
/* Length is the number of objects, not number of bytes */
|
||||
length = simple_strtoul(argv[1], NULL, 16);
|
||||
|
||||
/* Read the bytes to search for */
|
||||
end = search_buf + sizeof(search_buf);
|
||||
for (i = 2, ptr = search_buf; i < argc && ptr < end; i++) {
|
||||
if (SUPPORT_64BIT_DATA && size == 8) {
|
||||
u64 val = simple_strtoull(argv[i], NULL, 16);
|
||||
|
||||
*(u64 *)ptr = val;
|
||||
} else if (size == -2) { /* string */
|
||||
int len = min(strlen(argv[i]),
|
||||
(size_t)(end - ptr));
|
||||
|
||||
memcpy(ptr, argv[i], len);
|
||||
ptr += len;
|
||||
continue;
|
||||
} else {
|
||||
u32 val = simple_strtoul(argv[i], NULL, 16);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
*ptr = val;
|
||||
break;
|
||||
case 2:
|
||||
*(u16 *)ptr = val;
|
||||
break;
|
||||
case 4:
|
||||
*(u32 *)ptr = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ptr += size;
|
||||
}
|
||||
search_len = ptr - search_buf;
|
||||
}
|
||||
|
||||
/* Do the search */
|
||||
if (size == -2)
|
||||
size = 1;
|
||||
bytes = size * length;
|
||||
buf = map_sysmem(addr, bytes);
|
||||
last_pos = 0;
|
||||
last_addr = 0;
|
||||
count = 0;
|
||||
for (offset = 0; offset <= bytes - search_len && count < limit;
|
||||
offset += size) {
|
||||
void *ptr = buf + offset;
|
||||
|
||||
if (!memcmp(ptr, search_buf, search_len)) {
|
||||
uint align = (addr + offset) & 0xf;
|
||||
ulong match = addr + offset;
|
||||
|
||||
if (!count || (last_addr & ~0xf) != (match & ~0xf)) {
|
||||
if (!quiet) {
|
||||
if (count)
|
||||
printf("--\n");
|
||||
print_buffer(match - align, ptr - align,
|
||||
size,
|
||||
ALIGN(search_len + align,
|
||||
16) / size, 0);
|
||||
}
|
||||
last_addr = match;
|
||||
last_pos = offset / size;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (!quiet) {
|
||||
printf("%d match%s", count, count == 1 ? "" : "es");
|
||||
if (count == limit)
|
||||
printf(" (repeat command to check for more)");
|
||||
printf("\n");
|
||||
}
|
||||
env_set_hex("memmatches", count);
|
||||
env_set_hex("memaddr", last_addr);
|
||||
env_set_hex("mempos", last_pos);
|
||||
|
||||
unmap_sysmem(buf);
|
||||
|
||||
dp_last_addr = addr + offset / size;
|
||||
dp_last_size = size;
|
||||
dp_last_length = length - offset / size;
|
||||
|
||||
return count ? 0 : CMD_RET_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int do_mem_base(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
@ -391,9 +522,7 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
{
|
||||
ulong addr, length, i, bytes;
|
||||
int size;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
volatile u64 *llp;
|
||||
#endif
|
||||
volatile ulong *llp; /* 64-bit if SUPPORT_64BIT_DATA */
|
||||
volatile u32 *longp;
|
||||
volatile u16 *shortp;
|
||||
volatile u8 *cp;
|
||||
@ -424,13 +553,11 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
* If we have only one object, just run infinite loops.
|
||||
*/
|
||||
if (length == 1) {
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
if (size == 8) {
|
||||
llp = (u64 *)buf;
|
||||
if (SUPPORT_64BIT_DATA && size == 8) {
|
||||
llp = (ulong *)buf;
|
||||
for (;;)
|
||||
i = *llp;
|
||||
}
|
||||
#endif
|
||||
if (size == 4) {
|
||||
longp = (u32 *)buf;
|
||||
for (;;)
|
||||
@ -446,16 +573,14 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
i = *cp;
|
||||
}
|
||||
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
if (size == 8) {
|
||||
if (SUPPORT_64BIT_DATA && size == 8) {
|
||||
for (;;) {
|
||||
llp = (u64 *)buf;
|
||||
llp = (ulong *)buf;
|
||||
i = length;
|
||||
while (i-- > 0)
|
||||
*llp++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (size == 4) {
|
||||
for (;;) {
|
||||
longp = (u32 *)buf;
|
||||
@ -489,12 +614,8 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
{
|
||||
ulong addr, length, i, bytes;
|
||||
int size;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
volatile u64 *llp;
|
||||
u64 data;
|
||||
#else
|
||||
ulong data;
|
||||
#endif
|
||||
volatile ulong *llp; /* 64-bit if SUPPORT_64BIT_DATA */
|
||||
ulong data; /* 64-bit if SUPPORT_64BIT_DATA */
|
||||
volatile u32 *longp;
|
||||
volatile u16 *shortp;
|
||||
volatile u8 *cp;
|
||||
@ -519,11 +640,10 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
length = simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
/* data to write */
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
data = simple_strtoull(argv[3], NULL, 16);
|
||||
#else
|
||||
data = simple_strtoul(argv[3], NULL, 16);
|
||||
#endif
|
||||
if (SUPPORT_64BIT_DATA)
|
||||
data = simple_strtoull(argv[3], NULL, 16);
|
||||
else
|
||||
data = simple_strtoul(argv[3], NULL, 16);
|
||||
|
||||
bytes = size * length;
|
||||
buf = map_sysmem(addr, bytes);
|
||||
@ -532,13 +652,11 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
* If we have only one object, just run infinite loops.
|
||||
*/
|
||||
if (length == 1) {
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
if (size == 8) {
|
||||
llp = (u64 *)buf;
|
||||
if (SUPPORT_64BIT_DATA && size == 8) {
|
||||
llp = (ulong *)buf;
|
||||
for (;;)
|
||||
*llp = data;
|
||||
}
|
||||
#endif
|
||||
if (size == 4) {
|
||||
longp = (u32 *)buf;
|
||||
for (;;)
|
||||
@ -554,16 +672,14 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
*cp = data;
|
||||
}
|
||||
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
if (size == 8) {
|
||||
if (SUPPORT_64BIT_DATA && size == 8) {
|
||||
for (;;) {
|
||||
llp = (u64 *)buf;
|
||||
llp = (ulong *)buf;
|
||||
i = length;
|
||||
while (i-- > 0)
|
||||
*llp++ = data;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (size == 4) {
|
||||
for (;;) {
|
||||
longp = (u32 *)buf;
|
||||
@ -1016,18 +1132,13 @@ static int do_mem_mtest(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
*
|
||||
* Syntax:
|
||||
* mm{.b, .w, .l, .q} {addr}
|
||||
* nm{.b, .w, .l, .q} {addr}
|
||||
*/
|
||||
static int
|
||||
mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
ulong addr;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
u64 i;
|
||||
#else
|
||||
ulong i;
|
||||
#endif
|
||||
ulong i; /* 64-bit if SUPPORT_64BIT_DATA */
|
||||
int nbytes, size;
|
||||
void *ptr = NULL;
|
||||
|
||||
@ -1062,10 +1173,8 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc,
|
||||
printf("%08lx:", addr);
|
||||
if (size == 4)
|
||||
printf(" %08x", *((u32 *)ptr));
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
else if (size == 8)
|
||||
printf(" %016llx", *((u64 *)ptr));
|
||||
#endif
|
||||
else if (SUPPORT_64BIT_DATA && size == 8)
|
||||
printf(" %0lx", *((ulong *)ptr));
|
||||
else if (size == 2)
|
||||
printf(" %04x", *((u16 *)ptr));
|
||||
else
|
||||
@ -1089,11 +1198,10 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc,
|
||||
#endif
|
||||
else {
|
||||
char *endp;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
i = simple_strtoull(console_buffer, &endp, 16);
|
||||
#else
|
||||
i = simple_strtoul(console_buffer, &endp, 16);
|
||||
#endif
|
||||
if (SUPPORT_64BIT_DATA)
|
||||
i = simple_strtoull(console_buffer, &endp, 16);
|
||||
else
|
||||
i = simple_strtoul(console_buffer, &endp, 16);
|
||||
nbytes = endp - console_buffer;
|
||||
if (nbytes) {
|
||||
/* good enough to not time out
|
||||
@ -1101,10 +1209,8 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc,
|
||||
bootretry_reset_cmd_timeout();
|
||||
if (size == 4)
|
||||
*((u32 *)ptr) = i;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
else if (size == 8)
|
||||
*((u64 *)ptr) = i;
|
||||
#endif
|
||||
else if (SUPPORT_64BIT_DATA && size == 8)
|
||||
*((ulong *)ptr) = i;
|
||||
else if (size == 2)
|
||||
*((u16 *)ptr) = i;
|
||||
else
|
||||
@ -1196,65 +1302,51 @@ static int do_random(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
U_BOOT_CMD(
|
||||
md, 3, 1, do_mem_md,
|
||||
"memory display",
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
"[.b, .w, .l, .q] address [# of objects]"
|
||||
#else
|
||||
"[.b, .w, .l] address [# of objects]"
|
||||
#endif
|
||||
"[.b, .w, .l" HELP_Q "] address [# of objects]"
|
||||
);
|
||||
|
||||
|
||||
U_BOOT_CMD(
|
||||
mm, 2, 1, do_mem_mm,
|
||||
"memory modify (auto-incrementing address)",
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
"[.b, .w, .l, .q] address"
|
||||
#else
|
||||
"[.b, .w, .l] address"
|
||||
#endif
|
||||
"[.b, .w, .l" HELP_Q "] address"
|
||||
);
|
||||
|
||||
|
||||
U_BOOT_CMD(
|
||||
nm, 2, 1, do_mem_nm,
|
||||
"memory modify (constant address)",
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
"[.b, .w, .l, .q] address"
|
||||
#else
|
||||
"[.b, .w, .l] address"
|
||||
#endif
|
||||
"[.b, .w, .l" HELP_Q "] address"
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
mw, 4, 1, do_mem_mw,
|
||||
"memory write (fill)",
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
"[.b, .w, .l, .q] address value [count]"
|
||||
#else
|
||||
"[.b, .w, .l] address value [count]"
|
||||
#endif
|
||||
"[.b, .w, .l" HELP_Q "] address value [count]"
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
cp, 4, 1, do_mem_cp,
|
||||
"memory copy",
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
"[.b, .w, .l, .q] source target count"
|
||||
#else
|
||||
"[.b, .w, .l] source target count"
|
||||
#endif
|
||||
"[.b, .w, .l" HELP_Q "] source target count"
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
cmp, 4, 1, do_mem_cmp,
|
||||
"memory compare",
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
"[.b, .w, .l, .q] addr1 addr2 count"
|
||||
#else
|
||||
"[.b, .w, .l] addr1 addr2 count"
|
||||
#endif
|
||||
"[.b, .w, .l" HELP_Q "] addr1 addr2 count"
|
||||
);
|
||||
|
||||
#ifdef CONFIG_MEM_SEARCH
|
||||
/**************************************************/
|
||||
U_BOOT_CMD(
|
||||
ms, 255, 1, do_mem_search,
|
||||
"memory search",
|
||||
"[.b, .w, .l" HELP_Q ", .s] [-q | -<n>] address #-of-objects <value>..."
|
||||
" -q = quiet, -l<val> = match limit" :
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CMD_CRC32
|
||||
|
||||
#ifndef CONFIG_CRC32_VERIFY
|
||||
@ -1299,22 +1391,14 @@ U_BOOT_CMD(
|
||||
U_BOOT_CMD(
|
||||
loop, 3, 1, do_mem_loop,
|
||||
"infinite loop on address range",
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
"[.b, .w, .l, .q] address number_of_objects"
|
||||
#else
|
||||
"[.b, .w, .l] address number_of_objects"
|
||||
#endif
|
||||
"[.b, .w, .l" HELP_Q "] address number_of_objects"
|
||||
);
|
||||
|
||||
#ifdef CONFIG_LOOPW
|
||||
U_BOOT_CMD(
|
||||
loopw, 4, 1, do_mem_loopw,
|
||||
"infinite write loop on address range",
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
"[.b, .w, .l, .q] address number_of_objects data_to_write"
|
||||
#else
|
||||
"[.b, .w, .l] address number_of_objects data_to_write"
|
||||
#endif
|
||||
"[.b, .w, .l" HELP_Q "] address number_of_objects data_to_write"
|
||||
);
|
||||
#endif /* CONFIG_LOOPW */
|
||||
|
||||
@ -1330,21 +1414,13 @@ U_BOOT_CMD(
|
||||
U_BOOT_CMD(
|
||||
mdc, 4, 1, do_mem_mdc,
|
||||
"memory display cyclic",
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
"[.b, .w, .l, .q] address count delay(ms)"
|
||||
#else
|
||||
"[.b, .w, .l] address count delay(ms)"
|
||||
#endif
|
||||
"[.b, .w, .l" HELP_Q "] address count delay(ms)"
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
mwc, 4, 1, do_mem_mwc,
|
||||
"memory write cyclic",
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
"[.b, .w, .l, .q] address value delay(ms)"
|
||||
#else
|
||||
"[.b, .w, .l] address value delay(ms)"
|
||||
#endif
|
||||
"[.b, .w, .l" HELP_Q "] address value delay(ms)"
|
||||
);
|
||||
#endif /* CONFIG_CMD_MX_CYCLIC */
|
||||
|
||||
|
23
cmd/panic.c
Normal file
23
cmd/panic.c
Normal file
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
static int do_panic(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
char *text = (argc < 2) ? "" : argv[1];
|
||||
|
||||
panic(text);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
panic, 2, 1, do_panic,
|
||||
"Panic with optional message",
|
||||
"[message]"
|
||||
);
|
@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <compiler.h>
|
||||
#include <command.h>
|
||||
#include <console.h>
|
||||
#include <env.h>
|
||||
@ -473,12 +474,12 @@ int cmd_get_data_size(char* arg, int default_size)
|
||||
return 2;
|
||||
case 'l':
|
||||
return 4;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
case 'q':
|
||||
return 8;
|
||||
#endif
|
||||
case 's':
|
||||
return -2;
|
||||
case 'q':
|
||||
if (MEM_SUPPORT_64BIT_DATA)
|
||||
return 8;
|
||||
/* no break */
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -619,9 +619,12 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
|
||||
* Booting a next-stage U-Boot may require us to append the FDT.
|
||||
* We allow this to fail, as the U-Boot image might embed its FDT.
|
||||
*/
|
||||
if (spl_image->os == IH_OS_U_BOOT)
|
||||
spl_fit_append_fdt(spl_image, info, sector, fit,
|
||||
images, base_offset);
|
||||
if (spl_image->os == IH_OS_U_BOOT) {
|
||||
ret = spl_fit_append_fdt(spl_image, info, sector, fit,
|
||||
images, base_offset);
|
||||
if (!IS_ENABLED(CONFIG_OF_EMBED) && ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
firmware_node = node;
|
||||
/* Now check if there are more images for us to load */
|
||||
|
@ -42,13 +42,16 @@ static int spl_nand_load_image(struct spl_image_info *spl_image,
|
||||
static ulong spl_nand_fit_read(struct spl_load_info *load, ulong offs,
|
||||
ulong size, void *dst)
|
||||
{
|
||||
int ret;
|
||||
ulong sector;
|
||||
int err;
|
||||
|
||||
ret = nand_spl_load_image(offs, size, dst);
|
||||
if (!ret)
|
||||
return size;
|
||||
else
|
||||
sector = *(int *)load->priv;
|
||||
offs = sector + nand_spl_adjust_offset(sector, offs - sector);
|
||||
err = nand_spl_load_image(offs, size, dst);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int spl_nand_load_element(struct spl_image_info *spl_image,
|
||||
@ -66,7 +69,7 @@ static int spl_nand_load_element(struct spl_image_info *spl_image,
|
||||
|
||||
debug("Found FIT\n");
|
||||
load.dev = NULL;
|
||||
load.priv = NULL;
|
||||
load.priv = &offset;
|
||||
load.filename = NULL;
|
||||
load.bl_len = 1;
|
||||
load.read = spl_nand_fit_read;
|
||||
|
@ -2,7 +2,7 @@ ST33TPHF20 SPI TPMv2.0 bindings
|
||||
-------------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "tis,tpm2-spi"
|
||||
- compatible : Should be "tcg,tpm_tis-spi"
|
||||
- reg : SPI Chip select
|
||||
|
||||
Optional properties:
|
||||
@ -12,7 +12,7 @@ Optional properties:
|
||||
Example:
|
||||
|
||||
tpm@1 {
|
||||
compatible = "tis,tpm2-spi";
|
||||
compatible = "tcg,tpm_tis-spi";
|
||||
reg = <1>;
|
||||
spi-max-frequency = <10000000>;
|
||||
};
|
||||
|
@ -41,6 +41,34 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nand_spl_adjust_offset - Adjust offset from a starting sector
|
||||
* @sector: Address of the sector
|
||||
* @offs: Offset starting from @sector
|
||||
*
|
||||
* If one or more bad blocks are in the address space between @sector
|
||||
* and @sector + @offs, @offs is increased by the NAND block size for
|
||||
* each bad block found.
|
||||
*/
|
||||
u32 nand_spl_adjust_offset(u32 sector, u32 offs)
|
||||
{
|
||||
unsigned int block, lastblock;
|
||||
|
||||
block = sector / CONFIG_SYS_NAND_BLOCK_SIZE;
|
||||
lastblock = (sector + offs) / CONFIG_SYS_NAND_BLOCK_SIZE;
|
||||
|
||||
while (block <= lastblock) {
|
||||
if (nand_is_bad_block(block)) {
|
||||
offs += CONFIG_SYS_NAND_BLOCK_SIZE;
|
||||
lastblock++;
|
||||
}
|
||||
|
||||
block++;
|
||||
}
|
||||
|
||||
return offs;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_UBI
|
||||
/*
|
||||
* Temporary storage for non NAND page aligned and non NAND page sized
|
||||
|
@ -676,7 +676,7 @@ static const struct tpm_tis_chip_data tpm_tis_std_chip_data = {
|
||||
|
||||
static const struct udevice_id tpm_tis_spi_ids[] = {
|
||||
{
|
||||
.compatible = "tis,tpm2-spi",
|
||||
.compatible = "tcg,tpm_tis-spi",
|
||||
.data = (ulong)&tpm_tis_std_chip_data,
|
||||
},
|
||||
{ }
|
||||
|
@ -104,6 +104,7 @@ struct tpm_cmd_t {
|
||||
/* Max number of iterations after i2c NAK */
|
||||
#define MAX_COUNT 3
|
||||
|
||||
#ifndef __TPM_V2_H
|
||||
/*
|
||||
* Max number of iterations after i2c NAK for 'long' commands
|
||||
*
|
||||
@ -127,5 +128,6 @@ enum tis_status {
|
||||
TPM_STS_DATA_AVAIL = 0x10,
|
||||
TPM_STS_DATA_EXPECT = 0x08,
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -145,7 +145,9 @@ typedef unsigned long int uintptr_t;
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#ifdef __LP64__
|
||||
#define MEM_SUPPORT_64BIT_DATA
|
||||
#define MEM_SUPPORT_64BIT_DATA 1
|
||||
#else
|
||||
#define MEM_SUPPORT_64BIT_DATA 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -112,7 +112,7 @@ void printhex8(unsigned int value);
|
||||
void printdec(unsigned int value);
|
||||
|
||||
#ifdef CONFIG_DEBUG_UART_ANNOUNCE
|
||||
#define _DEBUG_UART_ANNOUNCE printascii("<debug_uart> ");
|
||||
#define _DEBUG_UART_ANNOUNCE printascii("\n<debug_uart>\n");
|
||||
#else
|
||||
#define _DEBUG_UART_ANNOUNCE
|
||||
#endif
|
||||
|
@ -120,6 +120,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length,
|
||||
int allexcept);
|
||||
int nand_get_lock_status(struct mtd_info *mtd, loff_t offset);
|
||||
|
||||
u32 nand_spl_adjust_offset(u32 sector, u32 offs);
|
||||
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst);
|
||||
int nand_spl_read_block(int block, int offset, int len, void *dst);
|
||||
void nand_deselect(void);
|
||||
|
@ -155,7 +155,7 @@ struct spl_image_info {
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* Information required to load data from a device
|
||||
*
|
||||
* @dev: Pointer to the device, e.g. struct mmc *
|
||||
|
@ -70,6 +70,7 @@ enum tpm2_handles {
|
||||
* @TPM2_CC_DAM_RESET: TPM2_DictionaryAttackLockReset().
|
||||
* @TPM2_CC_DAM_PARAMETERS: TPM2_DictionaryAttackParameters().
|
||||
* @TPM2_CC_GET_CAPABILITY: TPM2_GetCapibility().
|
||||
* @TPM2_CC_GET_RANDOM: TPM2_GetRandom().
|
||||
* @TPM2_CC_PCR_READ: TPM2_PCR_Read().
|
||||
* @TPM2_CC_PCR_EXTEND: TPM2_PCR_Extend().
|
||||
* @TPM2_CC_PCR_SETAUTHVAL: TPM2_PCR_SetAuthValue().
|
||||
@ -85,6 +86,7 @@ enum tpm2_command_codes {
|
||||
TPM2_CC_DAM_PARAMETERS = 0x013A,
|
||||
TPM2_CC_NV_READ = 0x014E,
|
||||
TPM2_CC_GET_CAPABILITY = 0x017A,
|
||||
TPM2_CC_GET_RANDOM = 0x017B,
|
||||
TPM2_CC_PCR_READ = 0x017E,
|
||||
TPM2_CC_PCR_EXTEND = 0x0182,
|
||||
TPM2_CC_PCR_SETAUTHVAL = 0x0183,
|
||||
@ -339,4 +341,15 @@ u32 tpm2_pcr_setauthvalue(struct udevice *dev, const char *pw,
|
||||
const ssize_t pw_sz, u32 index, const char *key,
|
||||
const ssize_t key_sz);
|
||||
|
||||
/**
|
||||
* Issue a TPM2_GetRandom command.
|
||||
*
|
||||
* @dev TPM device
|
||||
* @param data output buffer for the random bytes
|
||||
* @param count size of output buffer
|
||||
*
|
||||
* @return return code of the operation
|
||||
*/
|
||||
u32 tpm2_get_random(struct udevice *dev, void *data, u32 count);
|
||||
|
||||
#endif /* __TPM_V2_H */
|
||||
|
@ -82,6 +82,20 @@ static inline int rsa_add_verify_data(struct image_sign_info *info,
|
||||
#endif
|
||||
|
||||
#if IMAGE_ENABLE_VERIFY
|
||||
/**
|
||||
* rsa_verify_hash() - Verify a signature against a hash
|
||||
*
|
||||
* Verify a RSA PKCS1.5 signature against an expected hash.
|
||||
*
|
||||
* @info: Specifies key and FIT information
|
||||
* @hash: Hash according to algorithm specified in @info
|
||||
* @sig: Signature
|
||||
* @sig_len: Number of bytes in signature
|
||||
* @return 0 if verified, -ve on error
|
||||
*/
|
||||
int rsa_verify_hash(struct image_sign_info *info,
|
||||
const uint8_t *hash, uint8_t *sig, uint sig_len);
|
||||
|
||||
/**
|
||||
* rsa_verify() - Verify a signature against some data
|
||||
*
|
||||
@ -108,6 +122,13 @@ int padding_pss_verify(struct image_sign_info *info,
|
||||
const uint8_t *hash, int hash_len);
|
||||
#endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
|
||||
#else
|
||||
static inline int rsa_verify_hash(struct image_sign_info *info,
|
||||
const uint8_t *hash,
|
||||
uint8_t *sig, uint sig_len)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static inline int rsa_verify(struct image_sign_info *info,
|
||||
const struct image_region region[], int region_count,
|
||||
uint8_t *sig, uint sig_len)
|
||||
|
@ -138,19 +138,13 @@ int print_buffer(ulong addr, const void *data, uint width, uint count,
|
||||
{
|
||||
/* linebuf as a union causes proper alignment */
|
||||
union linebuf {
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1];
|
||||
#endif
|
||||
uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1];
|
||||
uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1];
|
||||
uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1];
|
||||
} lb;
|
||||
int i;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
uint64_t __maybe_unused x;
|
||||
#else
|
||||
uint32_t __maybe_unused x;
|
||||
#endif
|
||||
ulong x;
|
||||
|
||||
if (linelen*width > MAX_LINE_LENGTH_BYTES)
|
||||
linelen = MAX_LINE_LENGTH_BYTES / width;
|
||||
@ -169,20 +163,16 @@ int print_buffer(ulong addr, const void *data, uint width, uint count,
|
||||
for (i = 0; i < thislinelen; i++) {
|
||||
if (width == 4)
|
||||
x = lb.ui[i] = *(volatile uint32_t *)data;
|
||||
#ifdef MEM_SUPPORT_64BIT_DATA
|
||||
else if (width == 8)
|
||||
x = lb.uq[i] = *(volatile uint64_t *)data;
|
||||
#endif
|
||||
else if (MEM_SUPPORT_64BIT_DATA && width == 8)
|
||||
x = lb.uq[i] = *(volatile ulong *)data;
|
||||
else if (width == 2)
|
||||
x = lb.us[i] = *(volatile uint16_t *)data;
|
||||
else
|
||||
x = lb.uc[i] = *(volatile uint8_t *)data;
|
||||
#if defined(CONFIG_SPL_BUILD)
|
||||
printf(" %x", (uint)x);
|
||||
#elif defined(MEM_SUPPORT_64BIT_DATA)
|
||||
printf(" %0*llx", width * 2, (long long)x);
|
||||
#else
|
||||
printf(" %0*x", width * 2, x);
|
||||
printf(" %0*lx", width * 2, x);
|
||||
#endif
|
||||
data += width;
|
||||
}
|
||||
|
@ -5,6 +5,6 @@
|
||||
# (C) Copyright 2000-2007
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
|
||||
obj-$(CONFIG_$(SPL_)RSA_VERIFY) += rsa-verify.o rsa-checksum.o
|
||||
obj-$(CONFIG_RSA_VERIFY_WITH_PKEY) += rsa-keyprop.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)RSA_VERIFY) += rsa-verify.o rsa-checksum.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)RSA_VERIFY_WITH_PKEY) += rsa-keyprop.o
|
||||
obj-$(CONFIG_RSA_SOFTWARE_EXP) += rsa-mod-exp.o
|
||||
|
@ -654,21 +654,17 @@ int rsa_gen_key_prop(const void *key, uint32_t keylen, struct key_prop **prop)
|
||||
{
|
||||
struct rsa_key rsa_key;
|
||||
uint32_t *n = NULL, *rr = NULL, *rrtmp = NULL;
|
||||
const int max_rsa_size = 4096;
|
||||
int rlen, i, ret;
|
||||
int rlen, i, ret = 0;
|
||||
|
||||
*prop = calloc(sizeof(**prop), 1);
|
||||
n = calloc(sizeof(uint32_t), 1 + (max_rsa_size >> 5));
|
||||
rr = calloc(sizeof(uint32_t), 1 + (max_rsa_size >> 5));
|
||||
rrtmp = calloc(sizeof(uint32_t), 1 + (max_rsa_size >> 5));
|
||||
if (!(*prop) || !n || !rr || !rrtmp) {
|
||||
if (!(*prop)) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = rsa_parse_pub_key(&rsa_key, key, keylen);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto out;
|
||||
|
||||
/* modulus */
|
||||
/* removing leading 0's */
|
||||
@ -678,20 +674,28 @@ int rsa_gen_key_prop(const void *key, uint32_t keylen, struct key_prop **prop)
|
||||
(*prop)->modulus = malloc(rsa_key.n_sz - i);
|
||||
if (!(*prop)->modulus) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
goto out;
|
||||
}
|
||||
memcpy((void *)(*prop)->modulus, &rsa_key.n[i], rsa_key.n_sz - i);
|
||||
|
||||
n = calloc(sizeof(uint32_t), 1 + ((*prop)->num_bits >> 5));
|
||||
rr = calloc(sizeof(uint32_t), 1 + (((*prop)->num_bits * 2) >> 5));
|
||||
rrtmp = calloc(sizeof(uint32_t), 2 + (((*prop)->num_bits * 2) >> 5));
|
||||
if (!n || !rr || !rrtmp) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* exponent */
|
||||
(*prop)->public_exponent = calloc(1, sizeof(uint64_t));
|
||||
if (!(*prop)->public_exponent) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
goto out;
|
||||
}
|
||||
memcpy((void *)(*prop)->public_exponent + sizeof(uint64_t)
|
||||
- rsa_key.e_sz,
|
||||
rsa_key.e, rsa_key.e_sz);
|
||||
(*prop)->exp_len = rsa_key.e_sz;
|
||||
(*prop)->exp_len = sizeof(uint64_t);
|
||||
|
||||
/* n0 inverse */
|
||||
br_i32_decode(n, &rsa_key.n[i], rsa_key.n_sz - i);
|
||||
@ -710,16 +714,15 @@ int rsa_gen_key_prop(const void *key, uint32_t keylen, struct key_prop **prop)
|
||||
(*prop)->rr = malloc(rlen);
|
||||
if (!(*prop)->rr) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
goto out;
|
||||
}
|
||||
br_i32_encode((void *)(*prop)->rr, rlen, rr);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
out:
|
||||
free(n);
|
||||
free(rr);
|
||||
free(rrtmp);
|
||||
rsa_free_key_prop(*prop);
|
||||
if (ret < 0)
|
||||
rsa_free_key_prop(*prop);
|
||||
return ret;
|
||||
}
|
||||
|
@ -194,6 +194,19 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* padding_pss_verify() - verify the pss padding of a signature
|
||||
*
|
||||
* Only works with a rsa_pss_saltlen:-2 (default value) right now
|
||||
* saltlen:-1 "set the salt length to the digest length" is currently
|
||||
* not supported.
|
||||
*
|
||||
* @info: Specifies key and FIT information
|
||||
* @msg: byte array of message, len equal to msg_len
|
||||
* @msg_len: Message length
|
||||
* @hash: Pointer to the expected hash
|
||||
* @hash_len: Length of the hash
|
||||
*/
|
||||
int padding_pss_verify(struct image_sign_info *info,
|
||||
uint8_t *msg, int msg_len,
|
||||
const uint8_t *hash, int hash_len)
|
||||
@ -285,7 +298,7 @@ out:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(FIT_SIGNATURE) || IS_ENABLED(CONFIG_RSA_VERIFY_WITH_PKEY)
|
||||
#if CONFIG_IS_ENABLED(FIT_SIGNATURE) || CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY)
|
||||
/**
|
||||
* rsa_verify_key() - Verify a signature against some data using RSA Key
|
||||
*
|
||||
@ -359,7 +372,7 @@ static int rsa_verify_key(struct image_sign_info *info,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RSA_VERIFY_WITH_PKEY
|
||||
#if CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY)
|
||||
/**
|
||||
* rsa_verify_with_pkey() - Verify a signature against some data using
|
||||
* only modulus and exponent as RSA key properties.
|
||||
@ -465,34 +478,12 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
|
||||
}
|
||||
#endif
|
||||
|
||||
int rsa_verify(struct image_sign_info *info,
|
||||
const struct image_region region[], int region_count,
|
||||
uint8_t *sig, uint sig_len)
|
||||
int rsa_verify_hash(struct image_sign_info *info,
|
||||
const uint8_t *hash, uint8_t *sig, uint sig_len)
|
||||
{
|
||||
/* Reserve memory for maximum checksum-length */
|
||||
uint8_t hash[info->crypto->key_len];
|
||||
int ret = -EACCES;
|
||||
|
||||
/*
|
||||
* Verify that the checksum-length does not exceed the
|
||||
* rsa-signature-length
|
||||
*/
|
||||
if (info->checksum->checksum_len >
|
||||
info->crypto->key_len) {
|
||||
debug("%s: invlaid checksum-algorithm %s for %s\n",
|
||||
__func__, info->checksum->name, info->crypto->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Calculate checksum with checksum-algorithm */
|
||||
ret = info->checksum->calculate(info->checksum->name,
|
||||
region, region_count, hash);
|
||||
if (ret < 0) {
|
||||
debug("%s: Error in checksum calculation\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_RSA_VERIFY_WITH_PKEY) && !info->fdt_blob) {
|
||||
if (CONFIG_IS_ENABLED(RSA_VERIFY_WITH_PKEY) && !info->fdt_blob) {
|
||||
/* don't rely on fdt properties */
|
||||
ret = rsa_verify_with_pkey(info, hash, sig, sig_len);
|
||||
|
||||
@ -542,3 +533,33 @@ int rsa_verify(struct image_sign_info *info,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rsa_verify(struct image_sign_info *info,
|
||||
const struct image_region region[], int region_count,
|
||||
uint8_t *sig, uint sig_len)
|
||||
{
|
||||
/* Reserve memory for maximum checksum-length */
|
||||
uint8_t hash[info->crypto->key_len];
|
||||
int ret = -EACCES;
|
||||
|
||||
/*
|
||||
* Verify that the checksum-length does not exceed the
|
||||
* rsa-signature-length
|
||||
*/
|
||||
if (info->checksum->checksum_len >
|
||||
info->crypto->key_len) {
|
||||
debug("%s: invlaid checksum-algorithm %s for %s\n",
|
||||
__func__, info->checksum->name, info->crypto->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Calculate checksum with checksum-algorithm */
|
||||
ret = info->checksum->calculate(info->checksum->name,
|
||||
region, region_count, hash);
|
||||
if (ret < 0) {
|
||||
debug("%s: Error in checksum calculation\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rsa_verify_hash(info, hash, sig, sig_len);
|
||||
}
|
||||
|
44
lib/tpm-v2.c
44
lib/tpm-v2.c
@ -422,3 +422,47 @@ u32 tpm2_pcr_setauthvalue(struct udevice *dev, const char *pw,
|
||||
|
||||
return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
|
||||
}
|
||||
|
||||
u32 tpm2_get_random(struct udevice *dev, void *data, u32 count)
|
||||
{
|
||||
const u8 command_v2[10] = {
|
||||
tpm_u16(TPM2_ST_NO_SESSIONS),
|
||||
tpm_u32(12),
|
||||
tpm_u32(TPM2_CC_GET_RANDOM),
|
||||
};
|
||||
u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
|
||||
|
||||
const size_t data_size_offset = 10;
|
||||
const size_t data_offset = 12;
|
||||
size_t response_length = sizeof(response);
|
||||
u32 data_size;
|
||||
u8 *out = data;
|
||||
|
||||
while (count > 0) {
|
||||
u32 this_bytes = min((size_t)count,
|
||||
sizeof(response) - data_offset);
|
||||
u32 err;
|
||||
|
||||
if (pack_byte_string(buf, sizeof(buf), "sw",
|
||||
0, command_v2, sizeof(command_v2),
|
||||
sizeof(command_v2), this_bytes))
|
||||
return TPM_LIB_ERROR;
|
||||
err = tpm_sendrecv_command(dev, buf, response,
|
||||
&response_length);
|
||||
if (err)
|
||||
return err;
|
||||
if (unpack_byte_string(response, response_length, "w",
|
||||
data_size_offset, &data_size))
|
||||
return TPM_LIB_ERROR;
|
||||
if (data_size > this_bytes)
|
||||
return TPM_LIB_ERROR;
|
||||
if (unpack_byte_string(response, response_length, "s",
|
||||
data_offset, out, data_size))
|
||||
return TPM_LIB_ERROR;
|
||||
|
||||
count -= data_size;
|
||||
out += data_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
# (C) Copyright 2012 The Chromium Authors
|
||||
|
||||
obj-$(CONFIG_SANDBOX) += bloblist.o
|
||||
obj-$(CONFIG_CMDLINE) += cmd/
|
||||
obj-$(CONFIG_UNIT_TEST) += cmd_ut.o
|
||||
obj-$(CONFIG_UNIT_TEST) += ut.o
|
||||
obj-$(CONFIG_SANDBOX) += command_ut.o
|
||||
|
5
test/cmd/Makefile
Normal file
5
test/cmd/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (c) 2013 Google, Inc
|
||||
|
||||
obj-$(CONFIG_MEM_SEARCH) += mem_search.o
|
275
test/cmd/mem_search.c
Normal file
275
test/cmd/mem_search.c
Normal file
@ -0,0 +1,275 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Tests for memory commands
|
||||
*
|
||||
* Copyright 2020 Google LLC
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <console.h>
|
||||
#include <mapmem.h>
|
||||
#include <dm/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
#define BUF_SIZE 0x100
|
||||
|
||||
/* Test 'ms' command with bytes */
|
||||
static int dm_test_ms_b(struct unit_test_state *uts)
|
||||
{
|
||||
u8 *buf;
|
||||
|
||||
buf = map_sysmem(0, BUF_SIZE + 1);
|
||||
memset(buf, '\0', BUF_SIZE);
|
||||
buf[0x0] = 0x12;
|
||||
buf[0x31] = 0x12;
|
||||
buf[0xff] = 0x12;
|
||||
buf[0x100] = 0x12;
|
||||
console_record_reset();
|
||||
run_command("ms.b 1 ff 12", 0);
|
||||
ut_assert_nextline("00000030: 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................");
|
||||
ut_assert_nextline("--");
|
||||
ut_assert_nextline("000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 ................");
|
||||
ut_assert_nextline("2 matches");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(2, env_get_hex("memmatches", 0));
|
||||
ut_asserteq(0xff, env_get_hex("memaddr", 0));
|
||||
ut_asserteq(0xfe, env_get_hex("mempos", 0));
|
||||
|
||||
unmap_sysmem(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ms_b, 0);
|
||||
|
||||
/* Test 'ms' command with 16-bit values */
|
||||
static int dm_test_ms_w(struct unit_test_state *uts)
|
||||
{
|
||||
u16 *buf;
|
||||
|
||||
buf = map_sysmem(0, BUF_SIZE + 2);
|
||||
memset(buf, '\0', BUF_SIZE);
|
||||
buf[0x34 / 2] = 0x1234;
|
||||
buf[BUF_SIZE / 2] = 0x1234;
|
||||
console_record_reset();
|
||||
run_command("ms.w 0 80 1234", 0);
|
||||
ut_assert_nextline("00000030: 0000 0000 1234 0000 0000 0000 0000 0000 ....4...........");
|
||||
ut_assert_nextline("1 match");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(1, env_get_hex("memmatches", 0));
|
||||
ut_asserteq(0x34, env_get_hex("memaddr", 0));
|
||||
ut_asserteq(0x34 / 2, env_get_hex("mempos", 0));
|
||||
|
||||
unmap_sysmem(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ms_w, 0);
|
||||
|
||||
/* Test 'ms' command with 32-bit values */
|
||||
static int dm_test_ms_l(struct unit_test_state *uts)
|
||||
{
|
||||
u32 *buf;
|
||||
|
||||
buf = map_sysmem(0, BUF_SIZE + 4);
|
||||
memset(buf, '\0', BUF_SIZE);
|
||||
buf[0x38 / 4] = 0x12345678;
|
||||
buf[BUF_SIZE / 4] = 0x12345678;
|
||||
console_record_reset();
|
||||
run_command("ms 0 40 12345678", 0);
|
||||
ut_assert_nextline("00000030: 00000000 00000000 12345678 00000000 ........xV4.....");
|
||||
ut_assert_nextline("1 match");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(1, env_get_hex("memmatches", 0));
|
||||
ut_asserteq(0x38, env_get_hex("memaddr", 0));
|
||||
ut_asserteq(0x38 / 4, env_get_hex("mempos", 0));
|
||||
|
||||
console_record_reset();
|
||||
run_command("ms 0 80 12345679", 0);
|
||||
ut_assert_nextline("0 matches");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(0, env_get_hex("memmatches", 0));
|
||||
ut_asserteq(0, env_get_hex("memaddr", 0));
|
||||
ut_asserteq(0 / 4, env_get_hex("mempos", 0));
|
||||
|
||||
unmap_sysmem(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ms_l, 0);
|
||||
|
||||
/* Test 'ms' command with continuation */
|
||||
static int dm_test_ms_cont(struct unit_test_state *uts)
|
||||
{
|
||||
char *const args[] = {"ms.b", "0", "100", "34"};
|
||||
int repeatable;
|
||||
u8 *buf;
|
||||
int i;
|
||||
|
||||
buf = map_sysmem(0, BUF_SIZE);
|
||||
memset(buf, '\0', BUF_SIZE);
|
||||
for (i = 5; i < 0x33; i += 3)
|
||||
buf[i] = 0x34;
|
||||
console_record_reset();
|
||||
run_command("ms.b 0 100 34", 0);
|
||||
ut_assert_nextlinen("00000000: 00 00 00 00 00 34 00 00 34 00 00 34 00 00 34 00");
|
||||
ut_assert_nextline("--");
|
||||
ut_assert_nextlinen("00000010: 00 34 00 00 34 00 00 34 00 00 34 00 00 34 00 00");
|
||||
ut_assert_nextline("--");
|
||||
ut_assert_nextlinen("00000020: 34 00 00 34 00 00 34 00 00 34 00 00 34 00 00 34");
|
||||
ut_assert_nextlinen("10 matches (repeat command to check for more)");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(10, env_get_hex("memmatches", 0));
|
||||
ut_asserteq(0x20, env_get_hex("memaddr", 0));
|
||||
ut_asserteq(0x20, env_get_hex("mempos", 0));
|
||||
|
||||
/*
|
||||
* run_command() ignoes the repeatable flag when using hush, so call
|
||||
* cmd_process() directly
|
||||
*/
|
||||
console_record_reset();
|
||||
cmd_process(CMD_FLAG_REPEAT, 4, args, &repeatable, NULL);
|
||||
ut_assert_nextlinen("00000020: 34 00 00 34 00 00 34 00 00 34 00 00 34 00 00 34");
|
||||
ut_assert_nextline("--");
|
||||
ut_assert_nextlinen("00000030: 00 00 34 00 00 00 00 00");
|
||||
ut_assert_nextlinen("6 matches");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(6, env_get_hex("memmatches", 0));
|
||||
ut_asserteq(0x32, env_get_hex("memaddr", 0));
|
||||
|
||||
/* 0x32 less 0x21, where the second search started */
|
||||
ut_asserteq(0x11, env_get_hex("mempos", 0));
|
||||
|
||||
unmap_sysmem(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ms_cont, 0);
|
||||
|
||||
/* Test 'ms' command with multiple values */
|
||||
static int dm_test_ms_mult(struct unit_test_state *uts)
|
||||
{
|
||||
static const char str[] = "hello";
|
||||
char *buf;
|
||||
|
||||
buf = map_sysmem(0, BUF_SIZE + 5);
|
||||
memset(buf, '\0', BUF_SIZE);
|
||||
strcpy(buf + 0x1e, str);
|
||||
strcpy(buf + 0x63, str);
|
||||
strcpy(buf + BUF_SIZE - strlen(str) + 1, str);
|
||||
console_record_reset();
|
||||
run_command("ms.b 0 100 68 65 6c 6c 6f", 0);
|
||||
ut_assert_nextline("00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68 65 ..............he");
|
||||
ut_assert_nextline("00000020: 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 llo.............");
|
||||
ut_assert_nextline("--");
|
||||
ut_assert_nextline("00000060: 00 00 00 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 ...hello........");
|
||||
ut_assert_nextline("2 matches");
|
||||
ut_assert_console_end();
|
||||
unmap_sysmem(buf);
|
||||
|
||||
ut_asserteq(2, env_get_hex("memmatches", 0));
|
||||
ut_asserteq(0x63, env_get_hex("memaddr", 0));
|
||||
ut_asserteq(0x63, env_get_hex("mempos", 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ms_mult, 0);
|
||||
|
||||
/* Test 'ms' command with string */
|
||||
static int dm_test_ms_s(struct unit_test_state *uts)
|
||||
{
|
||||
static const char str[] = "hello";
|
||||
static const char str2[] = "hellothere";
|
||||
char *buf;
|
||||
|
||||
buf = map_sysmem(0, BUF_SIZE);
|
||||
memset(buf, '\0', BUF_SIZE);
|
||||
strcpy(buf + 0x1e, str);
|
||||
strcpy(buf + 0x63, str);
|
||||
strcpy(buf + 0xa1, str2);
|
||||
console_record_reset();
|
||||
run_command("ms.s 0 100 hello", 0);
|
||||
ut_assert_nextline("00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68 65 ..............he");
|
||||
ut_assert_nextline("00000020: 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 llo.............");
|
||||
ut_assert_nextline("--");
|
||||
ut_assert_nextline("00000060: 00 00 00 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 ...hello........");
|
||||
ut_assert_nextline("--");
|
||||
ut_assert_nextline("000000a0: 00 68 65 6c 6c 6f 74 68 65 72 65 00 00 00 00 00 .hellothere.....");
|
||||
ut_assert_nextline("3 matches");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(3, env_get_hex("memmatches", 0));
|
||||
ut_asserteq(0xa1, env_get_hex("memaddr", 0));
|
||||
ut_asserteq(0xa1, env_get_hex("mempos", 0));
|
||||
|
||||
console_record_reset();
|
||||
run_command("ms.s 0 100 hello there", 0);
|
||||
ut_assert_nextline("000000a0: 00 68 65 6c 6c 6f 74 68 65 72 65 00 00 00 00 00 .hellothere.....");
|
||||
ut_assert_nextline("1 match");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(1, env_get_hex("memmatches", 0));
|
||||
ut_asserteq(0xa1, env_get_hex("memaddr", 0));
|
||||
ut_asserteq(0xa1, env_get_hex("mempos", 0));
|
||||
|
||||
unmap_sysmem(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ms_s, 0);
|
||||
|
||||
/* Test 'ms' command with limit */
|
||||
static int dm_test_ms_limit(struct unit_test_state *uts)
|
||||
{
|
||||
u8 *buf;
|
||||
|
||||
buf = map_sysmem(0, BUF_SIZE + 1);
|
||||
memset(buf, '\0', BUF_SIZE);
|
||||
buf[0x0] = 0x12;
|
||||
buf[0x31] = 0x12;
|
||||
buf[0x62] = 0x12;
|
||||
buf[0x76] = 0x12;
|
||||
console_record_reset();
|
||||
run_command("ms.b -l2 1 ff 12", 0);
|
||||
ut_assert_nextline("00000030: 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................");
|
||||
ut_assert_nextline("--");
|
||||
ut_assert_nextlinen("00000060: 00 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00");
|
||||
ut_assert_nextline("2 matches (repeat command to check for more)");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(2, env_get_hex("memmatches", 0));
|
||||
ut_asserteq(0x62, env_get_hex("memaddr", 0));
|
||||
ut_asserteq(0x61, env_get_hex("mempos", 0));
|
||||
|
||||
unmap_sysmem(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ms_limit, 0);
|
||||
|
||||
/* Test 'ms' command in quiet mode */
|
||||
static int dm_test_ms_quiet(struct unit_test_state *uts)
|
||||
{
|
||||
u8 *buf;
|
||||
|
||||
buf = map_sysmem(0, BUF_SIZE + 1);
|
||||
memset(buf, '\0', BUF_SIZE);
|
||||
buf[0x0] = 0x12;
|
||||
buf[0x31] = 0x12;
|
||||
buf[0x62] = 0x12;
|
||||
buf[0x76] = 0x12;
|
||||
console_record_reset();
|
||||
run_command("ms.b -l2 1 ff 12", 0);
|
||||
ut_assert_console_end();
|
||||
unmap_sysmem(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ms_quiet, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user