Latest compatible version of Classicube from the original GitHub repository (https://github.com/ClassiCube/ClassiCube) that can be compiled on Classicube for PowerMac PPC running Mac OS X 10.4.
This commit is contained in:
38
third_party/dsiwifi/arm_iop/source/ieee/wpa.h
vendored
Normal file
38
third_party/dsiwifi/arm_iop/source/ieee/wpa.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Max Thomas
|
||||
* This file is part of DSiWifi and is distributed under the MIT license.
|
||||
* See dsiwifi_license.txt for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _WPA_H
|
||||
#define _WPA_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
typedef struct gtk_keyinfo
|
||||
{
|
||||
u8 keytype[4];
|
||||
u8 keyidx;
|
||||
u8 unk;
|
||||
u8 key[0x20];
|
||||
} gtk_keyinfo;
|
||||
|
||||
typedef struct ptk_keyinfo
|
||||
{
|
||||
u8 kck[0x10];
|
||||
u8 kek[0x10];
|
||||
u8 tk[0x10];
|
||||
u8 mic_tx[0x8]; // TKIP-only
|
||||
u8 mic_rx[0x8]; // TKIP-only
|
||||
} ptk_keyinfo;
|
||||
|
||||
#define PTK_KCK (0x00)
|
||||
#define PTK_KEK (0x10)
|
||||
#define PTK_TK (0x20)
|
||||
|
||||
void wpa_calc_pmk(const char* ssid, const char* pass, u8* pmk);
|
||||
void wpa_decrypt_gtk(const u8* kek, const u8* data, u32 data_len, gtk_keyinfo* out);
|
||||
void wpa_calc_mic(const u8* kck, const u8* pkt_data, u32 pkt_len, u8* mic_out);
|
||||
void wpa_calc_ptk(const u8* dev_mac, const u8* ap_mac, const u8* dev_nonce, const u8* ap_nonce, const u8* pmk, ptk_keyinfo* ptk);
|
||||
|
||||
#endif // _WPA_H
|
||||
184
third_party/dsiwifi/arm_iop/source/ieee/wpa.twl.c
vendored
Normal file
184
third_party/dsiwifi/arm_iop/source/ieee/wpa.twl.c
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Max Thomas
|
||||
* This file is part of DSiWifi and is distributed under the MIT license.
|
||||
* See dsiwifi_license.txt for terms of use.
|
||||
*/
|
||||
|
||||
#include "wpa.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "crypto/sha1.h"
|
||||
#include "crypto/md.h"
|
||||
#include "crypto/pkcs5.h"
|
||||
#include "crypto/nist_kw.h"
|
||||
|
||||
static int PBKDF2_HMAC_SHA_1(const char* pass, const char* salt, int32_t iterations, uint32_t outputBytes, uint8_t* out)
|
||||
{
|
||||
mbedtls_md_context_t sha1_ctx;
|
||||
const mbedtls_md_info_t *info_sha1;
|
||||
int ret;
|
||||
|
||||
info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
|
||||
if( info_sha1 == NULL )
|
||||
return( 104 );
|
||||
|
||||
if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 )
|
||||
{
|
||||
ret = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, (u8*)pass, strlen(pass), (u8*)salt,
|
||||
strlen(salt), iterations, outputBytes, out );
|
||||
if( ret != 0 )
|
||||
{
|
||||
return( 102 );
|
||||
}
|
||||
|
||||
mbedtls_md_free( &sha1_ctx );
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void get_arr_min(const uint8_t* a, const uint8_t* b, size_t len, uint8_t* out)
|
||||
{
|
||||
int a_is_max = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (a[i] == b[i]) continue;
|
||||
|
||||
if (a[i] > b[i])
|
||||
{
|
||||
a_is_max = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(out, a_is_max ? b : a, len);
|
||||
}
|
||||
|
||||
static void get_arr_max(const uint8_t* a, const uint8_t* b, size_t len, uint8_t* out)
|
||||
{
|
||||
int a_is_max = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (a[i] == b[i]) continue;
|
||||
|
||||
if (a[i] > b[i])
|
||||
{
|
||||
a_is_max = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(out, a_is_max ? a : b, len);
|
||||
}
|
||||
|
||||
// !! This takes about 3 seconds on the 3DS ARM11 !!
|
||||
// Use the cached version in NVRAM if you can.
|
||||
void wpa_calc_pmk(const char* ssid, const char* pass, u8* pmk)
|
||||
{
|
||||
// Generate PMK
|
||||
PBKDF2_HMAC_SHA_1(pass, ssid, 4096, 32, pmk);
|
||||
}
|
||||
|
||||
void wpa_decrypt_gtk(const u8* kek, const u8* data, u32 data_len, gtk_keyinfo* out)
|
||||
{
|
||||
mbedtls_nist_kw_context kw_ctx;
|
||||
uint8_t gtk_dec[0x200];
|
||||
size_t decrypted_length;
|
||||
|
||||
|
||||
mbedtls_nist_kw_init(&kw_ctx);
|
||||
|
||||
// Set KEK
|
||||
mbedtls_nist_kw_setkey(&kw_ctx, MBEDTLS_CIPHER_ID_AES, kek, 128, 0);
|
||||
|
||||
// Unwrap GTK
|
||||
mbedtls_nist_kw_unwrap(&kw_ctx, MBEDTLS_KW_MODE_KW,
|
||||
data, data_len,
|
||||
gtk_dec, &decrypted_length,
|
||||
0x200);
|
||||
|
||||
mbedtls_nist_kw_free(&kw_ctx);
|
||||
|
||||
//hexdump(gtk_dec, 0x40);
|
||||
|
||||
memset(out, 0, sizeof(gtk_keyinfo));
|
||||
|
||||
int i = 0;
|
||||
while (i < decrypted_length)
|
||||
{
|
||||
u8 ent_type = gtk_dec[i++];
|
||||
u8 ent_size = gtk_dec[i++];
|
||||
|
||||
const u8 expected_keytype[4] = {0x00, 0x0f, 0xAC, 0x01};
|
||||
|
||||
if (ent_type == 0xDD && !memcmp(>k_dec[i], expected_keytype, 4) && (ent_size == 0x16 || ent_size == 0x26))
|
||||
{
|
||||
memcpy(out, >k_dec[i], ent_size);
|
||||
}
|
||||
i += ent_size;
|
||||
}
|
||||
}
|
||||
|
||||
void wpa_calc_mic(const u8* kck, const u8* pkt_data, u32 pkt_len, u8* mic_out)
|
||||
{
|
||||
uint8_t out[0x20];
|
||||
sha1_hmac(kck, 0x10, pkt_data, pkt_len, out);
|
||||
|
||||
//hexdump(out, 16);
|
||||
memcpy(mic_out, out, 16);
|
||||
}
|
||||
|
||||
void wpa_calc_ptk(const u8* dev_mac, const u8* ap_mac, const u8* dev_nonce, const u8* ap_nonce, const u8* pmk, ptk_keyinfo* ptk)
|
||||
{
|
||||
uint8_t ptk_out[0x60];
|
||||
uint8_t mac_min[6];
|
||||
uint8_t mac_max[6];
|
||||
uint8_t nonce_min[32];
|
||||
uint8_t nonce_max[32];
|
||||
|
||||
get_arr_min(dev_mac, ap_mac, 6, mac_min);
|
||||
get_arr_max(dev_mac, ap_mac, 6, mac_max);
|
||||
|
||||
//hexdump(mac_min, 6);
|
||||
//hexdump(mac_max, 6);
|
||||
|
||||
get_arr_min(ap_nonce, dev_nonce, 32, nonce_min);
|
||||
get_arr_max(ap_nonce, dev_nonce, 32, nonce_max);
|
||||
|
||||
|
||||
// Generate PTK
|
||||
char ptk_data[512];
|
||||
memset(ptk_data, 0, sizeof(ptk_data));
|
||||
|
||||
int ptk_data_pos = 0;
|
||||
strcpy(ptk_data, "Pairwise key expansion");
|
||||
ptk_data_pos += strlen("Pairwise key expansion") + 1;
|
||||
memcpy(ptk_data + ptk_data_pos, mac_min, 6); ptk_data_pos += 6;
|
||||
memcpy(ptk_data + ptk_data_pos, mac_max, 6); ptk_data_pos += 6;
|
||||
memcpy(ptk_data + ptk_data_pos, nonce_min, 32); ptk_data_pos += 32;
|
||||
memcpy(ptk_data + ptk_data_pos, nonce_max, 32); ptk_data_pos += 32;
|
||||
ptk_data[ptk_data_pos] = 0; ptk_data_pos += 1; // key iteration
|
||||
|
||||
sha1_hmac(pmk, 0x20, (u8*)ptk_data, ptk_data_pos, ptk_out);
|
||||
|
||||
ptk_data[ptk_data_pos-1] = 1;
|
||||
sha1_hmac(pmk, 0x20, (u8*)ptk_data, ptk_data_pos, ptk_out + 0x14);
|
||||
|
||||
ptk_data[ptk_data_pos-1] = 2;
|
||||
sha1_hmac(pmk, 0x20, (u8*)ptk_data, ptk_data_pos, ptk_out + 0x14*2);
|
||||
|
||||
ptk_data[ptk_data_pos-1] = 3;
|
||||
sha1_hmac(pmk, 0x20, (u8*)ptk_data, ptk_data_pos, ptk_out + 0x14*3);
|
||||
|
||||
|
||||
memcpy(ptk, ptk_out, sizeof(ptk_keyinfo));
|
||||
//hexdump(ptk_out, 16);
|
||||
}
|
||||
Reference in New Issue
Block a user