27
27
#include "php_rand.h"
28
28
#include "php_string.h"
29
29
#include "php_variables.h"
30
+ #include "md5.h"
31
+ #include "xxhash.h"
30
32
#ifdef HAVE_LOCALE_H
31
33
# include <locale.h>
32
34
#endif
@@ -5616,146 +5618,130 @@ PHP_FUNCTION(substr_compare)
5616
5618
}
5617
5619
/* }}} */
5618
5620
5621
+ uint64_t php_siphash (const void * src , unsigned long src_sz , const char key [16 ]);
5619
5622
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
- */
5623
+ /* {{{ proto bool str_compare(string str1, string str2)
5624
+ Timing safe string compare */
5625
+ PHP_FUNCTION (str_siphash_compare )
5626
+ {
5627
+ zval * s1 , * s2 ;
5628
+ char key [16 ] = {0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,0xa ,0xb ,0xc ,0xd ,0xe ,0xf };
5653
5629
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
5630
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "zz" , & s1 , & s2 ) == FAILURE ) {
5631
+ RETURN_FALSE ;
5632
+ }
5667
5633
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
5634
+ if (Z_TYPE_P (s1 ) != IS_STRING || Z_TYPE_P (s2 ) != IS_STRING ) {
5635
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Paremeters must be string" );
5636
+ RETURN_FALSE ;
5637
+ }
5638
+ if (Z_STRLEN_P (s1 ) != Z_STRLEN_P (s2 )) {
5639
+ RETURN_FALSE ;
5640
+ }
5641
+
5680
5642
5681
- #endif
5643
+ RETURN_BOOL (php_siphash (Z_STRVAL_P (s1 ), Z_STRLEN_P (s1 ), key ) == php_siphash (Z_STRVAL_P (s2 ), Z_STRLEN_P (s2 ), key ));
5644
+ }
5645
+ /* }}} */
5682
5646
5683
5647
5684
- #define ROTATE (x , b ) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) )
5648
+ /* {{{ proto bool str_compare(string str1, string str2)
5649
+ Timing safe string compare */
5650
+ PHP_FUNCTION (str_xxhash32_compare )
5651
+ {
5652
+ zval * s1 , * s2 ;
5685
5653
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);
5654
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "zz" , & s1 , & s2 ) == FAILURE ) {
5655
+ RETURN_FALSE ;
5656
+ }
5657
+
5658
+ if (Z_TYPE_P (s1 ) != IS_STRING || Z_TYPE_P (s2 ) != IS_STRING ) {
5659
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Paremeters must be string" );
5660
+ RETURN_FALSE ;
5661
+ }
5662
+ if (Z_STRLEN_P (s1 ) != Z_STRLEN_P (s2 )) {
5663
+ RETURN_FALSE ;
5664
+ }
5665
+
5691
5666
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);
5667
+ RETURN_BOOL (XXH32 (Z_STRVAL_P (s1 ), Z_STRLEN_P (s1 ), 12345 ) == XXH32 (Z_STRVAL_P (s2 ), Z_STRLEN_P (s2 ), 12345 ));
5668
+ }
5669
+ /* }}} */
5697
5670
5698
5671
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
5672
5706
- uint64_t v0 = k0 ^ 0x736f6d6570736575ULL ;
5707
- uint64_t v1 = k1 ^ 0x646f72616e646f6dULL ;
5708
- uint64_t v2 = k0 ^ 0x6c7967656e657261ULL ;
5709
- uint64_t v3 = k1 ^ 0x7465646279746573ULL ;
5673
+ /* {{{ proto bool str_compare(string str1, string str2)
5674
+ string compare */
5675
+ PHP_FUNCTION (str_md5_compare )
5676
+ {
5677
+ zval * s1 , * s2 ;
5678
+ PHP_MD5_CTX context ;
5679
+ unsigned char d1 [16 ], d2 [16 ];
5710
5680
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 ;
5681
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "zz" , & s1 , & s2 ) == FAILURE ) {
5682
+ RETURN_FALSE ;
5717
5683
}
5718
5684
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 ];
5685
+ if (Z_TYPE_P (s1 ) != IS_STRING || Z_TYPE_P (s2 ) != IS_STRING ) {
5686
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Paremeters must be string" );
5687
+ RETURN_FALSE ;
5728
5688
}
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 );
5689
+ if (Z_STRLEN_P (s1 ) != Z_STRLEN_P (s2 )) {
5690
+ RETURN_FALSE ;
5691
+ }
5692
+
5693
+ PHP_MD5Init (& context );
5694
+ PHP_MD5Update (& context , Z_STRVAL_P (s1 ), Z_STRLEN_P (s1 ));
5695
+ PHP_MD5Final (d1 , & context );
5696
+ PHP_MD5Init (& context );
5697
+ PHP_MD5Update (& context , Z_STRVAL_P (s2 ), Z_STRLEN_P (s2 ));
5698
+ PHP_MD5Final (d2 , & context );
5699
+
5700
+ RETURN_BOOL (memcmp (d1 , d2 , 16 ) == 0 );
5737
5701
}
5738
- /* END SipHash */
5702
+ /* }}} */
5739
5703
5740
5704
/* Timing safe compare */
5741
- PHPAPI int php_compare (const void * b1 , const void * b2 , size_t n ) /* {{{ */
5705
+ PHPAPI int php_byte_compare (const void * b1 , const void * b2 , size_t n ) /* {{{ */
5742
5706
{
5743
5707
const unsigned char * p1 = b1 , * p2 = b2 ;
5744
5708
int ret = 0 ;
5745
5709
5746
5710
for (; n > 0 ; n -- ) {
5747
5711
ret |= * p1 ++ ^ * p2 ++ ;
5748
5712
}
5749
- return (ret ! = 0 );
5713
+ return (ret = = 0 );
5750
5714
}
5751
5715
/* }}} */
5752
5716
5753
5717
/* {{{ proto bool str_compare(string str1, string str2)
5754
5718
Timing safe string compare */
5719
+ PHP_FUNCTION (str_byte_compare )
5720
+ {
5721
+ zval * s1 , * s2 ;
5722
+
5723
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "zz" , & s1 , & s2 ) == FAILURE ) {
5724
+ RETURN_FALSE ;
5725
+ }
5726
+
5727
+ if (Z_TYPE_P (s1 ) != IS_STRING || Z_TYPE_P (s2 ) != IS_STRING ) {
5728
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Paremeters must be string" );
5729
+ RETURN_FALSE ;
5730
+ }
5731
+ if (Z_STRLEN_P (s1 ) != Z_STRLEN_P (s2 )) {
5732
+ RETURN_FALSE ;
5733
+ }
5734
+
5735
+
5736
+ RETURN_BOOL (php_byte_compare (Z_STRVAL_P (s1 ), Z_STRVAL_P (s2 ), Z_STRLEN_P (s2 )));
5737
+ }
5738
+ /* }}} */
5739
+
5740
+ /* {{{ proto bool str_compare(string str1, string str2)
5741
+ strncmp string compare */
5755
5742
PHP_FUNCTION (str_compare )
5756
5743
{
5757
5744
zval * s1 , * s2 ;
5758
- char key [16 ] = {0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,0xa ,0xb ,0xc ,0xd ,0xe ,0xf };
5759
5745
5760
5746
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "zz" , & s1 , & s2 ) == FAILURE ) {
5761
5747
RETURN_FALSE ;
@@ -5770,10 +5756,11 @@ PHP_FUNCTION(str_compare)
5770
5756
}
5771
5757
5772
5758
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 ) );
5759
+ RETURN_BOOL (strncmp (Z_STRVAL_P (s1 ), Z_STRVAL_P (s2 ), Z_STRLEN_P (s2 )) == 0 );
5774
5760
}
5775
5761
/* }}} */
5776
5762
5763
+
5777
5764
/*
5778
5765
* Local variables:
5779
5766
* tab-width: 4
0 commit comments