uboot/cmd/md5sum.c
<<
>>
Prefs
   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 */
  21static 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
  44static 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
  76int 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
 139static 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
 170U_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
 179U_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
 186