161 lines
4.7 KiB
C
161 lines
4.7 KiB
C
|
/* Copyright 2013-2016 IBM 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.
|
||
|
*/
|
||
|
|
||
|
#ifndef __STB_CONTAINER_H
|
||
|
#define __STB_CONTAINER_H
|
||
|
|
||
|
#include <stdint.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <ccan/endian/endian.h>
|
||
|
|
||
|
#define SECURE_BOOT_HEADERS_SIZE 4096
|
||
|
#define SHA256_DIGEST_LENGTH 32
|
||
|
|
||
|
/*
|
||
|
* The defines and structures below come from the secure ROM source code
|
||
|
* (trusted_boot_rom). Here you will find only the ones required by the
|
||
|
* secure and trusted boot implementation in skiboot.
|
||
|
*/
|
||
|
|
||
|
/* From trusted_boot_rom/src/sha512.h */
|
||
|
#define SHA512_DIGEST_LENGTH 64
|
||
|
typedef uint8_t __attribute__((aligned(8))) sha2_hash_t[ SHA512_DIGEST_LENGTH / sizeof(uint8_t) ];
|
||
|
typedef uint8_t sha2_byte; // Exactly 1 byte
|
||
|
|
||
|
/* From trusted_boot_rom/src/hw_utils.h */
|
||
|
#define ECID_SIZE 16
|
||
|
|
||
|
/* From trusted_boot_rom/src/ecverify.h */
|
||
|
#define EC_COORDBYTES 66 /* P-521 */
|
||
|
typedef uint8_t ecc_key_t[2*EC_COORDBYTES];
|
||
|
typedef uint8_t ecc_signature_t[2*EC_COORDBYTES];
|
||
|
|
||
|
/* From trusted_boot_rom/src/ROM.h */
|
||
|
#define ROM_MAGIC_NUMBER 0x17082011
|
||
|
|
||
|
typedef struct {
|
||
|
be16 version; /* (1: see versions above) */
|
||
|
uint8_t hash_alg; /* (1: SHA-512) */
|
||
|
uint8_t sig_alg; /* (1: SHA-512/ECDSA-521) */
|
||
|
}__attribute__((packed)) ROM_version_raw;
|
||
|
|
||
|
typedef struct {
|
||
|
ROM_version_raw ver_alg;
|
||
|
be64 code_start_offset;
|
||
|
be64 reserved;
|
||
|
be32 flags;
|
||
|
uint8_t sw_key_count;
|
||
|
be64 payload_size;
|
||
|
sha2_hash_t payload_hash;
|
||
|
uint8_t ecid_count;
|
||
|
struct { uint8_t ecid[ECID_SIZE]; } ecid[0]; /* optional ecid place
|
||
|
holder ecid_count * ecid_size(128 bits) */
|
||
|
/* followed by prefix data (sig,keys) key raw */
|
||
|
}__attribute__((packed)) ROM_prefix_header_raw;
|
||
|
|
||
|
typedef struct {
|
||
|
be32 magic_number; /* (17082011) */
|
||
|
be16 version; /* (1: see versions above) */
|
||
|
be64 container_size; /* filled by caller */
|
||
|
be64 target_hrmor; /* filled by caller */
|
||
|
be64 stack_pointer; /* filled by caller */
|
||
|
/* bottom of stack -> 128k added by rom code to get real stack pointer */
|
||
|
ecc_key_t hw_pkey_a;
|
||
|
ecc_key_t hw_pkey_b;
|
||
|
ecc_key_t hw_pkey_c;
|
||
|
/* followed by sw header (if not special prefix) */
|
||
|
/* followed by optional unprotected payload data */
|
||
|
}__attribute__((packed)) ROM_container_raw;
|
||
|
|
||
|
typedef struct {
|
||
|
ecc_signature_t hw_sig_a;
|
||
|
ecc_signature_t hw_sig_b;
|
||
|
ecc_signature_t hw_sig_c;
|
||
|
ecc_key_t sw_pkey_p;
|
||
|
ecc_key_t sw_pkey_q;
|
||
|
ecc_key_t sw_pkey_r;
|
||
|
}__attribute__((packed)) ROM_prefix_data_raw;
|
||
|
|
||
|
typedef struct {
|
||
|
ROM_version_raw ver_alg;
|
||
|
be64 code_start_offset;
|
||
|
be64 reserved;
|
||
|
be32 flags;
|
||
|
uint8_t reserved_0;
|
||
|
be64 payload_size;
|
||
|
sha2_hash_t payload_hash;
|
||
|
uint8_t ecid_count;
|
||
|
struct { uint8_t ecid[ECID_SIZE]; } ecid[0]; /* optional ecid place
|
||
|
holder ecid_count * ecid_size(128 bits) */
|
||
|
/* followed by sw sig raw */
|
||
|
}__attribute__((packed)) ROM_sw_header_raw;
|
||
|
|
||
|
typedef struct {
|
||
|
ecc_signature_t sw_sig_p;
|
||
|
ecc_signature_t sw_sig_q;
|
||
|
ecc_signature_t sw_sig_r;
|
||
|
/* followed by zero's padding to 4K */
|
||
|
/* followed by protected sw payload_data */
|
||
|
/* followed by unprotected sw payload_text */
|
||
|
}__attribute__((packed)) ROM_sw_sig_raw;
|
||
|
|
||
|
typedef enum { ROM_DONE, ROM_FAILED, PHYP_PARTIAL } ROM_response;
|
||
|
|
||
|
typedef struct {
|
||
|
sha2_hash_t hw_key_hash;
|
||
|
uint8_t my_ecid[ECID_SIZE];
|
||
|
be64 entry_point;
|
||
|
be64 log;
|
||
|
}__attribute__((packed)) ROM_hw_params;
|
||
|
|
||
|
struct parsed_stb_container {
|
||
|
const void *buf;
|
||
|
size_t bufsz;
|
||
|
const ROM_container_raw *c;
|
||
|
const ROM_prefix_header_raw *ph;
|
||
|
const ROM_prefix_data_raw *pd;
|
||
|
const ROM_sw_header_raw *sh;
|
||
|
const ROM_sw_sig_raw *ssig;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* Helper functions
|
||
|
*/
|
||
|
|
||
|
/* Get the container payload eyecatcher */
|
||
|
uint32_t stb_payload_magic(const void *buf, size_t size);
|
||
|
|
||
|
/* Check if buf is a secure boot container */
|
||
|
bool stb_is_container(const void* buf, size_t size);
|
||
|
|
||
|
/* Get the pointer for the sw-payload-hash field of the container header */
|
||
|
const uint8_t* stb_sw_payload_hash(const void* buf, size_t size);
|
||
|
uint64_t stb_sw_payload_size(const void *buf, size_t size);
|
||
|
|
||
|
int parse_stb_container(const void* data, size_t len, struct parsed_stb_container *c);
|
||
|
|
||
|
void stb_print_data(const void *data, size_t len);
|
||
|
|
||
|
void getPublicKeyRaw(ecc_key_t *pubkeyraw, char *filename);
|
||
|
|
||
|
void getSigRaw(ecc_signature_t *sigraw, char *filename);
|
||
|
|
||
|
void writeHdr(void *ph, const char *outFile, int hdr_type);
|
||
|
|
||
|
void printBytes(char *lead, unsigned char *buffer, size_t buflen, int wrap);
|
||
|
|
||
|
#endif /* __STB_CONTAINER_H */
|