From ea19f1e501e8eaefee55453f2f9deb2602b5284d Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Tue, 10 Apr 2012 08:21:35 -0500 Subject: [PATCH] masking utility functions and unit tests --- src/processors/hybi_util.cpp | 64 +++++++++++++++++++++++ src/processors/hybi_util.hpp | 70 ++++++++++++++++++++++++++ test/basic/hybi_util.cpp | 98 ++++++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+) create mode 100644 src/processors/hybi_util.cpp create mode 100644 src/processors/hybi_util.hpp create mode 100644 test/basic/hybi_util.cpp diff --git a/src/processors/hybi_util.cpp b/src/processors/hybi_util.cpp new file mode 100644 index 0000000000..435fb597be --- /dev/null +++ b/src/processors/hybi_util.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011, Peter Thorson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the WebSocket++ Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "hybi_util.hpp" + +namespace websocketpp { +namespace processor { +namespace hybi_util { + +size_t prepare_masking_key(const masking_key_type& key) { + size_t prepared_key = key.i; + if (sizeof(size_t) == 8) { + prepared_key <<= 32; + prepared_key |= (static_cast(key.i) & 0x00000000FFFFFFFFLL); + } + return prepared_key; +} + +size_t circshift_prepared_key(size_t prepared_key, size_t offset) { + size_t temp = prepared_key << (sizeof(size_t)-offset)*8; + return (prepared_key >> offset*8) | temp; +} + +void word_mask_exact(char* data,size_t length,const masking_key_type& key) { + size_t prepared_key = prepare_masking_key(key); + size_t n = length/sizeof(size_t); + size_t* word_data = reinterpret_cast(data); + + for (size_t i = 0; i < n; i++) { + word_data[i] ^= prepared_key; + } + + for (size_t i = n*sizeof(size_t); i < length; i++) { + data[i] ^= key.c[i%4]; + } +} + +} // namespace hybi_util +} // namespace processor +} // namespace websocketpp \ No newline at end of file diff --git a/src/processors/hybi_util.hpp b/src/processors/hybi_util.hpp new file mode 100644 index 0000000000..5f8c2cf4ea --- /dev/null +++ b/src/processors/hybi_util.hpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011, Peter Thorson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the WebSocket++ Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef WEBSOCKET_HYBI_UTIL_HPP +#define WEBSOCKET_HYBI_UTIL_HPP + +#include "../common.hpp" + +namespace websocketpp { +namespace processor { +namespace hybi_util { + +// type used to store a masking key +union masking_key_type { + int32_t i; + char c[4]; +}; + +// extract a masking key into a value the size of a machine word. Machine word +// size must be 4 or 8 +size_t prepare_masking_key(const masking_key_type& key); + +// circularly shifts the supplied prepared masking key by offset bytes +// prepared_key must be the output of prepare_masking_key with the associated +// restrictions on the machine word size. +// offset must be 0, 1, 2, or 3 +size_t circshift_prepared_key(size_t prepared_key, size_t offset); + +// basic byte by byte mask +template +void byte_mask(iter_type b, iter_type e, const masking_key_type& key, size_t key_offset = 0) { + size_t key_index = key_offset; + for (iter_type i = b; i != e; i++) { + *i ^= key.c[key_index++]; + key_index %= 4; + } +} + +// exactly masks the bytes from start to end using key `key` +void word_mask_exact(char* data,size_t length,const masking_key_type& key); + +} // namespace hybi_util +} // namespace processor +} // namespace websocketpp + +#endif // WEBSOCKET_HYBI_UTIL_HPP diff --git a/test/basic/hybi_util.cpp b/test/basic/hybi_util.cpp new file mode 100644 index 0000000000..2e89320744 --- /dev/null +++ b/test/basic/hybi_util.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011, Peter Thorson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the WebSocket++ Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +//#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE hybi_util +#include + +#include + +#include "../../src/processors/hybi_util.hpp" +#include "../../src/network_utilities.hpp" + +BOOST_AUTO_TEST_CASE( circshift_0 ) { + if (sizeof(size_t) == 8) { + size_t test = 0x0123456789abcdef; + + test = websocketpp::processor::hybi_util::circshift_prepared_key(test,0); + + BOOST_CHECK( test == 0x0123456789abcdef); + } else { + size_t test = 0x01234567; + + test = websocketpp::processor::hybi_util::circshift_prepared_key(test,0); + + BOOST_CHECK( test == 0x01234567); + } +} + +BOOST_AUTO_TEST_CASE( circshift_1 ) { + if (sizeof(size_t) == 8) { + size_t test = 0x0123456789abcdef; + + test = websocketpp::processor::hybi_util::circshift_prepared_key(test,1); + + BOOST_CHECK( test == 0xef0123456789abcd); + } else { + size_t test = 0x01234567; + + test = websocketpp::processor::hybi_util::circshift_prepared_key(test,1); + + BOOST_CHECK( test == 0x67012345); + } +} + +BOOST_AUTO_TEST_CASE( circshift_2 ) { + if (sizeof(size_t) == 8) { + size_t test = 0x0123456789abcdef; + + test = websocketpp::processor::hybi_util::circshift_prepared_key(test,2); + + BOOST_CHECK( test == 0xcdef0123456789ab); + } else { + size_t test = 0x01234567; + + test = websocketpp::processor::hybi_util::circshift_prepared_key(test,2); + + BOOST_CHECK( test == 0x45670123); + } +} + +BOOST_AUTO_TEST_CASE( circshift_3 ) { + if (sizeof(size_t) == 8) { + size_t test = 0x0123456789abcdef; + + test = websocketpp::processor::hybi_util::circshift_prepared_key(test,3); + + BOOST_CHECK( test == 0xabcdef0123456789); + } else { + size_t test = 0x01234567; + + test = websocketpp::processor::hybi_util::circshift_prepared_key(test,3); + + BOOST_CHECK( test == 0x23456701); + } +}