DECLARE_TEST(blowfish, initialize) { blowfish_t* blowfish; unsigned int i, j; uint32_t left, right; blowfish = blowfish_allocate(); for (i = 0; i < NUM_VARIABLEKEYTESTS; ++i) { blowfish_initialize(blowfish, _test_key_variable[i], 8); left = _test_plaintext_left[i]; right = _test_plaintext_right[i]; _blowfish_encrypt_words(blowfish, &left, &right); EXPECT_EQ(memcmp(&left, &_test_ciphertext_left[i], 4), 0); EXPECT_EQ(memcmp(&right, &_test_ciphertext_right[i], 4), 0); _blowfish_decrypt_words(blowfish, &left, &right); EXPECT_EQ(memcmp(&left, &_test_plaintext_left[i], 4), 0); EXPECT_EQ(memcmp(&right, &_test_plaintext_right[i], 4), 0); } for (j = 1, i = NUM_VARIABLEKEYTESTS; i < (NUM_VARIABLEKEYTESTS + NUM_SETKEYTESTS); ++i) { blowfish_initialize(blowfish, _test_key_set, j++); left = _test_plaintext_left[i]; right = _test_plaintext_right[i]; _blowfish_encrypt_words(blowfish, &left, &right); EXPECT_EQ(memcmp(&left, &_test_ciphertext_left[i], 4), 0); EXPECT_EQ(memcmp(&right, &_test_ciphertext_right[i], 4), 0); _blowfish_decrypt_words(blowfish, &left, &right); EXPECT_EQ(memcmp(&left, &_test_plaintext_left[i], 4), 0); EXPECT_EQ(memcmp(&right, &_test_plaintext_right[i], 4), 0); } blowfish_deallocate(blowfish); return 0; }
void blowfish_decrypt( const blowfish_t* blowfish, void* data, unsigned int length, const blowfish_mode_t mode, const uint64_t vec ) { uint32_t* RESTRICT cur; uint32_t* RESTRICT end; uint32_t chain[2]; uint32_t prev_chain[2]; uint32_t swap_chain[2]; if( length % 8 ) length -= ( length % 8 ); if( !data || !length ) return; /*lint --e{826} */ cur = data; end = pointer_offset( data, length ); chain[0] = (uint32_t)( ( vec >> 32ULL ) & 0xFFFFFFFFU ); chain[1] = (uint32_t)( vec & 0xFFFFFFFFU ); switch( mode ) { case BLOWFISH_ECB: { for( ; cur < end; cur += 2 ) _blowfish_decrypt_words( blowfish, cur, cur + 1 ); break; } case BLOWFISH_CBC: { for( ; cur < end; cur += 2 ) { prev_chain[0] = cur[0]; prev_chain[1] = cur[1]; _blowfish_decrypt_words( blowfish, cur, cur + 1 ); cur[0] ^= chain[0]; cur[1] ^= chain[1]; swap_chain[0] = chain[0]; swap_chain[1] = chain[1]; chain[0] = prev_chain[0]; chain[1] = prev_chain[1]; prev_chain[0] = swap_chain[0]; prev_chain[1] = swap_chain[1]; } break; } case BLOWFISH_CFB: { for( ; cur < end; cur += 2 ) { prev_chain[0] = cur[0]; prev_chain[1] = cur[1]; _blowfish_encrypt_words( blowfish, chain, chain + 1 ); cur[0] ^= chain[0]; cur[1] ^= chain[1]; swap_chain[0] = chain[0]; swap_chain[1] = chain[1]; chain[0] = prev_chain[0]; chain[1] = prev_chain[1]; prev_chain[0] = swap_chain[0]; prev_chain[1] = swap_chain[1]; } break; } case BLOWFISH_OFB: { for( ; cur < end; cur += 2 ) { _blowfish_encrypt_words( blowfish, chain, chain + 1 ); cur[0] ^= chain[0]; cur[1] ^= chain[1]; } break; } default: break; } //Reset memory for paranoids /*lint --e{438} */ chain[0] = 0; chain[1] = 0; prev_chain[0] = 0; prev_chain[1] = 0; swap_chain[0] = 0; swap_chain[1] = 0; }