fipsprov.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*
  2. * Copyright 2019 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 <string.h>
  10. #include <stdio.h>
  11. #include <openssl/core.h>
  12. #include <openssl/core_numbers.h>
  13. #include <openssl/core_names.h>
  14. #include <openssl/params.h>
  15. #include <openssl/err.h>
  16. #include <openssl/evp.h>
  17. /* TODO(3.0): Needed for dummy_evp_call(). To be removed */
  18. #include <openssl/sha.h>
  19. #include "internal/cryptlib.h"
  20. #include "internal/property.h"
  21. #include "internal/evp_int.h"
  22. #include "internal/provider_algs.h"
  23. #include "internal/provider_ctx.h"
  24. /* Functions provided by the core */
  25. static OSSL_core_get_param_types_fn *c_get_param_types = NULL;
  26. static OSSL_core_get_params_fn *c_get_params = NULL;
  27. static OSSL_core_put_error_fn *c_put_error = NULL;
  28. static OSSL_core_add_error_vdata_fn *c_add_error_vdata = NULL;
  29. /* Parameters we provide to the core */
  30. static const OSSL_ITEM fips_param_types[] = {
  31. { OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_NAME },
  32. { OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_VERSION },
  33. { OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_BUILDINFO },
  34. { 0, NULL }
  35. };
  36. /* TODO(3.0): To be removed */
  37. static int dummy_evp_call(void *provctx)
  38. {
  39. OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
  40. EVP_MD_CTX *ctx = EVP_MD_CTX_new();
  41. EVP_MD *sha256 = EVP_MD_fetch(libctx, "SHA256", NULL);
  42. char msg[] = "Hello World!";
  43. const unsigned char exptd[] = {
  44. 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
  45. 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28,
  46. 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69
  47. };
  48. unsigned int dgstlen = 0;
  49. unsigned char dgst[SHA256_DIGEST_LENGTH];
  50. int ret = 0;
  51. BN_CTX *bnctx = NULL;
  52. BIGNUM *a = NULL, *b = NULL;
  53. if (ctx == NULL || sha256 == NULL)
  54. goto err;
  55. if (!EVP_DigestInit_ex(ctx, sha256, NULL))
  56. goto err;
  57. if (!EVP_DigestUpdate(ctx, msg, sizeof(msg) - 1))
  58. goto err;
  59. if (!EVP_DigestFinal(ctx, dgst, &dgstlen))
  60. goto err;
  61. if (dgstlen != sizeof(exptd) || memcmp(dgst, exptd, sizeof(exptd)) != 0)
  62. goto err;
  63. bnctx = BN_CTX_new_ex(libctx);
  64. if (bnctx == NULL)
  65. goto err;
  66. BN_CTX_start(bnctx);
  67. a = BN_CTX_get(bnctx);
  68. b = BN_CTX_get(bnctx);
  69. if (b == NULL)
  70. goto err;
  71. BN_zero(a);
  72. if (!BN_one(b)
  73. || !BN_add(a, a, b)
  74. || BN_cmp(a, b) != 0)
  75. goto err;
  76. ret = 1;
  77. err:
  78. BN_CTX_end(bnctx);
  79. BN_CTX_free(bnctx);
  80. EVP_MD_CTX_free(ctx);
  81. EVP_MD_meth_free(sha256);
  82. return ret;
  83. }
  84. static const OSSL_ITEM *fips_get_param_types(const OSSL_PROVIDER *prov)
  85. {
  86. return fips_param_types;
  87. }
  88. static int fips_get_params(const OSSL_PROVIDER *prov,
  89. const OSSL_PARAM params[])
  90. {
  91. const OSSL_PARAM *p;
  92. p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
  93. if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL FIPS Provider"))
  94. return 0;
  95. p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
  96. if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR))
  97. return 0;
  98. p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO);
  99. if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR))
  100. return 0;
  101. return 1;
  102. }
  103. static const OSSL_ALGORITHM fips_digests[] = {
  104. { "SHA1", "fips=yes", sha1_functions },
  105. { "SHA224", "fips=yes", sha224_functions },
  106. { "SHA256", "fips=yes", sha256_functions },
  107. { "SHA384", "fips=yes", sha384_functions },
  108. { "SHA512", "fips=yes", sha512_functions },
  109. { "SHA512-224", "fips=yes", sha512_224_functions },
  110. { "SHA512-256", "fips=yes", sha512_256_functions },
  111. { "SHA3-224", "fips=yes", sha3_224_functions },
  112. { "SHA3-256", "fips=yes", sha3_256_functions },
  113. { "SHA3-384", "fips=yes", sha3_384_functions },
  114. { "SHA3-512", "fips=yes", sha3_512_functions },
  115. { "KMAC128", "fips=yes", keccak_kmac_128_functions },
  116. { "KMAC256", "fips=yes", keccak_kmac_256_functions },
  117. { NULL, NULL, NULL }
  118. };
  119. static const OSSL_ALGORITHM fips_ciphers[] = {
  120. { "AES-256-ECB", "fips=yes", aes256ecb_functions },
  121. { "AES-192-ECB", "fips=yes", aes192ecb_functions },
  122. { "AES-128-ECB", "fips=yes", aes128ecb_functions },
  123. { "AES-256-CBC", "fips=yes", aes256cbc_functions },
  124. { "AES-192-CBC", "fips=yes", aes192cbc_functions },
  125. { "AES-128-CBC", "fips=yes", aes128cbc_functions },
  126. { "AES-256-CTR", "fips=yes", aes256ctr_functions },
  127. { "AES-192-CTR", "fips=yes", aes192ctr_functions },
  128. { "AES-128-CTR", "fips=yes", aes128ctr_functions },
  129. { NULL, NULL, NULL }
  130. };
  131. static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
  132. int operation_id,
  133. int *no_cache)
  134. {
  135. *no_cache = 0;
  136. switch (operation_id) {
  137. case OSSL_OP_DIGEST:
  138. return fips_digests;
  139. case OSSL_OP_CIPHER:
  140. return fips_ciphers;
  141. }
  142. return NULL;
  143. }
  144. /* Functions we provide to the core */
  145. static const OSSL_DISPATCH fips_dispatch_table[] = {
  146. /*
  147. * To release our resources we just need to free the OPENSSL_CTX so we just
  148. * use OPENSSL_CTX_free directly as our teardown function
  149. */
  150. { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OPENSSL_CTX_free },
  151. { OSSL_FUNC_PROVIDER_GET_PARAM_TYPES, (void (*)(void))fips_get_param_types },
  152. { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))fips_get_params },
  153. { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
  154. { 0, NULL }
  155. };
  156. /* Functions we provide to ourself */
  157. static const OSSL_DISPATCH intern_dispatch_table[] = {
  158. { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
  159. { 0, NULL }
  160. };
  161. int OSSL_provider_init(const OSSL_PROVIDER *provider,
  162. const OSSL_DISPATCH *in,
  163. const OSSL_DISPATCH **out,
  164. void **provctx)
  165. {
  166. OPENSSL_CTX *ctx;
  167. for (; in->function_id != 0; in++) {
  168. switch (in->function_id) {
  169. case OSSL_FUNC_CORE_GET_PARAM_TYPES:
  170. c_get_param_types = OSSL_get_core_get_param_types(in);
  171. break;
  172. case OSSL_FUNC_CORE_GET_PARAMS:
  173. c_get_params = OSSL_get_core_get_params(in);
  174. break;
  175. case OSSL_FUNC_CORE_PUT_ERROR:
  176. c_put_error = OSSL_get_core_put_error(in);
  177. break;
  178. case OSSL_FUNC_CORE_ADD_ERROR_VDATA:
  179. c_add_error_vdata = OSSL_get_core_add_error_vdata(in);
  180. break;
  181. /* Just ignore anything we don't understand */
  182. default:
  183. break;
  184. }
  185. }
  186. ctx = OPENSSL_CTX_new();
  187. if (ctx == NULL)
  188. return 0;
  189. *out = fips_dispatch_table;
  190. *provctx = ctx;
  191. /*
  192. * TODO(3.0): Remove me. This is just a dummy call to demonstrate making
  193. * EVP calls from within the FIPS module.
  194. */
  195. if (!dummy_evp_call(*provctx)) {
  196. OPENSSL_CTX_free(*provctx);
  197. *provctx = NULL;
  198. return 0;
  199. }
  200. return 1;
  201. }
  202. /*
  203. * The internal init function used when the FIPS module uses EVP to call
  204. * another algorithm also in the FIPS module. This is a recursive call that has
  205. * been made from within the FIPS module itself. To make this work, we populate
  206. * the provider context of this inner instance with the same library context
  207. * that was used in the EVP call that initiated this recursive call.
  208. */
  209. OSSL_provider_init_fn fips_intern_provider_init;
  210. int fips_intern_provider_init(const OSSL_PROVIDER *provider,
  211. const OSSL_DISPATCH *in,
  212. const OSSL_DISPATCH **out,
  213. void **provctx)
  214. {
  215. OSSL_core_get_library_context_fn *c_get_libctx = NULL;
  216. for (; in->function_id != 0; in++) {
  217. switch (in->function_id) {
  218. case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT:
  219. c_get_libctx = OSSL_get_core_get_library_context(in);
  220. break;
  221. default:
  222. break;
  223. }
  224. }
  225. if (c_get_libctx == NULL)
  226. return 0;
  227. *provctx = c_get_libctx(provider);
  228. /*
  229. * Safety measure... we should get the library context that was
  230. * created up in OSSL_provider_init().
  231. */
  232. if (*provctx == NULL)
  233. return 0;
  234. *out = intern_dispatch_table;
  235. return 1;
  236. }
  237. void ERR_put_error(int lib, int func, int reason, const char *file, int line)
  238. {
  239. /*
  240. * TODO(3.0): This works for the FIPS module because we're going to be
  241. * using lib/func/reason codes that libcrypto already knows about. This
  242. * won't work for third party providers that have their own error mechanisms,
  243. * so we'll need to come up with something else for them.
  244. */
  245. c_put_error(lib, func, reason, file, line);
  246. }
  247. void ERR_add_error_data(int num, ...)
  248. {
  249. va_list args;
  250. va_start(args, num);
  251. ERR_add_error_vdata(num, args);
  252. va_end(args);
  253. }
  254. void ERR_add_error_vdata(int num, va_list args)
  255. {
  256. c_add_error_vdata(num, args);
  257. }