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 <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