--- /dev/null
+#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
--- /dev/null
+#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