summaryrefslogtreecommitdiffstats
path: root/crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto.c')
-rw-r--r--crypto.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/crypto.c b/crypto.c
new file mode 100644
index 0000000..f8d4b1f
--- /dev/null
+++ b/crypto.c
@@ -0,0 +1,70 @@
+/**
+ * crypto.c
+ */
+
+#include <stddef.h>
+#ifdef __WIN32__
+/* todo */
+#else
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <openssl/aes.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include "crypto.h"
+#include "wii_tik.h"
+
+void get_common_key(u8 *key) {
+ u8 i;
+ u8 table[16] = {
+ 0xC1, 0xce, 0x00, 0x08,
+ 0x74, 0xaf, 0xb9, 0xce,
+ 0x62, 0xf3, 0xef, 0x6f,
+ 0x59, 0xab, 0x80, 0xdd
+ };
+ u8 v = 42;
+
+ for (i = 0; i < 16; i++)
+ {
+ key[i] = v ^ table[i];
+ }
+}
+
+void md5(u8 *data, u32 len, u8 *hash) {
+ MD5(data, len, hash);
+}
+
+void sha(u8 *data, u32 len, u8 *hash) {
+ SHA1(data, len, hash);
+}
+
+void aes_cbc_dec(u8 *key, u8 *iv, u8 *in, u32 len, u8 *out) {
+ AES_KEY aes_key;
+
+ AES_set_decrypt_key(key, 128, &aes_key);
+ AES_cbc_encrypt(in, out, len, &aes_key, iv, AES_DECRYPT);
+}
+
+void aes_cbc_enc(u8 *key, u8 *iv, u8 *in, u32 len, u8 *out) {
+ AES_KEY aes_key;
+
+ AES_set_encrypt_key(key, 128, &aes_key);
+ AES_cbc_encrypt(in, out, len, &aes_key, iv, AES_ENCRYPT);
+}
+
+void decrypt_title_key(wii_tik *tik, u8 *title_key) {
+ u8 common_key[16];
+ u8 iv[16];
+ u64 title_id_le;
+
+ get_common_key(common_key);
+
+ title_id_le = ((u64)tik->title_id << 32);
+ title_id_le += be32((u8*)&tik->title_category);
+
+ memset(iv, 0, sizeof(iv));
+ memcpy(iv, &title_id_le, 8);
+
+ aes_cbc_dec(common_key, iv, (u8*)tik->title_key_enc, 16, title_key);
+}