Files
bootloader/apps/elftosb/common/Keyblob.h
László Monda e6c1fce5b4 Add KBOOT.
2016-08-10 01:45:15 +02:00

121 lines
4.6 KiB
C++

/*
* File: Keyblob.h
*
* Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
* See included license file for license details.
*/
#if !defined(_Keyblob_h_)
#define _Keyblob_h_
#include "smart_ptr.h"
#include "OptionContext.h"
#include "DataTarget.h"
#include "AESKey.h"
#include "AESCounter.h"
//! The names of the options.
#define kKeyblobOptionNameStart "start"
#define kKeyblobOptionNameEnd "end"
#define kKeyblobOptionNameKey "key"
#define kKeyblobOptionNameCounter "counter"
namespace elftosb
{
/*!
* @brief Keyblob specification.
*/
class Keyblob
{
public:
typedef std::vector<OptionContext *> option_vector_t; //!< List of options entries.
//! @brief Constants for encryption.
enum _encryption_constants
{
k_encryptBlockSize = 16, //!< Block size for AES-128 encryption
k_qspiAlignlength =
512 //!< QSPI image alignment length, 512 is supposed to be the safe alignment level for any QSPI device
//!< this means that all QSPI images generated by this tool will be sizes of multiple 512
};
public:
Keyblob()
: m_id(0)
, m_options(0)
{
}
Keyblob(uint32_t identifier)
: m_id(identifier)
, m_options(0)
{
}
virtual ~Keyblob() {}
static uint32_t getKekSizeBytes() { return kKekSizeBytes; }
void setIdentifier(uint32_t identifier) { m_id = identifier; }
uint32_t getIdentifier() const { return m_id; }
//! \brief Add options.
inline void addOptions(OptionContext *context) { m_options.push_back(context); }
//! \brief Return options vector.
inline option_vector_t *getOptions() { return &m_options; }
//! \brief Create and wrap keyblob data based on options.
//!
//! \retval Pointer to new wrapped data (caller must delete)
//! \retval Number of bytes in wrapped data
uint8_t *createWrappedKeyblobData(uint8_t *kek, uint32_t *byteCount);
//! \brief Encrypt for OTFAD if range is within a keyblob entry range.
//!
//! len must be a multiple of k_qspiAlignlength, which is also
//! a multiple of k_encryptBlockSize.
//!
//! \retval True if data was encrypted (range matched)
bool encryptMatchingRange(uint32_t start, uint32_t len, uint8_t *data);
protected:
//! @brief Keywrap constants.
enum _keywrap_constants
{
kKeySizeBits = 128, //!< AES-128
kExpandedKekSizeInts = 64, //!< Expanded KeK size
kNumKeyBlobs = 4, //!< Number of key blobs
kKeyBlobSizeBytes = 64, //!< Key blob size in bytes
kOutputLineSize = 16, //!< Number of bytes per output line
kRegionAddrMask = (0x400 - 1), //!< Region addresses are modulo 1024
kFlagMask = 0x07, //!< Key flags mask
kKeyFlags = 0x03, //!< Default flags: RO=0, ADE=1, VLD=1
kAesKeySizeBytes = 16, //!< Number of bytes in AES-128 key
kCtrSizeBytes = 8, //!< Number of bytes in Ctr
kKekSizeBytes = 16, //!< Number of bytes in KeK
kNumKeyChars = 32, //!< Number of characters in key string
kNumCtrChars = 16, //!< Number of characters in ctr string
kCrc32SizeBytes = 32 //!< Number of bytes covered by CRC32
};
//! @brief Key Blob format.
typedef struct KeyBlob
{
unsigned char key[kAesKeySizeBytes]; // 16 bytes, 128-bits, KEY[A15...A00]
unsigned char ctr[kCtrSizeBytes]; // 8 bytes, 64-bits, CTR[C7...C0]
unsigned int srtaddr; // region start, STRADDR[31 - 10]
unsigned int endaddr; // region end, ENDADDR[31 - 10]
// end of 32-byte area covered by CRC
unsigned int zero_fill; // zeros
unsigned int key_blob_crc32; // crc32 over 1st 32-bytes
// end of 40 byte (5*64-bit) key blob data
unsigned char expanded_wrap_data[8]; // 8 bytes, used for wrap expanded data
// end of 48 byte (6*64-bit) wrap data
unsigned char unused_filler[16]; // unused fill to 64 bytes
} keyblob_t;
void populateKeyBlob(keyblob_t *blob, uint32_t start, uint32_t end, const char *keyHex, const char *counterHex);
void encrypt(uint32_t length, uint8_t *data, AESKey<128> *key, AESCounter<128> *counter);
bool getOptionValues(OptionContext &opt, const char **key, const char **ctr, uint32_t *start, uint32_t *end);
uint32_t m_id; //!< Unique identifier.
option_vector_t m_options; //!< List of option entries.
};
}; // namespace elftosb
#endif // _Keyblob_h_