/* * CMAC Key Schedule */ void CMAC::key_schedule(const byte key[], size_t length) { clear(); m_cipher->set_key(key, length); m_cipher->encrypt(m_B); m_B = poly_double(m_B); m_P = poly_double(m_B); }
/* * Finish encrypting in XTS mode */ void XTS_Encryption::end_msg() { const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; if(position < BLOCK_SIZE) throw Exception("XTS_Encryption: insufficient data to encrypt"); else if(position == BLOCK_SIZE) { encrypt(buffer); } else if(position == 2*BLOCK_SIZE) { encrypt(buffer); encrypt(buffer + BLOCK_SIZE); } else { // steal ciphertext xor_buf(buffer, tweak, cipher->BLOCK_SIZE); cipher->encrypt(buffer); xor_buf(buffer, tweak, cipher->BLOCK_SIZE); poly_double(tweak, cipher->BLOCK_SIZE); for(u32bit i = 0; i != position - cipher->BLOCK_SIZE; ++i) std::swap(buffer[i], buffer[i + cipher->BLOCK_SIZE]); xor_buf(buffer, tweak, cipher->BLOCK_SIZE); cipher->encrypt(buffer); xor_buf(buffer, tweak, cipher->BLOCK_SIZE); send(buffer, position); } position = 0; }
/* * Decrypt a block */ void XTS_Decryption::decrypt(const byte block[]) { xor_buf(buffer, block, tweak, cipher->BLOCK_SIZE); cipher->decrypt(buffer); xor_buf(buffer, tweak, cipher->BLOCK_SIZE); poly_double(tweak, cipher->BLOCK_SIZE); send(buffer, cipher->BLOCK_SIZE); }
void XTS_Encryption::encrypt(const byte block[]) { /* * We can always use the first 16 bytes of buffer as temp space, * since either the input block is buffer (in which case this is * just buffer ^= tweak) or it not, in which case we already read * and used the data there and are processing new input. Kind of * subtle/nasty, but saves allocating a distinct temp buf. */ xor_buf(buffer, block, tweak, cipher->BLOCK_SIZE); cipher->encrypt(buffer); xor_buf(buffer, tweak, cipher->BLOCK_SIZE); poly_double(tweak, cipher->BLOCK_SIZE); send(buffer, cipher->BLOCK_SIZE); }
/* * Finish decrypting in XTS mode */ void XTS_Decryption::end_msg() { const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; if(position < BLOCK_SIZE) throw Exception("XTS_Decryption: insufficient data to decrypt"); else if(position == BLOCK_SIZE) { decrypt(buffer); } else if(position == 2*BLOCK_SIZE) { decrypt(buffer); decrypt(buffer + BLOCK_SIZE); } else { SecureVector<byte> tweak2 = tweak; poly_double(tweak2, cipher->BLOCK_SIZE); xor_buf(buffer, tweak2, cipher->BLOCK_SIZE); cipher->decrypt(buffer); xor_buf(buffer, tweak2, cipher->BLOCK_SIZE); for(u32bit i = 0; i != position - cipher->BLOCK_SIZE; ++i) std::swap(buffer[i], buffer[i + cipher->BLOCK_SIZE]); xor_buf(buffer, tweak, cipher->BLOCK_SIZE); cipher->decrypt(buffer); xor_buf(buffer, tweak, cipher->BLOCK_SIZE); send(buffer, position); } position = 0; }