ec_ctrl.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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 "internal/deprecated.h"
  10. #include <openssl/core_names.h>
  11. #include <openssl/err.h>
  12. #include <openssl/ec.h>
  13. #include "crypto/evp.h"
  14. #include "crypto/ec.h"
  15. /*
  16. * This file is meant to contain functions to provide EVP_PKEY support for EC
  17. * keys.
  18. */
  19. static ossl_inline
  20. int evp_pkey_ctx_getset_ecdh_param_checks(const EVP_PKEY_CTX *ctx)
  21. {
  22. if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
  23. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  24. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  25. return -2;
  26. }
  27. /* If key type not EC return error */
  28. if (evp_pkey_ctx_is_legacy(ctx)
  29. && ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_EC)
  30. return -1;
  31. return 1;
  32. }
  33. int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int cofactor_mode)
  34. {
  35. int ret;
  36. OSSL_PARAM params[2], *p = params;
  37. ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
  38. if (ret != 1)
  39. return ret;
  40. /*
  41. * Valid input values are:
  42. * * 0 for disable
  43. * * 1 for enable
  44. * * -1 for reset to default for associated priv key
  45. */
  46. if (cofactor_mode < -1 || cofactor_mode > 1) {
  47. /* Uses the same return value of pkey_ec_ctrl() */
  48. return -2;
  49. }
  50. *p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE,
  51. &cofactor_mode);
  52. *p++ = OSSL_PARAM_construct_end();
  53. ret = evp_pkey_ctx_set_params_strict(ctx, params);
  54. if (ret == -2)
  55. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  56. return ret;
  57. }
  58. int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx)
  59. {
  60. int ret, mode;
  61. OSSL_PARAM params[2], *p = params;
  62. ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
  63. if (ret != 1)
  64. return ret;
  65. *p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE,
  66. &mode);
  67. *p++ = OSSL_PARAM_construct_end();
  68. ret = evp_pkey_ctx_get_params_strict(ctx, params);
  69. switch (ret) {
  70. case -2:
  71. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  72. break;
  73. case 1:
  74. ret = mode;
  75. if (mode < 0 || mode > 1) {
  76. /*
  77. * The provider should return either 0 or 1, any other value is a
  78. * provider error.
  79. */
  80. ret = -1;
  81. }
  82. break;
  83. default:
  84. ret = -1;
  85. break;
  86. }
  87. return ret;
  88. }
  89. /*
  90. * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
  91. * simply because that's easier.
  92. */
  93. int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX *ctx, int kdf)
  94. {
  95. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE,
  96. EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL);
  97. }
  98. /*
  99. * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
  100. * simply because that's easier.
  101. */
  102. int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX *ctx)
  103. {
  104. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE,
  105. EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL);
  106. }
  107. /*
  108. * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
  109. * simply because that's easier.
  110. */
  111. int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
  112. {
  113. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE,
  114. EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md));
  115. }
  116. /*
  117. * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
  118. * simply because that's easier.
  119. */
  120. int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
  121. {
  122. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE,
  123. EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd));
  124. }
  125. int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int outlen)
  126. {
  127. int ret;
  128. size_t len = outlen;
  129. OSSL_PARAM params[2], *p = params;
  130. ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
  131. if (ret != 1)
  132. return ret;
  133. if (outlen <= 0) {
  134. /*
  135. * This would ideally be -1 or 0, but we have to retain compatibility
  136. * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
  137. * in <= 0
  138. */
  139. return -2;
  140. }
  141. *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
  142. &len);
  143. *p++ = OSSL_PARAM_construct_end();
  144. ret = evp_pkey_ctx_set_params_strict(ctx, params);
  145. if (ret == -2)
  146. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  147. return ret;
  148. }
  149. int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen)
  150. {
  151. size_t len = UINT_MAX;
  152. int ret;
  153. OSSL_PARAM params[2], *p = params;
  154. ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
  155. if (ret != 1)
  156. return ret;
  157. *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
  158. &len);
  159. *p++ = OSSL_PARAM_construct_end();
  160. ret = evp_pkey_ctx_get_params_strict(ctx, params);
  161. switch (ret) {
  162. case -2:
  163. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  164. break;
  165. case 1:
  166. if (len <= INT_MAX)
  167. *plen = (int)len;
  168. else
  169. ret = -1;
  170. break;
  171. default:
  172. ret = -1;
  173. break;
  174. }
  175. return ret;
  176. }
  177. int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len)
  178. {
  179. int ret;
  180. OSSL_PARAM params[2], *p = params;
  181. ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
  182. if (ret != 1)
  183. return ret;
  184. *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM,
  185. /*
  186. * Cast away the const. This is read
  187. * only so should be safe
  188. */
  189. (void *)ukm,
  190. (size_t)len);
  191. *p++ = OSSL_PARAM_construct_end();
  192. ret = evp_pkey_ctx_set_params_strict(ctx, params);
  193. switch (ret) {
  194. case -2:
  195. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  196. break;
  197. case 1:
  198. OPENSSL_free(ukm);
  199. break;
  200. }
  201. return ret;
  202. }
  203. #ifndef OPENSSL_NO_DEPRECATED_3_0
  204. int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
  205. {
  206. size_t ukmlen;
  207. int ret;
  208. OSSL_PARAM params[2], *p = params;
  209. ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
  210. if (ret != 1)
  211. return ret;
  212. *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM,
  213. (void **)pukm, 0);
  214. *p++ = OSSL_PARAM_construct_end();
  215. ret = evp_pkey_ctx_get_params_strict(ctx, params);
  216. switch (ret) {
  217. case -2:
  218. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  219. break;
  220. case 1:
  221. ret = -1;
  222. ukmlen = params[0].return_size;
  223. if (ukmlen <= INT_MAX)
  224. ret = (int)ukmlen;
  225. break;
  226. default:
  227. ret = -1;
  228. break;
  229. }
  230. return ret;
  231. }
  232. #endif
  233. #ifndef FIPS_MODULE
  234. /*
  235. * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
  236. * simply because that's easier.
  237. * ASN1_OBJECT (which would be converted to text internally)?
  238. */
  239. int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid)
  240. {
  241. int keytype = nid == EVP_PKEY_SM2 ? EVP_PKEY_SM2 : EVP_PKEY_EC;
  242. return EVP_PKEY_CTX_ctrl(ctx, keytype, EVP_PKEY_OP_TYPE_GEN,
  243. EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID,
  244. nid, NULL);
  245. }
  246. /*
  247. * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
  248. * simply because that's easier.
  249. */
  250. int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc)
  251. {
  252. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_TYPE_GEN,
  253. EVP_PKEY_CTRL_EC_PARAM_ENC, param_enc, NULL);
  254. }
  255. #endif