summaryrefslogtreecommitdiffstats
path: root/crypto.c
blob: d0f77dd5da4b43a703535aae11e07bdd6fd5631a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
 * crypto.c
 */

#include <stddef.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/aes.h>
#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);
}