121 lines
4.6 KiB
C++
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_
|