1 /*
2  * Copyright (c) 2017-2019 [Ribose Inc](https://www.ribose.com).
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *
11  * 2.  Redistributions in binary form must reproduce the above copyright notice,
12  *     this list of conditions and the following disclaimer in the documentation
13  *     and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <crypto/common.h>
28 #include <crypto.h>
29 #include <pgp-key.h>
30 #include "rnp.h"
31 #include <librepgp/stream-packet.h>
32 #include <librepgp/stream-key.h>
33 
34 #include "rnp_tests.h"
35 #include "support.h"
36 #include "fingerprint.h"
37 
TEST_F(rnp_tests,hash_test_success)38 TEST_F(rnp_tests, hash_test_success)
39 {
40     uint8_t hash_output[PGP_MAX_HASH_SIZE];
41 
42     const pgp_hash_alg_t hash_algs[] = {PGP_HASH_MD5,
43                                         PGP_HASH_SHA1,
44                                         PGP_HASH_SHA256,
45                                         PGP_HASH_SHA384,
46                                         PGP_HASH_SHA512,
47                                         PGP_HASH_SHA224,
48                                         PGP_HASH_SM3,
49                                         PGP_HASH_SHA3_256,
50                                         PGP_HASH_SHA3_512,
51                                         PGP_HASH_UNKNOWN};
52 
53     const uint8_t test_input[3] = {'a', 'b', 'c'};
54     const char *  hash_alg_expected_outputs[] = {
55       "900150983CD24FB0D6963F7D28E17F72",
56       "A9993E364706816ABA3E25717850C26C9CD0D89D",
57       "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD",
58       "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1"
59       "E7CC2358BAECA"
60       "134C825A7",
61       "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A27"
62       "4FC1A836BA3C2"
63       "3A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F",
64       "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7",
65       "66C7F0F462EEEDD9D1F2D46BDC10E4E24167C4875CF2F7A2297DA02B8F4BA8E0",
66       "3A985DA74FE225B2045C172D6BD390BD855F086E3E9D525B46BFE24511431532",
67       "B751850B1A57168A5693CD924B6B096E08F621827444F70D884F5D0240D2712E1"
68       "0E116E9192AF3C91A7EC57647E3934057340B4CF408D5A56592F8274EEC53F0"};
69 
70     for (int i = 0; hash_algs[i] != PGP_HASH_UNKNOWN; ++i) {
71 #if !defined(ENABLE_SM2)
72         if (hash_algs[i] == PGP_HASH_SM3) {
73             assert_throw({ rnp::Hash hash(hash_algs[i]); });
74             size_t hash_size = rnp::Hash::size(hash_algs[i]);
75             assert_int_equal(hash_size * 2, strlen(hash_alg_expected_outputs[i]));
76             continue;
77         }
78 #endif
79         rnp::Hash hash(hash_algs[i]);
80         size_t    hash_size = rnp::Hash::size(hash_algs[i]);
81         assert_int_equal(hash_size * 2, strlen(hash_alg_expected_outputs[i]));
82 
83         hash.add(test_input, 1);
84         hash.add(test_input + 1, sizeof(test_input) - 1);
85         hash.finish(hash_output);
86 
87         assert_int_equal(0,
88                          test_value_equal(rnp::Hash::name(hash_algs[i]),
89                                           hash_alg_expected_outputs[i],
90                                           hash_output,
91                                           hash_size));
92     }
93 }
94 
TEST_F(rnp_tests,cipher_test_success)95 TEST_F(rnp_tests, cipher_test_success)
96 {
97     const uint8_t  key[16] = {0};
98     uint8_t        iv[16];
99     pgp_symm_alg_t alg = PGP_SA_AES_128;
100     pgp_crypt_t    crypt;
101 
102     uint8_t cfb_data[20] = {0};
103     memset(iv, 0x42, sizeof(iv));
104 
105     assert_int_equal(1, pgp_cipher_cfb_start(&crypt, alg, key, iv));
106 
107     assert_int_equal(0, pgp_cipher_cfb_encrypt(&crypt, cfb_data, cfb_data, sizeof(cfb_data)));
108 
109     assert_int_equal(0,
110                      test_value_equal("AES CFB encrypt",
111                                       "BFDAA57CB812189713A950AD9947887983021617",
112                                       cfb_data,
113                                       sizeof(cfb_data)));
114     assert_int_equal(0, pgp_cipher_cfb_finish(&crypt));
115 
116     assert_int_equal(1, pgp_cipher_cfb_start(&crypt, alg, key, iv));
117     assert_int_equal(0, pgp_cipher_cfb_decrypt(&crypt, cfb_data, cfb_data, sizeof(cfb_data)));
118     assert_int_equal(0,
119                      test_value_equal("AES CFB decrypt",
120                                       "0000000000000000000000000000000000000000",
121                                       cfb_data,
122                                       sizeof(cfb_data)));
123     assert_int_equal(0, pgp_cipher_cfb_finish(&crypt));
124 }
125 
TEST_F(rnp_tests,pkcs1_rsa_test_success)126 TEST_F(rnp_tests, pkcs1_rsa_test_success)
127 {
128     uint8_t             ptext[1024 / 8] = {'a', 'b', 'c', 0};
129     uint8_t             dec[1024 / 8];
130     pgp_rsa_encrypted_t enc;
131     size_t              dec_size;
132 
133     rnp_keygen_crypto_params_t key_desc;
134     key_desc.key_alg = PGP_PKA_RSA;
135     key_desc.hash_alg = PGP_HASH_SHA256;
136     key_desc.rsa.modulus_bit_len = 1024;
137     key_desc.ctx = &global_ctx;
138     pgp_key_pkt_t seckey;
139     assert_true(pgp_generate_seckey(key_desc, seckey, true));
140     const pgp_rsa_key_t *key_rsa = &seckey.material.rsa;
141 
142     assert_rnp_success(rsa_encrypt_pkcs1(&global_ctx.rng, &enc, ptext, 3, key_rsa));
143     assert_int_equal(enc.m.len, 1024 / 8);
144 
145     memset(dec, 0, sizeof(dec));
146     dec_size = 0;
147     assert_rnp_success(rsa_decrypt_pkcs1(&global_ctx.rng, dec, &dec_size, &enc, key_rsa));
148     test_value_equal("RSA 1024 decrypt", "616263", dec, 3);
149     assert_int_equal(dec_size, 3);
150 }
151 
TEST_F(rnp_tests,rnp_test_eddsa)152 TEST_F(rnp_tests, rnp_test_eddsa)
153 {
154     rnp::SecurityContext       ctx;
155     rnp_keygen_crypto_params_t key_desc;
156     key_desc.key_alg = PGP_PKA_EDDSA;
157     key_desc.hash_alg = PGP_HASH_SHA256;
158     key_desc.ctx = &ctx;
159 
160     pgp_key_pkt_t seckey;
161     assert_true(pgp_generate_seckey(key_desc, seckey, true));
162 
163     const uint8_t      hash[32] = {0};
164     pgp_ec_signature_t sig = {{{0}}};
165 
166     assert_rnp_success(
167       eddsa_sign(&global_ctx.rng, &sig, hash, sizeof(hash), &seckey.material.ec));
168 
169     assert_rnp_success(eddsa_verify(&sig, hash, sizeof(hash), &seckey.material.ec));
170 
171     // cut one byte off hash -> invalid sig
172     assert_rnp_failure(eddsa_verify(&sig, hash, sizeof(hash) - 1, &seckey.material.ec));
173 
174     // swap r/s -> invalid sig
175     pgp_mpi_t tmp = sig.r;
176     sig.r = sig.s;
177     sig.s = tmp;
178     assert_rnp_failure(eddsa_verify(&sig, hash, sizeof(hash), &seckey.material.ec));
179 }
180 
TEST_F(rnp_tests,rnp_test_x25519)181 TEST_F(rnp_tests, rnp_test_x25519)
182 {
183     rnp_keygen_crypto_params_t key_desc = {};
184     pgp_key_pkt_t              seckey;
185     pgp_ecdh_encrypted_t       enc = {};
186     uint8_t           in[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
187     uint8_t           out[16] = {};
188     size_t            outlen = 0;
189     pgp_fingerprint_t fp = {};
190 
191     key_desc.key_alg = PGP_PKA_ECDH;
192     key_desc.hash_alg = PGP_HASH_SHA256;
193     key_desc.ctx = &global_ctx;
194     key_desc.ecc.curve = PGP_CURVE_25519;
195 
196     assert_true(pgp_generate_seckey(key_desc, seckey, true));
197     /* check for length and correctly tweaked bits */
198     assert_int_equal(seckey.material.ec.x.len, 32);
199     assert_int_equal(seckey.material.ec.x.mpi[31] & 7, 0);
200     assert_int_equal(seckey.material.ec.x.mpi[0] & 128, 0);
201     assert_int_equal(seckey.material.ec.x.mpi[0] & 64, 64);
202     assert_rnp_success(pgp_fingerprint(fp, seckey));
203     assert_rnp_success(
204       ecdh_encrypt_pkcs5(&global_ctx.rng, &enc, in, sizeof(in), &seckey.material.ec, fp));
205     assert_true(enc.mlen > 16);
206     assert_true((enc.p.mpi[0] == 0x40) && (enc.p.len == 33));
207     outlen = sizeof(out);
208     assert_rnp_success(ecdh_decrypt_pkcs5(out, &outlen, &enc, &seckey.material.ec, fp));
209     assert_true(outlen == 16);
210     assert_true(memcmp(in, out, 16) == 0);
211 
212     /* negative cases */
213     enc.p.mpi[16] ^= 0xff;
214     assert_rnp_failure(ecdh_decrypt_pkcs5(out, &outlen, &enc, &seckey.material.ec, fp));
215 
216     enc.p.mpi[16] ^= 0xff;
217     enc.p.mpi[0] = 0x04;
218     assert_rnp_failure(ecdh_decrypt_pkcs5(out, &outlen, &enc, &seckey.material.ec, fp));
219 
220     enc.p.mpi[0] = 0x40;
221     enc.mlen--;
222     assert_rnp_failure(ecdh_decrypt_pkcs5(out, &outlen, &enc, &seckey.material.ec, fp));
223 
224     enc.mlen += 2;
225     assert_rnp_failure(ecdh_decrypt_pkcs5(out, &outlen, &enc, &seckey.material.ec, fp));
226 }
227 
228 static void
elgamal_roundtrip(pgp_eg_key_t * key)229 elgamal_roundtrip(pgp_eg_key_t *key)
230 {
231     const uint8_t      in_b[] = {0x01, 0x02, 0x03, 0x04, 0x17};
232     pgp_eg_encrypted_t enc = {{{0}}};
233     uint8_t            res[1024];
234     size_t             res_len = 0;
235 
236     assert_int_equal(elgamal_encrypt_pkcs1(&global_ctx.rng, &enc, in_b, sizeof(in_b), key),
237                      RNP_SUCCESS);
238     assert_int_equal(elgamal_decrypt_pkcs1(&global_ctx.rng, res, &res_len, &enc, key),
239                      RNP_SUCCESS);
240     assert_int_equal(res_len, sizeof(in_b));
241     assert_int_equal(0, test_value_equal("ElGamal decrypt", "0102030417", res, res_len));
242 }
243 
TEST_F(rnp_tests,raw_elgamal_random_key_test_success)244 TEST_F(rnp_tests, raw_elgamal_random_key_test_success)
245 {
246     pgp_eg_key_t key;
247 
248     assert_int_equal(elgamal_generate(&global_ctx.rng, &key, 1024), RNP_SUCCESS);
249     elgamal_roundtrip(&key);
250 }
251 
TEST_F(rnp_tests,ecdsa_signverify_success)252 TEST_F(rnp_tests, ecdsa_signverify_success)
253 {
254     uint8_t              message[64];
255     const pgp_hash_alg_t hash_alg = PGP_HASH_SHA512;
256 
257     struct curve {
258         pgp_curve_t id;
259         size_t      size;
260     } curves[] = {
261       {PGP_CURVE_NIST_P_256, 32}, {PGP_CURVE_NIST_P_384, 48}, {PGP_CURVE_NIST_P_521, 64}};
262 
263     for (size_t i = 0; i < ARRAY_SIZE(curves); i++) {
264         // Generate test data. Mainly to make valgrind not to complain about uninitialized data
265         global_ctx.rng.get(message, sizeof(message));
266 
267         pgp_ec_signature_t         sig = {{{0}}};
268         rnp_keygen_crypto_params_t key_desc;
269         key_desc.key_alg = PGP_PKA_ECDSA;
270         key_desc.hash_alg = hash_alg;
271         key_desc.ecc.curve = curves[i].id;
272         key_desc.ctx = &global_ctx;
273 
274         pgp_key_pkt_t seckey1;
275         pgp_key_pkt_t seckey2;
276 
277         assert_true(pgp_generate_seckey(key_desc, seckey1, true));
278         assert_true(pgp_generate_seckey(key_desc, seckey2, true));
279 
280         const pgp_ec_key_t *key1 = &seckey1.material.ec;
281         const pgp_ec_key_t *key2 = &seckey2.material.ec;
282 
283         assert_rnp_success(
284           ecdsa_sign(&global_ctx.rng, &sig, hash_alg, message, sizeof(message), key1));
285 
286         assert_rnp_success(ecdsa_verify(&sig, hash_alg, message, sizeof(message), key1));
287 
288         // Fails because of different key used
289         assert_rnp_failure(ecdsa_verify(&sig, hash_alg, message, sizeof(message), key2));
290 
291         // Fails because message won't verify
292         message[0] = ~message[0];
293         assert_rnp_failure(ecdsa_verify(&sig, hash_alg, message, sizeof(message), key1));
294     }
295 }
296 
TEST_F(rnp_tests,ecdh_roundtrip)297 TEST_F(rnp_tests, ecdh_roundtrip)
298 {
299     struct curve {
300         pgp_curve_t id;
301         size_t      size;
302     } curves[] = {
303       {PGP_CURVE_NIST_P_256, 32}, {PGP_CURVE_NIST_P_384, 48}, {PGP_CURVE_NIST_P_521, 66}};
304 
305     pgp_ecdh_encrypted_t enc;
306     uint8_t              plaintext[32] = {0};
307     size_t               plaintext_len = sizeof(plaintext);
308     uint8_t              result[32] = {0};
309     size_t               result_len = sizeof(result);
310 
311     for (size_t i = 0; i < ARRAY_SIZE(curves); i++) {
312         rnp_keygen_crypto_params_t key_desc;
313         key_desc.key_alg = PGP_PKA_ECDH;
314         key_desc.hash_alg = PGP_HASH_SHA512;
315         key_desc.ecc.curve = curves[i].id;
316         key_desc.ctx = &global_ctx;
317 
318         pgp_key_pkt_t ecdh_key1;
319         assert_true(pgp_generate_seckey(key_desc, ecdh_key1, true));
320 
321         pgp_fingerprint_t ecdh_key1_fpr = {};
322         assert_rnp_success(pgp_fingerprint(ecdh_key1_fpr, ecdh_key1));
323 
324         assert_rnp_success(ecdh_encrypt_pkcs5(&global_ctx.rng,
325                                               &enc,
326                                               plaintext,
327                                               plaintext_len,
328                                               &ecdh_key1.material.ec,
329                                               ecdh_key1_fpr));
330 
331         assert_rnp_success(ecdh_decrypt_pkcs5(
332           result, &result_len, &enc, &ecdh_key1.material.ec, ecdh_key1_fpr));
333 
334         assert_int_equal(plaintext_len, result_len);
335         assert_int_equal(memcmp(plaintext, result, result_len), 0);
336     }
337 }
338 
TEST_F(rnp_tests,ecdh_decryptionNegativeCases)339 TEST_F(rnp_tests, ecdh_decryptionNegativeCases)
340 {
341     uint8_t              plaintext[32] = {0};
342     size_t               plaintext_len = sizeof(plaintext);
343     uint8_t              result[32] = {0};
344     size_t               result_len = sizeof(result);
345     pgp_ecdh_encrypted_t enc;
346 
347     rnp_keygen_crypto_params_t key_desc;
348     key_desc.key_alg = PGP_PKA_ECDH;
349     key_desc.hash_alg = PGP_HASH_SHA512;
350     key_desc.ecc = {.curve = PGP_CURVE_NIST_P_256};
351     key_desc.ctx = &global_ctx;
352 
353     pgp_key_pkt_t ecdh_key1;
354     assert_true(pgp_generate_seckey(key_desc, ecdh_key1, true));
355 
356     pgp_fingerprint_t ecdh_key1_fpr = {};
357     assert_rnp_success(pgp_fingerprint(ecdh_key1_fpr, ecdh_key1));
358 
359     assert_rnp_success(ecdh_encrypt_pkcs5(
360       &global_ctx.rng, &enc, plaintext, plaintext_len, &ecdh_key1.material.ec, ecdh_key1_fpr));
361 
362     assert_int_equal(ecdh_decrypt_pkcs5(NULL, 0, &enc, &ecdh_key1.material.ec, ecdh_key1_fpr),
363                      RNP_ERROR_BAD_PARAMETERS);
364 
365     assert_int_equal(ecdh_decrypt_pkcs5(result, &result_len, &enc, NULL, ecdh_key1_fpr),
366                      RNP_ERROR_BAD_PARAMETERS);
367 
368     assert_int_equal(
369       ecdh_decrypt_pkcs5(result, &result_len, NULL, &ecdh_key1.material.ec, ecdh_key1_fpr),
370       RNP_ERROR_BAD_PARAMETERS);
371 
372     size_t mlen = enc.mlen;
373     enc.mlen = 0;
374     assert_int_equal(
375       ecdh_decrypt_pkcs5(result, &result_len, &enc, &ecdh_key1.material.ec, ecdh_key1_fpr),
376       RNP_ERROR_GENERIC);
377 
378     enc.mlen = mlen - 1;
379     assert_int_equal(
380       ecdh_decrypt_pkcs5(result, &result_len, &enc, &ecdh_key1.material.ec, ecdh_key1_fpr),
381       RNP_ERROR_GENERIC);
382 
383     int key_wrapping_alg = ecdh_key1.material.ec.key_wrap_alg;
384     ecdh_key1.material.ec.key_wrap_alg = PGP_SA_IDEA;
385     assert_int_equal(
386       ecdh_decrypt_pkcs5(result, &result_len, &enc, &ecdh_key1.material.ec, ecdh_key1_fpr),
387       RNP_ERROR_NOT_SUPPORTED);
388     ecdh_key1.material.ec.key_wrap_alg = (pgp_symm_alg_t) key_wrapping_alg;
389 }
390 
391 #if defined(ENABLE_SM2)
TEST_F(rnp_tests,sm2_roundtrip)392 TEST_F(rnp_tests, sm2_roundtrip)
393 {
394     uint8_t key[27] = {0};
395     uint8_t decrypted[27];
396     size_t  decrypted_size;
397 
398     rnp_keygen_crypto_params_t key_desc;
399     key_desc.key_alg = PGP_PKA_SM2;
400     key_desc.hash_alg = PGP_HASH_SM3;
401     key_desc.ecc = {.curve = PGP_CURVE_SM2_P_256};
402     key_desc.ctx = &global_ctx;
403 
404     global_ctx.rng.get(key, sizeof(key));
405 
406     pgp_key_pkt_t seckey;
407     assert_true(pgp_generate_seckey(key_desc, seckey, true));
408 
409     const pgp_ec_key_t *eckey = &seckey.material.ec;
410 
411     pgp_hash_alg_t      hashes[] = {PGP_HASH_SM3, PGP_HASH_SHA256, PGP_HASH_SHA512};
412     pgp_sm2_encrypted_t enc;
413     rnp_result_t        ret;
414 
415     for (size_t i = 0; i < ARRAY_SIZE(hashes); ++i) {
416         ret = sm2_encrypt(&global_ctx.rng, &enc, key, sizeof(key), hashes[i], eckey);
417         assert_int_equal(ret, RNP_SUCCESS);
418 
419         memset(decrypted, 0, sizeof(decrypted));
420         decrypted_size = sizeof(decrypted);
421         ret = sm2_decrypt(decrypted, &decrypted_size, &enc, eckey);
422         assert_int_equal(ret, RNP_SUCCESS);
423         assert_int_equal(decrypted_size, sizeof(key));
424         for (size_t i = 0; i < decrypted_size; ++i) {
425             assert_int_equal(key[i], decrypted[i]);
426         }
427     }
428 }
429 #endif
430 
431 #if defined(ENABLE_SM2)
TEST_F(rnp_tests,sm2_sm3_signature_test)432 TEST_F(rnp_tests, sm2_sm3_signature_test)
433 {
434     const char *msg = "no backdoors here";
435 
436     pgp_ec_key_t       sm2_key;
437     pgp_ec_signature_t sig;
438 
439     pgp_hash_alg_t hash_alg = PGP_HASH_SM3;
440     const size_t   hash_len = rnp::Hash::size(hash_alg);
441 
442     uint8_t digest[PGP_MAX_HASH_SIZE];
443 
444     sm2_key.curve = PGP_CURVE_NIST_P_256;
445 
446     hex2mpi(&sm2_key.p,
447             "04d9a2025f1ab59bc44e35fc53aeb8e87a79787d30cd70a1f7c49e064b8b8a2fb24d8"
448             "c82f49ee0a5b11df22cb0c3c6d9d5526d9e24d02ff8c83c06a859c26565f1");
449     hex2mpi(&sm2_key.x, "110E7973206F68C19EE5F7328C036F26911C8C73B4E4F36AE3291097F8984FFC");
450 
451     assert_int_equal(sm2_validate_key(&global_ctx.rng, &sm2_key, true), RNP_SUCCESS);
452 
453     rnp::Hash hash(hash_alg);
454 
455     assert_int_equal(sm2_compute_za(sm2_key, hash, "sm2_p256_test@example.com"), RNP_SUCCESS);
456     hash.add(msg, strlen(msg));
457     assert_int_equal(hash.finish(digest), hash_len);
458 
459     // First generate a signature, then verify it
460     assert_int_equal(sm2_sign(&global_ctx.rng, &sig, hash_alg, digest, hash_len, &sm2_key),
461                      RNP_SUCCESS);
462     assert_int_equal(sm2_verify(&sig, hash_alg, digest, hash_len, &sm2_key), RNP_SUCCESS);
463 
464     // Check that invalid signatures are rejected
465     digest[0] ^= 1;
466     assert_int_not_equal(sm2_verify(&sig, hash_alg, digest, hash_len, &sm2_key), RNP_SUCCESS);
467 
468     digest[0] ^= 1;
469     assert_int_equal(sm2_verify(&sig, hash_alg, digest, hash_len, &sm2_key), RNP_SUCCESS);
470 
471     // Now verify a known good signature for this key/message (generated by GmSSL)
472     hex2mpi(&sig.r, "96AA39A0C4A5C454653F394E86386F2E38BE14C57D0E555F3A27A5CEF30E51BD");
473     hex2mpi(&sig.s, "62372BE4AC97DBE725AC0B279BB8FD15883858D814FD792DDB0A401DCC988E70");
474     assert_int_equal(sm2_verify(&sig, hash_alg, digest, hash_len, &sm2_key), RNP_SUCCESS);
475 }
476 #endif
477 
478 #if defined(ENABLE_SM2)
TEST_F(rnp_tests,sm2_sha256_signature_test)479 TEST_F(rnp_tests, sm2_sha256_signature_test)
480 {
481     const char *       msg = "hi chappy";
482     pgp_ec_key_t       sm2_key;
483     pgp_ec_signature_t sig;
484     pgp_hash_alg_t     hash_alg = PGP_HASH_SHA256;
485     const size_t       hash_len = rnp::Hash::size(hash_alg);
486     uint8_t            digest[PGP_MAX_HASH_SIZE];
487 
488     sm2_key.curve = PGP_CURVE_SM2_P_256;
489     hex2mpi(&sm2_key.p,
490             "04d03d30dd01ca3422aeaccf9b88043b554659d3092b0a9e8cce3e8c4530a98cb79d7"
491             "05e6213eee145b748e36e274e5f101dc10d7bbc9dab9a04022e73b76e02cd");
492     hex2mpi(&sm2_key.x, "110E7973206F68C19EE5F7328C036F26911C8C73B4E4F36AE3291097F8984FFC");
493 
494     assert_int_equal(sm2_validate_key(&global_ctx.rng, &sm2_key, true), RNP_SUCCESS);
495 
496     rnp::Hash hash(hash_alg);
497     assert_int_equal(sm2_compute_za(sm2_key, hash, "sm2test@example.com"), RNP_SUCCESS);
498     hash.add(msg, strlen(msg));
499     assert_int_equal(hash.finish(digest), hash_len);
500 
501     // First generate a signature, then verify it
502     assert_int_equal(sm2_sign(&global_ctx.rng, &sig, hash_alg, digest, hash_len, &sm2_key),
503                      RNP_SUCCESS);
504     assert_int_equal(sm2_verify(&sig, hash_alg, digest, hash_len, &sm2_key), RNP_SUCCESS);
505 
506     // Check that invalid signatures are rejected
507     digest[0] ^= 1;
508     assert_int_not_equal(sm2_verify(&sig, hash_alg, digest, hash_len, &sm2_key), RNP_SUCCESS);
509 
510     digest[0] ^= 1;
511     assert_int_equal(sm2_verify(&sig, hash_alg, digest, hash_len, &sm2_key), RNP_SUCCESS);
512 
513     // Now verify a known good signature for this key/message (generated by GmSSL)
514     hex2mpi(&sig.r, "94DA20EA69E4FC70692158BF3D30F87682A4B2F84DF4A4829A1EFC5D9C979D3F");
515     hex2mpi(&sig.s, "EE15AF8D455B728AB80E592FCB654BF5B05620B2F4D25749D263D5C01FAD365F");
516     assert_int_equal(sm2_verify(&sig, hash_alg, digest, hash_len, &sm2_key), RNP_SUCCESS);
517 }
518 #endif
519 
TEST_F(rnp_tests,test_dsa_roundtrip)520 TEST_F(rnp_tests, test_dsa_roundtrip)
521 {
522     uint8_t             message[PGP_MAX_HASH_SIZE];
523     pgp_key_pkt_t       seckey;
524     pgp_dsa_signature_t sig;
525 
526     struct key_params {
527         size_t         p;
528         size_t         q;
529         pgp_hash_alg_t h;
530     } keys[] = {
531       // all 1024 key-hash combinations
532       {1024, 160, PGP_HASH_SHA1},
533       {1024, 160, PGP_HASH_SHA224},
534       {1024, 160, PGP_HASH_SHA256},
535       {1024, 160, PGP_HASH_SHA384},
536       {1024, 160, PGP_HASH_SHA512},
537       // all 2048 key-hash combinations
538       {2048, 256, PGP_HASH_SHA256},
539       {2048, 256, PGP_HASH_SHA384},
540       {2048, 256, PGP_HASH_SHA512},
541       // misc
542       {1088, 224, PGP_HASH_SHA512},
543       {1024, 256, PGP_HASH_SHA256},
544     };
545 
546     global_ctx.rng.get(message, sizeof(message));
547 
548     for (size_t i = 0; i < ARRAY_SIZE(keys); i++) {
549         sig = {};
550         rnp_keygen_crypto_params_t key_desc;
551         key_desc.key_alg = PGP_PKA_DSA;
552         key_desc.hash_alg = keys[i].h;
553         key_desc.dsa.p_bitlen = keys[i].p;
554         key_desc.dsa.q_bitlen = keys[i].q;
555         key_desc.ctx = &global_ctx;
556 
557         assert_true(pgp_generate_seckey(key_desc, seckey, true));
558         // try to prevent timeouts in travis-ci
559         printf("p: %zu q: %zu h: %s\n",
560                key_desc.dsa.p_bitlen,
561                key_desc.dsa.q_bitlen,
562                rnp::Hash::name(key_desc.hash_alg));
563         fflush(stdout);
564 
565         pgp_dsa_key_t *key1 = &seckey.material.dsa;
566 
567         size_t h_size = rnp::Hash::size(keys[i].h);
568         assert_int_equal(dsa_sign(&global_ctx.rng, &sig, message, h_size, key1), RNP_SUCCESS);
569         assert_int_equal(dsa_verify(&sig, message, h_size, key1), RNP_SUCCESS);
570     }
571 }
572 
TEST_F(rnp_tests,test_dsa_verify_negative)573 TEST_F(rnp_tests, test_dsa_verify_negative)
574 {
575     uint8_t             message[PGP_MAX_HASH_SIZE];
576     pgp_key_pkt_t       sec_key1;
577     pgp_key_pkt_t       sec_key2;
578     pgp_dsa_signature_t sig = {};
579 
580     struct key_params {
581         size_t         p;
582         size_t         q;
583         pgp_hash_alg_t h;
584     } key = {1024, 160, PGP_HASH_SHA1};
585 
586     global_ctx.rng.get(message, sizeof(message));
587 
588     rnp_keygen_crypto_params_t key_desc;
589     key_desc.key_alg = PGP_PKA_DSA;
590     key_desc.hash_alg = key.h;
591     key_desc.dsa.p_bitlen = key.p;
592     key_desc.dsa.q_bitlen = key.q;
593     key_desc.ctx = &global_ctx;
594 
595     assert_true(pgp_generate_seckey(key_desc, sec_key1, true));
596     // try to prevent timeouts in travis-ci
597     printf("p: %zu q: %zu h: %s\n",
598            key_desc.dsa.p_bitlen,
599            key_desc.dsa.q_bitlen,
600            rnp::Hash::name(key_desc.hash_alg));
601     assert_true(pgp_generate_seckey(key_desc, sec_key2, true));
602 
603     pgp_dsa_key_t *key1 = &sec_key1.material.dsa;
604     pgp_dsa_key_t *key2 = &sec_key2.material.dsa;
605 
606     size_t h_size = rnp::Hash::size(key.h);
607     assert_int_equal(dsa_sign(&global_ctx.rng, &sig, message, h_size, key1), RNP_SUCCESS);
608     // wrong key used
609     assert_int_equal(dsa_verify(&sig, message, h_size, key2), RNP_ERROR_SIGNATURE_INVALID);
610     // different message
611     message[0] = ~message[0];
612     assert_int_equal(dsa_verify(&sig, message, h_size, key1), RNP_ERROR_SIGNATURE_INVALID);
613 }
614 
615 // platforms known to not have a robust response can compile with
616 // -DS2K_MINIMUM_TUNING_RATIO=2 (or whatever they need)
617 #ifndef S2K_MINIMUM_TUNING_RATIO
618 #define S2K_MINIMUM_TUNING_RATIO 6
619 #endif
620 
TEST_F(rnp_tests,s2k_iteration_tuning)621 TEST_F(rnp_tests, s2k_iteration_tuning)
622 {
623     pgp_hash_alg_t hash_alg = PGP_HASH_SHA512;
624 
625     /*
626     Run trials for a while (1/4 second) to ensure dynamically clocked
627     cores spin up to full speed.
628     */
629     const size_t TRIAL_MSEC = 250;
630 
631     const size_t iters_100 = pgp_s2k_compute_iters(hash_alg, 100, TRIAL_MSEC);
632     const size_t iters_10 = pgp_s2k_compute_iters(hash_alg, 10, TRIAL_MSEC);
633 
634     double ratio = static_cast<double>(iters_100) / iters_10;
635     printf("s2k iteration tuning ratio: %g, (%zu:%zu)\n", ratio, iters_10, iters_100);
636     // Test roughly linear cost, often skeyed by clock idle
637     assert_greater_than(ratio, S2K_MINIMUM_TUNING_RATIO);
638 
639     // Should not crash for unknown hash algorithm
640     assert_int_equal(pgp_s2k_compute_iters(PGP_HASH_UNKNOWN, 1000, TRIAL_MSEC), 0);
641     /// TODO test that hashing iters_xx data takes roughly requested time
642 }
643 
TEST_F(rnp_tests,s2k_iteration_encode_decode)644 TEST_F(rnp_tests, s2k_iteration_encode_decode)
645 {
646     const size_t MAX_ITER = 0x3e00000; // 0x1F << (0xF + 6);
647     // encoding tests
648     assert_int_equal(pgp_s2k_encode_iterations(0), 0);
649     assert_int_equal(pgp_s2k_encode_iterations(512), 0);
650     assert_int_equal(pgp_s2k_encode_iterations(1024), 0);
651     assert_int_equal(pgp_s2k_encode_iterations(1024), 0);
652     assert_int_equal(pgp_s2k_encode_iterations(1025), 1);
653     assert_int_equal(pgp_s2k_encode_iterations(1088), 1);
654     assert_int_equal(pgp_s2k_encode_iterations(1089), 2);
655     assert_int_equal(pgp_s2k_encode_iterations(2048), 16);
656     assert_int_equal(pgp_s2k_encode_iterations(MAX_ITER - 1), 0xFF);
657     assert_int_equal(pgp_s2k_encode_iterations(MAX_ITER), 0xFF);
658     assert_int_equal(pgp_s2k_encode_iterations(MAX_ITER + 1), 0xFF);
659     assert_int_equal(pgp_s2k_encode_iterations(SIZE_MAX), 0xFF);
660     // decoding tests
661     assert_int_equal(pgp_s2k_decode_iterations(0), 1024);
662     assert_int_equal(pgp_s2k_decode_iterations(1), 1088);
663     assert_int_equal(pgp_s2k_decode_iterations(16), 2048);
664     assert_int_equal(pgp_s2k_decode_iterations(0xFF), MAX_ITER);
665 }
666 
667 static bool
read_key_pkt(pgp_key_pkt_t * key,const char * path)668 read_key_pkt(pgp_key_pkt_t *key, const char *path)
669 {
670     pgp_source_t src = {};
671     if (init_file_src(&src, path)) {
672         return false;
673     }
674     bool res = !key->parse(src);
675     src_close(&src);
676     return res;
677 }
678 
679 #define KEYS "data/test_validate_key_material/"
680 
TEST_F(rnp_tests,test_validate_key_material)681 TEST_F(rnp_tests, test_validate_key_material)
682 {
683     pgp_key_pkt_t key;
684     rnp::RNG &    rng = global_ctx.rng;
685 
686     /* RSA key and subkey */
687     assert_true(read_key_pkt(&key, KEYS "rsa-pub.pgp"));
688     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
689     key.material.rsa.n.mpi[key.material.rsa.n.len - 1] &= ~1;
690     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
691     key.material.rsa.n.mpi[key.material.rsa.n.len - 1] |= 1;
692     key.material.rsa.e.mpi[key.material.rsa.e.len - 1] &= ~1;
693     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
694     key = pgp_key_pkt_t();
695 
696     assert_true(read_key_pkt(&key, KEYS "rsa-sub.pgp"));
697     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
698     key.material.rsa.n.mpi[key.material.rsa.n.len - 1] &= ~1;
699     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
700     key.material.rsa.n.mpi[key.material.rsa.n.len - 1] |= 1;
701     key.material.rsa.e.mpi[key.material.rsa.e.len - 1] &= ~1;
702     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
703     key = pgp_key_pkt_t();
704 
705     assert_true(read_key_pkt(&key, KEYS "rsa-sec.pgp"));
706     key.material.validate(global_ctx);
707     assert_true(key.material.validity.valid);
708     assert_true(key.material.validity.validated);
709     assert_rnp_success(decrypt_secret_key(&key, NULL));
710     /* make sure validity is reset after decryption */
711     assert_false(key.material.validity.valid);
712     assert_false(key.material.validity.validated);
713     assert_true(key.material.secret);
714     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
715     key.material.rsa.e.mpi[key.material.rsa.e.len - 1] += 1;
716     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
717     key.material.rsa.e.mpi[key.material.rsa.e.len - 1] -= 1;
718     key.material.rsa.p.mpi[key.material.rsa.p.len - 1] += 2;
719     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
720     key.material.rsa.p.mpi[key.material.rsa.p.len - 1] -= 2;
721     key.material.rsa.p.mpi[key.material.rsa.q.len - 1] += 2;
722     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
723     key.material.rsa.p.mpi[key.material.rsa.q.len - 1] -= 2;
724     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
725     key = pgp_key_pkt_t();
726 
727     assert_true(read_key_pkt(&key, KEYS "rsa-ssb.pgp"));
728     assert_rnp_success(decrypt_secret_key(&key, NULL));
729     assert_true(key.material.secret);
730     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
731     key.material.rsa.e.mpi[key.material.rsa.e.len - 1] += 1;
732     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
733     key.material.rsa.e.mpi[key.material.rsa.e.len - 1] -= 1;
734     key.material.rsa.p.mpi[key.material.rsa.p.len - 1] += 2;
735     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
736     key.material.rsa.p.mpi[key.material.rsa.p.len - 1] -= 2;
737     key.material.rsa.p.mpi[key.material.rsa.q.len - 1] += 2;
738     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
739     key.material.rsa.p.mpi[key.material.rsa.q.len - 1] -= 2;
740     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
741     key = pgp_key_pkt_t();
742 
743     /* DSA-ElGamal key */
744     assert_true(read_key_pkt(&key, KEYS "dsa-sec.pgp"));
745     key.material.dsa.q.mpi[key.material.dsa.q.len - 1] += 2;
746     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
747     key.material.dsa.q.mpi[key.material.dsa.q.len - 1] -= 2;
748     assert_rnp_success(decrypt_secret_key(&key, NULL));
749     assert_true(key.material.secret);
750     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
751     key.material.dsa.y.mpi[key.material.dsa.y.len - 1] += 2;
752     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
753     key.material.dsa.y.mpi[key.material.dsa.y.len - 1] -= 2;
754     key.material.dsa.p.mpi[key.material.dsa.p.len - 1] += 2;
755     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
756     key.material.dsa.p.mpi[key.material.dsa.p.len - 1] -= 2;
757     /* since Botan calculates y from x on key load we do not check x vs y */
758     key.material.dsa.x = key.material.dsa.q;
759     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
760     key = pgp_key_pkt_t();
761 
762     assert_true(read_key_pkt(&key, KEYS "eg-sec.pgp"));
763     key.material.eg.p.mpi[key.material.eg.p.len - 1] += 2;
764     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
765     key.material.eg.p.mpi[key.material.eg.p.len - 1] -= 2;
766     assert_rnp_success(decrypt_secret_key(&key, NULL));
767     assert_true(key.material.secret);
768     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
769     key.material.eg.p.mpi[key.material.eg.p.len - 1] += 2;
770     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
771     key.material.eg.p.mpi[key.material.eg.p.len - 1] -= 2;
772     /* since Botan calculates y from x on key load we do not check x vs y */
773     key.material.eg.x = key.material.eg.p;
774     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
775     key = pgp_key_pkt_t();
776 
777     /* ElGamal key with small subgroup */
778     assert_true(read_key_pkt(&key, KEYS "eg-sec-small-group.pgp"));
779     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
780     assert_rnp_success(decrypt_secret_key(&key, NULL));
781     key = pgp_key_pkt_t();
782 
783     assert_true(read_key_pkt(&key, KEYS "eg-sec-small-group-enc.pgp"));
784     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
785     assert_rnp_success(decrypt_secret_key(&key, "password"));
786     key = pgp_key_pkt_t();
787 
788     /* ECDSA key */
789     assert_true(read_key_pkt(&key, KEYS "ecdsa-p256-sec.pgp"));
790     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
791     key.material.ec.p.mpi[0] += 2;
792     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
793     key.material.ec.p.mpi[0] -= 2;
794     key.material.ec.p.mpi[10] += 2;
795     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
796     key.material.ec.p.mpi[10] -= 2;
797     assert_rnp_success(decrypt_secret_key(&key, NULL));
798     assert_true(key.material.secret);
799     key = pgp_key_pkt_t();
800 
801     /* ECDH key */
802     assert_true(read_key_pkt(&key, KEYS "ecdh-p256-sec.pgp"));
803     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
804     key.material.ec.p.mpi[0] += 2;
805     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
806     key.material.ec.p.mpi[0] -= 2;
807     key.material.ec.p.mpi[10] += 2;
808     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
809     key.material.ec.p.mpi[10] -= 2;
810     assert_rnp_success(decrypt_secret_key(&key, NULL));
811     assert_true(key.material.secret);
812     key = pgp_key_pkt_t();
813 
814     /* EDDSA key, just test for header since any value can be secret key */
815     assert_true(read_key_pkt(&key, KEYS "ed25519-sec.pgp"));
816     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
817     key.material.ec.p.mpi[0] += 2;
818     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
819     key.material.ec.p.mpi[0] -= 2;
820     key = pgp_key_pkt_t();
821 
822     /* x25519 key, same as the previous - botan calculates pub key from the secret one */
823     assert_true(read_key_pkt(&key, KEYS "x25519-sec.pgp"));
824     assert_rnp_success(validate_pgp_key_material(&key.material, &rng));
825     key.material.ec.p.mpi[0] += 2;
826     assert_rnp_failure(validate_pgp_key_material(&key.material, &rng));
827     key.material.ec.p.mpi[0] -= 2;
828     key = pgp_key_pkt_t();
829 }
830 
TEST_F(rnp_tests,test_sm2_enabled)831 TEST_F(rnp_tests, test_sm2_enabled)
832 {
833     char *features = NULL;
834     bool  supported = false;
835     /* check whether FFI returns value which corresponds to defines */
836 #if defined(ENABLE_SM2)
837     assert_true(sm2_enabled());
838     /* SM2 */
839     assert_rnp_success(rnp_supported_features(RNP_FEATURE_PK_ALG, &features));
840     assert_non_null(features);
841     assert_true(std::string(features).find("SM2") != std::string::npos);
842     rnp_buffer_destroy(features);
843     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_PK_ALG, "SM2", &supported));
844     assert_true(supported);
845     /* SM3 */
846     assert_rnp_success(rnp_supported_features(RNP_FEATURE_HASH_ALG, &features));
847     assert_non_null(features);
848     assert_true(std::string(features).find("SM3") != std::string::npos);
849     rnp_buffer_destroy(features);
850     supported = false;
851     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_HASH_ALG, "SM3", &supported));
852     assert_true(supported);
853     /* SM4 */
854     assert_rnp_success(rnp_supported_features(RNP_FEATURE_SYMM_ALG, &features));
855     assert_non_null(features);
856     assert_true(std::string(features).find("SM4") != std::string::npos);
857     rnp_buffer_destroy(features);
858     supported = false;
859     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_SYMM_ALG, "SM4", &supported));
860     assert_true(supported);
861     /* Curve */
862     assert_rnp_success(rnp_supported_features(RNP_FEATURE_CURVE, &features));
863     assert_non_null(features);
864     assert_true(std::string(features).find("SM2 P-256") != std::string::npos);
865     rnp_buffer_destroy(features);
866     supported = false;
867     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_CURVE, "SM2 P-256", &supported));
868     assert_true(supported);
869 #else
870     assert_false(sm2_enabled());
871     /* SM2 */
872     assert_rnp_success(rnp_supported_features(RNP_FEATURE_PK_ALG, &features));
873     assert_non_null(features);
874     assert_true(std::string(features).find("SM2") == std::string::npos);
875     rnp_buffer_destroy(features);
876     supported = true;
877     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_PK_ALG, "SM2", &supported));
878     assert_false(supported);
879     /* SM3 */
880     assert_rnp_success(rnp_supported_features(RNP_FEATURE_HASH_ALG, &features));
881     assert_non_null(features);
882     assert_true(std::string(features).find("SM3") == std::string::npos);
883     rnp_buffer_destroy(features);
884     supported = true;
885     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_HASH_ALG, "SM3", &supported));
886     assert_false(supported);
887     /* SM4 */
888     assert_rnp_success(rnp_supported_features(RNP_FEATURE_SYMM_ALG, &features));
889     assert_non_null(features);
890     assert_true(std::string(features).find("SM4") == std::string::npos);
891     rnp_buffer_destroy(features);
892     supported = true;
893     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_SYMM_ALG, "SM4", &supported));
894     assert_false(supported);
895     /* Curve */
896     assert_rnp_success(rnp_supported_features(RNP_FEATURE_CURVE, &features));
897     assert_non_null(features);
898     assert_true(std::string(features).find("SM2 P-256") == std::string::npos);
899     rnp_buffer_destroy(features);
900     supported = true;
901     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_CURVE, "SM2 P-256", &supported));
902     assert_false(supported);
903 #endif
904 }
905 
TEST_F(rnp_tests,test_aead_enabled)906 TEST_F(rnp_tests, test_aead_enabled)
907 {
908     char *features = NULL;
909     bool  supported = false;
910     /* check whether FFI returns value which corresponds to defines */
911 #if defined(ENABLE_AEAD)
912     assert_true(aead_eax_enabled());
913     assert_true(aead_ocb_enabled());
914     assert_rnp_success(rnp_supported_features(RNP_FEATURE_AEAD_ALG, &features));
915     assert_non_null(features);
916     assert_true(std::string(features).find("EAX") != std::string::npos);
917     assert_true(std::string(features).find("OCB") != std::string::npos);
918     rnp_buffer_destroy(features);
919     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_AEAD_ALG, "EAX", &supported));
920     assert_true(supported);
921     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_AEAD_ALG, "OCB", &supported));
922     assert_true(supported);
923 #else
924     assert_false(aead_eax_enabled());
925     assert_false(aead_ocb_enabled());
926     assert_rnp_success(rnp_supported_features(RNP_FEATURE_AEAD_ALG, &features));
927     assert_non_null(features);
928     assert_true(std::string(features).find("EAX") == std::string::npos);
929     assert_true(std::string(features).find("OCB") == std::string::npos);
930     rnp_buffer_destroy(features);
931     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_AEAD_ALG, "EAX", &supported));
932     assert_false(supported);
933     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_AEAD_ALG, "OCB", &supported));
934     assert_false(supported);
935 #endif
936 }
937 
TEST_F(rnp_tests,test_twofish_enabled)938 TEST_F(rnp_tests, test_twofish_enabled)
939 {
940     char *features = NULL;
941     bool  supported = false;
942     /* check whether FFI returns value which corresponds to defines */
943 #if defined(ENABLE_TWOFISH)
944     assert_true(twofish_enabled());
945     assert_rnp_success(rnp_supported_features(RNP_FEATURE_SYMM_ALG, &features));
946     assert_non_null(features);
947     assert_true(std::string(features).find("TWOFISH") != std::string::npos);
948     rnp_buffer_destroy(features);
949     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_SYMM_ALG, "TWOFISH", &supported));
950     assert_true(supported);
951 #else
952     assert_false(twofish_enabled());
953     assert_rnp_success(rnp_supported_features(RNP_FEATURE_SYMM_ALG, &features));
954     assert_non_null(features);
955     assert_true(std::string(features).find("TWOFISH") == std::string::npos);
956     rnp_buffer_destroy(features);
957     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_SYMM_ALG, "TWOFISH", &supported));
958     assert_false(supported);
959 #endif
960 }
961 
TEST_F(rnp_tests,test_brainpool_enabled)962 TEST_F(rnp_tests, test_brainpool_enabled)
963 {
964     char *features = NULL;
965     bool  supported = false;
966     /* check whether FFI returns value which corresponds to defines */
967 #if defined(ENABLE_BRAINPOOL)
968     assert_true(brainpool_enabled());
969     assert_rnp_success(rnp_supported_features(RNP_FEATURE_CURVE, &features));
970     assert_non_null(features);
971     assert_true(std::string(features).find("brainpool") != std::string::npos);
972     rnp_buffer_destroy(features);
973     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_CURVE, "brainpoolP256r1", &supported));
974     assert_true(supported);
975     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_CURVE, "brainpoolP384r1", &supported));
976     assert_true(supported);
977     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_CURVE, "brainpoolP512r1", &supported));
978     assert_true(supported);
979 #else
980     assert_false(brainpool_enabled());
981     assert_rnp_success(rnp_supported_features(RNP_FEATURE_CURVE, &features));
982     assert_non_null(features);
983     assert_true(std::string(features).find("brainpool") == std::string::npos);
984     rnp_buffer_destroy(features);
985     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_CURVE, "brainpoolP256r1", &supported));
986     assert_false(supported);
987     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_CURVE, "brainpoolP384r1", &supported));
988     assert_false(supported);
989     assert_rnp_success(rnp_supports_feature(RNP_FEATURE_CURVE, "brainpoolP512r1", &supported));
990     assert_false(supported);
991 #endif
992 }
993