/* * Copyright (C) 2016 Southern Storm Software, Pty Ltd. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "XTS.h" #include "Crypto.h" #include "GF128.h" #include /** * \class XTSCommon XTS.h * \brief Concrete base class to assist with implementing XTS mode for * 128-bit block ciphers. * * References: IEEE Std. 1619-2007, NIST SP 800-38E, a href="http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf">XEX. * * \sa XTS, XTSSingleKey */ /** * \brief Constructs an XTS object with a default sector size of 512 bytes. */ XTSCommon::XTSCommon() : sectSize(512) { } /** * \brief Clears all sensitive information and destroys this object. */ XTSCommon::~XTSCommon() { clean(twk); } /** * \brief Gets the size of the key for XTS mode. * * The key size for XTS mode is twice the size of the underlying * block cipher key size. * * \sa setKey(), tweakSize() */ size_t XTSCommon::keySize() const { return blockCipher1->keySize() * 2; } /** * \brief Gets the maximum supported size for the tweak. * * This function returns 16, which indicates that any tweak up to 16 bytes * in size can be specified via setTweak(). */ size_t XTSCommon::tweakSize() const { return 16; } /** * \fn size_t XTSCommon::sectorSize() const * \brief Gets the size of sectors encrypted or decrypted by this class. * * The default value is 512 bytes. * * \sa setSectorSize() */ /** * \brief Sets the size of sectors encrypted or decrypted by this class. * * \param size The sector size in bytes, which must be greater than or * equal to 16. * * \return Returns false if \a size is less than 16. * * \sa sectorSize(), encryptSector() */ bool XTSCommon::setSectorSize(size_t size) { if (size < 16) return false; sectSize = size; return true; } /** * \brief Sets the key to use for XTS mode. * * \param key Points to the key. * \param len The size of the key in bytes which must be twice the * size of the underlying block cipher's key size. * * \return Returns true if the key was set or false if \a len was incorrect. * * This function should be followed by a call to setTweak() to specify * the sector-specific tweak. * * \sa keySize(), setTweak(), encryptSector() */ bool XTSCommon::setKey(const uint8_t *key, size_t len) { if (!blockCipher1->setKey(key, len / 2)) return false; return blockCipher2->setKey(key + len / 2, len - (len / 2)); } /** * \brief Sets the tweak value for the current sector to encrypt or decrypt. * * \param tweak Points to the tweak. * \param len The length of the tweak which must be less than or equal to 16. * * \return Returns true if the tweak was set or false if \a len was incorrect. * * If \a len is less than 16, then the \a tweak will be zero-padded to * 16 bytes. * * The \a tweak is encrypted with the second half of the XTS key to generate * the actual tweak value for the sector. * * \sa tweakSize(), setKey(), encryptSector() */ bool XTSCommon::setTweak(const uint8_t *tweak, size_t len) { if (len > 16) return false; memcpy(twk, tweak, len); memset(((uint8_t *)twk) + len, 0, 16 - len); blockCipher2->encryptBlock((uint8_t *)twk, (uint8_t *)twk); return true; } #define xorTweak(output, input, tweak) \ do { \ for (uint8_t i = 0; i < 16; ++i) \ (output)[i] = (input)[i] ^ ((const uint8_t *)(tweak))[i]; \ } while (0) /** * \brief Encrypts an entire sector of data. * * \param output The output buffer to write the ciphertext to, which can * be the same as \a input. * \param input The input buffer to read the plaintext from. * * The \a input and \a output buffers must be at least sectorSize() * bytes in length. * * \sa decryptSector(), setKey(), setTweak() */ void XTSCommon::encryptSector(uint8_t *output, const uint8_t *input) { size_t sectLast = sectSize & ~15; size_t posn = 0; uint32_t t[4]; memcpy(t, twk, sizeof(t)); while (posn < sectLast) { // Process all complete 16-byte blocks. xorTweak(output, input, t); blockCipher1->encryptBlock(output, output); xorTweak(output, output, t); GF128::dblXTS(t); input += 16; output += 16; posn += 16; } if (posn < sectSize) { // Perform ciphertext stealing on the final partial block. uint8_t leftOver = sectSize - posn; output -= 16; while (leftOver > 0) { // Swap the left-over bytes in the last two blocks. --leftOver; uint8_t temp = input[leftOver]; output[leftOver + 16] = output[leftOver]; output[leftOver] = temp; } xorTweak(output, output, t); blockCipher1->encryptBlock(output, output); xorTweak(output, output, t); } } /** * \brief Decrypts an entire sector of data. * * \param output The output buffer to write the plaintext to, which can * be the same as \a input. * \param input The input buffer to read the ciphertext from. * * The \a input and \a output buffers must be at least sectorSize() * bytes in length. * * \sa encryptSector(), setKey(), setTweak() */ void XTSCommon::decryptSector(uint8_t *output, const uint8_t *input) { size_t sectLast = sectSize & ~15; size_t posn = 0; uint32_t t[4]; memcpy(t, twk, sizeof(t)); if (sectLast != sectSize) sectLast -= 16; while (posn < sectLast) { // Process all complete 16-byte blocks. xorTweak(output, input, t); blockCipher1->decryptBlock(output, output); xorTweak(output, output, t); GF128::dblXTS(t); input += 16; output += 16; posn += 16; } if (posn < sectSize) { // Perform ciphertext stealing on the final two blocks. uint8_t leftOver = sectSize - 16 - posn; uint32_t u[4]; // Decrypt the second-last block of ciphertext to recover // the last partial block of plaintext. We need to use // dblXTS(t) as the tweak for this block. Save the current // tweak in "u" for use later. memcpy(u, t, sizeof(t)); GF128::dblXTS(t); xorTweak(output, input, t); blockCipher1->decryptBlock(output, output); xorTweak(output, output, t); // Swap the left-over bytes in the last two blocks. while (leftOver > 0) { --leftOver; uint8_t temp = input[leftOver + 16]; output[leftOver + 16] = output[leftOver]; output[leftOver] = temp; } // Decrypt the second-last block using the second-last tweak. xorTweak(output, output, u); blockCipher1->decryptBlock(output, output); xorTweak(output, output, u); } } /** * \brief Clears all security-sensitive state from this XTS object. */ void XTSCommon::clear() { clean(twk); blockCipher1->clear(); blockCipher2->clear(); } /** * \fn void XTSCommon::setBlockCiphers(BlockCipher *cipher1, BlockCipher *cipher2) * \brief Sets the two block ciphers to use for XTS mode. * * \param cipher1 Points to the first block cipher object, which must be * capable of both encryption and decryption. * \param cipher2 Points to the second block cipher object, which must be * capable of both encryption but does not need to be capable of decryption. * * Both block ciphers must have a 128-bit block size. */ /** * \class XTSSingleKeyCommon XTS.h * \brief Concrete base class to assist with implementing single-key XTS * mode for 128-bit block ciphers. * * References: IEEE Std. 1619-2007, NIST SP 800-38E, a href="http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf">XEX. * * \sa XTSSingleKey, XTSCommon */ /** * \fn XTSSingleKeyCommon::XTSSingleKeyCommon() * \brief Constructs an XTS object with a default sector size of 512 bytes. */ /** * \brief Clears all sensitive information and destroys this object. */ XTSSingleKeyCommon::~XTSSingleKeyCommon() { } /** * \brief Gets the size of the key for single-pkey XTS mode. * * The key size for single-key XTS mode is the same as the key size * for the underlying block cipher. * * \sa setKey(), tweakSize() */ size_t XTSSingleKeyCommon::keySize() const { return blockCipher1->keySize(); } /** * \brief Sets the key to use for single-keyh XTS mode. * * \param key Points to the key. * \param len The size of the key in bytes which must be same as the * size of the underlying block cipher. * * \return Returns true if the key was set or false if \a len was incorrect. * * This function should be followed by a call to setTweak() to specify * the sector-specific tweak. * * \sa keySize(), setTweak(), encryptSector() */ bool XTSSingleKeyCommon::setKey(const uint8_t *key, size_t len) { return blockCipher1->setKey(key, len); } /** * \class XTS XTS.h * \brief Implementation of the XTS mode for 128-bit block ciphers. * * XTS mode implements the XEX tweakable block cipher mode with ciphertext * stealing for data that isn't a multiple of the 128-bit block size. * * XTS was designed for use in disk encryption where a large number of * equal-sized "sectors" need to be encrypted in a way that information * from one sector cannot be used to decrypt the other sectors. The mode * combines the key with a sector-specific "tweak" which is usually * based on the sector number. * * Some Arduino systems have SD cards, but typically embedded systems * do not have disk drives. However, XTS can still be useful on * Arduino systems with lots of EEPROM or flash memory. If the application * needs to store critical security parameters like private keys then * XTS can be used to encrypt non-volatile memory to protect the parameters. * * The following example encrypts a sector using XTS mode: * * \code * XTS xts; * xts.setSectorSize(520); * xts.setKey(key, 64); // Twice the AES256 key size. * xts.setTweak(sectorNumber, sizeof(sectorNumber)); * xts.encryptSector(output, input); * \endcode * * XTS keys are twice the size of the underlying block cipher * (AES256 in the above example). The XTS key is divided into two halves. * The first half is used to encrypt the plaintext and the second half * is used to encrypt the sector-specific tweak. The same key can be * used for both, in which case XTS is equivalent to the original * XEX design upon which XTS was based. The companion XTSSingleKey class * can be used for single-key scenarios. * * The template parameter must be a concrete subclass of BlockCipher * indicating the specific block cipher to use. The example above uses * AES256 as the underlying cipher. * * It is also possible to specify two different block ciphers, as long as * they have the same key size. Because the second half of the key is only * used to encrypt tweaks and never decrypt, a reduced block cipher * implementation like SpeckTiny that only supports encryption can be * used for the second block cipher: * * \code * XTS xts; * \endcode * * This might save some memory that would otherwise be needed for the * decryption key schedule of the second block cipher. XTSSingleKey provides * another method to save memory. * * References: IEEE Std. 1619-2007, NIST SP 800-38E, a href="http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf">XEX. * * \sa XTSSingleKey, XTSCommon */ /** * \fn XTS::XTS() * \brief Constructs an object for encrypting sectors in XTS mode. * * This constructor should be followed by a call to setSectorSize(). * The default sector size is 512 bytes. */ /** * \fn XTS::~XTS() * \brief Clears all sensitive information and destroys this object. */ /** * \class XTSSingleKey XTS.h * \brief Implementation of the single-key XTS mode for 128-bit block ciphers. * * XTS mode normally uses two keys to encrypt plaintext and the * sector-specific tweak values. This class uses the same key for * both purposes, which can help save memory. * * References: IEEE Std. 1619-2007, NIST SP 800-38E, a href="http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf">XEX. * * \sa XTS, XTSSingleKeyCommon */ /** * \fn XTSSingleKey::XTSSingleKey() * \brief Constructs an object for encrypting sectors in XTS mode * with a single key instead of two split keys. * * This constructor should be followed by a call to setSectorSize(). * The default sector size is 512 bytes. */ /** * \fn XTSSingleKey::~XTSSingleKey() * \brief Clears all sensitive information and destroys this object. */