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. /// 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);

View File

@ -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;