blob: e359dbf9d62996c95c105335ce19ee7be8d229c2 [file] [log] [blame]
Chris Frantz0f706ea2022-06-16 15:04:55 -07001# Copyright lowRISC contributors.
2# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3# SPDX-License-Identifier: Apache-2.0
4
Alphan Ulusoy59a4cd42022-11-01 15:23:56 -04005load("//rules:const.bzl", "CONST", "hex")
Chris Frantz0f706ea2022-06-16 15:04:55 -07006
Chris Frantz0f706ea2022-06-16 15:04:55 -07007_SEL_DEVICE_ID = 1
8_SEL_MANUF_STATE_CREATOR = (1 << 8)
9_SEL_MANUF_STATE_OWNER = (1 << 9)
10_SEL_LIFE_CYCLE_STATE = (1 << 10)
Chris Frantz0f706ea2022-06-16 15:04:55 -070011
Chris Frantz0f706ea2022-06-16 15:04:55 -070012def _manifest_impl(ctx):
13 mf = {}
14
15 # All the easy parameters are simple assignments
16 if ctx.attr.signature:
Miles Dai38700d52023-01-11 15:47:40 -050017 mf["signature"] = ctx.attr.signature
Chris Frantz0f706ea2022-06-16 15:04:55 -070018 if ctx.attr.modulus:
Miles Dai38700d52023-01-11 15:47:40 -050019 mf["modulus"] = ctx.attr.modulus
Chris Frantz0f706ea2022-06-16 15:04:55 -070020 if ctx.attr.identifier:
Miles Dai38700d52023-01-11 15:47:40 -050021 mf["identifier"] = ctx.attr.identifier
Chris Frantz0f706ea2022-06-16 15:04:55 -070022 if ctx.attr.length:
Miles Dai38700d52023-01-11 15:47:40 -050023 mf["length"] = ctx.attr.length
Chris Frantz0f706ea2022-06-16 15:04:55 -070024 if ctx.attr.version_major:
Miles Dai38700d52023-01-11 15:47:40 -050025 mf["version_major"] = ctx.attr.version_major
Chris Frantz0f706ea2022-06-16 15:04:55 -070026 if ctx.attr.version_minor:
Miles Dai38700d52023-01-11 15:47:40 -050027 mf["version_minor"] = ctx.attr.version_minor
Chris Frantz0f706ea2022-06-16 15:04:55 -070028 if ctx.attr.security_version:
Miles Dai38700d52023-01-11 15:47:40 -050029 mf["security_version"] = ctx.attr.security_version
Chris Frantz0f706ea2022-06-16 15:04:55 -070030 if ctx.attr.timestamp:
Miles Dai38700d52023-01-11 15:47:40 -050031 mf["timestamp"] = ctx.attr.timestamp
Chris Frantz0f706ea2022-06-16 15:04:55 -070032 if ctx.attr.max_key_version:
Miles Dai38700d52023-01-11 15:47:40 -050033 mf["max_key_version"] = ctx.attr.max_key_version
Chris Frantz0f706ea2022-06-16 15:04:55 -070034 if ctx.attr.code_start:
Miles Dai38700d52023-01-11 15:47:40 -050035 mf["code_start"] = ctx.attr.code_start
Chris Frantz0f706ea2022-06-16 15:04:55 -070036 if ctx.attr.code_end:
Miles Dai38700d52023-01-11 15:47:40 -050037 mf["code_end"] = ctx.attr.code_end
Chris Frantz0f706ea2022-06-16 15:04:55 -070038 if ctx.attr.entry_point:
Miles Dai38700d52023-01-11 15:47:40 -050039 mf["entry_point"] = ctx.attr.entry_point
Chris Frantz0f706ea2022-06-16 15:04:55 -070040
41 # Address Translation is a bool, but encoded as an int so we can have
42 # a special value mean "unset" and so we can set to non-standard values
43 # for testing.
44 if ctx.attr.address_translation:
Miles Dai38700d52023-01-11 15:47:40 -050045 mf["address_translation"] = ctx.attr.address_translation
Chris Frantz0f706ea2022-06-16 15:04:55 -070046
47 # The binding_value, if provided, must be exactly 8 words.
48 if ctx.attr.binding_value:
49 if len(ctx.attr.binding_value) != 8:
50 fail("The binding_value must be exactly 8 words.")
Miles Dai38700d52023-01-11 15:47:40 -050051 mf["binding_value"] = [v for v in ctx.attr.binding_value]
Chris Frantz0f706ea2022-06-16 15:04:55 -070052
53 # The selector_bits are set based on the values of the usage_constraints.
54 uc = {}
55 selector_bits = 0
56 device_id = list(ctx.attr.device_id)
57 if len(device_id) > 8:
58 fail("The device_id must be 8 words or fewer.")
59
60 # Extend the device_id to 8 words, then set the selector_bits for each
61 # non-default word.
62 if len(device_id) < 8:
Miles Dai38700d52023-01-11 15:47:40 -050063 device_id.extend([hex(CONST.DEFAULT_USAGE_CONSTRAINTS)] * (8 - len(device_id)))
Chris Frantz0f706ea2022-06-16 15:04:55 -070064 for i, d in enumerate(device_id):
Miles Dai38700d52023-01-11 15:47:40 -050065 if d != hex(CONST.DEFAULT_USAGE_CONSTRAINTS):
Chris Frantz0f706ea2022-06-16 15:04:55 -070066 selector_bits |= _SEL_DEVICE_ID << i
Miles Dai38700d52023-01-11 15:47:40 -050067 device_id[i] = d
Chris Frantz0f706ea2022-06-16 15:04:55 -070068 uc["device_id"] = device_id
69
70 # Set the selector bits for the remaining non-default values.
71 if ctx.attr.manuf_state_creator:
Miles Dai38700d52023-01-11 15:47:40 -050072 uc["manuf_state_creator"] = ctx.attr.manuf_state_creator
Chris Frantz0f706ea2022-06-16 15:04:55 -070073 selector_bits |= _SEL_MANUF_STATE_CREATOR
74 else:
Miles Dai38700d52023-01-11 15:47:40 -050075 uc["manuf_state_creator"] = hex(CONST.DEFAULT_USAGE_CONSTRAINTS)
Chris Frantz0f706ea2022-06-16 15:04:55 -070076
77 if ctx.attr.manuf_state_owner:
Miles Dai38700d52023-01-11 15:47:40 -050078 uc["manuf_state_owner"] = ctx.attr.manuf_state_owner
Chris Frantz0f706ea2022-06-16 15:04:55 -070079 selector_bits |= _SEL_MANUF_STATE_OWNER
80 else:
Miles Dai38700d52023-01-11 15:47:40 -050081 uc["manuf_state_owner"] = hex(CONST.DEFAULT_USAGE_CONSTRAINTS)
Chris Frantz0f706ea2022-06-16 15:04:55 -070082
83 if ctx.attr.life_cycle_state:
Miles Dai38700d52023-01-11 15:47:40 -050084 uc["life_cycle_state"] = ctx.attr.life_cycle_state
Chris Frantz0f706ea2022-06-16 15:04:55 -070085 selector_bits |= _SEL_LIFE_CYCLE_STATE
86 else:
Miles Dai38700d52023-01-11 15:47:40 -050087 uc["life_cycle_state"] = hex(CONST.DEFAULT_USAGE_CONSTRAINTS)
Chris Frantz0f706ea2022-06-16 15:04:55 -070088
89 # If the user supplied selector_bits, check if they make sense.
90 if ctx.attr.selector_bits:
91 # If they don't match, fail unless explicitly permitted to set a
92 # bad value.
Miles Dai620fda82022-11-04 16:56:36 -040093 if int(ctx.attr.selector_bits, base = 16) != selector_bits and ctx.attr.selector_mismatch_is_failure:
Miles Dai38700d52023-01-11 15:47:40 -050094 fail("User provided selector_bits ({}) don't match computed selector_bits ({})".format(ctx.attr.selector_bits, selector_bits))
95 uc["selector_bits"] = ctx.attr.selector_bits
Chris Frantz0f706ea2022-06-16 15:04:55 -070096 else:
Miles Dai38700d52023-01-11 15:47:40 -050097 uc["selector_bits"] = selector_bits
Chris Frantz0f706ea2022-06-16 15:04:55 -070098
99 mf["usage_constraints"] = uc
100
101 file = ctx.actions.declare_file("{}.json".format(ctx.attr.name))
102 ctx.actions.write(file, json.encode_indent(mf))
103 return DefaultInfo(
104 files = depset([file]),
105 data_runfiles = ctx.runfiles(files = [file]),
106 )
107
Alphan Ulusoybff55d42022-10-14 12:00:11 -0400108_manifest = rule(
Chris Frantz0f706ea2022-06-16 15:04:55 -0700109 implementation = _manifest_impl,
Miles Dai620fda82022-11-04 16:56:36 -0400110 # Manifest attrs are supplied as strings due to Bazel limiting int types to 32-bit signed integers
Chris Frantz0f706ea2022-06-16 15:04:55 -0700111 attrs = {
Miles Dai38700d52023-01-11 15:47:40 -0500112 "signature": attr.string(doc = "Image signature as a 0x-prefixed hex-encoded string"),
113 "modulus": attr.string(doc = "Signing key modulus as a 0x-prefixed hex-encoded string"),
114 "selector_bits": attr.string(doc = "Usage constraint selector bits as a 0x-prefixed hex-encoded string"),
Chris Frantz0f706ea2022-06-16 15:04:55 -0700115 "selector_mismatch_is_failure": attr.bool(default = True, doc = "A mismatch in computed selector bits is a failure"),
Miles Dai38700d52023-01-11 15:47:40 -0500116 "device_id": attr.string_list(doc = "Usage constraint device ID as a 0x-prefixed hex-encoded string"),
117 "manuf_state_creator": attr.string(doc = "Usage constraint for silicon creator manufacturing status as a 0x-prefixed hex-encoded string"),
118 "manuf_state_owner": attr.string(doc = "Usage constraint for silicon owner manufacturing status as a 0x-prefixed hex-encoded string"),
119 "life_cycle_state": attr.string(doc = "Usage constraint for life cycle status as a 0x-prefixed hex-encoded string"),
120 "address_translation": attr.string(doc = "Whether this image uses address translation as a 0x-prefixed hex-encoded string"),
121 "identifier": attr.string(doc = "Manifest identifier as a 0x-prefixed hex-encoded string"),
122 "length": attr.string(doc = "Length of this image as a 0x-prefixed hex-encoded string"),
123 "version_major": attr.string(doc = "Image major version as a 0x-prefixed hex-encoded string"),
124 "version_minor": attr.string(doc = "Image minor version as a 0x-prefixed hex-encoded string"),
125 "security_version": attr.string(doc = "Security version for anti-rollback protection as a 0x-prefixed hex-encoded string"),
126 "timestamp": attr.string(doc = "Unix timestamp of the image as a 0x-prefixed hex-encoded string"),
127 "binding_value": attr.string_list(doc = "Binding value used by key manager to derive secrets as a 0x-prefixed hex-encoded string"),
128 "max_key_version": attr.string(doc = "Maximum allowed version for keys generated at the next boot stage as a 0x-prefixed hex-encoded string"),
129 "code_start": attr.string(doc = "Start offset of the executable region in the image as a 0x-prefixed hex-encoded string"),
130 "code_end": attr.string(doc = "End offset of the executable region in the image as a 0x-prefixed hex-encoded string"),
131 "entry_point": attr.string(doc = "Offset of the first instruction in the image as a 0x-prefixed hex-encoded string"),
Chris Frantz0f706ea2022-06-16 15:04:55 -0700132 },
133)
Alphan Ulusoybff55d42022-10-14 12:00:11 -0400134
135def manifest(d):
136 _manifest(**d)
137 return d["name"]