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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/include/usr/secureboot/service.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2013,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
/* implied. See the License for the specific language governing */
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
#ifndef __SECUREBOOT_SERVICE_H
#define __SECUREBOOT_SERVICE_H
#include <errl/errlentry.H>
#include <config.h>
#include <secureboot/settings.H>
#include <utility>
#include <cstdint>
#include <securerom/sha512.H>
#include <securerom/ROM.H>
typedef uint8_t SHA512_t[SHA512_DIGEST_LENGTH];
/*
* @brief Used to capture the first 4 bytes of the hash for tracing purposes
*/
inline uint32_t sha512_to_u32(SHA512_t i_hash)
{
if (i_hash == nullptr)
{
return 0;
}
else
{
return *(reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(i_hash)));
}
};
typedef std::vector< std::pair<void*,size_t> > blobPair_t;
// TODO securebootp9 added for spnorrp.C - service.H needs many more updates
// in order to match the p8 version
const size_t HASH_PAGE_TABLE_ENTRY_SIZE = 32;
typedef uint8_t PAGE_TABLE_ENTRY_t[HASH_PAGE_TABLE_ENTRY_SIZE];
namespace SECUREBOOT
{
/** @brief Perform initialization of Secureboot for the Base image.
*
* - Copy secure header from original location.
* - Perform blind-purge of bottom-half of cache.
* - Add bottom-half of cache to available memory.
*/
void* initializeBase(void* unused);
/**
* @brief Initialize Secure Rom by loading it into memory and
* retrieving Hash Keys
*
* @return errlHndl_t NULL on success
*/
errlHndl_t initializeSecureRomManager(void);
/**
* @brief Trace the Security Settings on each functional processor
*
* @param[in] i_doConsoleTrace Optional variable that determines if
* register values are traced to the CONSOLE.
* Default is false
*
* @return errlHndl_t nullptr on success, else pointer to error log
*/
errlHndl_t traceSecuritySettings(bool i_doConsoleTrace = false);
/** @brief Determines if Secureboot is enabled.
*/
#if defined(CONFIG_SECUREBOOT)
bool enabled();
#else
inline bool enabled() { return false; };
#endif
/** @brief Get security switch register value
* @par Detailed Description:
* Returns the state of the security switch register as
* reported by the given processor (via the supplied target
* pointer).
* @param[out] o_regValue The value read from the register if the
* call was successful. If not successful this value is set to
* zero. Check the return value for a non null error log to
* determine if the call was unsuccessful.
* @param[in] i_pProc The target processor to obtain the jumper
* state from. Must not be null. Optional parameter that
* defaults to master processor.
* @return errlHndl_t indicating whether the query was successful.
* @retval null if successful otherwise pointer to error log
*/
errlHndl_t getSecuritySwitch(uint64_t& o_regValue,
TARGETING::Target* i_pProc
= TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL);
/** @brief Get Processor CBS Control register value
* @par Detailed Description:
* Returns the state of the Processor CBS Control register as
* reported by the given processor (via the supplied target
* pointer).
* @param[out] o_regValue The value read from the register if the
* call was successful. If not successful this value is set to
* zero. Check the return value for a non null error log to
* determine if the call was unsuccessful.
* @param[in] i_pProc The target processor to obtain the jumper
* state from. Must not be null. Optional parameter that
* defaults to the master processor sentinel.
*/
errlHndl_t getProcCbsControlRegister(uint64_t& o_regValue,
TARGETING::Target* i_pProc
= TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL);
/**
* @brief Clear specified bits in the processor security switch register
*
* @par Detailed Description:
* Clears the specified bits in the processor security switch register.
*
* @param[in] i_bits Vector of ProcSecurity (bit) enums
* @param[in] i_pTarget Processor target to write. Must be either
* the master processor target sentinel or valid processor target.
* Must not be NULL.
*
* @return errHndl_t Error log handle indicating success or failure
* @retval nullptr Cleared specified security switch register bits
* successfully
* @retval !nullptr Error log providing failure details
*/
errlHndl_t clearSecuritySwitchBits(
const std::vector<SECUREBOOT::ProcSecurity>& i_bits,
TARGETING::Target* i_pTarget =
TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL);
/**
* @brief Set specified bits in the processor security switch register
*
* @par Detailed Description:
* Sets the specified bits in the processor security switch register.
*
* @param[in] i_bits Vector of ProcSecurity (bit) enums
* @param[in] i_pTarget Processor target to write. Must be either
* the master processor target sentinel or valid processor target.
* Must not be NULL.
*
* @return errHndl_t Error log handle indicating success or failure
* @retval nullptr Set specified security switch register bits
* successfully
* @retval !nullptr Error log providing failure details
*/
errlHndl_t setSecuritySwitchBits(
const std::vector<SECUREBOOT::ProcSecurity>& i_bits,
TARGETING::Target* i_pTarget =
TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL);
/** @brief Returns the state of the secure jumper as reported by the
* given processor.
*
* @par Detailed Description:
* Returns the state of the secure jumper as reported by the
* the given processor. This should NOT be used to determine
* whether security is enabled, because several conditions are
* aggregated together to determine that. To query whether
* security is actually enabled or not, call the enabled() API.
* This is a limited-use API intended to be called by trusted
* boot code to determine whether a system shipped with a
* secure jumper applied or removed, in order to decide
* whether to enforce the "TPM Required" policy or not.
* @param[out] o_state Provides an enum value of type SecureJumperState
* that can be either SECURITY_DEASSERTED or SECURITY_ASSERTED
* indicating the given processor's secure jumper state.
* Asserted means it is configured to request HW security. This
* does not necessarily imply security is enabled, because the
* HW can be overridden by some functions. Use the getEnabled()
* API to determine whether security is actually enabled.
* Deasserted means the jumper is configured to disble HW security.
* @param[in] i_pProc The target processor to obtain the jumper
* state from. Must not be null. Optional parameter that
* defaults to master processor.
*
* @return errlHndl_t indicating whether the query was successful.
* @retval null if successful otherwise pointer to error log.
*/
errlHndl_t getJumperState(SecureJumperState& o_state,
TARGETING::Target* i_pProc
= TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL);
/* Defition in securerommgr.H */
sbFuncVer_t getSecRomFuncVersion(const sbFuncType_t i_funcType);
/* Defition in securerommgr.H */
uint64_t getSecRomFuncOffset(const sbFuncType_t i_funcType);
/**
* @brief Verify Signed Container
*
* @param[in] i_container Void pointer to effective address of container
* @param[in] i_hwKeyHash Custom hw keys' hash to test against
* [default = nullptr, use current hw hash key]
*
* @return errlHndl_t NULL on success
*/
errlHndl_t verifyContainer(void * i_container,
const sha2_hash_t* i_hwKeyHash = nullptr);
/**
* @brief Hash Signed Blob
*
* @param[in] i_blob Void pointer to effective address of blob
* @param[in] i_size Size of blob in bytes
* @param[out] o_hash SHA512 hash
*
* @return N/A
*/
void hashBlob(const void * i_blob, size_t i_size, SHA512_t o_buf);
/**
* @brief Retrieve the internal hardware keys' hash used to validate
* containers
* @param[out] o_hash Reference to the sha2_hash_t array to copy the
* hash to.
*/
void getHwKeyHash(sha2_hash_t o_hash);
/*
* @brief Hash the concatenation of N Blobs
*
* Asserts if any blob pointer is NULL
*
* @param[in] i_blobs Vector of pairs composed of a void
* pointer to effective address and size
* of the blob to concatenate
* @param[out] o_buf SHA512 hash
*
* @return N/A
*/
void hashConcatBlobs(const blobPair_t &i_blobs, SHA512_t o_buf);
/**
* @brief Common secureboot handler for secureboot failures.
* Properly handles callouts etc.
* @param[in/out] io_err Reference to error log handle. Caller's handle
* will be nullified. Handle must not be NULL, or function asserts.
* @param[in] i_waitForShutdown Whether to wait for system to shutdown (and
* never return from this call) or not (and return from this call).
* In general, code should wait for shutdown unless early in boot before
* basic services are up, or in a resource provider path.
*/
void handleSecurebootFailure(
errlHndl_t &io_err, bool i_waitForShutdown = true);
/**
* @brief Adds the values of the Security Registers of the processors in
* the system to an existing error log
*
* @param[in/out] io_err Error Log that the values of the security
* registers will be added to. Must not be nullptr.
* NOTE: The state of the system/processors
* (ie, SCOM vs FSI) determines which registers can
* be included.
*
* @return N/A
*/
void addSecurityRegistersToErrlog(errlHndl_t & io_err);
/**
* @brief Common handler for adding all relevant secureboot information to
* the user details section of an error log
* @param[in/out] io_err Error Log to add secure info to.
* Must not be nullptr.
*/
void addSecureUserDetailsToErrolog(errlHndl_t & io_err);
}
#endif
|