ntool/lib/keys.py
2023-03-26 23:48:17 +08:00

65 lines
14 KiB
Python

from .common import *
class CTR: # For tuples: index 0 for retail, index 1 for dev
fixed_system = 0x527CE630A9CA305F3696F3CDE954194B
# AES keyslots
KeyX0x2C = (0xb98e95ceca3e4d171f76a94de934c053, 0x510207515507cbb18e243dcb85e23a1d)
KeyX0x25 = (0xCEE7D8AB30C00DAE850EF5E382AC5AF3, 0x81907A4B6F1B47323A677974CE4AD71B)
KeyX0x18 = (0x82E9C9BEBFB8BDB875ECC0A07D474374, 0x304BF1468372EE64115EBD4093D84276)
KeyX0x1B = (0x45AD04953992C7C893724A9A7BCE6182, 0x6C8B2944A0726035F941DFC018524FB6)
KeyX0x3D = (0x617085719b7cfb316df4df2e8362c6e2, 0xBD4FE7E733C755FCE7540EABBD8AC30D)
KeyY0x3D = (
(0xD07B337F9CA4385932A2E25723232EB9, 0x85215E96CB95A9ECA4B4DE601CB562C7),
(0x0C767230F0998F1C46828202FAACBE4C, 0x0C767230F0998F1C46828202FAACBE4C),
(0xC475CB3AB8C788BB575E12A10907B8A4, 0xC475CB3AB8C788BB575E12A10907B8A4),
(0xE486EEE3D0C09C902F6686D4C06F649F, 0xE486EEE3D0C09C902F6686D4C06F649F),
(0xED31BA9C04B067506C4497A35B7804FC, 0xED31BA9C04B067506C4497A35B7804FC),
(0x5E66998AB4E8931606850FD7A16DD755, 0x5E66998AB4E8931606850FD7A16DD755)
)
KeyX0x3B = (0xB529221CDDB5DB5A1BF26EFF2041E875, 0x5C3D38AC1740994EFC8FD0BE8D8097B3)
# RSA signing keys
test_priv = bytes.fromhex('3E2BBEBA7F290252BF1BF1E4212FD9761E39234A6DFF99F633AA2B62030A0E15AC16B9856377F5742461B1016EEB72241E5DFA8FA85A101447BD05A07EE5FF60872A1831C1396CD545BB290504FB7AA268215FED4EFE646069BD96D0A7063D537B6892885086EE065D72739A39B6723B200139DF37281EF53963BC2AF25EAB1A99E45BEBE636306C40016160CC55896DCA7EE064787F7B26AE3EA3124516F6C8D0B94F91111211BBBB7FABC782DC4A619C14AE29FD3A601393192F5449B244345814D72F7025A048667655879B25776D0B75988BA639403C217F2A24C1A5C1DC5A5754F603F6AD5133406D5C265E299282E529137D7DFE0873BC5DC4E92BD671')
test_mod = bytes.fromhex('CAC588C7F12A092B7649C0A835751082C2B5E5B2E9C81888F39889BF9DE6E40B715DDD3F138271F2ED318699D947FEC57A7593E1F86DC63D9BE11599E1C2E05C384B35A24D3EE2CEFBB308A3DD0C2631849227C88A8EC883A86CA7A339719EF1349101DF114A9CF98BF92F46440A7238F38B6D233389BF6634A786E6ADF2DEF9AB16A140EED8F76CDC0092CB3149FC266424088FC660FF1EE3F0DDFB6D0D0F497CAD03EC9F6358FA46DFA2640ECC8557E72C617F59B8627D590EF684969942B0398380B5522E073F92E39EF547EBA7D7D415F1228232BE2AD08C01CC30A91196F6E92BEA0EF82D0DB191D51A9451B98539B0AF9F549E99E146E56FE25F4B4E23')
accessdesc_mod = (bytes.fromhex('B1E3E35F013980D156789DB706F71DBF3E2276EDF95DA236B630610596D300B9EDF1D7E01DA04FB7CF5A198775498840EDE36F7C904A644598D704B95A6B45AA7E94C0B3B7DB7B665920B708E2F383A37FE32021A0EBB7280FF32B15A4C9D0AB8939997E765F9E4D1E01228D74A6EB9AA39D45E510616E20FD2375C0C50503C54C024F544B5708B446C32CF1F9526CCD1455A855926DE24A4146EB08C5F3B48D0D5E21EAAF4D274DDE779397E2C76B661FDB2D6EA95F6114177B2B665AB50189F2237525259C869A89FF641D5BCED77E3F2DA8DAB55AC55F5920B0ED1C91FFA327B88ECF8215E549EFE458E15F8F53B9332A5624AAA1D36E471A634419B38EA5'),
bytes.fromhex('F43C4582FBF8905D07029F2A988B63B7D38F3CE2E0E093BFDF32434DBEF4D17A3A4E5431D773AE994CC41F3C3EF05705A38A455460D88FD91D680D0E2EEFC8E83DC919F3731E2DDA77883ECA5E25704BF77095835424E0C31A75DF613DD142EC351B38D6C1F67E182A8485DD57741F0A2EF6B294A23EE9A1D009F73A998005AF5755EF52FA243E7FD47C41447B067FB95B2E8E96AE46124D6421E50F85CCEB92E5F0F5A742273BECF8E781756F630A8B0D773851E66633BA79DC2F2C8FC32806BB039CDBD1640A66F0F8C12A491D0C6E35BBEAB35C0DE9957C67BE6577EC07C023050A724886E99EFC2515E7C82165E01BD5D50ED31154BB2978BF2A3C3BB6B1'))
accessdesc_priv = (None, bytes.fromhex('0cfbb8bec12e0a1f95e030eda2e1130e9a3d9cb11b5ef8dfbbe9d83bd56d3e8702bb37fcd3cd1ba09cdcf6a39d5d69a4dc381d1e228d549d4833c830e3341e40214bb3d8561bea38593f1a06683991860a4bf6f8bda3fdba45697373e005442b5a19ddbc45e0987ca8a2f59a49fc3b6baf4a303d584023ab954b7853ea45ccd776251d88ec4349a361e34878e5e658adb71b7b68ecf7171464d0d175f07cb769a929ef6a97cbef802f13ae3df772bbeb27807d8c6ab0ac2275905ca736c6a27cfb792f7becc36721e6fa9ceab04a24219dd99556a0df9c854ddf8753976a2edcddc8deec1f7f241a8897fcbbb823b7afc1a5e39d410bf291029bcf6c4ec1ebc1'))
cfa_mod = (bytes.fromhex('FBDEB82B40930FF6B19A08061B86FED0DF1079173D8CE27ACE8F2345B90A6DED300EC1A892C4BD1ACEA7AC77AA47E5204A4491DF1CFE8628122D66DFBEAD9661EDF2F7417B57886B241E7DECBE986565366599A9FE24678599EE2AAEEEB1811A22E36D756E21BCEF115C61AF0C3000B6A223EDFE7015DA52E1E62DCE34E8AA4CF1D6675657D3DBC090496F4573934E303070F5C98F3125F2C2E7337F4EB6F52ADF2000E579B2D0F917F77E1690400057914478EF1CE08509DAF4147E4BD735D687548F2AB5A76F50D0F7D1F119C9AC227E0511F5F26DEE9227575FE5150D2768BF52657473A6586D7918AC31DDDD808B7524E117E195251629AB6969C828EE5D'),
bytes.fromhex('B90CC4C678F86E300528C1CBD2CFA7805C574D169CAFA6CD01BB8333AD03BB0663D817F5E3DFDA0D3B860EA2804794446FD9977E786AC39393EF02FC229F80778C70921C43B1374C76E0573BAB89FFEFE5BB3EAB9139B8D9660B64289192E9D0B3DFD14BC173B53F56A04010FE152B1FA27ADE31B02640C357FD35CBF0FAFFFB6FDBCD341D512D2D8118FF0C0851D5B44B5616029F4E6ADF066ECB7285E92E43A208780C389C19BD7B747468C42DC1359E653BD899041C8B938E7E927CBBDD60ECE7FE0E9D4F3646E6F15C9470EE675F362B70448DCA09B95867D29FAD1F135474ADA6844428F3DE7E4C202BC5E912E95EFB8D77A9A4D20D3C3824BEF58AB5F5'))
cfa_priv = (None, bytes.fromhex('323643C2B31A7E13ABA2B68B4F05A7A6CDE7A6744749E651E47174157691F792B14EF699731ECFB51D7CAFC5EA5701E55C1047EA3A5486032A7605725316C2AE2DBE71F7176B23DD2CB88D1314E5DA3BC7337ABAE52A2B7D5A12273856DFED70030EED64C7F654ACFE1D77A4E4BCEBB9A6C5FE3AAF5881E43FA0E693132D987DB3E2C9C8D63191739DCAC944EFD039BF38FD1C91729340A98A0D3E32C4594B0CC7EA50419FF5E2B7507CE3C9EC4618ACB4912A32E0D8106FFC81B395F3FC78C0EFE57B8D14D436265FC632C019875C772637D8AE66D60B2826437C25DB6D5CE8948FA97707B2C085CD41BA48887334D5208A0FE39E99F0C8E8D92C2A2169E4C1'))
tik_mod = (bytes.fromhex('AD505BB6C67E2E5BDD6A3BEC43D910C772E9CC290DA58588B77DCC11680BB3E29F4EABBB26E98C2601985C041BB14378E689181AAD770568E928A2B98167EE3E10D072BEEF1FA22FA2AA3E13F11E1836A92A4281EF70AAF4E462998221C6FBB9BDD017E6AC590494E9CEA9859CEB2D2A4C1766F2C33912C58F14A803E36FCCDCCCDC13FD7AE77C7A78D997E6ACC35557E0D3E9EB64B43C92F4C50D67A602DEB391B06661CD32880BD64912AF1CBCB7162A06F02565D3B0ECE4FCECDDAE8A4934DB8EE67F3017986221155D131C6C3F09AB1945C206AC70C942B36F49A1183BCD78B6E4B47C6C5CAC0F8D62F897C6953DD12F28B70C5B7DF751819A9834652625'), bytes.fromhex('C0844CEB7EB0CFF0AEB777698593E4995A954E581738CED681B0BD7709E7F89ADFAD054883F6C3FDDF7B83E00C2681544329EA826C89F0A67442864D3260327DA77A13406659DA3E416B2794034FAA229DD55452DB270A6AA23D19B1661B197DABC70E881791A12AB43C6CCBF5AA7C3ADD36FB35717B20015900D6F69039354131F8C1C0573A35185890B1AD9A0EECE0F47A7DA52748C972AB0D087B62354091142BB11D1AFAF9CD5C1713535271CAE22A78B17F4ACD59D8BA1D7D705F781B9F9D37188ED7CD0D49577469883A6B8E4E1B85DDBE39450589561297599A09A4C82D2FF5CFB47370DB581EB24E776FA47E62DFB705E880425CB87887977F662C5F')) # XS0000000c, XS00000009
tik_priv = (None, bytes.fromhex('74CBCF1ED02DD4F9E005CE9C663DE36266624EB582E1241B5F732A7F1DB36E500783A0C0EDCEB7F93DAC61C57B99A0BCCE428FD3B0A5BF2A3D3E5EDC56C3A5DE35CD0A00F8176B2079EFD88323BF2128FF387D800715186CB920F88577BCD92A351CFEE3F1E8982EA04A48773503C97AACDABE6D1DFBE4DEEC7065FA1065A4B86ADF326B8E2879258772C07C5B81BC8192447DEA61BD3C48F30E18DC8D89A034C3AE9C5772A6D77C79F7E9146E15AC01FAFFC8A22A3AAB243C7E2EC5DA83D59D2410837AF4BBA36F88CEEC241BF4362E96C96D1902FEAA213E95A7FE83C8997FD1CB7C1F9130DBA4D3DDDA9B124E24D1A56F15FC2C72982C89C57D89DE2B4E01'))
tmd_mod = (bytes.fromhex('A689C590FD0B2F0D4F56B632FB934ED0739517B33A79DE040EE92DC31D37C7F73BF04BD3E44E20AB5A6FEAF5984CC1F6062E9A9FE56C3285DC6F25DDD5D0BF9FE2EFE835DF2634ED937FAB0214D104809CF74B860E6B0483F4CD2DAB2A9602BC56F0D6BD946AED6E0BE4F08F26686BD09EF7DB325F82B18F6AF2ED525BFD828B653FEE6ECE400D5A48FFE22D538BB5335B4153342D4335ACF590D0D30AE2043C7F5AD214FC9C0FE6FA40A5C86506CA6369BCEE44A32D9E695CF00B4FD79ADB568D149C2028A14C9D71B850CA365B37F70B657791FC5D728C4E18FD22557C4062D74771533C70179D3DAE8F92B117E45CB332F3B3C2A22E705CFEC66F6DA3772B'), bytes.fromhex('AA7F9380289BE89863107AE10C592C2F7CFFBDAADD74F4A2FBACD76F00934206347156D84049729F3E24FA5E19D15B635CD2EF09DE32EE6B6FC8FA328E2E96B99441047D076295DA0D91D80935D0DE8E6BC6AB1427019CFE4996FC9B54794DEBD7C66673A6DD3A77654794EC1C87AA46D978A97DDB11226ED412C2784B218392C710C77419FFAAF60B75D823DD33C3A15BA72D30A5A4D8F80FD673FD26CB29A6EF5039E25F5961846BDA2EC7CBE4384B28FB0DD58E7CAA7D4B373AD781DD73E30993BDBD7E08554A8CA5C9842D7101A22A01B015FB3078B913F4C73FB5A6F1A25E22B002B6E009547F0FBDF0FEA5501D9315F93D830F0F0E3DE23D96E709D977')) # CP0000000b, CP0000000a
tmd_priv = (None, bytes.fromhex('28CEDC39027F3E8EAAB75911E068BF80A64477DB1BA250A369E596B2C4CA7A350DFC4AB2FBC018A530B49D1044D1AD33FD15A78D0F17D5A4F55E7F33F68004276AEA9CEE68041AA5D435A225A231D9F2F0ACDE69B66456752E9BEADE2ABBD600AAE69BC2F69F60CD0EFAB1144A47D6639ACD9C93B90942DA8FFBE57BF14F9633F9455BCC84ABC2D8C40C85FA5128B99795238CB31D4EB61CCC6041FB26C7D6CB7718F7EACD103C5BA3C0774C11F37450EE2380C45DDD57F57D49574ABA62BF06D9D17F9110896F4909D7E9AF4C9F679D8982E4D5C19ADC5579E7E92D8142145561479BED76921D2FB57C284BFF7BC23B367399A621430EA11F82B8917111B2C1'))
root_mod = (bytes.fromhex('F8246C58BAE7500301FBB7C2EBE0010571DA922378F0514EC0031DD0D21ED3D07EFC852069B5DE9BB951A8BC90A244926D379295AE9436AAA6A302510C7B1DEDD5FB20869D7F3016F6BE65D383A16DB3321B95351890B17002937EE193F57E99A2474E9D3824C7AEE38541F567E7518C7A0E38E7EBAF41191BCFF17B42A6B4EDE6CE8DE7318F7F5204B3990E226745AFD485B24493008B08C7F6B7E56B02B3E8FE0C9D859CB8B68223B8AB27EE5F6538078B2DB91E2A153E85818072A23B6DD93281054F6FB0F6F5AD283ECA0B7AF35455E03DA7B68326F3EC834AF314048AC6DF20D28508673CAB62A2C7BC131A533E0B66806B1C30664B372331BDC4B0CAD8D11EE7BBD9285548AAEC1F66E821B3C8A0476900C5E688E80CCE3C61D69CBBA137C6604F7A72DD8C7B3E3D51290DAA6A597B081F9D3633A3467A356109ACA7DD7D2E2FB2C1AEB8E20F4892D8B9F8B46F4E3C11F4F47D8B757DFEFEA3899C33595C5EFDEBCBABE8413E3A9A803C69356EB2B2AD5CC4C858455EF5F7B30644B47C64068CDF809F76025A2DB446E03D7CF62F34E702457B02A4CF5D9DD53CA53A7CA629788C67CA08BFECCA43A957AD16C94E1CD875CA107DCE7E0118F0DF6BFEE51DDBD991C26E60CD4858AA592C820075F29F526C917C6FE5403EA7D4A50CEC3B7384DE886E82D2EB4D4E42B5F2B149A81EA7CE7144DC2994CFC44E1F91CBD495'), bytes.fromhex('D01FE100D43556B24B56DAE971B5A5D384B93003BE1BBF28A2305B060645467D5B0251D2561A274F9E9F9CEC646150AB3D2AE3366866ACA4BAE81AE3D79AA6B04A8BCBA7E6FB648945EBDFDB85BA091FD7D114B5A3A780E3A22E6ECD87B5A4C6F910E4032208814B0CEEA1A17DF739695F617EF63528DB949637A056037F7B32413895C0A8F1982E1565E38EEDC22E590EE2677B8609F48C2E303FBC405CAC18042F822084E4936803DA7F41349248562B8EE12F78F803246330BC7BE7EE724AF458A472E7AB46A1A7C10C2F18FA07C3DDD89806A11C9CC130B247A33C8D47DE67F29E5577B11C43493D5BBA7634A7E4E71531B7DF5981FE24A114554CBD8F005CE1DB35085CCFC77806B6DE254068A26CB5492D4580438FE1E5A9ED75C5ED451DCE789439CCC3BA28A2312A1B8719EF0F73B713950C02591A7462A607F37C0AA7A18FA943A36D752A5F4192F0136100AA9CB41BBE14BEB1F9FC692FDFA09446DE5A9DDE2CA5F68C1C0C21429287CB2DAAA3D263752F73E09FAF4479D2817429F69800AFDE6B592DC19882BDF581CCABF2CB91029EF35C4CFDBBFF49C1FA1B2FE31DE7A560ECB47EBCFE32425B956F81B69917487E3B789151DB2E78B1FD2EBE7E626B3EA165B4FB00CCB751AF507329C4A3939EA6DD9C50A0E7386B0145796B41AF61F78555944F3BC22DC3BD0D00F8798A42B1AAA08320659AC7395AB4F329'))
cci_mod = cfa_mod
cci_priv = cfa_priv
crr_mod = (bytes.fromhex('D00E6756858ABCF213D87FBB29D192349EE42743D1111DFE9593C4783F4A2D2AB1CA6FB0BA32A2242E2BE5726EF0B49768CCDA171514F074D435B4EE04D89CA9ECDBCB29E895F257BABD65473D6CE50DE5103EB5C37302AEC893777CC523220171CCC60BEACAA0FED4CDA949655A3B0D5BB7B2EA329A43856CCA045C900D9E34B9EF802B2E6D96BC31157E1401C000E0197A2E17E58BA37AD2C247779A8B832E9866A1A1020F0299E7D79FDCC852A22823081B87FFE4BA90025015C720A0AB76607D1FC1BF339D66246A803BF4A27F15B10C36EF44E8D036949A7484488789499A0B7E10F27355623D68AC9E5FAE1D54F8BA628E29BC49E7FDEEBD3D7BCCF8BF'), bytes.fromhex('c5f709805fdadcbd460752aa6dcd72b2500977478a4f092ae291b45f04975175c9196f95bb23147d34df777807e8d11011afce02b873a9fb64b76587e567dd673775fd0fe297bc79a8ccf9fa18b2624df7536b9c0e1aab90e65286c81c922c6153a901da4393d0422eddd54c8c4ce89156ecee12700b64f00ad6aff860c2a8267ac8ba559aa144fd094726a0c1999ef124dfa3c2bbff0745d9d6a4c0ff6c6c787b6d708c7444b095e6c6665e7ebe71c5913473a7d44c0dfca921499492a16a4d30a3d69f6c60400ceeebf89922e16ffc3c9623aa1134004efc2d604145e35d7806b1f1c307b9d347d0f18c26331f6b46ddf3e38464a7f15311e1534e99dbac53'))
crr_priv = (None, bytes.fromhex('3cde28a33a95ca323e126955f29ded4aab3645e10ec31f5ffabaef191a09c6a7af15ed8bbdb6db096654e1605c1a3711b8467452bcd0ff6e46f8e6b462924d6e7b8c812b3db206e6e74263080548efd5e61a55a76d64c0e4b414a2d16b8b7c2eceb0d3db7ed4b77f69f6962b4ba62809ec0ebc6299e5befad9724a37d5d4742b9a37efd8f68040f520ba28e2be7df98f04373534f13215f8fd9567bcad60867406c4a55aea403851026177e07bfee17b8cf9b341fdb76085d98ccbb02904028a6366baece494af4dd59a4c221e437575159d7cd8528a797ff196401e9ebc9a9eaa055a721be7a1f4fbe43ff499f344f5a54f36e73545201b339557d12562a781'))
crr_body_mod = bytes.fromhex('E2ADA6EACAA3E8CCA9701D2E234BC655CE13D9A758B4C773961DE8C3094D9BC3EB69A237835DD83704727A4FEA53989D0E0134709A8206E76AC9F80E495AA4E70EFAD4AB3BC5D7F1A4FC927FD0F3CDD5B92A1A4162B37B3E1E3546418EB2531A60F8C2D194B39D769F1D98ACF0CFE3A90585F2BF55761B891CC3192EEE94BE750FA3768B242497FAC05324F58502199DC5112E6BA326FEF755D4230A733F3753EAC2B7C1C9D8F32F78764AA0696091C27D1174EF96D97453B11CB0C43216823BAF61B2DE38873E374BA395888EE0279A1F7DB823C363E86851D98C4CC2598649F7469E3CD79F8923B473352F182376A39F400B769085C889DA65E76EEF2EF567')
crr_body_priv = bytes.fromhex('8D27296BC7A7EDCD942D365E86A826E7439E64C8AA9A582107F7B3FBCF8D3E53F002257B80182E0D847D6CE0DAC017A6A513E6FDBF98FC879A9E0E138766248DA56C588610809089EEFD4094CB1F26ABD1D3FFE97B76DC65C015D89BF629E149E9DCBE2417FF092CD6C46D5033DCA09D9DCCDD6E7BDF42224D80C7EBCBB1602F04EE040E4C76495592A5C113600A80153D1CC646572E7CB03D870687FD31F8E714972A5740AC9461CDCFDE8C404695A0D6F92C089B12BFF1889C5D40326D9D99A480A6C2455AD322FEFA175411EA41B4BD681EDD3FE592CB9EF8C00A8BF589A40368F8F8997CFEAD32DD5CB40629DA968BBACB15DE380DCAF70165F62D366E71')
def rol(val, r_bits, max_bits):
return (val << r_bits % max_bits) & (2 ** max_bits - 1) | ((val & (2 ** max_bits - 1)) >> (max_bits - (r_bits % max_bits)))
def key_scrambler(keyX, keyY):
return CTR.rol((CTR.rol(keyX, 2, 128) ^ keyY) + 0x1FF9E9AAC5FE0408024591DC5D52768A, 87, 128).to_bytes(0x10, 'big')
def titlekey_gen(titleID: str, password: str):
secret = hextobytes('fd040105060b111c2d49')
tid = hextobytes(titleID).lstrip(b'\x00')
salt = hashlib.md5(secret + tid).digest()
titlekey = hashlib.pbkdf2_hmac('sha1', password.encode(), salt, 20, 16)
return hex(readbe(titlekey))[2:]