1 /*
2 * (C) 2014,2015 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6
7 #include "tests.h"
8 #include "test_rng.h"
9
10 #if defined(BOTAN_HAS_RSA)
11 #include <botan/rsa.h>
12 #include "test_pubkey.h"
13 #endif
14
15 namespace Botan_Tests {
16
17 namespace {
18
19 #if defined(BOTAN_HAS_RSA)
20
load_rsa_private_key(const VarMap & vars)21 std::unique_ptr<Botan::Private_Key> load_rsa_private_key(const VarMap& vars)
22 {
23 const BigInt p = vars.get_req_bn("P");
24 const BigInt q = vars.get_req_bn("Q");
25 const BigInt e = vars.get_req_bn("E");
26
27 return std::unique_ptr<Botan::Private_Key>(new Botan::RSA_PrivateKey(p, q, e));
28 }
29
load_rsa_public_key(const VarMap & vars)30 std::unique_ptr<Botan::Public_Key> load_rsa_public_key(const VarMap& vars)
31 {
32 const BigInt n = vars.get_req_bn("N");
33 const BigInt e = vars.get_req_bn("E");
34
35 return std::unique_ptr<Botan::Public_Key>(new Botan::RSA_PublicKey(n, e));
36 }
37
38 class RSA_ES_KAT_Tests final : public PK_Encryption_Decryption_Test
39 {
40 public:
RSA_ES_KAT_Tests()41 RSA_ES_KAT_Tests()
42 : PK_Encryption_Decryption_Test(
43 "RSA",
44 "pubkey/rsaes.vec",
45 "E,P,Q,Msg,Ciphertext",
46 "Nonce") {}
47
load_private_key(const VarMap & vars)48 std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
49 {
50 return load_rsa_private_key(vars);
51 }
52 };
53
54 class RSA_Decryption_KAT_Tests final : public PK_Decryption_Test
55 {
56 public:
RSA_Decryption_KAT_Tests()57 RSA_Decryption_KAT_Tests() :
58 PK_Decryption_Test("RSA",
59 "pubkey/rsa_decrypt.vec",
60 "E,P,Q,Ciphertext,Msg") {}
61
clear_between_callbacks() const62 bool clear_between_callbacks() const override
63 {
64 return false;
65 }
66
load_private_key(const VarMap & vars)67 std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
68 {
69 return load_rsa_private_key(vars);
70 }
71 };
72
73 class RSA_KEM_Tests final : public PK_KEM_Test
74 {
75 public:
RSA_KEM_Tests()76 RSA_KEM_Tests()
77 : PK_KEM_Test(
78 "RSA",
79 "pubkey/rsa_kem.vec",
80 "E,P,Q,R,C0,KDF,OutLen,K") {}
81
load_private_key(const VarMap & vars)82 std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
83 {
84 return load_rsa_private_key(vars);
85 }
86
87 };
88
89 class RSA_Signature_KAT_Tests final : public PK_Signature_Generation_Test
90 {
91 public:
RSA_Signature_KAT_Tests()92 RSA_Signature_KAT_Tests()
93 : PK_Signature_Generation_Test(
94 "RSA",
95 "pubkey/rsa_sig.vec",
96 "E,P,Q,Msg,Signature",
97 "Nonce") {}
98
default_padding(const VarMap &) const99 std::string default_padding(const VarMap&) const override
100 {
101 return "Raw";
102 }
103
load_private_key(const VarMap & vars)104 std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
105 {
106 return load_rsa_private_key(vars);
107 }
108 };
109
110 class RSA_PSS_KAT_Tests final : public PK_Signature_Generation_Test
111 {
112 public:
RSA_PSS_KAT_Tests()113 RSA_PSS_KAT_Tests()
114 : PK_Signature_Generation_Test(
115 "RSA",
116 "pubkey/rsa_pss.vec",
117 "P,Q,E,Hash,Nonce,Msg,Signature",
118 "") {}
119
default_padding(const VarMap & vars) const120 std::string default_padding(const VarMap& vars) const override
121 {
122 const std::string hash_name = vars.get_req_str("Hash");
123 const size_t salt_size = vars.get_req_bin("Nonce").size();
124 return "PSSR(" + hash_name + ",MGF1," + std::to_string(salt_size) + ")";
125 }
126
clear_between_callbacks() const127 bool clear_between_callbacks() const override
128 {
129 return false;
130 }
131
load_private_key(const VarMap & vars)132 std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
133 {
134 return load_rsa_private_key(vars);
135 }
136 };
137
138 class RSA_PSS_Raw_KAT_Tests final : public PK_Signature_Generation_Test
139 {
140 public:
RSA_PSS_Raw_KAT_Tests()141 RSA_PSS_Raw_KAT_Tests()
142 : PK_Signature_Generation_Test(
143 "RSA",
144 "pubkey/rsa_pss_raw.vec",
145 "P,Q,E,Hash,Nonce,Msg,Signature",
146 "") {}
147
default_padding(const VarMap & vars) const148 std::string default_padding(const VarMap& vars) const override
149 {
150 const std::string hash_name = vars.get_req_str("Hash");
151 const size_t salt_size = vars.get_req_bin("Nonce").size();
152 return "PSSR_Raw(" + hash_name + ",MGF1," + std::to_string(salt_size) + ")";
153 }
154
clear_between_callbacks() const155 bool clear_between_callbacks() const override
156 {
157 return false;
158 }
159
load_private_key(const VarMap & vars)160 std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
161 {
162 return load_rsa_private_key(vars);
163 }
164 };
165
166 class RSA_Signature_Verify_Tests final : public PK_Signature_Verification_Test
167 {
168 public:
RSA_Signature_Verify_Tests()169 RSA_Signature_Verify_Tests()
170 : PK_Signature_Verification_Test(
171 "RSA",
172 "pubkey/rsa_verify.vec",
173 "E,N,Msg,Signature") {}
174
default_padding(const VarMap &) const175 std::string default_padding(const VarMap&) const override
176 {
177 return "Raw";
178 }
179
load_public_key(const VarMap & vars)180 std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override
181 {
182 return load_rsa_public_key(vars);
183 }
184 };
185
186 class RSA_Signature_Verify_Invalid_Tests final : public PK_Signature_NonVerification_Test
187 {
188 public:
RSA_Signature_Verify_Invalid_Tests()189 RSA_Signature_Verify_Invalid_Tests()
190 : PK_Signature_NonVerification_Test(
191 "RSA",
192 "pubkey/rsa_invalid.vec",
193 "E,N,Msg,InvalidSignature") {}
194
default_padding(const VarMap &) const195 std::string default_padding(const VarMap&) const override
196 {
197 return "Raw";
198 }
199
load_public_key(const VarMap & vars)200 std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override
201 {
202 return load_rsa_public_key(vars);
203 }
204 };
205
206 class RSA_Keygen_Tests final : public PK_Key_Generation_Test
207 {
208 public:
keygen_params() const209 std::vector<std::string> keygen_params() const override
210 {
211 return { "1024", "1280" };
212 }
algo_name() const213 std::string algo_name() const override
214 {
215 return "RSA";
216 }
217 };
218
219 class RSA_Keygen_Bad_RNG_Test final : public Test
220 {
221 public:
run()222 std::vector<Test::Result> run() override
223 {
224 Test::Result result("RSA keygen with bad RNG");
225
226 /*
227 We don't need to count requests here; actually this test
228 is relying on the fact that the Request_Counting_RNG outputs
229 repeating 808080...
230 */
231 Request_Counting_RNG rng;
232
233 try
234 {
235 Botan::RSA_PrivateKey rsa(rng, 1024);
236 result.test_failure("Generated a key with a bad RNG");
237 }
238 catch(Botan::Internal_Error& e)
239 {
240 result.test_success("Key generation with bad RNG failed");
241 result.test_eq("Expected message",
242 e.what(), "Internal error: RNG failure during RSA key generation");
243 }
244
245 return {result};
246 }
247 };
248
249 class RSA_Blinding_Tests final : public Test
250 {
251 public:
run()252 std::vector<Test::Result> run() override
253 {
254 Test::Result result("RSA blinding");
255
256 /* This test makes only sense with the base provider, else skip it. */
257 if (provider_filter({"base"}).empty())
258 {
259 result.note_missing("base provider");
260 return std::vector<Test::Result> {result};
261 }
262
263 #if defined(BOTAN_HAS_EMSA_RAW) || defined(BOTAN_HAS_EME_RAW)
264 Botan::RSA_PrivateKey rsa(Test::rng(), 1024);
265 Botan::Null_RNG null_rng;
266 #endif
267
268 #if defined(BOTAN_HAS_EMSA_RAW)
269
270 /*
271 * The blinder chooses a new starting point BOTAN_BLINDING_REINIT_INTERVAL
272 * so sign several times that with a single key.
273 *
274 * Very small values (padding/hashing disabled, only low byte set on input)
275 * are used as an additional test on the blinders.
276 */
277
278 Botan::PK_Signer signer(rsa, Test::rng(), "Raw", Botan::IEEE_1363, "base"); // don't try this at home
279 Botan::PK_Verifier verifier(rsa, "Raw", Botan::IEEE_1363, "base");
280
281 for(size_t i = 1; i <= BOTAN_BLINDING_REINIT_INTERVAL * 6; ++i)
282 {
283 std::vector<uint8_t> input(16);
284 input[input.size() - 1] = static_cast<uint8_t>(i | 1);
285
286 signer.update(input);
287
288 // assert RNG is not called in this situation
289 std::vector<uint8_t> signature = signer.signature(null_rng);
290
291 result.test_eq("Signature verifies",
292 verifier.verify_message(input, signature), true);
293 }
294 #endif
295
296 #if defined(BOTAN_HAS_EME_RAW)
297
298 /*
299 * The blinder chooses a new starting point BOTAN_BLINDING_REINIT_INTERVAL
300 * so decrypt several times that with a single key.
301 *
302 * Very small values (padding/hashing disabled, only low byte set on input)
303 * are used as an additional test on the blinders.
304 */
305
306 Botan::PK_Encryptor_EME encryptor(rsa, Test::rng(), "Raw", "base"); // don't try this at home
307
308 /*
309 Test blinding reinit interval
310
311 Seed Fixed_Output_RNG only with enough bytes for the initial
312 blinder initialization plus the exponent blinding bits which
313 is 2*64 bits per operation.
314 */
315 const size_t rng_bytes = rsa.get_n().bytes() + (2*8*BOTAN_BLINDING_REINIT_INTERVAL);
316
317 Botan_Tests::Fixed_Output_RNG fixed_rng(Test::rng(), rng_bytes);
318 Botan::PK_Decryptor_EME decryptor(rsa, fixed_rng, "Raw", "base");
319
320 for(size_t i = 1; i <= BOTAN_BLINDING_REINIT_INTERVAL ; ++i)
321 {
322 std::vector<uint8_t> input(16);
323 input[ input.size() - 1 ] = static_cast<uint8_t>(i);
324
325 std::vector<uint8_t> ciphertext = encryptor.encrypt(input, null_rng);
326
327 std::vector<uint8_t> plaintext = Botan::unlock(decryptor.decrypt(ciphertext));
328 plaintext.insert(plaintext.begin(), input.size() - 1, 0);
329
330 result.test_eq("Successful decryption", plaintext, input);
331 }
332
333 result.test_eq("RNG is no longer seeded", fixed_rng.is_seeded(), false);
334
335 // one more decryption should trigger a blinder reinitialization
336 result.test_throws("RSA blinding reinit",
337 "Test error Fixed output RNG ran out of bytes, test bug?",
338 [&decryptor, &encryptor, &null_rng]()
339 {
340 std::vector<uint8_t> ciphertext = encryptor.encrypt(std::vector<uint8_t>(16, 5), null_rng);
341 decryptor.decrypt(ciphertext);
342 });
343
344 #endif
345
346 return std::vector<Test::Result> {result};
347 }
348 };
349
350 BOTAN_REGISTER_TEST("pubkey", "rsa_encrypt", RSA_ES_KAT_Tests);
351 BOTAN_REGISTER_TEST("pubkey", "rsa_decrypt", RSA_Decryption_KAT_Tests);
352 BOTAN_REGISTER_TEST("pubkey", "rsa_sign", RSA_Signature_KAT_Tests);
353 BOTAN_REGISTER_TEST("pubkey", "rsa_pss", RSA_PSS_KAT_Tests);
354 BOTAN_REGISTER_TEST("pubkey", "rsa_pss_raw", RSA_PSS_Raw_KAT_Tests);
355 BOTAN_REGISTER_TEST("pubkey", "rsa_verify", RSA_Signature_Verify_Tests);
356 BOTAN_REGISTER_TEST("pubkey", "rsa_verify_invalid", RSA_Signature_Verify_Invalid_Tests);
357 BOTAN_REGISTER_TEST("pubkey", "rsa_kem", RSA_KEM_Tests);
358 BOTAN_REGISTER_TEST("pubkey", "rsa_keygen", RSA_Keygen_Tests);
359 BOTAN_REGISTER_TEST("pubkey", "rsa_keygen_badrng", RSA_Keygen_Bad_RNG_Test);
360 BOTAN_REGISTER_TEST("pubkey", "rsa_blinding", RSA_Blinding_Tests);
361
362 #endif
363
364 }
365
366 }
367