Exemple #1
0
 def decrypt(self, content):
     length = len(content)
     extra = length & 0x7
     if extra > 0:
         self.warn("content length not a multiple of block size")
         content += b"\0" * (8 - extra)
     msdes.deskey(self.bookkey, msdes.DE1)
     return msdes.des(content)
Exemple #2
0
 def _build_drm_storage(self):
     drmsource = 'Free as in freedom\0'.encode('utf-16-le')
     self._add_file('/DRMStorage/DRMSource', drmsource)
     tempkey = self._calculate_deskey([self._meta, drmsource])
     msdes.deskey(tempkey, msdes.EN0)
     self._add_file('/DRMStorage/DRMSealed', msdes.des(b"\0" * 16))
     self._bookkey = b'\0' * 8
     self._add_file('/DRMStorage/ValidationStream', b'MSReader', 3)
Exemple #3
0
 def _build_storage(self):
     mapping = [
         (1, 'MSCompressed', (LZXCOMPRESS_GUID, )),
         (2, 'EbEncryptDS', (LZXCOMPRESS_GUID, DESENCRYPT_GUID)),
         (3, 'EbEncryptOnlyDS', (DESENCRYPT_GUID, )),
     ]
     for secnum, name, transforms in mapping:
         root = '::DataSpace/Storage/' + name
         data = self._sections[secnum].getvalue()
         cdata, sdata, tdata, rdata = b'', b'', b'', b''
         for guid in transforms:
             tdata = packguid(guid) + tdata
             sdata = sdata + pack('<Q', len(data))
             if guid == DESENCRYPT_GUID:
                 cdata = MSDES_CONTROL + cdata
                 if not data:
                     continue
                 msdes.deskey(self._bookkey, msdes.EN0)
                 pad = 8 - (len(data) & 0x7)
                 if pad != 8:
                     data = data + (b'\0' * pad)
                 data = msdes.des(data)
             elif guid == LZXCOMPRESS_GUID:
                 cdata = LZXC_CONTROL + cdata
                 if not data:
                     continue
                 unlen = len(data)
                 lzx = Compressor(17)
                 data, rtable = lzx.compress(data, flush=True)
                 rdata = io.BytesIO()
                 rdata.write(
                     pack('<IIIIQQQQ', 3, len(rtable), 8, 0x28, unlen,
                          len(data), 0x8000, 0))
                 for uncomp, comp in rtable[:-1]:
                     rdata.write(pack('<Q', comp))
                 rdata = rdata.getvalue()
         self._add_file(root + '/Content', data)
         self._add_file(root + '/ControlData', cdata)
         self._add_file(root + '/SpanInfo', sdata)
         self._add_file(root + '/Transform/List', tdata)
         troot = root + '/Transform'
         for guid in transforms:
             dname = self._djoin(troot, guid, 'InstanceData')
             self._add_folder(dname)
             if guid == LZXCOMPRESS_GUID:
                 dname += '/ResetTable'
                 self._add_file(dname, rdata)
Exemple #4
0
 def read_drm(self):
     self.drmlevel = 0
     if '/DRMStorage/Licenses/EUL' in self.entries:
         self.drmlevel = 5
     elif '/DRMStorage/DRMBookplate' in self.entries:
         self.drmlevel = 3
     elif '/DRMStorage/DRMSealed' in self.entries:
         self.drmlevel = 1
     else:
         return
     if self.drmlevel < 5:
         msdes.deskey(self.calculate_deskey(), msdes.DE1)
         bookkey = msdes.des(self.get_file('/DRMStorage/DRMSealed'))
         if bookkey[0:1] != b'\0':
             raise LitError('Unable to decrypt title key!')
         self.bookkey = bookkey[1:9]
     else:
         raise DRMError("Cannot access DRM-protected book")