~ubuntu-branches/debian/sid/botan/sid

« back to all changes in this revision

Viewing changes to src/tests/test_ffi.cpp

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2018-03-01 22:23:25 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20180301222325-7p7vc45gu3hta34d
Tags: 2.4.0-2
* Don't remove .doctrees from the manual if it doesn't exist.
* Don't specify parallel to debhelper.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* (C) 2015 Jack Lloyd
 
3
* (C) 2016 René Korthaus
 
4
*
 
5
* Botan is released under the Simplified BSD License (see license.txt)
 
6
*/
 
7
 
 
8
#include "tests.h"
 
9
#include <botan/version.h>
 
10
 
 
11
#if defined(BOTAN_HAS_FFI)
 
12
   #include <botan/hex.h>
 
13
   #include <botan/ffi.h>
 
14
   #include <botan/loadstor.h>
 
15
#endif
 
16
 
 
17
namespace Botan_Tests {
 
18
 
 
19
namespace {
 
20
 
 
21
#if defined(BOTAN_HAS_FFI)
 
22
 
 
23
#define TEST_FFI_OK(func, args) result.test_rc_ok(#func, func args)
 
24
#define TEST_FFI_FAIL(msg, func, args) result.test_rc_fail(#func, msg, func args)
 
25
#define TEST_FFI_RC(rc, func, args) result.test_rc(#func, rc, func args)
 
26
 
 
27
#define REQUIRE_FFI_OK(func, args)                           \
 
28
   if(!TEST_FFI_OK(func, args)) {                            \
 
29
      result.test_note("Exiting test early due to failure"); \
 
30
      return result;                                         \
 
31
   }
 
32
 
 
33
class FFI_Unit_Tests final : public Test
 
34
   {
 
35
   public:
 
36
      std::vector<Test::Result> run() override
 
37
         {
 
38
         Test::Result result("FFI");
 
39
 
 
40
         result.test_is_eq("FFI API version", botan_ffi_api_version(), uint32_t(BOTAN_HAS_FFI));
 
41
         result.test_is_eq("Major version", botan_version_major(), Botan::version_major());
 
42
         result.test_is_eq("Minor version", botan_version_minor(), Botan::version_minor());
 
43
         result.test_is_eq("Patch version", botan_version_patch(), Botan::version_patch());
 
44
         result.test_is_eq("Botan version", botan_version_string(), Botan::version_cstr());
 
45
         result.test_is_eq("Botan version datestamp", botan_version_datestamp(), Botan::version_datestamp());
 
46
         result.test_is_eq("FFI supports its own version", botan_ffi_supports_api(botan_ffi_api_version()), 0);
 
47
 
 
48
         const std::vector<uint8_t> mem1 = { 0xFF, 0xAA, 0xFF };
 
49
         const std::vector<uint8_t> mem2 = mem1;
 
50
         const std::vector<uint8_t> mem3 = { 0xFF, 0xA9, 0xFF };
 
51
 
 
52
         TEST_FFI_RC(0, botan_same_mem, (mem1.data(), mem2.data(), mem1.size()));
 
53
         TEST_FFI_RC(-1, botan_same_mem, (mem1.data(), mem3.data(), mem1.size()));
 
54
 
 
55
         std::vector<uint8_t> to_zero = { 0xFF, 0xA0 };
 
56
         TEST_FFI_OK(botan_scrub_mem, (to_zero.data(), to_zero.size()));
 
57
         result.confirm("scrub_memory zeros", to_zero[0] == 0 && to_zero[1] == 0);
 
58
 
 
59
         const std::vector<uint8_t> bin = { 0xAA, 0xDE, 0x01 };
 
60
         const char* input_str = "ABC";
 
61
 
 
62
         std::string outstr;
 
63
         std::vector<uint8_t> outbuf;
 
64
         //char namebuf[32];
 
65
 
 
66
         outstr.resize(2 * bin.size());
 
67
         TEST_FFI_OK(botan_hex_encode, (bin.data(), bin.size(), &outstr[0], 0));
 
68
         result.test_eq("uppercase hex", outstr, "AADE01");
 
69
 
 
70
         TEST_FFI_OK(botan_hex_encode, (bin.data(), bin.size(), &outstr[0], BOTAN_FFI_HEX_LOWER_CASE));
 
71
         result.test_eq("lowercase hex", outstr, "aade01");
 
72
 
 
73
         // RNG test and initialization
 
74
         botan_rng_t rng;
 
75
 
 
76
         TEST_FFI_FAIL("invalid rng type", botan_rng_init, (&rng, "invalid_type"));
 
77
 
 
78
         outbuf.resize(512);
 
79
 
 
80
         if(TEST_FFI_OK(botan_rng_init, (&rng, "system")))
 
81
            {
 
82
            TEST_FFI_OK(botan_rng_get, (rng, outbuf.data(), outbuf.size()));
 
83
            TEST_FFI_OK(botan_rng_reseed, (rng, 256));
 
84
            TEST_FFI_OK(botan_rng_destroy, (rng));
 
85
            }
 
86
 
 
87
         if(TEST_FFI_OK(botan_rng_init, (&rng, "user")))
 
88
            {
 
89
            TEST_FFI_OK(botan_rng_get, (rng, outbuf.data(), outbuf.size()));
 
90
            TEST_FFI_OK(botan_rng_reseed, (rng, 256));
 
91
            // used for the rest of this function and destroyed at the end
 
92
            }
 
93
         else
 
94
            {
 
95
            result.test_note("Existing early due to missing FFI RNG");
 
96
            return {result};
 
97
            }
 
98
 
 
99
         // hashing test
 
100
         botan_hash_t hash;
 
101
         TEST_FFI_FAIL("invalid hash name", botan_hash_init, (&hash, "SHA-255", 0));
 
102
         TEST_FFI_FAIL("invalid flags", botan_hash_init, (&hash, "SHA-256", 1));
 
103
 
 
104
         if(TEST_FFI_OK(botan_hash_init, (&hash, "SHA-256", 0)))
 
105
            {
 
106
            /*
 
107
            TEST_FFI_FAIL("output buffer too short", botan_hash_name, (hash, namebuf, 5));
 
108
 
 
109
            if(TEST_FFI_OK(botan_hash_name, (hash, namebuf, sizeof(namebuf))))
 
110
            {
 
111
            result.test_eq("hash name", std::string(namebuf), "SHA-256");
 
112
            }
 
113
            */
 
114
            size_t block_size;
 
115
            if (TEST_FFI_OK(botan_hash_block_size, (hash, &block_size)))
 
116
               {
 
117
                  result.test_eq("hash block size", block_size, 64);
 
118
               }
 
119
 
 
120
            size_t output_len;
 
121
            if(TEST_FFI_OK(botan_hash_output_length, (hash, &output_len)))
 
122
               {
 
123
               result.test_eq("hash output length", output_len, 32);
 
124
 
 
125
               outbuf.resize(output_len);
 
126
 
 
127
               // Test that after clear or final the object can be reused
 
128
               for(size_t r = 0; r != 2; ++r)
 
129
                  {
 
130
                  TEST_FFI_OK(botan_hash_update, (hash, reinterpret_cast<const uint8_t*>(input_str), 1));
 
131
                  TEST_FFI_OK(botan_hash_clear, (hash));
 
132
 
 
133
                  TEST_FFI_OK(botan_hash_update, (hash, reinterpret_cast<const uint8_t*>(input_str), std::strlen(input_str)));
 
134
                  TEST_FFI_OK(botan_hash_final, (hash, outbuf.data()));
 
135
 
 
136
                  result.test_eq("SHA-256 output", outbuf, "B5D4045C3F466FA91FE2CC6ABE79232A1A57CDF104F7A26E716E0A1E2789DF78");
 
137
                  }
 
138
 
 
139
               // Test botan_hash_copy_state
 
140
               const char *msg = "message digest";
 
141
               const char *expected = "F7846F55CF23E14EEBEAB5B4E1550CAD5B509E3348FBC4EFA3A1413D393CB650";
 
142
               TEST_FFI_OK(botan_hash_clear, (hash));
 
143
               TEST_FFI_OK(botan_hash_update, (hash, reinterpret_cast<const uint8_t*>(&msg[0]), 1));
 
144
               botan_hash_t fork;
 
145
               if (TEST_FFI_OK(botan_hash_copy_state, (&fork, hash)))
 
146
                  {
 
147
                  TEST_FFI_OK(botan_hash_update, (fork, reinterpret_cast<const uint8_t*>(&msg[1]), std::strlen(msg) - 2));
 
148
 
 
149
                  TEST_FFI_OK(botan_hash_update, (hash, reinterpret_cast<const uint8_t*>(&msg[1]), std::strlen(msg) - 1));
 
150
                  TEST_FFI_OK(botan_hash_final, (hash, outbuf.data()));
 
151
                  result.test_eq("hashing split", outbuf, expected);
 
152
 
 
153
                  TEST_FFI_OK(botan_hash_update, (fork, reinterpret_cast<const uint8_t*>(&msg[std::strlen(msg)-1]), 1));
 
154
                  TEST_FFI_OK(botan_hash_final, (fork, outbuf.data()));
 
155
                  result.test_eq("hashing split", outbuf, expected);
 
156
 
 
157
                  TEST_FFI_OK(botan_hash_destroy, (fork));
 
158
                  }
 
159
               }
 
160
 
 
161
            TEST_FFI_OK(botan_hash_destroy, (hash));
 
162
            }
 
163
 
 
164
         // MAC test
 
165
         botan_mac_t mac;
 
166
         TEST_FFI_FAIL("bad flag", botan_mac_init, (&mac, "HMAC(SHA-256)", 1));
 
167
         TEST_FFI_FAIL("bad name", botan_mac_init, (&mac, "HMAC(SHA-259)", 0));
 
168
 
 
169
         if(TEST_FFI_OK(botan_mac_init, (&mac, "HMAC(SHA-256)", 0)))
 
170
            {
 
171
            /*
 
172
            TEST_FFI_FAIL("output buffer too short", botan_mac_name, (mac, namebuf, 5));
 
173
 
 
174
            if(TEST_FFI_OK(botan_mac_name, (mac, namebuf, 20)))
 
175
            {
 
176
            result.test_eq("mac name", std::string(namebuf), "HMAC(SHA-256)");
 
177
            }
 
178
            */
 
179
 
 
180
            size_t output_len;
 
181
            if(TEST_FFI_OK(botan_mac_output_length, (mac, &output_len)))
 
182
               {
 
183
               result.test_eq("MAC output length", output_len, 32);
 
184
 
 
185
               const uint8_t mac_key[] = { 0xAA, 0xBB, 0xCC, 0xDD };
 
186
               outbuf.resize(output_len);
 
187
 
 
188
               // Test that after clear or final the object can be reused
 
189
               for(size_t r = 0; r != 2; ++r)
 
190
                  {
 
191
                  TEST_FFI_OK(botan_mac_set_key, (mac, mac_key, sizeof(mac_key)));
 
192
                  TEST_FFI_OK(botan_mac_update, (mac, reinterpret_cast<const uint8_t*>(input_str), std::strlen(input_str)));
 
193
                  TEST_FFI_OK(botan_mac_clear, (mac));
 
194
 
 
195
                  TEST_FFI_OK(botan_mac_set_key, (mac, mac_key, sizeof(mac_key)));
 
196
                  TEST_FFI_OK(botan_mac_update, (mac, reinterpret_cast<const uint8_t*>(input_str), std::strlen(input_str)));
 
197
                  TEST_FFI_OK(botan_mac_final, (mac, outbuf.data()));
 
198
 
 
199
                  result.test_eq("HMAC output", outbuf, "1A82EEA984BC4A7285617CC0D05F1FE1D6C96675924A81BC965EE8FF7B0697A7");
 
200
                  }
 
201
               }
 
202
 
 
203
            TEST_FFI_OK(botan_mac_destroy, (mac));
 
204
            }
 
205
 
 
206
         // KDF test
 
207
         const std::vector<uint8_t> pbkdf_salt = Botan::hex_decode("ED1F39A0A7F3889AAF7E60743B3BC1CC2C738E60");
 
208
         const std::string passphrase = "ltexmfeyylmlbrsyikaw";
 
209
         const size_t pbkdf_out_len = 10;
 
210
         const size_t pbkdf_iterations = 1000;
 
211
 
 
212
         outbuf.resize(pbkdf_out_len);
 
213
 
 
214
         if(TEST_FFI_OK(botan_pbkdf, ("PBKDF2(SHA-1)",
 
215
                                      outbuf.data(), outbuf.size(),
 
216
                                      passphrase.c_str(),
 
217
                                      pbkdf_salt.data(), pbkdf_salt.size(),
 
218
                                      pbkdf_iterations)))
 
219
            {
 
220
            result.test_eq("PBKDF output", outbuf, "027AFADD48F4BE8DCC4F");
 
221
            }
 
222
 
 
223
         size_t iters_10ms, iters_100ms;
 
224
 
 
225
         TEST_FFI_OK(botan_pbkdf_timed, ("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
 
226
                                         passphrase.c_str(),
 
227
                                         pbkdf_salt.data(), pbkdf_salt.size(),
 
228
                                         10, &iters_10ms));
 
229
         TEST_FFI_OK(botan_pbkdf_timed, ("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
 
230
                                         passphrase.c_str(),
 
231
                                         pbkdf_salt.data(), pbkdf_salt.size(),
 
232
                                         100, &iters_100ms));
 
233
 
 
234
         result.test_note("PBKDF timed 10 ms " + std::to_string(iters_10ms) + " iterations " +
 
235
                          "100 ms " + std::to_string(iters_100ms) + " iterations");
 
236
 
 
237
#if defined(BOTAN_HAS_KDF2)
 
238
         const std::vector<uint8_t> kdf_secret = Botan::hex_decode("92167440112E");
 
239
         const std::vector<uint8_t> kdf_salt = Botan::hex_decode("45A9BEDED69163123D0348F5185F61ABFB1BF18D6AEA454F");
 
240
         const size_t kdf_out_len = 18;
 
241
         outbuf.resize(kdf_out_len);
 
242
 
 
243
         if(TEST_FFI_OK(botan_kdf, ("KDF2(SHA-1)", outbuf.data(), outbuf.size(),
 
244
                                    kdf_secret.data(),
 
245
                                    kdf_secret.size(),
 
246
                                    kdf_salt.data(),
 
247
                                    kdf_salt.size(),
 
248
                                    nullptr,
 
249
                                    0)))
 
250
            {
 
251
            result.test_eq("KDF output", outbuf, "3A5DC9AA1C872B4744515AC2702D6396FC2A");
 
252
            }
 
253
#endif
 
254
 
 
255
         size_t out_len = 64;
 
256
         outstr.resize(out_len);
 
257
 
 
258
         int rc = botan_bcrypt_generate(reinterpret_cast<uint8_t*>(&outstr[0]),
 
259
                                        &out_len, passphrase.c_str(), rng, 4, 0);
 
260
 
 
261
         if(rc == 0)
 
262
            {
 
263
            result.test_eq("bcrypt output size", out_len, 61);
 
264
 
 
265
            TEST_FFI_OK(botan_bcrypt_is_valid, (passphrase.c_str(), outstr.data()));
 
266
            TEST_FFI_FAIL("bad password", botan_bcrypt_is_valid, ("nope", outstr.data()));
 
267
            }
 
268
 
 
269
#if defined(BOTAN_HAS_ECDSA)
 
270
         // x509 cert test
 
271
         botan_x509_cert_t cert;
 
272
         if(TEST_FFI_OK(botan_x509_cert_load_file, (&cert, Test::data_file("x509/ecc/CSCA.CSCA.csca-germany.1.crt").c_str())))
 
273
            {
 
274
            size_t date_len = 0;
 
275
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_time_starts, (cert, nullptr, &date_len));
 
276
 
 
277
            std::string date(date_len - 1, '0');
 
278
            TEST_FFI_OK(botan_x509_cert_get_time_starts, (cert, &date[0], &date_len));
 
279
            result.test_eq("cert valid from", date, "070719152718Z");
 
280
 
 
281
            date_len = 0;
 
282
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_time_expires, (cert, nullptr, &date_len));
 
283
 
 
284
            date.resize(date_len - 1);
 
285
            TEST_FFI_OK(botan_x509_cert_get_time_expires, (cert, &date[0], &date_len));
 
286
            result.test_eq("cert valid until", date, "280119151800Z");
 
287
 
 
288
            size_t serial_len = 0;
 
289
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_serial_number, (cert, nullptr, &serial_len));
 
290
 
 
291
            std::vector<uint8_t> serial(serial_len);
 
292
            TEST_FFI_OK(botan_x509_cert_get_serial_number, (cert, serial.data(), &serial_len));
 
293
            result.test_eq("cert serial length", serial.size(), 1);
 
294
            result.test_int_eq(serial[0], 1, "cert serial");
 
295
 
 
296
            size_t fingerprint_len = 0;
 
297
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_fingerprint,
 
298
                        (cert, "SHA-256", nullptr, &fingerprint_len));
 
299
 
 
300
            std::vector<uint8_t> fingerprint(fingerprint_len);
 
301
            TEST_FFI_OK(botan_x509_cert_get_fingerprint, (cert, "SHA-256", fingerprint.data(), &fingerprint_len));
 
302
            result.test_eq("cert fingerprint", reinterpret_cast<const char*>(fingerprint.data()),
 
303
                           "3B:6C:99:1C:D6:5A:51:FC:EB:17:E3:AA:F6:3C:1A:DA:14:1F:82:41:30:6F:64:EE:FF:63:F3:1F:D6:07:14:9F");
 
304
 
 
305
            size_t key_id_len = 0;
 
306
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_authority_key_id,
 
307
                        (cert, nullptr, &key_id_len));
 
308
 
 
309
            std::vector<uint8_t> key_id(key_id_len);
 
310
            TEST_FFI_OK(botan_x509_cert_get_authority_key_id, (cert, key_id.data(), &key_id_len));
 
311
            result.test_eq("cert authority key id", Botan::hex_encode(key_id.data(), key_id.size(), true),
 
312
                           "0096452DE588F966C4CCDF161DD1F3F5341B71E7");
 
313
 
 
314
            key_id_len = 0;
 
315
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_subject_key_id,
 
316
                        (cert, nullptr, &key_id_len));
 
317
 
 
318
            key_id.resize(key_id_len);
 
319
            TEST_FFI_OK(botan_x509_cert_get_subject_key_id, (cert, key_id.data(), &key_id_len));
 
320
            result.test_eq("cert subject key id", Botan::hex_encode(key_id.data(), key_id.size(), true),
 
321
                           "0096452DE588F966C4CCDF161DD1F3F5341B71E7");
 
322
 
 
323
            size_t pubkey_len = 0;
 
324
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_public_key_bits,
 
325
                        (cert, nullptr, &pubkey_len));
 
326
 
 
327
            std::vector<uint8_t> pubkey(pubkey_len);
 
328
            TEST_FFI_OK(botan_x509_cert_get_public_key_bits, (cert, pubkey.data(), &pubkey_len));
 
329
 
 
330
            botan_pubkey_t pub;
 
331
            if(TEST_FFI_OK(botan_x509_cert_get_public_key, (cert, &pub)))
 
332
               {
 
333
               TEST_FFI_OK(botan_pubkey_destroy, (pub));
 
334
               }
 
335
 
 
336
            size_t dn_len = 0;
 
337
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_issuer_dn,
 
338
                        (cert, "Name", 0, nullptr, &dn_len));
 
339
 
 
340
            std::vector<uint8_t> dn(dn_len);
 
341
            TEST_FFI_OK(botan_x509_cert_get_issuer_dn, (cert, "Name", 0, dn.data(), &dn_len));
 
342
            result.test_eq("issuer dn", reinterpret_cast<const char*>(dn.data()), "csca-germany");
 
343
 
 
344
            dn_len = 0;
 
345
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_subject_dn,
 
346
                        (cert, "Name", 0, nullptr, &dn_len));
 
347
 
 
348
            dn.resize(dn_len);
 
349
            TEST_FFI_OK(botan_x509_cert_get_subject_dn, (cert, "Name", 0, dn.data(), &dn_len));
 
350
            result.test_eq("subject dn", reinterpret_cast<const char*>(dn.data()), "csca-germany");
 
351
 
 
352
            size_t printable_len = 0;
 
353
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_to_string,
 
354
                        (cert, nullptr, &printable_len));
 
355
 
 
356
            std::string printable(printable_len - 1, '0');
 
357
            TEST_FFI_OK(botan_x509_cert_to_string, (cert, &printable[0], &printable_len));
 
358
 
 
359
            TEST_FFI_RC(0, botan_x509_cert_allowed_usage, (cert, KEY_CERT_SIGN));
 
360
            TEST_FFI_RC(0, botan_x509_cert_allowed_usage, (cert, CRL_SIGN));
 
361
            TEST_FFI_RC(1, botan_x509_cert_allowed_usage, (cert, DIGITAL_SIGNATURE));
 
362
 
 
363
            TEST_FFI_OK(botan_x509_cert_destroy, (cert));
 
364
            }
 
365
#endif
 
366
 
 
367
         std::vector<Test::Result> results;
 
368
         results.push_back(ffi_test_errors());
 
369
         results.push_back(ffi_test_base64());
 
370
         results.push_back(ffi_test_mp(rng));
 
371
         results.push_back(ffi_test_block_ciphers());
 
372
         results.push_back(ffi_test_ciphers_cbc());
 
373
         results.push_back(ffi_test_ciphers_aead_gcm());
 
374
         results.push_back(ffi_test_ciphers_aead_eax());
 
375
         results.push_back(ffi_test_stream_ciphers());
 
376
         results.push_back(ffi_test_pkcs_hash_id());
 
377
 
 
378
#if defined(BOTAN_HAS_RFC3394_KEYWRAP)
 
379
         results.push_back(ffi_test_keywrap());
 
380
#endif
 
381
 
 
382
#if defined(BOTAN_HAS_RSA)
 
383
         results.push_back(ffi_test_rsa(rng));
 
384
#endif
 
385
 
 
386
#if defined(BOTAN_HAS_DSA)
 
387
         results.push_back(ffi_test_dsa(rng));
 
388
#endif
 
389
 
 
390
#if defined(BOTAN_HAS_ECDSA)
 
391
         results.push_back(ffi_test_ecdsa(rng));
 
392
#endif
 
393
 
 
394
#if defined(BOTAN_HAS_ECDH)
 
395
         results.push_back(ffi_test_ecdh(rng));
 
396
#endif
 
397
 
 
398
#if defined(BOTAN_HAS_SM2)
 
399
         results.push_back(ffi_test_sm2(rng));
 
400
         results.push_back(ffi_test_sm2_enc(rng));
 
401
#endif
 
402
 
 
403
#if defined(BOTAN_HAS_MCELIECE)
 
404
         results.push_back(ffi_test_mceliece(rng));
 
405
#endif
 
406
 
 
407
#if defined(BOTAN_HAS_ELGAMAL)
 
408
         results.push_back(ffi_test_elgamal(rng));
 
409
#endif
 
410
 
 
411
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
 
412
         results.push_back(ffi_test_dh(rng));
 
413
#endif
 
414
 
 
415
#if defined(BOTAN_HAS_ED25519)
 
416
         results.push_back(ffi_test_ed25519(rng));
 
417
#endif
 
418
 
 
419
         TEST_FFI_OK(botan_rng_destroy, (rng));
 
420
 
 
421
         results.push_back(result);
 
422
         return results;
 
423
         }
 
424
 
 
425
   private:
 
426
      Test::Result ffi_test_pkcs_hash_id()
 
427
         {
 
428
         Test::Result result("FFI PKCS hash id");
 
429
 
 
430
#if defined(BOTAN_HAS_HASH_ID)
 
431
         std::vector<uint8_t> hash_id(64);
 
432
         size_t hash_id_len;
 
433
 
 
434
         hash_id_len = 3; // too short
 
435
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE,
 
436
                     botan_pkcs_hash_id, ("SHA-256", hash_id.data(), &hash_id_len));
 
437
 
 
438
         result.test_eq("Expected SHA-256 PKCS hash id len", hash_id_len, 19);
 
439
 
 
440
         TEST_FFI_OK(botan_pkcs_hash_id, ("SHA-256", hash_id.data(), &hash_id_len));
 
441
 
 
442
         result.test_eq("Expected SHA-256 PKCS hash id len", hash_id_len, 19);
 
443
 
 
444
         hash_id.resize(hash_id_len);
 
445
         result.test_eq("Expected SHA_256 PKCS hash id",
 
446
                        hash_id, "3031300D060960864801650304020105000420");
 
447
#endif
 
448
 
 
449
         return result;
 
450
         }
 
451
 
 
452
      Test::Result ffi_test_ciphers_cbc()
 
453
         {
 
454
         Test::Result result("FFI CBC cipher");
 
455
 
 
456
         botan_cipher_t cipher_encrypt, cipher_decrypt;
 
457
 
 
458
         if(TEST_FFI_OK(botan_cipher_init, (&cipher_encrypt, "AES-128/CBC/PKCS7", BOTAN_CIPHER_INIT_FLAG_ENCRYPT)))
 
459
            {
 
460
            size_t min_keylen = 0;
 
461
            size_t max_keylen = 0;
 
462
            TEST_FFI_OK(botan_cipher_query_keylen, (cipher_encrypt, &min_keylen, &max_keylen));
 
463
            result.test_int_eq(min_keylen, 16, "Min key length");
 
464
            result.test_int_eq(max_keylen, 16, "Max key length");
 
465
 
 
466
            // from https://github.com/geertj/bluepass/blob/master/tests/vectors/aes-cbc-pkcs7.txt
 
467
            const std::vector<uint8_t> plaintext =
 
468
               Botan::hex_decode("0397f4f6820b1f9386f14403be5ac16e50213bd473b4874b9bcbf5f318ee686b1d");
 
469
            const std::vector<uint8_t> symkey = Botan::hex_decode("898be9cc5004ed0fa6e117c9a3099d31");
 
470
            const std::vector<uint8_t> nonce = Botan::hex_decode("9dea7621945988f96491083849b068df");
 
471
            const std::vector<uint8_t> exp_ciphertext =
 
472
               Botan::hex_decode("e232cd6ef50047801ee681ec30f61d53cfd6b0bca02fd03c1b234baa10ea82ac9dab8b960926433a19ce6dea08677e34");
 
473
 
 
474
            std::vector<uint8_t> ciphertext(16 + plaintext.size()); // TODO: no way to know this size from API
 
475
 
 
476
            size_t output_written = 0;
 
477
            size_t input_consumed = 0;
 
478
 
 
479
            // Test that after clear or final the object can be reused
 
480
            for(size_t r = 0; r != 2; ++r)
 
481
               {
 
482
               TEST_FFI_OK(botan_cipher_set_key, (cipher_encrypt, symkey.data(), symkey.size()));
 
483
               TEST_FFI_OK(botan_cipher_start, (cipher_encrypt, nonce.data(), nonce.size()));
 
484
               TEST_FFI_OK(botan_cipher_update, (cipher_encrypt, 0, ciphertext.data(), ciphertext.size(), &output_written,
 
485
                                                 plaintext.data(), plaintext.size(), &input_consumed));
 
486
               TEST_FFI_OK(botan_cipher_clear, (cipher_encrypt));
 
487
 
 
488
               TEST_FFI_OK(botan_cipher_set_key, (cipher_encrypt, symkey.data(), symkey.size()));
 
489
               TEST_FFI_OK(botan_cipher_start, (cipher_encrypt, nonce.data(), nonce.size()));
 
490
               TEST_FFI_OK(botan_cipher_update, (cipher_encrypt, BOTAN_CIPHER_UPDATE_FLAG_FINAL,
 
491
                                                 ciphertext.data(), ciphertext.size(), &output_written,
 
492
                                                 plaintext.data(), plaintext.size(), &input_consumed));
 
493
 
 
494
               ciphertext.resize(output_written);
 
495
               result.test_eq("AES/CBC ciphertext", ciphertext, exp_ciphertext);
 
496
 
 
497
               if(TEST_FFI_OK(botan_cipher_init, (&cipher_decrypt, "AES-128/CBC", BOTAN_CIPHER_INIT_FLAG_DECRYPT)))
 
498
                  {
 
499
                  std::vector<uint8_t> decrypted(plaintext.size());
 
500
 
 
501
                  TEST_FFI_OK(botan_cipher_set_key, (cipher_decrypt, symkey.data(), symkey.size()));
 
502
                  TEST_FFI_OK(botan_cipher_start, (cipher_decrypt, nonce.data(), nonce.size()));
 
503
                  TEST_FFI_OK(botan_cipher_update, (cipher_decrypt, BOTAN_CIPHER_UPDATE_FLAG_FINAL,
 
504
                                                    decrypted.data(), decrypted.size(),   &output_written,
 
505
                                                    ciphertext.data(), ciphertext.size(), &input_consumed));
 
506
 
 
507
                  result.test_eq("AES/CBC plaintext", decrypted, plaintext);
 
508
 
 
509
                  TEST_FFI_OK(botan_cipher_destroy, (cipher_decrypt));
 
510
                  }
 
511
               }
 
512
 
 
513
            TEST_FFI_OK(botan_cipher_destroy, (cipher_encrypt));
 
514
            }
 
515
 
 
516
         return result;
 
517
         }
 
518
 
 
519
      Test::Result ffi_test_ciphers_aead_gcm()
 
520
         {
 
521
         Test::Result result("FFI GCM");
 
522
 
 
523
#if defined(BOTAN_HAS_AEAD_GCM)
 
524
 
 
525
         botan_cipher_t cipher_encrypt, cipher_decrypt;
 
526
 
 
527
         if(TEST_FFI_OK(botan_cipher_init, (&cipher_encrypt, "AES-128/GCM", BOTAN_CIPHER_INIT_FLAG_ENCRYPT)))
 
528
            {
 
529
            size_t min_keylen = 0;
 
530
            size_t max_keylen = 0;
 
531
            size_t nonce_len = 0;
 
532
            size_t tag_len = 0;
 
533
 
 
534
            TEST_FFI_OK(botan_cipher_query_keylen, (cipher_encrypt, &min_keylen, &max_keylen));
 
535
            result.test_int_eq(min_keylen, 16, "Min key length");
 
536
            result.test_int_eq(max_keylen, 16, "Max key length");
 
537
 
 
538
            TEST_FFI_OK(botan_cipher_get_default_nonce_length, (cipher_encrypt, &nonce_len));
 
539
            result.test_int_eq(nonce_len, 12, "Expected default GCM nonce length");
 
540
 
 
541
            TEST_FFI_OK(botan_cipher_get_tag_length, (cipher_encrypt, &tag_len));
 
542
            result.test_int_eq(tag_len, 16, "Expected GCM tag length");
 
543
 
 
544
            TEST_FFI_RC(1, botan_cipher_valid_nonce_length, (cipher_encrypt, 12));
 
545
            // GCM accepts any nonce size...
 
546
            TEST_FFI_RC(1, botan_cipher_valid_nonce_length, (cipher_encrypt, 0));
 
547
 
 
548
            // NIST test vector
 
549
            const std::vector<uint8_t> plaintext =
 
550
               Botan::hex_decode("D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39");
 
551
 
 
552
            const std::vector<uint8_t> symkey = Botan::hex_decode("FEFFE9928665731C6D6A8F9467308308");
 
553
            const std::vector<uint8_t> nonce = Botan::hex_decode("CAFEBABEFACEDBADDECAF888");
 
554
            const std::vector<uint8_t> exp_ciphertext = Botan::hex_decode(
 
555
                     "42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E0915BC94FBC3221A5DB94FAE95AE7121A47");
 
556
            const std::vector<uint8_t> aad = Botan::hex_decode("FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2");
 
557
 
 
558
            std::vector<uint8_t> ciphertext(tag_len + plaintext.size());
 
559
 
 
560
            size_t output_written = 0;
 
561
            size_t input_consumed = 0;
 
562
 
 
563
            // Test that after clear or final the object can be reused
 
564
            for(size_t r = 0; r != 2; ++r)
 
565
               {
 
566
               TEST_FFI_OK(botan_cipher_set_key, (cipher_encrypt, symkey.data(), symkey.size()));
 
567
               TEST_FFI_OK(botan_cipher_start, (cipher_encrypt, nonce.data(), nonce.size()));
 
568
               TEST_FFI_OK(botan_cipher_update, (cipher_encrypt, 0,
 
569
                                                 ciphertext.data(), ciphertext.size(), &output_written,
 
570
                                                 plaintext.data(), plaintext.size(), &input_consumed));
 
571
               TEST_FFI_OK(botan_cipher_clear, (cipher_encrypt));
 
572
 
 
573
               TEST_FFI_OK(botan_cipher_set_key, (cipher_encrypt, symkey.data(), symkey.size()));
 
574
               TEST_FFI_OK(botan_cipher_set_associated_data, (cipher_encrypt, aad.data(), aad.size()));
 
575
               TEST_FFI_OK(botan_cipher_start, (cipher_encrypt, nonce.data(), nonce.size()));
 
576
               TEST_FFI_OK(botan_cipher_update, (cipher_encrypt, BOTAN_CIPHER_UPDATE_FLAG_FINAL,
 
577
                                                 ciphertext.data(), ciphertext.size(), &output_written,
 
578
                                                 plaintext.data(), plaintext.size(), &input_consumed));
 
579
 
 
580
               ciphertext.resize(output_written);
 
581
               result.test_eq("AES/GCM ciphertext", ciphertext, exp_ciphertext);
 
582
 
 
583
               if(TEST_FFI_OK(botan_cipher_init, (&cipher_decrypt, "AES-128/GCM", BOTAN_CIPHER_INIT_FLAG_DECRYPT)))
 
584
                  {
 
585
                  std::vector<uint8_t> decrypted(plaintext.size());
 
586
 
 
587
                  TEST_FFI_OK(botan_cipher_set_key, (cipher_decrypt, symkey.data(), symkey.size()));
 
588
                  TEST_FFI_OK(botan_cipher_set_associated_data, (cipher_decrypt, aad.data(), aad.size()));
 
589
                  TEST_FFI_OK(botan_cipher_start, (cipher_decrypt, nonce.data(), nonce.size()));
 
590
                  TEST_FFI_OK(botan_cipher_update, (cipher_decrypt, BOTAN_CIPHER_UPDATE_FLAG_FINAL,
 
591
                                                    decrypted.data(), decrypted.size(), &output_written,
 
592
                                                    ciphertext.data(), ciphertext.size(), &input_consumed));
 
593
 
 
594
                  result.test_int_eq(input_consumed, ciphertext.size(), "All input consumed");
 
595
                  result.test_int_eq(output_written, decrypted.size(), "Expected output size produced");
 
596
                  result.test_eq("AES/GCM plaintext", decrypted, plaintext);
 
597
 
 
598
                  TEST_FFI_OK(botan_cipher_destroy, (cipher_decrypt));
 
599
                  }
 
600
               }
 
601
 
 
602
            TEST_FFI_OK(botan_cipher_destroy, (cipher_encrypt));
 
603
            }
 
604
#endif
 
605
 
 
606
         return result;
 
607
         }
 
608
 
 
609
      Test::Result ffi_test_ciphers_aead_eax()
 
610
         {
 
611
         Test::Result result("FFI EAX");
 
612
 
 
613
#if defined(BOTAN_HAS_AEAD_EAX)
 
614
 
 
615
         botan_cipher_t cipher_encrypt, cipher_decrypt;
 
616
 
 
617
         if(TEST_FFI_OK(botan_cipher_init, (&cipher_encrypt, "AES-128/EAX", BOTAN_CIPHER_INIT_FLAG_ENCRYPT)))
 
618
            {
 
619
            size_t min_keylen = 0;
 
620
            size_t max_keylen = 0;
 
621
            size_t nonce_len = 0;
 
622
            size_t tag_len = 0;
 
623
 
 
624
            TEST_FFI_OK(botan_cipher_query_keylen, (cipher_encrypt, &min_keylen, &max_keylen));
 
625
            result.test_int_eq(min_keylen, 16, "Min key length");
 
626
            result.test_int_eq(max_keylen, 16, "Max key length");
 
627
 
 
628
            TEST_FFI_OK(botan_cipher_get_default_nonce_length, (cipher_encrypt, &nonce_len));
 
629
            result.test_int_eq(nonce_len, 12, "Expected default EAX nonce length");
 
630
 
 
631
            TEST_FFI_OK(botan_cipher_get_tag_length, (cipher_encrypt, &tag_len));
 
632
            result.test_int_eq(tag_len, 16, "Expected EAX tag length");
 
633
 
 
634
            TEST_FFI_RC(1, botan_cipher_valid_nonce_length, (cipher_encrypt, 12));
 
635
            // EAX accepts any nonce size...
 
636
            TEST_FFI_RC(1, botan_cipher_valid_nonce_length, (cipher_encrypt, 0));
 
637
 
 
638
            const std::vector<uint8_t> plaintext =
 
639
               Botan::hex_decode("0000000000000000000000000000000011111111111111111111111111111111");
 
640
            const std::vector<uint8_t> symkey = Botan::hex_decode("000102030405060708090a0b0c0d0e0f");
 
641
            const std::vector<uint8_t> nonce = Botan::hex_decode("3c8cc2970a008f75cc5beae2847258c2");
 
642
            const std::vector<uint8_t> exp_ciphertext =
 
643
               Botan::hex_decode("3c441f32ce07822364d7a2990e50bb13d7b02a26969e4a937e5e9073b0d9c968db90bdb3da3d00afd0fc6a83551da95e");
 
644
 
 
645
            std::vector<uint8_t> ciphertext(tag_len + plaintext.size());
 
646
 
 
647
            size_t output_written = 0;
 
648
            size_t input_consumed = 0;
 
649
 
 
650
            // Test that after clear or final the object can be reused
 
651
            for(size_t r = 0; r != 2; ++r)
 
652
               {
 
653
               TEST_FFI_OK(botan_cipher_set_key, (cipher_encrypt, symkey.data(), symkey.size()));
 
654
               TEST_FFI_OK(botan_cipher_start, (cipher_encrypt, nonce.data(), nonce.size()));
 
655
               TEST_FFI_OK(botan_cipher_update, (cipher_encrypt, 0,
 
656
                                                 ciphertext.data(), ciphertext.size(), &output_written,
 
657
                                                 plaintext.data(), plaintext.size(), &input_consumed));
 
658
               TEST_FFI_OK(botan_cipher_clear, (cipher_encrypt));
 
659
 
 
660
               TEST_FFI_OK(botan_cipher_set_key, (cipher_encrypt, symkey.data(), symkey.size()));
 
661
               TEST_FFI_OK(botan_cipher_start, (cipher_encrypt, nonce.data(), nonce.size()));
 
662
               TEST_FFI_OK(botan_cipher_update, (cipher_encrypt, BOTAN_CIPHER_UPDATE_FLAG_FINAL,
 
663
                                                 ciphertext.data(), ciphertext.size(), &output_written,
 
664
                                                 plaintext.data(), plaintext.size(), &input_consumed));
 
665
 
 
666
               ciphertext.resize(output_written);
 
667
               result.test_eq("AES/EAX ciphertext", ciphertext, exp_ciphertext);
 
668
 
 
669
               if(TEST_FFI_OK(botan_cipher_init, (&cipher_decrypt, "AES-128/EAX", BOTAN_CIPHER_INIT_FLAG_DECRYPT)))
 
670
                  {
 
671
                  std::vector<uint8_t> decrypted(plaintext.size());
 
672
 
 
673
                  TEST_FFI_OK(botan_cipher_set_key, (cipher_decrypt, symkey.data(), symkey.size()));
 
674
                  TEST_FFI_OK(botan_cipher_start, (cipher_decrypt, nonce.data(), nonce.size()));
 
675
                  TEST_FFI_OK(botan_cipher_update, (cipher_decrypt, BOTAN_CIPHER_UPDATE_FLAG_FINAL,
 
676
                                                    decrypted.data(), decrypted.size(), &output_written,
 
677
                                                    ciphertext.data(), ciphertext.size(), &input_consumed));
 
678
 
 
679
                  result.test_int_eq(input_consumed, ciphertext.size(), "All input consumed");
 
680
                  result.test_int_eq(output_written, decrypted.size(), "Expected output size produced");
 
681
                  result.test_eq("AES/EAX plaintext", decrypted, plaintext);
 
682
 
 
683
                  TEST_FFI_OK(botan_cipher_destroy, (cipher_decrypt));
 
684
                  }
 
685
               }
 
686
 
 
687
            TEST_FFI_OK(botan_cipher_destroy, (cipher_encrypt));
 
688
            }
 
689
#endif
 
690
 
 
691
         return result;
 
692
         }
 
693
 
 
694
      Test::Result ffi_test_stream_ciphers()
 
695
         {
 
696
         Test::Result result("FFI stream ciphers");
 
697
 
 
698
#if defined(BOTAN_HAS_CTR_BE)
 
699
 
 
700
         const std::vector<uint8_t> key = Botan::hex_decode("2B7E151628AED2A6ABF7158809CF4F3C");
 
701
         const std::vector<uint8_t> nonce = Botan::hex_decode("F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF");
 
702
         const std::vector<uint8_t> pt = Botan::hex_decode(
 
703
                                            "AE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710");
 
704
         const std::vector<uint8_t> exp_ct = Botan::hex_decode(
 
705
                                                "9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE");
 
706
 
 
707
         botan_cipher_t ctr;
 
708
 
 
709
         std::vector<uint8_t> ct(pt.size());
 
710
 
 
711
         if(TEST_FFI_OK(botan_cipher_init, (&ctr, "AES-128/CTR-BE", BOTAN_CIPHER_INIT_FLAG_ENCRYPT)))
 
712
            {
 
713
            size_t input_consumed = 0;
 
714
            size_t output_written = 0;
 
715
 
 
716
            TEST_FFI_OK(botan_cipher_set_key, (ctr, key.data(), key.size()));
 
717
            TEST_FFI_OK(botan_cipher_start, (ctr, nonce.data(), nonce.size()));
 
718
 
 
719
            // Test partial updates...
 
720
            TEST_FFI_OK(botan_cipher_update, (ctr, 0,
 
721
                                              ct.data(), ct.size(), &output_written,
 
722
                                              pt.data(), 5, &input_consumed));
 
723
 
 
724
            result.test_int_eq(output_written, 5, "Expected output written");
 
725
            result.test_int_eq(input_consumed, 5, "Expected input consumed");
 
726
 
 
727
            TEST_FFI_OK(botan_cipher_update, (ctr, 0,
 
728
                                              &ct[5], ct.size() - 5, &output_written,
 
729
                                              &pt[5], pt.size() - 5, &input_consumed));
 
730
 
 
731
            result.test_int_eq(output_written, ct.size() - 5, "Expected output written");
 
732
            result.test_int_eq(input_consumed, pt.size() - 5, "Expected input consumed");
 
733
            result.test_eq("AES-128/CTR ciphertext", ct, exp_ct);
 
734
 
 
735
            TEST_FFI_OK(botan_cipher_destroy, (ctr));
 
736
            }
 
737
 
 
738
#endif
 
739
 
 
740
         return result;
 
741
         }
 
742
 
 
743
      Test::Result ffi_test_block_ciphers()
 
744
         {
 
745
         Test::Result result("FFI block ciphers");
 
746
 
 
747
         botan_block_cipher_t cipher;
 
748
 
 
749
         if(TEST_FFI_OK(botan_block_cipher_init, (&cipher, "AES-128")))
 
750
            {
 
751
            const std::vector<uint8_t> zero16(16, 0);
 
752
            std::vector<uint8_t> block(16, 0);
 
753
 
 
754
            TEST_FFI_OK(botan_block_cipher_clear, (cipher));
 
755
 
 
756
            TEST_FFI_RC(16, botan_block_cipher_block_size, (cipher));
 
757
 
 
758
            TEST_FFI_OK(botan_block_cipher_set_key, (cipher, zero16.data(), zero16.size()));
 
759
 
 
760
            TEST_FFI_OK(botan_block_cipher_encrypt_blocks, (cipher, block.data(), block.data(), 1));
 
761
            result.test_eq("AES-128 encryption works", block, "66E94BD4EF8A2C3B884CFA59CA342B2E");
 
762
 
 
763
            TEST_FFI_OK(botan_block_cipher_encrypt_blocks, (cipher, block.data(), block.data(), 1));
 
764
            result.test_eq("AES-128 encryption works", block, "F795BD4A52E29ED713D313FA20E98DBC");
 
765
 
 
766
            TEST_FFI_OK(botan_block_cipher_decrypt_blocks, (cipher, block.data(), block.data(), 1));
 
767
            result.test_eq("AES-128 decryption works", block, "66E94BD4EF8A2C3B884CFA59CA342B2E");
 
768
 
 
769
            TEST_FFI_OK(botan_block_cipher_decrypt_blocks, (cipher, block.data(), block.data(), 1));
 
770
            result.test_eq("AES-128 decryption works", block, "00000000000000000000000000000000");
 
771
 
 
772
            TEST_FFI_OK(botan_block_cipher_clear, (cipher));
 
773
            botan_block_cipher_destroy(cipher);
 
774
            }
 
775
 
 
776
         return result;
 
777
         }
 
778
 
 
779
      Test::Result ffi_test_errors()
 
780
         {
 
781
         // Test some error handling situations
 
782
         Test::Result result("FFI error handling");
 
783
 
 
784
         // delete of null is ok/ignored
 
785
         TEST_FFI_RC(0, botan_hash_destroy, (nullptr));
 
786
 
 
787
         // Confirm that botan_x_destroy checks the argument type
 
788
         botan_mp_t mp;
 
789
         botan_mp_init(&mp);
 
790
         TEST_FFI_RC(BOTAN_FFI_ERROR_INVALID_OBJECT, botan_hash_destroy, (reinterpret_cast<botan_hash_t>(mp)));
 
791
         TEST_FFI_RC(0, botan_mp_destroy, (mp));
 
792
 
 
793
         return result;
 
794
         }
 
795
 
 
796
      Test::Result ffi_test_base64()
 
797
         {
 
798
         Test::Result result("FFI base64");
 
799
 
 
800
         const uint8_t bin[9] = { 0x16, 0x8a, 0x1f, 0x06, 0xe9, 0xe7, 0xcb, 0xdd, 0x34 };
 
801
         char out_buf[1024] = { 0 };
 
802
 
 
803
         size_t out_len = sizeof(out_buf);
 
804
         TEST_FFI_OK(botan_base64_encode, (bin, sizeof(bin), out_buf, &out_len));
 
805
 
 
806
         result.test_eq("encoded string", out_buf, "FoofBunny900");
 
807
 
 
808
         out_len -= 1;
 
809
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE,
 
810
                     botan_base64_encode,
 
811
                     (bin, sizeof(bin), out_buf, &out_len));
 
812
 
 
813
         const char* base64 = "U3VjaCBiYXNlNjQgd293IQ==";
 
814
         uint8_t out_bin[1024] = { 0 };
 
815
         out_len = sizeof(out_bin);
 
816
         TEST_FFI_OK(botan_base64_decode, (base64, strlen(base64), out_bin, &out_len));
 
817
 
 
818
         result.test_eq("decoded string",
 
819
                        std::string(reinterpret_cast<const char*>(out_bin), out_len),
 
820
                        "Such base64 wow!");
 
821
 
 
822
         return result;
 
823
         }
 
824
 
 
825
      Test::Result ffi_test_mp(botan_rng_t rng)
 
826
         {
 
827
         Test::Result result("FFI MP");
 
828
 
 
829
         botan_mp_t x;
 
830
         botan_mp_init(&x);
 
831
         TEST_FFI_RC(0, botan_mp_is_odd, (x));
 
832
         TEST_FFI_RC(1, botan_mp_is_even, (x));
 
833
         TEST_FFI_RC(0, botan_mp_is_negative, (x));
 
834
         TEST_FFI_RC(1, botan_mp_is_positive, (x));
 
835
         TEST_FFI_RC(1, botan_mp_is_zero, (x));
 
836
         botan_mp_destroy(x);
 
837
 
 
838
         botan_mp_init(&x);
 
839
         size_t bn_bytes = 0;
 
840
         TEST_FFI_OK(botan_mp_num_bytes, (x, &bn_bytes));
 
841
         result.test_eq("Expected size for MP 0", bn_bytes, 0);
 
842
 
 
843
         botan_mp_set_from_int(x, 5);
 
844
         TEST_FFI_OK(botan_mp_num_bytes, (x, &bn_bytes));
 
845
         result.test_eq("Expected size for MP 5", bn_bytes, 1);
 
846
 
 
847
         botan_mp_set_from_int(x, 259);
 
848
         TEST_FFI_OK(botan_mp_num_bytes, (x, &bn_bytes));
 
849
         result.test_eq("Expected size for MP 259", bn_bytes, 2);
 
850
 
 
851
         TEST_FFI_RC(1, botan_mp_is_odd, (x));
 
852
         TEST_FFI_RC(0, botan_mp_is_even, (x));
 
853
         TEST_FFI_RC(0, botan_mp_is_negative, (x));
 
854
         TEST_FFI_RC(1, botan_mp_is_positive, (x));
 
855
         TEST_FFI_RC(0, botan_mp_is_zero, (x));
 
856
 
 
857
 
 
858
            {
 
859
            botan_mp_t zero;
 
860
            botan_mp_init(&zero);
 
861
            int cmp;
 
862
            TEST_FFI_OK(botan_mp_cmp, (&cmp, x, zero));
 
863
            result.confirm("bigint_mp_cmp(+, 0)", cmp == 1);
 
864
 
 
865
            TEST_FFI_OK(botan_mp_cmp, (&cmp, zero, x));
 
866
            result.confirm("bigint_mp_cmp(0, +)", cmp == -1);
 
867
 
 
868
            TEST_FFI_RC(0, botan_mp_is_negative, (x));
 
869
            TEST_FFI_RC(1, botan_mp_is_positive, (x));
 
870
            TEST_FFI_OK(botan_mp_flip_sign, (x));
 
871
            TEST_FFI_RC(1, botan_mp_is_negative, (x));
 
872
            TEST_FFI_RC(0, botan_mp_is_positive, (x));
 
873
 
 
874
            // test no negative zero
 
875
            TEST_FFI_RC(0, botan_mp_is_negative, (zero));
 
876
            TEST_FFI_RC(1, botan_mp_is_positive, (zero));
 
877
            TEST_FFI_OK(botan_mp_flip_sign, (zero));
 
878
            TEST_FFI_RC(0, botan_mp_is_negative, (zero));
 
879
            TEST_FFI_RC(1, botan_mp_is_positive, (zero));
 
880
 
 
881
            TEST_FFI_OK(botan_mp_cmp, (&cmp, x, zero));
 
882
            result.confirm("bigint_mp_cmp(-, 0)", cmp == -1);
 
883
 
 
884
            TEST_FFI_OK(botan_mp_cmp, (&cmp, zero, x));
 
885
            result.confirm("bigint_mp_cmp(0, -)", cmp == 1);
 
886
 
 
887
            TEST_FFI_OK(botan_mp_cmp, (&cmp, zero, zero));
 
888
            result.confirm("bigint_mp_cmp(0, 0)", cmp == 0);
 
889
 
 
890
            TEST_FFI_OK(botan_mp_cmp, (&cmp, x, x));
 
891
            result.confirm("bigint_mp_cmp(x, x)", cmp == 0);
 
892
 
 
893
            TEST_FFI_OK(botan_mp_flip_sign, (x));
 
894
 
 
895
            botan_mp_destroy(zero);
 
896
            }
 
897
 
 
898
         size_t x_bits = 0;
 
899
         TEST_FFI_OK(botan_mp_num_bits, (x, &x_bits));
 
900
         result.test_eq("botan_mp_num_bits", x_bits, 9);
 
901
 
 
902
         char str_buf[1024] = { 0 };
 
903
         size_t str_len = 0;
 
904
 
 
905
         TEST_FFI_OK(botan_mp_to_hex, (x, str_buf));
 
906
         result.test_eq("botan_mp_to_hex", std::string(str_buf), "0103");
 
907
 
 
908
         uint32_t x_32;
 
909
         TEST_FFI_OK(botan_mp_to_uint32, (x, &x_32));
 
910
         result.test_eq("botan_mp_to_uint32", size_t(x_32), size_t(0x103));
 
911
 
 
912
         TEST_FFI_RC(1, botan_mp_get_bit, (x, 1));
 
913
         TEST_FFI_RC(0, botan_mp_get_bit, (x, 87));
 
914
         TEST_FFI_OK(botan_mp_set_bit, (x, 87));
 
915
         TEST_FFI_RC(1, botan_mp_get_bit, (x, 87));
 
916
         TEST_FFI_OK(botan_mp_to_hex, (x, str_buf));
 
917
         result.test_eq("botan_mp_set_bit", std::string(str_buf), "8000000000000000000103");
 
918
 
 
919
         TEST_FFI_OK(botan_mp_clear_bit, (x, 87));
 
920
         TEST_FFI_OK(botan_mp_to_hex, (x, str_buf));
 
921
         result.test_eq("botan_mp_set_bit", std::string(str_buf), "0103");
 
922
 
 
923
         botan_mp_t y;
 
924
         TEST_FFI_OK(botan_mp_init, (&y));
 
925
         TEST_FFI_OK(botan_mp_set_from_int, (y, 0x1234567));
 
926
 
 
927
         botan_mp_t r;
 
928
         botan_mp_init(&r);
 
929
 
 
930
         TEST_FFI_OK(botan_mp_add, (r, x, y));
 
931
         str_len = sizeof(str_buf);
 
932
         TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
 
933
         result.test_eq("botan_mp_add", std::string(str_buf), "19089002");
 
934
 
 
935
         TEST_FFI_OK(botan_mp_mul, (r, x, y));
 
936
         str_len = sizeof(str_buf);
 
937
         TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
 
938
         result.test_eq("botan_mp_mul", std::string(str_buf), "4943984437");
 
939
         TEST_FFI_RC(0, botan_mp_is_negative, (r));
 
940
 
 
941
         botan_mp_t q;
 
942
         botan_mp_init(&q);
 
943
         TEST_FFI_OK(botan_mp_div, (q, r, y, x));
 
944
 
 
945
         str_len = sizeof(str_buf);
 
946
         TEST_FFI_OK(botan_mp_to_str, (q, 10, str_buf, &str_len));
 
947
         result.test_eq("botan_mp_div_q", std::string(str_buf), "073701");
 
948
 
 
949
         str_len = sizeof(str_buf);
 
950
         TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
 
951
         result.test_eq("botan_mp_div_r", std::string(str_buf), "184");
 
952
 
 
953
         TEST_FFI_OK(botan_mp_set_from_str, (y, "4943984437"));
 
954
         TEST_FFI_OK(botan_mp_sub, (r, x, y));
 
955
         str_len = sizeof(str_buf);
 
956
         TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
 
957
         result.test_eq("botan_mp_sub", std::string(str_buf), "4943984178");
 
958
         TEST_FFI_RC(1, botan_mp_is_negative, (r));
 
959
 
 
960
         TEST_FFI_OK(botan_mp_lshift, (r, x, 39));
 
961
         str_len = sizeof(str_buf);
 
962
         TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
 
963
         result.test_eq("botan_mp_lshift", std::string(str_buf), "142386755796992");
 
964
 
 
965
         TEST_FFI_OK(botan_mp_rshift, (r, r, 3));
 
966
         str_len = sizeof(str_buf);
 
967
         TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
 
968
         result.test_eq("botan_mp_rshift", std::string(str_buf), "17798344474624");
 
969
 
 
970
         TEST_FFI_OK(botan_mp_gcd, (r, x, y));
 
971
         str_len = sizeof(str_buf);
 
972
         TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
 
973
         result.test_eq("botan_mp_gcd", std::string(str_buf), "259");
 
974
 
 
975
         botan_mp_t p;
 
976
         botan_mp_init(&p);
 
977
         const uint8_t M127[] = { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
978
         TEST_FFI_OK(botan_mp_from_bin, (p, M127, sizeof(M127)));
 
979
         TEST_FFI_RC(1, botan_mp_is_prime, (p, rng, 64));
 
980
 
 
981
         size_t p_bits = 0;
 
982
         TEST_FFI_OK(botan_mp_num_bits, (p, &p_bits));
 
983
         result.test_eq("botan_mp_num_bits", p_bits, 127);
 
984
 
 
985
         TEST_FFI_OK(botan_mp_mod_inverse, (r, x, p));
 
986
         str_len = sizeof(str_buf);
 
987
         TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
 
988
         result.test_eq("botan_mp_mod_inverse", std::string(str_buf), "40728777507911553541948312086427855425");
 
989
 
 
990
         TEST_FFI_OK(botan_mp_powmod, (r, x, r, p));
 
991
         str_len = sizeof(str_buf);
 
992
         TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
 
993
         result.test_eq("botan_mp_powmod", std::string(str_buf), "40550417419160441638948180641668117560");
 
994
 
 
995
         TEST_FFI_OK(botan_mp_num_bytes, (r, &bn_bytes));
 
996
         result.test_eq("botan_mp_num_bytes", bn_bytes, 16);
 
997
 
 
998
         std::vector<uint8_t> bn_buf;
 
999
         bn_buf.resize(bn_bytes);
 
1000
         botan_mp_to_bin(r, bn_buf.data());
 
1001
         result.test_eq("botan_mp_to_bin", bn_buf, "1E81B9EFE0BE1902F6D03F9F5E5FB438");
 
1002
 
 
1003
         TEST_FFI_OK(botan_mp_set_from_mp, (y, r));
 
1004
         TEST_FFI_OK(botan_mp_mod_mul, (r, x, y, p));
 
1005
         str_len = sizeof(str_buf);
 
1006
         TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
 
1007
         result.test_eq("botan_mp_mod_mul", std::string(str_buf), "123945920473931248854653259523111998693");
 
1008
 
 
1009
         str_len = 0;
 
1010
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_mp_to_str, (r, 10, str_buf, &str_len));
 
1011
 
 
1012
         size_t x_bytes;
 
1013
         botan_mp_rand_bits(x, rng, 512);
 
1014
         TEST_FFI_OK(botan_mp_num_bytes, (x, &x_bytes));
 
1015
         result.test_lte("botan_mp_num_bytes", x_bytes, 512 / 8);
 
1016
 
 
1017
         TEST_FFI_OK(botan_mp_set_from_radix_str, (x, "909A", 16));
 
1018
         TEST_FFI_OK(botan_mp_to_uint32, (x, &x_32));
 
1019
         result.test_eq("botan_mp_set_from_radix_str(16)", x_32, static_cast<size_t>(0x909A));
 
1020
 
 
1021
         TEST_FFI_OK(botan_mp_set_from_radix_str, (x, "9098135", 10));
 
1022
         TEST_FFI_OK(botan_mp_to_uint32, (x, &x_32));
 
1023
         result.test_eq("botan_mp_set_from_radix_str(10)", x_32, static_cast<size_t>(9098135));
 
1024
 
 
1025
         botan_mp_destroy(p);
 
1026
         botan_mp_destroy(x);
 
1027
         botan_mp_destroy(y);
 
1028
         botan_mp_destroy(r);
 
1029
         botan_mp_destroy(q);
 
1030
 
 
1031
         return result;
 
1032
         }
 
1033
 
 
1034
      void ffi_test_pubkey_export(Test::Result& result, botan_pubkey_t pub, botan_privkey_t priv, botan_rng_t rng)
 
1035
         {
 
1036
         const size_t pbkdf_iter = 1000;
 
1037
 
 
1038
         // export public key
 
1039
         size_t pubkey_len = 0;
 
1040
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pubkey_export, (pub, nullptr, &pubkey_len,
 
1041
                     BOTAN_PRIVKEY_EXPORT_FLAG_DER));
 
1042
 
 
1043
         std::vector<uint8_t> pubkey(pubkey_len);
 
1044
         TEST_FFI_OK(botan_pubkey_export, (pub, pubkey.data(), &pubkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_DER));
 
1045
 
 
1046
         pubkey_len = 0;
 
1047
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pubkey_export,
 
1048
                     (pub, nullptr, &pubkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM));
 
1049
 
 
1050
         pubkey.resize(pubkey_len);
 
1051
         TEST_FFI_OK(botan_pubkey_export, (pub, pubkey.data(), &pubkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM));
 
1052
 
 
1053
         // reimport exported public key
 
1054
         botan_pubkey_t pub_copy;
 
1055
         TEST_FFI_OK(botan_pubkey_load, (&pub_copy, pubkey.data(), pubkey_len));
 
1056
         TEST_FFI_OK(botan_pubkey_check_key, (pub_copy, rng, 0));
 
1057
         TEST_FFI_OK(botan_pubkey_destroy, (pub_copy));
 
1058
 
 
1059
         // export private key
 
1060
         std::vector<uint8_t> privkey;
 
1061
         size_t privkey_len = 0;
 
1062
 
 
1063
         // call with nullptr to query the length
 
1064
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export,
 
1065
                     (priv, nullptr, &privkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_DER));
 
1066
 
 
1067
         privkey.resize(privkey_len);
 
1068
         privkey_len = privkey.size(); // set buffer size
 
1069
 
 
1070
         TEST_FFI_OK(botan_privkey_export, (priv, privkey.data(), &privkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_DER));
 
1071
 
 
1072
         privkey.resize(privkey_len);
 
1073
 
 
1074
         result.test_gte("Reasonable size", privkey.size(), 32);
 
1075
 
 
1076
         // reimport exported private key
 
1077
         botan_privkey_t copy;
 
1078
         TEST_FFI_OK(botan_privkey_load, (&copy, rng, privkey.data(), privkey.size(), nullptr));
 
1079
         botan_privkey_destroy(copy);
 
1080
 
 
1081
         // Now again for PEM
 
1082
         privkey_len = 0;
 
1083
 
 
1084
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export,
 
1085
                     (priv, nullptr, &privkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM));
 
1086
 
 
1087
         privkey.resize(privkey_len);
 
1088
         TEST_FFI_OK(botan_privkey_export, (priv, privkey.data(), &privkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM));
 
1089
 
 
1090
         TEST_FFI_OK(botan_privkey_load, (&copy, rng, privkey.data(), privkey.size(), nullptr));
 
1091
         botan_privkey_destroy(copy);
 
1092
 
 
1093
         // export private key encrypted
 
1094
         privkey_len = 0;
 
1095
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export_encrypted_pbkdf_iter, (priv, nullptr,
 
1096
                     &privkey_len, rng, "password", pbkdf_iter, "", "", BOTAN_PRIVKEY_EXPORT_FLAG_DER));
 
1097
 
 
1098
         privkey.resize(privkey_len);
 
1099
         privkey_len = privkey.size();
 
1100
 
 
1101
         TEST_FFI_OK(botan_privkey_export_encrypted_pbkdf_iter, (priv, privkey.data(), &privkey_len, rng, "password", pbkdf_iter,
 
1102
                     "", "", BOTAN_PRIVKEY_EXPORT_FLAG_DER));
 
1103
 
 
1104
         // reimport encrypted private key
 
1105
         botan_privkey_load(&copy, rng, privkey.data(), privkey.size(), "password");
 
1106
         botan_privkey_destroy(copy);
 
1107
 
 
1108
         privkey_len = 0;
 
1109
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export_encrypted_pbkdf_iter, (priv, nullptr,
 
1110
                     &privkey_len, rng, "password", pbkdf_iter, "", "", BOTAN_PRIVKEY_EXPORT_FLAG_PEM));
 
1111
 
 
1112
         privkey.resize(privkey_len);
 
1113
         TEST_FFI_OK(botan_privkey_export_encrypted_pbkdf_iter, (priv, privkey.data(), &privkey_len, rng, "password", pbkdf_iter,
 
1114
                     "", "", BOTAN_PRIVKEY_EXPORT_FLAG_PEM));
 
1115
 
 
1116
         privkey.resize(privkey_len * 2);
 
1117
         privkey_len = privkey.size();
 
1118
         const uint32_t pbkdf_msec = 100;
 
1119
         size_t pbkdf_iters_out = 0;
 
1120
 
 
1121
         TEST_FFI_OK(botan_privkey_export_encrypted_pbkdf_msec,
 
1122
                     (priv, privkey.data(), &privkey_len, rng, "password",
 
1123
                      pbkdf_msec, &pbkdf_iters_out, "AES-256/GCM", "SHA-512", 0));
 
1124
         // PBKDF2 currently always rounds to multiple of 10,000
 
1125
         result.test_gte("Reasonable KDF iters", pbkdf_iters_out, 1000);
 
1126
         privkey.resize(privkey_len);
 
1127
 
 
1128
         TEST_FFI_OK(botan_privkey_load, (&copy, rng, privkey.data(), privkey.size(), "password"));
 
1129
         botan_privkey_destroy(copy);
 
1130
 
 
1131
         // calculate fingerprint
 
1132
         size_t strength = 0;
 
1133
         TEST_FFI_OK(botan_pubkey_estimated_strength, (pub, &strength));
 
1134
         result.test_gte("estimated strength", strength, 1);
 
1135
 
 
1136
         size_t fingerprint_len = 0;
 
1137
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pubkey_fingerprint,
 
1138
                     (pub, "SHA-512", nullptr, &fingerprint_len));
 
1139
 
 
1140
         std::vector<uint8_t> fingerprint(fingerprint_len);
 
1141
         TEST_FFI_OK(botan_pubkey_fingerprint, (pub, "SHA-512", fingerprint.data(), &fingerprint_len));
 
1142
         }
 
1143
 
 
1144
      Test::Result ffi_test_keywrap()
 
1145
         {
 
1146
         Test::Result result("FFI keywrap");
 
1147
 
 
1148
         const uint8_t key[16] = { 0 };
 
1149
         const uint8_t kek[16] = { 0xFF, 0 };
 
1150
 
 
1151
         const uint8_t expected_wrapped_key[16+8] = {
 
1152
            0x04, 0x13, 0x37, 0x39, 0x82, 0xCF, 0xFA, 0x31, 0x81, 0xCA, 0x4F, 0x59,
 
1153
            0x74, 0x4D, 0xED, 0x29, 0x1F, 0x3F, 0xE5, 0x24, 0x00, 0x1B, 0x93, 0x20
 
1154
         };
 
1155
 
 
1156
         uint8_t wrapped[16 + 8] = { 0 };
 
1157
         size_t wrapped_keylen = sizeof(wrapped);
 
1158
         TEST_FFI_OK(botan_key_wrap3394, (key, sizeof(key),
 
1159
                                          kek, sizeof(kek),
 
1160
                                          wrapped, &wrapped_keylen));
 
1161
 
 
1162
         result.test_eq("Expected wrapped keylen size", wrapped_keylen, 16 + 8);
 
1163
 
 
1164
         result.test_eq(nullptr, "Wrapped key", wrapped, wrapped_keylen,
 
1165
                        expected_wrapped_key, sizeof(expected_wrapped_key));
 
1166
 
 
1167
         uint8_t dec_key[16] = { 0 };
 
1168
         size_t dec_keylen = sizeof(dec_key);
 
1169
         TEST_FFI_OK(botan_key_unwrap3394, (wrapped, sizeof(wrapped),
 
1170
                                            kek, sizeof(kek),
 
1171
                                            dec_key, &dec_keylen));
 
1172
 
 
1173
         result.test_eq(nullptr, "Unwrapped key", dec_key, dec_keylen, key, sizeof(key));
 
1174
         return result;
 
1175
         }
 
1176
 
 
1177
      Test::Result ffi_test_rsa(botan_rng_t rng)
 
1178
         {
 
1179
         Test::Result result("FFI RSA");
 
1180
 
 
1181
         botan_privkey_t priv;
 
1182
 
 
1183
         if(TEST_FFI_OK(botan_privkey_create_rsa, (&priv, rng, 1024)))
 
1184
            {
 
1185
            TEST_FFI_OK(botan_privkey_check_key, (priv, rng, 0));
 
1186
 
 
1187
            botan_pubkey_t pub;
 
1188
            TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
 
1189
            TEST_FFI_OK(botan_pubkey_check_key, (pub, rng, 0));
 
1190
 
 
1191
            ffi_test_pubkey_export(result, pub, priv, rng);
 
1192
 
 
1193
            botan_mp_t p, q, d, n, e;
 
1194
            botan_mp_init(&p);
 
1195
            botan_mp_init(&q);
 
1196
            botan_mp_init(&d);
 
1197
            botan_mp_init(&n);
 
1198
            botan_mp_init(&e);
 
1199
 
 
1200
            TEST_FFI_OK(botan_privkey_rsa_get_p, (p, priv));
 
1201
            TEST_FFI_OK(botan_privkey_rsa_get_q, (q, priv));
 
1202
            TEST_FFI_OK(botan_privkey_rsa_get_d, (d, priv));
 
1203
            TEST_FFI_OK(botan_privkey_rsa_get_e, (e, priv));
 
1204
            TEST_FFI_OK(botan_privkey_rsa_get_n, (n, priv));
 
1205
 
 
1206
            // Confirm same (e,n) values in public key
 
1207
               {
 
1208
               botan_mp_t pub_e, pub_n;
 
1209
               botan_mp_init(&pub_e);
 
1210
               botan_mp_init(&pub_n);
 
1211
               TEST_FFI_OK(botan_pubkey_rsa_get_e, (pub_e, pub));
 
1212
               TEST_FFI_OK(botan_pubkey_rsa_get_n, (pub_n, pub));
 
1213
 
 
1214
               TEST_FFI_RC(1, botan_mp_equal, (pub_e, e));
 
1215
               TEST_FFI_RC(1, botan_mp_equal, (pub_n, n));
 
1216
               botan_mp_destroy(pub_e);
 
1217
               botan_mp_destroy(pub_n);
 
1218
               }
 
1219
 
 
1220
            TEST_FFI_RC(1, botan_mp_is_prime, (p, rng, 64));
 
1221
            TEST_FFI_RC(1, botan_mp_is_prime, (q, rng, 64));
 
1222
 
 
1223
            // Test p != q
 
1224
            TEST_FFI_RC(0, botan_mp_equal, (p, q));
 
1225
 
 
1226
            // Test p * q == n
 
1227
            botan_mp_t x;
 
1228
            botan_mp_init(&x);
 
1229
            TEST_FFI_OK(botan_mp_mul, (x, p, q));
 
1230
 
 
1231
            TEST_FFI_RC(1, botan_mp_equal, (x, n));
 
1232
            botan_mp_destroy(x);
 
1233
 
 
1234
            botan_privkey_t loaded_privkey;
 
1235
            // First try loading a bogus key and verify check_key fails
 
1236
            TEST_FFI_OK(botan_privkey_load_rsa, (&loaded_privkey, n, d, q));
 
1237
            TEST_FFI_RC(-1, botan_privkey_check_key, (loaded_privkey, rng, 0));
 
1238
            botan_privkey_destroy(loaded_privkey);
 
1239
 
 
1240
            TEST_FFI_OK(botan_privkey_load_rsa, (&loaded_privkey, p, q, e));
 
1241
            TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey, rng, 0));
 
1242
 
 
1243
            botan_pubkey_t loaded_pubkey;
 
1244
            TEST_FFI_OK(botan_pubkey_load_rsa, (&loaded_pubkey, n, e));
 
1245
            TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey, rng, 0));
 
1246
 
 
1247
            botan_mp_destroy(p);
 
1248
            botan_mp_destroy(q);
 
1249
            botan_mp_destroy(d);
 
1250
            botan_mp_destroy(e);
 
1251
            botan_mp_destroy(n);
 
1252
 
 
1253
            char namebuf[32] = { 0 };
 
1254
            size_t name_len = sizeof(namebuf);
 
1255
            if(TEST_FFI_OK(botan_pubkey_algo_name, (loaded_pubkey, namebuf, &name_len)))
 
1256
               {
 
1257
               result.test_eq("algo name", std::string(namebuf), "RSA");
 
1258
               }
 
1259
 
 
1260
            botan_pk_op_encrypt_t encrypt;
 
1261
 
 
1262
            if(TEST_FFI_OK(botan_pk_op_encrypt_create, (&encrypt, loaded_pubkey, "OAEP(SHA-256)", 0)))
 
1263
               {
 
1264
               std::vector<uint8_t> plaintext(32);
 
1265
               TEST_FFI_OK(botan_rng_get, (rng, plaintext.data(), plaintext.size()));
 
1266
 
 
1267
               std::vector<uint8_t> ciphertext(256); // TODO: no way to know this size from API
 
1268
               size_t ctext_len = ciphertext.size();
 
1269
 
 
1270
               if(TEST_FFI_OK(botan_pk_op_encrypt, (encrypt, rng,
 
1271
                                                    ciphertext.data(), &ctext_len,
 
1272
                                                    plaintext.data(), plaintext.size())))
 
1273
                  {
 
1274
                  ciphertext.resize(ctext_len);
 
1275
 
 
1276
                  botan_pk_op_decrypt_t decrypt;
 
1277
                  if(TEST_FFI_OK(botan_pk_op_decrypt_create, (&decrypt, priv, "OAEP(SHA-256)", 0)))
 
1278
                     {
 
1279
                     std::vector<uint8_t> decrypted(256); // TODO as with above
 
1280
                     size_t decrypted_len = decrypted.size();
 
1281
                     TEST_FFI_OK(botan_pk_op_decrypt, (decrypt, decrypted.data(), &decrypted_len,
 
1282
                                                       ciphertext.data(), ciphertext.size()));
 
1283
                     decrypted.resize(decrypted_len);
 
1284
 
 
1285
                     result.test_eq("RSA plaintext", decrypted, plaintext);
 
1286
                     }
 
1287
 
 
1288
                  TEST_FFI_OK(botan_pk_op_decrypt_destroy, (decrypt));
 
1289
                  }
 
1290
 
 
1291
               TEST_FFI_OK(botan_pk_op_encrypt_destroy, (encrypt));
 
1292
               }
 
1293
 
 
1294
            TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey));
 
1295
            TEST_FFI_OK(botan_pubkey_destroy, (pub));
 
1296
            TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey));
 
1297
            TEST_FFI_OK(botan_privkey_destroy, (priv));
 
1298
            }
 
1299
 
 
1300
         return result;
 
1301
         }
 
1302
 
 
1303
      Test::Result ffi_test_dsa(botan_rng_t rng)
 
1304
         {
 
1305
         Test::Result result("FFI DSA");
 
1306
 
 
1307
         botan_privkey_t priv;
 
1308
 
 
1309
         if(TEST_FFI_OK(botan_privkey_create, (&priv, "DSA", "dsa/jce/1024", rng)))
 
1310
            {
 
1311
            TEST_FFI_OK(botan_privkey_check_key, (priv, rng, 0));
 
1312
 
 
1313
            botan_pubkey_t pub;
 
1314
            TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
 
1315
            TEST_FFI_OK(botan_pubkey_check_key, (pub, rng, 0));
 
1316
 
 
1317
            ffi_test_pubkey_export(result, pub, priv, rng);
 
1318
 
 
1319
            botan_mp_t p, q, g, x, y;
 
1320
            botan_mp_init(&p);
 
1321
            botan_mp_init(&q);
 
1322
            botan_mp_init(&g);
 
1323
            botan_mp_init(&x);
 
1324
            botan_mp_init(&y);
 
1325
 
 
1326
            TEST_FFI_OK(botan_privkey_dsa_get_x, (x, priv));
 
1327
            TEST_FFI_OK(botan_pubkey_dsa_get_g, (g, pub));
 
1328
            TEST_FFI_OK(botan_pubkey_dsa_get_p, (p, pub));
 
1329
            TEST_FFI_OK(botan_pubkey_dsa_get_q, (q, pub));
 
1330
            TEST_FFI_OK(botan_pubkey_dsa_get_y, (y, pub));
 
1331
 
 
1332
            botan_mp_t cmp;
 
1333
            botan_mp_init(&cmp);
 
1334
            TEST_FFI_OK(botan_privkey_get_field, (cmp, priv, "x"));
 
1335
            TEST_FFI_RC(1, botan_mp_equal, (cmp, x));
 
1336
            TEST_FFI_OK(botan_privkey_get_field, (cmp, priv, "y"));
 
1337
            TEST_FFI_RC(1, botan_mp_equal, (cmp, y));
 
1338
            TEST_FFI_OK(botan_privkey_get_field, (cmp, priv, "p"));
 
1339
            TEST_FFI_RC(1, botan_mp_equal, (cmp, p));
 
1340
            botan_mp_destroy(cmp);
 
1341
 
 
1342
            botan_privkey_t loaded_privkey;
 
1343
            TEST_FFI_OK(botan_privkey_load_dsa, (&loaded_privkey, p, q, g, x));
 
1344
            TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey, rng, 0));
 
1345
 
 
1346
            botan_pubkey_t loaded_pubkey;
 
1347
            TEST_FFI_OK(botan_pubkey_load_dsa, (&loaded_pubkey, p, q, g, y));
 
1348
            TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey, rng, 0));
 
1349
 
 
1350
            botan_mp_destroy(p);
 
1351
            botan_mp_destroy(q);
 
1352
            botan_mp_destroy(g);
 
1353
            botan_mp_destroy(y);
 
1354
            botan_mp_destroy(x);
 
1355
 
 
1356
            botan_pk_op_sign_t signer;
 
1357
 
 
1358
            std::vector<uint8_t> message(6, 6);
 
1359
            std::vector<uint8_t> signature(20 * 2);
 
1360
 
 
1361
            if(TEST_FFI_OK(botan_pk_op_sign_create, (&signer, loaded_privkey, "EMSA1(SHA-256)", 0)))
 
1362
               {
 
1363
               // TODO: break input into multiple calls to update
 
1364
               TEST_FFI_OK(botan_pk_op_sign_update, (signer, message.data(), message.size()));
 
1365
 
 
1366
               signature.resize(20 * 2); // TODO: no way to derive this from API
 
1367
               size_t sig_len = signature.size();
 
1368
               TEST_FFI_OK(botan_pk_op_sign_finish, (signer, rng, signature.data(), &sig_len));
 
1369
               signature.resize(sig_len);
 
1370
 
 
1371
               TEST_FFI_OK(botan_pk_op_sign_destroy, (signer));
 
1372
               }
 
1373
 
 
1374
            botan_pk_op_verify_t verifier;
 
1375
 
 
1376
            if(TEST_FFI_OK(botan_pk_op_verify_create, (&verifier, pub, "EMSA1(SHA-256)", 0)))
 
1377
               {
 
1378
               TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1379
               TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1380
 
 
1381
               // TODO: randomize this
 
1382
               signature[0] ^= 1;
 
1383
               TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1384
               TEST_FFI_RC(BOTAN_FFI_INVALID_VERIFIER, botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1385
 
 
1386
               message[0] ^= 1;
 
1387
               TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1388
               TEST_FFI_RC(BOTAN_FFI_INVALID_VERIFIER, botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1389
 
 
1390
               signature[0] ^= 1;
 
1391
               TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1392
               TEST_FFI_RC(BOTAN_FFI_INVALID_VERIFIER, botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1393
 
 
1394
               message[0] ^= 1;
 
1395
               TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1396
               TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1397
 
 
1398
               TEST_FFI_OK(botan_pk_op_verify_destroy, (verifier));
 
1399
               }
 
1400
 
 
1401
            TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey));
 
1402
            TEST_FFI_OK(botan_pubkey_destroy, (pub));
 
1403
            TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey));
 
1404
            TEST_FFI_OK(botan_privkey_destroy, (priv));
 
1405
            }
 
1406
 
 
1407
         return result;
 
1408
         }
 
1409
      Test::Result ffi_test_ecdsa(botan_rng_t rng)
 
1410
         {
 
1411
         Test::Result result("FFI ECDSA");
 
1412
         static const char* kCurve = "secp384r1";
 
1413
         botan_privkey_t priv;
 
1414
         botan_pubkey_t pub;
 
1415
         botan_privkey_t loaded_privkey;
 
1416
         botan_pubkey_t loaded_pubkey;
 
1417
 
 
1418
         REQUIRE_FFI_OK(botan_privkey_create_ecdsa, (&priv, rng, kCurve));
 
1419
         TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
 
1420
         ffi_test_pubkey_export(result, pub, priv, rng);
 
1421
 
 
1422
         // Check key load functions
 
1423
         botan_mp_t private_scalar, public_x, public_y;
 
1424
         botan_mp_init(&private_scalar);
 
1425
         botan_mp_init(&public_x);
 
1426
         botan_mp_init(&public_y);
 
1427
 
 
1428
         TEST_FFI_OK(botan_privkey_get_field, (private_scalar, priv, "x"));
 
1429
         TEST_FFI_OK(botan_pubkey_get_field, (public_x, pub, "public_x"));
 
1430
         TEST_FFI_OK(botan_pubkey_get_field, (public_y, pub, "public_y"));
 
1431
         TEST_FFI_OK(botan_privkey_load_ecdsa, (&loaded_privkey, private_scalar, kCurve));
 
1432
         TEST_FFI_OK(botan_pubkey_load_ecdsa, (&loaded_pubkey, public_x, public_y, kCurve));
 
1433
         TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey, rng, 0));
 
1434
         TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey, rng, 0));
 
1435
 
 
1436
         char namebuf[32] = { 0 };
 
1437
         size_t name_len = sizeof(namebuf);
 
1438
 
 
1439
         TEST_FFI_OK(botan_pubkey_algo_name, (pub, &namebuf[0], &name_len));
 
1440
         result.test_eq(namebuf, namebuf, "ECDSA");
 
1441
 
 
1442
         std::vector<uint8_t> message(1280), signature;
 
1443
         TEST_FFI_OK(botan_rng_get, (rng, message.data(), message.size()));
 
1444
         botan_pk_op_sign_t signer;
 
1445
         if(TEST_FFI_OK(botan_pk_op_sign_create, (&signer, loaded_privkey, "EMSA1(SHA-384)", 0)))
 
1446
            {
 
1447
            // TODO: break input into multiple calls to update
 
1448
            TEST_FFI_OK(botan_pk_op_sign_update, (signer, message.data(), message.size()));
 
1449
 
 
1450
            signature.resize(96); // TODO: no way to derive this from API
 
1451
            size_t sig_len = signature.size();
 
1452
            TEST_FFI_OK(botan_pk_op_sign_finish, (signer, rng, signature.data(), &sig_len));
 
1453
            signature.resize(sig_len);
 
1454
 
 
1455
            TEST_FFI_OK(botan_pk_op_sign_destroy, (signer));
 
1456
            }
 
1457
 
 
1458
         botan_pk_op_verify_t verifier;
 
1459
 
 
1460
         if(TEST_FFI_OK(botan_pk_op_verify_create, (&verifier, pub, "EMSA1(SHA-384)", 0)))
 
1461
            {
 
1462
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1463
            TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1464
 
 
1465
            // TODO: randomize this
 
1466
            signature[0] ^= 1;
 
1467
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1468
            TEST_FFI_RC(BOTAN_FFI_INVALID_VERIFIER, botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1469
 
 
1470
            message[0] ^= 1;
 
1471
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1472
            TEST_FFI_RC(BOTAN_FFI_INVALID_VERIFIER, botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1473
 
 
1474
            signature[0] ^= 1;
 
1475
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1476
            TEST_FFI_RC(BOTAN_FFI_INVALID_VERIFIER, botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1477
 
 
1478
            message[0] ^= 1;
 
1479
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1480
            TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1481
 
 
1482
            TEST_FFI_OK(botan_pk_op_verify_destroy, (verifier));
 
1483
            }
 
1484
 
 
1485
         TEST_FFI_OK(botan_mp_destroy, (private_scalar));
 
1486
         TEST_FFI_OK(botan_mp_destroy, (public_x));
 
1487
         TEST_FFI_OK(botan_mp_destroy, (public_y));
 
1488
         TEST_FFI_OK(botan_pubkey_destroy, (pub));
 
1489
         TEST_FFI_OK(botan_privkey_destroy, (priv));
 
1490
         TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey));
 
1491
         TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey));
 
1492
 
 
1493
         return result;
 
1494
         }
 
1495
 
 
1496
      Test::Result ffi_test_sm2(botan_rng_t rng)
 
1497
         {
 
1498
         Test::Result result("FFI SM2 Sig");
 
1499
         static const char* kCurve = "sm2p256v1";
 
1500
         const std::string sm2_ident = "SM2 Ident Field";
 
1501
         botan_privkey_t priv;
 
1502
         botan_pubkey_t pub;
 
1503
         botan_privkey_t loaded_privkey;
 
1504
         botan_pubkey_t loaded_pubkey;
 
1505
 
 
1506
         REQUIRE_FFI_OK(botan_privkey_create, (&priv, "SM2_Sig", kCurve, rng));
 
1507
         TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
 
1508
         ffi_test_pubkey_export(result, pub, priv, rng);
 
1509
 
 
1510
         uint8_t za[32];
 
1511
         size_t sizeof_za = sizeof(za);
 
1512
         TEST_FFI_OK(botan_pubkey_sm2_compute_za, (za, &sizeof_za, "Ident", "SM3", pub));
 
1513
 
 
1514
         // Check key load functions
 
1515
         botan_mp_t private_scalar, public_x, public_y;
 
1516
         botan_mp_init(&private_scalar);
 
1517
         botan_mp_init(&public_x);
 
1518
         botan_mp_init(&public_y);
 
1519
 
 
1520
         TEST_FFI_OK(botan_privkey_get_field, (private_scalar, priv, "x"));
 
1521
         TEST_FFI_OK(botan_pubkey_get_field, (public_x, pub, "public_x"));
 
1522
         TEST_FFI_OK(botan_pubkey_get_field, (public_y, pub, "public_y"));
 
1523
         TEST_FFI_OK(botan_privkey_load_sm2, (&loaded_privkey, private_scalar, kCurve));
 
1524
         TEST_FFI_OK(botan_pubkey_load_sm2, (&loaded_pubkey, public_x, public_y, kCurve));
 
1525
         TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey, rng, 0));
 
1526
         TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey, rng, 0));
 
1527
 
 
1528
         char namebuf[32] = { 0 };
 
1529
         size_t name_len = sizeof(namebuf);
 
1530
 
 
1531
         TEST_FFI_OK(botan_pubkey_algo_name, (pub, &namebuf[0], &name_len));
 
1532
         result.test_eq(namebuf, namebuf, "SM2_Sig");
 
1533
 
 
1534
         std::vector<uint8_t> message(1280), signature;
 
1535
         TEST_FFI_OK(botan_rng_get, (rng, message.data(), message.size()));
 
1536
         botan_pk_op_sign_t signer;
 
1537
         if(TEST_FFI_OK(botan_pk_op_sign_create, (&signer, loaded_privkey, sm2_ident.c_str(), 0)))
 
1538
            {
 
1539
            // TODO: break input into multiple calls to update
 
1540
            TEST_FFI_OK(botan_pk_op_sign_update, (signer, message.data(), message.size()));
 
1541
 
 
1542
            signature.resize(96); // TODO: no way to derive this from API
 
1543
            size_t sig_len = signature.size();
 
1544
            TEST_FFI_OK(botan_pk_op_sign_finish, (signer, rng, signature.data(), &sig_len));
 
1545
            signature.resize(sig_len);
 
1546
 
 
1547
            TEST_FFI_OK(botan_pk_op_sign_destroy, (signer));
 
1548
            }
 
1549
 
 
1550
         botan_pk_op_verify_t verifier = nullptr;
 
1551
 
 
1552
         if(signature.size() > 0 && TEST_FFI_OK(botan_pk_op_verify_create, (&verifier, pub, sm2_ident.c_str(), 0)))
 
1553
            {
 
1554
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1555
            TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1556
 
 
1557
            // TODO: randomize this
 
1558
            signature[0] ^= 1;
 
1559
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1560
            TEST_FFI_RC(BOTAN_FFI_INVALID_VERIFIER, botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1561
 
 
1562
            message[0] ^= 1;
 
1563
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1564
            TEST_FFI_RC(BOTAN_FFI_INVALID_VERIFIER, botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1565
 
 
1566
            signature[0] ^= 1;
 
1567
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1568
            TEST_FFI_RC(BOTAN_FFI_INVALID_VERIFIER, botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1569
 
 
1570
            message[0] ^= 1;
 
1571
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1572
            TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1573
 
 
1574
            TEST_FFI_OK(botan_pk_op_verify_destroy, (verifier));
 
1575
            }
 
1576
 
 
1577
         TEST_FFI_OK(botan_mp_destroy, (private_scalar));
 
1578
         TEST_FFI_OK(botan_mp_destroy, (public_x));
 
1579
         TEST_FFI_OK(botan_mp_destroy, (public_y));
 
1580
         TEST_FFI_OK(botan_pubkey_destroy, (pub));
 
1581
         TEST_FFI_OK(botan_privkey_destroy, (priv));
 
1582
         TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey));
 
1583
         TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey));
 
1584
 
 
1585
         return result;
 
1586
         }
 
1587
 
 
1588
      Test::Result ffi_test_sm2_enc(botan_rng_t rng)
 
1589
         {
 
1590
         Test::Result result("FFI SM2 Enc");
 
1591
         static const char* kCurve = "sm2p256v1";
 
1592
         botan_privkey_t priv;
 
1593
         botan_pubkey_t pub;
 
1594
         botan_privkey_t loaded_privkey;
 
1595
         botan_pubkey_t loaded_pubkey;
 
1596
 
 
1597
         REQUIRE_FFI_OK(botan_privkey_create, (&priv, "SM2_Enc", kCurve, rng));
 
1598
         TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
 
1599
         ffi_test_pubkey_export(result, pub, priv, rng);
 
1600
 
 
1601
         uint8_t za[32];
 
1602
         size_t sizeof_za = sizeof(za);
 
1603
         TEST_FFI_OK(botan_pubkey_sm2_compute_za, (za, &sizeof_za, "Ident", "SM3", pub));
 
1604
 
 
1605
         // Check key load functions
 
1606
         botan_mp_t private_scalar, public_x, public_y;
 
1607
         botan_mp_init(&private_scalar);
 
1608
         botan_mp_init(&public_x);
 
1609
         botan_mp_init(&public_y);
 
1610
 
 
1611
         TEST_FFI_OK(botan_privkey_get_field, (private_scalar, priv, "x"));
 
1612
         TEST_FFI_OK(botan_pubkey_get_field, (public_x, pub, "public_x"));
 
1613
         TEST_FFI_OK(botan_pubkey_get_field, (public_y, pub, "public_y"));
 
1614
         TEST_FFI_OK(botan_privkey_load_sm2_enc, (&loaded_privkey, private_scalar, kCurve));
 
1615
         TEST_FFI_OK(botan_pubkey_load_sm2_enc, (&loaded_pubkey, public_x, public_y, kCurve));
 
1616
         TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey, rng, 0));
 
1617
         TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey, rng, 0));
 
1618
 
 
1619
         char namebuf[32] = { 0 };
 
1620
         size_t name_len = sizeof(namebuf);
 
1621
 
 
1622
         TEST_FFI_OK(botan_pubkey_algo_name, (pub, &namebuf[0], &name_len));
 
1623
         result.test_eq(namebuf, namebuf, "SM2_Enc");
 
1624
 
 
1625
         std::vector<uint8_t> message(32);
 
1626
 
 
1627
         std::vector<uint8_t> ciphertext(4096);
 
1628
         TEST_FFI_OK(botan_rng_get, (rng, message.data(), message.size()));
 
1629
 
 
1630
         botan_pk_op_encrypt_t enc;
 
1631
         if(TEST_FFI_OK(botan_pk_op_encrypt_create, (&enc, loaded_pubkey, "", 0)))
 
1632
            {
 
1633
            size_t ctext_len = ciphertext.size();
 
1634
            TEST_FFI_OK(botan_pk_op_encrypt, (enc, rng, ciphertext.data(), &ctext_len,
 
1635
                                              message.data(), message.size()));
 
1636
            ciphertext.resize(ctext_len);
 
1637
 
 
1638
            botan_pk_op_decrypt_t dec;
 
1639
            TEST_FFI_OK(botan_pk_op_decrypt_create, (&dec, loaded_privkey, "", 0));
 
1640
 
 
1641
            std::vector<uint8_t> recovered(message.size());
 
1642
            size_t recovered_len = recovered.size();
 
1643
 
 
1644
            TEST_FFI_OK(botan_pk_op_decrypt,
 
1645
                        (dec, recovered.data(), &recovered_len,
 
1646
                         ciphertext.data(), ciphertext.size()));
 
1647
 
 
1648
            botan_pk_op_decrypt_destroy(dec);
 
1649
            }
 
1650
         botan_pk_op_encrypt_destroy(enc);
 
1651
 
 
1652
         TEST_FFI_OK(botan_mp_destroy, (private_scalar));
 
1653
         TEST_FFI_OK(botan_mp_destroy, (public_x));
 
1654
         TEST_FFI_OK(botan_mp_destroy, (public_y));
 
1655
         TEST_FFI_OK(botan_pubkey_destroy, (pub));
 
1656
         TEST_FFI_OK(botan_privkey_destroy, (priv));
 
1657
         TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey));
 
1658
         TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey));
 
1659
 
 
1660
         return result;
 
1661
         }
 
1662
 
 
1663
      Test::Result ffi_test_ecdh(botan_rng_t rng)
 
1664
         {
 
1665
         Test::Result result("FFI ECDH");
 
1666
 
 
1667
         botan_mp_t private_scalar, public_x, public_y;
 
1668
         botan_privkey_t loaded_privkey1;
 
1669
         botan_pubkey_t loaded_pubkey1;
 
1670
         botan_mp_init(&private_scalar);
 
1671
         botan_mp_init(&public_x);
 
1672
         botan_mp_init(&public_y);
 
1673
 
 
1674
         botan_privkey_t priv1;
 
1675
         REQUIRE_FFI_OK(botan_privkey_create_ecdh, (&priv1, rng, "secp256r1"));
 
1676
 
 
1677
         botan_privkey_t priv2;
 
1678
         REQUIRE_FFI_OK(botan_privkey_create_ecdh, (&priv2, rng, "secp256r1"));
 
1679
 
 
1680
         botan_pubkey_t pub1;
 
1681
         REQUIRE_FFI_OK(botan_privkey_export_pubkey, (&pub1, priv1));
 
1682
 
 
1683
         botan_pubkey_t pub2;
 
1684
         REQUIRE_FFI_OK(botan_privkey_export_pubkey, (&pub2, priv2));
 
1685
 
 
1686
         /* Reload key-pair1 in order to test functions for key loading */
 
1687
         TEST_FFI_OK(botan_privkey_get_field, (private_scalar, priv1, "x"));
 
1688
         TEST_FFI_OK(botan_pubkey_get_field, (public_x, pub1, "public_x"));
 
1689
         TEST_FFI_OK(botan_pubkey_get_field, (public_y, pub1, "public_y"));
 
1690
         REQUIRE_FFI_OK(botan_privkey_load_ecdh, (&loaded_privkey1, private_scalar, "secp256r1"));
 
1691
         REQUIRE_FFI_OK(botan_pubkey_load_ecdh, (&loaded_pubkey1, public_x, public_y, "secp256r1"));
 
1692
         TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey1, rng, 0));
 
1693
         TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey1, rng, 0));
 
1694
 
 
1695
         ffi_test_pubkey_export(result, loaded_pubkey1, priv1, rng);
 
1696
         ffi_test_pubkey_export(result, pub2, priv2, rng);
 
1697
 
 
1698
         botan_pk_op_ka_t ka1;
 
1699
         REQUIRE_FFI_OK(botan_pk_op_key_agreement_create, (&ka1, loaded_privkey1, "KDF2(SHA-256)", 0));
 
1700
         botan_pk_op_ka_t ka2;
 
1701
         REQUIRE_FFI_OK(botan_pk_op_key_agreement_create, (&ka2, priv2, "KDF2(SHA-256)", 0));
 
1702
 
 
1703
         size_t pubkey1_len = 0;
 
1704
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pk_op_key_agreement_export_public, (priv1, nullptr, &pubkey1_len));
 
1705
         std::vector<uint8_t> pubkey1(pubkey1_len);
 
1706
         REQUIRE_FFI_OK(botan_pk_op_key_agreement_export_public, (priv1, pubkey1.data(), &pubkey1_len));
 
1707
         size_t pubkey2_len = 0;
 
1708
         TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pk_op_key_agreement_export_public, (priv2, nullptr, &pubkey2_len));
 
1709
         std::vector<uint8_t> pubkey2(pubkey2_len);
 
1710
         REQUIRE_FFI_OK(botan_pk_op_key_agreement_export_public, (priv2, pubkey2.data(), &pubkey2_len));
 
1711
 
 
1712
         std::vector<uint8_t> salt(32);
 
1713
         TEST_FFI_OK(botan_rng_get, (rng, salt.data(), salt.size()));
 
1714
 
 
1715
         const size_t shared_key_len = 64;
 
1716
 
 
1717
         std::vector<uint8_t> key1(shared_key_len);
 
1718
         size_t key1_len = key1.size();
 
1719
         TEST_FFI_OK(botan_pk_op_key_agreement, (ka1, key1.data(), &key1_len,
 
1720
                                                 pubkey2.data(), pubkey2.size(),
 
1721
                                                 salt.data(), salt.size()));
 
1722
 
 
1723
         std::vector<uint8_t> key2(shared_key_len);
 
1724
         size_t key2_len = key2.size();
 
1725
         TEST_FFI_OK(botan_pk_op_key_agreement, (ka2, key2.data(), &key2_len,
 
1726
                                                 pubkey1.data(), pubkey1.size(),
 
1727
                                                 salt.data(), salt.size()));
 
1728
 
 
1729
         result.test_eq("shared ECDH key", key1, key2);
 
1730
 
 
1731
         TEST_FFI_OK(botan_mp_destroy, (private_scalar));
 
1732
         TEST_FFI_OK(botan_mp_destroy, (public_x));
 
1733
         TEST_FFI_OK(botan_mp_destroy, (public_y));
 
1734
         TEST_FFI_OK(botan_pk_op_key_agreement_destroy, (ka1));
 
1735
         TEST_FFI_OK(botan_pk_op_key_agreement_destroy, (ka2));
 
1736
         TEST_FFI_OK(botan_privkey_destroy, (priv1));
 
1737
         TEST_FFI_OK(botan_privkey_destroy, (priv2));
 
1738
         TEST_FFI_OK(botan_pubkey_destroy, (pub1));
 
1739
         TEST_FFI_OK(botan_pubkey_destroy, (pub2));
 
1740
         TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey1));
 
1741
         TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey1));
 
1742
         return result;
 
1743
         }
 
1744
 
 
1745
      Test::Result ffi_test_mceliece(botan_rng_t rng)
 
1746
         {
 
1747
         Test::Result result("FFI McEliece");
 
1748
 
 
1749
         botan_privkey_t priv;
 
1750
#if defined(BOTAN_HAS_MCELIECE)
 
1751
         if(TEST_FFI_OK(botan_privkey_create_mceliece, (&priv, rng, 2048, 50)))
 
1752
            {
 
1753
            botan_pubkey_t pub;
 
1754
            TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
 
1755
 
 
1756
            ffi_test_pubkey_export(result, pub, priv, rng);
 
1757
 
 
1758
            char namebuf[32] = { 0 };
 
1759
            size_t name_len = sizeof(namebuf);
 
1760
            if(TEST_FFI_OK(botan_pubkey_algo_name, (pub, namebuf, &name_len)))
 
1761
               {
 
1762
               result.test_eq("algo name", std::string(namebuf), "McEliece");
 
1763
               }
 
1764
 
 
1765
            // TODO test KEM
 
1766
 
 
1767
#if defined(BOTAN_HAS_MCEIES)
 
1768
            const uint8_t ad[8] = { 0xAD, 0xAD, 0xAD, 0xAD, 0xBE, 0xEE, 0xEE, 0xFF };
 
1769
            const size_t ad_len = sizeof(ad);
 
1770
 
 
1771
            const Botan::secure_vector<uint8_t> plaintext = Test::rng().random_vec(Test::rng().next_byte());
 
1772
            size_t plaintext_len = plaintext.size();
 
1773
            size_t ciphertext_len = 0;
 
1774
 
 
1775
            // first calculate ciphertext length
 
1776
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_mceies_encrypt, (pub, rng, "AES-256/OCB", plaintext.data(),
 
1777
                        plaintext.size(), ad, ad_len, nullptr, &ciphertext_len));
 
1778
            std::vector<uint8_t> ciphertext(ciphertext_len);
 
1779
 
 
1780
            // now encrypt
 
1781
            if(TEST_FFI_OK(botan_mceies_encrypt, (pub, rng, "AES-256/OCB", plaintext.data(), plaintext.size(), ad, ad_len,
 
1782
                                                  ciphertext.data(), &ciphertext_len)))
 
1783
               {
 
1784
               std::vector<uint8_t> decrypted(plaintext.size());
 
1785
               size_t decrypted_len = plaintext_len;
 
1786
 
 
1787
               TEST_FFI_OK(botan_mceies_decrypt, (priv, "AES-256/OCB", ciphertext.data(), ciphertext.size(), ad, ad_len,
 
1788
                                                  decrypted.data(), &decrypted_len));
 
1789
 
 
1790
               result.test_eq("MCIES plaintext", decrypted, plaintext);
 
1791
               }
 
1792
#endif
 
1793
 
 
1794
            TEST_FFI_OK(botan_pubkey_destroy, (pub));
 
1795
            TEST_FFI_OK(botan_privkey_destroy, (priv));
 
1796
            }
 
1797
#else
 
1798
         // Not included, test that calling the FFI function work (and returns an error)
 
1799
         TEST_FFI_RC(BOTAN_FFI_ERROR_NOT_IMPLEMENTED, botan_privkey_create_mceliece, (&priv, rng, 2048, 50));
 
1800
#endif
 
1801
 
 
1802
         return result;
 
1803
         }
 
1804
 
 
1805
      Test::Result ffi_test_ed25519(botan_rng_t rng)
 
1806
         {
 
1807
         Test::Result result("FFI Ed25519");
 
1808
 
 
1809
         botan_pubkey_t pub;
 
1810
         botan_privkey_t priv;
 
1811
 
 
1812
         // From draft-koch-eddsa-for-openpgp-04
 
1813
         const std::vector<uint8_t> seed = Botan::hex_decode(
 
1814
            "1a8b1ff05ded48e18bf50166c664ab023ea70003d78d9e41f5758a91d850f8d2");
 
1815
         const std::vector<uint8_t> pubkey = Botan::hex_decode(
 
1816
            "3f098994bdd916ed4053197934e4a87c80733a1280d62f8010992e43ee3b2406");
 
1817
         const std::vector<uint8_t> message = Botan::hex_decode(
 
1818
            "4f70656e504750040016080006050255f95f9504ff0000000c");
 
1819
         const std::vector<uint8_t> exp_sig = Botan::hex_decode(
 
1820
            "56f90cca98e2102637bd983fdb16c131dfd27ed82bf4dde5606e0d756aed3366"
 
1821
            "d09c4fa11527f038e0f57f2201d82f2ea2c9033265fa6ceb489e854bae61b404");
 
1822
 
 
1823
         TEST_FFI_OK(botan_privkey_load_ed25519, (&priv, seed.data()));
 
1824
 
 
1825
         uint8_t retr_privkey[64];
 
1826
         TEST_FFI_OK(botan_privkey_ed25519_get_privkey, (priv, retr_privkey));
 
1827
 
 
1828
         result.test_eq(nullptr, "Public key matches", retr_privkey + 32, 32,
 
1829
                        pubkey.data(), pubkey.size());
 
1830
 
 
1831
         TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
 
1832
 
 
1833
         uint8_t retr_pubkey[32];
 
1834
         TEST_FFI_OK(botan_pubkey_ed25519_get_pubkey, (pub, retr_pubkey));
 
1835
         result.test_eq(nullptr, "Public key matches", retr_pubkey, 32,
 
1836
                        pubkey.data(), pubkey.size());
 
1837
 
 
1838
         TEST_FFI_OK(botan_pubkey_destroy, (pub));
 
1839
         TEST_FFI_OK(botan_pubkey_load_ed25519, (&pub, pubkey.data()));
 
1840
 
 
1841
         botan_pk_op_sign_t signer;
 
1842
         std::vector<uint8_t> signature;
 
1843
 
 
1844
         if(TEST_FFI_OK(botan_pk_op_sign_create, (&signer, priv, "SHA-256", 0)))
 
1845
            {
 
1846
            TEST_FFI_OK(botan_pk_op_sign_update, (signer, message.data(), message.size()));
 
1847
 
 
1848
            signature.resize(128);
 
1849
            size_t sig_len = signature.size();
 
1850
            TEST_FFI_OK(botan_pk_op_sign_finish, (signer, rng, signature.data(), &sig_len));
 
1851
            signature.resize(sig_len);
 
1852
 
 
1853
            TEST_FFI_OK(botan_pk_op_sign_destroy, (signer));
 
1854
            }
 
1855
 
 
1856
         result.test_eq("Expected signature", signature, exp_sig);
 
1857
 
 
1858
         botan_pk_op_verify_t verifier;
 
1859
 
 
1860
         if(TEST_FFI_OK(botan_pk_op_verify_create, (&verifier, pub, "SHA-256", 0)))
 
1861
            {
 
1862
            TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size()));
 
1863
            TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size()));
 
1864
 
 
1865
            TEST_FFI_OK(botan_pk_op_verify_destroy, (verifier));
 
1866
            }
 
1867
 
 
1868
         TEST_FFI_OK(botan_pubkey_destroy, (pub));
 
1869
         TEST_FFI_OK(botan_privkey_destroy, (priv));
 
1870
 
 
1871
         return result;
 
1872
         }
 
1873
 
 
1874
      Test::Result ffi_test_elgamal(botan_rng_t rng)
 
1875
         {
 
1876
         Test::Result result("FFI ELGAMAL");
 
1877
 
 
1878
         botan_privkey_t priv;
 
1879
 
 
1880
         if(TEST_FFI_OK(botan_privkey_create, (&priv, "ElGamal", nullptr, rng)))
 
1881
            {
 
1882
            TEST_FFI_OK(botan_privkey_check_key, (priv, rng, 0));
 
1883
 
 
1884
            botan_pubkey_t pub;
 
1885
            TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
 
1886
            TEST_FFI_OK(botan_pubkey_check_key, (pub, rng, 0));
 
1887
 
 
1888
            ffi_test_pubkey_export(result, pub, priv, rng);
 
1889
            botan_mp_t p, g, x, y;
 
1890
            botan_mp_init(&p);
 
1891
            botan_mp_init(&g);
 
1892
            botan_mp_init(&x);
 
1893
            botan_mp_init(&y);
 
1894
 
 
1895
            TEST_FFI_OK(botan_pubkey_get_field, (p, pub, "p"));
 
1896
            TEST_FFI_OK(botan_pubkey_get_field, (g, pub, "g"));
 
1897
            TEST_FFI_OK(botan_pubkey_get_field, (y, pub, "y"));
 
1898
            TEST_FFI_OK(botan_privkey_get_field, (x, priv, "x"));
 
1899
 
 
1900
            size_t p_len = 0;
 
1901
            TEST_FFI_OK(botan_mp_num_bytes, (p, &p_len));
 
1902
 
 
1903
            botan_privkey_t loaded_privkey;
 
1904
            TEST_FFI_OK(botan_privkey_load_elgamal, (&loaded_privkey, p, g, x));
 
1905
            TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey, rng, 0));
 
1906
 
 
1907
            botan_pubkey_t loaded_pubkey;
 
1908
            TEST_FFI_OK(botan_pubkey_load_elgamal, (&loaded_pubkey, p, g, y));
 
1909
            TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey, rng, 0));
 
1910
 
 
1911
            botan_mp_destroy(p);
 
1912
            botan_mp_destroy(g);
 
1913
            botan_mp_destroy(y);
 
1914
            botan_mp_destroy(x);
 
1915
 
 
1916
 
 
1917
            std::vector<uint8_t> plaintext(16, 0xFF);
 
1918
            std::vector<uint8_t> ciphertext(p_len*2, 0);
 
1919
            std::vector<uint8_t> decryption(16, 0);
 
1920
 
 
1921
            // Test encryption
 
1922
            botan_pk_op_encrypt_t op_enc;
 
1923
            size_t ct_len = ciphertext.size();
 
1924
            REQUIRE_FFI_OK(botan_pk_op_encrypt_create, (&op_enc, loaded_pubkey, "Raw", 0));
 
1925
            TEST_FFI_OK(botan_pk_op_encrypt, (op_enc, rng, ciphertext.data(), &ct_len, plaintext.data(), plaintext.size()));
 
1926
            TEST_FFI_OK(botan_pk_op_encrypt_destroy, (op_enc));
 
1927
 
 
1928
            // Test decryption
 
1929
            botan_pk_op_decrypt_t op_dec;
 
1930
            size_t pt_len = decryption.size();
 
1931
            REQUIRE_FFI_OK(botan_pk_op_decrypt_create, (&op_dec, loaded_privkey, "Raw", 0));
 
1932
            TEST_FFI_OK(botan_pk_op_decrypt, (op_dec, decryption.data(), &pt_len, ciphertext.data(), ct_len));
 
1933
            TEST_FFI_OK(botan_pk_op_decrypt_destroy, (op_dec));
 
1934
 
 
1935
            TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey));
 
1936
            TEST_FFI_OK(botan_pubkey_destroy, (pub));
 
1937
            TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey));
 
1938
            TEST_FFI_OK(botan_privkey_destroy, (priv));
 
1939
            }
 
1940
 
 
1941
         return result;
 
1942
         }
 
1943
 
 
1944
 
 
1945
      Test::Result ffi_test_dh(botan_rng_t rng)
 
1946
         {
 
1947
         Test::Result result("FFI DH");
 
1948
 
 
1949
            botan_mp_t private_x, public_g, public_p, public_y;
 
1950
 
 
1951
            botan_privkey_t loaded_privkey1;
 
1952
            botan_pubkey_t loaded_pubkey1;
 
1953
 
 
1954
            botan_mp_init(&private_x);
 
1955
 
 
1956
            botan_mp_init(&public_g);
 
1957
            botan_mp_init(&public_p);
 
1958
            botan_mp_init(&public_y);
 
1959
 
 
1960
            botan_privkey_t priv1;
 
1961
            REQUIRE_FFI_OK(botan_privkey_create_dh, (&priv1, rng, "modp/ietf/2048"));
 
1962
 
 
1963
            botan_privkey_t priv2;
 
1964
            REQUIRE_FFI_OK(botan_privkey_create_dh, (&priv2, rng, "modp/ietf/2048"));
 
1965
 
 
1966
            botan_pubkey_t pub1;
 
1967
            REQUIRE_FFI_OK(botan_privkey_export_pubkey, (&pub1, priv1));
 
1968
 
 
1969
            botan_pubkey_t pub2;
 
1970
            REQUIRE_FFI_OK(botan_privkey_export_pubkey, (&pub2, priv2));
 
1971
 
 
1972
            // Reload key-pair1 in order to test functions for key loading
 
1973
            TEST_FFI_OK(botan_privkey_get_field, (private_x, priv1, "x"));
 
1974
            TEST_FFI_OK(botan_pubkey_get_field, (public_g, pub1, "g"));
 
1975
            TEST_FFI_OK(botan_pubkey_get_field, (public_p, pub1, "p"));
 
1976
            TEST_FFI_OK(botan_pubkey_get_field, (public_y, pub1, "y"));
 
1977
 
 
1978
            TEST_FFI_OK(botan_privkey_load_dh, (&loaded_privkey1, public_p, public_g, private_x));
 
1979
 
 
1980
            TEST_FFI_OK(botan_pubkey_load_dh, (&loaded_pubkey1, public_p, public_g, public_y));
 
1981
 
 
1982
            TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey1, rng, 0));
 
1983
            TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey1, rng, 0));
 
1984
 
 
1985
            botan_mp_t loaded_public_g, loaded_public_p, loaded_public_y;
 
1986
            botan_mp_init(&loaded_public_g);
 
1987
            botan_mp_init(&loaded_public_p);
 
1988
            botan_mp_init(&loaded_public_y);
 
1989
 
 
1990
            TEST_FFI_OK(botan_pubkey_get_field, (loaded_public_g, loaded_pubkey1, "g"));
 
1991
            TEST_FFI_OK(botan_pubkey_get_field, (loaded_public_p, loaded_pubkey1, "p"));
 
1992
            TEST_FFI_OK(botan_pubkey_get_field, (loaded_public_y, loaded_pubkey1, "y"));
 
1993
 
 
1994
            int cmp;
 
1995
 
 
1996
            TEST_FFI_OK(botan_mp_cmp, (&cmp, loaded_public_g, public_g));
 
1997
            result.confirm("bigint_mp_cmp(g, g)", cmp == 0);
 
1998
 
 
1999
            TEST_FFI_OK(botan_mp_cmp, (&cmp, loaded_public_p, public_p));
 
2000
            result.confirm("bigint_mp_cmp(p, p)", cmp == 0);
 
2001
 
 
2002
            TEST_FFI_OK(botan_mp_cmp, (&cmp, loaded_public_y, public_y));
 
2003
            result.confirm("bigint_mp_cmp(y, y)", cmp == 0);
 
2004
 
 
2005
            botan_pk_op_ka_t ka1;
 
2006
            REQUIRE_FFI_OK(botan_pk_op_key_agreement_create, (&ka1, loaded_privkey1, "Raw", 0));
 
2007
            botan_pk_op_ka_t ka2;
 
2008
            REQUIRE_FFI_OK(botan_pk_op_key_agreement_create, (&ka2, priv2, "Raw", 0));
 
2009
 
 
2010
            size_t pubkey1_len = 0;
 
2011
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pk_op_key_agreement_export_public, (priv1, nullptr, &pubkey1_len));
 
2012
            std::vector<uint8_t> pubkey1(pubkey1_len);
 
2013
            REQUIRE_FFI_OK(botan_pk_op_key_agreement_export_public, (priv1, pubkey1.data(), &pubkey1_len));
 
2014
            size_t pubkey2_len = 0;
 
2015
            TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pk_op_key_agreement_export_public, (priv2, nullptr, &pubkey2_len));
 
2016
            std::vector<uint8_t> pubkey2(pubkey2_len);
 
2017
            REQUIRE_FFI_OK(botan_pk_op_key_agreement_export_public, (priv2, pubkey2.data(), &pubkey2_len));
 
2018
 
 
2019
            std::vector<uint8_t> salt(32);
 
2020
 
 
2021
            TEST_FFI_OK(botan_rng_get, (rng, salt.data(), salt.size()));
 
2022
 
 
2023
            const size_t shared_key_len = 256;
 
2024
 
 
2025
            std::vector<uint8_t> key1(shared_key_len);
 
2026
            size_t key1_len = key1.size();
 
2027
 
 
2028
            TEST_FFI_OK(botan_pk_op_key_agreement, (ka1, key1.data(), &key1_len,
 
2029
                                                    pubkey2.data(), pubkey2.size(),
 
2030
                                                    salt.data(), salt.size()));
 
2031
 
 
2032
            std::vector<uint8_t> key2(shared_key_len);
 
2033
            size_t key2_len = key2.size();
 
2034
 
 
2035
            TEST_FFI_OK(botan_pk_op_key_agreement, (ka2, key2.data(), &key2_len,
 
2036
                                                    pubkey1.data(), pubkey1.size(),
 
2037
                                                    salt.data(), salt.size()));
 
2038
 
 
2039
            result.test_eq("shared DH key", key1, key2);
 
2040
 
 
2041
            TEST_FFI_OK(botan_mp_destroy, (private_x));
 
2042
            TEST_FFI_OK(botan_mp_destroy, (public_p));
 
2043
            TEST_FFI_OK(botan_mp_destroy, (public_g));
 
2044
            TEST_FFI_OK(botan_mp_destroy, (public_y));
 
2045
 
 
2046
            TEST_FFI_OK(botan_mp_destroy, (loaded_public_p));
 
2047
            TEST_FFI_OK(botan_mp_destroy, (loaded_public_g));
 
2048
            TEST_FFI_OK(botan_mp_destroy, (loaded_public_y));
 
2049
 
 
2050
            TEST_FFI_OK(botan_pk_op_key_agreement_destroy, (ka1));
 
2051
            TEST_FFI_OK(botan_pk_op_key_agreement_destroy, (ka2));
 
2052
            TEST_FFI_OK(botan_privkey_destroy, (priv1));
 
2053
            TEST_FFI_OK(botan_privkey_destroy, (priv2));
 
2054
            TEST_FFI_OK(botan_pubkey_destroy, (pub1));
 
2055
            TEST_FFI_OK(botan_pubkey_destroy, (pub2));
 
2056
            TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey1));
 
2057
            TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey1));
 
2058
 
 
2059
         return result;
 
2060
         }
 
2061
 
 
2062
 
 
2063
   };
 
2064
 
 
2065
BOTAN_REGISTER_TEST("ffi", FFI_Unit_Tests);
 
2066
 
 
2067
#endif
 
2068
 
 
2069
}
 
2070
 
 
2071
}
 
2072