<div dir="ltr">There is no such thing as a scramble table. The way DJI actually generates these keys is to use the appropriate bytes (as mentioned above) to calculate a 64 bit CRC for the specific packet. This is the same general process you use to _select_ the right row in your scramble table, except, the CRC64 algorithm takes the same input and returns the actual key without using a specific tabular lookup. <div><br></div><div>Here is a quick write-up I did on the reverse engineering from the DJI Go application where this encryption method is implemented. The above is a working PoC (minus a few bits, since I haven't actually fully finished my parser), this simply covers how I got there. </div><div><br></div><div><pre style="color:rgb(0,0,0);white-space:pre-wrap">## Scrambling Process
The scrambling process is handled in the library `FRCorkscrew.so`. Within this library, there are two functions of interest with respect to the record scrambling, these are named `decryptFRData` and `encryptFRData`. From the open source documentation, we can glean that each record is encrypted with an 8-byte XOR key that is repeated over the length of the record. Looking at the `decryptFRData` function first, and reviewing some of the Java code that calls the library, the following line appears to do the decryption: `decryptData(decryptedBuf, encryptedBuf, encryptedBufLen, a6, a7);`. Notice the last two arguments are unknown at this stage, looking into the `decryptData` function a bit may give some insight.
```c
signed int decryptData(char *decBuf, char *encBuf, int bufLen, int messageId, __int64 a5)
{
  unsigned int firstPacketByte; // r7
  int crcSeed; // r9
  int v10; // ST10_4
  _QWORD *keyBuffer; // r8
  char *v12; // r5
  int v13; // r6

  if ( check != 1 )
    return -1;
  if ( a5 )
    return 0;
  firstPacketByte = *encBuf; //Dereference first byte in encrypted data, store in local variable
  crcSeed = messageId + firstPacketByte; //Based on the open source info, the fourth argument is likely the message id here.
  v10 = encBuf[bufLen - 1];
  keyBuffer = malloc(bufLen - 1); //Initialize space for the generated key.
  v12 = malloc(bufLen - 1); //Create temporary local variable for storing the decrypted data
  /**
   * Calls the key generation function, of note, the last two arguments.
   */
  getKey(keyBuffer, (bufLen - 1), crcSeed, 0x123456789ABCDEF0LL * firstPacketByte);
  v13 = bufLen - 2;
  /**
   * Decrypts the buffer. Of note, the second argument which skips the first byte in the encrypted buffer.
   */
  doXor(v12, (encBuf + 1), keyBuffer, v10, v13, v13 >> 31, v10);
  memcpy(decBuf, v12, bufLen - 2); //Move result to the return buffer
  if ( (unsigned __int8)v12[bufLen - 2] != crcSeed ) //Verifies the last byte buffer matches the seed (a basic validity check)
    v13 = 0;
  if ( keyBuffer )
    free(keyBuffer);
  free(v12);
  return v13;
}
```

Many lines have been renamed above but, the general idea is that there is a generation function for the key and then the XOR decryption process. Before we dig deeply into exactly what's happening, let's look at the `getKey` function.

```c
int getKey(char *keyBuffer, unsigned int keyLength, unsigned __int8 crcSeed, __int64 a4)
{
  signed int v6; // r10
  __int64 crcValue; // r0 MAPDST
  signed int v9; // r6

  v6 = keyLength >> 3;
  crcValue = crc64(crcSeed, (char *)&a4, _stack_chk_guard, 8);
  v9 = 0;
  /**
   * Extra code omitted, following the above, the CRC result value is used to generate a key the length of the packet.
   */
}
```
As this shows, the key generation is really a CRC64 function. The initial CRC value is set to the first byte in the encrypted buffer plus the message id. And the data for which the CRC is calculated is the result of `0x123456789ABCDEF0 * first_byte`. This is essentially the encryption/scrambling method. As seen in the actual record structure below, the packet before encryption looks like:
```
00 00 00 00 00 00 00 FF
ID LN PS [ data ] CK TM

ID: Packet Type ID
LN: Packet data length (data + PS byte + CK byte), for above it is 5.
PS: Pseudo-random generated number to seed encryption
data: The actual record information
CK: The ID+PS bytes to verify proper decryption
TM: Terminator byte, always 0xFF
```
If the above empty data were encrypted (assuming a key of `\x01\x02\x03\x04`, not actually generated with the CRC algorithm), it would look like the following:
```
00 00 00 01 02 03 04 FF
```</pre></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Jan 18, 2020 at 10:18 PM Ross Finlayson <<a href="mailto:finlayson@live555.com">finlayson@live555.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
> On Jan 18, 2020, at 7:45 PM, Daniel Flack <<a href="mailto:dflack95@gmail.com" target="_blank">dflack95@gmail.com</a>> wrote:<br>
> <br>
> Ross;<br>
> <br>
> Finished this up a while ago, thought the website was updated...the email today reminded me. It looks like the scramble table is still the setup you're documenting on the website. I've attached general PoC code for how to derive the scramble keys (using a CRC 64).<br>
<br>
I’m sorry.  How, specifically, does this generate the values of the ‘scramble table’: the data that’s in<br>
        <a href="http://djilogs.live555.com/doxygen/html/scrambleTable_8cpp_source.html" rel="noreferrer" target="_blank">http://djilogs.live555.com/doxygen/html/scrambleTable_8cpp_source.html</a><br>
?  And how could this generate more rows than the 0x1000 (i.e., 4096) rows that we already know?<br>
<br>
<br>
Ross Finlayson<br>
Live Networks, Inc.<br>
<a href="http://www.live555.com/" rel="noreferrer" target="_blank">http://www.live555.com/</a><br>
<br>
<br>
-- <br>
DJI-log-discuss mailing list<br>
<a href="mailto:DJI-log-discuss@lists.live555.com" target="_blank">DJI-log-discuss@lists.live555.com</a><br>
<a href="http://ns.live555.com/mailman/listinfo/dji-log-discuss" rel="noreferrer" target="_blank">http://ns.live555.com/mailman/listinfo/dji-log-discuss</a><br>
</blockquote></div>