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

« back to all changes in this revision

Viewing changes to extra/yassl/taocrypt/src/rsa.cpp

  • 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
/* based on Wei Dai's rsa.cpp from CryptoPP */
 
20
 
 
21
#include "runtime.hpp"
 
22
#include "rsa.hpp"
 
23
#include "asn.hpp"
 
24
#include "modarith.hpp"
 
25
 
 
26
 
 
27
 
 
28
namespace TaoCrypt {
 
29
 
 
30
 
 
31
Integer RSA_PublicKey::ApplyFunction(const Integer& x) const
 
32
{
 
33
    return a_exp_b_mod_c(x, e_, n_);
 
34
}
 
35
 
 
36
 
 
37
RSA_PublicKey::RSA_PublicKey(Source& source)
 
38
{
 
39
    Initialize(source);
 
40
}
 
41
 
 
42
 
 
43
void RSA_PublicKey::Initialize(Source& source)
 
44
{
 
45
    RSA_Public_Decoder decoder(source);
 
46
    decoder.Decode(*this);
 
47
}
 
48
 
 
49
 
 
50
Integer RSA_PrivateKey::CalculateInverse(RandomNumberGenerator& rng,
 
51
                                         const Integer& x) const
 
52
{
 
53
    ModularArithmetic modn(n_);
 
54
 
 
55
    Integer r(rng, Integer::One(), n_ - Integer::One());
 
56
    Integer re = modn.Exponentiate(r, e_);
 
57
    re = modn.Multiply(re, x);                  // blind
 
58
 
 
59
    // here we follow the notation of PKCS #1 and let u=q inverse mod p
 
60
    // but in ModRoot, u=p inverse mod q, so we reverse the order of p and q
 
61
 
 
62
    Integer y = ModularRoot(re, dq_, dp_, q_, p_, u_);
 
63
    y = modn.Divide(y, r);                                  // unblind
 
64
    assert(modn.Exponentiate(y, e_) == x);  // check
 
65
       
 
66
    return y;
 
67
}
 
68
 
 
69
 
 
70
RSA_PrivateKey::RSA_PrivateKey(Source& source)
 
71
{
 
72
    Initialize(source);
 
73
}
 
74
 
 
75
 
 
76
void RSA_PrivateKey::Initialize(Source& source)
 
77
{
 
78
    RSA_Private_Decoder decoder(source);
 
79
    decoder.Decode(*this);
 
80
}
 
81
 
 
82
 
 
83
void RSA_BlockType2::Pad(const byte *input, word32 inputLen, byte *pkcsBlock,
 
84
                         word32 pkcsBlockLen, RandomNumberGenerator& rng) const
 
85
{
 
86
    // convert from bit length to byte length
 
87
    if (pkcsBlockLen % 8 != 0)
 
88
    {
 
89
        pkcsBlock[0] = 0;
 
90
        pkcsBlock++;
 
91
    }
 
92
    pkcsBlockLen /= 8;
 
93
 
 
94
    pkcsBlock[0] = 2;  // block type 2
 
95
 
 
96
    // pad with non-zero random bytes
 
97
    word32 padLen = pkcsBlockLen - inputLen - 1;
 
98
    rng.GenerateBlock(&pkcsBlock[1], padLen);
 
99
    for (word32 i = 1; i < padLen; i++)
 
100
        if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
 
101
    
 
102
    pkcsBlock[pkcsBlockLen-inputLen-1] = 0;     // separator
 
103
    memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
 
104
}
 
105
 
 
106
word32 RSA_BlockType2::UnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
 
107
                           byte *output) const
 
108
{
 
109
    bool invalid = false;
 
110
    unsigned int maxOutputLen = SaturatingSubtract(pkcsBlockLen / 8, 10U);
 
111
 
 
112
    // convert from bit length to byte length
 
113
    if (pkcsBlockLen % 8 != 0)
 
114
    {
 
115
        invalid = (pkcsBlock[0] != 0) || invalid;
 
116
        pkcsBlock++;
 
117
    }
 
118
    pkcsBlockLen /= 8;
 
119
 
 
120
    // Require block type 2.
 
121
    invalid = (pkcsBlock[0] != 2) || invalid;
 
122
 
 
123
    // skip past the padding until we find the separator
 
124
    unsigned i=1;
 
125
    while (i<pkcsBlockLen && pkcsBlock[i++]) { // null body
 
126
        }
 
127
    assert(i==pkcsBlockLen || pkcsBlock[i-1]==0);
 
128
 
 
129
    unsigned int outputLen = pkcsBlockLen - i;
 
130
    invalid = (outputLen > maxOutputLen) || invalid;
 
131
 
 
132
    if (invalid)
 
133
        return 0;
 
134
 
 
135
    memcpy (output, pkcsBlock+i, outputLen);
 
136
    return outputLen;
 
137
}
 
138
 
 
139
 
 
140
void RSA_BlockType1::Pad(const byte* input, word32 inputLen, byte* pkcsBlock,
 
141
                         word32 pkcsBlockLen, RandomNumberGenerator&) const
 
142
{
 
143
    // convert from bit length to byte length
 
144
    if (pkcsBlockLen % 8 != 0)
 
145
    {
 
146
        pkcsBlock[0] = 0;
 
147
        pkcsBlock++;
 
148
    }
 
149
    pkcsBlockLen /= 8;
 
150
 
 
151
    pkcsBlock[0] = 1;  // block type 1 for SSL
 
152
 
 
153
    // pad with 0xff bytes
 
154
    memset(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
 
155
 
 
156
    pkcsBlock[pkcsBlockLen-inputLen-1] = 0;     // separator
 
157
    memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
 
158
}
 
159
 
 
160
 
 
161
word32 RSA_BlockType1::UnPad(const byte* pkcsBlock, word32 pkcsBlockLen,
 
162
                             byte* output) const
 
163
{
 
164
    bool invalid = false;
 
165
    unsigned int maxOutputLen = SaturatingSubtract(pkcsBlockLen / 8, 10U);
 
166
 
 
167
    // convert from bit length to byte length
 
168
    if (pkcsBlockLen % 8 != 0)
 
169
    {
 
170
        invalid = (pkcsBlock[0] != 0) || invalid;
 
171
        pkcsBlock++;
 
172
    }
 
173
    pkcsBlockLen /= 8;
 
174
 
 
175
    // Require block type 1 for SSL.
 
176
    invalid = (pkcsBlock[0] != 1) || invalid;
 
177
 
 
178
    // skip past the padding until we find the separator
 
179
    unsigned i=1;
 
180
    while (i<pkcsBlockLen && pkcsBlock[i++]) { // null body
 
181
        }
 
182
    assert(i==pkcsBlockLen || pkcsBlock[i-1]==0);
 
183
 
 
184
    unsigned int outputLen = pkcsBlockLen - i;
 
185
    invalid = (outputLen > maxOutputLen) || invalid;
 
186
 
 
187
    if (invalid)
 
188
        return 0;
 
189
 
 
190
    memcpy(output, pkcsBlock+i, outputLen);
 
191
    return outputLen;
 
192
}
 
193
 
 
194
 
 
195
word32 SSL_Decrypt(const RSA_PublicKey& key, const byte* sig, byte* plain)
 
196
{
 
197
    PK_Lengths lengths(key.GetModulus());
 
198
   
 
199
    ByteBlock paddedBlock(BitsToBytes(lengths.PaddedBlockBitLength()));
 
200
    Integer x = key.ApplyFunction(Integer(sig,
 
201
                                          lengths.FixedCiphertextLength()));
 
202
    if (x.ByteCount() > paddedBlock.size())
 
203
        x = Integer::Zero();    
 
204
    x.Encode(paddedBlock.get_buffer(), paddedBlock.size());
 
205
    return RSA_BlockType1().UnPad(paddedBlock.get_buffer(),
 
206
                                  lengths.PaddedBlockBitLength(), plain);
 
207
}
 
208
 
 
209
 
 
210
} // namespace