]>
Commit | Line | Data |
---|---|---|
5e55159b | 1 | /* |
33388b44 | 2 | * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. |
5e55159b | 3 | * |
4a8b0c55 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5e55159b RL |
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 | ||
e74bd290 | 10 | #include <string.h> |
5e55159b RL |
11 | #include <openssl/err.h> |
12 | #include <openssl/evp.h> | |
e74bd290 RL |
13 | #include <openssl/engine.h> |
14 | #include <openssl/params.h> | |
15 | #include <openssl/core_names.h> | |
25f2138b | 16 | #include "crypto/evp.h" |
706457b7 | 17 | #include "evp_local.h" |
5e55159b RL |
18 | |
19 | /* MAC PKEY context structure */ | |
20 | ||
21 | typedef struct { | |
22 | EVP_MAC_CTX *ctx; | |
23 | ||
24 | /* | |
25 | * We know of two MAC types: | |
26 | * | |
27 | * 1. those who take a secret in raw form, i.e. raw data as a | |
28 | * ASN1_OCTET_STRING embedded in a EVP_PKEY. So far, that's | |
29 | * all of them but CMAC. | |
30 | * 2. those who take a secret with associated cipher in very generic | |
31 | * form, i.e. a complete EVP_MAC_CTX embedded in a PKEY. So far, | |
32 | * only CMAC does this. | |
33 | * | |
34 | * (one might wonder why the second form isn't used for all) | |
35 | */ | |
36 | #define MAC_TYPE_RAW 1 /* HMAC like MAC type (all but CMAC so far) */ | |
37 | #define MAC_TYPE_MAC 2 /* CMAC like MAC type (only CMAC known so far) */ | |
38 | int type; | |
39 | ||
40 | /* The following is only used for MAC_TYPE_RAW implementations */ | |
41 | struct { | |
42 | const EVP_MD *md; /* temp storage of MD */ | |
43 | ASN1_OCTET_STRING ktmp; /* temp storage for key */ | |
44 | } raw_data; | |
45 | } MAC_PKEY_CTX; | |
46 | ||
e74bd290 RL |
47 | static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx); |
48 | ||
5e55159b RL |
49 | static int pkey_mac_init(EVP_PKEY_CTX *ctx) |
50 | { | |
51 | MAC_PKEY_CTX *hctx; | |
e74bd290 | 52 | /* We're being smart and using the same base NIDs for PKEY and for MAC */ |
5e55159b | 53 | int nid = ctx->pmeth->pkey_id; |
6b1e5fa4 MC |
54 | EVP_MAC *mac; |
55 | ||
56 | ERR_set_mark(); | |
57 | mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery); | |
58 | ERR_pop_to_mark(); | |
5e55159b | 59 | |
129c2284 MC |
60 | /* |
61 | * mac == NULL may actually be ok in some situations. In an | |
62 | * EVP_PKEY_new_mac_key() call a temporary EVP_PKEY_CTX is created with | |
63 | * default libctx. We don't actually need the underlying MAC to be present | |
64 | * to successfully set the key in that case. The resulting EVP_PKEY could | |
65 | * then be used in some other libctx where the MAC *is* present | |
66 | */ | |
67 | ||
5e55159b RL |
68 | if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) { |
69 | EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE); | |
70 | return 0; | |
71 | } | |
72 | ||
129c2284 MC |
73 | if (mac != NULL) { |
74 | hctx->ctx = EVP_MAC_CTX_new(mac); | |
75 | if (hctx->ctx == NULL) { | |
76 | OPENSSL_free(hctx); | |
77 | return 0; | |
78 | } | |
5e55159b RL |
79 | } |
80 | ||
81 | if (nid == EVP_PKEY_CMAC) { | |
82 | hctx->type = MAC_TYPE_MAC; | |
83 | } else { | |
84 | hctx->type = MAC_TYPE_RAW; | |
85 | hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING; | |
86 | } | |
87 | ||
e74bd290 | 88 | pkey_mac_cleanup(ctx); |
5e55159b RL |
89 | EVP_PKEY_CTX_set_data(ctx, hctx); |
90 | ctx->keygen_info_count = 0; | |
91 | ||
92 | return 1; | |
93 | } | |
94 | ||
9fdcc21f | 95 | static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) |
5e55159b RL |
96 | { |
97 | MAC_PKEY_CTX *sctx, *dctx; | |
98 | ||
be5fc053 | 99 | sctx = EVP_PKEY_CTX_get_data(src); |
129c2284 MC |
100 | |
101 | if (sctx->ctx == NULL) { | |
102 | /* This actually means the fetch failed during the init call */ | |
103 | EVPerr(0, EVP_R_FETCH_FAILED); | |
104 | return 0; | |
105 | } | |
106 | ||
be5fc053 | 107 | if (sctx->ctx->data == NULL) |
5e55159b RL |
108 | return 0; |
109 | ||
be5fc053 KR |
110 | dctx = OPENSSL_zalloc(sizeof(*dctx)); |
111 | if (dctx == NULL) { | |
112 | EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE); | |
113 | return 0; | |
114 | } | |
115 | ||
116 | EVP_PKEY_CTX_set_data(dst, dctx); | |
117 | dst->keygen_info_count = 0; | |
5e55159b | 118 | |
be5fc053 KR |
119 | dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx); |
120 | if (dctx->ctx == NULL) | |
5e55159b RL |
121 | goto err; |
122 | ||
e74bd290 RL |
123 | /* |
124 | * Normally, nothing special would be done with the MAC method. In | |
125 | * this particular case, though, the MAC method was fetched internally | |
126 | * by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed | |
127 | * via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX | |
128 | * fetches the MAC method anew in this case. Therefore, its reference | |
129 | * count must be adjusted here. | |
130 | */ | |
131 | if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx))) | |
132 | goto err; | |
133 | ||
be5fc053 KR |
134 | dctx->type = sctx->type; |
135 | ||
5e55159b RL |
136 | switch (dctx->type) { |
137 | case MAC_TYPE_RAW: | |
138 | dctx->raw_data.md = sctx->raw_data.md; | |
139 | if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL && | |
140 | !ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp)) | |
141 | goto err; | |
142 | break; | |
143 | case MAC_TYPE_MAC: | |
144 | /* Nothing more to do */ | |
145 | break; | |
146 | default: | |
147 | /* This should be dead code */ | |
148 | return 0; | |
149 | } | |
150 | return 1; | |
151 | err: | |
be5fc053 | 152 | pkey_mac_cleanup(dst); |
5e55159b RL |
153 | return 0; |
154 | } | |
155 | ||
156 | static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx) | |
157 | { | |
e74bd290 RL |
158 | /* |
159 | * For the exact same reasons the MAC reference count is incremented | |
160 | * in pkey_mac_copy() above, it must be explicitly freed here. | |
161 | */ | |
162 | ||
163 | MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx); | |
5e55159b RL |
164 | |
165 | if (hctx != NULL) { | |
129c2284 | 166 | EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_CTX_mac(hctx->ctx) : NULL; |
e74bd290 | 167 | |
5e55159b RL |
168 | switch (hctx->type) { |
169 | case MAC_TYPE_RAW: | |
170 | OPENSSL_clear_free(hctx->raw_data.ktmp.data, | |
171 | hctx->raw_data.ktmp.length); | |
172 | break; | |
173 | } | |
174 | EVP_MAC_CTX_free(hctx->ctx); | |
e74bd290 | 175 | EVP_MAC_free(mac); |
5e55159b RL |
176 | OPENSSL_free(hctx); |
177 | EVP_PKEY_CTX_set_data(ctx, NULL); | |
178 | } | |
179 | } | |
180 | ||
181 | static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | |
182 | { | |
183 | MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); | |
184 | int nid = ctx->pmeth->pkey_id; | |
185 | ||
186 | switch (hctx->type) { | |
187 | case MAC_TYPE_RAW: | |
188 | { | |
189 | ASN1_OCTET_STRING *hkey = NULL; | |
190 | ||
191 | if (!hctx->raw_data.ktmp.data) | |
192 | return 0; | |
193 | hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp); | |
194 | if (!hkey) | |
195 | return 0; | |
196 | EVP_PKEY_assign(pkey, nid, hkey); | |
197 | } | |
198 | break; | |
199 | case MAC_TYPE_MAC: | |
200 | { | |
129c2284 | 201 | EVP_MAC_CTX *cmkey; |
5e55159b | 202 | |
129c2284 MC |
203 | if (hctx->ctx == NULL) { |
204 | /* This actually means the fetch failed during the init call */ | |
205 | EVPerr(0, EVP_R_FETCH_FAILED); | |
206 | return 0; | |
207 | } | |
208 | ||
209 | cmkey = EVP_MAC_CTX_dup(hctx->ctx); | |
5e55159b RL |
210 | if (cmkey == NULL) |
211 | return 0; | |
e74bd290 RL |
212 | if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx))) |
213 | return 0; | |
5e55159b RL |
214 | EVP_PKEY_assign(pkey, nid, cmkey); |
215 | } | |
216 | break; | |
217 | default: | |
218 | /* This should be dead code */ | |
219 | return 0; | |
220 | } | |
221 | ||
222 | return 1; | |
223 | } | |
224 | ||
225 | static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) | |
226 | { | |
227 | MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx)); | |
228 | ||
229 | if (!EVP_MAC_update(hctx->ctx, data, count)) | |
230 | return 0; | |
231 | return 1; | |
232 | } | |
233 | ||
234 | static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) | |
235 | { | |
236 | MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); | |
237 | ASN1_OCTET_STRING *key = NULL; | |
238 | int rv = 1; | |
239 | /* | |
240 | * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that | |
241 | * gets the key passed as an ASN.1 OCTET STRING, we set the key here, | |
242 | * as this may be only time it's set during a DigestSign. | |
243 | * | |
244 | * MACs that pass around the key in form of EVP_MAC_CTX are setting | |
245 | * the key through other mechanisms. (this is only CMAC for now) | |
246 | */ | |
247 | int set_key = | |
248 | hctx->type == MAC_TYPE_RAW | |
249 | && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0; | |
250 | ||
129c2284 MC |
251 | if (hctx->ctx == NULL) { |
252 | /* This actually means the fetch failed during the init call */ | |
253 | EVPerr(0, EVP_R_FETCH_FAILED); | |
254 | return 0; | |
255 | } | |
256 | ||
5e55159b | 257 | if (set_key) { |
7cfa1717 RL |
258 | if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx), |
259 | OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))))) | |
5e55159b RL |
260 | return 0; |
261 | key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx)); | |
262 | if (key == NULL) | |
263 | return 0; | |
264 | } | |
265 | ||
5e55159b RL |
266 | EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); |
267 | EVP_MD_CTX_set_update_fn(mctx, int_update); | |
268 | ||
e74bd290 RL |
269 | /* Some MACs don't support this control... that's fine */ |
270 | { | |
271 | OSSL_PARAM params[3]; | |
272 | size_t params_n = 0; | |
273 | int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT); | |
274 | ||
275 | /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */ | |
276 | params[params_n++] = | |
277 | OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags); | |
278 | if (set_key) | |
279 | params[params_n++] = | |
280 | OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, | |
281 | key->data, key->length); | |
282 | params[params_n++] = OSSL_PARAM_construct_end(); | |
283 | rv = EVP_MAC_CTX_set_params(hctx->ctx, params); | |
284 | } | |
285 | return rv; | |
5e55159b RL |
286 | } |
287 | ||
288 | static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, | |
289 | size_t *siglen, EVP_MD_CTX *mctx) | |
290 | { | |
291 | MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); | |
292 | ||
e74bd290 | 293 | return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx)); |
5e55159b RL |
294 | } |
295 | ||
296 | static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | |
297 | { | |
298 | MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); | |
299 | ||
300 | switch (type) { | |
301 | ||
302 | case EVP_PKEY_CTRL_CIPHER: | |
303 | switch (hctx->type) { | |
304 | case MAC_TYPE_RAW: | |
305 | return -2; /* The raw types don't support ciphers */ | |
306 | case MAC_TYPE_MAC: | |
307 | { | |
e74bd290 RL |
308 | OSSL_PARAM params[3]; |
309 | size_t params_n = 0; | |
310 | char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2)); | |
3be06e0d | 311 | #ifndef OPENSSL_NO_ENGINE |
e74bd290 RL |
312 | char *engineid = (char *)ENGINE_get_id(ctx->engine); |
313 | ||
314 | params[params_n++] = | |
69db3044 | 315 | OSSL_PARAM_construct_utf8_string("engine", engineid, 0); |
3be06e0d | 316 | #endif |
e74bd290 | 317 | params[params_n++] = |
703170d4 | 318 | OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, |
7f588d20 | 319 | ciphname, 0); |
e74bd290 RL |
320 | params[params_n] = OSSL_PARAM_construct_end(); |
321 | ||
129c2284 MC |
322 | if (hctx->ctx == NULL) { |
323 | /* | |
324 | * This actually means the fetch failed during the init call | |
325 | */ | |
326 | EVPerr(0, EVP_R_FETCH_FAILED); | |
327 | return 0; | |
328 | } | |
329 | ||
e74bd290 RL |
330 | if (!EVP_MAC_CTX_set_params(hctx->ctx, params) |
331 | || !EVP_MAC_init(hctx->ctx)) | |
332 | return 0; | |
5e55159b RL |
333 | } |
334 | break; | |
335 | default: | |
336 | /* This should be dead code */ | |
337 | return 0; | |
338 | } | |
339 | break; | |
340 | ||
341 | case EVP_PKEY_CTRL_MD: | |
342 | switch (hctx->type) { | |
343 | case MAC_TYPE_RAW: | |
344 | hctx->raw_data.md = p2; | |
345 | break; | |
be5fc053 KR |
346 | case MAC_TYPE_MAC: { |
347 | EVP_MAC_CTX *new_mac_ctx; | |
348 | ||
349 | if (ctx->pkey == NULL) | |
350 | return 0; | |
8cc86b81 | 351 | new_mac_ctx = EVP_MAC_CTX_dup(ctx->pkey->pkey.ptr); |
be5fc053 KR |
352 | if (new_mac_ctx == NULL) |
353 | return 0; | |
354 | EVP_MAC_CTX_free(hctx->ctx); | |
355 | hctx->ctx = new_mac_ctx; | |
356 | } | |
5e55159b RL |
357 | break; |
358 | default: | |
359 | /* This should be dead code */ | |
360 | return 0; | |
361 | } | |
362 | break; | |
363 | ||
364 | case EVP_PKEY_CTRL_SET_DIGEST_SIZE: | |
e74bd290 RL |
365 | { |
366 | OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; | |
367 | size_t size = (size_t)p1; | |
368 | size_t verify = 0; | |
369 | ||
370 | /* | |
371 | * We verify that the length is actually set by getting back | |
372 | * the same parameter and checking that it matches what we | |
373 | * tried to set. | |
374 | * TODO(3.0) when we have a more direct mechanism to check if | |
375 | * a parameter was used, we must refactor this to use that. | |
376 | */ | |
377 | ||
378 | params[0] = | |
703170d4 | 379 | OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size); |
e74bd290 | 380 | |
129c2284 MC |
381 | if (hctx->ctx == NULL) { |
382 | /* | |
383 | * This actually means the fetch failed during the init call | |
384 | */ | |
385 | EVPerr(0, EVP_R_FETCH_FAILED); | |
386 | return 0; | |
387 | } | |
388 | ||
e74bd290 RL |
389 | if (!EVP_MAC_CTX_set_params(hctx->ctx, params)) |
390 | return 0; | |
5e55159b | 391 | |
e74bd290 | 392 | params[0] = |
703170d4 | 393 | OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify); |
e74bd290 RL |
394 | |
395 | if (!EVP_MAC_CTX_get_params(hctx->ctx, params)) | |
396 | return 0; | |
397 | ||
398 | /* | |
399 | * Since EVP_MAC_CTX_{get,set}_params() returned successfully, | |
400 | * we can only assume that the size was ignored, i.e. this | |
401 | * control is unsupported. | |
402 | */ | |
403 | if (verify != size) | |
404 | return -2; | |
405 | } | |
406 | break; | |
5e55159b RL |
407 | case EVP_PKEY_CTRL_SET_MAC_KEY: |
408 | switch (hctx->type) { | |
409 | case MAC_TYPE_RAW: | |
410 | if ((!p2 && p1 > 0) || (p1 < -1)) | |
411 | return 0; | |
412 | if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1)) | |
413 | return 0; | |
414 | break; | |
415 | case MAC_TYPE_MAC: | |
e74bd290 RL |
416 | { |
417 | OSSL_PARAM params[2]; | |
418 | size_t params_n = 0; | |
419 | ||
420 | params[params_n++] = | |
421 | OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, | |
422 | p2, p1); | |
423 | params[params_n] = OSSL_PARAM_construct_end(); | |
424 | ||
129c2284 MC |
425 | if (hctx->ctx == NULL) { |
426 | /* | |
427 | * This actually means the fetch failed during the init call | |
428 | */ | |
429 | EVPerr(0, EVP_R_FETCH_FAILED); | |
430 | return 0; | |
431 | } | |
432 | ||
e74bd290 RL |
433 | return EVP_MAC_CTX_set_params(hctx->ctx, params); |
434 | } | |
5e55159b RL |
435 | break; |
436 | default: | |
437 | /* This should be dead code */ | |
438 | return 0; | |
439 | } | |
440 | break; | |
441 | ||
442 | case EVP_PKEY_CTRL_DIGESTINIT: | |
443 | switch (hctx->type) { | |
444 | case MAC_TYPE_RAW: | |
129c2284 MC |
445 | if (hctx->ctx == NULL) { |
446 | /* This actually means the fetch failed during the init call */ | |
447 | EVPerr(0, EVP_R_FETCH_FAILED); | |
448 | return 0; | |
449 | } | |
450 | ||
5e55159b RL |
451 | /* Ensure that we have attached the implementation */ |
452 | if (!EVP_MAC_init(hctx->ctx)) | |
453 | return 0; | |
454 | { | |
5e55159b RL |
455 | ASN1_OCTET_STRING *key = |
456 | (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; | |
e74bd290 RL |
457 | OSSL_PARAM params[4]; |
458 | size_t params_n = 0; | |
459 | char *mdname = | |
460 | (char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md)); | |
3be06e0d | 461 | #ifndef OPENSSL_NO_ENGINE |
e74bd290 RL |
462 | char *engineid = ctx->engine == NULL |
463 | ? NULL : (char *)ENGINE_get_id(ctx->engine); | |
464 | ||
69db3044 | 465 | if (engineid != NULL) |
e74bd290 | 466 | params[params_n++] = |
69db3044 | 467 | OSSL_PARAM_construct_utf8_string("engine", engineid, 0); |
3be06e0d | 468 | #endif |
e74bd290 | 469 | params[params_n++] = |
703170d4 | 470 | OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, |
7f588d20 | 471 | mdname, 0); |
e74bd290 RL |
472 | params[params_n++] = |
473 | OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, | |
474 | key->data, key->length); | |
475 | params[params_n] = OSSL_PARAM_construct_end(); | |
476 | ||
477 | return EVP_MAC_CTX_set_params(hctx->ctx, params); | |
5e55159b RL |
478 | } |
479 | break; | |
480 | case MAC_TYPE_MAC: | |
481 | return -2; /* The mac types don't support ciphers */ | |
482 | default: | |
483 | /* This should be dead code */ | |
484 | return 0; | |
485 | } | |
486 | break; | |
487 | ||
488 | default: | |
489 | return -2; | |
490 | ||
491 | } | |
492 | return 1; | |
493 | } | |
494 | ||
495 | static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx, | |
4dcff55c | 496 | const char *type, const char *value) |
5e55159b RL |
497 | { |
498 | MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); | |
4dcff55c | 499 | const EVP_MAC *mac; |
e74bd290 RL |
500 | OSSL_PARAM params[2]; |
501 | int ok = 0; | |
5e55159b | 502 | |
4dcff55c P |
503 | if (hctx == NULL) { |
504 | EVPerr(0, EVP_R_NULL_MAC_PKEY_CTX); | |
505 | return 0; | |
506 | } | |
507 | if (hctx->ctx == NULL) { | |
508 | /* This actually means the fetch failed during the init call */ | |
509 | EVPerr(0, EVP_R_FETCH_FAILED); | |
510 | return 0; | |
511 | } | |
512 | mac = EVP_MAC_CTX_mac(hctx->ctx); | |
513 | ||
703170d4 RL |
514 | /* |
515 | * Translation of some control names that are equivalent to a single | |
516 | * parameter name. | |
517 | * | |
518 | * "md" and "digest" are the same thing, we use the single "digest" | |
519 | * | |
520 | * "digestsize" was a setting control in siphash, but naming wise, | |
521 | * it's really the same as "size". | |
522 | */ | |
523 | if (strcmp(type, "md") == 0) | |
524 | type = OSSL_MAC_PARAM_DIGEST; | |
525 | else if (strcmp(type, "digestsize") == 0) | |
526 | type = OSSL_MAC_PARAM_SIZE; | |
527 | ||
e74bd290 | 528 | if (!OSSL_PARAM_allocate_from_text(¶ms[0], |
41f7ecf3 | 529 | EVP_MAC_settable_ctx_params(mac), |
2ee0dfa6 | 530 | type, value, strlen(value) + 1, NULL)) |
e74bd290 RL |
531 | return 0; |
532 | params[1] = OSSL_PARAM_construct_end(); | |
129c2284 | 533 | |
e74bd290 RL |
534 | ok = EVP_MAC_CTX_set_params(hctx->ctx, params); |
535 | OPENSSL_free(params[0].data); | |
536 | return ok; | |
5e55159b RL |
537 | } |
538 | ||
19bd1fa1 | 539 | static const EVP_PKEY_METHOD cmac_pkey_meth = { |
e74a435f | 540 | EVP_PKEY_CMAC, |
5e55159b RL |
541 | EVP_PKEY_FLAG_SIGCTX_CUSTOM, |
542 | pkey_mac_init, | |
543 | pkey_mac_copy, | |
544 | pkey_mac_cleanup, | |
545 | ||
546 | 0, 0, | |
547 | ||
548 | 0, | |
549 | pkey_mac_keygen, | |
550 | ||
551 | 0, 0, | |
552 | ||
553 | 0, 0, | |
554 | ||
555 | 0, 0, | |
556 | ||
557 | pkey_mac_signctx_init, | |
558 | pkey_mac_signctx, | |
559 | ||
560 | 0, 0, | |
561 | ||
562 | 0, 0, | |
563 | ||
564 | 0, 0, | |
565 | ||
566 | 0, 0, | |
567 | ||
568 | pkey_mac_ctrl, | |
569 | pkey_mac_ctrl_str | |
570 | }; | |
f8c9a8e3 | 571 | |
19bd1fa1 PS |
572 | const EVP_PKEY_METHOD *cmac_pkey_method(void) |
573 | { | |
574 | return &cmac_pkey_meth; | |
575 | } | |
576 | ||
577 | static const EVP_PKEY_METHOD hmac_pkey_meth = { | |
f8c9a8e3 RL |
578 | EVP_PKEY_HMAC, |
579 | 0, | |
580 | pkey_mac_init, | |
581 | pkey_mac_copy, | |
582 | pkey_mac_cleanup, | |
583 | ||
584 | 0, 0, | |
585 | ||
586 | 0, | |
587 | pkey_mac_keygen, | |
588 | ||
589 | 0, 0, | |
590 | ||
591 | 0, 0, | |
592 | ||
593 | 0, 0, | |
594 | ||
595 | pkey_mac_signctx_init, | |
596 | pkey_mac_signctx, | |
597 | ||
598 | 0, 0, | |
599 | ||
600 | 0, 0, | |
601 | ||
602 | 0, 0, | |
603 | ||
604 | 0, 0, | |
605 | ||
606 | pkey_mac_ctrl, | |
607 | pkey_mac_ctrl_str | |
608 | }; | |
14f61f81 | 609 | |
19bd1fa1 PS |
610 | const EVP_PKEY_METHOD *hmac_pkey_method(void) |
611 | { | |
612 | return &hmac_pkey_meth; | |
613 | } | |
614 | ||
615 | static const EVP_PKEY_METHOD siphash_pkey_meth = { | |
14f61f81 RL |
616 | EVP_PKEY_SIPHASH, |
617 | EVP_PKEY_FLAG_SIGCTX_CUSTOM, | |
618 | pkey_mac_init, | |
619 | pkey_mac_copy, | |
620 | pkey_mac_cleanup, | |
621 | ||
622 | 0, 0, | |
623 | ||
624 | 0, | |
625 | pkey_mac_keygen, | |
626 | ||
627 | 0, 0, | |
628 | ||
629 | 0, 0, | |
630 | ||
631 | 0, 0, | |
632 | ||
633 | pkey_mac_signctx_init, | |
634 | pkey_mac_signctx, | |
635 | ||
636 | 0, 0, | |
637 | ||
638 | 0, 0, | |
639 | ||
640 | 0, 0, | |
641 | ||
642 | 0, 0, | |
643 | ||
644 | pkey_mac_ctrl, | |
645 | pkey_mac_ctrl_str | |
646 | }; | |
c1da4b2a | 647 | |
19bd1fa1 PS |
648 | const EVP_PKEY_METHOD *siphash_pkey_method(void) |
649 | { | |
650 | return &siphash_pkey_meth; | |
651 | } | |
652 | ||
653 | static const EVP_PKEY_METHOD poly1305_pkey_meth = { | |
c1da4b2a PY |
654 | EVP_PKEY_POLY1305, |
655 | EVP_PKEY_FLAG_SIGCTX_CUSTOM, | |
656 | pkey_mac_init, | |
657 | pkey_mac_copy, | |
658 | pkey_mac_cleanup, | |
659 | ||
660 | 0, 0, | |
661 | ||
662 | 0, | |
663 | pkey_mac_keygen, | |
664 | ||
665 | 0, 0, | |
666 | ||
667 | 0, 0, | |
668 | ||
669 | 0, 0, | |
670 | ||
671 | pkey_mac_signctx_init, | |
672 | pkey_mac_signctx, | |
673 | ||
674 | 0, 0, | |
675 | ||
676 | 0, 0, | |
677 | ||
678 | 0, 0, | |
679 | ||
680 | 0, 0, | |
681 | ||
682 | pkey_mac_ctrl, | |
683 | pkey_mac_ctrl_str | |
684 | }; | |
19bd1fa1 PS |
685 | |
686 | const EVP_PKEY_METHOD *poly1305_pkey_method(void) | |
687 | { | |
688 | return &poly1305_pkey_meth; | |
689 | } |