summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h
blob: 2b10abd050bcfdc374b28fae052c5aca25585cf2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//========================================================================
//
// Decrypt.h
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================

#ifndef DECRYPT_H
#define DECRYPT_H

#include <aconf.h>

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

#include "gtypes.h"
#include "GString.h"
#include "Object.h"
#include "Stream.h"

//------------------------------------------------------------------------
// Decrypt
//------------------------------------------------------------------------

class Decrypt {
public:

  // Generate a file key.  The <fileKey> buffer must have space for at
  // least 16 bytes.  Checks <ownerPassword> and then <userPassword>
  // and returns true if either is correct.  Sets <ownerPasswordOk> if
  // the owner password was correct.  Either or both of the passwords
  // may be NULL, which is treated as an empty string.
  static GBool makeFileKey(int encVersion, int encRevision, int keyLength,
			   GString *ownerKey, GString *userKey,
			   GString *ownerEnc, GString *userEnc,
			   int permissions, GString *fileID,
			   GString *ownerPassword, GString *userPassword,
			   Guchar *fileKey, GBool encryptMetadata,
			   GBool *ownerPasswordOk);

private:

  static void r6Hash(Guchar *key, int keyLen, const char *pwd, int pwdLen,
		     char *userKey);
  static GBool makeFileKey2(int encVersion, int encRevision, int keyLength,
			    GString *ownerKey, GString *userKey,
			    int permissions, GString *fileID,
			    GString *userPassword, Guchar *fileKey,
			    GBool encryptMetadata);
};

//------------------------------------------------------------------------
// DecryptStream
//------------------------------------------------------------------------

struct DecryptRC4State {
  Guchar state[256];
  Guchar x, y;
  int buf;
};

struct DecryptAESState {
  Guint w[44];
  Guchar state[16];
  Guchar cbc[16];
  Guchar buf[16];
  int bufIdx;
};

struct DecryptAES256State {
  Guint w[60];
  Guchar state[16];
  Guchar cbc[16];
  Guchar buf[16];
  int bufIdx;
};

class DecryptStream: public FilterStream {
public:

  DecryptStream(Stream *strA, Guchar *fileKeyA,
		CryptAlgorithm algoA, int keyLengthA,
		int objNumA, int objGenA);
  virtual ~DecryptStream();
  virtual Stream *copy();
  virtual StreamKind getKind() { return strWeird; }
  virtual void reset();
  virtual int getChar();
  virtual int lookChar();
  virtual GBool isBinary(GBool last);
  virtual Stream *getUndecodedStream() { return this; }

private:

  Guchar fileKey[32];
  CryptAlgorithm algo;
  int keyLength;
  int objNum, objGen;
  int objKeyLength;
  Guchar objKey[32];

  union {
    DecryptRC4State rc4;
    DecryptAESState aes;
    DecryptAES256State aes256;
  } state;
};

//------------------------------------------------------------------------

struct MD5State {
  Gulong a, b, c, d;
  Guchar buf[64];
  int bufLen;
  int msgLen;
  Guchar digest[16];
};

extern void rc4InitKey(Guchar *key, int keyLen, Guchar *state);
extern Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c);
void md5Start(MD5State *state);
void md5Append(MD5State *state, Guchar *data, int dataLen);
void md5Finish(MD5State *state);
extern void md5(Guchar *msg, int msgLen, Guchar *digest);
extern void aesKeyExpansion(DecryptAESState *s,
			    Guchar *objKey, int objKeyLen,
			    GBool decrypt);
extern void aesEncryptBlock(DecryptAESState *s, Guchar *in);
extern void aesDecryptBlock(DecryptAESState *s, Guchar *in, GBool last);

#endif