mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
add byte_mask_circ
This commit is contained in:
@@ -410,6 +410,43 @@ BOOST_AUTO_TEST_CASE( continuous_word_mask ) {
|
||||
BOOST_CHECK_EQUAL( pkey_temp, frame::circshift_prepared_key(pkey,3) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( continuous_byte_mask ) {
|
||||
uint8_t input[16];
|
||||
uint8_t output[16];
|
||||
|
||||
uint8_t masked[16] = {0x00, 0x01, 0x02, 0x03,
|
||||
0x00, 0x01, 0x02, 0x03,
|
||||
0x00, 0x01, 0x02, 0x03,
|
||||
0x00, 0x01, 0x02, 0x00};
|
||||
|
||||
frame::masking_key_type key;
|
||||
key.c[0] = 0x00;
|
||||
key.c[1] = 0x01;
|
||||
key.c[2] = 0x02;
|
||||
key.c[3] = 0x03;
|
||||
|
||||
// One call
|
||||
size_t pkey,pkey_temp;
|
||||
pkey = frame::prepare_masking_key(key);
|
||||
std::fill_n(input,16,0x00);
|
||||
std::fill_n(output,16,0x00);
|
||||
frame::byte_mask_circ(input,output,15,pkey);
|
||||
BOOST_CHECK( std::equal(output,output+16,masked) );
|
||||
|
||||
// calls not split on word boundaries
|
||||
pkey = frame::prepare_masking_key(key);
|
||||
std::fill_n(input,16,0x00);
|
||||
std::fill_n(output,16,0x00);
|
||||
|
||||
pkey_temp = frame::byte_mask_circ(input,output,7,pkey);
|
||||
BOOST_CHECK( std::equal(output,output+7,masked) );
|
||||
BOOST_CHECK( pkey_temp == frame::circshift_prepared_key(pkey,3) );
|
||||
|
||||
pkey_temp = frame::byte_mask_circ(input+7,output+7,8,pkey_temp);
|
||||
BOOST_CHECK( std::equal(output,output+16,masked) );
|
||||
BOOST_CHECK_EQUAL( pkey_temp, frame::circshift_prepared_key(pkey,3) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( continuous_word_mask_inplace ) {
|
||||
uint8_t buffer[16];
|
||||
|
||||
@@ -444,6 +481,40 @@ BOOST_AUTO_TEST_CASE( continuous_word_mask_inplace ) {
|
||||
BOOST_CHECK_EQUAL( pkey_temp, frame::circshift_prepared_key(pkey,3) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( continuous_byte_mask_inplace ) {
|
||||
uint8_t buffer[16];
|
||||
|
||||
uint8_t masked[16] = {0x00, 0x01, 0x02, 0x03,
|
||||
0x00, 0x01, 0x02, 0x03,
|
||||
0x00, 0x01, 0x02, 0x03,
|
||||
0x00, 0x01, 0x02, 0x00};
|
||||
|
||||
frame::masking_key_type key;
|
||||
key.c[0] = 0x00;
|
||||
key.c[1] = 0x01;
|
||||
key.c[2] = 0x02;
|
||||
key.c[3] = 0x03;
|
||||
|
||||
// One call
|
||||
size_t pkey,pkey_temp;
|
||||
pkey = frame::prepare_masking_key(key);
|
||||
std::fill_n(buffer,16,0x00);
|
||||
frame::byte_mask_circ(buffer,15,pkey);
|
||||
BOOST_CHECK( std::equal(buffer,buffer+16,masked) );
|
||||
|
||||
// calls not split on word boundaries
|
||||
pkey = frame::prepare_masking_key(key);
|
||||
std::fill_n(buffer,16,0x00);
|
||||
|
||||
pkey_temp = frame::byte_mask_circ(buffer,7,pkey);
|
||||
BOOST_CHECK( std::equal(buffer,buffer+7,masked) );
|
||||
BOOST_CHECK_EQUAL( pkey_temp, frame::circshift_prepared_key(pkey,3) );
|
||||
|
||||
pkey_temp = frame::byte_mask_circ(buffer+7,8,pkey_temp);
|
||||
BOOST_CHECK( std::equal(buffer,buffer+16,masked) );
|
||||
BOOST_CHECK_EQUAL( pkey_temp, frame::circshift_prepared_key(pkey,3) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( continuous_word_mask2 ) {
|
||||
uint8_t buffer[12] = {0xA6, 0x15, 0x97, 0xB9,
|
||||
0x81, 0x50, 0xAC, 0xBA,
|
||||
|
||||
@@ -831,6 +831,58 @@ inline size_t word_mask_circ(uint8_t* data, size_t length, size_t prepared_key){
|
||||
return word_mask_circ(data,data,length,prepared_key);
|
||||
}
|
||||
|
||||
/// Circular byte aligned mask/unmask
|
||||
/**
|
||||
* Performs a circular mask/unmask in byte sized chunks using pre-prepared keys
|
||||
* that store state between calls. Best for providing streaming masking or
|
||||
* unmasking of small chunks at a time of a larger message. Requires that the
|
||||
* underlying allocated size of the data buffer be a multiple of the word size.
|
||||
* Data in the buffer after `length` will be overwritten only with the same
|
||||
* values that were originally present.
|
||||
*
|
||||
* word_mask returns a copy of prepared_key circularly shifted based on the
|
||||
* length value. The returned value may be fed back into byte_mask when more
|
||||
* data is available.
|
||||
*
|
||||
* @param data Character buffer to mask
|
||||
*
|
||||
* @param length Length of data
|
||||
*
|
||||
* @param prepared_key Prepared key to use.
|
||||
*
|
||||
* @return the prepared_key shifted to account for the input length
|
||||
*/
|
||||
inline size_t byte_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
size_t prepared_key)
|
||||
{
|
||||
uint32_converter key;
|
||||
key.i = prepared_key;
|
||||
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
output[i] = input[i] ^ key.c[i % 4];
|
||||
}
|
||||
|
||||
return circshift_prepared_key(prepared_key,length % 4);
|
||||
}
|
||||
|
||||
/// Circular byte aligned mask/unmask (in place)
|
||||
/**
|
||||
* In place version of byte_mask_circ
|
||||
*
|
||||
* @see byte_mask_circ
|
||||
*
|
||||
* @param data Character buffer to read from and write to
|
||||
*
|
||||
* @param length Length of data
|
||||
*
|
||||
* @param prepared_key Prepared key to use.
|
||||
*
|
||||
* @return the prepared_key shifted to account for the input length
|
||||
*/
|
||||
inline size_t byte_mask_circ(uint8_t* data, size_t length, size_t prepared_key){
|
||||
return byte_mask_circ(data,data,length,prepared_key);
|
||||
}
|
||||
|
||||
} // namespace frame
|
||||
} // namespace websocketpp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user