]> Chaos Git - corbenik/ctrulib.git/commitdiff
Added psInitHandle and psGetSessionHandle. Updated PS_AESAlgorithm comments and added...
authoryellows8 <yellows8@users.noreply.github.com>
Sat, 17 Dec 2016 06:38:37 +0000 (01:38 -0500)
committeryellows8 <yellows8@users.noreply.github.com>
Sat, 17 Dec 2016 06:38:37 +0000 (01:38 -0500)
libctru/include/3ds/services/ps.h
libctru/source/services/ps.c

index 4d17fee5fc538f64a97aacdd11a3dae102190027..e138ce5ce5ac1939e02bc18e572abf96d64b092a 100644 (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);
 
index ab8520eb5d3e07efebee79ddb98688ea182e8138..2b029ad553a80d02b40083b1ceb0604e3000a4bc 100644 (file)
 static Handle psHandle;
 static int psRefCount;
 
-Result psInit(void)
+static Result _psInit(Handle handle)
 {
-       Result res;
+       Result res=0;
        if (AtomicPostIncrement(&psRefCount)) return 0;
-       res = srvGetServiceHandle(&psHandle, "ps:ps");
+       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)
+{
+       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;