mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-10 06:01:52 +00:00
crypto: constant-time pss (if it survives optimization)
This commit is contained in:
parent
5fa534fb71
commit
c3656aae30
2 changed files with 22 additions and 18 deletions
|
@ -73,9 +73,7 @@ namespace ams::crypto::impl {
|
||||||
|
|
||||||
bool Verify(u8 *buf, size_t size, Hash *hash) {
|
bool Verify(u8 *buf, size_t size, Hash *hash) {
|
||||||
/* Validate sanity byte. */
|
/* Validate sanity byte. */
|
||||||
if (buf[size - 1] != TailMagic) {
|
bool is_valid = buf[size - 1] == TailMagic;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrypt maskedDB */
|
/* Decrypt maskedDB */
|
||||||
const size_t db_len = size - HashSize - 1;
|
const size_t db_len = size - HashSize - 1;
|
||||||
|
@ -87,33 +85,37 @@ namespace ams::crypto::impl {
|
||||||
db[0] &= 0x7F;
|
db[0] &= 0x7F;
|
||||||
|
|
||||||
/* Verify that DB is of the form 0000...0001 */
|
/* Verify that DB is of the form 0000...0001 */
|
||||||
s32 salt_ofs = -1;
|
s32 salt_ofs = 0;
|
||||||
for (size_t i = 0; i < db_len; i++) {
|
{
|
||||||
if (db[i] != 0) {
|
int looking_for_one = 1;
|
||||||
salt_ofs = static_cast<s32>(i) + 1;
|
int invalid_db_padding = 0;
|
||||||
break;
|
int is_zero;
|
||||||
|
int is_one;
|
||||||
|
for (size_t i = 0; i < db_len; /* ... */) {
|
||||||
|
is_zero = (db[i] == 0);
|
||||||
|
is_one = (db[i] == 1);
|
||||||
|
salt_ofs += (looking_for_one & is_one) * (static_cast<s32>(++i));
|
||||||
|
looking_for_one &= ~is_one;
|
||||||
|
invalid_db_padding |= (looking_for_one & ~is_zero);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (salt_ofs == -1) {
|
is_valid &= (invalid_db_padding == 0);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (db[salt_ofs - 1] != 1) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify salt. */
|
/* Verify salt. */
|
||||||
const u8 *salt = db + salt_ofs;
|
const u8 *salt = db + salt_ofs;
|
||||||
const size_t salt_size = db_len - salt_ofs;
|
const size_t salt_size = db_len - salt_ofs;
|
||||||
if (salt_size == 0) {
|
is_valid &= (salt_size != 0);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify hash. */
|
/* Verify hash. */
|
||||||
u8 cmp_hash[HashSize];
|
u8 cmp_hash[HashSize];
|
||||||
ON_SCOPE_EXIT { ClearMemory(cmp_hash, sizeof(cmp_hash)); };
|
ON_SCOPE_EXIT { ClearMemory(cmp_hash, sizeof(cmp_hash)); };
|
||||||
|
|
||||||
ComputeHashWithPadding(cmp_hash, hash, salt, salt_size);
|
ComputeHashWithPadding(cmp_hash, hash, salt, salt_size);
|
||||||
return IsSameBytes(cmp_hash, h, HashSize);
|
is_valid &= IsSameBytes(cmp_hash, h, HashSize);
|
||||||
|
|
||||||
|
/* Succeed if all our checks succeeded. */
|
||||||
|
return is_valid;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,8 @@ namespace ams::svc {
|
||||||
static constexpr bool IsInput = std::is_const<typename std::remove_pointer<T>::type>::value;
|
static constexpr bool IsInput = std::is_const<typename std::remove_pointer<T>::type>::value;
|
||||||
private:
|
private:
|
||||||
T pointer;
|
T pointer;
|
||||||
|
public:
|
||||||
|
constexpr ALWAYS_INLINE UserPointer(T p) : pointer(p) { /* ... */ }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
Loading…
Reference in a new issue