1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

ext/sodium: Add support for libsodium 1.0.21 APIs (#20960)

Add support for new functions present in recent libsodium versions:

- Functions for IP address encryption:
  - sodium_crypto_ipcrypt_*
  - sodium_bin2ip/sodium_ip2bin helpers

- Extendable output functions:
  - SHAKE128/SHAKE256
  - TurboSHAKE128/TurboSHAKE256
This commit is contained in:
Frank Denis
2026-02-27 13:11:24 +01:00
committed by GitHub
parent f46bc8e3a7
commit 8a907a9bd8
11 changed files with 1874 additions and 1 deletions

3
NEWS
View File

@@ -104,6 +104,9 @@ PHP NEWS
. Fixed GH-20532 (socket_addrinfo_lookup gives the error code with a new . Fixed GH-20532 (socket_addrinfo_lookup gives the error code with a new
optional parameter). (David Carlier) optional parameter). (David Carlier)
- Sodium:
. Added support for libsodium 1.0.21 IPcrypt and XOF APIs. (jedisct1)
- SPL: - SPL:
. DirectoryIterator key can now work better with filesystem supporting larger . DirectoryIterator key can now work better with filesystem supporting larger
directory indexing. (David Carlier) directory indexing. (David Carlier)

View File

@@ -3913,3 +3913,917 @@ PHP_FUNCTION(sodium_crypto_core_ristretto255_sub)
RETURN_NEW_STR(r); RETURN_NEW_STR(r);
} }
#endif #endif
#ifdef crypto_ipcrypt_KEYBYTES
PHP_FUNCTION(sodium_crypto_ipcrypt_keygen)
{
unsigned char key[crypto_ipcrypt_KEYBYTES];
if (zend_parse_parameters_none() == FAILURE) {
RETURN_THROWS();
}
crypto_ipcrypt_keygen(key);
RETURN_STRINGL((const char *) key, sizeof key);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_encrypt)
{
char *ip;
size_t ip_len;
unsigned char *key;
size_t key_len;
unsigned char bin[crypto_ipcrypt_BYTES];
unsigned char encrypted[crypto_ipcrypt_BYTES];
char ip_out[46];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
&ip, &ip_len, &key, &key_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (key_len != crypto_ipcrypt_KEYBYTES) {
zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_KEYBYTES bytes long");
RETURN_THROWS();
}
if (sodium_ip2bin(bin, ip, ip_len) != 0) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address");
RETURN_THROWS();
}
crypto_ipcrypt_encrypt(encrypted, bin, key);
if (sodium_bin2ip(ip_out, sizeof ip_out, encrypted) == NULL) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
RETURN_STRING(ip_out);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_decrypt)
{
char *encrypted_ip;
size_t encrypted_ip_len;
unsigned char *key;
size_t key_len;
unsigned char bin[crypto_ipcrypt_BYTES];
unsigned char decrypted[crypto_ipcrypt_BYTES];
char ip_out[46];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
&encrypted_ip, &encrypted_ip_len, &key, &key_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (key_len != crypto_ipcrypt_KEYBYTES) {
zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_KEYBYTES bytes long");
RETURN_THROWS();
}
if (sodium_ip2bin(bin, encrypted_ip, encrypted_ip_len) != 0) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address");
RETURN_THROWS();
}
crypto_ipcrypt_decrypt(decrypted, bin, key);
if (sodium_bin2ip(ip_out, sizeof ip_out, decrypted) == NULL) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
RETURN_STRING(ip_out);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_nd_keygen)
{
unsigned char key[crypto_ipcrypt_ND_KEYBYTES];
if (zend_parse_parameters_none() == FAILURE) {
RETURN_THROWS();
}
randombytes_buf(key, sizeof key);
RETURN_STRINGL((const char *) key, sizeof key);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_nd_encrypt)
{
char *ip;
size_t ip_len;
unsigned char *key;
size_t key_len;
unsigned char bin[crypto_ipcrypt_ND_INPUTBYTES];
unsigned char tweak[crypto_ipcrypt_ND_TWEAKBYTES];
unsigned char encrypted[crypto_ipcrypt_ND_OUTPUTBYTES];
char hex_out[crypto_ipcrypt_ND_OUTPUTBYTES * 2 + 1];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
&ip, &ip_len, &key, &key_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (key_len != crypto_ipcrypt_ND_KEYBYTES) {
zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES bytes long");
RETURN_THROWS();
}
if (sodium_ip2bin(bin, ip, ip_len) != 0) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address");
RETURN_THROWS();
}
randombytes_buf(tweak, sizeof tweak);
crypto_ipcrypt_nd_encrypt(encrypted, bin, tweak, key);
sodium_bin2hex(hex_out, sizeof hex_out, encrypted, sizeof encrypted);
RETURN_STRINGL(hex_out, crypto_ipcrypt_ND_OUTPUTBYTES * 2);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_nd_decrypt)
{
char *ciphertext_hex;
size_t ciphertext_hex_len;
unsigned char *key;
size_t key_len;
unsigned char encrypted[crypto_ipcrypt_ND_OUTPUTBYTES];
unsigned char decrypted[crypto_ipcrypt_ND_INPUTBYTES];
char ip_out[46];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
&ciphertext_hex, &ciphertext_hex_len, &key, &key_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (key_len != crypto_ipcrypt_ND_KEYBYTES) {
zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES bytes long");
RETURN_THROWS();
}
if (ciphertext_hex_len != crypto_ipcrypt_ND_OUTPUTBYTES * 2) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid hex-encoded ciphertext");
RETURN_THROWS();
}
if (sodium_hex2bin(encrypted, sizeof encrypted, ciphertext_hex, ciphertext_hex_len,
NULL, NULL, NULL) != 0) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid hex-encoded ciphertext");
RETURN_THROWS();
}
crypto_ipcrypt_nd_decrypt(decrypted, encrypted, key);
if (sodium_bin2ip(ip_out, sizeof ip_out, decrypted) == NULL) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
RETURN_STRING(ip_out);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_ndx_keygen)
{
unsigned char key[crypto_ipcrypt_NDX_KEYBYTES];
if (zend_parse_parameters_none() == FAILURE) {
RETURN_THROWS();
}
crypto_ipcrypt_ndx_keygen(key);
RETURN_STRINGL((const char *) key, sizeof key);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_ndx_encrypt)
{
char *ip;
size_t ip_len;
unsigned char *key;
size_t key_len;
unsigned char bin[crypto_ipcrypt_NDX_INPUTBYTES];
unsigned char tweak[crypto_ipcrypt_NDX_TWEAKBYTES];
unsigned char encrypted[crypto_ipcrypt_NDX_OUTPUTBYTES];
char hex_out[crypto_ipcrypt_NDX_OUTPUTBYTES * 2 + 1];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
&ip, &ip_len, &key, &key_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (key_len != crypto_ipcrypt_NDX_KEYBYTES) {
zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES bytes long");
RETURN_THROWS();
}
if (sodium_ip2bin(bin, ip, ip_len) != 0) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address");
RETURN_THROWS();
}
randombytes_buf(tweak, sizeof tweak);
crypto_ipcrypt_ndx_encrypt(encrypted, bin, tweak, key);
sodium_bin2hex(hex_out, sizeof hex_out, encrypted, sizeof encrypted);
RETURN_STRINGL(hex_out, crypto_ipcrypt_NDX_OUTPUTBYTES * 2);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_ndx_decrypt)
{
char *ciphertext_hex;
size_t ciphertext_hex_len;
unsigned char *key;
size_t key_len;
unsigned char encrypted[crypto_ipcrypt_NDX_OUTPUTBYTES];
unsigned char decrypted[crypto_ipcrypt_NDX_INPUTBYTES];
char ip_out[46];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
&ciphertext_hex, &ciphertext_hex_len, &key, &key_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (key_len != crypto_ipcrypt_NDX_KEYBYTES) {
zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES bytes long");
RETURN_THROWS();
}
if (ciphertext_hex_len != crypto_ipcrypt_NDX_OUTPUTBYTES * 2) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid hex-encoded ciphertext");
RETURN_THROWS();
}
if (sodium_hex2bin(encrypted, sizeof encrypted, ciphertext_hex, ciphertext_hex_len,
NULL, NULL, NULL) != 0) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid hex-encoded ciphertext");
RETURN_THROWS();
}
crypto_ipcrypt_ndx_decrypt(decrypted, encrypted, key);
if (sodium_bin2ip(ip_out, sizeof ip_out, decrypted) == NULL) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
RETURN_STRING(ip_out);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_pfx_keygen)
{
unsigned char key[crypto_ipcrypt_PFX_KEYBYTES];
if (zend_parse_parameters_none() == FAILURE) {
RETURN_THROWS();
}
crypto_ipcrypt_pfx_keygen(key);
RETURN_STRINGL((const char *) key, sizeof key);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_pfx_encrypt)
{
char *ip;
size_t ip_len;
unsigned char *key;
size_t key_len;
unsigned char bin[crypto_ipcrypt_PFX_BYTES];
unsigned char encrypted[crypto_ipcrypt_PFX_BYTES];
char ip_out[46];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
&ip, &ip_len, &key, &key_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (key_len != crypto_ipcrypt_PFX_KEYBYTES) {
zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES bytes long");
RETURN_THROWS();
}
if (sodium_ip2bin(bin, ip, ip_len) != 0) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address");
RETURN_THROWS();
}
crypto_ipcrypt_pfx_encrypt(encrypted, bin, key);
if (sodium_bin2ip(ip_out, sizeof ip_out, encrypted) == NULL) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
RETURN_STRING(ip_out);
}
PHP_FUNCTION(sodium_crypto_ipcrypt_pfx_decrypt)
{
char *encrypted_ip;
size_t encrypted_ip_len;
unsigned char *key;
size_t key_len;
unsigned char bin[crypto_ipcrypt_PFX_BYTES];
unsigned char decrypted[crypto_ipcrypt_PFX_BYTES];
char ip_out[46];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
&encrypted_ip, &encrypted_ip_len, &key, &key_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (key_len != crypto_ipcrypt_PFX_KEYBYTES) {
zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES bytes long");
RETURN_THROWS();
}
if (sodium_ip2bin(bin, encrypted_ip, encrypted_ip_len) != 0) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address");
RETURN_THROWS();
}
crypto_ipcrypt_pfx_decrypt(decrypted, bin, key);
if (sodium_bin2ip(ip_out, sizeof ip_out, decrypted) == NULL) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
RETURN_STRING(ip_out);
}
PHP_FUNCTION(sodium_bin2ip)
{
unsigned char *bin;
size_t bin_len;
char ip_out[46];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s",
&bin, &bin_len) == FAILURE) {
RETURN_THROWS();
}
if (bin_len != 16) {
zend_argument_error(sodium_exception_ce, 1, "must be 16 bytes long");
RETURN_THROWS();
}
if (sodium_bin2ip(ip_out, sizeof ip_out, bin) == NULL) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
RETURN_STRING(ip_out);
}
PHP_FUNCTION(sodium_ip2bin)
{
char *ip;
size_t ip_len;
unsigned char bin[16];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s",
&ip, &ip_len) == FAILURE) {
RETURN_THROWS();
}
if (sodium_ip2bin(bin, ip, ip_len) != 0) {
zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address");
RETURN_THROWS();
}
RETURN_STRINGL((const char *) bin, sizeof bin);
}
#endif
#ifdef crypto_xof_shake128_STATEBYTES
PHP_FUNCTION(sodium_crypto_xof_shake128)
{
zend_string *out;
unsigned char *msg;
zend_long out_len;
size_t msg_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls",
&out_len, &msg, &msg_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (out_len <= 0 || out_len > ZSTR_MAX_LEN) {
zend_argument_error(sodium_exception_ce, 1, "must be a positive integer");
RETURN_THROWS();
}
out = zend_string_alloc((size_t) out_len, 0);
if (crypto_xof_shake128((unsigned char *) ZSTR_VAL(out), (size_t) out_len,
msg, (unsigned long long) msg_len) != 0) {
zend_string_efree(out);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
ZSTR_VAL(out)[out_len] = 0;
RETURN_NEW_STR(out);
}
PHP_FUNCTION(sodium_crypto_xof_shake128_init)
{
crypto_xof_shake128_state state_tmp;
zend_string *state;
zend_long domain = -1;
bool domain_is_null = 1;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_LONG_OR_NULL(domain, domain_is_null)
ZEND_PARSE_PARAMETERS_END();
memset(&state_tmp, 0, sizeof state_tmp);
if (domain_is_null) {
if (crypto_xof_shake128_init(&state_tmp) != 0) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
} else {
if (domain < 0x01 || domain > 0x7f) {
zend_argument_error(sodium_exception_ce, 1, "must be between 0x01 and 0x7f");
RETURN_THROWS();
}
if (crypto_xof_shake128_init_with_domain(&state_tmp, (unsigned char) domain) != 0) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
}
state = zend_string_alloc(sizeof state_tmp, 0);
memcpy(ZSTR_VAL(state), &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
ZSTR_VAL(state)[sizeof state_tmp] = 0;
RETURN_STR(state);
}
PHP_FUNCTION(sodium_crypto_xof_shake128_update)
{
crypto_xof_shake128_state state_tmp;
zval *state_zv;
unsigned char *msg;
unsigned char *state;
size_t msg_len;
size_t state_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs",
&state_zv, &msg, &msg_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
ZVAL_DEREF(state_zv);
if (Z_TYPE_P(state_zv) != IS_STRING) {
zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state");
RETURN_THROWS();
}
sodium_separate_string(state_zv);
state = (unsigned char *) Z_STRVAL(*state_zv);
state_len = Z_STRLEN(*state_zv);
if (state_len != sizeof (crypto_xof_shake128_state)) {
zend_argument_error(sodium_exception_ce, 1, "must have a correct state length");
RETURN_THROWS();
}
memcpy(&state_tmp, state, sizeof state_tmp);
if (crypto_xof_shake128_update(&state_tmp, msg, (unsigned long long) msg_len) != 0) {
sodium_memzero(&state_tmp, sizeof state_tmp);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
memcpy(state, &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
RETURN_TRUE;
}
PHP_FUNCTION(sodium_crypto_xof_shake128_squeeze)
{
crypto_xof_shake128_state state_tmp;
zval *state_zv;
zend_string *out;
unsigned char *state;
zend_long out_len;
size_t state_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl",
&state_zv, &out_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
ZVAL_DEREF(state_zv);
if (Z_TYPE_P(state_zv) != IS_STRING) {
zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state");
RETURN_THROWS();
}
sodium_separate_string(state_zv);
state = (unsigned char *) Z_STRVAL(*state_zv);
state_len = Z_STRLEN(*state_zv);
if (state_len != sizeof (crypto_xof_shake128_state)) {
zend_argument_error(sodium_exception_ce, 1, "must have a correct state length");
RETURN_THROWS();
}
if (out_len <= 0 || out_len > ZSTR_MAX_LEN) {
zend_argument_error(sodium_exception_ce, 2, "must be a positive integer");
RETURN_THROWS();
}
out = zend_string_alloc((size_t) out_len, 0);
memcpy(&state_tmp, state, sizeof state_tmp);
if (crypto_xof_shake128_squeeze(&state_tmp, (unsigned char *) ZSTR_VAL(out), (size_t) out_len) != 0) {
zend_string_efree(out);
sodium_memzero(&state_tmp, sizeof state_tmp);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
memcpy(state, &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
ZSTR_VAL(out)[out_len] = 0;
RETURN_NEW_STR(out);
}
PHP_FUNCTION(sodium_crypto_xof_shake256)
{
zend_string *out;
unsigned char *msg;
zend_long out_len;
size_t msg_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls",
&out_len, &msg, &msg_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (out_len <= 0 || out_len > ZSTR_MAX_LEN) {
zend_argument_error(sodium_exception_ce, 1, "must be a positive integer");
RETURN_THROWS();
}
out = zend_string_alloc((size_t) out_len, 0);
if (crypto_xof_shake256((unsigned char *) ZSTR_VAL(out), (size_t) out_len,
msg, (unsigned long long) msg_len) != 0) {
zend_string_efree(out);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
ZSTR_VAL(out)[out_len] = 0;
RETURN_NEW_STR(out);
}
PHP_FUNCTION(sodium_crypto_xof_shake256_init)
{
crypto_xof_shake256_state state_tmp;
zend_string *state;
zend_long domain = -1;
bool domain_is_null = 1;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_LONG_OR_NULL(domain, domain_is_null)
ZEND_PARSE_PARAMETERS_END();
memset(&state_tmp, 0, sizeof state_tmp);
if (domain_is_null) {
if (crypto_xof_shake256_init(&state_tmp) != 0) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
} else {
if (domain < 0x01 || domain > 0x7f) {
zend_argument_error(sodium_exception_ce, 1, "must be between 0x01 and 0x7f");
RETURN_THROWS();
}
if (crypto_xof_shake256_init_with_domain(&state_tmp, (unsigned char) domain) != 0) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
}
state = zend_string_alloc(sizeof state_tmp, 0);
memcpy(ZSTR_VAL(state), &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
ZSTR_VAL(state)[sizeof state_tmp] = 0;
RETURN_STR(state);
}
PHP_FUNCTION(sodium_crypto_xof_shake256_update)
{
crypto_xof_shake256_state state_tmp;
zval *state_zv;
unsigned char *msg;
unsigned char *state;
size_t msg_len;
size_t state_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs",
&state_zv, &msg, &msg_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
ZVAL_DEREF(state_zv);
if (Z_TYPE_P(state_zv) != IS_STRING) {
zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state");
RETURN_THROWS();
}
sodium_separate_string(state_zv);
state = (unsigned char *) Z_STRVAL(*state_zv);
state_len = Z_STRLEN(*state_zv);
if (state_len != sizeof (crypto_xof_shake256_state)) {
zend_argument_error(sodium_exception_ce, 1, "must have a correct state length");
RETURN_THROWS();
}
memcpy(&state_tmp, state, sizeof state_tmp);
if (crypto_xof_shake256_update(&state_tmp, msg, (unsigned long long) msg_len) != 0) {
sodium_memzero(&state_tmp, sizeof state_tmp);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
memcpy(state, &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
RETURN_TRUE;
}
PHP_FUNCTION(sodium_crypto_xof_shake256_squeeze)
{
crypto_xof_shake256_state state_tmp;
zval *state_zv;
zend_string *out;
unsigned char *state;
zend_long out_len;
size_t state_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl",
&state_zv, &out_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
ZVAL_DEREF(state_zv);
if (Z_TYPE_P(state_zv) != IS_STRING) {
zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state");
RETURN_THROWS();
}
sodium_separate_string(state_zv);
state = (unsigned char *) Z_STRVAL(*state_zv);
state_len = Z_STRLEN(*state_zv);
if (state_len != sizeof (crypto_xof_shake256_state)) {
zend_argument_error(sodium_exception_ce, 1, "must have a correct state length");
RETURN_THROWS();
}
if (out_len <= 0 || out_len > ZSTR_MAX_LEN) {
zend_argument_error(sodium_exception_ce, 2, "must be a positive integer");
RETURN_THROWS();
}
out = zend_string_alloc((size_t) out_len, 0);
memcpy(&state_tmp, state, sizeof state_tmp);
if (crypto_xof_shake256_squeeze(&state_tmp, (unsigned char *) ZSTR_VAL(out), (size_t) out_len) != 0) {
zend_string_efree(out);
sodium_memzero(&state_tmp, sizeof state_tmp);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
memcpy(state, &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
ZSTR_VAL(out)[out_len] = 0;
RETURN_NEW_STR(out);
}
PHP_FUNCTION(sodium_crypto_xof_turboshake128)
{
zend_string *out;
unsigned char *msg;
zend_long out_len;
size_t msg_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls",
&out_len, &msg, &msg_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (out_len <= 0 || out_len > ZSTR_MAX_LEN) {
zend_argument_error(sodium_exception_ce, 1, "must be a positive integer");
RETURN_THROWS();
}
out = zend_string_alloc((size_t) out_len, 0);
if (crypto_xof_turboshake128((unsigned char *) ZSTR_VAL(out), (size_t) out_len,
msg, (unsigned long long) msg_len) != 0) {
zend_string_efree(out);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
ZSTR_VAL(out)[out_len] = 0;
RETURN_NEW_STR(out);
}
PHP_FUNCTION(sodium_crypto_xof_turboshake128_init)
{
crypto_xof_turboshake128_state state_tmp;
zend_string *state;
zend_long domain = -1;
bool domain_is_null = 1;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_LONG_OR_NULL(domain, domain_is_null)
ZEND_PARSE_PARAMETERS_END();
memset(&state_tmp, 0, sizeof state_tmp);
if (domain_is_null) {
if (crypto_xof_turboshake128_init(&state_tmp) != 0) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
} else {
if (domain < 0x01 || domain > 0x7f) {
zend_argument_error(sodium_exception_ce, 1, "must be between 0x01 and 0x7f");
RETURN_THROWS();
}
if (crypto_xof_turboshake128_init_with_domain(&state_tmp, (unsigned char) domain) != 0) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
}
state = zend_string_alloc(sizeof state_tmp, 0);
memcpy(ZSTR_VAL(state), &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
ZSTR_VAL(state)[sizeof state_tmp] = 0;
RETURN_STR(state);
}
PHP_FUNCTION(sodium_crypto_xof_turboshake128_update)
{
crypto_xof_turboshake128_state state_tmp;
zval *state_zv;
unsigned char *msg;
unsigned char *state;
size_t msg_len;
size_t state_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs",
&state_zv, &msg, &msg_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
ZVAL_DEREF(state_zv);
if (Z_TYPE_P(state_zv) != IS_STRING) {
zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state");
RETURN_THROWS();
}
sodium_separate_string(state_zv);
state = (unsigned char *) Z_STRVAL(*state_zv);
state_len = Z_STRLEN(*state_zv);
if (state_len != sizeof (crypto_xof_turboshake128_state)) {
zend_argument_error(sodium_exception_ce, 1, "must have a correct state length");
RETURN_THROWS();
}
memcpy(&state_tmp, state, sizeof state_tmp);
if (crypto_xof_turboshake128_update(&state_tmp, msg, (unsigned long long) msg_len) != 0) {
sodium_memzero(&state_tmp, sizeof state_tmp);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
memcpy(state, &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
RETURN_TRUE;
}
PHP_FUNCTION(sodium_crypto_xof_turboshake128_squeeze)
{
crypto_xof_turboshake128_state state_tmp;
zval *state_zv;
zend_string *out;
unsigned char *state;
zend_long out_len;
size_t state_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl",
&state_zv, &out_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
ZVAL_DEREF(state_zv);
if (Z_TYPE_P(state_zv) != IS_STRING) {
zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state");
RETURN_THROWS();
}
sodium_separate_string(state_zv);
state = (unsigned char *) Z_STRVAL(*state_zv);
state_len = Z_STRLEN(*state_zv);
if (state_len != sizeof (crypto_xof_turboshake128_state)) {
zend_argument_error(sodium_exception_ce, 1, "must have a correct state length");
RETURN_THROWS();
}
if (out_len <= 0 || out_len > ZSTR_MAX_LEN) {
zend_argument_error(sodium_exception_ce, 2, "must be a positive integer");
RETURN_THROWS();
}
out = zend_string_alloc((size_t) out_len, 0);
memcpy(&state_tmp, state, sizeof state_tmp);
if (crypto_xof_turboshake128_squeeze(&state_tmp, (unsigned char *) ZSTR_VAL(out), (size_t) out_len) != 0) {
zend_string_efree(out);
sodium_memzero(&state_tmp, sizeof state_tmp);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
memcpy(state, &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
ZSTR_VAL(out)[out_len] = 0;
RETURN_NEW_STR(out);
}
PHP_FUNCTION(sodium_crypto_xof_turboshake256)
{
zend_string *out;
unsigned char *msg;
zend_long out_len;
size_t msg_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls",
&out_len, &msg, &msg_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (out_len <= 0 || out_len > ZSTR_MAX_LEN) {
zend_argument_error(sodium_exception_ce, 1, "must be a positive integer");
RETURN_THROWS();
}
out = zend_string_alloc((size_t) out_len, 0);
if (crypto_xof_turboshake256((unsigned char *) ZSTR_VAL(out), (size_t) out_len,
msg, (unsigned long long) msg_len) != 0) {
zend_string_efree(out);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
ZSTR_VAL(out)[out_len] = 0;
RETURN_NEW_STR(out);
}
PHP_FUNCTION(sodium_crypto_xof_turboshake256_init)
{
crypto_xof_turboshake256_state state_tmp;
zend_string *state;
zend_long domain = -1;
bool domain_is_null = 1;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_LONG_OR_NULL(domain, domain_is_null)
ZEND_PARSE_PARAMETERS_END();
memset(&state_tmp, 0, sizeof state_tmp);
if (domain_is_null) {
if (crypto_xof_turboshake256_init(&state_tmp) != 0) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
} else {
if (domain < 0x01 || domain > 0x7f) {
zend_argument_error(sodium_exception_ce, 1, "must be between 0x01 and 0x7f");
RETURN_THROWS();
}
if (crypto_xof_turboshake256_init_with_domain(&state_tmp, (unsigned char) domain) != 0) {
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
}
state = zend_string_alloc(sizeof state_tmp, 0);
memcpy(ZSTR_VAL(state), &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
ZSTR_VAL(state)[sizeof state_tmp] = 0;
RETURN_STR(state);
}
PHP_FUNCTION(sodium_crypto_xof_turboshake256_update)
{
crypto_xof_turboshake256_state state_tmp;
zval *state_zv;
unsigned char *msg;
unsigned char *state;
size_t msg_len;
size_t state_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs",
&state_zv, &msg, &msg_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
ZVAL_DEREF(state_zv);
if (Z_TYPE_P(state_zv) != IS_STRING) {
zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state");
RETURN_THROWS();
}
sodium_separate_string(state_zv);
state = (unsigned char *) Z_STRVAL(*state_zv);
state_len = Z_STRLEN(*state_zv);
if (state_len != sizeof (crypto_xof_turboshake256_state)) {
zend_argument_error(sodium_exception_ce, 1, "must have a correct state length");
RETURN_THROWS();
}
memcpy(&state_tmp, state, sizeof state_tmp);
if (crypto_xof_turboshake256_update(&state_tmp, msg, (unsigned long long) msg_len) != 0) {
sodium_memzero(&state_tmp, sizeof state_tmp);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
memcpy(state, &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
RETURN_TRUE;
}
PHP_FUNCTION(sodium_crypto_xof_turboshake256_squeeze)
{
crypto_xof_turboshake256_state state_tmp;
zval *state_zv;
zend_string *out;
unsigned char *state;
zend_long out_len;
size_t state_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl",
&state_zv, &out_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
ZVAL_DEREF(state_zv);
if (Z_TYPE_P(state_zv) != IS_STRING) {
zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state");
RETURN_THROWS();
}
sodium_separate_string(state_zv);
state = (unsigned char *) Z_STRVAL(*state_zv);
state_len = Z_STRLEN(*state_zv);
if (state_len != sizeof (crypto_xof_turboshake256_state)) {
zend_argument_error(sodium_exception_ce, 1, "must have a correct state length");
RETURN_THROWS();
}
if (out_len <= 0 || out_len > ZSTR_MAX_LEN) {
zend_argument_error(sodium_exception_ce, 2, "must be a positive integer");
RETURN_THROWS();
}
out = zend_string_alloc((size_t) out_len, 0);
memcpy(&state_tmp, state, sizeof state_tmp);
if (crypto_xof_turboshake256_squeeze(&state_tmp, (unsigned char *) ZSTR_VAL(out), (size_t) out_len) != 0) {
zend_string_efree(out);
sodium_memzero(&state_tmp, sizeof state_tmp);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
memcpy(state, &state_tmp, sizeof state_tmp);
sodium_memzero(&state_tmp, sizeof state_tmp);
ZSTR_VAL(out)[out_len] = 0;
RETURN_NEW_STR(out);
}
#endif

View File

@@ -801,4 +801,170 @@ function sodium_base642bin(#[\SensitiveParameter] string $string, int $id, strin
*/ */
function sodium_crypto_scalarmult_base(#[\SensitiveParameter] string $secret_key): string {} function sodium_crypto_scalarmult_base(#[\SensitiveParameter] string $secret_key): string {}
#ifdef crypto_ipcrypt_KEYBYTES
/**
* @var int
* @cvalue crypto_ipcrypt_BYTES
*/
const SODIUM_CRYPTO_IPCRYPT_BYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_KEYBYTES
*/
const SODIUM_CRYPTO_IPCRYPT_KEYBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_ND_KEYBYTES
*/
const SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_ND_TWEAKBYTES
*/
const SODIUM_CRYPTO_IPCRYPT_ND_TWEAKBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_ND_INPUTBYTES
*/
const SODIUM_CRYPTO_IPCRYPT_ND_INPUTBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_ND_OUTPUTBYTES
*/
const SODIUM_CRYPTO_IPCRYPT_ND_OUTPUTBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_NDX_KEYBYTES
*/
const SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_NDX_TWEAKBYTES
*/
const SODIUM_CRYPTO_IPCRYPT_NDX_TWEAKBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_NDX_INPUTBYTES
*/
const SODIUM_CRYPTO_IPCRYPT_NDX_INPUTBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_NDX_OUTPUTBYTES
*/
const SODIUM_CRYPTO_IPCRYPT_NDX_OUTPUTBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_PFX_KEYBYTES
*/
const SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_ipcrypt_PFX_BYTES
*/
const SODIUM_CRYPTO_IPCRYPT_PFX_BYTES = UNKNOWN;
function sodium_crypto_ipcrypt_keygen(): string {}
function sodium_crypto_ipcrypt_encrypt(string $ip, #[\SensitiveParameter] string $key): string {}
function sodium_crypto_ipcrypt_decrypt(string $encrypted_ip, #[\SensitiveParameter] string $key): string {}
function sodium_crypto_ipcrypt_nd_keygen(): string {}
function sodium_crypto_ipcrypt_nd_encrypt(string $ip, #[\SensitiveParameter] string $key): string {}
function sodium_crypto_ipcrypt_nd_decrypt(string $ciphertext_hex, #[\SensitiveParameter] string $key): string {}
function sodium_crypto_ipcrypt_ndx_keygen(): string {}
function sodium_crypto_ipcrypt_ndx_encrypt(string $ip, #[\SensitiveParameter] string $key): string {}
function sodium_crypto_ipcrypt_ndx_decrypt(string $ciphertext_hex, #[\SensitiveParameter] string $key): string {}
function sodium_crypto_ipcrypt_pfx_keygen(): string {}
function sodium_crypto_ipcrypt_pfx_encrypt(string $ip, #[\SensitiveParameter] string $key): string {}
function sodium_crypto_ipcrypt_pfx_decrypt(string $encrypted_ip, #[\SensitiveParameter] string $key): string {}
function sodium_bin2ip(string $bin): string {}
function sodium_ip2bin(string $ip): string {}
#endif
#ifdef crypto_xof_shake128_STATEBYTES
/**
* @var int
* @cvalue crypto_xof_shake128_BLOCKBYTES
*/
const SODIUM_CRYPTO_XOF_SHAKE128_BLOCKBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_xof_shake128_STATEBYTES
*/
const SODIUM_CRYPTO_XOF_SHAKE128_STATEBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_xof_shake256_BLOCKBYTES
*/
const SODIUM_CRYPTO_XOF_SHAKE256_BLOCKBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_xof_shake256_STATEBYTES
*/
const SODIUM_CRYPTO_XOF_SHAKE256_STATEBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_xof_turboshake128_BLOCKBYTES
*/
const SODIUM_CRYPTO_XOF_TURBOSHAKE128_BLOCKBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_xof_turboshake128_STATEBYTES
*/
const SODIUM_CRYPTO_XOF_TURBOSHAKE128_STATEBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_xof_turboshake256_BLOCKBYTES
*/
const SODIUM_CRYPTO_XOF_TURBOSHAKE256_BLOCKBYTES = UNKNOWN;
/**
* @var int
* @cvalue crypto_xof_turboshake256_STATEBYTES
*/
const SODIUM_CRYPTO_XOF_TURBOSHAKE256_STATEBYTES = UNKNOWN;
function sodium_crypto_xof_shake128(int $length, string $message): string {}
function sodium_crypto_xof_shake128_init(?int $domain = null): string {}
function sodium_crypto_xof_shake128_update(string &$state, string $message): true {}
function sodium_crypto_xof_shake128_squeeze(string &$state, int $length): string {}
function sodium_crypto_xof_shake256(int $length, string $message): string {}
function sodium_crypto_xof_shake256_init(?int $domain = null): string {}
function sodium_crypto_xof_shake256_update(string &$state, string $message): true {}
function sodium_crypto_xof_shake256_squeeze(string &$state, int $length): string {}
function sodium_crypto_xof_turboshake128(int $length, string $message): string {}
function sodium_crypto_xof_turboshake128_init(?int $domain = null): string {}
function sodium_crypto_xof_turboshake128_update(string &$state, string $message): true {}
function sodium_crypto_xof_turboshake128_squeeze(string &$state, int $length): string {}
function sodium_crypto_xof_turboshake256(int $length, string $message): string {}
function sodium_crypto_xof_turboshake256_init(?int $domain = null): string {}
function sodium_crypto_xof_turboshake256_update(string &$state, string $message): true {}
function sodium_crypto_xof_turboshake256_squeeze(string &$state, int $length): string {}
#endif
class SodiumException extends Exception {} class SodiumException extends Exception {}

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit libsodium.stub.php instead. /* This is a generated file, edit libsodium.stub.php instead.
* Stub hash: 89cbb449ee6146dc8d50ba4bb1e76f83444a2db2 */ * Stub hash: 7b337a297ae333dd8d0c232979b770332c9e7eb6 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_aead_aes256gcm_is_available, 0, 0, _IS_BOOL, 0) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_aead_aes256gcm_is_available, 0, 0, _IS_BOOL, 0)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
@@ -483,6 +483,95 @@ ZEND_END_ARG_INFO()
#define arginfo_sodium_crypto_scalarmult_base arginfo_sodium_crypto_box_publickey_from_secretkey #define arginfo_sodium_crypto_scalarmult_base arginfo_sodium_crypto_box_publickey_from_secretkey
#if defined(crypto_ipcrypt_KEYBYTES)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_ipcrypt_keygen, 0, 0, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_ipcrypt_encrypt, 0, 2, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, ip, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_ipcrypt_decrypt, 0, 2, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, encrypted_ip, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_END_ARG_INFO()
#define arginfo_sodium_crypto_ipcrypt_nd_keygen arginfo_sodium_crypto_ipcrypt_keygen
#define arginfo_sodium_crypto_ipcrypt_nd_encrypt arginfo_sodium_crypto_ipcrypt_encrypt
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_ipcrypt_nd_decrypt, 0, 2, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, ciphertext_hex, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_END_ARG_INFO()
#define arginfo_sodium_crypto_ipcrypt_ndx_keygen arginfo_sodium_crypto_ipcrypt_keygen
#define arginfo_sodium_crypto_ipcrypt_ndx_encrypt arginfo_sodium_crypto_ipcrypt_encrypt
#define arginfo_sodium_crypto_ipcrypt_ndx_decrypt arginfo_sodium_crypto_ipcrypt_nd_decrypt
#define arginfo_sodium_crypto_ipcrypt_pfx_keygen arginfo_sodium_crypto_ipcrypt_keygen
#define arginfo_sodium_crypto_ipcrypt_pfx_encrypt arginfo_sodium_crypto_ipcrypt_encrypt
#define arginfo_sodium_crypto_ipcrypt_pfx_decrypt arginfo_sodium_crypto_ipcrypt_decrypt
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_bin2ip, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, bin, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_ip2bin, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, ip, IS_STRING, 0)
ZEND_END_ARG_INFO()
#endif
#if defined(crypto_xof_shake128_STATEBYTES)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_xof_shake128, 0, 2, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_xof_shake128_init, 0, 0, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, domain, IS_LONG, 1, "null")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_xof_shake128_update, 0, 2, IS_TRUE, 0)
ZEND_ARG_TYPE_INFO(1, state, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_xof_shake128_squeeze, 0, 2, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(1, state, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0)
ZEND_END_ARG_INFO()
#define arginfo_sodium_crypto_xof_shake256 arginfo_sodium_crypto_xof_shake128
#define arginfo_sodium_crypto_xof_shake256_init arginfo_sodium_crypto_xof_shake128_init
#define arginfo_sodium_crypto_xof_shake256_update arginfo_sodium_crypto_xof_shake128_update
#define arginfo_sodium_crypto_xof_shake256_squeeze arginfo_sodium_crypto_xof_shake128_squeeze
#define arginfo_sodium_crypto_xof_turboshake128 arginfo_sodium_crypto_xof_shake128
#define arginfo_sodium_crypto_xof_turboshake128_init arginfo_sodium_crypto_xof_shake128_init
#define arginfo_sodium_crypto_xof_turboshake128_update arginfo_sodium_crypto_xof_shake128_update
#define arginfo_sodium_crypto_xof_turboshake128_squeeze arginfo_sodium_crypto_xof_shake128_squeeze
#define arginfo_sodium_crypto_xof_turboshake256 arginfo_sodium_crypto_xof_shake128
#define arginfo_sodium_crypto_xof_turboshake256_init arginfo_sodium_crypto_xof_shake128_init
#define arginfo_sodium_crypto_xof_turboshake256_update arginfo_sodium_crypto_xof_shake128_update
#define arginfo_sodium_crypto_xof_turboshake256_squeeze arginfo_sodium_crypto_xof_shake128_squeeze
#endif
ZEND_FUNCTION(sodium_crypto_aead_aes256gcm_is_available); ZEND_FUNCTION(sodium_crypto_aead_aes256gcm_is_available);
#if defined(HAVE_AESGCM) #if defined(HAVE_AESGCM)
ZEND_FUNCTION(sodium_crypto_aead_aes256gcm_decrypt); ZEND_FUNCTION(sodium_crypto_aead_aes256gcm_decrypt);
@@ -616,6 +705,40 @@ ZEND_FUNCTION(sodium_hex2bin);
ZEND_FUNCTION(sodium_bin2base64); ZEND_FUNCTION(sodium_bin2base64);
ZEND_FUNCTION(sodium_base642bin); ZEND_FUNCTION(sodium_base642bin);
#endif #endif
#if defined(crypto_ipcrypt_KEYBYTES)
ZEND_FUNCTION(sodium_crypto_ipcrypt_keygen);
ZEND_FUNCTION(sodium_crypto_ipcrypt_encrypt);
ZEND_FUNCTION(sodium_crypto_ipcrypt_decrypt);
ZEND_FUNCTION(sodium_crypto_ipcrypt_nd_keygen);
ZEND_FUNCTION(sodium_crypto_ipcrypt_nd_encrypt);
ZEND_FUNCTION(sodium_crypto_ipcrypt_nd_decrypt);
ZEND_FUNCTION(sodium_crypto_ipcrypt_ndx_keygen);
ZEND_FUNCTION(sodium_crypto_ipcrypt_ndx_encrypt);
ZEND_FUNCTION(sodium_crypto_ipcrypt_ndx_decrypt);
ZEND_FUNCTION(sodium_crypto_ipcrypt_pfx_keygen);
ZEND_FUNCTION(sodium_crypto_ipcrypt_pfx_encrypt);
ZEND_FUNCTION(sodium_crypto_ipcrypt_pfx_decrypt);
ZEND_FUNCTION(sodium_bin2ip);
ZEND_FUNCTION(sodium_ip2bin);
#endif
#if defined(crypto_xof_shake128_STATEBYTES)
ZEND_FUNCTION(sodium_crypto_xof_shake128);
ZEND_FUNCTION(sodium_crypto_xof_shake128_init);
ZEND_FUNCTION(sodium_crypto_xof_shake128_update);
ZEND_FUNCTION(sodium_crypto_xof_shake128_squeeze);
ZEND_FUNCTION(sodium_crypto_xof_shake256);
ZEND_FUNCTION(sodium_crypto_xof_shake256_init);
ZEND_FUNCTION(sodium_crypto_xof_shake256_update);
ZEND_FUNCTION(sodium_crypto_xof_shake256_squeeze);
ZEND_FUNCTION(sodium_crypto_xof_turboshake128);
ZEND_FUNCTION(sodium_crypto_xof_turboshake128_init);
ZEND_FUNCTION(sodium_crypto_xof_turboshake128_update);
ZEND_FUNCTION(sodium_crypto_xof_turboshake128_squeeze);
ZEND_FUNCTION(sodium_crypto_xof_turboshake256);
ZEND_FUNCTION(sodium_crypto_xof_turboshake256_init);
ZEND_FUNCTION(sodium_crypto_xof_turboshake256_update);
ZEND_FUNCTION(sodium_crypto_xof_turboshake256_squeeze);
#endif
static const zend_function_entry ext_functions[] = { static const zend_function_entry ext_functions[] = {
ZEND_FE(sodium_crypto_aead_aes256gcm_is_available, arginfo_sodium_crypto_aead_aes256gcm_is_available) ZEND_FE(sodium_crypto_aead_aes256gcm_is_available, arginfo_sodium_crypto_aead_aes256gcm_is_available)
@@ -752,6 +875,40 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(sodium_base642bin, arginfo_sodium_base642bin) ZEND_FE(sodium_base642bin, arginfo_sodium_base642bin)
#endif #endif
ZEND_RAW_FENTRY("sodium_crypto_scalarmult_base", zif_sodium_crypto_box_publickey_from_secretkey, arginfo_sodium_crypto_scalarmult_base, 0, NULL, NULL) ZEND_RAW_FENTRY("sodium_crypto_scalarmult_base", zif_sodium_crypto_box_publickey_from_secretkey, arginfo_sodium_crypto_scalarmult_base, 0, NULL, NULL)
#if defined(crypto_ipcrypt_KEYBYTES)
ZEND_FE(sodium_crypto_ipcrypt_keygen, arginfo_sodium_crypto_ipcrypt_keygen)
ZEND_FE(sodium_crypto_ipcrypt_encrypt, arginfo_sodium_crypto_ipcrypt_encrypt)
ZEND_FE(sodium_crypto_ipcrypt_decrypt, arginfo_sodium_crypto_ipcrypt_decrypt)
ZEND_FE(sodium_crypto_ipcrypt_nd_keygen, arginfo_sodium_crypto_ipcrypt_nd_keygen)
ZEND_FE(sodium_crypto_ipcrypt_nd_encrypt, arginfo_sodium_crypto_ipcrypt_nd_encrypt)
ZEND_FE(sodium_crypto_ipcrypt_nd_decrypt, arginfo_sodium_crypto_ipcrypt_nd_decrypt)
ZEND_FE(sodium_crypto_ipcrypt_ndx_keygen, arginfo_sodium_crypto_ipcrypt_ndx_keygen)
ZEND_FE(sodium_crypto_ipcrypt_ndx_encrypt, arginfo_sodium_crypto_ipcrypt_ndx_encrypt)
ZEND_FE(sodium_crypto_ipcrypt_ndx_decrypt, arginfo_sodium_crypto_ipcrypt_ndx_decrypt)
ZEND_FE(sodium_crypto_ipcrypt_pfx_keygen, arginfo_sodium_crypto_ipcrypt_pfx_keygen)
ZEND_FE(sodium_crypto_ipcrypt_pfx_encrypt, arginfo_sodium_crypto_ipcrypt_pfx_encrypt)
ZEND_FE(sodium_crypto_ipcrypt_pfx_decrypt, arginfo_sodium_crypto_ipcrypt_pfx_decrypt)
ZEND_FE(sodium_bin2ip, arginfo_sodium_bin2ip)
ZEND_FE(sodium_ip2bin, arginfo_sodium_ip2bin)
#endif
#if defined(crypto_xof_shake128_STATEBYTES)
ZEND_FE(sodium_crypto_xof_shake128, arginfo_sodium_crypto_xof_shake128)
ZEND_FE(sodium_crypto_xof_shake128_init, arginfo_sodium_crypto_xof_shake128_init)
ZEND_FE(sodium_crypto_xof_shake128_update, arginfo_sodium_crypto_xof_shake128_update)
ZEND_FE(sodium_crypto_xof_shake128_squeeze, arginfo_sodium_crypto_xof_shake128_squeeze)
ZEND_FE(sodium_crypto_xof_shake256, arginfo_sodium_crypto_xof_shake256)
ZEND_FE(sodium_crypto_xof_shake256_init, arginfo_sodium_crypto_xof_shake256_init)
ZEND_FE(sodium_crypto_xof_shake256_update, arginfo_sodium_crypto_xof_shake256_update)
ZEND_FE(sodium_crypto_xof_shake256_squeeze, arginfo_sodium_crypto_xof_shake256_squeeze)
ZEND_FE(sodium_crypto_xof_turboshake128, arginfo_sodium_crypto_xof_turboshake128)
ZEND_FE(sodium_crypto_xof_turboshake128_init, arginfo_sodium_crypto_xof_turboshake128_init)
ZEND_FE(sodium_crypto_xof_turboshake128_update, arginfo_sodium_crypto_xof_turboshake128_update)
ZEND_FE(sodium_crypto_xof_turboshake128_squeeze, arginfo_sodium_crypto_xof_turboshake128_squeeze)
ZEND_FE(sodium_crypto_xof_turboshake256, arginfo_sodium_crypto_xof_turboshake256)
ZEND_FE(sodium_crypto_xof_turboshake256_init, arginfo_sodium_crypto_xof_turboshake256_init)
ZEND_FE(sodium_crypto_xof_turboshake256_update, arginfo_sodium_crypto_xof_turboshake256_update)
ZEND_FE(sodium_crypto_xof_turboshake256_squeeze, arginfo_sodium_crypto_xof_turboshake256_squeeze)
#endif
ZEND_FE_END ZEND_FE_END
}; };
@@ -883,6 +1040,30 @@ static void register_libsodium_symbols(int module_number)
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES", crypto_core_ristretto255_SCALARBYTES, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES", crypto_core_ristretto255_SCALARBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES", crypto_core_ristretto255_NONREDUCEDSCALARBYTES, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES", crypto_core_ristretto255_NONREDUCEDSCALARBYTES, CONST_PERSISTENT);
#endif #endif
#if defined(crypto_ipcrypt_KEYBYTES)
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_BYTES", crypto_ipcrypt_BYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_KEYBYTES", crypto_ipcrypt_KEYBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES", crypto_ipcrypt_ND_KEYBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_ND_TWEAKBYTES", crypto_ipcrypt_ND_TWEAKBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_ND_INPUTBYTES", crypto_ipcrypt_ND_INPUTBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_ND_OUTPUTBYTES", crypto_ipcrypt_ND_OUTPUTBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES", crypto_ipcrypt_NDX_KEYBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_NDX_TWEAKBYTES", crypto_ipcrypt_NDX_TWEAKBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_NDX_INPUTBYTES", crypto_ipcrypt_NDX_INPUTBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_NDX_OUTPUTBYTES", crypto_ipcrypt_NDX_OUTPUTBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES", crypto_ipcrypt_PFX_KEYBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_PFX_BYTES", crypto_ipcrypt_PFX_BYTES, CONST_PERSISTENT);
#endif
#if defined(crypto_xof_shake128_STATEBYTES)
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_SHAKE128_BLOCKBYTES", crypto_xof_shake128_BLOCKBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_SHAKE128_STATEBYTES", crypto_xof_shake128_STATEBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_SHAKE256_BLOCKBYTES", crypto_xof_shake256_BLOCKBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_SHAKE256_STATEBYTES", crypto_xof_shake256_STATEBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_TURBOSHAKE128_BLOCKBYTES", crypto_xof_turboshake128_BLOCKBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_TURBOSHAKE128_STATEBYTES", crypto_xof_turboshake128_STATEBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_TURBOSHAKE256_BLOCKBYTES", crypto_xof_turboshake256_BLOCKBYTES, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_TURBOSHAKE256_STATEBYTES", crypto_xof_turboshake256_STATEBYTES, CONST_PERSISTENT);
#endif
#if defined(HAVE_AESGCM) #if defined(HAVE_AESGCM)
@@ -1060,6 +1241,24 @@ static void register_libsodium_symbols(int module_number)
#endif #endif
zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_scalarmult_base", sizeof("sodium_crypto_scalarmult_base") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_scalarmult_base", sizeof("sodium_crypto_scalarmult_base") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
#if defined(crypto_ipcrypt_KEYBYTES)
zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_encrypt", sizeof("sodium_crypto_ipcrypt_encrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_decrypt", sizeof("sodium_crypto_ipcrypt_decrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_nd_encrypt", sizeof("sodium_crypto_ipcrypt_nd_encrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_nd_decrypt", sizeof("sodium_crypto_ipcrypt_nd_decrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_ndx_encrypt", sizeof("sodium_crypto_ipcrypt_ndx_encrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_ndx_decrypt", sizeof("sodium_crypto_ipcrypt_ndx_decrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_pfx_encrypt", sizeof("sodium_crypto_ipcrypt_pfx_encrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_pfx_decrypt", sizeof("sodium_crypto_ipcrypt_pfx_decrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
#endif
} }
static zend_class_entry *register_class_SodiumException(zend_class_entry *class_entry_Exception) static zend_class_entry *register_class_SodiumException(zend_class_entry *class_entry_Exception)

View File

@@ -0,0 +1,63 @@
--TEST--
Check for libsodium ipcrypt
--EXTENSIONS--
sodium
--SKIPIF--
<?php
if (!defined('SODIUM_CRYPTO_IPCRYPT_KEYBYTES')) print "skip libsodium without ipcrypt (requires >= 1.0.21)";
?>
--FILE--
<?php
$key = str_repeat("\x01", SODIUM_CRYPTO_IPCRYPT_KEYBYTES);
/* Basic encrypt/decrypt roundtrip with IPv4 */
$enc = sodium_crypto_ipcrypt_encrypt("192.168.1.1", $key);
var_dump(sodium_crypto_ipcrypt_decrypt($enc, $key));
/* Deterministic: same input produces same output */
$enc2 = sodium_crypto_ipcrypt_encrypt("192.168.1.1", $key);
var_dump($enc === $enc2);
/* Different key produces different output */
$key2 = str_repeat("\x02", SODIUM_CRYPTO_IPCRYPT_KEYBYTES);
$enc3 = sodium_crypto_ipcrypt_encrypt("192.168.1.1", $key2);
var_dump($enc !== $enc3);
/* IPv6 roundtrip */
$enc6 = sodium_crypto_ipcrypt_encrypt("::1", $key);
var_dump(sodium_crypto_ipcrypt_decrypt($enc6, $key));
/* Keygen produces correct length */
$gen_key = sodium_crypto_ipcrypt_keygen();
var_dump(strlen($gen_key) === SODIUM_CRYPTO_IPCRYPT_KEYBYTES);
/* Error: wrong key length */
try {
sodium_crypto_ipcrypt_encrypt("192.168.1.1", "short");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* Error: invalid IP */
try {
sodium_crypto_ipcrypt_encrypt("not_an_ip", $key);
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* Error: wrong key length for decrypt */
try {
sodium_crypto_ipcrypt_decrypt("::1", "short");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
?>
--EXPECT--
string(11) "192.168.1.1"
bool(true)
bool(true)
string(3) "::1"
bool(true)
sodium_crypto_ipcrypt_encrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_KEYBYTES bytes long
sodium_crypto_ipcrypt_encrypt(): Argument #1 ($ip) must be a valid IP address
sodium_crypto_ipcrypt_decrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_KEYBYTES bytes long

View File

@@ -0,0 +1,98 @@
--TEST--
Check for libsodium ipcrypt non-deterministic (nd) and extended (ndx)
--EXTENSIONS--
sodium
--SKIPIF--
<?php
if (!defined('SODIUM_CRYPTO_IPCRYPT_KEYBYTES')) print "skip libsodium without ipcrypt (requires >= 1.0.21)";
?>
--FILE--
<?php
/* ND: non-deterministic encrypt/decrypt roundtrip */
$nd_key = sodium_crypto_ipcrypt_nd_keygen();
var_dump(strlen($nd_key) === SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES);
$ct = sodium_crypto_ipcrypt_nd_encrypt("192.168.1.1", $nd_key);
var_dump(strlen($ct) === SODIUM_CRYPTO_IPCRYPT_ND_OUTPUTBYTES * 2);
$pt = sodium_crypto_ipcrypt_nd_decrypt($ct, $nd_key);
var_dump($pt);
/* ND is non-deterministic: two encryptions of the same IP differ */
$ct2 = sodium_crypto_ipcrypt_nd_encrypt("192.168.1.1", $nd_key);
var_dump($ct !== $ct2);
$pt2 = sodium_crypto_ipcrypt_nd_decrypt($ct2, $nd_key);
var_dump($pt2);
/* ND: IPv6 roundtrip */
$ct6 = sodium_crypto_ipcrypt_nd_encrypt("::1", $nd_key);
var_dump(sodium_crypto_ipcrypt_nd_decrypt($ct6, $nd_key));
/* ND error: wrong key length */
try {
sodium_crypto_ipcrypt_nd_encrypt("192.168.1.1", "short");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* ND error: invalid IP */
try {
sodium_crypto_ipcrypt_nd_encrypt("bad", $nd_key);
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* ND error: bad ciphertext hex length */
try {
sodium_crypto_ipcrypt_nd_decrypt("tooshort", $nd_key);
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* NDX: keygen, encrypt, decrypt roundtrip */
$ndx_key = sodium_crypto_ipcrypt_ndx_keygen();
var_dump(strlen($ndx_key) === SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES);
$ct_ndx = sodium_crypto_ipcrypt_ndx_encrypt("10.0.0.1", $ndx_key);
var_dump(strlen($ct_ndx) === SODIUM_CRYPTO_IPCRYPT_NDX_OUTPUTBYTES * 2);
$pt_ndx = sodium_crypto_ipcrypt_ndx_decrypt($ct_ndx, $ndx_key);
var_dump($pt_ndx);
/* NDX is non-deterministic */
$ct_ndx2 = sodium_crypto_ipcrypt_ndx_encrypt("10.0.0.1", $ndx_key);
var_dump($ct_ndx !== $ct_ndx2);
/* NDX: IPv6 */
$ct_ndx6 = sodium_crypto_ipcrypt_ndx_encrypt("fe80::1", $ndx_key);
var_dump(sodium_crypto_ipcrypt_ndx_decrypt($ct_ndx6, $ndx_key));
/* NDX error: wrong key length */
try {
sodium_crypto_ipcrypt_ndx_encrypt("10.0.0.1", "short");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* NDX error: bad ciphertext hex */
try {
sodium_crypto_ipcrypt_ndx_decrypt("tooshort", $ndx_key);
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
?>
--EXPECT--
bool(true)
bool(true)
string(11) "192.168.1.1"
bool(true)
string(11) "192.168.1.1"
string(3) "::1"
sodium_crypto_ipcrypt_nd_encrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES bytes long
sodium_crypto_ipcrypt_nd_encrypt(): Argument #1 ($ip) must be a valid IP address
sodium_crypto_ipcrypt_nd_decrypt(): Argument #1 ($ciphertext_hex) must be a valid hex-encoded ciphertext
bool(true)
bool(true)
string(8) "10.0.0.1"
bool(true)
string(7) "fe80::1"
sodium_crypto_ipcrypt_ndx_encrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES bytes long
sodium_crypto_ipcrypt_ndx_decrypt(): Argument #1 ($ciphertext_hex) must be a valid hex-encoded ciphertext

View File

@@ -0,0 +1,65 @@
--TEST--
Check for libsodium ipcrypt prefix-preserving (pfx)
--EXTENSIONS--
sodium
--SKIPIF--
<?php
if (!defined('SODIUM_CRYPTO_IPCRYPT_KEYBYTES')) print "skip libsodium without ipcrypt (requires >= 1.0.21)";
?>
--FILE--
<?php
$key = str_repeat("\x02", SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES);
/* PFX encrypt/decrypt roundtrip with IPv4 */
$enc = sodium_crypto_ipcrypt_pfx_encrypt("10.0.0.1", $key);
var_dump(sodium_crypto_ipcrypt_pfx_decrypt($enc, $key));
/* PFX is deterministic */
$enc2 = sodium_crypto_ipcrypt_pfx_encrypt("10.0.0.1", $key);
var_dump($enc === $enc2);
/* PFX: IPv4 encrypted output looks like IPv4 */
var_dump(filter_var($enc, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false);
/* PFX: IPv6 roundtrip */
$enc6 = sodium_crypto_ipcrypt_pfx_encrypt("::1", $key);
var_dump(sodium_crypto_ipcrypt_pfx_decrypt($enc6, $key));
/* PFX: IPv6 encrypted output is valid IPv6 */
var_dump(filter_var($enc6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false);
/* PFX: keygen produces correct length */
$gen_key = sodium_crypto_ipcrypt_pfx_keygen();
var_dump(strlen($gen_key) === SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES);
/* PFX error: wrong key length */
try {
sodium_crypto_ipcrypt_pfx_encrypt("10.0.0.1", "short");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* PFX error: invalid IP */
try {
sodium_crypto_ipcrypt_pfx_encrypt("not_an_ip", $key);
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* PFX error: wrong key length for decrypt */
try {
sodium_crypto_ipcrypt_pfx_decrypt("10.0.0.1", "short");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
?>
--EXPECT--
string(8) "10.0.0.1"
bool(true)
bool(true)
string(3) "::1"
bool(true)
bool(true)
sodium_crypto_ipcrypt_pfx_encrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES bytes long
sodium_crypto_ipcrypt_pfx_encrypt(): Argument #1 ($ip) must be a valid IP address
sodium_crypto_ipcrypt_pfx_decrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES bytes long

View File

@@ -0,0 +1,104 @@
--TEST--
Check for libsodium XOF SHAKE128
--EXTENSIONS--
sodium
--SKIPIF--
<?php
if (!defined('SODIUM_CRYPTO_XOF_SHAKE128_STATEBYTES')) print "skip libsodium without XOF support (requires >= 1.0.21)";
?>
--FILE--
<?php
/* One-shot: NIST test vector SHAKE128("") */
$out = sodium_crypto_xof_shake128(32, "");
var_dump(bin2hex($out));
/* One-shot: SHAKE128("abc") */
$out = sodium_crypto_xof_shake128(32, "abc");
var_dump(bin2hex($out));
/* Variable output length */
$out16 = sodium_crypto_xof_shake128(16, "abc");
$out64 = sodium_crypto_xof_shake128(64, "abc");
var_dump(strlen($out16));
var_dump(strlen($out64));
var_dump(bin2hex($out16) === substr(bin2hex($out64), 0, 32));
/* Streaming matches one-shot */
$state = sodium_crypto_xof_shake128_init();
sodium_crypto_xof_shake128_update($state, "abc");
$sq = sodium_crypto_xof_shake128_squeeze($state, 32);
var_dump(bin2hex($sq));
/* Multi-part update matches one-shot */
$state = sodium_crypto_xof_shake128_init();
sodium_crypto_xof_shake128_update($state, "a");
sodium_crypto_xof_shake128_update($state, "bc");
$sq = sodium_crypto_xof_shake128_squeeze($state, 32);
var_dump(bin2hex($sq));
/* Multiple squeezes concatenated match single squeeze */
$state = sodium_crypto_xof_shake128_init();
sodium_crypto_xof_shake128_update($state, "abc");
$sq1 = sodium_crypto_xof_shake128_squeeze($state, 16);
$sq2 = sodium_crypto_xof_shake128_squeeze($state, 16);
var_dump(bin2hex($sq1 . $sq2));
/* Domain separation produces different output */
$state_d = sodium_crypto_xof_shake128_init(0x42);
sodium_crypto_xof_shake128_update($state_d, "abc");
$sq_d = sodium_crypto_xof_shake128_squeeze($state_d, 32);
var_dump(bin2hex($sq_d));
var_dump(bin2hex($sq_d) !== bin2hex($sq));
/* Error: zero length */
try {
sodium_crypto_xof_shake128(0, "test");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* Error: negative length */
try {
sodium_crypto_xof_shake128(-1, "test");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* Error: domain out of range (0x00) */
try {
sodium_crypto_xof_shake128_init(0);
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* Error: domain out of range (0x80) */
try {
sodium_crypto_xof_shake128_init(0x80);
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* Error: bad state */
try {
$bad = "not_a_state";
sodium_crypto_xof_shake128_update($bad, "test");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
?>
--EXPECT--
string(64) "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26"
string(64) "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8"
int(16)
int(64)
bool(true)
string(64) "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8"
string(64) "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8"
string(64) "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8"
string(64) "f3a3a89c329e644a7d2351744d9a28c953698b64102e912085ce1f6d79fa311e"
bool(true)
sodium_crypto_xof_shake128(): Argument #1 ($length) must be a positive integer
sodium_crypto_xof_shake128(): Argument #1 ($length) must be a positive integer
sodium_crypto_xof_shake128_init(): Argument #1 ($domain) must be between 0x01 and 0x7f
sodium_crypto_xof_shake128_init(): Argument #1 ($domain) must be between 0x01 and 0x7f
sodium_crypto_xof_shake128_update(): Argument #1 ($state) must have a correct state length

View File

@@ -0,0 +1,80 @@
--TEST--
Check for libsodium XOF SHAKE256
--EXTENSIONS--
sodium
--SKIPIF--
<?php
if (!defined('SODIUM_CRYPTO_XOF_SHAKE256_STATEBYTES')) print "skip libsodium without XOF support (requires >= 1.0.21)";
?>
--FILE--
<?php
/* One-shot: NIST test vector SHAKE256("") */
$out = sodium_crypto_xof_shake256(32, "");
var_dump(bin2hex($out));
/* One-shot: SHAKE256("abc") */
$out = sodium_crypto_xof_shake256(32, "abc");
var_dump(bin2hex($out));
/* Variable output length */
$out16 = sodium_crypto_xof_shake256(16, "abc");
$out64 = sodium_crypto_xof_shake256(64, "abc");
var_dump(strlen($out16));
var_dump(strlen($out64));
var_dump(bin2hex($out16) === substr(bin2hex($out64), 0, 32));
/* Streaming matches one-shot */
$state = sodium_crypto_xof_shake256_init();
sodium_crypto_xof_shake256_update($state, "abc");
$sq = sodium_crypto_xof_shake256_squeeze($state, 32);
var_dump(bin2hex($sq));
/* Multi-part update */
$state = sodium_crypto_xof_shake256_init();
sodium_crypto_xof_shake256_update($state, "a");
sodium_crypto_xof_shake256_update($state, "bc");
$sq = sodium_crypto_xof_shake256_squeeze($state, 32);
var_dump(bin2hex($sq));
/* Domain separation */
$state_d = sodium_crypto_xof_shake256_init(0x42);
sodium_crypto_xof_shake256_update($state_d, "abc");
$sq_d = sodium_crypto_xof_shake256_squeeze($state_d, 32);
var_dump(bin2hex($sq_d));
/* Error: zero length */
try {
sodium_crypto_xof_shake256(0, "test");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* Error: bad state */
try {
$bad = "not_a_state";
sodium_crypto_xof_shake256_update($bad, "test");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* Error: squeeze bad length */
try {
$state = sodium_crypto_xof_shake256_init();
sodium_crypto_xof_shake256_update($state, "abc");
sodium_crypto_xof_shake256_squeeze($state, 0);
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
?>
--EXPECT--
string(64) "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f"
string(64) "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739"
int(16)
int(64)
bool(true)
string(64) "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739"
string(64) "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739"
string(64) "1259d63c872d50fee4500685419f489966971c0a77e2058fab0e48dfb12d24bc"
sodium_crypto_xof_shake256(): Argument #1 ($length) must be a positive integer
sodium_crypto_xof_shake256_update(): Argument #1 ($state) must have a correct state length
sodium_crypto_xof_shake256_squeeze(): Argument #2 ($length) must be a positive integer

View File

@@ -0,0 +1,112 @@
--TEST--
Check for libsodium XOF TurboSHAKE128 and TurboSHAKE256
--EXTENSIONS--
sodium
--SKIPIF--
<?php
if (!defined('SODIUM_CRYPTO_XOF_TURBOSHAKE128_STATEBYTES')) print "skip libsodium without XOF support (requires >= 1.0.21)";
?>
--FILE--
<?php
/* TurboSHAKE128 one-shot */
$out = sodium_crypto_xof_turboshake128(32, "");
var_dump(bin2hex($out));
$out = sodium_crypto_xof_turboshake128(32, "abc");
var_dump(bin2hex($out));
/* TurboSHAKE256 one-shot */
$out = sodium_crypto_xof_turboshake256(32, "");
var_dump(bin2hex($out));
$out = sodium_crypto_xof_turboshake256(32, "abc");
var_dump(bin2hex($out));
/* TurboSHAKE128 streaming matches one-shot */
$state = sodium_crypto_xof_turboshake128_init();
sodium_crypto_xof_turboshake128_update($state, "abc");
$sq = sodium_crypto_xof_turboshake128_squeeze($state, 32);
var_dump(bin2hex($sq));
/* TurboSHAKE256 streaming matches one-shot */
$state = sodium_crypto_xof_turboshake256_init();
sodium_crypto_xof_turboshake256_update($state, "abc");
$sq = sodium_crypto_xof_turboshake256_squeeze($state, 32);
var_dump(bin2hex($sq));
/* TurboSHAKE128 multi-part update */
$state = sodium_crypto_xof_turboshake128_init();
sodium_crypto_xof_turboshake128_update($state, "a");
sodium_crypto_xof_turboshake128_update($state, "bc");
$sq = sodium_crypto_xof_turboshake128_squeeze($state, 32);
var_dump(bin2hex($sq));
/* TurboSHAKE256 multi-part update */
$state = sodium_crypto_xof_turboshake256_init();
sodium_crypto_xof_turboshake256_update($state, "a");
sodium_crypto_xof_turboshake256_update($state, "bc");
$sq = sodium_crypto_xof_turboshake256_squeeze($state, 32);
var_dump(bin2hex($sq));
/* TurboSHAKE128 domain separation */
$state_d = sodium_crypto_xof_turboshake128_init(0x42);
sodium_crypto_xof_turboshake128_update($state_d, "abc");
$sq_d = sodium_crypto_xof_turboshake128_squeeze($state_d, 32);
var_dump(bin2hex($sq_d));
/* TurboSHAKE256 domain separation */
$state_d = sodium_crypto_xof_turboshake256_init(0x42);
sodium_crypto_xof_turboshake256_update($state_d, "abc");
$sq_d = sodium_crypto_xof_turboshake256_squeeze($state_d, 32);
var_dump(bin2hex($sq_d));
/* Variable output length */
$out16 = sodium_crypto_xof_turboshake128(16, "abc");
$out64 = sodium_crypto_xof_turboshake128(64, "abc");
var_dump(strlen($out16));
var_dump(strlen($out64));
var_dump(bin2hex($out16) === substr(bin2hex($out64), 0, 32));
/* TurboSHAKE128 error: zero length */
try {
sodium_crypto_xof_turboshake128(0, "test");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* TurboSHAKE256 error: bad state */
try {
$bad = "not_a_state";
sodium_crypto_xof_turboshake256_update($bad, "test");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* TurboSHAKE128 error: domain out of range */
try {
sodium_crypto_xof_turboshake128_init(0);
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
try {
sodium_crypto_xof_turboshake256_init(0x80);
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
?>
--EXPECT--
string(64) "1e415f1c5983aff2169217277d17bb538cd945a397ddec541f1ce41af2c1b74c"
string(64) "dcf1646dfe993a8eb6b782d1faaca6d82416a5dcf1de98ee3c6dbc5e1dc63018"
string(64) "367a329dafea871c7802ec67f905ae13c57695dc2c6663c61035f59a18f8e7db"
string(64) "63824b1431a7372e85edc022c9d7afdd027472fcfa33c887d6f5aaf8dc5d4db6"
string(64) "dcf1646dfe993a8eb6b782d1faaca6d82416a5dcf1de98ee3c6dbc5e1dc63018"
string(64) "63824b1431a7372e85edc022c9d7afdd027472fcfa33c887d6f5aaf8dc5d4db6"
string(64) "dcf1646dfe993a8eb6b782d1faaca6d82416a5dcf1de98ee3c6dbc5e1dc63018"
string(64) "63824b1431a7372e85edc022c9d7afdd027472fcfa33c887d6f5aaf8dc5d4db6"
string(64) "3f7566fb02630888cba2af090aaf544ac6e85484d8662335b0c0fd6b3c83ea1b"
string(64) "0137a7e8cca0b99e9bdd557a7caac1f21d65bc2a2ccbde1e1f8c702352a2bf30"
int(16)
int(64)
bool(true)
sodium_crypto_xof_turboshake128(): Argument #1 ($length) must be a positive integer
sodium_crypto_xof_turboshake256_update(): Argument #1 ($state) must have a correct state length
sodium_crypto_xof_turboshake128_init(): Argument #1 ($domain) must be between 0x01 and 0x7f
sodium_crypto_xof_turboshake256_init(): Argument #1 ($domain) must be between 0x01 and 0x7f

View File

@@ -0,0 +1,69 @@
--TEST--
Check for libsodium bin2ip/ip2bin helpers
--EXTENSIONS--
sodium
--SKIPIF--
<?php
if (!defined('SODIUM_CRYPTO_IPCRYPT_KEYBYTES')) print "skip libsodium without ipcrypt (requires >= 1.0.21)";
?>
--FILE--
<?php
/* IPv4 roundtrip */
$bin = sodium_ip2bin("192.168.1.1");
var_dump(strlen($bin));
var_dump(bin2hex($bin));
var_dump(sodium_bin2ip($bin));
/* IPv6 roundtrip */
$bin6 = sodium_ip2bin("::1");
var_dump(bin2hex($bin6));
var_dump(sodium_bin2ip($bin6));
/* IPv4-mapped IPv6 preserved as IPv4 */
$bin4 = sodium_ip2bin("10.0.0.1");
var_dump(bin2hex($bin4));
var_dump(sodium_bin2ip($bin4));
/* Full IPv6 address */
$bin_full = sodium_ip2bin("fe80::1");
var_dump(bin2hex($bin_full));
var_dump(sodium_bin2ip($bin_full));
/* ip2bin -> bin2ip roundtrip for various addresses */
$addrs = ["0.0.0.0", "255.255.255.255", "127.0.0.1", "::ffff:192.168.0.1", "2001:db8::1"];
foreach ($addrs as $addr) {
$result = sodium_bin2ip(sodium_ip2bin($addr));
echo "$addr => $result\n";
}
/* Error: bin2ip wrong length */
try {
sodium_bin2ip("short");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
/* Error: ip2bin invalid address */
try {
sodium_ip2bin("not_an_ip");
} catch (SodiumException $e) {
echo $e->getMessage() . "\n";
}
?>
--EXPECT--
int(16)
string(32) "00000000000000000000ffffc0a80101"
string(11) "192.168.1.1"
string(32) "00000000000000000000000000000001"
string(3) "::1"
string(32) "00000000000000000000ffff0a000001"
string(8) "10.0.0.1"
string(32) "fe800000000000000000000000000001"
string(7) "fe80::1"
0.0.0.0 => 0.0.0.0
255.255.255.255 => 255.255.255.255
127.0.0.1 => 127.0.0.1
::ffff:192.168.0.1 => 192.168.0.1
2001:db8::1 => 2001:db8::1
sodium_bin2ip(): Argument #1 ($bin) must be 16 bytes long
sodium_ip2bin(): Argument #1 ($ip) must be a valid IP address