lin
2025-03-21 36aaa54056c4f4e150f6ee0636610d9a68470a08
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// SPDX-License-Identifier: GPL-2.0+
/*
 * The 'fsverity measure' command
 *
 * Copyright (C) 2018 Google LLC
 *
 * Written by Eric Biggers.
 */
 
#include <fcntl.h>
#include <stdlib.h>
#include <sys/ioctl.h>
 
#include "commands.h"
#include "fsverity_uapi.h"
#include "hash_algs.h"
 
int fsverity_cmd_measure(const struct fsverity_command *cmd,
            int argc, char *argv[])
{
   struct fsverity_digest *d = NULL;
   struct filedes file;
   char digest_hex[FS_VERITY_MAX_DIGEST_SIZE * 2 + 1];
   const struct fsverity_hash_alg *hash_alg;
   char _hash_alg_name[32];
   const char *hash_alg_name;
   int status;
   int i;
 
   if (argc < 2)
       goto out_usage;
 
   d = xzalloc(sizeof(*d) + FS_VERITY_MAX_DIGEST_SIZE);
 
   for (i = 1; i < argc; i++) {
       d->digest_size = FS_VERITY_MAX_DIGEST_SIZE;
 
       if (!open_file(&file, argv[i], O_RDONLY, 0))
           goto out_err;
       if (ioctl(file.fd, FS_IOC_MEASURE_VERITY, d) != 0) {
           error_msg_errno("FS_IOC_MEASURE_VERITY failed on '%s'",
                   file.name);
           filedes_close(&file);
           goto out_err;
       }
       filedes_close(&file);
 
       ASSERT(d->digest_size <= FS_VERITY_MAX_DIGEST_SIZE);
       bin2hex(d->digest, d->digest_size, digest_hex);
       hash_alg = find_hash_alg_by_num(d->digest_algorithm);
       if (hash_alg) {
           hash_alg_name = hash_alg->name;
       } else {
           sprintf(_hash_alg_name, "ALG_%u", d->digest_algorithm);
           hash_alg_name = _hash_alg_name;
       }
       printf("%s:%s %s\n", hash_alg_name, digest_hex, argv[i]);
   }
   status = 0;
out:
   free(d);
   return status;
 
out_err:
   status = 1;
   goto out;
 
out_usage:
   usage(cmd, stderr);
   status = 2;
   goto out;
}