@@ -5616,6 +5616,164 @@ PHP_FUNCTION(substr_compare)
5616
5616
}
5617
5617
/* }}} */
5618
5618
5619
+
5620
+ /* XXX: Just embed here for the time being
5621
+ https://github.com/majek/csiphash/blob/master/csiphash.c
5622
+ */
5623
+ /* <MIT License>
5624
+ Copyright (c) 2013 Marek Majkowski <[email protected] >
5625
+
5626
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5627
+ of this software and associated documentation files (the "Software"), to deal
5628
+ in the Software without restriction, including without limitation the rights
5629
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5630
+ copies of the Software, and to permit persons to whom the Software is
5631
+ furnished to do so, subject to the following conditions:
5632
+
5633
+ The above copyright notice and this permission notice shall be included in
5634
+ all copies or substantial portions of the Software.
5635
+
5636
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5637
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5638
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5639
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5640
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5641
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5642
+ THE SOFTWARE.
5643
+ </MIT License>
5644
+
5645
+ Original location:
5646
+ https://github.com/majek/csiphash/
5647
+
5648
+ Solution inspired by code from:
5649
+ Samuel Neves (supercop/crypto_auth/siphash24/little)
5650
+ djb (supercop/crypto_auth/siphash24/little2)
5651
+ Jean-Philippe Aumasson (https://131002.net/siphash/siphash24.c)
5652
+ */
5653
+
5654
+ /* #include <stdint.h> */
5655
+
5656
+ #if defined(__BYTE_ORDER__ ) && defined(__ORDER_LITTLE_ENDIAN__ ) && \
5657
+ __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
5658
+ # define _le64toh (x ) ((uint64_t)(x))
5659
+ #elif defined(_WIN32 )
5660
+ /* Windows is always little endian, unless you're on xbox360
5661
+ http://msdn.microsoft.com/en-us/library/b0084kay(v=vs.80).aspx */
5662
+ # define _le64toh (x ) ((uint64_t)(x))
5663
+ #elif defined(__APPLE__ )
5664
+ # include <libkern/OSByteOrder.h>
5665
+ # define _le64toh (x ) OSSwapLittleToHostInt64(x)
5666
+ #else
5667
+
5668
+ /* See: http://sourceforge.net/p/predef/wiki/Endianness/ */
5669
+ # if defined(__FreeBSD__ ) || defined(__NetBSD__ ) || defined(__OpenBSD__ )
5670
+ # include <sys/endian.h>
5671
+ # else
5672
+ # include <endian.h>
5673
+ # endif
5674
+ # if defined(__BYTE_ORDER ) && defined(__LITTLE_ENDIAN ) && \
5675
+ __BYTE_ORDER == __LITTLE_ENDIAN
5676
+ # define _le64toh (x ) ((uint64_t)(x))
5677
+ # else
5678
+ # define _le64toh (x ) le64toh(x)
5679
+ # endif
5680
+
5681
+ #endif
5682
+
5683
+
5684
+ #define ROTATE (x , b ) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) )
5685
+
5686
+ #define HALF_ROUND (a ,b ,c ,d ,s ,t ) \
5687
+ a += b; c += d; \
5688
+ b = ROTATE(b, s) ^ a; \
5689
+ d = ROTATE(d, t) ^ c; \
5690
+ a = ROTATE(a, 32);
5691
+
5692
+ #define DOUBLE_ROUND (v0 ,v1 ,v2 ,v3 ) \
5693
+ HALF_ROUND(v0,v1,v2,v3,13,16); \
5694
+ HALF_ROUND(v2,v1,v0,v3,17,21); \
5695
+ HALF_ROUND(v0,v1,v2,v3,13,16); \
5696
+ HALF_ROUND(v2,v1,v0,v3,17,21);
5697
+
5698
+
5699
+ static uint64_t php_siphash (const void * src , unsigned long src_sz , const char key [16 ]) {
5700
+ const uint64_t * _key = (uint64_t * )key ;
5701
+ uint64_t k0 = _le64toh (_key [0 ]);
5702
+ uint64_t k1 = _le64toh (_key [1 ]);
5703
+ uint64_t b = (uint64_t )src_sz << 56 ;
5704
+ const uint64_t * in = (uint64_t * )src ;
5705
+
5706
+ uint64_t v0 = k0 ^ 0x736f6d6570736575ULL ;
5707
+ uint64_t v1 = k1 ^ 0x646f72616e646f6dULL ;
5708
+ uint64_t v2 = k0 ^ 0x6c7967656e657261ULL ;
5709
+ uint64_t v3 = k1 ^ 0x7465646279746573ULL ;
5710
+
5711
+ while (src_sz >= 8 ) {
5712
+ uint64_t mi = _le64toh (* in );
5713
+ in += 1 ; src_sz -= 8 ;
5714
+ v3 ^= mi ;
5715
+ DOUBLE_ROUND (v0 ,v1 ,v2 ,v3 );
5716
+ v0 ^= mi ;
5717
+ }
5718
+
5719
+ uint64_t t = 0 ; uint8_t * pt = (uint8_t * )& t ; uint8_t * m = (uint8_t * )in ;
5720
+ switch (src_sz ) {
5721
+ case 7 : pt [6 ] = m [6 ];
5722
+ case 6 : pt [5 ] = m [5 ];
5723
+ case 5 : pt [4 ] = m [4 ];
5724
+ case 4 : * ((uint32_t * )& pt [0 ]) = * ((uint32_t * )& m [0 ]); break ;
5725
+ case 3 : pt [2 ] = m [2 ];
5726
+ case 2 : pt [1 ] = m [1 ];
5727
+ case 1 : pt [0 ] = m [0 ];
5728
+ }
5729
+ b |= _le64toh (t );
5730
+
5731
+ v3 ^= b ;
5732
+ DOUBLE_ROUND (v0 ,v1 ,v2 ,v3 );
5733
+ v0 ^= b ; v2 ^= 0xff ;
5734
+ DOUBLE_ROUND (v0 ,v1 ,v2 ,v3 );
5735
+ DOUBLE_ROUND (v0 ,v1 ,v2 ,v3 );
5736
+ return (v0 ^ v1 ) ^ (v2 ^ v3 );
5737
+ }
5738
+ /* END SipHash */
5739
+
5740
+ /* Timing safe compare */
5741
+ PHPAPI int php_compare (const void * b1 , const void * b2 , size_t n ) /* {{{ */
5742
+ {
5743
+ const unsigned char * p1 = b1 , * p2 = b2 ;
5744
+ int ret = 0 ;
5745
+
5746
+ for (; n > 0 ; n -- ) {
5747
+ ret |= * p1 ++ ^ * p2 ++ ;
5748
+ }
5749
+ return (ret != 0 );
5750
+ }
5751
+ /* }}} */
5752
+
5753
+ /* {{{ proto bool str_compare(string str1, string str2)
5754
+ Timing safe string compare */
5755
+ PHP_FUNCTION (str_compare )
5756
+ {
5757
+ zval * s1 , * s2 ;
5758
+ char key [16 ] = {0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,0xa ,0xb ,0xc ,0xd ,0xe ,0xf };
5759
+
5760
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "zz" , & s1 , & s2 ) == FAILURE ) {
5761
+ RETURN_FALSE ;
5762
+ }
5763
+
5764
+ if (Z_TYPE_P (s1 ) != IS_STRING || Z_TYPE_P (s2 ) != IS_STRING ) {
5765
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Paremeters must be string" );
5766
+ RETURN_FALSE ;
5767
+ }
5768
+ if (Z_STRLEN_P (s1 ) != Z_STRLEN_P (s2 )) {
5769
+ RETURN_FALSE ;
5770
+ }
5771
+
5772
+
5773
+ RETURN_BOOL (php_siphash (Z_STRVAL_P (s1 ), Z_STRLEN_P (s1 ), key ) == php_siphash (Z_STRVAL_P (s2 ), Z_STRLEN_P (s2 ), key ));
5774
+ }
5775
+ /* }}} */
5776
+
5619
5777
/*
5620
5778
* Local variables:
5621
5779
* tab-width: 4
0 commit comments