Exemplo n.º 1
0
void CPDF_CryptoHandler::CryptBlock(bool bEncrypt,
                                    uint32_t objnum,
                                    uint32_t gennum,
                                    const uint8_t* src_buf,
                                    uint32_t src_size,
                                    uint8_t* dest_buf,
                                    uint32_t& dest_size) {
  if (m_Cipher == FXCIPHER_NONE) {
    FXSYS_memcpy(dest_buf, src_buf, src_size);
    return;
  }
  uint8_t realkey[16];
  int realkeylen = 16;
  if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) {
    uint8_t key1[32];
    PopulateKey(objnum, gennum, key1);

    if (m_Cipher == FXCIPHER_AES) {
      FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4);
    }
    CRYPT_MD5Generate(
        key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey);
    realkeylen = m_KeyLen + 5;
    if (realkeylen > 16) {
      realkeylen = 16;
    }
  }
  if (m_Cipher == FXCIPHER_AES) {
    CRYPT_AESSetKey(m_pAESContext, 16, m_KeyLen == 32 ? m_EncryptKey : realkey,
                    m_KeyLen, bEncrypt);
    if (bEncrypt) {
      uint8_t iv[16];
      for (int i = 0; i < 16; i++) {
        iv[i] = (uint8_t)rand();
      }
      CRYPT_AESSetIV(m_pAESContext, iv);
      FXSYS_memcpy(dest_buf, iv, 16);
      int nblocks = src_size / 16;
      CRYPT_AESEncrypt(m_pAESContext, dest_buf + 16, src_buf, nblocks * 16);
      uint8_t padding[16];
      FXSYS_memcpy(padding, src_buf + nblocks * 16, src_size % 16);
      FXSYS_memset(padding + src_size % 16, 16 - src_size % 16,
                   16 - src_size % 16);
      CRYPT_AESEncrypt(m_pAESContext, dest_buf + nblocks * 16 + 16, padding,
                       16);
      dest_size = 32 + nblocks * 16;
    } else {
      CRYPT_AESSetIV(m_pAESContext, src_buf);
      CRYPT_AESDecrypt(m_pAESContext, dest_buf, src_buf + 16, src_size - 16);
      dest_size = src_size - 16;
      dest_size -= dest_buf[dest_size - 1];
    }
  } else {
    ASSERT(dest_size == src_size);
    if (dest_buf != src_buf) {
      FXSYS_memcpy(dest_buf, src_buf, src_size);
    }
    CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen);
  }
}
Exemplo n.º 2
0
void CPDF_SecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict,
                                           uint32_t permissions,
                                           FX_BOOL bEncryptMetadata,
                                           const uint8_t* key) {
  uint8_t buf[16];
  buf[0] = (uint8_t)permissions;
  buf[1] = (uint8_t)(permissions >> 8);
  buf[2] = (uint8_t)(permissions >> 16);
  buf[3] = (uint8_t)(permissions >> 24);
  buf[4] = 0xff;
  buf[5] = 0xff;
  buf[6] = 0xff;
  buf[7] = 0xff;
  buf[8] = bEncryptMetadata ? 'T' : 'F';
  buf[9] = 'a';
  buf[10] = 'd';
  buf[11] = 'b';
  uint8_t* aes = FX_Alloc(uint8_t, 2048);
  CRYPT_AESSetKey(aes, 16, key, 32, TRUE);
  uint8_t iv[16], buf1[16];
  FXSYS_memset(iv, 0, 16);
  CRYPT_AESSetIV(aes, iv);
  CRYPT_AESEncrypt(aes, buf1, buf, 16);
  FX_Free(aes);
  pEncryptDict->SetAtString("Perms", CFX_ByteString(buf1, 16));
}
Exemplo n.º 3
0
void CPDF_StandardSecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict, FX_DWORD permissions,
        FX_BOOL bEncryptMetadata, FX_LPCBYTE key)
{
    FX_BYTE buf[16];
    buf[0] = (FX_BYTE)permissions;
    buf[1] = (FX_BYTE)(permissions >> 8);
    buf[2] = (FX_BYTE)(permissions >> 16);
    buf[3] = (FX_BYTE)(permissions >> 24);
    buf[4] = 0xff;
    buf[5] = 0xff;
    buf[6] = 0xff;
    buf[7] = 0xff;
    buf[8] = bEncryptMetadata ? 'T' : 'F';
    buf[9] = 'a';
    buf[10] = 'd';
    buf[11] = 'b';
    FX_BYTE* aes = FX_Alloc(FX_BYTE, 2048);
    CRYPT_AESSetKey(aes, 16, key, 32, TRUE);
    FX_BYTE iv[16], buf1[16];
    FXSYS_memset32(iv, 0, 16);
    CRYPT_AESSetIV(aes, iv);
    CRYPT_AESEncrypt(aes, buf1, buf, 16);
    FX_Free(aes);
    pEncryptDict->SetAtString(FX_BSTRC("Perms"), CFX_ByteString(buf1, 16));
}
Exemplo n.º 4
0
bool CPDF_CryptoHandler::CryptStream(void* context,
                                     const uint8_t* src_buf,
                                     uint32_t src_size,
                                     CFX_BinaryBuf& dest_buf,
                                     bool bEncrypt) {
  if (!context) {
    return false;
  }
  if (m_Cipher == FXCIPHER_NONE) {
    dest_buf.AppendBlock(src_buf, src_size);
    return true;
  }
  if (m_Cipher == FXCIPHER_RC4) {
    int old_size = dest_buf.GetSize();
    dest_buf.AppendBlock(src_buf, src_size);
    CRYPT_ArcFourCrypt(reinterpret_cast<CRYPT_rc4_context*>(context),
                       dest_buf.GetBuffer() + old_size, src_size);
    return true;
  }
  AESCryptContext* pContext = reinterpret_cast<AESCryptContext*>(context);
  if (pContext->m_bIV && bEncrypt) {
    dest_buf.AppendBlock(pContext->m_Block, 16);
    pContext->m_bIV = false;
  }
  uint32_t src_off = 0;
  uint32_t src_left = src_size;
  while (1) {
    uint32_t copy_size = 16 - pContext->m_BlockOffset;
    if (copy_size > src_left) {
      copy_size = src_left;
    }
    FXSYS_memcpy(pContext->m_Block + pContext->m_BlockOffset, src_buf + src_off,
                 copy_size);
    src_off += copy_size;
    src_left -= copy_size;
    pContext->m_BlockOffset += copy_size;
    if (pContext->m_BlockOffset == 16) {
      if (!bEncrypt && pContext->m_bIV) {
        CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
        pContext->m_bIV = false;
        pContext->m_BlockOffset = 0;
      } else if (src_off < src_size) {
        uint8_t block_buf[16];
        if (bEncrypt) {
          CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block,
                           16);
        } else {
          CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block,
                           16);
        }
        dest_buf.AppendBlock(block_buf, 16);
        pContext->m_BlockOffset = 0;
      }
    }
    if (!src_left) {
      break;
    }
  }
  return true;
}
Exemplo n.º 5
0
void CPDF_StandardSecurityHandler::AES256_SetPassword(
    CPDF_Dictionary* pEncryptDict,
    const uint8_t* password,
    FX_DWORD size,
    FX_BOOL bOwner,
    const uint8_t* key) {
  uint8_t sha[128];
  CRYPT_SHA1Start(sha);
  CRYPT_SHA1Update(sha, key, 32);
  CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5);
  uint8_t digest[20];
  CRYPT_SHA1Finish(sha, digest);
  CFX_ByteString ukey = pEncryptDict->GetString(FX_BSTRC("U"));
  uint8_t digest1[48];
  if (m_Revision >= 6) {
    Revision6_Hash(password, size, digest,
                   (bOwner ? (const uint8_t*)ukey : NULL), digest1);
  } else {
    CRYPT_SHA256Start(sha);
    CRYPT_SHA256Update(sha, password, size);
    CRYPT_SHA256Update(sha, digest, 8);
    if (bOwner) {
      CRYPT_SHA256Update(sha, ukey, ukey.GetLength());
    }
    CRYPT_SHA256Finish(sha, digest1);
  }
  FXSYS_memcpy(digest1 + 32, digest, 16);
  pEncryptDict->SetAtString(bOwner ? FX_BSTRC("O") : FX_BSTRC("U"),
                            CFX_ByteString(digest1, 48));
  if (m_Revision >= 6) {
    Revision6_Hash(password, size, digest + 8,
                   (bOwner ? (const uint8_t*)ukey : NULL), digest1);
  } else {
    CRYPT_SHA256Start(sha);
    CRYPT_SHA256Update(sha, password, size);
    CRYPT_SHA256Update(sha, digest + 8, 8);
    if (bOwner) {
      CRYPT_SHA256Update(sha, ukey, ukey.GetLength());
    }
    CRYPT_SHA256Finish(sha, digest1);
  }
  uint8_t* aes = FX_Alloc(uint8_t, 2048);
  CRYPT_AESSetKey(aes, 16, digest1, 32, TRUE);
  uint8_t iv[16];
  FXSYS_memset(iv, 0, 16);
  CRYPT_AESSetIV(aes, iv);
  CRYPT_AESEncrypt(aes, digest1, key, 32);
  FX_Free(aes);
  pEncryptDict->SetAtString(bOwner ? FX_BSTRC("OE") : FX_BSTRC("UE"),
                            CFX_ByteString(digest1, 32));
}
Exemplo n.º 6
0
bool CPDF_CryptoHandler::CryptFinish(void* context,
                                     CFX_BinaryBuf& dest_buf,
                                     bool bEncrypt) {
  if (!context) {
    return false;
  }
  if (m_Cipher == FXCIPHER_NONE) {
    return true;
  }
  if (m_Cipher == FXCIPHER_RC4) {
    FX_Free(context);
    return true;
  }
  AESCryptContext* pContext = (AESCryptContext*)context;
  if (bEncrypt) {
    uint8_t block_buf[16];
    if (pContext->m_BlockOffset == 16) {
      CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
      dest_buf.AppendBlock(block_buf, 16);
      pContext->m_BlockOffset = 0;
    }
    FXSYS_memset(pContext->m_Block + pContext->m_BlockOffset,
                 (uint8_t)(16 - pContext->m_BlockOffset),
                 16 - pContext->m_BlockOffset);
    CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
    dest_buf.AppendBlock(block_buf, 16);
  } else if (pContext->m_BlockOffset == 16) {
    uint8_t block_buf[16];
    CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
    if (block_buf[15] <= 16) {
      dest_buf.AppendBlock(block_buf, 16 - block_buf[15]);
    }
  }
  FX_Free(pContext);
  return true;
}
Exemplo n.º 7
0
void Revision6_Hash(const uint8_t* password,
                    uint32_t size,
                    const uint8_t* salt,
                    const uint8_t* vector,
                    uint8_t* hash) {
  int iBlockSize = 32;
  uint8_t sha[128];
  CRYPT_SHA256Start(sha);
  CRYPT_SHA256Update(sha, password, size);
  CRYPT_SHA256Update(sha, salt, 8);
  if (vector) {
    CRYPT_SHA256Update(sha, vector, 48);
  }
  uint8_t digest[32];
  CRYPT_SHA256Finish(sha, digest);
  CFX_ByteTextBuf buf;
  uint8_t* input = digest;
  uint8_t* key = input;
  uint8_t* iv = input + 16;
  uint8_t* E = buf.GetBuffer();
  int iBufLen = buf.GetLength();
  CFX_ByteTextBuf interDigest;
  int i = 0;
  uint8_t* aes = FX_Alloc(uint8_t, 2048);
  while (i < 64 || i < E[iBufLen - 1] + 32) {
    int iRoundSize = size + iBlockSize;
    if (vector) {
      iRoundSize += 48;
    }
    iBufLen = iRoundSize * 64;
    buf.EstimateSize(iBufLen);
    E = buf.GetBuffer();
    CFX_ByteTextBuf content;
    for (int j = 0; j < 64; ++j) {
      content.AppendBlock(password, size);
      content.AppendBlock(input, iBlockSize);
      if (vector) {
        content.AppendBlock(vector, 48);
      }
    }
    CRYPT_AESSetKey(aes, 16, key, 16, TRUE);
    CRYPT_AESSetIV(aes, iv);
    CRYPT_AESEncrypt(aes, E, content.GetBuffer(), iBufLen);
    int iHash = 0;
    switch (BigOrder64BitsMod3(E)) {
      case 0:
        iHash = 0;
        iBlockSize = 32;
        break;
      case 1:
        iHash = 1;
        iBlockSize = 48;
        break;
      default:
        iHash = 2;
        iBlockSize = 64;
        break;
    }
    interDigest.EstimateSize(iBlockSize);
    input = interDigest.GetBuffer();
    if (iHash == 0) {
      CRYPT_SHA256Generate(E, iBufLen, input);
    } else if (iHash == 1) {
      CRYPT_SHA384Generate(E, iBufLen, input);
    } else if (iHash == 2) {
      CRYPT_SHA512Generate(E, iBufLen, input);
    }
    key = input;
    iv = input + 16;
    ++i;
  }
  FX_Free(aes);
  if (hash) {
    FXSYS_memcpy(hash, input, 32);
  }
}