blob: f6da7d947ffe69fe785ed778c8adaa4c6f3ae6ab [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
Bence Szépkúti86974652020-06-15 11:59:37 +02004/*
Bence Szépkúti1e148272020-08-07 13:07:28 +02005 * Copyright The Mbed TLS Contributors
Gilles Peskinee59236f2018-01-27 23:32:46 +01006 * 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.
Gilles Peskinee59236f2018-01-27 23:32:46 +010019 */
20
Gilles Peskinedb09ef62020-06-03 01:43:33 +020021#include "common.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010022
23#if defined(MBEDTLS_PSA_CRYPTO_C)
mohammad160327010052018-07-03 13:16:15 +030024
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020025# if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
26# include "check_crypto_config.h"
27# endif
John Durkop07cc04a2020-11-16 22:08:34 -080028
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020029# include "psa/crypto.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010030
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020031# include "psa_crypto_cipher.h"
32# include "psa_crypto_core.h"
33# include "psa_crypto_invasive.h"
34# include "psa_crypto_driver_wrappers.h"
35# include "psa_crypto_ecp.h"
36# include "psa_crypto_hash.h"
37# include "psa_crypto_mac.h"
38# include "psa_crypto_rsa.h"
39# include "psa_crypto_ecp.h"
40# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
41# include "psa_crypto_se.h"
42# endif
43# include "psa_crypto_slot_management.h"
Darryl Greend49a4992018-06-18 17:27:26 +010044/* Include internal declarations that are useful for implementing persistently
45 * stored keys. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020046# include "psa_crypto_storage.h"
Darryl Greend49a4992018-06-18 17:27:26 +010047
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020048# include "psa_crypto_random_impl.h"
Gilles Peskine90edc992020-11-13 15:39:19 +010049
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020050# include <assert.h>
51# include <stdlib.h>
52# include <string.h>
53# include "mbedtls/platform.h"
54# if !defined(MBEDTLS_PLATFORM_C)
55# define mbedtls_calloc calloc
56# define mbedtls_free free
57# endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010058
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020059# include "mbedtls/aes.h"
60# include "mbedtls/asn1.h"
61# include "mbedtls/asn1write.h"
62# include "mbedtls/bignum.h"
63# include "mbedtls/camellia.h"
64# include "mbedtls/chacha20.h"
65# include "mbedtls/chachapoly.h"
66# include "mbedtls/cipher.h"
67# include "mbedtls/ccm.h"
68# include "mbedtls/cmac.h"
69# include "mbedtls/des.h"
70# include "mbedtls/ecdh.h"
71# include "mbedtls/ecp.h"
72# include "mbedtls/entropy.h"
73# include "mbedtls/error.h"
74# include "mbedtls/gcm.h"
75# include "mbedtls/md5.h"
76# include "mbedtls/md.h"
77# include "md_wrap.h"
78# include "mbedtls/pk.h"
79# include "pk_wrap.h"
80# include "mbedtls/platform_util.h"
81# include "mbedtls/error.h"
82# include "mbedtls/ripemd160.h"
83# include "mbedtls/rsa.h"
84# include "mbedtls/sha1.h"
85# include "mbedtls/sha256.h"
86# include "mbedtls/sha512.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010087
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020088# define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array)))
Gilles Peskine996deb12018-08-01 15:45:45 +020089
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010090/****************************************************************/
91/* Global data, support functions and library management */
92/****************************************************************/
93
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020094static int key_type_is_raw_bytes(psa_key_type_t type)
Gilles Peskine48c0ea12018-06-21 14:15:31 +020095{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020096 return PSA_KEY_TYPE_IS_UNSTRUCTURED(type);
Gilles Peskine48c0ea12018-06-21 14:15:31 +020097}
98
Gilles Peskine5a3c50e2018-12-04 12:27:09 +010099/* Values for psa_global_data_t::rng_state */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200100# define RNG_NOT_INITIALIZED 0
101# define RNG_INITIALIZED 1
102# define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100103
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200104typedef struct {
Gilles Peskine30524eb2020-11-13 17:02:26 +0100105 mbedtls_psa_random_context_t rng;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100106 unsigned initialized : 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200107 unsigned rng_state : 2;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100108} psa_global_data_t;
109
110static psa_global_data_t global_data;
111
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200112# if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100113mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state =
114 &global_data.rng.drbg;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200115# endif
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100116
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200117# define GUARD_MODULE_INITIALIZED \
118 if (global_data.initialized == 0) \
119 return PSA_ERROR_BAD_STATE;
itayzafrir0adf0fc2018-09-06 16:24:41 +0300120
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200121psa_status_t mbedtls_to_psa_error(int ret)
Gilles Peskinee59236f2018-01-27 23:32:46 +0100122{
Gilles Peskinedbf68962021-01-06 20:04:23 +0100123 /* Mbed TLS error codes can combine a high-level error code and a
124 * low-level error code. The low-level error usually reflects the
125 * root cause better, so dispatch on that preferably. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200126 int low_level_ret = -(-ret & 0x007f);
127 switch (low_level_ret != 0 ? low_level_ret : ret) {
Gilles Peskinee59236f2018-01-27 23:32:46 +0100128 case 0:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200129 return PSA_SUCCESS;
Gilles Peskinea5905292018-02-07 20:59:33 +0100130
131 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
132 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200133 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine9a944802018-06-21 09:35:35 +0200134 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
135 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
136 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
137 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
138 case MBEDTLS_ERR_ASN1_INVALID_DATA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200139 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine9a944802018-06-21 09:35:35 +0200140 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200141 return PSA_ERROR_INSUFFICIENT_MEMORY;
Gilles Peskine9a944802018-06-21 09:35:35 +0200142 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200143 return PSA_ERROR_BUFFER_TOO_SMALL;
Gilles Peskine9a944802018-06-21 09:35:35 +0200144
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200145# if defined(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000146 case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200147# endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100148 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200149 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinea5905292018-02-07 20:59:33 +0100150
151 case MBEDTLS_ERR_CCM_BAD_INPUT:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200152 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea5905292018-02-07 20:59:33 +0100153 case MBEDTLS_ERR_CCM_AUTH_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200154 return PSA_ERROR_INVALID_SIGNATURE;
Gilles Peskinea5905292018-02-07 20:59:33 +0100155
Gilles Peskine26869f22019-05-06 15:25:00 +0200156 case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200157 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine26869f22019-05-06 15:25:00 +0200158
159 case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200160 return PSA_ERROR_BAD_STATE;
Gilles Peskine26869f22019-05-06 15:25:00 +0200161 case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200162 return PSA_ERROR_INVALID_SIGNATURE;
Gilles Peskine26869f22019-05-06 15:25:00 +0200163
Gilles Peskinea5905292018-02-07 20:59:33 +0100164 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200165 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinea5905292018-02-07 20:59:33 +0100166 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200167 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea5905292018-02-07 20:59:33 +0100168 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200169 return PSA_ERROR_INSUFFICIENT_MEMORY;
Gilles Peskinea5905292018-02-07 20:59:33 +0100170 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200171 return PSA_ERROR_INVALID_PADDING;
Gilles Peskinea5905292018-02-07 20:59:33 +0100172 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200173 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea5905292018-02-07 20:59:33 +0100174 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200175 return PSA_ERROR_INVALID_SIGNATURE;
Gilles Peskinea5905292018-02-07 20:59:33 +0100176 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200177 return PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea5905292018-02-07 20:59:33 +0100178
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200179# if !(defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) || \
180 defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE))
Gilles Peskinebee96c82020-11-23 21:00:09 +0100181 /* Only check CTR_DRBG error codes if underlying mbedtls_xxx
182 * functions are passed a CTR_DRBG instance. */
Gilles Peskinea5905292018-02-07 20:59:33 +0100183 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200184 return PSA_ERROR_INSUFFICIENT_ENTROPY;
Gilles Peskinea5905292018-02-07 20:59:33 +0100185 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
186 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200187 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinea5905292018-02-07 20:59:33 +0100188 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200189 return PSA_ERROR_INSUFFICIENT_ENTROPY;
190# endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100191
192 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200193 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinea5905292018-02-07 20:59:33 +0100194
Gilles Peskinee59236f2018-01-27 23:32:46 +0100195 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
196 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
197 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200198 return PSA_ERROR_INSUFFICIENT_ENTROPY;
Gilles Peskinea5905292018-02-07 20:59:33 +0100199
200 case MBEDTLS_ERR_GCM_AUTH_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200201 return PSA_ERROR_INVALID_SIGNATURE;
Gilles Peskinea5905292018-02-07 20:59:33 +0100202 case MBEDTLS_ERR_GCM_BAD_INPUT:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200203 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea5905292018-02-07 20:59:33 +0100204
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200205# if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \
206 defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
Gilles Peskinebee96c82020-11-23 21:00:09 +0100207 /* Only check HMAC_DRBG error codes if underlying mbedtls_xxx
208 * functions are passed a HMAC_DRBG instance. */
Gilles Peskine82e57d12020-11-13 21:31:17 +0100209 case MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200210 return PSA_ERROR_INSUFFICIENT_ENTROPY;
Gilles Peskine82e57d12020-11-13 21:31:17 +0100211 case MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG:
212 case MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200213 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine82e57d12020-11-13 21:31:17 +0100214 case MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200215 return PSA_ERROR_INSUFFICIENT_ENTROPY;
216# endif
Gilles Peskine82e57d12020-11-13 21:31:17 +0100217
Gilles Peskinea5905292018-02-07 20:59:33 +0100218 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200219 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinea5905292018-02-07 20:59:33 +0100220 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200221 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea5905292018-02-07 20:59:33 +0100222 case MBEDTLS_ERR_MD_ALLOC_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200223 return PSA_ERROR_INSUFFICIENT_MEMORY;
Gilles Peskinea5905292018-02-07 20:59:33 +0100224 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200225 return PSA_ERROR_STORAGE_FAILURE;
Gilles Peskinea5905292018-02-07 20:59:33 +0100226
Gilles Peskinef76aa772018-10-29 19:24:33 +0100227 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200228 return PSA_ERROR_STORAGE_FAILURE;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100229 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200230 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100231 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200232 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100233 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200234 return PSA_ERROR_BUFFER_TOO_SMALL;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100235 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200236 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100237 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200238 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100239 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200240 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100241 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200242 return PSA_ERROR_INSUFFICIENT_MEMORY;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100243
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100244 case MBEDTLS_ERR_PK_ALLOC_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200245 return PSA_ERROR_INSUFFICIENT_MEMORY;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100246 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
247 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200248 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100249 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200250 return PSA_ERROR_STORAGE_FAILURE;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100251 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
252 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200253 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100254 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200255 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100256 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
257 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200258 return PSA_ERROR_NOT_PERMITTED;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100259 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200260 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100261 case MBEDTLS_ERR_PK_INVALID_ALG:
262 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
263 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200264 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100265 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200266 return PSA_ERROR_INVALID_SIGNATURE;
Gilles Peskinef9f1bdf2021-06-23 20:32:27 +0200267 case MBEDTLS_ERR_PK_BUFFER_TOO_SMALL:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200268 return PSA_ERROR_BUFFER_TOO_SMALL;
Gilles Peskinea5905292018-02-07 20:59:33 +0100269
Gilles Peskineff2d2002019-05-06 15:26:23 +0200270 case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200271 return PSA_ERROR_HARDWARE_FAILURE;
Gilles Peskineff2d2002019-05-06 15:26:23 +0200272 case MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200273 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskineff2d2002019-05-06 15:26:23 +0200274
Gilles Peskinea5905292018-02-07 20:59:33 +0100275 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200276 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea5905292018-02-07 20:59:33 +0100277 case MBEDTLS_ERR_RSA_INVALID_PADDING:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200278 return PSA_ERROR_INVALID_PADDING;
Gilles Peskinea5905292018-02-07 20:59:33 +0100279 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200280 return PSA_ERROR_HARDWARE_FAILURE;
Gilles Peskinea5905292018-02-07 20:59:33 +0100281 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200282 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea5905292018-02-07 20:59:33 +0100283 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
284 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200285 return PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea5905292018-02-07 20:59:33 +0100286 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200287 return PSA_ERROR_INVALID_SIGNATURE;
Gilles Peskinea5905292018-02-07 20:59:33 +0100288 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200289 return PSA_ERROR_BUFFER_TOO_SMALL;
Gilles Peskinea5905292018-02-07 20:59:33 +0100290 case MBEDTLS_ERR_RSA_RNG_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200291 return PSA_ERROR_INSUFFICIENT_ENTROPY;
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200292
itayzafrir5c753392018-05-08 11:18:38 +0300293 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300294 case MBEDTLS_ERR_ECP_INVALID_KEY:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200295 return PSA_ERROR_INVALID_ARGUMENT;
itayzafrir7b30f8b2018-05-09 16:07:36 +0300296 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200297 return PSA_ERROR_BUFFER_TOO_SMALL;
itayzafrir7b30f8b2018-05-09 16:07:36 +0300298 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200299 return PSA_ERROR_NOT_SUPPORTED;
itayzafrir7b30f8b2018-05-09 16:07:36 +0300300 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
301 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200302 return PSA_ERROR_INVALID_SIGNATURE;
itayzafrir7b30f8b2018-05-09 16:07:36 +0300303 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200304 return PSA_ERROR_INSUFFICIENT_MEMORY;
Gilles Peskine40d81602020-11-25 00:09:47 +0100305 case MBEDTLS_ERR_ECP_RANDOM_FAILED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200306 return PSA_ERROR_INSUFFICIENT_ENTROPY;
Gilles Peskine40d81602020-11-25 00:09:47 +0100307
Janos Follatha13b9052019-11-22 12:48:59 +0000308 case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200309 return PSA_ERROR_CORRUPTION_DETECTED;
itayzafrir5c753392018-05-08 11:18:38 +0300310
Gilles Peskinee59236f2018-01-27 23:32:46 +0100311 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200312 return PSA_ERROR_GENERIC_ERROR;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100313 }
314}
315
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100316/****************************************************************/
317/* Key management */
318/****************************************************************/
319
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200320# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
321static inline int psa_key_slot_is_external(const psa_key_slot_t *slot)
Gilles Peskine73167e12019-07-12 23:44:37 +0200322{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200323 return psa_key_lifetime_is_external(slot->attr.lifetime);
Gilles Peskine73167e12019-07-12 23:44:37 +0200324}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200325# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine73167e12019-07-12 23:44:37 +0200326
John Durkop07cc04a2020-11-16 22:08:34 -0800327/* For now the MBEDTLS_PSA_ACCEL_ guards are also used here since the
328 * current test driver in key_management.c is using this function
329 * when accelerators are used for ECC key pair and public key.
330 * Once that dependency is resolved these guards can be removed.
331 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200332# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
333 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
334 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
335 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
336mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
337 size_t bits,
338 int bits_is_sloppy)
Gilles Peskine12313cd2018-06-20 00:20:32 +0200339{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200340 switch (curve) {
Paul Elliott8ff510a2020-06-02 17:19:28 +0100341 case PSA_ECC_FAMILY_SECP_R1:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200342 switch (bits) {
343# if defined(PSA_WANT_ECC_SECP_R1_192)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100344 case 192:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200345 return MBEDTLS_ECP_DP_SECP192R1;
346# endif
347# if defined(PSA_WANT_ECC_SECP_R1_224)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100348 case 224:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200349 return MBEDTLS_ECP_DP_SECP224R1;
350# endif
351# if defined(PSA_WANT_ECC_SECP_R1_256)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100352 case 256:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200353 return MBEDTLS_ECP_DP_SECP256R1;
354# endif
355# if defined(PSA_WANT_ECC_SECP_R1_384)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100356 case 384:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200357 return MBEDTLS_ECP_DP_SECP384R1;
358# endif
359# if defined(PSA_WANT_ECC_SECP_R1_521)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100360 case 521:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200361 return MBEDTLS_ECP_DP_SECP521R1;
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100362 case 528:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200363 if (bits_is_sloppy)
364 return MBEDTLS_ECP_DP_SECP521R1;
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100365 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200366# endif
Gilles Peskine228abc52019-12-03 17:24:19 +0100367 }
368 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100369
Paul Elliott8ff510a2020-06-02 17:19:28 +0100370 case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200371 switch (bits) {
372# if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100373 case 256:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200374 return MBEDTLS_ECP_DP_BP256R1;
375# endif
376# if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100377 case 384:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200378 return MBEDTLS_ECP_DP_BP384R1;
379# endif
380# if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100381 case 512:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200382 return MBEDTLS_ECP_DP_BP512R1;
383# endif
Gilles Peskine228abc52019-12-03 17:24:19 +0100384 }
385 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100386
Paul Elliott8ff510a2020-06-02 17:19:28 +0100387 case PSA_ECC_FAMILY_MONTGOMERY:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200388 switch (bits) {
389# if defined(PSA_WANT_ECC_MONTGOMERY_255)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100390 case 255:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200391 return MBEDTLS_ECP_DP_CURVE25519;
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100392 case 256:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200393 if (bits_is_sloppy)
394 return MBEDTLS_ECP_DP_CURVE25519;
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100395 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200396# endif
397# if defined(PSA_WANT_ECC_MONTGOMERY_448)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100398 case 448:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200399 return MBEDTLS_ECP_DP_CURVE448;
400# endif
Gilles Peskine228abc52019-12-03 17:24:19 +0100401 }
402 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100403
Paul Elliott8ff510a2020-06-02 17:19:28 +0100404 case PSA_ECC_FAMILY_SECP_K1:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200405 switch (bits) {
406# if defined(PSA_WANT_ECC_SECP_K1_192)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100407 case 192:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200408 return MBEDTLS_ECP_DP_SECP192K1;
409# endif
410# if defined(PSA_WANT_ECC_SECP_K1_224)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100411 case 224:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200412 return MBEDTLS_ECP_DP_SECP224K1;
413# endif
414# if defined(PSA_WANT_ECC_SECP_K1_256)
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100415 case 256:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200416 return MBEDTLS_ECP_DP_SECP256K1;
417# endif
Gilles Peskine228abc52019-12-03 17:24:19 +0100418 }
419 break;
Gilles Peskine12313cd2018-06-20 00:20:32 +0200420 }
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100421
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200422 (void)bits_is_sloppy;
423 return MBEDTLS_ECP_DP_NONE;
Gilles Peskine12313cd2018-06-20 00:20:32 +0200424}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200425# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
426 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
427 * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
428 * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200429
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200430static psa_status_t validate_unstructured_key_bit_size(psa_key_type_t type,
431 size_t bits)
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200432{
433 /* Check that the bit size is acceptable for the key type */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200434 switch (type) {
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200435 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200436 case PSA_KEY_TYPE_HMAC:
Gilles Peskineea0fb492018-07-12 17:17:20 +0200437 case PSA_KEY_TYPE_DERIVE:
438 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200439# if defined(PSA_WANT_KEY_TYPE_AES)
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200440 case PSA_KEY_TYPE_AES:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200441 if (bits != 128 && bits != 192 && bits != 256)
442 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200443 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200444# endif
445# if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200446 case PSA_KEY_TYPE_CAMELLIA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200447 if (bits != 128 && bits != 192 && bits != 256)
448 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200449 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200450# endif
451# if defined(PSA_WANT_KEY_TYPE_DES)
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200452 case PSA_KEY_TYPE_DES:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200453 if (bits != 64 && bits != 128 && bits != 192)
454 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200455 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200456# endif
457# if defined(PSA_WANT_KEY_TYPE_CHACHA20)
Gilles Peskine26869f22019-05-06 15:25:00 +0200458 case PSA_KEY_TYPE_CHACHA20:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200459 if (bits != 256)
460 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine26869f22019-05-06 15:25:00 +0200461 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200462# endif
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200463 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200464 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200465 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200466 if (bits % 8 != 0)
467 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200468
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200469 return PSA_SUCCESS;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200470}
471
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100472/** Check whether a given key type is valid for use with a given MAC algorithm
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100473 *
Steven Cooremancd640932021-03-08 12:00:27 +0100474 * Upon successful return of this function, the behavior of #PSA_MAC_LENGTH
475 * when called with the validated \p algorithm and \p key_type is well-defined.
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100476 *
477 * \param[in] algorithm The specific MAC algorithm (can be wildcard).
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100478 * \param[in] key_type The key type of the key to be used with the
479 * \p algorithm.
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100480 *
481 * \retval #PSA_SUCCESS
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100482 * The \p key_type is valid for use with the \p algorithm
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100483 * \retval #PSA_ERROR_INVALID_ARGUMENT
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100484 * The \p key_type is not valid for use with the \p algorithm
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100485 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200486MBEDTLS_STATIC_TESTABLE psa_status_t
487psa_mac_key_can_do(psa_algorithm_t algorithm, psa_key_type_t key_type)
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100488{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200489 if (PSA_ALG_IS_HMAC(algorithm)) {
490 if (key_type == PSA_KEY_TYPE_HMAC)
491 return PSA_SUCCESS;
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100492 }
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100493
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200494 if (PSA_ALG_IS_BLOCK_CIPHER_MAC(algorithm)) {
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100495 /* Check that we're calling PSA_BLOCK_CIPHER_BLOCK_LENGTH with a cipher
496 * key. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200497 if ((key_type & PSA_KEY_TYPE_CATEGORY_MASK) ==
498 PSA_KEY_TYPE_CATEGORY_SYMMETRIC) {
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100499 /* PSA_BLOCK_CIPHER_BLOCK_LENGTH returns 1 for stream ciphers and
500 * the block length (larger than 1) for block ciphers. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200501 if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1)
502 return PSA_SUCCESS;
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100503 }
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100504 }
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100505
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200506 return PSA_ERROR_INVALID_ARGUMENT;
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100507}
508
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200509psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot,
510 size_t buffer_length)
Steven Cooreman75b74362020-07-28 14:30:13 +0200511{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200512 if (slot->key.data != NULL)
513 return PSA_ERROR_ALREADY_EXISTS;
Steven Cooreman75b74362020-07-28 14:30:13 +0200514
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200515 slot->key.data = mbedtls_calloc(1, buffer_length);
516 if (slot->key.data == NULL)
517 return PSA_ERROR_INSUFFICIENT_MEMORY;
Steven Cooreman75b74362020-07-28 14:30:13 +0200518
Ronald Cronea0f8a62020-11-25 17:52:23 +0100519 slot->key.bytes = buffer_length;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200520 return PSA_SUCCESS;
Steven Cooreman75b74362020-07-28 14:30:13 +0200521}
522
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200523psa_status_t psa_copy_key_material_into_slot(psa_key_slot_t *slot,
524 const uint8_t *data,
525 size_t data_length)
Steven Cooremanf7cebd42020-10-13 20:27:40 +0200526{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200527 psa_status_t status = psa_allocate_buffer_to_slot(slot, data_length);
528 if (status != PSA_SUCCESS)
529 return status;
Steven Cooremanf7cebd42020-10-13 20:27:40 +0200530
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200531 memcpy(slot->key.data, data, data_length);
532 return PSA_SUCCESS;
Steven Cooremanf7cebd42020-10-13 20:27:40 +0200533}
534
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200535psa_status_t psa_import_key_into_slot(const psa_key_attributes_t *attributes,
536 const uint8_t *data,
537 size_t data_length,
538 uint8_t *key_buffer,
539 size_t key_buffer_size,
540 size_t *key_buffer_length,
541 size_t *bits)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100542{
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100543 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
544 psa_key_type_t type = attributes->core.type;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100545
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200546 /* zero-length keys are never supported. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200547 if (data_length == 0)
548 return PSA_ERROR_NOT_SUPPORTED;
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200549
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200550 if (key_type_is_raw_bytes(type)) {
551 *bits = PSA_BYTES_TO_BITS(data_length);
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200552
Steven Cooreman75b74362020-07-28 14:30:13 +0200553 /* Ensure that the bytes-to-bits conversion hasn't overflown. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200554 if (data_length > SIZE_MAX / 8)
555 return PSA_ERROR_NOT_SUPPORTED;
Steven Cooreman75b74362020-07-28 14:30:13 +0200556
Gilles Peskine1b9505c2019-08-07 10:59:45 +0200557 /* Enforce a size limit, and in particular ensure that the bit
558 * size fits in its representation type. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200559 if ((*bits) > PSA_MAX_KEY_BITS)
560 return PSA_ERROR_NOT_SUPPORTED;
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200561
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200562 status = validate_unstructured_key_bit_size(type, *bits);
563 if (status != PSA_SUCCESS)
564 return status;
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200565
Ronald Crondd04d422020-11-28 15:14:42 +0100566 /* Copy the key material. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200567 memcpy(key_buffer, data, data_length);
Ronald Crondd04d422020-11-28 15:14:42 +0100568 *key_buffer_length = data_length;
569 (void)key_buffer_size;
Steven Cooreman81be2fa2020-07-24 22:04:59 +0200570
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200571 return PSA_SUCCESS;
572 } else if (PSA_KEY_TYPE_IS_ASYMMETRIC(type)) {
573# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
574 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
575 if (PSA_KEY_TYPE_IS_ECC(type)) {
576 return (mbedtls_psa_ecp_import_key(attributes, data, data_length,
577 key_buffer, key_buffer_size,
578 key_buffer_length, bits));
Steven Cooreman40120f62020-10-29 11:42:22 +0100579 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200580# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
581 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
582# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
583 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
584 if (PSA_KEY_TYPE_IS_RSA(type)) {
585 return (mbedtls_psa_rsa_import_key(attributes, data, data_length,
586 key_buffer, key_buffer_size,
587 key_buffer_length, bits));
Steven Cooreman3ea0ce42020-10-23 11:37:05 +0200588 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200589# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
590 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Ronald Cron2ebfdcc2020-11-28 15:54:54 +0100591 }
Steven Cooreman40120f62020-10-29 11:42:22 +0100592
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200593 return PSA_ERROR_NOT_SUPPORTED;
Darryl Green06fd18d2018-07-16 11:21:11 +0100594}
595
Gilles Peskinef603c712019-01-19 13:40:11 +0100596/** Calculate the intersection of two algorithm usage policies.
597 *
598 * Return 0 (which allows no operation) on incompatibility.
599 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200600static psa_algorithm_t
601psa_key_policy_algorithm_intersection(psa_key_type_t key_type,
602 psa_algorithm_t alg1,
603 psa_algorithm_t alg2)
Gilles Peskinef603c712019-01-19 13:40:11 +0100604{
Gilles Peskine549ea862019-05-22 11:45:59 +0200605 /* Common case: both sides actually specify the same policy. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200606 if (alg1 == alg2)
607 return alg1;
Steven Cooreman03488022021-02-18 12:07:20 +0100608 /* If the policies are from the same hash-and-sign family, check
609 * if one is a wildcard. If so the other has the specific algorithm. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200610 if (PSA_ALG_IS_HASH_AND_SIGN(alg1) && PSA_ALG_IS_HASH_AND_SIGN(alg2) &&
611 (alg1 & ~PSA_ALG_HASH_MASK) == (alg2 & ~PSA_ALG_HASH_MASK)) {
612 if (PSA_ALG_SIGN_GET_HASH(alg1) == PSA_ALG_ANY_HASH)
613 return alg2;
614 if (PSA_ALG_SIGN_GET_HASH(alg2) == PSA_ALG_ANY_HASH)
615 return alg1;
Steven Cooreman03488022021-02-18 12:07:20 +0100616 }
617 /* If the policies are from the same AEAD family, check whether
Steven Cooreman7de9e2d2021-02-22 17:05:56 +0100618 * one of them is a minimum-tag-length wildcard. Calculate the most
Steven Cooreman03488022021-02-18 12:07:20 +0100619 * restrictive tag length. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200620 if (PSA_ALG_IS_AEAD(alg1) && PSA_ALG_IS_AEAD(alg2) &&
621 (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg1, 0) ==
622 PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg2, 0))) {
623 size_t alg1_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg1);
624 size_t alg2_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg2);
Steven Cooremancd640932021-03-08 12:00:27 +0100625 size_t restricted_len = alg1_len > alg2_len ? alg1_len : alg2_len;
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100626
Steven Cooreman7de9e2d2021-02-22 17:05:56 +0100627 /* If both are wildcards, return most restrictive wildcard */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200628 if (((alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) &&
629 ((alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0)) {
630 return (PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(alg1,
631 restricted_len));
Steven Cooreman03488022021-02-18 12:07:20 +0100632 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200633 /* If only one is a wildcard, return specific algorithm if compatible.
634 */
635 if (((alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) &&
636 (alg1_len <= alg2_len)) {
637 return alg2;
Steven Cooreman03488022021-02-18 12:07:20 +0100638 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200639 if (((alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) &&
640 (alg2_len <= alg1_len)) {
641 return alg1;
Steven Cooreman03488022021-02-18 12:07:20 +0100642 }
643 }
644 /* If the policies are from the same MAC family, check whether one
645 * of them is a minimum-MAC-length policy. Calculate the most
646 * restrictive tag length. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200647 if (PSA_ALG_IS_MAC(alg1) && PSA_ALG_IS_MAC(alg2) &&
648 (PSA_ALG_FULL_LENGTH_MAC(alg1) == PSA_ALG_FULL_LENGTH_MAC(alg2))) {
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100649 /* Validate the combination of key type and algorithm. Since the base
650 * algorithm of alg1 and alg2 are the same, we only need this once. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200651 if (PSA_SUCCESS != psa_mac_key_can_do(alg1, key_type))
652 return 0;
Steven Cooreman1ac5ce32021-03-02 16:34:49 +0100653
Steven Cooreman31a876d2021-03-03 20:47:40 +0100654 /* Get the (exact or at-least) output lengths for both sides of the
655 * requested intersection. None of the currently supported algorithms
656 * have an output length dependent on the actual key size, so setting it
657 * to a bogus value of 0 is currently OK.
658 *
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100659 * Note that for at-least-this-length wildcard algorithms, the output
660 * length is set to the shortest allowed length, which allows us to
661 * calculate the most restrictive tag length for the intersection. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200662 size_t alg1_len = PSA_MAC_LENGTH(key_type, 0, alg1);
663 size_t alg2_len = PSA_MAC_LENGTH(key_type, 0, alg2);
Steven Cooremancd640932021-03-08 12:00:27 +0100664 size_t restricted_len = alg1_len > alg2_len ? alg1_len : alg2_len;
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100665
Steven Cooremana1d83222021-02-25 10:20:29 +0100666 /* If both are wildcards, return most restrictive wildcard */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200667 if (((alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) &&
668 ((alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0)) {
669 return PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(alg1, restricted_len);
Steven Cooreman03488022021-02-18 12:07:20 +0100670 }
Steven Cooreman31a876d2021-03-03 20:47:40 +0100671
672 /* If only one is an at-least-this-length policy, the intersection would
673 * be the other (fixed-length) policy as long as said fixed length is
674 * equal to or larger than the shortest allowed length. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200675 if ((alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) {
676 return (alg1_len <= alg2_len) ? alg2 : 0;
Steven Cooreman03488022021-02-18 12:07:20 +0100677 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200678 if ((alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) {
679 return (alg2_len <= alg1_len) ? alg1 : 0;
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100680 }
Steven Cooreman31a876d2021-03-03 20:47:40 +0100681
Steven Cooremancd640932021-03-08 12:00:27 +0100682 /* If none of them are wildcards, check whether they define the same tag
683 * length. This is still possible here when one is default-length and
684 * the other specific-length. Ensure to always return the
685 * specific-length version for the intersection. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200686 if (alg1_len == alg2_len)
687 return PSA_ALG_TRUNCATED_MAC(alg1, alg1_len);
Gilles Peskinef603c712019-01-19 13:40:11 +0100688 }
689 /* If the policies are incompatible, allow nothing. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200690 return 0;
Gilles Peskinef603c712019-01-19 13:40:11 +0100691}
692
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200693static int psa_key_algorithm_permits(psa_key_type_t key_type,
694 psa_algorithm_t policy_alg,
695 psa_algorithm_t requested_alg)
Gilles Peskined6f371b2019-05-10 19:33:38 +0200696{
Gilles Peskine549ea862019-05-22 11:45:59 +0200697 /* Common case: the policy only allows requested_alg. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200698 if (requested_alg == policy_alg)
699 return 1;
Steven Cooreman03488022021-02-18 12:07:20 +0100700 /* If policy_alg is a hash-and-sign with a wildcard for the hash,
701 * and requested_alg is the same hash-and-sign family with any hash,
702 * then requested_alg is compliant with policy_alg. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200703 if (PSA_ALG_IS_HASH_AND_SIGN(requested_alg) &&
704 PSA_ALG_SIGN_GET_HASH(policy_alg) == PSA_ALG_ANY_HASH) {
705 return ((policy_alg & ~PSA_ALG_HASH_MASK) ==
706 (requested_alg & ~PSA_ALG_HASH_MASK));
Steven Cooreman03488022021-02-18 12:07:20 +0100707 }
708 /* If policy_alg is a wildcard AEAD algorithm of the same base as
709 * the requested algorithm, check the requested tag length to be
710 * equal-length or longer than the wildcard-specified length. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200711 if (PSA_ALG_IS_AEAD(policy_alg) && PSA_ALG_IS_AEAD(requested_alg) &&
712 (PSA_ALG_AEAD_WITH_SHORTENED_TAG(policy_alg, 0) ==
713 PSA_ALG_AEAD_WITH_SHORTENED_TAG(requested_alg, 0)) &&
714 ((policy_alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0)) {
715 return (PSA_ALG_AEAD_GET_TAG_LENGTH(policy_alg) <=
716 PSA_ALG_AEAD_GET_TAG_LENGTH(requested_alg));
Steven Cooreman03488022021-02-18 12:07:20 +0100717 }
Steven Cooremancd640932021-03-08 12:00:27 +0100718 /* If policy_alg is a MAC algorithm of the same base as the requested
719 * algorithm, check whether their MAC lengths are compatible. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200720 if (PSA_ALG_IS_MAC(policy_alg) && PSA_ALG_IS_MAC(requested_alg) &&
721 (PSA_ALG_FULL_LENGTH_MAC(policy_alg) ==
722 PSA_ALG_FULL_LENGTH_MAC(requested_alg))) {
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100723 /* Validate the combination of key type and algorithm. Since the policy
724 * and requested algorithms are the same, we only need this once. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200725 if (PSA_SUCCESS != psa_mac_key_can_do(policy_alg, key_type))
726 return 0;
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +0100727
Steven Cooreman31a876d2021-03-03 20:47:40 +0100728 /* Get both the requested output length for the algorithm which is to be
729 * verified, and the default output length for the base algorithm.
730 * Note that none of the currently supported algorithms have an output
731 * length dependent on actual key size, so setting it to a bogus value
732 * of 0 is currently OK. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200733 size_t requested_output_length =
734 PSA_MAC_LENGTH(key_type, 0, requested_alg);
735 size_t default_output_length =
736 PSA_MAC_LENGTH(key_type, 0, PSA_ALG_FULL_LENGTH_MAC(requested_alg));
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100737
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100738 /* If the policy is default-length, only allow an algorithm with
739 * a declared exact-length matching the default. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200740 if (PSA_MAC_TRUNCATED_LENGTH(policy_alg) == 0)
741 return requested_output_length == default_output_length;
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100742
743 /* If the requested algorithm is default-length, allow it if the policy
Steven Cooremancd640932021-03-08 12:00:27 +0100744 * length exactly matches the default length. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200745 if (PSA_MAC_TRUNCATED_LENGTH(requested_alg) == 0 &&
746 PSA_MAC_TRUNCATED_LENGTH(policy_alg) == default_output_length) {
747 return 1;
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100748 }
749
Steven Cooremancd640932021-03-08 12:00:27 +0100750 /* If policy_alg is an at-least-this-length wildcard MAC algorithm,
751 * check for the requested MAC length to be equal to or longer than the
752 * minimum allowed length. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200753 if ((policy_alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) {
754 return (PSA_MAC_TRUNCATED_LENGTH(policy_alg) <=
755 requested_output_length);
Steven Cooreman5ad4bf72021-03-02 15:11:57 +0100756 }
Gilles Peskined6f371b2019-05-10 19:33:38 +0200757 }
Steven Cooremance48e852020-10-05 16:02:45 +0200758 /* If policy_alg is a generic key agreement operation, then using it for
Steven Cooremanfa5e6312020-10-15 17:07:12 +0200759 * a key derivation with that key agreement should also be allowed. This
760 * behaviour is expected to be defined in a future specification version. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200761 if (PSA_ALG_IS_RAW_KEY_AGREEMENT(policy_alg) &&
762 PSA_ALG_IS_KEY_AGREEMENT(requested_alg)) {
763 return (PSA_ALG_KEY_AGREEMENT_GET_BASE(requested_alg) == policy_alg);
Steven Cooremance48e852020-10-05 16:02:45 +0200764 }
Steven Cooremanb3ce8152021-02-18 12:03:50 +0100765 /* If it isn't explicitly permitted, it's forbidden. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200766 return 0;
Gilles Peskined6f371b2019-05-10 19:33:38 +0200767}
768
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100769/** Test whether a policy permits an algorithm.
770 *
771 * The caller must test usage flags separately.
Steven Cooreman7e39f052021-02-23 14:18:32 +0100772 *
Steven Cooreman5a172672021-03-02 21:27:42 +0100773 * \note This function requires providing the key type for which the policy is
774 * being validated, since some algorithm policy definitions (e.g. MAC)
775 * have different properties depending on what kind of cipher it is
776 * combined with.
777 *
Steven Cooreman7e39f052021-02-23 14:18:32 +0100778 * \retval PSA_SUCCESS When \p alg is a specific algorithm
779 * allowed by the \p policy.
780 * \retval PSA_ERROR_INVALID_ARGUMENT When \p alg is not a specific algorithm
781 * \retval PSA_ERROR_NOT_PERMITTED When \p alg is a specific algorithm, but
782 * the \p policy does not allow it.
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100783 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200784static psa_status_t psa_key_policy_permits(const psa_key_policy_t *policy,
785 psa_key_type_t key_type,
786 psa_algorithm_t alg)
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100787{
Steven Cooremand788fab2021-02-25 11:29:17 +0100788 /* '0' is not a valid algorithm */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200789 if (alg == 0)
790 return PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremand788fab2021-02-25 11:29:17 +0100791
Steven Cooreman7e39f052021-02-23 14:18:32 +0100792 /* A requested algorithm cannot be a wildcard. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200793 if (PSA_ALG_IS_WILDCARD(alg))
794 return PSA_ERROR_INVALID_ARGUMENT;
Steven Cooreman7e39f052021-02-23 14:18:32 +0100795
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200796 if (psa_key_algorithm_permits(key_type, policy->alg, alg) ||
797 psa_key_algorithm_permits(key_type, policy->alg2, alg))
798 return PSA_SUCCESS;
Steven Cooreman7e39f052021-02-23 14:18:32 +0100799 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200800 return PSA_ERROR_NOT_PERMITTED;
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100801}
802
Gilles Peskinef603c712019-01-19 13:40:11 +0100803/** Restrict a key policy based on a constraint.
804 *
Steven Cooreman5a172672021-03-02 21:27:42 +0100805 * \note This function requires providing the key type for which the policy is
806 * being restricted, since some algorithm policy definitions (e.g. MAC)
807 * have different properties depending on what kind of cipher it is
808 * combined with.
809 *
Steven Cooreman1ac5ce32021-03-02 16:34:49 +0100810 * \param[in] key_type The key type for which to restrict the policy
Gilles Peskinef603c712019-01-19 13:40:11 +0100811 * \param[in,out] policy The policy to restrict.
812 * \param[in] constraint The policy constraint to apply.
813 *
814 * \retval #PSA_SUCCESS
815 * \c *policy contains the intersection of the original value of
816 * \c *policy and \c *constraint.
817 * \retval #PSA_ERROR_INVALID_ARGUMENT
Steven Cooreman1ac5ce32021-03-02 16:34:49 +0100818 * \c key_type, \c *policy and \c *constraint are incompatible.
Gilles Peskinef603c712019-01-19 13:40:11 +0100819 * \c *policy is unchanged.
820 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200821static psa_status_t psa_restrict_key_policy(psa_key_type_t key_type,
822 psa_key_policy_t *policy,
823 const psa_key_policy_t *constraint)
Gilles Peskinef603c712019-01-19 13:40:11 +0100824{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200825 psa_algorithm_t intersection_alg = psa_key_policy_algorithm_intersection(
826 key_type, policy->alg, constraint->alg);
827 psa_algorithm_t intersection_alg2 = psa_key_policy_algorithm_intersection(
828 key_type, policy->alg2, constraint->alg2);
829 if (intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0)
830 return PSA_ERROR_INVALID_ARGUMENT;
831 if (intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0)
832 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinef603c712019-01-19 13:40:11 +0100833 policy->usage &= constraint->usage;
834 policy->alg = intersection_alg;
Gilles Peskined6f371b2019-05-10 19:33:38 +0200835 policy->alg2 = intersection_alg2;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200836 return PSA_SUCCESS;
Gilles Peskinef603c712019-01-19 13:40:11 +0100837}
838
Ronald Cron5c522922020-11-14 16:35:34 +0100839/** Get the description of a key given its identifier and policy constraints
840 * and lock it.
Ronald Cronf95a2b12020-10-22 15:24:49 +0200841 *
Ronald Cron5c522922020-11-14 16:35:34 +0100842 * The key must have allow all the usage flags set in \p usage. If \p alg is
Steven Cooremand788fab2021-02-25 11:29:17 +0100843 * nonzero, the key must allow operations with this algorithm. If \p alg is
844 * zero, the algorithm is not checked.
Ronald Cron7587ae42020-11-11 15:04:25 +0100845 *
Ronald Cron5c522922020-11-14 16:35:34 +0100846 * In case of a persistent key, the function loads the description of the key
847 * into a key slot if not already done.
848 *
849 * On success, the returned key slot is locked. It is the responsibility of
850 * the caller to unlock the key slot when it does not access it anymore.
Ronald Cronf95a2b12020-10-22 15:24:49 +0200851 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200852static psa_status_t
853psa_get_and_lock_key_slot_with_policy(mbedtls_svc_key_id_t key,
854 psa_key_slot_t **p_slot,
855 psa_key_usage_t usage,
856 psa_algorithm_t alg)
Darryl Green06fd18d2018-07-16 11:21:11 +0100857{
Ronald Cronf95a2b12020-10-22 15:24:49 +0200858 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
859 psa_key_slot_t *slot;
Darryl Green06fd18d2018-07-16 11:21:11 +0100860
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200861 status = psa_get_and_lock_key_slot(key, p_slot);
862 if (status != PSA_SUCCESS)
863 return status;
Ronald Cronf95a2b12020-10-22 15:24:49 +0200864 slot = *p_slot;
Darryl Green06fd18d2018-07-16 11:21:11 +0100865
866 /* Enforce that usage policy for the key slot contains all the flags
867 * required by the usage parameter. There is one exception: public
868 * keys can always be exported, so we treat public key objects as
869 * if they had the export flag. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200870 if (PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type))
Darryl Green06fd18d2018-07-16 11:21:11 +0100871 usage &= ~PSA_KEY_USAGE_EXPORT;
Ronald Cronf95a2b12020-10-22 15:24:49 +0200872
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200873 if ((slot->attr.policy.usage & usage) != usage) {
Steven Cooreman328f11c2021-03-02 11:44:51 +0100874 status = PSA_ERROR_NOT_PERMITTED;
Ronald Cronf95a2b12020-10-22 15:24:49 +0200875 goto error;
Steven Cooreman328f11c2021-03-02 11:44:51 +0100876 }
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100877
878 /* Enforce that the usage policy permits the requested algortihm. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200879 if (alg != 0) {
880 status =
881 psa_key_policy_permits(&slot->attr.policy, slot->attr.type, alg);
882 if (status != PSA_SUCCESS)
Steven Cooreman7e39f052021-02-23 14:18:32 +0100883 goto error;
884 }
Darryl Green06fd18d2018-07-16 11:21:11 +0100885
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200886 return PSA_SUCCESS;
Ronald Cronf95a2b12020-10-22 15:24:49 +0200887
888error:
889 *p_slot = NULL;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200890 psa_unlock_key_slot(slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +0200891
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200892 return status;
Darryl Green06fd18d2018-07-16 11:21:11 +0100893}
Darryl Green940d72c2018-07-13 13:18:51 +0100894
Ronald Cron5c522922020-11-14 16:35:34 +0100895/** Get a key slot containing a transparent key and lock it.
Gilles Peskine28f8f302019-07-24 13:30:31 +0200896 *
897 * A transparent key is a key for which the key material is directly
898 * available, as opposed to a key in a secure element.
899 *
Ronald Cron5c522922020-11-14 16:35:34 +0100900 * This is a temporary function to use instead of
901 * psa_get_and_lock_key_slot_with_policy() until secure element support is
902 * fully implemented.
Ronald Cronf95a2b12020-10-22 15:24:49 +0200903 *
Ronald Cron5c522922020-11-14 16:35:34 +0100904 * On success, the returned key slot is locked. It is the responsibility of the
905 * caller to unlock the key slot when it does not access it anymore.
Gilles Peskine28f8f302019-07-24 13:30:31 +0200906 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200907# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
908static psa_status_t
909psa_get_and_lock_transparent_key_slot_with_policy(mbedtls_svc_key_id_t key,
910 psa_key_slot_t **p_slot,
911 psa_key_usage_t usage,
912 psa_algorithm_t alg)
Gilles Peskine28f8f302019-07-24 13:30:31 +0200913{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200914 psa_status_t status =
915 psa_get_and_lock_key_slot_with_policy(key, p_slot, usage, alg);
916 if (status != PSA_SUCCESS)
917 return status;
Ronald Cronf95a2b12020-10-22 15:24:49 +0200918
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200919 if (psa_key_slot_is_external(*p_slot)) {
920 psa_unlock_key_slot(*p_slot);
Gilles Peskine28f8f302019-07-24 13:30:31 +0200921 *p_slot = NULL;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200922 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine28f8f302019-07-24 13:30:31 +0200923 }
Ronald Cronf95a2b12020-10-22 15:24:49 +0200924
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200925 return PSA_SUCCESS;
Gilles Peskine28f8f302019-07-24 13:30:31 +0200926}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200927# else /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine28f8f302019-07-24 13:30:31 +0200928/* With no secure element support, all keys are transparent. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200929# define psa_get_and_lock_transparent_key_slot_with_policy(key, p_slot, \
930 usage, alg) \
931 psa_get_and_lock_key_slot_with_policy(key, p_slot, usage, alg)
932# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine28f8f302019-07-24 13:30:31 +0200933
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200934psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot)
Darryl Green40225ba2018-11-15 14:48:15 +0000935{
Ronald Cronea0f8a62020-11-25 17:52:23 +0100936 /* Data pointer will always be either a valid pointer or NULL in an
937 * initialized slot, so we can just free it. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200938 if (slot->key.data != NULL)
939 mbedtls_platform_zeroize(slot->key.data, slot->key.bytes);
Ronald Cronea0f8a62020-11-25 17:52:23 +0100940
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200941 mbedtls_free(slot->key.data);
Ronald Cronea0f8a62020-11-25 17:52:23 +0100942 slot->key.data = NULL;
943 slot->key.bytes = 0;
Darryl Green40225ba2018-11-15 14:48:15 +0000944
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200945 return PSA_SUCCESS;
Darryl Green40225ba2018-11-15 14:48:15 +0000946}
947
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100948/** Completely wipe a slot in memory, including its policy.
949 * Persistent storage is not affected. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200950psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot)
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100951{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200952 psa_status_t status = psa_remove_key_data_from_memory(slot);
Ronald Cronddd3d052020-10-30 14:07:07 +0100953
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200954 /*
955 * As the return error code may not be handled in case of multiple errors,
956 * do our best to report an unexpected lock counter. Assert with
957 * MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is equal to one:
958 * if the MBEDTLS_TEST_HOOKS configuration option is enabled and the
959 * function is called as part of the execution of a test suite, the
960 * execution of the test suite is stopped in error if the assertion fails.
961 */
962 if (slot->lock_count != 1) {
963 MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->lock_count == 1);
Ronald Cronddd3d052020-10-30 14:07:07 +0100964 status = PSA_ERROR_CORRUPTION_DETECTED;
965 }
966
Gilles Peskine3f7cd622019-08-13 15:01:08 +0200967 /* Multipart operations may still be using the key. This is safe
968 * because all multipart operation objects are independent from
969 * the key slot: if they need to access the key after the setup
970 * phase, they have a copy of the key. Note that this means that
971 * key material can linger until all operations are completed. */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100972 /* At this point, key material and other type-specific content has
973 * been wiped. Clear remaining metadata. We can call memset and not
974 * zeroize because the metadata is not particularly sensitive. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200975 memset(slot, 0, sizeof(*slot));
976 return status;
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100977}
978
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200979psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100980{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100981 psa_key_slot_t *slot;
Gilles Peskine4b7f3402019-08-13 15:58:36 +0200982 psa_status_t status; /* status of the last operation */
983 psa_status_t overall_status = PSA_SUCCESS;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200984# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine354f7672019-07-12 23:46:38 +0200985 psa_se_drv_table_entry_t *driver;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200986# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100987
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200988 if (mbedtls_svc_key_id_is_null(key))
989 return PSA_SUCCESS;
Gilles Peskine1841cf42019-10-08 15:48:25 +0200990
Ronald Cronf2911112020-10-29 17:51:10 +0100991 /*
Ronald Cron19daca92020-11-10 18:08:03 +0100992 * Get the description of the key in a key slot. In case of a persistent
Ronald Cronf2911112020-10-29 17:51:10 +0100993 * key, this will load the key description from persistent memory if not
994 * done yet. We cannot avoid this loading as without it we don't know if
995 * the key is operated by an SE or not and this information is needed by
996 * the current implementation.
997 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200998 status = psa_get_and_lock_key_slot(key, &slot);
999 if (status != PSA_SUCCESS)
1000 return status;
Gilles Peskine354f7672019-07-12 23:46:38 +02001001
Ronald Cronf2911112020-10-29 17:51:10 +01001002 /*
1003 * If the key slot containing the key description is under access by the
1004 * library (apart from the present access), the key cannot be destroyed
1005 * yet. For the time being, just return in error. Eventually (to be
1006 * implemented), the key should be destroyed when all accesses have
1007 * stopped.
1008 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001009 if (slot->lock_count > 1) {
1010 psa_unlock_key_slot(slot);
1011 return PSA_ERROR_GENERIC_ERROR;
Ronald Cronf2911112020-10-29 17:51:10 +01001012 }
1013
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001014 if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) {
Gilles Peskine6687cd02021-04-21 22:32:05 +02001015 /* Refuse the destruction of a read-only key (which may or may not work
1016 * if we attempt it, depending on whether the key is merely read-only
1017 * by policy or actually physically read-only).
Gilles Peskinef9a046e2021-06-07 23:27:54 +02001018 * Just do the best we can, which is to wipe the copy in memory
1019 * (done in this function's cleanup code). */
1020 overall_status = PSA_ERROR_NOT_PERMITTED;
1021 goto exit;
Gilles Peskine6687cd02021-04-21 22:32:05 +02001022 }
1023
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001024# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1025 driver = psa_get_se_driver_entry(slot->attr.lifetime);
1026 if (driver != NULL) {
Gilles Peskine60450a42019-07-25 11:32:45 +02001027 /* For a key in a secure element, we need to do three things:
1028 * remove the key file in internal storage, destroy the
1029 * key inside the secure element, and update the driver's
1030 * persistent data. Start a transaction that will encompass these
1031 * three actions. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001032 psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_DESTROY_KEY);
Gilles Peskine8e338702019-07-30 20:06:31 +02001033 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001034 psa_crypto_transaction.key.slot = psa_key_slot_get_slot_number(slot);
Gilles Peskine8e338702019-07-30 20:06:31 +02001035 psa_crypto_transaction.key.id = slot->attr.id;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001036 status = psa_crypto_save_transaction();
1037 if (status != PSA_SUCCESS) {
1038 (void)psa_crypto_stop_transaction();
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001039 /* We should still try to destroy the key in the secure
1040 * element and the key metadata in storage. This is especially
1041 * important if the error is that the storage is full.
1042 * But how to do it exactly without risking an inconsistent
1043 * state after a reset?
1044 * https://github.com/ARMmbed/mbed-crypto/issues/215
1045 */
1046 overall_status = status;
1047 goto exit;
Gilles Peskinefc762652019-07-22 19:30:34 +02001048 }
1049
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001050 status = psa_destroy_se_key(driver, psa_key_slot_get_slot_number(slot));
1051 if (overall_status == PSA_SUCCESS)
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001052 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001053 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001054# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine354f7672019-07-12 23:46:38 +02001055
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001056# if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
1057 if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
1058 status = psa_destroy_persistent_key(slot->attr.id);
1059 if (overall_status == PSA_SUCCESS)
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001060 overall_status = status;
1061
Gilles Peskine9ce31c42019-08-13 15:14:20 +02001062 /* TODO: other slots may have a copy of the same key. We should
1063 * invalidate them.
1064 * https://github.com/ARMmbed/mbed-crypto/issues/214
1065 */
Darryl Greend49a4992018-06-18 17:27:26 +01001066 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001067# endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskine354f7672019-07-12 23:46:38 +02001068
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001069# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1070 if (driver != NULL) {
1071 status = psa_save_se_persistent_data(driver);
1072 if (overall_status == PSA_SUCCESS)
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001073 overall_status = status;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001074 status = psa_crypto_stop_transaction();
1075 if (overall_status == PSA_SUCCESS)
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001076 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001077 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001078# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinefc762652019-07-22 19:30:34 +02001079
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001080exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001081 status = psa_wipe_key_slot(slot);
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001082 /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001083 if (status != PSA_SUCCESS)
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001084 overall_status = status;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001085 return overall_status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001086}
1087
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001088# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1089 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
1090static psa_status_t
1091psa_get_rsa_public_exponent(const mbedtls_rsa_context *rsa,
1092 psa_key_attributes_t *attributes)
Gilles Peskineb699f072019-04-26 16:06:02 +02001093{
1094 mbedtls_mpi mpi;
Janos Follath24eed8d2019-11-22 13:21:35 +00001095 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb699f072019-04-26 16:06:02 +02001096 uint8_t *buffer = NULL;
1097 size_t buflen;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001098 mbedtls_mpi_init(&mpi);
Gilles Peskineb699f072019-04-26 16:06:02 +02001099
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001100 ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &mpi);
1101 if (ret != 0)
Gilles Peskineb699f072019-04-26 16:06:02 +02001102 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001103 if (mbedtls_mpi_cmp_int(&mpi, 65537) == 0) {
Gilles Peskine772c8b12019-04-26 17:37:21 +02001104 /* It's the default value, which is reported as an empty string,
1105 * so there's nothing to do. */
1106 goto exit;
1107 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001108
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001109 buflen = mbedtls_mpi_size(&mpi);
1110 buffer = mbedtls_calloc(1, buflen);
1111 if (buffer == NULL) {
Gilles Peskineb699f072019-04-26 16:06:02 +02001112 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
1113 goto exit;
1114 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001115 ret = mbedtls_mpi_write_binary(&mpi, buffer, buflen);
1116 if (ret != 0)
Gilles Peskineb699f072019-04-26 16:06:02 +02001117 goto exit;
1118 attributes->domain_parameters = buffer;
1119 attributes->domain_parameters_size = buflen;
1120
1121exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001122 mbedtls_mpi_free(&mpi);
1123 if (ret != 0)
1124 mbedtls_free(buffer);
1125 return mbedtls_to_psa_error(ret);
Gilles Peskineb699f072019-04-26 16:06:02 +02001126}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001127# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1128 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineb699f072019-04-26 16:06:02 +02001129
Gilles Peskinebfd322f2019-07-23 11:58:03 +02001130/** Retrieve all the publicly-accessible attributes of a key.
1131 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001132psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key,
1133 psa_key_attributes_t *attributes)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001134{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001135 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001136 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001137 psa_key_slot_t *slot;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001138
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001139 psa_reset_key_attributes(attributes);
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001140
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001141 status = psa_get_and_lock_key_slot_with_policy(key, &slot, 0, 0);
1142 if (status != PSA_SUCCESS)
1143 return status;
Gilles Peskineb870b182018-07-06 16:02:09 +02001144
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001145 attributes->core = slot->attr;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001146 attributes->core.flags &=
1147 (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY | MBEDTLS_PSA_KA_MASK_DUAL_USE);
Gilles Peskinec8000c02019-08-02 20:15:51 +02001148
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001149# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1150 if (psa_key_slot_is_external(slot))
1151 psa_set_key_slot_number(attributes, psa_key_slot_get_slot_number(slot));
1152# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineb699f072019-04-26 16:06:02 +02001153
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001154 switch (slot->attr.type) {
1155# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1156 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001157 case PSA_KEY_TYPE_RSA_KEY_PAIR:
Gilles Peskineb699f072019-04-26 16:06:02 +02001158 case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001159# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01001160 /* TODO: reporting the public exponent for opaque keys
Gilles Peskinec9d7f942019-08-13 16:17:16 +02001161 * is not yet implemented.
1162 * https://github.com/ARMmbed/mbed-crypto/issues/216
1163 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001164 if (psa_key_slot_is_external(slot))
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001165 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001166# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Steven Cooremana01795d2020-07-24 22:48:15 +02001167 {
Steven Cooremana2371e52020-07-28 14:30:39 +02001168 mbedtls_rsa_context *rsa = NULL;
Steven Cooremana01795d2020-07-24 22:48:15 +02001169
Ronald Cron90857082020-11-25 14:58:33 +01001170 status = mbedtls_psa_rsa_load_representation(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001171 slot->attr.type, slot->key.data, slot->key.bytes, &rsa);
1172 if (status != PSA_SUCCESS)
Steven Cooremana01795d2020-07-24 22:48:15 +02001173 break;
1174
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001175 status = psa_get_rsa_public_exponent(rsa, attributes);
1176 mbedtls_rsa_free(rsa);
1177 mbedtls_free(rsa);
Steven Cooremana01795d2020-07-24 22:48:15 +02001178 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001179 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001180# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1181 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskineb699f072019-04-26 16:06:02 +02001182 default:
1183 /* Nothing else to do. */
1184 break;
1185 }
1186
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001187 if (status != PSA_SUCCESS)
1188 psa_reset_key_attributes(attributes);
Ronald Cronf95a2b12020-10-22 15:24:49 +02001189
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001190 unlock_status = psa_unlock_key_slot(slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +02001191
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001192 return (status == PSA_SUCCESS) ? unlock_status : status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001193}
1194
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001195# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1196psa_status_t psa_get_key_slot_number(const psa_key_attributes_t *attributes,
1197 psa_key_slot_number_t *slot_number)
Gilles Peskinec8000c02019-08-02 20:15:51 +02001198{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001199 if (attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER) {
Gilles Peskinec8000c02019-08-02 20:15:51 +02001200 *slot_number = attributes->slot_number;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001201 return PSA_SUCCESS;
1202 } else
1203 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinec8000c02019-08-02 20:15:51 +02001204}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001205# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinec8000c02019-08-02 20:15:51 +02001206
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001207static psa_status_t psa_export_key_buffer_internal(const uint8_t *key_buffer,
1208 size_t key_buffer_size,
1209 uint8_t *data,
1210 size_t data_size,
1211 size_t *data_length)
Steven Cooremana01795d2020-07-24 22:48:15 +02001212{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001213 if (key_buffer_size > data_size)
1214 return PSA_ERROR_BUFFER_TOO_SMALL;
1215 memcpy(data, key_buffer, key_buffer_size);
1216 memset(data + key_buffer_size, 0, data_size - key_buffer_size);
Ronald Crond18b5f82020-11-25 16:46:05 +01001217 *data_length = key_buffer_size;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001218 return PSA_SUCCESS;
Steven Cooremana01795d2020-07-24 22:48:15 +02001219}
1220
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001221psa_status_t psa_export_key_internal(const psa_key_attributes_t *attributes,
1222 const uint8_t *key_buffer,
1223 size_t key_buffer_size,
1224 uint8_t *data,
1225 size_t data_size,
1226 size_t *data_length)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001227{
Ronald Crond18b5f82020-11-25 16:46:05 +01001228 psa_key_type_t type = attributes->core.type;
1229
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001230 if (key_type_is_raw_bytes(type) || PSA_KEY_TYPE_IS_RSA(type) ||
1231 PSA_KEY_TYPE_IS_ECC(type)) {
1232 return (psa_export_key_buffer_internal(key_buffer, key_buffer_size,
1233 data, data_size, data_length));
1234 } else {
Ronald Cron9486f9d2020-11-26 13:36:23 +01001235 /* This shouldn't happen in the reference implementation, but
1236 it is valid for a special-purpose implementation to omit
1237 support for exporting certain key types. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001238 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron9486f9d2020-11-26 13:36:23 +01001239 }
1240}
1241
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001242psa_status_t psa_export_key(mbedtls_svc_key_id_t key,
1243 uint8_t *data,
1244 size_t data_size,
1245 size_t *data_length)
Ronald Cron9486f9d2020-11-26 13:36:23 +01001246{
1247 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1248 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
1249 psa_key_slot_t *slot;
1250
Ronald Crone907e552021-01-18 13:22:38 +01001251 /* Reject a zero-length output buffer now, since this can never be a
1252 * valid key representation. This way we know that data must be a valid
1253 * pointer and we can do things like memset(data, ..., data_size). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001254 if (data_size == 0)
1255 return PSA_ERROR_BUFFER_TOO_SMALL;
Ronald Crone907e552021-01-18 13:22:38 +01001256
Ronald Cron9486f9d2020-11-26 13:36:23 +01001257 /* Set the key to empty now, so that even when there are errors, we always
1258 * set data_length to a value between 0 and data_size. On error, setting
1259 * the key to empty is a good choice because an empty key representation is
1260 * unlikely to be accepted anywhere. */
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001261 *data_length = 0;
1262
Ronald Cron9486f9d2020-11-26 13:36:23 +01001263 /* Export requires the EXPORT flag. There is an exception for public keys,
1264 * which don't require any flag, but
1265 * psa_get_and_lock_key_slot_with_policy() takes care of this.
1266 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001267 status = psa_get_and_lock_key_slot_with_policy(key, &slot,
1268 PSA_KEY_USAGE_EXPORT, 0);
1269 if (status != PSA_SUCCESS)
1270 return status;
mohammad160306e79202018-03-28 13:17:44 +03001271
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001272 psa_key_attributes_t attributes = { .core = slot->attr };
1273 status = psa_driver_wrapper_export_key(&attributes, slot->key.data,
1274 slot->key.bytes, data, data_size,
1275 data_length);
Ronald Cron9486f9d2020-11-26 13:36:23 +01001276
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001277 unlock_status = psa_unlock_key_slot(slot);
Ronald Cron9486f9d2020-11-26 13:36:23 +01001278
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001279 return (status == PSA_SUCCESS) ? unlock_status : status;
Ronald Cron9486f9d2020-11-26 13:36:23 +01001280}
1281
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001282psa_status_t
1283psa_export_public_key_internal(const psa_key_attributes_t *attributes,
1284 const uint8_t *key_buffer,
1285 size_t key_buffer_size,
1286 uint8_t *data,
1287 size_t data_size,
1288 size_t *data_length)
Ronald Cron9486f9d2020-11-26 13:36:23 +01001289{
Ronald Crond18b5f82020-11-25 16:46:05 +01001290 psa_key_type_t type = attributes->core.type;
Ronald Crond18b5f82020-11-25 16:46:05 +01001291
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001292 if (PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type)) {
1293 if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
Steven Cooreman560c28a2020-07-24 23:20:24 +02001294 /* Exporting public -> public */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001295 return (psa_export_key_buffer_internal(
1296 key_buffer, key_buffer_size, data, data_size, data_length));
Steven Cooreman560c28a2020-07-24 23:20:24 +02001297 }
Steven Cooremanb9b84422020-10-14 14:39:20 +02001298
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001299 if (PSA_KEY_TYPE_IS_RSA(type)) {
1300# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1301 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
1302 return (mbedtls_psa_rsa_export_public_key(attributes, key_buffer,
1303 key_buffer_size, data,
1304 data_size, data_length));
1305# else
Steven Cooreman560c28a2020-07-24 23:20:24 +02001306 /* We don't know how to convert a private RSA key to public. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001307 return PSA_ERROR_NOT_SUPPORTED;
1308# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1309 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
1310 } else {
1311# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
1312 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
1313 return (mbedtls_psa_ecp_export_public_key(attributes, key_buffer,
1314 key_buffer_size, data,
1315 data_size, data_length));
1316# else
Steven Cooreman560c28a2020-07-24 23:20:24 +02001317 /* We don't know how to convert a private ECC key to public */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001318 return PSA_ERROR_NOT_SUPPORTED;
1319# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
1320 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
Moran Pekera998bc62018-04-16 18:16:20 +03001321 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001322 } else {
Steven Cooreman560c28a2020-07-24 23:20:24 +02001323 /* This shouldn't happen in the reference implementation, but
1324 it is valid for a special-purpose implementation to omit
1325 support for exporting certain key types. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001326 return PSA_ERROR_NOT_SUPPORTED;
Steven Cooreman560c28a2020-07-24 23:20:24 +02001327 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001328}
Ronald Crond18b5f82020-11-25 16:46:05 +01001329
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001330psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key,
1331 uint8_t *data,
1332 size_t data_size,
1333 size_t *data_length)
Moran Pekerdd4ea382018-04-03 15:30:03 +03001334{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001335 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001336 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001337 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001338
Ronald Crone907e552021-01-18 13:22:38 +01001339 /* Reject a zero-length output buffer now, since this can never be a
1340 * valid key representation. This way we know that data must be a valid
1341 * pointer and we can do things like memset(data, ..., data_size). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001342 if (data_size == 0)
1343 return PSA_ERROR_BUFFER_TOO_SMALL;
Ronald Crone907e552021-01-18 13:22:38 +01001344
Darryl Greendd8fb772018-11-07 16:00:44 +00001345 /* Set the key to empty now, so that even when there are errors, we always
1346 * set data_length to a value between 0 and data_size. On error, setting
1347 * the key to empty is a good choice because an empty key representation is
1348 * unlikely to be accepted anywhere. */
1349 *data_length = 0;
1350
1351 /* Exporting a public key doesn't require a usage flag. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001352 status = psa_get_and_lock_key_slot_with_policy(key, &slot, 0, 0);
1353 if (status != PSA_SUCCESS)
1354 return status;
Ronald Cronf95a2b12020-10-22 15:24:49 +02001355
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001356 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(slot->attr.type)) {
1357 status = PSA_ERROR_INVALID_ARGUMENT;
1358 goto exit;
Ronald Cron9486f9d2020-11-26 13:36:23 +01001359 }
1360
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001361 psa_key_attributes_t attributes = { .core = slot->attr };
1362 status = psa_driver_wrapper_export_public_key(&attributes, slot->key.data,
1363 slot->key.bytes, data,
1364 data_size, data_length);
Ronald Cron9486f9d2020-11-26 13:36:23 +01001365
1366exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001367 unlock_status = psa_unlock_key_slot(slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +02001368
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001369 return (status == PSA_SUCCESS) ? unlock_status : status;
Moran Pekerdd4ea382018-04-03 15:30:03 +03001370}
1371
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001372# if defined(static_assert)
1373static_assert(
1374 (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0,
1375 "One or more key attribute flag is listed as both external-only and dual-use");
1376static_assert(
1377 (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0,
1378 "One or more key attribute flag is listed as both internal-only and dual-use");
1379static_assert(
1380 (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY) == 0,
1381 "One or more key attribute flag is listed as both internal-only and external-only");
1382# endif
Gilles Peskine91e8c332019-08-02 19:19:39 +02001383
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001384/** Validate that a key policy is internally well-formed.
1385 *
1386 * This function only rejects invalid policies. It does not validate the
1387 * consistency of the policy with respect to other attributes of the key
1388 * such as the key type.
1389 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001390static psa_status_t psa_validate_key_policy(const psa_key_policy_t *policy)
Gilles Peskine4747d192019-04-17 15:05:45 +02001391{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001392 if ((policy->usage &
1393 ~(PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_ENCRYPT |
1394 PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_SIGN_MESSAGE |
1395 PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_SIGN_HASH |
1396 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_DERIVATION |
1397 PSA_KEY_USAGE_DERIVE)) != 0)
1398 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine4747d192019-04-17 15:05:45 +02001399
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001400 return PSA_SUCCESS;
Gilles Peskine4747d192019-04-17 15:05:45 +02001401}
1402
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001403/** Validate the internal consistency of key attributes.
1404 *
1405 * This function only rejects invalid attribute values. If does not
1406 * validate the consistency of the attributes with any key data that may
1407 * be involved in the creation of the key.
1408 *
1409 * Call this function early in the key creation process.
1410 *
1411 * \param[in] attributes Key attributes for the new key.
1412 * \param[out] p_drv On any return, the driver for the key, if any.
1413 * NULL for a transparent key.
1414 *
1415 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001416static psa_status_t
1417psa_validate_key_attributes(const psa_key_attributes_t *attributes,
1418 psa_se_drv_table_entry_t **p_drv)
Darryl Green0c6575a2018-11-07 16:05:30 +00001419{
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001420 psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001421 psa_key_lifetime_t lifetime = psa_get_key_lifetime(attributes);
1422 mbedtls_svc_key_id_t key = psa_get_key_id(attributes);
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001423
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001424 status = psa_validate_key_location(lifetime, p_drv);
1425 if (status != PSA_SUCCESS)
1426 return status;
Steven Cooreman81fe7c32020-06-08 18:37:19 +02001427
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001428 status = psa_validate_key_persistence(lifetime);
1429 if (status != PSA_SUCCESS)
1430 return status;
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001431
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001432 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
1433 if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key) != 0)
1434 return PSA_ERROR_INVALID_ARGUMENT;
1435 } else {
1436 if (!psa_is_valid_key_id(psa_get_key_id(attributes), 0))
1437 return PSA_ERROR_INVALID_ARGUMENT;
Ronald Crond2ed4812020-07-17 16:11:30 +02001438 }
1439
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001440 status = psa_validate_key_policy(&attributes->core.policy);
1441 if (status != PSA_SUCCESS)
1442 return status;
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001443
1444 /* Refuse to create overly large keys.
1445 * Note that this doesn't trigger on import if the attributes don't
1446 * explicitly specify a size (so psa_get_key_bits returns 0), so
1447 * psa_import_key() needs its own checks. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001448 if (psa_get_key_bits(attributes) > PSA_MAX_KEY_BITS)
1449 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001450
Gilles Peskine91e8c332019-08-02 19:19:39 +02001451 /* Reject invalid flags. These should not be reachable through the API. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001452 if (attributes->core.flags &
1453 ~(MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY | MBEDTLS_PSA_KA_MASK_DUAL_USE))
1454 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine91e8c332019-08-02 19:19:39 +02001455
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001456 return PSA_SUCCESS;
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001457}
1458
Gilles Peskine4747d192019-04-17 15:05:45 +02001459/** Prepare a key slot to receive key material.
1460 *
1461 * This function allocates a key slot and sets its metadata.
1462 *
1463 * If this function fails, call psa_fail_key_creation().
1464 *
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001465 * This function is intended to be used as follows:
1466 * -# Call psa_start_key_creation() to allocate a key slot, prepare
Ronald Croncf56a0a2020-08-04 09:51:30 +02001467 * it with the specified attributes, and in case of a volatile key assign it
1468 * a volatile key identifier.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001469 * -# Populate the slot with the key material.
1470 * -# Call psa_finish_key_creation() to finalize the creation of the slot.
1471 * In case of failure at any step, stop the sequence and call
1472 * psa_fail_key_creation().
1473 *
Ronald Cron5c522922020-11-14 16:35:34 +01001474 * On success, the key slot is locked. It is the responsibility of the caller
1475 * to unlock the key slot when it does not access it anymore.
Ronald Cronf95a2b12020-10-22 15:24:49 +02001476 *
Gilles Peskinedf179142019-07-15 22:02:14 +02001477 * \param method An identification of the calling function.
Gilles Peskine011e4282019-06-26 18:34:38 +02001478 * \param[in] attributes Key attributes for the new key.
Gilles Peskine011e4282019-06-26 18:34:38 +02001479 * \param[out] p_slot On success, a pointer to the prepared slot.
1480 * \param[out] p_drv On any return, the driver for the key, if any.
1481 * NULL for a transparent key.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001482 *
1483 * \retval #PSA_SUCCESS
1484 * The key slot is ready to receive key material.
1485 * \return If this function fails, the key slot is an invalid state.
1486 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02001487 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001488static psa_status_t
1489psa_start_key_creation(psa_key_creation_method_t method,
1490 const psa_key_attributes_t *attributes,
1491 psa_key_slot_t **p_slot,
1492 psa_se_drv_table_entry_t **p_drv)
Gilles Peskine4747d192019-04-17 15:05:45 +02001493{
1494 psa_status_t status;
Ronald Cron2a993152020-07-17 14:13:26 +02001495 psa_key_id_t volatile_key_id;
Gilles Peskine4747d192019-04-17 15:05:45 +02001496 psa_key_slot_t *slot;
1497
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001498 (void)method;
Gilles Peskine011e4282019-06-26 18:34:38 +02001499 *p_drv = NULL;
1500
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001501 status = psa_validate_key_attributes(attributes, p_drv);
1502 if (status != PSA_SUCCESS)
1503 return status;
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001504
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001505 status = psa_get_empty_key_slot(&volatile_key_id, p_slot);
1506 if (status != PSA_SUCCESS)
1507 return status;
Gilles Peskine4747d192019-04-17 15:05:45 +02001508 slot = *p_slot;
1509
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001510 /* We're storing the declared bit-size of the key. It's up to each
1511 * creation mechanism to verify that this information is correct.
1512 * It's automatically correct for mechanisms that use the bit-size as
Gilles Peskineb46bef22019-07-30 21:32:04 +02001513 * an input (generate, device) but not for those where the bit-size
Ronald Cronc4d1b512020-07-31 11:26:37 +02001514 * is optional (import, copy). In case of a volatile key, assign it the
1515 * volatile key identifier associated to the slot returned to contain its
1516 * definition. */
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001517
1518 slot->attr = attributes->core;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001519 if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
1520# if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
Ronald Cronc4d1b512020-07-31 11:26:37 +02001521 slot->attr.id = volatile_key_id;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001522# else
Ronald Cronc4d1b512020-07-31 11:26:37 +02001523 slot->attr.id.key_id = volatile_key_id;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001524# endif
Ronald Cronc4d1b512020-07-31 11:26:37 +02001525 }
Gilles Peskinec744d992019-07-30 17:26:54 +02001526
Gilles Peskine91e8c332019-08-02 19:19:39 +02001527 /* Erase external-only flags from the internal copy. To access
Gilles Peskine013f5472019-08-07 15:42:14 +02001528 * external-only flags, query `attributes`. Thanks to the check
1529 * in psa_validate_key_attributes(), this leaves the dual-use
Gilles Peskineedbed562019-08-07 18:19:59 +02001530 * flags and any internal flag that psa_get_empty_key_slot()
Gilles Peskine013f5472019-08-07 15:42:14 +02001531 * may have set. */
1532 slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
Gilles Peskine91e8c332019-08-02 19:19:39 +02001533
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001534# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02001535 /* For a key in a secure element, we need to do three things
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001536 * when creating or registering a persistent key:
Gilles Peskine60450a42019-07-25 11:32:45 +02001537 * create the key file in internal storage, create the
1538 * key inside the secure element, and update the driver's
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001539 * persistent data. This is done by starting a transaction that will
1540 * encompass these three actions.
1541 * For registering a volatile key, we just need to find an appropriate
1542 * slot number inside the SE. Since the key is designated volatile, creating
1543 * a transaction is not required. */
Gilles Peskine60450a42019-07-25 11:32:45 +02001544 /* The first thing to do is to find a slot number for the new key.
1545 * We save the slot number in persistent storage as part of the
1546 * transaction data. It will be needed to recover if the power
1547 * fails during the key creation process, to clean up on the secure
1548 * element side after restarting. Obtaining a slot number from the
1549 * secure element driver updates its persistent state, but we do not yet
1550 * save the driver's persistent state, so that if the power fails,
Gilles Peskinefc762652019-07-22 19:30:34 +02001551 * we can roll back to a state where the key doesn't exist. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001552 if (*p_drv != NULL) {
Ronald Cronea0f8a62020-11-25 17:52:23 +01001553 psa_key_slot_number_t slot_number;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001554 status =
1555 psa_find_se_slot_for_key(attributes, method, *p_drv, &slot_number);
1556 if (status != PSA_SUCCESS)
1557 return status;
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001558
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001559 if (!PSA_KEY_LIFETIME_IS_VOLATILE(attributes->core.lifetime)) {
1560 psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_CREATE_KEY);
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001561 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
Ronald Cronea0f8a62020-11-25 17:52:23 +01001562 psa_crypto_transaction.key.slot = slot_number;
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001563 psa_crypto_transaction.key.id = slot->attr.id;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001564 status = psa_crypto_save_transaction();
1565 if (status != PSA_SUCCESS) {
1566 (void)psa_crypto_stop_transaction();
1567 return status;
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001568 }
Gilles Peskine66be51c2019-07-25 18:02:52 +02001569 }
Ronald Cronea0f8a62020-11-25 17:52:23 +01001570
1571 status = psa_copy_key_material_into_slot(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001572 slot, (uint8_t *)(&slot_number), sizeof(slot_number));
Darryl Green0c6575a2018-11-07 16:05:30 +00001573 }
Gilles Peskine3efcebb2019-10-01 14:18:35 +02001574
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001575 if (*p_drv == NULL && method == PSA_KEY_CREATION_REGISTER) {
Gilles Peskine3efcebb2019-10-01 14:18:35 +02001576 /* Key registration only makes sense with a secure element. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001577 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine3efcebb2019-10-01 14:18:35 +02001578 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001579# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinecbaff462019-07-12 23:46:04 +02001580
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001581 return PSA_SUCCESS;
Darryl Green0c6575a2018-11-07 16:05:30 +00001582}
Gilles Peskine4747d192019-04-17 15:05:45 +02001583
1584/** Finalize the creation of a key once its key material has been set.
1585 *
1586 * This entails writing the key to persistent storage.
1587 *
1588 * If this function fails, call psa_fail_key_creation().
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001589 * See the documentation of psa_start_key_creation() for the intended use
1590 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02001591 *
Ronald Cron5c522922020-11-14 16:35:34 +01001592 * If the finalization succeeds, the function unlocks the key slot (it was
1593 * locked by psa_start_key_creation()) and the key slot cannot be accessed
1594 * anymore as part of the key creation process.
Ronald Cron50972942020-11-14 11:28:25 +01001595 *
Gilles Peskine011e4282019-06-26 18:34:38 +02001596 * \param[in,out] slot Pointer to the slot with key material.
1597 * \param[in] driver The secure element driver for the key,
1598 * or NULL for a transparent key.
Ronald Cron81709fc2020-11-14 12:10:32 +01001599 * \param[out] key On success, identifier of the key. Note that the
1600 * key identifier is also stored in the key slot.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001601 *
1602 * \retval #PSA_SUCCESS
Ronald Croncf56a0a2020-08-04 09:51:30 +02001603 * The key was successfully created.
gabor-mezei-arm452b0a32020-11-09 17:42:55 +01001604 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
1605 * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
1606 * \retval #PSA_ERROR_ALREADY_EXISTS
1607 * \retval #PSA_ERROR_DATA_INVALID
1608 * \retval #PSA_ERROR_DATA_CORRUPT
gabor-mezei-arm86326a92020-11-30 16:50:34 +01001609 * \retval #PSA_ERROR_STORAGE_FAILURE
gabor-mezei-arm452b0a32020-11-09 17:42:55 +01001610 *
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001611 * \return If this function fails, the key slot is an invalid state.
1612 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02001613 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001614static psa_status_t psa_finish_key_creation(psa_key_slot_t *slot,
1615 psa_se_drv_table_entry_t *driver,
1616 mbedtls_svc_key_id_t *key)
Gilles Peskine4747d192019-04-17 15:05:45 +02001617{
1618 psa_status_t status = PSA_SUCCESS;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001619 (void)slot;
1620 (void)driver;
Gilles Peskine4747d192019-04-17 15:05:45 +02001621
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001622# if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
1623 if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
1624# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1625 if (driver != NULL) {
Gilles Peskineb46bef22019-07-30 21:32:04 +02001626 psa_se_key_data_storage_t data;
Ronald Cronea0f8a62020-11-25 17:52:23 +01001627 psa_key_slot_number_t slot_number =
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001628 psa_key_slot_get_slot_number(slot);
Ronald Cronea0f8a62020-11-25 17:52:23 +01001629
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001630# if defined(static_assert)
1631 static_assert(
1632 sizeof(slot_number) == sizeof(data.slot_number),
1633 "Slot number size does not match psa_se_key_data_storage_t");
1634# endif
1635 memcpy(&data.slot_number, &slot_number, sizeof(slot_number));
1636 status = psa_save_persistent_key(&slot->attr, (uint8_t *)&data,
1637 sizeof(data));
1638 } else
1639# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine1df83d42019-07-23 16:13:14 +02001640 {
Steven Cooreman40120f62020-10-29 11:42:22 +01001641 /* Key material is saved in export representation in the slot, so
1642 * just pass the slot buffer for storage. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001643 status = psa_save_persistent_key(&slot->attr, slot->key.data,
1644 slot->key.bytes);
Gilles Peskine1df83d42019-07-23 16:13:14 +02001645 }
Gilles Peskine4747d192019-04-17 15:05:45 +02001646 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001647# endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Darryl Green0c6575a2018-11-07 16:05:30 +00001648
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001649# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02001650 /* Finish the transaction for a key creation. This does not
1651 * happen when registering an existing key. Detect this case
1652 * by checking whether a transaction is in progress (actual
Steven Cooremanbbeaf182020-06-08 18:29:44 +02001653 * creation of a persistent key in a secure element requires a transaction,
1654 * but registration or volatile key creation doesn't use one). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001655 if (driver != NULL && psa_crypto_transaction.unknown.type ==
1656 PSA_CRYPTO_TRANSACTION_CREATE_KEY) {
1657 status = psa_save_se_persistent_data(driver);
1658 if (status != PSA_SUCCESS) {
1659 psa_destroy_persistent_key(slot->attr.id);
1660 return status;
Gilles Peskinecbaff462019-07-12 23:46:04 +02001661 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001662 status = psa_crypto_stop_transaction();
Gilles Peskinecbaff462019-07-12 23:46:04 +02001663 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001664# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinecbaff462019-07-12 23:46:04 +02001665
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001666 if (status == PSA_SUCCESS) {
Ronald Cron81709fc2020-11-14 12:10:32 +01001667 *key = slot->attr.id;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001668 status = psa_unlock_key_slot(slot);
1669 if (status != PSA_SUCCESS)
Ronald Cron81709fc2020-11-14 12:10:32 +01001670 *key = MBEDTLS_SVC_KEY_ID_INIT;
1671 }
Ronald Cron50972942020-11-14 11:28:25 +01001672
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001673 return status;
Gilles Peskine4747d192019-04-17 15:05:45 +02001674}
1675
1676/** Abort the creation of a key.
1677 *
1678 * You may call this function after calling psa_start_key_creation(),
1679 * or after psa_finish_key_creation() fails. In other circumstances, this
1680 * function may not clean up persistent storage.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001681 * See the documentation of psa_start_key_creation() for the intended use
1682 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02001683 *
Gilles Peskine011e4282019-06-26 18:34:38 +02001684 * \param[in,out] slot Pointer to the slot with key material.
1685 * \param[in] driver The secure element driver for the key,
1686 * or NULL for a transparent key.
Gilles Peskine4747d192019-04-17 15:05:45 +02001687 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001688static void psa_fail_key_creation(psa_key_slot_t *slot,
1689 psa_se_drv_table_entry_t *driver)
Gilles Peskine4747d192019-04-17 15:05:45 +02001690{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001691 (void)driver;
Gilles Peskine011e4282019-06-26 18:34:38 +02001692
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001693 if (slot == NULL)
Gilles Peskine4747d192019-04-17 15:05:45 +02001694 return;
Gilles Peskine011e4282019-06-26 18:34:38 +02001695
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001696# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01001697 /* TODO: If the key has already been created in the secure
Gilles Peskine011e4282019-06-26 18:34:38 +02001698 * element, and the failure happened later (when saving metadata
1699 * to internal storage), we need to destroy the key in the secure
Gilles Peskinec9d7f942019-08-13 16:17:16 +02001700 * element.
1701 * https://github.com/ARMmbed/mbed-crypto/issues/217
1702 */
Gilles Peskinefc762652019-07-22 19:30:34 +02001703
Gilles Peskined7729582019-08-05 15:55:54 +02001704 /* Abort the ongoing transaction if any (there may not be one if
1705 * the creation process failed before starting one, or if the
1706 * key creation is a registration of a key in a secure element).
1707 * Earlier functions must already have done what it takes to undo any
1708 * partial creation. All that's left is to update the transaction data
1709 * itself. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001710 (void)psa_crypto_stop_transaction();
1711# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine011e4282019-06-26 18:34:38 +02001712
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001713 psa_wipe_key_slot(slot);
Gilles Peskine4747d192019-04-17 15:05:45 +02001714}
1715
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001716/** Validate optional attributes during key creation.
1717 *
1718 * Some key attributes are optional during key creation. If they are
1719 * specified in the attributes structure, check that they are consistent
1720 * with the data in the slot.
1721 *
1722 * This function should be called near the end of key creation, after
1723 * the slot in memory is fully populated but before saving persistent data.
1724 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001725static psa_status_t
1726psa_validate_optional_attributes(const psa_key_slot_t *slot,
1727 const psa_key_attributes_t *attributes)
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001728{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001729 if (attributes->core.type != 0) {
1730 if (attributes->core.type != slot->attr.type)
1731 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001732 }
1733
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001734 if (attributes->domain_parameters_size != 0) {
1735# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1736 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
1737 if (PSA_KEY_TYPE_IS_RSA(slot->attr.type)) {
Steven Cooremana2371e52020-07-28 14:30:39 +02001738 mbedtls_rsa_context *rsa = NULL;
Steven Cooreman75b74362020-07-28 14:30:13 +02001739 mbedtls_mpi actual, required;
Steven Cooreman6d839f02020-07-30 11:36:45 +02001740 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Steven Cooremana01795d2020-07-24 22:48:15 +02001741
Ronald Cron90857082020-11-25 14:58:33 +01001742 psa_status_t status = mbedtls_psa_rsa_load_representation(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001743 slot->attr.type, slot->key.data, slot->key.bytes, &rsa);
1744 if (status != PSA_SUCCESS)
1745 return status;
Steven Cooreman75b74362020-07-28 14:30:13 +02001746
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001747 mbedtls_mpi_init(&actual);
1748 mbedtls_mpi_init(&required);
1749 ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &actual);
1750 mbedtls_rsa_free(rsa);
1751 mbedtls_free(rsa);
1752 if (ret != 0)
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001753 goto rsa_exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001754 ret = mbedtls_mpi_read_binary(&required,
1755 attributes->domain_parameters,
1756 attributes->domain_parameters_size);
1757 if (ret != 0)
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001758 goto rsa_exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001759 if (mbedtls_mpi_cmp_mpi(&actual, &required) != 0)
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001760 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001761rsa_exit:
1762 mbedtls_mpi_free(&actual);
1763 mbedtls_mpi_free(&required);
1764 if (ret != 0)
1765 return mbedtls_to_psa_error(ret);
1766 } else
1767# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
1768 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001769 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001770 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001771 }
1772 }
1773
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001774 if (attributes->core.bits != 0) {
1775 if (attributes->core.bits != slot->attr.bits)
1776 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001777 }
1778
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001779 return PSA_SUCCESS;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001780}
1781
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001782psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
1783 const uint8_t *data,
1784 size_t data_length,
1785 mbedtls_svc_key_id_t *key)
Gilles Peskine4747d192019-04-17 15:05:45 +02001786{
1787 psa_status_t status;
1788 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001789 psa_se_drv_table_entry_t *driver = NULL;
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001790 size_t bits;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001791
Ronald Cron81709fc2020-11-14 12:10:32 +01001792 *key = MBEDTLS_SVC_KEY_ID_INIT;
1793
Gilles Peskine0f84d622019-09-12 19:03:13 +02001794 /* Reject zero-length symmetric keys (including raw data key objects).
1795 * This also rejects any key which might be encoded as an empty string,
1796 * which is never valid. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001797 if (data_length == 0)
1798 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine0f84d622019-09-12 19:03:13 +02001799
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001800 status = psa_start_key_creation(PSA_KEY_CREATION_IMPORT, attributes, &slot,
1801 &driver);
1802 if (status != PSA_SUCCESS)
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001803 goto exit;
1804
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001805 /* In the case of a transparent key or an opaque key stored in local
1806 * storage (thus not in the case of generating a key in a secure element
1807 * or cryptoprocessor with storage), we have to allocate a buffer to
1808 * hold the generated key material. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001809 if (slot->key.data == NULL) {
1810 status = psa_allocate_buffer_to_slot(slot, data_length);
1811 if (status != PSA_SUCCESS)
Gilles Peskineb46bef22019-07-30 21:32:04 +02001812 goto exit;
Gilles Peskine5d309672019-07-12 23:47:28 +02001813 }
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001814
1815 bits = slot->attr.bits;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001816 status = psa_driver_wrapper_import_key(attributes, data, data_length,
1817 slot->key.data, slot->key.bytes,
1818 &slot->key.bytes, &bits);
1819 if (status != PSA_SUCCESS)
Ronald Cronfb2ed5b2020-11-30 12:11:01 +01001820 goto exit;
1821
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001822 if (slot->attr.bits == 0)
1823 slot->attr.bits = (psa_key_bits_t)bits;
1824 else if (bits != slot->attr.bits) {
Steven Cooremanac3434f2021-01-15 17:36:02 +01001825 status = PSA_ERROR_INVALID_ARGUMENT;
1826 goto exit;
Gilles Peskine5d309672019-07-12 23:47:28 +02001827 }
Ronald Cron2ebfdcc2020-11-28 15:54:54 +01001828
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001829 status = psa_validate_optional_attributes(slot, attributes);
1830 if (status != PSA_SUCCESS)
Gilles Peskine18017402019-07-24 20:25:59 +02001831 goto exit;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001832
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001833 status = psa_finish_key_creation(slot, driver, key);
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001834exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001835 if (status != PSA_SUCCESS)
1836 psa_fail_key_creation(slot, driver);
Ronald Cronf95a2b12020-10-22 15:24:49 +02001837
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001838 return status;
Gilles Peskine4747d192019-04-17 15:05:45 +02001839}
1840
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001841# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1842psa_status_t mbedtls_psa_register_se_key(const psa_key_attributes_t *attributes)
Gilles Peskined7729582019-08-05 15:55:54 +02001843{
1844 psa_status_t status;
1845 psa_key_slot_t *slot = NULL;
1846 psa_se_drv_table_entry_t *driver = NULL;
Ronald Croncf56a0a2020-08-04 09:51:30 +02001847 mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
Gilles Peskined7729582019-08-05 15:55:54 +02001848
1849 /* Leaving attributes unspecified is not currently supported.
1850 * It could make sense to query the key type and size from the
1851 * secure element, but not all secure elements support this
1852 * and the driver HAL doesn't currently support it. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001853 if (psa_get_key_type(attributes) == PSA_KEY_TYPE_NONE)
1854 return PSA_ERROR_NOT_SUPPORTED;
1855 if (psa_get_key_bits(attributes) == 0)
1856 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskined7729582019-08-05 15:55:54 +02001857
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001858 status = psa_start_key_creation(PSA_KEY_CREATION_REGISTER, attributes,
1859 &slot, &driver);
1860 if (status != PSA_SUCCESS)
Gilles Peskined7729582019-08-05 15:55:54 +02001861 goto exit;
1862
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001863 status = psa_finish_key_creation(slot, driver, &key);
Gilles Peskined7729582019-08-05 15:55:54 +02001864
1865exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001866 if (status != PSA_SUCCESS)
1867 psa_fail_key_creation(slot, driver);
Ronald Cronf95a2b12020-10-22 15:24:49 +02001868
Gilles Peskined7729582019-08-05 15:55:54 +02001869 /* Registration doesn't keep the key in RAM. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001870 psa_close_key(key);
1871 return status;
Gilles Peskined7729582019-08-05 15:55:54 +02001872}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001873# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskined7729582019-08-05 15:55:54 +02001874
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001875static psa_status_t psa_copy_key_material(const psa_key_slot_t *source,
1876 psa_key_slot_t *target)
Gilles Peskinef603c712019-01-19 13:40:11 +01001877{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001878 psa_status_t status = psa_copy_key_material_into_slot(
1879 target, source->key.data, source->key.bytes);
1880 if (status != PSA_SUCCESS)
1881 return status;
Gilles Peskinef603c712019-01-19 13:40:11 +01001882
Steven Cooreman398aee52020-10-13 14:35:45 +02001883 target->attr.type = source->attr.type;
1884 target->attr.bits = source->attr.bits;
1885
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001886 return PSA_SUCCESS;
Gilles Peskinef603c712019-01-19 13:40:11 +01001887}
1888
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001889psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key,
1890 const psa_key_attributes_t *specified_attributes,
1891 mbedtls_svc_key_id_t *target_key)
Gilles Peskinef603c712019-01-19 13:40:11 +01001892{
Ronald Cronf95a2b12020-10-22 15:24:49 +02001893 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01001894 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinef603c712019-01-19 13:40:11 +01001895 psa_key_slot_t *source_slot = NULL;
1896 psa_key_slot_t *target_slot = NULL;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001897 psa_key_attributes_t actual_attributes = *specified_attributes;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001898 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskinef603c712019-01-19 13:40:11 +01001899
Ronald Cron81709fc2020-11-14 12:10:32 +01001900 *target_key = MBEDTLS_SVC_KEY_ID_INIT;
1901
Ronald Cron5c522922020-11-14 16:35:34 +01001902 status = psa_get_and_lock_transparent_key_slot_with_policy(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001903 source_key, &source_slot, PSA_KEY_USAGE_COPY, 0);
1904 if (status != PSA_SUCCESS)
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001905 goto exit;
1906
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001907 status =
1908 psa_validate_optional_attributes(source_slot, specified_attributes);
1909 if (status != PSA_SUCCESS)
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001910 goto exit;
1911
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001912 status = psa_restrict_key_policy(source_slot->attr.type,
1913 &actual_attributes.core.policy,
1914 &source_slot->attr.policy);
1915 if (status != PSA_SUCCESS)
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001916 goto exit;
1917
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001918 status = psa_start_key_creation(PSA_KEY_CREATION_COPY, &actual_attributes,
1919 &target_slot, &driver);
1920 if (status != PSA_SUCCESS)
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001921 goto exit;
1922
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001923# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1924 if (driver != NULL) {
Gilles Peskinef4ee6622019-07-24 13:44:30 +02001925 /* Copying to a secure element is not implemented yet. */
1926 status = PSA_ERROR_NOT_SUPPORTED;
1927 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01001928 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001929# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef603c712019-01-19 13:40:11 +01001930
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001931 if (psa_key_lifetime_is_external(actual_attributes.core.lifetime)) {
Ronald Cron6cc66312021-04-02 12:27:47 +02001932 /*
1933 * Copying through an opaque driver is not implemented yet, consider
1934 * a lifetime with an external location as an invalid parameter for
1935 * now.
1936 */
1937 status = PSA_ERROR_INVALID_ARGUMENT;
1938 goto exit;
1939 }
1940
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001941 status = psa_copy_key_material(source_slot, target_slot);
1942 if (status != PSA_SUCCESS)
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001943 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01001944
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001945 status = psa_finish_key_creation(target_slot, driver, target_key);
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001946exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001947 if (status != PSA_SUCCESS)
1948 psa_fail_key_creation(target_slot, driver);
Ronald Cronf95a2b12020-10-22 15:24:49 +02001949
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001950 unlock_status = psa_unlock_key_slot(source_slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +02001951
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001952 return (status == PSA_SUCCESS) ? unlock_status : status;
Gilles Peskinef603c712019-01-19 13:40:11 +01001953}
1954
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001955/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001956/* Message digests */
1957/****************************************************************/
1958
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001959psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001960{
Steven Cooremandbf8ced2021-03-04 13:01:18 +01001961 /* Aborting a non-active operation is allowed */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001962 if (operation->id == 0)
1963 return PSA_SUCCESS;
Steven Cooremandbf8ced2021-03-04 13:01:18 +01001964
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001965 psa_status_t status = psa_driver_wrapper_hash_abort(operation);
Steven Cooremandbf8ced2021-03-04 13:01:18 +01001966 operation->id = 0;
1967
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001968 return status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001969}
1970
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001971psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
1972 psa_algorithm_t alg)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001973{
Dave Rodgman685b6a72021-06-24 11:49:14 +01001974 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Steven Cooremandbf8ced2021-03-04 13:01:18 +01001975
Steven Cooremandbf8ced2021-03-04 13:01:18 +01001976 /* A context must be freshly initialized before it can be set up. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001977 if (operation->id != 0) {
Dave Rodgman685b6a72021-06-24 11:49:14 +01001978 status = PSA_ERROR_BAD_STATE;
1979 goto exit;
1980 }
Steven Cooremandbf8ced2021-03-04 13:01:18 +01001981
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001982 if (!PSA_ALG_IS_HASH(alg)) {
Dave Rodgman685b6a72021-06-24 11:49:14 +01001983 status = PSA_ERROR_INVALID_ARGUMENT;
1984 goto exit;
1985 }
Jaeden Amero36ee5d02019-02-19 09:25:10 +00001986
Steven Cooremanb6bf4bb2021-03-15 19:00:14 +01001987 /* Ensure all of the context is zeroized, since PSA_HASH_OPERATION_INIT only
1988 * directly zeroes the int-sized dummy member of the context union. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001989 memset(&operation->ctx, 0, sizeof(operation->ctx));
Steven Cooreman893232f2021-03-15 12:23:37 +01001990
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001991 status = psa_driver_wrapper_hash_setup(operation, alg);
Dave Rodgman685b6a72021-06-24 11:49:14 +01001992
1993exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001994 if (status != PSA_SUCCESS)
1995 psa_hash_abort(operation);
Dave Rodgman685b6a72021-06-24 11:49:14 +01001996
1997 return status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001998}
1999
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002000psa_status_t psa_hash_update(psa_hash_operation_t *operation,
2001 const uint8_t *input,
2002 size_t input_length)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002003{
Dave Rodgman685b6a72021-06-24 11:49:14 +01002004 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2005
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002006 if (operation->id == 0) {
Dave Rodgman685b6a72021-06-24 11:49:14 +01002007 status = PSA_ERROR_BAD_STATE;
2008 goto exit;
2009 }
Gilles Peskine94e44542018-07-12 16:58:43 +02002010
Steven Cooremanc8288352021-03-04 14:02:19 +01002011 /* Don't require hash implementations to behave correctly on a
2012 * zero-length input, which may have an invalid pointer. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002013 if (input_length == 0)
2014 return PSA_SUCCESS;
Steven Cooremanc8288352021-03-04 14:02:19 +01002015
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002016 status = psa_driver_wrapper_hash_update(operation, input, input_length);
Dave Rodgman685b6a72021-06-24 11:49:14 +01002017
2018exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002019 if (status != PSA_SUCCESS)
2020 psa_hash_abort(operation);
Steven Cooremandbf8ced2021-03-04 13:01:18 +01002021
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002022 return status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002023}
2024
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002025psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
2026 uint8_t *hash,
2027 size_t hash_size,
2028 size_t *hash_length)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002029{
Steven Cooremanfbe09282021-03-08 18:41:12 +01002030 *hash_length = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002031 if (operation->id == 0)
2032 return PSA_ERROR_BAD_STATE;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002033
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002034 psa_status_t status =
2035 psa_driver_wrapper_hash_finish(operation, hash, hash_size, hash_length);
2036 psa_hash_abort(operation);
2037 return status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002038}
2039
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002040psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
2041 const uint8_t *hash,
2042 size_t hash_length)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002043{
2044 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
2045 size_t actual_hash_length;
Steven Cooremandbf8ced2021-03-04 13:01:18 +01002046 psa_status_t status = psa_hash_finish(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002047 operation, actual_hash, sizeof(actual_hash), &actual_hash_length);
Dave Rodgman685b6a72021-06-24 11:49:14 +01002048
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002049 if (status != PSA_SUCCESS)
Dave Rodgman685b6a72021-06-24 11:49:14 +01002050 goto exit;
2051
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002052 if (actual_hash_length != hash_length) {
Dave Rodgman685b6a72021-06-24 11:49:14 +01002053 status = PSA_ERROR_INVALID_SIGNATURE;
2054 goto exit;
2055 }
2056
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002057 if (mbedtls_psa_safer_memcmp(hash, actual_hash, actual_hash_length) != 0)
Dave Rodgman685b6a72021-06-24 11:49:14 +01002058 status = PSA_ERROR_INVALID_SIGNATURE;
2059
2060exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002061 if (status != PSA_SUCCESS)
Dave Rodgman685b6a72021-06-24 11:49:14 +01002062 psa_hash_abort(operation);
2063
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002064 return status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002065}
2066
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002067psa_status_t psa_hash_compute(psa_algorithm_t alg,
2068 const uint8_t *input,
2069 size_t input_length,
2070 uint8_t *hash,
2071 size_t hash_size,
2072 size_t *hash_length)
Gilles Peskine0a749c82019-11-28 19:33:58 +01002073{
Steven Cooremanfbe09282021-03-08 18:41:12 +01002074 *hash_length = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002075 if (!PSA_ALG_IS_HASH(alg))
2076 return PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremanf66d5fd2021-03-08 18:40:40 +01002077
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002078 return (psa_driver_wrapper_hash_compute(alg, input, input_length, hash,
2079 hash_size, hash_length));
Gilles Peskine0a749c82019-11-28 19:33:58 +01002080}
2081
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002082psa_status_t psa_hash_compare(psa_algorithm_t alg,
2083 const uint8_t *input,
2084 size_t input_length,
2085 const uint8_t *hash,
2086 size_t hash_length)
Gilles Peskine0a749c82019-11-28 19:33:58 +01002087{
Steven Cooreman84d670d2021-02-18 16:22:53 +01002088 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
2089 size_t actual_hash_length;
Steven Cooremanf66d5fd2021-03-08 18:40:40 +01002090
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002091 if (!PSA_ALG_IS_HASH(alg))
2092 return PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremanf66d5fd2021-03-08 18:40:40 +01002093
Steven Cooreman1e582352021-02-18 17:24:37 +01002094 psa_status_t status = psa_driver_wrapper_hash_compute(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002095 alg, input, input_length, actual_hash, sizeof(actual_hash),
2096 &actual_hash_length);
2097 if (status != PSA_SUCCESS)
2098 return status;
2099 if (actual_hash_length != hash_length)
2100 return PSA_ERROR_INVALID_SIGNATURE;
2101 if (mbedtls_psa_safer_memcmp(hash, actual_hash, actual_hash_length) != 0)
2102 return PSA_ERROR_INVALID_SIGNATURE;
2103 return PSA_SUCCESS;
Gilles Peskine0a749c82019-11-28 19:33:58 +01002104}
2105
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002106psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
2107 psa_hash_operation_t *target_operation)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002108{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002109 if (source_operation->id == 0 || target_operation->id != 0) {
2110 return PSA_ERROR_BAD_STATE;
Steven Cooremandbf8ced2021-03-04 13:01:18 +01002111 }
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002112
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002113 psa_status_t status =
2114 psa_driver_wrapper_hash_clone(source_operation, target_operation);
2115 if (status != PSA_SUCCESS)
2116 psa_hash_abort(target_operation);
Steven Cooremandbf8ced2021-03-04 13:01:18 +01002117
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002118 return status;
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002119}
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002120
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002121/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01002122/* MAC */
2123/****************************************************************/
2124
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002125psa_status_t psa_mac_abort(psa_mac_operation_t *operation)
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002126{
Steven Cooremane6804192021-03-19 18:28:56 +01002127 /* Aborting a non-active operation is allowed */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002128 if (operation->id == 0)
2129 return PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002130
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002131 psa_status_t status = psa_driver_wrapper_mac_abort(operation);
Steven Cooreman72f736a2021-05-07 14:14:37 +02002132 operation->mac_size = 0;
2133 operation->is_sign = 0;
Steven Cooremane6804192021-03-19 18:28:56 +01002134 operation->id = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002135
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002136 return status;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002137}
2138
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002139static psa_status_t
2140psa_mac_finalize_alg_and_key_validation(psa_algorithm_t alg,
2141 const psa_key_attributes_t *attributes,
2142 uint8_t *mac_size)
Gilles Peskine8c9def32018-02-08 10:02:12 +01002143{
Ronald Cronf95a2b12020-10-22 15:24:49 +02002144 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002145 psa_key_type_t key_type = psa_get_key_type(attributes);
2146 size_t key_bits = psa_get_key_bits(attributes);
Steven Cooreman77e2cc52021-03-19 17:05:52 +01002147
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002148 if (!PSA_ALG_IS_MAC(alg))
2149 return PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremane6804192021-03-19 18:28:56 +01002150
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +01002151 /* Validate the combination of key type and algorithm */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002152 status = psa_mac_key_can_do(alg, key_type);
2153 if (status != PSA_SUCCESS)
2154 return status;
Steven Cooreman15472f82021-03-02 16:16:22 +01002155
Steven Cooremand1a68f12021-05-10 11:13:41 +02002156 /* Get the output length for the algorithm and key combination */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002157 *mac_size = PSA_MAC_LENGTH(key_type, key_bits, alg);
Steven Cooreman15472f82021-03-02 16:16:22 +01002158
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002159 if (*mac_size < 4) {
Steven Cooreman15472f82021-03-02 16:16:22 +01002160 /* A very short MAC is too short for security since it can be
2161 * brute-forced. Ancient protocols with 32-bit MACs do exist,
2162 * so we make this our minimum, even though 32 bits is still
2163 * too small for security. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002164 return PSA_ERROR_NOT_SUPPORTED;
Steven Cooreman15472f82021-03-02 16:16:22 +01002165 }
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002166
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002167 if (*mac_size >
2168 PSA_MAC_LENGTH(key_type, key_bits, PSA_ALG_FULL_LENGTH_MAC(alg))) {
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +01002169 /* It's impossible to "truncate" to a larger length than the full length
2170 * of the algorithm. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002171 return PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremanf9f7fdf2021-03-03 19:04:05 +01002172 }
2173
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002174 return PSA_SUCCESS;
Ronald Cron2dff3b22021-06-17 16:33:22 +02002175}
2176
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002177static psa_status_t psa_mac_setup(psa_mac_operation_t *operation,
2178 mbedtls_svc_key_id_t key,
2179 psa_algorithm_t alg,
2180 int is_sign)
Gilles Peskinee59236f2018-01-27 23:32:46 +01002181{
2182 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2183 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Dave Rodgman54648242021-06-24 11:49:45 +01002184 psa_key_slot_t *slot = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002185
2186 /* A context must be freshly initialized before it can be set up. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002187 if (operation->id != 0) {
Dave Rodgman54648242021-06-24 11:49:45 +01002188 status = PSA_ERROR_BAD_STATE;
2189 goto exit;
2190 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01002191
Gilles Peskine8c9def32018-02-08 10:02:12 +01002192 status = psa_get_and_lock_key_slot_with_policy(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002193 key, &slot,
2194 is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH, alg);
2195 if (status != PSA_SUCCESS)
Dave Rodgman54648242021-06-24 11:49:45 +01002196 goto exit;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002197
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002198 psa_key_attributes_t attributes = { .core = slot->attr };
Gilles Peskine8c9def32018-02-08 10:02:12 +01002199
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002200 status = psa_mac_finalize_alg_and_key_validation(alg, &attributes,
2201 &operation->mac_size);
2202 if (status != PSA_SUCCESS)
Gilles Peskine8c9def32018-02-08 10:02:12 +01002203 goto exit;
2204
2205 operation->is_sign = is_sign;
Steven Cooremane6804192021-03-19 18:28:56 +01002206 /* Dispatch the MAC setup call with validated input */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002207 if (is_sign) {
2208 status = psa_driver_wrapper_mac_sign_setup(
2209 operation, &attributes, slot->key.data, slot->key.bytes, alg);
2210 } else {
2211 status = psa_driver_wrapper_mac_verify_setup(
2212 operation, &attributes, slot->key.data, slot->key.bytes, alg);
Gilles Peskine8c9def32018-02-08 10:02:12 +01002213 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002214
Gilles Peskinefbfac682018-07-08 20:51:54 +02002215exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002216 if (status != PSA_SUCCESS)
2217 psa_mac_abort(operation);
Ronald Cronf95a2b12020-10-22 15:24:49 +02002218
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002219 unlock_status = psa_unlock_key_slot(slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +02002220
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002221 return (status == PSA_SUCCESS) ? unlock_status : status;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002222}
2223
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002224psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
2225 mbedtls_svc_key_id_t key,
2226 psa_algorithm_t alg)
Gilles Peskine89167cb2018-07-08 20:12:23 +02002227{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002228 return psa_mac_setup(operation, key, alg, 1);
Gilles Peskine89167cb2018-07-08 20:12:23 +02002229}
2230
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002231psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
2232 mbedtls_svc_key_id_t key,
2233 psa_algorithm_t alg)
Gilles Peskine89167cb2018-07-08 20:12:23 +02002234{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002235 return psa_mac_setup(operation, key, alg, 0);
Gilles Peskine89167cb2018-07-08 20:12:23 +02002236}
2237
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002238psa_status_t psa_mac_update(psa_mac_operation_t *operation,
2239 const uint8_t *input,
2240 size_t input_length)
Gilles Peskine8c9def32018-02-08 10:02:12 +01002241{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002242 if (operation->id == 0)
2243 return PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002244
Steven Cooreman6e7f2912021-03-19 18:38:46 +01002245 /* Don't require hash implementations to behave correctly on a
2246 * zero-length input, which may have an invalid pointer. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002247 if (input_length == 0)
2248 return PSA_SUCCESS;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03002249
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002250 psa_status_t status =
2251 psa_driver_wrapper_mac_update(operation, input, input_length);
2252 if (status != PSA_SUCCESS)
2253 psa_mac_abort(operation);
Steven Cooreman6e7f2912021-03-19 18:38:46 +01002254
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002255 return status;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002256}
2257
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002258psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
2259 uint8_t *mac,
2260 size_t mac_size,
2261 size_t *mac_length)
mohammad16036df908f2018-04-02 08:34:15 -07002262{
Steven Cooremana5b860a2021-03-19 19:04:39 +01002263 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2264 psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
Steven Cooreman77e2cc52021-03-19 17:05:52 +01002265
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002266 if (operation->id == 0) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002267 status = PSA_ERROR_BAD_STATE;
Dave Rodgman90d1cb82021-06-25 09:09:02 +01002268 goto exit;
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002269 }
Jaeden Amero252ef282019-02-15 14:05:35 +00002270
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002271 if (!operation->is_sign) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002272 status = PSA_ERROR_BAD_STATE;
Dave Rodgman90d1cb82021-06-25 09:09:02 +01002273 goto exit;
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002274 }
Steven Cooreman72f736a2021-05-07 14:14:37 +02002275
Steven Cooreman8af5c5c2021-05-11 11:09:13 +02002276 /* Sanity check. This will guarantee that mac_size != 0 (and so mac != NULL)
2277 * once all the error checks are done. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002278 if (operation->mac_size == 0) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002279 status = PSA_ERROR_BAD_STATE;
Dave Rodgman90d1cb82021-06-25 09:09:02 +01002280 goto exit;
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002281 }
Steven Cooreman8af5c5c2021-05-11 11:09:13 +02002282
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002283 if (mac_size < operation->mac_size) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002284 status = PSA_ERROR_BUFFER_TOO_SMALL;
Dave Rodgman90d1cb82021-06-25 09:09:02 +01002285 goto exit;
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002286 }
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002287
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002288 status = psa_driver_wrapper_mac_sign_finish(
2289 operation, mac, operation->mac_size, mac_length);
Steven Cooreman72f736a2021-05-07 14:14:37 +02002290
Dave Rodgman90d1cb82021-06-25 09:09:02 +01002291exit:
Ronald Cronc3dd75f2021-06-18 13:05:48 +02002292 /* In case of success, set the potential excess room in the output buffer
2293 * to an invalid value, to avoid potentially leaking a longer MAC.
2294 * In case of error, set the output length and content to a safe default,
2295 * such that in case the caller misses an error check, the output would be
2296 * an unachievable MAC.
2297 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002298 if (status != PSA_SUCCESS) {
Steven Cooreman72f736a2021-05-07 14:14:37 +02002299 *mac_length = mac_size;
Ronald Cronc3dd75f2021-06-18 13:05:48 +02002300 operation->mac_size = 0;
Steven Cooreman72f736a2021-05-07 14:14:37 +02002301 }
mohammad16036df908f2018-04-02 08:34:15 -07002302
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002303 if (mac_size > operation->mac_size)
2304 memset(&mac[operation->mac_size], '!', mac_size - operation->mac_size);
Ronald Cronc3dd75f2021-06-18 13:05:48 +02002305
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002306 abort_status = psa_mac_abort(operation);
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002307
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002308 return status == PSA_SUCCESS ? abort_status : status;
mohammad16036df908f2018-04-02 08:34:15 -07002309}
2310
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002311psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
2312 const uint8_t *mac,
2313 size_t mac_length)
Gilles Peskine8c9def32018-02-08 10:02:12 +01002314{
Steven Cooremana5b860a2021-03-19 19:04:39 +01002315 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2316 psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
Steven Cooreman77e2cc52021-03-19 17:05:52 +01002317
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002318 if (operation->id == 0) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002319 status = PSA_ERROR_BAD_STATE;
Dave Rodgman90d1cb82021-06-25 09:09:02 +01002320 goto exit;
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002321 }
Jaeden Amero252ef282019-02-15 14:05:35 +00002322
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002323 if (operation->is_sign) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002324 status = PSA_ERROR_BAD_STATE;
Dave Rodgman90d1cb82021-06-25 09:09:02 +01002325 goto exit;
Dave Rodgman38e62ae2021-06-23 11:38:39 +01002326 }
Steven Cooreman72f736a2021-05-07 14:14:37 +02002327
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002328 if (operation->mac_size != mac_length) {
Steven Cooreman72f736a2021-05-07 14:14:37 +02002329 status = PSA_ERROR_INVALID_SIGNATURE;
Dave Rodgman90d1cb82021-06-25 09:09:02 +01002330 goto exit;
Steven Cooreman72f736a2021-05-07 14:14:37 +02002331 }
2332
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002333 status = psa_driver_wrapper_mac_verify_finish(operation, mac, mac_length);
Steven Cooreman72f736a2021-05-07 14:14:37 +02002334
Dave Rodgman90d1cb82021-06-25 09:09:02 +01002335exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002336 abort_status = psa_mac_abort(operation);
mohammad16036df908f2018-04-02 08:34:15 -07002337
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002338 return status == PSA_SUCCESS ? abort_status : status;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002339}
2340
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002341static psa_status_t psa_mac_compute_internal(mbedtls_svc_key_id_t key,
2342 psa_algorithm_t alg,
2343 const uint8_t *input,
2344 size_t input_length,
2345 uint8_t *mac,
2346 size_t mac_size,
2347 size_t *mac_length,
2348 int is_sign)
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002349{
2350 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron51131b52021-06-17 17:17:20 +02002351 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2352 psa_key_slot_t *slot;
2353 uint8_t operation_mac_size = 0;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002354
Ronald Cron51131b52021-06-17 17:17:20 +02002355 status = psa_get_and_lock_key_slot_with_policy(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002356 key, &slot,
2357 is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH, alg);
2358 if (status != PSA_SUCCESS)
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002359 goto exit;
2360
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002361 psa_key_attributes_t attributes = { .core = slot->attr };
Ronald Cron51131b52021-06-17 17:17:20 +02002362
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002363 status = psa_mac_finalize_alg_and_key_validation(alg, &attributes,
2364 &operation_mac_size);
2365 if (status != PSA_SUCCESS)
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002366 goto exit;
2367
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002368 if (mac_size < operation_mac_size) {
Ronald Cron51131b52021-06-17 17:17:20 +02002369 status = PSA_ERROR_BUFFER_TOO_SMALL;
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002370 goto exit;
Ronald Cron51131b52021-06-17 17:17:20 +02002371 }
2372
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002373 status = psa_driver_wrapper_mac_compute(&attributes, slot->key.data,
2374 slot->key.bytes, alg, input,
2375 input_length, mac,
2376 operation_mac_size, mac_length);
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002377
2378exit:
Ronald Cronc3dd75f2021-06-18 13:05:48 +02002379 /* In case of success, set the potential excess room in the output buffer
2380 * to an invalid value, to avoid potentially leaking a longer MAC.
2381 * In case of error, set the output length and content to a safe default,
2382 * such that in case the caller misses an error check, the output would be
2383 * an unachievable MAC.
2384 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002385 if (status != PSA_SUCCESS) {
Ronald Cron51131b52021-06-17 17:17:20 +02002386 *mac_length = mac_size;
Ronald Cronc3dd75f2021-06-18 13:05:48 +02002387 operation_mac_size = 0;
Ronald Cron51131b52021-06-17 17:17:20 +02002388 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002389 if (mac_size > operation_mac_size)
2390 memset(&mac[operation_mac_size], '!', mac_size - operation_mac_size);
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002391
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002392 unlock_status = psa_unlock_key_slot(slot);
Ronald Cron51131b52021-06-17 17:17:20 +02002393
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002394 return (status == PSA_SUCCESS) ? unlock_status : status;
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002395}
2396
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002397psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key,
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002398 psa_algorithm_t alg,
2399 const uint8_t *input,
2400 size_t input_length,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002401 uint8_t *mac,
2402 size_t mac_size,
2403 size_t *mac_length)
2404{
2405 return (psa_mac_compute_internal(key, alg, input, input_length, mac,
2406 mac_size, mac_length, 1));
2407}
2408
2409psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key,
2410 psa_algorithm_t alg,
2411 const uint8_t *input,
2412 size_t input_length,
2413 const uint8_t *mac,
2414 size_t mac_length)
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002415{
2416 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Crona587cbc2021-06-18 14:51:29 +02002417 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
2418 size_t actual_mac_length;
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002419
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002420 status = psa_mac_compute_internal(key, alg, input, input_length, actual_mac,
2421 sizeof(actual_mac), &actual_mac_length,
2422 0);
2423 if (status != PSA_SUCCESS)
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002424 goto exit;
2425
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002426 if (mac_length != actual_mac_length) {
Ronald Crona587cbc2021-06-18 14:51:29 +02002427 status = PSA_ERROR_INVALID_SIGNATURE;
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002428 goto exit;
Ronald Crona587cbc2021-06-18 14:51:29 +02002429 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002430 if (mbedtls_psa_safer_memcmp(mac, actual_mac, actual_mac_length) != 0) {
Ronald Crona587cbc2021-06-18 14:51:29 +02002431 status = PSA_ERROR_INVALID_SIGNATURE;
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002432 goto exit;
Ronald Crona587cbc2021-06-18 14:51:29 +02002433 }
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002434
2435exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002436 mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac));
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002437
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002438 return status;
gabor-mezei-arm4076d3e2021-03-01 15:34:18 +01002439}
Gilles Peskinee59236f2018-01-27 23:32:46 +01002440
Gilles Peskinee59236f2018-01-27 23:32:46 +01002441/****************************************************************/
2442/* Asymmetric cryptography */
2443/****************************************************************/
2444
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002445static psa_status_t psa_sign_verify_check_alg(int input_is_message,
2446 psa_algorithm_t alg)
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002447{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002448 if (input_is_message) {
2449 if (!PSA_ALG_IS_SIGN_MESSAGE(alg))
2450 return PSA_ERROR_INVALID_ARGUMENT;
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002451
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002452 if (PSA_ALG_IS_HASH_AND_SIGN(alg)) {
2453 if (!PSA_ALG_IS_HASH(PSA_ALG_SIGN_GET_HASH(alg)))
2454 return PSA_ERROR_INVALID_ARGUMENT;
gabor-mezei-arm8b3e8862021-05-05 13:56:27 +02002455 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002456 } else {
2457 if (!PSA_ALG_IS_HASH_AND_SIGN(alg))
2458 return PSA_ERROR_INVALID_ARGUMENT;
gabor-mezei-arm8b3e8862021-05-05 13:56:27 +02002459 }
2460
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002461 return PSA_SUCCESS;
gabor-mezei-arm8b3e8862021-05-05 13:56:27 +02002462}
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002463
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002464static psa_status_t psa_sign_internal(mbedtls_svc_key_id_t key,
2465 int input_is_message,
2466 psa_algorithm_t alg,
2467 const uint8_t *input,
2468 size_t input_length,
2469 uint8_t *signature,
2470 size_t signature_size,
2471 size_t *signature_length)
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002472{
2473 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2474 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2475 psa_key_slot_t *slot;
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002476
2477 *signature_length = 0;
2478
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002479 status = psa_sign_verify_check_alg(input_is_message, alg);
2480 if (status != PSA_SUCCESS)
gabor-mezei-arm8b3e8862021-05-05 13:56:27 +02002481 return status;
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002482
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002483 /* Immediately reject a zero-length signature buffer. This guarantees
gabor-mezei-arm12b4f342021-05-05 13:54:55 +02002484 * that signature must be a valid pointer. (On the other hand, the input
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002485 * buffer can in principle be empty since it doesn't actually have
2486 * to be a hash.) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002487 if (signature_size == 0)
2488 return PSA_ERROR_BUFFER_TOO_SMALL;
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002489
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002490 status = psa_get_and_lock_key_slot_with_policy(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002491 key, &slot,
2492 input_is_message ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_SIGN_HASH,
2493 alg);
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002494
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002495 if (status != PSA_SUCCESS)
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002496 goto exit;
2497
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002498 if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) {
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002499 status = PSA_ERROR_INVALID_ARGUMENT;
2500 goto exit;
2501 }
2502
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002503 psa_key_attributes_t attributes = { .core = slot->attr };
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002504
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002505 if (input_is_message) {
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002506 status = psa_driver_wrapper_sign_message(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002507 &attributes, slot->key.data, slot->key.bytes, alg, input,
2508 input_length, signature, signature_size, signature_length);
2509 } else {
2510 status = psa_driver_wrapper_sign_hash(&attributes, slot->key.data,
2511 slot->key.bytes, alg, input,
2512 input_length, signature,
2513 signature_size, signature_length);
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002514 }
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002515
2516exit:
2517 /* Fill the unused part of the output buffer (the whole buffer on error,
2518 * the trailing part on success) with something that isn't a valid signature
2519 * (barring an attack on the signature and deliberately-crafted input),
2520 * in case the caller doesn't check the return status properly. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002521 if (status == PSA_SUCCESS)
2522 memset(signature + *signature_length, '!',
2523 signature_size - *signature_length);
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002524 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002525 memset(signature, '!', signature_size);
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002526 /* If signature_size is 0 then we have nothing to do. We must not call
2527 * memset because signature may be NULL in this case. */
2528
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002529 unlock_status = psa_unlock_key_slot(slot);
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002530
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002531 return (status == PSA_SUCCESS) ? unlock_status : status;
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002532}
2533
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002534static psa_status_t psa_verify_internal(mbedtls_svc_key_id_t key,
2535 int input_is_message,
2536 psa_algorithm_t alg,
2537 const uint8_t *input,
2538 size_t input_length,
2539 const uint8_t *signature,
2540 size_t signature_length)
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002541{
2542 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2543 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
2544 psa_key_slot_t *slot;
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002545
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002546 status = psa_sign_verify_check_alg(input_is_message, alg);
2547 if (status != PSA_SUCCESS)
gabor-mezei-arm8b3e8862021-05-05 13:56:27 +02002548 return status;
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002549
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002550 status = psa_get_and_lock_key_slot_with_policy(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002551 key, &slot,
2552 input_is_message ? PSA_KEY_USAGE_VERIFY_MESSAGE :
2553 PSA_KEY_USAGE_VERIFY_HASH,
2554 alg);
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002555
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002556 if (status != PSA_SUCCESS)
2557 return status;
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002558
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002559 psa_key_attributes_t attributes = { .core = slot->attr };
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002560
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002561 if (input_is_message) {
2562 status = psa_driver_wrapper_verify_message(&attributes, slot->key.data,
2563 slot->key.bytes, alg, input,
2564 input_length, signature,
2565 signature_length);
2566 } else {
2567 status = psa_driver_wrapper_verify_hash(&attributes, slot->key.data,
2568 slot->key.bytes, alg, input,
2569 input_length, signature,
2570 signature_length);
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002571 }
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002572
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002573 unlock_status = psa_unlock_key_slot(slot);
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002574
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002575 return (status == PSA_SUCCESS) ? unlock_status : status;
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002576}
2577
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002578psa_status_t psa_sign_message_builtin(const psa_key_attributes_t *attributes,
2579 const uint8_t *key_buffer,
2580 size_t key_buffer_size,
2581 psa_algorithm_t alg,
2582 const uint8_t *input,
2583 size_t input_length,
2584 uint8_t *signature,
2585 size_t signature_size,
2586 size_t *signature_length)
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002587{
2588 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002589
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002590 if (PSA_ALG_IS_HASH_AND_SIGN(alg)) {
gabor-mezei-armf9820f92021-05-03 16:26:20 +02002591 size_t hash_length;
2592 uint8_t hash[PSA_HASH_MAX_SIZE];
2593
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002594 status = psa_driver_wrapper_hash_compute(PSA_ALG_SIGN_GET_HASH(alg),
2595 input, input_length, hash,
2596 sizeof(hash), &hash_length);
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002597
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002598 if (status != PSA_SUCCESS)
gabor-mezei-arm0f622402021-04-29 16:48:44 +02002599 return status;
gabor-mezei-armf9820f92021-05-03 16:26:20 +02002600
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002601 return psa_driver_wrapper_sign_hash(attributes, key_buffer,
2602 key_buffer_size, alg, hash,
2603 hash_length, signature,
2604 signature_size, signature_length);
gabor-mezei-arm0f622402021-04-29 16:48:44 +02002605 }
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002606
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002607 return PSA_ERROR_NOT_SUPPORTED;
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002608}
2609
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002610psa_status_t psa_sign_message(mbedtls_svc_key_id_t key,
2611 psa_algorithm_t alg,
2612 const uint8_t *input,
2613 size_t input_length,
2614 uint8_t *signature,
2615 size_t signature_size,
2616 size_t *signature_length)
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002617{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002618 return psa_sign_internal(key, 1, alg, input, input_length, signature,
2619 signature_size, signature_length);
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002620}
2621
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002622psa_status_t psa_verify_message_builtin(const psa_key_attributes_t *attributes,
2623 const uint8_t *key_buffer,
2624 size_t key_buffer_size,
2625 psa_algorithm_t alg,
2626 const uint8_t *input,
2627 size_t input_length,
2628 const uint8_t *signature,
2629 size_t signature_length)
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002630{
2631 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002632
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002633 if (PSA_ALG_IS_HASH_AND_SIGN(alg)) {
gabor-mezei-armf9820f92021-05-03 16:26:20 +02002634 size_t hash_length;
2635 uint8_t hash[PSA_HASH_MAX_SIZE];
2636
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002637 status = psa_driver_wrapper_hash_compute(PSA_ALG_SIGN_GET_HASH(alg),
2638 input, input_length, hash,
2639 sizeof(hash), &hash_length);
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002640
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002641 if (status != PSA_SUCCESS)
gabor-mezei-arm0f622402021-04-29 16:48:44 +02002642 return status;
gabor-mezei-armf9820f92021-05-03 16:26:20 +02002643
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002644 return psa_driver_wrapper_verify_hash(attributes, key_buffer,
2645 key_buffer_size, alg, hash,
2646 hash_length, signature,
2647 signature_length);
gabor-mezei-arm0f622402021-04-29 16:48:44 +02002648 }
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002649
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002650 return PSA_ERROR_NOT_SUPPORTED;
gabor-mezei-arm50eac352021-04-22 11:32:19 +02002651}
2652
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002653psa_status_t psa_verify_message(mbedtls_svc_key_id_t key,
2654 psa_algorithm_t alg,
2655 const uint8_t *input,
2656 size_t input_length,
2657 const uint8_t *signature,
2658 size_t signature_length)
gabor-mezei-arm5b446522021-04-20 12:11:35 +02002659{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002660 return psa_verify_internal(key, 1, alg, input, input_length, signature,
2661 signature_length);
gabor-mezei-arm4a210192021-04-14 21:14:28 +02002662}
2663
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002664psa_status_t psa_sign_hash_builtin(const psa_key_attributes_t *attributes,
2665 const uint8_t *key_buffer,
2666 size_t key_buffer_size,
2667 psa_algorithm_t alg,
2668 const uint8_t *hash,
2669 size_t hash_length,
2670 uint8_t *signature,
2671 size_t signature_size,
2672 size_t *signature_length)
Gilles Peskinee59236f2018-01-27 23:32:46 +01002673{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002674 if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
2675 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || PSA_ALG_IS_RSA_PSS(alg)) {
2676# if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
2677 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
2678 return (mbedtls_psa_rsa_sign_hash(
2679 attributes, key_buffer, key_buffer_size, alg, hash, hash_length,
2680 signature, signature_size, signature_length));
2681# endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
2682 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
2683 } else {
2684 return PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremanacda8342020-07-24 23:09:52 +02002685 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002686 } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
2687 if (PSA_ALG_IS_ECDSA(alg)) {
2688# if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
2689 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
2690 return (mbedtls_psa_ecdsa_sign_hash(
2691 attributes, key_buffer, key_buffer_size, alg, hash, hash_length,
2692 signature, signature_size, signature_length));
2693# endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
2694 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
2695 } else {
2696 return PSA_ERROR_INVALID_ARGUMENT;
Ronald Cron4501c982021-03-19 20:09:32 +01002697 }
Ronald Cron8a494f32021-02-17 09:49:51 +01002698 }
Ronald Cron4501c982021-03-19 20:09:32 +01002699
2700 (void)key_buffer;
2701 (void)key_buffer_size;
2702 (void)hash;
2703 (void)hash_length;
2704 (void)signature;
2705 (void)signature_size;
2706 (void)signature_length;
2707
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002708 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron18659932020-12-08 16:32:23 +01002709}
Gilles Peskinee59236f2018-01-27 23:32:46 +01002710
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002711psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key,
2712 psa_algorithm_t alg,
2713 const uint8_t *hash,
2714 size_t hash_length,
2715 uint8_t *signature,
2716 size_t signature_size,
2717 size_t *signature_length)
Gilles Peskinee59236f2018-01-27 23:32:46 +01002718{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002719 return psa_sign_internal(key, 0, alg, hash, hash_length, signature,
2720 signature_size, signature_length);
itayzafrir5c753392018-05-08 11:18:38 +03002721}
2722
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002723psa_status_t psa_verify_hash_builtin(const psa_key_attributes_t *attributes,
2724 const uint8_t *key_buffer,
2725 size_t key_buffer_size,
2726 psa_algorithm_t alg,
2727 const uint8_t *hash,
2728 size_t hash_length,
2729 const uint8_t *signature,
2730 size_t signature_length)
itayzafrir5c753392018-05-08 11:18:38 +03002731{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002732 if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) {
2733 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || PSA_ALG_IS_RSA_PSS(alg)) {
2734# if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
2735 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
2736 return (mbedtls_psa_rsa_verify_hash(
2737 attributes, key_buffer, key_buffer_size, alg, hash, hash_length,
2738 signature, signature_length));
2739# endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
2740 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
2741 } else {
2742 return PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremanacda8342020-07-24 23:09:52 +02002743 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002744 } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
2745 if (PSA_ALG_IS_ECDSA(alg)) {
2746# if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
2747 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
2748 return (mbedtls_psa_ecdsa_verify_hash(
2749 attributes, key_buffer, key_buffer_size, alg, hash, hash_length,
2750 signature, signature_length));
2751# endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
2752 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
2753 } else {
2754 return PSA_ERROR_INVALID_ARGUMENT;
Ronald Cron4501c982021-03-19 20:09:32 +01002755 }
Ronald Cron8a494f32021-02-17 09:49:51 +01002756 }
Ronald Cron4501c982021-03-19 20:09:32 +01002757
2758 (void)key_buffer;
2759 (void)key_buffer_size;
2760 (void)hash;
2761 (void)hash_length;
2762 (void)signature;
2763 (void)signature_length;
2764
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002765 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron18659932020-12-08 16:32:23 +01002766}
2767
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002768psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key,
2769 psa_algorithm_t alg,
2770 const uint8_t *hash,
2771 size_t hash_length,
2772 const uint8_t *signature,
2773 size_t signature_length)
itayzafrir5c753392018-05-08 11:18:38 +03002774{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002775 return psa_verify_internal(key, 0, alg, hash, hash_length, signature,
2776 signature_length);
Gilles Peskinee59236f2018-01-27 23:32:46 +01002777}
2778
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002779# if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
2780static int psa_rsa_oaep_set_padding_mode(psa_algorithm_t alg,
2781 mbedtls_rsa_context *rsa)
Gilles Peskine072ac562018-06-30 00:21:29 +02002782{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002783 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH(alg);
2784 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa(hash_alg);
2785 mbedtls_md_type_t md_alg = mbedtls_md_get_type(md_info);
Ronald Cronea7631b2021-06-03 18:51:59 +02002786
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002787 return mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
Gilles Peskine072ac562018-06-30 00:21:29 +02002788}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002789# endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Gilles Peskine072ac562018-06-30 00:21:29 +02002790
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002791psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key,
2792 psa_algorithm_t alg,
2793 const uint8_t *input,
2794 size_t input_length,
2795 const uint8_t *salt,
2796 size_t salt_length,
2797 uint8_t *output,
2798 size_t output_size,
2799 size_t *output_length)
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002800{
Ronald Cronf95a2b12020-10-22 15:24:49 +02002801 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01002802 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01002803 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002804
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002805 (void)input;
2806 (void)input_length;
2807 (void)salt;
2808 (void)output;
2809 (void)output_size;
Darryl Green5cc689a2018-07-24 15:34:10 +01002810
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002811 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002812
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002813 if (!PSA_ALG_IS_RSA_OAEP(alg) && salt_length != 0)
2814 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002815
Ronald Cron5c522922020-11-14 16:35:34 +01002816 status = psa_get_and_lock_transparent_key_slot_with_policy(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002817 key, &slot, PSA_KEY_USAGE_ENCRYPT, alg);
2818 if (status != PSA_SUCCESS)
2819 return status;
2820 if (!(PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type) ||
2821 PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type))) {
Ronald Cronf95a2b12020-10-22 15:24:49 +02002822 status = PSA_ERROR_INVALID_ARGUMENT;
2823 goto exit;
2824 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002825
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002826# if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
2827 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
2828 if (PSA_KEY_TYPE_IS_RSA(slot->attr.type)) {
Steven Cooremana2371e52020-07-28 14:30:39 +02002829 mbedtls_rsa_context *rsa = NULL;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002830 status = mbedtls_psa_rsa_load_representation(
2831 slot->attr.type, slot->key.data, slot->key.bytes, &rsa);
2832 if (status != PSA_SUCCESS)
Steven Cooreman4fed4552020-08-03 14:46:03 +02002833 goto rsa_exit;
Steven Cooremana2371e52020-07-28 14:30:39 +02002834
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002835 if (output_size < mbedtls_rsa_get_len(rsa)) {
Steven Cooreman4fed4552020-08-03 14:46:03 +02002836 status = PSA_ERROR_BUFFER_TOO_SMALL;
2837 goto rsa_exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02002838 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002839# if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
2840 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
2841 status = mbedtls_to_psa_error(mbedtls_rsa_pkcs1_encrypt(
2842 rsa, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE,
2843 input_length, input, output));
2844 } else
2845# endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
2846# if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
2847 if (PSA_ALG_IS_RSA_OAEP(alg)) {
2848 status =
2849 mbedtls_to_psa_error(psa_rsa_oaep_set_padding_mode(alg, rsa));
2850 if (status != PSA_SUCCESS)
Ronald Cronea7631b2021-06-03 18:51:59 +02002851 goto rsa_exit;
2852
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002853 status = mbedtls_to_psa_error(mbedtls_rsa_rsaes_oaep_encrypt(
2854 rsa, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE, salt,
2855 salt_length, input_length, input, output));
2856 } else
2857# endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002858 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02002859 status = PSA_ERROR_INVALID_ARGUMENT;
2860 goto rsa_exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002861 }
Steven Cooreman4fed4552020-08-03 14:46:03 +02002862rsa_exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002863 if (status == PSA_SUCCESS)
2864 *output_length = mbedtls_rsa_get_len(rsa);
Steven Cooremana01795d2020-07-24 22:48:15 +02002865
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002866 mbedtls_rsa_free(rsa);
2867 mbedtls_free(rsa);
2868 } else
2869# endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
2870 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002871 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02002872 status = PSA_ERROR_NOT_SUPPORTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002873 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02002874
2875exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002876 unlock_status = psa_unlock_key_slot(slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +02002877
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002878 return (status == PSA_SUCCESS) ? unlock_status : status;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002879}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002880
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002881psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key,
2882 psa_algorithm_t alg,
2883 const uint8_t *input,
2884 size_t input_length,
2885 const uint8_t *salt,
2886 size_t salt_length,
2887 uint8_t *output,
2888 size_t output_size,
2889 size_t *output_length)
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002890{
Ronald Cronf95a2b12020-10-22 15:24:49 +02002891 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01002892 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01002893 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002894
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002895 (void)input;
2896 (void)input_length;
2897 (void)salt;
2898 (void)output;
2899 (void)output_size;
Darryl Green5cc689a2018-07-24 15:34:10 +01002900
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002901 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002902
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002903 if (!PSA_ALG_IS_RSA_OAEP(alg) && salt_length != 0)
2904 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002905
Ronald Cron5c522922020-11-14 16:35:34 +01002906 status = psa_get_and_lock_transparent_key_slot_with_policy(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002907 key, &slot, PSA_KEY_USAGE_DECRYPT, alg);
2908 if (status != PSA_SUCCESS)
2909 return status;
2910 if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) {
Ronald Cronf95a2b12020-10-22 15:24:49 +02002911 status = PSA_ERROR_INVALID_ARGUMENT;
2912 goto exit;
2913 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002914
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002915# if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
2916 defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
2917 if (slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
Steven Cooreman4fed4552020-08-03 14:46:03 +02002918 mbedtls_rsa_context *rsa = NULL;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002919 status = mbedtls_psa_rsa_load_representation(
2920 slot->attr.type, slot->key.data, slot->key.bytes, &rsa);
2921 if (status != PSA_SUCCESS)
Ronald Cronf95a2b12020-10-22 15:24:49 +02002922 goto exit;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002923
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002924 if (input_length != mbedtls_rsa_get_len(rsa)) {
Steven Cooreman4fed4552020-08-03 14:46:03 +02002925 status = PSA_ERROR_INVALID_ARGUMENT;
2926 goto rsa_exit;
Steven Cooremana01795d2020-07-24 22:48:15 +02002927 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002928
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002929# if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
2930 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
2931 status = mbedtls_to_psa_error(mbedtls_rsa_pkcs1_decrypt(
2932 rsa, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE,
2933 output_length, input, output, output_size));
2934 } else
2935# endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
2936# if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
2937 if (PSA_ALG_IS_RSA_OAEP(alg)) {
2938 status =
2939 mbedtls_to_psa_error(psa_rsa_oaep_set_padding_mode(alg, rsa));
2940 if (status != PSA_SUCCESS)
Ronald Cronea7631b2021-06-03 18:51:59 +02002941 goto rsa_exit;
2942
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002943 status = mbedtls_to_psa_error(mbedtls_rsa_rsaes_oaep_decrypt(
2944 rsa, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE, salt,
2945 salt_length, output_length, input, output, output_size));
2946 } else
2947# endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002948 {
Steven Cooreman4fed4552020-08-03 14:46:03 +02002949 status = PSA_ERROR_INVALID_ARGUMENT;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002950 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002951
Steven Cooreman4fed4552020-08-03 14:46:03 +02002952rsa_exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002953 mbedtls_rsa_free(rsa);
2954 mbedtls_free(rsa);
2955 } else
2956# endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
2957 * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002958 {
Ronald Cronf95a2b12020-10-22 15:24:49 +02002959 status = PSA_ERROR_NOT_SUPPORTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002960 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02002961
2962exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002963 unlock_status = psa_unlock_key_slot(slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +02002964
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002965 return (status == PSA_SUCCESS) ? unlock_status : status;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002966}
Gilles Peskinee59236f2018-01-27 23:32:46 +01002967
mohammad1603503973b2018-03-12 15:59:30 +02002968/****************************************************************/
2969/* Symmetric cryptography */
2970/****************************************************************/
2971
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002972static psa_status_t psa_cipher_setup(psa_cipher_operation_t *operation,
2973 mbedtls_svc_key_id_t key,
2974 psa_algorithm_t alg,
2975 mbedtls_operation_t cipher_operation)
Ronald Cronab99ac22020-10-01 16:38:28 +02002976{
2977 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2978 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Dave Rodgman54648242021-06-24 11:49:45 +01002979 psa_key_slot_t *slot = NULL;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002980 psa_key_usage_t usage = (cipher_operation == MBEDTLS_ENCRYPT ?
2981 PSA_KEY_USAGE_ENCRYPT :
2982 PSA_KEY_USAGE_DECRYPT);
Ronald Cronab99ac22020-10-01 16:38:28 +02002983
2984 /* A context must be freshly initialized before it can be set up. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002985 if (operation->id != 0) {
Dave Rodgman54648242021-06-24 11:49:45 +01002986 status = PSA_ERROR_BAD_STATE;
2987 goto exit;
2988 }
Ronald Cronab99ac22020-10-01 16:38:28 +02002989
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002990 if (!PSA_ALG_IS_CIPHER(alg)) {
Dave Rodgman54648242021-06-24 11:49:45 +01002991 status = PSA_ERROR_INVALID_ARGUMENT;
2992 goto exit;
2993 }
Ronald Cronab99ac22020-10-01 16:38:28 +02002994
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002995 status = psa_get_and_lock_key_slot_with_policy(key, &slot, usage, alg);
2996 if (status != PSA_SUCCESS)
Ronald Cronab99ac22020-10-01 16:38:28 +02002997 goto exit;
2998
Ronald Cron49fafa92021-03-10 08:34:23 +01002999 /* Initialize the operation struct members, except for id. The id member
Ronald Cronab99ac22020-10-01 16:38:28 +02003000 * is used to indicate to psa_cipher_abort that there are resources to free,
Ronald Cron49fafa92021-03-10 08:34:23 +01003001 * so we only set it (in the driver wrapper) after resources have been
3002 * allocated/initialized. */
Ronald Cronab99ac22020-10-01 16:38:28 +02003003 operation->iv_set = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003004 if (alg == PSA_ALG_ECB_NO_PADDING)
Ronald Cronab99ac22020-10-01 16:38:28 +02003005 operation->iv_required = 0;
3006 else
3007 operation->iv_required = 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003008 operation->default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg);
Ronald Cronab99ac22020-10-01 16:38:28 +02003009
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003010 psa_key_attributes_t attributes = { .core = slot->attr };
Ronald Crona4af55f2020-12-14 14:36:06 +01003011
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003012 /* Try doing the operation through a driver before using software fallback.
3013 */
3014 if (cipher_operation == MBEDTLS_ENCRYPT)
3015 status = psa_driver_wrapper_cipher_encrypt_setup(
3016 operation, &attributes, slot->key.data, slot->key.bytes, alg);
Ronald Cronab99ac22020-10-01 16:38:28 +02003017 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003018 status = psa_driver_wrapper_cipher_decrypt_setup(
3019 operation, &attributes, slot->key.data, slot->key.bytes, alg);
Ronald Cronab99ac22020-10-01 16:38:28 +02003020
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003021exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003022 if (status != PSA_SUCCESS)
3023 psa_cipher_abort(operation);
Ronald Cronf95a2b12020-10-22 15:24:49 +02003024
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003025 unlock_status = psa_unlock_key_slot(slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +02003026
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003027 return (status == PSA_SUCCESS) ? unlock_status : status;
mohammad1603503973b2018-03-12 15:59:30 +02003028}
3029
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003030psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
3031 mbedtls_svc_key_id_t key,
3032 psa_algorithm_t alg)
mohammad16038481e742018-03-18 13:57:31 +02003033{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003034 return psa_cipher_setup(operation, key, alg, MBEDTLS_ENCRYPT);
mohammad16038481e742018-03-18 13:57:31 +02003035}
3036
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003037psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
3038 mbedtls_svc_key_id_t key,
3039 psa_algorithm_t alg)
mohammad16038481e742018-03-18 13:57:31 +02003040{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003041 return psa_cipher_setup(operation, key, alg, MBEDTLS_DECRYPT);
mohammad16038481e742018-03-18 13:57:31 +02003042}
3043
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003044psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
3045 uint8_t *iv,
3046 size_t iv_size,
3047 size_t *iv_length)
mohammad1603503973b2018-03-12 15:59:30 +02003048{
Ronald Cron6d051732020-10-01 14:10:20 +02003049 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cronc45b4af2020-09-29 16:18:05 +02003050
Ronald Cron5618a392021-03-26 09:52:26 +01003051 *iv_length = 0;
3052
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003053 if (operation->id == 0) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003054 status = PSA_ERROR_BAD_STATE;
3055 goto exit;
Ronald Cronc45b4af2020-09-29 16:18:05 +02003056 }
3057
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003058 if (operation->iv_set || !operation->iv_required) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003059 status = PSA_ERROR_BAD_STATE;
3060 goto exit;
Steven Cooreman7df02922020-09-09 15:28:49 +02003061 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02003062
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003063 if (iv_size < operation->default_iv_length) {
Ronald Cron5618a392021-03-26 09:52:26 +01003064 status = PSA_ERROR_BUFFER_TOO_SMALL;
3065 goto exit;
3066 }
Gilles Peskinee553c652018-06-04 16:22:46 +02003067
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003068 status = psa_generate_random(iv, operation->default_iv_length);
3069 if (status != PSA_SUCCESS)
Ronald Cron5618a392021-03-26 09:52:26 +01003070 goto exit;
3071
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003072 status = psa_driver_wrapper_cipher_set_iv(operation, iv,
3073 operation->default_iv_length);
Ronald Cron5618a392021-03-26 09:52:26 +01003074
3075exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003076 if (status == PSA_SUCCESS) {
Steven Cooreman7df02922020-09-09 15:28:49 +02003077 operation->iv_set = 1;
Ronald Cron5618a392021-03-26 09:52:26 +01003078 *iv_length = operation->default_iv_length;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003079 } else
3080 psa_cipher_abort(operation);
Ronald Cron6d051732020-10-01 14:10:20 +02003081
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003082 return status;
mohammad1603503973b2018-03-12 15:59:30 +02003083}
3084
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003085psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
3086 const uint8_t *iv,
3087 size_t iv_length)
mohammad1603503973b2018-03-12 15:59:30 +02003088{
Ronald Cron6d051732020-10-01 14:10:20 +02003089 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cronc45b4af2020-09-29 16:18:05 +02003090
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003091 if (operation->id == 0) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003092 status = PSA_ERROR_BAD_STATE;
3093 goto exit;
3094 }
Ronald Cronc45b4af2020-09-29 16:18:05 +02003095
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003096 if (operation->iv_set || !operation->iv_required) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003097 status = PSA_ERROR_BAD_STATE;
3098 goto exit;
3099 }
Ronald Crona0d68172021-03-26 10:15:08 +01003100
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003101 if (iv_length > PSA_CIPHER_IV_MAX_SIZE) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003102 status = PSA_ERROR_INVALID_ARGUMENT;
3103 goto exit;
3104 }
Steven Cooremand3feccd2020-09-01 15:56:14 +02003105
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003106 status = psa_driver_wrapper_cipher_set_iv(operation, iv, iv_length);
Steven Cooremand3feccd2020-09-01 15:56:14 +02003107
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003108exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003109 if (status == PSA_SUCCESS)
itayzafrir534bd7c2018-08-02 13:56:32 +03003110 operation->iv_set = 1;
3111 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003112 psa_cipher_abort(operation);
3113 return status;
mohammad1603503973b2018-03-12 15:59:30 +02003114}
3115
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003116psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
3117 const uint8_t *input,
3118 size_t input_length,
3119 uint8_t *output,
3120 size_t output_size,
3121 size_t *output_length)
mohammad1603503973b2018-03-12 15:59:30 +02003122{
Steven Cooremanffecb7b2020-08-25 15:13:13 +02003123 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron6d051732020-10-01 14:10:20 +02003124
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003125 if (operation->id == 0) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003126 status = PSA_ERROR_BAD_STATE;
3127 goto exit;
Steven Cooreman7df02922020-09-09 15:28:49 +02003128 }
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003129
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003130 if (operation->iv_required && !operation->iv_set) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003131 status = PSA_ERROR_BAD_STATE;
3132 goto exit;
Steven Cooreman7df02922020-09-09 15:28:49 +02003133 }
Jaeden Ameroab439972019-02-15 14:12:05 +00003134
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003135 status = psa_driver_wrapper_cipher_update(
3136 operation, input, input_length, output, output_size, output_length);
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003137
3138exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003139 if (status != PSA_SUCCESS)
3140 psa_cipher_abort(operation);
Ronald Cron6d051732020-10-01 14:10:20 +02003141
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003142 return status;
mohammad1603503973b2018-03-12 15:59:30 +02003143}
3144
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003145psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
3146 uint8_t *output,
3147 size_t output_size,
3148 size_t *output_length)
mohammad1603503973b2018-03-12 15:59:30 +02003149{
David Saadab4ecc272019-02-14 13:48:10 +02003150 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Ronald Cron6d051732020-10-01 14:10:20 +02003151
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003152 if (operation->id == 0) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003153 status = PSA_ERROR_BAD_STATE;
3154 goto exit;
Steven Cooreman7df02922020-09-09 15:28:49 +02003155 }
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003156
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003157 if (operation->iv_required && !operation->iv_set) {
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003158 status = PSA_ERROR_BAD_STATE;
3159 goto exit;
Steven Cooreman7df02922020-09-09 15:28:49 +02003160 }
Moran Pekerbed71a22018-04-22 20:19:20 +03003161
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003162 status = psa_driver_wrapper_cipher_finish(operation, output, output_size,
3163 output_length);
Dave Rodgman38e62ae2021-06-23 11:38:39 +01003164
3165exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003166 if (status == PSA_SUCCESS)
3167 return psa_cipher_abort(operation);
3168 else {
Steven Cooremanef8575e2020-09-11 11:44:50 +02003169 *output_length = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003170 (void)psa_cipher_abort(operation);
Janos Follath315b51c2018-07-09 16:04:51 +01003171
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003172 return status;
Steven Cooremanef8575e2020-09-11 11:44:50 +02003173 }
mohammad1603503973b2018-03-12 15:59:30 +02003174}
3175
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003176psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
Gilles Peskinee553c652018-06-04 16:22:46 +02003177{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003178 if (operation->id == 0) {
Steven Cooremana07b9972020-09-10 14:54:14 +02003179 /* The object has (apparently) been initialized but it is not (yet)
Gilles Peskine81736312018-06-26 15:04:31 +02003180 * in use. It's ok to call abort on such an object, and there's
3181 * nothing to do. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003182 return PSA_SUCCESS;
Gilles Peskine81736312018-06-26 15:04:31 +02003183 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003184
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003185 psa_driver_wrapper_cipher_abort(operation);
Gilles Peskinee553c652018-06-04 16:22:46 +02003186
Ronald Cron49fafa92021-03-10 08:34:23 +01003187 operation->id = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03003188 operation->iv_set = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03003189 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03003190
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003191 return PSA_SUCCESS;
mohammad1603503973b2018-03-12 15:59:30 +02003192}
3193
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003194psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key,
3195 psa_algorithm_t alg,
3196 const uint8_t *input,
3197 size_t input_length,
3198 uint8_t *output,
3199 size_t output_size,
3200 size_t *output_length)
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003201{
3202 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
gabor-mezei-arma9449a02021-03-25 11:17:10 +01003203 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3204 psa_key_slot_t *slot;
3205 psa_key_type_t key_type;
3206 size_t iv_length;
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003207
gabor-mezei-arm6f4e5bb2021-06-25 15:21:11 +02003208 *output_length = 0;
3209
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003210 if (!PSA_ALG_IS_CIPHER(alg))
3211 return PSA_ERROR_INVALID_ARGUMENT;
gabor-mezei-arma9449a02021-03-25 11:17:10 +01003212
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003213 status = psa_get_and_lock_key_slot_with_policy(key, &slot,
3214 PSA_KEY_USAGE_ENCRYPT, alg);
3215 if (status != PSA_SUCCESS)
3216 return status;
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003217
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003218 psa_key_attributes_t attributes = { .core = slot->attr };
gabor-mezei-arma9449a02021-03-25 11:17:10 +01003219
3220 key_type = slot->attr.type;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003221 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
gabor-mezei-arma9449a02021-03-25 11:17:10 +01003222
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003223 if (iv_length > 0) {
3224 if (output_size < iv_length) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +01003225 status = PSA_ERROR_BUFFER_TOO_SMALL;
3226 goto exit;
3227 }
3228
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003229 status = psa_generate_random(output, iv_length);
3230 if (status != PSA_SUCCESS)
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003231 goto exit;
3232 }
3233
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003234 status = psa_driver_wrapper_cipher_encrypt(&attributes, slot->key.data,
3235 slot->key.bytes, alg, input,
3236 input_length, output,
3237 output_size, output_length);
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003238
3239exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003240 unlock_status = psa_unlock_key_slot(slot);
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003241
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003242 return (status == PSA_SUCCESS) ? unlock_status : status;
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003243}
3244
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003245psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key,
3246 psa_algorithm_t alg,
3247 const uint8_t *input,
3248 size_t input_length,
3249 uint8_t *output,
3250 size_t output_size,
3251 size_t *output_length)
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003252{
3253 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
gabor-mezei-arma9449a02021-03-25 11:17:10 +01003254 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
3255 psa_key_slot_t *slot;
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003256
gabor-mezei-arm6f4e5bb2021-06-25 15:21:11 +02003257 *output_length = 0;
3258
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003259 if (!PSA_ALG_IS_CIPHER(alg))
3260 return PSA_ERROR_INVALID_ARGUMENT;
gabor-mezei-arma9449a02021-03-25 11:17:10 +01003261
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003262 status = psa_get_and_lock_key_slot_with_policy(key, &slot,
3263 PSA_KEY_USAGE_DECRYPT, alg);
3264 if (status != PSA_SUCCESS)
3265 return status;
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003266
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003267 psa_key_attributes_t attributes = { .core = slot->attr };
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003268
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003269 if (input_length < PSA_CIPHER_IV_LENGTH(slot->attr.type, alg)) {
gabor-mezei-arm258ae072021-06-25 15:25:38 +02003270 status = PSA_ERROR_INVALID_ARGUMENT;
3271 goto exit;
3272 }
3273
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003274 status = psa_driver_wrapper_cipher_decrypt(&attributes, slot->key.data,
3275 slot->key.bytes, alg, input,
3276 input_length, output,
3277 output_size, output_length);
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003278
gabor-mezei-arm258ae072021-06-25 15:25:38 +02003279exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003280 unlock_status = psa_unlock_key_slot(slot);
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003281
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003282 return (status == PSA_SUCCESS) ? unlock_status : status;
gabor-mezei-armba0fa752021-03-01 15:04:24 +01003283}
3284
mohammad16035955c982018-04-26 00:53:03 +03003285/****************************************************************/
3286/* AEAD */
3287/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003288
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003289psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key,
3290 psa_algorithm_t alg,
3291 const uint8_t *nonce,
3292 size_t nonce_length,
3293 const uint8_t *additional_data,
3294 size_t additional_data_length,
3295 const uint8_t *plaintext,
3296 size_t plaintext_length,
3297 uint8_t *ciphertext,
3298 size_t ciphertext_size,
3299 size_t *ciphertext_length)
mohammad16035955c982018-04-26 00:53:03 +03003300{
Ronald Cron215633c2021-03-16 17:15:37 +01003301 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3302 psa_key_slot_t *slot;
Gilles Peskine2d277862018-06-18 15:41:12 +02003303
mohammad1603f08a5502018-06-03 15:05:47 +03003304 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003305
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003306 if (!PSA_ALG_IS_AEAD(alg) || PSA_ALG_IS_WILDCARD(alg))
3307 return PSA_ERROR_NOT_SUPPORTED;
Steven Cooremanea7ab132021-03-17 16:28:00 +01003308
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003309 status = psa_get_and_lock_key_slot_with_policy(key, &slot,
3310 PSA_KEY_USAGE_ENCRYPT, alg);
3311 if (status != PSA_SUCCESS)
3312 return status;
mohammad16035955c982018-04-26 00:53:03 +03003313
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003314 psa_key_attributes_t attributes = { .core = slot->attr };
mohammad16035955c982018-04-26 00:53:03 +03003315
Ronald Cronde822812021-03-17 16:08:20 +01003316 status = psa_driver_wrapper_aead_encrypt(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003317 &attributes, slot->key.data, slot->key.bytes, alg, nonce, nonce_length,
3318 additional_data, additional_data_length, plaintext, plaintext_length,
3319 ciphertext, ciphertext_size, ciphertext_length);
Gilles Peskine2d277862018-06-18 15:41:12 +02003320
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003321 if (status != PSA_SUCCESS && ciphertext_size != 0)
3322 memset(ciphertext, 0, ciphertext_size);
Gilles Peskine2d277862018-06-18 15:41:12 +02003323
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003324 psa_unlock_key_slot(slot);
mohammad16035955c982018-04-26 00:53:03 +03003325
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003326 return status;
Gilles Peskineee652a32018-06-01 19:23:52 +02003327}
3328
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003329psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key,
3330 psa_algorithm_t alg,
3331 const uint8_t *nonce,
3332 size_t nonce_length,
3333 const uint8_t *additional_data,
3334 size_t additional_data_length,
3335 const uint8_t *ciphertext,
3336 size_t ciphertext_length,
3337 uint8_t *plaintext,
3338 size_t plaintext_size,
3339 size_t *plaintext_length)
mohammad16035955c982018-04-26 00:53:03 +03003340{
Ronald Cron215633c2021-03-16 17:15:37 +01003341 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3342 psa_key_slot_t *slot;
Gilles Peskine2d277862018-06-18 15:41:12 +02003343
Gilles Peskineee652a32018-06-01 19:23:52 +02003344 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003345
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003346 if (!PSA_ALG_IS_AEAD(alg) || PSA_ALG_IS_WILDCARD(alg))
3347 return PSA_ERROR_NOT_SUPPORTED;
Steven Cooremanea7ab132021-03-17 16:28:00 +01003348
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003349 status = psa_get_and_lock_key_slot_with_policy(key, &slot,
3350 PSA_KEY_USAGE_DECRYPT, alg);
3351 if (status != PSA_SUCCESS)
3352 return status;
mohammad16035955c982018-04-26 00:53:03 +03003353
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003354 psa_key_attributes_t attributes = { .core = slot->attr };
Gilles Peskinef7e7b012019-05-06 15:27:16 +02003355
Ronald Cronde822812021-03-17 16:08:20 +01003356 status = psa_driver_wrapper_aead_decrypt(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003357 &attributes, slot->key.data, slot->key.bytes, alg, nonce, nonce_length,
3358 additional_data, additional_data_length, ciphertext, ciphertext_length,
3359 plaintext, plaintext_size, plaintext_length);
Gilles Peskinea40d7742018-06-01 16:28:30 +02003360
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003361 if (status != PSA_SUCCESS && plaintext_size != 0)
3362 memset(plaintext, 0, plaintext_size);
mohammad160360a64d02018-06-03 17:20:42 +03003363
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003364 psa_unlock_key_slot(slot);
Ronald Cron215633c2021-03-16 17:15:37 +01003365
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003366 return status;
mohammad16035955c982018-04-26 00:53:03 +03003367}
3368
Gilles Peskinee59236f2018-01-27 23:32:46 +01003369/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003370/* Generators */
3371/****************************************************************/
3372
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003373# if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
3374 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
3375 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
3376# define AT_LEAST_ONE_BUILTIN_KDF
3377# endif /* At least one builtin KDF */
Steven Cooreman094a77e2021-05-06 17:58:36 +02003378
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003379# if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \
3380 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
3381 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
3382static psa_status_t
3383psa_key_derivation_start_hmac(psa_mac_operation_t *operation,
3384 psa_algorithm_t hash_alg,
3385 const uint8_t *hmac_key,
3386 size_t hmac_key_length)
Steven Cooreman094a77e2021-05-06 17:58:36 +02003387{
3388 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3389 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003390 psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
3391 psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(hmac_key_length));
3392 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
Steven Cooreman094a77e2021-05-06 17:58:36 +02003393
Steven Cooreman72f736a2021-05-07 14:14:37 +02003394 operation->is_sign = 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003395 operation->mac_size = PSA_HASH_LENGTH(hash_alg);
Steven Cooreman72f736a2021-05-07 14:14:37 +02003396
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003397 status = psa_driver_wrapper_mac_sign_setup(operation, &attributes, hmac_key,
3398 hmac_key_length,
3399 PSA_ALG_HMAC(hash_alg));
Steven Cooreman094a77e2021-05-06 17:58:36 +02003400
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003401 psa_reset_key_attributes(&attributes);
3402 return status;
Steven Cooreman094a77e2021-05-06 17:58:36 +02003403}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003404# endif /* KDF algorithms reliant on HMAC */
John Durkop07cc04a2020-11-16 22:08:34 -08003405
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003406# define HKDF_STATE_INIT 0 /* no input yet */
3407# define HKDF_STATE_STARTED 1 /* got salt */
3408# define HKDF_STATE_KEYED 2 /* got key */
3409# define HKDF_STATE_OUTPUT 3 /* output started */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003410
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003411static psa_algorithm_t
3412psa_key_derivation_get_kdf_alg(const psa_key_derivation_operation_t *operation)
Gilles Peskine969c5d62019-01-16 15:53:06 +01003413{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003414 if (PSA_ALG_IS_KEY_AGREEMENT(operation->alg))
3415 return PSA_ALG_KEY_AGREEMENT_GET_KDF(operation->alg);
Gilles Peskine969c5d62019-01-16 15:53:06 +01003416 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003417 return operation->alg;
Gilles Peskine969c5d62019-01-16 15:53:06 +01003418}
3419
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003420psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t *operation)
Gilles Peskineeab56e42018-07-12 17:12:33 +02003421{
3422 psa_status_t status = PSA_SUCCESS;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003423 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
3424 if (kdf_alg == 0) {
Gilles Peskineeab56e42018-07-12 17:12:33 +02003425 /* The object has (apparently) been initialized but it is not
3426 * in use. It's ok to call abort on such an object, and there's
3427 * nothing to do. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003428 } else
3429# if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
3430 if (PSA_ALG_IS_HKDF(kdf_alg)) {
3431 mbedtls_free(operation->ctx.hkdf.info);
3432 status = psa_mac_abort(&operation->ctx.hkdf.hmac);
3433 } else
3434# endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF */
3435# if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
3436 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
3437 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
3438 /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
3439 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
3440 if (operation->ctx.tls12_prf.secret != NULL) {
3441 mbedtls_platform_zeroize(operation->ctx.tls12_prf.secret,
3442 operation->ctx.tls12_prf.secret_length);
3443 mbedtls_free(operation->ctx.tls12_prf.secret);
Steven Cooremana6df6042021-04-29 19:32:25 +02003444 }
3445
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003446 if (operation->ctx.tls12_prf.seed != NULL) {
3447 mbedtls_platform_zeroize(operation->ctx.tls12_prf.seed,
3448 operation->ctx.tls12_prf.seed_length);
3449 mbedtls_free(operation->ctx.tls12_prf.seed);
Janos Follath6a1d2622019-06-11 10:37:28 +01003450 }
3451
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003452 if (operation->ctx.tls12_prf.label != NULL) {
3453 mbedtls_platform_zeroize(operation->ctx.tls12_prf.label,
3454 operation->ctx.tls12_prf.label_length);
3455 mbedtls_free(operation->ctx.tls12_prf.label);
Janos Follath6a1d2622019-06-11 10:37:28 +01003456 }
3457
Steven Cooremana6df6042021-04-29 19:32:25 +02003458 status = PSA_SUCCESS;
Janos Follath6a1d2622019-06-11 10:37:28 +01003459
3460 /* We leave the fields Ai and output_block to be erased safely by the
3461 * mbedtls_platform_zeroize() in the end of this function. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003462 } else
3463# endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
3464 * defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003465 {
3466 status = PSA_ERROR_BAD_STATE;
3467 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003468 mbedtls_platform_zeroize(operation, sizeof(*operation));
3469 return status;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003470}
3471
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003472psa_status_t
3473psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation,
3474 size_t *capacity)
Gilles Peskineeab56e42018-07-12 17:12:33 +02003475{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003476 if (operation->alg == 0) {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003477 /* This is a blank key derivation operation. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003478 return PSA_ERROR_BAD_STATE;
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003479 }
3480
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003481 *capacity = operation->capacity;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003482 return PSA_SUCCESS;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003483}
3484
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003485psa_status_t
3486psa_key_derivation_set_capacity(psa_key_derivation_operation_t *operation,
3487 size_t capacity)
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003488{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003489 if (operation->alg == 0)
3490 return PSA_ERROR_BAD_STATE;
3491 if (capacity > operation->capacity)
3492 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003493 operation->capacity = capacity;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003494 return PSA_SUCCESS;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003495}
3496
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003497# if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003498/* Read some bytes from an HKDF-based operation. This performs a chunk
Gilles Peskinebef7f142018-07-12 17:22:21 +02003499 * of the expand phase of the HKDF algorithm. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003500static psa_status_t
3501psa_key_derivation_hkdf_read(psa_hkdf_key_derivation_t *hkdf,
3502 psa_algorithm_t hash_alg,
3503 uint8_t *output,
3504 size_t output_length)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003505{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003506 uint8_t hash_length = PSA_HASH_LENGTH(hash_alg);
Steven Cooremand1ed1d92021-04-29 19:11:25 +02003507 size_t hmac_output_length;
Gilles Peskinebef7f142018-07-12 17:22:21 +02003508 psa_status_t status;
3509
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003510 if (hkdf->state < HKDF_STATE_KEYED || !hkdf->info_set)
3511 return PSA_ERROR_BAD_STATE;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003512 hkdf->state = HKDF_STATE_OUTPUT;
3513
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003514 while (output_length != 0) {
Gilles Peskinebef7f142018-07-12 17:22:21 +02003515 /* Copy what remains of the current block */
3516 uint8_t n = hash_length - hkdf->offset_in_block;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003517 if (n > output_length)
3518 n = (uint8_t)output_length;
3519 memcpy(output, hkdf->output_block + hkdf->offset_in_block, n);
Gilles Peskinebef7f142018-07-12 17:22:21 +02003520 output += n;
3521 output_length -= n;
3522 hkdf->offset_in_block += n;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003523 if (output_length == 0)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003524 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003525 /* We can't be wanting more output after block 0xff, otherwise
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02003526 * the capacity check in psa_key_derivation_output_bytes() would have
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003527 * prevented this call. It could happen only if the operation
Gilles Peskined54931c2018-07-17 21:06:59 +02003528 * object was corrupted or if this function is called directly
3529 * inside the library. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003530 if (hkdf->block_number == 0xff)
3531 return PSA_ERROR_BAD_STATE;
Gilles Peskinebef7f142018-07-12 17:22:21 +02003532
3533 /* We need a new block */
3534 ++hkdf->block_number;
3535 hkdf->offset_in_block = 0;
Steven Cooremand1ed1d92021-04-29 19:11:25 +02003536
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003537 status = psa_key_derivation_start_hmac(&hkdf->hmac, hash_alg, hkdf->prk,
3538 hash_length);
3539 if (status != PSA_SUCCESS)
3540 return status;
Steven Cooremand1ed1d92021-04-29 19:11:25 +02003541
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003542 if (hkdf->block_number != 1) {
3543 status =
3544 psa_mac_update(&hkdf->hmac, hkdf->output_block, hash_length);
3545 if (status != PSA_SUCCESS)
3546 return status;
Gilles Peskinebef7f142018-07-12 17:22:21 +02003547 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003548 status = psa_mac_update(&hkdf->hmac, hkdf->info, hkdf->info_length);
3549 if (status != PSA_SUCCESS)
3550 return status;
3551 status = psa_mac_update(&hkdf->hmac, &hkdf->block_number, 1);
3552 if (status != PSA_SUCCESS)
3553 return status;
3554 status = psa_mac_sign_finish(&hkdf->hmac, hkdf->output_block,
3555 sizeof(hkdf->output_block),
3556 &hmac_output_length);
3557 if (status != PSA_SUCCESS)
3558 return status;
Gilles Peskinebef7f142018-07-12 17:22:21 +02003559 }
3560
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003561 return PSA_SUCCESS;
Gilles Peskinebef7f142018-07-12 17:22:21 +02003562}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003563# endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003564
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003565# if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
3566 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
Janos Follath7742fee2019-06-17 12:58:10 +01003567static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
3568 psa_tls12_prf_key_derivation_t *tls12_prf,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003569 psa_algorithm_t alg)
Janos Follath7742fee2019-06-17 12:58:10 +01003570{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003571 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(alg);
3572 uint8_t hash_length = PSA_HASH_LENGTH(hash_alg);
Steven Cooremana6df6042021-04-29 19:32:25 +02003573 psa_mac_operation_t hmac = PSA_MAC_OPERATION_INIT;
3574 size_t hmac_output_length;
Janos Follathea29bfb2019-06-19 12:21:20 +01003575 psa_status_t status, cleanup_status;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003576
Janos Follath7742fee2019-06-17 12:58:10 +01003577 /* We can't be wanting more output after block 0xff, otherwise
3578 * the capacity check in psa_key_derivation_output_bytes() would have
3579 * prevented this call. It could happen only if the operation
3580 * object was corrupted or if this function is called directly
3581 * inside the library. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003582 if (tls12_prf->block_number == 0xff)
3583 return PSA_ERROR_CORRUPTION_DETECTED;
Janos Follath7742fee2019-06-17 12:58:10 +01003584
3585 /* We need a new block */
3586 ++tls12_prf->block_number;
Janos Follath844eb0e2019-06-19 12:10:49 +01003587 tls12_prf->left_in_block = hash_length;
Janos Follath7742fee2019-06-17 12:58:10 +01003588
3589 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3590 *
3591 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3592 *
3593 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3594 * HMAC_hash(secret, A(2) + seed) +
3595 * HMAC_hash(secret, A(3) + seed) + ...
3596 *
3597 * A(0) = seed
Janos Follathea29bfb2019-06-19 12:21:20 +01003598 * A(i) = HMAC_hash(secret, A(i-1))
Janos Follath7742fee2019-06-17 12:58:10 +01003599 *
Janos Follathea29bfb2019-06-19 12:21:20 +01003600 * The `psa_tls12_prf_key_derivation` structure saves the block
Janos Follath7742fee2019-06-17 12:58:10 +01003601 * `HMAC_hash(secret, A(i) + seed)` from which the output
Janos Follath76c39842019-06-26 12:50:36 +01003602 * is currently extracted as `output_block` and where i is
3603 * `block_number`.
Janos Follath7742fee2019-06-17 12:58:10 +01003604 */
3605
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003606 status = psa_key_derivation_start_hmac(&hmac, hash_alg, tls12_prf->secret,
3607 tls12_prf->secret_length);
3608 if (status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003609 goto cleanup;
3610
3611 /* Calculate A(i) where i = tls12_prf->block_number. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003612 if (tls12_prf->block_number == 1) {
Janos Follathea29bfb2019-06-19 12:21:20 +01003613 /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads
3614 * the variable seed and in this instance means it in the context of the
3615 * P_hash function, where seed = label + seed.) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003616 status =
3617 psa_mac_update(&hmac, tls12_prf->label, tls12_prf->label_length);
3618 if (status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003619 goto cleanup;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003620 status = psa_mac_update(&hmac, tls12_prf->seed, tls12_prf->seed_length);
3621 if (status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003622 goto cleanup;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003623 } else {
Janos Follathea29bfb2019-06-19 12:21:20 +01003624 /* A(i) = HMAC_hash(secret, A(i-1)) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003625 status = psa_mac_update(&hmac, tls12_prf->Ai, hash_length);
3626 if (status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003627 goto cleanup;
3628 }
3629
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003630 status = psa_mac_sign_finish(&hmac, tls12_prf->Ai, hash_length,
3631 &hmac_output_length);
3632 if (hmac_output_length != hash_length)
Steven Cooremana6df6042021-04-29 19:32:25 +02003633 status = PSA_ERROR_CORRUPTION_DETECTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003634 if (status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003635 goto cleanup;
3636
3637 /* Calculate HMAC_hash(secret, A(i) + label + seed). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003638 status = psa_key_derivation_start_hmac(&hmac, hash_alg, tls12_prf->secret,
3639 tls12_prf->secret_length);
3640 if (status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003641 goto cleanup;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003642 status = psa_mac_update(&hmac, tls12_prf->Ai, hash_length);
3643 if (status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003644 goto cleanup;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003645 status = psa_mac_update(&hmac, tls12_prf->label, tls12_prf->label_length);
3646 if (status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003647 goto cleanup;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003648 status = psa_mac_update(&hmac, tls12_prf->seed, tls12_prf->seed_length);
3649 if (status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003650 goto cleanup;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003651 status = psa_mac_sign_finish(&hmac, tls12_prf->output_block, hash_length,
3652 &hmac_output_length);
3653 if (status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003654 goto cleanup;
3655
Janos Follath7742fee2019-06-17 12:58:10 +01003656cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003657 cleanup_status = psa_mac_abort(&hmac);
3658 if (status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS)
Janos Follathea29bfb2019-06-19 12:21:20 +01003659 status = cleanup_status;
3660
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003661 return status;
Janos Follath7742fee2019-06-17 12:58:10 +01003662}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003663
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003664static psa_status_t
3665psa_key_derivation_tls12_prf_read(psa_tls12_prf_key_derivation_t *tls12_prf,
3666 psa_algorithm_t alg,
3667 uint8_t *output,
3668 size_t output_length)
Janos Follath844eb0e2019-06-19 12:10:49 +01003669{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003670 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH(alg);
3671 uint8_t hash_length = PSA_HASH_LENGTH(hash_alg);
Janos Follath844eb0e2019-06-19 12:10:49 +01003672 psa_status_t status;
3673 uint8_t offset, length;
3674
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003675 switch (tls12_prf->state) {
Gilles Peskineb1edaec2021-06-11 22:41:46 +02003676 case PSA_TLS12_PRF_STATE_LABEL_SET:
3677 tls12_prf->state = PSA_TLS12_PRF_STATE_OUTPUT;
3678 break;
3679 case PSA_TLS12_PRF_STATE_OUTPUT:
3680 break;
3681 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003682 return PSA_ERROR_BAD_STATE;
Gilles Peskineb1edaec2021-06-11 22:41:46 +02003683 }
3684
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003685 while (output_length != 0) {
Janos Follath844eb0e2019-06-19 12:10:49 +01003686 /* Check if we have fully processed the current block. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003687 if (tls12_prf->left_in_block == 0) {
3688 status = psa_key_derivation_tls12_prf_generate_next_block(tls12_prf,
3689 alg);
3690 if (status != PSA_SUCCESS)
3691 return status;
Janos Follath844eb0e2019-06-19 12:10:49 +01003692
3693 continue;
3694 }
3695
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003696 if (tls12_prf->left_in_block > output_length)
3697 length = (uint8_t)output_length;
Janos Follath844eb0e2019-06-19 12:10:49 +01003698 else
3699 length = tls12_prf->left_in_block;
3700
3701 offset = hash_length - tls12_prf->left_in_block;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003702 memcpy(output, tls12_prf->output_block + offset, length);
Janos Follath844eb0e2019-06-19 12:10:49 +01003703 output += length;
3704 output_length -= length;
3705 tls12_prf->left_in_block -= length;
3706 }
3707
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003708 return PSA_SUCCESS;
Janos Follath844eb0e2019-06-19 12:10:49 +01003709}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003710# endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF || \
3711 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003712
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003713psa_status_t
3714psa_key_derivation_output_bytes(psa_key_derivation_operation_t *operation,
3715 uint8_t *output,
3716 size_t output_length)
Gilles Peskineeab56e42018-07-12 17:12:33 +02003717{
3718 psa_status_t status;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003719 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
Gilles Peskineeab56e42018-07-12 17:12:33 +02003720
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003721 if (operation->alg == 0) {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003722 /* This is a blank operation. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003723 return PSA_ERROR_BAD_STATE;
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003724 }
3725
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003726 if (output_length > operation->capacity) {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003727 operation->capacity = 0;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003728 /* Go through the error path to wipe all confidential data now
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003729 * that the operation object is useless. */
David Saadab4ecc272019-02-14 13:48:10 +02003730 status = PSA_ERROR_INSUFFICIENT_DATA;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003731 goto exit;
3732 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003733 if (output_length == 0 && operation->capacity == 0) {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003734 /* Edge case: this is a finished operation, and 0 bytes
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003735 * were requested. The right error in this case could
Gilles Peskineeab56e42018-07-12 17:12:33 +02003736 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3737 * INSUFFICIENT_CAPACITY, which is right for a finished
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003738 * operation, for consistency with the case when
Gilles Peskineeab56e42018-07-12 17:12:33 +02003739 * output_length > 0. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003740 return PSA_ERROR_INSUFFICIENT_DATA;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003741 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003742 operation->capacity -= output_length;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003743
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003744# if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
3745 if (PSA_ALG_IS_HKDF(kdf_alg)) {
3746 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
3747 status = psa_key_derivation_hkdf_read(&operation->ctx.hkdf, hash_alg,
3748 output, output_length);
3749 } else
3750# endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
3751# if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
3752 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
3753 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
3754 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
3755 status = psa_key_derivation_tls12_prf_read(
3756 &operation->ctx.tls12_prf, kdf_alg, output, output_length);
3757 } else
3758# endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF || \
3759 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003760 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003761 (void)kdf_alg;
3762 return PSA_ERROR_BAD_STATE;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003763 }
3764
3765exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003766 if (status != PSA_SUCCESS) {
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003767 /* Preserve the algorithm upon errors, but clear all sensitive state.
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003768 * This allows us to differentiate between exhausted operations and
3769 * blank operations, so we can return PSA_ERROR_BAD_STATE on blank
3770 * operations. */
3771 psa_algorithm_t alg = operation->alg;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003772 psa_key_derivation_abort(operation);
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003773 operation->alg = alg;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003774 memset(output, '!', output_length);
Gilles Peskineeab56e42018-07-12 17:12:33 +02003775 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003776 return status;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003777}
3778
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003779# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
3780static void psa_des_set_key_parity(uint8_t *data, size_t data_size)
Gilles Peskine08542d82018-07-19 17:05:42 +02003781{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003782 if (data_size >= 8)
3783 mbedtls_des_key_set_parity(data);
3784 if (data_size >= 16)
3785 mbedtls_des_key_set_parity(data + 8);
3786 if (data_size >= 24)
3787 mbedtls_des_key_set_parity(data + 16);
Gilles Peskine08542d82018-07-19 17:05:42 +02003788}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003789# endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
Gilles Peskine08542d82018-07-19 17:05:42 +02003790
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003791static psa_status_t
3792psa_generate_derived_key_internal(psa_key_slot_t *slot,
3793 size_t bits,
3794 psa_key_derivation_operation_t *operation)
Gilles Peskineeab56e42018-07-12 17:12:33 +02003795{
3796 uint8_t *data = NULL;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003797 size_t bytes = PSA_BITS_TO_BYTES(bits);
Gilles Peskineeab56e42018-07-12 17:12:33 +02003798 psa_status_t status;
3799
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003800 if (!key_type_is_raw_bytes(slot->attr.type))
3801 return PSA_ERROR_INVALID_ARGUMENT;
3802 if (bits % 8 != 0)
3803 return PSA_ERROR_INVALID_ARGUMENT;
3804 data = mbedtls_calloc(1, bytes);
3805 if (data == NULL)
3806 return PSA_ERROR_INSUFFICIENT_MEMORY;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003807
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003808 status = psa_key_derivation_output_bytes(operation, data, bytes);
3809 if (status != PSA_SUCCESS)
Gilles Peskineeab56e42018-07-12 17:12:33 +02003810 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003811# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
3812 if (slot->attr.type == PSA_KEY_TYPE_DES)
3813 psa_des_set_key_parity(data, bytes);
3814# endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
Ronald Crondd04d422020-11-28 15:14:42 +01003815
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003816 status = psa_allocate_buffer_to_slot(slot, bytes);
3817 if (status != PSA_SUCCESS)
Paul Elliottda3e7db2021-02-09 18:58:20 +00003818 goto exit;
Ronald Crondd04d422020-11-28 15:14:42 +01003819
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003820 slot->attr.bits = (psa_key_bits_t)bits;
3821 psa_key_attributes_t attributes = { .core = slot->attr };
Ronald Cron2ebfdcc2020-11-28 15:54:54 +01003822
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003823 status = psa_driver_wrapper_import_key(&attributes, data, bytes,
3824 slot->key.data, slot->key.bytes,
3825 &slot->key.bytes, &bits);
3826 if (bits != slot->attr.bits)
Ronald Cronbf33c932020-11-28 18:06:53 +01003827 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003828
3829exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003830 mbedtls_free(data);
3831 return status;
Gilles Peskineeab56e42018-07-12 17:12:33 +02003832}
3833
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003834psa_status_t
3835psa_key_derivation_output_key(const psa_key_attributes_t *attributes,
3836 psa_key_derivation_operation_t *operation,
3837 mbedtls_svc_key_id_t *key)
Gilles Peskineff5f0e72019-04-18 12:53:30 +02003838{
3839 psa_status_t status;
3840 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02003841 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine0f84d622019-09-12 19:03:13 +02003842
Ronald Cron81709fc2020-11-14 12:10:32 +01003843 *key = MBEDTLS_SVC_KEY_ID_INIT;
3844
Gilles Peskine0f84d622019-09-12 19:03:13 +02003845 /* Reject any attempt to create a zero-length key so that we don't
3846 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003847 if (psa_get_key_bits(attributes) == 0)
3848 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine0f84d622019-09-12 19:03:13 +02003849
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003850 if (!operation->can_output_key)
3851 return PSA_ERROR_NOT_PERMITTED;
Gilles Peskine178c9aa2019-09-24 18:21:06 +02003852
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003853 status = psa_start_key_creation(PSA_KEY_CREATION_DERIVE, attributes, &slot,
3854 &driver);
3855# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
3856 if (driver != NULL) {
Gilles Peskinef4ee6622019-07-24 13:44:30 +02003857 /* Deriving a key in a secure element is not implemented yet. */
3858 status = PSA_ERROR_NOT_SUPPORTED;
3859 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003860# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
3861 if (status == PSA_SUCCESS) {
3862 status = psa_generate_derived_key_internal(slot, attributes->core.bits,
3863 operation);
Gilles Peskineff5f0e72019-04-18 12:53:30 +02003864 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003865 if (status == PSA_SUCCESS)
3866 status = psa_finish_key_creation(slot, driver, key);
3867 if (status != PSA_SUCCESS)
3868 psa_fail_key_creation(slot, driver);
Ronald Cronf95a2b12020-10-22 15:24:49 +02003869
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003870 return status;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02003871}
3872
Gilles Peskineeab56e42018-07-12 17:12:33 +02003873/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003874/* Key derivation */
3875/****************************************************************/
3876
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003877# if defined(AT_LEAST_ONE_BUILTIN_KDF)
3878static psa_status_t
3879psa_key_derivation_setup_kdf(psa_key_derivation_operation_t *operation,
3880 psa_algorithm_t kdf_alg)
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003881{
John Durkop07cc04a2020-11-16 22:08:34 -08003882 int is_kdf_alg_supported;
3883
Janos Follath5fe19732019-06-20 15:09:30 +01003884 /* Make sure that operation->ctx is properly zero-initialised. (Macro
3885 * initialisers for this union leave some bytes unspecified.) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003886 memset(&operation->ctx, 0, sizeof(operation->ctx));
Janos Follath5fe19732019-06-20 15:09:30 +01003887
Gilles Peskine969c5d62019-01-16 15:53:06 +01003888 /* Make sure that kdf_alg is a supported key derivation algorithm. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003889# if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
3890 if (PSA_ALG_IS_HKDF(kdf_alg))
John Durkop07cc04a2020-11-16 22:08:34 -08003891 is_kdf_alg_supported = 1;
3892 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003893# endif
3894# if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
3895 if (PSA_ALG_IS_TLS12_PRF(kdf_alg))
John Durkop07cc04a2020-11-16 22:08:34 -08003896 is_kdf_alg_supported = 1;
3897 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003898# endif
3899# if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
3900 if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg))
John Durkop07cc04a2020-11-16 22:08:34 -08003901 is_kdf_alg_supported = 1;
3902 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003903# endif
3904 is_kdf_alg_supported = 0;
John Durkop07cc04a2020-11-16 22:08:34 -08003905
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003906 if (is_kdf_alg_supported) {
3907 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
3908 size_t hash_size = PSA_HASH_LENGTH(hash_alg);
3909 if (hash_size == 0)
3910 return PSA_ERROR_NOT_SUPPORTED;
3911 if ((PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
3912 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) &&
3913 !(hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384)) {
3914 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003915 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003916 operation->capacity = 255 * hash_size;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003917 return PSA_SUCCESS;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003918 }
John Durkop07cc04a2020-11-16 22:08:34 -08003919
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003920 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine969c5d62019-01-16 15:53:06 +01003921}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003922# endif /* AT_LEAST_ONE_BUILTIN_KDF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01003923
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003924psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation,
3925 psa_algorithm_t alg)
Gilles Peskine969c5d62019-01-16 15:53:06 +01003926{
3927 psa_status_t status;
3928
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003929 if (operation->alg != 0)
3930 return PSA_ERROR_BAD_STATE;
Gilles Peskine969c5d62019-01-16 15:53:06 +01003931
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003932 if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg))
3933 return PSA_ERROR_INVALID_ARGUMENT;
3934 else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
3935# if defined(AT_LEAST_ONE_BUILTIN_KDF)
3936 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
3937 status = psa_key_derivation_setup_kdf(operation, kdf_alg);
3938# else
3939 return PSA_ERROR_NOT_SUPPORTED;
3940# endif /* AT_LEAST_ONE_BUILTIN_KDF */
3941 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
3942# if defined(AT_LEAST_ONE_BUILTIN_KDF)
3943 status = psa_key_derivation_setup_kdf(operation, alg);
3944# else
3945 return PSA_ERROR_NOT_SUPPORTED;
3946# endif /* AT_LEAST_ONE_BUILTIN_KDF */
3947 } else
3948 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969c5d62019-01-16 15:53:06 +01003949
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003950 if (status == PSA_SUCCESS)
Gilles Peskine51ae0e42019-05-16 17:31:03 +02003951 operation->alg = alg;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003952 return status;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003953}
3954
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003955# if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
3956static psa_status_t psa_hkdf_input(psa_hkdf_key_derivation_t *hkdf,
3957 psa_algorithm_t hash_alg,
3958 psa_key_derivation_step_t step,
3959 const uint8_t *data,
3960 size_t data_length)
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003961{
3962 psa_status_t status;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003963 switch (step) {
Gilles Peskine03410b52019-05-16 16:05:19 +02003964 case PSA_KEY_DERIVATION_INPUT_SALT:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003965 if (hkdf->state != HKDF_STATE_INIT)
3966 return PSA_ERROR_BAD_STATE;
3967 else {
3968 status = psa_key_derivation_start_hmac(&hkdf->hmac, hash_alg,
3969 data, data_length);
3970 if (status != PSA_SUCCESS)
3971 return status;
Steven Cooremand1ed1d92021-04-29 19:11:25 +02003972 hkdf->state = HKDF_STATE_STARTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003973 return PSA_SUCCESS;
Steven Cooremand1ed1d92021-04-29 19:11:25 +02003974 }
Gilles Peskine03410b52019-05-16 16:05:19 +02003975 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003976 /* If no salt was provided, use an empty salt. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003977 if (hkdf->state == HKDF_STATE_INIT) {
3978 status = psa_key_derivation_start_hmac(&hkdf->hmac, hash_alg,
3979 NULL, 0);
3980 if (status != PSA_SUCCESS)
3981 return status;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003982 hkdf->state = HKDF_STATE_STARTED;
3983 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003984 if (hkdf->state != HKDF_STATE_STARTED)
3985 return PSA_ERROR_BAD_STATE;
3986 status = psa_mac_update(&hkdf->hmac, data, data_length);
3987 if (status != PSA_SUCCESS)
3988 return status;
3989 status = psa_mac_sign_finish(&hkdf->hmac, hkdf->prk,
3990 sizeof(hkdf->prk), &data_length);
3991 if (status != PSA_SUCCESS)
3992 return status;
3993 hkdf->offset_in_block = PSA_HASH_LENGTH(hash_alg);
Gilles Peskine2b522db2019-04-12 15:11:49 +02003994 hkdf->block_number = 0;
3995 hkdf->state = HKDF_STATE_KEYED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003996 return PSA_SUCCESS;
Gilles Peskine03410b52019-05-16 16:05:19 +02003997 case PSA_KEY_DERIVATION_INPUT_INFO:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003998 if (hkdf->state == HKDF_STATE_OUTPUT)
3999 return PSA_ERROR_BAD_STATE;
4000 if (hkdf->info_set)
4001 return PSA_ERROR_BAD_STATE;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004002 hkdf->info_length = data_length;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004003 if (data_length != 0) {
4004 hkdf->info = mbedtls_calloc(1, data_length);
4005 if (hkdf->info == NULL)
4006 return PSA_ERROR_INSUFFICIENT_MEMORY;
4007 memcpy(hkdf->info, data, data_length);
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004008 }
4009 hkdf->info_set = 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004010 return PSA_SUCCESS;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004011 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004012 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004013 }
4014}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004015# endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
Janos Follathb03233e2019-06-11 15:30:30 +01004016
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004017# if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4018 defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4019static psa_status_t psa_tls12_prf_set_seed(psa_tls12_prf_key_derivation_t *prf,
4020 const uint8_t *data,
4021 size_t data_length)
Janos Follathf08e2652019-06-13 09:05:41 +01004022{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004023 if (prf->state != PSA_TLS12_PRF_STATE_INIT)
4024 return PSA_ERROR_BAD_STATE;
Janos Follathf08e2652019-06-13 09:05:41 +01004025
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004026 if (data_length != 0) {
4027 prf->seed = mbedtls_calloc(1, data_length);
4028 if (prf->seed == NULL)
4029 return PSA_ERROR_INSUFFICIENT_MEMORY;
Janos Follathf08e2652019-06-13 09:05:41 +01004030
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004031 memcpy(prf->seed, data, data_length);
Janos Follathd6dce9f2019-07-04 09:11:38 +01004032 prf->seed_length = data_length;
4033 }
Janos Follathf08e2652019-06-13 09:05:41 +01004034
Gilles Peskine43f958b2020-12-13 14:55:14 +01004035 prf->state = PSA_TLS12_PRF_STATE_SEED_SET;
Janos Follathf08e2652019-06-13 09:05:41 +01004036
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004037 return PSA_SUCCESS;
Janos Follathf08e2652019-06-13 09:05:41 +01004038}
4039
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004040static psa_status_t psa_tls12_prf_set_key(psa_tls12_prf_key_derivation_t *prf,
4041 const uint8_t *data,
4042 size_t data_length)
Janos Follath81550542019-06-13 14:26:34 +01004043{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004044 if (prf->state != PSA_TLS12_PRF_STATE_SEED_SET)
4045 return PSA_ERROR_BAD_STATE;
Janos Follath81550542019-06-13 14:26:34 +01004046
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004047 if (data_length != 0) {
4048 prf->secret = mbedtls_calloc(1, data_length);
4049 if (prf->secret == NULL)
4050 return PSA_ERROR_INSUFFICIENT_MEMORY;
Steven Cooremana6df6042021-04-29 19:32:25 +02004051
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004052 memcpy(prf->secret, data, data_length);
Steven Cooremana6df6042021-04-29 19:32:25 +02004053 prf->secret_length = data_length;
4054 }
Janos Follath81550542019-06-13 14:26:34 +01004055
Gilles Peskine43f958b2020-12-13 14:55:14 +01004056 prf->state = PSA_TLS12_PRF_STATE_KEY_SET;
Janos Follath81550542019-06-13 14:26:34 +01004057
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004058 return PSA_SUCCESS;
Janos Follath81550542019-06-13 14:26:34 +01004059}
4060
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004061static psa_status_t psa_tls12_prf_set_label(psa_tls12_prf_key_derivation_t *prf,
4062 const uint8_t *data,
4063 size_t data_length)
Janos Follath63028dd2019-06-13 09:15:47 +01004064{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004065 if (prf->state != PSA_TLS12_PRF_STATE_KEY_SET)
4066 return PSA_ERROR_BAD_STATE;
Janos Follath63028dd2019-06-13 09:15:47 +01004067
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004068 if (data_length != 0) {
4069 prf->label = mbedtls_calloc(1, data_length);
4070 if (prf->label == NULL)
4071 return PSA_ERROR_INSUFFICIENT_MEMORY;
Janos Follath63028dd2019-06-13 09:15:47 +01004072
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004073 memcpy(prf->label, data, data_length);
Janos Follathd6dce9f2019-07-04 09:11:38 +01004074 prf->label_length = data_length;
4075 }
Janos Follath63028dd2019-06-13 09:15:47 +01004076
Gilles Peskine43f958b2020-12-13 14:55:14 +01004077 prf->state = PSA_TLS12_PRF_STATE_LABEL_SET;
Janos Follath63028dd2019-06-13 09:15:47 +01004078
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004079 return PSA_SUCCESS;
Janos Follath63028dd2019-06-13 09:15:47 +01004080}
4081
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004082static psa_status_t psa_tls12_prf_input(psa_tls12_prf_key_derivation_t *prf,
4083 psa_key_derivation_step_t step,
4084 const uint8_t *data,
4085 size_t data_length)
Janos Follathb03233e2019-06-11 15:30:30 +01004086{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004087 switch (step) {
Janos Follathf08e2652019-06-13 09:05:41 +01004088 case PSA_KEY_DERIVATION_INPUT_SEED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004089 return psa_tls12_prf_set_seed(prf, data, data_length);
Janos Follath81550542019-06-13 14:26:34 +01004090 case PSA_KEY_DERIVATION_INPUT_SECRET:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004091 return psa_tls12_prf_set_key(prf, data, data_length);
Janos Follath63028dd2019-06-13 09:15:47 +01004092 case PSA_KEY_DERIVATION_INPUT_LABEL:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004093 return psa_tls12_prf_set_label(prf, data, data_length);
Janos Follathb03233e2019-06-11 15:30:30 +01004094 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004095 return PSA_ERROR_INVALID_ARGUMENT;
Janos Follathb03233e2019-06-11 15:30:30 +01004096 }
4097}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004098# endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
4099 * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
John Durkop07cc04a2020-11-16 22:08:34 -08004100
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004101# if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4102static psa_status_t
4103psa_tls12_prf_psk_to_ms_set_key(psa_tls12_prf_key_derivation_t *prf,
4104 const uint8_t *data,
4105 size_t data_length)
John Durkop07cc04a2020-11-16 22:08:34 -08004106{
4107 psa_status_t status;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004108 uint8_t pms[4 + 2 * PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE];
John Durkop07cc04a2020-11-16 22:08:34 -08004109 uint8_t *cur = pms;
4110
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004111 if (data_length > PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE)
4112 return PSA_ERROR_INVALID_ARGUMENT;
John Durkop07cc04a2020-11-16 22:08:34 -08004113
4114 /* Quoting RFC 4279, Section 2:
4115 *
4116 * The premaster secret is formed as follows: if the PSK is N octets
4117 * long, concatenate a uint16 with the value N, N zero octets, a second
4118 * uint16 with the value N, and the PSK itself.
4119 */
4120
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004121 *cur++ = (data_length >> 8) & 0xff;
4122 *cur++ = (data_length >> 0) & 0xff;
4123 memset(cur, 0, data_length);
John Durkop07cc04a2020-11-16 22:08:34 -08004124 cur += data_length;
4125 *cur++ = pms[0];
4126 *cur++ = pms[1];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004127 memcpy(cur, data, data_length);
John Durkop07cc04a2020-11-16 22:08:34 -08004128 cur += data_length;
4129
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004130 status = psa_tls12_prf_set_key(prf, pms, cur - pms);
John Durkop07cc04a2020-11-16 22:08:34 -08004131
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004132 mbedtls_platform_zeroize(pms, sizeof(pms));
4133 return status;
John Durkop07cc04a2020-11-16 22:08:34 -08004134}
Janos Follath6660f0e2019-06-17 08:44:03 +01004135
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004136static psa_status_t
4137psa_tls12_prf_psk_to_ms_input(psa_tls12_prf_key_derivation_t *prf,
4138 psa_key_derivation_step_t step,
4139 const uint8_t *data,
4140 size_t data_length)
Janos Follath6660f0e2019-06-17 08:44:03 +01004141{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004142 if (step == PSA_KEY_DERIVATION_INPUT_SECRET) {
4143 return (psa_tls12_prf_psk_to_ms_set_key(prf, data, data_length));
Janos Follath0c1ed842019-06-28 13:35:36 +01004144 }
Janos Follath6660f0e2019-06-17 08:44:03 +01004145
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004146 return psa_tls12_prf_input(prf, step, data, data_length);
Janos Follath6660f0e2019-06-17 08:44:03 +01004147}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004148# endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004149
Gilles Peskineb8965192019-09-24 16:21:10 +02004150/** Check whether the given key type is acceptable for the given
4151 * input step of a key derivation.
4152 *
4153 * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE.
4154 * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA.
4155 * Both secret and non-secret inputs can alternatively have the type
4156 * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning
4157 * that the input was passed as a buffer rather than via a key object.
4158 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004159static int psa_key_derivation_check_input_type(psa_key_derivation_step_t step,
4160 psa_key_type_t key_type)
Gilles Peskine224b0d62019-09-23 18:13:17 +02004161{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004162 switch (step) {
Gilles Peskine224b0d62019-09-23 18:13:17 +02004163 case PSA_KEY_DERIVATION_INPUT_SECRET:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004164 if (key_type == PSA_KEY_TYPE_DERIVE)
4165 return PSA_SUCCESS;
4166 if (key_type == PSA_KEY_TYPE_NONE)
4167 return PSA_SUCCESS;
Gilles Peskine224b0d62019-09-23 18:13:17 +02004168 break;
4169 case PSA_KEY_DERIVATION_INPUT_LABEL:
4170 case PSA_KEY_DERIVATION_INPUT_SALT:
4171 case PSA_KEY_DERIVATION_INPUT_INFO:
4172 case PSA_KEY_DERIVATION_INPUT_SEED:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004173 if (key_type == PSA_KEY_TYPE_RAW_DATA)
4174 return PSA_SUCCESS;
4175 if (key_type == PSA_KEY_TYPE_NONE)
4176 return PSA_SUCCESS;
Gilles Peskine224b0d62019-09-23 18:13:17 +02004177 break;
4178 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004179 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine224b0d62019-09-23 18:13:17 +02004180}
4181
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004182static psa_status_t
4183psa_key_derivation_input_internal(psa_key_derivation_operation_t *operation,
4184 psa_key_derivation_step_t step,
4185 psa_key_type_t key_type,
4186 const uint8_t *data,
4187 size_t data_length)
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004188{
Gilles Peskine46d7faf2019-09-23 19:22:55 +02004189 psa_status_t status;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004190 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
Gilles Peskine46d7faf2019-09-23 19:22:55 +02004191
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004192 status = psa_key_derivation_check_input_type(step, key_type);
4193 if (status != PSA_SUCCESS)
Gilles Peskine224b0d62019-09-23 18:13:17 +02004194 goto exit;
4195
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004196# if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF)
4197 if (PSA_ALG_IS_HKDF(kdf_alg)) {
4198 status = psa_hkdf_input(&operation->ctx.hkdf,
4199 PSA_ALG_HKDF_GET_HASH(kdf_alg), step, data,
4200 data_length);
4201 } else
4202# endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */
4203# if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF)
4204 if (PSA_ALG_IS_TLS12_PRF(kdf_alg)) {
4205 status = psa_tls12_prf_input(&operation->ctx.tls12_prf, step, data,
4206 data_length);
4207 } else
4208# endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF */
4209# if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
4210 if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
4211 status = psa_tls12_prf_psk_to_ms_input(&operation->ctx.tls12_prf, step,
4212 data, data_length);
4213 } else
4214# endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004215 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004216 /* This can't happen unless the operation object was not initialized */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004217 (void)data;
4218 (void)data_length;
4219 (void)kdf_alg;
4220 return PSA_ERROR_BAD_STATE;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004221 }
4222
Gilles Peskine224b0d62019-09-23 18:13:17 +02004223exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004224 if (status != PSA_SUCCESS)
4225 psa_key_derivation_abort(operation);
4226 return status;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004227}
4228
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004229psa_status_t
4230psa_key_derivation_input_bytes(psa_key_derivation_operation_t *operation,
4231 psa_key_derivation_step_t step,
4232 const uint8_t *data,
4233 size_t data_length)
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01004234{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004235 return (psa_key_derivation_input_internal(
4236 operation, step, PSA_KEY_TYPE_NONE, data, data_length));
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01004237}
4238
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004239psa_status_t
4240psa_key_derivation_input_key(psa_key_derivation_operation_t *operation,
4241 psa_key_derivation_step_t step,
4242 mbedtls_svc_key_id_t key)
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004243{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004244 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004245 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004246 psa_key_slot_t *slot;
Gilles Peskine178c9aa2019-09-24 18:21:06 +02004247
Ronald Cron5c522922020-11-14 16:35:34 +01004248 status = psa_get_and_lock_transparent_key_slot_with_policy(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004249 key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg);
4250 if (status != PSA_SUCCESS) {
4251 psa_key_derivation_abort(operation);
4252 return status;
Gilles Peskine593773d2019-09-23 18:17:40 +02004253 }
Gilles Peskine178c9aa2019-09-24 18:21:06 +02004254
4255 /* Passing a key object as a SECRET input unlocks the permission
4256 * to output to a key object. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004257 if (step == PSA_KEY_DERIVATION_INPUT_SECRET)
Gilles Peskine178c9aa2019-09-24 18:21:06 +02004258 operation->can_output_key = 1;
4259
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004260 status = psa_key_derivation_input_internal(operation, step, slot->attr.type,
4261 slot->key.data, slot->key.bytes);
Ronald Cronf95a2b12020-10-22 15:24:49 +02004262
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004263 unlock_status = psa_unlock_key_slot(slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +02004264
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004265 return (status == PSA_SUCCESS) ? unlock_status : status;
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004266}
Gilles Peskineea0fb492018-07-12 17:17:20 +02004267
Gilles Peskineea0fb492018-07-12 17:17:20 +02004268/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02004269/* Key agreement */
4270/****************************************************************/
4271
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004272# if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
4273static psa_status_t psa_key_agreement_ecdh(const uint8_t *peer_key,
4274 size_t peer_key_length,
4275 const mbedtls_ecp_keypair *our_key,
4276 uint8_t *shared_secret,
4277 size_t shared_secret_size,
4278 size_t *shared_secret_length)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004279{
Steven Cooremand4867872020-08-05 16:31:39 +02004280 mbedtls_ecp_keypair *their_key = NULL;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004281 mbedtls_ecdh_context ecdh;
Jaeden Amero97271b32019-01-10 19:38:51 +00004282 psa_status_t status;
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01004283 size_t bits = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004284 psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(our_key->grp.id, &bits);
4285 mbedtls_ecdh_init(&ecdh);
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004286
Ronald Cron90857082020-11-25 14:58:33 +01004287 status = mbedtls_psa_ecp_load_representation(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004288 PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve), bits, peer_key, peer_key_length,
4289 &their_key);
4290 if (status != PSA_SUCCESS)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004291 goto exit;
4292
Jaeden Amero97271b32019-01-10 19:38:51 +00004293 status = mbedtls_to_psa_error(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004294 mbedtls_ecdh_get_params(&ecdh, their_key, MBEDTLS_ECDH_THEIRS));
4295 if (status != PSA_SUCCESS)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004296 goto exit;
Jaeden Amero97271b32019-01-10 19:38:51 +00004297 status = mbedtls_to_psa_error(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004298 mbedtls_ecdh_get_params(&ecdh, our_key, MBEDTLS_ECDH_OURS));
4299 if (status != PSA_SUCCESS)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004300 goto exit;
4301
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004302 status = mbedtls_to_psa_error(mbedtls_ecdh_calc_secret(
4303 &ecdh, shared_secret_length, shared_secret, shared_secret_size,
4304 mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE));
4305 if (status != PSA_SUCCESS)
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01004306 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004307 if (PSA_BITS_TO_BYTES(bits) != *shared_secret_length)
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01004308 status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004309
4310exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004311 if (status != PSA_SUCCESS)
4312 mbedtls_platform_zeroize(shared_secret, shared_secret_size);
4313 mbedtls_ecdh_free(&ecdh);
4314 mbedtls_ecp_keypair_free(their_key);
4315 mbedtls_free(their_key);
Steven Cooremana2371e52020-07-28 14:30:39 +02004316
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004317 return status;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004318}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004319# endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004320
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004321# define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
Gilles Peskine01d718c2018-09-18 12:01:02 +02004322
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004323static psa_status_t psa_key_agreement_raw_internal(psa_algorithm_t alg,
4324 psa_key_slot_t *private_key,
4325 const uint8_t *peer_key,
4326 size_t peer_key_length,
4327 uint8_t *shared_secret,
4328 size_t shared_secret_size,
4329 size_t *shared_secret_length)
Gilles Peskine01d718c2018-09-18 12:01:02 +02004330{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004331 switch (alg) {
4332# if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
Gilles Peskine0216fe12019-04-11 21:23:21 +02004333 case PSA_ALG_ECDH:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004334 if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(private_key->attr.type))
4335 return PSA_ERROR_INVALID_ARGUMENT;
Steven Cooremana2371e52020-07-28 14:30:39 +02004336 mbedtls_ecp_keypair *ecp = NULL;
Ronald Cron90857082020-11-25 14:58:33 +01004337 psa_status_t status = mbedtls_psa_ecp_load_representation(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004338 private_key->attr.type, private_key->attr.bits,
4339 private_key->key.data, private_key->key.bytes, &ecp);
4340 if (status != PSA_SUCCESS)
4341 return status;
4342 status = psa_key_agreement_ecdh(peer_key, peer_key_length, ecp,
4343 shared_secret, shared_secret_size,
4344 shared_secret_length);
4345 mbedtls_ecp_keypair_free(ecp);
4346 mbedtls_free(ecp);
4347 return status;
4348# endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004349 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004350 (void)private_key;
4351 (void)peer_key;
4352 (void)peer_key_length;
4353 (void)shared_secret;
4354 (void)shared_secret_size;
4355 (void)shared_secret_length;
4356 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004357 }
Gilles Peskine0216fe12019-04-11 21:23:21 +02004358}
4359
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004360/* Note that if this function fails, you must call psa_key_derivation_abort()
Gilles Peskine01d718c2018-09-18 12:01:02 +02004361 * to potentially free embedded data structures and wipe confidential data.
4362 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004363static psa_status_t
4364psa_key_agreement_internal(psa_key_derivation_operation_t *operation,
4365 psa_key_derivation_step_t step,
4366 psa_key_slot_t *private_key,
4367 const uint8_t *peer_key,
4368 size_t peer_key_length)
Gilles Peskine01d718c2018-09-18 12:01:02 +02004369{
4370 psa_status_t status;
4371 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4372 size_t shared_secret_length = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004373 psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE(operation->alg);
Gilles Peskine01d718c2018-09-18 12:01:02 +02004374
4375 /* Step 1: run the secret agreement algorithm to generate the shared
4376 * secret. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004377 status = psa_key_agreement_raw_internal(ka_alg, private_key, peer_key,
4378 peer_key_length, shared_secret,
4379 sizeof(shared_secret),
4380 &shared_secret_length);
4381 if (status != PSA_SUCCESS)
Gilles Peskine12313cd2018-06-20 00:20:32 +02004382 goto exit;
4383
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004384 /* Step 2: set up the key derivation to generate key material from
Gilles Peskine224b0d62019-09-23 18:13:17 +02004385 * the shared secret. A shared secret is permitted wherever a key
4386 * of type DERIVE is permitted. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004387 status =
4388 psa_key_derivation_input_internal(operation, step, PSA_KEY_TYPE_DERIVE,
4389 shared_secret, shared_secret_length);
Gilles Peskine12313cd2018-06-20 00:20:32 +02004390exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004391 mbedtls_platform_zeroize(shared_secret, shared_secret_length);
4392 return status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004393}
4394
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004395psa_status_t
4396psa_key_derivation_key_agreement(psa_key_derivation_operation_t *operation,
4397 psa_key_derivation_step_t step,
4398 mbedtls_svc_key_id_t private_key,
4399 const uint8_t *peer_key,
4400 size_t peer_key_length)
Gilles Peskine12313cd2018-06-20 00:20:32 +02004401{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004402 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004403 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2f060a82018-12-04 17:12:32 +01004404 psa_key_slot_t *slot;
Ronald Cronf95a2b12020-10-22 15:24:49 +02004405
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004406 if (!PSA_ALG_IS_KEY_AGREEMENT(operation->alg))
4407 return PSA_ERROR_INVALID_ARGUMENT;
Ronald Cron5c522922020-11-14 16:35:34 +01004408 status = psa_get_and_lock_transparent_key_slot_with_policy(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004409 private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg);
4410 if (status != PSA_SUCCESS)
4411 return status;
4412 status = psa_key_agreement_internal(operation, step, slot, peer_key,
4413 peer_key_length);
4414 if (status != PSA_SUCCESS)
4415 psa_key_derivation_abort(operation);
4416 else {
Steven Cooremanfa5e6312020-10-15 17:07:12 +02004417 /* If a private key has been added as SECRET, we allow the derived
4418 * key material to be used as a key in PSA Crypto. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004419 if (step == PSA_KEY_DERIVATION_INPUT_SECRET)
Steven Cooremanfa5e6312020-10-15 17:07:12 +02004420 operation->can_output_key = 1;
4421 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004422
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004423 unlock_status = psa_unlock_key_slot(slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +02004424
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004425 return (status == PSA_SUCCESS) ? unlock_status : status;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02004426}
4427
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004428psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
4429 mbedtls_svc_key_id_t private_key,
4430 const uint8_t *peer_key,
4431 size_t peer_key_length,
4432 uint8_t *output,
4433 size_t output_size,
4434 size_t *output_length)
Gilles Peskine0216fe12019-04-11 21:23:21 +02004435{
Ronald Cronf95a2b12020-10-22 15:24:49 +02004436 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron5c522922020-11-14 16:35:34 +01004437 psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cronf95a2b12020-10-22 15:24:49 +02004438 psa_key_slot_t *slot = NULL;
Gilles Peskine0216fe12019-04-11 21:23:21 +02004439
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004440 if (!PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Gilles Peskine0216fe12019-04-11 21:23:21 +02004441 status = PSA_ERROR_INVALID_ARGUMENT;
4442 goto exit;
4443 }
Ronald Cron5c522922020-11-14 16:35:34 +01004444 status = psa_get_and_lock_transparent_key_slot_with_policy(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004445 private_key, &slot, PSA_KEY_USAGE_DERIVE, alg);
4446 if (status != PSA_SUCCESS)
Gilles Peskine0216fe12019-04-11 21:23:21 +02004447 goto exit;
4448
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004449 status = psa_key_agreement_raw_internal(alg, slot, peer_key,
4450 peer_key_length, output,
4451 output_size, output_length);
Gilles Peskine0216fe12019-04-11 21:23:21 +02004452
4453exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004454 if (status != PSA_SUCCESS) {
Gilles Peskine0216fe12019-04-11 21:23:21 +02004455 /* If an error happens and is not handled properly, the output
4456 * may be used as a key to protect sensitive data. Arrange for such
4457 * a key to be random, which is likely to result in decryption or
4458 * verification errors. This is better than filling the buffer with
4459 * some constant data such as zeros, which would result in the data
4460 * being protected with a reproducible, easily knowable key.
4461 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004462 psa_generate_random(output, output_size);
Gilles Peskine0216fe12019-04-11 21:23:21 +02004463 *output_length = output_size;
4464 }
Ronald Cronf95a2b12020-10-22 15:24:49 +02004465
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004466 unlock_status = psa_unlock_key_slot(slot);
Ronald Cronf95a2b12020-10-22 15:24:49 +02004467
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004468 return (status == PSA_SUCCESS) ? unlock_status : status;
Gilles Peskine0216fe12019-04-11 21:23:21 +02004469}
Gilles Peskine86a440b2018-11-12 18:39:40 +01004470
Gilles Peskine86a440b2018-11-12 18:39:40 +01004471/****************************************************************/
4472/* Random generation */
Gilles Peskine53d991e2018-07-12 01:14:59 +02004473/****************************************************************/
Gilles Peskine12313cd2018-06-20 00:20:32 +02004474
Gilles Peskine30524eb2020-11-13 17:02:26 +01004475/** Initialize the PSA random generator.
4476 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004477static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng)
Gilles Peskine30524eb2020-11-13 17:02:26 +01004478{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004479# if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
4480 memset(rng, 0, sizeof(*rng));
4481# else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01004482
Gilles Peskine30524eb2020-11-13 17:02:26 +01004483 /* Set default configuration if
4484 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004485 if (rng->entropy_init == NULL)
Gilles Peskine30524eb2020-11-13 17:02:26 +01004486 rng->entropy_init = mbedtls_entropy_init;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004487 if (rng->entropy_free == NULL)
Gilles Peskine30524eb2020-11-13 17:02:26 +01004488 rng->entropy_free = mbedtls_entropy_free;
4489
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004490 rng->entropy_init(&rng->entropy);
4491# if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
4492 defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
Gilles Peskine30524eb2020-11-13 17:02:26 +01004493 /* The PSA entropy injection feature depends on using NV seed as an entropy
4494 * source. Add NV seed as an entropy source for PSA entropy injection. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004495 mbedtls_entropy_add_source(&rng->entropy, mbedtls_nv_seed_poll, NULL,
4496 MBEDTLS_ENTROPY_BLOCK_SIZE,
4497 MBEDTLS_ENTROPY_SOURCE_STRONG);
4498# endif
Gilles Peskine30524eb2020-11-13 17:02:26 +01004499
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004500 mbedtls_psa_drbg_init(MBEDTLS_PSA_RANDOM_STATE);
4501# endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01004502}
4503
4504/** Deinitialize the PSA random generator.
4505 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004506static void mbedtls_psa_random_free(mbedtls_psa_random_context_t *rng)
Gilles Peskine30524eb2020-11-13 17:02:26 +01004507{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004508# if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
4509 memset(rng, 0, sizeof(*rng));
4510# else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
4511 mbedtls_psa_drbg_free(MBEDTLS_PSA_RANDOM_STATE);
4512 rng->entropy_free(&rng->entropy);
4513# endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01004514}
4515
4516/** Seed the PSA random generator.
4517 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004518static psa_status_t mbedtls_psa_random_seed(mbedtls_psa_random_context_t *rng)
Gilles Peskine30524eb2020-11-13 17:02:26 +01004519{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004520# if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01004521 /* Do nothing: the external RNG seeds itself. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004522 (void)rng;
4523 return PSA_SUCCESS;
4524# else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01004525 const unsigned char drbg_seed[] = "PSA";
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004526 int ret =
4527 mbedtls_psa_drbg_seed(&rng->entropy, drbg_seed, sizeof(drbg_seed) - 1);
4528 return mbedtls_to_psa_error(ret);
4529# endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine30524eb2020-11-13 17:02:26 +01004530}
4531
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004532psa_status_t psa_generate_random(uint8_t *output, size_t output_size)
Gilles Peskinee59236f2018-01-27 23:32:46 +01004533{
Gilles Peskinee59236f2018-01-27 23:32:46 +01004534 GUARD_MODULE_INITIALIZED;
4535
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004536# if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01004537
4538 size_t output_length = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004539 psa_status_t status = mbedtls_psa_external_get_random(
4540 &global_data.rng, output, output_size, &output_length);
4541 if (status != PSA_SUCCESS)
4542 return status;
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01004543 /* Breaking up a request into smaller chunks is currently not supported
4544 * for the extrernal RNG interface. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004545 if (output_length != output_size)
4546 return PSA_ERROR_INSUFFICIENT_ENTROPY;
4547 return PSA_SUCCESS;
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01004548
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004549# else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine4fc21fd2020-11-13 18:47:18 +01004550
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004551 while (output_size > 0) {
4552 size_t request_size = (output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
4553 MBEDTLS_PSA_RANDOM_MAX_REQUEST :
4554 output_size);
4555 int ret = mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, output,
4556 request_size);
4557 if (ret != 0)
4558 return mbedtls_to_psa_error(ret);
Gilles Peskine71ddab92021-01-04 21:01:07 +01004559 output_size -= request_size;
4560 output += request_size;
Gilles Peskinef181eca2019-08-07 13:49:00 +02004561 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004562 return PSA_SUCCESS;
4563# endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004564}
4565
Gilles Peskine8814fc42020-12-14 15:33:44 +01004566/* Wrapper function allowing the classic API to use the PSA RNG.
Gilles Peskine9c3e0602021-01-05 16:03:55 +01004567 *
4568 * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
4569 * `psa_generate_random(...)`. The state parameter is ignored since the
4570 * PSA API doesn't support passing an explicit state.
4571 *
4572 * In the non-external case, psa_generate_random() calls an
4573 * `mbedtls_xxx_drbg_random` function which has exactly the same signature
4574 * and semantics as mbedtls_psa_get_random(). As an optimization,
4575 * instead of doing this back-and-forth between the PSA API and the
4576 * classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
4577 * as a constant function pointer to `mbedtls_xxx_drbg_random`.
Gilles Peskine8814fc42020-12-14 15:33:44 +01004578 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004579# if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
4580int mbedtls_psa_get_random(void *p_rng,
4581 unsigned char *output,
4582 size_t output_size)
Gilles Peskine8814fc42020-12-14 15:33:44 +01004583{
Gilles Peskine9c3e0602021-01-05 16:03:55 +01004584 /* This function takes a pointer to the RNG state because that's what
4585 * classic mbedtls functions using an RNG expect. The PSA RNG manages
4586 * its own state internally and doesn't let the caller access that state.
4587 * So we just ignore the state parameter, and in practice we'll pass
4588 * NULL. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004589 (void)p_rng;
4590 psa_status_t status = psa_generate_random(output, output_size);
4591 if (status == PSA_SUCCESS)
4592 return 0;
Gilles Peskine8814fc42020-12-14 15:33:44 +01004593 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004594 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
Gilles Peskine8814fc42020-12-14 15:33:44 +01004595}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004596# endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
Gilles Peskine8814fc42020-12-14 15:33:44 +01004597
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004598# if defined(MBEDTLS_PSA_INJECT_ENTROPY)
4599# include "entropy_poll.h"
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01004600
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004601psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, size_t seed_size)
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004602{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004603 if (global_data.initialized)
4604 return PSA_ERROR_NOT_PERMITTED;
Netanel Gonen21f37cb2018-11-19 11:53:55 +02004605
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004606 if (((seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM) ||
4607 (seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE)) ||
4608 (seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE))
4609 return PSA_ERROR_INVALID_ARGUMENT;
Netanel Gonen21f37cb2018-11-19 11:53:55 +02004610
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004611 return mbedtls_psa_storage_inject_entropy(seed, seed_size);
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004612}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004613# endif /* MBEDTLS_PSA_INJECT_ENTROPY */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004614
Ronald Cron3772afe2021-02-08 16:10:05 +01004615/** Validate the key type and size for key generation
Ronald Cron01b2aba2020-10-05 09:42:02 +02004616 *
Ronald Cron3772afe2021-02-08 16:10:05 +01004617 * \param type The key type
4618 * \param bits The number of bits of the key
Ronald Cron01b2aba2020-10-05 09:42:02 +02004619 *
4620 * \retval #PSA_SUCCESS
Ronald Cron3772afe2021-02-08 16:10:05 +01004621 * The key type and size are valid.
Ronald Cron01b2aba2020-10-05 09:42:02 +02004622 * \retval #PSA_ERROR_INVALID_ARGUMENT
4623 * The size in bits of the key is not valid.
4624 * \retval #PSA_ERROR_NOT_SUPPORTED
4625 * The type and/or the size in bits of the key or the combination of
4626 * the two is not supported.
4627 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004628static psa_status_t
4629psa_validate_key_type_and_size_for_key_generation(psa_key_type_t type,
4630 size_t bits)
Gilles Peskinee59236f2018-01-27 23:32:46 +01004631{
Ronald Cronf3bb7612020-10-02 20:11:59 +02004632 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004633
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004634 if (key_type_is_raw_bytes(type)) {
4635 status = validate_unstructured_key_bit_size(type, bits);
4636 if (status != PSA_SUCCESS)
4637 return status;
4638 } else
4639# if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
4640 if (PSA_KEY_TYPE_IS_RSA(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
4641 if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS)
4642 return PSA_ERROR_NOT_SUPPORTED;
Steven Cooreman81be2fa2020-07-24 22:04:59 +02004643
Ronald Cron01b2aba2020-10-05 09:42:02 +02004644 /* Accept only byte-aligned keys, for the same reasons as
4645 * in psa_import_rsa_key(). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004646 if (bits % 8 != 0)
4647 return PSA_ERROR_NOT_SUPPORTED;
4648 } else
4649# endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) */
Ronald Cron01b2aba2020-10-05 09:42:02 +02004650
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004651# if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
4652 if (PSA_KEY_TYPE_IS_ECC(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
Ronald Crond81ab562021-02-16 09:01:16 +01004653 /* To avoid empty block, return successfully here. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004654 return PSA_SUCCESS;
4655 } else
4656# endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) */
Ronald Cron01b2aba2020-10-05 09:42:02 +02004657 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004658 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron01b2aba2020-10-05 09:42:02 +02004659 }
4660
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004661 return PSA_SUCCESS;
Ronald Cron01b2aba2020-10-05 09:42:02 +02004662}
4663
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004664psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes,
4665 uint8_t *key_buffer,
4666 size_t key_buffer_size,
4667 size_t *key_buffer_length)
Ronald Cron01b2aba2020-10-05 09:42:02 +02004668{
4669 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron2a38a6b2020-10-02 20:02:04 +02004670 psa_key_type_t type = attributes->core.type;
Ronald Cron01b2aba2020-10-05 09:42:02 +02004671
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004672 if ((attributes->domain_parameters == NULL) &&
4673 (attributes->domain_parameters_size != 0))
4674 return PSA_ERROR_INVALID_ARGUMENT;
Ronald Cron01b2aba2020-10-05 09:42:02 +02004675
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004676 if (key_type_is_raw_bytes(type)) {
4677 status = psa_generate_random(key_buffer, key_buffer_size);
4678 if (status != PSA_SUCCESS)
4679 return status;
Steven Cooreman81be2fa2020-07-24 22:04:59 +02004680
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004681# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
4682 if (type == PSA_KEY_TYPE_DES)
4683 psa_des_set_key_parity(key_buffer, key_buffer_size);
4684# endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
4685 } else
4686# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) && \
4687 defined(MBEDTLS_GENPRIME)
4688 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
4689 return (mbedtls_psa_rsa_generate_key(
4690 attributes, key_buffer, key_buffer_size, key_buffer_length));
4691 } else
4692# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) \
4693 * defined(MBEDTLS_GENPRIME) */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004694
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004695# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
4696 if (PSA_KEY_TYPE_IS_ECC(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
4697 return (mbedtls_psa_ecp_generate_key(
4698 attributes, key_buffer, key_buffer_size, key_buffer_length));
4699 } else
4700# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
Steven Cooreman29149862020-08-05 15:43:42 +02004701 {
Ronald Cron2a38a6b2020-10-02 20:02:04 +02004702 (void)key_buffer_length;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004703 return PSA_ERROR_NOT_SUPPORTED;
Steven Cooreman29149862020-08-05 15:43:42 +02004704 }
Gilles Peskinee59236f2018-01-27 23:32:46 +01004705
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004706 return PSA_SUCCESS;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004707}
Darryl Green0c6575a2018-11-07 16:05:30 +00004708
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004709psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
4710 mbedtls_svc_key_id_t *key)
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004711{
4712 psa_status_t status;
4713 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02004714 psa_se_drv_table_entry_t *driver = NULL;
Ronald Cron2b56bc82020-10-05 10:02:26 +02004715 size_t key_buffer_size;
Gilles Peskine11792082019-08-06 18:36:36 +02004716
Ronald Cron81709fc2020-11-14 12:10:32 +01004717 *key = MBEDTLS_SVC_KEY_ID_INIT;
4718
Gilles Peskine0f84d622019-09-12 19:03:13 +02004719 /* Reject any attempt to create a zero-length key so that we don't
4720 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004721 if (psa_get_key_bits(attributes) == 0)
4722 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine0f84d622019-09-12 19:03:13 +02004723
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004724 status = psa_start_key_creation(PSA_KEY_CREATION_GENERATE, attributes,
4725 &slot, &driver);
4726 if (status != PSA_SUCCESS)
Gilles Peskine11792082019-08-06 18:36:36 +02004727 goto exit;
4728
Ronald Cron977c2472020-10-13 08:32:21 +02004729 /* In the case of a transparent key or an opaque key stored in local
4730 * storage (thus not in the case of generating a key in a secure element
4731 * or cryptoprocessor with storage), we have to allocate a buffer to
4732 * hold the generated key material. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004733 if (slot->key.data == NULL) {
4734 if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime) ==
4735 PSA_KEY_LOCATION_LOCAL_STORAGE) {
Ronald Cron3772afe2021-02-08 16:10:05 +01004736 status = psa_validate_key_type_and_size_for_key_generation(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004737 attributes->core.type, attributes->core.bits);
4738 if (status != PSA_SUCCESS)
Ronald Cron3772afe2021-02-08 16:10:05 +01004739 goto exit;
4740
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004741 key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(attributes->core.type,
4742 attributes->core.bits);
4743 } else {
4744 status = psa_driver_wrapper_get_key_buffer_size(attributes,
4745 &key_buffer_size);
4746 if (status != PSA_SUCCESS)
Ronald Cron3772afe2021-02-08 16:10:05 +01004747 goto exit;
Ronald Cron977c2472020-10-13 08:32:21 +02004748 }
Ronald Cron977c2472020-10-13 08:32:21 +02004749
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004750 status = psa_allocate_buffer_to_slot(slot, key_buffer_size);
4751 if (status != PSA_SUCCESS)
Ronald Cron977c2472020-10-13 08:32:21 +02004752 goto exit;
4753 }
4754
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004755 status = psa_driver_wrapper_generate_key(attributes, slot->key.data,
4756 slot->key.bytes, &slot->key.bytes);
Gilles Peskine11792082019-08-06 18:36:36 +02004757
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004758 if (status != PSA_SUCCESS)
4759 psa_remove_key_data_from_memory(slot);
Ronald Cron2b56bc82020-10-05 10:02:26 +02004760
Gilles Peskine11792082019-08-06 18:36:36 +02004761exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004762 if (status == PSA_SUCCESS)
4763 status = psa_finish_key_creation(slot, driver, key);
4764 if (status != PSA_SUCCESS)
4765 psa_fail_key_creation(slot, driver);
Ronald Cronf95a2b12020-10-22 15:24:49 +02004766
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004767 return status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004768}
4769
Gilles Peskinee59236f2018-01-27 23:32:46 +01004770/****************************************************************/
4771/* Module setup */
4772/****************************************************************/
4773
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004774# if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
Gilles Peskine5e769522018-11-20 21:59:56 +01004775psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004776 void (*entropy_init)(mbedtls_entropy_context *ctx),
4777 void (*entropy_free)(mbedtls_entropy_context *ctx))
Gilles Peskine5e769522018-11-20 21:59:56 +01004778{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004779 if (global_data.rng_state != RNG_NOT_INITIALIZED)
4780 return PSA_ERROR_BAD_STATE;
Gilles Peskine30524eb2020-11-13 17:02:26 +01004781 global_data.rng.entropy_init = entropy_init;
4782 global_data.rng.entropy_free = entropy_free;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004783 return PSA_SUCCESS;
Gilles Peskine5e769522018-11-20 21:59:56 +01004784}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004785# endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
Gilles Peskine5e769522018-11-20 21:59:56 +01004786
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004787void mbedtls_psa_crypto_free(void)
Gilles Peskinee59236f2018-01-27 23:32:46 +01004788{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004789 psa_wipe_all_key_slots();
4790 if (global_data.rng_state != RNG_NOT_INITIALIZED) {
4791 mbedtls_psa_random_free(&global_data.rng);
Gilles Peskinec6b69072018-11-20 21:42:52 +01004792 }
4793 /* Wipe all remaining data, including configuration.
4794 * In particular, this sets all state indicator to the value
4795 * indicating "uninitialized". */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004796 mbedtls_platform_zeroize(&global_data, sizeof(global_data));
4797# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined0890212019-06-24 14:34:43 +02004798 /* Unregister all secure element drivers, so that we restart from
4799 * a pristine state. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004800 psa_unregister_all_se_drivers();
4801# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004802}
4803
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004804# if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02004805/** Recover a transaction that was interrupted by a power failure.
4806 *
4807 * This function is called during initialization, before psa_crypto_init()
4808 * returns. If this function returns a failure status, the initialization
4809 * fails.
4810 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004811static psa_status_t
4812psa_crypto_recover_transaction(const psa_crypto_transaction_t *transaction)
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02004813{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004814 switch (transaction->unknown.type) {
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02004815 case PSA_CRYPTO_TRANSACTION_CREATE_KEY:
4816 case PSA_CRYPTO_TRANSACTION_DESTROY_KEY:
Janos Follath1d57a202019-08-13 12:15:34 +01004817 /* TODO - fall through to the failure case until this
Gilles Peskinec9d7f942019-08-13 16:17:16 +02004818 * is implemented.
4819 * https://github.com/ARMmbed/mbed-crypto/issues/218
4820 */
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02004821 default:
4822 /* We found an unsupported transaction in the storage.
4823 * We don't know what state the storage is in. Give up. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004824 return PSA_ERROR_DATA_INVALID;
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02004825 }
4826}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004827# endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02004828
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004829psa_status_t psa_crypto_init(void)
Gilles Peskinee59236f2018-01-27 23:32:46 +01004830{
Gilles Peskine66fb1262018-12-10 16:29:04 +01004831 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004832
Gilles Peskinec6b69072018-11-20 21:42:52 +01004833 /* Double initialization is explicitly allowed. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004834 if (global_data.initialized != 0)
4835 return PSA_SUCCESS;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004836
Gilles Peskine30524eb2020-11-13 17:02:26 +01004837 /* Initialize and seed the random generator. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004838 mbedtls_psa_random_init(&global_data.rng);
Gilles Peskinec6b69072018-11-20 21:42:52 +01004839 global_data.rng_state = RNG_INITIALIZED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004840 status = mbedtls_psa_random_seed(&global_data.rng);
4841 if (status != PSA_SUCCESS)
Gilles Peskinee59236f2018-01-27 23:32:46 +01004842 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004843 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004844
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004845 status = psa_initialize_key_slots();
4846 if (status != PSA_SUCCESS)
Gilles Peskine66fb1262018-12-10 16:29:04 +01004847 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004848
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004849# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
4850 status = psa_init_all_se_drivers();
4851 if (status != PSA_SUCCESS)
Gilles Peskined9348f22019-10-01 15:22:29 +02004852 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004853# endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskined9348f22019-10-01 15:22:29 +02004854
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004855# if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
4856 status = psa_crypto_load_transaction();
4857 if (status == PSA_SUCCESS) {
4858 status = psa_crypto_recover_transaction(&psa_crypto_transaction);
4859 if (status != PSA_SUCCESS)
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02004860 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004861 status = psa_crypto_stop_transaction();
4862 } else if (status == PSA_ERROR_DOES_NOT_EXIST) {
Gilles Peskinefc762652019-07-22 19:30:34 +02004863 /* There's no transaction to complete. It's all good. */
4864 status = PSA_SUCCESS;
4865 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004866# endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
Gilles Peskinefc762652019-07-22 19:30:34 +02004867
Gilles Peskinec6b69072018-11-20 21:42:52 +01004868 /* All done. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004869 global_data.initialized = 1;
4870
4871exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004872 if (status != PSA_SUCCESS)
4873 mbedtls_psa_crypto_free();
4874 return status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004875}
4876
4877#endif /* MBEDTLS_PSA_CRYPTO_C */