Skip to content

Commit c0eb7d9

Browse files
Stephen Cprekdcrowell77
authored andcommitted
Add parser class for secure container headers
Change-Id: Ide2b14d0452fba4d0043abcb939980839764f606 RTC: 125298 ForwardPort: yes Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/24219 Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: FSP CI Jenkins Tested-by: Jenkins OP HW Reviewed-by: Christopher J. Engel <cjengel@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
1 parent f23950a commit c0eb7d9

File tree

7 files changed

+580
-115
lines changed

7 files changed

+580
-115
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/* IBM_PROLOG_BEGIN_TAG */
2+
/* This is an automatically generated prolog. */
3+
/* */
4+
/* $Source: src/include/usr/secureboot/containerheader.H $ */
5+
/* */
6+
/* OpenPOWER HostBoot Project */
7+
/* */
8+
/* Contributors Listed Below - COPYRIGHT 2016 */
9+
/* [+] International Business Machines Corp. */
10+
/* */
11+
/* */
12+
/* Licensed under the Apache License, Version 2.0 (the "License"); */
13+
/* you may not use this file except in compliance with the License. */
14+
/* You may obtain a copy of the License at */
15+
/* */
16+
/* http://www.apache.org/licenses/LICENSE-2.0 */
17+
/* */
18+
/* Unless required by applicable law or agreed to in writing, software */
19+
/* distributed under the License is distributed on an "AS IS" BASIS, */
20+
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
21+
/* implied. See the License for the specific language governing */
22+
/* permissions and limitations under the License. */
23+
/* */
24+
/* IBM_PROLOG_END_TAG */
25+
#ifndef __SECUREBOOT_CONTAINER_HEADER_H
26+
#define __SECUREBOOT_CONTAINER_HEADER_H
27+
28+
#include <errl/errlentry.H>
29+
#include <secureboot/service.H>
30+
#include <secureboot/rom.H>
31+
32+
// Forward Declaration
33+
class SecureROMTest;
34+
35+
namespace SECUREBOOT
36+
{
37+
38+
/** @class ContainerHeader
39+
* @brief Class for parsing secureboot container headers.
40+
*/
41+
class ContainerHeader
42+
{
43+
public:
44+
45+
/**
46+
* @brief ContainerHeader
47+
*
48+
* This constructor parses the input container header and sets values
49+
* accordingly so they can be retrieved later.
50+
*
51+
* @param[in] i_header Secure container header to parse.
52+
* NULL input will assert
53+
*/
54+
ContainerHeader(const void* i_header):
55+
iv_isValid(false),iv_hdrBytesRead(0)
56+
{
57+
assert(i_header != NULL);
58+
iv_pHdrStart = reinterpret_cast<const uint8_t*>(i_header);
59+
memset(&iv_headerInfo, 0x00, sizeof(iv_headerInfo));
60+
parse_header(i_header);
61+
};
62+
63+
/**
64+
* @brief Destructor
65+
*/
66+
~ContainerHeader(){};
67+
68+
/**
69+
* @brief Retrieves payload text size
70+
* @return size_t - size of payload text size
71+
*/
72+
size_t payloadTextSize() const;
73+
74+
/**
75+
* @brief Retrieves payload text hash
76+
* @return SHA512_t* - ptr to hash of payload text
77+
*/
78+
const SHA512_t* payloadTextHash() const;
79+
80+
// @TODO RTC: 155374 remove, SecureROMTest will use iv_isValid.
81+
/**
82+
* @brief Returns if the parsed header is a valid secureboot one. This
83+
* is a temporary, non-secure way of pragmatically determining
84+
* if secureboot signing was supported. Eventually it will always
85+
* happen
86+
* @return bool - whether or not the container is a valid secureboot
87+
*/
88+
bool isValid() const;
89+
90+
private:
91+
/**
92+
* @brief Default Constructor in private to prevent being instantiated
93+
* by non friend/children derivatives.
94+
*/
95+
ContainerHeader(){};
96+
97+
/**
98+
* @brief Complete container header structure based on ROM structures
99+
*/
100+
struct SecureHeaderInfo
101+
{
102+
ROM_container_raw hw_hdr;
103+
ROM_prefix_header_raw hw_prefix_hdr;
104+
ROM_prefix_data_raw hw_prefix_data;
105+
ROM_sw_header_raw sw_hdr;
106+
ROM_sw_sig_raw sw_sig;
107+
};
108+
109+
// Entire cached container header content
110+
SecureHeaderInfo iv_headerInfo;
111+
112+
// Indicates if container header is a valid, in a very loose sense,
113+
// secureboot header.
114+
bool iv_isValid;
115+
116+
// Pointer to the start of the container header
117+
const uint8_t* iv_pHdrStart;
118+
119+
// Counter for bytes read while parsing the container header
120+
size_t iv_hdrBytesRead;
121+
122+
/**
123+
* @brief Weak check to determine if secureboot header looks right.
124+
* Also sets iv_isValid private member
125+
*/
126+
void validate();
127+
128+
/**
129+
* @brief Print out useful sections of the container header
130+
*/
131+
void print() const;
132+
133+
/**
134+
* @brief parse_header Blob
135+
*
136+
* Parses a secure container header defined by ROM structures and set
137+
* internal header structure.
138+
*
139+
* @param[in] i_containerHdr Secure container header to parse
140+
* NULL input will assert
141+
*/
142+
void parse_header(const void* i_header);
143+
144+
/**
145+
* @brief Checks bounds of parsing before mempy and increments pointer
146+
*
147+
* Ensures that we don't memcpy more bytes than the max size of a
148+
* secure container header. Asserts on out of bounds memcpy.
149+
*
150+
* @param[in] i_dest Pointer to the memory location to copy to
151+
* NULL input will assert
152+
* @param[in] io_hdr Pointer to current location of container header
153+
* NULL input will assert
154+
* @param[in] i_size Number of bytes to copy
155+
*/
156+
void safeMemCpyAndInc(void* i_dest, const uint8_t* &io_hdr,
157+
const size_t i_size);
158+
159+
friend class ::SecureROMTest;
160+
};
161+
162+
}; //end of SECUREBOOT namespace
163+
164+
#endif
165+
166+

src/include/usr/secureboot/rom.H

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/* IBM_PROLOG_BEGIN_TAG */
2+
/* This is an automatically generated prolog. */
3+
/* */
4+
/* $Source: src/include/usr/secureboot/rom.H $ */
5+
/* */
6+
/* OpenPOWER HostBoot Project */
7+
/* */
8+
/* Contributors Listed Below - COPYRIGHT 2016 */
9+
/* [+] International Business Machines Corp. */
10+
/* */
11+
/* */
12+
/* Licensed under the Apache License, Version 2.0 (the "License"); */
13+
/* you may not use this file except in compliance with the License. */
14+
/* You may obtain a copy of the License at */
15+
/* */
16+
/* http://www.apache.org/licenses/LICENSE-2.0 */
17+
/* */
18+
/* Unless required by applicable law or agreed to in writing, software */
19+
/* distributed under the License is distributed on an "AS IS" BASIS, */
20+
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
21+
/* implied. See the License for the specific language governing */
22+
/* permissions and limitations under the License. */
23+
/* */
24+
/* IBM_PROLOG_END_TAG */
25+
#ifndef __SECUREBOOT_ROM_H
26+
#define __SECUREBOOT_ROM_H
27+
28+
// Consts used for container header validation
29+
const uint32_t MAGIC_NUMBER = 0x17082011;
30+
const uint16_t ROM_VERSION = 1;
31+
const uint8_t ROM_HASH_ALG = 1;
32+
const uint8_t ROM_SIG_ALG = 1;
33+
const uint8_t SW_KEY_COUNT_MIN = 1;
34+
const uint8_t SW_KEY_COUNT_MAX = 3;
35+
const size_t MAX_SECURE_HEADER_SIZE = 4096;
36+
37+
/******************************************************************/
38+
/* Start of Chip Logic Secure ROM include section */
39+
/******************************************************************/
40+
// These defines come from the following directory:
41+
// /afs/awd/projects/eclipz/c22/libs/tp/logic/p8m/head/trusted_boot_rom/src
42+
43+
/* From hw_utils.h: */
44+
#define ECID_SIZE 16
45+
#define PIBMEM 0x00080000
46+
#define PIBMEM_HW_KEY_HASH (PIBMEM +0x0008)
47+
48+
/* From ecverify.h */
49+
#define EC_COORDBYTES 66 /* P-521 */
50+
typedef uint8_t ecc_key_t[2*EC_COORDBYTES];
51+
typedef uint8_t ecc_signature_t[2*EC_COORDBYTES];
52+
53+
/* From sha512.h: */
54+
#define SHA512_DIGEST_LENGTH 64
55+
typedef uint8_t __attribute__((aligned(8))) sha2_hash_t[ \
56+
SHA512_DIGEST_LENGTH / sizeof(uint8_t) ];
57+
58+
typedef uint8_t sha2_byte; /* Exactly 1 byte */
59+
60+
/* From ROM.h */
61+
typedef enum { ROM_DONE, ROM_FAILED, PHYP_PARTIAL } ROM_response;
62+
63+
/* From ROM.h */
64+
typedef struct {
65+
uint16_t version; // (1: see versions above)
66+
uint8_t hash_alg; // (1: SHA-512)
67+
uint8_t sig_alg; // (1: SHA-512/ECDSA-521)
68+
}__attribute__((packed)) ROM_version_raw;
69+
70+
typedef struct {
71+
uint32_t magic_number; // (17082011)
72+
uint16_t version; // (1: see versions above)
73+
uint64_t container_size; // filled by caller
74+
uint64_t target_hrmor; // filled by caller
75+
uint64_t stack_pointer; // filled by caller
76+
//bottom of stack -> 128k added by rom code to get real stack pointer
77+
ecc_key_t hw_pkey_a;
78+
ecc_key_t hw_pkey_b;
79+
ecc_key_t hw_pkey_c;
80+
uint64_t prefix; // prefix header place holder
81+
// followed by sw header (if not special prefix)
82+
// followed by optional unprotected payload data
83+
}__attribute__((packed)) ROM_container_raw;
84+
85+
typedef struct {
86+
ROM_version_raw ver_alg;
87+
uint64_t code_start_offset;
88+
uint64_t reserved;
89+
uint32_t flags;
90+
uint8_t sw_key_count;
91+
uint64_t payload_size;
92+
sha2_hash_t payload_hash;
93+
uint8_t ecid_count;
94+
uint8_t ecid[ECID_SIZE]; // optional ecid place holder ecid_count * ecid_size(128 bits)
95+
// followed by prefix data (sig,keys) key raw
96+
}__attribute__((packed)) ROM_prefix_header_raw;
97+
98+
#define PREFIX_HEADER_SIZE(_p) (sizeof(ROM_prefix_header_raw)+((_p->ecid_count-1)*ECID_SIZE))
99+
100+
typedef struct {
101+
ecc_signature_t hw_sig_a;
102+
ecc_signature_t hw_sig_b;
103+
ecc_signature_t hw_sig_c;
104+
ecc_key_t sw_pkey_p;
105+
ecc_key_t sw_pkey_q;
106+
ecc_key_t sw_pkey_r;
107+
}__attribute__((packed)) ROM_prefix_data_raw;
108+
109+
typedef struct {
110+
ROM_version_raw ver_alg;
111+
uint64_t code_start_offset;
112+
uint64_t reserved;
113+
uint32_t flags;
114+
uint8_t reserved_0;
115+
uint64_t payload_size;
116+
sha2_hash_t payload_hash;
117+
uint8_t ecid_count;
118+
uint8_t ecid[ECID_SIZE]; // optional ecid place holder ecid_count * ecid_size(128 bits)
119+
// followed by sw sig raw
120+
}__attribute__((packed)) ROM_sw_header_raw;
121+
122+
#define SW_HEADER_SIZE(_p) (sizeof(ROM_sw_header_raw)+((_p->ecid_count-1)*ECID_SIZE))
123+
124+
typedef struct {
125+
ecc_signature_t sw_sig_p;
126+
ecc_signature_t sw_sig_q;
127+
ecc_signature_t sw_sig_r;
128+
// followed by zero's padding to 4K
129+
// followed by protected sw payload_data
130+
// followed by unprotected sw payload_text
131+
}__attribute__((packed)) ROM_sw_sig_raw;
132+
133+
typedef struct {
134+
sha2_hash_t hw_key_hash;
135+
uint8_t my_ecid[ECID_SIZE];
136+
uint64_t entry_point;
137+
uint64_t log;
138+
}__attribute__((packed)) ROM_hw_params;
139+
140+
// Need this for the following definition
141+
#ifdef __cplusplus
142+
extern "C"
143+
{
144+
#endif
145+
146+
// Interfaces for Assembly Functions to call into Secure ROM
147+
// - 1st parameter is address of function offset into Secure ROM,
148+
// followed by additional parameters as necssary
149+
150+
ROM_response call_rom_verify(void*, ROM_container_raw*, ROM_hw_params*);
151+
void call_rom_SHA512(void*, const sha2_byte *, size_t, sha2_hash_t*);
152+
153+
#ifdef __cplusplus
154+
}
155+
#endif
156+
157+
/* Offsets needed to call functions in jump table at start of */
158+
/* SecureROM code - see .../trusted_boot_rom/bootrom.dis */
159+
#define SHA512_HASH_FUNCTION_OFFSET 0x20
160+
#define ROM_VERIFY_FUNCTION_OFFSET 0x30
161+
162+
/******************************************************************/
163+
/* End of Chip Logic ROM include section */
164+
/******************************************************************/
165+
166+
#endif

0 commit comments

Comments
 (0)