~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to extra/yassl/taocrypt/include/rsa.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (C) 2000-2007 MySQL AB
 
3
 
 
4
   This program is free software; you can redistribute it and/or modify
 
5
   it under the terms of the GNU General Public License as published by
 
6
   the Free Software Foundation; version 2 of the License.
 
7
 
 
8
   This program is distributed in the hope that it will be useful,
 
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
   GNU General Public License for more details.
 
12
 
 
13
   You should have received a copy of the GNU General Public License
 
14
   along with this program; see the file COPYING. If not, write to the
 
15
   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
 
16
   MA  02110-1301  USA.
 
17
*/
 
18
 
 
19
/* rsa.hpp provides RSA ES encrypt/decrypt, SSL (block type 1) sign and verify
 
20
*/
 
21
 
 
22
#ifndef TAO_CRYPT_RSA_HPP
 
23
#define TAO_CRYPT_RSA_HPP
 
24
 
 
25
#include "integer.hpp"
 
26
#include "random.hpp"
 
27
 
 
28
 
 
29
namespace TaoCrypt {
 
30
 
 
31
class Source;
 
32
 
 
33
 
 
34
// Public Key Length helper
 
35
class PK_Lengths {
 
36
    const Integer& image_;
 
37
public:
 
38
    explicit PK_Lengths(const Integer& i) : image_(i) {}
 
39
 
 
40
    word32 PaddedBlockBitLength()  const {return image_.BitCount() - 1;}
 
41
    word32 PaddedBlockByteLength() const 
 
42
                {return BitsToBytes(PaddedBlockBitLength());}
 
43
 
 
44
    word32 FixedCiphertextLength()   const {return image_.ByteCount();}
 
45
    word32 FixedMaxPlaintextLength() const 
 
46
                {return SaturatingSubtract(PaddedBlockBitLength() / 8, 10U); }
 
47
};
 
48
 
 
49
 
 
50
// RSA Public Key
 
51
class RSA_PublicKey {
 
52
protected:
 
53
    Integer n_;
 
54
    Integer e_;
 
55
public:
 
56
    RSA_PublicKey() {}
 
57
    explicit RSA_PublicKey(Source&);
 
58
 
 
59
    void Initialize(const Integer& n, const Integer& e) {n_ = n; e_ = e;}
 
60
    void Initialize(Source&);
 
61
 
 
62
    Integer ApplyFunction(const Integer& x) const;
 
63
 
 
64
    const Integer& GetModulus() const {return n_;}
 
65
    const Integer& GetPublicExponent() const {return e_;}
 
66
 
 
67
    void SetModulus(const Integer& n) {n_ = n;}
 
68
    void SetPublicExponent(const Integer& e) {e_ = e;}
 
69
 
 
70
    word32 FixedCiphertextLength()
 
71
    {
 
72
        return PK_Lengths(n_).FixedCiphertextLength();
 
73
    }
 
74
 
 
75
    RSA_PublicKey(const RSA_PublicKey& other) : n_(other.n_), e_(other.e_) {}
 
76
    RSA_PublicKey& operator=(const RSA_PublicKey& that)
 
77
    {
 
78
        RSA_PublicKey tmp(that);
 
79
        Swap(tmp);
 
80
        return *this;
 
81
    }
 
82
 
 
83
    void Swap(RSA_PublicKey& other)
 
84
    {
 
85
        n_.Swap(other.n_);
 
86
        e_.Swap(other.e_);
 
87
    }
 
88
};
 
89
 
 
90
 
 
91
// RSA Private Key
 
92
class RSA_PrivateKey : public RSA_PublicKey {
 
93
    Integer d_;
 
94
    Integer p_;
 
95
    Integer q_;
 
96
    Integer dp_;
 
97
    Integer dq_;
 
98
    Integer u_;
 
99
public:
 
100
    RSA_PrivateKey() {}
 
101
    explicit RSA_PrivateKey(Source&);
 
102
 
 
103
    void Initialize(const Integer& n,  const Integer& e, const Integer& d,
 
104
                    const Integer& p,  const Integer& q, const Integer& dp, 
 
105
                    const Integer& dq, const Integer& u)
 
106
        {n_ = n; e_ = e; d_ = d; p_ = p; q_ = q; dp_ = dp; dq_ = dq; u_ = u;}
 
107
    void Initialize(Source&);
 
108
 
 
109
    Integer CalculateInverse(RandomNumberGenerator&, const Integer&) const;
 
110
 
 
111
    const Integer& GetPrime1() const {return p_;}
 
112
    const Integer& GetPrime2() const {return q_;}
 
113
    const Integer& GetPrivateExponent() const {return d_;}
 
114
    const Integer& GetModPrime1PrivateExponent() const {return dp_;}
 
115
    const Integer& GetModPrime2PrivateExponent() const {return dq_;}
 
116
    const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const 
 
117
                   {return u_;}
 
118
 
 
119
    void SetPrime1(const Integer& p) {p_ = p;}
 
120
    void SetPrime2(const Integer& q) {q_ = q;}
 
121
    void SetPrivateExponent(const Integer& d) {d_ = d;}
 
122
    void SetModPrime1PrivateExponent(const Integer& dp) {dp_ = dp;}
 
123
    void SetModPrime2PrivateExponent(const Integer& dq) {dq_ = dq;}
 
124
    void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer& u) {u_ = u;}
 
125
private:
 
126
    RSA_PrivateKey(const RSA_PrivateKey&);              // hide copy
 
127
    RSA_PrivateKey& operator=(const RSA_PrivateKey&);   // and assign
 
128
};
 
129
 
 
130
 
 
131
// block type 2 padding
 
132
class RSA_BlockType2  {
 
133
public:
 
134
    void   Pad(const byte*, word32, byte*, word32,
 
135
               RandomNumberGenerator&) const;
 
136
    word32 UnPad(const byte*, word32, byte*) const;
 
137
};
 
138
 
 
139
 
 
140
// block type 1 padding
 
141
class RSA_BlockType1  {
 
142
public:
 
143
    void   Pad(const byte*, word32, byte*, word32, 
 
144
               RandomNumberGenerator&) const;
 
145
    word32 UnPad(const byte*, word32, byte*) const;
 
146
};
 
147
 
 
148
 
 
149
// RSA Encryptor, can use any padding
 
150
template<class Pad = RSA_BlockType2>
 
151
class RSA_Encryptor {
 
152
    const RSA_PublicKey& key_;
 
153
    Pad                  padding_;
 
154
public:
 
155
    explicit RSA_Encryptor(const RSA_PublicKey& k) : key_(k) {}
 
156
 
 
157
    void Encrypt(const byte*, word32, byte*, RandomNumberGenerator&);
 
158
    bool SSL_Verify(const byte* msg, word32 sz, const byte* sig);
 
159
};
 
160
 
 
161
 
 
162
// RSA Decryptor, can use any padding
 
163
template<class Pad = RSA_BlockType2>
 
164
class RSA_Decryptor {
 
165
    const RSA_PrivateKey& key_;
 
166
    Pad                   padding_;
 
167
public:
 
168
    explicit RSA_Decryptor(const RSA_PrivateKey& k) : key_(k) {}
 
169
 
 
170
    word32 Decrypt(const byte*, word32, byte*, RandomNumberGenerator&);
 
171
    void   SSL_Sign(const byte*, word32, byte*, RandomNumberGenerator&);
 
172
};
 
173
 
 
174
 
 
175
// Public Encrypt
 
176
template<class Pad>
 
177
void RSA_Encryptor<Pad>::Encrypt(const byte* plain, word32 sz, byte* cipher,
 
178
                                 RandomNumberGenerator& rng)
 
179
{
 
180
    PK_Lengths lengths(key_.GetModulus());
 
181
    assert(sz <= lengths.FixedMaxPlaintextLength());
 
182
 
 
183
    ByteBlock paddedBlock(lengths.PaddedBlockByteLength());
 
184
    padding_.Pad(plain, sz, paddedBlock.get_buffer(),
 
185
                 lengths.PaddedBlockBitLength(), rng);
 
186
 
 
187
    key_.ApplyFunction(Integer(paddedBlock.get_buffer(), paddedBlock.size())).
 
188
        Encode(cipher, lengths.FixedCiphertextLength());
 
189
}
 
190
 
 
191
 
 
192
// Private Decrypt
 
193
template<class Pad>
 
194
word32 RSA_Decryptor<Pad>::Decrypt(const byte* cipher, word32 sz, byte* plain,
 
195
                                   RandomNumberGenerator& rng)
 
196
{
 
197
    PK_Lengths lengths(key_.GetModulus());
 
198
    assert(sz == lengths.FixedCiphertextLength());
 
199
 
 
200
    if (sz != lengths.FixedCiphertextLength())
 
201
        return 0;
 
202
       
 
203
    ByteBlock paddedBlock(lengths.PaddedBlockByteLength());
 
204
    Integer x = key_.CalculateInverse(rng, Integer(cipher,
 
205
                                      lengths.FixedCiphertextLength()).Ref());
 
206
    if (x.ByteCount() > paddedBlock.size())
 
207
        x = Integer::Zero();    // don't return false, prevents timing attack
 
208
    x.Encode(paddedBlock.get_buffer(), paddedBlock.size());
 
209
    return padding_.UnPad(paddedBlock.get_buffer(),
 
210
                          lengths.PaddedBlockBitLength(), plain);
 
211
}
 
212
 
 
213
 
 
214
// Private SSL type (block 1) Encrypt
 
215
template<class Pad>
 
216
void RSA_Decryptor<Pad>::SSL_Sign(const byte* message, word32 sz, byte* sig,
 
217
                                  RandomNumberGenerator& rng)
 
218
{
 
219
    RSA_PublicKey inverse;
 
220
    inverse.Initialize(key_.GetModulus(), key_.GetPrivateExponent());
 
221
    RSA_Encryptor<RSA_BlockType1> enc(inverse); // SSL Type
 
222
    enc.Encrypt(message, sz, sig, rng);
 
223
}
 
224
 
 
225
 
 
226
word32 SSL_Decrypt(const RSA_PublicKey& key, const byte* sig, byte* plain);
 
227
 
 
228
 
 
229
// Public SSL type (block 1) Decrypt
 
230
template<class Pad>
 
231
bool RSA_Encryptor<Pad>::SSL_Verify(const byte* message, word32 sz,
 
232
                                    const byte* sig)
 
233
{
 
234
    ByteBlock plain(PK_Lengths(key_.GetModulus()).FixedMaxPlaintextLength());
 
235
    if (SSL_Decrypt(key_, sig, plain.get_buffer()) != sz)
 
236
        return false;   // not right justified or bad padding
 
237
 
 
238
    if ( (memcmp(plain.get_buffer(), message, sz)) == 0)
 
239
        return true;
 
240
    return false;
 
241
}
 
242
 
 
243
 
 
244
typedef RSA_Encryptor<> RSAES_Encryptor;
 
245
typedef RSA_Decryptor<> RSAES_Decryptor;
 
246
 
 
247
 
 
248
} // namespace
 
249
 
 
250
#endif // TAO_CRYPT_RSA_HPP