usbdsec.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. usbdsec.c - part of libxsm3
  3. Copyright (C) 2013 oct0xor
  4. Copyright (C) 2022 InvoxiPlayGames
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. #include <string.h>
  18. #include <stdio.h>
  19. #include "excrypt.h"
  20. static uint8_t UsbdSecSboxData[256] __attribute__ ((aligned(4))) = {
  21. 0xB0, 0x3D, 0x9B, 0x70, 0xF3, 0xC7, 0x80, 0x60,
  22. 0x73, 0x9F, 0x6C, 0xC0, 0xF1, 0x3D, 0xBB, 0x40,
  23. 0xB3, 0xC8, 0x37, 0x14, 0xDF, 0x49, 0xDA, 0xD4,
  24. 0x48, 0x22, 0x78, 0x80, 0x6E, 0xCD, 0xE7, 0x00,
  25. 0x81, 0x86, 0x68, 0xE1, 0x5D, 0x7C, 0x54, 0x2C,
  26. 0x55, 0x7B, 0xEF, 0x48, 0x42, 0x7B, 0x3B, 0x68,
  27. 0xE3, 0xDB, 0xAA, 0xC0, 0x0F, 0xA9, 0x96, 0x20,
  28. 0x95, 0x05, 0x93, 0x94, 0x9A, 0xF6, 0xA3, 0x64,
  29. 0x5D, 0xCC, 0x76, 0x00, 0xE5, 0x08, 0x19, 0xE8,
  30. 0x8D, 0x29, 0xD7, 0x4C, 0x21, 0x91, 0x17, 0xF4,
  31. 0xBC, 0x6A, 0xB3, 0x80, 0x83, 0xC6, 0xD4, 0x90,
  32. 0x9B, 0xAE, 0x0E, 0xFE, 0x2E, 0x4A, 0xF2, 0x00,
  33. 0x73, 0x88, 0xD9, 0x40, 0x66, 0xC5, 0xD4, 0x08,
  34. 0x57, 0xB1, 0x89, 0x48, 0xDC, 0x54, 0xFC, 0x43,
  35. 0x6A, 0x26, 0x87, 0xB8, 0x09, 0x5F, 0xCE, 0x80,
  36. 0xE4, 0x0B, 0x05, 0x9C, 0x24, 0xF3, 0xDE, 0xE2,
  37. 0x3E, 0xEC, 0x38, 0x8A, 0xA2, 0x55, 0xA4, 0x50,
  38. 0x4E, 0x4B, 0xE9, 0x58, 0x7F, 0x9F, 0x7D, 0x80,
  39. 0x23, 0x0C, 0x4D, 0x80, 0x05, 0x44, 0x26, 0xB8,
  40. 0xE9, 0xD8, 0xBC, 0xE6, 0x76, 0x3A, 0x6E, 0xA4,
  41. 0x19, 0xDE, 0xC2, 0xD0, 0xC4, 0xBC, 0xC3, 0x5C,
  42. 0x59, 0xDF, 0x16, 0x46, 0x39, 0x70, 0xF4, 0xEE,
  43. 0x2D, 0x58, 0x5A, 0xA8, 0x17, 0x86, 0x6B, 0x60,
  44. 0x29, 0x58, 0x4D, 0xD2, 0x5F, 0x28, 0x7A, 0xD8,
  45. 0x8E, 0x79, 0xEA, 0x82, 0x94, 0x33, 0x31, 0x81,
  46. 0xD9, 0x22, 0xD5, 0x10, 0xDA, 0x92, 0xA0, 0x7D,
  47. 0x3D, 0xDA, 0xAC, 0x1C, 0xA2, 0x53, 0x31, 0xB8,
  48. 0x3C, 0x96, 0x52, 0x00, 0x82, 0x6B, 0x56, 0xA0,
  49. 0xD3, 0xC2, 0x40, 0xC7, 0x1B, 0x7F, 0xDC, 0x01,
  50. 0x72, 0x70, 0xB1, 0x8C, 0x01, 0x09, 0x09, 0x36,
  51. 0xFC, 0x97, 0xEA, 0xDE, 0xE3, 0x0D, 0xAE, 0x7E,
  52. 0xE3, 0x0D, 0xAE, 0x7E, 0x33, 0x69, 0x80, 0x40
  53. };
  54. static uint8_t UsbdSecPlainTextData[128] __attribute__ ((aligned(4))) = {
  55. 0xD1, 0xD2, 0xF2, 0x80, 0x6E, 0xBA, 0x0C, 0xC0,
  56. 0xB6, 0xC4, 0xC9, 0xD8, 0x61, 0x75, 0x1D, 0x1A,
  57. 0x3F, 0x95, 0x58, 0xBE, 0xD8, 0x0D, 0xE2, 0xC0,
  58. 0xD0, 0x21, 0x79, 0x20, 0x65, 0x2D, 0x99, 0x40,
  59. 0x3C, 0x96, 0x52, 0x00, 0x1B, 0x7F, 0xDC, 0x01,
  60. 0x82, 0x1C, 0x13, 0xD8, 0x33, 0x69, 0x80, 0x40,
  61. 0xFC, 0x97, 0xEA, 0xDE, 0x08, 0xEA, 0x14, 0xDC,
  62. 0xEB, 0x0F, 0x6A, 0x18, 0x6F, 0x78, 0x2C, 0xB0,
  63. 0xD3, 0xC2, 0x40, 0xC7, 0x82, 0x6B, 0x56, 0xA0,
  64. 0x19, 0x09, 0x36, 0xE0, 0x72, 0x70, 0xB1, 0x8C,
  65. 0xE3, 0x0D, 0xAE, 0x7E, 0x50, 0xA5, 0x2B, 0xE2,
  66. 0xC9, 0xAF, 0xC7, 0x70, 0x1C, 0x29, 0x80, 0x56,
  67. 0x24, 0xF0, 0x66, 0xFA, 0x02, 0x2B, 0x58, 0x98,
  68. 0x8F, 0xE4, 0xD1, 0x3C, 0x6E, 0x38, 0x2A, 0xFF,
  69. 0xB8, 0xFA, 0x35, 0xB0, 0x52, 0x49, 0xC5, 0xB4,
  70. 0x66, 0xFA, 0x47, 0x55, 0x6C, 0x8D, 0x40, 0x08
  71. };
  72. void UsbdSecXSM3AuthenticationCrypt(const uint8_t *key, const uint8_t *input, size_t length, uint8_t *output, uint8_t encrypt) {
  73. EXCRYPT_DES3_STATE des;
  74. uint64_t sk[3];
  75. uint8_t iv[8];
  76. // clear local variables
  77. memset(iv, 0, sizeof(iv));
  78. // run parity on the key
  79. ExCryptDesParity(key, 0x10, (uint8_t *)sk);
  80. sk[2] = sk[0];
  81. // set the key in the state and run triple-des cbc en/decryption on it
  82. ExCryptDes3Key(&des, sk);
  83. ExCryptDes3Cbc(&des, input, length, output, iv, encrypt);
  84. }
  85. void UsbdSecXSM3AuthenticationMac(const uint8_t *key, uint8_t *salt, uint8_t *input, size_t length, uint8_t *output) {
  86. EXCRYPT_DES3_STATE des3;
  87. EXCRYPT_DES_STATE des;
  88. uint64_t sk[3];
  89. uint8_t iv[8];
  90. uint8_t temp[8];
  91. uint64_t input_temp;
  92. size_t i;
  93. // clear iv + temp value of stack junk
  94. memset(iv, 0, sizeof(iv));
  95. memset(temp, 0, sizeof(temp));
  96. // run parity on the key
  97. ExCryptDesParity(key, 0x10, (uint8_t *)sk);
  98. sk[2] = sk[0];
  99. // set the key in our initial des state
  100. ExCryptDesKey(&des, (uint8_t *)&sk[0]);
  101. // if we have a salt, encrypt it into the temp value
  102. if (salt) {
  103. memcpy(&input_temp, salt, sizeof(input_temp));
  104. input_temp = SWAP64(SWAP64(input_temp) + 1);
  105. memcpy(salt, &input_temp, sizeof(input_temp)); // no idea what this does
  106. ExCryptDesEcb(&des, salt, temp, 1);
  107. }
  108. // for every 8 byte input block, xor the temp value with it and encrypt over itself
  109. for (i = 0; i < length; i += 8) {
  110. memcpy(&input_temp, input+i, sizeof(input_temp));
  111. *(uint64_t *)temp ^= input_temp;
  112. ExCryptDesEcb(&des, temp, temp, 1);
  113. }
  114. // xor the highest bit of the temp value
  115. temp[0] ^= 0x80;
  116. // set the key and perform the final triple-des encryption
  117. ExCryptDes3Key(&des3, sk);
  118. ExCryptDes3Cbc(&des3, temp, 8, output, iv, 1);
  119. // real kernel does the following, but the above works:
  120. // XeCryptDesEcb(des_state_1, temp, temp, 1);
  121. // XeCryptDesEcb(des_state_2, temp, temp, 0);
  122. // XeCryptDesEcb(des_state_1, temp, output, 1);
  123. }
  124. void UsbdSecXSMAuthenticationAcr(const uint8_t *console_id, const uint8_t *input, const uint8_t *key, uint8_t *output) {
  125. uint8_t block[8];
  126. uint8_t iv[8];
  127. uint8_t ab[8];
  128. uint8_t cd[8];
  129. // fill in the input block with the first 4 bytes of input data and the first 4 bytes of the console ID
  130. // *(uint32_t *)block = *(uint32_t *)input;
  131. // *(uint32_t *)(block + 4) = *(uint32_t *)console_id;
  132. memcpy(block, input, 4);
  133. memcpy(block+4, console_id, 4);
  134. // run custom "parve" crypto algorithms. idk whar they do
  135. ExCryptParveEcb(key, UsbdSecSboxData, input + 0x10, iv);
  136. ExCryptParveEcb(key, UsbdSecSboxData, block, cd);
  137. ExCryptParveCbcMac(key, UsbdSecSboxData, iv, UsbdSecPlainTextData, 0x80, ab);
  138. ExCryptChainAndSumMac((uint32_t *)cd, (uint32_t *)ab, (uint32_t *)UsbdSecPlainTextData, 0x20, (uint32_t *)output);
  139. uint64_t current;
  140. memcpy(&current, output, sizeof(current));
  141. current ^= *(uint64_t *)ab;
  142. // *(uint64_t *)output ^= *(uint64_t *)ab;
  143. memcpy(output, &current, sizeof(current));
  144. }