Added psInitHandle and psGetSessionHandle. Updated PS_AESAlgorithm comments and added psRSAContext. Added PS_SignRsaSha256 and PS_VerifyRsaSha256. Fixed PS_EncryptDecryptAes and PS_EncryptSignDecryptVerifyAesCcm, these originally implemented pxips9 commands not psps.
This commit is contained in:
parent
3501efd7e5
commit
e37ebf3ef1
@ -7,12 +7,12 @@
|
|||||||
/// PS AES algorithms.
|
/// PS AES algorithms.
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PS_ALGORITHM_CBC_ENC, ///< CBC encoding.
|
PS_ALGORITHM_CBC_ENC, ///< CBC encryption.
|
||||||
PS_ALGORITHM_CBC_DEC, ///< CBC decoding.
|
PS_ALGORITHM_CBC_DEC, ///< CBC decryption.
|
||||||
PS_ALGORITHM_CTR_ENC, ///< CTR encoding.
|
PS_ALGORITHM_CTR_ENC, ///< CTR encryption.
|
||||||
PS_ALGORITHM_CTR_DEC, ///< CTR decoding.
|
PS_ALGORITHM_CTR_DEC, ///< CTR decryption(same as PS_ALGORITHM_CTR_ENC).
|
||||||
PS_ALGORITHM_CCM_ENC, ///< CCM encoding.
|
PS_ALGORITHM_CCM_ENC, ///< CCM encryption.
|
||||||
PS_ALGORITHM_CCM_DEC, ///< CCM decoding.
|
PS_ALGORITHM_CCM_DEC, ///< CCM decryption.
|
||||||
} PS_AESAlgorithm;
|
} PS_AESAlgorithm;
|
||||||
|
|
||||||
/// PS key slots.
|
/// PS key slots.
|
||||||
@ -30,12 +30,45 @@ typedef enum
|
|||||||
PS_KEYSLOT_39_NFC ///< Key slot 0x39. (NFC)
|
PS_KEYSLOT_39_NFC ///< Key slot 0x39. (NFC)
|
||||||
} PS_AESKeyType;
|
} PS_AESKeyType;
|
||||||
|
|
||||||
|
/// RSA context.
|
||||||
|
typedef struct {
|
||||||
|
u8 modulo[0x100];
|
||||||
|
u8 exponent[0x100];
|
||||||
|
u32 rsa_bitsize;//The signature byte size is rsa_bitsize>>3.
|
||||||
|
u32 unk;//Normally zero?
|
||||||
|
} psRSAContext;
|
||||||
|
|
||||||
/// Initializes PS.
|
/// Initializes PS.
|
||||||
Result psInit(void);
|
Result psInit(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes PS with the specified session handle.
|
||||||
|
* @param handle Session handle.
|
||||||
|
*/
|
||||||
|
Result psInitHandle(Handle handle);
|
||||||
|
|
||||||
/// Exits PS.
|
/// Exits PS.
|
||||||
void psExit(void);
|
void psExit(void);
|
||||||
|
|
||||||
|
/// Returns the PS session handle.
|
||||||
|
Handle psGetSessionHandle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Signs a RSA signature.
|
||||||
|
* @param hash SHA256 hash to sign.
|
||||||
|
* @param ctx RSA context.
|
||||||
|
* @param signature RSA signature.
|
||||||
|
*/
|
||||||
|
Result PS_SignRsaSha256(u8 *hash, psRSAContext *ctx, u8 *signature);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Verifies a RSA signature.
|
||||||
|
* @param hash SHA256 hash to compare with.
|
||||||
|
* @param ctx RSA context.
|
||||||
|
* @param signature RSA signature.
|
||||||
|
*/
|
||||||
|
Result PS_VerifyRsaSha256(u8 *hash, psRSAContext *ctx, u8 *signature);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Encrypts/Decrypts AES data. Does not support AES CCM.
|
* @brief Encrypts/Decrypts AES data. Does not support AES CCM.
|
||||||
* @param size Size of the data.
|
* @param size Size of the data.
|
||||||
@ -43,7 +76,7 @@ void psExit(void);
|
|||||||
* @param out Output buffer.
|
* @param out Output buffer.
|
||||||
* @param aes_algo AES algorithm to use.
|
* @param aes_algo AES algorithm to use.
|
||||||
* @param key_type Key type to use.
|
* @param key_type Key type to use.
|
||||||
* @param iv Pointer to the CTR/IV.
|
* @param iv Pointer to the CTR/IV. The output CTR/IV is also written here.
|
||||||
*/
|
*/
|
||||||
Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, PS_AESAlgorithm aes_algo, PS_AESKeyType key_type, u8* iv);
|
Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, PS_AESAlgorithm aes_algo, PS_AESKeyType key_type, u8* iv);
|
||||||
|
|
||||||
|
@ -11,19 +11,78 @@
|
|||||||
static Handle psHandle;
|
static Handle psHandle;
|
||||||
static int psRefCount;
|
static int psRefCount;
|
||||||
|
|
||||||
|
static Result _psInit(Handle handle)
|
||||||
|
{
|
||||||
|
Result res=0;
|
||||||
|
if (AtomicPostIncrement(&psRefCount)) return 0;
|
||||||
|
if(handle==0)res = srvGetServiceHandle(&handle, "ps:ps");
|
||||||
|
if (R_FAILED(res)) AtomicDecrement(&psRefCount);
|
||||||
|
if (R_SUCCEEDED(res)) psHandle = handle;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
Result psInit(void)
|
Result psInit(void)
|
||||||
{
|
{
|
||||||
Result res;
|
return _psInit(0);
|
||||||
if (AtomicPostIncrement(&psRefCount)) return 0;
|
}
|
||||||
res = srvGetServiceHandle(&psHandle, "ps:ps");
|
|
||||||
if (R_FAILED(res)) AtomicDecrement(&psRefCount);
|
Result psInitHandle(Handle handle)
|
||||||
return res;
|
{
|
||||||
|
return _psInit(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void psExit(void)
|
void psExit(void)
|
||||||
{
|
{
|
||||||
if (AtomicDecrement(&psRefCount)) return;
|
if (AtomicDecrement(&psRefCount)) return;
|
||||||
svcCloseHandle(psHandle);
|
svcCloseHandle(psHandle);
|
||||||
|
psHandle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle psGetSessionHandle()
|
||||||
|
{
|
||||||
|
return psHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result PS_SignRsaSha256(u8 *hash, psRSAContext *ctx, u8 *signature)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32 *cmdbuf = getThreadCommandBuffer();
|
||||||
|
u32 size;
|
||||||
|
|
||||||
|
size = ctx->rsa_bitsize>>3;
|
||||||
|
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x1,9,4); // 0x10244
|
||||||
|
memcpy(&cmdbuf[1], hash, 32);
|
||||||
|
cmdbuf[9] = size;
|
||||||
|
cmdbuf[10] = IPC_Desc_StaticBuffer(0x208, 0);
|
||||||
|
cmdbuf[11] = (u32)ctx;
|
||||||
|
cmdbuf[12] = IPC_Desc_Buffer(size, IPC_BUFFER_W);
|
||||||
|
cmdbuf[13] = (u32)signature;
|
||||||
|
|
||||||
|
if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret;
|
||||||
|
|
||||||
|
return (Result)cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result PS_VerifyRsaSha256(u8 *hash, psRSAContext *ctx, u8 *signature)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32 *cmdbuf = getThreadCommandBuffer();
|
||||||
|
u32 size;
|
||||||
|
|
||||||
|
size = ctx->rsa_bitsize>>3;
|
||||||
|
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x2,9,4); // 0x20244
|
||||||
|
memcpy(&cmdbuf[1], hash, 32);
|
||||||
|
cmdbuf[9] = size;
|
||||||
|
cmdbuf[10] = IPC_Desc_StaticBuffer(0x208, 0);
|
||||||
|
cmdbuf[11] = (u32)ctx;
|
||||||
|
cmdbuf[12] = IPC_Desc_Buffer(size, IPC_BUFFER_R);
|
||||||
|
cmdbuf[13] = (u32)signature;
|
||||||
|
|
||||||
|
if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret;
|
||||||
|
|
||||||
|
return (Result)cmdbuf[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, PS_AESAlgorithm aes_algo, PS_AESKeyType key_type, u8* iv)
|
Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, PS_AESAlgorithm aes_algo, PS_AESKeyType key_type, u8* iv)
|
||||||
@ -33,15 +92,16 @@ Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, PS_AESAlgorithm aes_algo,
|
|||||||
|
|
||||||
u32 *_iv = (u32*)iv;
|
u32 *_iv = (u32*)iv;
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x4,7,4); // 0x401C4
|
cmdbuf[0] = IPC_MakeHeader(0x4,8,4); // 0x40204
|
||||||
cmdbuf[1] = size;
|
cmdbuf[1] = size;
|
||||||
memcpy(&cmdbuf[2], _iv, 16);
|
cmdbuf[2] = size;
|
||||||
cmdbuf[6] = aes_algo;
|
memcpy(&cmdbuf[3], _iv, 16);
|
||||||
cmdbuf[7] = key_type;
|
cmdbuf[7] = aes_algo;
|
||||||
cmdbuf[8] = IPC_Desc_PXIBuffer(size,0,false);
|
cmdbuf[8] = key_type;
|
||||||
cmdbuf[9] = (u32)in;
|
cmdbuf[9] = IPC_Desc_Buffer(size, IPC_BUFFER_R);
|
||||||
cmdbuf[10] = IPC_Desc_PXIBuffer(size,1,false);
|
cmdbuf[10] = (u32)in;
|
||||||
cmdbuf[11] = (u32)out;
|
cmdbuf[11] = IPC_Desc_Buffer(size, IPC_BUFFER_W);
|
||||||
|
cmdbuf[12] = (u32)out;
|
||||||
|
|
||||||
if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret;
|
if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret;
|
||||||
|
|
||||||
@ -59,16 +119,16 @@ Result PS_EncryptSignDecryptVerifyAesCcm(u8* in, u32 in_size, u8* out, u32 out_s
|
|||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x5,10,4); // 0x50284
|
cmdbuf[0] = IPC_MakeHeader(0x5,10,4); // 0x50284
|
||||||
cmdbuf[1] = in_size;
|
cmdbuf[1] = in_size;
|
||||||
cmdbuf[2] = out_size;
|
cmdbuf[2] = mac_data_len;
|
||||||
cmdbuf[3] = mac_data_len;
|
cmdbuf[3] = data_len;
|
||||||
cmdbuf[4] = data_len;
|
cmdbuf[4] = out_size;
|
||||||
cmdbuf[5] = mac_len;
|
cmdbuf[5] = mac_len;
|
||||||
memcpy(&cmdbuf[6], _nonce, 12);
|
memcpy(&cmdbuf[6], _nonce, 12);
|
||||||
cmdbuf[9] = aes_algo;
|
cmdbuf[9] = aes_algo;
|
||||||
cmdbuf[10] = key_type;
|
cmdbuf[10] = key_type;
|
||||||
cmdbuf[11] = IPC_Desc_PXIBuffer(in_size,0,false);
|
cmdbuf[11] = IPC_Desc_Buffer(in_size, IPC_BUFFER_R);
|
||||||
cmdbuf[12] = (u32)in;
|
cmdbuf[12] = (u32)in;
|
||||||
cmdbuf[13] = IPC_Desc_PXIBuffer(out_size,1,false);
|
cmdbuf[13] = IPC_Desc_Buffer(out_size, IPC_BUFFER_W);
|
||||||
cmdbuf[14] = (u32)out;
|
cmdbuf[14] = (u32)out;
|
||||||
|
|
||||||
if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret;
|
if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user