partition_data_manager: Make data arrays constexpr

Previously the constructor for all of these would run at program
startup, consuming time before the application can enter main().

This is also particularly dangerous, given the logging system wouldn't
have been initialized properly yet, yet the program would use the logs
to signify an error.

To rectify this, we can replace the literals with constexpr functions
that perform the conversion at compile-time, completely eliminating the
runtime cost of initializing these arrays.
This commit is contained in:
Lioncash 2020-08-03 13:18:43 -04:00
parent 9b75481755
commit 7f0f37fca7
4 changed files with 133 additions and 130 deletions

View File

@ -3,21 +3,9 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common/hex_util.h" #include "common/hex_util.h"
#include "common/logging/log.h"
namespace Common { namespace Common {
u8 ToHexNibble(char c1) {
if (c1 >= 65 && c1 <= 70)
return c1 - 55;
if (c1 >= 97 && c1 <= 102)
return c1 - 87;
if (c1 >= 48 && c1 <= 57)
return c1 - 48;
LOG_ERROR(Common, "Invalid hex digit: 0x{:02X}", c1);
return 0;
}
std::vector<u8> HexStringToVector(std::string_view str, bool little_endian) { std::vector<u8> HexStringToVector(std::string_view str, bool little_endian) {
std::vector<u8> out(str.size() / 2); std::vector<u8> out(str.size() / 2);
if (little_endian) { if (little_endian) {
@ -30,26 +18,4 @@ std::vector<u8> HexStringToVector(std::string_view str, bool little_endian) {
return out; return out;
} }
std::array<u8, 16> operator""_array16(const char* str, std::size_t len) {
if (len != 32) {
LOG_ERROR(Common,
"Attempting to parse string to array that is not of correct size (expected=32, "
"actual={}).",
len);
return {};
}
return HexStringToArray<16>(str);
}
std::array<u8, 32> operator""_array32(const char* str, std::size_t len) {
if (len != 64) {
LOG_ERROR(Common,
"Attempting to parse string to array that is not of correct size (expected=64, "
"actual={}).",
len);
return {};
}
return HexStringToArray<32>(str);
}
} // namespace Common } // namespace Common

View File

@ -14,19 +14,31 @@
namespace Common { namespace Common {
u8 ToHexNibble(char c1); constexpr u8 ToHexNibble(char c) {
if (c >= 65 && c <= 70) {
return c - 55;
}
if (c >= 97 && c <= 102) {
return c - 87;
}
return c - 48;
}
std::vector<u8> HexStringToVector(std::string_view str, bool little_endian); std::vector<u8> HexStringToVector(std::string_view str, bool little_endian);
template <std::size_t Size, bool le = false> template <std::size_t Size, bool le = false>
std::array<u8, Size> HexStringToArray(std::string_view str) { constexpr std::array<u8, Size> HexStringToArray(std::string_view str) {
std::array<u8, Size> out{}; std::array<u8, Size> out{};
if constexpr (le) { if constexpr (le) {
for (std::size_t i = 2 * Size - 2; i <= 2 * Size; i -= 2) for (std::size_t i = 2 * Size - 2; i <= 2 * Size; i -= 2) {
out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]); out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
}
} else { } else {
for (std::size_t i = 0; i < 2 * Size; i += 2) for (std::size_t i = 0; i < 2 * Size; i += 2) {
out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]); out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
}
} }
return out; return out;
} }
@ -48,7 +60,12 @@ std::string HexToString(const ContiguousContainer& data, bool upper = true) {
return out; return out;
} }
std::array<u8, 0x10> operator"" _array16(const char* str, std::size_t len); constexpr std::array<u8, 16> AsArray(const char (&data)[17]) {
std::array<u8, 0x20> operator"" _array32(const char* str, std::size_t len); return HexStringToArray<16>(data);
}
constexpr std::array<u8, 32> AsArray(const char (&data)[65]) {
return HexStringToArray<32>(data);
}
} // namespace Common } // namespace Common

View File

@ -40,12 +40,14 @@ namespace Core::Crypto {
constexpr u64 CURRENT_CRYPTO_REVISION = 0x5; constexpr u64 CURRENT_CRYPTO_REVISION = 0x5;
constexpr u64 FULL_TICKET_SIZE = 0x400; constexpr u64 FULL_TICKET_SIZE = 0x400;
using namespace Common; using Common::AsArray;
const std::array<SHA256Hash, 2> eticket_source_hashes{ // clang-format off
"B71DB271DC338DF380AA2C4335EF8873B1AFD408E80B3582D8719FC81C5E511C"_array32, // eticket_rsa_kek_source constexpr std::array eticket_source_hashes{
"E8965A187D30E57869F562D04383C996DE487BBA5761363D2D4D32391866A85C"_array32, // eticket_rsa_kekek_source AsArray("B71DB271DC338DF380AA2C4335EF8873B1AFD408E80B3582D8719FC81C5E511C"), // eticket_rsa_kek_source
AsArray("E8965A187D30E57869F562D04383C996DE487BBA5761363D2D4D32391866A85C"), // eticket_rsa_kekek_source
}; };
// clang-format on
const std::map<std::pair<S128KeyType, u64>, std::string> KEYS_VARIABLE_LENGTH{ const std::map<std::pair<S128KeyType, u64>, std::string> KEYS_VARIABLE_LENGTH{
{{S128KeyType::Master, 0}, "master_key_"}, {{S128KeyType::Master, 0}, "master_key_"},

View File

@ -27,7 +27,7 @@
#include "core/file_sys/vfs_offset.h" #include "core/file_sys/vfs_offset.h"
#include "core/file_sys/vfs_vector.h" #include "core/file_sys/vfs_vector.h"
using namespace Common; using Common::AsArray;
namespace Core::Crypto { namespace Core::Crypto {
@ -47,105 +47,123 @@ struct Package2Header {
}; };
static_assert(sizeof(Package2Header) == 0x200, "Package2Header has incorrect size."); static_assert(sizeof(Package2Header) == 0x200, "Package2Header has incorrect size.");
const std::array<SHA256Hash, 0x10> source_hashes{ // clang-format off
"B24BD293259DBC7AC5D63F88E60C59792498E6FC5443402C7FFE87EE8B61A3F0"_array32, // keyblob_mac_key_source constexpr std::array source_hashes{
"7944862A3A5C31C6720595EFD302245ABD1B54CCDCF33000557681E65C5664A4"_array32, // master_key_source AsArray("B24BD293259DBC7AC5D63F88E60C59792498E6FC5443402C7FFE87EE8B61A3F0"), // keyblob_mac_key_source
"21E2DF100FC9E094DB51B47B9B1D6E94ED379DB8B547955BEF8FE08D8DD35603"_array32, // package2_key_source AsArray("7944862A3A5C31C6720595EFD302245ABD1B54CCDCF33000557681E65C5664A4"), // master_key_source
"FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"_array32, // aes_kek_generation_source AsArray("21E2DF100FC9E094DB51B47B9B1D6E94ED379DB8B547955BEF8FE08D8DD35603"), // package2_key_source
"FBD10056999EDC7ACDB96098E47E2C3606230270D23281E671F0F389FC5BC585"_array32, // aes_key_generation_source AsArray("FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"), // aes_kek_generation_source
"C48B619827986C7F4E3081D59DB2B460C84312650E9A8E6B458E53E8CBCA4E87"_array32, // titlekek_source AsArray("FBD10056999EDC7ACDB96098E47E2C3606230270D23281E671F0F389FC5BC585"), // aes_key_generation_source
"04AD66143C726B2A139FB6B21128B46F56C553B2B3887110304298D8D0092D9E"_array32, // key_area_key_application_source AsArray("C48B619827986C7F4E3081D59DB2B460C84312650E9A8E6B458E53E8CBCA4E87"), // titlekek_source
"FD434000C8FF2B26F8E9A9D2D2C12F6BE5773CBB9DC86300E1BD99F8EA33A417"_array32, // key_area_key_ocean_source AsArray("04AD66143C726B2A139FB6B21128B46F56C553B2B3887110304298D8D0092D9E"), // key_area_key_application_source
"1F17B1FD51AD1C2379B58F152CA4912EC2106441E51722F38700D5937A1162F7"_array32, // key_area_key_system_source AsArray("FD434000C8FF2B26F8E9A9D2D2C12F6BE5773CBB9DC86300E1BD99F8EA33A417"), // key_area_key_ocean_source
"6B2ED877C2C52334AC51E59ABFA7EC457F4A7D01E46291E9F2EAA45F011D24B7"_array32, // sd_card_kek_source AsArray("1F17B1FD51AD1C2379B58F152CA4912EC2106441E51722F38700D5937A1162F7"), // key_area_key_system_source
"D482743563D3EA5DCDC3B74E97C9AC8A342164FA041A1DC80F17F6D31E4BC01C"_array32, // sd_card_save_key_source AsArray("6B2ED877C2C52334AC51E59ABFA7EC457F4A7D01E46291E9F2EAA45F011D24B7"), // sd_card_kek_source
"2E751CECF7D93A2B957BD5FFCB082FD038CC2853219DD3092C6DAB9838F5A7CC"_array32, // sd_card_nca_key_source AsArray("D482743563D3EA5DCDC3B74E97C9AC8A342164FA041A1DC80F17F6D31E4BC01C"), // sd_card_save_key_source
"1888CAED5551B3EDE01499E87CE0D86827F80820EFB275921055AA4E2ABDFFC2"_array32, // header_kek_source AsArray("2E751CECF7D93A2B957BD5FFCB082FD038CC2853219DD3092C6DAB9838F5A7CC"), // sd_card_nca_key_source
"8F783E46852DF6BE0BA4E19273C4ADBAEE16380043E1B8C418C4089A8BD64AA6"_array32, // header_key_source AsArray("1888CAED5551B3EDE01499E87CE0D86827F80820EFB275921055AA4E2ABDFFC2"), // header_kek_source
"D1757E52F1AE55FA882EC690BC6F954AC46A83DC22F277F8806BD55577C6EED7"_array32, // rsa_kek_seed3 AsArray("8F783E46852DF6BE0BA4E19273C4ADBAEE16380043E1B8C418C4089A8BD64AA6"), // header_key_source
"FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"_array32, // rsa_kek_mask0 AsArray("D1757E52F1AE55FA882EC690BC6F954AC46A83DC22F277F8806BD55577C6EED7"), // rsa_kek_seed3
AsArray("FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"), // rsa_kek_mask0
}; };
// clang-format on
const std::array<SHA256Hash, 0x20> keyblob_source_hashes{ // clang-format off
"8A06FE274AC491436791FDB388BCDD3AB9943BD4DEF8094418CDAC150FD73786"_array32, // keyblob_key_source_00 constexpr std::array keyblob_source_hashes{
"2D5CAEB2521FEF70B47E17D6D0F11F8CE2C1E442A979AD8035832C4E9FBCCC4B"_array32, // keyblob_key_source_01 AsArray("8A06FE274AC491436791FDB388BCDD3AB9943BD4DEF8094418CDAC150FD73786"), // keyblob_key_source_00
"61C5005E713BAE780641683AF43E5F5C0E03671117F702F401282847D2FC6064"_array32, // keyblob_key_source_02 AsArray("2D5CAEB2521FEF70B47E17D6D0F11F8CE2C1E442A979AD8035832C4E9FBCCC4B"), // keyblob_key_source_01
"8E9795928E1C4428E1B78F0BE724D7294D6934689C11B190943923B9D5B85903"_array32, // keyblob_key_source_03 AsArray("61C5005E713BAE780641683AF43E5F5C0E03671117F702F401282847D2FC6064"), // keyblob_key_source_02
"95FA33AF95AFF9D9B61D164655B32710ED8D615D46C7D6CC3CC70481B686B402"_array32, // keyblob_key_source_04 AsArray("8E9795928E1C4428E1B78F0BE724D7294D6934689C11B190943923B9D5B85903"), // keyblob_key_source_03
"3F5BE7B3C8B1ABD8C10B4B703D44766BA08730562C172A4FE0D6B866B3E2DB3E"_array32, // keyblob_key_source_05 AsArray("95FA33AF95AFF9D9B61D164655B32710ED8D615D46C7D6CC3CC70481B686B402"), // keyblob_key_source_04
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_06 AsArray("3F5BE7B3C8B1ABD8C10B4B703D44766BA08730562C172A4FE0D6B866B3E2DB3E"), // keyblob_key_source_05
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_07 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_06
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_07
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_08 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_08
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_09 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_09
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0A AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0A
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0B AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0B
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0C AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0C
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0D AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0D
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0E AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0E
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0F AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0F
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_10 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_10
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_11 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_11
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_12 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_12
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_13 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_13
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_14 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_14
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_15 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_15
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_16 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_16
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_17 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_17
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_18 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_18
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_19 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_19
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1A AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1A
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1B AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1B
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1C AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1C
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1D AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1D
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1E AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1E
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1F AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1F
}; };
// clang-format on
const std::array<SHA256Hash, 0x20> master_key_hashes{ // clang-format off
"0EE359BE3C864BB0782E1D70A718A0342C551EED28C369754F9C4F691BECF7CA"_array32, // master_key_00 constexpr std::array master_key_hashes{
"4FE707B7E4ABDAF727C894AAF13B1351BFE2AC90D875F73B2E20FA94B9CC661E"_array32, // master_key_01 AsArray("0EE359BE3C864BB0782E1D70A718A0342C551EED28C369754F9C4F691BECF7CA"), // master_key_00
"79277C0237A2252EC3DFAC1F7C359C2B3D121E9DB15BB9AB4C2B4408D2F3AE09"_array32, // master_key_02 AsArray("4FE707B7E4ABDAF727C894AAF13B1351BFE2AC90D875F73B2E20FA94B9CC661E"), // master_key_01
"4F36C565D13325F65EE134073C6A578FFCB0008E02D69400836844EAB7432754"_array32, // master_key_03 AsArray("79277C0237A2252EC3DFAC1F7C359C2B3D121E9DB15BB9AB4C2B4408D2F3AE09"), // master_key_02
"75FF1D95D26113550EE6FCC20ACB58E97EDEB3A2FF52543ED5AEC63BDCC3DA50"_array32, // master_key_04 AsArray("4F36C565D13325F65EE134073C6A578FFCB0008E02D69400836844EAB7432754"), // master_key_03
"EBE2BCD6704673EC0F88A187BB2AD9F1CC82B718C389425941BDC194DC46B0DD"_array32, // master_key_05 AsArray("75FF1D95D26113550EE6FCC20ACB58E97EDEB3A2FF52543ED5AEC63BDCC3DA50"), // master_key_04
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_06 AsArray("EBE2BCD6704673EC0F88A187BB2AD9F1CC82B718C389425941BDC194DC46B0DD"), // master_key_05
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_07 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_06
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_07
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_08 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_08
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_09 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_09
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0A AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0A
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0B AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0B
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0C AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0C
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0D AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0D
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0E AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0E
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0F AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0F
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_10 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_10
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_11 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_11
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_12 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_12
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_13 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_13
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_14 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_14
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_15 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_15
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_16 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_16
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_17 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_17
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_18 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_18
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_19 AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_19
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1A AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1A
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1B AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1B
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1C AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1C
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1D AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1D
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1E AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1E
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1F AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1F
}; };
// clang-format on
static constexpr u8 CalculateMaxKeyblobSourceHash() {
const auto is_zero = [](const auto& data) {
// TODO: Replace with std::all_of whenever mingw decides to update their
// libraries to include the constexpr variant of it.
for (const auto element : data) {
if (element != 0) {
return false;
}
}
return true;
};
static u8 CalculateMaxKeyblobSourceHash() {
for (s8 i = 0x1F; i >= 0; --i) { for (s8 i = 0x1F; i >= 0; --i) {
if (keyblob_source_hashes[i] != SHA256Hash{}) if (!is_zero(keyblob_source_hashes[i])) {
return static_cast<u8>(i + 1); return static_cast<u8>(i + 1);
}
} }
return 0; return 0;