/*
* Copyright 2012 Rui Araújo, Luís Fonseca
*
* This file is part of Router Keygen.
*
* Router Keygen is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Router Keygen is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Router Keygen. If not, see <http://www.gnu.org/licenses/>.
*/
package org.exobel.routerkeygen.algorithms;
import android.os.Parcel;
import android.os.Parcelable;
import org.exobel.routerkeygen.R;
import java.util.List;
/*
*
* Algorithm:
* Can be consulted here:
* http://websec.ca/blog/view/mac2wepkey_huawei
* It has nice graphics that explain it all.
* */
public class HuaweiKeygen extends Keygen {
public static final Parcelable.Creator<HuaweiKeygen> CREATOR = new Parcelable.Creator<HuaweiKeygen>() {
public HuaweiKeygen createFromParcel(Parcel in) {
return new HuaweiKeygen(in);
}
public HuaweiKeygen[] newArray(int size) {
return new HuaweiKeygen[size];
}
};
// Java adaptation of mac2wepkey.py from
// http://websec.ca/blog/view/mac2wepkey_huawei
private final int[] a0 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
private final int[] a1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
private final int[] a2 = {0, 13, 10, 7, 5, 8, 15, 2, 10, 7, 0, 13, 15, 2, 5, 8};
private final int[] a3 = {0, 1, 3, 2, 7, 6, 4, 5, 15, 14, 12, 13, 8, 9, 11, 10};
private final int[] a4 = {0, 5, 11, 14, 7, 2, 12, 9, 15, 10, 4, 1, 8, 13, 3, 6};
private final int[] a5 = {0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12};
private final int[] a6 = {0, 1, 3, 2, 6, 7, 5, 4, 12, 13, 15, 14, 10, 11, 9, 8};
private final int[] a7 = {0, 8, 0, 8, 1, 9, 1, 9, 2, 10, 2, 10, 3, 11, 3, 11};
private final int[] a8 = {0, 5, 11, 14, 6, 3, 13, 8, 12, 9, 7, 2, 10, 15, 1, 4};
private final int[] a9 = {0, 9, 2, 11, 5, 12, 7, 14, 10, 3, 8, 1, 15, 6, 13, 4};
private final int[] a10 = {0, 14, 13, 3, 11, 5, 6, 8, 6, 8, 11, 5, 13, 3, 0, 14};
private final int[] a11 = {0, 12, 8, 4, 1, 13, 9, 5, 2, 14, 10, 6, 3, 15, 11, 7};
private final int[] a12 = {0, 4, 9, 13, 2, 6, 11, 15, 4, 0, 13, 9, 6, 2, 15, 11};
private final int[] a13 = {0, 8, 1, 9, 3, 11, 2, 10, 6, 14, 7, 15, 5, 13, 4, 12};
private final int[] a14 = {0, 1, 3, 2, 7, 6, 4, 5, 14, 15, 13, 12, 9, 8, 10, 11};
private final int[] a15 = {0, 1, 3, 2, 6, 7, 5, 4, 13, 12, 14, 15, 11, 10, 8, 9};
private final int[] n1 = {0, 14, 10, 4, 8, 6, 2, 12, 0, 14, 10, 4, 8, 6, 2, 12};
private final int[] n2 = {0, 8, 0, 8, 3, 11, 3, 11, 6, 14, 6, 14, 5, 13, 5, 13};
private final int[] n3 = {0, 0, 3, 3, 2, 2, 1, 1, 4, 4, 7, 7, 6, 6, 5, 5};
private final int[] n4 = {0, 11, 12, 7, 15, 4, 3, 8, 14, 5, 2, 9, 1, 10, 13, 6};
private final int[] n5 = {0, 5, 1, 4, 6, 3, 7, 2, 12, 9, 13, 8, 10, 15, 11, 14};
private final int[] n6 = {0, 14, 4, 10, 11, 5, 15, 1, 6, 8, 2, 12, 13, 3, 9, 7};
private final int[] n7 = {0, 9, 0, 9, 5, 12, 5, 12, 10, 3, 10, 3, 15, 6, 15, 6};
private final int[] n8 = {0, 5, 11, 14, 2, 7, 9, 12, 12, 9, 7, 2, 14, 11, 5, 0};
private final int[] n9 = {0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4};
private final int[] n10 = {0, 8, 1, 9, 3, 11, 2, 10, 5, 13, 4, 12, 6, 14, 7, 15};
private final int[] n11 = {0, 14, 13, 3, 9, 7, 4, 10, 6, 8, 11, 5, 15, 1, 2, 12};
private final int[] n12 = {0, 13, 10, 7, 4, 9, 14, 3, 10, 7, 0, 13, 14, 3, 4, 9};
private final int[] n13 = {0, 1, 3, 2, 6, 7, 5, 4, 15, 14, 12, 13, 9, 8, 10, 11};
private final int[] n14 = {0, 1, 3, 2, 4, 5, 7, 6, 12, 13, 15, 14, 8, 9, 11, 10};
private final int[] n15 = {0, 6, 12, 10, 9, 15, 5, 3, 2, 4, 14, 8, 11, 13, 7, 1};
private final int[] n16 = {0, 11, 6, 13, 13, 6, 11, 0, 11, 0, 13, 6, 6, 13, 0, 11};
private final int[] n17 = {0, 12, 8, 4, 1, 13, 9, 5, 3, 15, 11, 7, 2, 14, 10, 6};
private final int[] n18 = {0, 12, 9, 5, 2, 14, 11, 7, 5, 9, 12, 0, 7, 11, 14, 2};
private final int[] n19 = {0, 6, 13, 11, 10, 12, 7, 1, 5, 3, 8, 14, 15, 9, 2, 4};
private final int[] n20 = {0, 9, 3, 10, 7, 14, 4, 13, 14, 7, 13, 4, 9, 0, 10, 3};
private final int[] n21 = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15};
private final int[] n22 = {0, 1, 2, 3, 5, 4, 7, 6, 11, 10, 9, 8, 14, 15, 12, 13};
private final int[] n23 = {0, 7, 15, 8, 14, 9, 1, 6, 12, 11, 3, 4, 2, 5, 13, 10};
private final int[] n24 = {0, 5, 10, 15, 4, 1, 14, 11, 8, 13, 2, 7, 12, 9, 6, 3};
private final int[] n25 = {0, 11, 6, 13, 13, 6, 11, 0, 10, 1, 12, 7, 7, 12, 1, 10};
private final int[] n26 = {0, 13, 10, 7, 4, 9, 14, 3, 8, 5, 2, 15, 12, 1, 6, 11};
private final int[] n27 = {0, 4, 9, 13, 2, 6, 11, 15, 5, 1, 12, 8, 7, 3, 14, 10};
private final int[] n28 = {0, 14, 12, 2, 8, 6, 4, 10, 0, 14, 12, 2, 8, 6, 4, 10};
private final int[] n29 = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3};
private final int[] n30 = {0, 15, 14, 1, 12, 3, 2, 13, 8, 7, 6, 9, 4, 11, 10, 5};
private final int[] n31 = {0, 10, 4, 14, 9, 3, 13, 7, 2, 8, 6, 12, 11, 1, 15, 5};
private final int[] n32 = {0, 10, 5, 15, 11, 1, 14, 4, 6, 12, 3, 9, 13, 7, 8, 2};
private final int[] n33 = {0, 4, 9, 13, 3, 7, 10, 14, 7, 3, 14, 10, 4, 0, 13, 9};
private final int[] key = {30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 61, 62, 63, 64,
65, 66};
private final char[] ssid = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};
final private String ssidIdentifier;
public HuaweiKeygen(String ssid, String mac) {
super(ssid, mac);
if (getSsidName().matches("INFINITUM[0-9a-zA-Z]{4}"))
ssidIdentifier = ssid.substring(ssid.length() - 4);
else
ssidIdentifier = "";
}
private HuaweiKeygen(Parcel in) {
super(in);
ssidIdentifier = in.readString();
}
public List<String> getKeys() {
if (getMacAddress().length() != 12) {
setErrorCode(R.string.msg_errpirelli);
return null;
}
int[] mac = new int[12];
for (int i = 0; i < 12; ++i) {
mac[i] = Integer.parseInt(getMacAddress().substring(i, i + 1), 16);
}
int s1 = (n1[mac[0]]) ^ (a4[mac[1]]) ^ (a6[mac[2]]) ^ (a1[mac[3]])
^ (a11[mac[4]]) ^ (n20[mac[5]]) ^ (a10[mac[6]]) ^ (a4[mac[7]])
^ (a8[mac[8]]) ^ (a2[mac[9]]) ^ (a5[mac[10]]) ^ (a9[mac[11]])
^ 5;
int s2 = (n2[mac[0]]) ^ (n8[mac[1]]) ^ (n15[mac[2]]) ^ (n17[mac[3]])
^ (a12[mac[4]]) ^ (n21[mac[5]]) ^ (n24[mac[6]]) ^ (a9[mac[7]])
^ (n27[mac[8]]) ^ (n29[mac[9]]) ^ (a11[mac[10]])
^ (n32[mac[11]]) ^ 10;
int s3 = (n3[mac[0]]) ^ (n9[mac[1]]) ^ (a5[mac[2]]) ^ (a9[mac[3]])
^ (n19[mac[4]]) ^ (n22[mac[5]]) ^ (a12[mac[6]]) ^ (n25[mac[7]])
^ (a11[mac[8]]) ^ (a13[mac[9]]) ^ (n30[mac[10]])
^ (n33[mac[11]]) ^ 11;
int s4 = (n4[mac[0]]) ^ (n10[mac[1]]) ^ (n16[mac[2]]) ^ (n18[mac[3]])
^ (a13[mac[4]]) ^ (n23[mac[5]]) ^ (a1[mac[6]]) ^ (n26[mac[7]])
^ (n28[mac[8]]) ^ (a3[mac[9]]) ^ (a6[mac[10]]) ^ (a0[mac[11]])
^ 10;
String ssidFinal = Character.toString(ssid[s1])
+ Character.toString(ssid[s2]) + Character.toString(ssid[s3])
+ Character.toString(ssid[s4]);
int ya = (a2[mac[0]]) ^ (n11[mac[1]]) ^ (a7[mac[2]]) ^ (a8[mac[3]])
^ (a14[mac[4]]) ^ (a5[mac[5]]) ^ (a5[mac[6]]) ^ (a2[mac[7]])
^ (a0[mac[8]]) ^ (a1[mac[9]]) ^ (a15[mac[10]]) ^ (a0[mac[11]])
^ 13;
int yb = (n5[mac[0]]) ^ (n12[mac[1]]) ^ (a5[mac[2]]) ^ (a7[mac[3]])
^ (a2[mac[4]]) ^ (a14[mac[5]]) ^ (a1[mac[6]]) ^ (a5[mac[7]])
^ (a0[mac[8]]) ^ (a0[mac[9]]) ^ (n31[mac[10]]) ^ (a15[mac[11]])
^ 4;
int yc = (a3[mac[0]]) ^ (a5[mac[1]]) ^ (a2[mac[2]]) ^ (a10[mac[3]])
^ (a7[mac[4]]) ^ (a8[mac[5]]) ^ (a14[mac[6]]) ^ (a5[mac[7]])
^ (a5[mac[8]]) ^ (a2[mac[9]]) ^ (a0[mac[10]]) ^ (a1[mac[11]])
^ 7;
int yd = (n6[mac[0]]) ^ (n13[mac[1]]) ^ (a8[mac[2]]) ^ (a2[mac[3]])
^ (a5[mac[4]]) ^ (a7[mac[5]]) ^ (a2[mac[6]]) ^ (a14[mac[7]])
^ (a1[mac[8]]) ^ (a5[mac[9]]) ^ (a0[mac[10]]) ^ (a0[mac[11]])
^ 14;
int ye = (n7[mac[0]]) ^ (n14[mac[1]]) ^ (a3[mac[2]]) ^ (a5[mac[3]])
^ (a2[mac[4]]) ^ (a10[mac[5]]) ^ (a7[mac[6]]) ^ (a8[mac[7]])
^ (a14[mac[8]]) ^ (a5[mac[9]]) ^ (a5[mac[10]]) ^ (a2[mac[11]])
^ 7;
addPassword(Integer.toString(key[ya]) + Integer.toString(key[yb])
+ Integer.toString(key[yc]) + Integer.toString(key[yd])
+ Integer.toString(key[ye]));
if (!ssidIdentifier.equalsIgnoreCase(ssidFinal)
&& getSsidName().matches("INFINITUM[0-9a-zA-Z]{4}")) {
setErrorCode(R.string.msg_err_essid_no_match);
}
return getResults();
}
@Override
public int getSupportState() {
if (getSsidName().matches("INFINITUM[0-9a-zA-Z]{4}"))
return SUPPORTED;
return UNLIKELY_SUPPORTED;
}
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(ssidIdentifier);
}
}