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