2 * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved.
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
11 * CMAC low level APIs are deprecated for public use, but still ok for internal
14 #include "internal/deprecated.h"
16 #include <openssl/core_dispatch.h>
17 #include <openssl/core_names.h>
18 #include <openssl/params.h>
19 #include <openssl/evp.h>
20 #include <openssl/cmac.h>
21 #include <openssl/err.h>
22 #include <openssl/proverr.h>
24 #include "prov/implementations.h"
25 #include "prov/provider_ctx.h"
26 #include "prov/provider_util.h"
27 #include "prov/providercommon.h"
30 * Forward declaration of everything implemented here. This is not strictly
31 * necessary for the compiler, but provides an assurance that the signatures
32 * of the functions in the dispatch table are correct.
34 static OSSL_FUNC_mac_newctx_fn cmac_new
;
35 static OSSL_FUNC_mac_dupctx_fn cmac_dup
;
36 static OSSL_FUNC_mac_freectx_fn cmac_free
;
37 static OSSL_FUNC_mac_gettable_ctx_params_fn cmac_gettable_ctx_params
;
38 static OSSL_FUNC_mac_get_ctx_params_fn cmac_get_ctx_params
;
39 static OSSL_FUNC_mac_settable_ctx_params_fn cmac_settable_ctx_params
;
40 static OSSL_FUNC_mac_set_ctx_params_fn cmac_set_ctx_params
;
41 static OSSL_FUNC_mac_init_fn cmac_init
;
42 static OSSL_FUNC_mac_update_fn cmac_update
;
43 static OSSL_FUNC_mac_final_fn cmac_final
;
53 static void *cmac_new(void *provctx
)
55 struct cmac_data_st
*macctx
;
57 if (!ossl_prov_is_running())
60 if ((macctx
= OPENSSL_zalloc(sizeof(*macctx
))) == NULL
61 || (macctx
->ctx
= CMAC_CTX_new()) == NULL
) {
65 macctx
->provctx
= provctx
;
71 static void cmac_free(void *vmacctx
)
73 struct cmac_data_st
*macctx
= vmacctx
;
76 CMAC_CTX_free(macctx
->ctx
);
77 ossl_prov_cipher_reset(&macctx
->cipher
);
82 static void *cmac_dup(void *vsrc
)
84 struct cmac_data_st
*src
= vsrc
;
85 struct cmac_data_st
*dst
;
87 if (!ossl_prov_is_running())
90 dst
= cmac_new(src
->provctx
);
93 if (!CMAC_CTX_copy(dst
->ctx
, src
->ctx
)
94 || !ossl_prov_cipher_copy(&dst
->cipher
, &src
->cipher
)) {
101 static size_t cmac_size(void *vmacctx
)
103 struct cmac_data_st
*macctx
= vmacctx
;
105 return EVP_CIPHER_CTX_get_block_size(CMAC_CTX_get0_cipher_ctx(macctx
->ctx
));
108 static int cmac_setkey(struct cmac_data_st
*macctx
,
109 const unsigned char *key
, size_t keylen
)
111 int rv
= CMAC_Init(macctx
->ctx
, key
, keylen
,
112 ossl_prov_cipher_cipher(&macctx
->cipher
),
113 ossl_prov_cipher_engine(&macctx
->cipher
));
114 ossl_prov_cipher_reset(&macctx
->cipher
);
118 static int cmac_init(void *vmacctx
, const unsigned char *key
,
119 size_t keylen
, const OSSL_PARAM params
[])
121 struct cmac_data_st
*macctx
= vmacctx
;
123 if (!ossl_prov_is_running() || !cmac_set_ctx_params(macctx
, params
))
126 return cmac_setkey(macctx
, key
, keylen
);
127 /* Reinitialize the CMAC context */
128 return CMAC_Init(macctx
->ctx
, NULL
, 0, NULL
, NULL
);
131 static int cmac_update(void *vmacctx
, const unsigned char *data
,
134 struct cmac_data_st
*macctx
= vmacctx
;
136 return CMAC_Update(macctx
->ctx
, data
, datalen
);
139 static int cmac_final(void *vmacctx
, unsigned char *out
, size_t *outl
,
142 struct cmac_data_st
*macctx
= vmacctx
;
144 if (!ossl_prov_is_running())
147 return CMAC_Final(macctx
->ctx
, out
, outl
);
150 static const OSSL_PARAM known_gettable_ctx_params
[] = {
151 OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE
, NULL
),
152 OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE
, NULL
),
155 static const OSSL_PARAM
*cmac_gettable_ctx_params(ossl_unused
void *ctx
,
156 ossl_unused
void *provctx
)
158 return known_gettable_ctx_params
;
161 static int cmac_get_ctx_params(void *vmacctx
, OSSL_PARAM params
[])
165 if ((p
= OSSL_PARAM_locate(params
, OSSL_MAC_PARAM_SIZE
)) != NULL
166 && !OSSL_PARAM_set_size_t(p
, cmac_size(vmacctx
)))
169 if ((p
= OSSL_PARAM_locate(params
, OSSL_MAC_PARAM_BLOCK_SIZE
)) != NULL
170 && !OSSL_PARAM_set_size_t(p
, cmac_size(vmacctx
)))
176 static const OSSL_PARAM known_settable_ctx_params
[] = {
177 OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER
, NULL
, 0),
178 OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES
, NULL
, 0),
179 OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY
, NULL
, 0),
182 static const OSSL_PARAM
*cmac_settable_ctx_params(ossl_unused
void *ctx
,
183 ossl_unused
void *provctx
)
185 return known_settable_ctx_params
;
189 * ALL parameters should be set before init().
191 static int cmac_set_ctx_params(void *vmacctx
, const OSSL_PARAM params
[])
193 struct cmac_data_st
*macctx
= vmacctx
;
194 OSSL_LIB_CTX
*ctx
= PROV_LIBCTX_OF(macctx
->provctx
);
200 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_MAC_PARAM_CIPHER
)) != NULL
) {
201 if (!ossl_prov_cipher_load_from_params(&macctx
->cipher
, params
, ctx
))
204 if (EVP_CIPHER_get_mode(ossl_prov_cipher_cipher(&macctx
->cipher
))
205 != EVP_CIPH_CBC_MODE
) {
206 ERR_raise(ERR_LIB_PROV
, PROV_R_INVALID_MODE
);
211 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_MAC_PARAM_KEY
)) != NULL
) {
212 if (p
->data_type
!= OSSL_PARAM_OCTET_STRING
)
214 return cmac_setkey(macctx
, p
->data
, p
->data_size
);
219 const OSSL_DISPATCH ossl_cmac_functions
[] = {
220 { OSSL_FUNC_MAC_NEWCTX
, (void (*)(void))cmac_new
},
221 { OSSL_FUNC_MAC_DUPCTX
, (void (*)(void))cmac_dup
},
222 { OSSL_FUNC_MAC_FREECTX
, (void (*)(void))cmac_free
},
223 { OSSL_FUNC_MAC_INIT
, (void (*)(void))cmac_init
},
224 { OSSL_FUNC_MAC_UPDATE
, (void (*)(void))cmac_update
},
225 { OSSL_FUNC_MAC_FINAL
, (void (*)(void))cmac_final
},
226 { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS
,
227 (void (*)(void))cmac_gettable_ctx_params
},
228 { OSSL_FUNC_MAC_GET_CTX_PARAMS
, (void (*)(void))cmac_get_ctx_params
},
229 { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS
,
230 (void (*)(void))cmac_settable_ctx_params
},
231 { OSSL_FUNC_MAC_SET_CTX_PARAMS
, (void (*)(void))cmac_set_ctx_params
},