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