1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-12-18 00:12:03 +00:00

Implement RSA2048-PSS validation.

This commit is contained in:
Michael Scire 2018-02-22 15:19:29 -08:00
parent 32238984bf
commit ead0e2ba86
2 changed files with 59 additions and 4 deletions

View file

@ -90,8 +90,61 @@ void setup_boot_config(void) {
}
}
int rsa_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size) {
/* TODO: Implement RSA-PSS, using security engine for exponentiation. */
int rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size) {
uint8_t message[RSA_2048_BYTES];
uint8_t h_buf[0x24];
/* Hardcode RSA with keyslot 0. */
const uint8_t public_exponent[4] = {0x00, 0x01, 0x00, 0x01};
set_rsa_keyslot(0, modulus, modulus_size, public_exponent, sizeof(public_exponent));
se_synchronous_exp_mod(0, message, sizeof(message), signature, signature_size);
/* Validate sanity byte. */
if (message[RSA_2048_BYTES - 1] != 0xBC) {
return 0;
}
/* Copy Salt into MGF1 Hash Buffer. */
memset(h_buf, 0, sizeof(h_buf));
memcpy(h_buf, message + RSA_2048_BYTES - 0x20 - 0x1, 0x20);
/* Decrypt maskedDB (via inline MGF1). */
uint8_t seed = 0;
uint8_t mgf1_buf[0x20];
for (unsigned int ofs = 0; ofs < RSA_2048_BYTES - 0x20 - 1; ofs += 0x20) {
h_buf[sizeof(h_buf) - 1] = seed++;
flush_dcache_range(h_buf, h_buf + sizeof(h_buf));
se_calculate_sha256(mgf1_buf, h_buf, sizeof(h_buf));
for (unsigned int i = ofs; i < ofs + 0x20 && i < RSA_2048_BYTES - 0x20 - 1; i++) {
message[i] ^= mgf1_buf[i - ofs];
}
}
/* Constant lmask for rsa-2048-pss. */
message[0] &= 0x7F;
/* Validate DB is of the form 0000...0001. */
for (unsigned int i = 0; i < RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1; i++) {
if (message[i] != 0) {
return false;
}
}
if (message[RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1] != 1) {
return false;
}
/* Check hash correctness. */
uint8_t validate_buf[8 + 0x20 + 0x20];
uint8_t validate_hash[0x20];
memset(validate_buf, 0, sizeof(validate_buf));
flush_dcache_range((uint8_t *)data, (uint8_t *)data + data_size);
se_calculate_sha256(&validate_buf[8], data, data_size);
memcpy(&validate_buf[0x28], &m_buf[RSA_2048_BYTES - 0x20 - 0x20 - 1], 0x20);
flush_dcache_range(validate_buf, validate_buf + sizeof(validate_buf));
se_calculate_sha256(validate_hash, validate_buf, sizeof(validate_buf));
return memcmp(h_buf, validate_hash, 0x20) == 0;
}
void package2_crypt_ctr(unsigned int master_key_rev, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) {
@ -153,7 +206,7 @@ void verify_header_signature(package2_header_t *header) {
}
/* This is normally only allowed on dev units, but we'll allow it anywhere. */
if (bootconfig_is_package2_unsigned() == 0 && rsa_pss_verify(header->signature, 0x100, modulus, 0x100, header->encrypted_header, 0x100) == 0) {
if (bootconfig_is_package2_unsigned() == 0 && rsa2048_pss_verify(header->signature, 0x100, modulus, 0x100, header->encrypted_header, 0x100) == 0) {
panic();
}
}
@ -324,7 +377,7 @@ void load_package2_sections(package2_meta_t *metadata, uint32_t master_key_rev)
if (bootconfig_is_package2_plaintext()) {
memcpy(dst_start, src_start, size);
} else {
package2_crypt_ctr(master_key_rev, dst_start, size, src_start, size, metadata->ctr, 0x10);
package2_crypt_ctr(master_key_rev, dst_start, size, src_start, size, metadata->section_ctrs[section], 0x10);
}
}

View file

@ -49,6 +49,7 @@
#define OP_CTX_SAVE 3
#define OP_RESTART_IN 4
#define RSA_2048_BYTES 0x100
typedef struct security_engine {
unsigned int _0x0;
@ -163,6 +164,7 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size);
/* RSA API */
void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*callback)(void));
void se_get_exp_mod_output(void *buf, size_t size);
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
/* RNG API */
void se_initialize_rng(unsigned int keyslot);