Home | History | Annotate | Download | only in cmd
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2011
      4  * Joe Hershberger, National Instruments, joe.hershberger (at) ni.com
      5  *
      6  * (C) Copyright 2000
      7  * Wolfgang Denk, DENX Software Engineering, wd (at) denx.de.
      8  */
      9 
     10 #include <common.h>
     11 #include <command.h>
     12 #include <mapmem.h>
     13 #include <u-boot/md5.h>
     14 #include <asm/io.h>
     15 
     16 /*
     17  * Store the resulting sum to an address or variable
     18  */
     19 static void store_result(const u8 *sum, const char *dest)
     20 {
     21 	unsigned int i;
     22 
     23 	if (*dest == '*') {
     24 		u8 *ptr;
     25 
     26 		ptr = (u8 *)simple_strtoul(dest + 1, NULL, 16);
     27 		for (i = 0; i < 16; i++)
     28 			*ptr++ = sum[i];
     29 	} else {
     30 		char str_output[33];
     31 		char *str_ptr = str_output;
     32 
     33 		for (i = 0; i < 16; i++) {
     34 			sprintf(str_ptr, "%02x", sum[i]);
     35 			str_ptr += 2;
     36 		}
     37 		env_set(dest, str_output);
     38 	}
     39 }
     40 
     41 #ifdef CONFIG_MD5SUM_VERIFY
     42 static int parse_verify_sum(char *verify_str, u8 *vsum)
     43 {
     44 	if (*verify_str == '*') {
     45 		u8 *ptr;
     46 
     47 		ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16);
     48 		memcpy(vsum, ptr, 16);
     49 	} else {
     50 		unsigned int i;
     51 		char *vsum_str;
     52 
     53 		if (strlen(verify_str) == 32)
     54 			vsum_str = verify_str;
     55 		else {
     56 			vsum_str = env_get(verify_str);
     57 			if (vsum_str == NULL || strlen(vsum_str) != 32)
     58 				return 1;
     59 		}
     60 
     61 		for (i = 0; i < 16; i++) {
     62 			char *nullp = vsum_str + (i + 1) * 2;
     63 			char end = *nullp;
     64 
     65 			*nullp = '\0';
     66 			*(u8 *)(vsum + i) =
     67 				simple_strtoul(vsum_str + (i * 2), NULL, 16);
     68 			*nullp = end;
     69 		}
     70 	}
     71 	return 0;
     72 }
     73 
     74 int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
     75 {
     76 	ulong addr, len;
     77 	unsigned int i;
     78 	u8 output[16];
     79 	u8 vsum[16];
     80 	int verify = 0;
     81 	int ac;
     82 	char * const *av;
     83 	void *buf;
     84 
     85 	if (argc < 3)
     86 		return CMD_RET_USAGE;
     87 
     88 	av = argv + 1;
     89 	ac = argc - 1;
     90 	if (strcmp(*av, "-v") == 0) {
     91 		verify = 1;
     92 		av++;
     93 		ac--;
     94 		if (ac < 3)
     95 			return CMD_RET_USAGE;
     96 	}
     97 
     98 	addr = simple_strtoul(*av++, NULL, 16);
     99 	len = simple_strtoul(*av++, NULL, 16);
    100 
    101 	buf = map_sysmem(addr, len);
    102 	md5_wd(buf, len, output, CHUNKSZ_MD5);
    103 	unmap_sysmem(buf);
    104 
    105 	if (!verify) {
    106 		printf("md5 for %08lx ... %08lx ==> ", addr, addr + len - 1);
    107 		for (i = 0; i < 16; i++)
    108 			printf("%02x", output[i]);
    109 		printf("\n");
    110 
    111 		if (ac > 2)
    112 			store_result(output, *av);
    113 	} else {
    114 		char *verify_str = *av++;
    115 
    116 		if (parse_verify_sum(verify_str, vsum)) {
    117 			printf("ERROR: %s does not contain a valid md5 sum\n",
    118 				verify_str);
    119 			return 1;
    120 		}
    121 		if (memcmp(output, vsum, 16) != 0) {
    122 			printf("md5 for %08lx ... %08lx ==> ", addr,
    123 				addr + len - 1);
    124 			for (i = 0; i < 16; i++)
    125 				printf("%02x", output[i]);
    126 			printf(" != ");
    127 			for (i = 0; i < 16; i++)
    128 				printf("%02x", vsum[i]);
    129 			printf(" ** ERROR **\n");
    130 			return 1;
    131 		}
    132 	}
    133 
    134 	return 0;
    135 }
    136 #else
    137 static int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
    138 {
    139 	unsigned long addr, len;
    140 	unsigned int i;
    141 	u8 output[16];
    142 	void *buf;
    143 
    144 	if (argc < 3)
    145 		return CMD_RET_USAGE;
    146 
    147 	addr = simple_strtoul(argv[1], NULL, 16);
    148 	len = simple_strtoul(argv[2], NULL, 16);
    149 
    150 	buf = map_sysmem(addr, len);
    151 	md5_wd(buf, len, output, CHUNKSZ_MD5);
    152 	unmap_sysmem(buf);
    153 
    154 	printf("md5 for %08lx ... %08lx ==> ", addr, addr + len - 1);
    155 	for (i = 0; i < 16; i++)
    156 		printf("%02x", output[i]);
    157 	printf("\n");
    158 
    159 	if (argc > 3)
    160 		store_result(output, argv[3]);
    161 
    162 	return 0;
    163 }
    164 #endif
    165 
    166 #ifdef CONFIG_MD5SUM_VERIFY
    167 U_BOOT_CMD(
    168 	md5sum,	5,	1,	do_md5sum,
    169 	"compute MD5 message digest",
    170 	"address count [[*]sum]\n"
    171 		"    - compute MD5 message digest [save to sum]\n"
    172 	"md5sum -v address count [*]sum\n"
    173 		"    - verify md5sum of memory area"
    174 );
    175 #else
    176 U_BOOT_CMD(
    177 	md5sum,	4,	1,	do_md5sum,
    178 	"compute MD5 message digest",
    179 	"address count [[*]sum]\n"
    180 		"    - compute MD5 message digest [save to sum]"
    181 );
    182 #endif
    183