]> Chaos Git - corbenik/ctrulib.git/commitdiff
PS: Added API
authoridunoe <idunoe@asia.com>
Mon, 27 Oct 2014 05:17:56 +0000 (13:17 +0800)
committeridunoe <idunoe@asia.com>
Mon, 27 Oct 2014 05:17:56 +0000 (13:17 +0800)
libctru/include/3ds/services/ps.h [new file with mode: 0644]
libctru/source/services/ps.c [new file with mode: 0644]

diff --git a/libctru/include/3ds/services/ps.h b/libctru/include/3ds/services/ps.h
new file mode 100644 (file)
index 0000000..29c9d95
--- /dev/null
@@ -0,0 +1,76 @@
+#pragma once
+
+typedef enum
+{
+       ps_CBC_ENC,
+       ps_CBC_DEC,
+       ps_CTR_ENC,
+       ps_CTR_DEC,
+       ps_CCM_ENC,
+       ps_CCM_DEC,
+} ps_aes_algo;
+
+typedef enum
+{
+       ps_KEYSLOT_0D,
+       ps_KEYSLOT_2D,
+       ps_KEYSLOT_31,
+       ps_KEYSLOT_38,
+       ps_KEYSLOT_32,
+       ps_KEYSLOT_39,
+       ps_KEYSLOT_2E,
+       ps_KEYSLOT_INVALID,
+       ps_KEYSLOT_36
+} ps_aes_keytypes;
+
+/*
+       Requires access to "ps:ps" service
+*/
+
+Result psInit();
+Result psExit();
+
+/* PS_EncryptDecryptAes()
+About: Is an interface for the AES Engine, you can only use predetermined keyslots though.
+Note: Does not support AES CCM, see PS_EncryptSignDecryptVerifyAesCcm()
+
+  size                 size of data
+  in                   input buffer ptr
+  out                  output buffer ptr
+  aes_algo             AES Algorithm to use, see ps_aes_algo
+  key_type             see ps_aes_keytypes
+  iv                   ptr to the CTR/IV (This is updated before returning)
+*/
+Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, u32 aes_algo, u32 key_type, u8* iv);
+
+/* PS_EncryptSignDecryptVerifyAesCcm()
+About: Is an interface for the AES Engine (CCM Encrypt/Decrypt only), you can only use predetermined keyslots though.
+Note: When encrypting, the output buffer size must include the MAC size, when decrypting, the input buffer size must include MAC size.
+MAC: When decrypting, if the MAC is invalid, 0xC9010401 is returned. After encrypting the MAC is located at inputbufptr+(totalassocdata+totaldatasize)
+
+  in                   input buffer ptr
+  in_size              size of input buffer
+  out                  output buffer ptr
+  out_size             size of output buffer
+  data_len             length of data to be crypted
+  mac_data_len length of data associated with MAC
+  mac_len              length of MAC
+  aes_algo             AES Algorithm to use, see ps_aes_algo
+  key_type             see ps_aes_keytypes
+  nonce                        ptr to the nonce
+*/
+Result PS_EncryptSignDecryptVerifyAesCcm(u8* in, u32 in_size, u8* out, u32 out_size, u32 data_len, u32 mac_data_len, u32 mac_len, u32 aes_algo, u32 key_type, u8* nonce);
+
+/* PS_GetLocalFriendCodeSeed()
+About: Gets a 64bit console id, it's used for some key slot inits
+
+  seed                 ptr to where the seed is written to
+*/
+Result PS_GetLocalFriendCodeSeed(u64* seed);
+
+/* PS_GetDeviceId()
+About: Gets a 32bit device id, it's used for some key slot inits
+
+  device_id            ptr to where the device id is written to
+*/
+Result PS_GetDeviceId(u32* device_id);
\ No newline at end of file
diff --git a/libctru/source/services/ps.c b/libctru/source/services/ps.c
new file mode 100644 (file)
index 0000000..6ea4fb2
--- /dev/null
@@ -0,0 +1,100 @@
+#include <stdlib.h>
+#include <3ds.h>
+
+static Handle psHandle;
+
+Result psInit()
+{
+       return srvGetServiceHandle(&psHandle, "ps:ps"); 
+}
+
+Result psExit()
+{
+       return svcCloseHandle(psHandle);
+}
+
+Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, u32 aes_algo, u32 key_type, u8* iv)
+{
+       Result ret = 0;
+       u32 *cmdbuf = getThreadCommandBuffer();
+       
+       u32 *_iv = (u32*)iv;
+
+       cmdbuf[0] = 0x000401C4;
+       cmdbuf[1] = size;
+       cmdbuf[2] = _iv[0];
+       cmdbuf[3] = _iv[1];
+       cmdbuf[4] = _iv[2];
+       cmdbuf[5] = _iv[3];
+       cmdbuf[6] = aes_algo;
+       cmdbuf[7] = key_type;
+       cmdbuf[8] = (size << 0x8) | 0x4;
+       cmdbuf[9] = (u32)in;
+       cmdbuf[10] = (size << 0x8) | 0x14;
+       cmdbuf[11] = (u32)out;
+       
+       if((ret = svcSendSyncRequest(psHandle))!=0)return ret;
+
+       _iv[0] = cmdbuf[2];
+       _iv[1] = cmdbuf[3];
+       _iv[2] = cmdbuf[4];
+       _iv[3] = cmdbuf[5];
+       
+       return (Result)cmdbuf[1];
+}
+
+Result PS_EncryptSignDecryptVerifyAesCcm(u8* in, u32 in_size, u8* out, u32 out_size, u32 data_len, u32 mac_data_len, u32 mac_len, u32 aes_algo, u32 key_type, u8* nonce)
+{
+       Result ret = 0;
+       u32 *cmdbuf = getThreadCommandBuffer();
+       
+       u32 *_nonce = (u32*)nonce;
+
+       cmdbuf[0] = 0x00050284;
+       cmdbuf[1] = in_size;
+       cmdbuf[2] = out_size;
+       cmdbuf[3] = mac_data_len;
+       cmdbuf[4] = data_len;
+       cmdbuf[5] = mac_len;
+       cmdbuf[6] = _nonce[0];
+       cmdbuf[7] = _nonce[1];
+       cmdbuf[8] = _nonce[2];
+       cmdbuf[9] = aes_algo;
+       cmdbuf[10] = key_type;
+       cmdbuf[8] = (in_size << 0x8) | 0x4;
+       cmdbuf[9] = (u32)in;
+       cmdbuf[10] = (out_size << 0x8) | 0x14;
+       cmdbuf[11] = (u32)out;
+       
+       if((ret = svcSendSyncRequest(psHandle))!=0)return ret;
+       
+       return (Result)cmdbuf[1];
+}
+
+Result PS_GetLocalFriendCodeSeed(u64* seed)
+{
+       Result ret = 0;
+       u32 *cmdbuf = getThreadCommandBuffer();
+       
+       cmdbuf[0] = 0x000A0000;
+       
+       if((ret = svcSendSyncRequest(psHandle))!=0)return ret;
+
+       *seed = (u64)cmdbuf[2] | (u64)cmdbuf[3] << 32;
+       
+       return (Result)cmdbuf[1];
+}
+
+Result PS_GetDeviceId(u32* device_id)
+{
+       Result ret = 0;
+       u32 *cmdbuf = getThreadCommandBuffer();
+       
+       cmdbuf[0] = 0x000B0000;
+       
+       if((ret = svcSendSyncRequest(psHandle))!=0)return ret;
+
+       *device_id = cmdbuf[2];
+       
+       return (Result)cmdbuf[1];
+}
\ No newline at end of file