Merge branch 'master' of git://git.denx.de/u-boot-video
[platform/kernel/u-boot.git] / cmd / md5sum.c
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                 setenv(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 = getenv(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