all: Use bool where applicable (#30)

This commit is contained in:
Mat M 2018-02-22 22:58:39 -05:00 committed by SciresM
parent 1d8f443f68
commit 83216409d2
15 changed files with 154 additions and 145 deletions

View file

@ -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

View file

@ -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) {

View file

@ -1,9 +1,9 @@
#ifndef EXOSPHERE_CFG_ITEM_H
#define EXOSPHERE_CFG_ITEM_H
#include <stdbool.h>
#include <stdint.h>
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

View file

@ -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;

View file

@ -1,8 +1,13 @@
#ifndef EXOSPHERE_GCM_H
#define EXOSPHERE_GCM_H
#include <stdbool.h>
#include <stdint.h>
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

View file

@ -1,3 +1,4 @@
#include <stdbool.h>
#include <stdint.h>
#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 {

View file

@ -1,6 +1,7 @@
#ifndef EXOSPHERE_MMU_H
#define EXOSPHERE_MMU_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include "utils.h"

View file

@ -1,3 +1,4 @@
#include <stdbool.h>
#include <stdint.h>
#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++) {

View file

@ -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);
}

View file

@ -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;
}

View file

@ -1,3 +1,4 @@
#include <stdbool.h>
#include <stdint.h>
#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]);

View file

@ -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

View file

@ -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;
}

View file

@ -1,6 +1,7 @@
#ifndef EXOSPHERE_USERPAGE_H
#define EXOSPHERE_USERPAGE_H
#include <stdbool.h>
#include <stdint.h>
#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;

View file

@ -1,8 +1,9 @@
#ifndef EXOSPHERE_UTILS_H
#define EXOSPHERE_UTILS_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#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;
}