From ee8fb8dca47a27fefda50e915a18a7178a804fc8 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sat, 17 Jan 2026 14:49:53 +0100 Subject: [PATCH] ext/sodium: Add support for libsodium 1.0.21 APIs 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 --- NEWS | 3 + ext/sodium/libsodium.c | 914 ++++++++++++++++++++ ext/sodium/libsodium.stub.php | 166 ++++ ext/sodium/libsodium_arginfo.h | 201 ++++- ext/sodium/tests/crypto_ipcrypt.phpt | 63 ++ ext/sodium/tests/crypto_ipcrypt_nd.phpt | 98 +++ ext/sodium/tests/crypto_ipcrypt_pfx.phpt | 65 ++ ext/sodium/tests/crypto_xof_shake128.phpt | 104 +++ ext/sodium/tests/crypto_xof_shake256.phpt | 80 ++ ext/sodium/tests/crypto_xof_turboshake.phpt | 112 +++ ext/sodium/tests/sodium_bin2ip.phpt | 69 ++ 11 files changed, 1874 insertions(+), 1 deletion(-) create mode 100644 ext/sodium/tests/crypto_ipcrypt.phpt create mode 100644 ext/sodium/tests/crypto_ipcrypt_nd.phpt create mode 100644 ext/sodium/tests/crypto_ipcrypt_pfx.phpt create mode 100644 ext/sodium/tests/crypto_xof_shake128.phpt create mode 100644 ext/sodium/tests/crypto_xof_shake256.phpt create mode 100644 ext/sodium/tests/crypto_xof_turboshake.phpt create mode 100644 ext/sodium/tests/sodium_bin2ip.phpt diff --git a/NEWS b/NEWS index 3ea4407433664..fd2f2fa82ec80 100644 --- a/NEWS +++ b/NEWS @@ -104,6 +104,9 @@ PHP NEWS . Fixed GH-20532 (socket_addrinfo_lookup gives the error code with a new optional parameter). (David Carlier) +- Sodium: + . Added support for libsodium 1.0.21 IPcrypt and XOF APIs. (jedisct1) + - SPL: . DirectoryIterator key can now work better with filesystem supporting larger directory indexing. (David Carlier) diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index 7d36fbb892884..bb11a6ef9116f 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -3913,3 +3913,917 @@ PHP_FUNCTION(sodium_crypto_core_ristretto255_sub) RETURN_NEW_STR(r); } #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 diff --git a/ext/sodium/libsodium.stub.php b/ext/sodium/libsodium.stub.php index 4bf6fade9136f..9fda5f4ddd73e 100644 --- a/ext/sodium/libsodium.stub.php +++ b/ext/sodium/libsodium.stub.php @@ -801,4 +801,170 @@ function sodium_base642bin(#[\SensitiveParameter] string $string, int $id, strin */ 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 {} diff --git a/ext/sodium/libsodium_arginfo.h b/ext/sodium/libsodium_arginfo.h index 0af7528eec72a..1b291e9a23300 100644 --- a/ext/sodium/libsodium_arginfo.h +++ b/ext/sodium/libsodium_arginfo.h @@ -1,5 +1,5 @@ /* 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_END_ARG_INFO() @@ -483,6 +483,95 @@ ZEND_END_ARG_INFO() #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); #if defined(HAVE_AESGCM) ZEND_FUNCTION(sodium_crypto_aead_aes256gcm_decrypt); @@ -616,6 +705,40 @@ ZEND_FUNCTION(sodium_hex2bin); ZEND_FUNCTION(sodium_bin2base64); ZEND_FUNCTION(sodium_base642bin); #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[] = { 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) #endif 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 }; @@ -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_NONREDUCEDSCALARBYTES", crypto_core_ristretto255_NONREDUCEDSCALARBYTES, CONST_PERSISTENT); #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) @@ -1060,6 +1241,24 @@ static void register_libsodium_symbols(int module_number) #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); +#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) diff --git a/ext/sodium/tests/crypto_ipcrypt.phpt b/ext/sodium/tests/crypto_ipcrypt.phpt new file mode 100644 index 0000000000000..f398d21c70fc1 --- /dev/null +++ b/ext/sodium/tests/crypto_ipcrypt.phpt @@ -0,0 +1,63 @@ +--TEST-- +Check for libsodium ipcrypt +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +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 diff --git a/ext/sodium/tests/crypto_ipcrypt_nd.phpt b/ext/sodium/tests/crypto_ipcrypt_nd.phpt new file mode 100644 index 0000000000000..fed36bbda4447 --- /dev/null +++ b/ext/sodium/tests/crypto_ipcrypt_nd.phpt @@ -0,0 +1,98 @@ +--TEST-- +Check for libsodium ipcrypt non-deterministic (nd) and extended (ndx) +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +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 diff --git a/ext/sodium/tests/crypto_ipcrypt_pfx.phpt b/ext/sodium/tests/crypto_ipcrypt_pfx.phpt new file mode 100644 index 0000000000000..1ee51ef1f0e11 --- /dev/null +++ b/ext/sodium/tests/crypto_ipcrypt_pfx.phpt @@ -0,0 +1,65 @@ +--TEST-- +Check for libsodium ipcrypt prefix-preserving (pfx) +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +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 diff --git a/ext/sodium/tests/crypto_xof_shake128.phpt b/ext/sodium/tests/crypto_xof_shake128.phpt new file mode 100644 index 0000000000000..cb075b7ec2855 --- /dev/null +++ b/ext/sodium/tests/crypto_xof_shake128.phpt @@ -0,0 +1,104 @@ +--TEST-- +Check for libsodium XOF SHAKE128 +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +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 diff --git a/ext/sodium/tests/crypto_xof_shake256.phpt b/ext/sodium/tests/crypto_xof_shake256.phpt new file mode 100644 index 0000000000000..3e69167133286 --- /dev/null +++ b/ext/sodium/tests/crypto_xof_shake256.phpt @@ -0,0 +1,80 @@ +--TEST-- +Check for libsodium XOF SHAKE256 +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +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 diff --git a/ext/sodium/tests/crypto_xof_turboshake.phpt b/ext/sodium/tests/crypto_xof_turboshake.phpt new file mode 100644 index 0000000000000..1f404140cc0ba --- /dev/null +++ b/ext/sodium/tests/crypto_xof_turboshake.phpt @@ -0,0 +1,112 @@ +--TEST-- +Check for libsodium XOF TurboSHAKE128 and TurboSHAKE256 +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +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 diff --git a/ext/sodium/tests/sodium_bin2ip.phpt b/ext/sodium/tests/sodium_bin2ip.phpt new file mode 100644 index 0000000000000..ab72b4b297acc --- /dev/null +++ b/ext/sodium/tests/sodium_bin2ip.phpt @@ -0,0 +1,69 @@ +--TEST-- +Check for libsodium bin2ip/ip2bin helpers +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- + 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