1b077aed3SPierre Pronchery /*
2b077aed3SPierre Pronchery * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved.
3b077aed3SPierre Pronchery *
4b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy
6b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at
7b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html
8b077aed3SPierre Pronchery */
9b077aed3SPierre Pronchery
10b077aed3SPierre Pronchery /*
11b077aed3SPierre Pronchery * CMAC low level APIs are deprecated for public use, but still ok for internal
12b077aed3SPierre Pronchery * use.
13b077aed3SPierre Pronchery */
14b077aed3SPierre Pronchery #include "internal/deprecated.h"
15b077aed3SPierre Pronchery
16b077aed3SPierre Pronchery #include <openssl/core_dispatch.h>
17b077aed3SPierre Pronchery #include <openssl/core_names.h>
18b077aed3SPierre Pronchery #include <openssl/params.h>
19b077aed3SPierre Pronchery #include <openssl/evp.h>
20b077aed3SPierre Pronchery #include <openssl/cmac.h>
21b077aed3SPierre Pronchery
22b077aed3SPierre Pronchery #include "prov/implementations.h"
23b077aed3SPierre Pronchery #include "prov/provider_ctx.h"
24b077aed3SPierre Pronchery #include "prov/provider_util.h"
25b077aed3SPierre Pronchery #include "prov/providercommon.h"
26b077aed3SPierre Pronchery
27b077aed3SPierre Pronchery /*
28b077aed3SPierre Pronchery * Forward declaration of everything implemented here. This is not strictly
29b077aed3SPierre Pronchery * necessary for the compiler, but provides an assurance that the signatures
30b077aed3SPierre Pronchery * of the functions in the dispatch table are correct.
31b077aed3SPierre Pronchery */
32b077aed3SPierre Pronchery static OSSL_FUNC_mac_newctx_fn cmac_new;
33b077aed3SPierre Pronchery static OSSL_FUNC_mac_dupctx_fn cmac_dup;
34b077aed3SPierre Pronchery static OSSL_FUNC_mac_freectx_fn cmac_free;
35b077aed3SPierre Pronchery static OSSL_FUNC_mac_gettable_ctx_params_fn cmac_gettable_ctx_params;
36b077aed3SPierre Pronchery static OSSL_FUNC_mac_get_ctx_params_fn cmac_get_ctx_params;
37b077aed3SPierre Pronchery static OSSL_FUNC_mac_settable_ctx_params_fn cmac_settable_ctx_params;
38b077aed3SPierre Pronchery static OSSL_FUNC_mac_set_ctx_params_fn cmac_set_ctx_params;
39b077aed3SPierre Pronchery static OSSL_FUNC_mac_init_fn cmac_init;
40b077aed3SPierre Pronchery static OSSL_FUNC_mac_update_fn cmac_update;
41b077aed3SPierre Pronchery static OSSL_FUNC_mac_final_fn cmac_final;
42b077aed3SPierre Pronchery
43b077aed3SPierre Pronchery /* local CMAC data */
44b077aed3SPierre Pronchery
45b077aed3SPierre Pronchery struct cmac_data_st {
46b077aed3SPierre Pronchery void *provctx;
47b077aed3SPierre Pronchery CMAC_CTX *ctx;
48b077aed3SPierre Pronchery PROV_CIPHER cipher;
49b077aed3SPierre Pronchery };
50b077aed3SPierre Pronchery
cmac_new(void * provctx)51b077aed3SPierre Pronchery static void *cmac_new(void *provctx)
52b077aed3SPierre Pronchery {
53b077aed3SPierre Pronchery struct cmac_data_st *macctx;
54b077aed3SPierre Pronchery
55b077aed3SPierre Pronchery if (!ossl_prov_is_running())
56b077aed3SPierre Pronchery return NULL;
57b077aed3SPierre Pronchery
58b077aed3SPierre Pronchery if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL
59b077aed3SPierre Pronchery || (macctx->ctx = CMAC_CTX_new()) == NULL) {
60b077aed3SPierre Pronchery OPENSSL_free(macctx);
61b077aed3SPierre Pronchery macctx = NULL;
62b077aed3SPierre Pronchery } else {
63b077aed3SPierre Pronchery macctx->provctx = provctx;
64b077aed3SPierre Pronchery }
65b077aed3SPierre Pronchery
66b077aed3SPierre Pronchery return macctx;
67b077aed3SPierre Pronchery }
68b077aed3SPierre Pronchery
cmac_free(void * vmacctx)69b077aed3SPierre Pronchery static void cmac_free(void *vmacctx)
70b077aed3SPierre Pronchery {
71b077aed3SPierre Pronchery struct cmac_data_st *macctx = vmacctx;
72b077aed3SPierre Pronchery
73b077aed3SPierre Pronchery if (macctx != NULL) {
74b077aed3SPierre Pronchery CMAC_CTX_free(macctx->ctx);
75b077aed3SPierre Pronchery ossl_prov_cipher_reset(&macctx->cipher);
76b077aed3SPierre Pronchery OPENSSL_free(macctx);
77b077aed3SPierre Pronchery }
78b077aed3SPierre Pronchery }
79b077aed3SPierre Pronchery
cmac_dup(void * vsrc)80b077aed3SPierre Pronchery static void *cmac_dup(void *vsrc)
81b077aed3SPierre Pronchery {
82b077aed3SPierre Pronchery struct cmac_data_st *src = vsrc;
83b077aed3SPierre Pronchery struct cmac_data_st *dst;
84b077aed3SPierre Pronchery
85b077aed3SPierre Pronchery if (!ossl_prov_is_running())
86b077aed3SPierre Pronchery return NULL;
87b077aed3SPierre Pronchery
88b077aed3SPierre Pronchery dst = cmac_new(src->provctx);
89b077aed3SPierre Pronchery if (dst == NULL)
90b077aed3SPierre Pronchery return NULL;
91b077aed3SPierre Pronchery if (!CMAC_CTX_copy(dst->ctx, src->ctx)
92b077aed3SPierre Pronchery || !ossl_prov_cipher_copy(&dst->cipher, &src->cipher)) {
93b077aed3SPierre Pronchery cmac_free(dst);
94b077aed3SPierre Pronchery return NULL;
95b077aed3SPierre Pronchery }
96b077aed3SPierre Pronchery return dst;
97b077aed3SPierre Pronchery }
98b077aed3SPierre Pronchery
cmac_size(void * vmacctx)99b077aed3SPierre Pronchery static size_t cmac_size(void *vmacctx)
100b077aed3SPierre Pronchery {
101b077aed3SPierre Pronchery struct cmac_data_st *macctx = vmacctx;
102*e0c4386eSCy Schubert const EVP_CIPHER_CTX *cipherctx = CMAC_CTX_get0_cipher_ctx(macctx->ctx);
103b077aed3SPierre Pronchery
104*e0c4386eSCy Schubert if (EVP_CIPHER_CTX_get0_cipher(cipherctx) == NULL)
105*e0c4386eSCy Schubert return 0;
106*e0c4386eSCy Schubert
107*e0c4386eSCy Schubert return EVP_CIPHER_CTX_get_block_size(cipherctx);
108b077aed3SPierre Pronchery }
109b077aed3SPierre Pronchery
cmac_setkey(struct cmac_data_st * macctx,const unsigned char * key,size_t keylen)110b077aed3SPierre Pronchery static int cmac_setkey(struct cmac_data_st *macctx,
111b077aed3SPierre Pronchery const unsigned char *key, size_t keylen)
112b077aed3SPierre Pronchery {
113b077aed3SPierre Pronchery int rv = CMAC_Init(macctx->ctx, key, keylen,
114b077aed3SPierre Pronchery ossl_prov_cipher_cipher(&macctx->cipher),
115b077aed3SPierre Pronchery ossl_prov_cipher_engine(&macctx->cipher));
116b077aed3SPierre Pronchery ossl_prov_cipher_reset(&macctx->cipher);
117b077aed3SPierre Pronchery return rv;
118b077aed3SPierre Pronchery }
119b077aed3SPierre Pronchery
cmac_init(void * vmacctx,const unsigned char * key,size_t keylen,const OSSL_PARAM params[])120b077aed3SPierre Pronchery static int cmac_init(void *vmacctx, const unsigned char *key,
121b077aed3SPierre Pronchery size_t keylen, const OSSL_PARAM params[])
122b077aed3SPierre Pronchery {
123b077aed3SPierre Pronchery struct cmac_data_st *macctx = vmacctx;
124b077aed3SPierre Pronchery
125b077aed3SPierre Pronchery if (!ossl_prov_is_running() || !cmac_set_ctx_params(macctx, params))
126b077aed3SPierre Pronchery return 0;
127b077aed3SPierre Pronchery if (key != NULL)
128b077aed3SPierre Pronchery return cmac_setkey(macctx, key, keylen);
129b077aed3SPierre Pronchery /* Reinitialize the CMAC context */
130b077aed3SPierre Pronchery return CMAC_Init(macctx->ctx, NULL, 0, NULL, NULL);
131b077aed3SPierre Pronchery }
132b077aed3SPierre Pronchery
cmac_update(void * vmacctx,const unsigned char * data,size_t datalen)133b077aed3SPierre Pronchery static int cmac_update(void *vmacctx, const unsigned char *data,
134b077aed3SPierre Pronchery size_t datalen)
135b077aed3SPierre Pronchery {
136b077aed3SPierre Pronchery struct cmac_data_st *macctx = vmacctx;
137b077aed3SPierre Pronchery
138b077aed3SPierre Pronchery return CMAC_Update(macctx->ctx, data, datalen);
139b077aed3SPierre Pronchery }
140b077aed3SPierre Pronchery
cmac_final(void * vmacctx,unsigned char * out,size_t * outl,size_t outsize)141b077aed3SPierre Pronchery static int cmac_final(void *vmacctx, unsigned char *out, size_t *outl,
142b077aed3SPierre Pronchery size_t outsize)
143b077aed3SPierre Pronchery {
144b077aed3SPierre Pronchery struct cmac_data_st *macctx = vmacctx;
145b077aed3SPierre Pronchery
146b077aed3SPierre Pronchery if (!ossl_prov_is_running())
147b077aed3SPierre Pronchery return 0;
148b077aed3SPierre Pronchery
149b077aed3SPierre Pronchery return CMAC_Final(macctx->ctx, out, outl);
150b077aed3SPierre Pronchery }
151b077aed3SPierre Pronchery
152b077aed3SPierre Pronchery static const OSSL_PARAM known_gettable_ctx_params[] = {
153b077aed3SPierre Pronchery OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
154b077aed3SPierre Pronchery OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE, NULL),
155b077aed3SPierre Pronchery OSSL_PARAM_END
156b077aed3SPierre Pronchery };
cmac_gettable_ctx_params(ossl_unused void * ctx,ossl_unused void * provctx)157b077aed3SPierre Pronchery static const OSSL_PARAM *cmac_gettable_ctx_params(ossl_unused void *ctx,
158b077aed3SPierre Pronchery ossl_unused void *provctx)
159b077aed3SPierre Pronchery {
160b077aed3SPierre Pronchery return known_gettable_ctx_params;
161b077aed3SPierre Pronchery }
162b077aed3SPierre Pronchery
cmac_get_ctx_params(void * vmacctx,OSSL_PARAM params[])163b077aed3SPierre Pronchery static int cmac_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
164b077aed3SPierre Pronchery {
165b077aed3SPierre Pronchery OSSL_PARAM *p;
166b077aed3SPierre Pronchery
167b077aed3SPierre Pronchery if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL
168b077aed3SPierre Pronchery && !OSSL_PARAM_set_size_t(p, cmac_size(vmacctx)))
169b077aed3SPierre Pronchery return 0;
170b077aed3SPierre Pronchery
171b077aed3SPierre Pronchery if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_BLOCK_SIZE)) != NULL
172b077aed3SPierre Pronchery && !OSSL_PARAM_set_size_t(p, cmac_size(vmacctx)))
173b077aed3SPierre Pronchery return 0;
174b077aed3SPierre Pronchery
175b077aed3SPierre Pronchery return 1;
176b077aed3SPierre Pronchery }
177b077aed3SPierre Pronchery
178b077aed3SPierre Pronchery static const OSSL_PARAM known_settable_ctx_params[] = {
179b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER, NULL, 0),
180b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
181b077aed3SPierre Pronchery OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
182b077aed3SPierre Pronchery OSSL_PARAM_END
183b077aed3SPierre Pronchery };
cmac_settable_ctx_params(ossl_unused void * ctx,ossl_unused void * provctx)184b077aed3SPierre Pronchery static const OSSL_PARAM *cmac_settable_ctx_params(ossl_unused void *ctx,
185b077aed3SPierre Pronchery ossl_unused void *provctx)
186b077aed3SPierre Pronchery {
187b077aed3SPierre Pronchery return known_settable_ctx_params;
188b077aed3SPierre Pronchery }
189b077aed3SPierre Pronchery
190b077aed3SPierre Pronchery /*
191b077aed3SPierre Pronchery * ALL parameters should be set before init().
192b077aed3SPierre Pronchery */
cmac_set_ctx_params(void * vmacctx,const OSSL_PARAM params[])193b077aed3SPierre Pronchery static int cmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
194b077aed3SPierre Pronchery {
195b077aed3SPierre Pronchery struct cmac_data_st *macctx = vmacctx;
196b077aed3SPierre Pronchery OSSL_LIB_CTX *ctx = PROV_LIBCTX_OF(macctx->provctx);
197b077aed3SPierre Pronchery const OSSL_PARAM *p;
198b077aed3SPierre Pronchery
199b077aed3SPierre Pronchery if (params == NULL)
200b077aed3SPierre Pronchery return 1;
201b077aed3SPierre Pronchery
202b077aed3SPierre Pronchery if (!ossl_prov_cipher_load_from_params(&macctx->cipher, params, ctx))
203b077aed3SPierre Pronchery return 0;
204b077aed3SPierre Pronchery
205b077aed3SPierre Pronchery if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
206b077aed3SPierre Pronchery if (p->data_type != OSSL_PARAM_OCTET_STRING)
207b077aed3SPierre Pronchery return 0;
208b077aed3SPierre Pronchery return cmac_setkey(macctx, p->data, p->data_size);
209b077aed3SPierre Pronchery }
210b077aed3SPierre Pronchery return 1;
211b077aed3SPierre Pronchery }
212b077aed3SPierre Pronchery
213b077aed3SPierre Pronchery const OSSL_DISPATCH ossl_cmac_functions[] = {
214b077aed3SPierre Pronchery { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))cmac_new },
215b077aed3SPierre Pronchery { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))cmac_dup },
216b077aed3SPierre Pronchery { OSSL_FUNC_MAC_FREECTX, (void (*)(void))cmac_free },
217b077aed3SPierre Pronchery { OSSL_FUNC_MAC_INIT, (void (*)(void))cmac_init },
218b077aed3SPierre Pronchery { OSSL_FUNC_MAC_UPDATE, (void (*)(void))cmac_update },
219b077aed3SPierre Pronchery { OSSL_FUNC_MAC_FINAL, (void (*)(void))cmac_final },
220b077aed3SPierre Pronchery { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
221b077aed3SPierre Pronchery (void (*)(void))cmac_gettable_ctx_params },
222b077aed3SPierre Pronchery { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))cmac_get_ctx_params },
223b077aed3SPierre Pronchery { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
224b077aed3SPierre Pronchery (void (*)(void))cmac_settable_ctx_params },
225b077aed3SPierre Pronchery { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))cmac_set_ctx_params },
226b077aed3SPierre Pronchery { 0, NULL }
227b077aed3SPierre Pronchery };
228