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