summaryrefslogtreecommitdiffstats
path: root/src/include/usr/secureboot/service.H
blob: 2a01cdd6b1c110cb99904b1df133890d8f7c1959 (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
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
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
/* 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,2019                        */
/* [+] 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 <secureboot/settings.H>
#include <utility>
#include <cstdint>
#include <securerom/sha512.H>
#include <securerom/ROM.H>

/*
 * @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
{
    class ContainerHeader;

    /** @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_ids  Vector of IDs (PNOR or Lid Id(s)) associated with
     *                   the blob that is being verified.
     *                   [default = empty vector]
     * @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 RomVerifyIds& i_ids = RomVerifyIds(),
                               const SHA512_t* i_hwKeyHash = nullptr);

    /**
     * @brief Verify component ID in a container header against a reference
     *     component ID. Up to 8 ASCII characters, not including NULL, will be
     *     compared (thus, it is critical that all components are unique with
     *     respect to the first 8 bytes).
     *
     * @param[in] i_containerHeader Verified container's header
     * @param[in] i_pComponentString Reference component ID string; must not be
     *     nullptr or function will assert.
     *
     * @return errlHndl_t Error log handle
     * @retval nullptr Component ID verification succeeded
     * @retval !nullptr Error; component ID verification failed
     */
    errlHndl_t verifyComponentId(
        const ContainerHeader& i_containerHeader,
        const char*            i_pComponentId);

    /**
     * @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 SHA512_t array to copy the
     *                     hash to.
     */
     void getHwKeyHash(SHA512_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.
     * @param[in] i_calledByRP Indicates that this function is being called from
     *     within a resource provider message handler, which lets the
     *     implementation know that it needs to take precautionary measures to
     *     avoid deadlock scenarios. If called by a resource provider pass true.
     *     If not, false.
     */
    void handleSecurebootFailure(errlHndl_t &io_err,
                                 bool i_waitForShutdown = true,
                                 bool i_calledByRP = false);

    /**
     *  @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.
     *  @param[in] i_calledByRP See the handleSecurebootFailure function's
     *                         "called by resource provider" option.
     *  @return N/A
     */
    void addSecurityRegistersToErrlog(errlHndl_t & io_err,
                                      bool i_calledByRP = false);

    /**
     * @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.
     * @param[in] i_calledByRP See the handleSecurebootFailure function's
     *                        "called by resource provider" option.
     */
    void addSecureUserDetailsToErrlog(errlHndl_t & io_err,
                                      bool i_calledByRP = false);

    /**
     *  @brief Log an informational error containing platform security
     *      configuration.
     */
    void logPlatformSecurityConfiguration(void);

    /*
     *  @brief Determines if Attribute Overrides are Allowed
     *         If Secureboot is enabled, check allowAttrOverrides setting;
     *         If Secureboot is not enabled, always allow Attribute Overrides
     *
     *  @return bool   TRUE if Attribute Overrides Are Allowed; FALSE otherwise
     */
    bool allowAttrOverrides();

   /*
    * @brief Determines if SBE security backdoor bit is set
    * @return bool TRUE if SBE security backdoor is enabled; FALSE otherwise
    */
    bool getSbeSecurityBackdoor();

    /*
     *  @brief Gets the current SBE security mode value from the secureboot
     *         subsystem
     *
     *  @return uint8_t returns 0 if SBE should check for security disable
     *                  requests, 1 if not
     */
    uint8_t getSbeSecurityMode();

    /*
     *  @brief Sets the current SBE security mode value in the secureboot
     *         subsystem
     *
     *  @param[in] uint8_t The value to set the security mode to. Will accept a
     *                     a value of 0 if SBE should check for security disable
     *                     requests and 1 if not. All other values are not
     *                     allowed and will be rejected via an assert.
     *
     *  @return errlHndl_t Error log handle; nullptr if success, pointer to
     *      valid error log otherwise.
     */
    errlHndl_t setSbeSecurityMode(uint8_t i_sbeSecurityMode);

}

#endif
OpenPOWER on IntegriCloud