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