smcDecryptRsaPrivateKey

This commit is contained in:
Michael Scire 2018-02-20 12:56:41 -08:00
parent 81b874cc14
commit 3d80b4edbc
4 changed files with 58 additions and 2 deletions

View file

@ -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. */ /* This function is a doozy. It decrypts and validates a (non-standard) AES-GCM wrapped keypair. */
size_t gcm_decrypt_key(unsigned int keyslot, 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, int is_personalized) {
if (is_personalized == 0) { if (is_personalized == 0) {
/* Devkit keys use a different keyformat without a MAC/Device ID. */ /* Devkit keys use a different keyformat without a MAC/Device ID. */
if (src_size <= 0x10 || src_size - 0x10 > dst_size) { if (src_size <= 0x10 || src_size - 0x10 > dst_size) {

View file

@ -3,6 +3,6 @@
#include <stdint.h> #include <stdint.h>
size_t gcm_decrypt_key(unsigned int keyslot, 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, int is_personalized);
#endif #endif

View file

@ -309,6 +309,10 @@ uint32_t smc_compute_cmac(smc_args_t *args) {
return smc_wrapper_sync(args, user_compute_cmac); return smc_wrapper_sync(args, user_compute_cmac);
} }
uint32_t smc_decrypt_rsa_private_key(smc_args_t *args) {
return smc_wrapper_sync(args, user_decrypt_rsa_private_key);
}
uint32_t smc_rsa_oaep(smc_args_t *args) { uint32_t smc_rsa_oaep(smc_args_t *args) {
return smc_wrapper_async(args, user_rsa_oaep, smc_exp_mod_get_result); return smc_wrapper_async(args, user_rsa_oaep, smc_exp_mod_get_result);
} }

View file

@ -296,6 +296,58 @@ uint32_t user_compute_cmac(smc_args_t *args) {
return 0; return 0;
} }
uint32_t user_decrypt_rsa_private_key(smc_args_t *args) {
uint64_t sealed_kek[2];
uint64_t wrapped_key[2];
int is_personalized;
uint8_t user_data[0x400];
void *user_address;
size_t size;
upage_ref_t page_ref;
/* Copy keydata */
sealed_kek[0] = args->X[1];
sealed_kek[1] = args->X[2];
if (args->X[3] > 1) {
return 2;
}
is_personalized = (int)args->X[3];
user_address = (void *)args->X[4];
size = = (size_t)args->X[5];
wrapped_key[0] = args->X[6];
wrapped_key[1] = args->X[7];
if (size > 0x240) {
return 2;
}
if (is_personalized && size < 0x31) {
return 2;
}
if (!is_personalized && (size < 0x11 /* || GET_BOOTROM_PATCH_VERSION >= 0x7F */)) {
return 2;
}
if (upage_init(&page_ref, user_address) == 0 || user_copy_to_secure(&page_ref, user_data, user_address, size) == 0) {
return 2;
}
size_t out_size;
if ((out_size = gcm_decrypt_key(user_data, size, user_data, size, sealed_kek, 0x10, wrapped_key, 0x10, CRYPTOUSECASE_RSAPRIVATE, is_personalized)) == 0) {
return 2;
}
if (secure_copy_to_user(&page_ref, user_address, user_data, size) == 0) {
return 2;
}
args->X[1] = out_size;
return 0;
}
uint32_t user_rsa_oaep(smc_args_t *args) { uint32_t user_rsa_oaep(smc_args_t *args) {
uint8_t modulus[0x100]; uint8_t modulus[0x100];
uint8_t input[0x100]; uint8_t input[0x100];