21 #include "runtime.hpp"
24 #include "modarith.hpp"
31 Integer RSA_PublicKey::ApplyFunction(
const Integer& x)
const
33 return a_exp_b_mod_c(x, e_, n_);
37 RSA_PublicKey::RSA_PublicKey(Source& source)
43 void RSA_PublicKey::Initialize(Source& source)
45 RSA_Public_Decoder decoder(source);
46 decoder.Decode(*
this);
50 Integer RSA_PrivateKey::CalculateInverse(RandomNumberGenerator& rng,
51 const Integer& x)
const
53 ModularArithmetic modn(n_);
55 Integer r(rng, Integer::One(), n_ - Integer::One());
56 Integer re = modn.Exponentiate(r, e_);
57 re = modn.Multiply(re, x);
62 Integer y = ModularRoot(re, dq_, dp_, q_, p_, u_);
63 y = modn.Divide(y, r);
69 RSA_PrivateKey::RSA_PrivateKey(Source& source)
75 void RSA_PrivateKey::Initialize(Source& source)
77 RSA_Private_Decoder decoder(source);
78 decoder.Decode(*
this);
82 void RSA_BlockType2::Pad(
const byte *input, word32 inputLen, byte *pkcsBlock,
83 word32 pkcsBlockLen, RandomNumberGenerator& rng)
const
86 if (pkcsBlockLen % 8 != 0)
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;
101 pkcsBlock[pkcsBlockLen-inputLen-1] = 0;
102 memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
105 word32 RSA_BlockType2::UnPad(
const byte *pkcsBlock,
unsigned int pkcsBlockLen,
108 bool invalid =
false;
109 unsigned int maxOutputLen = SaturatingSubtract(pkcsBlockLen / 8, 10
U);
112 if (pkcsBlockLen % 8 != 0)
114 invalid = (pkcsBlock[0] != 0) || invalid;
120 invalid = (pkcsBlock[0] != 2) || invalid;
124 while (i<pkcsBlockLen && pkcsBlock[i++]) {
126 if (!(i==pkcsBlockLen || pkcsBlock[i-1]==0))
129 unsigned int outputLen = pkcsBlockLen -
i;
130 invalid = (outputLen > maxOutputLen) || invalid;
135 memcpy (output, pkcsBlock+i, outputLen);
140 void RSA_BlockType1::Pad(
const byte* input, word32 inputLen, byte* pkcsBlock,
141 word32 pkcsBlockLen, RandomNumberGenerator&)
const
144 if (pkcsBlockLen % 8 != 0)
154 memset(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
156 pkcsBlock[pkcsBlockLen-inputLen-1] = 0;
157 memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
161 word32 RSA_BlockType1::UnPad(
const byte* pkcsBlock, word32 pkcsBlockLen,
164 bool invalid =
false;
165 unsigned int maxOutputLen = SaturatingSubtract(pkcsBlockLen / 8, 10
U);
168 if (pkcsBlockLen % 8 != 0)
170 invalid = (pkcsBlock[0] != 0) || invalid;
176 invalid = (pkcsBlock[0] != 1) || invalid;
180 while (i<pkcsBlockLen && pkcsBlock[i++]) {
182 if (!(i==pkcsBlockLen || pkcsBlock[i-1]==0))
185 unsigned int outputLen = pkcsBlockLen -
i;
186 invalid = (outputLen > maxOutputLen) || invalid;
191 memcpy(output, pkcsBlock+i, outputLen);
196 word32 SSL_Decrypt(
const RSA_PublicKey& key,
const byte* sig, byte* plain)
198 PK_Lengths lengths(key.GetModulus());
200 ByteBlock paddedBlock(BitsToBytes(lengths.PaddedBlockBitLength()));
201 Integer x = key.ApplyFunction(Integer(sig,
202 lengths.FixedCiphertextLength()));
203 if (x.ByteCount() > paddedBlock.size())
205 x.Encode(paddedBlock.get_buffer(), paddedBlock.size());
206 return RSA_BlockType1().UnPad(paddedBlock.get_buffer(),
207 lengths.PaddedBlockBitLength(), plain);