@@ -67,12 +67,12 @@ distribution.
6767#define IOCTL_ES_GETVIEWS 0x13
6868#define IOCTL_ES_GETTMDVIEWCNT 0x14
6969#define IOCTL_ES_GETTMDVIEWS 0x15
70- // #define IOCTL_ES_GETCONSUMPTION 0x16
70+ #define IOCTL_ES_GETCONSUMPTION 0x16
7171#define IOCTL_ES_DELETETITLE 0x17
7272#define IOCTL_ES_DELETETICKET 0x18
73- // #define IOCTL_ES_DIGETTMDVIEWSIZE 0x19
74- // #define IOCTL_ES_DIGETTMDVIEW 0x1A
75- // #define IOCTL_ES_DIGETTICKETVIEW 0x1B
73+ #define IOCTL_ES_DIGETTMDVIEWSIZE 0x19
74+ #define IOCTL_ES_DIGETTMDVIEW 0x1A
75+ #define IOCTL_ES_DIGETTICKETVIEW 0x1B
7676#define IOCTL_ES_DIVERIFY 0x1C
7777#define IOCTL_ES_GETTITLEDIR 0x1D
7878#define IOCTL_ES_GETDEVICECERT 0x1E
@@ -102,6 +102,7 @@ distribution.
102102#define IOCTL_ES_GETSHAREDCONTENTCNT 0x36
103103#define IOCTL_ES_GETSHAREDCONTENTS 0x37
104104#define IOCTL_ES_DIVERIFYWITHTIKVIEW 0x3B
105+ #define IOCTL_ES_CHECKHASKOREANKEY 0x45
105106
106107#define ES_HEAP_SIZE 0x800
107108
@@ -350,7 +351,7 @@ s32 ES_GetNumStoredTMDContents(const signed_blob *stmd, u32 tmd_size, u32 *cnt)
350351 if (__es_fd < 0 ) return ES_ENOTINIT ;
351352 if (!cnt ) return ES_EINVAL ;
352353 if (!stmd || !IS_VALID_SIGNATURE (stmd )) return ES_EINVAL ;
353- if (!ISALIGNED (stmd , 64 )) return ES_EALIGN ; /* !? passed directly to VerifyContainer */
354+ if (!ISALIGNED (stmd , 64 )) return ES_EALIGN ; /* !? passed directly to VerifyContainer -> passed directly to IOSC_GenerateHash */
354355
355356 ret = IOS_IoctlvFormat (__es_hid ,__es_fd ,IOCTL_ES_GETSTOREDCONTENTCNT ,"d:i" ,stmd ,tmd_size ,& cntct );
356357
@@ -413,14 +414,74 @@ s32 ES_GetTMDViewSize(u64 titleID, u32 *size)
413414 return ret ;
414415}
415416
416- s32 ES_GetTMDView (u64 titleID , u8 * data , u32 size )
417+ s32 ES_GetTMDView (u64 titleID , tmd_view * view , u32 size )
417418{
418419 if (__es_fd < 0 ) return ES_ENOTINIT ;
419420 if (size <= 0 ) return ES_EINVAL ;
420- if (!data ) return ES_EINVAL ;
421- if (!ISALIGNED (data , 4 )) return ES_EALIGN ;
421+ if (!view ) return ES_EINVAL ;
422+ if (!ISALIGNED (view , 4 )) return ES_EALIGN ;
423+
424+ return IOS_IoctlvFormat (__es_hid ,__es_fd ,IOCTL_ES_GETTMDVIEWS ,"qi:d" ,titleID ,size ,view ,size );
425+ }
426+
427+ s32 ES_GetConsumptionCount (u64 ticketID , u32 * n_limits )
428+ {
429+ s32 ret ;
430+ u32 _n_limits = 0 ;
431+
432+ if (__es_fd < 0 ) return ES_ENOTINIT ;
433+ if (!n_limits ) return ES_EINVAL ;
434+
435+ ret = IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_GETCONSUMPTION , "q:di" , ticketID , NULL , 0 , & _n_limits );
436+ * n_limits = _n_limits ;
437+
438+ return ret ;
439+ }
440+
441+ s32 ES_GetConsumption (u64 ticketID , tiklimit * limits , u32 n_limits )
442+ {
443+ if (__es_fd < 0 ) return ES_ENOTINIT ;
444+ if (!n_limits || !limits ) return ES_EINVAL ;
445+ if (!ISALIGNED (limits , 4 )) return ES_EALIGN ;
446+
447+ return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_GETCONSUMPTION , "q:di" , ticketID , limits , n_limits * sizeof (tiklimit ), & n_limits );
448+ }
449+
450+ s32 ES_DiGetTMDViewSize (const signed_blob * s_tmd , u32 tmd_size , u32 * view_size )
451+ {
452+ s32 ret ;
453+ u32 size = 0 ;
454+
455+ if (__es_fd < 0 ) return ES_ENOTINIT ;
456+ if (s_tmd && tmd_size != SIGNED_TMD_SIZE (s_tmd )) return ES_EINVAL ;
457+ if (!size ) return ES_EINVAL ;
458+ if (!ISALIGNED (s_tmd , 4 )) return ES_EALIGN ;
459+
460+ if (!s_tmd ) tmd_size = 0 ;
461+
462+ ret = IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_DIGETTMDVIEWSIZE , "d:i" , s_tmd , tmd_size , & size );
463+ * view_size = size ;
464+
465+ return ret ;
466+ }
467+
468+ s32 ES_DiGetTMDView (const signed_blob * s_tmd , u32 tmd_size , tmd_view * view , u32 view_size )
469+ {
470+ if (__es_fd < 0 ) return ES_ENOTINIT ;
471+ if (s_tmd && tmd_size != SIGNED_TMD_SIZE (s_tmd )) return ES_EINVAL ;
472+ if (view_size < sizeof (tmd_view )) return ES_EINVAL ;
473+ if (!ISALIGNED (s_tmd , 4 ) || !ISALIGNED (view , 4 )) return ES_EALIGN ;
422474
423- return IOS_IoctlvFormat (__es_hid ,__es_fd ,IOCTL_ES_GETTMDVIEWS ,"qi:d" ,titleID ,size ,data ,size );
475+ return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_DIGETTMDVIEW , "di:d" , s_tmd , (s_tmd == NULL ? 0 : tmd_size ), & view_size , view , view_size );
476+ }
477+
478+ s32 ES_DiGetTicketView (const signed_blob * s_tik , tikview * view )
479+ {
480+ if (__es_fd < 0 ) return ES_ENOTINIT ;
481+ if (!view ) return ES_EINVAL ;
482+ if (!ISALIGNED (s_tik , 4 ) || !ISALIGNED (view , 4 )) return ES_EALIGN ;
483+
484+ return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_DIGETTICKETVIEW , "d:d" , s_tik , (s_tik == NULL ? 0 : STD_SIGNED_TIK_SIZE ), view , sizeof (tikview ));
424485}
425486
426487s32 ES_GetStoredTMDSize (u64 titleID , u32 * size )
@@ -474,7 +535,7 @@ s32 ES_GetSharedContents(sha1 *contents, u32 cnt)
474535 return IOS_IoctlvFormat (__es_hid ,__es_fd ,IOCTL_ES_GETSHAREDCONTENTS ,"i:d" ,cnt ,contents ,sizeof (sha1 )* cnt );
475536}
476537
477- signed_blob * ES_NextCert (const signed_blob * certs )
538+ const signed_blob * ES_NextCert (const signed_blob * certs )
478539{
479540 cert_header * cert ;
480541 if (!SIGNATURE_SIZE (certs )) return NULL ;
@@ -558,7 +619,7 @@ s32 ES_DiVerifyWithTicketView(const signed_blob *certificates, u32 certificates_
558619 if (!s_tmd || !IS_VALID_SIGNATURE (s_tmd ) || tmd_size != SIGNED_TMD_SIZE (s_tmd ))
559620 return ES_EINVAL ;
560621
561- if (certificates_size && !__ES_sanity_check_certlist (certificates , certificates_size )) // ES_DiVerifyWithTicketView must fetch the system's certificate store for the ticket. It also does not check the size. It does check the pointer though.
622+ if (! certificates || ( certificates_size && !__ES_sanity_check_certlist (certificates , certificates_size )) || ! ISALIGNED ( certificates_size , 64 )) // ES will copy our certificates first then read the system's on top of that. So if the size is somehow not a multiple of 64 bytes then, unless you plan to provide the ticket certificates yourself, the function is going to break
562623 return ES_EINVAL ;
563624
564625 // Alignment demands according to the actual IPC handler. ES ultimately allocates it's own 64-byte aligned buffer and copies our data.
@@ -630,7 +691,7 @@ s32 ES_ExportContentBegin(u64 titleID, u32 contentID) {
630691s32 ES_ExportContentData (s32 cfd , void * data , u32 size ) {
631692 if (__es_fd < 0 ) return ES_ENOTINIT ;
632693 if (!data || !size ) return ES_EINVAL ;
633- if (!ISALIGNED (data , 16 ) /* passed directly to IOSC_Encrypt */ || !ISALIGNED (size , 32 ) /* !? ES rounds up data_read to 32 bytes */ )
694+ if (!ISALIGNED (data , 32 ) || !ISALIGNED (size , 32 ))
634695 return ES_EALIGN ;
635696
636697 return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_EXPORTCONTENTDATA , "i:d" , cfd , data , size );
@@ -690,7 +751,7 @@ s32 ES_AddContentStart(u64 titleID, u32 cid)
690751 return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_ADDCONTENTSTART , "qi:" , titleID , cid );
691752}
692753
693- s32 ES_AddContentData (s32 cfd , u8 * data , u32 data_size )
754+ s32 ES_AddContentData (s32 cfd , const void * data , u32 data_size )
694755{
695756 if (__es_fd < 0 ) return ES_ENOTINIT ;
696757 if (cfd < 0 ) return ES_EINVAL ;
@@ -740,14 +801,14 @@ s32 ES_OpenContent(u16 index)
740801 return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_OPENCONTENT , "i:" , index );
741802}
742803
743- s32 ES_OpenTitleContent (u64 titleID , tikview * views , u16 index )
804+ s32 ES_OpenTitleContent (u64 titleID , const tikview * views , u16 index )
744805{
745806 if (__es_fd < 0 ) return ES_ENOTINIT ;
746807 if (!ISALIGNED (views , 4 )) return ES_EALIGN ;
747808 return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_OPENTITLECONTENT , "qdi:" , titleID , views , sizeof (tikview ), index );
748809}
749810
750- s32 ES_ReadContent (s32 cfd , u8 * data , u32 data_size )
811+ s32 ES_ReadContent (s32 cfd , void * data , u32 data_size )
751812{
752813 if (__es_fd < 0 ) return ES_ENOTINIT ;
753814 if (cfd < 0 ) return ES_EINVAL ;
@@ -782,31 +843,31 @@ s32 ES_DeleteTitleContent(u64 titleID)
782843 return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_DELETETITLECONTENT , "q:" , titleID );
783844}
784845
785- s32 ES_Encrypt (u32 keynum , u32 * iv , void * source , u32 size , void * dest )
846+ s32 ES_Encrypt (u32 keynum , u32 * iv , const void * source , u32 size , void * dest )
786847{
787848 if (__es_fd < 0 )
788849 return ES_ENOTINIT ;
789850 if (!iv || !source || !size || !dest )
790851 return ES_EINVAL ;
791- if (!ISALIGNED (iv , 4 ) || !ISALIGNED (source , 16 ) || !ISALIGNED (dest , 16 ) || !ISALIGNED (size , 16 ))
852+ if (!ISALIGNED (iv , 4 ) || !ISALIGNED (source , 32 ) || !ISALIGNED (dest , 32 ) || !ISALIGNED (size , 16 ))
792853 return ES_EALIGN ;
793854
794855 return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_ENCRYPT , "idd:dd" , keynum , iv , 0x10 , source , size , iv , 0x10 , dest , size );
795856}
796857
797- s32 ES_Decrypt (u32 keynum , u32 * iv , void * source , u32 size , void * dest )
858+ s32 ES_Decrypt (u32 keynum , u32 * iv , const void * source , u32 size , void * dest )
798859{
799860 if (__es_fd < 0 )
800861 return ES_ENOTINIT ;
801862 if (!iv || !source || !size || !dest )
802863 return ES_EINVAL ;
803- if (!ISALIGNED (iv , 4 ) || !ISALIGNED (source , 16 ) || !ISALIGNED (dest , 16 ) || !ISALIGNED (size , 16 ))
864+ if (!ISALIGNED (iv , 4 ) || !ISALIGNED (source , 32 ) || !ISALIGNED (dest , 32 ) || !ISALIGNED (size , 16 ))
804865 return ES_EALIGN ;
805866
806867 return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_DECRYPT , "idd:dd" , keynum , iv , 0x10 , source , size , iv , 0x10 , dest , size );
807868}
808869
809- s32 ES_Sign (void * data , u32 size , u8 * ap_signature , signed_blob * ap_certificate )
870+ s32 ES_Sign (const void * data , u32 size , u8 * ap_signature , signed_blob * ap_certificate )
810871{
811872 if (__es_fd < 0 ) return ES_ENOTINIT ;
812873 if (!data || !size || !ap_signature || !ap_certificate ) return ES_EINVAL ;
@@ -817,7 +878,7 @@ s32 ES_Sign(void *data, u32 size, u8 *ap_signature, signed_blob *ap_certificate)
817878 return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_SIGN , "d:dd" , data , size , ap_signature , 0x3C , ap_certificate , 0x180 );
818879}
819880
820- s32 ES_VerifySign (void * data , u32 size , u8 * ap_signature , signed_blob * certificates , u32 certificates_size ) {
881+ s32 ES_VerifySign (const void * data , u32 size , const u8 * ap_signature , const signed_blob * certificates , u32 certificates_size ) {
821882 if (__es_fd < 0 ) return ES_ENOTINIT ;
822883 if (!data || !size || !ap_signature || !certificates || !certificates_size ) return ES_EINVAL ;
823884 if (!__ES_sanity_check_certlist (certificates , certificates_size )) return ES_EINVAL ;
@@ -863,6 +924,13 @@ s32 ES_GetBoot2Version(u32 *version)
863924 return ret ;
864925}
865926
927+ s32 ES_CheckHasKoreanKey (void )
928+ {
929+ if (__es_fd < 0 ) return ES_ENOTINIT ;
930+
931+ return IOS_IoctlvFormat (__es_hid , __es_fd , IOCTL_ES_CHECKHASKOREANKEY , "" );
932+ }
933+
866934// 64k buffer size for alignment
867935#define ES_READ_BUF_SIZE 65536
868936
0 commit comments