Beispiel #1
0
/*!
 Decrypts cleartext data using EAX' mode (see ANSI Standard C12.22-2008).

 @param[in]	pN	pointer to cleartext (canonified form)
 @param[in]	pK	pointer to secret key
 @param[in,out] pC	pointer to ciphertext
 @param[in]	SizeN	byte length of cleartext (pN) buffer
 @param[in]	SizeK	byte length of secret key (pK) 
 @param[in]	SizeC	byte length of ciphertext (pC) buffer
 @param[in]	pMac	four-byte Message Authentication Code
 @param[in]	Mode	EAX_MODE_CLEARTEXT_AUTH or EAX_MODE_CIPHERTEXT_AUTH
 @return		TRUE if message has been authenticated; FALSE if not 
			authenticated, invalid Mode or error
 */
gboolean Eax_Decrypt(guint8 *pN, guint8 *pK, guint8 *pC, 
                 guint32 SizeN, guint32 SizeK, guint32 SizeC, MAC_T *pMac, 
		 guint8 Mode)
{
    guint8 wsn[EAX_SIZEOF_KEY];
    guint8 wsc[EAX_SIZEOF_KEY];
    int i;
    
    /* key size must match this implementation */
    if (SizeK != EAX_SIZEOF_KEY)
	return FALSE;

    /* the key is new */
    for (i = 0; i < EAX_SIZEOF_KEY; i++)
	instance.L[i] = 0;
    AesEncrypt(instance.L, pK);
    Dbl(instance.D, instance.L);
    Dbl(instance.Q, instance.D);
    /* the key is set up */
    /* first copy the nonce into our working space */
    BLK_CPY(wsn, instance.D);
    if (Mode == EAX_MODE_CLEARTEXT_AUTH) {
	dCMAC(pK, wsn, pN, SizeN, pC, SizeC);
    } else {
	CMAC(pK, wsn, pN, SizeN);
    }
    /* 
     *  In authentication mode the inputs are: pN, pK (and associated sizes), 
     *	the result is the 4 byte MAC.
     */
    if (Mode == EAX_MODE_CLEARTEXT_AUTH)
    {
        return (memcmp(pMac, &wsn[EAX_SIZEOF_KEY-sizeof(*pMac)], sizeof(*pMac)) ? FALSE : TRUE);
    
    }

    /* 
     * In cipher mode the inputs are: pN, pK, pP (and associated sizes), 
     * the results are pC (and its size) along with the 4 byte MAC.
     */
    else if (Mode == EAX_MODE_CIPHERTEXT_AUTH)
    {
	    if (SizeC == 0)
            return (memcmp(pMac, &wsn[EAX_SIZEOF_KEY-sizeof(*pMac)], sizeof(*pMac)) ? FALSE : TRUE);
	    {
	        /* first copy the nonce into our working space */
	        BLK_CPY(wsc, instance.Q);
	        CMAC(pK, wsc, pC, SizeC);
	        BLK_XOR(wsc, wsn);
	    }
	    if (memcmp(pMac, &wsc[EAX_SIZEOF_KEY-sizeof(*pMac)], sizeof(*pMac)) == 0)
	    {
	        CTR(wsn, pK, pC, SizeC);
	        return TRUE;
	    }
    }
    return FALSE;
}
Beispiel #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; 
} 
Beispiel #3
0
Wad::Wad( const QList< QByteArray > &stuff, bool encrypted )
{
	ok = false;
    if( stuff.size() < 3 )
    {
        Err( "Cant treate a wad with < 3 items" );
        return;
    }

    tmdData = stuff.at( 0 );
    tikData = stuff.at( 1 );

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

    quint16 cnt = stuff.size() - 2;
    if( cnt != t.Count() )
    {
        Err( "The number of items given doesnt match the number in the tmd" );
        return;
    }
    for( quint16 i = 0; i < cnt; i++ )
    {
        QByteArray encData;

        if( encrypted )
        {
            encData = stuff.at( i + 2 );
        }
        else
        {
            QByteArray decDataPadded = PaddedByteArray( stuff.at( i + 2 ), 0x40 );
            //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() );
			encData = AesEncrypt( t.Index( i ), decDataPadded );
        }
        partsEnc << encData;
    }
    ok = true;

}
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);
}
void CRandomNumber16Byte::GenerateRandomNumber()
{
	BYTE internalkey[16]= {1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};
	PrepareRandSeed(((DWORD *)RandNumber)+3);
	AesEncrypt(internalkey, RandNumber, RandNumber);
}
Beispiel #7
0
Wad::Wad( QDir dir )
{
	ok = false;
	QFileInfoList tmds = dir.entryInfoList( QStringList() << "*.tmd" << "tmd.*", QDir::Files );
	if( tmds.isEmpty() )
	{
		Err( "TMD not found" );
		return;
	}
	tmdData = ReadFile( tmds.at( 0 ).absoluteFilePath() );
	if( tmdData.isEmpty() )
		return;
	QFileInfoList tiks = dir.entryInfoList( QStringList() << "*.tik" << "cetk", QDir::Files );
	if( tiks.isEmpty() )
	{
		Err( "Ticket not found" );
		return;
	}
	tikData = ReadFile( tiks.at( 0 ).absoluteFilePath() );
	if( tikData.isEmpty() )
		return;

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

	//make sure to only add the tmd & ticket without all the cert mumbo jumbo
	tmdData = t.Data();
	tikData = ticket.Data();
	t = Tmd( tmdData );
	ticket = Ticket( tikData );

	quint16 cnt = t.Count();

	bool tmdChanged = false;
	for( quint16 i = 0; i < cnt; i++ )
	{
		QByteArray appD = ReadFile( dir.absoluteFilePath( t.Cid( i ) + ".app" ) );
		if( appD.isEmpty() )
		{
			Err( t.Cid( i ) + ".app not found" );
			return;
		}

		if( (quint32)appD.size() != t.Size( i ) )
		{
			t.SetSize( i, appD.size() );
			tmdChanged = true;
		}
		QByteArray realHash = GetSha1( appD );
		if( t.Hash( i ) != realHash )
		{
			t.SetHash( i, realHash );
			tmdChanged = true;
		}
		AesSetKey( ticket.DecryptedKey() );
		appD = PaddedByteArray( appD, 0x40 );
		QByteArray encData = AesEncrypt( t.Index( i ), appD );
		partsEnc << encData;
	}
	//if something in the tmd changed, fakesign it
	if( tmdChanged )
	{
		if( !t.FakeSign() )
		{
			Err( "Error signing the wad" );
			return;
		}
		else
		{
			tmdData = t.Data();
		}
	}
	QFileInfoList certs = dir.entryInfoList( QStringList() << "*.cert", QDir::Files );
	if( !certs.isEmpty() )
	{
		certData = ReadFile( certs.at( 0 ).absoluteFilePath() );
	}
	ok = true;
}