# libSceLibreSsl3 technical debt ### Unknown function info - [libSceLibreSsl3 pending exports](../../../core/libs/prx/libSceLibreSsl3/Export.cpp) - 77 named callable exports, excluding `CRYPTO_memcmp`, `MD5`, `SHA1`, `d2i_ASN1_INTEGER`, `EVP_PKEY_up_ref`, `EC_KEY_up_ref`, `RSA_up_ref`, `EVP_PKEY_get0_RSA`, `EVP_PKEY_get0_DSA` and `EVP_PKEY_get0_DH`, remain unimplemented from the [PS5 3.20 export table](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceLibreSsl3.c), cross-checked against the same module in PS5 firmware 13.60. Their signatures and behaviour are unverified; the declarations use the no-parameter unknown-signature convention and throw through `NotImplemented_nid_no_patch`. ### Functional - [ASN.1 integer decoding](../../../core/libs/prx/libSceLibreSsl3/src/IntegerDecoder.cpp) - nothing is checked on a console, and the console's application-heap ABI is unverified. Rejections, allocation failures, their error codes and the old output follow [13.42 native-PC evidence](https://github.com/boykopovar/AnyPS5/pull/10948#issuecomment-6412137728) from a recording allocator. Nonnegative null input faults natively and throws here. Error combinations the evidence does not cover and content over `INT_MAX` bytes follow [LibreSSL 4.0.0](https://github.com/libressl/openbsd/tree/ce488b78e0bd994780569df718596b9776ff681a/src/lib/libcrypto/asn1). Closes when: compared with the console. - [CRYPTO_memcmp](../../../core/libs/prx/libSceLibreSsl3/Export.cpp) follows the public [LibreSSL signature and equality contract](https://man.openbsd.org/CRYPTO_memcmp.3), without PS5 verification. The exact nonzero result for unequal buffers is unspecified by that contract. Content-independent execution of its volatile byte reads still depends on the compiler; inspect optimized code when changing toolchains. Closes when: measured on a PS5 and the supported toolchains' generated code is checked. - [MD5 and SHA1](../../../core/libs/prx/libSceLibreSsl3/src/Digest.cpp) (libSceLibreSsl3) - follow LibreSSL's [md5.c, sha1.c](https://github.com/libressl/openbsd/tree/bc9483725c5815efb64b6d9acc52fc5fba139212/src/lib/libcrypto) and hash through libSceLibreSsl's `MD5_*` and `SHA1_*`. A null digest buffer, which LibreSSL 4.0.0 does not check, throws. Nothing is checked on the console - [EVP_PKEY_up_ref, EC_KEY_up_ref and RSA_up_ref](../../../core/libs/prx/libSceLibreSsl3/src/Key.cpp) - console layouts and retain/release interoperability are unverified. The 32-byte EVP, 64-byte EC and 152-byte RSA layouts, with counters at offsets 4, 48 and 104, follow [LibreSSL 4.0.0](https://github.com/libressl/openbsd/tree/ce488b78e0bd994780569df718596b9776ff681a/src/lib/libcrypto) `evp/evp_local.h`, `evp/p_lib.c`, `ec/ec_local.h`, `ec/ec_key.c`, `rsa/rsa_local.h` and `rsa/rsa_lib.c`; the RSA layout has no `engine` field, unlike libSceLibreSsl's `LibreSslRsa`. Atomic retains replace its internal mutex; future releases must synchronize with the same counters. With no key constructors/destructors in this module, tests use caller-owned objects without validating allocator or destruction compatibility. Null keys and signed-counter overflow, undefined upstream, throw without mutation. Closes when: console layouts and lifetime interoperability are measured. - [EVP_PKEY_get0_RSA, EVP_PKEY_get0_DSA and EVP_PKEY_get0_DH](../../../core/libs/prx/libSceLibreSsl3/src/PkeyGetters.cpp) (libSceLibreSsl3) - a key of another type throws, where [LibreSSL 4.0.0](https://github.com/libressl/openbsd/blob/ce488b78e0bd994780569df718596b9776ff681a/src/lib/libcrypto/evp/p_lib.c#L630-L751) queues `EVP_R_EXPECTING_AN_RSA_KEY`, `EVP_R_EXPECTING_A_DSA_KEY` or `EVP_R_EXPECTING_A_DH_KEY` and returns NULL, because the LibreSSL3 error queue is not modelled; a null key throws, where LibreSSL dereferences it. A matching key returns the inner key pointer of the 32-byte layout without taking a reference: `EVP_PKEY_RSA` (6) or `EVP_PKEY_RSA_PSS` (912) for RSA, `EVP_PKEY_DSA` (116) and `EVP_PKEY_DH` (28). None of this is verified on a PS5 - [Parent export forwarding](../../../core/libs/prx/libSceLibreSsl3/ParentExports.cpp) exposes 395 parent-library exports on Windows through IAT tail jumps without changing their ABI. Non-Windows hosts use their existing dependency lookup. Static COFF inspection verifies names, parent imports and tail jumps; Windows loading and runtime behavior remain unverified. Parent functions retain their existing implementation limitations. - [EVP_MD_CTX_md](../../../core/libs/prx/libSceLibreSsl3/src/DigestContext.cpp) (libSceLibreSsl3) - nothing is checked on the console. As in [LibreSSL 4.0.0](https://github.com/libressl/openbsd/blob/ce488b78e0bd994780569df718596b9776ff681a/src/lib/libcrypto/evp/evp_digest.c) `evp_digest.c`, a null context returns null and any other returns its first field, `digest`. That field is first in 4.0.0's `evp_local.h` and in the [2.5.4 layout](https://github.com/libressl/openbsd/blob/2e2c612066aa993717528a0249c15c51128d61cb/src/lib/libcrypto/evp/evp.h) of the contexts the forwarded libSceLibreSsl exports handle; the layouts differ after it, so the context and digest are declared opaque. Closes when: compared with the console. - [EVP_CIPHER_key_length and EVP_CIPHER_iv_length](../../../core/libs/prx/libSceLibreSsl3/src/Cipher.cpp) (libSceLibreSsl3) - nothing is checked on the console. They return `key_len` and `iv_len` from the 80-byte `EVP_CIPHER` of [LibreSSL 4.0.0](https://github.com/libressl/openbsd/tree/ce488b78e0bd994780569df718596b9776ff681a/src/lib/libcrypto/evp) `evp_local.h` and `evp_cipher.c`. The fields are at offsets 8 and 12, as in the [2.5.4 layout](https://github.com/libressl/openbsd/blob/2e2c612066aa993717528a0249c15c51128d61cb/src/lib/libcrypto/evp/evp.h) of the ciphers the forwarded libSceLibreSsl exports handle. A null cipher, which LibreSSL dereferences, throws. Closes when: compared with the console. - [X509_VERIFY_PARAM_set_flags](../../../core/libs/prx/libSceLibreSsl3/src/X509VerifyParam.cpp) (libSceLibreSsl3) - nothing is checked on the console. It ORs the flags into `flags` and returns 1, as both [LibreSSL 2.5.4](https://github.com/libressl/openbsd/blob/2e2c612066aa993717528a0249c15c51128d61cb/src/lib/libcrypto/x509/x509_vpm.c) and [4.0.0](https://github.com/libressl/openbsd/blob/ce488b78e0bd994780569df718596b9776ff681a/src/lib/libcrypto/x509/x509_vpm.c) `x509_vpm.c` do. They differ when `EXPLICIT_POLICY`, `INHIBIT_ANY` or `INHIBIT_MAP` is set while `POLICY_CHECK` is neither set nor requested: 2.5.4 also adds `POLICY_CHECK` and 4.0.0 does not. The console's choice is unknown, so that case throws through `NotImplemented_nid_no_patch` and leaves the parameters unchanged. It writes libSceLibreSsl's 2.5.4 `LibreSslX509VerifyParam`, whose `flags` is at offset 24 as in 4.0.0. Null parameters throw. Closes when: the console's policy behaviour is measured. - [sk_new, sk_push and sk_free](../../../core/libs/prx/libSceLibreSsl3/src/Stack.cpp) (libSceLibreSsl3) - follow [LibreSSL 4.0.0](https://github.com/libressl/openbsd/blob/ce488b78e0bd994780569df718596b9776ff681a/src/lib/libcrypto/stack/stack.c) `stack.c` with libSceLibreSsl's 32-byte `_STACK` layout, which `stack_local.h` keeps there. Stacks and element arrays come from the guest heap, so the forwarded `sk_pop_free` can release them. Nothing is checked on the console. Where LibreSSL faults or overflows, they throw: `sk_push` on a null stack, on a negative element count, on a null element array it does not regrow, or when the element array cannot double without overflowing `int` ### Additional callable export inventory - [Additional exports](../../../core/libs/prx/libSceLibreSsl3/AdditionalExports.cpp) declare 176 callable exports: 50 named and 126 known only by NID. Every entry throws. Parameterless `int` declarations are unknown-signature placeholders, not verified ABI contracts. Names/NIDs match the 13.60 export table. No functional implementation or title unblock is claimed. | Name | NID | | --- | --- | | `EC_KEY_set_asn1_flag` | `++b0FizBrJk` | | `BIO_set_init` | `+STC2BUY9vY` | | `EC_POINT_get_affine_coordinates_GFp` | `+Tu0gXSas9s` | | `tls_config_set_cert_mem` | `+bQfpiUHRVk` | | `SSL_SESSION_get_protocol_version` | `0BW+8jTsY54` | | `X509_NAME_add_entry_by_txt` | `0IxWzLyU8PI` | | `SSL_SESSION_get_timeout` | `0JcHkrKJ9iw` | | `BIO_meth_free` | `13BHMSblVyY` | | `tls_handshake` | `27Fuliv3Om8` | | `AUTHORITY_KEYID_free` | `2bIZM-OfE8Y` | | `X509V3_EXT_d2i` | `2l+JidqxyZQ` | | `TLS_method` | `31eWdro1jqs` | | `unknown` | `3KZ-L4y1gak` | | `EVP_chacha20_poly1305` | `3m4CmAyOXwQ` | | `BIO_clear_flags` | `3sypCuBDdQs` | | `EVP_chacha20` | `3tGgkjBQ82A` | | `ASN1_INTEGER_set` | `3v2Omd4sqcU` | | `RSA_set0_factors` | `3wlK0tLONvk` | | `X509_set_pubkey` | `409ieWBMPUk` | | `BIO_get_shutdown` | `44M+SEbpNdQ` | | `tls_accept_socket` | `4Q3bvOy4LY8` | | `unknown` | `4pEl-5DmrrM` | | `SSL_set_accept_state` | `5BoCLZK9mGk` | | `BIO_meth_set_write` | `5DhOJmgra8E` | | `BIO_meth_set_create` | `5NBoRJYLH0U` | | `X509_CRL_free` | `5PWK0cYOpHs` | | `i2d_SSL_SESSION` | `5aSlVeVSKVc` | | `tls_config_error` | `5ex+694ri90` | | `tls_read` | `7RvDjfy4gUA` | | `BIO_meth_set_read` | `8A-gU2xQfjY` | | `EC_POINT_set_affine_coordinates_GFp` | `8AGfaSvdDq4` | | `SSL_CTX_set_max_early_data` | `8kct4CSWwOA` | | `tls_configure` | `8pwP-7j5UZI` | | `X509_STORE_CTX_get0_param` | `8wroYNJAQpo` | | `unknown` | `A-Hs-8mau+8` | | `ERR_load_X509_strings` | `A0lZtFjhcTw` | | `tls_config_set_key_mem` | `A65b+ZhOt9k` | | `BN_clear_free` | `ABcJv8S1KEM` | | `unknown` | `AiNud8LR8B4` | | `X509_cmp_current_time` | `Ax+Uu++rnrA` | | `SSL_CTX_set_timeout` | `BBOgwZLvXHA` | | `tls_config_new` | `BQNyLN2nA9w` | | `X509_get_ext_by_NID` | `BRjfzlGULmU` | | `EVP_PKEY_security_bits` | `BS5yWv6X-hg` | | `X509_check_akid` | `C7eFtWPfLdk` | | `SSL_set_quic_use_legacy_codepoint` | `CFRaBB2+R+s` | | `SSL_CTX_set_default_verify_paths` | `DZ6fywqpaik` | | `TLS_server_method` | `EtM5Jwx4EFo` | | `ERR_lib_error_string` | `F7jknWesBTY` | | `tls_close` | `Fqc0-3YCXjo` | | `tls_client` | `GEK3LmjM9Q4` | | `BIO_meth_set_ctrl` | `GFEaREp1UFw` | | `EVP_PKEY_get0_EC_KEY` | `GY2X+VHs568` | | `unknown` | `GjO5Ap3E-t4` | | `unknown` | `HE-vihq-KKw` | | `EVP_PKEY_verify` | `HEuvmk+aHs4` | | `X509_set_version` | `IOutZPRNNPo` | | `d2i_SSL_SESSION` | `IiG4HLr+cOw` | | `DES_set_key_unchecked` | `J437jVn9pjI` | | `EVP_PKEY_CTX_new_id` | `J5ZLHxWkT6k` | | `RSAPublicKey_dup` | `JSqFTYGaWhU` | | `AES_unwrap_key` | `JvoQz7GYOMo` | | `ASN1_OCTET_STRING_cmp` | `Jzebx477Q3M` | | `SSL_CTX_add1_chain_cert` | `L897DuAuXKk` | | `X509_print` | `LA1MlgDx80o` | | `tls_config_free` | `LL8N+X6DA-4` | | `HMAC_CTX_new` | `LcxutSyn11o` | | `X509_CRL_get0_by_cert` | `LdGe2IfIlpI` | | `ERR_load_PEM_strings` | `M7ze0mz2jQM` | | `tls_error` | `N+G3Gxequt0` | | `OpenSSL_add_all_digests` | `O9Thca3enw8` | | `EVP_PKEY_base_id` | `OqtHJ7QUZg8` | | `unknown` | `PBYz0kpXwg8` | | `X509_new` | `PNfwr3s6dEs` | | `RSA_get0_factors` | `PcUZS7XHwHk` | | `SSL_get0_verified_chain` | `QKIOxHfZLh8` | | `RSA_set0_crt_params` | `QTV9Nyi7ryg` | | `EVP_PKEY_derive` | `QYEjNnn6PT4` | | `SSL_CIPHER_get_id` | `QaiPrM-RrrM` | | `EVP_PKEY_sign` | `QhYzE+Jdvuk` | | `X509_get_signature_nid` | `QnjD8S6Rgk4` | | `ECDSA_SIG_new` | `R3NyckUcClU` | | `BN_dup` | `RMhEgJs6KLI` | | `EVP_sha512_256` | `Sea+FOS2GOI` | | `tls_config_set_ca_mem` | `Sqn+7yQmQWc` | | `EVP_PKEY_derive_init` | `Ssfu1yw4Em4` | | `X509V3_EXT_conf_nid` | `TKGJOgbeyuA` | | `X509_sign` | `TpBvY92mrSM` | | `SSL_get_peer_quic_transport_params` | `U1dQZ1rXHdA` | | `BIO_get_data` | `U3AsZ-9e2MI` | | `SSL_CTX_set0_chain` | `UHkYqkyfwOs` | | `EVP_PKEY2PKCS8` | `UT6E1YgI8mw` | | `ASN1_TIME_new` | `UmAPG5bxYYk` | | `X509_STORE_load_locations` | `V3JtebYui1A` | | `ERR_func_error_string` | `VXuysR7ySzw` | | `EVP_get_digestbyname` | `Wm24hhTLqWM` | | `SSL_SESSION_set_time` | `XG3hIzt9VXY` | | `X509_set_issuer_name` | `XK3FmaTS6pg` | | `HMAC_CTX_free` | `YAxGqtnKQFY` | | `X509_add_ext` | `YJ7bfxMHniE` | | `tls_connect_socket` | `ZERQN8ewpgk` | | `SSL_CTX_set_quic_method` | `ZFeTGo4ybcw` | | `X509_gmtime_adj` | `ZQ3b6SakHkc` | | `SSL_process_quic_post_handshake` | `aKGUCnoiE+k` | | `unknown` | `aLdgrI2jAF0` | | `EC_POINT_clear_free` | `aSO3Svp7umY` | | `tls_config_set_protocols` | `agQxMaXVE8o` | | `d2i_PKCS8_PRIV_KEY_INFO` | `as+t2ZOg5fw` | | `ECDSA_do_sign` | `ba4o0Ih6kSs` | | `SSL_CTX_set_ciphersuites` | `bpOQdoGE2es` | | `SSL_get_version` | `dL2V0os4TZ4` | | `PEM_write_bio_PrivateKey` | `dQE7FIbNsUE` | | `i2d_X509` | `e2ReciVG21w` | | `RSA_get0_crt_params` | `eyrIagsax0w` | | `BIO_set_data` | `f6Pa2rYH-dw` | | `SSL_CTX_set_keylog_callback` | `fR2Wat3ssHs` | | `d2i_X509_CRL` | `fVos2kAqfMI` | | `tls_write` | `fZJr2OF+KGw` | | `X509_ALGOR_get0` | `fdvZNUHm-dE` | | `BIO_set_shutdown` | `fq1vAGKJNrI` | | `ASN1_STRING_set` | `gavhu7SX2FI` | | `PEM_read_bio_PUBKEY` | `gn7mRF71J4k` | | `EVP_PKEY_assign` | `gp5dGS14-pI` | | `OPENSSL_init_ssl` | `hGiyDq-l4AE` | | `i2d_PKCS8_PRIV_KEY_INFO` | `iFlkTGEbE9k` | | `BN_div` | `iHetf873n+4` | | `X509_CRL_get_ext_d2i` | `je-ydGAbgFg` | | `X509_digest` | `k1AHUWet-oU` | | `X509V3_set_ctx` | `kO-jQ3HS9kE` | | `BIO_meth_set_destroy` | `kPCJUQuguzE` | | `BIO_set_flags` | `lLHlEb1nt5U` | | `tls_config_set_ciphers` | `lTdt9OsPAV0` | | `SSL_set_alpn_protos` | `lyk0UDADPAc` | | `RSA_pkey_ctx_ctrl` | `mKlCMgWMU84` | | `SSL_set_info_callback` | `mOQe5RQATT4` | | `ASN1_get_object` | `mXrusLhI3CI` | | `SSL_provide_quic_data` | `mhAgol4ETgY` | | `tls_server` | `nCOh70mg3K0` | | `BIO_meth_new` | `o0dpw6ZZ6K0` | | `d2i_PUBKEY` | `o3Q8yQAMT-k` | | `EVP_PKEY_derive_set_peer` | `ovH4WphWIQQ` | | `OBJ_find_sigid_algs` | `pW329hq95Hc` | | `unknown` | `pdxCm9+CCc4` | | `unknown` | `qGsc6uT6p1E` | | `EVP_PKEY_verify_init` | `qseLIVbdvMQ` | | `ERR_reason_error_string` | `rJZ-aiNIYCA` | | `X509_add1_ext_i2d` | `s8WMaKNjwvE` | | `EC_GROUP_cmp` | `sENJFZ7WbLU` | | `EVP_PKEY_bits` | `ssruelYxprY` | | `SSL_do_handshake` | `tJsbVTdWjT4` | | `EVP_PKEY_sign_init` | `tZG2VIefbX0` | | `EC_POINT_dup` | `uITUdhDDAg8` | | `HKDF` | `uJ2ZXq4z3As` | | `EVP_aes_128_ccm` | `uM9UnC8KFjY` | | `RSA_set0_key` | `uihDBp74nLI` | | `EVP_PKEY_CTX_free` | `ulzAPWCIBkw` | | `tls_free` | `uz3bWkbHZu4` | | `tls_config_verify_client` | `v1vHv4jOJxQ` | | `EVP_PKEY_cmp` | `vLuIwBfrxrk` | | `d2i_ASN1_SEQUENCE_ANY` | `vR0po3nBkBs` | | `PKCS5_PBKDF2_HMAC` | `vnwZHU5FvBQ` | | `ASN1_OCTET_STRING_free` | `vo-cv5gnPUA` | | `tls_config_parse_protocols` | `vu4FgwGayHY` | | `SSL_CTX_set_post_handshake_auth` | `wHdymWL7CbE` | | `tls_config_insecure_noverifyname` | `wNQT6Zn4UG4` | | `X509_EXTENSION_free` | `wbJDMMsje6s` | | `ASN1_TYPE_free` | `whL1IRBxFZA` | | `ASN1_TIME_diff` | `xBkcXV1OqWQ` | | `ECDSA_SIG_set0` | `xVv3qlSRldc` | | `OBJ_obj2txt` | `xZ1BME5qDv0` | | `SSL_set_quic_transport_params` | `xf6anoZpWRM` | | `X509_get0_pubkey` | `xj7cFYOV4+Y` | | `SSL_is_quic` | `xpB+BNkO2Z0` | | `X509_get_X509_PUBKEY` | `yLm956jsJpc` | | `ECDSA_SIG_get0` | `z8fsXF8JuL0` | | `EVP_MD_block_size` | `zCa75KLWWn4` | - 116 of the 126 exports the 13.60 table lists only by NID carry, in the table above and in [Additional exports](../../../core/libs/prx/libSceLibreSsl3/AdditionalExports.cpp), the LibreSSL names whose `tools/nid_names.py` hash equals the NID; the names were taken from the identifiers of the LibreSSL 3.8.4 and 4.0.0 `include`, `crypto`, `ssl` and `tls` sources. A name match does not show that the console function has LibreSSL's prototype or behavior; each keeps the no-parameter import-resolution convention and throws through `NotImplemented_nid_no_patch`. `AES_wrap_key`, `ECDSA_SIG_free`, `ECDSA_do_verify`, `ERR_load_ERR_strings`, `ERR_print_errors_fp` and `i2d_PUBKEY` also hash to the NIDs of six `unknown` rows, which keep their NID names; `PBYz0kpXwg8` hashes to no identifier of those sources.