summaryrefslogtreecommitdiffstats
path: root/src/usr/pnor/spnorrp.H
blob: 11da539efdabd0f4c51f04fd7d9e3059f93aa5f1 (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
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/pnor/spnorrp.H $                                      */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2011,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 __PNOR_SPNORRP_H
#define __PNOR_SPNORRP_H
#include <pnor/pnorif.H>
#include <sys/msg.h>
#include <stdint.h>
#include <builtins.h>
#include <errl/errlentry.H>
#include <vmmconst.h>
#include <map>
#include "pnor_common.H"
#include "ffs.h"
#include <config.h>
#include <securerom/ROM.H>

namespace SECUREBOOT
{
    class ContainerHeader;
}

/**
 * Secure PNOR Resource Provider
 */

class SPnorRP
{
  public:
   /**
     * @brief Static Initializer
     * @param[in]  ref to errlHndl_t
     */
    static void init( errlHndl_t &io_rtaskRetErrl );

   /**
     * @brief  Returns true if the initial startup failed for some reason
     * @param[out]  Return code
     * @return  true if startup failed
     */
    bool didStartupFail( uint64_t& o_rc ) const
    {
        if( iv_startupRC )
        {
            o_rc = iv_startupRC;
            return true;
        }
        return false;
    };


  protected:
    /**
     * @brief  Constructor, default TOC offsets to side A
     */
    SPnorRP();

    /**
     * @brief  Destructor
     */
    ~SPnorRP();

  private:

    enum
    {
        SBASE_VADDR = VMM_VADDR_SPNOR_RP, /**< 8GB = 0x200000000*/
        TEMP_VADDR = VMM_VADDR_SPNOR_TEMP, /**< 5GB = 0x140000000 */
        LAST_VADDR = SBASE_VADDR + PNOR::PNOR_SIZE,  /**< End of our VA range */
    };

    /* bitwise enumeration to keep track of verified sections */
    enum
    {
        HBI_SECTION = 0x1,
    };

    /**
     * Pointer to the message queue where we receive messages for
     * secure space.
     */
    msg_q_t iv_msgQ;

    /**
     * Remember that we failed during initial startup
     *   This is set by startup methods to indicate to constructor that
     *   something went wrong
     */
    uint64_t iv_startupRC;

    /**
     * Keep track of secured payload size and secure section addresses
     */
    struct LoadRecord{
        uint8_t* secAddr;
        size_t textSize;
        size_t infoSize;
        size_t refCount;
        SHA512_t payloadTextHash;
        LoadRecord()
        :secAddr(nullptr), textSize(0), infoSize(0), refCount(0)
        {
            memset(&payloadTextHash[0], 0, SHA512_DIGEST_LENGTH);
        }
    };
    std::map<PNOR::SectionId, LoadRecord*> iv_loadedSections;


    /**
     * @brief Initialize the daemon, called by constructor
     */
    void initDaemon();

    /**
     * @brief Load secure sections into temporary address space and verify them
     * @note The Load record is not only used for output of the section info
     *       from the verifySections, but is also used as input via the
     *       payloadTextHash field, which is used (if i_loadedPreviously is
     *       true) to help determine if the PCR extend should be recalculated.
     *
     * @param[in]     i_secId - PNOR section id to verify
     * @param[in]     i_loadedPreviously - indicates section has been securely
     *                loaded previously
     * @param[in/out] io_rec - Load record to store section information in
     *                io_rec->payloadTextHash is used for comparision if
     *                i_loadedPreviusly is true.
     * @param[out]    o_plid - On function failure (return code is non-zero),
     *                PLID of the related error that was committed internally,
     *                otherwise 0.
     * @return  uint64_t - Return code to pass back to message handler.  If a
     *                     non-0 return code is returned, that implies the
     *                     function also committed an error and returned a non-0
     *                     PLID in o_plid
     */
    uint64_t verifySections(PNOR::SectionId i_id,
                            bool i_loadedPreviously,
                            LoadRecord* io_rec,
                            uint32_t& o_plid);

    /**
     * @brief  Message receiver for secure space
     */
    void waitForMessage();

    // disable copy ctor
    SPnorRP(const SPnorRP&);

    // disable assignment operator
    SPnorRP& operator=(const SPnorRP&);

    // allow local helper function to call private methods
    friend void* secure_wait_for_message( void* unused );

    /**
     * @brief  A wrapper for mm_alloc_block that encapsulates error log
     *         creation.
     */
    errlHndl_t allocBlock(msg_q_t mq, void* va, uint64_t size) const;

    /**
     * @brief  A wrapper for mm_set_permission that encapsulates error log
     *         creation.
     */
    errlHndl_t setPermission(void* va, uint64_t size,
                                       uint64_t accessType) const;

    /**
     * @brief  A wrapper for mm_remove_pages that encapsulates an error log
     * @note   This is a special case of mm_remove_pages that makes use of
     *         PAGE_REMOVAL_OPS "RELEASE" setting
     *
     * @param[in] i_va - virtual start address of pages to be removed
     * @param[in] i_size - size of block to remove
     */
    errlHndl_t removePages(void* i_va, uint64_t i_size) const;

    /**
     * @brief  Handles any additional section specific verification checks.
     * @param[in]  i_vaddr - vaddr of PNOR section to verify. Includes header
     *                       NULL will assert
     * @param[in]  i_secId - PNOR section id to verify
     * @return  errlHndl_t - NULL if success, errlHndl_t otherwise.
     */
    errlHndl_t miscSectionVerification(const uint8_t *i_vaddr,
                                       PNOR::SectionId i_secId) const;

    /**
     * @brief  Check if HBB and HBI were part of the same build
     *         Calculate HBB sw signatures hash and compare that to the build
     *         time hash of HBB sw signatures. The build time HBB hash is stored
     *         in the first entry (SALT) of HBI's hash page table.
     * @param[in]  i_vaddr - vaddr points to start of hash page table of HBI
     *                       NOTE: Since this expects the vaddr to point to the
     *                       start of the hash page table, the secureboot header
     *                       must be skipped prior by the caller.
     *                       NULL will assert
     * @return  errlHndl_t - NULL if success, errlHndl_t otherwise.
     */
    errlHndl_t baseExtVersCheck(const uint8_t *i_vaddr) const;

    /**
     * @brief  Check if SBKT is properly formatted to then provide the new HW
     *         key hash to transition the system to.
     * @param[in]  i_vaddr - vaddr points to start of the SBKT container
     *                       NULL will assert
     * @return  errlHndl_t - NULL if success, errlHndl_t otherwise.
     */
    errlHndl_t keyTransitionCheck(const uint8_t *i_vaddr) const;

    /**
     *  @brief Apply lab override policy to the attribute model
     *
     *  @par Detailed Description:
     *      Reads the lab override flag from the input flag set, inverts it, and
     *      writes it to the ATTR_HB_SECURITY_MODE attribute (which directly
     *      maps to FAPI attribute ATTR_SECURITY_MODE).  Later, SBE update
     *      will customize that FAPI attribute into the SBEs.  If the policy is
     *      set (attribute clear), the SBE will watch mailbox scratch register 3
     *      bit 6 to be set.  In that case, SBE will disable security for the
     *      processor, otherwise (policy clear/attribute set) it will not change
     *      the security settings.
     *
     *  @param[in] i_flags Various flags read from the secure header
     *
     *  @return errlHndl_t Error log handle; nullptr if success, pointer to
     *      valid error log otherwise.
     */
    errlHndl_t processLabOverride(
        const sb_flags_t& i_flags) const;

    /**
     *  @brief Apply firmware key indicator policies for the given section
     *
     *  @par Detailed Description:
     *      Reads the HW/SW policy flags from the given section's container
     *      header and applies any applicable policies.
     *
     *  @param[in] i_header Reference to requested section's container header
     *  @param[in] i_sectionId Section's ID
     *
     *  @return errlHndl_t Error log handle; nullptr if success, pointer to
     *      valid error log otherwise.
     */
    errlHndl_t processFwKeyIndicators(
        const SECUREBOOT::ContainerHeader& i_header,
        const PNOR::SectionId              i_sectionId) const;
};
#endif
OpenPOWER on IntegriCloud