blob: 404358ab97f1484c0f9312ff2f205ed169d2f96c [file] [log] [blame]
Nicola Tuveri4fe54d62019-12-15 00:20:53 +02001/*
Richard Levitte4333b892021-01-28 13:54:57 +01002 * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
Nicola Tuveri4fe54d62019-12-15 00:20:53 +02003 *
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
Shane Lontis5b5eea42020-10-15 13:41:59 +100010#include "internal/deprecated.h"
11
Nicola Tuveri4fe54d62019-12-15 00:20:53 +020012#include <openssl/core_names.h>
Richard Levitte565b3392020-12-01 19:21:04 +010013#include <openssl/err.h>
14#include <openssl/ec.h>
Nicola Tuveri4fe54d62019-12-15 00:20:53 +020015#include "crypto/evp.h"
Richard Levitte565b3392020-12-01 19:21:04 +010016#include "crypto/ec.h"
Nicola Tuveri4fe54d62019-12-15 00:20:53 +020017
18/*
19 * This file is meant to contain functions to provide EVP_PKEY support for EC
20 * keys.
21 */
22
23static ossl_inline
24int evp_pkey_ctx_getset_ecdh_param_checks(const EVP_PKEY_CTX *ctx)
25{
26 if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
27 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
28 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
29 return -2;
30 }
31
32 /* If key type not EC return error */
Richard Levittef5b00832021-02-10 19:00:05 +010033 if (evp_pkey_ctx_is_legacy(ctx)
34 && ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_EC)
Nicola Tuveri4fe54d62019-12-15 00:20:53 +020035 return -1;
36
37 return 1;
38}
39
40int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int cofactor_mode)
41{
42 int ret;
43 OSSL_PARAM params[2], *p = params;
44
45 ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
46 if (ret != 1)
47 return ret;
48
49 /*
50 * Valid input values are:
51 * * 0 for disable
52 * * 1 for enable
53 * * -1 for reset to default for associated priv key
54 */
55 if (cofactor_mode < -1 || cofactor_mode > 1) {
56 /* Uses the same return value of pkey_ec_ctrl() */
57 return -2;
58 }
59
Nicola Tuveri4fe54d62019-12-15 00:20:53 +020060 *p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE,
61 &cofactor_mode);
62 *p++ = OSSL_PARAM_construct_end();
63
64 ret = evp_pkey_ctx_set_params_strict(ctx, params);
Richard Levittef5b00832021-02-10 19:00:05 +010065 if (ret == -2)
Nicola Tuveri4fe54d62019-12-15 00:20:53 +020066 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
Nicola Tuveri4fe54d62019-12-15 00:20:53 +020067 return ret;
68}
69
70int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx)
71{
72 int ret, mode;
73 OSSL_PARAM params[2], *p = params;
74
75 ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
76 if (ret != 1)
77 return ret;
78
Nicola Tuveri4fe54d62019-12-15 00:20:53 +020079 *p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE,
80 &mode);
81 *p++ = OSSL_PARAM_construct_end();
82
83 ret = evp_pkey_ctx_get_params_strict(ctx, params);
Richard Levittef5b00832021-02-10 19:00:05 +010084
85 switch (ret) {
86 case -2:
Nicola Tuveri4fe54d62019-12-15 00:20:53 +020087 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
Richard Levittef5b00832021-02-10 19:00:05 +010088 break;
89 case 1:
90 ret = mode;
91 if (mode < 0 || mode > 1) {
92 /*
93 * The provider should return either 0 or 1, any other value is a
94 * provider error.
95 */
96 ret = -1;
97 }
98 break;
99 default:
100 ret = -1;
101 break;
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200102 }
103
Richard Levittef5b00832021-02-10 19:00:05 +0100104 return ret;
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200105}
106
Richard Levittef5b00832021-02-10 19:00:05 +0100107/*
108 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
109 * simply because that's easier.
110 */
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200111int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX *ctx, int kdf)
112{
Richard Levittef5b00832021-02-10 19:00:05 +0100113 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE,
114 EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL);
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200115}
116
Richard Levittef5b00832021-02-10 19:00:05 +0100117/*
118 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
119 * simply because that's easier.
120 */
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200121int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX *ctx)
122{
Richard Levittef5b00832021-02-10 19:00:05 +0100123 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE,
124 EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL);
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200125}
126
Richard Levittef5b00832021-02-10 19:00:05 +0100127/*
128 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
129 * simply because that's easier.
Richard Levittef5b00832021-02-10 19:00:05 +0100130 */
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200131int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
132{
Richard Levittef5b00832021-02-10 19:00:05 +0100133 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE,
134 EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md));
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200135}
136
Richard Levittef5b00832021-02-10 19:00:05 +0100137/*
138 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
139 * simply because that's easier.
Richard Levittef5b00832021-02-10 19:00:05 +0100140 */
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200141int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
142{
Richard Levittef5b00832021-02-10 19:00:05 +0100143 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE,
144 EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd));
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200145}
146
Richard Levittef5b00832021-02-10 19:00:05 +0100147int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int outlen)
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200148{
149 int ret;
Richard Levittef5b00832021-02-10 19:00:05 +0100150 size_t len = outlen;
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200151 OSSL_PARAM params[2], *p = params;
152
153 ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
154 if (ret != 1)
155 return ret;
156
Richard Levittef5b00832021-02-10 19:00:05 +0100157 if (outlen <= 0) {
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200158 /*
159 * This would ideally be -1 or 0, but we have to retain compatibility
160 * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
161 * in <= 0
162 */
163 return -2;
164 }
165
166 *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
167 &len);
168 *p++ = OSSL_PARAM_construct_end();
169
170 ret = evp_pkey_ctx_set_params_strict(ctx, params);
Richard Levittef5b00832021-02-10 19:00:05 +0100171 if (ret == -2)
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200172 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200173 return ret;
174}
175
176int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen)
177{
178 size_t len = UINT_MAX;
179 int ret;
180 OSSL_PARAM params[2], *p = params;
181
182 ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
183 if (ret != 1)
184 return ret;
185
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200186 *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
187 &len);
188 *p++ = OSSL_PARAM_construct_end();
189
190 ret = evp_pkey_ctx_get_params_strict(ctx, params);
Richard Levittef5b00832021-02-10 19:00:05 +0100191
192 switch (ret) {
193 case -2:
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200194 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
Richard Levittef5b00832021-02-10 19:00:05 +0100195 break;
196 case 1:
197 if (len <= INT_MAX)
198 *plen = (int)len;
199 else
200 ret = -1;
201 break;
202 default:
203 ret = -1;
204 break;
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200205 }
206
Richard Levittef5b00832021-02-10 19:00:05 +0100207 return ret;
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200208}
209
210int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len)
211{
212 int ret;
213 OSSL_PARAM params[2], *p = params;
214
215 ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
216 if (ret != 1)
217 return ret;
218
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200219 *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM,
220 /*
221 * Cast away the const. This is read
222 * only so should be safe
223 */
224 (void *)ukm,
225 (size_t)len);
226 *p++ = OSSL_PARAM_construct_end();
227
228 ret = evp_pkey_ctx_set_params_strict(ctx, params);
Richard Levittef5b00832021-02-10 19:00:05 +0100229
230 switch (ret) {
231 case -2:
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200232 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
Richard Levittef5b00832021-02-10 19:00:05 +0100233 break;
234 case 1:
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200235 OPENSSL_free(ukm);
Richard Levittef5b00832021-02-10 19:00:05 +0100236 break;
237 }
238
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200239 return ret;
240}
241
Tomas Mraz76e48c92021-02-22 17:28:17 +0100242#ifndef OPENSSL_NO_DEPRECATED_3_0
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200243int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
244{
245 size_t ukmlen;
246 int ret;
Richard Levitteba0a6d12021-01-24 20:37:09 +0100247 OSSL_PARAM params[2], *p = params;
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200248
249 ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
250 if (ret != 1)
251 return ret;
252
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200253 *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM,
254 (void **)pukm, 0);
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200255 *p++ = OSSL_PARAM_construct_end();
256
257 ret = evp_pkey_ctx_get_params_strict(ctx, params);
Richard Levittef5b00832021-02-10 19:00:05 +0100258
259 switch (ret) {
260 case -2:
Nicola Tuveri4fe54d62019-12-15 00:20:53 +0200261 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
Richard Levitte7229a2f2020-09-10 22:06:46 +0200262 break;
Richard Levittef5b00832021-02-10 19:00:05 +0100263 case 1:
264 ret = -1;
265 ukmlen = params[0].return_size;
266 if (ukmlen <= INT_MAX)
267 ret = (int)ukmlen;
Richard Levitte7229a2f2020-09-10 22:06:46 +0200268 break;
269 default:
Richard Levittef5b00832021-02-10 19:00:05 +0100270 ret = -1;
271 break;
Richard Levitte7229a2f2020-09-10 22:06:46 +0200272 }
273
Richard Levitte7229a2f2020-09-10 22:06:46 +0200274 return ret;
275}
Tomas Mraz76e48c92021-02-22 17:28:17 +0100276#endif
Richard Levitte7229a2f2020-09-10 22:06:46 +0200277
Richard Levittef5b00832021-02-10 19:00:05 +0100278#ifndef FIPS_MODULE
279/*
280 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
281 * simply because that's easier.
Richard Levittef5b00832021-02-10 19:00:05 +0100282 * ASN1_OBJECT (which would be converted to text internally)?
283 */
284int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid)
285{
286 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_TYPE_GEN,
287 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID,
288 nid, NULL);
289}
290
291/*
292 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
293 * simply because that's easier.
294 */
Richard Levitte7229a2f2020-09-10 22:06:46 +0200295int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc)
296{
Richard Levittef5b00832021-02-10 19:00:05 +0100297 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_TYPE_GEN,
Richard Levitte7229a2f2020-09-10 22:06:46 +0200298 EVP_PKEY_CTRL_EC_PARAM_ENC, param_enc, NULL);
299}
Richard Levitte10d756a2020-03-19 14:02:42 +0100300#endif