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:
yellows8 2016-12-17 01:38:37 -05:00
parent 3501efd7e5
commit e37ebf3ef1
2 changed files with 118 additions and 25 deletions

View File

@ -7,12 +7,12 @@
/// PS AES algorithms.
typedef enum
{
PS_ALGORITHM_CBC_ENC, ///< CBC encoding.
PS_ALGORITHM_CBC_DEC, ///< CBC decoding.
PS_ALGORITHM_CTR_ENC, ///< CTR encoding.
PS_ALGORITHM_CTR_DEC, ///< CTR decoding.
PS_ALGORITHM_CCM_ENC, ///< CCM encoding.
PS_ALGORITHM_CCM_DEC, ///< CCM decoding.
PS_ALGORITHM_CBC_ENC, ///< CBC encryption.
PS_ALGORITHM_CBC_DEC, ///< CBC decryption.
PS_ALGORITHM_CTR_ENC, ///< CTR encryption.
PS_ALGORITHM_CTR_DEC, ///< CTR decryption(same as PS_ALGORITHM_CTR_ENC).
PS_ALGORITHM_CCM_ENC, ///< CCM encryption.
PS_ALGORITHM_CCM_DEC, ///< CCM decryption.
} PS_AESAlgorithm;
/// PS key slots.
@ -30,12 +30,45 @@ typedef enum
PS_KEYSLOT_39_NFC ///< Key slot 0x39. (NFC)
} 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.
Result psInit(void);
/**
* @brief Initializes PS with the specified session handle.
* @param handle Session handle.
*/
Result psInitHandle(Handle handle);
/// Exits PS.
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.
* @param size Size of the data.
@ -43,7 +76,7 @@ void psExit(void);
* @param out Output buffer.
* @param aes_algo AES algorithm 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);

View File

@ -11,19 +11,78 @@
static Handle psHandle;
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 res;
if (AtomicPostIncrement(&psRefCount)) return 0;
res = srvGetServiceHandle(&psHandle, "ps:ps");
if (R_FAILED(res)) AtomicDecrement(&psRefCount);
return res;
return _psInit(0);
}
Result psInitHandle(Handle handle)
{
return _psInit(handle);
}
void psExit(void)
{
if (AtomicDecrement(&psRefCount)) return;
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)
@ -33,15 +92,16 @@ Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, PS_AESAlgorithm aes_algo,
u32 *_iv = (u32*)iv;
cmdbuf[0] = IPC_MakeHeader(0x4,7,4); // 0x401C4
cmdbuf[0] = IPC_MakeHeader(0x4,8,4); // 0x40204
cmdbuf[1] = size;
memcpy(&cmdbuf[2], _iv, 16);
cmdbuf[6] = aes_algo;
cmdbuf[7] = key_type;
cmdbuf[8] = IPC_Desc_PXIBuffer(size,0,false);
cmdbuf[9] = (u32)in;
cmdbuf[10] = IPC_Desc_PXIBuffer(size,1,false);
cmdbuf[11] = (u32)out;
cmdbuf[2] = size;
memcpy(&cmdbuf[3], _iv, 16);
cmdbuf[7] = aes_algo;
cmdbuf[8] = key_type;
cmdbuf[9] = IPC_Desc_Buffer(size, IPC_BUFFER_R);
cmdbuf[10] = (u32)in;
cmdbuf[11] = IPC_Desc_Buffer(size, IPC_BUFFER_W);
cmdbuf[12] = (u32)out;
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[1] = in_size;
cmdbuf[2] = out_size;
cmdbuf[3] = mac_data_len;
cmdbuf[4] = data_len;
cmdbuf[2] = mac_data_len;
cmdbuf[3] = data_len;
cmdbuf[4] = out_size;
cmdbuf[5] = mac_len;
memcpy(&cmdbuf[6], _nonce, 12);
cmdbuf[9] = aes_algo;
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[13] = IPC_Desc_PXIBuffer(out_size,1,false);
cmdbuf[13] = IPC_Desc_Buffer(out_size, IPC_BUFFER_W);
cmdbuf[14] = (u32)out;
if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret;