Skip to content

feat(libSceSsl): implement sceSslGetCaList, sceSslFreeCaList and sceSslUnloadCert - #15

Closed
SleglJan wants to merge 14 commits into
mainfrom
feat/libscessl-ca-list
Closed

SleglJan wants to merge 14 commits into
mainfrom
feat/libscessl-ca-list

Conversation

@SleglJan

@SleglJan SleglJan commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

What

Implements sceSslGetCaList, sceSslFreeCaList and sceSslUnloadCert in libSceSsl.

  • PPSA11386 (007 First Light) imports sceSslGetCaList and sceSslFreeCaList, and PPSA15508 (The Last of Us Part II Remastered) imports sceSslUnloadCert. On main 8b393b6 all three are missing: PPSA11386's loader stops with undefined symbol: qOn+wm28wmA (sceSslGetCaList), PPSA15508's with undefined symbol: UQ+3Qu7v3cA (sceSslUnloadCert).
  • No root certificate bundle is shipped and no loaded certificate is kept, so a context holds no certificates. sceSslGetCaList clears the list and returns NOT_FOUND (0x8095F004), as sceSslGetCaCerts already does; sceSslFreeCaList accepts that cleared list and returns 0; sceSslUnloadCert has nothing to drop and returns 0, which is assumed.
  • A null list returns 0x8095177A, the code sceSslGetCaCerts and KytyPS5 return for a null argument; shadPS4 (PS4) returns 0x8095F007. An unknown context and a list sceSslGetCaList did not return throw: KytyPS5 returns SSL_ERROR_INVALID_ID (0x8095F006) for an unknown context in sceSslGetCaCerts, but nothing confirms a code for these functions.
  • Signatures and the 16-byte SceSslCaList (handle array, 32-bit count) follow SharpProspero and shadPS4's OrbisSslCaList; the size is a static_assert.
  • guest_ssl_tests now links libc and calls configure_windows_unwind, as guest_http2_tests does. Without it the test binary's static libstdc++ __cxa_throw raises an exception thrown in libSceSsl and libc.prx's _Unwind_Resume resumes it after the lock_guard cleanup, which aborts.
  • sceSslGetCaCerts and sceSslFreeCaCerts stay as they are (they ignore the context and clear any list), to keep this to one topic.

All of it is recorded in TechnicalDebt, including that on the console the list holds the certificate authorities the SSL service has (shadPS4 #4104 returns a placeholder certificate from sceSslGetCaCerts because Rise of the Tomb Raider fails its initialization checks without one).

Overlap: closed boykopovar#1884 (Albaloola) implemented the same three functions with Mbed TLS and certificate parsing; its author closed it without a review. Open boykopovar#2193 rewrites sceSslLoadCert to return 0 and keep nothing, which keeps the store empty, so the two agree; both add declarations at the top of GuestSsl.cpp, so whichever merges second needs a one-hunk rebase. No open pull request implements these three functions.

Tested

  • Linux (CachyOS, kernel 7.2.9, GCC 16.2.1), Release with BUILD_TESTING=ON and ANYPS5_ENABLE_SPIRV_TOOLS=ON, on main 8b393b6: guest_ssl passes 3 repeats; tools/check_conventions.py --base upstream/main passes. Full ctest on an integration build of this branch with the two sibling branches below: 520/521 on the RTX 3080; the failure, agc_driver_dcc_keys_first_write, fails on main too ([bug] agc_driver_dcc_keys_first_write fails on main on a real NVIDIA GPU boykopovar/AnyPS5#2188).
  • guest_ssl additions: a null list (also with an unknown context, which pins the check order), the cleared list after NOT_FOUND, three lists sceSslGetCaList did not return ({p, 1}, {nullptr, 1}, {p, 0}), sceSslUnloadCert returning 0 with the list still NOT_FOUND after it, and all three functions throwing after sceSslTerm. Written before the implementation; on main it does not link. Eight mutations of the implementation each fail it (list not cleared, 0 instead of NOT_FOUND, foreign lists accepted, the count ignored, no context check, sceSslUnloadCert without it, 0 for a null list, the context check before the null check).
  • The patched libSceSsl.prx exports qOn+wm28wmA, +DzXseDVkeI and UQ+3Qu7v3cA.
  • PPSA11386 v01.018.000, relinked on main 8b393b6 and run in a bubblewrap sandbox: the loader stops on qOn+wm28wmA. With this branch, feat/libscenet-show-netstat and fix/libSceSharePlay-null-heap (this fork) the loader passes with no absent imports, and the title calls sceSslGetCaList, sceSslGetCaCerts, sceSslFreeCaList and sceSslFreeCaCerts once each at start-up and continues; its next stop is the shader in Recompiler: SPIR-V validation fails on a continue construct its back-edge block does not post-dominate boykopovar/AnyPS5#1921. PPSA15508 v02.001.010: the loader stop moves from UQ+3Qu7v3cA to sceVoiceGetMuteFlag.
  • Fork Actions full Build of this pull request merged onto main 8b393b6, run 37987888113: Linux 520/520 (lavapipe), Windows 511/511; guest_ssl passes on both.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes (Claude Code)

@github-actions github-actions Bot added the intake paused Closed while PR intake is limited to authors with at least 20 PRs merged into main label Oct 9, 2026
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown

Thank you for your interest in the project! We are sorry, but we cannot accept more PRs while we work through the existing backlog. This PR has been automatically closed and labeled "intake paused". This is not a judgment of the quality of your changes.

oneandonlydean and others added 14 commits October 10, 2026 23:02
…raws

A draw whose stages bind a BDA table or a fault buffer builds resources
that need completion work, so noteReusable never keeps them and the shared
resource cache never holds an entry such a draw could hit. Building the
content key and probing the cache for each of them was pure cost. Those
draws now skip both (ShaderResources::NeverReusable) and count as
uncacheable.
Every small host buffer (size classes below 1 MiB: draw and dispatch data,
copied regions, snapshots) had a VkDeviceMemory of its own. When the pool
missed, the worker paid a vkAllocateMemory and vkMapMemory, and the release
thread a vkUnmapMemory and vkFreeMemory, for each one. The frees also stall
the worker's vkQueueSubmit in the driver.

A host-visible buffer of a size class now gets its own VkBuffer bound into a
slot of a shared block (2 MiB, or 8 slots for the large classes) per memory
type, size class and device-address use, mapped once. Releasing it destroys
only the VkBuffer and returns the slot; a block is freed when it empties and
its slab already keeps an empty one. A slot is used only when the buffer's
alignment and the non-coherent atom divide its size class, so the slot
offset is valid for the bind and Invalidate covers exactly the slot. The
pool still retains released buffers by class as before; only what backs
them changed.
DescriptorBinding gains bufferRead next to bufferWritten and bufferAtomic,
filled from the resource tracker's per-buffer read flag and kept in the
shader disk cache (format 24).
A written V# element bound in place in a host import makes every load a
PCIe round trip. A particle update that loads and stores a 10 MiB pool
(2048x64 threads over 131072 records of 80 bytes), above the 2 MiB written
window, took about 4.8 ms of GPU per frame.

An element the shader also reads (DescriptorBinding::bufferRead), written by
a direct dispatch whose threads times the V# stride cover at least half of
it, now takes device-local staging up to 16 MiB: that dispatch drops to
about 0.06 ms plus 0.9 ms of bulk copies. The coverage test keeps a kernel
that updates about 12k records of a 16 MiB pool in place, where staging all
of it would cost 1.3 ms of copies for a 0.08 ms kernel. Write-only
elements, indirect dispatches and raw (stride 0) buffers keep the 2 MiB
window.
perf(agc): sub-allocate small host buffers from shared memory blocks
…aw-key

perf(agc): skip the resource-cache key and lookup for address-based draws
…entries

A resource build decodes every image element's eight descriptor words,
describes the surface (a mip layout with a vector of levels) and finds the
sampled texture's cache entry by hashing its key, once in stage A and again
in stage B. Most elements repeat a small set of descriptors from build to
build.

Each worker now keeps a small direct-mapped memo by descriptor words of the
decoded resource, its guest size and view component mapping (pure functions
of the words) and of the cache entry the words last found. The entry is
reused only while the sampled texture cache has erased no entry since it
was found (an erase counter bumped by eraseTexture), so the list iterator is
still valid and still holds the same key; anything else takes the hash
lookup.
…he same texture

A build's sampled image elements often repeat the element just before them
in plan order (the same eight descriptor words). Each still took its own
stage-A record (decode, collect, DCC key read, cache entry) and its own
stage-B lookup.

The lookups run in plan order and nothing runs between two consecutive ones,
so a repeated element's lookup would find the state the previous lookup just
left: the entry it validated or made, current against the same collect. Such
an element now binds the previous element's texture (when the depth-compare
flag matches too, which is part of the cache key), and stage A gives it a
record of the decoded descriptor only. An element repeating an earlier but
not the immediately preceding one still takes its own lookup, as does any
element after a storage image lookup.
perf(agc): memoize decoded image descriptors and their texture cache entries
perf(agc): resolve a sampled element repeating the one before it to the same texture
…er-staging

perf(agc): stage read and written buffer elements a dispatch sweeps
…slUnloadCert

PPSA11386 imports sceSslGetCaList and sceSslFreeCaList and PPSA15508
imports sceSslUnloadCert; on main all three are missing and the loaders of
both titles stop on them. No root certificate bundle is shipped and no
loaded certificate is kept, so an SSL context holds no certificates:
sceSslGetCaList clears the list and returns NOT_FOUND, as sceSslGetCaCerts
does; sceSslFreeCaList accepts only that cleared list; sceSslUnloadCert has
nothing to drop and is assumed to return 0. A null list returns the
invalid-argument code that sceSslGetCaCerts and KytyPS5 return. An unknown
context and a list sceSslGetCaList did not return throw, as their codes are
not confirmed. Signatures and the SceSslCaList layout follow SharpProspero
and shadPS4.

guest_ssl_tests now links libc, as guest_http2_tests does, so an exception
thrown from libSceSsl unwinds with the same unwinder that resumes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@SleglJan
SleglJan force-pushed the feat/libscessl-ca-list branch from 6a39e8e to 33184a1 Compare October 10, 2026 16:15
@SleglJan

Copy link
Copy Markdown
Owner Author

Merged upstream as boykopovar#2830.

@SleglJan SleglJan closed this Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants