Replace EVP_MAC_CTX_copy() by EVP_MAC_CTX_dup()
[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 <openssl/err.h>
11 #include <openssl/evp.h>
12 #include "internal/evp_int.h"
13 #include "evp_locl.h"
14
15 /* MAC PKEY context structure */
16
17 typedef struct {
18     EVP_MAC_CTX *ctx;
19
20     /*
21      * We know of two MAC types:
22      *
23      * 1. those who take a secret in raw form, i.e. raw data as a
24      *    ASN1_OCTET_STRING embedded in a EVP_PKEY.  So far, that's
25      *    all of them but CMAC.
26      * 2. those who take a secret with associated cipher in very generic
27      *    form, i.e. a complete EVP_MAC_CTX embedded in a PKEY.  So far,
28      *    only CMAC does this.
29      *
30      * (one might wonder why the second form isn't used for all)
31      */
32 #define MAC_TYPE_RAW    1   /* HMAC like MAC type (all but CMAC so far) */
33 #define MAC_TYPE_MAC    2   /* CMAC like MAC type (only CMAC known so far) */
34     int type;
35
36     /* The following is only used for MAC_TYPE_RAW implementations */
37     struct {
38         const EVP_MD *md;           /* temp storage of MD */
39         ASN1_OCTET_STRING ktmp;     /* temp storage for key */
40     } raw_data;
41 } MAC_PKEY_CTX;
42
43 static int pkey_mac_init(EVP_PKEY_CTX *ctx)
44 {
45     MAC_PKEY_CTX *hctx;
46     int nid = ctx->pmeth->pkey_id;
47
48     if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
49         EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
50         return 0;
51     }
52
53     /* We're being smart and using the same base NIDs for PKEY and for MAC */
54     hctx->ctx = EVP_MAC_CTX_new_id(nid);
55     if (hctx->ctx == NULL) {
56         OPENSSL_free(hctx);
57         return 0;
58     }
59
60     if (nid == EVP_PKEY_CMAC) {
61         hctx->type = MAC_TYPE_MAC;
62     } else {
63         hctx->type = MAC_TYPE_RAW;
64         hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING;
65     }
66
67     EVP_PKEY_CTX_set_data(ctx, hctx);
68     ctx->keygen_info_count = 0;
69
70     return 1;
71 }
72
73 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
74
75 static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
76 {
77     MAC_PKEY_CTX *sctx, *dctx;
78
79     sctx = EVP_PKEY_CTX_get_data(src);
80     if (sctx->ctx->data == NULL)
81         return 0;
82
83     dctx = OPENSSL_zalloc(sizeof(*dctx));
84     if (dctx == NULL) {
85         EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE);
86         return 0;
87     }
88
89     EVP_PKEY_CTX_set_data(dst, dctx);
90     dst->keygen_info_count = 0;
91
92     dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx);
93     if (dctx->ctx == NULL)
94         goto err;
95
96     dctx->type = sctx->type;
97
98     switch (dctx->type) {
99     case MAC_TYPE_RAW:
100         dctx->raw_data.md = sctx->raw_data.md;
101         if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL &&
102             !ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp))
103             goto err;
104         break;
105     case MAC_TYPE_MAC:
106         /* Nothing more to do */
107         break;
108     default:
109         /* This should be dead code */
110         return 0;
111     }
112     return 1;
113  err:
114     pkey_mac_cleanup(dst);
115     return 0;
116 }
117
118 static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
119 {
120     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
121
122     if (hctx != NULL) {
123         switch (hctx->type) {
124         case MAC_TYPE_RAW:
125             OPENSSL_clear_free(hctx->raw_data.ktmp.data,
126                                hctx->raw_data.ktmp.length);
127             break;
128         }
129         EVP_MAC_CTX_free(hctx->ctx);
130         OPENSSL_free(hctx);
131         EVP_PKEY_CTX_set_data(ctx, NULL);
132     }
133 }
134
135 static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
136 {
137     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
138     int nid = ctx->pmeth->pkey_id;
139
140     switch (hctx->type) {
141     case MAC_TYPE_RAW:
142         {
143             ASN1_OCTET_STRING *hkey = NULL;
144
145             if (!hctx->raw_data.ktmp.data)
146                 return 0;
147             hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp);
148             if (!hkey)
149                 return 0;
150             EVP_PKEY_assign(pkey, nid, hkey);
151         }
152         break;
153     case MAC_TYPE_MAC:
154         {
155             EVP_MAC_CTX *cmkey = EVP_MAC_CTX_dup(hctx->ctx);
156
157             if (cmkey == NULL)
158                 return 0;
159             EVP_PKEY_assign(pkey, nid, cmkey);
160         }
161         break;
162     default:
163         /* This should be dead code */
164         return 0;
165     }
166
167     return 1;
168 }
169
170 static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
171 {
172     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
173
174     if (!EVP_MAC_update(hctx->ctx, data, count))
175         return 0;
176     return 1;
177 }
178
179 static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
180 {
181     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
182     ASN1_OCTET_STRING *key = NULL;
183     int rv = 1;
184     /*
185      * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
186      * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
187      * as this may be only time it's set during a DigestSign.
188      *
189      * MACs that pass around the key in form of EVP_MAC_CTX are setting
190      * the key through other mechanisms.  (this is only CMAC for now)
191      */
192     int set_key =
193         hctx->type == MAC_TYPE_RAW
194         && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
195
196     if (set_key) {
197         if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))
198             != EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->ctx)))
199             return 0;
200         key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
201         if (key == NULL)
202             return 0;
203     }
204
205     /* Some MACs don't support this control...  that's fine */
206     EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_FLAGS,
207                  EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));
208
209     EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
210     EVP_MD_CTX_set_update_fn(mctx, int_update);
211
212     if (set_key)
213         rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, key->data,
214                           key->length);
215     return rv > 0;
216 }
217
218 static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
219                              size_t *siglen, EVP_MD_CTX *mctx)
220 {
221     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
222
223     return EVP_MAC_final(hctx->ctx, sig, siglen);
224 }
225
226 static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
227 {
228     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
229
230     switch (type) {
231
232     case EVP_PKEY_CTRL_CIPHER:
233         switch (hctx->type) {
234         case MAC_TYPE_RAW:
235             return -2;       /* The raw types don't support ciphers */
236         case MAC_TYPE_MAC:
237             {
238                 int rv;
239
240                 if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
241                                        ctx->engine)) <= 0
242                     || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_CIPHER,
243                                           p2)) <= 0
244                     || !(rv = EVP_MAC_init(hctx->ctx)))
245                     return rv;
246             }
247             break;
248         default:
249             /* This should be dead code */
250             return 0;
251         }
252         break;
253
254     case EVP_PKEY_CTRL_MD:
255         switch (hctx->type) {
256         case MAC_TYPE_RAW:
257             hctx->raw_data.md = p2;
258             break;
259         case MAC_TYPE_MAC: {
260                 EVP_MAC_CTX *new_mac_ctx;
261
262                 if (ctx->pkey == NULL)
263                     return 0;
264                 new_mac_ctx = EVP_MAC_CTX_dup((EVP_MAC_CTX *)ctx->pkey
265                                               ->pkey.ptr);
266                 if (new_mac_ctx == NULL)
267                     return 0;
268                 EVP_MAC_CTX_free(hctx->ctx);
269                 hctx->ctx = new_mac_ctx;
270             }
271             break;
272         default:
273             /* This should be dead code */
274             return 0;
275         }
276         break;
277
278     case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
279         return EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_SIZE, (size_t)p1);
280
281     case EVP_PKEY_CTRL_SET_MAC_KEY:
282         switch (hctx->type) {
283         case MAC_TYPE_RAW:
284             if ((!p2 && p1 > 0) || (p1 < -1))
285                 return 0;
286             if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1))
287                 return 0;
288             break;
289         case MAC_TYPE_MAC:
290             if (EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1) <= 0)
291                 return 0;
292             break;
293         default:
294             /* This should be dead code */
295             return 0;
296         }
297         break;
298
299     case EVP_PKEY_CTRL_DIGESTINIT:
300         switch (hctx->type) {
301         case MAC_TYPE_RAW:
302             /* Ensure that we have attached the implementation */
303             if (!EVP_MAC_init(hctx->ctx))
304                 return 0;
305             {
306                 int rv;
307                 ASN1_OCTET_STRING *key =
308                     (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
309
310                 if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
311                                        ctx->engine)) <= 0
312                     || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_MD,
313                                           hctx->raw_data.md)) <= 0
314                     || (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY,
315                                           key->data, key->length)) <= 0)
316                     return rv;
317             }
318             break;
319         case MAC_TYPE_MAC:
320             return -2;       /* The mac types don't support ciphers */
321         default:
322             /* This should be dead code */
323             return 0;
324         }
325         break;
326
327     default:
328         return -2;
329
330     }
331     return 1;
332 }
333
334 static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
335                               const char *type, const char *value)
336 {
337     MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
338
339     return EVP_MAC_ctrl_str(hctx->ctx, type, value);
340 }
341
342 const EVP_PKEY_METHOD cmac_pkey_meth = {
343     EVP_PKEY_CMAC,
344     EVP_PKEY_FLAG_SIGCTX_CUSTOM,
345     pkey_mac_init,
346     pkey_mac_copy,
347     pkey_mac_cleanup,
348
349     0, 0,
350
351     0,
352     pkey_mac_keygen,
353
354     0, 0,
355
356     0, 0,
357
358     0, 0,
359
360     pkey_mac_signctx_init,
361     pkey_mac_signctx,
362
363     0, 0,
364
365     0, 0,
366
367     0, 0,
368
369     0, 0,
370
371     pkey_mac_ctrl,
372     pkey_mac_ctrl_str
373 };
374
375 const EVP_PKEY_METHOD hmac_pkey_meth = {
376     EVP_PKEY_HMAC,
377     0,
378     pkey_mac_init,
379     pkey_mac_copy,
380     pkey_mac_cleanup,
381
382     0, 0,
383
384     0,
385     pkey_mac_keygen,
386
387     0, 0,
388
389     0, 0,
390
391     0, 0,
392
393     pkey_mac_signctx_init,
394     pkey_mac_signctx,
395
396     0, 0,
397
398     0, 0,
399
400     0, 0,
401
402     0, 0,
403
404     pkey_mac_ctrl,
405     pkey_mac_ctrl_str
406 };
407
408 const EVP_PKEY_METHOD siphash_pkey_meth = {
409     EVP_PKEY_SIPHASH,
410     EVP_PKEY_FLAG_SIGCTX_CUSTOM,
411     pkey_mac_init,
412     pkey_mac_copy,
413     pkey_mac_cleanup,
414
415     0, 0,
416
417     0,
418     pkey_mac_keygen,
419
420     0, 0,
421
422     0, 0,
423
424     0, 0,
425
426     pkey_mac_signctx_init,
427     pkey_mac_signctx,
428
429     0, 0,
430
431     0, 0,
432
433     0, 0,
434
435     0, 0,
436
437     pkey_mac_ctrl,
438     pkey_mac_ctrl_str
439 };
440
441 const EVP_PKEY_METHOD poly1305_pkey_meth = {
442     EVP_PKEY_POLY1305,
443     EVP_PKEY_FLAG_SIGCTX_CUSTOM,
444     pkey_mac_init,
445     pkey_mac_copy,
446     pkey_mac_cleanup,
447
448     0, 0,
449
450     0,
451     pkey_mac_keygen,
452
453     0, 0,
454
455     0, 0,
456
457     0, 0,
458
459     pkey_mac_signctx_init,
460     pkey_mac_signctx,
461
462     0, 0,
463
464     0, 0,
465
466     0, 0,
467
468     0, 0,
469
470     pkey_mac_ctrl,
471     pkey_mac_ctrl_str
472 };