Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
5.3 KiB

  1. #include "drmkPCH.h"
  2. #include "CryptoHelpers.h"
  3. #include "KList.h"
  4. #include "../DRMKMain/StreamMgr.h"
  5. #include "AudioDescrambler.h"
  6. //------------------------------------------------------------------------------
  7. // When doing noise addition, we only decryptt the low bits. These constants define
  8. // the number of bits encrypted.
  9. // If you change this, change the contants in DRMKMain, too.
  10. WORD mask16=(WORD) 0x3FFF;
  11. char mask8=(char) 0x7F;
  12. //------------------------------------------------------------------------------
  13. DRM_STATUS DescrambleBlock(WAVEFORMATEX* Wfx, DWORD StreamId,
  14. BYTE* Dest, DWORD DestSize, DWORD* DestUsed,
  15. BYTE* Src, DWORD SrcSize, DWORD* SrcUsed,
  16. BOOL InitKey, STREAMKEY* streamKey,
  17. DWORD FrameSize){
  18. if(StreamId==0){
  19. // StreamId==0 is a dummy debugging stream that is unencrypted
  20. DWORD NumBytes=min(SrcSize, DestSize);
  21. memcpy(Dest, Src, NumBytes);
  22. *SrcUsed=NumBytes;
  23. *DestUsed=NumBytes;
  24. return DRM_OK;
  25. };
  26. *SrcUsed=0;
  27. *DestUsed=0;
  28. DWORD blockLen=min(SrcSize, DestSize);
  29. blockLen=blockLen/FrameSize*FrameSize;
  30. if(blockLen==0){
  31. _DbgPrintF(DEBUGLVL_VERBOSE,("Not enough data"));
  32. return DRM_DATALENGTH;
  33. };
  34. static bool firstTime=true;
  35. if(firstTime){
  36. _DbgPrintF(DEBUGLVL_VERBOSE,("Descramble: streamId=%d, isPCM=%d, (bits=%d, mono=%d), FrameSize=%d\n",
  37. StreamId, Wfx->wFormatTag, (int) Wfx->wBitsPerSample, (int) Wfx->nChannels, FrameSize));
  38. firstTime=false;
  39. };
  40. if(InitKey){
  41. if(TheStreamMgr!=NULL){
  42. STREAMKEY* theStreamKey;
  43. DRM_STATUS stat=TheStreamMgr->getKey(StreamId, theStreamKey);
  44. // note, we keep a local copy. If you call an encryption fucntion on this
  45. // key, state in streamManager will NOT be updated.
  46. if(stat!=KRM_OK){
  47. _DbgPrintF(DEBUGLVL_VERBOSE,("Can't get key for stream: %x", StreamId));
  48. return stat;
  49. };
  50. *streamKey= *theStreamKey;
  51. } else {
  52. _DbgPrintF(DEBUGLVL_VERBOSE,("TheStreamMgr not initted"));
  53. return KRM_SYSERR;
  54. };
  55. };
  56. DWORD bitsPerSample=Wfx->wBitsPerSample;
  57. DWORD numChannels=Wfx->nChannels;
  58. bool isPcm=(Wfx->wFormatTag==WAVE_FORMAT_PCM);
  59. // for non-pcm, we scramble al but the msb in each byte.
  60. DWORD effectiveBitsPerSample=bitsPerSample;
  61. if(!isPcm)effectiveBitsPerSample=8;
  62. // We deal with data in FrameSize lumps
  63. DWORD numLumps=blockLen/FrameSize;
  64. for(DWORD k=0;k<numLumps;k++){
  65. BYTE* inData=Src+k*FrameSize;
  66. BYTE* outData=Dest+k*FrameSize;
  67. memcpy(outData, inData, FrameSize);
  68. // If the frame is all zeros, pass it unscrambled (the audio system inserts
  69. // blank frames. These will not necessarily have been scrambled. we take
  70. // a frame of zeros as a special case and do not unscramble).
  71. DWORD* inBuffer=reinterpret_cast<DWORD*> (inData);
  72. DWORD numDwordsPerFrame=FrameSize/4;
  73. bool isBlankFrame=true;
  74. for(DWORD kk=0;kk<numDwordsPerFrame;kk++){
  75. if(inBuffer[kk]!=0){
  76. isBlankFrame=false;
  77. break;
  78. };
  79. };
  80. if(isBlankFrame){
  81. _DbgPrintF(DEBUGLVL_VERBOSE,("Blank buffer"));
  82. continue;
  83. };
  84. // we seed the packet sample key with some MSBs from the data stream
  85. // (these are not encrypted). We take bits from the first 64 samples.
  86. // We could tune this for speed/security.
  87. int samplesForSeed=64;
  88. __int64 seed=0;
  89. if(effectiveBitsPerSample==8){
  90. // grab MSBs
  91. for(int j=0;j<samplesForSeed; j++){
  92. BYTE c=inData[j] & ~mask8;
  93. c >>= 7;
  94. seed = (seed << 1) + c;
  95. };
  96. } else {
  97. for(int j=0;j<samplesForSeed; j++){
  98. WORD& w= (WORD&) *((WORD*) &inData[j*2]);
  99. WORD m=w & ~mask16;
  100. m >>= 14;
  101. seed = (seed << 1) + m;
  102. };
  103. };
  104. // MAC the seed using the main stream key. Generate the packet key from the mac.
  105. // (user mode performs identical operations to generate the scrmabling key)
  106. CBCKey macKey;
  107. CBCState macState;
  108. DRM_STATUS stat=CryptoHelpers::InitMac(macKey, macState, (BYTE*) streamKey, sizeof(STREAMKEY));
  109. DRMDIGEST mac;
  110. stat=CryptoHelpers::Mac(macKey, (BYTE*) &seed, sizeof(seed), mac);
  111. STREAMKEY packetKey;
  112. bv4_key_C(&packetKey, sizeof(mac),(BYTE*) &mac);
  113. // If there has been a fatal error (usually out-of-memory somewhere)
  114. // we do not descramble (an alternative would be to return silence).
  115. if(TheStreamMgr->getFatalError()==DRM_OK){
  116. // We have already copied the inBlock to the outBlock, now we can decrypt it
  117. CryptoHelpers::Xcrypt(packetKey, outData, FrameSize);
  118. // We know about noise addition on 8 and 16 bit PCM audio. Other
  119. // audio formats get treated like 8 bit audio.
  120. DWORD numSamples=FrameSize/(effectiveBitsPerSample/8);
  121. if(effectiveBitsPerSample==16){
  122. WORD* in=(WORD*) inData;
  123. WORD* out=(WORD*) outData;
  124. for(DWORD j=0;j<numSamples;j++){
  125. out[j]=(out[j] & mask16) | (in[j] & ~mask16);
  126. };
  127. }
  128. if(effectiveBitsPerSample==8){
  129. char* in=(char*) inData;
  130. char* out=(char*) outData;
  131. for(DWORD j=0;j<numSamples;j++){
  132. out[j]=(out[j] & mask8) | (in[j] & ~mask8);
  133. };
  134. };
  135. };
  136. }; // of loop over blocks
  137. *SrcUsed=blockLen;
  138. *DestUsed=blockLen;
  139. return DRM_OK;
  140. };
  141. //------------------------------------------------------------------------------