Line | Count | Source (jump to first uncovered line) |
1 | | // rsa.h - originally written and placed in the public domain by Wei Dai |
2 | | |
3 | | /// \file rsa.h |
4 | | /// \brief Classes for the RSA cryptosystem |
5 | | /// \details This file contains classes that implement the RSA |
6 | | /// ciphers and signature schemes as defined in PKCS #1 v2.0. |
7 | | |
8 | | #ifndef CRYPTOPP_RSA_H |
9 | | #define CRYPTOPP_RSA_H |
10 | | |
11 | | #include "cryptlib.h" |
12 | | #include "pubkey.h" |
13 | | #include "integer.h" |
14 | | #include "pkcspad.h" |
15 | | #include "oaep.h" |
16 | | #include "emsa2.h" |
17 | | #include "asn.h" |
18 | | |
19 | | NAMESPACE_BEGIN(CryptoPP) |
20 | | |
21 | | /// \brief RSA trapdoor function using the public key |
22 | | /// \since Crypto++ 1.0 |
23 | | class CRYPTOPP_DLL RSAFunction : public TrapdoorFunction, public X509PublicKey |
24 | | { |
25 | | typedef RSAFunction ThisClass; |
26 | | |
27 | | public: |
28 | | /// \brief Initialize a RSA public key |
29 | | /// \param n the modulus |
30 | | /// \param e the public exponent |
31 | | void Initialize(const Integer &n, const Integer &e) |
32 | 0 | {m_n = n; m_e = e;} |
33 | | |
34 | | // X509PublicKey |
35 | | OID GetAlgorithmID() const; |
36 | | void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); |
37 | | void DEREncodePublicKey(BufferedTransformation &bt) const; |
38 | | |
39 | | // CryptoMaterial |
40 | | bool Validate(RandomNumberGenerator &rng, unsigned int level) const; |
41 | | bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; |
42 | | void AssignFrom(const NameValuePairs &source); |
43 | | |
44 | | // TrapdoorFunction |
45 | | Integer ApplyFunction(const Integer &x) const; |
46 | 0 | Integer PreimageBound() const {return m_n;} |
47 | 0 | Integer ImageBound() const {return m_n;} |
48 | | |
49 | | // non-derived |
50 | 0 | const Integer & GetModulus() const {return m_n;} |
51 | 0 | const Integer & GetPublicExponent() const {return m_e;} |
52 | | |
53 | 0 | void SetModulus(const Integer &n) {m_n = n;} |
54 | 0 | void SetPublicExponent(const Integer &e) {m_e = e;} |
55 | | |
56 | | protected: |
57 | | Integer m_n, m_e; |
58 | | }; |
59 | | |
60 | | /// \brief RSA trapdoor function using the private key |
61 | | /// \since Crypto++ 1.0 |
62 | | class CRYPTOPP_DLL InvertibleRSAFunction : public RSAFunction, public TrapdoorFunctionInverse, public PKCS8PrivateKey |
63 | | { |
64 | | typedef InvertibleRSAFunction ThisClass; |
65 | | |
66 | | public: |
67 | | /// \brief Create a RSA private key |
68 | | /// \param rng a RandomNumberGenerator derived class |
69 | | /// \param modulusBits the size of the modulus, in bits |
70 | | /// \param e the desired public exponent |
71 | | /// \details Initialize() creates a new keypair using a public exponent of 17. |
72 | | /// \details This function overload of Initialize() creates a new private key because it |
73 | | /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, |
74 | | /// then use one of the other Initialize() overloads. |
75 | | void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits, const Integer &e = 17); |
76 | | |
77 | | /// \brief Initialize a RSA private key |
78 | | /// \param n modulus |
79 | | /// \param e public exponent |
80 | | /// \param d private exponent |
81 | | /// \param p first prime factor |
82 | | /// \param q second prime factor |
83 | | /// \param dp d mod p |
84 | | /// \param dq d mod q |
85 | | /// \param u q<sup>-1</sup> mod p |
86 | | /// \details This Initialize() function overload initializes a private key from existing parameters. |
87 | | void Initialize(const Integer &n, const Integer &e, const Integer &d, const Integer &p, const Integer &q, const Integer &dp, const Integer &dq, const Integer &u) |
88 | 0 | {m_n = n; m_e = e; m_d = d; m_p = p; m_q = q; m_dp = dp; m_dq = dq; m_u = u;} |
89 | | |
90 | | /// \brief Initialize a RSA private key |
91 | | /// \param n modulus |
92 | | /// \param e public exponent |
93 | | /// \param d private exponent |
94 | | /// \details This Initialize() function overload initializes a private key from existing parameters. |
95 | | /// Initialize() will factor n using d and populate {p,q,dp,dq,u}. |
96 | | void Initialize(const Integer &n, const Integer &e, const Integer &d); |
97 | | |
98 | | // PKCS8PrivateKey |
99 | | void BERDecode(BufferedTransformation &bt) |
100 | 0 | {PKCS8PrivateKey::BERDecode(bt);} |
101 | | void DEREncode(BufferedTransformation &bt) const |
102 | 0 | {PKCS8PrivateKey::DEREncode(bt);} |
103 | | void Load(BufferedTransformation &bt) |
104 | 0 | {PKCS8PrivateKey::BERDecode(bt);} |
105 | | void Save(BufferedTransformation &bt) const |
106 | 0 | {PKCS8PrivateKey::DEREncode(bt);} |
107 | 0 | OID GetAlgorithmID() const {return RSAFunction::GetAlgorithmID();} |
108 | | void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); |
109 | | void DEREncodePrivateKey(BufferedTransformation &bt) const; |
110 | | |
111 | | // TrapdoorFunctionInverse |
112 | | Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; |
113 | | |
114 | | // GeneratableCryptoMaterial |
115 | | bool Validate(RandomNumberGenerator &rng, unsigned int level) const; |
116 | | // parameters: (ModulusSize, PublicExponent (default 17)) |
117 | | void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); |
118 | | bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; |
119 | | void AssignFrom(const NameValuePairs &source); |
120 | | |
121 | | // non-derived interface |
122 | 0 | const Integer& GetPrime1() const {return m_p;} |
123 | 0 | const Integer& GetPrime2() const {return m_q;} |
124 | 0 | const Integer& GetPrivateExponent() const {return m_d;} |
125 | 0 | const Integer& GetModPrime1PrivateExponent() const {return m_dp;} |
126 | 0 | const Integer& GetModPrime2PrivateExponent() const {return m_dq;} |
127 | 0 | const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} |
128 | | |
129 | 0 | void SetPrime1(const Integer &p) {m_p = p;} |
130 | 0 | void SetPrime2(const Integer &q) {m_q = q;} |
131 | 0 | void SetPrivateExponent(const Integer &d) {m_d = d;} |
132 | 0 | void SetModPrime1PrivateExponent(const Integer &dp) {m_dp = dp;} |
133 | 0 | void SetModPrime2PrivateExponent(const Integer &dq) {m_dq = dq;} |
134 | 0 | void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} |
135 | | |
136 | | protected: |
137 | | Integer m_d, m_p, m_q, m_dp, m_dq, m_u; |
138 | | }; |
139 | | |
140 | | /// \brief RSA trapdoor function using the public key |
141 | | /// \since Crypto++ 1.0 |
142 | | class CRYPTOPP_DLL RSAFunction_ISO : public RSAFunction |
143 | | { |
144 | | public: |
145 | | Integer ApplyFunction(const Integer &x) const; |
146 | 0 | Integer PreimageBound() const {return ++(m_n>>1);} |
147 | | }; |
148 | | |
149 | | /// \brief RSA trapdoor function using the private key |
150 | | /// \since Crypto++ 1.0 |
151 | | class CRYPTOPP_DLL InvertibleRSAFunction_ISO : public InvertibleRSAFunction |
152 | | { |
153 | | public: |
154 | | Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; |
155 | 0 | Integer PreimageBound() const {return ++(m_n>>1);} |
156 | | }; |
157 | | |
158 | | /// \brief RSA algorithm |
159 | | /// \since Crypto++ 1.0 |
160 | | struct CRYPTOPP_DLL RSA |
161 | | { |
162 | 0 | CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "RSA";} |
163 | | typedef RSAFunction PublicKey; |
164 | | typedef InvertibleRSAFunction PrivateKey; |
165 | | }; |
166 | | |
167 | | /// \brief RSA encryption algorithm |
168 | | /// \tparam STANDARD signature standard |
169 | | /// \sa <a href="http://www.weidai.com/scan-mirror/ca.html#RSA">RSA cryptosystem</a> |
170 | | /// \since Crypto++ 1.0 |
171 | | template <class STANDARD> |
172 | | struct RSAES : public TF_ES<RSA, STANDARD> |
173 | | { |
174 | | }; |
175 | | |
176 | | /// \brief RSA signature algorithm |
177 | | /// \tparam STANDARD signature standard |
178 | | /// \tparam H hash transformation |
179 | | /// \details See documentation of PKCS1v15 for a list of hash functions that can be used with it. |
180 | | /// \sa <a href="http://www.weidai.com/scan-mirror/sig.html#RSA">RSA signature scheme with appendix</a> |
181 | | /// \since Crypto++ 1.0 |
182 | | template <class STANDARD, class H> |
183 | | struct RSASS : public TF_SS<RSA, STANDARD, H> |
184 | | { |
185 | | }; |
186 | | |
187 | | /// \brief RSA algorithm |
188 | | /// \since Crypto++ 1.0 |
189 | | struct CRYPTOPP_DLL RSA_ISO |
190 | | { |
191 | 0 | CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "RSA-ISO";} |
192 | | typedef RSAFunction_ISO PublicKey; |
193 | | typedef InvertibleRSAFunction_ISO PrivateKey; |
194 | | }; |
195 | | |
196 | | /// \brief RSA signature algorithm |
197 | | /// \tparam H hash transformation |
198 | | /// \since Crypto++ 1.0 |
199 | | template <class H> |
200 | | struct RSASS_ISO : public TF_SS<RSA_ISO, P1363_EMSA2, H> |
201 | | { |
202 | | }; |
203 | | |
204 | | /// \brief \ref RSAES<STANDARD> "RSAES<PKCS1v15>::Decryptor" typedef |
205 | | /// \details RSA encryption scheme defined in PKCS #1 v2.0 |
206 | | /// \since Crypto++ 1.0 |
207 | | DOCUMENTED_TYPEDEF(RSAES<PKCS1v15>::Decryptor, RSAES_PKCS1v15_Decryptor); |
208 | | /// \brief \ref RSAES<STANDARD> "RSAES<PKCS1v15>::Encryptor" typedef |
209 | | /// \details RSA encryption scheme defined in PKCS #1 v2.0 |
210 | | /// \since Crypto++ 1.0 |
211 | | DOCUMENTED_TYPEDEF(RSAES<PKCS1v15>::Encryptor, RSAES_PKCS1v15_Encryptor); |
212 | | |
213 | | /// \brief \ref RSAES<STANDARD> "RSAES<OAEP<SHA1>>::Decryptor" typedef |
214 | | /// \details RSA encryption scheme defined in PKCS #1 v2.0 |
215 | | /// \since Crypto++ 1.0 |
216 | | DOCUMENTED_TYPEDEF(RSAES<OAEP<SHA1> >::Decryptor, RSAES_OAEP_SHA_Decryptor); |
217 | | /// \brief \ref RSAES<STANDARD> "RSAES<OAEP<SHA1>>::Encryptor" typedef |
218 | | /// \details RSA encryption scheme defined in PKCS #1 v2.0 |
219 | | /// \since Crypto++ 1.0 |
220 | | DOCUMENTED_TYPEDEF(RSAES<OAEP<SHA1> >::Encryptor, RSAES_OAEP_SHA_Encryptor); |
221 | | |
222 | | /// \brief \ref RSAES<STANDARD> "RSAES<OAEP<SHA256>>::Decryptor" typedef |
223 | | /// \details RSA encryption scheme defined in PKCS #1 v2.0 |
224 | | /// \since Crypto++ 8.8 |
225 | | DOCUMENTED_TYPEDEF(RSAES<OAEP<SHA256> >::Decryptor, RSAES_OAEP_SHA256_Decryptor); |
226 | | /// \brief \ref RSAES<STANDARD> "RSAES<OAEP<SHA256>>::Encryptor" typedef |
227 | | /// \details RSA encryption scheme defined in PKCS #1 v2.0 |
228 | | /// \since Crypto++ 8.8 |
229 | | DOCUMENTED_TYPEDEF(RSAES<OAEP<SHA256> >::Encryptor, RSAES_OAEP_SHA256_Encryptor); |
230 | | |
231 | | #ifdef CRYPTOPP_DOXYGEN_PROCESSING |
232 | | /// \brief \ref RSASS<STANDARD,HASH> "RSASS<PKCS1v15,SHA1>::Signer" typedef |
233 | | /// \details RSA signature schemes defined in PKCS #1 v2.0 |
234 | | /// \since Crypto++ 1.0 |
235 | | class RSASSA_PKCS1v15_SHA_Signer : public RSASS<PKCS1v15,SHA1>::Signer {}; |
236 | | /// \brief \ref RSASS<STANDARD,HASH> "RSASS<PKCS1v15,SHA1>::Verifier" typedef |
237 | | /// \details RSA signature schemes defined in PKCS #1 v2.0 |
238 | | /// \since Crypto++ 1.0 |
239 | | class RSASSA_PKCS1v15_SHA_Verifier : public RSASS<PKCS1v15,SHA1>::Verifier {}; |
240 | | |
241 | | /// \brief \ref RSASS<STANDARD,HASH> "RSASS<PKCS1v15,SHA256>::Signer" typedef |
242 | | /// \details RSA signature schemes defined in PKCS #1 v2.0 |
243 | | /// \since Crypto++ 8.8 |
244 | | class RSASSA_PKCS1v15_SHA256_Signer : public RSASS<PKCS1v15,SHA256>::Signer {}; |
245 | | /// \brief \ref RSASS<STANDARD,HASH> "RSASS<PKCS1v15,SHA256>::Verifier" typedef |
246 | | /// \details RSA signature schemes defined in PKCS #1 v2.0 |
247 | | /// \since Crypto++ 8.8 |
248 | | class RSASSA_PKCS1v15_SHA256_Verifier : public RSASS<PKCS1v15,SHA256>::Verifier {}; |
249 | | |
250 | | namespace Weak { |
251 | | |
252 | | /// \brief \ref RSASS<STANDARD,HASH> "RSASS<PKCS1v15, Weak::MD2>::Signer" typedef |
253 | | /// \details RSA signature schemes defined in PKCS #1 v2.0 |
254 | | /// \since Crypto++ 1.0 |
255 | | class RSASSA_PKCS1v15_MD2_Signer : public RSASS<PKCS1v15, Weak1::MD2>::Signer {}; |
256 | | /// \brief \ref RSASS<STANDARD,HASH> "RSASS<PKCS1v15, Weak::MD2>::Verifier" typedef |
257 | | /// \details RSA signature schemes defined in PKCS #1 v2.0 |
258 | | /// \since Crypto++ 1.0 |
259 | | class RSASSA_PKCS1v15_MD2_Verifier : public RSASS<PKCS1v15, Weak1::MD2>::Verifier {}; |
260 | | |
261 | | /// \brief \ref RSASS<STANDARD,HASH> "RSASS<PKCS1v15, Weak::MD5>::Signer" typedef |
262 | | /// \details RSA signature schemes defined in PKCS #1 v2.0 |
263 | | /// \since Crypto++ 1.0 |
264 | | class RSASSA_PKCS1v15_MD5_Signer : public RSASS<PKCS1v15, Weak1::MD5>::Signer {}; |
265 | | /// \brief \ref RSASS<STANDARD,HASH> "RSASS<PKCS1v15, Weak::MD5>::Verifier" typedef |
266 | | /// \details RSA signature schemes defined in PKCS #1 v2.0 |
267 | | /// \since Crypto++ 1.0 |
268 | | class RSASSA_PKCS1v15_MD5_Verifier : public RSASS<PKCS1v15, Weak1::MD5>::Verifier {}; |
269 | | } |
270 | | |
271 | | #else |
272 | | typedef RSASS<PKCS1v15,SHA1>::Signer RSASSA_PKCS1v15_SHA_Signer; |
273 | | typedef RSASS<PKCS1v15,SHA1>::Verifier RSASSA_PKCS1v15_SHA_Verifier; |
274 | | |
275 | | typedef RSASS<PKCS1v15,SHA256>::Signer RSASSA_PKCS1v15_SHA256_Signer; |
276 | | typedef RSASS<PKCS1v15,SHA256>::Verifier RSASSA_PKCS1v15_SHA256_Verifier; |
277 | | |
278 | | namespace Weak { |
279 | | typedef RSASS<PKCS1v15, Weak1::MD2>::Signer RSASSA_PKCS1v15_MD2_Signer; |
280 | | typedef RSASS<PKCS1v15, Weak1::MD2>::Verifier RSASSA_PKCS1v15_MD2_Verifier; |
281 | | typedef RSASS<PKCS1v15, Weak1::MD5>::Signer RSASSA_PKCS1v15_MD5_Signer; |
282 | | typedef RSASS<PKCS1v15, Weak1::MD5>::Verifier RSASSA_PKCS1v15_MD5_Verifier; |
283 | | } |
284 | | #endif // CRYPTOPP_DOXYGEN_PROCESSING |
285 | | |
286 | | NAMESPACE_END |
287 | | |
288 | | #endif |