text: /*
   * 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 <string.h>
  
  /**
   * \class XTSCommon XTS.h <XTS.h>
   * \brief Concrete base class to assist with implementing XTS mode for
   * 128-bit block ciphers.
   *
   * References: <a href="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE Std. 1619-2007</a>, <a href="http://csrc.nist.gov/publications/nistpubs/800-38E/nist-sp-800-38E.pdf">NIST SP 800-38E</a>, a href="http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf">XEX</a>.
   *
   * \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 <XTS.h>
   * \brief Concrete base class to assist with implementing single-key XTS
   * mode for 128-bit block ciphers.
   *
   * References: <a href="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE Std. 1619-2007</a>, <a href="http://csrc.nist.gov/publications/nistpubs/800-38E/nist-sp-800-38E.pdf">NIST SP 800-38E</a>, a href="http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf">XEX</a>.
   *
   * \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 <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<AES256> 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<SpeckSmall, SpeckTiny> 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: <a href="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE Std. 1619-2007</a>, <a href="http://csrc.nist.gov/publications/nistpubs/800-38E/nist-sp-800-38E.pdf">NIST SP 800-38E</a>, a href="http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf">XEX</a>.
   *
   * \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 <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: <a href="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE Std. 1619-2007</a>, <a href="http://csrc.nist.gov/publications/nistpubs/800-38E/nist-sp-800-38E.pdf">NIST SP 800-38E</a>, a href="http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf">XEX</a>.
   *
   * \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.
   */
  