1# SPDX-License-Identifier: GPL-2.0+ 2# Copyright (c) 2018 Google, Inc 3# Written by Simon Glass <sjg@chromium.org> 4# 5 6# Support for a Chromium OS verified boot block, used to sign a read-write 7# section of the image. 8 9from collections import OrderedDict 10import os 11 12from entry import Entry, EntryArg 13 14import fdt_util 15import tools 16 17class Entry_vblock(Entry): 18 """An entry which contains a Chromium OS verified boot block 19 20 Properties / Entry arguments: 21 - keydir: Directory containing the public keys to use 22 - keyblock: Name of the key file to use (inside keydir) 23 - signprivate: Name of provide key file to use (inside keydir) 24 - version: Version number of the vblock (typically 1) 25 - kernelkey: Name of the kernel key to use (inside keydir) 26 - preamble-flags: Value of the vboot preamble flags (typically 0) 27 28 Chromium OS signs the read-write firmware and kernel, writing the signature 29 in this block. This allows U-Boot to verify that the next firmware stage 30 and kernel are genuine. 31 """ 32 def __init__(self, section, etype, node): 33 Entry.__init__(self, section, etype, node) 34 self.content = fdt_util.GetPhandleList(self._node, 'content') 35 if not self.content: 36 self.Raise("Vblock must have a 'content' property") 37 (self.keydir, self.keyblock, self.signprivate, self.version, 38 self.kernelkey, self.preamble_flags) = self.GetEntryArgsOrProps([ 39 EntryArg('keydir', str), 40 EntryArg('keyblock', str), 41 EntryArg('signprivate', str), 42 EntryArg('version', int), 43 EntryArg('kernelkey', str), 44 EntryArg('preamble-flags', int)]) 45 46 def ObtainContents(self): 47 # Join up the data files to be signed 48 input_data = '' 49 for entry_phandle in self.content: 50 data = self.section.GetContentsByPhandle(entry_phandle, self) 51 if data is None: 52 # Data not available yet 53 return False 54 input_data += data 55 56 output_fname = tools.GetOutputFilename('vblock.%s' % self.name) 57 input_fname = tools.GetOutputFilename('input.%s' % self.name) 58 tools.WriteFile(input_fname, input_data) 59 prefix = self.keydir + '/' 60 args = [ 61 'vbutil_firmware', 62 '--vblock', output_fname, 63 '--keyblock', prefix + self.keyblock, 64 '--signprivate', prefix + self.signprivate, 65 '--version', '%d' % self.version, 66 '--fv', input_fname, 67 '--kernelkey', prefix + self.kernelkey, 68 '--flags', '%d' % self.preamble_flags, 69 ] 70 #out.Notice("Sign '%s' into %s" % (', '.join(self.value), self.label)) 71 stdout = tools.Run('futility', *args) 72 #out.Debug(stdout) 73 self.SetContents(tools.ReadFile(output_fname)) 74 return True 75