blob: c812ff4679573d965f2edfd3c84504aa96c3e8ce [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
4/* Copyright (C) 2018, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PSA_CRYPTO_C)
mohammad160327010052018-07-03 13:16:15 +030029
itayzafrir7723ab12019-02-14 10:28:02 +020030#include "psa_crypto_service_integration.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010031#include "psa/crypto.h"
32
Gilles Peskine039b90c2018-12-07 18:24:41 +010033#include "psa_crypto_core.h"
Gilles Peskine5e769522018-11-20 21:59:56 +010034#include "psa_crypto_invasive.h"
Gilles Peskinea8ade162019-06-26 11:24:49 +020035#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined0890212019-06-24 14:34:43 +020036#include "psa_crypto_se.h"
Gilles Peskinea8ade162019-06-26 11:24:49 +020037#endif
Gilles Peskine961849f2018-11-30 18:54:54 +010038#include "psa_crypto_slot_management.h"
Darryl Greend49a4992018-06-18 17:27:26 +010039/* Include internal declarations that are useful for implementing persistently
40 * stored keys. */
41#include "psa_crypto_storage.h"
42
Gilles Peskineb46bef22019-07-30 21:32:04 +020043#include <assert.h>
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010044#include <stdlib.h>
45#include <string.h>
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010046#include "mbedtls/platform.h"
Gilles Peskineff2d2002019-05-06 15:26:23 +020047#if !defined(MBEDTLS_PLATFORM_C)
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010048#define mbedtls_calloc calloc
49#define mbedtls_free free
50#endif
51
Gilles Peskinea5905292018-02-07 20:59:33 +010052#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020053#include "mbedtls/asn1.h"
Jaeden Amero25384a22019-01-10 10:23:21 +000054#include "mbedtls/asn1write.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020055#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010056#include "mbedtls/blowfish.h"
57#include "mbedtls/camellia.h"
Gilles Peskine26869f22019-05-06 15:25:00 +020058#include "mbedtls/chacha20.h"
59#include "mbedtls/chachapoly.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010060#include "mbedtls/cipher.h"
61#include "mbedtls/ccm.h"
62#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010063#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010064#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020065#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010066#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010067#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010068#include "mbedtls/error.h"
69#include "mbedtls/gcm.h"
70#include "mbedtls/md2.h"
71#include "mbedtls/md4.h"
72#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010073#include "mbedtls/md.h"
74#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010075#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010076#include "mbedtls/pk_internal.h"
Gilles Peskine3f108122018-12-07 18:14:53 +010077#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000078#include "mbedtls/error.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010079#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010080#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010081#include "mbedtls/sha1.h"
82#include "mbedtls/sha256.h"
83#include "mbedtls/sha512.h"
84#include "mbedtls/xtea.h"
85
Gilles Peskine996deb12018-08-01 15:45:45 +020086#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
87
Gilles Peskine9ef733f2018-02-07 21:05:37 +010088/* constant-time buffer comparison */
89static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
90{
91 size_t i;
92 unsigned char diff = 0;
93
94 for( i = 0; i < n; i++ )
95 diff |= a[i] ^ b[i];
96
97 return( diff );
98}
99
100
101
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100102/****************************************************************/
103/* Global data, support functions and library management */
104/****************************************************************/
105
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200106static int key_type_is_raw_bytes( psa_key_type_t type )
107{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200108 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200109}
110
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100111/* Values for psa_global_data_t::rng_state */
112#define RNG_NOT_INITIALIZED 0
113#define RNG_INITIALIZED 1
114#define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100115
Gilles Peskine2d277862018-06-18 15:41:12 +0200116typedef struct
117{
Gilles Peskine5e769522018-11-20 21:59:56 +0100118 void (* entropy_init )( mbedtls_entropy_context *ctx );
119 void (* entropy_free )( mbedtls_entropy_context *ctx );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100120 mbedtls_entropy_context entropy;
121 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100122 unsigned initialized : 1;
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100123 unsigned rng_state : 2;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100124} psa_global_data_t;
125
126static psa_global_data_t global_data;
127
itayzafrir0adf0fc2018-09-06 16:24:41 +0300128#define GUARD_MODULE_INITIALIZED \
129 if( global_data.initialized == 0 ) \
130 return( PSA_ERROR_BAD_STATE );
131
Michael Thomas863b5d62020-02-10 19:41:16 +0000132psa_status_t mbedtls_to_psa_error( int ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100133{
Gilles Peskinea5905292018-02-07 20:59:33 +0100134 /* If there's both a high-level code and low-level code, dispatch on
135 * the high-level code. */
136 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100137 {
138 case 0:
139 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100140
141 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
142 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
143 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
144 return( PSA_ERROR_NOT_SUPPORTED );
145 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
146 return( PSA_ERROR_HARDWARE_FAILURE );
147
148 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
149 return( PSA_ERROR_HARDWARE_FAILURE );
150
Gilles Peskine9a944802018-06-21 09:35:35 +0200151 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
152 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
153 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
154 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
155 case MBEDTLS_ERR_ASN1_INVALID_DATA:
156 return( PSA_ERROR_INVALID_ARGUMENT );
157 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
158 return( PSA_ERROR_INSUFFICIENT_MEMORY );
159 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
160 return( PSA_ERROR_BUFFER_TOO_SMALL );
161
Jaeden Amero93e21112019-02-20 13:57:28 +0000162#if defined(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000163 case MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA:
Jaeden Amero93e21112019-02-20 13:57:28 +0000164#elif defined(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH)
165 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
166#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100167 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
168 return( PSA_ERROR_NOT_SUPPORTED );
169 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
170 return( PSA_ERROR_HARDWARE_FAILURE );
171
Jaeden Amero93e21112019-02-20 13:57:28 +0000172#if defined(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000173 case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA:
Jaeden Amero93e21112019-02-20 13:57:28 +0000174#elif defined(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH)
175 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
176#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100177 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
178 return( PSA_ERROR_NOT_SUPPORTED );
179 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
180 return( PSA_ERROR_HARDWARE_FAILURE );
181
182 case MBEDTLS_ERR_CCM_BAD_INPUT:
183 return( PSA_ERROR_INVALID_ARGUMENT );
184 case MBEDTLS_ERR_CCM_AUTH_FAILED:
185 return( PSA_ERROR_INVALID_SIGNATURE );
186 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
187 return( PSA_ERROR_HARDWARE_FAILURE );
188
Gilles Peskine26869f22019-05-06 15:25:00 +0200189 case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA:
190 return( PSA_ERROR_INVALID_ARGUMENT );
191
192 case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE:
193 return( PSA_ERROR_BAD_STATE );
194 case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED:
195 return( PSA_ERROR_INVALID_SIGNATURE );
196
Gilles Peskinea5905292018-02-07 20:59:33 +0100197 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
198 return( PSA_ERROR_NOT_SUPPORTED );
199 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
200 return( PSA_ERROR_INVALID_ARGUMENT );
201 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
202 return( PSA_ERROR_INSUFFICIENT_MEMORY );
203 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
204 return( PSA_ERROR_INVALID_PADDING );
205 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
206 return( PSA_ERROR_BAD_STATE );
207 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
208 return( PSA_ERROR_INVALID_SIGNATURE );
209 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
Gilles Peskine4b3eb692019-05-16 21:35:18 +0200210 return( PSA_ERROR_CORRUPTION_DETECTED );
Gilles Peskinea5905292018-02-07 20:59:33 +0100211 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
212 return( PSA_ERROR_HARDWARE_FAILURE );
213
214 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
215 return( PSA_ERROR_HARDWARE_FAILURE );
216
217 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
218 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
219 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
220 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
221 return( PSA_ERROR_NOT_SUPPORTED );
222 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
223 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
224
225 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
226 return( PSA_ERROR_NOT_SUPPORTED );
227 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
228 return( PSA_ERROR_HARDWARE_FAILURE );
229
Gilles Peskinee59236f2018-01-27 23:32:46 +0100230 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
231 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
232 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
233 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100234
235 case MBEDTLS_ERR_GCM_AUTH_FAILED:
236 return( PSA_ERROR_INVALID_SIGNATURE );
237 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200238 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100239 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
240 return( PSA_ERROR_HARDWARE_FAILURE );
241
242 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
243 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
244 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
245 return( PSA_ERROR_HARDWARE_FAILURE );
246
247 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
248 return( PSA_ERROR_NOT_SUPPORTED );
249 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
250 return( PSA_ERROR_INVALID_ARGUMENT );
251 case MBEDTLS_ERR_MD_ALLOC_FAILED:
252 return( PSA_ERROR_INSUFFICIENT_MEMORY );
253 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
254 return( PSA_ERROR_STORAGE_FAILURE );
255 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
256 return( PSA_ERROR_HARDWARE_FAILURE );
257
Gilles Peskinef76aa772018-10-29 19:24:33 +0100258 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
259 return( PSA_ERROR_STORAGE_FAILURE );
260 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
261 return( PSA_ERROR_INVALID_ARGUMENT );
262 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
263 return( PSA_ERROR_INVALID_ARGUMENT );
264 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
265 return( PSA_ERROR_BUFFER_TOO_SMALL );
266 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
267 return( PSA_ERROR_INVALID_ARGUMENT );
268 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
269 return( PSA_ERROR_INVALID_ARGUMENT );
270 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
271 return( PSA_ERROR_INVALID_ARGUMENT );
272 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
273 return( PSA_ERROR_INSUFFICIENT_MEMORY );
274
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100275 case MBEDTLS_ERR_PK_ALLOC_FAILED:
276 return( PSA_ERROR_INSUFFICIENT_MEMORY );
277 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
278 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
279 return( PSA_ERROR_INVALID_ARGUMENT );
280 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100281 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100282 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
283 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
284 return( PSA_ERROR_INVALID_ARGUMENT );
285 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
286 return( PSA_ERROR_NOT_SUPPORTED );
287 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
288 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
289 return( PSA_ERROR_NOT_PERMITTED );
290 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
291 return( PSA_ERROR_INVALID_ARGUMENT );
292 case MBEDTLS_ERR_PK_INVALID_ALG:
293 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
294 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
295 return( PSA_ERROR_NOT_SUPPORTED );
296 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
297 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100298 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
299 return( PSA_ERROR_HARDWARE_FAILURE );
300
Gilles Peskineff2d2002019-05-06 15:26:23 +0200301 case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED:
302 return( PSA_ERROR_HARDWARE_FAILURE );
303 case MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
304 return( PSA_ERROR_NOT_SUPPORTED );
305
Gilles Peskinea5905292018-02-07 20:59:33 +0100306 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
307 return( PSA_ERROR_HARDWARE_FAILURE );
308
309 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
310 return( PSA_ERROR_INVALID_ARGUMENT );
311 case MBEDTLS_ERR_RSA_INVALID_PADDING:
312 return( PSA_ERROR_INVALID_PADDING );
313 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
314 return( PSA_ERROR_HARDWARE_FAILURE );
315 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
316 return( PSA_ERROR_INVALID_ARGUMENT );
317 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
318 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
Gilles Peskine4b3eb692019-05-16 21:35:18 +0200319 return( PSA_ERROR_CORRUPTION_DETECTED );
Gilles Peskinea5905292018-02-07 20:59:33 +0100320 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
321 return( PSA_ERROR_INVALID_SIGNATURE );
322 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
323 return( PSA_ERROR_BUFFER_TOO_SMALL );
324 case MBEDTLS_ERR_RSA_RNG_FAILED:
325 return( PSA_ERROR_INSUFFICIENT_MEMORY );
326 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
327 return( PSA_ERROR_NOT_SUPPORTED );
328 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
329 return( PSA_ERROR_HARDWARE_FAILURE );
330
331 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
332 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
333 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
334 return( PSA_ERROR_HARDWARE_FAILURE );
335
336 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
337 return( PSA_ERROR_INVALID_ARGUMENT );
338 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
339 return( PSA_ERROR_HARDWARE_FAILURE );
340
itayzafrir5c753392018-05-08 11:18:38 +0300341 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300342 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300343 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300344 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
345 return( PSA_ERROR_BUFFER_TOO_SMALL );
346 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
347 return( PSA_ERROR_NOT_SUPPORTED );
348 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
349 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
350 return( PSA_ERROR_INVALID_SIGNATURE );
351 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
352 return( PSA_ERROR_INSUFFICIENT_MEMORY );
353 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
354 return( PSA_ERROR_HARDWARE_FAILURE );
Janos Follatha13b9052019-11-22 12:48:59 +0000355 case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
356 return( PSA_ERROR_CORRUPTION_DETECTED );
itayzafrir5c753392018-05-08 11:18:38 +0300357
Gilles Peskinee59236f2018-01-27 23:32:46 +0100358 default:
David Saadab4ecc272019-02-14 13:48:10 +0200359 return( PSA_ERROR_GENERIC_ERROR );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100360 }
361}
362
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200363
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200364
365
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100366/****************************************************************/
367/* Key management */
368/****************************************************************/
369
Gilles Peskine73167e12019-07-12 23:44:37 +0200370#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
371static inline int psa_key_slot_is_external( const psa_key_slot_t *slot )
372{
Gilles Peskine8e338702019-07-30 20:06:31 +0200373 return( psa_key_lifetime_is_external( slot->attr.lifetime ) );
Gilles Peskine73167e12019-07-12 23:44:37 +0200374}
375#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
376
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100377#if defined(MBEDTLS_ECP_C)
Gilles Peskine5055b232019-12-12 17:49:31 +0100378psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid,
379 size_t *bits )
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200380{
381 switch( grpid )
382 {
383 case MBEDTLS_ECP_DP_SECP192R1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100384 *bits = 192;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100385 return( PSA_ECC_CURVE_SECP_R1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200386 case MBEDTLS_ECP_DP_SECP224R1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100387 *bits = 224;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100388 return( PSA_ECC_CURVE_SECP_R1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200389 case MBEDTLS_ECP_DP_SECP256R1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100390 *bits = 256;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100391 return( PSA_ECC_CURVE_SECP_R1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200392 case MBEDTLS_ECP_DP_SECP384R1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100393 *bits = 384;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100394 return( PSA_ECC_CURVE_SECP_R1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200395 case MBEDTLS_ECP_DP_SECP521R1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100396 *bits = 521;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100397 return( PSA_ECC_CURVE_SECP_R1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200398 case MBEDTLS_ECP_DP_BP256R1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100399 *bits = 256;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100400 return( PSA_ECC_CURVE_BRAINPOOL_P_R1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200401 case MBEDTLS_ECP_DP_BP384R1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100402 *bits = 384;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100403 return( PSA_ECC_CURVE_BRAINPOOL_P_R1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200404 case MBEDTLS_ECP_DP_BP512R1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100405 *bits = 512;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100406 return( PSA_ECC_CURVE_BRAINPOOL_P_R1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200407 case MBEDTLS_ECP_DP_CURVE25519:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100408 *bits = 255;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100409 return( PSA_ECC_CURVE_MONTGOMERY );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200410 case MBEDTLS_ECP_DP_SECP192K1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100411 *bits = 192;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100412 return( PSA_ECC_CURVE_SECP_K1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200413 case MBEDTLS_ECP_DP_SECP224K1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100414 *bits = 224;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100415 return( PSA_ECC_CURVE_SECP_K1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200416 case MBEDTLS_ECP_DP_SECP256K1:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100417 *bits = 256;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100418 return( PSA_ECC_CURVE_SECP_K1 );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200419 case MBEDTLS_ECP_DP_CURVE448:
Gilles Peskinec7ef5b32019-12-12 16:58:00 +0100420 *bits = 448;
Gilles Peskineb87b7192019-12-04 16:24:10 +0100421 return( PSA_ECC_CURVE_MONTGOMERY );
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200422 default:
423 return( 0 );
424 }
425}
426
Gilles Peskine5055b232019-12-12 17:49:31 +0100427mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve,
428 size_t byte_length )
Gilles Peskine12313cd2018-06-20 00:20:32 +0200429{
430 switch( curve )
431 {
Gilles Peskine228abc52019-12-03 17:24:19 +0100432 case PSA_ECC_CURVE_SECP_R1:
433 switch( byte_length )
434 {
435 case PSA_BITS_TO_BYTES( 192 ):
436 return( MBEDTLS_ECP_DP_SECP192R1 );
437 case PSA_BITS_TO_BYTES( 224 ):
438 return( MBEDTLS_ECP_DP_SECP224R1 );
439 case PSA_BITS_TO_BYTES( 256 ):
440 return( MBEDTLS_ECP_DP_SECP256R1 );
441 case PSA_BITS_TO_BYTES( 384 ):
442 return( MBEDTLS_ECP_DP_SECP384R1 );
443 case PSA_BITS_TO_BYTES( 521 ):
444 return( MBEDTLS_ECP_DP_SECP521R1 );
445 default:
446 return( MBEDTLS_ECP_DP_NONE );
447 }
448 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100449
450 case PSA_ECC_CURVE_BRAINPOOL_P_R1:
451 switch( byte_length )
452 {
453 case PSA_BITS_TO_BYTES( 256 ):
454 return( MBEDTLS_ECP_DP_BP256R1 );
455 case PSA_BITS_TO_BYTES( 384 ):
456 return( MBEDTLS_ECP_DP_BP384R1 );
457 case PSA_BITS_TO_BYTES( 512 ):
458 return( MBEDTLS_ECP_DP_BP512R1 );
459 default:
460 return( MBEDTLS_ECP_DP_NONE );
461 }
462 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100463
464 case PSA_ECC_CURVE_MONTGOMERY:
465 switch( byte_length )
466 {
467 case PSA_BITS_TO_BYTES( 255 ):
468 return( MBEDTLS_ECP_DP_CURVE25519 );
469 case PSA_BITS_TO_BYTES( 448 ):
470 return( MBEDTLS_ECP_DP_CURVE448 );
471 default:
472 return( MBEDTLS_ECP_DP_NONE );
473 }
474 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100475
476 case PSA_ECC_CURVE_SECP_K1:
477 switch( byte_length )
478 {
479 case PSA_BITS_TO_BYTES( 192 ):
480 return( MBEDTLS_ECP_DP_SECP192K1 );
481 case PSA_BITS_TO_BYTES( 224 ):
482 return( MBEDTLS_ECP_DP_SECP224K1 );
483 case PSA_BITS_TO_BYTES( 256 ):
484 return( MBEDTLS_ECP_DP_SECP256K1 );
485 default:
486 return( MBEDTLS_ECP_DP_NONE );
487 }
488 break;
Gilles Peskine228abc52019-12-03 17:24:19 +0100489
Gilles Peskine12313cd2018-06-20 00:20:32 +0200490 default:
491 return( MBEDTLS_ECP_DP_NONE );
492 }
493}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100494#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200495
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200496static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
497 size_t bits,
498 struct raw_data *raw )
499{
500 /* Check that the bit size is acceptable for the key type */
501 switch( type )
502 {
503 case PSA_KEY_TYPE_RAW_DATA:
504#if defined(MBEDTLS_MD_C)
505 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200506#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200507 case PSA_KEY_TYPE_DERIVE:
508 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200509#if defined(MBEDTLS_AES_C)
510 case PSA_KEY_TYPE_AES:
511 if( bits != 128 && bits != 192 && bits != 256 )
512 return( PSA_ERROR_INVALID_ARGUMENT );
513 break;
514#endif
515#if defined(MBEDTLS_CAMELLIA_C)
516 case PSA_KEY_TYPE_CAMELLIA:
517 if( bits != 128 && bits != 192 && bits != 256 )
518 return( PSA_ERROR_INVALID_ARGUMENT );
519 break;
520#endif
521#if defined(MBEDTLS_DES_C)
522 case PSA_KEY_TYPE_DES:
523 if( bits != 64 && bits != 128 && bits != 192 )
524 return( PSA_ERROR_INVALID_ARGUMENT );
525 break;
526#endif
527#if defined(MBEDTLS_ARC4_C)
528 case PSA_KEY_TYPE_ARC4:
529 if( bits < 8 || bits > 2048 )
530 return( PSA_ERROR_INVALID_ARGUMENT );
531 break;
532#endif
Gilles Peskine26869f22019-05-06 15:25:00 +0200533#if defined(MBEDTLS_CHACHA20_C)
534 case PSA_KEY_TYPE_CHACHA20:
535 if( bits != 256 )
536 return( PSA_ERROR_INVALID_ARGUMENT );
537 break;
538#endif
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200539 default:
540 return( PSA_ERROR_NOT_SUPPORTED );
541 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200542 if( bits % 8 != 0 )
543 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200544
545 /* Allocate memory for the key */
546 raw->bytes = PSA_BITS_TO_BYTES( bits );
547 raw->data = mbedtls_calloc( 1, raw->bytes );
548 if( raw->data == NULL )
549 {
550 raw->bytes = 0;
551 return( PSA_ERROR_INSUFFICIENT_MEMORY );
552 }
553 return( PSA_SUCCESS );
554}
555
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200556#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine86a440b2018-11-12 18:39:40 +0100557/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
558 * that are not a multiple of 8) well. For example, there is only
559 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
560 * way to return the exact bit size of a key.
561 * To keep things simple, reject non-byte-aligned key sizes. */
562static psa_status_t psa_check_rsa_key_byte_aligned(
563 const mbedtls_rsa_context *rsa )
564{
565 mbedtls_mpi n;
566 psa_status_t status;
567 mbedtls_mpi_init( &n );
568 status = mbedtls_to_psa_error(
569 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
570 if( status == PSA_SUCCESS )
571 {
572 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
573 status = PSA_ERROR_NOT_SUPPORTED;
574 }
575 mbedtls_mpi_free( &n );
576 return( status );
577}
578
Michael Thomas1ed98bd2020-02-18 22:11:30 +0000579psa_status_t psa_import_rsa_key( psa_key_type_t type,
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000580 const uint8_t *data,
581 size_t data_length,
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200582 mbedtls_rsa_context **p_rsa )
583{
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000584 psa_status_t status;
585 mbedtls_pk_context pk;
586 mbedtls_rsa_context *rsa;
587 size_t bits;
588
589 mbedtls_pk_init( &pk );
590
591 /* Parse the data. */
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200592 if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000593 status = mbedtls_to_psa_error(
594 mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200595 else
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000596 status = mbedtls_to_psa_error(
597 mbedtls_pk_parse_public_key( &pk, data, data_length ) );
598 if( status != PSA_SUCCESS )
599 goto exit;
600
601 /* We have something that the pkparse module recognizes. If it is a
602 * valid RSA key, store it. */
603 if( mbedtls_pk_get_type( &pk ) != MBEDTLS_PK_RSA )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200604 {
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000605 status = PSA_ERROR_INVALID_ARGUMENT;
606 goto exit;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200607 }
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000608
609 rsa = mbedtls_pk_rsa( pk );
610 /* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
611 * supports non-byte-aligned key sizes, but not well. For example,
612 * mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
613 bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
614 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
615 {
616 status = PSA_ERROR_NOT_SUPPORTED;
617 goto exit;
618 }
619 status = psa_check_rsa_key_byte_aligned( rsa );
620
621exit:
622 /* Free the content of the pk object only on error. */
623 if( status != PSA_SUCCESS )
624 {
625 mbedtls_pk_free( &pk );
626 return( status );
627 }
628
629 /* On success, store the content of the object in the RSA context. */
630 *p_rsa = rsa;
631
632 return( PSA_SUCCESS );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200633}
634#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
635
Jaeden Ameroccdce902019-01-10 11:42:27 +0000636#if defined(MBEDTLS_ECP_C)
Gilles Peskine4cd32772019-12-02 20:49:42 +0100637static psa_status_t psa_prepare_import_ec_key( psa_ecc_curve_t curve,
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100638 size_t data_length,
639 int is_public,
Gilles Peskine4cd32772019-12-02 20:49:42 +0100640 mbedtls_ecp_keypair **p_ecp )
641{
642 mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
643 *p_ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
644 if( *p_ecp == NULL )
645 return( PSA_ERROR_INSUFFICIENT_MEMORY );
646 mbedtls_ecp_keypair_init( *p_ecp );
647
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100648 if( is_public )
649 {
650 /* A public key is represented as:
651 * - The byte 0x04;
652 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
653 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
654 * So its data length is 2m+1 where n is the key size in bits.
655 */
656 if( ( data_length & 1 ) == 0 )
657 return( PSA_ERROR_INVALID_ARGUMENT );
658 data_length = data_length / 2;
659 }
660
Gilles Peskine4cd32772019-12-02 20:49:42 +0100661 /* Load the group. */
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100662 grp_id = mbedtls_ecc_group_of_psa( curve, data_length );
663 if( grp_id == MBEDTLS_ECP_DP_NONE )
664 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4cd32772019-12-02 20:49:42 +0100665 return( mbedtls_to_psa_error(
666 mbedtls_ecp_group_load( &( *p_ecp )->grp, grp_id ) ) );
667}
Jaeden Ameroccdce902019-01-10 11:42:27 +0000668
669/* Import a public key given as the uncompressed representation defined by SEC1
670 * 2.3.3 as the content of an ECPoint. */
Michael Thomas863b5d62020-02-10 19:41:16 +0000671psa_status_t psa_import_ec_public_key( psa_ecc_curve_t curve,
Jaeden Ameroccdce902019-01-10 11:42:27 +0000672 const uint8_t *data,
673 size_t data_length,
674 mbedtls_ecp_keypair **p_ecp )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200675{
Gilles Peskine4b3eb692019-05-16 21:35:18 +0200676 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Jaeden Ameroccdce902019-01-10 11:42:27 +0000677 mbedtls_ecp_keypair *ecp = NULL;
Jaeden Ameroccdce902019-01-10 11:42:27 +0000678
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100679 status = psa_prepare_import_ec_key( curve, data_length, 1, &ecp );
Jaeden Ameroccdce902019-01-10 11:42:27 +0000680 if( status != PSA_SUCCESS )
681 goto exit;
Gilles Peskine4cd32772019-12-02 20:49:42 +0100682
Jaeden Ameroccdce902019-01-10 11:42:27 +0000683 /* Load the public value. */
684 status = mbedtls_to_psa_error(
685 mbedtls_ecp_point_read_binary( &ecp->grp, &ecp->Q,
686 data, data_length ) );
687 if( status != PSA_SUCCESS )
688 goto exit;
689
690 /* Check that the point is on the curve. */
691 status = mbedtls_to_psa_error(
692 mbedtls_ecp_check_pubkey( &ecp->grp, &ecp->Q ) );
693 if( status != PSA_SUCCESS )
694 goto exit;
695
696 *p_ecp = ecp;
697 return( PSA_SUCCESS );
698
699exit:
700 if( ecp != NULL )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200701 {
Jaeden Ameroccdce902019-01-10 11:42:27 +0000702 mbedtls_ecp_keypair_free( ecp );
703 mbedtls_free( ecp );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200704 }
Jaeden Ameroccdce902019-01-10 11:42:27 +0000705 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200706}
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200707
Gilles Peskinef76aa772018-10-29 19:24:33 +0100708/* Import a private key given as a byte string which is the private value
709 * in big-endian order. */
710static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
711 const uint8_t *data,
712 size_t data_length,
713 mbedtls_ecp_keypair **p_ecp )
714{
Gilles Peskine4b3eb692019-05-16 21:35:18 +0200715 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100716 mbedtls_ecp_keypair *ecp = NULL;
Gilles Peskinef76aa772018-10-29 19:24:33 +0100717
Gilles Peskine4295e8b2019-12-02 21:39:10 +0100718 status = psa_prepare_import_ec_key( curve, data_length, 0, &ecp );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100719 if( status != PSA_SUCCESS )
720 goto exit;
Gilles Peskine4cd32772019-12-02 20:49:42 +0100721
Gilles Peskinef76aa772018-10-29 19:24:33 +0100722 /* Load the secret value. */
723 status = mbedtls_to_psa_error(
724 mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
725 if( status != PSA_SUCCESS )
726 goto exit;
727 /* Validate the private key. */
728 status = mbedtls_to_psa_error(
729 mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
730 if( status != PSA_SUCCESS )
731 goto exit;
732 /* Calculate the public key from the private key. */
733 status = mbedtls_to_psa_error(
734 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
735 mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
736 if( status != PSA_SUCCESS )
737 goto exit;
738
739 *p_ecp = ecp;
740 return( PSA_SUCCESS );
741
742exit:
743 if( ecp != NULL )
744 {
745 mbedtls_ecp_keypair_free( ecp );
746 mbedtls_free( ecp );
747 }
748 return( status );
749}
750#endif /* defined(MBEDTLS_ECP_C) */
751
Gilles Peskineb46bef22019-07-30 21:32:04 +0200752
753/** Return the size of the key in the given slot, in bits.
754 *
755 * \param[in] slot A key slot.
756 *
757 * \return The key size in bits, read from the metadata in the slot.
758 */
759static inline size_t psa_get_key_slot_bits( const psa_key_slot_t *slot )
760{
761 return( slot->attr.bits );
762}
763
764/** Calculate the size of the key in the given slot, in bits.
765 *
766 * \param[in] slot A key slot containing a transparent key.
767 *
768 * \return The key size in bits, calculated from the key data.
769 */
Gilles Peskine8908c5e2019-07-31 18:55:00 +0200770static psa_key_bits_t psa_calculate_key_bits( const psa_key_slot_t *slot )
Gilles Peskineb46bef22019-07-30 21:32:04 +0200771{
Gilles Peskine8908c5e2019-07-31 18:55:00 +0200772 size_t bits = 0; /* return 0 on an empty slot */
773
Gilles Peskineb46bef22019-07-30 21:32:04 +0200774 if( key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskine8908c5e2019-07-31 18:55:00 +0200775 bits = PSA_BYTES_TO_BITS( slot->data.raw.bytes );
Gilles Peskineb46bef22019-07-30 21:32:04 +0200776#if defined(MBEDTLS_RSA_C)
Gilles Peskine8908c5e2019-07-31 18:55:00 +0200777 else if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
778 bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) );
Gilles Peskineb46bef22019-07-30 21:32:04 +0200779#endif /* defined(MBEDTLS_RSA_C) */
780#if defined(MBEDTLS_ECP_C)
Gilles Peskine8908c5e2019-07-31 18:55:00 +0200781 else if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
782 bits = slot->data.ecp->grp.pbits;
Gilles Peskineb46bef22019-07-30 21:32:04 +0200783#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine8908c5e2019-07-31 18:55:00 +0200784
785 /* We know that the size fits in psa_key_bits_t thanks to checks
786 * when the key was created. */
787 return( (psa_key_bits_t) bits );
Gilles Peskineb46bef22019-07-30 21:32:04 +0200788}
789
Gilles Peskine8e338702019-07-30 20:06:31 +0200790/** Import key data into a slot. `slot->attr.type` must have been set
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100791 * previously. This function assumes that the slot does not contain
792 * any key material yet. On failure, the slot content is unchanged. */
Gilles Peskinefa4135b2018-12-10 16:48:53 +0100793psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
794 const uint8_t *data,
795 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100796{
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200797 psa_status_t status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100798
Gilles Peskine8e338702019-07-30 20:06:31 +0200799 if( key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100800 {
Gilles Peskinec744d992019-07-30 17:26:54 +0200801 size_t bit_size = PSA_BYTES_TO_BITS( data_length );
Gilles Peskine1b9505c2019-08-07 10:59:45 +0200802 /* Ensure that the bytes-to-bit conversion didn't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100803 if( data_length > SIZE_MAX / 8 )
804 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine1b9505c2019-08-07 10:59:45 +0200805 /* Enforce a size limit, and in particular ensure that the bit
806 * size fits in its representation type. */
Gilles Peskinec744d992019-07-30 17:26:54 +0200807 if( bit_size > PSA_MAX_KEY_BITS )
808 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine8e338702019-07-30 20:06:31 +0200809 status = prepare_raw_data_slot( slot->attr.type, bit_size,
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200810 &slot->data.raw );
811 if( status != PSA_SUCCESS )
812 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200813 if( data_length != 0 )
814 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100815 }
816 else
Gilles Peskinef76aa772018-10-29 19:24:33 +0100817#if defined(MBEDTLS_ECP_C)
Gilles Peskine8e338702019-07-30 20:06:31 +0200818 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->attr.type ) )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100819 {
Gilles Peskine8e338702019-07-30 20:06:31 +0200820 status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->attr.type ),
Gilles Peskinef76aa772018-10-29 19:24:33 +0100821 data, data_length,
822 &slot->data.ecp );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100823 }
Gilles Peskine8e338702019-07-30 20:06:31 +0200824 else if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( slot->attr.type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100825 {
Jaeden Ameroccdce902019-01-10 11:42:27 +0000826 status = psa_import_ec_public_key(
Gilles Peskine8e338702019-07-30 20:06:31 +0200827 PSA_KEY_TYPE_GET_CURVE( slot->attr.type ),
Jaeden Ameroccdce902019-01-10 11:42:27 +0000828 data, data_length,
829 &slot->data.ecp );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100830 }
831 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100832#endif /* MBEDTLS_ECP_C */
Jaeden Ameroccdce902019-01-10 11:42:27 +0000833#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine8e338702019-07-30 20:06:31 +0200834 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100835 {
Gilles Peskine8e338702019-07-30 20:06:31 +0200836 status = psa_import_rsa_key( slot->attr.type,
Jaeden Amerocd09d8c2019-01-11 17:53:05 +0000837 data, data_length,
838 &slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100839 }
840 else
Jaeden Ameroccdce902019-01-10 11:42:27 +0000841#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100842 {
843 return( PSA_ERROR_NOT_SUPPORTED );
844 }
Darryl Green940d72c2018-07-13 13:18:51 +0100845
Gilles Peskineb46bef22019-07-30 21:32:04 +0200846 if( status == PSA_SUCCESS )
847 {
848 /* Write the actual key size to the slot.
849 * psa_start_key_creation() wrote the size declared by the
850 * caller, which may be 0 (meaning unspecified) or wrong. */
851 slot->attr.bits = psa_calculate_key_bits( slot );
852 }
Darryl Green06fd18d2018-07-16 11:21:11 +0100853 return( status );
854}
855
Gilles Peskinef603c712019-01-19 13:40:11 +0100856/** Calculate the intersection of two algorithm usage policies.
857 *
858 * Return 0 (which allows no operation) on incompatibility.
859 */
860static psa_algorithm_t psa_key_policy_algorithm_intersection(
861 psa_algorithm_t alg1,
862 psa_algorithm_t alg2 )
863{
Gilles Peskine549ea862019-05-22 11:45:59 +0200864 /* Common case: both sides actually specify the same policy. */
Gilles Peskinef603c712019-01-19 13:40:11 +0100865 if( alg1 == alg2 )
866 return( alg1 );
867 /* If the policies are from the same hash-and-sign family, check
868 * if one is a wildcard. If so the other has the specific algorithm. */
869 if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) &&
870 PSA_ALG_IS_HASH_AND_SIGN( alg2 ) &&
871 ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
872 {
873 if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
874 return( alg2 );
875 if( PSA_ALG_SIGN_GET_HASH( alg2 ) == PSA_ALG_ANY_HASH )
876 return( alg1 );
877 }
878 /* If the policies are incompatible, allow nothing. */
879 return( 0 );
880}
881
Gilles Peskined6f371b2019-05-10 19:33:38 +0200882static int psa_key_algorithm_permits( psa_algorithm_t policy_alg,
883 psa_algorithm_t requested_alg )
884{
Gilles Peskine549ea862019-05-22 11:45:59 +0200885 /* Common case: the policy only allows requested_alg. */
Gilles Peskined6f371b2019-05-10 19:33:38 +0200886 if( requested_alg == policy_alg )
887 return( 1 );
888 /* If policy_alg is a hash-and-sign with a wildcard for the hash,
Gilles Peskine549ea862019-05-22 11:45:59 +0200889 * and requested_alg is the same hash-and-sign family with any hash,
890 * then requested_alg is compliant with policy_alg. */
Gilles Peskined6f371b2019-05-10 19:33:38 +0200891 if( PSA_ALG_IS_HASH_AND_SIGN( requested_alg ) &&
892 PSA_ALG_SIGN_GET_HASH( policy_alg ) == PSA_ALG_ANY_HASH )
893 {
894 return( ( policy_alg & ~PSA_ALG_HASH_MASK ) ==
895 ( requested_alg & ~PSA_ALG_HASH_MASK ) );
896 }
897 /* If it isn't permitted, it's forbidden. */
898 return( 0 );
899}
900
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100901/** Test whether a policy permits an algorithm.
902 *
903 * The caller must test usage flags separately.
904 */
905static int psa_key_policy_permits( const psa_key_policy_t *policy,
906 psa_algorithm_t alg )
907{
Gilles Peskined6f371b2019-05-10 19:33:38 +0200908 return( psa_key_algorithm_permits( policy->alg, alg ) ||
909 psa_key_algorithm_permits( policy->alg2, alg ) );
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100910}
911
Gilles Peskinef603c712019-01-19 13:40:11 +0100912/** Restrict a key policy based on a constraint.
913 *
914 * \param[in,out] policy The policy to restrict.
915 * \param[in] constraint The policy constraint to apply.
916 *
917 * \retval #PSA_SUCCESS
918 * \c *policy contains the intersection of the original value of
919 * \c *policy and \c *constraint.
920 * \retval #PSA_ERROR_INVALID_ARGUMENT
921 * \c *policy and \c *constraint are incompatible.
922 * \c *policy is unchanged.
923 */
924static psa_status_t psa_restrict_key_policy(
925 psa_key_policy_t *policy,
926 const psa_key_policy_t *constraint )
927{
928 psa_algorithm_t intersection_alg =
929 psa_key_policy_algorithm_intersection( policy->alg, constraint->alg );
Gilles Peskined6f371b2019-05-10 19:33:38 +0200930 psa_algorithm_t intersection_alg2 =
931 psa_key_policy_algorithm_intersection( policy->alg2, constraint->alg2 );
Gilles Peskinef603c712019-01-19 13:40:11 +0100932 if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
933 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskined6f371b2019-05-10 19:33:38 +0200934 if( intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0 )
935 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinef603c712019-01-19 13:40:11 +0100936 policy->usage &= constraint->usage;
937 policy->alg = intersection_alg;
Gilles Peskined6f371b2019-05-10 19:33:38 +0200938 policy->alg2 = intersection_alg2;
Gilles Peskinef603c712019-01-19 13:40:11 +0100939 return( PSA_SUCCESS );
940}
941
Darryl Green06fd18d2018-07-16 11:21:11 +0100942/** Retrieve a slot which must contain a key. The key must have allow all the
943 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
944 * operations with this algorithm. */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100945static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle,
Gilles Peskine2f060a82018-12-04 17:12:32 +0100946 psa_key_slot_t **p_slot,
Darryl Green06fd18d2018-07-16 11:21:11 +0100947 psa_key_usage_t usage,
948 psa_algorithm_t alg )
949{
950 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +0100951 psa_key_slot_t *slot = NULL;
Darryl Green06fd18d2018-07-16 11:21:11 +0100952
953 *p_slot = NULL;
954
Gilles Peskinec5487a82018-12-03 18:08:14 +0100955 status = psa_get_key_slot( handle, &slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100956 if( status != PSA_SUCCESS )
957 return( status );
Darryl Green06fd18d2018-07-16 11:21:11 +0100958
959 /* Enforce that usage policy for the key slot contains all the flags
960 * required by the usage parameter. There is one exception: public
961 * keys can always be exported, so we treat public key objects as
962 * if they had the export flag. */
Gilles Peskine8e338702019-07-30 20:06:31 +0200963 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
Darryl Green06fd18d2018-07-16 11:21:11 +0100964 usage &= ~PSA_KEY_USAGE_EXPORT;
Gilles Peskine8e338702019-07-30 20:06:31 +0200965 if( ( slot->attr.policy.usage & usage ) != usage )
Darryl Green06fd18d2018-07-16 11:21:11 +0100966 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100967
968 /* Enforce that the usage policy permits the requested algortihm. */
Gilles Peskine8e338702019-07-30 20:06:31 +0200969 if( alg != 0 && ! psa_key_policy_permits( &slot->attr.policy, alg ) )
Darryl Green06fd18d2018-07-16 11:21:11 +0100970 return( PSA_ERROR_NOT_PERMITTED );
971
972 *p_slot = slot;
973 return( PSA_SUCCESS );
974}
Darryl Green940d72c2018-07-13 13:18:51 +0100975
Gilles Peskine28f8f302019-07-24 13:30:31 +0200976/** Retrieve a slot which must contain a transparent key.
977 *
978 * A transparent key is a key for which the key material is directly
979 * available, as opposed to a key in a secure element.
980 *
Gilles Peskine60450a42019-07-25 11:32:45 +0200981 * This is a temporary function to use instead of psa_get_key_from_slot()
982 * until secure element support is fully implemented.
Gilles Peskine28f8f302019-07-24 13:30:31 +0200983 */
984#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
985static psa_status_t psa_get_transparent_key( psa_key_handle_t handle,
986 psa_key_slot_t **p_slot,
987 psa_key_usage_t usage,
988 psa_algorithm_t alg )
989{
990 psa_status_t status = psa_get_key_from_slot( handle, p_slot, usage, alg );
991 if( status != PSA_SUCCESS )
992 return( status );
Gilles Peskineadad8132019-07-25 11:31:23 +0200993 if( psa_key_slot_is_external( *p_slot ) )
Gilles Peskine28f8f302019-07-24 13:30:31 +0200994 {
995 *p_slot = NULL;
996 return( PSA_ERROR_NOT_SUPPORTED );
997 }
998 return( PSA_SUCCESS );
999}
1000#else /* MBEDTLS_PSA_CRYPTO_SE_C */
1001/* With no secure element support, all keys are transparent. */
1002#define psa_get_transparent_key( handle, p_slot, usage, alg ) \
1003 psa_get_key_from_slot( handle, p_slot, usage, alg )
1004#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1005
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001006/** Wipe key data from a slot. Preserve metadata such as the policy. */
Gilles Peskine2f060a82018-12-04 17:12:32 +01001007static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
Darryl Green40225ba2018-11-15 14:48:15 +00001008{
Gilles Peskine73167e12019-07-12 23:44:37 +02001009#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1010 if( psa_key_slot_is_external( slot ) )
Darryl Green40225ba2018-11-15 14:48:15 +00001011 {
1012 /* No key material to clean. */
1013 }
Gilles Peskine73167e12019-07-12 23:44:37 +02001014 else
1015#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine8e338702019-07-30 20:06:31 +02001016 if( slot->attr.type == PSA_KEY_TYPE_NONE )
Darryl Green40225ba2018-11-15 14:48:15 +00001017 {
1018 /* No key material to clean. */
1019 }
Gilles Peskine8e338702019-07-30 20:06:31 +02001020 else if( key_type_is_raw_bytes( slot->attr.type ) )
Darryl Green40225ba2018-11-15 14:48:15 +00001021 {
1022 mbedtls_free( slot->data.raw.data );
1023 }
1024 else
1025#if defined(MBEDTLS_RSA_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001026 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Darryl Green40225ba2018-11-15 14:48:15 +00001027 {
1028 mbedtls_rsa_free( slot->data.rsa );
1029 mbedtls_free( slot->data.rsa );
1030 }
1031 else
1032#endif /* defined(MBEDTLS_RSA_C) */
1033#if defined(MBEDTLS_ECP_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001034 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
Darryl Green40225ba2018-11-15 14:48:15 +00001035 {
1036 mbedtls_ecp_keypair_free( slot->data.ecp );
1037 mbedtls_free( slot->data.ecp );
1038 }
1039 else
1040#endif /* defined(MBEDTLS_ECP_C) */
1041 {
1042 /* Shouldn't happen: the key type is not any type that we
1043 * put in. */
Gilles Peskine4b3eb692019-05-16 21:35:18 +02001044 return( PSA_ERROR_CORRUPTION_DETECTED );
Darryl Green40225ba2018-11-15 14:48:15 +00001045 }
1046
1047 return( PSA_SUCCESS );
1048}
1049
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001050/** Completely wipe a slot in memory, including its policy.
1051 * Persistent storage is not affected. */
Gilles Peskine66fb1262018-12-10 16:29:04 +01001052psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001053{
1054 psa_status_t status = psa_remove_key_data_from_memory( slot );
Gilles Peskine3f7cd622019-08-13 15:01:08 +02001055 /* Multipart operations may still be using the key. This is safe
1056 * because all multipart operation objects are independent from
1057 * the key slot: if they need to access the key after the setup
1058 * phase, they have a copy of the key. Note that this means that
1059 * key material can linger until all operations are completed. */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001060 /* At this point, key material and other type-specific content has
1061 * been wiped. Clear remaining metadata. We can call memset and not
1062 * zeroize because the metadata is not particularly sensitive. */
1063 memset( slot, 0, sizeof( *slot ) );
1064 return( status );
1065}
1066
Gilles Peskinec5487a82018-12-03 18:08:14 +01001067psa_status_t psa_destroy_key( psa_key_handle_t handle )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001068{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001069 psa_key_slot_t *slot;
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001070 psa_status_t status; /* status of the last operation */
1071 psa_status_t overall_status = PSA_SUCCESS;
Gilles Peskine354f7672019-07-12 23:46:38 +02001072#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1073 psa_se_drv_table_entry_t *driver;
1074#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001075
Gilles Peskine1841cf42019-10-08 15:48:25 +02001076 if( handle == 0 )
1077 return( PSA_SUCCESS );
1078
Gilles Peskinec5487a82018-12-03 18:08:14 +01001079 status = psa_get_key_slot( handle, &slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001080 if( status != PSA_SUCCESS )
1081 return( status );
Gilles Peskine354f7672019-07-12 23:46:38 +02001082
1083#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001084 driver = psa_get_se_driver_entry( slot->attr.lifetime );
Gilles Peskine354f7672019-07-12 23:46:38 +02001085 if( driver != NULL )
Gilles Peskinefc762652019-07-22 19:30:34 +02001086 {
Gilles Peskine60450a42019-07-25 11:32:45 +02001087 /* For a key in a secure element, we need to do three things:
1088 * remove the key file in internal storage, destroy the
1089 * key inside the secure element, and update the driver's
1090 * persistent data. Start a transaction that will encompass these
1091 * three actions. */
Gilles Peskinefc762652019-07-22 19:30:34 +02001092 psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_DESTROY_KEY );
Gilles Peskine8e338702019-07-30 20:06:31 +02001093 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
Gilles Peskinefc762652019-07-22 19:30:34 +02001094 psa_crypto_transaction.key.slot = slot->data.se.slot_number;
Gilles Peskine8e338702019-07-30 20:06:31 +02001095 psa_crypto_transaction.key.id = slot->attr.id;
Gilles Peskinefc762652019-07-22 19:30:34 +02001096 status = psa_crypto_save_transaction( );
1097 if( status != PSA_SUCCESS )
1098 {
Gilles Peskine66be51c2019-07-25 18:02:52 +02001099 (void) psa_crypto_stop_transaction( );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001100 /* We should still try to destroy the key in the secure
1101 * element and the key metadata in storage. This is especially
1102 * important if the error is that the storage is full.
1103 * But how to do it exactly without risking an inconsistent
1104 * state after a reset?
1105 * https://github.com/ARMmbed/mbed-crypto/issues/215
1106 */
1107 overall_status = status;
1108 goto exit;
Gilles Peskinefc762652019-07-22 19:30:34 +02001109 }
1110
Gilles Peskine354f7672019-07-12 23:46:38 +02001111 status = psa_destroy_se_key( driver, slot->data.se.slot_number );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001112 if( overall_status == PSA_SUCCESS )
1113 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001114 }
Gilles Peskine354f7672019-07-12 23:46:38 +02001115#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1116
Darryl Greend49a4992018-06-18 17:27:26 +01001117#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskinecaec2782019-08-13 15:11:49 +02001118 if( slot->attr.lifetime != PSA_KEY_LIFETIME_VOLATILE )
Darryl Greend49a4992018-06-18 17:27:26 +01001119 {
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001120 status = psa_destroy_persistent_key( slot->attr.id );
1121 if( overall_status == PSA_SUCCESS )
1122 overall_status = status;
1123
Gilles Peskine9ce31c42019-08-13 15:14:20 +02001124 /* TODO: other slots may have a copy of the same key. We should
1125 * invalidate them.
1126 * https://github.com/ARMmbed/mbed-crypto/issues/214
1127 */
Darryl Greend49a4992018-06-18 17:27:26 +01001128 }
1129#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskine354f7672019-07-12 23:46:38 +02001130
Gilles Peskinefc762652019-07-22 19:30:34 +02001131#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1132 if( driver != NULL )
1133 {
Gilles Peskine725f22a2019-07-25 11:31:48 +02001134 status = psa_save_se_persistent_data( driver );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001135 if( overall_status == PSA_SUCCESS )
1136 overall_status = status;
1137 status = psa_crypto_stop_transaction( );
1138 if( overall_status == PSA_SUCCESS )
1139 overall_status = status;
Gilles Peskinefc762652019-07-22 19:30:34 +02001140 }
1141#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1142
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001143#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1144exit:
1145#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +01001146 status = psa_wipe_key_slot( slot );
Gilles Peskine4b7f3402019-08-13 15:58:36 +02001147 /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
1148 if( overall_status == PSA_SUCCESS )
1149 overall_status = status;
1150 return( overall_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001151}
1152
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001153void psa_reset_key_attributes( psa_key_attributes_t *attributes )
Gilles Peskineb870b182018-07-06 16:02:09 +02001154{
Gilles Peskineb699f072019-04-26 16:06:02 +02001155 mbedtls_free( attributes->domain_parameters );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001156 memset( attributes, 0, sizeof( *attributes ) );
Gilles Peskineb870b182018-07-06 16:02:09 +02001157}
1158
Gilles Peskineb699f072019-04-26 16:06:02 +02001159psa_status_t psa_set_key_domain_parameters( psa_key_attributes_t *attributes,
1160 psa_key_type_t type,
1161 const uint8_t *data,
1162 size_t data_length )
1163{
1164 uint8_t *copy = NULL;
1165
1166 if( data_length != 0 )
1167 {
1168 copy = mbedtls_calloc( 1, data_length );
1169 if( copy == NULL )
1170 return( PSA_ERROR_INSUFFICIENT_MEMORY );
1171 memcpy( copy, data, data_length );
1172 }
1173 /* After this point, this function is guaranteed to succeed, so it
1174 * can start modifying `*attributes`. */
1175
1176 if( attributes->domain_parameters != NULL )
1177 {
1178 mbedtls_free( attributes->domain_parameters );
1179 attributes->domain_parameters = NULL;
1180 attributes->domain_parameters_size = 0;
1181 }
1182
1183 attributes->domain_parameters = copy;
1184 attributes->domain_parameters_size = data_length;
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001185 attributes->core.type = type;
Gilles Peskineb699f072019-04-26 16:06:02 +02001186 return( PSA_SUCCESS );
1187}
1188
1189psa_status_t psa_get_key_domain_parameters(
1190 const psa_key_attributes_t *attributes,
1191 uint8_t *data, size_t data_size, size_t *data_length )
1192{
1193 if( attributes->domain_parameters_size > data_size )
1194 return( PSA_ERROR_BUFFER_TOO_SMALL );
1195 *data_length = attributes->domain_parameters_size;
1196 if( attributes->domain_parameters_size != 0 )
1197 memcpy( data, attributes->domain_parameters,
1198 attributes->domain_parameters_size );
1199 return( PSA_SUCCESS );
1200}
1201
1202#if defined(MBEDTLS_RSA_C)
1203static psa_status_t psa_get_rsa_public_exponent(
1204 const mbedtls_rsa_context *rsa,
1205 psa_key_attributes_t *attributes )
1206{
1207 mbedtls_mpi mpi;
Janos Follath24eed8d2019-11-22 13:21:35 +00001208 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb699f072019-04-26 16:06:02 +02001209 uint8_t *buffer = NULL;
1210 size_t buflen;
1211 mbedtls_mpi_init( &mpi );
1212
1213 ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &mpi );
1214 if( ret != 0 )
1215 goto exit;
Gilles Peskine772c8b12019-04-26 17:37:21 +02001216 if( mbedtls_mpi_cmp_int( &mpi, 65537 ) == 0 )
1217 {
1218 /* It's the default value, which is reported as an empty string,
1219 * so there's nothing to do. */
1220 goto exit;
1221 }
Gilles Peskineb699f072019-04-26 16:06:02 +02001222
1223 buflen = mbedtls_mpi_size( &mpi );
1224 buffer = mbedtls_calloc( 1, buflen );
1225 if( buffer == NULL )
1226 {
1227 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
1228 goto exit;
1229 }
1230 ret = mbedtls_mpi_write_binary( &mpi, buffer, buflen );
1231 if( ret != 0 )
1232 goto exit;
1233 attributes->domain_parameters = buffer;
1234 attributes->domain_parameters_size = buflen;
1235
1236exit:
1237 mbedtls_mpi_free( &mpi );
1238 if( ret != 0 )
1239 mbedtls_free( buffer );
1240 return( mbedtls_to_psa_error( ret ) );
1241}
1242#endif /* MBEDTLS_RSA_C */
1243
Gilles Peskinebfd322f2019-07-23 11:58:03 +02001244/** Retrieve all the publicly-accessible attributes of a key.
1245 */
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001246psa_status_t psa_get_key_attributes( psa_key_handle_t handle,
1247 psa_key_attributes_t *attributes )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001248{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001249 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001250 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001251
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001252 psa_reset_key_attributes( attributes );
1253
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001254 status = psa_get_key_from_slot( handle, &slot, 0, 0 );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001255 if( status != PSA_SUCCESS )
1256 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +02001257
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001258 attributes->core = slot->attr;
Gilles Peskinec8000c02019-08-02 20:15:51 +02001259 attributes->core.flags &= ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1260 MBEDTLS_PSA_KA_MASK_DUAL_USE );
1261
1262#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1263 if( psa_key_slot_is_external( slot ) )
1264 psa_set_key_slot_number( attributes, slot->data.se.slot_number );
1265#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineb699f072019-04-26 16:06:02 +02001266
Gilles Peskine8e338702019-07-30 20:06:31 +02001267 switch( slot->attr.type )
Gilles Peskineb699f072019-04-26 16:06:02 +02001268 {
1269#if defined(MBEDTLS_RSA_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02001270 case PSA_KEY_TYPE_RSA_KEY_PAIR:
Gilles Peskineb699f072019-04-26 16:06:02 +02001271 case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001272#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01001273 /* TODO: reporting the public exponent for opaque keys
Gilles Peskinec9d7f942019-08-13 16:17:16 +02001274 * is not yet implemented.
1275 * https://github.com/ARMmbed/mbed-crypto/issues/216
1276 */
Gilles Peskinec8000c02019-08-02 20:15:51 +02001277 if( psa_key_slot_is_external( slot ) )
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001278 break;
1279#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineb699f072019-04-26 16:06:02 +02001280 status = psa_get_rsa_public_exponent( slot->data.rsa, attributes );
1281 break;
Gilles Peskinedc5bfe92019-07-24 19:09:30 +02001282#endif /* MBEDTLS_RSA_C */
Gilles Peskineb699f072019-04-26 16:06:02 +02001283 default:
1284 /* Nothing else to do. */
1285 break;
1286 }
1287
1288 if( status != PSA_SUCCESS )
1289 psa_reset_key_attributes( attributes );
1290 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001291}
1292
Gilles Peskinec8000c02019-08-02 20:15:51 +02001293#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1294psa_status_t psa_get_key_slot_number(
1295 const psa_key_attributes_t *attributes,
1296 psa_key_slot_number_t *slot_number )
1297{
1298 if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
1299 {
1300 *slot_number = attributes->slot_number;
1301 return( PSA_SUCCESS );
1302 }
1303 else
1304 return( PSA_ERROR_INVALID_ARGUMENT );
1305}
1306#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1307
Jaeden Ameroccdce902019-01-10 11:42:27 +00001308#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
Jaeden Amero25384a22019-01-10 10:23:21 +00001309static int pk_write_pubkey_simple( mbedtls_pk_context *key,
1310 unsigned char *buf, size_t size )
1311{
Janos Follath24eed8d2019-11-22 13:21:35 +00001312 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero25384a22019-01-10 10:23:21 +00001313 unsigned char *c;
1314 size_t len = 0;
1315
1316 c = buf + size;
1317
1318 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
1319
1320 return( (int) len );
1321}
Jaeden Ameroccdce902019-01-10 11:42:27 +00001322#endif /* defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C) */
Jaeden Amero25384a22019-01-10 10:23:21 +00001323
Gilles Peskinef603c712019-01-19 13:40:11 +01001324static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
1325 uint8_t *data,
1326 size_t data_size,
1327 size_t *data_length,
1328 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001329{
Gilles Peskine5d309672019-07-12 23:47:28 +02001330#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1331 const psa_drv_se_t *drv;
1332 psa_drv_se_context_t *drv_context;
1333#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1334
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001335 *data_length = 0;
1336
Gilles Peskine8e338702019-07-30 20:06:31 +02001337 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001338 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +03001339
Gilles Peskinef9168942019-09-12 19:20:29 +02001340 /* Reject a zero-length output buffer now, since this can never be a
1341 * valid key representation. This way we know that data must be a valid
1342 * pointer and we can do things like memset(data, ..., data_size). */
1343 if( data_size == 0 )
1344 return( PSA_ERROR_BUFFER_TOO_SMALL );
1345
Gilles Peskine5d309672019-07-12 23:47:28 +02001346#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001347 if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
Gilles Peskine5d309672019-07-12 23:47:28 +02001348 {
1349 psa_drv_se_export_key_t method;
1350 if( drv->key_management == NULL )
1351 return( PSA_ERROR_NOT_SUPPORTED );
1352 method = ( export_public_key ?
1353 drv->key_management->p_export_public :
1354 drv->key_management->p_export );
1355 if( method == NULL )
1356 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine2e0f3882019-07-25 11:34:33 +02001357 return( method( drv_context,
1358 slot->data.se.slot_number,
1359 data, data_size, data_length ) );
Gilles Peskine5d309672019-07-12 23:47:28 +02001360 }
1361#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1362
Gilles Peskine8e338702019-07-30 20:06:31 +02001363 if( key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001364 {
1365 if( slot->data.raw.bytes > data_size )
1366 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskinef9168942019-09-12 19:20:29 +02001367 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
1368 memset( data + slot->data.raw.bytes, 0,
1369 data_size - slot->data.raw.bytes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001370 *data_length = slot->data.raw.bytes;
1371 return( PSA_SUCCESS );
1372 }
Gilles Peskine188c71e2018-10-29 19:26:02 +01001373#if defined(MBEDTLS_ECP_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001374 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->attr.type ) && !export_public_key )
Gilles Peskine188c71e2018-10-29 19:26:02 +01001375 {
Darryl Greendd8fb772018-11-07 16:00:44 +00001376 psa_status_t status;
1377
Gilles Peskineb46bef22019-07-30 21:32:04 +02001378 size_t bytes = PSA_BITS_TO_BYTES( slot->attr.bits );
Gilles Peskine188c71e2018-10-29 19:26:02 +01001379 if( bytes > data_size )
1380 return( PSA_ERROR_BUFFER_TOO_SMALL );
1381 status = mbedtls_to_psa_error(
1382 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
1383 if( status != PSA_SUCCESS )
1384 return( status );
1385 memset( data + bytes, 0, data_size - bytes );
1386 *data_length = bytes;
1387 return( PSA_SUCCESS );
1388 }
1389#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001390 else
Moran Peker17e36e12018-05-02 12:55:20 +03001391 {
Gilles Peskine969ac722018-01-28 18:16:59 +01001392#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001393 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ||
1394 PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001395 {
Moran Pekera998bc62018-04-16 18:16:20 +03001396 mbedtls_pk_context pk;
Janos Follath24eed8d2019-11-22 13:21:35 +00001397 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine8e338702019-07-30 20:06:31 +02001398 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001399 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001400#if defined(MBEDTLS_RSA_C)
1401 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001402 pk.pk_info = &mbedtls_rsa_info;
1403 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001404#else
1405 return( PSA_ERROR_NOT_SUPPORTED );
1406#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001407 }
1408 else
1409 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001410#if defined(MBEDTLS_ECP_C)
1411 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001412 pk.pk_info = &mbedtls_eckey_info;
1413 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001414#else
1415 return( PSA_ERROR_NOT_SUPPORTED );
1416#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001417 }
Gilles Peskine8e338702019-07-30 20:06:31 +02001418 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) )
Jaeden Amero25384a22019-01-10 10:23:21 +00001419 {
Jaeden Ameroccdce902019-01-10 11:42:27 +00001420 ret = pk_write_pubkey_simple( &pk, data, data_size );
Jaeden Amero25384a22019-01-10 10:23:21 +00001421 }
Moran Peker17e36e12018-05-02 12:55:20 +03001422 else
Jaeden Amero25384a22019-01-10 10:23:21 +00001423 {
Moran Peker17e36e12018-05-02 12:55:20 +03001424 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Jaeden Amero25384a22019-01-10 10:23:21 +00001425 }
Moran Peker60364322018-04-29 11:34:58 +03001426 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001427 {
Gilles Peskinef9168942019-09-12 19:20:29 +02001428 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +03001429 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001430 }
Gilles Peskine0e231582018-06-20 00:11:07 +02001431 /* The mbedtls_pk_xxx functions write to the end of the buffer.
1432 * Move the data to the beginning and erase remaining data
1433 * at the original location. */
1434 if( 2 * (size_t) ret <= data_size )
1435 {
1436 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001437 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001438 }
1439 else if( (size_t) ret < data_size )
1440 {
1441 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001442 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001443 }
Moran Pekera998bc62018-04-16 18:16:20 +03001444 *data_length = ret;
1445 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +01001446 }
1447 else
Gilles Peskine6d912132018-03-07 16:41:37 +01001448#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +03001449 {
1450 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001451 it is valid for a special-purpose implementation to omit
1452 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001453 return( PSA_ERROR_NOT_SUPPORTED );
1454 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001455 }
1456}
1457
Gilles Peskinec5487a82018-12-03 18:08:14 +01001458psa_status_t psa_export_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001459 uint8_t *data,
1460 size_t data_size,
1461 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001462{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001463 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001464 psa_status_t status;
1465
1466 /* Set the key to empty now, so that even when there are errors, we always
1467 * set data_length to a value between 0 and data_size. On error, setting
1468 * the key to empty is a good choice because an empty key representation is
1469 * unlikely to be accepted anywhere. */
1470 *data_length = 0;
1471
1472 /* Export requires the EXPORT flag. There is an exception for public keys,
1473 * which don't require any flag, but psa_get_key_from_slot takes
1474 * care of this. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001475 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_EXPORT, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001476 if( status != PSA_SUCCESS )
1477 return( status );
1478 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001479 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001480}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001481
Gilles Peskinec5487a82018-12-03 18:08:14 +01001482psa_status_t psa_export_public_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001483 uint8_t *data,
1484 size_t data_size,
1485 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001486{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001487 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001488 psa_status_t status;
1489
1490 /* Set the key to empty now, so that even when there are errors, we always
1491 * set data_length to a value between 0 and data_size. On error, setting
1492 * the key to empty is a good choice because an empty key representation is
1493 * unlikely to be accepted anywhere. */
1494 *data_length = 0;
1495
1496 /* Exporting a public key doesn't require a usage flag. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001497 status = psa_get_key_from_slot( handle, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001498 if( status != PSA_SUCCESS )
1499 return( status );
1500 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001501 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001502}
1503
Gilles Peskine91e8c332019-08-02 19:19:39 +02001504#if defined(static_assert)
1505static_assert( ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
1506 "One or more key attribute flag is listed as both external-only and dual-use" );
Gilles Peskine5a680562019-08-05 17:32:13 +02001507static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0,
Gilles Peskine094dac12019-08-07 18:19:46 +02001508 "One or more key attribute flag is listed as both internal-only and dual-use" );
Gilles Peskine5a680562019-08-05 17:32:13 +02001509static_assert( ( PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ) == 0,
Gilles Peskine91e8c332019-08-02 19:19:39 +02001510 "One or more key attribute flag is listed as both internal-only and external-only" );
1511#endif
1512
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001513/** Validate that a key policy is internally well-formed.
1514 *
1515 * This function only rejects invalid policies. It does not validate the
1516 * consistency of the policy with respect to other attributes of the key
1517 * such as the key type.
1518 */
1519static psa_status_t psa_validate_key_policy( const psa_key_policy_t *policy )
Gilles Peskine4747d192019-04-17 15:05:45 +02001520{
1521 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
Gilles Peskine8e0206a2019-05-14 14:24:28 +02001522 PSA_KEY_USAGE_COPY |
Gilles Peskine4747d192019-04-17 15:05:45 +02001523 PSA_KEY_USAGE_ENCRYPT |
1524 PSA_KEY_USAGE_DECRYPT |
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01001525 PSA_KEY_USAGE_SIGN_HASH |
1526 PSA_KEY_USAGE_VERIFY_HASH |
Gilles Peskine4747d192019-04-17 15:05:45 +02001527 PSA_KEY_USAGE_DERIVE ) ) != 0 )
1528 return( PSA_ERROR_INVALID_ARGUMENT );
1529
Gilles Peskine4747d192019-04-17 15:05:45 +02001530 return( PSA_SUCCESS );
1531}
1532
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001533/** Validate the internal consistency of key attributes.
1534 *
1535 * This function only rejects invalid attribute values. If does not
1536 * validate the consistency of the attributes with any key data that may
1537 * be involved in the creation of the key.
1538 *
1539 * Call this function early in the key creation process.
1540 *
1541 * \param[in] attributes Key attributes for the new key.
1542 * \param[out] p_drv On any return, the driver for the key, if any.
1543 * NULL for a transparent key.
1544 *
1545 */
1546static psa_status_t psa_validate_key_attributes(
1547 const psa_key_attributes_t *attributes,
1548 psa_se_drv_table_entry_t **p_drv )
Darryl Green0c6575a2018-11-07 16:05:30 +00001549{
1550 psa_status_t status;
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001551
Michael Thomas153cd2f2020-01-22 16:54:38 +00001552 if( PSA_KEY_LIFETIME_IS_PERSISTENT (attributes->core.lifetime))
Darryl Green0c6575a2018-11-07 16:05:30 +00001553 {
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001554 status = psa_validate_persistent_key_parameters(
1555 attributes->core.lifetime, attributes->core.id,
1556 p_drv, 1 );
1557 if( status != PSA_SUCCESS )
1558 return( status );
Darryl Green0c6575a2018-11-07 16:05:30 +00001559 }
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001560
1561 status = psa_validate_key_policy( &attributes->core.policy );
Darryl Green0c6575a2018-11-07 16:05:30 +00001562 if( status != PSA_SUCCESS )
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001563 return( status );
1564
1565 /* Refuse to create overly large keys.
1566 * Note that this doesn't trigger on import if the attributes don't
1567 * explicitly specify a size (so psa_get_key_bits returns 0), so
1568 * psa_import_key() needs its own checks. */
1569 if( psa_get_key_bits( attributes ) > PSA_MAX_KEY_BITS )
1570 return( PSA_ERROR_NOT_SUPPORTED );
1571
Gilles Peskine91e8c332019-08-02 19:19:39 +02001572 /* Reject invalid flags. These should not be reachable through the API. */
1573 if( attributes->core.flags & ~ ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
1574 MBEDTLS_PSA_KA_MASK_DUAL_USE ) )
1575 return( PSA_ERROR_INVALID_ARGUMENT );
1576
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001577 return( PSA_SUCCESS );
1578}
1579
Gilles Peskine4747d192019-04-17 15:05:45 +02001580/** Prepare a key slot to receive key material.
1581 *
1582 * This function allocates a key slot and sets its metadata.
1583 *
1584 * If this function fails, call psa_fail_key_creation().
1585 *
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001586 * This function is intended to be used as follows:
1587 * -# Call psa_start_key_creation() to allocate a key slot, prepare
1588 * it with the specified attributes, and assign it a handle.
1589 * -# Populate the slot with the key material.
1590 * -# Call psa_finish_key_creation() to finalize the creation of the slot.
1591 * In case of failure at any step, stop the sequence and call
1592 * psa_fail_key_creation().
1593 *
Gilles Peskinedf179142019-07-15 22:02:14 +02001594 * \param method An identification of the calling function.
Gilles Peskine011e4282019-06-26 18:34:38 +02001595 * \param[in] attributes Key attributes for the new key.
1596 * \param[out] handle On success, a handle for the allocated slot.
1597 * \param[out] p_slot On success, a pointer to the prepared slot.
1598 * \param[out] p_drv On any return, the driver for the key, if any.
1599 * NULL for a transparent key.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001600 *
1601 * \retval #PSA_SUCCESS
1602 * The key slot is ready to receive key material.
1603 * \return If this function fails, the key slot is an invalid state.
1604 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02001605 */
1606static psa_status_t psa_start_key_creation(
Gilles Peskinedf179142019-07-15 22:02:14 +02001607 psa_key_creation_method_t method,
Gilles Peskine4747d192019-04-17 15:05:45 +02001608 const psa_key_attributes_t *attributes,
1609 psa_key_handle_t *handle,
Gilles Peskine011e4282019-06-26 18:34:38 +02001610 psa_key_slot_t **p_slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001611 psa_se_drv_table_entry_t **p_drv )
Gilles Peskine4747d192019-04-17 15:05:45 +02001612{
1613 psa_status_t status;
1614 psa_key_slot_t *slot;
1615
Gilles Peskinedf179142019-07-15 22:02:14 +02001616 (void) method;
Gilles Peskine011e4282019-06-26 18:34:38 +02001617 *p_drv = NULL;
1618
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001619 status = psa_validate_key_attributes( attributes, p_drv );
1620 if( status != PSA_SUCCESS )
1621 return( status );
1622
Gilles Peskineedbed562019-08-07 18:19:59 +02001623 status = psa_get_empty_key_slot( handle, p_slot );
Gilles Peskine4747d192019-04-17 15:05:45 +02001624 if( status != PSA_SUCCESS )
1625 return( status );
1626 slot = *p_slot;
1627
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001628 /* We're storing the declared bit-size of the key. It's up to each
1629 * creation mechanism to verify that this information is correct.
1630 * It's automatically correct for mechanisms that use the bit-size as
Gilles Peskineb46bef22019-07-30 21:32:04 +02001631 * an input (generate, device) but not for those where the bit-size
1632 * is optional (import, copy). */
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001633
1634 slot->attr = attributes->core;
Gilles Peskinec744d992019-07-30 17:26:54 +02001635
Gilles Peskine91e8c332019-08-02 19:19:39 +02001636 /* Erase external-only flags from the internal copy. To access
Gilles Peskine013f5472019-08-07 15:42:14 +02001637 * external-only flags, query `attributes`. Thanks to the check
1638 * in psa_validate_key_attributes(), this leaves the dual-use
Gilles Peskineedbed562019-08-07 18:19:59 +02001639 * flags and any internal flag that psa_get_empty_key_slot()
Gilles Peskine013f5472019-08-07 15:42:14 +02001640 * may have set. */
1641 slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
Gilles Peskine91e8c332019-08-02 19:19:39 +02001642
Gilles Peskinecbaff462019-07-12 23:46:04 +02001643#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02001644 /* For a key in a secure element, we need to do three things
Gilles Peskine3efcebb2019-10-01 14:18:35 +02001645 * when creating or registering a key:
Gilles Peskine60450a42019-07-25 11:32:45 +02001646 * create the key file in internal storage, create the
1647 * key inside the secure element, and update the driver's
1648 * persistent data. Start a transaction that will encompass these
1649 * three actions. */
1650 /* The first thing to do is to find a slot number for the new key.
1651 * We save the slot number in persistent storage as part of the
1652 * transaction data. It will be needed to recover if the power
1653 * fails during the key creation process, to clean up on the secure
1654 * element side after restarting. Obtaining a slot number from the
1655 * secure element driver updates its persistent state, but we do not yet
1656 * save the driver's persistent state, so that if the power fails,
Gilles Peskinefc762652019-07-22 19:30:34 +02001657 * we can roll back to a state where the key doesn't exist. */
Gilles Peskine3efcebb2019-10-01 14:18:35 +02001658 if( *p_drv != NULL )
Darryl Green0c6575a2018-11-07 16:05:30 +00001659 {
Gilles Peskinee88c2c12019-08-05 16:44:14 +02001660 status = psa_find_se_slot_for_key( attributes, method, *p_drv,
Gilles Peskinecbaff462019-07-12 23:46:04 +02001661 &slot->data.se.slot_number );
1662 if( status != PSA_SUCCESS )
1663 return( status );
Gilles Peskine4aea1032019-07-25 17:38:34 +02001664 psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_CREATE_KEY );
Gilles Peskine8e338702019-07-30 20:06:31 +02001665 psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
Gilles Peskine4aea1032019-07-25 17:38:34 +02001666 psa_crypto_transaction.key.slot = slot->data.se.slot_number;
Gilles Peskine8e338702019-07-30 20:06:31 +02001667 psa_crypto_transaction.key.id = slot->attr.id;
Gilles Peskine4aea1032019-07-25 17:38:34 +02001668 status = psa_crypto_save_transaction( );
1669 if( status != PSA_SUCCESS )
Gilles Peskine66be51c2019-07-25 18:02:52 +02001670 {
1671 (void) psa_crypto_stop_transaction( );
Gilles Peskine4aea1032019-07-25 17:38:34 +02001672 return( status );
Gilles Peskine66be51c2019-07-25 18:02:52 +02001673 }
Darryl Green0c6575a2018-11-07 16:05:30 +00001674 }
Gilles Peskine3efcebb2019-10-01 14:18:35 +02001675
1676 if( *p_drv == NULL && method == PSA_KEY_CREATION_REGISTER )
1677 {
1678 /* Key registration only makes sense with a secure element. */
1679 return( PSA_ERROR_INVALID_ARGUMENT );
1680 }
Gilles Peskinecbaff462019-07-12 23:46:04 +02001681#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1682
Darryl Green0c6575a2018-11-07 16:05:30 +00001683 return( status );
1684}
Gilles Peskine4747d192019-04-17 15:05:45 +02001685
1686/** Finalize the creation of a key once its key material has been set.
1687 *
1688 * This entails writing the key to persistent storage.
1689 *
1690 * If this function fails, call psa_fail_key_creation().
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001691 * See the documentation of psa_start_key_creation() for the intended use
1692 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02001693 *
Gilles Peskine011e4282019-06-26 18:34:38 +02001694 * \param[in,out] slot Pointer to the slot with key material.
1695 * \param[in] driver The secure element driver for the key,
1696 * or NULL for a transparent key.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001697 *
1698 * \retval #PSA_SUCCESS
1699 * The key was successfully created. The handle is now valid.
1700 * \return If this function fails, the key slot is an invalid state.
1701 * You must call psa_fail_key_creation() to wipe and free the slot.
Gilles Peskine4747d192019-04-17 15:05:45 +02001702 */
Michael Thomas863b5d62020-02-10 19:41:16 +00001703psa_status_t psa_finish_key_creation(
Gilles Peskine011e4282019-06-26 18:34:38 +02001704 psa_key_slot_t *slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001705 psa_se_drv_table_entry_t *driver )
Gilles Peskine4747d192019-04-17 15:05:45 +02001706{
1707 psa_status_t status = PSA_SUCCESS;
Gilles Peskine30afafd2019-04-25 13:47:40 +02001708 (void) slot;
Gilles Peskine011e4282019-06-26 18:34:38 +02001709 (void) driver;
Gilles Peskine4747d192019-04-17 15:05:45 +02001710
1711#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Michael Thomasaf675252020-03-13 05:51:57 +00001712 if( PSA_KEY_LIFETIME_IS_PERSISTENT(slot->attr.lifetime ))
Gilles Peskine4747d192019-04-17 15:05:45 +02001713 {
Gilles Peskine1df83d42019-07-23 16:13:14 +02001714#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1715 if( driver != NULL )
1716 {
Gilles Peskineb46bef22019-07-30 21:32:04 +02001717 psa_se_key_data_storage_t data;
1718#if defined(static_assert)
1719 static_assert( sizeof( slot->data.se.slot_number ) ==
1720 sizeof( data.slot_number ),
1721 "Slot number size does not match psa_se_key_data_storage_t" );
1722 static_assert( sizeof( slot->attr.bits ) == sizeof( data.bits ),
1723 "Bit-size size does not match psa_se_key_data_storage_t" );
1724#endif
1725 memcpy( &data.slot_number, &slot->data.se.slot_number,
1726 sizeof( slot->data.se.slot_number ) );
1727 memcpy( &data.bits, &slot->attr.bits,
1728 sizeof( slot->attr.bits ) );
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001729 status = psa_save_persistent_key( &slot->attr,
Gilles Peskineb46bef22019-07-30 21:32:04 +02001730 (uint8_t*) &data,
1731 sizeof( data ) );
Gilles Peskine1df83d42019-07-23 16:13:14 +02001732 }
1733 else
1734#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1735 {
Gilles Peskinee60d1d02019-07-24 20:27:59 +02001736 size_t buffer_size =
Gilles Peskine8e338702019-07-30 20:06:31 +02001737 PSA_KEY_EXPORT_MAX_SIZE( slot->attr.type,
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001738 slot->attr.bits );
Gilles Peskinee60d1d02019-07-24 20:27:59 +02001739 uint8_t *buffer = mbedtls_calloc( 1, buffer_size );
1740 size_t length = 0;
Gilles Peskinef9168942019-09-12 19:20:29 +02001741 if( buffer == NULL )
Gilles Peskine1df83d42019-07-23 16:13:14 +02001742 return( PSA_ERROR_INSUFFICIENT_MEMORY );
1743 status = psa_internal_export_key( slot,
1744 buffer, buffer_size, &length,
1745 0 );
Gilles Peskinee60d1d02019-07-24 20:27:59 +02001746 if( status == PSA_SUCCESS )
Gilles Peskine76aa09c2019-07-31 14:15:34 +02001747 status = psa_save_persistent_key( &slot->attr,
Gilles Peskine4ed0e6f2019-07-30 20:22:33 +02001748 buffer, length );
Gilles Peskine4747d192019-04-17 15:05:45 +02001749
Gilles Peskinef9168942019-09-12 19:20:29 +02001750 mbedtls_platform_zeroize( buffer, buffer_size );
Gilles Peskine1df83d42019-07-23 16:13:14 +02001751 mbedtls_free( buffer );
1752 }
Gilles Peskine4747d192019-04-17 15:05:45 +02001753 }
Darryl Green0c6575a2018-11-07 16:05:30 +00001754#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1755
Gilles Peskinecbaff462019-07-12 23:46:04 +02001756#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined7729582019-08-05 15:55:54 +02001757 /* Finish the transaction for a key creation. This does not
1758 * happen when registering an existing key. Detect this case
1759 * by checking whether a transaction is in progress (actual
1760 * creation of a key in a secure element requires a transaction,
1761 * but registration doesn't use one). */
1762 if( driver != NULL &&
1763 psa_crypto_transaction.unknown.type == PSA_CRYPTO_TRANSACTION_CREATE_KEY )
Gilles Peskinecbaff462019-07-12 23:46:04 +02001764 {
1765 status = psa_save_se_persistent_data( driver );
1766 if( status != PSA_SUCCESS )
1767 {
Gilles Peskine8e338702019-07-30 20:06:31 +02001768 psa_destroy_persistent_key( slot->attr.id );
Gilles Peskinecbaff462019-07-12 23:46:04 +02001769 return( status );
1770 }
Gilles Peskinefc762652019-07-22 19:30:34 +02001771 status = psa_crypto_stop_transaction( );
1772 if( status != PSA_SUCCESS )
1773 return( status );
Gilles Peskinecbaff462019-07-12 23:46:04 +02001774 }
1775#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1776
Gilles Peskine4747d192019-04-17 15:05:45 +02001777 return( status );
1778}
1779
1780/** Abort the creation of a key.
1781 *
1782 * You may call this function after calling psa_start_key_creation(),
1783 * or after psa_finish_key_creation() fails. In other circumstances, this
1784 * function may not clean up persistent storage.
Gilles Peskine9bc88c62019-04-28 11:37:03 +02001785 * See the documentation of psa_start_key_creation() for the intended use
1786 * of this function.
Gilles Peskine4747d192019-04-17 15:05:45 +02001787 *
Gilles Peskine011e4282019-06-26 18:34:38 +02001788 * \param[in,out] slot Pointer to the slot with key material.
1789 * \param[in] driver The secure element driver for the key,
1790 * or NULL for a transparent key.
Gilles Peskine4747d192019-04-17 15:05:45 +02001791 */
Gilles Peskine011e4282019-06-26 18:34:38 +02001792static void psa_fail_key_creation( psa_key_slot_t *slot,
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001793 psa_se_drv_table_entry_t *driver )
Gilles Peskine4747d192019-04-17 15:05:45 +02001794{
Gilles Peskine011e4282019-06-26 18:34:38 +02001795 (void) driver;
1796
Gilles Peskine4747d192019-04-17 15:05:45 +02001797 if( slot == NULL )
1798 return;
Gilles Peskine011e4282019-06-26 18:34:38 +02001799
1800#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Janos Follath1d57a202019-08-13 12:15:34 +01001801 /* TODO: If the key has already been created in the secure
Gilles Peskine011e4282019-06-26 18:34:38 +02001802 * element, and the failure happened later (when saving metadata
1803 * to internal storage), we need to destroy the key in the secure
Gilles Peskinec9d7f942019-08-13 16:17:16 +02001804 * element.
1805 * https://github.com/ARMmbed/mbed-crypto/issues/217
1806 */
Gilles Peskinefc762652019-07-22 19:30:34 +02001807
Gilles Peskined7729582019-08-05 15:55:54 +02001808 /* Abort the ongoing transaction if any (there may not be one if
1809 * the creation process failed before starting one, or if the
1810 * key creation is a registration of a key in a secure element).
1811 * Earlier functions must already have done what it takes to undo any
1812 * partial creation. All that's left is to update the transaction data
1813 * itself. */
Gilles Peskinefc762652019-07-22 19:30:34 +02001814 (void) psa_crypto_stop_transaction( );
Gilles Peskine011e4282019-06-26 18:34:38 +02001815#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1816
Gilles Peskine4747d192019-04-17 15:05:45 +02001817 psa_wipe_key_slot( slot );
1818}
1819
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001820/** Validate optional attributes during key creation.
1821 *
1822 * Some key attributes are optional during key creation. If they are
1823 * specified in the attributes structure, check that they are consistent
1824 * with the data in the slot.
1825 *
1826 * This function should be called near the end of key creation, after
1827 * the slot in memory is fully populated but before saving persistent data.
1828 */
1829static psa_status_t psa_validate_optional_attributes(
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001830 const psa_key_slot_t *slot,
1831 const psa_key_attributes_t *attributes )
1832{
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001833 if( attributes->core.type != 0 )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001834 {
Gilles Peskine8e338702019-07-30 20:06:31 +02001835 if( attributes->core.type != slot->attr.type )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001836 return( PSA_ERROR_INVALID_ARGUMENT );
1837 }
1838
1839 if( attributes->domain_parameters_size != 0 )
1840 {
1841#if defined(MBEDTLS_RSA_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02001842 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001843 {
1844 mbedtls_mpi actual, required;
Janos Follath24eed8d2019-11-22 13:21:35 +00001845 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001846 mbedtls_mpi_init( &actual );
1847 mbedtls_mpi_init( &required );
1848 ret = mbedtls_rsa_export( slot->data.rsa,
1849 NULL, NULL, NULL, NULL, &actual );
1850 if( ret != 0 )
1851 goto rsa_exit;
1852 ret = mbedtls_mpi_read_binary( &required,
1853 attributes->domain_parameters,
1854 attributes->domain_parameters_size );
1855 if( ret != 0 )
1856 goto rsa_exit;
1857 if( mbedtls_mpi_cmp_mpi( &actual, &required ) != 0 )
1858 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1859 rsa_exit:
1860 mbedtls_mpi_free( &actual );
1861 mbedtls_mpi_free( &required );
1862 if( ret != 0)
1863 return( mbedtls_to_psa_error( ret ) );
1864 }
1865 else
1866#endif
1867 {
1868 return( PSA_ERROR_INVALID_ARGUMENT );
1869 }
1870 }
1871
Gilles Peskine7e0cff92019-07-30 13:48:52 +02001872 if( attributes->core.bits != 0 )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001873 {
Gilles Peskineb46bef22019-07-30 21:32:04 +02001874 if( attributes->core.bits != slot->attr.bits )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001875 return( PSA_ERROR_INVALID_ARGUMENT );
1876 }
1877
1878 return( PSA_SUCCESS );
1879}
1880
Gilles Peskine4747d192019-04-17 15:05:45 +02001881psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
Gilles Peskine4747d192019-04-17 15:05:45 +02001882 const uint8_t *data,
Gilles Peskine73676cb2019-05-15 20:15:10 +02001883 size_t data_length,
1884 psa_key_handle_t *handle )
Gilles Peskine4747d192019-04-17 15:05:45 +02001885{
1886 psa_status_t status;
1887 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02001888 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001889
Gilles Peskine0f84d622019-09-12 19:03:13 +02001890 /* Reject zero-length symmetric keys (including raw data key objects).
1891 * This also rejects any key which might be encoded as an empty string,
1892 * which is never valid. */
1893 if( data_length == 0 )
1894 return( PSA_ERROR_INVALID_ARGUMENT );
1895
Gilles Peskinedf179142019-07-15 22:02:14 +02001896 status = psa_start_key_creation( PSA_KEY_CREATION_IMPORT, attributes,
1897 handle, &slot, &driver );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001898 if( status != PSA_SUCCESS )
1899 goto exit;
1900
Gilles Peskine5d309672019-07-12 23:47:28 +02001901#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1902 if( driver != NULL )
1903 {
1904 const psa_drv_se_t *drv = psa_get_se_driver_methods( driver );
Darryl Green0892d0f2019-08-20 09:50:14 +01001905 /* The driver should set the number of key bits, however in
1906 * case it doesn't, we initialize bits to an invalid value. */
1907 size_t bits = PSA_MAX_KEY_BITS + 1;
Gilles Peskine5d309672019-07-12 23:47:28 +02001908 if( drv->key_management == NULL ||
1909 drv->key_management->p_import == NULL )
1910 {
1911 status = PSA_ERROR_NOT_SUPPORTED;
1912 goto exit;
1913 }
1914 status = drv->key_management->p_import(
1915 psa_get_se_driver_context( driver ),
Gilles Peskinef3801ff2019-08-06 17:32:04 +02001916 slot->data.se.slot_number, attributes, data, data_length,
Gilles Peskineb46bef22019-07-30 21:32:04 +02001917 &bits );
1918 if( status != PSA_SUCCESS )
1919 goto exit;
1920 if( bits > PSA_MAX_KEY_BITS )
1921 {
1922 status = PSA_ERROR_NOT_SUPPORTED;
1923 goto exit;
1924 }
1925 slot->attr.bits = (psa_key_bits_t) bits;
Gilles Peskine5d309672019-07-12 23:47:28 +02001926 }
1927 else
1928#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Michael Thomas863b5d62020-02-10 19:41:16 +00001929#if defined (MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C)
1930 if (PSA_KEY_LIFETIME_IS_VENDOR_DEFINED(slot->attr.lifetime))
1931 {
1932 status = psa_import_key_into_slot_vendor( slot, data, data_length);
1933 goto exit;
1934 }
1935 else
1936#endif /* MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C */
Gilles Peskine5d309672019-07-12 23:47:28 +02001937 {
1938 status = psa_import_key_into_slot( slot, data, data_length );
1939 if( status != PSA_SUCCESS )
1940 goto exit;
Gilles Peskine5d309672019-07-12 23:47:28 +02001941 }
Gilles Peskine1b8594a2019-07-31 17:21:46 +02001942 status = psa_validate_optional_attributes( slot, attributes );
Gilles Peskine18017402019-07-24 20:25:59 +02001943 if( status != PSA_SUCCESS )
1944 goto exit;
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001945
Gilles Peskine011e4282019-06-26 18:34:38 +02001946 status = psa_finish_key_creation( slot, driver );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02001947exit:
Gilles Peskine4747d192019-04-17 15:05:45 +02001948 if( status != PSA_SUCCESS )
1949 {
Gilles Peskine011e4282019-06-26 18:34:38 +02001950 psa_fail_key_creation( slot, driver );
Gilles Peskine4747d192019-04-17 15:05:45 +02001951 *handle = 0;
1952 }
1953 return( status );
1954}
1955
Gilles Peskined7729582019-08-05 15:55:54 +02001956#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1957psa_status_t mbedtls_psa_register_se_key(
1958 const psa_key_attributes_t *attributes )
1959{
1960 psa_status_t status;
1961 psa_key_slot_t *slot = NULL;
1962 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskined7729582019-08-05 15:55:54 +02001963 psa_key_handle_t handle = 0;
1964
1965 /* Leaving attributes unspecified is not currently supported.
1966 * It could make sense to query the key type and size from the
1967 * secure element, but not all secure elements support this
1968 * and the driver HAL doesn't currently support it. */
1969 if( psa_get_key_type( attributes ) == PSA_KEY_TYPE_NONE )
1970 return( PSA_ERROR_NOT_SUPPORTED );
1971 if( psa_get_key_bits( attributes ) == 0 )
1972 return( PSA_ERROR_NOT_SUPPORTED );
1973
1974 status = psa_start_key_creation( PSA_KEY_CREATION_REGISTER, attributes,
1975 &handle, &slot, &driver );
1976 if( status != PSA_SUCCESS )
1977 goto exit;
1978
Gilles Peskined7729582019-08-05 15:55:54 +02001979 status = psa_finish_key_creation( slot, driver );
1980
1981exit:
1982 if( status != PSA_SUCCESS )
1983 {
1984 psa_fail_key_creation( slot, driver );
1985 }
1986 /* Registration doesn't keep the key in RAM. */
1987 psa_close_key( handle );
1988 return( status );
1989}
1990#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1991
Gilles Peskinef603c712019-01-19 13:40:11 +01001992static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001993 psa_key_slot_t *target )
Gilles Peskinef603c712019-01-19 13:40:11 +01001994{
1995 psa_status_t status;
1996 uint8_t *buffer = NULL;
1997 size_t buffer_size = 0;
1998 size_t length;
1999
Gilles Peskine8e338702019-07-30 20:06:31 +02002000 buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->attr.type,
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02002001 psa_get_key_slot_bits( source ) );
Gilles Peskinef603c712019-01-19 13:40:11 +01002002 buffer = mbedtls_calloc( 1, buffer_size );
Gilles Peskinef9168942019-09-12 19:20:29 +02002003 if( buffer == NULL )
Gilles Peskine122d0022019-01-23 10:55:43 +01002004 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Gilles Peskinef603c712019-01-19 13:40:11 +01002005 status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 );
2006 if( status != PSA_SUCCESS )
2007 goto exit;
Gilles Peskine8e338702019-07-30 20:06:31 +02002008 target->attr.type = source->attr.type;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002009 status = psa_import_key_into_slot( target, buffer, length );
Gilles Peskinef603c712019-01-19 13:40:11 +01002010
2011exit:
Gilles Peskinef9168942019-09-12 19:20:29 +02002012 mbedtls_platform_zeroize( buffer, buffer_size );
Gilles Peskine122d0022019-01-23 10:55:43 +01002013 mbedtls_free( buffer );
Gilles Peskinef603c712019-01-19 13:40:11 +01002014 return( status );
2015}
2016
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002017psa_status_t psa_copy_key( psa_key_handle_t source_handle,
2018 const psa_key_attributes_t *specified_attributes,
2019 psa_key_handle_t *target_handle )
Gilles Peskinef603c712019-01-19 13:40:11 +01002020{
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002021 psa_status_t status;
Gilles Peskinef603c712019-01-19 13:40:11 +01002022 psa_key_slot_t *source_slot = NULL;
2023 psa_key_slot_t *target_slot = NULL;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002024 psa_key_attributes_t actual_attributes = *specified_attributes;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02002025 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskinef603c712019-01-19 13:40:11 +01002026
Gilles Peskine28f8f302019-07-24 13:30:31 +02002027 status = psa_get_transparent_key( source_handle, &source_slot,
Gilles Peskinef77a6ac2019-07-25 10:51:03 +02002028 PSA_KEY_USAGE_COPY, 0 );
Gilles Peskinef603c712019-01-19 13:40:11 +01002029 if( status != PSA_SUCCESS )
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002030 goto exit;
2031
Gilles Peskine1b8594a2019-07-31 17:21:46 +02002032 status = psa_validate_optional_attributes( source_slot,
2033 specified_attributes );
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002034 if( status != PSA_SUCCESS )
2035 goto exit;
2036
Gilles Peskine7e0cff92019-07-30 13:48:52 +02002037 status = psa_restrict_key_policy( &actual_attributes.core.policy,
Gilles Peskine8e338702019-07-30 20:06:31 +02002038 &source_slot->attr.policy );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002039 if( status != PSA_SUCCESS )
2040 goto exit;
2041
Gilles Peskinedf179142019-07-15 22:02:14 +02002042 status = psa_start_key_creation( PSA_KEY_CREATION_COPY,
2043 &actual_attributes,
Gilles Peskine011e4282019-06-26 18:34:38 +02002044 target_handle, &target_slot, &driver );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002045 if( status != PSA_SUCCESS )
2046 goto exit;
2047
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002048#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
2049 if( driver != NULL )
Gilles Peskinef603c712019-01-19 13:40:11 +01002050 {
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002051 /* Copying to a secure element is not implemented yet. */
2052 status = PSA_ERROR_NOT_SUPPORTED;
2053 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01002054 }
Gilles Peskinef4ee6622019-07-24 13:44:30 +02002055#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinef603c712019-01-19 13:40:11 +01002056
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002057 status = psa_copy_key_material( source_slot, target_slot );
Gilles Peskinef603c712019-01-19 13:40:11 +01002058 if( status != PSA_SUCCESS )
Gilles Peskine4ce2a9d2019-05-03 16:57:15 +02002059 goto exit;
Gilles Peskinef603c712019-01-19 13:40:11 +01002060
Gilles Peskine011e4282019-06-26 18:34:38 +02002061 status = psa_finish_key_creation( target_slot, driver );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002062exit:
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002063 if( status != PSA_SUCCESS )
2064 {
Gilles Peskine011e4282019-06-26 18:34:38 +02002065 psa_fail_key_creation( target_slot, driver );
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02002066 *target_handle = 0;
2067 }
2068 return( status );
Gilles Peskinef603c712019-01-19 13:40:11 +01002069}
2070
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002071
2072
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002073/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01002074/* Message digests */
2075/****************************************************************/
2076
Gilles Peskineb16841e2019-10-10 20:36:12 +02002077#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinedc2fc842018-03-07 16:42:59 +01002078static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01002079{
2080 switch( alg )
2081 {
2082#if defined(MBEDTLS_MD2_C)
2083 case PSA_ALG_MD2:
2084 return( &mbedtls_md2_info );
2085#endif
2086#if defined(MBEDTLS_MD4_C)
2087 case PSA_ALG_MD4:
2088 return( &mbedtls_md4_info );
2089#endif
2090#if defined(MBEDTLS_MD5_C)
2091 case PSA_ALG_MD5:
2092 return( &mbedtls_md5_info );
2093#endif
2094#if defined(MBEDTLS_RIPEMD160_C)
2095 case PSA_ALG_RIPEMD160:
2096 return( &mbedtls_ripemd160_info );
2097#endif
2098#if defined(MBEDTLS_SHA1_C)
2099 case PSA_ALG_SHA_1:
2100 return( &mbedtls_sha1_info );
2101#endif
2102#if defined(MBEDTLS_SHA256_C)
2103 case PSA_ALG_SHA_224:
2104 return( &mbedtls_sha224_info );
2105 case PSA_ALG_SHA_256:
2106 return( &mbedtls_sha256_info );
2107#endif
2108#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +02002109#if !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine20035e32018-02-03 22:44:14 +01002110 case PSA_ALG_SHA_384:
2111 return( &mbedtls_sha384_info );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +02002112#endif
Gilles Peskine20035e32018-02-03 22:44:14 +01002113 case PSA_ALG_SHA_512:
2114 return( &mbedtls_sha512_info );
2115#endif
2116 default:
2117 return( NULL );
2118 }
2119}
Gilles Peskineb16841e2019-10-10 20:36:12 +02002120#endif
Gilles Peskine20035e32018-02-03 22:44:14 +01002121
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002122psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
2123{
2124 switch( operation->alg )
2125 {
Gilles Peskine81736312018-06-26 15:04:31 +02002126 case 0:
2127 /* The object has (apparently) been initialized but it is not
2128 * in use. It's ok to call abort on such an object, and there's
2129 * nothing to do. */
2130 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002131#if defined(MBEDTLS_MD2_C)
2132 case PSA_ALG_MD2:
2133 mbedtls_md2_free( &operation->ctx.md2 );
2134 break;
2135#endif
2136#if defined(MBEDTLS_MD4_C)
2137 case PSA_ALG_MD4:
2138 mbedtls_md4_free( &operation->ctx.md4 );
2139 break;
2140#endif
2141#if defined(MBEDTLS_MD5_C)
2142 case PSA_ALG_MD5:
2143 mbedtls_md5_free( &operation->ctx.md5 );
2144 break;
2145#endif
2146#if defined(MBEDTLS_RIPEMD160_C)
2147 case PSA_ALG_RIPEMD160:
2148 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
2149 break;
2150#endif
2151#if defined(MBEDTLS_SHA1_C)
2152 case PSA_ALG_SHA_1:
2153 mbedtls_sha1_free( &operation->ctx.sha1 );
2154 break;
2155#endif
2156#if defined(MBEDTLS_SHA256_C)
2157 case PSA_ALG_SHA_224:
2158 case PSA_ALG_SHA_256:
2159 mbedtls_sha256_free( &operation->ctx.sha256 );
2160 break;
2161#endif
2162#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002163#if !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002164 case PSA_ALG_SHA_384:
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002165#endif
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002166 case PSA_ALG_SHA_512:
2167 mbedtls_sha512_free( &operation->ctx.sha512 );
2168 break;
2169#endif
2170 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002171 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002172 }
2173 operation->alg = 0;
2174 return( PSA_SUCCESS );
2175}
2176
Gilles Peskineda8191d2018-07-08 19:46:38 +02002177psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002178 psa_algorithm_t alg )
2179{
Janos Follath24eed8d2019-11-22 13:21:35 +00002180 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002181
2182 /* A context must be freshly initialized before it can be set up. */
2183 if( operation->alg != 0 )
2184 {
2185 return( PSA_ERROR_BAD_STATE );
2186 }
2187
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002188 switch( alg )
2189 {
2190#if defined(MBEDTLS_MD2_C)
2191 case PSA_ALG_MD2:
2192 mbedtls_md2_init( &operation->ctx.md2 );
2193 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
2194 break;
2195#endif
2196#if defined(MBEDTLS_MD4_C)
2197 case PSA_ALG_MD4:
2198 mbedtls_md4_init( &operation->ctx.md4 );
2199 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
2200 break;
2201#endif
2202#if defined(MBEDTLS_MD5_C)
2203 case PSA_ALG_MD5:
2204 mbedtls_md5_init( &operation->ctx.md5 );
2205 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
2206 break;
2207#endif
2208#if defined(MBEDTLS_RIPEMD160_C)
2209 case PSA_ALG_RIPEMD160:
2210 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
2211 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
2212 break;
2213#endif
2214#if defined(MBEDTLS_SHA1_C)
2215 case PSA_ALG_SHA_1:
2216 mbedtls_sha1_init( &operation->ctx.sha1 );
2217 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
2218 break;
2219#endif
2220#if defined(MBEDTLS_SHA256_C)
2221 case PSA_ALG_SHA_224:
2222 mbedtls_sha256_init( &operation->ctx.sha256 );
2223 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
2224 break;
2225 case PSA_ALG_SHA_256:
2226 mbedtls_sha256_init( &operation->ctx.sha256 );
2227 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
2228 break;
2229#endif
2230#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002231#if !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002232 case PSA_ALG_SHA_384:
2233 mbedtls_sha512_init( &operation->ctx.sha512 );
2234 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
2235 break;
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002236#endif
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002237 case PSA_ALG_SHA_512:
2238 mbedtls_sha512_init( &operation->ctx.sha512 );
2239 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
2240 break;
2241#endif
2242 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02002243 return( PSA_ALG_IS_HASH( alg ) ?
2244 PSA_ERROR_NOT_SUPPORTED :
2245 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002246 }
2247 if( ret == 0 )
2248 operation->alg = alg;
2249 else
2250 psa_hash_abort( operation );
2251 return( mbedtls_to_psa_error( ret ) );
2252}
2253
2254psa_status_t psa_hash_update( psa_hash_operation_t *operation,
2255 const uint8_t *input,
2256 size_t input_length )
2257{
Janos Follath24eed8d2019-11-22 13:21:35 +00002258 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine94e44542018-07-12 16:58:43 +02002259
2260 /* Don't require hash implementations to behave correctly on a
2261 * zero-length input, which may have an invalid pointer. */
2262 if( input_length == 0 )
2263 return( PSA_SUCCESS );
2264
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002265 switch( operation->alg )
2266 {
2267#if defined(MBEDTLS_MD2_C)
2268 case PSA_ALG_MD2:
2269 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
2270 input, input_length );
2271 break;
2272#endif
2273#if defined(MBEDTLS_MD4_C)
2274 case PSA_ALG_MD4:
2275 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
2276 input, input_length );
2277 break;
2278#endif
2279#if defined(MBEDTLS_MD5_C)
2280 case PSA_ALG_MD5:
2281 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
2282 input, input_length );
2283 break;
2284#endif
2285#if defined(MBEDTLS_RIPEMD160_C)
2286 case PSA_ALG_RIPEMD160:
2287 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
2288 input, input_length );
2289 break;
2290#endif
2291#if defined(MBEDTLS_SHA1_C)
2292 case PSA_ALG_SHA_1:
2293 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
2294 input, input_length );
2295 break;
2296#endif
2297#if defined(MBEDTLS_SHA256_C)
2298 case PSA_ALG_SHA_224:
2299 case PSA_ALG_SHA_256:
2300 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
2301 input, input_length );
2302 break;
2303#endif
2304#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002305#if !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002306 case PSA_ALG_SHA_384:
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002307#endif
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002308 case PSA_ALG_SHA_512:
2309 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
2310 input, input_length );
2311 break;
2312#endif
2313 default:
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002314 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002315 }
Gilles Peskine94e44542018-07-12 16:58:43 +02002316
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002317 if( ret != 0 )
2318 psa_hash_abort( operation );
2319 return( mbedtls_to_psa_error( ret ) );
2320}
2321
2322psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
2323 uint8_t *hash,
2324 size_t hash_size,
2325 size_t *hash_length )
2326{
itayzafrir40835d42018-08-02 13:14:17 +03002327 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00002328 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02002329 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002330
2331 /* Fill the output buffer with something that isn't a valid hash
2332 * (barring an attack on the hash and deliberately-crafted input),
2333 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02002334 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002335 /* If hash_size is 0 then hash may be NULL and then the
2336 * call to memset would have undefined behavior. */
2337 if( hash_size != 0 )
2338 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002339
2340 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03002341 {
2342 status = PSA_ERROR_BUFFER_TOO_SMALL;
2343 goto exit;
2344 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002345
2346 switch( operation->alg )
2347 {
2348#if defined(MBEDTLS_MD2_C)
2349 case PSA_ALG_MD2:
2350 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
2351 break;
2352#endif
2353#if defined(MBEDTLS_MD4_C)
2354 case PSA_ALG_MD4:
2355 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
2356 break;
2357#endif
2358#if defined(MBEDTLS_MD5_C)
2359 case PSA_ALG_MD5:
2360 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
2361 break;
2362#endif
2363#if defined(MBEDTLS_RIPEMD160_C)
2364 case PSA_ALG_RIPEMD160:
2365 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
2366 break;
2367#endif
2368#if defined(MBEDTLS_SHA1_C)
2369 case PSA_ALG_SHA_1:
2370 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
2371 break;
2372#endif
2373#if defined(MBEDTLS_SHA256_C)
2374 case PSA_ALG_SHA_224:
2375 case PSA_ALG_SHA_256:
2376 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
2377 break;
2378#endif
2379#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002380#if !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002381 case PSA_ALG_SHA_384:
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002382#endif
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002383 case PSA_ALG_SHA_512:
2384 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
2385 break;
2386#endif
2387 default:
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00002388 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002389 }
itayzafrir40835d42018-08-02 13:14:17 +03002390 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002391
itayzafrir40835d42018-08-02 13:14:17 +03002392exit:
2393 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002394 {
Gilles Peskineaee13332018-07-02 12:15:28 +02002395 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002396 return( psa_hash_abort( operation ) );
2397 }
2398 else
2399 {
2400 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03002401 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002402 }
2403}
2404
Gilles Peskine2d277862018-06-18 15:41:12 +02002405psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
2406 const uint8_t *hash,
2407 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002408{
2409 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
2410 size_t actual_hash_length;
2411 psa_status_t status = psa_hash_finish( operation,
2412 actual_hash, sizeof( actual_hash ),
2413 &actual_hash_length );
2414 if( status != PSA_SUCCESS )
2415 return( status );
2416 if( actual_hash_length != hash_length )
2417 return( PSA_ERROR_INVALID_SIGNATURE );
2418 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
2419 return( PSA_ERROR_INVALID_SIGNATURE );
2420 return( PSA_SUCCESS );
2421}
2422
Gilles Peskine0a749c82019-11-28 19:33:58 +01002423psa_status_t psa_hash_compute( psa_algorithm_t alg,
2424 const uint8_t *input, size_t input_length,
2425 uint8_t *hash, size_t hash_size,
2426 size_t *hash_length )
2427{
2428 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
2429 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2430
2431 *hash_length = hash_size;
2432 status = psa_hash_setup( &operation, alg );
2433 if( status != PSA_SUCCESS )
2434 goto exit;
2435 status = psa_hash_update( &operation, input, input_length );
2436 if( status != PSA_SUCCESS )
2437 goto exit;
2438 status = psa_hash_finish( &operation, hash, hash_size, hash_length );
2439 if( status != PSA_SUCCESS )
2440 goto exit;
2441
2442exit:
2443 if( status == PSA_SUCCESS )
2444 status = psa_hash_abort( &operation );
2445 else
2446 psa_hash_abort( &operation );
2447 return( status );
2448}
2449
2450psa_status_t psa_hash_compare( psa_algorithm_t alg,
2451 const uint8_t *input, size_t input_length,
2452 const uint8_t *hash, size_t hash_length )
2453{
2454 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
2455 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2456
2457 status = psa_hash_setup( &operation, alg );
2458 if( status != PSA_SUCCESS )
2459 goto exit;
2460 status = psa_hash_update( &operation, input, input_length );
2461 if( status != PSA_SUCCESS )
2462 goto exit;
2463 status = psa_hash_verify( &operation, hash, hash_length );
2464 if( status != PSA_SUCCESS )
2465 goto exit;
2466
2467exit:
2468 if( status == PSA_SUCCESS )
2469 status = psa_hash_abort( &operation );
2470 else
2471 psa_hash_abort( &operation );
2472 return( status );
2473}
2474
Gilles Peskineeb35d782019-01-22 17:56:16 +01002475psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
2476 psa_hash_operation_t *target_operation )
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002477{
2478 if( target_operation->alg != 0 )
2479 return( PSA_ERROR_BAD_STATE );
2480
2481 switch( source_operation->alg )
2482 {
2483 case 0:
2484 return( PSA_ERROR_BAD_STATE );
2485#if defined(MBEDTLS_MD2_C)
2486 case PSA_ALG_MD2:
2487 mbedtls_md2_clone( &target_operation->ctx.md2,
2488 &source_operation->ctx.md2 );
2489 break;
2490#endif
2491#if defined(MBEDTLS_MD4_C)
2492 case PSA_ALG_MD4:
2493 mbedtls_md4_clone( &target_operation->ctx.md4,
2494 &source_operation->ctx.md4 );
2495 break;
2496#endif
2497#if defined(MBEDTLS_MD5_C)
2498 case PSA_ALG_MD5:
2499 mbedtls_md5_clone( &target_operation->ctx.md5,
2500 &source_operation->ctx.md5 );
2501 break;
2502#endif
2503#if defined(MBEDTLS_RIPEMD160_C)
2504 case PSA_ALG_RIPEMD160:
2505 mbedtls_ripemd160_clone( &target_operation->ctx.ripemd160,
2506 &source_operation->ctx.ripemd160 );
2507 break;
2508#endif
2509#if defined(MBEDTLS_SHA1_C)
2510 case PSA_ALG_SHA_1:
2511 mbedtls_sha1_clone( &target_operation->ctx.sha1,
2512 &source_operation->ctx.sha1 );
2513 break;
2514#endif
2515#if defined(MBEDTLS_SHA256_C)
2516 case PSA_ALG_SHA_224:
2517 case PSA_ALG_SHA_256:
2518 mbedtls_sha256_clone( &target_operation->ctx.sha256,
2519 &source_operation->ctx.sha256 );
2520 break;
2521#endif
2522#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002523#if !defined(MBEDTLS_SHA512_NO_SHA384)
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002524 case PSA_ALG_SHA_384:
Manuel Pégourié-Gonnard792b16d2020-01-07 10:13:18 +01002525#endif
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01002526 case PSA_ALG_SHA_512:
2527 mbedtls_sha512_clone( &target_operation->ctx.sha512,
2528 &source_operation->ctx.sha512 );
2529 break;
2530#endif
2531 default:
2532 return( PSA_ERROR_NOT_SUPPORTED );
2533 }
2534
2535 target_operation->alg = source_operation->alg;
2536 return( PSA_SUCCESS );
2537}
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002538
2539
Gilles Peskine9ef733f2018-02-07 21:05:37 +01002540/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01002541/* MAC */
2542/****************************************************************/
2543
Michael Thomas863b5d62020-02-10 19:41:16 +00002544const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01002545 psa_algorithm_t alg,
2546 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02002547 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03002548 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002549{
Gilles Peskine8c9def32018-02-08 10:02:12 +01002550 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03002551 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002552
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02002553 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02002554 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02002555
Gilles Peskine8c9def32018-02-08 10:02:12 +01002556 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
2557 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03002558 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002559 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002560 case PSA_ALG_ARC4:
Gilles Peskine26869f22019-05-06 15:25:00 +02002561 case PSA_ALG_CHACHA20:
Gilles Peskine8c9def32018-02-08 10:02:12 +01002562 mode = MBEDTLS_MODE_STREAM;
2563 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002564 case PSA_ALG_CTR:
2565 mode = MBEDTLS_MODE_CTR;
2566 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002567 case PSA_ALG_CFB:
2568 mode = MBEDTLS_MODE_CFB;
2569 break;
2570 case PSA_ALG_OFB:
2571 mode = MBEDTLS_MODE_OFB;
2572 break;
2573 case PSA_ALG_CBC_NO_PADDING:
2574 mode = MBEDTLS_MODE_CBC;
2575 break;
2576 case PSA_ALG_CBC_PKCS7:
2577 mode = MBEDTLS_MODE_CBC;
2578 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02002579 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01002580 mode = MBEDTLS_MODE_CCM;
2581 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02002582 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01002583 mode = MBEDTLS_MODE_GCM;
2584 break;
Gilles Peskine26869f22019-05-06 15:25:00 +02002585 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CHACHA20_POLY1305, 0 ):
2586 mode = MBEDTLS_MODE_CHACHAPOLY;
2587 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002588 default:
2589 return( NULL );
2590 }
2591 }
2592 else if( alg == PSA_ALG_CMAC )
2593 mode = MBEDTLS_MODE_ECB;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002594 else
2595 return( NULL );
2596
2597 switch( key_type )
2598 {
2599 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03002600 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002601 break;
2602 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002603 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
2604 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01002605 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03002606 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002607 else
mohammad1603f4f0d612018-06-03 15:04:51 +03002608 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002609 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
2610 * but two-key Triple-DES is functionally three-key Triple-DES
2611 * with K1=K3, so that's how we present it to mbedtls. */
2612 if( key_bits == 128 )
2613 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002614 break;
2615 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03002616 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002617 break;
2618 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03002619 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002620 break;
Gilles Peskine26869f22019-05-06 15:25:00 +02002621 case PSA_KEY_TYPE_CHACHA20:
2622 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
2623 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002624 default:
2625 return( NULL );
2626 }
mohammad1603f4f0d612018-06-03 15:04:51 +03002627 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03002628 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002629
Jaeden Amero23bbb752018-06-26 14:16:54 +01002630 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
2631 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002632}
2633
Gilles Peskinea05219c2018-11-16 16:02:56 +01002634#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002635static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03002636{
Gilles Peskine2d277862018-06-18 15:41:12 +02002637 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03002638 {
2639 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002640 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002641 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002642 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002643 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002644 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002645 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002646 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002647 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002648 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002649 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002650 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002651 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002652 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002653 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03002654 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002655 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02002656 return( 128 );
2657 default:
2658 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03002659 }
2660}
Gilles Peskinea05219c2018-11-16 16:02:56 +01002661#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03002662
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002663/* Initialize the MAC operation structure. Once this function has been
2664 * called, psa_mac_abort can run and will do the right thing. */
2665static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
2666 psa_algorithm_t alg )
2667{
2668 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
2669
2670 operation->alg = alg;
2671 operation->key_set = 0;
2672 operation->iv_set = 0;
2673 operation->iv_required = 0;
2674 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002675 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002676
2677#if defined(MBEDTLS_CMAC_C)
2678 if( alg == PSA_ALG_CMAC )
2679 {
2680 operation->iv_required = 0;
2681 mbedtls_cipher_init( &operation->ctx.cmac );
2682 status = PSA_SUCCESS;
2683 }
2684 else
2685#endif /* MBEDTLS_CMAC_C */
2686#if defined(MBEDTLS_MD_C)
2687 if( PSA_ALG_IS_HMAC( operation->alg ) )
2688 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02002689 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
2690 operation->ctx.hmac.hash_ctx.alg = 0;
2691 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002692 }
2693 else
2694#endif /* MBEDTLS_MD_C */
2695 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02002696 if( ! PSA_ALG_IS_MAC( alg ) )
2697 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002698 }
2699
2700 if( status != PSA_SUCCESS )
2701 memset( operation, 0, sizeof( *operation ) );
2702 return( status );
2703}
2704
Gilles Peskine01126fa2018-07-12 17:04:55 +02002705#if defined(MBEDTLS_MD_C)
2706static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
2707{
Gilles Peskine3f108122018-12-07 18:14:53 +01002708 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002709 return( psa_hash_abort( &hmac->hash_ctx ) );
2710}
2711#endif /* MBEDTLS_MD_C */
2712
Gilles Peskine8c9def32018-02-08 10:02:12 +01002713psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
2714{
Gilles Peskinefbfac682018-07-08 20:51:54 +02002715 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002716 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02002717 /* The object has (apparently) been initialized but it is not
2718 * in use. It's ok to call abort on such an object, and there's
2719 * nothing to do. */
2720 return( PSA_SUCCESS );
2721 }
2722 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002723#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002724 if( operation->alg == PSA_ALG_CMAC )
2725 {
2726 mbedtls_cipher_free( &operation->ctx.cmac );
2727 }
2728 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002729#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01002730#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002731 if( PSA_ALG_IS_HMAC( operation->alg ) )
2732 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002733 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002734 }
2735 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002736#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02002737 {
2738 /* Sanity check (shouldn't happen: operation->alg should
2739 * always have been initialized to a valid value). */
2740 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002741 }
Moran Peker41deec42018-04-04 15:43:05 +03002742
Gilles Peskine8c9def32018-02-08 10:02:12 +01002743 operation->alg = 0;
2744 operation->key_set = 0;
2745 operation->iv_set = 0;
2746 operation->iv_required = 0;
2747 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002748 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002749
Gilles Peskine8c9def32018-02-08 10:02:12 +01002750 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002751
2752bad_state:
2753 /* If abort is called on an uninitialized object, we can't trust
2754 * anything. Wipe the object in case it contains confidential data.
2755 * This may result in a memory leak if a pointer gets overwritten,
2756 * but it's too late to do anything about this. */
2757 memset( operation, 0, sizeof( *operation ) );
2758 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002759}
2760
Gilles Peskinee3b07d82018-06-19 11:57:35 +02002761#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02002762static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002763 size_t key_bits,
Gilles Peskine2f060a82018-12-04 17:12:32 +01002764 psa_key_slot_t *slot,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002765 const mbedtls_cipher_info_t *cipher_info )
2766{
Janos Follath24eed8d2019-11-22 13:21:35 +00002767 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002768
2769 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002770
2771 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
2772 if( ret != 0 )
2773 return( ret );
2774
2775 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
2776 slot->data.raw.data,
2777 key_bits );
2778 return( ret );
2779}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02002780#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002781
Gilles Peskine248051a2018-06-20 16:09:38 +02002782#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02002783static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
2784 const uint8_t *key,
2785 size_t key_length,
2786 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002787{
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02002788 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002789 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002790 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002791 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002792 psa_status_t status;
2793
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002794 /* Sanity checks on block_size, to guarantee that there won't be a buffer
2795 * overflow below. This should never trigger if the hash algorithm
2796 * is implemented correctly. */
2797 /* The size checks against the ipad and opad buffers cannot be written
2798 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
2799 * because that triggers -Wlogical-op on GCC 7.3. */
2800 if( block_size > sizeof( ipad ) )
2801 return( PSA_ERROR_NOT_SUPPORTED );
2802 if( block_size > sizeof( hmac->opad ) )
2803 return( PSA_ERROR_NOT_SUPPORTED );
2804 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002805 return( PSA_ERROR_NOT_SUPPORTED );
2806
Gilles Peskined223b522018-06-11 18:12:58 +02002807 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002808 {
Gilles Peskine84b8fc82019-11-28 20:07:20 +01002809 status = psa_hash_compute( hash_alg, key, key_length,
2810 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002811 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02002812 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002813 }
Gilles Peskine96889972018-07-12 17:07:03 +02002814 /* A 0-length key is not commonly used in HMAC when used as a MAC,
2815 * but it is permitted. It is common when HMAC is used in HKDF, for
2816 * example. Don't call `memcpy` in the 0-length because `key` could be
2817 * an invalid pointer which would make the behavior undefined. */
2818 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02002819 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002820
Gilles Peskined223b522018-06-11 18:12:58 +02002821 /* ipad contains the key followed by garbage. Xor and fill with 0x36
2822 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002823 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02002824 ipad[i] ^= 0x36;
2825 memset( ipad + key_length, 0x36, block_size - key_length );
2826
2827 /* Copy the key material from ipad to opad, flipping the requisite bits,
2828 * and filling the rest of opad with the requisite constant. */
2829 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02002830 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
2831 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002832
Gilles Peskine01126fa2018-07-12 17:04:55 +02002833 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002834 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002835 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002836
Gilles Peskine01126fa2018-07-12 17:04:55 +02002837 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002838
2839cleanup:
Ron Eldor296eca62019-09-10 15:21:37 +03002840 mbedtls_platform_zeroize( ipad, sizeof(ipad) );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002841
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002842 return( status );
2843}
Gilles Peskine248051a2018-06-20 16:09:38 +02002844#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002845
Gilles Peskine89167cb2018-07-08 20:12:23 +02002846static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002847 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02002848 psa_algorithm_t alg,
2849 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002850{
Gilles Peskine8c9def32018-02-08 10:02:12 +01002851 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +01002852 psa_key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002853 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002854 psa_key_usage_t usage =
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01002855 is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH;
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02002856 uint8_t truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02002857 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002858
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002859 /* A context must be freshly initialized before it can be set up. */
2860 if( operation->alg != 0 )
2861 {
2862 return( PSA_ERROR_BAD_STATE );
2863 }
2864
Gilles Peskined911eb72018-08-14 15:18:45 +02002865 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002866 if( status != PSA_SUCCESS )
2867 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002868 if( is_sign )
2869 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002870
Gilles Peskine28f8f302019-07-24 13:30:31 +02002871 status = psa_get_transparent_key( handle, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002872 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002873 goto exit;
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02002874 key_bits = psa_get_key_slot_bits( slot );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002875
Gilles Peskine8c9def32018-02-08 10:02:12 +01002876#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02002877 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002878 {
2879 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02002880 mbedtls_cipher_info_from_psa( full_length_alg,
Gilles Peskine8e338702019-07-30 20:06:31 +02002881 slot->attr.type, key_bits, NULL );
Janos Follath24eed8d2019-11-22 13:21:35 +00002882 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinefbfac682018-07-08 20:51:54 +02002883 if( cipher_info == NULL )
2884 {
2885 status = PSA_ERROR_NOT_SUPPORTED;
2886 goto exit;
2887 }
2888 operation->mac_size = cipher_info->block_size;
2889 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
2890 status = mbedtls_to_psa_error( ret );
2891 }
2892 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002893#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01002894#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02002895 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002896 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02002897 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002898 if( hash_alg == 0 )
2899 {
2900 status = PSA_ERROR_NOT_SUPPORTED;
2901 goto exit;
2902 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002903
2904 operation->mac_size = PSA_HASH_SIZE( hash_alg );
2905 /* Sanity check. This shouldn't fail on a valid configuration. */
2906 if( operation->mac_size == 0 ||
2907 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
2908 {
2909 status = PSA_ERROR_NOT_SUPPORTED;
2910 goto exit;
2911 }
2912
Gilles Peskine8e338702019-07-30 20:06:31 +02002913 if( slot->attr.type != PSA_KEY_TYPE_HMAC )
Gilles Peskine01126fa2018-07-12 17:04:55 +02002914 {
2915 status = PSA_ERROR_INVALID_ARGUMENT;
2916 goto exit;
2917 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002918
Gilles Peskine01126fa2018-07-12 17:04:55 +02002919 status = psa_hmac_setup_internal( &operation->ctx.hmac,
2920 slot->data.raw.data,
2921 slot->data.raw.bytes,
2922 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002923 }
2924 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002925#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02002926 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00002927 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02002928 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002929 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002930
Gilles Peskined911eb72018-08-14 15:18:45 +02002931 if( truncated == 0 )
2932 {
2933 /* The "normal" case: untruncated algorithm. Nothing to do. */
2934 }
2935 else if( truncated < 4 )
2936 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02002937 /* A very short MAC is too short for security since it can be
2938 * brute-forced. Ancient protocols with 32-bit MACs do exist,
2939 * so we make this our minimum, even though 32 bits is still
2940 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02002941 status = PSA_ERROR_NOT_SUPPORTED;
2942 }
2943 else if( truncated > operation->mac_size )
2944 {
2945 /* It's impossible to "truncate" to a larger length. */
2946 status = PSA_ERROR_INVALID_ARGUMENT;
2947 }
2948 else
2949 operation->mac_size = truncated;
2950
Gilles Peskinefbfac682018-07-08 20:51:54 +02002951exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002952 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002953 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002954 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002955 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002956 else
2957 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002958 operation->key_set = 1;
2959 }
2960 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002961}
2962
Gilles Peskine89167cb2018-07-08 20:12:23 +02002963psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002964 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02002965 psa_algorithm_t alg )
2966{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002967 return( psa_mac_setup( operation, handle, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002968}
2969
2970psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002971 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02002972 psa_algorithm_t alg )
2973{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002974 return( psa_mac_setup( operation, handle, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002975}
2976
Gilles Peskine8c9def32018-02-08 10:02:12 +01002977psa_status_t psa_mac_update( psa_mac_operation_t *operation,
2978 const uint8_t *input,
2979 size_t input_length )
2980{
Gilles Peskinefbfac682018-07-08 20:51:54 +02002981 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002982 if( ! operation->key_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00002983 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002984 if( operation->iv_required && ! operation->iv_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00002985 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002986 operation->has_input = 1;
2987
Gilles Peskine8c9def32018-02-08 10:02:12 +01002988#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002989 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03002990 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02002991 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
2992 input, input_length );
2993 status = mbedtls_to_psa_error( ret );
2994 }
2995 else
2996#endif /* MBEDTLS_CMAC_C */
2997#if defined(MBEDTLS_MD_C)
2998 if( PSA_ALG_IS_HMAC( operation->alg ) )
2999 {
3000 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
3001 input_length );
3002 }
3003 else
3004#endif /* MBEDTLS_MD_C */
3005 {
3006 /* This shouldn't happen if `operation` was initialized by
3007 * a setup function. */
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003008 return( PSA_ERROR_BAD_STATE );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03003009 }
3010
Gilles Peskinefbfac682018-07-08 20:51:54 +02003011 if( status != PSA_SUCCESS )
3012 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003013 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003014}
3015
Gilles Peskine01126fa2018-07-12 17:04:55 +02003016#if defined(MBEDTLS_MD_C)
3017static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
3018 uint8_t *mac,
3019 size_t mac_size )
3020{
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02003021 uint8_t tmp[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine01126fa2018-07-12 17:04:55 +02003022 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
3023 size_t hash_size = 0;
3024 size_t block_size = psa_get_hash_block_size( hash_alg );
3025 psa_status_t status;
3026
Gilles Peskine01126fa2018-07-12 17:04:55 +02003027 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
3028 if( status != PSA_SUCCESS )
3029 return( status );
3030 /* From here on, tmp needs to be wiped. */
3031
3032 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
3033 if( status != PSA_SUCCESS )
3034 goto exit;
3035
3036 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
3037 if( status != PSA_SUCCESS )
3038 goto exit;
3039
3040 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
3041 if( status != PSA_SUCCESS )
3042 goto exit;
3043
Gilles Peskined911eb72018-08-14 15:18:45 +02003044 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
3045 if( status != PSA_SUCCESS )
3046 goto exit;
3047
3048 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003049
3050exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01003051 mbedtls_platform_zeroize( tmp, hash_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02003052 return( status );
3053}
3054#endif /* MBEDTLS_MD_C */
3055
mohammad16036df908f2018-04-02 08:34:15 -07003056static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02003057 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003058 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003059{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02003060 if( ! operation->key_set )
3061 return( PSA_ERROR_BAD_STATE );
3062 if( operation->iv_required && ! operation->iv_set )
3063 return( PSA_ERROR_BAD_STATE );
3064
Gilles Peskine8c9def32018-02-08 10:02:12 +01003065 if( mac_size < operation->mac_size )
3066 return( PSA_ERROR_BUFFER_TOO_SMALL );
3067
Gilles Peskine8c9def32018-02-08 10:02:12 +01003068#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02003069 if( operation->alg == PSA_ALG_CMAC )
3070 {
Gilles Peskined911eb72018-08-14 15:18:45 +02003071 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
3072 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
3073 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02003074 memcpy( mac, tmp, operation->mac_size );
Gilles Peskine3f108122018-12-07 18:14:53 +01003075 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003076 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003077 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02003078 else
3079#endif /* MBEDTLS_CMAC_C */
3080#if defined(MBEDTLS_MD_C)
3081 if( PSA_ALG_IS_HMAC( operation->alg ) )
3082 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02003083 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02003084 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02003085 }
3086 else
3087#endif /* MBEDTLS_MD_C */
3088 {
3089 /* This shouldn't happen if `operation` was initialized by
3090 * a setup function. */
3091 return( PSA_ERROR_BAD_STATE );
3092 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01003093}
3094
Gilles Peskineacd4be32018-07-08 19:56:25 +02003095psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
3096 uint8_t *mac,
3097 size_t mac_size,
3098 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07003099{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003100 psa_status_t status;
3101
Jaeden Amero252ef282019-02-15 14:05:35 +00003102 if( operation->alg == 0 )
3103 {
3104 return( PSA_ERROR_BAD_STATE );
3105 }
3106
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003107 /* Fill the output buffer with something that isn't a valid mac
3108 * (barring an attack on the mac and deliberately-crafted input),
3109 * in case the caller doesn't check the return status properly. */
3110 *mac_length = mac_size;
3111 /* If mac_size is 0 then mac may be NULL and then the
3112 * call to memset would have undefined behavior. */
3113 if( mac_size != 0 )
3114 memset( mac, '!', mac_size );
3115
Gilles Peskine89167cb2018-07-08 20:12:23 +02003116 if( ! operation->is_sign )
3117 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003118 return( PSA_ERROR_BAD_STATE );
Gilles Peskine89167cb2018-07-08 20:12:23 +02003119 }
mohammad16036df908f2018-04-02 08:34:15 -07003120
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003121 status = psa_mac_finish_internal( operation, mac, mac_size );
3122
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003123 if( status == PSA_SUCCESS )
3124 {
3125 status = psa_mac_abort( operation );
3126 if( status == PSA_SUCCESS )
3127 *mac_length = operation->mac_size;
3128 else
3129 memset( mac, '!', mac_size );
3130 }
3131 else
3132 psa_mac_abort( operation );
3133 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07003134}
3135
Gilles Peskineacd4be32018-07-08 19:56:25 +02003136psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
3137 const uint8_t *mac,
3138 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01003139{
Gilles Peskine828ed142018-06-18 23:25:51 +02003140 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07003141 psa_status_t status;
3142
Jaeden Amero252ef282019-02-15 14:05:35 +00003143 if( operation->alg == 0 )
3144 {
3145 return( PSA_ERROR_BAD_STATE );
3146 }
3147
Gilles Peskine89167cb2018-07-08 20:12:23 +02003148 if( operation->is_sign )
3149 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003150 return( PSA_ERROR_BAD_STATE );
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003151 }
3152 if( operation->mac_size != mac_length )
3153 {
3154 status = PSA_ERROR_INVALID_SIGNATURE;
3155 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02003156 }
mohammad16036df908f2018-04-02 08:34:15 -07003157
3158 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003159 actual_mac, sizeof( actual_mac ) );
Gilles Peskine28cd4162020-01-20 16:31:06 +01003160 if( status != PSA_SUCCESS )
3161 goto cleanup;
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003162
3163 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
3164 status = PSA_ERROR_INVALID_SIGNATURE;
3165
3166cleanup:
3167 if( status == PSA_SUCCESS )
3168 status = psa_mac_abort( operation );
3169 else
3170 psa_mac_abort( operation );
3171
Gilles Peskine3f108122018-12-07 18:14:53 +01003172 mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02003173
Gilles Peskine5d0b8642018-07-08 20:35:02 +02003174 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01003175}
3176
3177
Gilles Peskine20035e32018-02-03 22:44:14 +01003178
Gilles Peskine20035e32018-02-03 22:44:14 +01003179/****************************************************************/
3180/* Asymmetric cryptography */
3181/****************************************************************/
3182
Gilles Peskine2b450e32018-06-27 15:42:46 +02003183#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02003184/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003185 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02003186static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
3187 size_t hash_length,
3188 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003189{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02003190 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02003191 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003192 *md_alg = mbedtls_md_get_type( md_info );
3193
3194 /* The Mbed TLS RSA module uses an unsigned int for hash length
3195 * parameters. Validate that it fits so that we don't risk an
3196 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003197#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003198 if( hash_length > UINT_MAX )
3199 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003200#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003201
3202#if defined(MBEDTLS_PKCS1_V15)
3203 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
3204 * must be correct. */
3205 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
3206 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003207 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003208 if( md_info == NULL )
3209 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02003210 if( mbedtls_md_get_size( md_info ) != hash_length )
3211 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003212 }
3213#endif /* MBEDTLS_PKCS1_V15 */
3214
3215#if defined(MBEDTLS_PKCS1_V21)
3216 /* PSS requires a hash internally. */
3217 if( PSA_ALG_IS_RSA_PSS( alg ) )
3218 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02003219 if( md_info == NULL )
3220 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003221 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003222#endif /* MBEDTLS_PKCS1_V21 */
3223
Gilles Peskine61b91d42018-06-08 16:09:36 +02003224 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03003225}
3226
Michael Thomas7ab51742020-02-12 03:48:56 +00003227psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003228 psa_algorithm_t alg,
3229 const uint8_t *hash,
3230 size_t hash_length,
3231 uint8_t *signature,
3232 size_t signature_size,
3233 size_t *signature_length )
3234{
3235 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003236 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003237 mbedtls_md_type_t md_alg;
3238
3239 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
3240 if( status != PSA_SUCCESS )
3241 return( status );
3242
Gilles Peskine630a18a2018-06-29 17:49:35 +02003243 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02003244 return( PSA_ERROR_BUFFER_TOO_SMALL );
3245
3246#if defined(MBEDTLS_PKCS1_V15)
3247 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
3248 {
3249 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
3250 MBEDTLS_MD_NONE );
3251 ret = mbedtls_rsa_pkcs1_sign( rsa,
3252 mbedtls_ctr_drbg_random,
3253 &global_data.ctr_drbg,
3254 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003255 md_alg,
3256 (unsigned int) hash_length,
3257 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003258 signature );
3259 }
3260 else
3261#endif /* MBEDTLS_PKCS1_V15 */
3262#if defined(MBEDTLS_PKCS1_V21)
3263 if( PSA_ALG_IS_RSA_PSS( alg ) )
3264 {
3265 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3266 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
3267 mbedtls_ctr_drbg_random,
3268 &global_data.ctr_drbg,
3269 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003270 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003271 (unsigned int) hash_length,
3272 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003273 signature );
3274 }
3275 else
3276#endif /* MBEDTLS_PKCS1_V21 */
3277 {
3278 return( PSA_ERROR_INVALID_ARGUMENT );
3279 }
3280
3281 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02003282 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003283 return( mbedtls_to_psa_error( ret ) );
3284}
3285
Michael Thomas7ab51742020-02-12 03:48:56 +00003286psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003287 psa_algorithm_t alg,
3288 const uint8_t *hash,
3289 size_t hash_length,
3290 const uint8_t *signature,
3291 size_t signature_length )
3292{
3293 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003294 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine2b450e32018-06-27 15:42:46 +02003295 mbedtls_md_type_t md_alg;
3296
3297 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
3298 if( status != PSA_SUCCESS )
3299 return( status );
3300
Gilles Peskine89cc74f2019-09-12 22:08:23 +02003301 if( signature_length != mbedtls_rsa_get_len( rsa ) )
3302 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003303
3304#if defined(MBEDTLS_PKCS1_V15)
3305 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
3306 {
3307 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
3308 MBEDTLS_MD_NONE );
3309 ret = mbedtls_rsa_pkcs1_verify( rsa,
3310 mbedtls_ctr_drbg_random,
3311 &global_data.ctr_drbg,
3312 MBEDTLS_RSA_PUBLIC,
3313 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003314 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003315 hash,
3316 signature );
3317 }
3318 else
3319#endif /* MBEDTLS_PKCS1_V15 */
3320#if defined(MBEDTLS_PKCS1_V21)
3321 if( PSA_ALG_IS_RSA_PSS( alg ) )
3322 {
3323 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3324 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
3325 mbedtls_ctr_drbg_random,
3326 &global_data.ctr_drbg,
3327 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02003328 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01003329 (unsigned int) hash_length,
3330 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02003331 signature );
3332 }
3333 else
3334#endif /* MBEDTLS_PKCS1_V21 */
3335 {
3336 return( PSA_ERROR_INVALID_ARGUMENT );
3337 }
Gilles Peskineef12c632018-09-13 20:37:48 +02003338
3339 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
3340 * the rest of the signature is invalid". This has little use in
3341 * practice and PSA doesn't report this distinction. */
3342 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
3343 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02003344 return( mbedtls_to_psa_error( ret ) );
3345}
3346#endif /* MBEDTLS_RSA_C */
3347
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003348#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003349/* `ecp` cannot be const because `ecp->grp` needs to be non-const
3350 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
3351 * (even though these functions don't modify it). */
Michael Thomas257d3be2020-02-24 17:16:42 +00003352psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003353 psa_algorithm_t alg,
3354 const uint8_t *hash,
3355 size_t hash_length,
3356 uint8_t *signature,
3357 size_t signature_size,
3358 size_t *signature_length )
3359{
Janos Follath24eed8d2019-11-22 13:21:35 +00003360 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003361 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003362 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003363 mbedtls_mpi_init( &r );
3364 mbedtls_mpi_init( &s );
3365
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003366 if( signature_size < 2 * curve_bytes )
3367 {
3368 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
3369 goto cleanup;
3370 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003371
Gilles Peskinea05219c2018-11-16 16:02:56 +01003372#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003373 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
3374 {
3375 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
3376 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
3377 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
Darryl Green5e843fa2019-09-05 14:06:34 +01003378 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det_ext( &ecp->grp, &r, &s,
3379 &ecp->d, hash,
3380 hash_length, md_alg,
3381 mbedtls_ctr_drbg_random,
3382 &global_data.ctr_drbg ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003383 }
3384 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01003385#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003386 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003387 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003388 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
3389 hash, hash_length,
3390 mbedtls_ctr_drbg_random,
3391 &global_data.ctr_drbg ) );
3392 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003393
3394 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
3395 signature,
3396 curve_bytes ) );
3397 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
3398 signature + curve_bytes,
3399 curve_bytes ) );
3400
3401cleanup:
3402 mbedtls_mpi_free( &r );
3403 mbedtls_mpi_free( &s );
3404 if( ret == 0 )
3405 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003406 return( mbedtls_to_psa_error( ret ) );
3407}
3408
Michael Thomas257d3be2020-02-24 17:16:42 +00003409psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003410 const uint8_t *hash,
3411 size_t hash_length,
3412 const uint8_t *signature,
3413 size_t signature_length )
3414{
Janos Follath24eed8d2019-11-22 13:21:35 +00003415 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003416 mbedtls_mpi r, s;
3417 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
3418 mbedtls_mpi_init( &r );
3419 mbedtls_mpi_init( &s );
3420
3421 if( signature_length != 2 * curve_bytes )
3422 return( PSA_ERROR_INVALID_SIGNATURE );
3423
3424 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
3425 signature,
3426 curve_bytes ) );
3427 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
3428 signature + curve_bytes,
3429 curve_bytes ) );
3430
3431 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
3432 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003433
3434cleanup:
3435 mbedtls_mpi_free( &r );
3436 mbedtls_mpi_free( &s );
3437 return( mbedtls_to_psa_error( ret ) );
3438}
3439#endif /* MBEDTLS_ECDSA_C */
3440
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003441psa_status_t psa_sign_hash( psa_key_handle_t handle,
3442 psa_algorithm_t alg,
3443 const uint8_t *hash,
3444 size_t hash_length,
3445 uint8_t *signature,
3446 size_t signature_size,
3447 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01003448{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003449 psa_key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003450 psa_status_t status;
Gilles Peskineedc64242019-08-07 21:05:07 +02003451#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
3452 const psa_drv_se_t *drv;
3453 psa_drv_se_context_t *drv_context;
3454#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003455
3456 *signature_length = signature_size;
Gilles Peskine4019f0e2019-09-12 22:05:59 +02003457 /* Immediately reject a zero-length signature buffer. This guarantees
3458 * that signature must be a valid pointer. (On the other hand, the hash
3459 * buffer can in principle be empty since it doesn't actually have
3460 * to be a hash.) */
3461 if( signature_size == 0 )
3462 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003463
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003464 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN_HASH, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003465 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003466 goto exit;
Gilles Peskine8e338702019-07-30 20:06:31 +02003467 if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003468 {
3469 status = PSA_ERROR_INVALID_ARGUMENT;
3470 goto exit;
3471 }
Gilles Peskine20035e32018-02-03 22:44:14 +01003472
Gilles Peskineedc64242019-08-07 21:05:07 +02003473#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
3474 if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
3475 {
3476 if( drv->asymmetric == NULL ||
3477 drv->asymmetric->p_sign == NULL )
3478 {
3479 status = PSA_ERROR_NOT_SUPPORTED;
3480 goto exit;
3481 }
3482 status = drv->asymmetric->p_sign( drv_context,
3483 slot->data.se.slot_number,
3484 alg,
3485 hash, hash_length,
3486 signature, signature_size,
3487 signature_length );
3488 }
3489 else
3490#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine20035e32018-02-03 22:44:14 +01003491#if defined(MBEDTLS_RSA_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02003492 if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskine20035e32018-02-03 22:44:14 +01003493 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003494 status = psa_rsa_sign( slot->data.rsa,
3495 alg,
3496 hash, hash_length,
3497 signature, signature_size,
3498 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01003499 }
3500 else
3501#endif /* defined(MBEDTLS_RSA_C) */
3502#if defined(MBEDTLS_ECP_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02003503 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01003504 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003505#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01003506 if(
3507#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
3508 PSA_ALG_IS_ECDSA( alg )
3509#else
3510 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
3511#endif
3512 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003513 status = psa_ecdsa_sign( slot->data.ecp,
3514 alg,
3515 hash, hash_length,
3516 signature, signature_size,
3517 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003518 else
3519#endif /* defined(MBEDTLS_ECDSA_C) */
3520 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003521 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003522 }
itayzafrir5c753392018-05-08 11:18:38 +03003523 }
3524 else
3525#endif /* defined(MBEDTLS_ECP_C) */
3526 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003527 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01003528 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003529
3530exit:
3531 /* Fill the unused part of the output buffer (the whole buffer on error,
3532 * the trailing part on success) with something that isn't a valid mac
3533 * (barring an attack on the mac and deliberately-crafted input),
3534 * in case the caller doesn't check the return status properly. */
3535 if( status == PSA_SUCCESS )
3536 memset( signature + *signature_length, '!',
3537 signature_size - *signature_length );
Gilles Peskine4019f0e2019-09-12 22:05:59 +02003538 else
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003539 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02003540 /* If signature_size is 0 then we have nothing to do. We must not call
3541 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02003542 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03003543}
3544
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003545psa_status_t psa_verify_hash( psa_key_handle_t handle,
3546 psa_algorithm_t alg,
3547 const uint8_t *hash,
3548 size_t hash_length,
3549 const uint8_t *signature,
3550 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03003551{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003552 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003553 psa_status_t status;
Gilles Peskineedc64242019-08-07 21:05:07 +02003554#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
3555 const psa_drv_se_t *drv;
3556 psa_drv_se_context_t *drv_context;
3557#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine2b450e32018-06-27 15:42:46 +02003558
Gilles Peskine89d8c5c2019-11-26 17:01:59 +01003559 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY_HASH, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003560 if( status != PSA_SUCCESS )
3561 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03003562
Gilles Peskineedc64242019-08-07 21:05:07 +02003563#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
3564 if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
3565 {
3566 if( drv->asymmetric == NULL ||
3567 drv->asymmetric->p_verify == NULL )
3568 return( PSA_ERROR_NOT_SUPPORTED );
3569 return( drv->asymmetric->p_verify( drv_context,
3570 slot->data.se.slot_number,
3571 alg,
3572 hash, hash_length,
3573 signature, signature_length ) );
3574 }
3575 else
3576#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskine61b91d42018-06-08 16:09:36 +02003577#if defined(MBEDTLS_RSA_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02003578 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003579 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02003580 return( psa_rsa_verify( slot->data.rsa,
3581 alg,
3582 hash, hash_length,
3583 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003584 }
3585 else
3586#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03003587#if defined(MBEDTLS_ECP_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02003588 if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
itayzafrir5c753392018-05-08 11:18:38 +03003589 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003590#if defined(MBEDTLS_ECDSA_C)
3591 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02003592 return( psa_ecdsa_verify( slot->data.ecp,
3593 hash, hash_length,
3594 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02003595 else
3596#endif /* defined(MBEDTLS_ECDSA_C) */
3597 {
3598 return( PSA_ERROR_INVALID_ARGUMENT );
3599 }
itayzafrir5c753392018-05-08 11:18:38 +03003600 }
Gilles Peskine20035e32018-02-03 22:44:14 +01003601 else
3602#endif /* defined(MBEDTLS_ECP_C) */
3603 {
3604 return( PSA_ERROR_NOT_SUPPORTED );
3605 }
3606}
3607
Gilles Peskine072ac562018-06-30 00:21:29 +02003608#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
3609static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
3610 mbedtls_rsa_context *rsa )
3611{
3612 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
3613 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
3614 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
3615 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
3616}
3617#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
3618
Gilles Peskinec5487a82018-12-03 18:08:14 +01003619psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02003620 psa_algorithm_t alg,
3621 const uint8_t *input,
3622 size_t input_length,
3623 const uint8_t *salt,
3624 size_t salt_length,
3625 uint8_t *output,
3626 size_t output_size,
3627 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003628{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003629 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003630 psa_status_t status;
3631
Darryl Green5cc689a2018-07-24 15:34:10 +01003632 (void) input;
3633 (void) input_length;
3634 (void) salt;
3635 (void) output;
3636 (void) output_size;
3637
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03003638 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003639
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02003640 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
3641 return( PSA_ERROR_INVALID_ARGUMENT );
3642
Gilles Peskine28f8f302019-07-24 13:30:31 +02003643 status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003644 if( status != PSA_SUCCESS )
3645 return( status );
Gilles Peskine8e338702019-07-30 20:06:31 +02003646 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) ||
3647 PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003648 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003649
3650#if defined(MBEDTLS_RSA_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02003651 if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003652 {
3653 mbedtls_rsa_context *rsa = slot->data.rsa;
Janos Follath24eed8d2019-11-22 13:21:35 +00003654 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine630a18a2018-06-29 17:49:35 +02003655 if( output_size < mbedtls_rsa_get_len( rsa ) )
Vikas Katariya21599b62019-08-02 12:26:29 +01003656 return( PSA_ERROR_BUFFER_TOO_SMALL );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003657#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02003658 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003659 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02003660 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
3661 mbedtls_ctr_drbg_random,
3662 &global_data.ctr_drbg,
3663 MBEDTLS_RSA_PUBLIC,
3664 input_length,
3665 input,
3666 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003667 }
3668 else
3669#endif /* MBEDTLS_PKCS1_V15 */
3670#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02003671 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003672 {
Gilles Peskine072ac562018-06-30 00:21:29 +02003673 psa_rsa_oaep_set_padding_mode( alg, rsa );
3674 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
3675 mbedtls_ctr_drbg_random,
3676 &global_data.ctr_drbg,
3677 MBEDTLS_RSA_PUBLIC,
3678 salt, salt_length,
3679 input_length,
3680 input,
3681 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003682 }
3683 else
3684#endif /* MBEDTLS_PKCS1_V21 */
3685 {
3686 return( PSA_ERROR_INVALID_ARGUMENT );
3687 }
3688 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02003689 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003690 return( mbedtls_to_psa_error( ret ) );
3691 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003692 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02003693#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003694 {
3695 return( PSA_ERROR_NOT_SUPPORTED );
3696 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003697}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003698
Gilles Peskinec5487a82018-12-03 18:08:14 +01003699psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02003700 psa_algorithm_t alg,
3701 const uint8_t *input,
3702 size_t input_length,
3703 const uint8_t *salt,
3704 size_t salt_length,
3705 uint8_t *output,
3706 size_t output_size,
3707 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003708{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003709 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003710 psa_status_t status;
3711
Darryl Green5cc689a2018-07-24 15:34:10 +01003712 (void) input;
3713 (void) input_length;
3714 (void) salt;
3715 (void) output;
3716 (void) output_size;
3717
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03003718 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003719
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02003720 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
3721 return( PSA_ERROR_INVALID_ARGUMENT );
3722
Gilles Peskine28f8f302019-07-24 13:30:31 +02003723 status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003724 if( status != PSA_SUCCESS )
3725 return( status );
Gilles Peskine8e338702019-07-30 20:06:31 +02003726 if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003727 return( PSA_ERROR_INVALID_ARGUMENT );
3728
3729#if defined(MBEDTLS_RSA_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02003730 if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003731 {
3732 mbedtls_rsa_context *rsa = slot->data.rsa;
Janos Follath24eed8d2019-11-22 13:21:35 +00003733 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003734
Gilles Peskine630a18a2018-06-29 17:49:35 +02003735 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003736 return( PSA_ERROR_INVALID_ARGUMENT );
3737
3738#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02003739 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003740 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02003741 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
3742 mbedtls_ctr_drbg_random,
3743 &global_data.ctr_drbg,
3744 MBEDTLS_RSA_PRIVATE,
3745 output_length,
3746 input,
3747 output,
3748 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003749 }
3750 else
3751#endif /* MBEDTLS_PKCS1_V15 */
3752#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02003753 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003754 {
Gilles Peskine072ac562018-06-30 00:21:29 +02003755 psa_rsa_oaep_set_padding_mode( alg, rsa );
3756 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
3757 mbedtls_ctr_drbg_random,
3758 &global_data.ctr_drbg,
3759 MBEDTLS_RSA_PRIVATE,
3760 salt, salt_length,
3761 output_length,
3762 input,
3763 output,
3764 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003765 }
3766 else
3767#endif /* MBEDTLS_PKCS1_V21 */
3768 {
3769 return( PSA_ERROR_INVALID_ARGUMENT );
3770 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03003771
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003772 return( mbedtls_to_psa_error( ret ) );
3773 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003774 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02003775#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003776 {
3777 return( PSA_ERROR_NOT_SUPPORTED );
3778 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003779}
Gilles Peskine20035e32018-02-03 22:44:14 +01003780
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003781
3782
mohammad1603503973b2018-03-12 15:59:30 +02003783/****************************************************************/
3784/* Symmetric cryptography */
3785/****************************************************************/
3786
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003787/* Initialize the cipher operation structure. Once this function has been
3788 * called, psa_cipher_abort can run and will do the right thing. */
3789static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
3790 psa_algorithm_t alg )
3791{
Gilles Peskinec06e0712018-06-20 16:21:04 +02003792 if( ! PSA_ALG_IS_CIPHER( alg ) )
3793 {
3794 memset( operation, 0, sizeof( *operation ) );
3795 return( PSA_ERROR_INVALID_ARGUMENT );
3796 }
3797
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003798 operation->alg = alg;
3799 operation->key_set = 0;
3800 operation->iv_set = 0;
3801 operation->iv_required = 1;
3802 operation->iv_size = 0;
3803 operation->block_size = 0;
3804 mbedtls_cipher_init( &operation->ctx.cipher );
3805 return( PSA_SUCCESS );
3806}
3807
Gilles Peskinee553c652018-06-04 16:22:46 +02003808static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003809 psa_key_handle_t handle,
Gilles Peskine7e928852018-06-04 16:23:10 +02003810 psa_algorithm_t alg,
3811 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02003812{
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003813 int ret = 0;
3814 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003815 psa_key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02003816 size_t key_bits;
3817 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003818 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
3819 PSA_KEY_USAGE_ENCRYPT :
3820 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02003821
Jaeden Amero36ee5d02019-02-19 09:25:10 +00003822 /* A context must be freshly initialized before it can be set up. */
3823 if( operation->alg != 0 )
3824 {
3825 return( PSA_ERROR_BAD_STATE );
3826 }
3827
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003828 status = psa_cipher_init( operation, alg );
3829 if( status != PSA_SUCCESS )
3830 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003831
Gilles Peskine28f8f302019-07-24 13:30:31 +02003832 status = psa_get_transparent_key( handle, &slot, usage, alg);
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003833 if( status != PSA_SUCCESS )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003834 goto exit;
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02003835 key_bits = psa_get_key_slot_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02003836
Michael Thomas863b5d62020-02-10 19:41:16 +00003837#if defined (MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C)
3838 if (PSA_KEY_LIFETIME_IS_VENDOR_DEFINED(slot->attr.lifetime))
3839 {
3840 status = psa_cipher_setup_vendor(operation, handle, alg, cipher_operation);
3841 goto exit;
3842 }
3843#endif /* MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C */
3844
Gilles Peskine8e338702019-07-30 20:06:31 +02003845 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02003846 if( cipher_info == NULL )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003847 {
3848 status = PSA_ERROR_NOT_SUPPORTED;
3849 goto exit;
3850 }
mohammad1603503973b2018-03-12 15:59:30 +02003851
mohammad1603503973b2018-03-12 15:59:30 +02003852 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03003853 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003854 goto exit;
Michael Thomasaf675252020-03-13 05:51:57 +00003855
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003856#if defined(MBEDTLS_DES_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02003857 if( slot->attr.type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003858 {
3859 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02003860 uint8_t keys[24];
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003861 memcpy( keys, slot->data.raw.data, 16 );
3862 memcpy( keys + 16, slot->data.raw.data, 8 );
3863 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
3864 keys,
3865 192, cipher_operation );
3866 }
3867 else
3868#endif
3869 {
3870 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
3871 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01003872 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003873 }
Moran Peker41deec42018-04-04 15:43:05 +03003874 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003875 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02003876
mohammad16038481e742018-03-18 13:57:31 +02003877#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003878 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02003879 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003880 case PSA_ALG_CBC_NO_PADDING:
3881 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
3882 MBEDTLS_PADDING_NONE );
3883 break;
3884 case PSA_ALG_CBC_PKCS7:
3885 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
3886 MBEDTLS_PADDING_PKCS7 );
3887 break;
3888 default:
3889 /* The algorithm doesn't involve padding. */
3890 ret = 0;
3891 break;
3892 }
3893 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003894 goto exit;
mohammad16038481e742018-03-18 13:57:31 +02003895#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
3896
mohammad1603503973b2018-03-12 15:59:30 +02003897 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003898 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
Gilles Peskine8e338702019-07-30 20:06:31 +02003899 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) );
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003900 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02003901 {
Gilles Peskine8e338702019-07-30 20:06:31 +02003902 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type );
mohammad16038481e742018-03-18 13:57:31 +02003903 }
Gilles Peskine26869f22019-05-06 15:25:00 +02003904#if defined(MBEDTLS_CHACHA20_C)
3905 else
3906 if( alg == PSA_ALG_CHACHA20 )
3907 operation->iv_size = 12;
3908#endif
mohammad1603503973b2018-03-12 15:59:30 +02003909
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003910exit:
3911 if( status == 0 )
3912 status = mbedtls_to_psa_error( ret );
3913 if( status != 0 )
3914 psa_cipher_abort( operation );
3915 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003916}
3917
Gilles Peskinefe119512018-07-08 21:39:34 +02003918psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003919 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02003920 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02003921{
Gilles Peskinec5487a82018-12-03 18:08:14 +01003922 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02003923}
3924
Gilles Peskinefe119512018-07-08 21:39:34 +02003925psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003926 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02003927 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02003928{
Gilles Peskinec5487a82018-12-03 18:08:14 +01003929 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02003930}
3931
Gilles Peskinefe119512018-07-08 21:39:34 +02003932psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
Andrew Thoelke163639b2019-05-15 12:33:23 +01003933 uint8_t *iv,
Gilles Peskinefe119512018-07-08 21:39:34 +02003934 size_t iv_size,
3935 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02003936{
itayzafrir534bd7c2018-08-02 13:56:32 +03003937 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003938 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003939 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03003940 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003941 return( PSA_ERROR_BAD_STATE );
itayzafrir534bd7c2018-08-02 13:56:32 +03003942 }
Moran Peker41deec42018-04-04 15:43:05 +03003943 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02003944 {
itayzafrir534bd7c2018-08-02 13:56:32 +03003945 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03003946 goto exit;
3947 }
Gilles Peskine7e928852018-06-04 16:23:10 +02003948 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
3949 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03003950 if( ret != 0 )
3951 {
itayzafrir534bd7c2018-08-02 13:56:32 +03003952 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02003953 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02003954 }
Gilles Peskinee553c652018-06-04 16:22:46 +02003955
mohammad16038481e742018-03-18 13:57:31 +02003956 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03003957 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03003958
Moran Peker395db872018-05-31 14:07:14 +03003959exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03003960 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03003961 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03003962 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003963}
3964
Gilles Peskinefe119512018-07-08 21:39:34 +02003965psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
Andrew Thoelke163639b2019-05-15 12:33:23 +01003966 const uint8_t *iv,
Gilles Peskinefe119512018-07-08 21:39:34 +02003967 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02003968{
itayzafrir534bd7c2018-08-02 13:56:32 +03003969 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003970 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003971 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03003972 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003973 return( PSA_ERROR_BAD_STATE );
itayzafrir534bd7c2018-08-02 13:56:32 +03003974 }
Moran Pekera28258c2018-05-29 16:25:04 +03003975 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03003976 {
itayzafrir534bd7c2018-08-02 13:56:32 +03003977 status = PSA_ERROR_INVALID_ARGUMENT;
3978 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03003979 }
itayzafrir534bd7c2018-08-02 13:56:32 +03003980 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
3981 status = mbedtls_to_psa_error( ret );
3982exit:
3983 if( status == PSA_SUCCESS )
3984 operation->iv_set = 1;
3985 else
mohammad1603503973b2018-03-12 15:59:30 +02003986 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03003987 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003988}
3989
Gilles Peskinee553c652018-06-04 16:22:46 +02003990psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
3991 const uint8_t *input,
3992 size_t input_length,
Andrew Thoelke163639b2019-05-15 12:33:23 +01003993 uint8_t *output,
Gilles Peskinee553c652018-06-04 16:22:46 +02003994 size_t output_size,
3995 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02003996{
itayzafrir534bd7c2018-08-02 13:56:32 +03003997 psa_status_t status;
Janos Follath24eed8d2019-11-22 13:21:35 +00003998 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine89d789c2018-06-04 17:17:16 +02003999 size_t expected_output_size;
Jaeden Ameroab439972019-02-15 14:12:05 +00004000
4001 if( operation->alg == 0 )
4002 {
4003 return( PSA_ERROR_BAD_STATE );
4004 }
4005
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004006 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02004007 {
4008 /* Take the unprocessed partial block left over from previous
4009 * update calls, if any, plus the input to this call. Remove
4010 * the last partial block, if any. You get the data that will be
4011 * output in this call. */
4012 expected_output_size =
4013 ( operation->ctx.cipher.unprocessed_len + input_length )
4014 / operation->block_size * operation->block_size;
4015 }
4016 else
4017 {
4018 expected_output_size = input_length;
4019 }
itayzafrir534bd7c2018-08-02 13:56:32 +03004020
Gilles Peskine89d789c2018-06-04 17:17:16 +02004021 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03004022 {
4023 status = PSA_ERROR_BUFFER_TOO_SMALL;
4024 goto exit;
4025 }
mohammad160382759612018-03-12 18:16:40 +02004026
mohammad1603503973b2018-03-12 15:59:30 +02004027 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02004028 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03004029 status = mbedtls_to_psa_error( ret );
4030exit:
4031 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02004032 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03004033 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004034}
4035
Gilles Peskinee553c652018-06-04 16:22:46 +02004036psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
4037 uint8_t *output,
4038 size_t output_size,
4039 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02004040{
David Saadab4ecc272019-02-14 13:48:10 +02004041 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Janos Follath315b51c2018-07-09 16:04:51 +01004042 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02004043 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03004044
mohammad1603503973b2018-03-12 15:59:30 +02004045 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004046 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00004047 return( PSA_ERROR_BAD_STATE );
Moran Peker7cb22b82018-06-05 11:40:02 +03004048 }
4049 if( operation->iv_required && ! operation->iv_set )
4050 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00004051 return( PSA_ERROR_BAD_STATE );
Moran Peker7cb22b82018-06-05 11:40:02 +03004052 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004053
Gilles Peskine2c5219a2018-06-06 15:12:32 +02004054 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004055 operation->alg == PSA_ALG_CBC_NO_PADDING &&
4056 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03004057 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02004058 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01004059 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004060 }
4061
Janos Follath315b51c2018-07-09 16:04:51 +01004062 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
4063 temp_output_buffer,
4064 output_length );
4065 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02004066 {
Janos Follath315b51c2018-07-09 16:04:51 +01004067 status = mbedtls_to_psa_error( cipher_ret );
4068 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02004069 }
Janos Follath315b51c2018-07-09 16:04:51 +01004070
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004071 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01004072 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02004073 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004074 memcpy( output, temp_output_buffer, *output_length );
4075 else
4076 {
Janos Follath315b51c2018-07-09 16:04:51 +01004077 status = PSA_ERROR_BUFFER_TOO_SMALL;
4078 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03004079 }
mohammad1603503973b2018-03-12 15:59:30 +02004080
Gilles Peskine3f108122018-12-07 18:14:53 +01004081 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01004082 status = psa_cipher_abort( operation );
4083
4084 return( status );
4085
4086error:
4087
4088 *output_length = 0;
4089
Gilles Peskine3f108122018-12-07 18:14:53 +01004090 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01004091 (void) psa_cipher_abort( operation );
4092
4093 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02004094}
4095
Gilles Peskinee553c652018-06-04 16:22:46 +02004096psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
4097{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004098 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02004099 {
4100 /* The object has (apparently) been initialized but it is not
4101 * in use. It's ok to call abort on such an object, and there's
4102 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004103 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02004104 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02004105
Gilles Peskinef9c2c092018-06-21 16:57:07 +02004106 /* Sanity check (shouldn't happen: operation->alg should
4107 * always have been initialized to a valid value). */
4108 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
4109 return( PSA_ERROR_BAD_STATE );
Michael Thomasaf675252020-03-13 05:51:57 +00004110
mohammad1603503973b2018-03-12 15:59:30 +02004111 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02004112
Moran Peker41deec42018-04-04 15:43:05 +03004113 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004114 operation->key_set = 0;
4115 operation->iv_set = 0;
4116 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03004117 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03004118 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03004119
Moran Peker395db872018-05-31 14:07:14 +03004120 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02004121}
4122
Gilles Peskinea0655c32018-04-30 17:06:50 +02004123
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004124
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004125
mohammad16035955c982018-04-26 00:53:03 +03004126/****************************************************************/
4127/* AEAD */
4128/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004129
Gilles Peskineedf9a652018-08-17 18:11:56 +02004130typedef struct
4131{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004132 psa_key_slot_t *slot;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004133 const mbedtls_cipher_info_t *cipher_info;
4134 union
4135 {
4136#if defined(MBEDTLS_CCM_C)
4137 mbedtls_ccm_context ccm;
4138#endif /* MBEDTLS_CCM_C */
4139#if defined(MBEDTLS_GCM_C)
4140 mbedtls_gcm_context gcm;
4141#endif /* MBEDTLS_GCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004142#if defined(MBEDTLS_CHACHAPOLY_C)
4143 mbedtls_chachapoly_context chachapoly;
4144#endif /* MBEDTLS_CHACHAPOLY_C */
Gilles Peskineedf9a652018-08-17 18:11:56 +02004145 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004146 psa_algorithm_t core_alg;
4147 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004148 uint8_t tag_length;
4149} aead_operation_t;
4150
Gilles Peskine30a9e412019-01-14 18:36:12 +01004151static void psa_aead_abort_internal( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004152{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02004153 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004154 {
4155#if defined(MBEDTLS_CCM_C)
4156 case PSA_ALG_CCM:
4157 mbedtls_ccm_free( &operation->ctx.ccm );
4158 break;
4159#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004160#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02004161 case PSA_ALG_GCM:
4162 mbedtls_gcm_free( &operation->ctx.gcm );
4163 break;
4164#endif /* MBEDTLS_GCM_C */
4165 }
4166}
4167
4168static psa_status_t psa_aead_setup( aead_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004169 psa_key_handle_t handle,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004170 psa_key_usage_t usage,
4171 psa_algorithm_t alg )
4172{
4173 psa_status_t status;
4174 size_t key_bits;
4175 mbedtls_cipher_id_t cipher_id;
4176
Gilles Peskine28f8f302019-07-24 13:30:31 +02004177 status = psa_get_transparent_key( handle, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004178 if( status != PSA_SUCCESS )
4179 return( status );
4180
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02004181 key_bits = psa_get_key_slot_bits( operation->slot );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004182
4183 operation->cipher_info =
Gilles Peskine8e338702019-07-30 20:06:31 +02004184 mbedtls_cipher_info_from_psa( alg, operation->slot->attr.type, key_bits,
Gilles Peskineedf9a652018-08-17 18:11:56 +02004185 &cipher_id );
4186 if( operation->cipher_info == NULL )
4187 return( PSA_ERROR_NOT_SUPPORTED );
4188
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004189 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004190 {
4191#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004192 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
4193 operation->core_alg = PSA_ALG_CCM;
4194 operation->full_tag_length = 16;
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004195 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
4196 * The call to mbedtls_ccm_encrypt_and_tag or
4197 * mbedtls_ccm_auth_decrypt will validate the tag length. */
Gilles Peskine8e338702019-07-30 20:06:31 +02004198 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004199 return( PSA_ERROR_INVALID_ARGUMENT );
4200 mbedtls_ccm_init( &operation->ctx.ccm );
4201 status = mbedtls_to_psa_error(
4202 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
4203 operation->slot->data.raw.data,
4204 (unsigned int) key_bits ) );
4205 if( status != 0 )
4206 goto cleanup;
4207 break;
4208#endif /* MBEDTLS_CCM_C */
4209
4210#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004211 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
4212 operation->core_alg = PSA_ALG_GCM;
4213 operation->full_tag_length = 16;
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004214 /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
4215 * The call to mbedtls_gcm_crypt_and_tag or
4216 * mbedtls_gcm_auth_decrypt will validate the tag length. */
Gilles Peskine8e338702019-07-30 20:06:31 +02004217 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 )
Gilles Peskineedf9a652018-08-17 18:11:56 +02004218 return( PSA_ERROR_INVALID_ARGUMENT );
4219 mbedtls_gcm_init( &operation->ctx.gcm );
4220 status = mbedtls_to_psa_error(
4221 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
4222 operation->slot->data.raw.data,
4223 (unsigned int) key_bits ) );
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004224 if( status != 0 )
4225 goto cleanup;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004226 break;
4227#endif /* MBEDTLS_GCM_C */
4228
Gilles Peskine26869f22019-05-06 15:25:00 +02004229#if defined(MBEDTLS_CHACHAPOLY_C)
4230 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CHACHA20_POLY1305, 0 ):
4231 operation->core_alg = PSA_ALG_CHACHA20_POLY1305;
4232 operation->full_tag_length = 16;
4233 /* We only support the default tag length. */
4234 if( alg != PSA_ALG_CHACHA20_POLY1305 )
4235 return( PSA_ERROR_NOT_SUPPORTED );
4236 mbedtls_chachapoly_init( &operation->ctx.chachapoly );
4237 status = mbedtls_to_psa_error(
4238 mbedtls_chachapoly_setkey( &operation->ctx.chachapoly,
4239 operation->slot->data.raw.data ) );
4240 if( status != 0 )
4241 goto cleanup;
4242 break;
4243#endif /* MBEDTLS_CHACHAPOLY_C */
4244
Gilles Peskineedf9a652018-08-17 18:11:56 +02004245 default:
4246 return( PSA_ERROR_NOT_SUPPORTED );
4247 }
4248
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004249 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
4250 {
4251 status = PSA_ERROR_INVALID_ARGUMENT;
4252 goto cleanup;
4253 }
4254 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004255
Gilles Peskineedf9a652018-08-17 18:11:56 +02004256 return( PSA_SUCCESS );
4257
4258cleanup:
Gilles Peskine30a9e412019-01-14 18:36:12 +01004259 psa_aead_abort_internal( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004260 return( status );
4261}
4262
Gilles Peskinec5487a82018-12-03 18:08:14 +01004263psa_status_t psa_aead_encrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03004264 psa_algorithm_t alg,
4265 const uint8_t *nonce,
4266 size_t nonce_length,
4267 const uint8_t *additional_data,
4268 size_t additional_data_length,
4269 const uint8_t *plaintext,
4270 size_t plaintext_length,
4271 uint8_t *ciphertext,
4272 size_t ciphertext_size,
4273 size_t *ciphertext_length )
4274{
mohammad16035955c982018-04-26 00:53:03 +03004275 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004276 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03004277 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02004278
mohammad1603f08a5502018-06-03 15:05:47 +03004279 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07004280
Gilles Peskinec5487a82018-12-03 18:08:14 +01004281 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004282 if( status != PSA_SUCCESS )
4283 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004284
Gilles Peskineedf9a652018-08-17 18:11:56 +02004285 /* For all currently supported modes, the tag is at the end of the
4286 * ciphertext. */
4287 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
4288 {
4289 status = PSA_ERROR_BUFFER_TOO_SMALL;
4290 goto exit;
4291 }
4292 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03004293
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004294#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004295 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03004296 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004297 status = mbedtls_to_psa_error(
4298 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
4299 MBEDTLS_GCM_ENCRYPT,
4300 plaintext_length,
4301 nonce, nonce_length,
4302 additional_data, additional_data_length,
4303 plaintext, ciphertext,
4304 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03004305 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004306 else
4307#endif /* MBEDTLS_GCM_C */
4308#if defined(MBEDTLS_CCM_C)
4309 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03004310 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004311 status = mbedtls_to_psa_error(
4312 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
4313 plaintext_length,
4314 nonce, nonce_length,
4315 additional_data,
4316 additional_data_length,
4317 plaintext, ciphertext,
4318 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03004319 }
mohammad16035c8845f2018-05-09 05:40:09 -07004320 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004321#endif /* MBEDTLS_CCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004322#if defined(MBEDTLS_CHACHAPOLY_C)
4323 if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
4324 {
4325 if( nonce_length != 12 || operation.tag_length != 16 )
4326 {
4327 status = PSA_ERROR_NOT_SUPPORTED;
4328 goto exit;
4329 }
4330 status = mbedtls_to_psa_error(
4331 mbedtls_chachapoly_encrypt_and_tag( &operation.ctx.chachapoly,
4332 plaintext_length,
4333 nonce,
4334 additional_data,
4335 additional_data_length,
4336 plaintext,
4337 ciphertext,
4338 tag ) );
4339 }
4340 else
4341#endif /* MBEDTLS_CHACHAPOLY_C */
mohammad16035c8845f2018-05-09 05:40:09 -07004342 {
mohammad1603554faad2018-06-03 15:07:38 +03004343 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07004344 }
Gilles Peskine2d277862018-06-18 15:41:12 +02004345
Gilles Peskineedf9a652018-08-17 18:11:56 +02004346 if( status != PSA_SUCCESS && ciphertext_size != 0 )
4347 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02004348
Gilles Peskineedf9a652018-08-17 18:11:56 +02004349exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01004350 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004351 if( status == PSA_SUCCESS )
4352 *ciphertext_length = plaintext_length + operation.tag_length;
4353 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004354}
4355
Gilles Peskineee652a32018-06-01 19:23:52 +02004356/* Locate the tag in a ciphertext buffer containing the encrypted data
4357 * followed by the tag. Return the length of the part preceding the tag in
4358 * *plaintext_length. This is the size of the plaintext in modes where
4359 * the encrypted data has the same size as the plaintext, such as
4360 * CCM and GCM. */
4361static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
4362 const uint8_t *ciphertext,
4363 size_t ciphertext_length,
4364 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02004365 const uint8_t **p_tag )
4366{
4367 size_t payload_length;
4368 if( tag_length > ciphertext_length )
4369 return( PSA_ERROR_INVALID_ARGUMENT );
4370 payload_length = ciphertext_length - tag_length;
4371 if( payload_length > plaintext_size )
4372 return( PSA_ERROR_BUFFER_TOO_SMALL );
4373 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02004374 return( PSA_SUCCESS );
4375}
4376
Gilles Peskinec5487a82018-12-03 18:08:14 +01004377psa_status_t psa_aead_decrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03004378 psa_algorithm_t alg,
4379 const uint8_t *nonce,
4380 size_t nonce_length,
4381 const uint8_t *additional_data,
4382 size_t additional_data_length,
4383 const uint8_t *ciphertext,
4384 size_t ciphertext_length,
4385 uint8_t *plaintext,
4386 size_t plaintext_size,
4387 size_t *plaintext_length )
4388{
mohammad16035955c982018-04-26 00:53:03 +03004389 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02004390 aead_operation_t operation;
4391 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02004392
Gilles Peskineee652a32018-06-01 19:23:52 +02004393 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03004394
Gilles Peskinec5487a82018-12-03 18:08:14 +01004395 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004396 if( status != PSA_SUCCESS )
4397 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004398
Gilles Peskinef7e7b012019-05-06 15:27:16 +02004399 status = psa_aead_unpadded_locate_tag( operation.tag_length,
4400 ciphertext, ciphertext_length,
4401 plaintext_size, &tag );
4402 if( status != PSA_SUCCESS )
4403 goto exit;
4404
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004405#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02004406 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03004407 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004408 status = mbedtls_to_psa_error(
4409 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
4410 ciphertext_length - operation.tag_length,
4411 nonce, nonce_length,
4412 additional_data,
4413 additional_data_length,
4414 tag, operation.tag_length,
4415 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03004416 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004417 else
4418#endif /* MBEDTLS_GCM_C */
4419#if defined(MBEDTLS_CCM_C)
4420 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03004421 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02004422 status = mbedtls_to_psa_error(
4423 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
4424 ciphertext_length - operation.tag_length,
4425 nonce, nonce_length,
4426 additional_data,
4427 additional_data_length,
4428 ciphertext, plaintext,
4429 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03004430 }
mohammad160339574652018-06-01 04:39:53 -07004431 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01004432#endif /* MBEDTLS_CCM_C */
Gilles Peskine26869f22019-05-06 15:25:00 +02004433#if defined(MBEDTLS_CHACHAPOLY_C)
4434 if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 )
4435 {
4436 if( nonce_length != 12 || operation.tag_length != 16 )
4437 {
4438 status = PSA_ERROR_NOT_SUPPORTED;
4439 goto exit;
4440 }
4441 status = mbedtls_to_psa_error(
4442 mbedtls_chachapoly_auth_decrypt( &operation.ctx.chachapoly,
4443 ciphertext_length - operation.tag_length,
4444 nonce,
4445 additional_data,
4446 additional_data_length,
4447 tag,
4448 ciphertext,
4449 plaintext ) );
4450 }
4451 else
4452#endif /* MBEDTLS_CHACHAPOLY_C */
mohammad160339574652018-06-01 04:39:53 -07004453 {
mohammad1603554faad2018-06-03 15:07:38 +03004454 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07004455 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02004456
Gilles Peskineedf9a652018-08-17 18:11:56 +02004457 if( status != PSA_SUCCESS && plaintext_size != 0 )
4458 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03004459
Gilles Peskineedf9a652018-08-17 18:11:56 +02004460exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01004461 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02004462 if( status == PSA_SUCCESS )
4463 *plaintext_length = ciphertext_length - operation.tag_length;
4464 return( status );
mohammad16035955c982018-04-26 00:53:03 +03004465}
4466
Gilles Peskinea0655c32018-04-30 17:06:50 +02004467
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02004468
Gilles Peskine20035e32018-02-03 22:44:14 +01004469/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004470/* Generators */
4471/****************************************************************/
4472
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004473#define HKDF_STATE_INIT 0 /* no input yet */
4474#define HKDF_STATE_STARTED 1 /* got salt */
4475#define HKDF_STATE_KEYED 2 /* got key */
4476#define HKDF_STATE_OUTPUT 3 /* output started */
4477
Gilles Peskinecbe66502019-05-16 16:59:18 +02004478static psa_algorithm_t psa_key_derivation_get_kdf_alg(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004479 const psa_key_derivation_operation_t *operation )
Gilles Peskine969c5d62019-01-16 15:53:06 +01004480{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004481 if ( PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
4482 return( PSA_ALG_KEY_AGREEMENT_GET_KDF( operation->alg ) );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004483 else
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004484 return( operation->alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004485}
4486
4487
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004488psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004489{
4490 psa_status_t status = PSA_SUCCESS;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004491 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004492 if( kdf_alg == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004493 {
4494 /* The object has (apparently) been initialized but it is not
4495 * in use. It's ok to call abort on such an object, and there's
4496 * nothing to do. */
4497 }
4498 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02004499#if defined(MBEDTLS_MD_C)
Gilles Peskine969c5d62019-01-16 15:53:06 +01004500 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02004501 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004502 mbedtls_free( operation->ctx.hkdf.info );
4503 status = psa_hmac_abort_internal( &operation->ctx.hkdf.hmac );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004504 }
Gilles Peskine969c5d62019-01-16 15:53:06 +01004505 else if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004506 /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01004507 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004508 {
Janos Follath6a1d2622019-06-11 10:37:28 +01004509 if( operation->ctx.tls12_prf.seed != NULL )
4510 {
4511 mbedtls_platform_zeroize( operation->ctx.tls12_prf.seed,
4512 operation->ctx.tls12_prf.seed_length );
4513 mbedtls_free( operation->ctx.tls12_prf.seed );
4514 }
4515
4516 if( operation->ctx.tls12_prf.label != NULL )
4517 {
4518 mbedtls_platform_zeroize( operation->ctx.tls12_prf.label,
4519 operation->ctx.tls12_prf.label_length );
4520 mbedtls_free( operation->ctx.tls12_prf.label );
4521 }
4522
4523 status = psa_hmac_abort_internal( &operation->ctx.tls12_prf.hmac );
4524
4525 /* We leave the fields Ai and output_block to be erased safely by the
4526 * mbedtls_platform_zeroize() in the end of this function. */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004527 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02004528 else
4529#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02004530 {
4531 status = PSA_ERROR_BAD_STATE;
4532 }
Janos Follath083036a2019-06-11 10:22:26 +01004533 mbedtls_platform_zeroize( operation, sizeof( *operation ) );
Gilles Peskineeab56e42018-07-12 17:12:33 +02004534 return( status );
4535}
4536
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004537psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation,
Gilles Peskineeab56e42018-07-12 17:12:33 +02004538 size_t *capacity)
4539{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004540 if( operation->alg == 0 )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004541 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004542 /* This is a blank key derivation operation. */
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004543 return PSA_ERROR_BAD_STATE;
4544 }
4545
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004546 *capacity = operation->capacity;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004547 return( PSA_SUCCESS );
4548}
4549
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004550psa_status_t psa_key_derivation_set_capacity( psa_key_derivation_operation_t *operation,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004551 size_t capacity )
4552{
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004553 if( operation->alg == 0 )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004554 return( PSA_ERROR_BAD_STATE );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004555 if( capacity > operation->capacity )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004556 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004557 operation->capacity = capacity;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004558 return( PSA_SUCCESS );
4559}
4560
Gilles Peskinebef7f142018-07-12 17:22:21 +02004561#if defined(MBEDTLS_MD_C)
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004562/* Read some bytes from an HKDF-based operation. This performs a chunk
Gilles Peskinebef7f142018-07-12 17:22:21 +02004563 * of the expand phase of the HKDF algorithm. */
Gilles Peskinecbe66502019-05-16 16:59:18 +02004564static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkdf,
Gilles Peskinebef7f142018-07-12 17:22:21 +02004565 psa_algorithm_t hash_alg,
4566 uint8_t *output,
4567 size_t output_length )
4568{
4569 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
4570 psa_status_t status;
4571
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004572 if( hkdf->state < HKDF_STATE_KEYED || ! hkdf->info_set )
4573 return( PSA_ERROR_BAD_STATE );
4574 hkdf->state = HKDF_STATE_OUTPUT;
4575
Gilles Peskinebef7f142018-07-12 17:22:21 +02004576 while( output_length != 0 )
4577 {
4578 /* Copy what remains of the current block */
4579 uint8_t n = hash_length - hkdf->offset_in_block;
4580 if( n > output_length )
4581 n = (uint8_t) output_length;
4582 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
4583 output += n;
4584 output_length -= n;
4585 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02004586 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02004587 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02004588 /* We can't be wanting more output after block 0xff, otherwise
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004589 * the capacity check in psa_key_derivation_output_bytes() would have
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004590 * prevented this call. It could happen only if the operation
Gilles Peskined54931c2018-07-17 21:06:59 +02004591 * object was corrupted or if this function is called directly
4592 * inside the library. */
4593 if( hkdf->block_number == 0xff )
4594 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004595
4596 /* We need a new block */
4597 ++hkdf->block_number;
4598 hkdf->offset_in_block = 0;
4599 status = psa_hmac_setup_internal( &hkdf->hmac,
4600 hkdf->prk, hash_length,
4601 hash_alg );
4602 if( status != PSA_SUCCESS )
4603 return( status );
4604 if( hkdf->block_number != 1 )
4605 {
4606 status = psa_hash_update( &hkdf->hmac.hash_ctx,
4607 hkdf->output_block,
4608 hash_length );
4609 if( status != PSA_SUCCESS )
4610 return( status );
4611 }
4612 status = psa_hash_update( &hkdf->hmac.hash_ctx,
4613 hkdf->info,
4614 hkdf->info_length );
4615 if( status != PSA_SUCCESS )
4616 return( status );
4617 status = psa_hash_update( &hkdf->hmac.hash_ctx,
4618 &hkdf->block_number, 1 );
4619 if( status != PSA_SUCCESS )
4620 return( status );
4621 status = psa_hmac_finish_internal( &hkdf->hmac,
4622 hkdf->output_block,
4623 sizeof( hkdf->output_block ) );
4624 if( status != PSA_SUCCESS )
4625 return( status );
4626 }
4627
4628 return( PSA_SUCCESS );
4629}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004630
Janos Follath7742fee2019-06-17 12:58:10 +01004631static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
4632 psa_tls12_prf_key_derivation_t *tls12_prf,
4633 psa_algorithm_t alg )
4634{
4635 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
4636 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Janos Follathea29bfb2019-06-19 12:21:20 +01004637 psa_hash_operation_t backup = PSA_HASH_OPERATION_INIT;
4638 psa_status_t status, cleanup_status;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004639
Janos Follath7742fee2019-06-17 12:58:10 +01004640 /* We can't be wanting more output after block 0xff, otherwise
4641 * the capacity check in psa_key_derivation_output_bytes() would have
4642 * prevented this call. It could happen only if the operation
4643 * object was corrupted or if this function is called directly
4644 * inside the library. */
4645 if( tls12_prf->block_number == 0xff )
Janos Follath30090bc2019-06-25 10:15:04 +01004646 return( PSA_ERROR_CORRUPTION_DETECTED );
Janos Follath7742fee2019-06-17 12:58:10 +01004647
4648 /* We need a new block */
4649 ++tls12_prf->block_number;
Janos Follath844eb0e2019-06-19 12:10:49 +01004650 tls12_prf->left_in_block = hash_length;
Janos Follath7742fee2019-06-17 12:58:10 +01004651
4652 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
4653 *
4654 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
4655 *
4656 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
4657 * HMAC_hash(secret, A(2) + seed) +
4658 * HMAC_hash(secret, A(3) + seed) + ...
4659 *
4660 * A(0) = seed
Janos Follathea29bfb2019-06-19 12:21:20 +01004661 * A(i) = HMAC_hash(secret, A(i-1))
Janos Follath7742fee2019-06-17 12:58:10 +01004662 *
Janos Follathea29bfb2019-06-19 12:21:20 +01004663 * The `psa_tls12_prf_key_derivation` structure saves the block
Janos Follath7742fee2019-06-17 12:58:10 +01004664 * `HMAC_hash(secret, A(i) + seed)` from which the output
Janos Follath76c39842019-06-26 12:50:36 +01004665 * is currently extracted as `output_block` and where i is
4666 * `block_number`.
Janos Follath7742fee2019-06-17 12:58:10 +01004667 */
4668
Janos Follathea29bfb2019-06-19 12:21:20 +01004669 /* Save the hash context before using it, to preserve the hash state with
4670 * only the inner padding in it. We need this, because inner padding depends
4671 * on the key (secret in the RFC's terminology). */
4672 status = psa_hash_clone( &tls12_prf->hmac.hash_ctx, &backup );
4673 if( status != PSA_SUCCESS )
4674 goto cleanup;
4675
4676 /* Calculate A(i) where i = tls12_prf->block_number. */
4677 if( tls12_prf->block_number == 1 )
4678 {
4679 /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads
4680 * the variable seed and in this instance means it in the context of the
4681 * P_hash function, where seed = label + seed.) */
4682 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
4683 tls12_prf->label, tls12_prf->label_length );
4684 if( status != PSA_SUCCESS )
4685 goto cleanup;
4686 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
4687 tls12_prf->seed, tls12_prf->seed_length );
4688 if( status != PSA_SUCCESS )
4689 goto cleanup;
4690 }
4691 else
4692 {
4693 /* A(i) = HMAC_hash(secret, A(i-1)) */
4694 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
4695 tls12_prf->Ai, hash_length );
4696 if( status != PSA_SUCCESS )
4697 goto cleanup;
4698 }
4699
4700 status = psa_hmac_finish_internal( &tls12_prf->hmac,
4701 tls12_prf->Ai, hash_length );
4702 if( status != PSA_SUCCESS )
4703 goto cleanup;
4704 status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
4705 if( status != PSA_SUCCESS )
4706 goto cleanup;
4707
4708 /* Calculate HMAC_hash(secret, A(i) + label + seed). */
4709 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
4710 tls12_prf->Ai, hash_length );
4711 if( status != PSA_SUCCESS )
4712 goto cleanup;
4713 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
4714 tls12_prf->label, tls12_prf->label_length );
4715 if( status != PSA_SUCCESS )
4716 goto cleanup;
4717 status = psa_hash_update( &tls12_prf->hmac.hash_ctx,
4718 tls12_prf->seed, tls12_prf->seed_length );
4719 if( status != PSA_SUCCESS )
4720 goto cleanup;
4721 status = psa_hmac_finish_internal( &tls12_prf->hmac,
4722 tls12_prf->output_block, hash_length );
4723 if( status != PSA_SUCCESS )
4724 goto cleanup;
4725 status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx );
4726 if( status != PSA_SUCCESS )
4727 goto cleanup;
4728
Janos Follath7742fee2019-06-17 12:58:10 +01004729
4730cleanup:
4731
Janos Follathea29bfb2019-06-19 12:21:20 +01004732 cleanup_status = psa_hash_abort( &backup );
4733 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
4734 status = cleanup_status;
4735
4736 return( status );
Janos Follath7742fee2019-06-17 12:58:10 +01004737}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004738
Janos Follath844eb0e2019-06-19 12:10:49 +01004739static psa_status_t psa_key_derivation_tls12_prf_read(
4740 psa_tls12_prf_key_derivation_t *tls12_prf,
4741 psa_algorithm_t alg,
4742 uint8_t *output,
4743 size_t output_length )
4744{
4745 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
4746 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
4747 psa_status_t status;
4748 uint8_t offset, length;
4749
4750 while( output_length != 0 )
4751 {
4752 /* Check if we have fully processed the current block. */
4753 if( tls12_prf->left_in_block == 0 )
4754 {
4755 status = psa_key_derivation_tls12_prf_generate_next_block( tls12_prf,
4756 alg );
4757 if( status != PSA_SUCCESS )
4758 return( status );
4759
4760 continue;
4761 }
4762
4763 if( tls12_prf->left_in_block > output_length )
4764 length = (uint8_t) output_length;
4765 else
4766 length = tls12_prf->left_in_block;
4767
4768 offset = hash_length - tls12_prf->left_in_block;
4769 memcpy( output, tls12_prf->output_block + offset, length );
4770 output += length;
4771 output_length -= length;
4772 tls12_prf->left_in_block -= length;
4773 }
4774
4775 return( PSA_SUCCESS );
4776}
Gilles Peskinebef7f142018-07-12 17:22:21 +02004777#endif /* MBEDTLS_MD_C */
4778
Janos Follath6c6c8fc2019-06-17 12:38:20 +01004779psa_status_t psa_key_derivation_output_bytes(
4780 psa_key_derivation_operation_t *operation,
4781 uint8_t *output,
4782 size_t output_length )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004783{
4784 psa_status_t status;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004785 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
Gilles Peskineeab56e42018-07-12 17:12:33 +02004786
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004787 if( operation->alg == 0 )
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004788 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004789 /* This is a blank operation. */
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004790 return PSA_ERROR_BAD_STATE;
4791 }
4792
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004793 if( output_length > operation->capacity )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004794 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004795 operation->capacity = 0;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004796 /* Go through the error path to wipe all confidential data now
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004797 * that the operation object is useless. */
David Saadab4ecc272019-02-14 13:48:10 +02004798 status = PSA_ERROR_INSUFFICIENT_DATA;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004799 goto exit;
4800 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004801 if( output_length == 0 && operation->capacity == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004802 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004803 /* Edge case: this is a finished operation, and 0 bytes
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004804 * were requested. The right error in this case could
Gilles Peskineeab56e42018-07-12 17:12:33 +02004805 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
4806 * INSUFFICIENT_CAPACITY, which is right for a finished
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004807 * operation, for consistency with the case when
Gilles Peskineeab56e42018-07-12 17:12:33 +02004808 * output_length > 0. */
David Saadab4ecc272019-02-14 13:48:10 +02004809 return( PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskineeab56e42018-07-12 17:12:33 +02004810 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004811 operation->capacity -= output_length;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004812
Gilles Peskinebef7f142018-07-12 17:22:21 +02004813#if defined(MBEDTLS_MD_C)
Gilles Peskine969c5d62019-01-16 15:53:06 +01004814 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02004815 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01004816 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004817 status = psa_key_derivation_hkdf_read( &operation->ctx.hkdf, hash_alg,
Gilles Peskinebef7f142018-07-12 17:22:21 +02004818 output, output_length );
4819 }
Janos Follathadbec812019-06-14 11:05:39 +01004820 else
Janos Follathadbec812019-06-14 11:05:39 +01004821 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
Gilles Peskine969c5d62019-01-16 15:53:06 +01004822 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004823 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004824 status = psa_key_derivation_tls12_prf_read( &operation->ctx.tls12_prf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004825 kdf_alg, output,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004826 output_length );
4827 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02004828 else
4829#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02004830 {
4831 return( PSA_ERROR_BAD_STATE );
4832 }
4833
4834exit:
4835 if( status != PSA_SUCCESS )
4836 {
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004837 /* Preserve the algorithm upon errors, but clear all sensitive state.
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004838 * This allows us to differentiate between exhausted operations and
4839 * blank operations, so we can return PSA_ERROR_BAD_STATE on blank
4840 * operations. */
4841 psa_algorithm_t alg = operation->alg;
4842 psa_key_derivation_abort( operation );
4843 operation->alg = alg;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004844 memset( output, '!', output_length );
4845 }
4846 return( status );
4847}
4848
Gilles Peskine08542d82018-07-19 17:05:42 +02004849#if defined(MBEDTLS_DES_C)
4850static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
4851{
4852 if( data_size >= 8 )
4853 mbedtls_des_key_set_parity( data );
4854 if( data_size >= 16 )
4855 mbedtls_des_key_set_parity( data + 8 );
4856 if( data_size >= 24 )
4857 mbedtls_des_key_set_parity( data + 16 );
4858}
4859#endif /* MBEDTLS_DES_C */
4860
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004861static psa_status_t psa_generate_derived_key_internal(
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004862 psa_key_slot_t *slot,
4863 size_t bits,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004864 psa_key_derivation_operation_t *operation )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004865{
4866 uint8_t *data = NULL;
4867 size_t bytes = PSA_BITS_TO_BYTES( bits );
4868 psa_status_t status;
4869
Gilles Peskine8e338702019-07-30 20:06:31 +02004870 if( ! key_type_is_raw_bytes( slot->attr.type ) )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004871 return( PSA_ERROR_INVALID_ARGUMENT );
4872 if( bits % 8 != 0 )
4873 return( PSA_ERROR_INVALID_ARGUMENT );
4874 data = mbedtls_calloc( 1, bytes );
4875 if( data == NULL )
4876 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4877
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004878 status = psa_key_derivation_output_bytes( operation, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02004879 if( status != PSA_SUCCESS )
4880 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02004881#if defined(MBEDTLS_DES_C)
Gilles Peskine8e338702019-07-30 20:06:31 +02004882 if( slot->attr.type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02004883 psa_des_set_key_parity( data, bytes );
4884#endif /* MBEDTLS_DES_C */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004885 status = psa_import_key_into_slot( slot, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02004886
4887exit:
4888 mbedtls_free( data );
4889 return( status );
4890}
4891
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02004892psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attributes,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004893 psa_key_derivation_operation_t *operation,
Gilles Peskine98dd7792019-05-15 19:43:49 +02004894 psa_key_handle_t *handle )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004895{
4896 psa_status_t status;
4897 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02004898 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine0f84d622019-09-12 19:03:13 +02004899
4900 /* Reject any attempt to create a zero-length key so that we don't
4901 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
4902 if( psa_get_key_bits( attributes ) == 0 )
4903 return( PSA_ERROR_INVALID_ARGUMENT );
4904
Gilles Peskine178c9aa2019-09-24 18:21:06 +02004905 if( ! operation->can_output_key )
4906 return( PSA_ERROR_NOT_PERMITTED );
4907
Gilles Peskinedf179142019-07-15 22:02:14 +02004908 status = psa_start_key_creation( PSA_KEY_CREATION_DERIVE,
4909 attributes, handle, &slot, &driver );
Gilles Peskinef4ee6622019-07-24 13:44:30 +02004910#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
4911 if( driver != NULL )
4912 {
4913 /* Deriving a key in a secure element is not implemented yet. */
4914 status = PSA_ERROR_NOT_SUPPORTED;
4915 }
4916#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004917 if( status == PSA_SUCCESS )
4918 {
Adrian L. Shaw5a5a79a2019-05-03 15:44:28 +01004919 status = psa_generate_derived_key_internal( slot,
Gilles Peskine7e0cff92019-07-30 13:48:52 +02004920 attributes->core.bits,
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004921 operation );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004922 }
4923 if( status == PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02004924 status = psa_finish_key_creation( slot, driver );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004925 if( status != PSA_SUCCESS )
4926 {
Gilles Peskine011e4282019-06-26 18:34:38 +02004927 psa_fail_key_creation( slot, driver );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004928 *handle = 0;
4929 }
4930 return( status );
4931}
4932
Gilles Peskineeab56e42018-07-12 17:12:33 +02004933
4934
4935/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02004936/* Key derivation */
4937/****************************************************************/
4938
Gilles Peskine969c5d62019-01-16 15:53:06 +01004939static psa_status_t psa_key_derivation_setup_kdf(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004940 psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004941 psa_algorithm_t kdf_alg )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004942{
Janos Follath5fe19732019-06-20 15:09:30 +01004943 /* Make sure that operation->ctx is properly zero-initialised. (Macro
4944 * initialisers for this union leave some bytes unspecified.) */
4945 memset( &operation->ctx, 0, sizeof( operation->ctx ) );
4946
Gilles Peskine969c5d62019-01-16 15:53:06 +01004947 /* Make sure that kdf_alg is a supported key derivation algorithm. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004948#if defined(MBEDTLS_MD_C)
Gilles Peskine969c5d62019-01-16 15:53:06 +01004949 if( PSA_ALG_IS_HKDF( kdf_alg ) ||
4950 PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
4951 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004952 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01004953 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004954 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4955 if( hash_size == 0 )
4956 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004957 if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
4958 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) &&
Gilles Peskineab4b2012019-04-12 15:06:27 +02004959 ! ( hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384 ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004960 {
4961 return( PSA_ERROR_NOT_SUPPORTED );
4962 }
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004963 operation->capacity = 255 * hash_size;
Gilles Peskine969c5d62019-01-16 15:53:06 +01004964 return( PSA_SUCCESS );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004965 }
4966#endif /* MBEDTLS_MD_C */
Gilles Peskine969c5d62019-01-16 15:53:06 +01004967 else
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004968 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004969}
4970
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004971psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004972 psa_algorithm_t alg )
4973{
4974 psa_status_t status;
4975
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004976 if( operation->alg != 0 )
Gilles Peskine969c5d62019-01-16 15:53:06 +01004977 return( PSA_ERROR_BAD_STATE );
4978
Gilles Peskine6843c292019-01-18 16:44:49 +01004979 if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
4980 return( PSA_ERROR_INVALID_ARGUMENT );
4981 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskine969c5d62019-01-16 15:53:06 +01004982 {
4983 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004984 status = psa_key_derivation_setup_kdf( operation, kdf_alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004985 }
4986 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
4987 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004988 status = psa_key_derivation_setup_kdf( operation, alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004989 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004990 else
4991 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004992
4993 if( status == PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02004994 operation->alg = alg;
Gilles Peskine969c5d62019-01-16 15:53:06 +01004995 return( status );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004996}
4997
4998#if defined(MBEDTLS_MD_C)
Gilles Peskinecbe66502019-05-16 16:59:18 +02004999static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf,
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005000 psa_algorithm_t hash_alg,
5001 psa_key_derivation_step_t step,
5002 const uint8_t *data,
5003 size_t data_length )
5004{
5005 psa_status_t status;
5006 switch( step )
5007 {
Gilles Peskine03410b52019-05-16 16:05:19 +02005008 case PSA_KEY_DERIVATION_INPUT_SALT:
Gilles Peskine2b522db2019-04-12 15:11:49 +02005009 if( hkdf->state != HKDF_STATE_INIT )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005010 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005011 status = psa_hmac_setup_internal( &hkdf->hmac,
5012 data, data_length,
5013 hash_alg );
5014 if( status != PSA_SUCCESS )
5015 return( status );
5016 hkdf->state = HKDF_STATE_STARTED;
5017 return( PSA_SUCCESS );
Gilles Peskine03410b52019-05-16 16:05:19 +02005018 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005019 /* If no salt was provided, use an empty salt. */
5020 if( hkdf->state == HKDF_STATE_INIT )
5021 {
5022 status = psa_hmac_setup_internal( &hkdf->hmac,
5023 NULL, 0,
Gilles Peskinef9ee6332019-04-11 21:22:52 +02005024 hash_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005025 if( status != PSA_SUCCESS )
5026 return( status );
5027 hkdf->state = HKDF_STATE_STARTED;
5028 }
Gilles Peskine2b522db2019-04-12 15:11:49 +02005029 if( hkdf->state != HKDF_STATE_STARTED )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005030 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02005031 status = psa_hash_update( &hkdf->hmac.hash_ctx,
5032 data, data_length );
5033 if( status != PSA_SUCCESS )
5034 return( status );
5035 status = psa_hmac_finish_internal( &hkdf->hmac,
5036 hkdf->prk,
5037 sizeof( hkdf->prk ) );
5038 if( status != PSA_SUCCESS )
5039 return( status );
5040 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
5041 hkdf->block_number = 0;
5042 hkdf->state = HKDF_STATE_KEYED;
5043 return( PSA_SUCCESS );
Gilles Peskine03410b52019-05-16 16:05:19 +02005044 case PSA_KEY_DERIVATION_INPUT_INFO:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005045 if( hkdf->state == HKDF_STATE_OUTPUT )
5046 return( PSA_ERROR_BAD_STATE );
5047 if( hkdf->info_set )
5048 return( PSA_ERROR_BAD_STATE );
5049 hkdf->info_length = data_length;
5050 if( data_length != 0 )
5051 {
5052 hkdf->info = mbedtls_calloc( 1, data_length );
5053 if( hkdf->info == NULL )
5054 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5055 memcpy( hkdf->info, data, data_length );
5056 }
5057 hkdf->info_set = 1;
5058 return( PSA_SUCCESS );
5059 default:
5060 return( PSA_ERROR_INVALID_ARGUMENT );
5061 }
5062}
Janos Follathb03233e2019-06-11 15:30:30 +01005063
Janos Follathf08e2652019-06-13 09:05:41 +01005064static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf,
5065 const uint8_t *data,
5066 size_t data_length )
5067{
5068 if( prf->state != TLS12_PRF_STATE_INIT )
5069 return( PSA_ERROR_BAD_STATE );
5070
Janos Follathd6dce9f2019-07-04 09:11:38 +01005071 if( data_length != 0 )
5072 {
5073 prf->seed = mbedtls_calloc( 1, data_length );
5074 if( prf->seed == NULL )
5075 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Janos Follathf08e2652019-06-13 09:05:41 +01005076
Janos Follathd6dce9f2019-07-04 09:11:38 +01005077 memcpy( prf->seed, data, data_length );
5078 prf->seed_length = data_length;
5079 }
Janos Follathf08e2652019-06-13 09:05:41 +01005080
5081 prf->state = TLS12_PRF_STATE_SEED_SET;
5082
5083 return( PSA_SUCCESS );
5084}
5085
Janos Follath81550542019-06-13 14:26:34 +01005086static psa_status_t psa_tls12_prf_set_key( psa_tls12_prf_key_derivation_t *prf,
5087 psa_algorithm_t hash_alg,
5088 const uint8_t *data,
5089 size_t data_length )
5090{
5091 psa_status_t status;
5092 if( prf->state != TLS12_PRF_STATE_SEED_SET )
5093 return( PSA_ERROR_BAD_STATE );
5094
5095 status = psa_hmac_setup_internal( &prf->hmac, data, data_length, hash_alg );
5096 if( status != PSA_SUCCESS )
5097 return( status );
5098
5099 prf->state = TLS12_PRF_STATE_KEY_SET;
5100
5101 return( PSA_SUCCESS );
5102}
5103
Janos Follath6660f0e2019-06-17 08:44:03 +01005104static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
5105 psa_tls12_prf_key_derivation_t *prf,
5106 psa_algorithm_t hash_alg,
5107 const uint8_t *data,
5108 size_t data_length )
5109{
5110 psa_status_t status;
Gilles Peskinec11c4dc2019-07-15 11:06:38 +02005111 uint8_t pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
5112 uint8_t *cur = pms;
Janos Follath6660f0e2019-06-17 08:44:03 +01005113
5114 if( data_length > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
5115 return( PSA_ERROR_INVALID_ARGUMENT );
5116
5117 /* Quoting RFC 4279, Section 2:
5118 *
5119 * The premaster secret is formed as follows: if the PSK is N octets
5120 * long, concatenate a uint16 with the value N, N zero octets, a second
5121 * uint16 with the value N, and the PSK itself.
5122 */
5123
Janos Follath40e13932019-06-26 13:22:29 +01005124 *cur++ = ( data_length >> 8 ) & 0xff;
5125 *cur++ = ( data_length >> 0 ) & 0xff;
5126 memset( cur, 0, data_length );
5127 cur += data_length;
5128 *cur++ = pms[0];
5129 *cur++ = pms[1];
5130 memcpy( cur, data, data_length );
5131 cur += data_length;
Janos Follath6660f0e2019-06-17 08:44:03 +01005132
Janos Follath40e13932019-06-26 13:22:29 +01005133 status = psa_tls12_prf_set_key( prf, hash_alg, pms, cur - pms );
Janos Follath6660f0e2019-06-17 08:44:03 +01005134
5135 mbedtls_platform_zeroize( pms, sizeof( pms ) );
5136 return( status );
5137}
5138
Janos Follath63028dd2019-06-13 09:15:47 +01005139static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf,
5140 const uint8_t *data,
5141 size_t data_length )
5142{
5143 if( prf->state != TLS12_PRF_STATE_KEY_SET )
5144 return( PSA_ERROR_BAD_STATE );
5145
Janos Follathd6dce9f2019-07-04 09:11:38 +01005146 if( data_length != 0 )
5147 {
5148 prf->label = mbedtls_calloc( 1, data_length );
5149 if( prf->label == NULL )
5150 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Janos Follath63028dd2019-06-13 09:15:47 +01005151
Janos Follathd6dce9f2019-07-04 09:11:38 +01005152 memcpy( prf->label, data, data_length );
5153 prf->label_length = data_length;
5154 }
Janos Follath63028dd2019-06-13 09:15:47 +01005155
5156 prf->state = TLS12_PRF_STATE_LABEL_SET;
5157
5158 return( PSA_SUCCESS );
5159}
5160
Janos Follathb03233e2019-06-11 15:30:30 +01005161static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
5162 psa_algorithm_t hash_alg,
5163 psa_key_derivation_step_t step,
5164 const uint8_t *data,
5165 size_t data_length )
5166{
Janos Follathb03233e2019-06-11 15:30:30 +01005167 switch( step )
5168 {
Janos Follathf08e2652019-06-13 09:05:41 +01005169 case PSA_KEY_DERIVATION_INPUT_SEED:
5170 return( psa_tls12_prf_set_seed( prf, data, data_length ) );
Janos Follath81550542019-06-13 14:26:34 +01005171 case PSA_KEY_DERIVATION_INPUT_SECRET:
5172 return( psa_tls12_prf_set_key( prf, hash_alg, data, data_length ) );
Janos Follath63028dd2019-06-13 09:15:47 +01005173 case PSA_KEY_DERIVATION_INPUT_LABEL:
5174 return( psa_tls12_prf_set_label( prf, data, data_length ) );
Janos Follathb03233e2019-06-11 15:30:30 +01005175 default:
5176 return( PSA_ERROR_INVALID_ARGUMENT );
5177 }
5178}
Janos Follath6660f0e2019-06-17 08:44:03 +01005179
5180static psa_status_t psa_tls12_prf_psk_to_ms_input(
5181 psa_tls12_prf_key_derivation_t *prf,
5182 psa_algorithm_t hash_alg,
5183 psa_key_derivation_step_t step,
5184 const uint8_t *data,
5185 size_t data_length )
5186{
5187 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
Janos Follath0c1ed842019-06-28 13:35:36 +01005188 {
Janos Follath6660f0e2019-06-17 08:44:03 +01005189 return( psa_tls12_prf_psk_to_ms_set_key( prf, hash_alg,
5190 data, data_length ) );
Janos Follath0c1ed842019-06-28 13:35:36 +01005191 }
Janos Follath6660f0e2019-06-17 08:44:03 +01005192
5193 return( psa_tls12_prf_input( prf, hash_alg, step, data, data_length ) );
5194}
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005195#endif /* MBEDTLS_MD_C */
5196
Gilles Peskineb8965192019-09-24 16:21:10 +02005197/** Check whether the given key type is acceptable for the given
5198 * input step of a key derivation.
5199 *
5200 * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE.
5201 * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA.
5202 * Both secret and non-secret inputs can alternatively have the type
5203 * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning
5204 * that the input was passed as a buffer rather than via a key object.
5205 */
Gilles Peskine224b0d62019-09-23 18:13:17 +02005206static int psa_key_derivation_check_input_type(
5207 psa_key_derivation_step_t step,
5208 psa_key_type_t key_type )
5209{
5210 switch( step )
5211 {
5212 case PSA_KEY_DERIVATION_INPUT_SECRET:
Gilles Peskineb8965192019-09-24 16:21:10 +02005213 if( key_type == PSA_KEY_TYPE_DERIVE )
5214 return( PSA_SUCCESS );
5215 if( key_type == PSA_KEY_TYPE_NONE )
Gilles Peskine224b0d62019-09-23 18:13:17 +02005216 return( PSA_SUCCESS );
5217 break;
5218 case PSA_KEY_DERIVATION_INPUT_LABEL:
5219 case PSA_KEY_DERIVATION_INPUT_SALT:
5220 case PSA_KEY_DERIVATION_INPUT_INFO:
5221 case PSA_KEY_DERIVATION_INPUT_SEED:
Gilles Peskineb8965192019-09-24 16:21:10 +02005222 if( key_type == PSA_KEY_TYPE_RAW_DATA )
5223 return( PSA_SUCCESS );
5224 if( key_type == PSA_KEY_TYPE_NONE )
Gilles Peskine224b0d62019-09-23 18:13:17 +02005225 return( PSA_SUCCESS );
5226 break;
5227 }
5228 return( PSA_ERROR_INVALID_ARGUMENT );
5229}
5230
Janos Follathb80a94e2019-06-12 15:54:46 +01005231static psa_status_t psa_key_derivation_input_internal(
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005232 psa_key_derivation_operation_t *operation,
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005233 psa_key_derivation_step_t step,
Gilles Peskine224b0d62019-09-23 18:13:17 +02005234 psa_key_type_t key_type,
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005235 const uint8_t *data,
5236 size_t data_length )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005237{
Gilles Peskine46d7faf2019-09-23 19:22:55 +02005238 psa_status_t status;
5239 psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation );
5240
5241 status = psa_key_derivation_check_input_type( step, key_type );
Gilles Peskine224b0d62019-09-23 18:13:17 +02005242 if( status != PSA_SUCCESS )
5243 goto exit;
5244
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005245#if defined(MBEDTLS_MD_C)
Gilles Peskine969c5d62019-01-16 15:53:06 +01005246 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005247 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005248 status = psa_hkdf_input( &operation->ctx.hkdf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005249 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005250 step, data, data_length );
5251 }
k-stachowiak012dcc42019-08-13 14:55:03 +02005252 else if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005253 {
Janos Follathb03233e2019-06-11 15:30:30 +01005254 status = psa_tls12_prf_input( &operation->ctx.tls12_prf,
5255 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
5256 step, data, data_length );
Janos Follath6660f0e2019-06-17 08:44:03 +01005257 }
5258 else if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
5259 {
5260 status = psa_tls12_prf_psk_to_ms_input( &operation->ctx.tls12_prf,
5261 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
5262 step, data, data_length );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005263 }
5264 else
5265#endif /* MBEDTLS_MD_C */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005266 {
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005267 /* This can't happen unless the operation object was not initialized */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005268 return( PSA_ERROR_BAD_STATE );
5269 }
5270
Gilles Peskine224b0d62019-09-23 18:13:17 +02005271exit:
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005272 if( status != PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005273 psa_key_derivation_abort( operation );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005274 return( status );
5275}
5276
Janos Follath51f4a0f2019-06-14 11:35:55 +01005277psa_status_t psa_key_derivation_input_bytes(
5278 psa_key_derivation_operation_t *operation,
5279 psa_key_derivation_step_t step,
5280 const uint8_t *data,
5281 size_t data_length )
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005282{
Gilles Peskineb8965192019-09-24 16:21:10 +02005283 return( psa_key_derivation_input_internal( operation, step,
5284 PSA_KEY_TYPE_NONE,
Janos Follathc5621512019-06-14 11:27:57 +01005285 data, data_length ) );
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01005286}
5287
Janos Follath51f4a0f2019-06-14 11:35:55 +01005288psa_status_t psa_key_derivation_input_key(
5289 psa_key_derivation_operation_t *operation,
5290 psa_key_derivation_step_t step,
5291 psa_key_handle_t handle )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005292{
5293 psa_key_slot_t *slot;
5294 psa_status_t status;
Gilles Peskine178c9aa2019-09-24 18:21:06 +02005295
Gilles Peskine28f8f302019-07-24 13:30:31 +02005296 status = psa_get_transparent_key( handle, &slot,
Gilles Peskinef77a6ac2019-07-25 10:51:03 +02005297 PSA_KEY_USAGE_DERIVE,
5298 operation->alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005299 if( status != PSA_SUCCESS )
Gilles Peskine593773d2019-09-23 18:17:40 +02005300 {
5301 psa_key_derivation_abort( operation );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005302 return( status );
Gilles Peskine593773d2019-09-23 18:17:40 +02005303 }
Gilles Peskine178c9aa2019-09-24 18:21:06 +02005304
5305 /* Passing a key object as a SECRET input unlocks the permission
5306 * to output to a key object. */
5307 if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
5308 operation->can_output_key = 1;
5309
Janos Follathb80a94e2019-06-12 15:54:46 +01005310 return( psa_key_derivation_input_internal( operation,
Gilles Peskine224b0d62019-09-23 18:13:17 +02005311 step, slot->attr.type,
Janos Follathb80a94e2019-06-12 15:54:46 +01005312 slot->data.raw.data,
5313 slot->data.raw.bytes ) );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01005314}
Gilles Peskineea0fb492018-07-12 17:17:20 +02005315
5316
5317
5318/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02005319/* Key agreement */
5320/****************************************************************/
5321
Gilles Peskinea05219c2018-11-16 16:02:56 +01005322#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005323static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
5324 size_t peer_key_length,
5325 const mbedtls_ecp_keypair *our_key,
5326 uint8_t *shared_secret,
5327 size_t shared_secret_size,
5328 size_t *shared_secret_length )
5329{
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005330 mbedtls_ecp_keypair *their_key = NULL;
5331 mbedtls_ecdh_context ecdh;
Jaeden Amero97271b32019-01-10 19:38:51 +00005332 psa_status_t status;
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01005333 size_t bits = 0;
5334 psa_ecc_curve_t curve = mbedtls_ecc_group_to_psa( our_key->grp.id, &bits );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005335 mbedtls_ecdh_init( &ecdh );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005336
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01005337 status = psa_import_ec_public_key( curve,
5338 peer_key, peer_key_length,
5339 &their_key );
Jaeden Amero97271b32019-01-10 19:38:51 +00005340 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005341 goto exit;
5342
Jaeden Amero97271b32019-01-10 19:38:51 +00005343 status = mbedtls_to_psa_error(
5344 mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
5345 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005346 goto exit;
Jaeden Amero97271b32019-01-10 19:38:51 +00005347 status = mbedtls_to_psa_error(
5348 mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS ) );
5349 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005350 goto exit;
5351
Jaeden Amero97271b32019-01-10 19:38:51 +00005352 status = mbedtls_to_psa_error(
5353 mbedtls_ecdh_calc_secret( &ecdh,
5354 shared_secret_length,
5355 shared_secret, shared_secret_size,
5356 mbedtls_ctr_drbg_random,
5357 &global_data.ctr_drbg ) );
Gilles Peskinec7ef5b32019-12-12 16:58:00 +01005358 if( status != PSA_SUCCESS )
5359 goto exit;
5360 if( PSA_BITS_TO_BYTES( bits ) != *shared_secret_length )
5361 status = PSA_ERROR_CORRUPTION_DETECTED;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005362
5363exit:
Gilles Peskine3e819b72019-12-20 14:09:55 +01005364 if( status != PSA_SUCCESS )
5365 mbedtls_platform_zeroize( shared_secret, shared_secret_size );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005366 mbedtls_ecdh_free( &ecdh );
Jaeden Ameroccdce902019-01-10 11:42:27 +00005367 mbedtls_ecp_keypair_free( their_key );
5368 mbedtls_free( their_key );
Jaeden Amero97271b32019-01-10 19:38:51 +00005369 return( status );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005370}
Gilles Peskinea05219c2018-11-16 16:02:56 +01005371#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005372
Gilles Peskine01d718c2018-09-18 12:01:02 +02005373#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
5374
Gilles Peskine0216fe12019-04-11 21:23:21 +02005375static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
5376 psa_key_slot_t *private_key,
5377 const uint8_t *peer_key,
5378 size_t peer_key_length,
5379 uint8_t *shared_secret,
5380 size_t shared_secret_size,
5381 size_t *shared_secret_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02005382{
Gilles Peskine0216fe12019-04-11 21:23:21 +02005383 switch( alg )
Gilles Peskine01d718c2018-09-18 12:01:02 +02005384 {
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005385#if defined(MBEDTLS_ECDH_C)
Gilles Peskine0216fe12019-04-11 21:23:21 +02005386 case PSA_ALG_ECDH:
Gilles Peskine8e338702019-07-30 20:06:31 +02005387 if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005388 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0216fe12019-04-11 21:23:21 +02005389 return( psa_key_agreement_ecdh( peer_key, peer_key_length,
5390 private_key->data.ecp,
5391 shared_secret, shared_secret_size,
5392 shared_secret_length ) );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02005393#endif /* MBEDTLS_ECDH_C */
Gilles Peskine01d718c2018-09-18 12:01:02 +02005394 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01005395 (void) private_key;
5396 (void) peer_key;
5397 (void) peer_key_length;
Gilles Peskine0216fe12019-04-11 21:23:21 +02005398 (void) shared_secret;
5399 (void) shared_secret_size;
5400 (void) shared_secret_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02005401 return( PSA_ERROR_NOT_SUPPORTED );
5402 }
Gilles Peskine0216fe12019-04-11 21:23:21 +02005403}
5404
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02005405/* Note that if this function fails, you must call psa_key_derivation_abort()
Gilles Peskine01d718c2018-09-18 12:01:02 +02005406 * to potentially free embedded data structures and wipe confidential data.
5407 */
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005408static psa_status_t psa_key_agreement_internal( psa_key_derivation_operation_t *operation,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005409 psa_key_derivation_step_t step,
Gilles Peskine01d718c2018-09-18 12:01:02 +02005410 psa_key_slot_t *private_key,
5411 const uint8_t *peer_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005412 size_t peer_key_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02005413{
5414 psa_status_t status;
5415 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
5416 size_t shared_secret_length = 0;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005417 psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( operation->alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02005418
5419 /* Step 1: run the secret agreement algorithm to generate the shared
5420 * secret. */
Gilles Peskine0216fe12019-04-11 21:23:21 +02005421 status = psa_key_agreement_raw_internal( ka_alg,
5422 private_key,
5423 peer_key, peer_key_length,
itayzafrir0adf0fc2018-09-06 16:24:41 +03005424 shared_secret,
5425 sizeof( shared_secret ),
Gilles Peskine05d69892018-06-19 22:00:52 +02005426 &shared_secret_length );
Gilles Peskine53d991e2018-07-12 01:14:59 +02005427 if( status != PSA_SUCCESS )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005428 goto exit;
5429
Gilles Peskineb0b255c2018-07-06 17:01:38 +02005430 /* Step 2: set up the key derivation to generate key material from
Gilles Peskine224b0d62019-09-23 18:13:17 +02005431 * the shared secret. A shared secret is permitted wherever a key
5432 * of type DERIVE is permitted. */
Janos Follathb80a94e2019-06-12 15:54:46 +01005433 status = psa_key_derivation_input_internal( operation, step,
Gilles Peskine224b0d62019-09-23 18:13:17 +02005434 PSA_KEY_TYPE_DERIVE,
Janos Follathb80a94e2019-06-12 15:54:46 +01005435 shared_secret,
5436 shared_secret_length );
Gilles Peskine969c5d62019-01-16 15:53:06 +01005437
Gilles Peskine12313cd2018-06-20 00:20:32 +02005438exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01005439 mbedtls_platform_zeroize( shared_secret, shared_secret_length );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005440 return( status );
5441}
5442
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005443psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *operation,
Gilles Peskinecf7292e2019-05-16 17:53:40 +02005444 psa_key_derivation_step_t step,
5445 psa_key_handle_t private_key,
5446 const uint8_t *peer_key,
5447 size_t peer_key_length )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005448{
Gilles Peskine2f060a82018-12-04 17:12:32 +01005449 psa_key_slot_t *slot;
Gilles Peskine08542d82018-07-19 17:05:42 +02005450 psa_status_t status;
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005451 if( ! PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005452 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine28f8f302019-07-24 13:30:31 +02005453 status = psa_get_transparent_key( private_key, &slot,
Gilles Peskinef77a6ac2019-07-25 10:51:03 +02005454 PSA_KEY_USAGE_DERIVE, operation->alg );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005455 if( status != PSA_SUCCESS )
5456 return( status );
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005457 status = psa_key_agreement_internal( operation, step,
Gilles Peskine346797d2018-11-16 16:05:06 +01005458 slot,
Gilles Peskine969c5d62019-01-16 15:53:06 +01005459 peer_key, peer_key_length );
Gilles Peskine346797d2018-11-16 16:05:06 +01005460 if( status != PSA_SUCCESS )
Gilles Peskine51ae0e42019-05-16 17:31:03 +02005461 psa_key_derivation_abort( operation );
Gilles Peskine346797d2018-11-16 16:05:06 +01005462 return( status );
Gilles Peskineaf3baab2018-06-27 22:55:52 +02005463}
5464
Gilles Peskinebe697d82019-05-16 18:00:41 +02005465psa_status_t psa_raw_key_agreement( psa_algorithm_t alg,
5466 psa_key_handle_t private_key,
5467 const uint8_t *peer_key,
5468 size_t peer_key_length,
5469 uint8_t *output,
5470 size_t output_size,
5471 size_t *output_length )
Gilles Peskine0216fe12019-04-11 21:23:21 +02005472{
5473 psa_key_slot_t *slot;
5474 psa_status_t status;
5475
5476 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
5477 {
5478 status = PSA_ERROR_INVALID_ARGUMENT;
5479 goto exit;
5480 }
Gilles Peskine28f8f302019-07-24 13:30:31 +02005481 status = psa_get_transparent_key( private_key, &slot,
Gilles Peskinef77a6ac2019-07-25 10:51:03 +02005482 PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskine0216fe12019-04-11 21:23:21 +02005483 if( status != PSA_SUCCESS )
5484 goto exit;
5485
5486 status = psa_key_agreement_raw_internal( alg, slot,
5487 peer_key, peer_key_length,
5488 output, output_size,
5489 output_length );
5490
5491exit:
5492 if( status != PSA_SUCCESS )
5493 {
5494 /* If an error happens and is not handled properly, the output
5495 * may be used as a key to protect sensitive data. Arrange for such
5496 * a key to be random, which is likely to result in decryption or
5497 * verification errors. This is better than filling the buffer with
5498 * some constant data such as zeros, which would result in the data
5499 * being protected with a reproducible, easily knowable key.
5500 */
5501 psa_generate_random( output, output_size );
5502 *output_length = output_size;
5503 }
5504 return( status );
5505}
Gilles Peskine86a440b2018-11-12 18:39:40 +01005506
5507
5508/****************************************************************/
5509/* Random generation */
Gilles Peskine53d991e2018-07-12 01:14:59 +02005510/****************************************************************/
Gilles Peskine12313cd2018-06-20 00:20:32 +02005511
Gilles Peskine4c317f42018-07-12 01:24:09 +02005512psa_status_t psa_generate_random( uint8_t *output,
Gilles Peskine53d991e2018-07-12 01:14:59 +02005513 size_t output_size )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005514{
Janos Follath24eed8d2019-11-22 13:21:35 +00005515 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005516 GUARD_MODULE_INITIALIZED;
5517
Gilles Peskinef181eca2019-08-07 13:49:00 +02005518 while( output_size > MBEDTLS_CTR_DRBG_MAX_REQUEST )
5519 {
5520 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
5521 output,
5522 MBEDTLS_CTR_DRBG_MAX_REQUEST );
5523 if( ret != 0 )
5524 return( mbedtls_to_psa_error( ret ) );
5525 output += MBEDTLS_CTR_DRBG_MAX_REQUEST;
5526 output_size -= MBEDTLS_CTR_DRBG_MAX_REQUEST;
5527 }
5528
Gilles Peskinee59236f2018-01-27 23:32:46 +01005529 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
5530 return( mbedtls_to_psa_error( ret ) );
5531}
5532
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01005533#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
5534#include "mbedtls/entropy_poll.h"
5535
Gilles Peskine7228da22019-07-15 11:06:15 +02005536psa_status_t mbedtls_psa_inject_entropy( const uint8_t *seed,
Netanel Gonen2bcd3122018-11-19 11:53:02 +02005537 size_t seed_size )
5538{
Netanel Gonen2bcd3122018-11-19 11:53:02 +02005539 if( global_data.initialized )
5540 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02005541
5542 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
5543 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
5544 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
5545 return( PSA_ERROR_INVALID_ARGUMENT );
5546
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01005547 return( mbedtls_psa_storage_inject_entropy( seed, seed_size ) );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02005548}
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01005549#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02005550
Gilles Peskinee56e8782019-04-26 17:34:02 +02005551#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
Michael Thomas863b5d62020-02-10 19:41:16 +00005552psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters,
Gilles Peskinee56e8782019-04-26 17:34:02 +02005553 size_t domain_parameters_size,
5554 int *exponent )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005555{
Gilles Peskinee56e8782019-04-26 17:34:02 +02005556 size_t i;
5557 uint32_t acc = 0;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005558
Gilles Peskinee56e8782019-04-26 17:34:02 +02005559 if( domain_parameters_size == 0 )
5560 {
5561 *exponent = 65537;
5562 return( PSA_SUCCESS );
5563 }
5564
5565 /* Mbed TLS encodes the public exponent as an int. For simplicity, only
5566 * support values that fit in a 32-bit integer, which is larger than
5567 * int on just about every platform anyway. */
5568 if( domain_parameters_size > sizeof( acc ) )
5569 return( PSA_ERROR_NOT_SUPPORTED );
5570 for( i = 0; i < domain_parameters_size; i++ )
5571 acc = ( acc << 8 ) | domain_parameters[i];
5572 if( acc > INT_MAX )
5573 return( PSA_ERROR_NOT_SUPPORTED );
5574 *exponent = acc;
5575 return( PSA_SUCCESS );
5576}
5577#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
5578
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005579static psa_status_t psa_generate_key_internal(
Gilles Peskinee56e8782019-04-26 17:34:02 +02005580 psa_key_slot_t *slot, size_t bits,
5581 const uint8_t *domain_parameters, size_t domain_parameters_size )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005582{
Gilles Peskine8e338702019-07-30 20:06:31 +02005583 psa_key_type_t type = slot->attr.type;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005584
Gilles Peskinee56e8782019-04-26 17:34:02 +02005585 if( domain_parameters == NULL && domain_parameters_size != 0 )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005586 return( PSA_ERROR_INVALID_ARGUMENT );
5587
Gilles Peskinee59236f2018-01-27 23:32:46 +01005588 if( key_type_is_raw_bytes( type ) )
5589 {
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005590 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005591 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
5592 if( status != PSA_SUCCESS )
5593 return( status );
5594 status = psa_generate_random( slot->data.raw.data,
5595 slot->data.raw.bytes );
5596 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005597 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01005598#if defined(MBEDTLS_DES_C)
5599 if( type == PSA_KEY_TYPE_DES )
5600 psa_des_set_key_parity( slot->data.raw.data,
5601 slot->data.raw.bytes );
5602#endif /* MBEDTLS_DES_C */
5603 }
5604 else
5605
5606#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02005607 if ( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005608 {
5609 mbedtls_rsa_context *rsa;
Janos Follath24eed8d2019-11-22 13:21:35 +00005610 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinee56e8782019-04-26 17:34:02 +02005611 int exponent;
5612 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005613 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
5614 return( PSA_ERROR_NOT_SUPPORTED );
5615 /* Accept only byte-aligned keys, for the same reasons as
5616 * in psa_import_rsa_key(). */
5617 if( bits % 8 != 0 )
5618 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskinee56e8782019-04-26 17:34:02 +02005619 status = psa_read_rsa_exponent( domain_parameters,
5620 domain_parameters_size,
5621 &exponent );
5622 if( status != PSA_SUCCESS )
5623 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01005624 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
5625 if( rsa == NULL )
5626 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5627 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
5628 ret = mbedtls_rsa_gen_key( rsa,
5629 mbedtls_ctr_drbg_random,
5630 &global_data.ctr_drbg,
5631 (unsigned int) bits,
5632 exponent );
5633 if( ret != 0 )
5634 {
5635 mbedtls_rsa_free( rsa );
5636 mbedtls_free( rsa );
5637 return( mbedtls_to_psa_error( ret ) );
5638 }
5639 slot->data.rsa = rsa;
5640 }
5641 else
5642#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
5643
5644#if defined(MBEDTLS_ECP_C)
Gilles Peskinec93b80c2019-05-16 19:39:54 +02005645 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005646 {
5647 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
Gilles Peskine4295e8b2019-12-02 21:39:10 +01005648 mbedtls_ecp_group_id grp_id =
5649 mbedtls_ecc_group_of_psa( curve, PSA_BITS_TO_BYTES( bits ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01005650 const mbedtls_ecp_curve_info *curve_info =
5651 mbedtls_ecp_curve_info_from_grp_id( grp_id );
5652 mbedtls_ecp_keypair *ecp;
Janos Follath24eed8d2019-11-22 13:21:35 +00005653 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinee56e8782019-04-26 17:34:02 +02005654 if( domain_parameters_size != 0 )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005655 return( PSA_ERROR_NOT_SUPPORTED );
5656 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
5657 return( PSA_ERROR_NOT_SUPPORTED );
5658 if( curve_info->bit_size != bits )
5659 return( PSA_ERROR_INVALID_ARGUMENT );
5660 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
5661 if( ecp == NULL )
5662 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5663 mbedtls_ecp_keypair_init( ecp );
5664 ret = mbedtls_ecp_gen_key( grp_id, ecp,
5665 mbedtls_ctr_drbg_random,
5666 &global_data.ctr_drbg );
5667 if( ret != 0 )
5668 {
5669 mbedtls_ecp_keypair_free( ecp );
5670 mbedtls_free( ecp );
5671 return( mbedtls_to_psa_error( ret ) );
5672 }
5673 slot->data.ecp = ecp;
5674 }
5675 else
5676#endif /* MBEDTLS_ECP_C */
5677
5678 return( PSA_ERROR_NOT_SUPPORTED );
5679
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005680 return( PSA_SUCCESS );
5681}
Darryl Green0c6575a2018-11-07 16:05:30 +00005682
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005683psa_status_t psa_generate_key( const psa_key_attributes_t *attributes,
Gilles Peskinee56e8782019-04-26 17:34:02 +02005684 psa_key_handle_t *handle )
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005685{
5686 psa_status_t status;
5687 psa_key_slot_t *slot = NULL;
Gilles Peskine8abe6a22019-07-12 23:40:35 +02005688 psa_se_drv_table_entry_t *driver = NULL;
Gilles Peskine11792082019-08-06 18:36:36 +02005689
Gilles Peskine0f84d622019-09-12 19:03:13 +02005690 /* Reject any attempt to create a zero-length key so that we don't
5691 * risk tripping up later, e.g. on a malloc(0) that returns NULL. */
5692 if( psa_get_key_bits( attributes ) == 0 )
5693 return( PSA_ERROR_INVALID_ARGUMENT );
5694
Gilles Peskinedf179142019-07-15 22:02:14 +02005695 status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE,
5696 attributes, handle, &slot, &driver );
Gilles Peskine11792082019-08-06 18:36:36 +02005697 if( status != PSA_SUCCESS )
5698 goto exit;
5699
Gilles Peskinef4ee6622019-07-24 13:44:30 +02005700#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
5701 if( driver != NULL )
Darryl Green0c6575a2018-11-07 16:05:30 +00005702 {
Gilles Peskine11792082019-08-06 18:36:36 +02005703 const psa_drv_se_t *drv = psa_get_se_driver_methods( driver );
5704 size_t pubkey_length = 0; /* We don't support this feature yet */
5705 if( drv->key_management == NULL ||
5706 drv->key_management->p_generate == NULL )
5707 {
5708 status = PSA_ERROR_NOT_SUPPORTED;
5709 goto exit;
5710 }
5711 status = drv->key_management->p_generate(
5712 psa_get_se_driver_context( driver ),
5713 slot->data.se.slot_number, attributes,
5714 NULL, 0, &pubkey_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00005715 }
Gilles Peskine11792082019-08-06 18:36:36 +02005716 else
Gilles Peskinef4ee6622019-07-24 13:44:30 +02005717#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Michael Thomas4c53fc72020-01-24 03:45:51 +00005718#if defined (MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C)
Michael Thomas153cd2f2020-01-22 16:54:38 +00005719 if (PSA_KEY_LIFETIME_IS_VENDOR_DEFINED(slot->attr.lifetime))
Michael Thomas1d573ec2020-01-21 04:02:54 +00005720 {
5721 status = psa_generate_key_vendor(slot, attributes->core.bits,
5722 attributes->domain_parameters, attributes->domain_parameters_size);
Michael Thomasefcf4cf2020-02-24 17:46:31 +00005723 goto exit;
Michael Thomas1d573ec2020-01-21 04:02:54 +00005724 }
5725 else
Michael Thomas863b5d62020-02-10 19:41:16 +00005726#endif /* MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C */
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005727 {
Gilles Peskine35ef36b2019-05-16 19:42:05 +02005728 status = psa_generate_key_internal(
Gilles Peskine7e0cff92019-07-30 13:48:52 +02005729 slot, attributes->core.bits,
Gilles Peskinee56e8782019-04-26 17:34:02 +02005730 attributes->domain_parameters, attributes->domain_parameters_size );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005731 }
Gilles Peskine11792082019-08-06 18:36:36 +02005732exit:
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005733 if( status == PSA_SUCCESS )
Gilles Peskine011e4282019-06-26 18:34:38 +02005734 status = psa_finish_key_creation( slot, driver );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005735 if( status != PSA_SUCCESS )
5736 {
Gilles Peskine011e4282019-06-26 18:34:38 +02005737 psa_fail_key_creation( slot, driver );
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005738 *handle = 0;
5739 }
Darryl Green0c6575a2018-11-07 16:05:30 +00005740 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01005741}
5742
5743
Gilles Peskinee59236f2018-01-27 23:32:46 +01005744
5745/****************************************************************/
5746/* Module setup */
5747/****************************************************************/
5748
Gilles Peskine5e769522018-11-20 21:59:56 +01005749psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
5750 void (* entropy_init )( mbedtls_entropy_context *ctx ),
5751 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
5752{
5753 if( global_data.rng_state != RNG_NOT_INITIALIZED )
5754 return( PSA_ERROR_BAD_STATE );
5755 global_data.entropy_init = entropy_init;
5756 global_data.entropy_free = entropy_free;
5757 return( PSA_SUCCESS );
5758}
5759
Gilles Peskinee59236f2018-01-27 23:32:46 +01005760void mbedtls_psa_crypto_free( void )
5761{
Gilles Peskine66fb1262018-12-10 16:29:04 +01005762 psa_wipe_all_key_slots( );
Gilles Peskinec6b69072018-11-20 21:42:52 +01005763 if( global_data.rng_state != RNG_NOT_INITIALIZED )
5764 {
5765 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
Gilles Peskine5e769522018-11-20 21:59:56 +01005766 global_data.entropy_free( &global_data.entropy );
Gilles Peskinec6b69072018-11-20 21:42:52 +01005767 }
5768 /* Wipe all remaining data, including configuration.
5769 * In particular, this sets all state indicator to the value
5770 * indicating "uninitialized". */
Gilles Peskine3f108122018-12-07 18:14:53 +01005771 mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
Gilles Peskinea8ade162019-06-26 11:24:49 +02005772#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskined0890212019-06-24 14:34:43 +02005773 /* Unregister all secure element drivers, so that we restart from
5774 * a pristine state. */
5775 psa_unregister_all_se_drivers( );
Gilles Peskinea8ade162019-06-26 11:24:49 +02005776#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
Gilles Peskinee59236f2018-01-27 23:32:46 +01005777}
5778
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02005779#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
5780/** Recover a transaction that was interrupted by a power failure.
5781 *
5782 * This function is called during initialization, before psa_crypto_init()
5783 * returns. If this function returns a failure status, the initialization
5784 * fails.
5785 */
5786static psa_status_t psa_crypto_recover_transaction(
5787 const psa_crypto_transaction_t *transaction )
5788{
5789 switch( transaction->unknown.type )
5790 {
5791 case PSA_CRYPTO_TRANSACTION_CREATE_KEY:
5792 case PSA_CRYPTO_TRANSACTION_DESTROY_KEY:
Janos Follath1d57a202019-08-13 12:15:34 +01005793 /* TODO - fall through to the failure case until this
Gilles Peskinec9d7f942019-08-13 16:17:16 +02005794 * is implemented.
5795 * https://github.com/ARMmbed/mbed-crypto/issues/218
5796 */
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02005797 default:
5798 /* We found an unsupported transaction in the storage.
5799 * We don't know what state the storage is in. Give up. */
5800 return( PSA_ERROR_STORAGE_FAILURE );
5801 }
5802}
5803#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
5804
Gilles Peskinee59236f2018-01-27 23:32:46 +01005805psa_status_t psa_crypto_init( void )
5806{
Gilles Peskine66fb1262018-12-10 16:29:04 +01005807 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005808 const unsigned char drbg_seed[] = "PSA";
5809
Gilles Peskinec6b69072018-11-20 21:42:52 +01005810 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01005811 if( global_data.initialized != 0 )
5812 return( PSA_SUCCESS );
5813
Gilles Peskine5e769522018-11-20 21:59:56 +01005814 /* Set default configuration if
5815 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
5816 if( global_data.entropy_init == NULL )
5817 global_data.entropy_init = mbedtls_entropy_init;
5818 if( global_data.entropy_free == NULL )
5819 global_data.entropy_free = mbedtls_entropy_free;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005820
Gilles Peskinec6b69072018-11-20 21:42:52 +01005821 /* Initialize the random generator. */
Gilles Peskine5e769522018-11-20 21:59:56 +01005822 global_data.entropy_init( &global_data.entropy );
Jaeden Amero76541612019-06-04 17:14:43 +01005823#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
5824 defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
5825 /* The PSA entropy injection feature depends on using NV seed as an entropy
5826 * source. Add NV seed as an entropy source for PSA entropy injection. */
5827 mbedtls_entropy_add_source( &global_data.entropy,
5828 mbedtls_nv_seed_poll, NULL,
5829 MBEDTLS_ENTROPY_BLOCK_SIZE,
5830 MBEDTLS_ENTROPY_SOURCE_STRONG );
5831#endif
Gilles Peskinee59236f2018-01-27 23:32:46 +01005832 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
Gilles Peskinec6b69072018-11-20 21:42:52 +01005833 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskine66fb1262018-12-10 16:29:04 +01005834 status = mbedtls_to_psa_error(
5835 mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
5836 mbedtls_entropy_func,
5837 &global_data.entropy,
5838 drbg_seed, sizeof( drbg_seed ) - 1 ) );
5839 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005840 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01005841 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005842
Gilles Peskine66fb1262018-12-10 16:29:04 +01005843 status = psa_initialize_key_slots( );
5844 if( status != PSA_SUCCESS )
5845 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01005846
Gilles Peskined9348f22019-10-01 15:22:29 +02005847#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
5848 status = psa_init_all_se_drivers( );
5849 if( status != PSA_SUCCESS )
5850 goto exit;
5851#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
5852
Gilles Peskine4b734222019-07-24 15:56:31 +02005853#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
Gilles Peskinefc762652019-07-22 19:30:34 +02005854 status = psa_crypto_load_transaction( );
5855 if( status == PSA_SUCCESS )
5856 {
Gilles Peskinef9bb29e2019-07-25 17:52:59 +02005857 status = psa_crypto_recover_transaction( &psa_crypto_transaction );
5858 if( status != PSA_SUCCESS )
5859 goto exit;
5860 status = psa_crypto_stop_transaction( );
Gilles Peskinefc762652019-07-22 19:30:34 +02005861 }
5862 else if( status == PSA_ERROR_DOES_NOT_EXIST )
5863 {
5864 /* There's no transaction to complete. It's all good. */
5865 status = PSA_SUCCESS;
5866 }
Gilles Peskine4b734222019-07-24 15:56:31 +02005867#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
Gilles Peskinefc762652019-07-22 19:30:34 +02005868
Gilles Peskinec6b69072018-11-20 21:42:52 +01005869 /* All done. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01005870 global_data.initialized = 1;
5871
5872exit:
Gilles Peskine66fb1262018-12-10 16:29:04 +01005873 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005874 mbedtls_psa_crypto_free( );
Gilles Peskine66fb1262018-12-10 16:29:04 +01005875 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01005876}
5877
5878#endif /* MBEDTLS_PSA_CRYPTO_C */