Get rid of the diversity of names for MAC parameters
[openssl.git] / crypto / evp / pkey_mac.c
1 /*
2  * Copyright 2018 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
10 #include <string.h>
11 #include <openssl/err.h>
12 #include <openssl/evp.h>
13 #include <openssl/engine.h>
14 #include <openssl/params.h>
15 #include <openssl/core_names.h>
16 #include "internal/evp_int.h"
17 #include "evp_locl.h"
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
47 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
48
49 static int pkey_mac_init(EVP_PKEY_CTX *ctx)
50 {
51     MAC_PKEY_CTX *hctx;
52     /* We're being smart and using the same base NIDs for PKEY and for MAC */
53     int nid = ctx->pmeth->pkey_id;
54     EVP_MAC *mac = EVP_MAC_fetch(NULL, OBJ_nid2sn(nid), NULL);
55
56     if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
57         EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
58         return 0;
59     }
60
61     hctx->ctx = EVP_MAC_CTX_new(mac);
62     if (hctx->ctx == NULL) {
63         OPENSSL_free(hctx);
64         return 0;
65     }
66
67     if (nid == EVP_PKEY_CMAC) {
68         hctx->type = MAC_TYPE_MAC;
69     } else {
70         hctx->type = MAC_TYPE_RAW;
71         hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING;
72     }
73
74     pkey_mac_cleanup(ctx);
75     EVP_PKEY_CTX_set_data(ctx, hctx);
76     ctx->keygen_info_count = 0;
77
78     return 1;
79 }
80
81 static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
82 {
83     MAC_PKEY_CTX *sctx, *dctx;
84
85     sctx = EVP_PKEY_CTX_get_data(src);
86     if (sctx->ctx->data == NULL)
87         return 0;
88
89     dctx = OPENSSL_zalloc(sizeof(*dctx));
90     if (dctx == NULL) {
91         EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE);
92         return 0;
93     }
94
95     EVP_PKEY_CTX_set_data(dst, dctx);
96     dst->keygen_info_count = 0;
97
98     dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx);
99     if (dctx->ctx == NULL)
100         goto err;
101
102     /*
103      * Normally, nothing special would be done with the MAC method.  In
104      * this particular case, though, the MAC method was fetched internally
105      * by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed
106      * via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX
107      * fetches the MAC method anew in this case.  Therefore, its reference
108      * count must be adjusted here.
109      */
110     if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx)))
111         goto err;
112
113     dctx->type = sctx->type;
114
115     switch (dctx->type) {
116     case MAC_TYPE_RAW:
117         dctx->raw_data.md = sctx->raw_data.md;
118         if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL &&
119             !ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp))
120             goto err;
121         break;
122     case MAC_TYPE_MAC:
123         /* Nothing more to do */
124         break;
125     default:
126         /* This should be dead code */
127         return 0;
128     }
129     return 1;
130  err:
131     pkey_mac_cleanup(dst);
132     return 0;
133 }
134
135 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
136 {
137     /*
138      * For the exact same reasons the MAC reference count is incremented
139      * in pkey_mac_copy() above, it must be explicitly freed here.
140      */
141
142     MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
143
144     if (hctx != NULL) {
145         EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
146
147         switch (hctx->type) {
148         case MAC_TYPE_RAW:
149             OPENSSL_clear_free(hctx->raw_data.ktmp.data,
150                                hctx->raw_data.ktmp.length);
151             break;
152         }
153         EVP_MAC_CTX_free(hctx->ctx);
154         EVP_MAC_free(mac);
155         OPENSSL_free(hctx);
156         EVP_PKEY_CTX_set_data(ctx, NULL);
157     }
158 }
159
160 static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
161 {
162     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
163     int nid = ctx->pmeth->pkey_id;
164
165     switch (hctx->type) {
166     case MAC_TYPE_RAW:
167         {
168             ASN1_OCTET_STRING *hkey = NULL;
169
170             if (!hctx->raw_data.ktmp.data)
171                 return 0;
172             hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp);
173             if (!hkey)
174                 return 0;
175             EVP_PKEY_assign(pkey, nid, hkey);
176         }
177         break;
178     case MAC_TYPE_MAC:
179         {
180             EVP_MAC_CTX *cmkey = EVP_MAC_CTX_dup(hctx->ctx);
181
182             if (cmkey == NULL)
183                 return 0;
184             if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
185                 return 0;
186             EVP_PKEY_assign(pkey, nid, cmkey);
187         }
188         break;
189     default:
190         /* This should be dead code */
191         return 0;
192     }
193
194     return 1;
195 }
196
197 static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
198 {
199     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
200
201     if (!EVP_MAC_update(hctx->ctx, data, count))
202         return 0;
203     return 1;
204 }
205
206 static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
207 {
208     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
209     ASN1_OCTET_STRING *key = NULL;
210     int rv = 1;
211     /*
212      * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
213      * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
214      * as this may be only time it's set during a DigestSign.
215      *
216      * MACs that pass around the key in form of EVP_MAC_CTX are setting
217      * the key through other mechanisms.  (this is only CMAC for now)
218      */
219     int set_key =
220         hctx->type == MAC_TYPE_RAW
221         && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
222
223     if (set_key) {
224         if (strcmp(OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))),
225                    EVP_MAC_name(EVP_MAC_CTX_mac(hctx->ctx))) != 0)
226             return 0;
227         key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
228         if (key == NULL)
229             return 0;
230     }
231
232     EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
233     EVP_MD_CTX_set_update_fn(mctx, int_update);
234
235     /* Some MACs don't support this control...  that's fine */
236     {
237         OSSL_PARAM params[3];
238         size_t params_n = 0;
239         int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT);
240
241         /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */
242         params[params_n++] =
243             OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags);
244         if (set_key)
245             params[params_n++] =
246                 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
247                                                   key->data, key->length);
248         params[params_n++] = OSSL_PARAM_construct_end();
249         rv = EVP_MAC_CTX_set_params(hctx->ctx, params);
250     }
251     return rv;
252 }
253
254 static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
255                              size_t *siglen, EVP_MD_CTX *mctx)
256 {
257     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
258
259     return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx));
260 }
261
262 static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
263 {
264     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
265
266     switch (type) {
267
268     case EVP_PKEY_CTRL_CIPHER:
269         switch (hctx->type) {
270         case MAC_TYPE_RAW:
271             return -2;       /* The raw types don't support ciphers */
272         case MAC_TYPE_MAC:
273             {
274                 OSSL_PARAM params[3];
275                 size_t params_n = 0;
276                 char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2));
277                 char *engineid = (char *)ENGINE_get_id(ctx->engine);
278
279                 params[params_n++] =
280                     OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
281                                                      engineid,
282                                                      strlen(engineid) + 1);
283                 params[params_n++] =
284                     OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
285                                                      ciphname,
286                                                      strlen(ciphname) + 1);
287                 params[params_n] = OSSL_PARAM_construct_end();
288
289                 if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
290                     || !EVP_MAC_init(hctx->ctx))
291                     return 0;
292             }
293             break;
294         default:
295             /* This should be dead code */
296             return 0;
297         }
298         break;
299
300     case EVP_PKEY_CTRL_MD:
301         switch (hctx->type) {
302         case MAC_TYPE_RAW:
303             hctx->raw_data.md = p2;
304             break;
305         case MAC_TYPE_MAC: {
306                 EVP_MAC_CTX *new_mac_ctx;
307
308                 if (ctx->pkey == NULL)
309                     return 0;
310                 new_mac_ctx = EVP_MAC_CTX_dup((EVP_MAC_CTX *)ctx->pkey
311                                               ->pkey.ptr);
312                 if (new_mac_ctx == NULL)
313                     return 0;
314                 EVP_MAC_CTX_free(hctx->ctx);
315                 hctx->ctx = new_mac_ctx;
316             }
317             break;
318         default:
319             /* This should be dead code */
320             return 0;
321         }
322         break;
323
324     case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
325         {
326             OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
327             size_t size = (size_t)p1;
328             size_t verify = 0;
329
330             /*
331              * We verify that the length is actually set by getting back
332              * the same parameter and checking that it matches what we
333              * tried to set.
334              * TODO(3.0) when we have a more direct mechanism to check if
335              * a parameter was used, we must refactor this to use that.
336              */
337
338             params[0] =
339                 OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
340
341             if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
342                 return 0;
343
344             params[0] =
345                 OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify);
346
347             if (!EVP_MAC_CTX_get_params(hctx->ctx, params))
348                 return 0;
349
350             /*
351              * Since EVP_MAC_CTX_{get,set}_params() returned successfully,
352              * we can only assume that the size was ignored, i.e. this
353              * control is unsupported.
354              */
355             if (verify != size)
356                 return -2;
357         }
358         break;
359     case EVP_PKEY_CTRL_SET_MAC_KEY:
360         switch (hctx->type) {
361         case MAC_TYPE_RAW:
362             if ((!p2 && p1 > 0) || (p1 < -1))
363                 return 0;
364             if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1))
365                 return 0;
366             break;
367         case MAC_TYPE_MAC:
368             {
369                 OSSL_PARAM params[2];
370                 size_t params_n = 0;
371
372                 params[params_n++] =
373                     OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
374                                                       p2, p1);
375                 params[params_n] = OSSL_PARAM_construct_end();
376
377                 return EVP_MAC_CTX_set_params(hctx->ctx, params);
378             }
379             break;
380         default:
381             /* This should be dead code */
382             return 0;
383         }
384         break;
385
386     case EVP_PKEY_CTRL_DIGESTINIT:
387         switch (hctx->type) {
388         case MAC_TYPE_RAW:
389             /* Ensure that we have attached the implementation */
390             if (!EVP_MAC_init(hctx->ctx))
391                 return 0;
392             {
393                 ASN1_OCTET_STRING *key =
394                     (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
395                 OSSL_PARAM params[4];
396                 size_t params_n = 0;
397                 char *mdname =
398                     (char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md));
399                 char *engineid = ctx->engine == NULL
400                     ? NULL : (char *)ENGINE_get_id(ctx->engine);
401
402                 if (engineid != NULL) {
403                     size_t engineid_l = strlen(engineid) + 1;
404                     params[params_n++] =
405                         OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
406                                                          engineid,
407                                                          engineid_l);
408                 }
409                 params[params_n++] =
410                     OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
411                                                      mdname,
412                                                      strlen(mdname) + 1);
413                 params[params_n++] =
414                     OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
415                                                       key->data, key->length);
416                 params[params_n] = OSSL_PARAM_construct_end();
417
418                 return EVP_MAC_CTX_set_params(hctx->ctx, params);
419             }
420             break;
421         case MAC_TYPE_MAC:
422             return -2;       /* The mac types don't support ciphers */
423         default:
424             /* This should be dead code */
425             return 0;
426         }
427         break;
428
429     default:
430         return -2;
431
432     }
433     return 1;
434 }
435
436 static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
437                               const char *type, const char *value)
438 {
439     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
440     const EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
441     OSSL_PARAM params[2];
442     int ok = 0;
443
444     /*
445      * Translation of some control names that are equivalent to a single
446      * parameter name.
447      *
448      * "md" and "digest" are the same thing, we use the single "digest"
449      *
450      * "digestsize" was a setting control in siphash, but naming wise,
451      * it's really the same as "size".
452      */
453     if (strcmp(type, "md") == 0)
454         type = OSSL_MAC_PARAM_DIGEST;
455     else if (strcmp(type, "digestsize") == 0)
456         type = OSSL_MAC_PARAM_SIZE;
457
458     if (!OSSL_PARAM_allocate_from_text(&params[0],
459                                        EVP_MAC_CTX_settable_params(mac),
460                                        type, value, strlen(value) + 1))
461         return 0;
462     params[1] = OSSL_PARAM_construct_end();
463     ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
464     OPENSSL_free(params[0].data);
465     return ok;
466 }
467
468 const EVP_PKEY_METHOD cmac_pkey_meth = {
469     EVP_PKEY_CMAC,
470     EVP_PKEY_FLAG_SIGCTX_CUSTOM,
471     pkey_mac_init,
472     pkey_mac_copy,
473     pkey_mac_cleanup,
474
475     0, 0,
476
477     0,
478     pkey_mac_keygen,
479
480     0, 0,
481
482     0, 0,
483
484     0, 0,
485
486     pkey_mac_signctx_init,
487     pkey_mac_signctx,
488
489     0, 0,
490
491     0, 0,
492
493     0, 0,
494
495     0, 0,
496
497     pkey_mac_ctrl,
498     pkey_mac_ctrl_str
499 };
500
501 const EVP_PKEY_METHOD hmac_pkey_meth = {
502     EVP_PKEY_HMAC,
503     0,
504     pkey_mac_init,
505     pkey_mac_copy,
506     pkey_mac_cleanup,
507
508     0, 0,
509
510     0,
511     pkey_mac_keygen,
512
513     0, 0,
514
515     0, 0,
516
517     0, 0,
518
519     pkey_mac_signctx_init,
520     pkey_mac_signctx,
521
522     0, 0,
523
524     0, 0,
525
526     0, 0,
527
528     0, 0,
529
530     pkey_mac_ctrl,
531     pkey_mac_ctrl_str
532 };
533
534 const EVP_PKEY_METHOD siphash_pkey_meth = {
535     EVP_PKEY_SIPHASH,
536     EVP_PKEY_FLAG_SIGCTX_CUSTOM,
537     pkey_mac_init,
538     pkey_mac_copy,
539     pkey_mac_cleanup,
540
541     0, 0,
542
543     0,
544     pkey_mac_keygen,
545
546     0, 0,
547
548     0, 0,
549
550     0, 0,
551
552     pkey_mac_signctx_init,
553     pkey_mac_signctx,
554
555     0, 0,
556
557     0, 0,
558
559     0, 0,
560
561     0, 0,
562
563     pkey_mac_ctrl,
564     pkey_mac_ctrl_str
565 };
566
567 const EVP_PKEY_METHOD poly1305_pkey_meth = {
568     EVP_PKEY_POLY1305,
569     EVP_PKEY_FLAG_SIGCTX_CUSTOM,
570     pkey_mac_init,
571     pkey_mac_copy,
572     pkey_mac_cleanup,
573
574     0, 0,
575
576     0,
577     pkey_mac_keygen,
578
579     0, 0,
580
581     0, 0,
582
583     0, 0,
584
585     pkey_mac_signctx_init,
586     pkey_mac_signctx,
587
588     0, 0,
589
590     0, 0,
591
592     0, 0,
593
594     0, 0,
595
596     pkey_mac_ctrl,
597     pkey_mac_ctrl_str
598 };