mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
Fusee: Implement BIS crypto functions.
This commit is contained in:
parent
5631b27449
commit
bb1dcb2655
3 changed files with 45 additions and 16 deletions
|
@ -6,6 +6,8 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define DEVPART_IV_MAX_SIZE 16
|
#define DEVPART_IV_MAX_SIZE 16
|
||||||
|
#define DEVPART_KEY_MAX 2
|
||||||
|
#define DEVPART_KEY_MAX_SIZE 16
|
||||||
|
|
||||||
struct device_partition_t;
|
struct device_partition_t;
|
||||||
|
|
||||||
|
@ -18,6 +20,12 @@ typedef int (*device_partition_cipher_t)(struct device_partition_t *devpart, uin
|
||||||
typedef int (*device_partition_reader_t)(struct device_partition_t *devpart, void *dst, uint64_t sector, uint64_t num_sectors);
|
typedef int (*device_partition_reader_t)(struct device_partition_t *devpart, void *dst, uint64_t sector, uint64_t num_sectors);
|
||||||
typedef int (*device_partition_writer_t)(struct device_partition_t *devpart, const void *src, uint64_t sector, uint64_t num_sectors);
|
typedef int (*device_partition_writer_t)(struct device_partition_t *devpart, const void *src, uint64_t sector, uint64_t num_sectors);
|
||||||
|
|
||||||
|
typedef enum DevicePartitionCryptoMode {
|
||||||
|
DevicePartitionCryptoMode_None,
|
||||||
|
DevicePartitionCryptoMode_Ctr,
|
||||||
|
DevicePartitionCryptoMode_Xts,
|
||||||
|
} DevicePartitionCryptoMode;
|
||||||
|
|
||||||
typedef struct device_partition_t {
|
typedef struct device_partition_t {
|
||||||
size_t sector_size; /* The size of a sector */
|
size_t sector_size; /* The size of a sector */
|
||||||
uint64_t start_sector; /* Offset in the parent device, in sectors. */
|
uint64_t start_sector; /* Offset in the parent device, in sectors. */
|
||||||
|
@ -25,7 +33,7 @@ typedef struct device_partition_t {
|
||||||
|
|
||||||
device_partition_cipher_t read_cipher; /* Cipher for read operations. */
|
device_partition_cipher_t read_cipher; /* Cipher for read operations. */
|
||||||
device_partition_cipher_t write_cipher; /* Cipher for write operations. */
|
device_partition_cipher_t write_cipher; /* Cipher for write operations. */
|
||||||
uint64_t crypto_flags; /* Additional information for crypto, for conveniency. */
|
DevicePartitionCryptoMode crypto_mode; /* Mode to use for cryptographic operations. */
|
||||||
|
|
||||||
device_partition_initializer_t initializer; /* Initializer. */
|
device_partition_initializer_t initializer; /* Initializer. */
|
||||||
device_partition_finalizer_t finalizer; /* Finalizer. */
|
device_partition_finalizer_t finalizer; /* Finalizer. */
|
||||||
|
@ -38,6 +46,7 @@ typedef struct device_partition_t {
|
||||||
void *crypto_work_buffer; /* Work buffer for crypto. */
|
void *crypto_work_buffer; /* Work buffer for crypto. */
|
||||||
uint64_t crypto_work_buffer_num_sectors; /* Size of the crypto work buffer in sectors. */
|
uint64_t crypto_work_buffer_num_sectors; /* Size of the crypto work buffer in sectors. */
|
||||||
|
|
||||||
|
uint8_t keys[DEVPART_KEY_MAX][DEVPART_KEY_MAX_SIZE]; /* Key. */
|
||||||
uint8_t iv[DEVPART_IV_MAX_SIZE]; /* IV. */
|
uint8_t iv[DEVPART_IV_MAX_SIZE]; /* IV. */
|
||||||
bool initialized;
|
bool initialized;
|
||||||
} device_partition_t;
|
} device_partition_t;
|
||||||
|
|
|
@ -438,7 +438,7 @@ void aes_128_xts_nintendo_crypt_sector(unsigned int keyslot_1, unsigned int keys
|
||||||
SECURITY_ENGINE->CRYPTO_REG = keyslot_1 << 24;
|
SECURITY_ENGINE->CRYPTO_REG = keyslot_1 << 24;
|
||||||
}
|
}
|
||||||
SECURITY_ENGINE->BLOCK_COUNT_REG = (size >> 4) - 1;
|
SECURITY_ENGINE->BLOCK_COUNT_REG = (size >> 4) - 1;
|
||||||
trigger_se_blocking_op(OP_START, dst, size, src, size);
|
trigger_se_blocking_op(OP_START, dst, size, dst, size);
|
||||||
|
|
||||||
/* XOR. */
|
/* XOR. */
|
||||||
aes_128_xts_nintendo_xor_with_tweak(keyslot_2, sector, dst, dst, size);
|
aes_128_xts_nintendo_xor_with_tweak(keyslot_2, sector, dst, dst, size);
|
||||||
|
|
|
@ -91,23 +91,43 @@ static int mmc_partition_write(device_partition_t *devpart, const void *src, uin
|
||||||
}
|
}
|
||||||
|
|
||||||
static int switchfs_bis_crypto_decrypt(device_partition_t *devpart, uint64_t sector, uint64_t num_sectors) {
|
static int switchfs_bis_crypto_decrypt(device_partition_t *devpart, uint64_t sector, uint64_t num_sectors) {
|
||||||
unsigned int keyslot = (unsigned int)devpart->crypto_flags;
|
unsigned int keyslot_a = 4; /* These keyslots are never used by exosphere, and should be safe. */
|
||||||
(void)keyslot;
|
unsigned int keyslot_b = 5;
|
||||||
(void)sector;
|
size_t size = num_sectors * devpart->sector_size;
|
||||||
(void)num_sectors;
|
switch (devpart->crypto_mode) {
|
||||||
/*devpart->crypto_work_buffer*/
|
case DevicePartitionCryptoMode_Ctr:
|
||||||
/* TODO */
|
set_aes_keyslot(keyslot_a, devpart->keys[0], 0x10);
|
||||||
|
se_aes_ctr_crypt(keyslot_a, devpart->crypto_work_buffer, size, devpart->crypto_work_buffer, size, devpart->iv, 0x10);
|
||||||
return 0;
|
return 0;
|
||||||
|
case DevicePartitionCryptoMode_Xts:
|
||||||
|
set_aes_keyslot(keyslot_a, devpart->keys[0], 0x10);
|
||||||
|
set_aes_keyslot(keyslot_b, devpart->keys[1], 0x10);
|
||||||
|
se_aes_128_xts_nintendo_decrypt(keyslot_a, keyslot_b, sector, devpart->crypto_work_buffer, devpart->crypto_work_buffer, num_sectors * devpart->sector_size, devpart->sector_size);
|
||||||
|
return 0;
|
||||||
|
case DevicePartitionCryptoMode_None:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int switchfs_bis_crypto_encrypt(device_partition_t *devpart, uint64_t sector, uint64_t num_sectors) {
|
static int switchfs_bis_crypto_encrypt(device_partition_t *devpart, uint64_t sector, uint64_t num_sectors) {
|
||||||
unsigned int keyslot = (unsigned int)devpart->crypto_flags;
|
unsigned int keyslot_a = 4; /* These keyslots are never used by exosphere, and should be safe. */
|
||||||
(void)keyslot;
|
unsigned int keyslot_b = 5;
|
||||||
(void)sector;
|
size_t size = num_sectors * devpart->sector_size;
|
||||||
(void)num_sectors;
|
switch (devpart->crypto_mode) {
|
||||||
/*devpart->crypto_work_buffer*/
|
case DevicePartitionCryptoMode_Ctr:
|
||||||
/* TODO */
|
set_aes_keyslot(keyslot_a, devpart->keys[0], 0x10);
|
||||||
|
se_aes_ctr_crypt(keyslot_a, devpart->crypto_work_buffer, size, devpart->crypto_work_buffer, size, devpart->iv, 0x10);
|
||||||
return 0;
|
return 0;
|
||||||
|
case DevicePartitionCryptoMode_Xts:
|
||||||
|
set_aes_keyslot(keyslot_a, devpart->keys[0], 0x10);
|
||||||
|
set_aes_keyslot(keyslot_b, devpart->keys[1], 0x10);
|
||||||
|
se_aes_128_xts_nintendo_encrypt(keyslot_a, keyslot_b, sector, devpart->crypto_work_buffer, devpart->crypto_work_buffer, num_sectors * devpart->sector_size, devpart->sector_size);
|
||||||
|
return 0;
|
||||||
|
case DevicePartitionCryptoMode_None:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mmc_partition_info_t g_sd_mmcpart = { &g_sd_mmc, SWITCH_MICROSD, SDMMC_PARTITION_USER };
|
static mmc_partition_info_t g_sd_mmcpart = { &g_sd_mmc, SWITCH_MICROSD, SDMMC_PARTITION_USER };
|
||||||
|
|
Loading…
Reference in a new issue