mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-05 13:20:11 +00:00
feat(libSceLibreSsl): implement X509_LOOKUP_file and X509_STORE_add_lookup
Both exports threw and were declared without parameters. They follow LibreSSL 2.5.4, unchanged in 2.7: X509_LOOKUP_file returns the static 80-byte file method, and X509_STORE_add_lookup returns the store's lookup for a method, or mallocs a 32-byte lookup owned by the store and pushes it on the store's methods, growing the stack the way sk_insert does. X509_STORE_free now frees the store's lookups. The file method's ctrl, which loads PEM files, throws: there is no certificate model yet. Callbacks of guest-supplied methods throw instead of being called. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
a2d4d38a15
commit
e8d6c3fb47
6 files changed
+294
-15
No files matched your search
@@ -109,3 +109,17 @@ if(BUILD_TESTING)
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceLibreSsl>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test_executable(guest_libressl_x509_lookup_tests ${CMAKE_CURRENT_SOURCE_DIR}/tests/X509Lookup.cpp)
|
||||
target_include_directories(guest_libressl_x509_lookup_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_libressl_x509_lookup_tests PRIVATE libSceLibreSsl libc)
|
||||
configure_windows_unwind(guest_libressl_x509_lookup_tests)
|
||||
add_test(NAME guest_libressl_x509_lookup COMMAND guest_libressl_x509_lookup_tests)
|
||||
add_test(NAME guest_libressl_x509_lookup_allocator COMMAND guest_libressl_x509_lookup_tests allocator)
|
||||
set_tests_properties(guest_libressl_x509_lookup guest_libressl_x509_lookup_allocator PROPERTIES TIMEOUT 30)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_libressl_x509_lookup guest_libressl_x509_lookup_allocator PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceLibreSsl>")
|
||||
endif()
|
||||
endif()
|
||||
@@ -1518,11 +1518,6 @@ int APS5_VABI X509_INFO_free_nid_postfix(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI X509_LOOKUP_file_nid_postfix(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI X509_NAME_ENTRY_get_data_nid_postfix(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
@@ -1598,11 +1593,6 @@ int APS5_VABI X509_STORE_add_crl_nid_postfix(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI X509_STORE_add_lookup_nid_postfix(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI X509_VERIFY_PARAM_set1_host_nid_postfix(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
|
||||
@@ -41,6 +41,27 @@ struct LibreSslX509Store {
|
||||
std::int32_t references;
|
||||
};
|
||||
|
||||
struct LibreSslX509LookupMethod {
|
||||
const char* name;
|
||||
void* newItem;
|
||||
void* free;
|
||||
void* init;
|
||||
void* shutdown;
|
||||
void* ctrl;
|
||||
void* getBySubject;
|
||||
void* getByIssuerSerial;
|
||||
void* getByFingerprint;
|
||||
void* getByAlias;
|
||||
};
|
||||
|
||||
struct LibreSslX509Lookup {
|
||||
std::int32_t init;
|
||||
std::int32_t skip;
|
||||
LibreSslX509LookupMethod* method;
|
||||
char* methodData;
|
||||
LibreSslX509Store* storeContext;
|
||||
};
|
||||
|
||||
inline constexpr int MaxRounds = 14;
|
||||
|
||||
struct AesKey {
|
||||
@@ -395,7 +416,7 @@ int APS5_VABI X509_EXTENSION_get_critical_nid_postfix(void);
|
||||
int APS5_VABI X509_EXTENSION_get_data_nid_postfix(void);
|
||||
int APS5_VABI X509_EXTENSION_get_object_nid_postfix(void);
|
||||
int APS5_VABI X509_INFO_free_nid_postfix(void);
|
||||
int APS5_VABI X509_LOOKUP_file_nid_postfix(void);
|
||||
LibreSslX509LookupMethod* APS5_VABI X509_LOOKUP_file_nid_postfix(void);
|
||||
int APS5_VABI X509_NAME_ENTRY_get_data_nid_postfix(void);
|
||||
int APS5_VABI X509_NAME_get_entry_nid_postfix(void);
|
||||
int APS5_VABI X509_NAME_get_index_by_NID_nid_postfix(void);
|
||||
@@ -411,7 +432,7 @@ int APS5_VABI X509_STORE_CTX_get_ex_data_nid_postfix(void);
|
||||
int APS5_VABI X509_STORE_CTX_set_error_nid_postfix(void);
|
||||
int APS5_VABI X509_STORE_add_cert_nid_postfix(void);
|
||||
int APS5_VABI X509_STORE_add_crl_nid_postfix(void);
|
||||
int APS5_VABI X509_STORE_add_lookup_nid_postfix(void);
|
||||
LibreSslX509Lookup* APS5_VABI X509_STORE_add_lookup_nid_postfix(LibreSslX509Store* store, LibreSslX509LookupMethod* method);
|
||||
void APS5_VABI X509_STORE_free_nid_postfix(LibreSslX509Store* store);
|
||||
LibreSslX509Store* APS5_VABI X509_STORE_new_nid_postfix(void);
|
||||
int APS5_VABI X509_STORE_set_flags_nid_postfix(LibreSslX509Store* store, std::uint64_t flags);
|
||||
|
||||
@@ -24,6 +24,13 @@ static_assert(offsetof(LibreSslX509Store, param) == 24);
|
||||
static_assert(offsetof(LibreSslX509Store, callbacks) == 32);
|
||||
static_assert(offsetof(LibreSslX509Store, exData) == 120);
|
||||
static_assert(offsetof(LibreSslX509Store, references) == 128);
|
||||
static_assert(sizeof(LibreSslX509LookupMethod) == 80);
|
||||
static_assert(offsetof(LibreSslX509LookupMethod, shutdown) == 32);
|
||||
static_assert(offsetof(LibreSslX509LookupMethod, ctrl) == 40);
|
||||
static_assert(sizeof(LibreSslX509Lookup) == 32);
|
||||
static_assert(offsetof(LibreSslX509Lookup, method) == 8);
|
||||
static_assert(offsetof(LibreSslX509Lookup, methodData) == 16);
|
||||
static_assert(offsetof(LibreSslX509Lookup, storeContext) == 24);
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -51,6 +58,14 @@ int APS5_VABI CompareObjects(const void*, const void*) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI LoadFile(LibreSslX509Lookup*, int, const char*, std::int64_t, char**) {
|
||||
NotImplemented_nid_no_patch("X509_LOOKUP_file: loading certificates and CRLs from a file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
LibreSslX509LookupMethod fileLookup{"Load file into cache", nullptr, nullptr, nullptr, nullptr,
|
||||
reinterpret_cast<void*>(LoadFile), nullptr, nullptr, nullptr, nullptr};
|
||||
|
||||
Stack* NewStack(Compare compare) {
|
||||
auto* stack = static_cast<Stack*>(malloc_nid_postfix(sizeof(Stack)));
|
||||
if (!stack) return nullptr;
|
||||
@@ -78,6 +93,29 @@ char** Elements(const Stack* stack, const char* function) {
|
||||
return stack->data;
|
||||
}
|
||||
|
||||
bool Push(Stack* stack, void* element, const char* function) {
|
||||
if (!stack) return false;
|
||||
if (stack->numAlloc <= stack->num + 1) {
|
||||
if (stack->numAlloc <= 0 || stack->num < 0) NotImplemented_nid_no_patch(function);
|
||||
auto* grown = static_cast<char**>(realloc_nid_postfix(stack->data, static_cast<std::size_t>(stack->numAlloc) * 2 * sizeof(char*)));
|
||||
if (!grown) return false;
|
||||
stack->data = grown;
|
||||
stack->numAlloc *= 2;
|
||||
}
|
||||
stack->data[stack->num] = static_cast<char*>(element);
|
||||
++stack->num;
|
||||
stack->sorted = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeLookup(LibreSslX509Lookup* lookup, bool shutdown, const char* function) {
|
||||
if (!lookup) NotImplemented_nid_no_patch(function);
|
||||
const auto* method = lookup->method;
|
||||
if (shutdown && method && method->shutdown) NotImplemented_nid_no_patch("X509_LOOKUP shutdown callback");
|
||||
if (method && method->free) NotImplemented_nid_no_patch("X509_LOOKUP free callback");
|
||||
free_nid_postfix(lookup);
|
||||
}
|
||||
|
||||
bool HoldsElements(const Stack* stack, const char* function) {
|
||||
if (!stack || stack->num <= 0) return false;
|
||||
char** const elements = Elements(stack, function);
|
||||
@@ -150,7 +188,11 @@ void APS5_VABI X509_STORE_free_nid_postfix(LibreSslX509Store* store) {
|
||||
if (!store) return;
|
||||
if (std::atomic_ref<std::int32_t>(store->references).fetch_sub(1) - 1 > 0) return;
|
||||
auto* lookupMethods = static_cast<Stack*>(store->lookupMethods);
|
||||
if (lookupMethods && lookupMethods->num > 0) NotImplemented_nid_no_patch("X509_STORE_free: lookup methods");
|
||||
if (lookupMethods && lookupMethods->num > 0) {
|
||||
char** const lookups = Elements(lookupMethods, __func__);
|
||||
for (int index = 0; index < lookupMethods->num; ++index)
|
||||
FreeLookup(reinterpret_cast<LibreSslX509Lookup*>(lookups[index]), true, __func__);
|
||||
}
|
||||
FreeStack(lookupMethods);
|
||||
auto* objects = static_cast<Stack*>(store->objects);
|
||||
if (HoldsElements(objects, __func__)) NotImplemented_nid_no_patch("X509_STORE_free: stored certificates and CRLs");
|
||||
@@ -167,4 +209,34 @@ int APS5_VABI X509_STORE_set_flags_nid_postfix(LibreSslX509Store* store, std::ui
|
||||
return 1;
|
||||
}
|
||||
|
||||
LibreSslX509LookupMethod* APS5_VABI X509_LOOKUP_file_nid_postfix(void) {
|
||||
return &fileLookup;
|
||||
}
|
||||
|
||||
LibreSslX509Lookup* APS5_VABI X509_STORE_add_lookup_nid_postfix(LibreSslX509Store* store, LibreSslX509LookupMethod* method) {
|
||||
if (!store) NotImplemented_nid_no_patch(__func__);
|
||||
auto* lookupMethods = static_cast<Stack*>(store->lookupMethods);
|
||||
if (lookupMethods && lookupMethods->num > 0) {
|
||||
char** const lookups = Elements(lookupMethods, __func__);
|
||||
for (int index = 0; index < lookupMethods->num; ++index) {
|
||||
auto* lookup = reinterpret_cast<LibreSslX509Lookup*>(lookups[index]);
|
||||
if (!lookup) NotImplemented_nid_no_patch(__func__);
|
||||
if (lookup->method == method) return lookup;
|
||||
}
|
||||
}
|
||||
auto* lookup = static_cast<LibreSslX509Lookup*>(malloc_nid_postfix(sizeof(LibreSslX509Lookup)));
|
||||
if (!lookup) return nullptr;
|
||||
lookup->init = 0;
|
||||
lookup->skip = 0;
|
||||
lookup->method = method;
|
||||
lookup->methodData = nullptr;
|
||||
lookup->storeContext = nullptr;
|
||||
if (!method) NotImplemented_nid_no_patch(__func__);
|
||||
if (method->newItem) NotImplemented_nid_no_patch("X509_LOOKUP new_item callback");
|
||||
lookup->storeContext = store;
|
||||
if (Push(lookupMethods, lookup, __func__)) return lookup;
|
||||
FreeLookup(lookup, false, __func__);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
#include "prx/libSceLibreSsl/libSceLibreSsl.hpp"
|
||||
#include "prx/libc/include/Api.hpp"
|
||||
#include "prx/libc/include/ApplicationHeap.hpp"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace {
|
||||
|
||||
struct Stack {
|
||||
std::int32_t num;
|
||||
char** data;
|
||||
std::int32_t sorted;
|
||||
std::int32_t numAlloc;
|
||||
int (APS5_VABI* comp)(const void*, const void*);
|
||||
};
|
||||
|
||||
using LookupControl = int (APS5_VABI*)(LibreSslX509Lookup*, int, const char*, std::int64_t, char**);
|
||||
|
||||
void Require(bool condition, const char* message) {
|
||||
if (condition) return;
|
||||
std::fprintf(stderr, "failed: %s\n", message);
|
||||
std::abort();
|
||||
}
|
||||
|
||||
template<typename TAction>
|
||||
void RequireThrows(TAction action, const char* message) {
|
||||
try {
|
||||
action();
|
||||
} catch (const std::exception&) {
|
||||
return;
|
||||
}
|
||||
Require(false, message);
|
||||
}
|
||||
|
||||
Stack* Lookups(LibreSslX509Store* store) {
|
||||
return static_cast<Stack*>(store->lookupMethods);
|
||||
}
|
||||
|
||||
void FileMethod() {
|
||||
auto* method = X509_LOOKUP_file_nid_postfix();
|
||||
Require(method && method == X509_LOOKUP_file_nid_postfix(), "the file method is one static object");
|
||||
Require(std::strcmp(method->name, "Load file into cache") == 0, "file method name");
|
||||
Require(!method->newItem && !method->free && !method->init && !method->shutdown, "the file method has no lifecycle callbacks");
|
||||
Require(!method->getBySubject && !method->getByIssuerSerial && !method->getByFingerprint && !method->getByAlias,
|
||||
"the file method has no lookup callbacks");
|
||||
Require(method->ctrl, "the file method has a control callback");
|
||||
auto control = reinterpret_cast<LookupControl>(method->ctrl);
|
||||
RequireThrows([&] { control(nullptr, 1, "certs.pem", 1, nullptr); }, "loading a file needs the certificate model");
|
||||
}
|
||||
|
||||
void AddLookup() {
|
||||
auto* store = X509_STORE_new_nid_postfix();
|
||||
auto* method = X509_LOOKUP_file_nid_postfix();
|
||||
auto* lookup = X509_STORE_add_lookup_nid_postfix(store, method);
|
||||
Require(lookup && lookup->init == 0 && lookup->skip == 0 && lookup->method == method && lookup->methodData == nullptr
|
||||
&& lookup->storeContext == store, "a new lookup starts as X509_LOOKUP_new leaves it, owned by the store");
|
||||
Require(Lookups(store)->num == 1 && Lookups(store)->data[0] == reinterpret_cast<char*>(lookup) && Lookups(store)->sorted == 0,
|
||||
"the lookup is pushed on the store's methods");
|
||||
Require(X509_STORE_add_lookup_nid_postfix(store, method) == lookup && Lookups(store)->num == 1, "the same method returns the same lookup");
|
||||
lookup->init = 1;
|
||||
Require(X509_STORE_add_lookup_nid_postfix(store, method) == lookup && lookup->init == 1, "an existing lookup is returned unchanged");
|
||||
|
||||
std::array<LibreSslX509LookupMethod, 5> methods{};
|
||||
std::array<LibreSslX509Lookup*, 5> added{};
|
||||
for (std::size_t index = 0; index < methods.size(); ++index) {
|
||||
added[index] = X509_STORE_add_lookup_nid_postfix(store, &methods[index]);
|
||||
Require(added[index] && added[index]->method == &methods[index], "each method gets its own lookup");
|
||||
}
|
||||
Require(Lookups(store)->num == 6 && Lookups(store)->numAlloc == 8, "the stack doubles once four slots are not enough");
|
||||
for (std::size_t index = 0; index < methods.size(); ++index)
|
||||
Require(X509_STORE_add_lookup_nid_postfix(store, &methods[index]) == added[index], "lookups are found after growth");
|
||||
Require(Lookups(store)->num == 6, "finding a lookup adds nothing");
|
||||
X509_STORE_free_nid_postfix(store);
|
||||
}
|
||||
|
||||
void Unsupported() {
|
||||
auto* store = X509_STORE_new_nid_postfix();
|
||||
RequireThrows([] { X509_STORE_add_lookup_nid_postfix(nullptr, X509_LOOKUP_file_nid_postfix()); }, "null store");
|
||||
RequireThrows([&] { X509_STORE_add_lookup_nid_postfix(store, nullptr); }, "null method");
|
||||
LibreSslX509LookupMethod withNewItem{};
|
||||
withNewItem.newItem = reinterpret_cast<void*>(&Require);
|
||||
RequireThrows([&] { X509_STORE_add_lookup_nid_postfix(store, &withNewItem); }, "a guest new_item callback");
|
||||
Require(Lookups(store)->num == 0, "a refused method adds no lookup");
|
||||
X509_STORE_free_nid_postfix(store);
|
||||
|
||||
store = X509_STORE_new_nid_postfix();
|
||||
LibreSslX509LookupMethod withShutdown{};
|
||||
withShutdown.shutdown = reinterpret_cast<void*>(&Require);
|
||||
Require(X509_STORE_add_lookup_nid_postfix(store, &withShutdown) != nullptr, "a method with only a shutdown callback is added");
|
||||
RequireThrows([&] { X509_STORE_free_nid_postfix(store); }, "a guest shutdown callback");
|
||||
|
||||
store = X509_STORE_new_nid_postfix();
|
||||
LibreSslX509LookupMethod withFree{};
|
||||
withFree.free = reinterpret_cast<void*>(&Require);
|
||||
Require(X509_STORE_add_lookup_nid_postfix(store, &withFree) != nullptr, "a method with only a free callback is added");
|
||||
RequireThrows([&] { X509_STORE_free_nid_postfix(store); }, "a guest free callback");
|
||||
|
||||
store = X509_STORE_new_nid_postfix();
|
||||
Lookups(store)->num = 1;
|
||||
RequireThrows([&] { X509_STORE_add_lookup_nid_postfix(store, X509_LOOKUP_file_nid_postfix()); }, "a null listed lookup");
|
||||
}
|
||||
|
||||
int allocations = 0;
|
||||
int frees = 0;
|
||||
int reallocations = 0;
|
||||
bool failRealloc = false;
|
||||
|
||||
void* APS5_VABI Allocate_nid_no_patch(std::size_t size) {
|
||||
++allocations;
|
||||
return std::malloc(size);
|
||||
}
|
||||
|
||||
void APS5_VABI Free_nid_no_patch(void* pointer) {
|
||||
if (pointer) ++frees;
|
||||
std::free(pointer);
|
||||
}
|
||||
|
||||
void* APS5_VABI Reallocate_nid_no_patch(void* pointer, std::size_t size) {
|
||||
++reallocations;
|
||||
if (failRealloc) return nullptr;
|
||||
return std::realloc(pointer, size);
|
||||
}
|
||||
|
||||
void* APS5_VABI Calloc_nid_no_patch(std::size_t count, std::size_t size) { return std::calloc(count, size); }
|
||||
void* APS5_VABI Align_nid_no_patch(std::size_t, std::size_t) { throw std::runtime_error("unexpected aligned allocation"); }
|
||||
void* APS5_VABI Realign_nid_no_patch(void*, std::size_t, std::size_t) { throw std::runtime_error("unexpected aligned reallocation"); }
|
||||
int APS5_VABI PosixAlign_nid_no_patch(void**, std::size_t, std::size_t) { throw std::runtime_error("unexpected posix_memalign"); }
|
||||
|
||||
void Allocator() {
|
||||
std::array<void*, 10> api{
|
||||
reinterpret_cast<void*>(Allocate_nid_no_patch), reinterpret_cast<void*>(Free_nid_no_patch), reinterpret_cast<void*>(Calloc_nid_no_patch),
|
||||
reinterpret_cast<void*>(Reallocate_nid_no_patch), reinterpret_cast<void*>(Align_nid_no_patch), reinterpret_cast<void*>(Realign_nid_no_patch),
|
||||
reinterpret_cast<void*>(PosixAlign_nid_no_patch)};
|
||||
ApplicationHeapRegister_nid_no_patch(api.data());
|
||||
std::array<LibreSslX509LookupMethod, 4> methods{};
|
||||
|
||||
auto* store = X509_STORE_new_nid_postfix();
|
||||
allocations = frees = reallocations = 0;
|
||||
for (auto& method : methods) X509_STORE_add_lookup_nid_postfix(store, &method);
|
||||
Require(allocations == 4 && reallocations == 1 && frees == 0, "four lookups are malloc'd and the fourth push grows the array");
|
||||
X509_STORE_free_nid_postfix(store);
|
||||
Require(frees == 4 + 7, "freeing the store frees its lookups");
|
||||
|
||||
store = X509_STORE_new_nid_postfix();
|
||||
for (std::size_t index = 0; index < 3; ++index) X509_STORE_add_lookup_nid_postfix(store, &methods[index]);
|
||||
allocations = frees = 0;
|
||||
failRealloc = true;
|
||||
Require(X509_STORE_add_lookup_nid_postfix(store, &methods[3]) == nullptr, "a failed growth fails the call");
|
||||
Require(allocations == 1 && frees == 1 && Lookups(store)->num == 3 && Lookups(store)->numAlloc == 4, "a failed growth frees the new lookup and keeps the stack");
|
||||
failRealloc = false;
|
||||
X509_STORE_free_nid_postfix(store);
|
||||
|
||||
store = X509_STORE_new_nid_postfix();
|
||||
auto* lookupMethods = Lookups(store);
|
||||
store->lookupMethods = nullptr;
|
||||
allocations = frees = 0;
|
||||
Require(X509_STORE_add_lookup_nid_postfix(store, &methods[0]) == nullptr && allocations == 1 && frees == 1,
|
||||
"a store without a method stack frees the new lookup");
|
||||
store->lookupMethods = lookupMethods;
|
||||
X509_STORE_free_nid_postfix(store);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char**) {
|
||||
if (argc > 1) {
|
||||
Allocator();
|
||||
return 0;
|
||||
}
|
||||
std::array<void*, 10> api{};
|
||||
ApplicationHeapRegister_nid_no_patch(api.data());
|
||||
FileMethod();
|
||||
AddLookup();
|
||||
Unsupported();
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Unknown function info
|
||||
|
||||
- [libSceLibreSsl pending exports](../../../core/libs/prx/libSceLibreSsl/Export.cpp) - 342 named callable exports are listed in the [PS5 3.20 export table](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceLibreSsl.c) and were 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`.
|
||||
- [libSceLibreSsl pending exports](../../../core/libs/prx/libSceLibreSsl/Export.cpp) - 340 named callable exports are listed in the [PS5 3.20 export table](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceLibreSsl.c) and were 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`.
|
||||
- [MD4, MD5, SHA1, SHA224, SHA256, SHA384 and SHA512 Init/Update/Final and SHA256](../../../core/libs/prx/libSceLibreSsl/src/Digest.cpp) (libSceLibreSsl) - signatures and context layouts follow the [LibreSSL headers](https://github.com/libressl/openbsd/blob/bc9483725c5815efb64b6d9acc52fc5fba139212/src/lib/libcrypto/sha/sha.h), and buffering and `Final` follow its [sources](https://github.com/libressl/openbsd/tree/bc9483725c5815efb64b6d9acc52fc5fba139212/src/lib/libcrypto/sha); nothing is checked on the console. Null contexts, null input with a nonzero length, null digest buffers in the 32-bit `Final` functions and a buffered byte count that is not below the block size, which LibreSSL does not check, throw
|
||||
- [DES_set_key, DES_ecb_encrypt, DES_set_odd_parity](../../../core/libs/prx/libSceLibreSsl/Export.cpp) (libSceLibreSsl) - the 128-byte `DES_key_schedule` holds the 8-byte key followed by zeros instead of LibreSSL's precomputed subkeys, so a title reading its contents sees different bytes; `DES_ecb_encrypt` derives the subkeys through mbedtls on each call. Not compared with the console. Results follow LibreSSL [des_key.c](https://github.com/libressl/openbsd/blob/bc9483725c5815efb64b6d9acc52fc5fba139212/src/lib/libcrypto/des/des_key.c) and [des.c](https://github.com/libressl/openbsd/blob/bc9483725c5815efb64b6d9acc52fc5fba139212/src/lib/libcrypto/des/des.c): `DES_set_key` skips the parity and weak-key checks and returns 0, as it does while `DES_check_key` is 0 (that variable is not in the PS5 export inventory), a nonzero `enc` encrypts, and `DES_set_odd_parity` sets each byte's low bit for odd parity. Null pointers throw where LibreSSL faults
|
||||
- [X509_verify_cert_error_string](../../../core/libs/prx/libSceLibreSsl/Export.cpp) - no console call is verified. The 64-bit argument, low-32-bit lookup, messages and shared numeric fallback follow [LibreSSL 2.5.4](https://github.com/libressl/openbsd/blob/2e2c612066aa993717528a0249c15c51128d61cb/src/lib/libcrypto/x509/x509_txt.c), the version identified in [published firmware 13.40 measurements](https://github.com/boykopovar/AnyPS5/discussions/8981#discussioncomment-19111214). Console modifications and other firmware versions remain unverified. Unknown-code results share an overwritten static buffer and are not safe for concurrent use, as in that release; code 1 and codes above 54 use the numeric fallback.
|
||||
@@ -18,4 +18,6 @@
|
||||
|
||||
- [ASN1_INTEGER_get and ASN1_STRING_data/length/type/to_UTF8](../../../core/libs/prx/libSceLibreSsl/src/Asn1.cpp) are unverified on PS5. Signatures, the 24-byte guest string layout and conversions follow [LibreSSL 2.5.4's ASN.1 sources](https://github.com/libressl/openbsd/tree/2e2c612066aa993717528a0249c15c51128d61cb/src/lib/libcrypto/asn1), the version reported for firmware 13.40 in [discussion #8981](https://github.com/boykopovar/AnyPS5/discussions/8981#discussioncomment-19111214). Null accessor inputs, null conversion outputs, missing nonempty data, oversized converted output and unrepresentable signed integer values throw where the source has undefined behaviour. Malformed encodings and allocation failure throw until ASN.1 error-queue reporting is implemented. Conversion buffers use the guest libc allocator and can be released with guest `free`.
|
||||
|
||||
- [X509_STORE_new, X509_STORE_free and X509_STORE_set_flags](../../../core/libs/prx/libSceLibreSsl/src/X509Store.cpp) are unverified on PS5. The 136-byte store, 64-byte verify parameters, 56-byte parameter identity, 32-byte stacks and the results follow [LibreSSL 2.5.4](https://github.com/libressl/openbsd/tree/2e2c612066aa993717528a0249c15c51128d61cb/src/lib/libcrypto/x509) `x509_lu.c` and `x509_vpm.c`, the version in [firmware 13.40 measurements](https://github.com/boykopovar/AnyPS5/discussions/8981#discussioncomment-19111214). No export adds a certificate, CRL, lookup method or policy object, so `X509_STORE_free` throws instead of freeing one and the object cache's comparator throws. A null store or verify parameters, and a null element array behind a positive count, throw where LibreSSL faults
|
||||
- [X509_STORE_new, X509_STORE_free and X509_STORE_set_flags](../../../core/libs/prx/libSceLibreSsl/src/X509Store.cpp) are unverified on PS5. The 136-byte store, 64-byte verify parameters, 56-byte parameter identity, 32-byte stacks and the results follow [LibreSSL 2.5.4](https://github.com/libressl/openbsd/tree/2e2c612066aa993717528a0249c15c51128d61cb/src/lib/libcrypto/x509) `x509_lu.c` and `x509_vpm.c`, the version in [firmware 13.40 measurements](https://github.com/boykopovar/AnyPS5/discussions/8981#discussioncomment-19111214). No export adds a certificate, CRL or policy object, so `X509_STORE_free` throws instead of freeing one and the object cache's comparator throws. A null store or verify parameters, and a null element array behind a positive count, throw where LibreSSL faults
|
||||
|
||||
- [X509_LOOKUP_file and X509_STORE_add_lookup](../../../core/libs/prx/libSceLibreSsl/src/X509Store.cpp) are unverified on PS5. The 80-byte method, the 32-byte lookup, the stack growth and the results follow LibreSSL 2.5.4 [`by_file.c`, `x509_lu.c`](https://github.com/libressl/openbsd/tree/2e2c612066aa993717528a0249c15c51128d61cb/src/lib/libcrypto/x509) and `stack.c`, unchanged in 2.7. The file method's `ctrl`, which loads PEM certificates and CRLs, throws: there is no certificate model. Callbacks of a guest-supplied method (`new_item`, `shutdown`, `free`) throw instead of being called, and a null store, method or listed lookup throws where LibreSSL faults
|
||||
Reference in new issue
Block a user