diff --git a/makerom/aes_keygen.c b/makerom/aes_keygen.c new file mode 100644 index 0000000..e5a35d6 --- /dev/null +++ b/makerom/aes_keygen.c @@ -0,0 +1,124 @@ +#include "aes_keygen.h" + +// 128bit wrap-around math +int32_t wrap_index(int32_t i) +{ + return i < 0 ? ((i % 16) + 16) % 16 : (i > 15 ? i % 16 : i); +} + +void n128_rrot(const uint8_t *in, uint32_t rot, uint8_t *out) +{ + uint32_t bit_shift, byte_shift; + + rot = rot % 128; + byte_shift = rot / 8; + bit_shift = rot % 8; + + for (int32_t i = 0; i < 16; i++) { + out[i] = (in[wrap_index(i - byte_shift)] >> bit_shift) | (in[wrap_index(i - byte_shift - 1)] << (8 - bit_shift)); + } + +} + +void n128_lrot(const uint8_t *in, uint32_t rot, uint8_t *out) +{ + uint32_t bit_shift, byte_shift; + + rot = rot % 128; + byte_shift = rot / 8; + bit_shift = rot % 8; + + for (int32_t i = 0; i < 16; i++) { + out[i] = (in[wrap_index(i + byte_shift)] << bit_shift) | (in[wrap_index(i + byte_shift + 1)] >> (8 - bit_shift)); + } +} + +/* out = a + b +*/ +void n128_add(const uint8_t *a, const uint8_t *b, uint8_t *out) +{ + uint8_t carry = 0; + uint32_t sum = 0; + + for (int i = 15; i >= 0; i--) { + sum = a[i] + b[i] + carry; + carry = sum >> 8; + out[i] = sum & 0xff; + } + + while (carry != 0) { + for (int i = 15; i >= 0; i--) { + sum = out[i] + carry; + carry = sum >> 8; + out[i] = sum & 0xff; + } + } +} + +/* out = a - b +*/ +void n128_sub(const uint8_t *a, const uint8_t *b, uint8_t *out) +{ + uint8_t carry = 0; + uint32_t sum = 0; + + for (int i = 15; i >= 0; i--) { + sum = a[i] - (b[i] + carry); + + // check to see if anything was borrowed from next byte + if (a[i] < (b[i] + carry)) { + sum += 0x100; + carry = 1; + } + else { + carry = 0; + } + + // set value + out[i] = sum & 0xff; + } + + + while (carry != 0) { + for (int i = 15; i >= 0; i--) { + sum = out[i] - carry; + + // check to see if anything was borrowed from next byte + if (out[i] < carry) { + sum += 0x100; + carry = 1; + } + else { + carry = 0; + } + + out[i] = sum & 0xff; + } + } + +} + +void n128_xor(const uint8_t *a, const uint8_t *b, uint8_t *out) +{ + for (int i = 0; i < 16; i++) { + out[i] = a[i] ^ b[i]; + } +} + +// keygen algorithm +void n_aes_keygen(const uint8_t *x, uint8_t x_shift, const uint8_t *y, uint8_t y_shift, const uint8_t *keygen_constant, uint8_t *key) +{ + // overall algo: + // key = ((x >>> x_shift) ^ (y >>> y_shift)) + keygen_constant + uint8_t x_rot[16], y_rot[16], key_xy[16]; + + // Rotate x and y + n128_rrot(x, x_shift, x_rot); + n128_rrot(y, y_shift, y_rot); + + // XOR rotated x and y + n128_xor(x_rot, y_rot, key_xy); + + // Add secret + n128_add(key_xy, keygen_constant, key); +} \ No newline at end of file diff --git a/makerom/aes_keygen.h b/makerom/aes_keygen.h new file mode 100644 index 0000000..0314744 --- /dev/null +++ b/makerom/aes_keygen.h @@ -0,0 +1,12 @@ +#pragma once +#include + +/* + AES Key generator for the Nintendo (Handheld) Consoles + + BYO keygen constants, and input >>> parameters + + key = ((x >>> x_shift) ^ (y >>> y_shift)) + keygen_constant +*/ + +void n_aes_keygen(const uint8_t *x, uint8_t x_shift, const uint8_t *y, uint8_t y_shift, const uint8_t *keygen_constant, uint8_t *key); diff --git a/makerom/keyset.c b/makerom/keyset.c index cdb32a6..d468471 100644 --- a/makerom/keyset.c +++ b/makerom/keyset.c @@ -1,4 +1,5 @@ #include "lib.h" +#include "aes_keygen.h" // KeyData #include "pki/test.h" // Test PKI @@ -49,16 +50,10 @@ void PrintBadKeySize(char *path, u32 size) u8* AesKeyScrambler(u8 *key, const u8 *keyX, const u8 *keyY) { - // Process keyX/keyY to get raw normal key - for(int i = 0; i < 16; i++) - key[i] = keyX[i] ^ ((keyY[i] >> 2) | ((keyY[i < 15 ? i+1 : 0] & 3) << 6)); // keyX[i] ^ - - const u8 SCRAMBLE_SECRET[16] = {0x51, 0xD7, 0x5D, 0xBE, 0xFD, 0x07, 0x57, 0x6A, 0x1C, 0xFC, 0x2A, 0xF0, 0x94, 0x4B, 0xD5, 0x6C}; - - // Apply Secret to get final normal key - for(int i = 0; i < 16; i++) - key[i] = key[i] ^ SCRAMBLE_SECRET[i]; - + static const uint8_t CTR_KEYGEN_CONST[16] = { 0xEE, 0x2E, 0xA9, 0x3B, 0x45, 0x0F, 0xFC, 0xF4, 0xD5, 0x62, 0xFF, 0x02, 0x04, 0x01, 0x22, 0xC8 }; + static const uint8_t CTR_KEYX_SHIFT = 39; + static const uint8_t CTR_KEYY_SHIFT = 41; + n_aes_keygen(keyX, CTR_KEYX_SHIFT, keyY, CTR_KEYY_SHIFT, CTR_KEYGEN_CONST, key); return key; } diff --git a/makerom/makerom.vcxproj b/makerom/makerom.vcxproj index 7d44201..dbdfd0a 100644 --- a/makerom/makerom.vcxproj +++ b/makerom/makerom.vcxproj @@ -91,6 +91,7 @@ + @@ -194,6 +195,7 @@ + diff --git a/makerom/makerom.vcxproj.filters b/makerom/makerom.vcxproj.filters index 472d9e1..992fd34 100644 --- a/makerom/makerom.vcxproj.filters +++ b/makerom/makerom.vcxproj.filters @@ -339,6 +339,9 @@ Resource Files\DESC + + Header Files + @@ -479,6 +482,9 @@ Source Files + + Source Files +