MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rsa.cpp
1 /*
2  Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
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 
65  return y;
66 }
67 
68 
69 RSA_PrivateKey::RSA_PrivateKey(Source& source)
70 {
71  Initialize(source);
72 }
73 
74 
75 void RSA_PrivateKey::Initialize(Source& source)
76 {
77  RSA_Private_Decoder decoder(source);
78  decoder.Decode(*this);
79 }
80 
81 
82 void RSA_BlockType2::Pad(const byte *input, word32 inputLen, byte *pkcsBlock,
83  word32 pkcsBlockLen, RandomNumberGenerator& rng) const
84 {
85  // convert from bit length to byte length
86  if (pkcsBlockLen % 8 != 0)
87  {
88  pkcsBlock[0] = 0;
89  pkcsBlock++;
90  }
91  pkcsBlockLen /= 8;
92 
93  pkcsBlock[0] = 2; // block type 2
94 
95  // pad with non-zero random bytes
96  word32 padLen = pkcsBlockLen - inputLen - 1;
97  rng.GenerateBlock(&pkcsBlock[1], padLen);
98  for (word32 i = 1; i < padLen; i++)
99  if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
100 
101  pkcsBlock[pkcsBlockLen-inputLen-1] = 0; // separator
102  memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
103 }
104 
105 word32 RSA_BlockType2::UnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
106  byte *output) const
107 {
108  bool invalid = false;
109  unsigned int maxOutputLen = SaturatingSubtract(pkcsBlockLen / 8, 10U);
110 
111  // convert from bit length to byte length
112  if (pkcsBlockLen % 8 != 0)
113  {
114  invalid = (pkcsBlock[0] != 0) || invalid;
115  pkcsBlock++;
116  }
117  pkcsBlockLen /= 8;
118 
119  // Require block type 2.
120  invalid = (pkcsBlock[0] != 2) || invalid;
121 
122  // skip past the padding until we find the separator
123  unsigned i=1;
124  while (i<pkcsBlockLen && pkcsBlock[i++]) { // null body
125  }
126  if (!(i==pkcsBlockLen || pkcsBlock[i-1]==0))
127  return 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  if (!(i==pkcsBlockLen || pkcsBlock[i-1]==0))
183  return 0;
184 
185  unsigned int outputLen = pkcsBlockLen - i;
186  invalid = (outputLen > maxOutputLen) || invalid;
187 
188  if (invalid)
189  return 0;
190 
191  memcpy(output, pkcsBlock+i, outputLen);
192  return outputLen;
193 }
194 
195 
196 word32 SSL_Decrypt(const RSA_PublicKey& key, const byte* sig, byte* plain)
197 {
198  PK_Lengths lengths(key.GetModulus());
199 
200  ByteBlock paddedBlock(BitsToBytes(lengths.PaddedBlockBitLength()));
201  Integer x = key.ApplyFunction(Integer(sig,
202  lengths.FixedCiphertextLength()));
203  if (x.ByteCount() > paddedBlock.size())
204  x = Integer::Zero();
205  x.Encode(paddedBlock.get_buffer(), paddedBlock.size());
206  return RSA_BlockType1().UnPad(paddedBlock.get_buffer(),
207  lengths.PaddedBlockBitLength(), plain);
208 }
209 
210 
211 } // namespace