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
|
# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2018 Google, Inc
# Written by Simon Glass <sjg@chromium.org>
#
# Support for a Chromium OS verified boot block, used to sign a read-write
# section of the image.
from collections import OrderedDict
import os
from binman.entry import EntryArg
from binman.etype.collection import Entry_collection
from dtoc import fdt_util
from patman import tools
class Entry_vblock(Entry_collection):
"""An entry which contains a Chromium OS verified boot block
Properties / Entry arguments:
- content: List of phandles to entries to sign
- keydir: Directory containing the public keys to use
- keyblock: Name of the key file to use (inside keydir)
- signprivate: Name of provide key file to use (inside keydir)
- version: Version number of the vblock (typically 1)
- kernelkey: Name of the kernel key to use (inside keydir)
- preamble-flags: Value of the vboot preamble flags (typically 0)
Output files:
- input.<unique_name> - input file passed to futility
- vblock.<unique_name> - output file generated by futility (which is
used as the entry contents)
Chromium OS signs the read-write firmware and kernel, writing the signature
in this block. This allows U-Boot to verify that the next firmware stage
and kernel are genuine.
"""
def __init__(self, section, etype, node):
super().__init__(section, etype, node)
(self.keydir, self.keyblock, self.signprivate, self.version,
self.kernelkey, self.preamble_flags) = self.GetEntryArgsOrProps([
EntryArg('keydir', str),
EntryArg('keyblock', str),
EntryArg('signprivate', str),
EntryArg('version', int),
EntryArg('kernelkey', str),
EntryArg('preamble-flags', int)])
def GetVblock(self):
"""Get the contents of this entry
Returns:
bytes content of the entry, which is the signed vblock for the
provided data
"""
# Join up the data files to be signed
input_data = self.GetContents()
if input_data is None:
return None
uniq = self.GetUniqueName()
output_fname = tools.GetOutputFilename('vblock.%s' % uniq)
input_fname = tools.GetOutputFilename('input.%s' % uniq)
tools.WriteFile(input_fname, input_data)
prefix = self.keydir + '/'
args = [
'vbutil_firmware',
'--vblock', output_fname,
'--keyblock', prefix + self.keyblock,
'--signprivate', prefix + self.signprivate,
'--version', '%d' % self.version,
'--fv', input_fname,
'--kernelkey', prefix + self.kernelkey,
'--flags', '%d' % self.preamble_flags,
]
#out.Notice("Sign '%s' into %s" % (', '.join(self.value), self.label))
stdout = tools.Run('futility', *args)
return tools.ReadFile(output_fname)
def ObtainContents(self):
data = self.GetVblock()
if data is None:
return False
self.SetContents(data)
return True
def ProcessContents(self):
# The blob may have changed due to WriteSymbols()
data = self.GetVblock()
return self.ProcessContentsUpdate(data)
|