@@ -335,6 +335,13 @@ PHP_MINIT_FUNCTION(sodium)
335335 crypto_stream_NONCEBYTES , CONST_CS | CONST_PERSISTENT );
336336 REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_STREAM_KEYBYTES" ,
337337 crypto_stream_KEYBYTES , CONST_CS | CONST_PERSISTENT );
338+
339+ #ifdef crypto_stream_xchacha20_KEYBYTES
340+ REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES" ,
341+ crypto_stream_xchacha20_NONCEBYTES , CONST_CS | CONST_PERSISTENT );
342+ REGISTER_LONG_CONSTANT ("SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES" ,
343+ crypto_stream_xchacha20_KEYBYTES , CONST_CS | CONST_PERSISTENT );
344+ #endif
338345#ifdef sodium_base64_VARIANT_ORIGINAL
339346 REGISTER_LONG_CONSTANT ("SODIUM_BASE64_VARIANT_ORIGINAL" ,
340347 sodium_base64_VARIANT_ORIGINAL , CONST_CS | CONST_PERSISTENT );
@@ -1465,6 +1472,83 @@ PHP_FUNCTION(sodium_crypto_stream_xor)
14651472 RETURN_NEW_STR (ciphertext );
14661473}
14671474
1475+ #ifdef crypto_stream_xchacha20_KEYBYTES
1476+ PHP_FUNCTION (sodium_crypto_stream_xchacha20 )
1477+ {
1478+ zend_string * ciphertext ;
1479+ unsigned char * key ;
1480+ unsigned char * nonce ;
1481+ zend_long ciphertext_len ;
1482+ size_t key_len ;
1483+ size_t nonce_len ;
1484+
1485+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "lss" ,
1486+ & ciphertext_len ,
1487+ & nonce , & nonce_len ,
1488+ & key , & key_len ) == FAILURE ) {
1489+ return ;
1490+ }
1491+ if (ciphertext_len <= 0 || ciphertext_len >= SIZE_MAX ) {
1492+ zend_throw_exception (sodium_exception_ce , "ciphertext length must be greater than 0" , 0 );
1493+ return ;
1494+ }
1495+ if (nonce_len != crypto_stream_xchacha20_NONCEBYTES ) {
1496+ zend_throw_exception (sodium_exception_ce , "nonce should be SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES bytes" , 0 );
1497+ return ;
1498+ }
1499+ if (key_len != crypto_stream_xchacha20_KEYBYTES ) {
1500+ zend_throw_exception (sodium_exception_ce , "key should be SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES bytes" , 0 );
1501+ return ;
1502+ }
1503+ ciphertext = zend_string_checked_alloc ((size_t ) ciphertext_len , 0 );
1504+ if (crypto_stream_xchacha20 ((unsigned char * ) ZSTR_VAL (ciphertext ),
1505+ (unsigned long long ) ciphertext_len , nonce , key ) != 0 ) {
1506+ zend_string_free (ciphertext );
1507+ zend_throw_exception (sodium_exception_ce , "internal error" , 0 );
1508+ return ;
1509+ }
1510+
1511+ RETURN_STR (ciphertext );
1512+ }
1513+
1514+ PHP_FUNCTION (sodium_crypto_stream_xchacha20_xor )
1515+ {
1516+ zend_string * ciphertext ;
1517+ unsigned char * key ;
1518+ unsigned char * msg ;
1519+ unsigned char * nonce ;
1520+ size_t ciphertext_len ;
1521+ size_t key_len ;
1522+ size_t msg_len ;
1523+ size_t nonce_len ;
1524+
1525+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "sss" ,
1526+ & msg , & msg_len ,
1527+ & nonce , & nonce_len ,
1528+ & key , & key_len ) == FAILURE ) {
1529+ return ;
1530+ }
1531+ if (nonce_len != crypto_stream_xchacha20_NONCEBYTES ) {
1532+ zend_throw_exception (sodium_exception_ce , "nonce should be SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES bytes" , 0 );
1533+ return ;
1534+ }
1535+ if (key_len != crypto_stream_xchacha20_KEYBYTES ) {
1536+ zend_throw_exception (sodium_exception_ce , "key should be SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES bytes" , 0 );
1537+ return ;
1538+ }
1539+ ciphertext_len = msg_len ;
1540+ ciphertext = zend_string_checked_alloc ((size_t ) ciphertext_len , 0 );
1541+ if (crypto_stream_xchacha20_xor ((unsigned char * ) ZSTR_VAL (ciphertext ), msg ,
1542+ (unsigned long long ) msg_len , nonce , key ) != 0 ) {
1543+ zend_string_free (ciphertext );
1544+ zend_throw_exception (sodium_exception_ce , "internal error" , 0 );
1545+ return ;
1546+ }
1547+
1548+ RETURN_STR (ciphertext );
1549+ }
1550+ #endif
1551+
14681552#ifdef crypto_pwhash_SALTBYTES
14691553PHP_FUNCTION (sodium_crypto_pwhash )
14701554{
@@ -2894,6 +2978,18 @@ PHP_FUNCTION(sodium_crypto_stream_keygen)
28942978 randombytes_buf (key , sizeof key );
28952979 RETURN_STRINGL ((const char * ) key , sizeof key );
28962980}
2981+ #ifdef crypto_stream_xchacha20_KEYBYTES
2982+ PHP_FUNCTION (sodium_crypto_stream_xchacha20_keygen )
2983+ {
2984+ unsigned char key [crypto_stream_xchacha20_KEYBYTES ];
2985+
2986+ if (zend_parse_parameters_none () == FAILURE ) {
2987+ return ;
2988+ }
2989+ randombytes_buf (key , sizeof key );
2990+ RETURN_STRINGL ((const char * ) key , sizeof key );
2991+ }
2992+ #endif
28972993
28982994PHP_FUNCTION (sodium_crypto_kdf_derive_from_key )
28992995{
0 commit comments