summaryrefslogtreecommitdiff
path: root/futility/bdb_helper.c
blob: b0f2dcd02d670c4cc8209181d8ec419062f5fb2d (plain)
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* Copyright 2016 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Boot descriptor block helper functions
 */

#include <inttypes.h>
#include <stdio.h>

#include "2sha.h"
#include "bdb.h"
#include "bdb_struct.h"
#include "file_type.h"

enum futil_file_type ft_recognize_bdb(uint8_t *buf, uint32_t len)
{
	const struct bdb_header *header = bdb_get_header(buf);

	if (bdb_check_header(header, len))
		return FILE_TYPE_UNKNOWN;

	return FILE_TYPE_BDB;
}

static void print_digest(const char *label, const uint8_t *digest, size_t size)
{
	int i;

	if (label)
		printf("%s", label);
	for (i = 0; i < size; i++)
		printf("%02x", digest[i]);
	printf("\n");
}

static void print_hash_entry(const char *label, const struct bdb_hash *hash)
{
	if (label)
		printf("%s", label);
	printf("  Offset:       0x%" PRIx64 "\n", hash->offset);
	printf("  Size:         %d\n", hash->size);
	printf("  Partition:    %d\n", hash->partition);
	printf("  Type:         %d\n", hash->type);
	printf("  Load Address: 0x%" PRIx64 "\n", hash->load_address);
	print_digest("  Digest:       ", hash->digest, sizeof(hash->digest));
}

static void print_key_info(const char *label, const struct bdb_key *key)
{
	uint8_t digest[BDB_SHA256_DIGEST_SIZE];

	if (label)
		printf("%s", label);
	printf("  Struct Version: 0x%x:0x%x\n",
	       key->struct_major_version, key->struct_minor_version);
	printf("  Size:           %d\n", key->struct_size);
	printf("  Hash Algorithm: %d\n", key->hash_alg);
	printf("  Sign Algorithm: %d\n", key->sig_alg);
	printf("  Version:        %d\n", key->key_version);
	printf("  Description:    %s\n", key->description);
	bdb_sha256(digest, key, key->struct_size);
	print_digest("  Digest:         ", digest, sizeof(digest));
}

static void print_sig_info(const char *label, const struct bdb_sig *sig)
{
	if (label)
		printf("%s", label);
	printf("  Struct Version: 0x%x:0x%x\n",
	       sig->struct_major_version, sig->struct_minor_version);
	printf("  Hash Algorithm: %d\n", sig->hash_alg);
	printf("  Sign Algorithm: %d\n", sig->sig_alg);
	printf("  Signed Size:    %d\n", sig->signed_size);
	printf("  Description:    %s\n", sig->description);
}

static void show_bdb_header(const uint8_t *bdb)
{
	const struct bdb_header *header = bdb_get_header(bdb);

	printf("BDB Header:\n");
	printf("  Struct Version: 0x%x:0x%x\n",
	       header->struct_major_version, header->struct_minor_version);
	printf("  Struct Size:    %d\n", header->struct_size);
	printf("  Load Address:   0x%" PRIx64 "\n", header->bdb_load_address);
	printf("  Size:           %d\n", header->bdb_size);
	printf("  Signed Size:    %d\n", header->signed_size);
	printf("  OEM0 Size:      %d\n", header->oem_area_0_size);
}

static void show_bdbkey_info(const uint8_t *bdb)
{
	print_key_info("BDB key:\n", bdb_get_bdbkey(bdb));
}

static void show_datakey_info(const uint8_t *bdb)
{
	print_key_info("Data key:\n", bdb_get_datakey(bdb));
}

static void show_header_signature(const uint8_t *bdb)
{
	print_sig_info("Header Signature:\n" , bdb_get_header_sig(bdb));
}

static void show_data_header(const uint8_t *bdb)
{
	const struct bdb_data *data = bdb_get_data(bdb);

	printf("Data Header:\n");
	printf("  Struct Version:  0x%x:0x%x\n",
	       data->struct_major_version, data->struct_minor_version);
	printf("  Data Version:    %d\n", data->data_version);
	printf("  # of Hashes:     %d\n", data->num_hashes);
	printf("  Hash Entry Size: %d\n", data->hash_entry_size);
	printf("  Signed Size:     %d\n", data->signed_size);
	printf("  Description:     %s\n", data->description);
}

static void show_hashes(const uint8_t *bdb)
{
	const struct bdb_data *data = bdb_get_data(bdb);
	int i;

	for (i = 0; i < data->num_hashes; i++) {
		const struct bdb_hash *hash = bdb_get_hash_by_index(bdb, i);
		printf("Hash #%d:\n", i);
		print_hash_entry(NULL, hash);
	}
}

static void show_data_signature(const uint8_t *bdb)
{
	print_sig_info("Data Signature:\n" , bdb_get_data_sig(bdb));
}

int ft_show_bdb(const char *name, uint8_t *buf, uint32_t len, void *data)
{
	const struct bdb_header *header = bdb_get_header(buf);
	int rv;

	/* We can get here because of '--type' option */
	rv  = bdb_check_header(header, len);
	if (rv) {
		fprintf(stderr, "ERROR: Invalid BDB blob: %d\n", rv);
		return 1;
	}

	printf("Boot Descriptor Block: %s\n", name);
	show_bdb_header(buf);
	show_bdbkey_info(buf);
	show_datakey_info(buf);
	show_header_signature(buf);
	show_data_header(buf);
	show_hashes(buf);
	show_data_signature(buf);

	return 0;
}