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