12e192b24SSimon Glass /* 22e192b24SSimon Glass * (C) Copyright 2011 32e192b24SSimon Glass * Joe Hershberger, National Instruments, joe.hershberger@ni.com 42e192b24SSimon Glass * 52e192b24SSimon Glass * (C) Copyright 2000 62e192b24SSimon Glass * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 72e192b24SSimon Glass * 82e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 92e192b24SSimon Glass */ 102e192b24SSimon Glass 112e192b24SSimon Glass #include <common.h> 122e192b24SSimon Glass #include <command.h> 132e192b24SSimon Glass #include <mapmem.h> 142e192b24SSimon Glass #include <u-boot/md5.h> 152e192b24SSimon Glass #include <asm/io.h> 162e192b24SSimon Glass 172e192b24SSimon Glass /* 182e192b24SSimon Glass * Store the resulting sum to an address or variable 192e192b24SSimon Glass */ 202e192b24SSimon Glass static void store_result(const u8 *sum, const char *dest) 212e192b24SSimon Glass { 222e192b24SSimon Glass unsigned int i; 232e192b24SSimon Glass 242e192b24SSimon Glass if (*dest == '*') { 252e192b24SSimon Glass u8 *ptr; 262e192b24SSimon Glass 272e192b24SSimon Glass ptr = (u8 *)simple_strtoul(dest + 1, NULL, 16); 282e192b24SSimon Glass for (i = 0; i < 16; i++) 292e192b24SSimon Glass *ptr++ = sum[i]; 302e192b24SSimon Glass } else { 312e192b24SSimon Glass char str_output[33]; 322e192b24SSimon Glass char *str_ptr = str_output; 332e192b24SSimon Glass 342e192b24SSimon Glass for (i = 0; i < 16; i++) { 352e192b24SSimon Glass sprintf(str_ptr, "%02x", sum[i]); 362e192b24SSimon Glass str_ptr += 2; 372e192b24SSimon Glass } 38*382bee57SSimon Glass env_set(dest, str_output); 392e192b24SSimon Glass } 402e192b24SSimon Glass } 412e192b24SSimon Glass 422e192b24SSimon Glass #ifdef CONFIG_MD5SUM_VERIFY 432e192b24SSimon Glass static int parse_verify_sum(char *verify_str, u8 *vsum) 442e192b24SSimon Glass { 452e192b24SSimon Glass if (*verify_str == '*') { 462e192b24SSimon Glass u8 *ptr; 472e192b24SSimon Glass 482e192b24SSimon Glass ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16); 492e192b24SSimon Glass memcpy(vsum, ptr, 16); 502e192b24SSimon Glass } else { 512e192b24SSimon Glass unsigned int i; 522e192b24SSimon Glass char *vsum_str; 532e192b24SSimon Glass 542e192b24SSimon Glass if (strlen(verify_str) == 32) 552e192b24SSimon Glass vsum_str = verify_str; 562e192b24SSimon Glass else { 572e192b24SSimon Glass vsum_str = getenv(verify_str); 582e192b24SSimon Glass if (vsum_str == NULL || strlen(vsum_str) != 32) 592e192b24SSimon Glass return 1; 602e192b24SSimon Glass } 612e192b24SSimon Glass 622e192b24SSimon Glass for (i = 0; i < 16; i++) { 632e192b24SSimon Glass char *nullp = vsum_str + (i + 1) * 2; 642e192b24SSimon Glass char end = *nullp; 652e192b24SSimon Glass 662e192b24SSimon Glass *nullp = '\0'; 672e192b24SSimon Glass *(u8 *)(vsum + i) = 682e192b24SSimon Glass simple_strtoul(vsum_str + (i * 2), NULL, 16); 692e192b24SSimon Glass *nullp = end; 702e192b24SSimon Glass } 712e192b24SSimon Glass } 722e192b24SSimon Glass return 0; 732e192b24SSimon Glass } 742e192b24SSimon Glass 752e192b24SSimon Glass int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 762e192b24SSimon Glass { 772e192b24SSimon Glass ulong addr, len; 782e192b24SSimon Glass unsigned int i; 792e192b24SSimon Glass u8 output[16]; 802e192b24SSimon Glass u8 vsum[16]; 812e192b24SSimon Glass int verify = 0; 822e192b24SSimon Glass int ac; 832e192b24SSimon Glass char * const *av; 842e192b24SSimon Glass void *buf; 852e192b24SSimon Glass 862e192b24SSimon Glass if (argc < 3) 872e192b24SSimon Glass return CMD_RET_USAGE; 882e192b24SSimon Glass 892e192b24SSimon Glass av = argv + 1; 902e192b24SSimon Glass ac = argc - 1; 912e192b24SSimon Glass if (strcmp(*av, "-v") == 0) { 922e192b24SSimon Glass verify = 1; 932e192b24SSimon Glass av++; 942e192b24SSimon Glass ac--; 952e192b24SSimon Glass if (ac < 3) 962e192b24SSimon Glass return CMD_RET_USAGE; 972e192b24SSimon Glass } 982e192b24SSimon Glass 992e192b24SSimon Glass addr = simple_strtoul(*av++, NULL, 16); 1002e192b24SSimon Glass len = simple_strtoul(*av++, NULL, 16); 1012e192b24SSimon Glass 1022e192b24SSimon Glass buf = map_sysmem(addr, len); 1032e192b24SSimon Glass md5_wd(buf, len, output, CHUNKSZ_MD5); 1042e192b24SSimon Glass unmap_sysmem(buf); 1052e192b24SSimon Glass 1062e192b24SSimon Glass if (!verify) { 1072e192b24SSimon Glass printf("md5 for %08lx ... %08lx ==> ", addr, addr + len - 1); 1082e192b24SSimon Glass for (i = 0; i < 16; i++) 1092e192b24SSimon Glass printf("%02x", output[i]); 1102e192b24SSimon Glass printf("\n"); 1112e192b24SSimon Glass 1122e192b24SSimon Glass if (ac > 2) 1132e192b24SSimon Glass store_result(output, *av); 1142e192b24SSimon Glass } else { 1152e192b24SSimon Glass char *verify_str = *av++; 1162e192b24SSimon Glass 1172e192b24SSimon Glass if (parse_verify_sum(verify_str, vsum)) { 1182e192b24SSimon Glass printf("ERROR: %s does not contain a valid md5 sum\n", 1192e192b24SSimon Glass verify_str); 1202e192b24SSimon Glass return 1; 1212e192b24SSimon Glass } 1222e192b24SSimon Glass if (memcmp(output, vsum, 16) != 0) { 1232e192b24SSimon Glass printf("md5 for %08lx ... %08lx ==> ", addr, 1242e192b24SSimon Glass addr + len - 1); 1252e192b24SSimon Glass for (i = 0; i < 16; i++) 1262e192b24SSimon Glass printf("%02x", output[i]); 1272e192b24SSimon Glass printf(" != "); 1282e192b24SSimon Glass for (i = 0; i < 16; i++) 1292e192b24SSimon Glass printf("%02x", vsum[i]); 1302e192b24SSimon Glass printf(" ** ERROR **\n"); 1312e192b24SSimon Glass return 1; 1322e192b24SSimon Glass } 1332e192b24SSimon Glass } 1342e192b24SSimon Glass 1352e192b24SSimon Glass return 0; 1362e192b24SSimon Glass } 1372e192b24SSimon Glass #else 1382e192b24SSimon Glass static int do_md5sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1392e192b24SSimon Glass { 1402e192b24SSimon Glass unsigned long addr, len; 1412e192b24SSimon Glass unsigned int i; 1422e192b24SSimon Glass u8 output[16]; 1432e192b24SSimon Glass void *buf; 1442e192b24SSimon Glass 1452e192b24SSimon Glass if (argc < 3) 1462e192b24SSimon Glass return CMD_RET_USAGE; 1472e192b24SSimon Glass 1482e192b24SSimon Glass addr = simple_strtoul(argv[1], NULL, 16); 1492e192b24SSimon Glass len = simple_strtoul(argv[2], NULL, 16); 1502e192b24SSimon Glass 1512e192b24SSimon Glass buf = map_sysmem(addr, len); 1522e192b24SSimon Glass md5_wd(buf, len, output, CHUNKSZ_MD5); 1532e192b24SSimon Glass unmap_sysmem(buf); 1542e192b24SSimon Glass 1552e192b24SSimon Glass printf("md5 for %08lx ... %08lx ==> ", addr, addr + len - 1); 1562e192b24SSimon Glass for (i = 0; i < 16; i++) 1572e192b24SSimon Glass printf("%02x", output[i]); 1582e192b24SSimon Glass printf("\n"); 1592e192b24SSimon Glass 1602e192b24SSimon Glass if (argc > 3) 1612e192b24SSimon Glass store_result(output, argv[3]); 1622e192b24SSimon Glass 1632e192b24SSimon Glass return 0; 1642e192b24SSimon Glass } 1652e192b24SSimon Glass #endif 1662e192b24SSimon Glass 1672e192b24SSimon Glass #ifdef CONFIG_MD5SUM_VERIFY 1682e192b24SSimon Glass U_BOOT_CMD( 1692e192b24SSimon Glass md5sum, 5, 1, do_md5sum, 1702e192b24SSimon Glass "compute MD5 message digest", 1712e192b24SSimon Glass "address count [[*]sum]\n" 1722e192b24SSimon Glass " - compute MD5 message digest [save to sum]\n" 1732e192b24SSimon Glass "md5sum -v address count [*]sum\n" 1742e192b24SSimon Glass " - verify md5sum of memory area" 1752e192b24SSimon Glass ); 1762e192b24SSimon Glass #else 1772e192b24SSimon Glass U_BOOT_CMD( 1782e192b24SSimon Glass md5sum, 4, 1, do_md5sum, 1792e192b24SSimon Glass "compute MD5 message digest", 1802e192b24SSimon Glass "address count [[*]sum]\n" 1812e192b24SSimon Glass " - compute MD5 message digest [save to sum]" 1822e192b24SSimon Glass ); 1832e192b24SSimon Glass #endif 184