ams: revamp target firmware

This commit is contained in:
Michael Scire
2020-05-06 22:29:07 -07:00
parent 85cd2c97a0
commit 8e75a4169d
48 changed files with 863 additions and 693 deletions

View File

@@ -122,23 +122,10 @@ static void validate_rsa_result(unsigned int which) {
}
static bool is_user_keyslot_valid(unsigned int keyslot) {
switch (exosphere_get_target_firmware()) {
case ATMOSPHERE_TARGET_FIRMWARE_100:
case ATMOSPHERE_TARGET_FIRMWARE_200:
case ATMOSPHERE_TARGET_FIRMWARE_300:
case ATMOSPHERE_TARGET_FIRMWARE_400:
case ATMOSPHERE_TARGET_FIRMWARE_500:
return keyslot <= 3;
case ATMOSPHERE_TARGET_FIRMWARE_600:
case ATMOSPHERE_TARGET_FIRMWARE_620:
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900:
case ATMOSPHERE_TARGET_FIRMWARE_910:
case ATMOSPHERE_TARGET_FIRMWARE_1000:
default:
return keyslot <= 5;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
return keyslot <= 5;
} else {
return keyslot <= 3;
}
}
@@ -262,7 +249,7 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
uint8_t mask_id = (uint8_t)((packed_options >> 1) & 3);
/* Switches the output based on how it will be used. */
uint8_t usecase = (uint8_t)((packed_options >> 5) & (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500 ? 7 : 3));
uint8_t usecase = (uint8_t)((packed_options >> 5) & (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0 ? 7 : 3));
/* Switched the output based on whether it should be console unique. */
bool is_personalized = (int)(packed_options & 1);
@@ -270,7 +257,7 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
bool is_recovery_boot = configitem_is_recovery_boot();
/* 5.0.0+ Bounds checking. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
if (is_personalized) {
if (master_key_rev >= MASTERKEY_REVISION_MAX || (MASTERKEY_REVISION_300 <= master_key_rev && master_key_rev < MASTERKEY_REVISION_400_410)) {
return 2;
@@ -324,9 +311,9 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
unsigned int keyslot;
if (is_personalized) {
/* Behavior changed in 4.0.0, and in 5.0.0. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
keyslot = devkey_get_keyslot(master_key_rev);
} else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_400) {
} else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
if (master_key_rev >= 1) {
keyslot = KEYSLOT_SWITCH_DEVICEKEY; /* New device key, 4.x. */
} else {
@@ -399,7 +386,7 @@ uint32_t user_crypt_aes(smc_args_t *args) {
uint32_t keyslot = args->X[1] & 3;
uint32_t mode = (args->X[1] >> 4) & 3;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
keyslot = args->X[1] & 7;
}
@@ -415,7 +402,7 @@ uint32_t user_crypt_aes(smc_args_t *args) {
return 2;
}
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
/* Disallow dma lists outside of safe range. */
if (in_ll_paddr - 0x80000000 >= 0x3FF7F5) {
return 2;
@@ -463,7 +450,7 @@ uint32_t user_generate_specific_aes_key(smc_args_t *args) {
if (master_key_rev > 0) {
master_key_rev -= 1;
}
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
master_key_rev = 0;
}
@@ -479,9 +466,9 @@ uint32_t user_generate_specific_aes_key(smc_args_t *args) {
unsigned int keyslot;
/* Behavior changed in 5.0.0. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
keyslot = devkey_get_keyslot(master_key_rev);
} else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_400) {
} else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_4_0_0) {
if (master_key_rev >= 1) {
keyslot = KEYSLOT_SWITCH_DEVICEKEY; /* New device key, 4.x. */
} else {
@@ -560,7 +547,7 @@ uint32_t user_load_rsa_oaep_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function no longer exists in 5.x+. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
generic_panic();
}
@@ -609,7 +596,7 @@ uint32_t user_decrypt_rsa_private_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function no longer exists in 5.x+. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
generic_panic();
}
@@ -667,7 +654,7 @@ uint32_t user_load_secure_exp_mod_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function no longer exists in 5.x+. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
generic_panic();
}
@@ -723,7 +710,7 @@ uint32_t user_secure_exp_mod(smc_args_t *args) {
void *user_modulus = (void *)args->X[2];
unsigned int exponent_id = 1;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
switch (args->X[3]) {
case 0:
exponent_id = 1;
@@ -753,7 +740,7 @@ uint32_t user_secure_exp_mod(smc_args_t *args) {
set_exp_mod_result(3);
/* Hardcode RSA keyslot 0. */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_1000) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
set_rsa_keyslot(0, modulus, 0x100, g_imported_exponents[exponent_id], 0x100);
se_exp_mod(0, input, 0x100, exp_mod_done_handler);
} else if (load_imported_rsa_keypair(0, exponent_id)) {
@@ -780,7 +767,7 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
unsigned int option = (unsigned int)args->X[7];
unsigned int master_key_rev;
unsigned int titlekey_type;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_6_0_0) {
master_key_rev = option & 0x3F;
titlekey_type = (option >> 6) & 1;
} else {
@@ -792,7 +779,7 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
master_key_rev -= 1;
}
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_3_0_0) {
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
return 2;
}
@@ -857,7 +844,7 @@ uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args) {
if (master_key_rev > 0) {
master_key_rev -= 1;
}
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_3_0_0) {
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
return 2;
}
@@ -953,7 +940,7 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function only exists in 5.x+. */
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_500) {
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_5_0_0) {
generic_panic();
}
@@ -1019,7 +1006,7 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
}
/* Modulus import isn't implemented on < 10.0.0. */
import_modulus &= (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_1000);
import_modulus &= (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0);
/* Import the key. */
import_rsa_exponent(exponent_id, user_data, 0x100);