blob: 07f123ee055171435931f8eb0880ead4cbc5ad56 [file] [log] [blame]
Steven Cooreman896d51e2021-03-19 15:24:23 +01001/*
2 * PSA MAC layer on top of Mbed TLS software crypto
3 */
4/*
5 * Copyright The Mbed TLS Contributors
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#include "common.h"
22
23#if defined(MBEDTLS_PSA_CRYPTO_C)
24
25#include <psa/crypto.h>
26#include "psa_crypto_core.h"
Dave Rodgman8e322b12022-11-02 09:25:38 +000027#include "psa_crypto_cipher.h"
Steven Cooreman896d51e2021-03-19 15:24:23 +010028#include "psa_crypto_mac.h"
Steven Cooreman32d56942021-03-19 17:39:17 +010029#include <mbedtls/md.h>
Steven Cooreman896d51e2021-03-19 15:24:23 +010030
31#include <mbedtls/error.h>
32#include <string.h>
33
Ronald Croncfc3c7b2021-03-13 18:50:11 +010034#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Steven Cooreman22dea1d2021-04-29 19:32:25 +020035static psa_status_t psa_hmac_abort_internal(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010036 mbedtls_psa_hmac_operation_t *hmac)
Steven Cooreman32d56942021-03-19 17:39:17 +010037{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010038 mbedtls_platform_zeroize(hmac->opad, sizeof(hmac->opad));
39 return psa_hash_abort(&hmac->hash_ctx);
Steven Cooreman32d56942021-03-19 17:39:17 +010040}
41
Steven Cooreman22dea1d2021-04-29 19:32:25 +020042static psa_status_t psa_hmac_setup_internal(
43 mbedtls_psa_hmac_operation_t *hmac,
44 const uint8_t *key,
45 size_t key_length,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010046 psa_algorithm_t hash_alg)
Steven Cooreman32d56942021-03-19 17:39:17 +010047{
48 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
49 size_t i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010050 size_t hash_size = PSA_HASH_LENGTH(hash_alg);
51 size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
Steven Cooreman32d56942021-03-19 17:39:17 +010052 psa_status_t status;
53
54 hmac->alg = hash_alg;
55
56 /* Sanity checks on block_size, to guarantee that there won't be a buffer
57 * overflow below. This should never trigger if the hash algorithm
58 * is implemented correctly. */
59 /* The size checks against the ipad and opad buffers cannot be written
60 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
61 * because that triggers -Wlogical-op on GCC 7.3. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010062 if (block_size > sizeof(ipad)) {
63 return PSA_ERROR_NOT_SUPPORTED;
64 }
65 if (block_size > sizeof(hmac->opad)) {
66 return PSA_ERROR_NOT_SUPPORTED;
67 }
68 if (block_size < hash_size) {
69 return PSA_ERROR_NOT_SUPPORTED;
70 }
Steven Cooreman32d56942021-03-19 17:39:17 +010071
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010072 if (key_length > block_size) {
73 status = psa_hash_compute(hash_alg, key, key_length,
74 ipad, sizeof(ipad), &key_length);
75 if (status != PSA_SUCCESS) {
Steven Cooreman32d56942021-03-19 17:39:17 +010076 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010077 }
Steven Cooreman32d56942021-03-19 17:39:17 +010078 }
79 /* A 0-length key is not commonly used in HMAC when used as a MAC,
80 * but it is permitted. It is common when HMAC is used in HKDF, for
81 * example. Don't call `memcpy` in the 0-length because `key` could be
82 * an invalid pointer which would make the behavior undefined. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010083 else if (key_length != 0) {
84 memcpy(ipad, key, key_length);
85 }
Steven Cooreman32d56942021-03-19 17:39:17 +010086
87 /* ipad contains the key followed by garbage. Xor and fill with 0x36
88 * to create the ipad value. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010089 for (i = 0; i < key_length; i++) {
Steven Cooreman32d56942021-03-19 17:39:17 +010090 ipad[i] ^= 0x36;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010091 }
92 memset(ipad + key_length, 0x36, block_size - key_length);
Steven Cooreman32d56942021-03-19 17:39:17 +010093
94 /* Copy the key material from ipad to opad, flipping the requisite bits,
95 * and filling the rest of opad with the requisite constant. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010096 for (i = 0; i < key_length; i++) {
Steven Cooreman32d56942021-03-19 17:39:17 +010097 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010098 }
99 memset(hmac->opad + key_length, 0x5C, block_size - key_length);
Steven Cooreman32d56942021-03-19 17:39:17 +0100100
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100101 status = psa_hash_setup(&hmac->hash_ctx, hash_alg);
102 if (status != PSA_SUCCESS) {
Steven Cooreman32d56942021-03-19 17:39:17 +0100103 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100104 }
Steven Cooreman32d56942021-03-19 17:39:17 +0100105
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100106 status = psa_hash_update(&hmac->hash_ctx, ipad, block_size);
Steven Cooreman32d56942021-03-19 17:39:17 +0100107
108cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100109 mbedtls_platform_zeroize(ipad, sizeof(ipad));
Steven Cooreman32d56942021-03-19 17:39:17 +0100110
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100111 return status;
Steven Cooreman32d56942021-03-19 17:39:17 +0100112}
113
Steven Cooreman22dea1d2021-04-29 19:32:25 +0200114static psa_status_t psa_hmac_update_internal(
115 mbedtls_psa_hmac_operation_t *hmac,
116 const uint8_t *data,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100117 size_t data_length)
Steven Cooreman76720f62021-03-22 12:21:10 +0100118{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100119 return psa_hash_update(&hmac->hash_ctx, data, data_length);
Steven Cooreman76720f62021-03-22 12:21:10 +0100120}
121
Steven Cooreman22dea1d2021-04-29 19:32:25 +0200122static psa_status_t psa_hmac_finish_internal(
123 mbedtls_psa_hmac_operation_t *hmac,
124 uint8_t *mac,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100125 size_t mac_size)
Steven Cooreman32d56942021-03-19 17:39:17 +0100126{
Ronald Cron3a95d2b2021-10-18 09:47:58 +0200127 uint8_t tmp[PSA_HASH_MAX_SIZE];
Steven Cooreman32d56942021-03-19 17:39:17 +0100128 psa_algorithm_t hash_alg = hmac->alg;
129 size_t hash_size = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100130 size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
Steven Cooreman32d56942021-03-19 17:39:17 +0100131 psa_status_t status;
132
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100133 status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size);
134 if (status != PSA_SUCCESS) {
135 return status;
136 }
Steven Cooreman32d56942021-03-19 17:39:17 +0100137 /* From here on, tmp needs to be wiped. */
138
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100139 status = psa_hash_setup(&hmac->hash_ctx, hash_alg);
140 if (status != PSA_SUCCESS) {
Steven Cooreman32d56942021-03-19 17:39:17 +0100141 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100142 }
Steven Cooreman32d56942021-03-19 17:39:17 +0100143
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100144 status = psa_hash_update(&hmac->hash_ctx, hmac->opad, block_size);
145 if (status != PSA_SUCCESS) {
Steven Cooreman32d56942021-03-19 17:39:17 +0100146 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100147 }
Steven Cooreman32d56942021-03-19 17:39:17 +0100148
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100149 status = psa_hash_update(&hmac->hash_ctx, tmp, hash_size);
150 if (status != PSA_SUCCESS) {
Steven Cooreman32d56942021-03-19 17:39:17 +0100151 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100152 }
Steven Cooreman32d56942021-03-19 17:39:17 +0100153
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100154 status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size);
155 if (status != PSA_SUCCESS) {
Steven Cooreman32d56942021-03-19 17:39:17 +0100156 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100157 }
Steven Cooreman32d56942021-03-19 17:39:17 +0100158
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100159 memcpy(mac, tmp, mac_size);
Steven Cooreman32d56942021-03-19 17:39:17 +0100160
161exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100162 mbedtls_platform_zeroize(tmp, hash_size);
163 return status;
Steven Cooreman32d56942021-03-19 17:39:17 +0100164}
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100165#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Steven Cooreman07897832021-03-19 18:28:56 +0100166
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100167#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100168static psa_status_t cmac_setup(mbedtls_psa_mac_operation_t *operation,
169 const psa_key_attributes_t *attributes,
170 const uint8_t *key_buffer)
Steven Cooreman07897832021-03-19 18:28:56 +0100171{
172 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooreman63fa40e2021-05-07 17:27:27 +0200173
174#if defined(PSA_WANT_KEY_TYPE_DES)
175 /* Mbed TLS CMAC does not accept 3DES with only two keys, nor does it accept
176 * to do CMAC with pure DES, so return NOT_SUPPORTED here. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100177 if (psa_get_key_type(attributes) == PSA_KEY_TYPE_DES &&
178 (psa_get_key_bits(attributes) == 64 ||
179 psa_get_key_bits(attributes) == 128)) {
180 return PSA_ERROR_NOT_SUPPORTED;
181 }
Steven Cooreman63fa40e2021-05-07 17:27:27 +0200182#endif
183
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100184 const mbedtls_cipher_info_t *cipher_info =
Steven Cooreman07897832021-03-19 18:28:56 +0100185 mbedtls_cipher_info_from_psa(
186 PSA_ALG_CMAC,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100187 psa_get_key_type(attributes),
188 psa_get_key_bits(attributes),
189 NULL);
Steven Cooreman07897832021-03-19 18:28:56 +0100190
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100191 if (cipher_info == NULL) {
192 return PSA_ERROR_NOT_SUPPORTED;
193 }
Steven Cooreman07897832021-03-19 18:28:56 +0100194
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100195 ret = mbedtls_cipher_setup(&operation->ctx.cmac, cipher_info);
196 if (ret != 0) {
Steven Cooreman07897832021-03-19 18:28:56 +0100197 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100198 }
Steven Cooreman07897832021-03-19 18:28:56 +0100199
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100200 ret = mbedtls_cipher_cmac_starts(&operation->ctx.cmac,
201 key_buffer,
202 psa_get_key_bits(attributes));
Steven Cooreman07897832021-03-19 18:28:56 +0100203exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100204 return mbedtls_to_psa_error(ret);
Steven Cooreman07897832021-03-19 18:28:56 +0100205}
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100206#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
Steven Cooreman07897832021-03-19 18:28:56 +0100207
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100208#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || \
209 defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
Steven Cooremanaaf99442021-05-07 15:55:27 +0200210
Steven Cooreman07897832021-03-19 18:28:56 +0100211/* Initialize this driver's MAC operation structure. Once this function has been
212 * called, mbedtls_psa_mac_abort can run and will do the right thing. */
213static psa_status_t mac_init(
214 mbedtls_psa_mac_operation_t *operation,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100215 psa_algorithm_t alg)
Steven Cooreman07897832021-03-19 18:28:56 +0100216{
Steven Cooreman6e6451e2021-04-29 16:21:24 +0200217 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Steven Cooreman07897832021-03-19 18:28:56 +0100218
Steven Cooreman15f0d922021-05-07 14:14:37 +0200219 operation->alg = alg;
Steven Cooreman07897832021-03-19 18:28:56 +0100220
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100221#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100222 if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
223 mbedtls_cipher_init(&operation->ctx.cmac);
Steven Cooreman07897832021-03-19 18:28:56 +0100224 status = PSA_SUCCESS;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100225 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100226#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
227#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100228 if (PSA_ALG_IS_HMAC(operation->alg)) {
Steven Cooreman07897832021-03-19 18:28:56 +0100229 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
230 operation->ctx.hmac.alg = 0;
231 status = PSA_SUCCESS;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100232 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100233#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Steven Cooreman07897832021-03-19 18:28:56 +0100234 {
Ronald Cron485559e2021-04-28 14:29:00 +0200235 (void) operation;
Steven Cooreman6e6451e2021-04-29 16:21:24 +0200236 status = PSA_ERROR_NOT_SUPPORTED;
Steven Cooreman07897832021-03-19 18:28:56 +0100237 }
238
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100239 if (status != PSA_SUCCESS) {
240 memset(operation, 0, sizeof(*operation));
241 }
242 return status;
Steven Cooreman07897832021-03-19 18:28:56 +0100243}
244
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100245psa_status_t mbedtls_psa_mac_abort(mbedtls_psa_mac_operation_t *operation)
Steven Cooreman07897832021-03-19 18:28:56 +0100246{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100247 if (operation->alg == 0) {
Steven Cooreman07897832021-03-19 18:28:56 +0100248 /* The object has (apparently) been initialized but it is not
249 * in use. It's ok to call abort on such an object, and there's
250 * nothing to do. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100251 return PSA_SUCCESS;
252 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100253#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100254 if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
255 mbedtls_cipher_free(&operation->ctx.cmac);
256 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100257#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
258#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100259 if (PSA_ALG_IS_HMAC(operation->alg)) {
260 psa_hmac_abort_internal(&operation->ctx.hmac);
261 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100262#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Steven Cooreman07897832021-03-19 18:28:56 +0100263 {
264 /* Sanity check (shouldn't happen: operation->alg should
265 * always have been initialized to a valid value). */
266 goto bad_state;
267 }
268
269 operation->alg = 0;
Steven Cooreman07897832021-03-19 18:28:56 +0100270
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100271 return PSA_SUCCESS;
Steven Cooreman07897832021-03-19 18:28:56 +0100272
273bad_state:
274 /* If abort is called on an uninitialized object, we can't trust
275 * anything. Wipe the object in case it contains confidential data.
276 * This may result in a memory leak if a pointer gets overwritten,
277 * but it's too late to do anything about this. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100278 memset(operation, 0, sizeof(*operation));
279 return PSA_ERROR_BAD_STATE;
Steven Cooreman07897832021-03-19 18:28:56 +0100280}
281
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100282static psa_status_t psa_mac_setup(mbedtls_psa_mac_operation_t *operation,
283 const psa_key_attributes_t *attributes,
284 const uint8_t *key_buffer,
285 size_t key_buffer_size,
286 psa_algorithm_t alg)
Steven Cooreman07897832021-03-19 18:28:56 +0100287{
288 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
289
290 /* A context must be freshly initialized before it can be set up. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100291 if (operation->alg != 0) {
292 return PSA_ERROR_BAD_STATE;
293 }
Steven Cooreman07897832021-03-19 18:28:56 +0100294
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100295 status = mac_init(operation, alg);
296 if (status != PSA_SUCCESS) {
297 return status;
298 }
Steven Cooreman07897832021-03-19 18:28:56 +0100299
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100300#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100301 if (PSA_ALG_FULL_LENGTH_MAC(alg) == PSA_ALG_CMAC) {
Steven Cooremanaf81a712021-05-06 18:00:37 +0200302 /* Key buffer size for CMAC is dictated by the key bits set on the
303 * attributes, and previously validated by the core on key import. */
304 (void) key_buffer_size;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100305 status = cmac_setup(operation, attributes, key_buffer);
306 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100307#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
308#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100309 if (PSA_ALG_IS_HMAC(alg)) {
310 status = psa_hmac_setup_internal(&operation->ctx.hmac,
311 key_buffer,
312 key_buffer_size,
313 PSA_ALG_HMAC_GET_HASH(alg));
314 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100315#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Steven Cooreman07897832021-03-19 18:28:56 +0100316 {
Steven Cooreman9621f442021-05-10 09:47:05 +0200317 (void) attributes;
318 (void) key_buffer;
319 (void) key_buffer_size;
Steven Cooreman07897832021-03-19 18:28:56 +0100320 status = PSA_ERROR_NOT_SUPPORTED;
321 }
322
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100323 if (status != PSA_SUCCESS) {
324 mbedtls_psa_mac_abort(operation);
325 }
Steven Cooreman07897832021-03-19 18:28:56 +0100326
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100327 return status;
Steven Cooreman07897832021-03-19 18:28:56 +0100328}
329
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100330psa_status_t mbedtls_psa_mac_sign_setup(
331 mbedtls_psa_mac_operation_t *operation,
332 const psa_key_attributes_t *attributes,
333 const uint8_t *key_buffer,
334 size_t key_buffer_size,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100335 psa_algorithm_t alg)
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100336{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100337 return psa_mac_setup(operation, attributes,
338 key_buffer, key_buffer_size, alg);
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100339}
340
341psa_status_t mbedtls_psa_mac_verify_setup(
342 mbedtls_psa_mac_operation_t *operation,
343 const psa_key_attributes_t *attributes,
344 const uint8_t *key_buffer,
345 size_t key_buffer_size,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100346 psa_algorithm_t alg)
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100347{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100348 return psa_mac_setup(operation, attributes,
349 key_buffer, key_buffer_size, alg);
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100350}
351
352psa_status_t mbedtls_psa_mac_update(
Steven Cooreman896d51e2021-03-19 15:24:23 +0100353 mbedtls_psa_mac_operation_t *operation,
354 const uint8_t *input,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100355 size_t input_length)
Steven Cooreman896d51e2021-03-19 15:24:23 +0100356{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100357 if (operation->alg == 0) {
358 return PSA_ERROR_BAD_STATE;
359 }
Steven Cooreman11743f92021-03-19 18:38:46 +0100360
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100361#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362 if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
363 return mbedtls_to_psa_error(
364 mbedtls_cipher_cmac_update(&operation->ctx.cmac,
365 input, input_length));
366 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100367#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
368#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369 if (PSA_ALG_IS_HMAC(operation->alg)) {
370 return psa_hmac_update_internal(&operation->ctx.hmac,
371 input, input_length);
372 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100373#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Steven Cooreman11743f92021-03-19 18:38:46 +0100374 {
375 /* This shouldn't happen if `operation` was initialized by
376 * a setup function. */
Steven Cooreman9621f442021-05-10 09:47:05 +0200377 (void) input;
378 (void) input_length;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100379 return PSA_ERROR_BAD_STATE;
Steven Cooreman11743f92021-03-19 18:38:46 +0100380 }
Steven Cooreman896d51e2021-03-19 15:24:23 +0100381}
382
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100383static psa_status_t psa_mac_finish_internal(
384 mbedtls_psa_mac_operation_t *operation,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 uint8_t *mac, size_t mac_size)
Steven Cooreman87885df2021-03-19 19:04:39 +0100386{
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100387#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100388 if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
Steven Cooreman87885df2021-03-19 19:04:39 +0100389 uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 int ret = mbedtls_cipher_cmac_finish(&operation->ctx.cmac, tmp);
391 if (ret == 0) {
392 memcpy(mac, tmp, mac_size);
393 }
394 mbedtls_platform_zeroize(tmp, sizeof(tmp));
395 return mbedtls_to_psa_error(ret);
396 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100397#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
398#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100399 if (PSA_ALG_IS_HMAC(operation->alg)) {
400 return psa_hmac_finish_internal(&operation->ctx.hmac,
401 mac, mac_size);
402 } else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100403#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
Steven Cooreman87885df2021-03-19 19:04:39 +0100404 {
405 /* This shouldn't happen if `operation` was initialized by
406 * a setup function. */
Steven Cooreman15f0d922021-05-07 14:14:37 +0200407 (void) operation;
408 (void) mac;
409 (void) mac_size;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100410 return PSA_ERROR_BAD_STATE;
Steven Cooreman87885df2021-03-19 19:04:39 +0100411 }
412}
413
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100414psa_status_t mbedtls_psa_mac_sign_finish(
Steven Cooreman896d51e2021-03-19 15:24:23 +0100415 mbedtls_psa_mac_operation_t *operation,
416 uint8_t *mac,
417 size_t mac_size,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100418 size_t *mac_length)
Steven Cooreman896d51e2021-03-19 15:24:23 +0100419{
Steven Cooreman9878a162021-05-06 17:58:36 +0200420 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Steven Cooreman87885df2021-03-19 19:04:39 +0100421
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 if (operation->alg == 0) {
423 return PSA_ERROR_BAD_STATE;
424 }
Steven Cooreman87885df2021-03-19 19:04:39 +0100425
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100426 status = psa_mac_finish_internal(operation, mac, mac_size);
427 if (status == PSA_SUCCESS) {
Steven Cooreman15f0d922021-05-07 14:14:37 +0200428 *mac_length = mac_size;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100429 }
Steven Cooreman87885df2021-03-19 19:04:39 +0100430
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 return status;
Steven Cooreman87885df2021-03-19 19:04:39 +0100432}
433
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100434psa_status_t mbedtls_psa_mac_verify_finish(
Steven Cooreman896d51e2021-03-19 15:24:23 +0100435 mbedtls_psa_mac_operation_t *operation,
436 const uint8_t *mac,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100437 size_t mac_length)
Steven Cooreman896d51e2021-03-19 15:24:23 +0100438{
Steven Cooreman87885df2021-03-19 19:04:39 +0100439 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Steven Cooreman9878a162021-05-06 17:58:36 +0200440 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Steven Cooreman87885df2021-03-19 19:04:39 +0100441
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100442 if (operation->alg == 0) {
443 return PSA_ERROR_BAD_STATE;
444 }
Steven Cooreman87885df2021-03-19 19:04:39 +0100445
Steven Cooreman15f0d922021-05-07 14:14:37 +0200446 /* Consistency check: requested MAC length fits our local buffer */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100447 if (mac_length > sizeof(actual_mac)) {
448 return PSA_ERROR_INVALID_ARGUMENT;
449 }
Steven Cooreman87885df2021-03-19 19:04:39 +0100450
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100451 status = psa_mac_finish_internal(operation, actual_mac, mac_length);
452 if (status != PSA_SUCCESS) {
Steven Cooreman87885df2021-03-19 19:04:39 +0100453 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100454 }
Steven Cooreman87885df2021-03-19 19:04:39 +0100455
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100456 if (mbedtls_psa_safer_memcmp(mac, actual_mac, mac_length) != 0) {
Steven Cooreman87885df2021-03-19 19:04:39 +0100457 status = PSA_ERROR_INVALID_SIGNATURE;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100458 }
Steven Cooreman87885df2021-03-19 19:04:39 +0100459
460cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100461 mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac));
Steven Cooreman87885df2021-03-19 19:04:39 +0100462
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100463 return status;
Steven Cooreman896d51e2021-03-19 15:24:23 +0100464}
Ronald Cronbfdfaa62021-06-17 17:34:43 +0200465
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100466psa_status_t mbedtls_psa_mac_compute(
Ronald Cronbfdfaa62021-06-17 17:34:43 +0200467 const psa_key_attributes_t *attributes,
468 const uint8_t *key_buffer,
469 size_t key_buffer_size,
470 psa_algorithm_t alg,
471 const uint8_t *input,
472 size_t input_length,
473 uint8_t *mac,
474 size_t mac_size,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100475 size_t *mac_length)
Ronald Cronbfdfaa62021-06-17 17:34:43 +0200476{
477 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
478 mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT;
479
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100480 status = psa_mac_setup(&operation,
481 attributes, key_buffer, key_buffer_size,
482 alg);
483 if (status != PSA_SUCCESS) {
Ronald Cronbfdfaa62021-06-17 17:34:43 +0200484 goto exit;
Ronald Cronbfdfaa62021-06-17 17:34:43 +0200485 }
486
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487 if (input_length > 0) {
488 status = mbedtls_psa_mac_update(&operation, input, input_length);
489 if (status != PSA_SUCCESS) {
490 goto exit;
491 }
492 }
493
494 status = psa_mac_finish_internal(&operation, mac, mac_size);
495 if (status == PSA_SUCCESS) {
Ronald Cronbfdfaa62021-06-17 17:34:43 +0200496 *mac_length = mac_size;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497 }
Ronald Cronbfdfaa62021-06-17 17:34:43 +0200498
499exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100500 mbedtls_psa_mac_abort(&operation);
Ronald Cronbfdfaa62021-06-17 17:34:43 +0200501
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100502 return status;
Ronald Cronbfdfaa62021-06-17 17:34:43 +0200503}
504
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100505#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || MBEDTLS_PSA_BUILTIN_ALG_CMAC */
Steven Cooreman896d51e2021-03-19 15:24:23 +0100506
507#endif /* MBEDTLS_PSA_CRYPTO_C */