/************************************************* * OFB Constructor * *************************************************/ OFB::OFB(const std::string& cipher_name, const SymmetricKey& key, const InitializationVector& iv) : BlockCipherMode(cipher_name, "OFB", block_size_of(cipher_name), 2) { set_key(key); set_iv(iv); }
/** \brief Decipher Data * * @param dst_len The destination buffer length. * It MUST be greated than or equal to src_len. * @return the plain text length used in the destination buffer, or -1 if an * error occured (e.g. invalid padding in the resulting plain text) */ ssize_t skey_ciph_t::decipher( const skey_ciph_iv_t & iv, const void *src_ptr , size_t src_len, void *dst_ptr, size_t dst_len ) throw() { // sanity check - the key_data MUST be initialized, so init_key() MUST have been called DBG_ASSERT( !key_datum.is_null() ); // copy the src buffer to the destination DBG_ASSERT( dst_len >= src_len ); memcpy( dst_ptr, src_ptr, src_len ); // set the iv set_iv( iv ); // does the encrypt itself gcry_error_t err; err = gcry_cipher_decrypt(gcry_cipher_hd, (unsigned char *)dst_ptr, src_len, NULL, 0 ); if( err ){ KLOG_ERR("gcry_cipher_decrypt failed due to " << gcry_strerror(err) ); return -1; } // parse the padding ssize_t padding_len = padding_parse( dst_ptr, src_len ); // if the padding is invalid, return -1 if( padding_len == -1 ) return -1; // return the plain text length aka src_len - padding_len return src_len - padding_len; }
/************************************************* * CTR-BE Constructor * *************************************************/ CTR_BE::CTR_BE(const std::string& cipher_name, const SymmetricKey& key, const InitializationVector& iv) : BlockCipherMode(cipher_name, "CTR-BE", block_size_of(cipher_name), 1) { set_key(key); set_iv(iv); }
void OFB::key_schedule(const byte key[], size_t key_len) { m_cipher->set_key(key, key_len); // Set a default all-zeros IV set_iv(nullptr, 0); }
/* * Salsa20 Key Schedule */ void Salsa20::key_schedule(const uint8_t key[], size_t length) { static const uint32_t TAU[] = { 0x61707865, 0x3120646e, 0x79622d36, 0x6b206574 }; static const uint32_t SIGMA[] = { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 }; const uint32_t* CONSTANTS = (length == 16) ? TAU : SIGMA; m_state.resize(16); m_buffer.resize(64); m_state[0] = CONSTANTS[0]; m_state[5] = CONSTANTS[1]; m_state[10] = CONSTANTS[2]; m_state[15] = CONSTANTS[3]; m_state[1] = load_le<uint32_t>(key, 0); m_state[2] = load_le<uint32_t>(key, 1); m_state[3] = load_le<uint32_t>(key, 2); m_state[4] = load_le<uint32_t>(key, 3); if(length == 32) key += 16; m_state[11] = load_le<uint32_t>(key, 0); m_state[12] = load_le<uint32_t>(key, 1); m_state[13] = load_le<uint32_t>(key, 2); m_state[14] = load_le<uint32_t>(key, 3); m_position = 0; set_iv(nullptr, 0); // all-zero IV }
/* * EAX_Decryption Constructor */ EAX_Decryption::EAX_Decryption(BlockCipher* ciph, const SymmetricKey& key, const InitializationVector& iv, size_t tag_size) : EAX_Base(ciph, tag_size) { set_key(key); set_iv(iv); queue.resize(2*TAG_SIZE + DEFAULT_BUFFERSIZE); queue_start = queue_end = 0; }
/* * XTS_Decryption constructor */ XTS_Decryption::XTS_Decryption(BlockCipher* ciph, const SymmetricKey& key, const InitializationVector& iv) { cipher = ciph; cipher2 = ciph->clone(); tweak.create(cipher->BLOCK_SIZE); buffer.create(2 * cipher->BLOCK_SIZE); position = 0; set_key(key); set_iv(iv); }
/*---------------------------------------------------------------------------*/ static void mic(const uint8_t *nonce, const uint8_t *m, uint8_t m_len, const uint8_t *a, uint8_t a_len, uint8_t *result, uint8_t mic_len) { uint8_t x[AES_128_BLOCK_SIZE]; uint8_t pos; uint8_t i; set_iv(x, CCM_STAR_AUTH_FLAGS(a_len, mic_len), nonce, m_len); AES_128.encrypt(x); if(a_len) { x[1] = x[1] ^ a_len; for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) { x[i] ^= a[i - 2]; } AES_128.encrypt(x); pos = 14; while(pos < a_len) { for(i = 0; (pos + i < a_len) && (i < AES_128_BLOCK_SIZE); i++) { x[i] ^= a[pos + i]; } pos += AES_128_BLOCK_SIZE; AES_128.encrypt(x); } } if(m_len) { pos = 0; while(pos < m_len) { for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) { x[i] ^= m[pos + i]; } pos += AES_128_BLOCK_SIZE; AES_128.encrypt(x); } } ctr_step(nonce, 0, x, AES_128_BLOCK_SIZE, 0); memcpy(result, x, mic_len); }
/* XORs the block m[pos] ... m[pos + 15] with K_{counter} */ static void ctr_step(const uint8_t *nonce, uint8_t pos, uint8_t *m_and_result, uint8_t m_len, uint8_t counter) { uint8_t a[AES_128_BLOCK_SIZE]; uint8_t i; set_iv(a, CCM_STAR_ENCRYPTION_FLAGS, nonce, counter); AES_128.encrypt(a); for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) { m_and_result[pos + i] ^= a[i]; } }
/** \brief encipher data * * @param dst_len The destination buffer length. * dst_len MUST be equal to src_len + get_padding_length(src_len) */ void skey_ciph_t::encipher(const skey_ciph_iv_t & iv, const void *src_ptr, size_t src_len , void *dst_ptr, size_t dst_len) throw() { // sanity check - dst_len MUST be equal ::get_ciphertxt_len(src_len) DBG_ASSERT( dst_len == get_ciphertxt_len(src_len) ); // sanity check - the key_data MUST be initialized, so init_key() MUST have been called DBG_ASSERT( !key_datum.is_null() ); // copy the src buffer to the destination DBG_ASSERT( dst_len >= src_len ); // TODO here to do that IIF src_ptr != dst_ptr memcpy( dst_ptr, src_ptr, src_len ); // build the padding padding_build( src_len, dst_ptr ); // set the iv set_iv( iv ); // Now Do encipher the data if( gcry_cipher_encrypt(gcry_cipher_hd, (unsigned char *)dst_ptr, dst_len, NULL, 0) ) DBG_ASSERT( 0 ); }
/* * ChaCha Key Schedule */ void ChaCha::key_schedule(const byte key[], size_t length) { static const u32bit TAU[] = { 0x61707865, 0x3120646e, 0x79622d36, 0x6b206574 }; static const u32bit SIGMA[] = { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 }; const u32bit* CONSTANTS = (length == 16) ? TAU : SIGMA; m_state.resize(16); m_buffer.resize(64); m_state[0] = CONSTANTS[0]; m_state[1] = CONSTANTS[1]; m_state[2] = CONSTANTS[2]; m_state[3] = CONSTANTS[3]; m_state[4] = load_le<u32bit>(key, 0); m_state[5] = load_le<u32bit>(key, 1); m_state[6] = load_le<u32bit>(key, 2); m_state[7] = load_le<u32bit>(key, 3); if(length == 32) key += 16; m_state[8] = load_le<u32bit>(key, 0); m_state[9] = load_le<u32bit>(key, 1); m_state[10] = load_le<u32bit>(key, 2); m_state[11] = load_le<u32bit>(key, 3); m_position = 0; const byte ZERO[8] = { 0 }; set_iv(ZERO, sizeof(ZERO)); }
/* * ChaCha Key Schedule */ void ChaCha::key_schedule(const byte key[], size_t length) { static const u32bit TAU[] = { 0x61707865, 0x3120646e, 0x79622d36, 0x6b206574 }; static const u32bit SIGMA[] = { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 }; const u32bit* CONSTANTS = (length == 16) ? TAU : SIGMA; // Repeat the key if 128 bits const byte* key2 = (length == 32) ? key + 16 : key; m_position = 0; m_state.resize(16); m_buffer.resize(4*64); m_state[0] = CONSTANTS[0]; m_state[1] = CONSTANTS[1]; m_state[2] = CONSTANTS[2]; m_state[3] = CONSTANTS[3]; m_state[4] = load_le<u32bit>(key, 0); m_state[5] = load_le<u32bit>(key, 1); m_state[6] = load_le<u32bit>(key, 2); m_state[7] = load_le<u32bit>(key, 3); m_state[8] = load_le<u32bit>(key2, 0); m_state[9] = load_le<u32bit>(key2, 1); m_state[10] = load_le<u32bit>(key2, 2); m_state[11] = load_le<u32bit>(key2, 3); // Default all-zero IV const byte ZERO[8] = { 0 }; set_iv(ZERO, sizeof(ZERO)); }