Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
1301914
move f to direct k2 header api
LLirikkkk Sep 29, 2026
1f8d229
refactor f arguments types
LLirikkkk Sep 30, 2026
4d127d5
refactor k2_openssl_encrypt arguments types
LLirikkkk Sep 30, 2026
f0c298b
refactor f arguments types
LLirikkkk Sep 30, 2026
9354e1f
improve parse_cipher_algorithm perf
LLirikkkk Oct 12, 2026
7737d59
improve is_*_algorithm function perf
LLirikkkk Oct 12, 2026
2a5ccaa
improve is_*_algorithm function perf
LLirikkkk Oct 12, 2026
9e5244b
improve is_*_algorithm function perf
LLirikkkk Oct 12, 2026
5dbd856
improve is_*_algorithm function perf
LLirikkkk Oct 12, 2026
f68c88d
add cipher algo traits
LLirikkkk Oct 13, 2026
0baf313
refactor f
LLirikkkk Oct 13, 2026
646fc7b
refactor f
LLirikkkk Oct 13, 2026
d8eda41
refactor f
LLirikkkk Oct 13, 2026
73f419c
rename k2_openssl_encrypt arguments
LLirikkkk Oct 13, 2026
1ba746e
refactor f
LLirikkkk Oct 15, 2026
81dd019
refactor f
LLirikkkk Oct 15, 2026
6247bae
implement all hash functions via k2 header
LLirikkkk Oct 15, 2026
a12c236
remove redundant hash algos
LLirikkkk Oct 15, 2026
7e73a2e
remove interurptible from php doc
LLirikkkk Oct 15, 2026
cf48d46
add hash traits
LLirikkkk Oct 20, 2026
e6776fe
make hash functions zero copy
LLirikkkk Oct 20, 2026
e8832d4
implement f via k2 header
LLirikkkk Oct 20, 2026
e233feb
implement f and f via k2 header
LLirikkkk Oct 21, 2026
23ba288
implement f and f via k2 header
LLirikkkk Oct 21, 2026
31cfe59
implement f and f via k2 header
LLirikkkk Oct 21, 2026
3e022df
implement pkey_get_public and pkey_get_private functions via k2 header
LLirikkkk Oct 21, 2026
0651d05
implement random_pseudo_bytes function via k2 header
LLirikkkk Oct 21, 2026
09019c7
add crypto cache
LLirikkkk Oct 22, 2026
3dee51f
extend hash algorithms support
LLirikkkk Oct 22, 2026
ee52128
implement sign and verify functions via k2 header
LLirikkkk Oct 23, 2026
19f6909
implement openssl_x509_parse via k2 header
LLirikkkk Oct 27, 2026
17550bb
define unsupported constants for md2 and md4
LLirikkkk Oct 27, 2026
d76452e
define unsupported constants for md2 and md4
LLirikkkk Oct 27, 2026
1752cae
remove constants for md2 and md4
LLirikkkk Oct 28, 2026
9659332
add constants for md2 and md4
LLirikkkk Oct 29, 2026
ad37920
add support of md2 and md4
LLirikkkk Nov 2, 2026
ca2725d
add cache for pkeys
LLirikkkk Nov 5, 2026
4ab9859
add comments for k2-api
LLirikkkk Nov 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 10 additions & 27 deletions builtin-functions/kphp-light/stdlib/crypto-functions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,50 @@

// ===== SUPPORTED =====

define('OPENSSL_ALGO_SHA1' , 0x215fb97d);
define('OPENSSL_ALGO_MD5' , 0x257ddf13);
define('OPENSSL_ALGO_MD4' , 0x317fe3d1);
define('OPENSSL_ALGO_MD2' , 0x5aca6998);
define('OPENSSL_ALGO_DSS1' , 0xf572d6b6);
define('OPENSSL_ALGO_SHA224', 0x8bce55e9);
define('OPENSSL_ALGO_SHA256', 0x6c977f8c);
define('OPENSSL_ALGO_SHA384', 0xf54c2608);
define('OPENSSL_ALGO_SHA512', 0x225df2b6);
define('OPENSSL_ALGO_RMD160', 0x1887e6b4);
define('OPENSSL_ALGO_DSS1' , 0);
define('OPENSSL_ALGO_SHA1' , 1);
define('OPENSSL_ALGO_SHA224', 2);
define('OPENSSL_ALGO_SHA256', 3);
define('OPENSSL_ALGO_SHA384', 4);
define('OPENSSL_ALGO_SHA512', 5);
define('OPENSSL_ALGO_MD5' , 6);
define('OPENSSL_ALGO_RMD160', 7);
define('OPENSSL_ALGO_MD2' , 8);
define('OPENSSL_ALGO_MD4' , 9);

define('OPENSSL_RAW_DATA', 1);
define('OPENSSL_ZERO_PADDING', 2);
define('OPENSSL_DONT_ZERO_PAD_KEY', 4);


/** @kphp-extern-func-info interruptible */
function openssl_sign ($data ::: string, &$signature ::: string, $priv_key_id ::: string, $signature_alg ::: int = 1) ::: bool;

/** @kphp-extern-func-info interruptible */
function openssl_verify ($data ::: string, $signature ::: string, $pub_key_id ::: string, $signature_alg ::: int = 1) ::: int;

/** @kphp-extern-func-info interruptible */
function openssl_random_pseudo_bytes ($length ::: int) ::: string | false;

/** @kphp-extern-func-info interruptible */
function openssl_x509_parse ($x509cert ::: string, $shortnames ::: bool = true) ::: mixed[] | false;

function openssl_get_cipher_methods($aliases ::: bool = false) ::: string[];

function openssl_cipher_iv_length($method ::: string) ::: int | false;

/** @kphp-extern-func-info interruptible */
function openssl_encrypt($data ::: string, $method ::: string, $key ::: string, $options ::: int = 0, $iv ::: string = '',
string &$tag = TODO, $aad ::: string = '', $tag_length ::: int = 16) ::: string | false;

/** @kphp-extern-func-info interruptible */
function openssl_decrypt($data ::: string, $method ::: string, $key ::: string, $options ::: int = 0, $iv ::: string = '',
$tag ::: string = '', $aad ::: string = '') ::: string | false;

/** @kphp-extern-func-info interruptible */
function openssl_pkey_get_private ($key ::: string, $passphrase ::: string = '') ::: string | false;
/** @kphp-extern-func-info interruptible */
function openssl_pkey_get_public ($key ::: string) ::: string | false;

/** @kphp-extern-func-info interruptible */
function openssl_public_encrypt ($data ::: string, &$result ::: mixed, $key ::: string) ::: bool;
/** @kphp-extern-func-info interruptible */
function openssl_private_decrypt ($data ::: string, &$result ::: mixed, $key ::: string) ::: bool;

function hash_algos () ::: string[];
function hash_hmac_algos () ::: string[];

/** @kphp-extern-func-info interruptible */
function hash ($algo ::: string, $data ::: string, $raw_output ::: bool = false) ::: string;
/** @kphp-extern-func-info interruptible */
function hash_hmac ($algo ::: string, $data ::: string, $key ::: string, $raw_output ::: bool = false) ::: string;

/** @kphp-extern-func-info interruptible */
function sha1 ($s ::: string, $raw_output ::: bool = false) ::: string;
function md5 ($s ::: string, $raw_output ::: bool = false): string;

Expand Down Expand Up @@ -93,9 +78,7 @@ define('PKCS7_NOATTR', 0x100);
/** @kphp-extern-func-info stub generation-required */
function openssl_x509_verify ($x509cert ::: string, $public_key ::: string) ::: int;


/** @kphp-extern-func-info stub generation-required */
function openssl_pkcs7_sign($infile ::: string, $outfile ::: string,
$sign_cert ::: string, $priv_key ::: string,
string[] $headers, $flags ::: int = PKCS7_DETACHED, $extra_certs ::: string = "") ::: bool;

19 changes: 14 additions & 5 deletions runtime-common/stdlib/string/string-functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,24 @@
namespace kphp {
namespace strings {

inline void bin2hex(const char* src, size_t src_len, char* dst, size_t dst_len) noexcept {
php_assert(dst_len >= 2 * src_len);
const auto& string_lib_constants{StringLibConstants::get()};
for (size_t i = src_len; i-- > 0;) {
dst[2 * i + 1] = string_lib_constants.lhex_digits[src[i] & 15];
dst[2 * i] = string_lib_constants.lhex_digits[(src[i] >> 4) & 15];
}
}

inline void bin2hex(char* buf, size_t src_len, size_t buf_len) noexcept {
bin2hex(buf, src_len, buf, buf_len);
}

inline string bin2hex(std::string_view str) noexcept {
int len = str.size();
string result(2 * len, false);

const auto& string_lib_constants{StringLibConstants::get()};
for (int i = 0; i < len; i++) {
result[2 * i] = string_lib_constants.lhex_digits[(str[i] >> 4) & 15];
result[2 * i + 1] = string_lib_constants.lhex_digits[str[i] & 15];
}
bin2hex(str.data(), str.size(), result.buffer(), result.size());

return result;
}
Expand Down
239 changes: 239 additions & 0 deletions runtime-light/k2-platform/k2-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,245 @@ inline int32_t component_access(std::string_view component_name) noexcept {
return k2_component_access(component_name.size(), component_name.data());
}

inline std::expected<void, int32_t> openssl_random_pseudo_bytes(std::span<char> bytes) noexcept {
if (auto ret{k2_openssl_random_pseudo_bytes(bytes.data(), bytes.size())}; ret != 0) {
return std::unexpected(ret);
}

return {};
}

inline std::expected<void, int32_t> openssl_x509_open(std::string_view data) noexcept {
if (auto error_code{k2_openssl_x509_open(data.data(), data.size())}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {};
}

inline std::expected<size_t, int32_t> openssl_x509_get_subject_name(std::span<char> result, bool retry = false) noexcept {
size_t result_written{0};
if (auto error_code{k2_openssl_x509_get_subject_name(result.data(), result.size(), std::addressof(result_written), retry)}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result_written};
}

inline std::expected<size_t, int32_t> openssl_x509_name_entry_count(bool is_issuer) noexcept {
size_t result{0};
if (auto error_code{k2_openssl_x509_name_entry_count(is_issuer, std::addressof(result))}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result};
}

inline std::expected<size_t, int32_t> openssl_x509_name_entry_key(bool is_issuer, bool shortnames, size_t index, std::span<char> result) noexcept {
size_t result_written{0};
if (auto error_code{k2_openssl_x509_name_entry_key(is_issuer, shortnames, index, result.data(), result.size(), std::addressof(result_written))};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result_written};
}

inline std::expected<size_t, int32_t> openssl_x509_name_entry_value(bool is_issuer, size_t index, std::span<char> result) noexcept {
size_t result_written{0};
if (auto error_code{k2_openssl_x509_name_entry_value(is_issuer, index, result.data(), result.size(), std::addressof(result_written))};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result_written};
}

inline std::expected<void, int32_t> openssl_x509_get_hash(std::span<char> result) noexcept {
if (auto error_code{k2_openssl_x509_get_hash(result.data(), result.size())}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {};
}

inline std::expected<int64_t, int32_t> openssl_x509_get_version() noexcept {
int64_t result{0};
if (auto error_code{k2_openssl_x509_get_version(std::addressof(result))}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result};
}

inline std::expected<int64_t, int32_t> openssl_x509_get_valid_from() noexcept {
int64_t result{0};
if (auto error_code{k2_openssl_x509_get_valid_from(std::addressof(result))}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result};
}

inline std::expected<int64_t, int32_t> openssl_x509_get_valid_to() noexcept {
int64_t result{0};
if (auto error_code{k2_openssl_x509_get_valid_to(std::addressof(result))}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result};
}

inline std::expected<size_t, int32_t> openssl_x509_purpose_count() noexcept {
size_t result{0};
if (auto error_code{k2_openssl_x509_purpose_count(std::addressof(result))}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result};
}

inline std::expected<int64_t, int32_t> openssl_x509_purpose_id(size_t index) noexcept {
int64_t result{0};
if (auto error_code{k2_openssl_x509_purpose_id(index, std::addressof(result))}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result};
}

inline std::expected<bool, int32_t> openssl_x509_purpose_check(size_t index, bool ca) noexcept {
bool result{false};
if (auto error_code{k2_openssl_x509_purpose_check(index, ca, std::addressof(result))}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return result;
}

inline std::expected<size_t, int32_t> openssl_x509_purpose_name(size_t index, bool shortnames, std::span<char> result) noexcept {
size_t result_written{0};
if (auto error_code{k2_openssl_x509_purpose_name(index, shortnames, result.data(), result.size(), std::addressof(result_written))};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result_written};
}

inline std::expected<size_t, int32_t> openssl_sign(HashAlgorithm algorithm, std::string_view data, std::string_view private_key, std::span<char> result,
bool retry = false) noexcept {
size_t result_written{0};
if (auto error_code{k2_openssl_sign(algorithm, data.data(), data.size(), private_key.data(), private_key.size(), result.data(), result.size(),
std::addressof(result_written), retry)};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result_written};
}

inline std::expected<bool, int32_t> openssl_verify(HashAlgorithm algorithm, std::string_view data, std::string_view public_key,
std::string_view signature) noexcept {
int32_t is_valid{0};
if (auto error_code{k2_openssl_verify(algorithm, data.data(), data.size(), public_key.data(), public_key.size(), signature.data(), signature.size(),
std::addressof(is_valid))};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {is_valid != 0};
}

inline std::expected<size_t, int32_t> openssl_pkey_get_public(std::string_view public_key, std::span<char> result) noexcept {
size_t result_written{0};
if (auto error_code{k2_openssl_pkey_get_public(public_key.data(), public_key.size(), result.data(), result.size(), std::addressof(result_written))};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result_written};
}

inline std::expected<size_t, int32_t> openssl_pkey_get_private(std::string_view private_key, std::string_view passphrase, std::span<char> result) noexcept {
size_t result_written{0};
if (auto error_code{k2_openssl_pkey_get_private(private_key.data(), private_key.size(), passphrase.data(), passphrase.size(), result.data(), result.size(),
std::addressof(result_written))};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {result_written};
}

inline std::expected<size_t, int32_t> openssl_encrypt(CipherAlgorithm algorithm, BlockPadding padding, std::string_view key, std::string_view iv,
std::string_view aad, std::string_view data, std::span<char> encrypted_data,
std::span<char> received_tag) noexcept {
size_t encrypted_data_written{0};
if (auto error_code{k2_openssl_encrypt(algorithm, padding, key.data(), key.size(), iv.data(), iv.size(), aad.data(), aad.size(), data.data(), data.size(),
encrypted_data.data(), encrypted_data.size(), std::addressof(encrypted_data_written), received_tag.data(),
received_tag.size())};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {encrypted_data_written};
}

inline std::expected<size_t, int32_t> openssl_decrypt(CipherAlgorithm algorithm, BlockPadding padding, std::string_view key, std::string_view iv,
std::string_view aad, std::string_view tag, std::string_view data,
std::span<char> decrypted_data) noexcept {
size_t decrypted_data_written{0};
if (auto error_code{k2_openssl_decrypt(algorithm, padding, key.data(), key.size(), iv.data(), iv.size(), aad.data(), aad.size(), tag.data(), tag.size(),
data.data(), data.size(), decrypted_data.data(), decrypted_data.size(), std::addressof(decrypted_data_written))};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {decrypted_data_written};
}

inline std::expected<size_t, int32_t> openssl_public_encrypt(std::string_view data, std::span<char> encrypted_data, std::string_view public_key,
RsaPadding padding, bool retry = false) noexcept {
size_t encrypted_data_written{0};
if (auto error_code{k2_openssl_public_encrypt(data.data(), data.size(), encrypted_data.data(), encrypted_data.size(), public_key.data(), public_key.size(),
padding, std::addressof(encrypted_data_written), retry)};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {encrypted_data_written};
}

inline std::expected<size_t, int32_t> openssl_private_decrypt(std::string_view data, std::span<char> decrypted_data, std::string_view private_key,
RsaPadding padding) noexcept {
size_t decrypted_data_written{0};
if (auto error_code{k2_openssl_private_decrypt(data.data(), data.size(), decrypted_data.data(), decrypted_data.size(), private_key.data(), private_key.size(),
padding, std::addressof(decrypted_data_written))};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {decrypted_data_written};
}

inline std::expected<void, int32_t> hash(HashAlgorithm algorithm, std::string_view data, std::span<char> hashed_data) noexcept {
if (auto error_code{k2_hash(algorithm, data.data(), data.size(), hashed_data.data(), hashed_data.size())}; error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {};
}

inline std::expected<void, int32_t> hash_hmac(HashAlgorithm algorithm, std::string_view data, std::string_view key, std::span<char> hashed_data) noexcept {
if (auto error_code{k2_hash_hmac(algorithm, data.data(), data.size(), key.data(), key.size(), hashed_data.data(), hashed_data.size())};
error_code != k2::errno_ok) {
return std::unexpected{error_code};
}

return {};
}

inline std::expected<k2::descriptor, int32_t> rpc_send_request(std::string_view actor_name, std::span<const std::byte> request_buffer,
k2::RpcKind rpc_kind) noexcept {
k2::descriptor descriptor{};
Expand Down
Loading
Loading