loader: update for 10.0.0

This commit is contained in:
Michael Scire 2020-04-14 02:45:28 -07:00
parent dd80e1f463
commit 73552c86c3
22 changed files with 486 additions and 56 deletions

View file

@ -42,6 +42,14 @@ namespace ams::crypto {
return Rsa2048PssSha256Verifier::Verify(sig, sig_size, mod, mod_size, exp, exp_size, msg, msg_size, work_buf, work_buf_size);
}
inline bool VerifyRsa2048PssSha256WithHash(const void *sig, size_t sig_size, const void *mod, size_t mod_size, const void *exp, size_t exp_size, const void *hash, size_t hash_size) {
return Rsa2048PssSha256Verifier::VerifyWithHash(sig, sig_size, mod, mod_size, exp, exp_size, hash, hash_size);
}
inline bool VerifyRsa2048PssSha256WithHash(const void *sig, size_t sig_size, const void *mod, size_t mod_size, const void *exp, size_t exp_size, const void *hash, size_t hash_size, void *work_buf, size_t work_buf_size) {
return Rsa2048PssSha256Verifier::VerifyWithHash(sig, sig_size, mod, mod_size, exp, exp_size, hash, hash_size, work_buf, work_buf_size);
}
inline bool VerifyRsa4096PssSha256(const void *sig, size_t sig_size, const void *mod, size_t mod_size, const void *exp, size_t exp_size, const void *msg, size_t msg_size) {
return Rsa4096PssSha256Verifier::Verify(sig, sig_size, mod, mod_size, exp, exp_size, msg, msg_size);
}
@ -50,4 +58,12 @@ namespace ams::crypto {
return Rsa4096PssSha256Verifier::Verify(sig, sig_size, mod, mod_size, exp, exp_size, msg, msg_size, work_buf, work_buf_size);
}
inline bool VerifyRsa4096PssSha256WithHash(const void *sig, size_t sig_size, const void *mod, size_t mod_size, const void *exp, size_t exp_size, const void *hash, size_t hash_size) {
return Rsa4096PssSha256Verifier::VerifyWithHash(sig, sig_size, mod, mod_size, exp, exp_size, hash, hash_size);
}
inline bool VerifyRsa4096PssSha256WithHash(const void *sig, size_t sig_size, const void *mod, size_t mod_size, const void *exp, size_t exp_size, const void *hash, size_t hash_size, void *work_buf, size_t work_buf_size) {
return Rsa4096PssSha256Verifier::VerifyWithHash(sig, sig_size, mod, mod_size, exp, exp_size, hash, hash_size, work_buf, work_buf_size);
}
}

View file

@ -23,13 +23,14 @@
namespace ams::crypto {
template<size_t ModulusSize, typename Hash> /* requires HashFunction<Hash> */
template<size_t _ModulusSize, typename Hash> /* requires HashFunction<Hash> */
class RsaPssVerifier {
NON_COPYABLE(RsaPssVerifier);
NON_MOVEABLE(RsaPssVerifier);
public:
static constexpr size_t HashSize = Hash::HashSize;
static constexpr size_t SaltSize = Hash::HashSize;
static constexpr size_t ModulusSize = _ModulusSize;
static constexpr size_t SignatureSize = ModulusSize;
static constexpr size_t MaximumExponentSize = 3;
static constexpr size_t RequiredWorkBufferSize = RsaCalculator<ModulusSize, MaximumExponentSize>::RequiredWorkBufferSize;
@ -70,8 +71,15 @@ namespace ams::crypto {
u8 message[SignatureSize];
ON_SCOPE_EXIT { ClearMemory(message, sizeof(message)); };
return this->calculator.ExpMod(message, signature, SignatureSize) &&
impl.Verify(message, sizeof(message), std::addressof(this->hash));
if (!this->calculator.ExpMod(message, signature, SignatureSize)) {
return false;
}
u8 calc_hash[Hash::HashSize];
this->hash.GetHash(calc_hash, sizeof(calc_hash));
ON_SCOPE_EXIT { ClearMemory(calc_hash, sizeof(calc_hash)); };
return impl.Verify(message, sizeof(message), calc_hash, sizeof(calc_hash));
}
bool Verify(const void *signature, size_t size, void *work_buf, size_t work_buf_size) {
@ -83,8 +91,47 @@ namespace ams::crypto {
u8 message[SignatureSize];
ON_SCOPE_EXIT { ClearMemory(message, sizeof(message)); };
return this->calculator.ExpMod(message, signature, SignatureSize, work_buf, work_buf_size) &&
impl.Verify(message, sizeof(message), std::addressof(this->hash));
if (!this->calculator.ExpMod(message, signature, SignatureSize, work_buf, work_buf_size)) {
return false;
}
u8 calc_hash[Hash::HashSize];
this->hash.GetHash(calc_hash, sizeof(calc_hash));
ON_SCOPE_EXIT { ClearMemory(calc_hash, sizeof(calc_hash)); };
return impl.Verify(message, sizeof(message), calc_hash, sizeof(calc_hash));
}
bool VerifyWithHash(const void *signature, size_t size, const void *hash, size_t hash_size) {
AMS_ASSERT(this->state == State::Initialized);
AMS_ASSERT(size == SignatureSize);
ON_SCOPE_EXIT { this->state = State::Done; };
impl::RsaPssImpl<Hash> impl;
u8 message[SignatureSize];
ON_SCOPE_EXIT { ClearMemory(message, sizeof(message)); };
if (!this->calculator.ExpMod(message, signature, SignatureSize)) {
return false;
}
return impl.Verify(message, sizeof(message), static_cast<const u8 *>(hash), hash_size);
}
bool VerifyWithHash(const void *signature, size_t size, const void *hash, size_t hash_size, void *work_buf, size_t work_buf_size) {
AMS_ASSERT(this->state == State::Initialized);
AMS_ASSERT(size == SignatureSize);
ON_SCOPE_EXIT { this->state = State::Done; };
impl::RsaPssImpl<Hash> impl;
u8 message[SignatureSize];
ON_SCOPE_EXIT { ClearMemory(message, sizeof(message)); };
if (!this->calculator.ExpMod(message, signature, SignatureSize, work_buf, work_buf_size)) {
return false;
}
return impl.Verify(message, sizeof(message), static_cast<const u8 *>(hash), hash_size);
}
static bool Verify(const void *sig, size_t sig_size, const void *mod, size_t mod_size, const void *exp, size_t exp_size, const void *msg, size_t msg_size) {
@ -104,6 +151,22 @@ namespace ams::crypto {
verifier.Update(msg, msg_size);
return verifier.Verify(sig, sig_size, work_buf, work_buf_size);
}
static bool VerifyWithHash(const void *sig, size_t sig_size, const void *mod, size_t mod_size, const void *exp, size_t exp_size, const void *hash, size_t hash_size) {
RsaPssVerifier<ModulusSize, Hash> verifier;
if (!verifier.Initialize(mod, mod_size, exp, exp_size)) {
return false;
}
return verifier.VerifyWithHash(sig, sig_size, hash, hash_size);
}
static bool VerifyWithHash(const void *sig, size_t sig_size, const void *mod, size_t mod_size, const void *exp, size_t exp_size, const void *hash, size_t hash_size, void *work_buf, size_t work_buf_size) {
RsaPssVerifier<ModulusSize, Hash> verifier;
if (!verifier.Initialize(mod, mod_size, exp, exp_size)) {
return false;
}
return verifier.VerifyWithHash(sig, sig_size, hash, hash_size, work_buf, work_buf_size);
}
};
}

View file

@ -31,19 +31,22 @@ namespace ams::crypto::impl {
private:
static constexpr u8 TailMagic = 0xBC;
private:
static void ComputeHashWithPadding(void *dst, Hash *hash, const void *salt, size_t salt_size) {
static void ComputeHashWithPadding(void *dst, const u8 *user_hash, size_t user_hash_size, const void *salt, size_t salt_size) {
AMS_ASSERT(user_hash_size == HashSize);
/* Initialize our buffer. */
u8 buf[8 + HashSize];
std::memset(buf, 0, 8);
hash->GetHash(buf + 8, HashSize);
std::memcpy(buf + 8, user_hash, HashSize);
ON_SCOPE_EXIT { ClearMemory(buf, sizeof(buf)); };
/* Calculate our hash. */
hash->Initialize();
hash->Update(buf, sizeof(buf));
hash->Update(salt, salt_size);
hash->GetHash(dst, HashSize);
Hash hash;
hash.Initialize();
hash.Update(buf, sizeof(buf));
hash.Update(salt, salt_size);
hash.GetHash(dst, HashSize);
}
static void ApplyMGF1(u8 *dst, size_t dst_size, const void *src, size_t src_size) {
@ -71,7 +74,7 @@ namespace ams::crypto::impl {
public:
RsaPssImpl() { /* ... */ }
bool Verify(u8 *buf, size_t size, Hash *hash) {
bool Verify(u8 *buf, size_t size, const u8 *hash, size_t hash_size) {
/* Validate sanity byte. */
bool is_valid = buf[size - 1] == TailMagic;
@ -112,7 +115,7 @@ namespace ams::crypto::impl {
u8 cmp_hash[HashSize];
ON_SCOPE_EXIT { ClearMemory(cmp_hash, sizeof(cmp_hash)); };
ComputeHashWithPadding(cmp_hash, hash, salt, salt_size);
ComputeHashWithPadding(cmp_hash, hash, hash_size, salt, salt_size);
is_valid &= IsSameBytes(cmp_hash, h, HashSize);
/* Succeed if all our checks succeeded. */

View file

@ -31,6 +31,8 @@ namespace ams::ldr {
R_DEFINE_ERROR_RESULT(NotPinned, 8);
R_DEFINE_ERROR_RESULT(InvalidProgramId, 9);
R_DEFINE_ERROR_RESULT(InvalidVersion, 10);
R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11);
R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 12);
R_DEFINE_ERROR_RESULT(InsufficientAddressSpace, 51);
R_DEFINE_ERROR_RESULT(InvalidNro, 52);