From 83216409d2988003a4367c7334967f03092cbf0b Mon Sep 17 00:00:00 2001 From: Mat M Date: Thu, 22 Feb 2018 22:58:39 -0500 Subject: [PATCH] all: Use bool where applicable (#30) --- exosphere/bootconfig.h | 5 ++- exosphere/configitem.c | 6 ++-- exosphere/configitem.h | 6 ++-- exosphere/gcm.c | 10 +++--- exosphere/gcm.h | 7 ++++- exosphere/masterkey.c | 29 +++++++++--------- exosphere/mmu.h | 1 + exosphere/package2.c | 69 +++++++++++++++++++++--------------------- exosphere/se.c | 9 +++--- exosphere/smc_api.c | 36 +++++++++++----------- exosphere/smc_user.c | 65 +++++++++++++++++++-------------------- exosphere/smc_user.h | 8 ++--- exosphere/userpage.c | 28 ++++++++--------- exosphere/userpage.h | 7 +++-- exosphere/utils.h | 13 ++++---- 15 files changed, 154 insertions(+), 145 deletions(-) diff --git a/exosphere/bootconfig.h b/exosphere/bootconfig.h index f89191163..67db52e34 100644 --- a/exosphere/bootconfig.h +++ b/exosphere/bootconfig.h @@ -15,9 +15,8 @@ typedef struct { void bootconfig_load_and_verify(const bootconfig_t *bootconfig); void bootconfig_clear(void); - /* Actual configuration getters. */ -int bootconfig_is_package2_plaintext(void); -void bootconfig_is_package2_unsigned(void); +bool bootconfig_is_package2_plaintext(void); +bool bootconfig_is_package2_unsigned(void); #endif \ No newline at end of file diff --git a/exosphere/configitem.c b/exosphere/configitem.c index 051b75f50..8a9cd2d65 100644 --- a/exosphere/configitem.c +++ b/exosphere/configitem.c @@ -13,13 +13,13 @@ uint32_t configitem_set(enum ConfigItem item, uint64_t value) { g_battery_profile = ((int)(value != 0)) & 1; } -uint64_t configitem_is_recovery_boot(void) { +bool configitem_is_recovery_boot(void) { uint64_t is_recovery_boot; if (configitem_get(CONFIGITEM_ISRECOVERYBOOT, &is_recovery_boot) != 0) { panic(); } - - return is_recovery_boot; + + return is_recovery_boot != 0; } uint32_t configitem_get(enum ConfigItem item, uint64_t *p_outvalue) { diff --git a/exosphere/configitem.h b/exosphere/configitem.h index c5a35f9cc..593f653e9 100644 --- a/exosphere/configitem.h +++ b/exosphere/configitem.h @@ -1,9 +1,9 @@ #ifndef EXOSPHERE_CFG_ITEM_H #define EXOSPHERE_CFG_ITEM_H +#include #include - enum ConfigItem { CONFIGITEM_DISABLEPROGRAMVERIFICATION = 1, CONFIGITEM_MEMORYCONFIGURATION = 2, @@ -23,7 +23,7 @@ enum ConfigItem { uint32_t configitem_set(enum ConfigItem item, uint64_t value); uint32_t configitem_get(enum ConfigItem item, uint64_t *p_outvalue); -uint64_t configitem_is_recovery_boot(void); -uint64_t configitem_is_retail(void); +bool configitem_is_recovery_boot(void); +bool configitem_is_retail(void); #endif \ No newline at end of file diff --git a/exosphere/gcm.c b/exosphere/gcm.c index dbded44ab..15040b4df 100644 --- a/exosphere/gcm.c +++ b/exosphere/gcm.c @@ -56,7 +56,7 @@ static void gf128_mul(uint8_t *dst, const uint8_t *x, const uint8_t *y) { /* Performs an AES-GCM GHASH operation over the data into dst. */ -static void ghash(void *dst, const void *data, size_t data_size, const void *j_block, int encrypt) { +static void ghash(void *dst, const void *data, size_t data_size, const void *j_block, bool encrypt) { uint8_t x[0x10]; uint8_t h[0x10]; @@ -112,7 +112,7 @@ static void ghash(void *dst, const void *data, size_t data_size, const void *j_b /* This function is a doozy. It decrypts and validates a (non-standard) AES-GCM wrapped keypair. */ -size_t gcm_decrypt_key(void *dst, size_t dst_size, const void *src, size_t src_size, const void *sealed_kek, size_t kek_size, const void *wrapped_key, size_t key_size, unsigned int usecase, int is_personalized) { +size_t gcm_decrypt_key(void *dst, size_t dst_size, const void *src, size_t src_size, const void *sealed_kek, size_t kek_size, const void *wrapped_key, size_t key_size, unsigned int usecase, bool is_personalized) { if (is_personalized == 0) { /* Devkit keys use a different keyformat without a MAC/Device ID. */ if (src_size <= 0x10 || src_size - 0x10 > dst_size) { @@ -132,20 +132,20 @@ size_t gcm_decrypt_key(void *dst, size_t dst_size, const void *src, size_t src_s se_aes_ctr_crypt(KEYSLOT_SWITCH_TEMPKEY, dst, dst_size, src + 0x10, src_size - 0x10, src, 0x10); - if (is_personalized == 0) { + if (!is_personalized) { /* Devkit non-personalized keys have no further authentication. */ return src_size - 0x10; } /* J = GHASH(CTR); */ uint8_t j_block[0x10]; - ghash(j_block, src, 0x10, NULL, 0); + ghash(j_block, src, 0x10, NULL, false); /* MAC = GHASH(PLAINTEXT) ^ ENCRYPT(J) */ /* Note: That MAC is calculated over plaintext is non-standard. */ /* It is supposed to be over the ciphertext. */ uint8_t calc_mac[0x10]; - ghash(calc_mac, dst, src_size - 0x20, j_block, 1); + ghash(calc_mac, dst, src_size - 0x20, j_block, true); /* Const-time memcmp. */ const uint8_t *src_bytes = src; diff --git a/exosphere/gcm.h b/exosphere/gcm.h index 03911ffba..15caa11aa 100644 --- a/exosphere/gcm.h +++ b/exosphere/gcm.h @@ -1,8 +1,13 @@ #ifndef EXOSPHERE_GCM_H #define EXOSPHERE_GCM_H +#include #include -size_t gcm_decrypt_key(void *dst, size_t dst_size, const void *src, size_t src_size, const void *sealed_kek, size_t kek_size, const void *wrapped_key, size_t key_size, unsigned int usecase, int is_personalized); +size_t gcm_decrypt_key(void *dst, size_t dst_size, + const void *src, size_t src_size, + const void *sealed_kek, size_t kek_size, + const void *wrapped_key, size_t key_size, + unsigned int usecase, bool is_personalized); #endif diff --git a/exosphere/masterkey.c b/exosphere/masterkey.c index b7fde1916..f1bba7989 100644 --- a/exosphere/masterkey.c +++ b/exosphere/masterkey.c @@ -1,3 +1,4 @@ +#include #include #include "utils.h" @@ -5,7 +6,7 @@ #include "se.h" unsigned int g_mkey_revision = 0; -int g_determined_mkey_revision = 0; +bool g_determined_mkey_revision = false; uint8_t g_old_masterkeys[MASTERKEY_REVISION_MAX][0x10]; @@ -20,9 +21,9 @@ const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] = {0x0A, 0x0D, 0xDF, 0x34, 0x22, 0x06, 0x6C, 0xA4, 0xE6, 0xB1, 0xEC, 0x71, 0x85, 0xCA, 0x4E, 0x07}, /* Master key 02 encrypted with Master key 03. */ }; -int check_mkey_revision(unsigned int revision) { +bool check_mkey_revision(unsigned int revision) { uint8_t final_vector[0x10]; - + unsigned int check_keyslot = KEYSLOT_SWITCH_MASTERKEY; if (revision > 0) { /* Generate old master key array. */ @@ -32,24 +33,24 @@ int check_mkey_revision(unsigned int revision) { check_keyslot = KEYSLOT_SWITCH_TEMPKEY; } } - + se_aes_ecb_decrypt_block(check_keyslot, final_vector, 0x10, mkey_vectors[0], 0x10); for (unsigned int i = 0; i < 0x10; i++) { if (final_vector[i] != 0) { - return 0; + return false; } } - return 1; + return true; } void mkey_detect_revision(void) { - if (g_determined_mkey_revision == 1) { + if (g_determined_mkey_revision) { panic(); } for (unsigned int rev = 0; rev < MASTERKEY_REVISION_MAX; rev++) { if (check_mkey_revision(rev)) { - g_determined_mkey_revision = 1; + g_determined_mkey_revision = true; g_mkey_revision = rev; break; } @@ -58,28 +59,28 @@ void mkey_detect_revision(void) { /* We must have determined the master key, or we're not running on a Switch. */ /* TODO: When panic is implemented, make this a really distinctive color. */ /* Maybe bright red? */ - if (g_determined_mkey_revision == 0) { + if (!g_determined_mkey_revision) { panic(); } } unsigned int mkey_get_revision(void) { - if (g_determined_mkey_revision == 0) { + if (!g_determined_mkey_revision) { panic(); } - + return g_mkey_revision; } unsigned int mkey_get_keyslot(unsigned int revision) { - if (g_determined_mkey_revision == 0 || revision >= MASTERKEY_REVISION_MAX) { + if (!g_determined_mkey_revision || revision >= MASTERKEY_REVISION_MAX) { panic(); } - + if (revision > g_mkey_revision) { panic(); } - + if (revision == g_mkey_revision) { return KEYSLOT_SWITCH_MASTERKEY; } else { diff --git a/exosphere/mmu.h b/exosphere/mmu.h index 9a2ed391d..49c556449 100644 --- a/exosphere/mmu.h +++ b/exosphere/mmu.h @@ -1,6 +1,7 @@ #ifndef EXOSPHERE_MMU_H #define EXOSPHERE_MMU_H +#include #include #include #include "utils.h" diff --git a/exosphere/package2.c b/exosphere/package2.c index 5223b3a9d..338629e69 100644 --- a/exosphere/package2.c +++ b/exosphere/package2.c @@ -1,3 +1,4 @@ +#include #include #include "utils.h" @@ -90,7 +91,7 @@ void setup_boot_config(void) { } } -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) { +bool 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]; @@ -102,7 +103,7 @@ int rsa2048_pss_verify(const void *signature, size_t signature_size, const void /* Validate sanity byte. */ if (message[RSA_2048_BYTES - 1] != 0xBC) { - return 0; + return false; } /* Copy Salt into MGF1 Hash Buffer. */ @@ -211,85 +212,85 @@ void verify_header_signature(package2_header_t *header) { } } -int validate_package2_metadata(package2_meta_t *metadata) { +bool validate_package2_metadata(package2_meta_t *metadata) { if (metadata->magic != MAGIC_PK21) { - return 0; + return false; } - + /* Package2 size, version number is stored XORed in header CTR. */ /* Nintendo, what the fuck? */ uint32_t package_size = metadata->ctr_dwords[0] ^ metadata->ctr_dwords[2] ^ metadata->ctr_dwords[3]; uint8_t header_version = (uint8_t)((metadata->ctr_dwords[1] ^ (metadata->ctr_dwords[1] >> 16) ^ (metadata->ctr_dwords[1] >> 24)) & 0xFF); - + /* Ensure package isn't too big or too small. */ if (package_size <= sizeof(package2_header_t) || package_size > PACKAGE2_SIZE_MAX - sizeof(package2_header_t)) { - return 0; + return false; } - + /* Validate that we're working with a header we know how to handle. */ if (header_version > MASTERKEY_REVISION_MAX) { - return 0; + return false; } - + /* Require aligned entrypoint. */ if (metadata->entrypoint & 3) { - return 0; + return false; } - + /* Validate section size sanity. */ if (metadata->section_sizes[0] + metadata->section_sizes[1] + metadata->section_sizes[2] + sizeof(package2_header_t) != package_size) { - return 0; + return false; } - - int entrypoint_found = 0; - + + bool entrypoint_found = false; + /* Header has space for 4 sections, but only 3 are validated/potentially loaded on hardware. */ for (unsigned int section = 0; section < PACKAGE2_SECTION_MAX; section++) { /* Validate section size alignment. */ if (metadata->section_sizes[section] & 3) { - return 0; + return false; } - + /* Validate section does not overflow. */ if (check_32bit_additive_overflow(metadata->section_offsets[section], metadata->section_sizes[section])) { - return 0; + return false; } - + /* Check for entrypoint presence. */ uint32_t section_end = metadata->section_offsets[section] + metadata->section_sizes[section]; if (metadata->section_offsets[section] <= metadata->entrypoint && metadata->entrypoint < section_end) { - entrypoint_found = 1; + entrypoint_found = true; } - + /* Ensure no overlap with later sections. */ for (unsigned int later_section = section + 1; later_section < PACKAGE2_SECTION_MAX; later_section++) { uint32_t later_section_end = metadata->section_offsets[later_section] + metadata->section_sizes[later_section]; if (overlaps(metadata->section_offsets[section], section_end, metadata->section_offsets[later_section], later_section_end)) { - return 0; + return false; } } - + /* Validate section hashes. */ void *section_data = (void *)((uint8_t *)NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS + sizeof(package2_header_t) + metadata->section_offsets[section]); uint8_t calculated_hash[0x20]; se_calculate_sha256(calculated_hash, section_data, metadata->section_sizes[section]); if (memcmp(calculated_hash, metadata->section_hashes[section], sizeof(metadata->section_hashes[section])) != 0) { - return 0; + return false; } } - + /* Ensure that entrypoint is present in one of our sections. */ if (!entrypoint_found) { - return 0; + return false; } - + /* Perform version checks. */ /* We will be compatible with all package2s released before current, but not newer ones. */ if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_400_CURRENT) { - return 0; + return false; } - - return 1; + + return true; } /* Decrypts package2 header, and returns the master key revision required. */ @@ -322,12 +323,12 @@ void load_package2_sections(package2_meta_t *metadata, uint32_t master_key_rev) void *load_buf = NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS; /* Check whether any of our sections overlap this region. If they do, we must relocate and copy from elsewhere. */ - int needs_relocation = 0; + bool needs_relocation = false; for (unsigned int section = 0; section < PACKAGE2_SECTION_MAX; section++) { uint64_t section_start = DRAM_BASE_PHYSICAL + (uint64_t)metadata->section_offsets[section]; uint64_t section_end = section_start + (uint64_t)metadata->section_sizes[section]; if (overlaps(section_start, section_end, (uint64_t)(NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS), (uint64_t)(NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS) + PACKAGE2_SIZE_MAX)) { - needs_relocation = 1; + needs_relocation = true; } } if (needs_relocation) { @@ -336,7 +337,7 @@ void load_package2_sections(package2_meta_t *metadata, uint32_t master_key_rev) /* However, Nintendo tries panics after 8 loops if a safe section is not found. */ /* This should never be the case, mathematically. */ /* We will replicate this behavior. */ - int found_safe_carveout = 0; + bool found_safe_carveout = false; uint64_t potential_base_start = DRAM_BASE_PHYSICAL; uint64_t potential_base_end = potential_base_start + PACKAGE2_SIZE_MAX; for (unsigned int i = 0; i < 8; i++) { diff --git a/exosphere/se.c b/exosphere/se.c index 9933759b8..477ec2584 100644 --- a/exosphere/se.c +++ b/exosphere/se.c @@ -214,7 +214,7 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr trigger_se_aes_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size); } -void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, unsigned int crypt_config, int encrypt, unsigned int (*callback)(void)) { +void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, unsigned int crypt_config, bool encrypt, unsigned int (*callback)(void)) { if (keyslot >= KEYSLOT_AES_MAX) { panic(); } @@ -224,7 +224,6 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, } /* Setup Config register. */ - encrypt &= 1; if (encrypt) { SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); } else { @@ -263,17 +262,17 @@ void se_aes_ctr_crypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint /* Unknown what this write does, but official code writes it for CTR mode. */ SECURITY_ENGINE->_0x80C = 1; set_se_ctr(ctr); - se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x81E, 1, callback); + se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x81E, true, callback); } void se_aes_cbc_encrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)) { set_aes_keyslot_iv(keyslot, iv, 0x10); - se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x44, 1, callback); + se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x44, true, callback); } void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)) { set_aes_keyslot_iv(keyslot, iv, 0x10); - se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x66, 0, callback); + se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x66, false, callback); } diff --git a/exosphere/smc_api.c b/exosphere/smc_api.c index 88746dcf6..2e307e975 100644 --- a/exosphere/smc_api.c +++ b/exosphere/smc_api.c @@ -97,7 +97,7 @@ smc_table_t g_smc_tables[2] = { } }; -int g_is_smc_in_progress = 0; +bool g_is_smc_in_progress = false; uint32_t (*g_smc_callback)(void *, uint64_t) = NULL; uint64_t g_smc_callback_key = 0; @@ -162,9 +162,9 @@ uint32_t smc_wrapper_sync(smc_args_t *args, uint32_t (*handler)(smc_args_t *)) { if (g_is_smc_in_progress) { return 3; } - g_is_smc_in_progress = 1; + g_is_smc_in_progress = true; result = handler(args); - g_is_smc_in_progress = 0; + g_is_smc_in_progress = false; return result; } @@ -191,7 +191,7 @@ uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *), /* smcCheckStatus needs to be called. */ result = 3; } - g_is_smc_in_progress = 0; + g_is_smc_in_progress = false; return result; } @@ -271,7 +271,7 @@ uint32_t smc_exp_mod_get_result(void *buf, uint64_t size) { se_get_exp_mod_output(buf, 0x100); /* smc_exp_mod is done now. */ - g_is_smc_in_progress = 0; + g_is_smc_in_progress = false; return 0; } @@ -297,7 +297,7 @@ uint32_t smc_crypt_aes_status_check(void *buf, uint64_t size) { return 3; } /* smc_crypt_aes is done now. */ - g_is_smc_in_progress = 0; + g_is_smc_in_progress = false; return 0; } @@ -346,7 +346,7 @@ uint32_t smc_unwrap_rsa_oaep_wrapped_titlekey_get_result(void *buf, uint64_t siz se_get_exp_mod_output(wrapped_titlekey, 0x100); if (tkey_rsa_oaep_unwrap(aes_wrapped_titlekey, 0x10, rsa_wrapped_titlekey, 0x100) != 0x10) { /* Failed to extract RSA OAEP wrapped key. */ - g_is_smc_in_progress = 0; + g_is_smc_in_progress = false; return 2; } @@ -357,7 +357,7 @@ uint32_t smc_unwrap_rsa_oaep_wrapped_titlekey_get_result(void *buf, uint64_t siz p_sealed_key[1] = sealed_titlekey[1]; /* smc_unwrap_rsa_oaep_wrapped_titlekey is done now. */ - g_is_smc_in_progress = 0; + g_is_smc_in_progress = false; return 0; } @@ -394,18 +394,11 @@ uint32_t smc_get_random_bytes_for_priv(smc_args_t *args) { /* This is an interesting SMC. */ /* The kernel must NEVER be unable to get random bytes, if it needs them */ /* As such: */ - + uint32_t result; - + /* TODO: Make atomic. */ - if (g_is_smc_in_progress == 0) { - g_is_smc_in_progress = 1; - /* If the kernel isn't denied service by a usermode SMC, generate fresh random bytes. */ - result = user_get_random_bytes(args); - /* Also, refill our cache while we have the chance in case we get denied later. */ - randomcache_refill(); - g_is_smc_in_progress = 0; - } else { + if (g_is_smc_in_progress) { if (args->X[1] > 0x38) { return 2; } @@ -413,6 +406,13 @@ uint32_t smc_get_random_bytes_for_priv(smc_args_t *args) { size_t num_bytes = (size_t)args->X[1]; randomcache_getbytes(&args->X[1], num_bytes); result = 0; + } else { + g_is_smc_in_progress = true; + /* If the kernel isn't denied service by a usermode SMC, generate fresh random bytes. */ + result = user_get_random_bytes(args); + /* Also, refill our cache while we have the chance in case we get denied later. */ + randomcache_refill(); + g_is_smc_in_progress = false; } return result; } diff --git a/exosphere/smc_user.c b/exosphere/smc_user.c index 416548581..511857d7e 100644 --- a/exosphere/smc_user.c +++ b/exosphere/smc_user.c @@ -1,3 +1,4 @@ +#include #include #include "utils.h" @@ -12,26 +13,26 @@ #include "titlekey.h" /* Globals. */ -int g_crypt_aes_done = 0; -int g_exp_mod_done = 0; +bool g_crypt_aes_done = false; +bool g_exp_mod_done = false; uint8_t g_secure_exp_mod_exponent[0x100]; uint8_t g_rsa_oaep_exponent[0x100]; -void set_exp_mod_done(int done) { - g_exp_mod_done = done & 1; +void set_exp_mod_done(bool done) { + g_exp_mod_done = done; } -int get_exp_mod_done(void) { +bool get_exp_mod_done(void) { return g_exp_mod_done; } -uint32_t exp_mod_done_handler(void) { - set_exp_mod_done(1); - +uint32_t exp_mod_done_handler(void) { + set_exp_mod_done(true); + se_trigger_interrupt(); - + return 0; } @@ -67,7 +68,7 @@ uint32_t user_exp_mod(smc_args_t *args) { return 2; } - set_exp_mod_done(0); + set_exp_mod_done(false); /* Hardcode RSA keyslot 0. */ set_rsa_keyslot(0, modulus, 0x100, exponent, exponent_size); se_exp_mod(0, input, 0x100, exp_mod_done_handler); @@ -122,16 +123,16 @@ uint32_t user_generate_aes_kek(smc_args_t *args) { uint8_t usecase = (uint8_t)((packed_options >> 5) & 3); /* Switched the output based on whether it should be console unique. */ - int is_personalized = (int)(packed_options & 1); + bool is_personalized = (int)(packed_options & 1); - uint64_t is_recovery_boot = configitem_is_recovery_boot(); + bool is_recovery_boot = configitem_is_recovery_boot(); /* Mask 2 is only allowed when booted from recovery. */ - if (mask_id == 2 && is_recovery_boot == 0) { + if (mask_id == 2 && !is_recovery_boot) { return 2; } /* Mask 1 is only allowed when booted normally. */ - if (mask_id == 1 && is_recovery_boot != 0) { + if (mask_id == 1 && is_recovery_boot) { return 2; } @@ -209,21 +210,21 @@ uint32_t user_load_aes_key(smc_args_t *args) { } -void set_crypt_aes_done(int done) { - g_crypt_aes_done = done & 1; +void set_crypt_aes_done(bool done) { + g_crypt_aes_done = done; } -int get_crypt_aes_done(void) { +bool get_crypt_aes_done(void) { return g_crypt_aes_done; } uint32_t crypt_aes_done_handler(void) { se_check_for_error(); - - set_crypt_aes_done(1); - + + set_crypt_aes_done(true); + se_trigger_interrupt(); - + return 0; } @@ -243,7 +244,7 @@ uint32_t user_crypt_aes(smc_args_t *args) { panic(); } - set_crypt_aes_done(0); + set_crypt_aes_done(false); uint64_t result = 0; switch (mode) { @@ -272,7 +273,7 @@ uint32_t user_generate_specific_aes_key(smc_args_t *args) { uint64_t wrapped_key[2]; uint8_t key[0x10]; unsigned int master_key_rev; - int should_mask; + bool should_mask; wrapped_key[0] = args->X[1]; wrapped_key[1] = args->X[2]; @@ -283,7 +284,7 @@ uint32_t user_generate_specific_aes_key(smc_args_t *args) { if (args->X[3] > 1) { return 2; } - should_mask = (int)(args->X[3]); + should_mask = args->X[3] != 0; unsigned int keyslot; @@ -358,7 +359,7 @@ uint32_t user_compute_cmac(smc_args_t *args) { uint32_t user_load_rsa_oaep_key(smc_args_t *args) { uint64_t sealed_kek[2]; uint64_t wrapped_key[2]; - int is_personalized; + bool is_personalized; uint8_t user_data[0x400]; void *user_address; @@ -372,7 +373,7 @@ uint32_t user_load_rsa_oaep_key(smc_args_t *args) { if (args->X[3] > 1) { return 2; } - is_personalized = (int)args->X[3]; + is_personalized = args->X[3] != 0; user_address = (void *)args->X[4]; size = (size_t)args->X[5]; wrapped_key[0] = args->X[6]; @@ -401,7 +402,7 @@ uint32_t user_load_rsa_oaep_key(smc_args_t *args) { uint32_t user_decrypt_rsa_private_key(smc_args_t *args) { uint64_t sealed_kek[2]; uint64_t wrapped_key[2]; - int is_personalized; + bool is_personalized; uint8_t user_data[0x400]; void *user_address; @@ -415,7 +416,7 @@ uint32_t user_decrypt_rsa_private_key(smc_args_t *args) { if (args->X[3] > 1) { return 2; } - is_personalized = (int)args->X[3]; + is_personalized = args->X[3] != 0; user_address = (void *)args->X[4]; size = (size_t)args->X[5]; wrapped_key[0] = args->X[6]; @@ -453,7 +454,7 @@ uint32_t user_decrypt_rsa_private_key(smc_args_t *args) { uint32_t user_load_secure_exp_mod_key(smc_args_t *args) { uint64_t sealed_kek[2]; uint64_t wrapped_key[2]; - int is_personalized; + bool is_personalized; uint8_t user_data[0x400]; void *user_address; @@ -467,7 +468,7 @@ uint32_t user_load_secure_exp_mod_key(smc_args_t *args) { if (args->X[3] > 1) { return 2; } - is_personalized = (int)args->X[3]; + is_personalized = args->X[3] != 0; user_address = (void *)args->X[4]; size = (size_t)args->X[5]; wrapped_key[0] = args->X[6]; @@ -521,7 +522,7 @@ uint32_t user_secure_exp_mod(smc_args_t *args) { return 2; } - set_exp_mod_done(0); + set_exp_mod_done(false); /* Hardcode RSA keyslot 0. */ set_rsa_keyslot(0, modulus, 0x100, g_secure_exp_mod_exponent, 0x100); se_exp_mod(0, input, 0x100, exp_mod_done_handler); @@ -554,7 +555,7 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) { return 2; } - set_exp_mod_done(0); + set_exp_mod_done(false); /* Expected label_hash occupies args->X[3] to args->X[6]. */ tkey_set_expected_label_hash(&args->X[3]); diff --git a/exosphere/smc_user.h b/exosphere/smc_user.h index 4c65d0b91..58deda4c6 100644 --- a/exosphere/smc_user.h +++ b/exosphere/smc_user.h @@ -19,10 +19,10 @@ uint32_t user_load_titlekey(smc_args_t *args); uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args); -void set_crypt_aes_done(int done); -int get_crypt_aes_done(void); +void set_crypt_aes_done(bool done); +bool get_crypt_aes_done(void); -void set_exp_mod_done(int done); -int get_exp_mod_done(void); +void set_exp_mod_done(bool done); +bool get_exp_mod_done(void); #endif \ No newline at end of file diff --git a/exosphere/userpage.c b/exosphere/userpage.c index 6e0bf2801..6fdcc3cf4 100644 --- a/exosphere/userpage.c +++ b/exosphere/userpage.c @@ -7,10 +7,10 @@ uint64_t g_secure_page_user_address = NULL; /* Create a user page reference for the desired address. */ /* Returns 1 on success, 0 on failure. */ -int upage_init(upage_ref_t *upage, void *user_address) { +bool upage_init(upage_ref_t *upage, void *user_address) { upage->user_page = get_page_for_address(user_address); upage->secure_page = 0ULL; - + if (g_secure_page_user_address != NULL) { /* Different physical address indicate SPL was rebooted, or another process got access to svcCallSecureMonitor. Panic. */ if (g_secure_page_user_address != upage->user_page) { @@ -25,38 +25,38 @@ int upage_init(upage_ref_t *upage, void *user_address) { upage->secure_page = SECURE_USER_PAGE_ADDR; } } - + return upage->secure_page != 0ULL; } -int user_copy_to_secure(upage_ref_t *upage, void *secure_dst, void *user_src, size_t size) { +bool user_copy_to_secure(upage_ref_t *upage, void *secure_dst, void *user_src, size_t size) { /* Fail if the page doesn't match. */ if (get_page_for_address(user_src) != upage->user_page) { - return 0; + return false; } - + /* Fail if we go past the page boundary. */ if (size != 0 && get_page_for_address(user_src + size - 1) != upage->user_page) { - return 0; + return false; } - + void *secure_src = (void *)(upage->secure_page + ((uint64_t)user_src - upage->user_page)); memcpy(secure_dst, secure_src, size); - return 1; + return true; } -int secure_copy_to_user(upage_ref_t *upage, void *user_dst, void *secure_src, size_t size) { +bool secure_copy_to_user(upage_ref_t *upage, void *user_dst, void *secure_src, size_t size) { /* Fail if the page doesn't match. */ if (get_page_for_address(user_dst) != upage->user_page) { - return 0; + return false; } - + /* Fail if we go past the page boundary. */ if (size != 0 && get_page_for_address(user_dst + size - 1) != upage->user_page) { - return 0; + return false; } void *secure_dst = (void *)(upage->secure_page + ((uint64_t)user_dst - upage->user_page)); memcpy(secure_dst, secure_src, size); - return 1; + return true; } \ No newline at end of file diff --git a/exosphere/userpage.h b/exosphere/userpage.h index d6aef89ed..d6e59f91c 100644 --- a/exosphere/userpage.h +++ b/exosphere/userpage.h @@ -1,6 +1,7 @@ #ifndef EXOSPHERE_USERPAGE_H #define EXOSPHERE_USERPAGE_H +#include #include #define SECURE_USER_PAGE_ADDR (0x1F01F4000ULL) @@ -10,10 +11,10 @@ typedef struct { uint64_t secure_page; } upage_ref_t; -int upage_init(upage_ref_t *user_page, void *user_address); +bool upage_init(upage_ref_t *user_page, void *user_address); -int user_copy_to_secure(upage_ref_t *user_page, void *secure_dst, void *user_src, size_t size); -int secure_copy_to_user(upage_ref_t *user_page, void *user_dst, void *secure_src, size_t size); +bool user_copy_to_secure(upage_ref_t *user_page, void *secure_dst, void *user_src, size_t size); +bool secure_copy_to_user(upage_ref_t *user_page, void *user_dst, void *secure_src, size_t size); static inline uint64_t get_page_for_address(void *address) { return ((uint64_t)(address)) & 0xFFFFFFFFFFFFF000ULL; diff --git a/exosphere/utils.h b/exosphere/utils.h index 4ab559bd6..93e8a3bd8 100644 --- a/exosphere/utils.h +++ b/exosphere/utils.h @@ -1,8 +1,9 @@ #ifndef EXOSPHERE_UTILS_H #define EXOSPHERE_UTILS_H -#include +#include #include +#include #define BIT(x) (1u << (x)) #define BITL(x) (1ull << (x)) @@ -19,18 +20,18 @@ static inline uint32_t read32be(const unsigned char *dword, size_t offset) { return __builtin_bswap32(read32le(dword, offset)); } -static __attribute__((noinline)) int check_32bit_additive_overflow(uint32_t a, uint32_t b) { +static __attribute__((noinline)) bool check_32bit_additive_overflow(uint32_t a, uint32_t b) { uint64_t x = (uint64_t)a + (uint64_t)b; return x > (uint64_t)(UINT32_MAX); } -static __attribute__((noinline)) int overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be) +static __attribute__((noinline)) bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be) { if(as <= bs && bs <= ae) - return 1; + return true; if(bs <= as && as <= be) - return 1; - return 0; + return true; + return false; }