Coverage Report

Created: 2026-10-13 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/barebox/commands/digest.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-only
2
// SPDX-FileCopyrightText: © 2015 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
3
4
#include <common.h>
5
#include <command.h>
6
#include <linux/pagemap.h>
7
#include <fs.h>
8
#include <fcntl.h>
9
#include <errno.h>
10
#include <xfuncs.h>
11
#include <malloc.h>
12
#include <digest.h>
13
#include <getopt.h>
14
#include <libfile.h>
15
16
#include "internal.h"
17
18
int __do_digest(struct digest *d, unsigned char *sig,
19
           int argc, char *argv[])
20
0
{
21
0
  int ret = COMMAND_ERROR_USAGE;
22
0
  int i;
23
0
  unsigned char *hash;
24
25
0
  if (argc < 1)
26
0
    goto err;
27
28
0
  hash = calloc(digest_length(d), sizeof(unsigned char));
29
0
  if (!hash) {
30
0
    perror("calloc");
31
0
    goto err;
32
0
  }
33
34
0
  while (*argv) {
35
0
    char *filename = "/dev/mem";
36
0
    loff_t start = 0, size = MAX_LFS_FILESIZE;
37
0
    int show_area = 1;
38
39
    /* arguments are either file, file+area or area */
40
0
    if (parse_area_spec(*argv, &start, &size)) {
41
0
      filename = *argv;
42
0
      show_area = 0;
43
0
      if (argv[1] && !parse_area_spec(argv[1], &start, &size)) {
44
0
        argv++;
45
0
        show_area = 1;
46
0
      }
47
0
    }
48
49
0
    ret = digest_file_window(d, filename,
50
0
           hash, sig, start, size);
51
0
    if (ret < 0) {
52
0
      ret = 1;
53
0
    } else {
54
0
      if (!sig) {
55
0
        for (i = 0; i < digest_length(d); i++)
56
0
          printf("%02x", hash[i]);
57
58
0
        printf("  %s", filename);
59
0
        if (show_area)
60
0
          printf("\t0x%08llx ... 0x%08llx",
61
0
            start, start + size);
62
63
0
        puts("\n");
64
0
      }
65
0
    }
66
67
0
    argv++;
68
0
  }
69
70
0
  free(hash);
71
0
err:
72
0
  digest_free(d);
73
74
0
  return ret;
75
0
}
76
77
static void __maybe_unused prints_algo_help(void)
78
0
{
79
0
  puts("\navailable algo:\n");
80
0
  digest_algo_prints("\t");
81
0
}
82
83
static int do_digest(int argc, char *argv[])
84
0
{
85
0
  struct digest *d;
86
0
  unsigned char *tmp_key = NULL;
87
0
  unsigned char *tmp_sig = NULL;
88
0
  char *sig = NULL;
89
0
  char *sigfile = NULL;
90
0
  size_t siglen = 0;
91
0
  char *key = NULL;
92
0
  char *keyfile = NULL;
93
0
  size_t keylen = 0;
94
0
  size_t digestlen = 0;
95
0
  char *algo = NULL;
96
0
  int opt;
97
0
  int ret = COMMAND_ERROR;
98
99
0
  if (argc < 2)
100
0
    return COMMAND_ERROR_USAGE;
101
102
0
  while((opt = getopt(argc, argv, "a:k:K:s:S:")) > 0) {
103
0
    switch(opt) {
104
0
    case 'k':
105
0
      key = optarg;
106
0
      keylen = strlen(key);
107
0
      break;
108
0
    case 'K':
109
0
      keyfile = optarg;
110
0
      break;
111
0
    case 'a':
112
0
      algo = optarg;
113
0
      break;
114
0
    case 's':
115
0
      sig = optarg;
116
0
      siglen = strlen(sig);
117
0
      break;
118
0
    case 'S':
119
0
      sigfile = optarg;
120
0
      break;
121
0
    }
122
0
  }
123
124
0
  if (!algo)
125
0
    return COMMAND_ERROR_USAGE;
126
127
0
  d = digest_alloc(algo);
128
0
  if (!d) {
129
0
    eprintf("algo '%s' not found\n", algo);
130
0
    return COMMAND_ERROR_USAGE;
131
0
  }
132
133
0
  argc -= optind;
134
0
  argv += optind;
135
136
0
  if (keyfile) {
137
0
    tmp_key = key = read_file(keyfile, &keylen);
138
0
    if (!key) {
139
0
      eprintf("file '%s' not found\n", keyfile);
140
0
      goto err;
141
0
    }
142
0
  }
143
144
0
  if (key) {
145
0
    ret = digest_set_key(d, key, keylen);
146
0
    free(tmp_key);
147
0
    if (ret)
148
0
      goto err;
149
0
  } else if (digest_is_flags(d, DIGEST_ALGO_NEED_KEY)) {
150
0
    eprintf("%s need a key to be used\n", digest_name(d));
151
0
    goto err;
152
0
  }
153
154
0
  if (sigfile) {
155
0
    sig = tmp_sig = read_file(sigfile, &siglen);
156
0
    if (!tmp_sig) {
157
0
      eprintf("file '%s' not found\n", sigfile);
158
0
      goto err;
159
0
    }
160
0
  }
161
162
0
  if (sig) {
163
0
    digestlen = digest_length(d);
164
0
    if (siglen >= 2 * digestlen) {
165
0
      if (!tmp_sig)
166
0
        tmp_sig = xmalloc(digestlen);
167
168
0
      ret = hex2bin(tmp_sig, sig, digestlen);
169
0
      if (ret)
170
0
        goto err;
171
172
0
      sig = tmp_sig;
173
0
    } else if (siglen != digestlen) {
174
0
      eprintf("%s wrong size %zu, expected %zu\n",
175
0
        sigfile, siglen, digestlen);
176
0
      ret = COMMAND_ERROR;
177
0
      goto err;
178
0
    }
179
0
  }
180
181
0
  ret = __do_digest(d, sig, argc, argv);
182
0
  free(tmp_sig);
183
0
  return ret;
184
185
0
err:
186
0
  digest_free(d);
187
0
  return ret;
188
0
}
189
190
BAREBOX_CMD_HELP_START(digest)
191
BAREBOX_CMD_HELP_TEXT("Calculate a digest over a FILE or a memory area.")
192
BAREBOX_CMD_HELP_TEXT("Options:")
193
BAREBOX_CMD_HELP_OPT ("-a <algo>\t",  "hash or signature algorithm name/driver to use")
194
BAREBOX_CMD_HELP_OPT ("-k <key>\t",   "use supplied <key> (ASCII or hex) for MAC")
195
BAREBOX_CMD_HELP_OPT ("-K <file>\t",  "use key from <file> (binary) for MAC")
196
BAREBOX_CMD_HELP_OPT ("-s <hex>\t",   "verify data against supplied <hex> (hash, MAC or signature)")
197
BAREBOX_CMD_HELP_OPT ("-S <file>\t",  "verify data against <file> (hash, MAC or signature)")
198
BAREBOX_CMD_HELP_END
199
200
BAREBOX_CMD_START(digest)
201
  .cmd    = do_digest,
202
  BAREBOX_CMD_DESC("calculate digest")
203
  BAREBOX_CMD_OPTS("-a <algo> [-k <key> | -K <file>] [-s <sig> | -S <file>] FILE|AREA")
204
  BAREBOX_CMD_GROUP(CMD_GRP_FILE)
205
  BAREBOX_CMD_HELP(cmd_digest_help)
206
  BAREBOX_CMD_USAGE(prints_algo_help)
207
BAREBOX_CMD_END