]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
62867571 | 2 | * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. |
f5cda4cb | 3 | * |
4a8b0c55 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
62867571 RS |
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 | |
f5cda4cb DSH |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
11 | #include <stdlib.h> | |
b39fc560 | 12 | #include "internal/cryptlib.h" |
c20276e4 | 13 | #include <openssl/objects.h> |
f5cda4cb | 14 | #include <openssl/evp.h> |
25f2138b DMSP |
15 | #include "crypto/bn.h" |
16 | #include "crypto/asn1.h" | |
17 | #include "crypto/evp.h" | |
46e2dd05 RL |
18 | #include "evp_local.h" |
19 | ||
e683582b | 20 | #ifndef FIPS_MODE |
f5cda4cb | 21 | int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) |
0f113f3e MC |
22 | { |
23 | int ret; | |
24 | if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { | |
25 | EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT, | |
26 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | |
27 | return -2; | |
28 | } | |
29 | ctx->operation = EVP_PKEY_OP_PARAMGEN; | |
30 | if (!ctx->pmeth->paramgen_init) | |
31 | return 1; | |
32 | ret = ctx->pmeth->paramgen_init(ctx); | |
33 | if (ret <= 0) | |
34 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | |
35 | return ret; | |
36 | } | |
f5cda4cb DSH |
37 | |
38 | int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) | |
0f113f3e MC |
39 | { |
40 | int ret; | |
41 | if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { | |
42 | EVPerr(EVP_F_EVP_PKEY_PARAMGEN, | |
43 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | |
44 | return -2; | |
45 | } | |
46 | ||
47 | if (ctx->operation != EVP_PKEY_OP_PARAMGEN) { | |
48 | EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED); | |
49 | return -1; | |
50 | } | |
51 | ||
e34c66c6 | 52 | if (ppkey == NULL) |
0f113f3e MC |
53 | return -1; |
54 | ||
e34c66c6 | 55 | if (*ppkey == NULL) |
0f113f3e MC |
56 | *ppkey = EVP_PKEY_new(); |
57 | ||
e34c66c6 EK |
58 | if (*ppkey == NULL) { |
59 | EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE); | |
60 | return -1; | |
61 | } | |
62 | ||
0f113f3e MC |
63 | ret = ctx->pmeth->paramgen(ctx, *ppkey); |
64 | if (ret <= 0) { | |
65 | EVP_PKEY_free(*ppkey); | |
66 | *ppkey = NULL; | |
67 | } | |
68 | return ret; | |
69 | } | |
f5cda4cb DSH |
70 | |
71 | int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) | |
0f113f3e MC |
72 | { |
73 | int ret; | |
74 | if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { | |
75 | EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT, | |
76 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | |
77 | return -2; | |
78 | } | |
79 | ctx->operation = EVP_PKEY_OP_KEYGEN; | |
80 | if (!ctx->pmeth->keygen_init) | |
81 | return 1; | |
82 | ret = ctx->pmeth->keygen_init(ctx); | |
83 | if (ret <= 0) | |
84 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | |
85 | return ret; | |
86 | } | |
f5cda4cb DSH |
87 | |
88 | int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) | |
0f113f3e MC |
89 | { |
90 | int ret; | |
91 | ||
92 | if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { | |
93 | EVPerr(EVP_F_EVP_PKEY_KEYGEN, | |
94 | EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | |
95 | return -2; | |
96 | } | |
97 | if (ctx->operation != EVP_PKEY_OP_KEYGEN) { | |
98 | EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED); | |
99 | return -1; | |
100 | } | |
101 | ||
90945fa3 | 102 | if (ppkey == NULL) |
0f113f3e MC |
103 | return -1; |
104 | ||
90945fa3 | 105 | if (*ppkey == NULL) |
0f113f3e | 106 | *ppkey = EVP_PKEY_new(); |
90945fa3 MC |
107 | if (*ppkey == NULL) |
108 | return -1; | |
0f113f3e MC |
109 | |
110 | ret = ctx->pmeth->keygen(ctx, *ppkey); | |
111 | if (ret <= 0) { | |
112 | EVP_PKEY_free(*ppkey); | |
113 | *ppkey = NULL; | |
114 | } | |
115 | return ret; | |
116 | } | |
f5cda4cb DSH |
117 | |
118 | void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb) | |
0f113f3e MC |
119 | { |
120 | ctx->pkey_gencb = cb; | |
121 | } | |
f5cda4cb | 122 | |
b28dea4e | 123 | EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx) |
0f113f3e MC |
124 | { |
125 | return ctx->pkey_gencb; | |
126 | } | |
b28dea4e | 127 | |
0f113f3e MC |
128 | /* |
129 | * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style | |
130 | * callbacks. | |
f5cda4cb DSH |
131 | */ |
132 | ||
133 | static int trans_cb(int a, int b, BN_GENCB *gcb) | |
0f113f3e MC |
134 | { |
135 | EVP_PKEY_CTX *ctx = BN_GENCB_get_arg(gcb); | |
136 | ctx->keygen_info[0] = a; | |
137 | ctx->keygen_info[1] = b; | |
138 | return ctx->pkey_gencb(ctx); | |
139 | } | |
f5cda4cb DSH |
140 | |
141 | void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx) | |
0f113f3e MC |
142 | { |
143 | BN_GENCB_set(cb, trans_cb, ctx); | |
144 | } | |
f5cda4cb DSH |
145 | |
146 | int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx) | |
0f113f3e MC |
147 | { |
148 | if (idx == -1) | |
149 | return ctx->keygen_info_count; | |
150 | if (idx < 0 || idx > ctx->keygen_info_count) | |
151 | return 0; | |
152 | return ctx->keygen_info[idx]; | |
153 | } | |
2022cfe0 DSH |
154 | |
155 | EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, | |
0f113f3e MC |
156 | const unsigned char *key, int keylen) |
157 | { | |
158 | EVP_PKEY_CTX *mac_ctx = NULL; | |
159 | EVP_PKEY *mac_key = NULL; | |
160 | mac_ctx = EVP_PKEY_CTX_new_id(type, e); | |
161 | if (!mac_ctx) | |
162 | return NULL; | |
163 | if (EVP_PKEY_keygen_init(mac_ctx) <= 0) | |
164 | goto merr; | |
eff1a4d2 | 165 | if (EVP_PKEY_CTX_set_mac_key(mac_ctx, key, keylen) <= 0) |
0f113f3e MC |
166 | goto merr; |
167 | if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) | |
168 | goto merr; | |
169 | merr: | |
c5ba2d99 | 170 | EVP_PKEY_CTX_free(mac_ctx); |
0f113f3e MC |
171 | return mac_key; |
172 | } | |
2aee35d3 | 173 | |
e683582b SL |
174 | #endif /* FIPS_MODE */ |
175 | ||
176 | /*- All methods below can also be used in FIPS_MODE */ | |
177 | ||
178 | static int fromdata_init(EVP_PKEY_CTX *ctx, int operation) | |
179 | { | |
180 | if (ctx == NULL || ctx->keytype == NULL) | |
181 | goto not_supported; | |
182 | ||
183 | evp_pkey_ctx_free_old_ops(ctx); | |
184 | ctx->operation = operation; | |
185 | if (ctx->keymgmt == NULL) | |
186 | ctx->keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, | |
187 | ctx->propquery); | |
188 | if (ctx->keymgmt == NULL) | |
189 | goto not_supported; | |
190 | ||
191 | return 1; | |
192 | ||
193 | not_supported: | |
194 | ctx->operation = EVP_PKEY_OP_UNDEFINED; | |
195 | ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | |
196 | return -2; | |
197 | } | |
198 | ||
199 | int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx) | |
200 | { | |
201 | return fromdata_init(ctx, EVP_PKEY_OP_PARAMFROMDATA); | |
202 | } | |
203 | ||
204 | int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx) | |
205 | { | |
206 | return fromdata_init(ctx, EVP_PKEY_OP_KEYFROMDATA); | |
207 | } | |
208 | ||
209 | int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[]) | |
210 | { | |
211 | void *provdata = NULL; | |
212 | ||
213 | if (ctx == NULL || (ctx->operation & EVP_PKEY_OP_TYPE_FROMDATA) == 0) { | |
214 | ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | |
215 | return -2; | |
216 | } | |
217 | ||
218 | if (ppkey == NULL) | |
219 | return -1; | |
220 | ||
221 | if (*ppkey == NULL) | |
222 | *ppkey = EVP_PKEY_new(); | |
223 | ||
224 | if (*ppkey == NULL) { | |
225 | ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); | |
226 | return -1; | |
227 | } | |
228 | ||
229 | provdata = | |
68552cde RL |
230 | evp_keymgmt_util_fromdata(*ppkey, ctx->keymgmt, params, |
231 | ctx->operation == EVP_PKEY_OP_PARAMFROMDATA); | |
e683582b SL |
232 | |
233 | if (provdata == NULL) | |
234 | return 0; | |
235 | /* provdata is cached in *ppkey, so we need not bother with it further */ | |
236 | return 1; | |
237 | } | |
238 | ||
239 | /* | |
240 | * TODO(3.0) Re-evaluate the names, it's possible that we find these to be | |
241 | * better: | |
242 | * | |
243 | * EVP_PKEY_param_settable() | |
244 | * EVP_PKEY_param_gettable() | |
245 | */ | |
246 | const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx) | |
247 | { | |
248 | /* We call fromdata_init to get ctx->keymgmt populated */ | |
249 | if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED)) | |
250 | return evp_keymgmt_importdomparam_types(ctx->keymgmt); | |
251 | return NULL; | |
252 | } | |
253 | ||
254 | const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx) | |
255 | { | |
256 | /* We call fromdata_init to get ctx->keymgmt populated */ | |
257 | if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED)) | |
258 | return evp_keymgmt_importdomparam_types(ctx->keymgmt); | |
259 | return NULL; | |
260 | } |