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