示例#1
0
文件: wad.cpp 项目: Swyter/wiiqt
const QByteArray Wad::Content( quint16 i )
{
    if( tmdData.isEmpty() || tikData.isEmpty() )
    {
        Err( "Can't decryte data without a TMD and ticket" );
        return QByteArray();
    }
    Ticket ticket( tikData );
    Tmd t( tmdData );
    if( partsEnc.size() != t.Count() || i >= partsEnc.size() )
    {
        Err( "I dont know whats going on some number is out of range and i dont like it" );
        return QByteArray();
    }
    QByteArray encData = partsEnc.at( i );

    AesSetKey( ticket.DecryptedKey() );

	QByteArray decData = AesDecrypt( t.Index( i ), encData );
    decData.resize( t.Size( i ) );
    QByteArray realHash = GetSha1( decData );
    if( realHash != t.Hash( i ) )
    {
        Err( QString( "hash doesnt match for content %1" ).arg( i ) );
        return QByteArray();
    }
    return decData;
}
示例#2
0
int main() { 
        std::string ToEncrypt, Encrypted, Decrypted, AesKey1, AesKey2; 
        int retval=0; 

        AesKey1 = "111112222233333444445555566666664444888885554444888548136241859641"; // 32 Byte = 256 Bit key. 
	AesKey2 = "111112222233333444445555566666664444888885554444888548136241859641"; // 32 Byte = 256 Bit key.
        ToEncrypt = "aaaaaaaaaaaaaabbbbbbbbbbbbbcccccccccccccccddddddddddddddddeeeeeeeeeeeeee"; 

	// Not sure why this is here?
        //OpenSSL_add_all_algorithms(); 
        //OpenSSL_add_all_ciphers(); 
        //OpenSSL_add_all_digests(); 

        retval = AesEncrypt(AesKey1, ToEncrypt, Encrypted); 
        retval = AesDecrypt(AesKey2, Encrypted, Decrypted); 

        printf( "Original: %s\nDecrypted: %s\n", ToEncrypt.c_str(), Decrypted.c_str() );
        return 0; 
} 
int main(int argc, char** argv)
{
    Aes    aes;
    byte*  key;       /* user entered key */
    FILE*  inFile;
    FILE*  outFile = NULL;

    const char* in;
    const char* out;

    int    option;    /* choice of how to run program */
    int    ret = 0;   /* return value */
    int    size = 0;
    int    inCheck = 0;
    int    outCheck = 0;
    char   choice = 'n';

    while ((option = getopt(argc, argv, "d:e:i:o:h")) != -1) {
        switch (option) {
            case 'd': /* if entered decrypt */
                size = atoi(optarg);
                ret = SizeCheck(size);
                choice = 'd';
                break;
            case 'e': /* if entered encrypt */
                size = atoi(optarg);
                ret = SizeCheck(size);
                choice = 'e';
                break;
            case 'h': /* if entered 'help' */
                help();
                break;
            case 'i': /* input file */
                in = optarg;
                inCheck = 1;
                inFile = fopen(in, "r");
                break;
            case 'o': /* output file */
                out = optarg;
                outCheck = 1;
                outFile = fopen(out, "w");
                break;
            case '?':
                if (optopt) {
                    printf("Ending Session\n");
                    return -111;
                }
            default:
                abort();
        }
    }
    if (inCheck == 0 || outCheck == 0) {
            printf("Must have both input and output file");
            printf(": -i filename -o filename\n");
    }
    else if (ret == 0 && choice != 'n') {
        key = malloc(size);    /* sets size memory of key */
        ret = NoEcho((char*)key, size);
        if (choice == 'e')
            AesEncrypt(&aes, key, size, inFile, outFile);
        else if (choice == 'd')
            AesDecrypt(&aes, key, size, inFile, outFile);
    }
    else if (choice == 'n') {
        printf("Must select either -e or -d for encryption and decryption\n");
        ret = -110;
    }

    return ret;
}
void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno,  uint8_t *datain){

	int len = 0;
	//uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
	uint8_t PICC_MASTER_KEY16[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
	uint8_t null_key_data8[8] = {0x00};
	//uint8_t null_key_data16[16] = {0x00};	
	//uint8_t new_key_data8[8]  = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
	//uint8_t new_key_data16[16]  = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};

	uint8_t resp[256] = {0x00};
	uint8_t IV[16] = {0x00};

	size_t datalen = datain[0];
	
	uint8_t cmd[40] = {0x00};
	uint8_t encRndB[16] = {0x00};
	uint8_t decRndB[16] = {0x00};
	uint8_t nonce[16] = {0x00};
	uint8_t both[32] = {0x00};
	uint8_t encBoth[32] = {0x00};

	InitDesfireCard();
	
	LED_A_ON();
	LED_B_OFF();
	LED_C_OFF();
	
	// 3 olika sätt att authenticera.   AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
	// 4 olika crypto algo   DES, 3DES, 3K3DES, AES
	// 3 olika kommunikations sätt,   PLAIN,MAC,CRYPTO
	
	// des, nyckel 0, 
	switch (mode){
        case 1:{
            uint8_t keybytes[16];
            uint8_t RndA[8] = {0x00};
            uint8_t RndB[8] = {0x00};
            
            if (algo == 2) {
            if (datain[1] == 0xff){
                    memcpy(keybytes,PICC_MASTER_KEY16,16);
                } else {
                    memcpy(keybytes, datain+1, datalen);
                }
            } else {
                if (algo == 1) {
                    if (datain[1] == 0xff){
                memcpy(keybytes,null_key_data8,8);
            } else{
                memcpy(keybytes, datain+1, datalen);
            }
                }
            }
            
            struct desfire_key defaultkey = {0};
            desfirekey_t key = &defaultkey;
            
            if (algo == 2)
                Desfire_3des_key_new_with_version(keybytes, key);
            else if (algo ==1)
            Desfire_des_key_new(keybytes, key);
            
            cmd[0] = AUTHENTICATE;
            cmd[1] = keyno;  //keynumber
            len = DesfireAPDU(cmd, 2, resp);
            if ( !len ) {
                if (MF_DBGLEVEL >= MF_DBG_ERROR) {
                    DbpString("Authentication failed. Card timeout.");
                }
                OnError(3);
                return;
            }
            
            if ( resp[2] == 0xaf ){
            } else {
                DbpString("Authetication failed. Invalid key number.");
                OnError(3);
                return;
            }
            
            memcpy( encRndB, resp+3, 8);
            if (algo == 2)
                tdes_dec(&decRndB, &encRndB, key->data);
            else if (algo == 1)
            des_dec(&decRndB, &encRndB, key->data);
            
            memcpy(RndB, decRndB, 8);
            rol(decRndB,8);
            
            // This should be random
            uint8_t decRndA[8] = {0x00};
            memcpy(RndA, decRndA, 8);
            uint8_t encRndA[8] = {0x00};
            
            if (algo == 2)
                tdes_dec(&encRndA, &decRndA, key->data);
            else if (algo == 1)
            des_dec(&encRndA, &decRndA, key->data);
            
            memcpy(both, encRndA, 8);
            
            for (int x = 0; x < 8; x++) {
                decRndB[x] = decRndB[x] ^ encRndA[x];
                
            }
            
            if (algo == 2)
                tdes_dec(&encRndB, &decRndB, key->data);
            else if (algo == 1)
            des_dec(&encRndB, &decRndB, key->data);
            
            memcpy(both + 8, encRndB, 8);
            
            cmd[0] = ADDITIONAL_FRAME;
            memcpy(cmd+1, both, 16 );
            
            len = DesfireAPDU(cmd, 17, resp);
            if ( !len ) {
                if (MF_DBGLEVEL >= MF_DBG_ERROR) {
                    DbpString("Authentication failed. Card timeout.");
                }
                OnError(3);
                return;
            }
            
            if ( resp[2] == 0x00 ){
                
                struct desfire_key sessionKey = {0};
                desfirekey_t skey = &sessionKey;
                Desfire_session_key_new( RndA, RndB , key, skey );
                //print_result("SESSION : ", skey->data, 8);
                
                memcpy(encRndA, resp+3, 8);
                
                if (algo == 2)
                    tdes_dec(&encRndA, &encRndA, key->data);
                else if (algo == 1)
                des_dec(&encRndA, &encRndA, key->data);
                
                rol(decRndA,8);
                for (int x = 0; x < 8; x++) {
                    if (decRndA[x] != encRndA[x]) {
                        DbpString("Authetication failed. Cannot varify PICC.");
                        OnError(4);
                        return;
                    }
                }
                
                //Change the selected key to a new value.
                /*
                 
                 // Current key is a 3DES key, change it to a DES key
                 if (algo == 2) {
                cmd[0] = CHANGE_KEY;
                cmd[1] = keyno;
                
                uint8_t newKey[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
                
                uint8_t first, second;
                uint8_t buff1[8] = {0x00};
                uint8_t buff2[8] = {0x00};
                uint8_t buff3[8] = {0x00};
                
                memcpy(buff1,newKey, 8);
                memcpy(buff2,newKey + 8, 8);
                
                ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second);
                memcpy(buff3, &first, 1);
                memcpy(buff3 + 1, &second, 1);
                
                 tdes_dec(&buff1, &buff1, skey->data);
                 memcpy(cmd+2,buff1,8);
                 
                 for (int x = 0; x < 8; x++) {
                 buff2[x] = buff2[x] ^ buff1[x];
                 }
                 tdes_dec(&buff2, &buff2, skey->data);
                 memcpy(cmd+10,buff2,8);
                 
                 for (int x = 0; x < 8; x++) {
                 buff3[x] = buff3[x] ^ buff2[x];
                 }
                 tdes_dec(&buff3, &buff3, skey->data);
                 memcpy(cmd+18,buff3,8);
                 
                 // The command always times out on the first attempt, this will retry until a response
                 // is recieved.
                 len = 0;
                 while(!len) {
                 len = DesfireAPDU(cmd,26,resp);
                 }
                 
                 } else {
                    // Current key is a DES key, change it to a 3DES key
                    if (algo == 1) {
                        cmd[0] = CHANGE_KEY;
                        cmd[1] = keyno;
                        
                        uint8_t newKey[16] = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
                        
                        uint8_t first, second;
                        uint8_t buff1[8] = {0x00};
                        uint8_t buff2[8] = {0x00};
                        uint8_t buff3[8] = {0x00};
                        
                        memcpy(buff1,newKey, 8);
                        memcpy(buff2,newKey + 8, 8);
                        
                        ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second);
                        memcpy(buff3, &first, 1);
                        memcpy(buff3 + 1, &second, 1);
                        
                des_dec(&buff1, &buff1, skey->data);
                memcpy(cmd+2,buff1,8);
                
                for (int x = 0; x < 8; x++) {
                    buff2[x] = buff2[x] ^ buff1[x];
                }
                des_dec(&buff2, &buff2, skey->data);
                memcpy(cmd+10,buff2,8);
                
                for (int x = 0; x < 8; x++) {
                    buff3[x] = buff3[x] ^ buff2[x];
                }
                des_dec(&buff3, &buff3, skey->data);
                memcpy(cmd+18,buff3,8);
                
                // The command always times out on the first attempt, this will retry until a response
                // is recieved.
                len = 0;
                while(!len) {
                    len = DesfireAPDU(cmd,26,resp);
                }
                    }
                 }
                */
                
                OnSuccess();
                if (algo == 2)
                    cmd_send(CMD_ACK,1,0,0,skey->data,16);
                else if (algo == 1)
                cmd_send(CMD_ACK,1,0,0,skey->data,8);
            } else {
                DbpString("Authetication failed.");
                OnError(6);
                return;
            }
            }
			break;
		case 2:
			//SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
			break;
		case 3:{
		
			//defaultkey
			uint8_t keybytes[16] = {0x00};
			if (datain[1] == 0xff){
				memcpy(keybytes,PICC_MASTER_KEY16,16); 
			} else{
				memcpy(keybytes, datain+1, datalen);
			}
			
			struct desfire_key defaultkey = {0x00};
			desfirekey_t key = &defaultkey;
			Desfire_aes_key_new( keybytes, key);
		
			AesCtx ctx;
			if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){
				if( MF_DBGLEVEL >= 4) {
					Dbprintf("AES context failed to init");
				}
				OnError(7);
				return;
			}
			
			cmd[0] = AUTHENTICATE_AES;
			cmd[1] = 0x00;  //keynumber
			len = DesfireAPDU(cmd, 2, resp);
			if ( !len ) {
				if (MF_DBGLEVEL >= MF_DBG_ERROR) {
					DbpString("Authentication failed. Card timeout.");
				}
				OnError(3);
				return;
			}
			
			memcpy( encRndB, resp+3, 16);
		
			// dekryptera tagnonce.
			AesDecrypt(&ctx, encRndB, decRndB, 16);
			rol(decRndB,16);
			memcpy(both, nonce,16);
			memcpy(both+16, decRndB ,16 );
			AesEncrypt(&ctx, both, encBoth, 32 );
			
			cmd[0] = ADDITIONAL_FRAME;
			memcpy(cmd+1, encBoth, 32 );
			
			len = DesfireAPDU(cmd, 33, resp);  // 1 + 32 == 33
			if ( !len ) {
				if (MF_DBGLEVEL >= MF_DBG_ERROR) {
					DbpString("Authentication failed. Card timeout.");
				}
                OnError(3);
				return;
			}
			
			if ( resp[2] == 0x00 ){
				// Create AES Session key		
				struct desfire_key sessionKey = {0};
				desfirekey_t skey = &sessionKey;
				Desfire_session_key_new( nonce, decRndB , key, skey );
				print_result("SESSION : ", skey->data, 16);
			} else {
				DbpString("Authetication failed.");
				OnError(7);
				return;
			}
			
			break;
		}	
	}
	
	OnSuccess();
	cmd_send(CMD_ACK,1,len,0,resp,len);
}
示例#5
0
文件: wad.cpp 项目: Swyter/wiiqt
Wad::Wad( const QByteArray &stuff )
{
	ok = false;
	if( !stuff.size() )//prevent error text when it isnt required
		return;
	if( stuff.size() < 0x80 )//less than this and there is definitely nothing there
	{
		Err( "Size is < 0x80" );
		return;
	}

	QByteArray copy = stuff;
	QBuffer b( &copy );
	b.open( QIODevice::ReadOnly );

	quint32 tmp;
	if(b.read( (char*)&tmp, 4 ) != 4)
	{
		b.close();
		Err( "Can't read header size" );
		return;
	}
	if( qFromBigEndian( tmp ) != 0x20 )
	{
		b.close();
		hexdump(stuff, 0, 0x10);
		Err( "Bad header size" );
		return;
	}
	b.read( (char*)&tmp, 4 );
	tmp = qFromBigEndian( tmp );
	if( tmp != 0x49730000 &&
		tmp != 0x69620000 &&
		tmp != 0x426b0000 )
	{
		b.close();
		hexdump( stuff, 0, 0x40 );
		Err( "Bad file magic word" );
		return;
	}

	quint32 certSize;
	quint32 tikSize;
	quint32 tmdSize;
	quint32 appSize;
	quint32 footerSize;

	b.read( (char*)&certSize, 4 );
	certSize = qFromBigEndian( certSize );

	b.seek( 0x10 );
	b.read( (char*)&tikSize, 4 );
	tikSize = qFromBigEndian( tikSize );
	b.read( (char*)&tmdSize, 4 );
	tmdSize = qFromBigEndian( tmdSize );
	b.read( (char*)&appSize, 4 );
	appSize = qFromBigEndian( appSize );
	b.read( (char*)&footerSize, 4 );
	footerSize = qFromBigEndian( footerSize );

	b.close();//close the buffer, the rest of the data can be checked without it

	//sanity check this thing
	quint32 s = stuff.size();
	if( s < ( RU( certSize, 0x40 ) + RU( tikSize, 0x40 ) + RU( tmdSize, 0x40 ) + RU( appSize, 0x40 ) + RU( footerSize, 0x40 ) ) )
	{
		Err( "Total size is less than the combined sizes of all the parts that it is supposed to contain" );
		return;
	}

	quint32 pos = 0x40;
	certData = stuff.mid( pos, certSize );
	pos += RU( certSize, 0x4 );
	tikData = stuff.mid( pos, tikSize );
	pos += RU( tikSize, 0x40 );
	tmdData = stuff.mid( pos, tmdSize );
	pos += RU( tmdSize, 0x40 );

	Ticket ticket( tikData );
	Tmd t( tmdData );

	//the constructor for Ticket may have fixed a bad key index.  replace the data just incase it did
	tikData = ticket.Data();

	//hexdump( tikData );
	//hexdump( tmdData );

	if( ticket.Tid() != t.Tid() )
		qWarning() << "wad contains 2 different TIDs";

	quint32 cnt = t.Count();
	//qDebug() << "Wad contains" << hex << cnt << "contents";

	//another quick sanity check
	quint32 totalSize = 0;
	for( quint32 i = 0; i < cnt; i++ )
		totalSize += t.Size( i );

	if( totalSize > appSize )
	{
		Err( "Size of all the apps in the tmd is greater than the size in the wad header" );
		return;
	}
	//read all the contents, check the hash, and remember the data ( still encrypted )
	for( quint32 i = 0; i < cnt; i++ )
	{

		quint32 s = RU( t.Size( i ), 0x40 );
		//qDebug() << "content" << i << "is at" << hex << pos
		//        << "with size" << s;
		QByteArray encData = stuff.mid( pos, s );
		pos += s;

		//doing this here in case there is some other object that
		//is using the AES that would change the key on us
		AesSetKey( ticket.DecryptedKey() );

		QByteArray decData = AesDecrypt( t.Index( i ), encData );
		decData.resize( t.Size( i ) );
		QByteArray realHash = GetSha1( decData );
		if( realHash != t.Hash( i ) )
		{
			Err( QString( "hash doesnt match for content %1" ).arg( i ) );
		}
		partsEnc << encData;
	}
	//wtf?  some VC titles have a full banner as the footer?  maybe somebody's wad packer is busted
	//QByteArray footer = stuff.mid( pos, stuff.size() - pos );
	//qDebug() << "footer";
	//hexdump( footer );
	ok = true;
}