provider_seeding.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * Copyright 2020-2023 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/core_dispatch.h>
  10. #include "prov/seeding.h"
  11. #include "prov/providercommon.h"
  12. static OSSL_FUNC_get_entropy_fn *c_get_entropy = NULL;
  13. static OSSL_FUNC_get_user_entropy_fn *c_get_user_entropy = NULL;
  14. static OSSL_FUNC_cleanup_entropy_fn *c_cleanup_entropy = NULL;
  15. static OSSL_FUNC_cleanup_user_entropy_fn *c_cleanup_user_entropy = NULL;
  16. static OSSL_FUNC_get_nonce_fn *c_get_nonce = NULL;
  17. static OSSL_FUNC_get_user_nonce_fn *c_get_user_nonce = NULL;
  18. static OSSL_FUNC_cleanup_nonce_fn *c_cleanup_nonce = NULL;
  19. static OSSL_FUNC_cleanup_user_nonce_fn *c_cleanup_user_nonce = NULL;
  20. #ifdef FIPS_MODULE
  21. /*
  22. * The FIPS provider uses an internal library context which is what the
  23. * passed provider context references. Since the seed source is external
  24. * to the FIPS provider, this is the wrong one. We need to convert this
  25. * to the correct core handle before up-calling libcrypto.
  26. */
  27. # define CORE_HANDLE(provctx) \
  28. FIPS_get_core_handle(ossl_prov_ctx_get0_libctx(provctx))
  29. #else
  30. /*
  31. * The non-FIPS path *should* be unused because the full DRBG chain including
  32. * seed source is instantiated. However, that might not apply for third
  33. * party providers, so this is retained for compatibility.
  34. */
  35. # define CORE_HANDLE(provctx) ossl_prov_ctx_get0_handle(provctx)
  36. #endif
  37. int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns)
  38. {
  39. for (; fns->function_id != 0; fns++) {
  40. /*
  41. * We do not support the scenario of an application linked against
  42. * multiple versions of libcrypto (e.g. one static and one dynamic), but
  43. * sharing a single fips.so. We do a simple sanity check here.
  44. */
  45. #define set_func(c, f) \
  46. do { if (c == NULL) c = f; else if (c != f) return 0; } while (0)
  47. switch (fns->function_id) {
  48. case OSSL_FUNC_GET_ENTROPY:
  49. set_func(c_get_entropy, OSSL_FUNC_get_entropy(fns));
  50. break;
  51. case OSSL_FUNC_GET_USER_ENTROPY:
  52. set_func(c_get_user_entropy, OSSL_FUNC_get_user_entropy(fns));
  53. break;
  54. case OSSL_FUNC_CLEANUP_ENTROPY:
  55. set_func(c_cleanup_entropy, OSSL_FUNC_cleanup_entropy(fns));
  56. break;
  57. case OSSL_FUNC_CLEANUP_USER_ENTROPY:
  58. set_func(c_cleanup_user_entropy, OSSL_FUNC_cleanup_user_entropy(fns));
  59. break;
  60. case OSSL_FUNC_GET_NONCE:
  61. set_func(c_get_nonce, OSSL_FUNC_get_nonce(fns));
  62. break;
  63. case OSSL_FUNC_GET_USER_NONCE:
  64. set_func(c_get_user_nonce, OSSL_FUNC_get_user_nonce(fns));
  65. break;
  66. case OSSL_FUNC_CLEANUP_NONCE:
  67. set_func(c_cleanup_nonce, OSSL_FUNC_cleanup_nonce(fns));
  68. break;
  69. case OSSL_FUNC_CLEANUP_USER_NONCE:
  70. set_func(c_cleanup_user_nonce, OSSL_FUNC_cleanup_user_nonce(fns));
  71. break;
  72. }
  73. #undef set_func
  74. }
  75. return 1;
  76. }
  77. size_t ossl_prov_get_entropy(PROV_CTX *prov_ctx, unsigned char **pout,
  78. int entropy, size_t min_len, size_t max_len)
  79. {
  80. const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx);
  81. if (c_get_user_entropy != NULL)
  82. return c_get_user_entropy(handle, pout, entropy, min_len, max_len);
  83. if (c_get_entropy != NULL)
  84. return c_get_entropy(handle, pout, entropy, min_len, max_len);
  85. return 0;
  86. }
  87. void ossl_prov_cleanup_entropy(PROV_CTX *prov_ctx, unsigned char *buf,
  88. size_t len)
  89. {
  90. const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx);
  91. if (c_cleanup_user_entropy != NULL)
  92. c_cleanup_user_entropy(handle, buf, len);
  93. else if (c_cleanup_entropy != NULL)
  94. c_cleanup_entropy(handle, buf, len);
  95. }
  96. size_t ossl_prov_get_nonce(PROV_CTX *prov_ctx, unsigned char **pout,
  97. size_t min_len, size_t max_len,
  98. const void *salt, size_t salt_len)
  99. {
  100. const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx);
  101. if (c_get_user_nonce != NULL)
  102. return c_get_user_nonce(handle, pout, min_len, max_len, salt, salt_len);
  103. if (c_get_nonce != NULL)
  104. return c_get_nonce(handle, pout, min_len, max_len, salt, salt_len);
  105. return 0;
  106. }
  107. void ossl_prov_cleanup_nonce(PROV_CTX *prov_ctx, unsigned char *buf, size_t len)
  108. {
  109. const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx);
  110. if (c_cleanup_user_nonce != NULL)
  111. c_cleanup_user_nonce(handle, buf, len);
  112. else if (c_cleanup_nonce != NULL)
  113. c_cleanup_nonce(handle, buf, len);
  114. }