pairwise_fail_test.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <openssl/pem.h>
  10. #include <openssl/core_names.h>
  11. #include <openssl/self_test.h>
  12. #include "testutil.h"
  13. typedef enum OPTION_choice {
  14. OPT_ERR = -1,
  15. OPT_EOF = 0,
  16. OPT_PROVIDER_NAME,
  17. OPT_CONFIG_FILE,
  18. OPT_PAIRWISETEST,
  19. OPT_DSAPARAM,
  20. OPT_TEST_ENUM
  21. } OPTION_CHOICE;
  22. struct self_test_arg {
  23. const char *type;
  24. };
  25. static OSSL_LIB_CTX *libctx = NULL;
  26. static char *pairwise_name = NULL;
  27. static char *dsaparam_file = NULL;
  28. static struct self_test_arg self_test_args = { 0 };
  29. const OPTIONS *test_get_options(void)
  30. {
  31. static const OPTIONS test_options[] = {
  32. OPT_TEST_OPTIONS_DEFAULT_USAGE,
  33. { "config", OPT_CONFIG_FILE, '<',
  34. "The configuration file to use for the libctx" },
  35. { "pairwise", OPT_PAIRWISETEST, 's',
  36. "Test keygen pairwise test failures" },
  37. { "dsaparam", OPT_DSAPARAM, 's', "DSA param file" },
  38. { NULL }
  39. };
  40. return test_options;
  41. }
  42. static int self_test_on_pairwise_fail(const OSSL_PARAM params[], void *arg)
  43. {
  44. struct self_test_arg *args = arg;
  45. const OSSL_PARAM *p = NULL;
  46. const char *type = NULL, *phase = NULL;
  47. p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_PHASE);
  48. if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
  49. return 0;
  50. phase = (const char *)p->data;
  51. if (strcmp(phase, OSSL_SELF_TEST_PHASE_CORRUPT) == 0) {
  52. p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_TYPE);
  53. if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
  54. return 0;
  55. type = (const char *)p->data;
  56. if (strcmp(type, args->type) == 0)
  57. return 0;
  58. }
  59. return 1;
  60. }
  61. static int setup_selftest_pairwise_failure(const char *type)
  62. {
  63. int ret = 0;
  64. OSSL_PROVIDER *prov = NULL;
  65. if (!TEST_ptr(prov = OSSL_PROVIDER_load(libctx, "fips")))
  66. goto err;
  67. /* Setup a callback that corrupts the pairwise self tests and causes failures */
  68. self_test_args.type = type;
  69. OSSL_SELF_TEST_set_callback(libctx, self_test_on_pairwise_fail, &self_test_args);
  70. ret = 1;
  71. err:
  72. OSSL_PROVIDER_unload(prov);
  73. return ret;
  74. }
  75. static int test_keygen_pairwise_failure(void)
  76. {
  77. BIO *bio = NULL;
  78. EVP_PKEY_CTX *ctx = NULL;
  79. EVP_PKEY *pParams = NULL;
  80. EVP_PKEY *pkey = NULL;
  81. const char *type = OSSL_SELF_TEST_TYPE_PCT;
  82. int ret = 0;
  83. if (strcmp(pairwise_name, "rsa") == 0) {
  84. if (!TEST_true(setup_selftest_pairwise_failure(type)))
  85. goto err;
  86. if (!TEST_ptr_null(pkey = EVP_PKEY_Q_keygen(libctx, NULL, "RSA", 2048)))
  87. goto err;
  88. } else if (strncmp(pairwise_name, "ec", 2) == 0) {
  89. if (strcmp(pairwise_name, "eckat") == 0)
  90. type = OSSL_SELF_TEST_TYPE_PCT_KAT;
  91. if (!TEST_true(setup_selftest_pairwise_failure(type)))
  92. goto err;
  93. if (!TEST_ptr_null(pkey = EVP_PKEY_Q_keygen(libctx, NULL, "EC", "P-256")))
  94. goto err;
  95. } else if (strncmp(pairwise_name, "dsa", 3) == 0) {
  96. if (strcmp(pairwise_name, "dsakat") == 0)
  97. type = OSSL_SELF_TEST_TYPE_PCT_KAT;
  98. if (!TEST_true(setup_selftest_pairwise_failure(type)))
  99. goto err;
  100. if (!TEST_ptr(bio = BIO_new_file(dsaparam_file, "r")))
  101. goto err;
  102. if (!TEST_ptr(pParams = PEM_read_bio_Parameters_ex(bio, NULL, libctx, NULL)))
  103. goto err;
  104. if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pParams, NULL)))
  105. goto err;
  106. if (!TEST_int_eq(EVP_PKEY_keygen_init(ctx), 1))
  107. goto err;
  108. if (!TEST_int_le(EVP_PKEY_keygen(ctx, &pkey), 0))
  109. goto err;
  110. if (!TEST_ptr_null(pkey))
  111. goto err;
  112. } else if (strncmp(pairwise_name, "eddsa", 5) == 0) {
  113. if (!TEST_true(setup_selftest_pairwise_failure(type)))
  114. goto err;
  115. if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "ED25519", NULL)))
  116. goto err;
  117. if (!TEST_int_eq(EVP_PKEY_keygen_init(ctx), 1))
  118. goto err;
  119. if (!TEST_int_le(EVP_PKEY_keygen(ctx, &pkey), 0))
  120. goto err;
  121. if (!TEST_ptr_null(pkey))
  122. goto err;
  123. }
  124. ret = 1;
  125. err:
  126. EVP_PKEY_free(pkey);
  127. EVP_PKEY_CTX_free(ctx);
  128. BIO_free(bio);
  129. EVP_PKEY_free(pParams);
  130. return ret;
  131. }
  132. int setup_tests(void)
  133. {
  134. OPTION_CHOICE o;
  135. char *config_file = NULL;
  136. while ((o = opt_next()) != OPT_EOF) {
  137. switch (o) {
  138. case OPT_CONFIG_FILE:
  139. config_file = opt_arg();
  140. break;
  141. case OPT_PAIRWISETEST:
  142. pairwise_name = opt_arg();
  143. break;
  144. case OPT_DSAPARAM:
  145. dsaparam_file = opt_arg();
  146. break;
  147. case OPT_TEST_CASES:
  148. break;
  149. default:
  150. case OPT_ERR:
  151. return 0;
  152. }
  153. }
  154. libctx = OSSL_LIB_CTX_new();
  155. if (libctx == NULL)
  156. return 0;
  157. if (!OSSL_LIB_CTX_load_config(libctx, config_file)) {
  158. opt_printf_stderr("Failed to load config\n");
  159. return 0;
  160. }
  161. ADD_TEST(test_keygen_pairwise_failure);
  162. return 1;
  163. }
  164. void cleanup_tests(void)
  165. {
  166. OSSL_LIB_CTX_free(libctx);
  167. }