#include "drmkPCH.h" #include "CryptoHelpers.h" #include "KList.h" #include "../DRMKMain/StreamMgr.h" #include "AudioDescrambler.h" //------------------------------------------------------------------------------ // When doing noise addition, we only decryptt the low bits. These constants define // the number of bits encrypted. // If you change this, change the contants in DRMKMain, too. WORD mask16=(WORD) 0x3FFF; char mask8=(char) 0x7F; //------------------------------------------------------------------------------ DRM_STATUS DescrambleBlock(WAVEFORMATEX* Wfx, DWORD StreamId, BYTE* Dest, DWORD DestSize, DWORD* DestUsed, BYTE* Src, DWORD SrcSize, DWORD* SrcUsed, BOOL InitKey, STREAMKEY* streamKey, DWORD FrameSize){ if(StreamId==0){ // StreamId==0 is a dummy debugging stream that is unencrypted DWORD NumBytes=min(SrcSize, DestSize); memcpy(Dest, Src, NumBytes); *SrcUsed=NumBytes; *DestUsed=NumBytes; return DRM_OK; }; *SrcUsed=0; *DestUsed=0; DWORD blockLen=min(SrcSize, DestSize); blockLen=blockLen/FrameSize*FrameSize; if(blockLen==0){ _DbgPrintF(DEBUGLVL_VERBOSE,("Not enough data")); return DRM_DATALENGTH; }; static bool firstTime=true; if(firstTime){ _DbgPrintF(DEBUGLVL_VERBOSE,("Descramble: streamId=%d, isPCM=%d, (bits=%d, mono=%d), FrameSize=%d\n", StreamId, Wfx->wFormatTag, (int) Wfx->wBitsPerSample, (int) Wfx->nChannels, FrameSize)); firstTime=false; }; if(InitKey){ if(TheStreamMgr!=NULL){ STREAMKEY* theStreamKey; DRM_STATUS stat=TheStreamMgr->getKey(StreamId, theStreamKey); // note, we keep a local copy. If you call an encryption fucntion on this // key, state in streamManager will NOT be updated. if(stat!=KRM_OK){ _DbgPrintF(DEBUGLVL_VERBOSE,("Can't get key for stream: %x", StreamId)); return stat; }; *streamKey= *theStreamKey; } else { _DbgPrintF(DEBUGLVL_VERBOSE,("TheStreamMgr not initted")); return KRM_SYSERR; }; }; DWORD bitsPerSample=Wfx->wBitsPerSample; DWORD numChannels=Wfx->nChannels; bool isPcm=(Wfx->wFormatTag==WAVE_FORMAT_PCM); // for non-pcm, we scramble al but the msb in each byte. DWORD effectiveBitsPerSample=bitsPerSample; if(!isPcm)effectiveBitsPerSample=8; // We deal with data in FrameSize lumps DWORD numLumps=blockLen/FrameSize; for(DWORD k=0;k (inData); DWORD numDwordsPerFrame=FrameSize/4; bool isBlankFrame=true; for(DWORD kk=0;kk>= 7; seed = (seed << 1) + c; }; } else { for(int j=0;j>= 14; seed = (seed << 1) + m; }; }; // MAC the seed using the main stream key. Generate the packet key from the mac. // (user mode performs identical operations to generate the scrmabling key) CBCKey macKey; CBCState macState; DRM_STATUS stat=CryptoHelpers::InitMac(macKey, macState, (BYTE*) streamKey, sizeof(STREAMKEY)); DRMDIGEST mac; stat=CryptoHelpers::Mac(macKey, (BYTE*) &seed, sizeof(seed), mac); STREAMKEY packetKey; bv4_key_C(&packetKey, sizeof(mac),(BYTE*) &mac); // If there has been a fatal error (usually out-of-memory somewhere) // we do not descramble (an alternative would be to return silence). if(TheStreamMgr->getFatalError()==DRM_OK){ // We have already copied the inBlock to the outBlock, now we can decrypt it CryptoHelpers::Xcrypt(packetKey, outData, FrameSize); // We know about noise addition on 8 and 16 bit PCM audio. Other // audio formats get treated like 8 bit audio. DWORD numSamples=FrameSize/(effectiveBitsPerSample/8); if(effectiveBitsPerSample==16){ WORD* in=(WORD*) inData; WORD* out=(WORD*) outData; for(DWORD j=0;j