dh_exch.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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 <openssl/crypto.h>
  10. #include <openssl/core_numbers.h>
  11. #include <openssl/core_names.h>
  12. #include <openssl/dh.h>
  13. #include <openssl/params.h>
  14. #include "internal/provider_algs.h"
  15. static OSSL_OP_keyexch_newctx_fn dh_newctx;
  16. static OSSL_OP_keyexch_init_fn dh_init;
  17. static OSSL_OP_keyexch_set_peer_fn dh_set_peer;
  18. static OSSL_OP_keyexch_derive_fn dh_derive;
  19. static OSSL_OP_keyexch_freectx_fn dh_freectx;
  20. static OSSL_OP_keyexch_dupctx_fn dh_dupctx;
  21. static OSSL_OP_keyexch_set_ctx_params_fn dh_set_ctx_params;
  22. static OSSL_OP_keyexch_settable_ctx_params_fn dh_settable_ctx_params;
  23. /*
  24. * What's passed as an actual key is defined by the KEYMGMT interface.
  25. * We happen to know that our KEYMGMT simply passes DH structures, so
  26. * we use that here too.
  27. */
  28. typedef struct {
  29. DH *dh;
  30. DH *dhpeer;
  31. unsigned int pad : 1;
  32. } PROV_DH_CTX;
  33. static void *dh_newctx(void *provctx)
  34. {
  35. return OPENSSL_zalloc(sizeof(PROV_DH_CTX));
  36. }
  37. static int dh_init(void *vpdhctx, void *vdh)
  38. {
  39. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  40. if (pdhctx == NULL || vdh == NULL || !DH_up_ref(vdh))
  41. return 0;
  42. DH_free(pdhctx->dh);
  43. pdhctx->dh = vdh;
  44. return 1;
  45. }
  46. static int dh_set_peer(void *vpdhctx, void *vdh)
  47. {
  48. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  49. if (pdhctx == NULL || vdh == NULL || !DH_up_ref(vdh))
  50. return 0;
  51. DH_free(pdhctx->dhpeer);
  52. pdhctx->dhpeer = vdh;
  53. return 1;
  54. }
  55. static int dh_derive(void *vpdhctx, unsigned char *secret, size_t *secretlen,
  56. size_t outlen)
  57. {
  58. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  59. int ret;
  60. size_t dhsize;
  61. const BIGNUM *pub_key = NULL;
  62. /* TODO(3.0): Add errors to stack */
  63. if (pdhctx->dh == NULL || pdhctx->dhpeer == NULL)
  64. return 0;
  65. dhsize = (size_t)DH_size(pdhctx->dh);
  66. if (secret == NULL) {
  67. *secretlen = dhsize;
  68. return 1;
  69. }
  70. if (outlen < dhsize)
  71. return 0;
  72. DH_get0_key(pdhctx->dhpeer, &pub_key, NULL);
  73. ret = (pdhctx->pad) ? DH_compute_key_padded(secret, pub_key, pdhctx->dh)
  74. : DH_compute_key(secret, pub_key, pdhctx->dh);
  75. if (ret <= 0)
  76. return 0;
  77. *secretlen = ret;
  78. return 1;
  79. }
  80. static void dh_freectx(void *vpdhctx)
  81. {
  82. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  83. DH_free(pdhctx->dh);
  84. DH_free(pdhctx->dhpeer);
  85. OPENSSL_free(pdhctx);
  86. }
  87. static void *dh_dupctx(void *vpdhctx)
  88. {
  89. PROV_DH_CTX *srcctx = (PROV_DH_CTX *)vpdhctx;
  90. PROV_DH_CTX *dstctx;
  91. dstctx = OPENSSL_zalloc(sizeof(*srcctx));
  92. if (dstctx == NULL)
  93. return NULL;
  94. *dstctx = *srcctx;
  95. if (dstctx->dh != NULL && !DH_up_ref(dstctx->dh)) {
  96. OPENSSL_free(dstctx);
  97. return NULL;
  98. }
  99. if (dstctx->dhpeer != NULL && !DH_up_ref(dstctx->dhpeer)) {
  100. DH_free(dstctx->dh);
  101. OPENSSL_free(dstctx);
  102. return NULL;
  103. }
  104. return dstctx;
  105. }
  106. static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[])
  107. {
  108. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  109. const OSSL_PARAM *p;
  110. unsigned int pad;
  111. if (pdhctx == NULL || params == NULL)
  112. return 0;
  113. p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD);
  114. if (p == NULL || !OSSL_PARAM_get_uint(p, &pad))
  115. return 0;
  116. pdhctx->pad = pad ? 1 : 0;
  117. return 1;
  118. }
  119. static const OSSL_PARAM known_settable_ctx_params[] = {
  120. OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL),
  121. OSSL_PARAM_END
  122. };
  123. static const OSSL_PARAM *dh_settable_ctx_params(void)
  124. {
  125. return known_settable_ctx_params;
  126. }
  127. const OSSL_DISPATCH dh_keyexch_functions[] = {
  128. { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
  129. { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
  130. { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))dh_derive },
  131. { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))dh_set_peer },
  132. { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))dh_freectx },
  133. { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))dh_dupctx },
  134. { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))dh_set_ctx_params },
  135. { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS,
  136. (void (*)(void))dh_settable_ctx_params },
  137. { 0, NULL }
  138. };