// // Method name : Initialize // Description : This function chews over the input strings and tries to // interpret it as a method signature. If it is successful, then // this value is set appropriately and 'true' is returned. If // not, then this value becomes invalid and a false value is given. // bool CJavaMethodSignature::Initialize(const unicode_string& methodName, const unicode_string& signatureString) { fMethodName = methodName; unicode_string::const_iterator stringPointer = signatureString.begin(); unicode_string::const_iterator stringEnd = signatureString.end(); bool result = stringPointer < stringEnd && *stringPointer++ == '('; if (result) { fArgumentTypes.erase(fArgumentTypes.begin(), fArgumentTypes.end()); while (stringPointer < stringEnd && *stringPointer != ')') { CJavaTypeSignature argument; bool valid = argument.ParseSignatureString(stringPointer, stringEnd); if (valid) { fArgumentTypes.push_back(argument); } else { result = false; break; } } result = result && *stringPointer++ == ')' && stringPointer < stringEnd; if (result) { result = fReturnType.ParseSignatureString(stringPointer, stringEnd); } } SetHashKey(); return result; }
// // Method name : CJavaMethodSignature // Description : Constructs a method signature out of a the constituent // parts. // CJavaMethodSignature::CJavaMethodSignature( const CJavaTypeSignature& returnType, const unicode_string& name, const deque<CJavaTypeSignature>& argumentTypes) : fMethodName(name), fArgumentTypes(argumentTypes), fReturnType(returnType) { SetHashKey(); }
void cSystemViaccess::ProcessEMM(int pid, int caid, const unsigned char *data) { for(cViaccessCardInfo *mkey=Vcards.First(); mkey; mkey=Vcards.Next(mkey)) { int updtype; cAssembleData ad(data); if(mkey->cCardViaccess::MatchEMM(data)) { updtype=3; HashClear(); memcpy(hbuff+3,mkey->ua,sizeof(mkey->ua)); } else if(mkey->cProviderViaccess::MatchEMM(data)) { if(mkey->cProviderViaccess::Assemble(&ad)<0) continue; updtype=2; HashClear(); memcpy(hbuff+5,mkey->sa,sizeof(mkey->sa)-1); } else continue; const unsigned char *buff; if((buff=ad.Assembled())) { const unsigned char *scan=cParseViaccess::NanoStart(buff); unsigned int scanlen=SCT_LEN(buff)-(scan-buff); if(scanlen>=5 && mkey->cProviderViaccess::MatchID(buff) && cParseViaccess::KeyNrFromNano(scan)==mkey->keyno) { scan+=5; scanlen-=5; SetHashKey(mkey->key); Hash(); unsigned int n; if(scan[0]==0x9e && scanlen>=(n=scan[1]+2)) { for(unsigned int i=0; i<n; i++) HashByte(scan[i]); Hash(); pH=0; scan+=n; scanlen-=5; } if(scanlen>0) { unsigned char newKey[MAX_NEW_KEYS][8]; int numKeys=0, updPrv[MAX_NEW_KEYS]={}, updKey[MAX_NEW_KEYS]={}; for(unsigned int cnt=0; cnt<scanlen && numKeys<MAX_NEW_KEYS;) { const unsigned int parm=scan[cnt++]; unsigned int plen=scan[cnt++]; switch(parm) { case 0x90: case 0x9E: cnt+=plen; break; case 0xA1: // keyupdate updPrv[numKeys]=(scan[cnt]<<16)+(scan[cnt+1]<<8)+(scan[cnt+2]&0xF0); updKey[numKeys]=scan[cnt+2]&0x0F; // fall through default: HashByte(parm); HashByte(plen); while(plen--) HashByte(scan[cnt++]); break; case 0xEF: // crypted key(s) HashByte(parm); HashByte(plen); if(plen==sizeof(newKey[0])) { const unsigned char k7=mkey->key[7]; for(unsigned int kc=0 ; kc<sizeof(newKey[0]) ; kc++) { const unsigned char b=scan[cnt++]; if(k7&1) newKey[numKeys][kc]=b^(hbuff[pH]&(k7<0x10 ? 0x5a : 0xa5)); else newKey[numKeys][kc]=b; HashByte(b); } numKeys++; } else { PRINTF(L_SYS_EMM,"key length mismatch %d!=%d",plen,(int)sizeof(newKey[0])); cnt=scanlen; } break; case 0xF0: // signature { char str[20], str2[20]; static const char *ptext[] = { 0,0,"SHARED","UNIQUE" }; const char *addr = (updtype==2) ? HexStr(str,mkey->sa,sizeof(mkey->sa)) : HexStr(str,mkey->ua,sizeof(mkey->ua)); Hash(); if(!memcmp(&scan[cnt],hbuff,sizeof(hbuff))) { unsigned char key[8]; memcpy(key,mkey->key,sizeof(key)); if(key[7]) { // Rotate key const unsigned char t1=key[0], t2=key[1]; key[0]=key[2]; key[1]=key[3]; key[2]=key[4]; key[3]=key[5]; key[4]=key[6]; key[5]=t1; key[6]=t2; } while(numKeys--) { Decode(newKey[numKeys],key); PRINTF(L_SYS_EMM,"%02X%02X %02X %s %s - KEY %06X.%02X -> %s", mkey->ident[0],mkey->ident[1],mkey->keyno,addr, ptext[updtype],updPrv[numKeys],updKey[numKeys], HexStr(str2,newKey[numKeys],sizeof(newKey[numKeys]))); FoundKey(); if(keys.NewKey('V',updPrv[numKeys],updKey[numKeys],newKey[numKeys],8)) NewKey(); } } else PRINTF(L_SYS_EMM,"%02X%02X %02X %s %s - FAIL",mkey->ident[0],mkey->ident[1],mkey->keyno,addr,ptext[updtype]); cnt=scanlen; break; } } } } } } } }
bool cViaccess::Decrypt(const unsigned char *work_key, const unsigned char *data, int len, unsigned char *des_data1, unsigned char *des_data2) { int pos=0, encStart=0; unsigned char signatur[8]; while(pos<len) { switch(data[pos]) { case 0xea: // encrypted bytes encStart = pos + 2; memcpy(des_data1,&data[pos+2],8); memcpy(des_data2,&data[pos+2+8],8); break; case 0xf0: // signature memcpy(signatur,&data[pos+2],8); break; } pos += data[pos+1]+2; } HashClear(); SetHashKey(work_key); // key preparation unsigned char prepared_key[8]; if(work_key[7]==0) { // 8th key-byte = 0 then like Eurocrypt-M but with viaccess mods HashNanos(data,encStart+16); memcpy(prepared_key,work_key,sizeof(prepared_key)); } else { // key8 not zero // rotate the key 2x left prepared_key[0]=work_key[2]; prepared_key[1]=work_key[3]; prepared_key[2]=work_key[4]; prepared_key[3]=work_key[5]; prepared_key[4]=work_key[6]; prepared_key[5]=work_key[0]; prepared_key[6]=work_key[1]; prepared_key[7]=work_key[7]; // test if key8 odd if(work_key[7]&1) { HashNanos(data,encStart); // test if low nibble zero unsigned char k = ((work_key[7] & 0xf0) == 0) ? 0x5a : 0xa5; for(int i=0; i<8; i++) { unsigned char tmp=des_data1[i]; des_data1[i]=(k & hbuff[pH]) ^ tmp; HashByte(tmp); } for(int i=0; i<8; i++) { unsigned char tmp=des_data2[i]; des_data2[i]=(k & hbuff[pH]) ^ tmp; HashByte(tmp); } } else { HashNanos(data,encStart+16); } } Decode(des_data1,prepared_key); Decode(des_data2,prepared_key); Hash(); return (memcmp(signatur,hbuff,8)==0); }