/* * 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 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_