blob: a43ccaf57f3bbfa8a7a8143b6f5103821eb0baff [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 Peskine961849f2018-11-30 18:54:54 +010035#include "psa_crypto_slot_management.h"
Darryl Greend49a4992018-06-18 17:27:26 +010036/* Include internal declarations that are useful for implementing persistently
37 * stored keys. */
38#include "psa_crypto_storage.h"
39
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010040#include <stdlib.h>
41#include <string.h>
42#if defined(MBEDTLS_PLATFORM_C)
43#include "mbedtls/platform.h"
44#else
45#define mbedtls_calloc calloc
46#define mbedtls_free free
47#endif
48
Gilles Peskinea5905292018-02-07 20:59:33 +010049#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020050#include "mbedtls/asn1.h"
Jaeden Amero6b196002019-01-10 10:23:21 +000051#include "mbedtls/asn1write.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020052#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010053#include "mbedtls/blowfish.h"
54#include "mbedtls/camellia.h"
55#include "mbedtls/cipher.h"
56#include "mbedtls/ccm.h"
57#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010058#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010059#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020060#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010061#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010062#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010063#include "mbedtls/error.h"
64#include "mbedtls/gcm.h"
65#include "mbedtls/md2.h"
66#include "mbedtls/md4.h"
67#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010068#include "mbedtls/md.h"
69#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010070#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010071#include "mbedtls/pk_internal.h"
Gilles Peskine3f108122018-12-07 18:14:53 +010072#include "mbedtls/platform_util.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010073#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010074#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010075#include "mbedtls/sha1.h"
76#include "mbedtls/sha256.h"
77#include "mbedtls/sha512.h"
78#include "mbedtls/xtea.h"
79
Gilles Peskine996deb12018-08-01 15:45:45 +020080#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
81
Gilles Peskine9ef733f2018-02-07 21:05:37 +010082/* constant-time buffer comparison */
83static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
84{
85 size_t i;
86 unsigned char diff = 0;
87
88 for( i = 0; i < n; i++ )
89 diff |= a[i] ^ b[i];
90
91 return( diff );
92}
93
94
95
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010096/****************************************************************/
97/* Global data, support functions and library management */
98/****************************************************************/
99
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200100static int key_type_is_raw_bytes( psa_key_type_t type )
101{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200102 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200103}
104
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100105/* Values for psa_global_data_t::rng_state */
106#define RNG_NOT_INITIALIZED 0
107#define RNG_INITIALIZED 1
108#define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100109
Gilles Peskine2d277862018-06-18 15:41:12 +0200110typedef struct
111{
Gilles Peskine5e769522018-11-20 21:59:56 +0100112 void (* entropy_init )( mbedtls_entropy_context *ctx );
113 void (* entropy_free )( mbedtls_entropy_context *ctx );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100114 mbedtls_entropy_context entropy;
115 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100116 unsigned initialized : 1;
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100117 unsigned rng_state : 2;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100118} psa_global_data_t;
119
120static psa_global_data_t global_data;
121
itayzafrir0adf0fc2018-09-06 16:24:41 +0300122#define GUARD_MODULE_INITIALIZED \
123 if( global_data.initialized == 0 ) \
124 return( PSA_ERROR_BAD_STATE );
125
Gilles Peskinee59236f2018-01-27 23:32:46 +0100126static psa_status_t mbedtls_to_psa_error( int ret )
127{
Gilles Peskinea5905292018-02-07 20:59:33 +0100128 /* If there's both a high-level code and low-level code, dispatch on
129 * the high-level code. */
130 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100131 {
132 case 0:
133 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100134
135 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
136 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
137 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
138 return( PSA_ERROR_NOT_SUPPORTED );
139 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
140 return( PSA_ERROR_HARDWARE_FAILURE );
141
142 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
143 return( PSA_ERROR_HARDWARE_FAILURE );
144
Gilles Peskine9a944802018-06-21 09:35:35 +0200145 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
146 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
147 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
148 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
149 case MBEDTLS_ERR_ASN1_INVALID_DATA:
150 return( PSA_ERROR_INVALID_ARGUMENT );
151 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
152 return( PSA_ERROR_INSUFFICIENT_MEMORY );
153 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
154 return( PSA_ERROR_BUFFER_TOO_SMALL );
155
Jaeden Amero93e21112019-02-20 13:57:28 +0000156#if defined(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000157 case MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA:
Jaeden Amero93e21112019-02-20 13:57:28 +0000158#elif defined(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH)
Gilles Peskinea5905292018-02-07 20:59:33 +0100159 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
Jaeden Amero93e21112019-02-20 13:57:28 +0000160#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100161 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
162 return( PSA_ERROR_NOT_SUPPORTED );
163 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
164 return( PSA_ERROR_HARDWARE_FAILURE );
165
Jaeden Amero93e21112019-02-20 13:57:28 +0000166#if defined(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
Jaeden Amero892cd6d2019-02-11 12:21:12 +0000167 case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA:
Jaeden Amero93e21112019-02-20 13:57:28 +0000168#elif defined(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH)
Gilles Peskinea5905292018-02-07 20:59:33 +0100169 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
Jaeden Amero93e21112019-02-20 13:57:28 +0000170#endif
Gilles Peskinea5905292018-02-07 20:59:33 +0100171 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
172 return( PSA_ERROR_NOT_SUPPORTED );
173 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
174 return( PSA_ERROR_HARDWARE_FAILURE );
175
176 case MBEDTLS_ERR_CCM_BAD_INPUT:
177 return( PSA_ERROR_INVALID_ARGUMENT );
178 case MBEDTLS_ERR_CCM_AUTH_FAILED:
179 return( PSA_ERROR_INVALID_SIGNATURE );
180 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
181 return( PSA_ERROR_HARDWARE_FAILURE );
182
183 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
184 return( PSA_ERROR_NOT_SUPPORTED );
185 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
186 return( PSA_ERROR_INVALID_ARGUMENT );
187 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
188 return( PSA_ERROR_INSUFFICIENT_MEMORY );
189 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
190 return( PSA_ERROR_INVALID_PADDING );
191 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
192 return( PSA_ERROR_BAD_STATE );
193 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
194 return( PSA_ERROR_INVALID_SIGNATURE );
195 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
196 return( PSA_ERROR_TAMPERING_DETECTED );
197 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
198 return( PSA_ERROR_HARDWARE_FAILURE );
199
200 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
201 return( PSA_ERROR_HARDWARE_FAILURE );
202
203 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
204 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
205 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
206 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
207 return( PSA_ERROR_NOT_SUPPORTED );
208 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
209 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
210
211 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
212 return( PSA_ERROR_NOT_SUPPORTED );
213 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
214 return( PSA_ERROR_HARDWARE_FAILURE );
215
Gilles Peskinee59236f2018-01-27 23:32:46 +0100216 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
217 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
218 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
219 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100220
221 case MBEDTLS_ERR_GCM_AUTH_FAILED:
222 return( PSA_ERROR_INVALID_SIGNATURE );
223 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200224 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100225 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
226 return( PSA_ERROR_HARDWARE_FAILURE );
227
228 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
229 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
230 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
231 return( PSA_ERROR_HARDWARE_FAILURE );
232
233 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
234 return( PSA_ERROR_NOT_SUPPORTED );
235 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
236 return( PSA_ERROR_INVALID_ARGUMENT );
237 case MBEDTLS_ERR_MD_ALLOC_FAILED:
238 return( PSA_ERROR_INSUFFICIENT_MEMORY );
239 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
240 return( PSA_ERROR_STORAGE_FAILURE );
241 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
242 return( PSA_ERROR_HARDWARE_FAILURE );
243
Gilles Peskinef76aa772018-10-29 19:24:33 +0100244 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
245 return( PSA_ERROR_STORAGE_FAILURE );
246 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
247 return( PSA_ERROR_INVALID_ARGUMENT );
248 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
249 return( PSA_ERROR_INVALID_ARGUMENT );
250 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
251 return( PSA_ERROR_BUFFER_TOO_SMALL );
252 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
253 return( PSA_ERROR_INVALID_ARGUMENT );
254 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
255 return( PSA_ERROR_INVALID_ARGUMENT );
256 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
257 return( PSA_ERROR_INVALID_ARGUMENT );
258 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
259 return( PSA_ERROR_INSUFFICIENT_MEMORY );
260
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100261 case MBEDTLS_ERR_PK_ALLOC_FAILED:
262 return( PSA_ERROR_INSUFFICIENT_MEMORY );
263 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
264 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
265 return( PSA_ERROR_INVALID_ARGUMENT );
266 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100267 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100268 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
269 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
270 return( PSA_ERROR_INVALID_ARGUMENT );
271 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
272 return( PSA_ERROR_NOT_SUPPORTED );
273 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
274 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
275 return( PSA_ERROR_NOT_PERMITTED );
276 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
277 return( PSA_ERROR_INVALID_ARGUMENT );
278 case MBEDTLS_ERR_PK_INVALID_ALG:
279 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
280 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
281 return( PSA_ERROR_NOT_SUPPORTED );
282 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
283 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100284 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
285 return( PSA_ERROR_HARDWARE_FAILURE );
286
287 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
288 return( PSA_ERROR_HARDWARE_FAILURE );
289
290 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
291 return( PSA_ERROR_INVALID_ARGUMENT );
292 case MBEDTLS_ERR_RSA_INVALID_PADDING:
293 return( PSA_ERROR_INVALID_PADDING );
294 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
295 return( PSA_ERROR_HARDWARE_FAILURE );
296 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
297 return( PSA_ERROR_INVALID_ARGUMENT );
298 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
299 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
300 return( PSA_ERROR_TAMPERING_DETECTED );
301 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
302 return( PSA_ERROR_INVALID_SIGNATURE );
303 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
304 return( PSA_ERROR_BUFFER_TOO_SMALL );
305 case MBEDTLS_ERR_RSA_RNG_FAILED:
306 return( PSA_ERROR_INSUFFICIENT_MEMORY );
307 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
308 return( PSA_ERROR_NOT_SUPPORTED );
309 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
310 return( PSA_ERROR_HARDWARE_FAILURE );
311
312 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
313 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
314 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
315 return( PSA_ERROR_HARDWARE_FAILURE );
316
317 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
318 return( PSA_ERROR_INVALID_ARGUMENT );
319 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
320 return( PSA_ERROR_HARDWARE_FAILURE );
321
itayzafrir5c753392018-05-08 11:18:38 +0300322 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300323 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300324 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300325 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
326 return( PSA_ERROR_BUFFER_TOO_SMALL );
327 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
328 return( PSA_ERROR_NOT_SUPPORTED );
329 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
330 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
331 return( PSA_ERROR_INVALID_SIGNATURE );
332 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
333 return( PSA_ERROR_INSUFFICIENT_MEMORY );
334 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
335 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300336
Gilles Peskinee59236f2018-01-27 23:32:46 +0100337 default:
David Saadab4ecc272019-02-14 13:48:10 +0200338 return( PSA_ERROR_GENERIC_ERROR );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100339 }
340}
341
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200342
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200343
344
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100345/****************************************************************/
346/* Key management */
347/****************************************************************/
348
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100349#if defined(MBEDTLS_ECP_C)
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200350static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
351{
352 switch( grpid )
353 {
354 case MBEDTLS_ECP_DP_SECP192R1:
355 return( PSA_ECC_CURVE_SECP192R1 );
356 case MBEDTLS_ECP_DP_SECP224R1:
357 return( PSA_ECC_CURVE_SECP224R1 );
358 case MBEDTLS_ECP_DP_SECP256R1:
359 return( PSA_ECC_CURVE_SECP256R1 );
360 case MBEDTLS_ECP_DP_SECP384R1:
361 return( PSA_ECC_CURVE_SECP384R1 );
362 case MBEDTLS_ECP_DP_SECP521R1:
363 return( PSA_ECC_CURVE_SECP521R1 );
364 case MBEDTLS_ECP_DP_BP256R1:
365 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
366 case MBEDTLS_ECP_DP_BP384R1:
367 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
368 case MBEDTLS_ECP_DP_BP512R1:
369 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
370 case MBEDTLS_ECP_DP_CURVE25519:
371 return( PSA_ECC_CURVE_CURVE25519 );
372 case MBEDTLS_ECP_DP_SECP192K1:
373 return( PSA_ECC_CURVE_SECP192K1 );
374 case MBEDTLS_ECP_DP_SECP224K1:
375 return( PSA_ECC_CURVE_SECP224K1 );
376 case MBEDTLS_ECP_DP_SECP256K1:
377 return( PSA_ECC_CURVE_SECP256K1 );
378 case MBEDTLS_ECP_DP_CURVE448:
379 return( PSA_ECC_CURVE_CURVE448 );
380 default:
381 return( 0 );
382 }
383}
384
Gilles Peskine12313cd2018-06-20 00:20:32 +0200385static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
386{
387 switch( curve )
388 {
389 case PSA_ECC_CURVE_SECP192R1:
390 return( MBEDTLS_ECP_DP_SECP192R1 );
391 case PSA_ECC_CURVE_SECP224R1:
392 return( MBEDTLS_ECP_DP_SECP224R1 );
393 case PSA_ECC_CURVE_SECP256R1:
394 return( MBEDTLS_ECP_DP_SECP256R1 );
395 case PSA_ECC_CURVE_SECP384R1:
396 return( MBEDTLS_ECP_DP_SECP384R1 );
397 case PSA_ECC_CURVE_SECP521R1:
398 return( MBEDTLS_ECP_DP_SECP521R1 );
399 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
400 return( MBEDTLS_ECP_DP_BP256R1 );
401 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
402 return( MBEDTLS_ECP_DP_BP384R1 );
403 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
404 return( MBEDTLS_ECP_DP_BP512R1 );
405 case PSA_ECC_CURVE_CURVE25519:
406 return( MBEDTLS_ECP_DP_CURVE25519 );
407 case PSA_ECC_CURVE_SECP192K1:
408 return( MBEDTLS_ECP_DP_SECP192K1 );
409 case PSA_ECC_CURVE_SECP224K1:
410 return( MBEDTLS_ECP_DP_SECP224K1 );
411 case PSA_ECC_CURVE_SECP256K1:
412 return( MBEDTLS_ECP_DP_SECP256K1 );
413 case PSA_ECC_CURVE_CURVE448:
414 return( MBEDTLS_ECP_DP_CURVE448 );
415 default:
416 return( MBEDTLS_ECP_DP_NONE );
417 }
418}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100419#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200420
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200421static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
422 size_t bits,
423 struct raw_data *raw )
424{
425 /* Check that the bit size is acceptable for the key type */
426 switch( type )
427 {
428 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200429 if( bits == 0 )
430 {
431 raw->bytes = 0;
432 raw->data = NULL;
433 return( PSA_SUCCESS );
434 }
435 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200436#if defined(MBEDTLS_MD_C)
437 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200438#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200439 case PSA_KEY_TYPE_DERIVE:
440 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200441#if defined(MBEDTLS_AES_C)
442 case PSA_KEY_TYPE_AES:
443 if( bits != 128 && bits != 192 && bits != 256 )
444 return( PSA_ERROR_INVALID_ARGUMENT );
445 break;
446#endif
447#if defined(MBEDTLS_CAMELLIA_C)
448 case PSA_KEY_TYPE_CAMELLIA:
449 if( bits != 128 && bits != 192 && bits != 256 )
450 return( PSA_ERROR_INVALID_ARGUMENT );
451 break;
452#endif
453#if defined(MBEDTLS_DES_C)
454 case PSA_KEY_TYPE_DES:
455 if( bits != 64 && bits != 128 && bits != 192 )
456 return( PSA_ERROR_INVALID_ARGUMENT );
457 break;
458#endif
459#if defined(MBEDTLS_ARC4_C)
460 case PSA_KEY_TYPE_ARC4:
461 if( bits < 8 || bits > 2048 )
462 return( PSA_ERROR_INVALID_ARGUMENT );
463 break;
464#endif
465 default:
466 return( PSA_ERROR_NOT_SUPPORTED );
467 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200468 if( bits % 8 != 0 )
469 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200470
471 /* Allocate memory for the key */
472 raw->bytes = PSA_BITS_TO_BYTES( bits );
473 raw->data = mbedtls_calloc( 1, raw->bytes );
474 if( raw->data == NULL )
475 {
476 raw->bytes = 0;
477 return( PSA_ERROR_INSUFFICIENT_MEMORY );
478 }
479 return( PSA_SUCCESS );
480}
481
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200482#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine86a440b2018-11-12 18:39:40 +0100483/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
484 * that are not a multiple of 8) well. For example, there is only
485 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
486 * way to return the exact bit size of a key.
487 * To keep things simple, reject non-byte-aligned key sizes. */
488static psa_status_t psa_check_rsa_key_byte_aligned(
489 const mbedtls_rsa_context *rsa )
490{
491 mbedtls_mpi n;
492 psa_status_t status;
493 mbedtls_mpi_init( &n );
494 status = mbedtls_to_psa_error(
495 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
496 if( status == PSA_SUCCESS )
497 {
498 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
499 status = PSA_ERROR_NOT_SUPPORTED;
500 }
501 mbedtls_mpi_free( &n );
502 return( status );
503}
504
Jaeden Ameroec6ff862019-01-11 17:53:05 +0000505static psa_status_t psa_import_rsa_key( psa_key_type_t type,
506 const uint8_t *data,
507 size_t data_length,
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200508 mbedtls_rsa_context **p_rsa )
509{
Jaeden Ameroec6ff862019-01-11 17:53:05 +0000510 psa_status_t status;
511 mbedtls_pk_context pk;
512 mbedtls_rsa_context *rsa;
513 size_t bits;
514
515 mbedtls_pk_init( &pk );
516
517 /* Parse the data. */
518 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
519 status = mbedtls_to_psa_error(
520 mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200521 else
Jaeden Ameroec6ff862019-01-11 17:53:05 +0000522 status = mbedtls_to_psa_error(
523 mbedtls_pk_parse_public_key( &pk, data, data_length ) );
524 if( status != PSA_SUCCESS )
525 goto exit;
526
527 /* We have something that the pkparse module recognizes. If it is a
528 * valid RSA key, store it. */
529 if( mbedtls_pk_get_type( &pk ) != MBEDTLS_PK_RSA )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200530 {
Jaeden Ameroec6ff862019-01-11 17:53:05 +0000531 status = PSA_ERROR_INVALID_ARGUMENT;
532 goto exit;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200533 }
Jaeden Ameroec6ff862019-01-11 17:53:05 +0000534
535 rsa = mbedtls_pk_rsa( pk );
536 /* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
537 * supports non-byte-aligned key sizes, but not well. For example,
538 * mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
539 bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
540 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
541 {
542 status = PSA_ERROR_NOT_SUPPORTED;
543 goto exit;
544 }
545 status = psa_check_rsa_key_byte_aligned( rsa );
546
547exit:
548 /* Free the content of the pk object only on error. */
549 if( status != PSA_SUCCESS )
550 {
551 mbedtls_pk_free( &pk );
552 return( status );
553 }
554
555 /* On success, store the content of the object in the RSA context. */
556 *p_rsa = rsa;
557
558 return( PSA_SUCCESS );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200559}
560#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
561
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000562#if defined(MBEDTLS_ECP_C)
563
564/* Import a public key given as the uncompressed representation defined by SEC1
565 * 2.3.3 as the content of an ECPoint. */
566static psa_status_t psa_import_ec_public_key( psa_ecc_curve_t curve,
567 const uint8_t *data,
568 size_t data_length,
569 mbedtls_ecp_keypair **p_ecp )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200570{
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000571 psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
572 mbedtls_ecp_keypair *ecp = NULL;
573 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
574
575 *p_ecp = NULL;
576 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
577 if( ecp == NULL )
578 return( PSA_ERROR_INSUFFICIENT_MEMORY );
579 mbedtls_ecp_keypair_init( ecp );
580
581 /* Load the group. */
582 status = mbedtls_to_psa_error(
583 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
584 if( status != PSA_SUCCESS )
585 goto exit;
586 /* Load the public value. */
587 status = mbedtls_to_psa_error(
588 mbedtls_ecp_point_read_binary( &ecp->grp, &ecp->Q,
589 data, data_length ) );
590 if( status != PSA_SUCCESS )
591 goto exit;
592
593 /* Check that the point is on the curve. */
594 status = mbedtls_to_psa_error(
595 mbedtls_ecp_check_pubkey( &ecp->grp, &ecp->Q ) );
596 if( status != PSA_SUCCESS )
597 goto exit;
598
599 *p_ecp = ecp;
600 return( PSA_SUCCESS );
601
602exit:
603 if( ecp != NULL )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200604 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000605 mbedtls_ecp_keypair_free( ecp );
606 mbedtls_free( ecp );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200607 }
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000608 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200609}
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000610#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200611
Gilles Peskinef76aa772018-10-29 19:24:33 +0100612#if defined(MBEDTLS_ECP_C)
613/* Import a private key given as a byte string which is the private value
614 * in big-endian order. */
615static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
616 const uint8_t *data,
617 size_t data_length,
618 mbedtls_ecp_keypair **p_ecp )
619{
620 psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
621 mbedtls_ecp_keypair *ecp = NULL;
622 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
623
624 *p_ecp = NULL;
625 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
626 if( ecp == NULL )
627 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Jaeden Amero83d29392019-01-10 20:17:42 +0000628 mbedtls_ecp_keypair_init( ecp );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100629
630 /* Load the group. */
631 status = mbedtls_to_psa_error(
632 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
633 if( status != PSA_SUCCESS )
634 goto exit;
635 /* Load the secret value. */
636 status = mbedtls_to_psa_error(
637 mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
638 if( status != PSA_SUCCESS )
639 goto exit;
640 /* Validate the private key. */
641 status = mbedtls_to_psa_error(
642 mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
643 if( status != PSA_SUCCESS )
644 goto exit;
645 /* Calculate the public key from the private key. */
646 status = mbedtls_to_psa_error(
647 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
648 mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
649 if( status != PSA_SUCCESS )
650 goto exit;
651
652 *p_ecp = ecp;
653 return( PSA_SUCCESS );
654
655exit:
656 if( ecp != NULL )
657 {
658 mbedtls_ecp_keypair_free( ecp );
659 mbedtls_free( ecp );
660 }
661 return( status );
662}
663#endif /* defined(MBEDTLS_ECP_C) */
664
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100665/** Import key data into a slot. `slot->type` must have been set
666 * previously. This function assumes that the slot does not contain
667 * any key material yet. On failure, the slot content is unchanged. */
Gilles Peskinefa4135b2018-12-10 16:48:53 +0100668psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
669 const uint8_t *data,
670 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100671{
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200672 psa_status_t status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100673
Darryl Green940d72c2018-07-13 13:18:51 +0100674 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100675 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100676 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100677 if( data_length > SIZE_MAX / 8 )
678 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green940d72c2018-07-13 13:18:51 +0100679 status = prepare_raw_data_slot( slot->type,
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200680 PSA_BYTES_TO_BITS( data_length ),
681 &slot->data.raw );
682 if( status != PSA_SUCCESS )
683 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200684 if( data_length != 0 )
685 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100686 }
687 else
Gilles Peskinef76aa772018-10-29 19:24:33 +0100688#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100689 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100690 {
Darryl Green940d72c2018-07-13 13:18:51 +0100691 status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskinef76aa772018-10-29 19:24:33 +0100692 data, data_length,
693 &slot->data.ecp );
Gilles Peskinef76aa772018-10-29 19:24:33 +0100694 }
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000695 else if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( slot->type ) )
696 {
697 status = psa_import_ec_public_key(
698 PSA_KEY_TYPE_GET_CURVE( slot->type ),
699 data, data_length,
700 &slot->data.ecp );
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000701 }
Gilles Peskinef76aa772018-10-29 19:24:33 +0100702 else
703#endif /* MBEDTLS_ECP_C */
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000704#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
705 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100706 {
Jaeden Ameroec6ff862019-01-11 17:53:05 +0000707 status = psa_import_rsa_key( slot->type,
708 data, data_length,
709 &slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100710 }
711 else
Jaeden Amero0ae445f2019-01-10 11:42:27 +0000712#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100713 {
714 return( PSA_ERROR_NOT_SUPPORTED );
715 }
Jaeden Amero08ad3272019-01-14 13:12:39 +0000716 return( status );
Darryl Green940d72c2018-07-13 13:18:51 +0100717}
718
Darryl Green06fd18d2018-07-16 11:21:11 +0100719/* Retrieve an empty key slot (slot with no key data, but possibly
Jaeden Amero283dfd12019-01-11 12:06:22 +0000720 * with some metadata such as a policy or domain parameters). */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100721static psa_status_t psa_get_empty_key_slot( psa_key_handle_t handle,
Gilles Peskine2f060a82018-12-04 17:12:32 +0100722 psa_key_slot_t **p_slot )
Darryl Green06fd18d2018-07-16 11:21:11 +0100723{
724 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +0100725 psa_key_slot_t *slot = NULL;
Darryl Green06fd18d2018-07-16 11:21:11 +0100726
727 *p_slot = NULL;
728
Gilles Peskinec5487a82018-12-03 18:08:14 +0100729 status = psa_get_key_slot( handle, &slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100730 if( status != PSA_SUCCESS )
731 return( status );
732
733 if( slot->type != PSA_KEY_TYPE_NONE )
David Saadab4ecc272019-02-14 13:48:10 +0200734 return( PSA_ERROR_ALREADY_EXISTS );
Darryl Green06fd18d2018-07-16 11:21:11 +0100735
736 *p_slot = slot;
737 return( status );
738}
739
Gilles Peskine4cb9dde2019-01-19 13:40:11 +0100740/** Calculate the intersection of two algorithm usage policies.
741 *
742 * Return 0 (which allows no operation) on incompatibility.
743 */
744static psa_algorithm_t psa_key_policy_algorithm_intersection(
745 psa_algorithm_t alg1,
746 psa_algorithm_t alg2 )
747{
748 /* Common case: the policy only allows alg. */
749 if( alg1 == alg2 )
750 return( alg1 );
751 /* If the policies are from the same hash-and-sign family, check
Gilles Peskinef603c712019-01-19 13:40:11 +0100752 * if one is a wildcard. If so the other has the specific algorithm. */
Gilles Peskine4cb9dde2019-01-19 13:40:11 +0100753 if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) &&
754 PSA_ALG_IS_HASH_AND_SIGN( alg2 ) &&
755 ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
756 {
757 if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
758 return( alg2 );
Gilles Peskinef603c712019-01-19 13:40:11 +0100759 if( PSA_ALG_SIGN_GET_HASH( alg2 ) == PSA_ALG_ANY_HASH )
Gilles Peskine4cb9dde2019-01-19 13:40:11 +0100760 return( alg1 );
761 }
762 /* If the policies are incompatible, allow nothing. */
763 return( 0 );
764}
765
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100766/** Test whether a policy permits an algorithm.
767 *
768 * The caller must test usage flags separately.
769 */
770static int psa_key_policy_permits( const psa_key_policy_t *policy,
771 psa_algorithm_t alg )
772{
773 /* Common case: the policy only allows alg. */
774 if( alg == policy->alg )
775 return( 1 );
776 /* If policy->alg is a hash-and-sign with a wildcard for the hash,
777 * and alg is the same hash-and-sign family with any hash,
778 * then alg is compliant with policy->alg. */
779 if( PSA_ALG_IS_HASH_AND_SIGN( alg ) &&
780 PSA_ALG_SIGN_GET_HASH( policy->alg ) == PSA_ALG_ANY_HASH )
781 {
782 return( ( policy->alg & ~PSA_ALG_HASH_MASK ) ==
783 ( alg & ~PSA_ALG_HASH_MASK ) );
784 }
785 /* If it isn't permitted, it's forbidden. */
786 return( 0 );
787}
788
Gilles Peskinef603c712019-01-19 13:40:11 +0100789/** Restrict a key policy based on a constraint.
790 *
791 * \param[in,out] policy The policy to restrict.
792 * \param[in] constraint The policy constraint to apply.
793 *
794 * \retval #PSA_SUCCESS
795 * \c *policy contains the intersection of the original value of
796 * \c *policy and \c *constraint.
797 * \retval #PSA_ERROR_INVALID_ARGUMENT
798 * \c *policy and \c *constraint are incompatible.
799 * \c *policy is unchanged.
800 */
Gilles Peskine4cb9dde2019-01-19 13:40:11 +0100801static psa_status_t psa_restrict_key_policy(
802 psa_key_policy_t *policy,
803 const psa_key_policy_t *constraint )
804{
805 psa_algorithm_t intersection_alg =
806 psa_key_policy_algorithm_intersection( policy->alg, constraint->alg );
807 if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
808 return( PSA_ERROR_INVALID_ARGUMENT );
809 policy->usage &= constraint->usage;
Gilles Peskinef603c712019-01-19 13:40:11 +0100810 policy->alg = intersection_alg;
Gilles Peskine4cb9dde2019-01-19 13:40:11 +0100811 return( PSA_SUCCESS );
812}
813
Darryl Green06fd18d2018-07-16 11:21:11 +0100814/** Retrieve a slot which must contain a key. The key must have allow all the
815 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
816 * operations with this algorithm. */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100817static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle,
Gilles Peskine2f060a82018-12-04 17:12:32 +0100818 psa_key_slot_t **p_slot,
Darryl Green06fd18d2018-07-16 11:21:11 +0100819 psa_key_usage_t usage,
820 psa_algorithm_t alg )
821{
822 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +0100823 psa_key_slot_t *slot = NULL;
Darryl Green06fd18d2018-07-16 11:21:11 +0100824
825 *p_slot = NULL;
826
Gilles Peskinec5487a82018-12-03 18:08:14 +0100827 status = psa_get_key_slot( handle, &slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100828 if( status != PSA_SUCCESS )
829 return( status );
830 if( slot->type == PSA_KEY_TYPE_NONE )
David Saadab4ecc272019-02-14 13:48:10 +0200831 return( PSA_ERROR_DOES_NOT_EXIST );
Darryl Green06fd18d2018-07-16 11:21:11 +0100832
833 /* Enforce that usage policy for the key slot contains all the flags
834 * required by the usage parameter. There is one exception: public
835 * keys can always be exported, so we treat public key objects as
836 * if they had the export flag. */
837 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
838 usage &= ~PSA_KEY_USAGE_EXPORT;
839 if( ( slot->policy.usage & usage ) != usage )
840 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine30f77cd2019-01-14 16:06:39 +0100841
842 /* Enforce that the usage policy permits the requested algortihm. */
843 if( alg != 0 && ! psa_key_policy_permits( &slot->policy, alg ) )
Darryl Green06fd18d2018-07-16 11:21:11 +0100844 return( PSA_ERROR_NOT_PERMITTED );
845
846 *p_slot = slot;
847 return( PSA_SUCCESS );
848}
Darryl Green940d72c2018-07-13 13:18:51 +0100849
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100850/** Wipe key data from a slot. Preserve metadata such as the policy. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100851static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
Darryl Green40225ba2018-11-15 14:48:15 +0000852{
853 if( slot->type == PSA_KEY_TYPE_NONE )
854 {
855 /* No key material to clean. */
856 }
857 else if( key_type_is_raw_bytes( slot->type ) )
858 {
859 mbedtls_free( slot->data.raw.data );
860 }
861 else
862#if defined(MBEDTLS_RSA_C)
863 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
864 {
865 mbedtls_rsa_free( slot->data.rsa );
866 mbedtls_free( slot->data.rsa );
867 }
868 else
869#endif /* defined(MBEDTLS_RSA_C) */
870#if defined(MBEDTLS_ECP_C)
871 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
872 {
873 mbedtls_ecp_keypair_free( slot->data.ecp );
874 mbedtls_free( slot->data.ecp );
875 }
876 else
877#endif /* defined(MBEDTLS_ECP_C) */
878 {
879 /* Shouldn't happen: the key type is not any type that we
880 * put in. */
881 return( PSA_ERROR_TAMPERING_DETECTED );
882 }
883
884 return( PSA_SUCCESS );
885}
886
Gilles Peskine5f25dd02019-01-14 18:24:53 +0100887static void psa_abort_operations_using_key( psa_key_slot_t *slot )
888{
Gilles Peskinec88644d2019-04-12 15:03:38 +0200889 /*FIXME how to implement this?*/
Gilles Peskine5f25dd02019-01-14 18:24:53 +0100890 (void) slot;
891}
892
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100893/** Completely wipe a slot in memory, including its policy.
894 * Persistent storage is not affected. */
Gilles Peskine66fb1262018-12-10 16:29:04 +0100895psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100896{
897 psa_status_t status = psa_remove_key_data_from_memory( slot );
Gilles Peskine5f25dd02019-01-14 18:24:53 +0100898 psa_abort_operations_using_key( slot );
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100899 /* At this point, key material and other type-specific content has
900 * been wiped. Clear remaining metadata. We can call memset and not
901 * zeroize because the metadata is not particularly sensitive. */
902 memset( slot, 0, sizeof( *slot ) );
903 return( status );
904}
905
Gilles Peskine87a5e562019-04-17 12:28:25 +0200906psa_status_t psa_import_key_to_handle( psa_key_handle_t handle,
Darryl Green940d72c2018-07-13 13:18:51 +0100907 psa_key_type_t type,
908 const uint8_t *data,
909 size_t data_length )
910{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100911 psa_key_slot_t *slot;
Darryl Green940d72c2018-07-13 13:18:51 +0100912 psa_status_t status;
913
Gilles Peskinec5487a82018-12-03 18:08:14 +0100914 status = psa_get_empty_key_slot( handle, &slot );
Darryl Green940d72c2018-07-13 13:18:51 +0100915 if( status != PSA_SUCCESS )
916 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100917
918 slot->type = type;
Darryl Green940d72c2018-07-13 13:18:51 +0100919
920 status = psa_import_key_into_slot( slot, data, data_length );
921 if( status != PSA_SUCCESS )
922 {
923 slot->type = PSA_KEY_TYPE_NONE;
924 return( status );
925 }
926
Darryl Greend49a4992018-06-18 17:27:26 +0100927#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
928 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
929 {
930 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +0100931 status = psa_save_persistent_key( slot->persistent_storage_id,
932 slot->type, &slot->policy, data,
Darryl Greend49a4992018-06-18 17:27:26 +0100933 data_length );
934 if( status != PSA_SUCCESS )
935 {
936 (void) psa_remove_key_data_from_memory( slot );
937 slot->type = PSA_KEY_TYPE_NONE;
938 }
939 }
940#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
941
942 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100943}
944
Gilles Peskinec5487a82018-12-03 18:08:14 +0100945psa_status_t psa_destroy_key( psa_key_handle_t handle )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100946{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100947 psa_key_slot_t *slot;
Darryl Greend49a4992018-06-18 17:27:26 +0100948 psa_status_t status = PSA_SUCCESS;
949 psa_status_t storage_status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100950
Gilles Peskinec5487a82018-12-03 18:08:14 +0100951 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200952 if( status != PSA_SUCCESS )
953 return( status );
Darryl Greend49a4992018-06-18 17:27:26 +0100954#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
955 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
956 {
Gilles Peskine69f976b2018-11-30 18:46:56 +0100957 storage_status =
958 psa_destroy_persistent_key( slot->persistent_storage_id );
Darryl Greend49a4992018-06-18 17:27:26 +0100959 }
960#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100961 status = psa_wipe_key_slot( slot );
Darryl Greend49a4992018-06-18 17:27:26 +0100962 if( status != PSA_SUCCESS )
963 return( status );
964 return( storage_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100965}
966
Gilles Peskineb870b182018-07-06 16:02:09 +0200967/* Return the size of the key in the given slot, in bits. */
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +0200968static size_t psa_get_key_slot_bits( const psa_key_slot_t *slot )
Gilles Peskineb870b182018-07-06 16:02:09 +0200969{
970 if( key_type_is_raw_bytes( slot->type ) )
971 return( slot->data.raw.bytes * 8 );
972#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200973 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaac64a22018-11-12 18:37:42 +0100974 return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
Gilles Peskineb870b182018-07-06 16:02:09 +0200975#endif /* defined(MBEDTLS_RSA_C) */
976#if defined(MBEDTLS_ECP_C)
977 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
978 return( slot->data.ecp->grp.pbits );
979#endif /* defined(MBEDTLS_ECP_C) */
980 /* Shouldn't happen except on an empty slot. */
981 return( 0 );
982}
983
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +0200984void psa_reset_key_attributes( psa_key_attributes_t *attributes )
985{
986 memset( attributes, 0, sizeof( *attributes ) );
987}
988
989psa_status_t psa_get_key_attributes( psa_key_handle_t handle,
990 psa_key_attributes_t *attributes )
991{
992 psa_key_slot_t *slot;
993 psa_status_t status;
994
995 psa_reset_key_attributes( attributes );
996
997 status = psa_get_key_slot( handle, &slot );
998 if( status != PSA_SUCCESS )
999 return( status );
1000
1001 attributes->id = slot->persistent_storage_id;
1002 attributes->lifetime = slot->lifetime;
1003 attributes->policy = slot->policy;
1004 attributes->type = slot->type;
1005 attributes->bits = psa_get_key_slot_bits( slot );
1006 return( PSA_SUCCESS );
1007}
1008
Gilles Peskinec5487a82018-12-03 18:08:14 +01001009psa_status_t psa_get_key_information( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001010 psa_key_type_t *type,
1011 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001012{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001013 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001014 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001015
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001016 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001017 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001018 if( bits != NULL )
1019 *bits = 0;
Gilles Peskinec5487a82018-12-03 18:08:14 +01001020 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001021 if( status != PSA_SUCCESS )
1022 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +02001023
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001024 if( slot->type == PSA_KEY_TYPE_NONE )
David Saadab4ecc272019-02-14 13:48:10 +02001025 return( PSA_ERROR_DOES_NOT_EXIST );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001026 if( type != NULL )
1027 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +02001028 if( bits != NULL )
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02001029 *bits = psa_get_key_slot_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001030 return( PSA_SUCCESS );
1031}
1032
Jaeden Amero0ae445f2019-01-10 11:42:27 +00001033#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
Jaeden Amero6b196002019-01-10 10:23:21 +00001034static int pk_write_pubkey_simple( mbedtls_pk_context *key,
1035 unsigned char *buf, size_t size )
1036{
1037 int ret;
1038 unsigned char *c;
1039 size_t len = 0;
1040
1041 c = buf + size;
1042
1043 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
1044
1045 return( (int) len );
1046}
Jaeden Amero0ae445f2019-01-10 11:42:27 +00001047#endif /* defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C) */
Jaeden Amero6b196002019-01-10 10:23:21 +00001048
Gilles Peskine4cb9dde2019-01-19 13:40:11 +01001049static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
1050 uint8_t *data,
1051 size_t data_size,
1052 size_t *data_length,
1053 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001054{
Jaeden Amerof24c7f82018-06-27 17:20:43 +01001055 *data_length = 0;
1056
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001057 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001058 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +03001059
Gilles Peskine48c0ea12018-06-21 14:15:31 +02001060 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001061 {
1062 if( slot->data.raw.bytes > data_size )
1063 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine52b90182018-10-29 19:26:27 +01001064 if( data_size != 0 )
1065 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001066 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine52b90182018-10-29 19:26:27 +01001067 memset( data + slot->data.raw.bytes, 0,
1068 data_size - slot->data.raw.bytes );
1069 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001070 *data_length = slot->data.raw.bytes;
1071 return( PSA_SUCCESS );
1072 }
Gilles Peskine188c71e2018-10-29 19:26:02 +01001073#if defined(MBEDTLS_ECP_C)
1074 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
1075 {
Darryl Greendd8fb772018-11-07 16:00:44 +00001076 psa_status_t status;
1077
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02001078 size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_slot_bits( slot ) );
Gilles Peskine188c71e2018-10-29 19:26:02 +01001079 if( bytes > data_size )
1080 return( PSA_ERROR_BUFFER_TOO_SMALL );
1081 status = mbedtls_to_psa_error(
1082 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
1083 if( status != PSA_SUCCESS )
1084 return( status );
1085 memset( data + bytes, 0, data_size - bytes );
1086 *data_length = bytes;
1087 return( PSA_SUCCESS );
1088 }
1089#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001090 else
Moran Peker17e36e12018-05-02 12:55:20 +03001091 {
Gilles Peskine969ac722018-01-28 18:16:59 +01001092#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02001093 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +03001094 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +01001095 {
Moran Pekera998bc62018-04-16 18:16:20 +03001096 mbedtls_pk_context pk;
1097 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +02001098 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +03001099 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001100#if defined(MBEDTLS_RSA_C)
1101 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001102 pk.pk_info = &mbedtls_rsa_info;
1103 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001104#else
1105 return( PSA_ERROR_NOT_SUPPORTED );
1106#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001107 }
1108 else
1109 {
Darryl Green9e2d7a02018-07-24 16:33:30 +01001110#if defined(MBEDTLS_ECP_C)
1111 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +03001112 pk.pk_info = &mbedtls_eckey_info;
1113 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +01001114#else
1115 return( PSA_ERROR_NOT_SUPPORTED );
1116#endif
Moran Pekera998bc62018-04-16 18:16:20 +03001117 }
Moran Pekerd7326592018-05-29 16:56:39 +03001118 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Jaeden Amero6b196002019-01-10 10:23:21 +00001119 {
Jaeden Amero0ae445f2019-01-10 11:42:27 +00001120 ret = pk_write_pubkey_simple( &pk, data, data_size );
Jaeden Amero6b196002019-01-10 10:23:21 +00001121 }
Moran Peker17e36e12018-05-02 12:55:20 +03001122 else
Jaeden Amero6b196002019-01-10 10:23:21 +00001123 {
Moran Peker17e36e12018-05-02 12:55:20 +03001124 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Jaeden Amero6b196002019-01-10 10:23:21 +00001125 }
Moran Peker60364322018-04-29 11:34:58 +03001126 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001127 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001128 /* If data_size is 0 then data may be NULL and then the
1129 * call to memset would have undefined behavior. */
1130 if( data_size != 0 )
1131 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +03001132 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001133 }
Gilles Peskine0e231582018-06-20 00:11:07 +02001134 /* The mbedtls_pk_xxx functions write to the end of the buffer.
1135 * Move the data to the beginning and erase remaining data
1136 * at the original location. */
1137 if( 2 * (size_t) ret <= data_size )
1138 {
1139 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001140 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001141 }
1142 else if( (size_t) ret < data_size )
1143 {
1144 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001145 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001146 }
Moran Pekera998bc62018-04-16 18:16:20 +03001147 *data_length = ret;
1148 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +01001149 }
1150 else
Gilles Peskine6d912132018-03-07 16:41:37 +01001151#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +03001152 {
1153 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001154 it is valid for a special-purpose implementation to omit
1155 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001156 return( PSA_ERROR_NOT_SUPPORTED );
1157 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001158 }
1159}
1160
Gilles Peskinec5487a82018-12-03 18:08:14 +01001161psa_status_t psa_export_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001162 uint8_t *data,
1163 size_t data_size,
1164 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001165{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001166 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001167 psa_status_t status;
1168
1169 /* Set the key to empty now, so that even when there are errors, we always
1170 * set data_length to a value between 0 and data_size. On error, setting
1171 * the key to empty is a good choice because an empty key representation is
1172 * unlikely to be accepted anywhere. */
1173 *data_length = 0;
1174
1175 /* Export requires the EXPORT flag. There is an exception for public keys,
1176 * which don't require any flag, but psa_get_key_from_slot takes
1177 * care of this. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001178 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_EXPORT, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001179 if( status != PSA_SUCCESS )
1180 return( status );
1181 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001182 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001183}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001184
Gilles Peskinec5487a82018-12-03 18:08:14 +01001185psa_status_t psa_export_public_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001186 uint8_t *data,
1187 size_t data_size,
1188 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001189{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001190 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001191 psa_status_t status;
1192
1193 /* Set the key to empty now, so that even when there are errors, we always
1194 * set data_length to a value between 0 and data_size. On error, setting
1195 * the key to empty is a good choice because an empty key representation is
1196 * unlikely to be accepted anywhere. */
1197 *data_length = 0;
1198
1199 /* Exporting a public key doesn't require a usage flag. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001200 status = psa_get_key_from_slot( handle, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001201 if( status != PSA_SUCCESS )
1202 return( status );
1203 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001204 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001205}
1206
Darryl Green0c6575a2018-11-07 16:05:30 +00001207#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine2f060a82018-12-04 17:12:32 +01001208static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t *slot,
Darryl Green0c6575a2018-11-07 16:05:30 +00001209 size_t bits )
1210{
1211 psa_status_t status;
1212 uint8_t *data;
1213 size_t key_length;
1214 size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits );
1215 data = mbedtls_calloc( 1, data_size );
itayzafrir910c76b2018-11-21 16:03:21 +02001216 if( data == NULL )
1217 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Darryl Green0c6575a2018-11-07 16:05:30 +00001218 /* Get key data in export format */
1219 status = psa_internal_export_key( slot, data, data_size, &key_length, 0 );
1220 if( status != PSA_SUCCESS )
1221 {
1222 slot->type = PSA_KEY_TYPE_NONE;
1223 goto exit;
1224 }
1225 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +01001226 status = psa_save_persistent_key( slot->persistent_storage_id,
1227 slot->type, &slot->policy,
Darryl Green0c6575a2018-11-07 16:05:30 +00001228 data, key_length );
1229 if( status != PSA_SUCCESS )
1230 {
1231 slot->type = PSA_KEY_TYPE_NONE;
1232 }
1233exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01001234 mbedtls_platform_zeroize( data, key_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00001235 mbedtls_free( data );
1236 return( status );
1237}
1238#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1239
Gilles Peskine4747d192019-04-17 15:05:45 +02001240static psa_status_t psa_set_key_policy_internal(
1241 psa_key_slot_t *slot,
1242 const psa_key_policy_t *policy )
1243{
1244 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
1245 PSA_KEY_USAGE_ENCRYPT |
1246 PSA_KEY_USAGE_DECRYPT |
1247 PSA_KEY_USAGE_SIGN |
1248 PSA_KEY_USAGE_VERIFY |
1249 PSA_KEY_USAGE_DERIVE ) ) != 0 )
1250 return( PSA_ERROR_INVALID_ARGUMENT );
1251
1252 slot->policy = *policy;
1253 return( PSA_SUCCESS );
1254}
1255
1256/** Prepare a key slot to receive key material.
1257 *
1258 * This function allocates a key slot and sets its metadata.
1259 *
1260 * If this function fails, call psa_fail_key_creation().
1261 *
1262 * \param attributes Key attributes for the new key.
1263 * \param handle On success, the allocated handle.
1264 * \param p_slot On success, a pointer to the prepared slot.
1265 */
1266static psa_status_t psa_start_key_creation(
1267 const psa_key_attributes_t *attributes,
1268 psa_key_handle_t *handle,
1269 psa_key_slot_t **p_slot )
1270{
1271 psa_status_t status;
1272 psa_key_slot_t *slot;
1273
1274 status = psa_allocate_key( handle );
1275 if( status != PSA_SUCCESS )
1276 return( status );
1277 status = psa_get_key_slot( *handle, p_slot );
1278 if( status != PSA_SUCCESS )
1279 return( status );
1280 slot = *p_slot;
1281
1282 status = psa_set_key_policy_internal( slot, &attributes->policy );
1283 if( status != PSA_SUCCESS )
1284 return( status );
1285 slot->lifetime = attributes->lifetime;
1286 if( attributes->lifetime != PSA_KEY_LIFETIME_VOLATILE )
1287 slot->persistent_storage_id = attributes->id;
1288 slot->type = attributes->type;
1289
1290 return( status );
1291}
1292
1293/** Finalize the creation of a key once its key material has been set.
1294 *
1295 * This entails writing the key to persistent storage.
1296 *
1297 * If this function fails, call psa_fail_key_creation().
1298 *
1299 * \param slot Pointer to the slot with key material.
1300 */
1301static psa_status_t psa_finish_key_creation( psa_key_slot_t *slot )
1302{
1303 psa_status_t status = PSA_SUCCESS;
1304
1305#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
1306 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
1307 {
1308 uint8_t *buffer = NULL;
1309 size_t buffer_size = 0;
1310 size_t length;
1311
1312 buffer_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type,
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02001313 psa_get_key_slot_bits( slot ) );
Gilles Peskine4747d192019-04-17 15:05:45 +02001314 buffer = mbedtls_calloc( 1, buffer_size );
1315 if( buffer == NULL && buffer_size != 0 )
1316 return( PSA_ERROR_INSUFFICIENT_MEMORY );
1317 status = psa_internal_export_key( slot,
1318 buffer, buffer_size, &length,
1319 0 );
1320
1321 if( status == PSA_SUCCESS )
1322 {
1323 status = psa_save_persistent_key( slot->persistent_storage_id,
1324 slot->type, &slot->policy,
1325 buffer, length );
1326 }
1327
1328 if( buffer_size != 0 )
1329 mbedtls_platform_zeroize( buffer, buffer_size );
1330 mbedtls_free( buffer );
1331 }
1332#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1333
1334 return( status );
1335}
1336
1337/** Abort the creation of a key.
1338 *
1339 * You may call this function after calling psa_start_key_creation(),
1340 * or after psa_finish_key_creation() fails. In other circumstances, this
1341 * function may not clean up persistent storage.
1342 *
1343 * \param slot Pointer to the slot with key material.
1344 */
1345static void psa_fail_key_creation( psa_key_slot_t *slot )
1346{
1347 if( slot == NULL )
1348 return;
1349 psa_wipe_key_slot( slot );
1350}
1351
1352psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
1353 psa_key_handle_t *handle,
1354 const uint8_t *data,
1355 size_t data_length )
1356{
1357 psa_status_t status;
1358 psa_key_slot_t *slot = NULL;
1359 status = psa_start_key_creation( attributes, handle, &slot );
1360 if( status == PSA_SUCCESS )
1361 {
1362 status = psa_import_key_into_slot( slot, data, data_length );
1363 }
1364 if( status == PSA_SUCCESS )
1365 status = psa_finish_key_creation( slot );
1366 if( status != PSA_SUCCESS )
1367 {
1368 psa_fail_key_creation( slot );
1369 *handle = 0;
1370 }
1371 return( status );
1372}
1373
Gilles Peskine4cb9dde2019-01-19 13:40:11 +01001374static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001375 psa_key_slot_t *target )
Gilles Peskine4cb9dde2019-01-19 13:40:11 +01001376{
1377 psa_status_t status;
1378 uint8_t *buffer = NULL;
1379 size_t buffer_size = 0;
1380 size_t length;
1381
1382 buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->type,
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02001383 psa_get_key_slot_bits( source ) );
Gilles Peskine4cb9dde2019-01-19 13:40:11 +01001384 buffer = mbedtls_calloc( 1, buffer_size );
Darryl Green8593bca2019-02-11 11:45:58 +00001385 if( buffer == NULL && buffer_size != 0 )
Gilles Peskine122d0022019-01-23 10:55:43 +01001386 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Gilles Peskine4cb9dde2019-01-19 13:40:11 +01001387 status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 );
1388 if( status != PSA_SUCCESS )
1389 goto exit;
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001390 target->type = source->type;
1391 status = psa_import_key_into_slot( target, buffer, length );
Gilles Peskine4cb9dde2019-01-19 13:40:11 +01001392
1393exit:
Darryl Green8096caf2019-02-11 14:03:03 +00001394 if( buffer_size != 0 )
1395 mbedtls_platform_zeroize( buffer, buffer_size );
Gilles Peskine122d0022019-01-23 10:55:43 +01001396 mbedtls_free( buffer );
Gilles Peskine4cb9dde2019-01-19 13:40:11 +01001397 return( status );
1398}
1399
Gilles Peskine87a5e562019-04-17 12:28:25 +02001400psa_status_t psa_copy_key_to_handle(psa_key_handle_t source_handle,
Gilles Peskine4cb9dde2019-01-19 13:40:11 +01001401 psa_key_handle_t target_handle,
1402 const psa_key_policy_t *constraint)
1403{
1404 psa_key_slot_t *source_slot = NULL;
1405 psa_key_slot_t *target_slot = NULL;
1406 psa_key_policy_t new_policy;
1407 psa_status_t status;
1408 status = psa_get_key_from_slot( source_handle, &source_slot, 0, 0 );
1409 if( status != PSA_SUCCESS )
1410 return( status );
1411 status = psa_get_empty_key_slot( target_handle, &target_slot );
1412 if( status != PSA_SUCCESS )
1413 return( status );
1414
1415 new_policy = target_slot->policy;
1416 status = psa_restrict_key_policy( &new_policy, &source_slot->policy );
1417 if( status != PSA_SUCCESS )
1418 return( status );
1419 if( constraint != NULL )
1420 {
1421 status = psa_restrict_key_policy( &new_policy, constraint );
1422 if( status != PSA_SUCCESS )
1423 return( status );
1424 }
1425
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001426 status = psa_copy_key_material( source_slot, target_slot );
Gilles Peskine4cb9dde2019-01-19 13:40:11 +01001427 if( status != PSA_SUCCESS )
1428 return( status );
1429
1430 target_slot->policy = new_policy;
1431 return( PSA_SUCCESS );
1432}
1433
Gilles Peskine8c8f2ab2019-04-18 21:44:46 +02001434psa_status_t psa_copy_key( psa_key_handle_t source_handle,
1435 const psa_key_attributes_t *specified_attributes,
1436 psa_key_handle_t *target_handle )
1437{
1438 psa_status_t status;
1439 psa_key_slot_t *source_slot = NULL;
1440 psa_key_slot_t *target_slot = NULL;
1441 psa_key_attributes_t actual_attributes = *specified_attributes;
1442
1443 status = psa_get_key_from_slot( source_handle, &source_slot, 0, 0 );
1444 if( status != PSA_SUCCESS )
1445 goto exit;
1446
1447 status = psa_restrict_key_policy( &actual_attributes.policy,
1448 &source_slot->policy );
1449 if( status != PSA_SUCCESS )
1450 goto exit;
1451
1452 status = psa_start_key_creation( &actual_attributes,
1453 target_handle, &target_slot );
1454 if( status != PSA_SUCCESS )
1455 goto exit;
1456
1457 status = psa_copy_key_material( source_slot, target_slot );
1458
1459exit:
1460 if( status == PSA_SUCCESS )
1461 status = psa_finish_key_creation( target_slot );
1462 if( status != PSA_SUCCESS )
1463 {
1464 psa_fail_key_creation( target_slot );
1465 *target_handle = 0;
1466 }
1467 return( status );
1468}
1469
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001470
1471
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001472/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001473/* Message digests */
1474/****************************************************************/
1475
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001476static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01001477{
1478 switch( alg )
1479 {
1480#if defined(MBEDTLS_MD2_C)
1481 case PSA_ALG_MD2:
1482 return( &mbedtls_md2_info );
1483#endif
1484#if defined(MBEDTLS_MD4_C)
1485 case PSA_ALG_MD4:
1486 return( &mbedtls_md4_info );
1487#endif
1488#if defined(MBEDTLS_MD5_C)
1489 case PSA_ALG_MD5:
1490 return( &mbedtls_md5_info );
1491#endif
1492#if defined(MBEDTLS_RIPEMD160_C)
1493 case PSA_ALG_RIPEMD160:
1494 return( &mbedtls_ripemd160_info );
1495#endif
1496#if defined(MBEDTLS_SHA1_C)
1497 case PSA_ALG_SHA_1:
1498 return( &mbedtls_sha1_info );
1499#endif
1500#if defined(MBEDTLS_SHA256_C)
1501 case PSA_ALG_SHA_224:
1502 return( &mbedtls_sha224_info );
1503 case PSA_ALG_SHA_256:
1504 return( &mbedtls_sha256_info );
1505#endif
1506#if defined(MBEDTLS_SHA512_C)
1507 case PSA_ALG_SHA_384:
1508 return( &mbedtls_sha384_info );
1509 case PSA_ALG_SHA_512:
1510 return( &mbedtls_sha512_info );
1511#endif
1512 default:
1513 return( NULL );
1514 }
1515}
1516
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001517psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
1518{
1519 switch( operation->alg )
1520 {
Gilles Peskine81736312018-06-26 15:04:31 +02001521 case 0:
1522 /* The object has (apparently) been initialized but it is not
1523 * in use. It's ok to call abort on such an object, and there's
1524 * nothing to do. */
1525 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001526#if defined(MBEDTLS_MD2_C)
1527 case PSA_ALG_MD2:
1528 mbedtls_md2_free( &operation->ctx.md2 );
1529 break;
1530#endif
1531#if defined(MBEDTLS_MD4_C)
1532 case PSA_ALG_MD4:
1533 mbedtls_md4_free( &operation->ctx.md4 );
1534 break;
1535#endif
1536#if defined(MBEDTLS_MD5_C)
1537 case PSA_ALG_MD5:
1538 mbedtls_md5_free( &operation->ctx.md5 );
1539 break;
1540#endif
1541#if defined(MBEDTLS_RIPEMD160_C)
1542 case PSA_ALG_RIPEMD160:
1543 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
1544 break;
1545#endif
1546#if defined(MBEDTLS_SHA1_C)
1547 case PSA_ALG_SHA_1:
1548 mbedtls_sha1_free( &operation->ctx.sha1 );
1549 break;
1550#endif
1551#if defined(MBEDTLS_SHA256_C)
1552 case PSA_ALG_SHA_224:
1553 case PSA_ALG_SHA_256:
1554 mbedtls_sha256_free( &operation->ctx.sha256 );
1555 break;
1556#endif
1557#if defined(MBEDTLS_SHA512_C)
1558 case PSA_ALG_SHA_384:
1559 case PSA_ALG_SHA_512:
1560 mbedtls_sha512_free( &operation->ctx.sha512 );
1561 break;
1562#endif
1563 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001564 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001565 }
1566 operation->alg = 0;
1567 return( PSA_SUCCESS );
1568}
1569
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02001570psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001571 psa_algorithm_t alg )
1572{
1573 int ret;
Jaeden Amero36ee5d02019-02-19 09:25:10 +00001574
1575 /* A context must be freshly initialized before it can be set up. */
1576 if( operation->alg != 0 )
1577 {
1578 return( PSA_ERROR_BAD_STATE );
1579 }
1580
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001581 switch( alg )
1582 {
1583#if defined(MBEDTLS_MD2_C)
1584 case PSA_ALG_MD2:
1585 mbedtls_md2_init( &operation->ctx.md2 );
1586 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
1587 break;
1588#endif
1589#if defined(MBEDTLS_MD4_C)
1590 case PSA_ALG_MD4:
1591 mbedtls_md4_init( &operation->ctx.md4 );
1592 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
1593 break;
1594#endif
1595#if defined(MBEDTLS_MD5_C)
1596 case PSA_ALG_MD5:
1597 mbedtls_md5_init( &operation->ctx.md5 );
1598 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
1599 break;
1600#endif
1601#if defined(MBEDTLS_RIPEMD160_C)
1602 case PSA_ALG_RIPEMD160:
1603 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
1604 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
1605 break;
1606#endif
1607#if defined(MBEDTLS_SHA1_C)
1608 case PSA_ALG_SHA_1:
1609 mbedtls_sha1_init( &operation->ctx.sha1 );
1610 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1611 break;
1612#endif
1613#if defined(MBEDTLS_SHA256_C)
1614 case PSA_ALG_SHA_224:
1615 mbedtls_sha256_init( &operation->ctx.sha256 );
1616 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1617 break;
1618 case PSA_ALG_SHA_256:
1619 mbedtls_sha256_init( &operation->ctx.sha256 );
1620 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1621 break;
1622#endif
1623#if defined(MBEDTLS_SHA512_C)
1624 case PSA_ALG_SHA_384:
1625 mbedtls_sha512_init( &operation->ctx.sha512 );
1626 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1627 break;
1628 case PSA_ALG_SHA_512:
1629 mbedtls_sha512_init( &operation->ctx.sha512 );
1630 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1631 break;
1632#endif
1633 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001634 return( PSA_ALG_IS_HASH( alg ) ?
1635 PSA_ERROR_NOT_SUPPORTED :
1636 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001637 }
1638 if( ret == 0 )
1639 operation->alg = alg;
1640 else
1641 psa_hash_abort( operation );
1642 return( mbedtls_to_psa_error( ret ) );
1643}
1644
1645psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1646 const uint8_t *input,
1647 size_t input_length )
1648{
1649 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001650
1651 /* Don't require hash implementations to behave correctly on a
1652 * zero-length input, which may have an invalid pointer. */
1653 if( input_length == 0 )
1654 return( PSA_SUCCESS );
1655
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001656 switch( operation->alg )
1657 {
1658#if defined(MBEDTLS_MD2_C)
1659 case PSA_ALG_MD2:
1660 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1661 input, input_length );
1662 break;
1663#endif
1664#if defined(MBEDTLS_MD4_C)
1665 case PSA_ALG_MD4:
1666 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1667 input, input_length );
1668 break;
1669#endif
1670#if defined(MBEDTLS_MD5_C)
1671 case PSA_ALG_MD5:
1672 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1673 input, input_length );
1674 break;
1675#endif
1676#if defined(MBEDTLS_RIPEMD160_C)
1677 case PSA_ALG_RIPEMD160:
1678 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1679 input, input_length );
1680 break;
1681#endif
1682#if defined(MBEDTLS_SHA1_C)
1683 case PSA_ALG_SHA_1:
1684 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1685 input, input_length );
1686 break;
1687#endif
1688#if defined(MBEDTLS_SHA256_C)
1689 case PSA_ALG_SHA_224:
1690 case PSA_ALG_SHA_256:
1691 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1692 input, input_length );
1693 break;
1694#endif
1695#if defined(MBEDTLS_SHA512_C)
1696 case PSA_ALG_SHA_384:
1697 case PSA_ALG_SHA_512:
1698 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1699 input, input_length );
1700 break;
1701#endif
1702 default:
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00001703 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001704 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001705
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001706 if( ret != 0 )
1707 psa_hash_abort( operation );
1708 return( mbedtls_to_psa_error( ret ) );
1709}
1710
1711psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1712 uint8_t *hash,
1713 size_t hash_size,
1714 size_t *hash_length )
1715{
itayzafrir40835d42018-08-02 13:14:17 +03001716 psa_status_t status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001717 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001718 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001719
1720 /* Fill the output buffer with something that isn't a valid hash
1721 * (barring an attack on the hash and deliberately-crafted input),
1722 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001723 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001724 /* If hash_size is 0 then hash may be NULL and then the
1725 * call to memset would have undefined behavior. */
1726 if( hash_size != 0 )
1727 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001728
1729 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03001730 {
1731 status = PSA_ERROR_BUFFER_TOO_SMALL;
1732 goto exit;
1733 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001734
1735 switch( operation->alg )
1736 {
1737#if defined(MBEDTLS_MD2_C)
1738 case PSA_ALG_MD2:
1739 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1740 break;
1741#endif
1742#if defined(MBEDTLS_MD4_C)
1743 case PSA_ALG_MD4:
1744 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1745 break;
1746#endif
1747#if defined(MBEDTLS_MD5_C)
1748 case PSA_ALG_MD5:
1749 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1750 break;
1751#endif
1752#if defined(MBEDTLS_RIPEMD160_C)
1753 case PSA_ALG_RIPEMD160:
1754 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1755 break;
1756#endif
1757#if defined(MBEDTLS_SHA1_C)
1758 case PSA_ALG_SHA_1:
1759 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1760 break;
1761#endif
1762#if defined(MBEDTLS_SHA256_C)
1763 case PSA_ALG_SHA_224:
1764 case PSA_ALG_SHA_256:
1765 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1766 break;
1767#endif
1768#if defined(MBEDTLS_SHA512_C)
1769 case PSA_ALG_SHA_384:
1770 case PSA_ALG_SHA_512:
1771 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1772 break;
1773#endif
1774 default:
Jaeden Ameroa0f625a2019-02-15 13:52:25 +00001775 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001776 }
itayzafrir40835d42018-08-02 13:14:17 +03001777 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001778
itayzafrir40835d42018-08-02 13:14:17 +03001779exit:
1780 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001781 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001782 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001783 return( psa_hash_abort( operation ) );
1784 }
1785 else
1786 {
1787 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03001788 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001789 }
1790}
1791
Gilles Peskine2d277862018-06-18 15:41:12 +02001792psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1793 const uint8_t *hash,
1794 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001795{
1796 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1797 size_t actual_hash_length;
1798 psa_status_t status = psa_hash_finish( operation,
1799 actual_hash, sizeof( actual_hash ),
1800 &actual_hash_length );
1801 if( status != PSA_SUCCESS )
1802 return( status );
1803 if( actual_hash_length != hash_length )
1804 return( PSA_ERROR_INVALID_SIGNATURE );
1805 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1806 return( PSA_ERROR_INVALID_SIGNATURE );
1807 return( PSA_SUCCESS );
1808}
1809
Gilles Peskineeb35d782019-01-22 17:56:16 +01001810psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
1811 psa_hash_operation_t *target_operation )
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01001812{
1813 if( target_operation->alg != 0 )
1814 return( PSA_ERROR_BAD_STATE );
1815
1816 switch( source_operation->alg )
1817 {
1818 case 0:
1819 return( PSA_ERROR_BAD_STATE );
1820#if defined(MBEDTLS_MD2_C)
1821 case PSA_ALG_MD2:
1822 mbedtls_md2_clone( &target_operation->ctx.md2,
1823 &source_operation->ctx.md2 );
1824 break;
1825#endif
1826#if defined(MBEDTLS_MD4_C)
1827 case PSA_ALG_MD4:
1828 mbedtls_md4_clone( &target_operation->ctx.md4,
1829 &source_operation->ctx.md4 );
1830 break;
1831#endif
1832#if defined(MBEDTLS_MD5_C)
1833 case PSA_ALG_MD5:
1834 mbedtls_md5_clone( &target_operation->ctx.md5,
1835 &source_operation->ctx.md5 );
1836 break;
1837#endif
1838#if defined(MBEDTLS_RIPEMD160_C)
1839 case PSA_ALG_RIPEMD160:
1840 mbedtls_ripemd160_clone( &target_operation->ctx.ripemd160,
1841 &source_operation->ctx.ripemd160 );
1842 break;
1843#endif
1844#if defined(MBEDTLS_SHA1_C)
1845 case PSA_ALG_SHA_1:
1846 mbedtls_sha1_clone( &target_operation->ctx.sha1,
1847 &source_operation->ctx.sha1 );
1848 break;
1849#endif
1850#if defined(MBEDTLS_SHA256_C)
1851 case PSA_ALG_SHA_224:
1852 case PSA_ALG_SHA_256:
1853 mbedtls_sha256_clone( &target_operation->ctx.sha256,
1854 &source_operation->ctx.sha256 );
1855 break;
1856#endif
1857#if defined(MBEDTLS_SHA512_C)
1858 case PSA_ALG_SHA_384:
1859 case PSA_ALG_SHA_512:
1860 mbedtls_sha512_clone( &target_operation->ctx.sha512,
1861 &source_operation->ctx.sha512 );
1862 break;
1863#endif
1864 default:
1865 return( PSA_ERROR_NOT_SUPPORTED );
1866 }
1867
1868 target_operation->alg = source_operation->alg;
1869 return( PSA_SUCCESS );
1870}
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001871
1872
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001873/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001874/* MAC */
1875/****************************************************************/
1876
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001877static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001878 psa_algorithm_t alg,
1879 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001880 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001881 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001882{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001883 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001884 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001885
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001886 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001887 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001888
Gilles Peskine8c9def32018-02-08 10:02:12 +01001889 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1890 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001891 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001892 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001893 case PSA_ALG_ARC4:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001894 mode = MBEDTLS_MODE_STREAM;
1895 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001896 case PSA_ALG_CTR:
1897 mode = MBEDTLS_MODE_CTR;
1898 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001899 case PSA_ALG_CFB:
1900 mode = MBEDTLS_MODE_CFB;
1901 break;
1902 case PSA_ALG_OFB:
1903 mode = MBEDTLS_MODE_OFB;
1904 break;
1905 case PSA_ALG_CBC_NO_PADDING:
1906 mode = MBEDTLS_MODE_CBC;
1907 break;
1908 case PSA_ALG_CBC_PKCS7:
1909 mode = MBEDTLS_MODE_CBC;
1910 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001911 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001912 mode = MBEDTLS_MODE_CCM;
1913 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001914 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001915 mode = MBEDTLS_MODE_GCM;
1916 break;
1917 default:
1918 return( NULL );
1919 }
1920 }
1921 else if( alg == PSA_ALG_CMAC )
1922 mode = MBEDTLS_MODE_ECB;
1923 else if( alg == PSA_ALG_GMAC )
1924 mode = MBEDTLS_MODE_GCM;
1925 else
1926 return( NULL );
1927
1928 switch( key_type )
1929 {
1930 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001931 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001932 break;
1933 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001934 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1935 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001936 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001937 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001938 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001939 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001940 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1941 * but two-key Triple-DES is functionally three-key Triple-DES
1942 * with K1=K3, so that's how we present it to mbedtls. */
1943 if( key_bits == 128 )
1944 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001945 break;
1946 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001947 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001948 break;
1949 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001950 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001951 break;
1952 default:
1953 return( NULL );
1954 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001955 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001956 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001957
Jaeden Amero23bbb752018-06-26 14:16:54 +01001958 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1959 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001960}
1961
Gilles Peskinea05219c2018-11-16 16:02:56 +01001962#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001963static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001964{
Gilles Peskine2d277862018-06-18 15:41:12 +02001965 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001966 {
1967 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001968 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001969 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001970 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001971 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001972 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001973 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001974 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001975 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001976 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001977 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001978 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001979 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001980 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001981 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001982 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001983 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001984 return( 128 );
1985 default:
1986 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001987 }
1988}
Gilles Peskinea05219c2018-11-16 16:02:56 +01001989#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001990
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001991/* Initialize the MAC operation structure. Once this function has been
1992 * called, psa_mac_abort can run and will do the right thing. */
1993static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1994 psa_algorithm_t alg )
1995{
1996 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1997
1998 operation->alg = alg;
1999 operation->key_set = 0;
2000 operation->iv_set = 0;
2001 operation->iv_required = 0;
2002 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002003 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002004
2005#if defined(MBEDTLS_CMAC_C)
2006 if( alg == PSA_ALG_CMAC )
2007 {
2008 operation->iv_required = 0;
2009 mbedtls_cipher_init( &operation->ctx.cmac );
2010 status = PSA_SUCCESS;
2011 }
2012 else
2013#endif /* MBEDTLS_CMAC_C */
2014#if defined(MBEDTLS_MD_C)
2015 if( PSA_ALG_IS_HMAC( operation->alg ) )
2016 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02002017 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
2018 operation->ctx.hmac.hash_ctx.alg = 0;
2019 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002020 }
2021 else
2022#endif /* MBEDTLS_MD_C */
2023 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02002024 if( ! PSA_ALG_IS_MAC( alg ) )
2025 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002026 }
2027
2028 if( status != PSA_SUCCESS )
2029 memset( operation, 0, sizeof( *operation ) );
2030 return( status );
2031}
2032
Gilles Peskine01126fa2018-07-12 17:04:55 +02002033#if defined(MBEDTLS_MD_C)
2034static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
2035{
Gilles Peskine3f108122018-12-07 18:14:53 +01002036 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002037 return( psa_hash_abort( &hmac->hash_ctx ) );
2038}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01002039
2040static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
2041{
2042 /* Instances of psa_hash_operation_s can be initialized by zeroization. */
2043 memset( hmac, 0, sizeof( *hmac ) );
2044}
Gilles Peskine01126fa2018-07-12 17:04:55 +02002045#endif /* MBEDTLS_MD_C */
2046
Gilles Peskine8c9def32018-02-08 10:02:12 +01002047psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
2048{
Gilles Peskinefbfac682018-07-08 20:51:54 +02002049 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002050 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02002051 /* The object has (apparently) been initialized but it is not
2052 * in use. It's ok to call abort on such an object, and there's
2053 * nothing to do. */
2054 return( PSA_SUCCESS );
2055 }
2056 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002057#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002058 if( operation->alg == PSA_ALG_CMAC )
2059 {
2060 mbedtls_cipher_free( &operation->ctx.cmac );
2061 }
2062 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002063#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01002064#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002065 if( PSA_ALG_IS_HMAC( operation->alg ) )
2066 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002067 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002068 }
2069 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002070#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02002071 {
2072 /* Sanity check (shouldn't happen: operation->alg should
2073 * always have been initialized to a valid value). */
2074 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002075 }
Moran Peker41deec42018-04-04 15:43:05 +03002076
Gilles Peskine8c9def32018-02-08 10:02:12 +01002077 operation->alg = 0;
2078 operation->key_set = 0;
2079 operation->iv_set = 0;
2080 operation->iv_required = 0;
2081 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002082 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002083
Gilles Peskine8c9def32018-02-08 10:02:12 +01002084 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002085
2086bad_state:
2087 /* If abort is called on an uninitialized object, we can't trust
2088 * anything. Wipe the object in case it contains confidential data.
2089 * This may result in a memory leak if a pointer gets overwritten,
2090 * but it's too late to do anything about this. */
2091 memset( operation, 0, sizeof( *operation ) );
2092 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002093}
2094
Gilles Peskinee3b07d82018-06-19 11:57:35 +02002095#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02002096static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002097 size_t key_bits,
Gilles Peskine2f060a82018-12-04 17:12:32 +01002098 psa_key_slot_t *slot,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002099 const mbedtls_cipher_info_t *cipher_info )
2100{
2101 int ret;
2102
2103 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002104
2105 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
2106 if( ret != 0 )
2107 return( ret );
2108
2109 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
2110 slot->data.raw.data,
2111 key_bits );
2112 return( ret );
2113}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02002114#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002115
Gilles Peskine248051a2018-06-20 16:09:38 +02002116#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02002117static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
2118 const uint8_t *key,
2119 size_t key_length,
2120 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002121{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02002122 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002123 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002124 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002125 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002126 psa_status_t status;
2127
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002128 /* Sanity checks on block_size, to guarantee that there won't be a buffer
2129 * overflow below. This should never trigger if the hash algorithm
2130 * is implemented correctly. */
2131 /* The size checks against the ipad and opad buffers cannot be written
2132 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
2133 * because that triggers -Wlogical-op on GCC 7.3. */
2134 if( block_size > sizeof( ipad ) )
2135 return( PSA_ERROR_NOT_SUPPORTED );
2136 if( block_size > sizeof( hmac->opad ) )
2137 return( PSA_ERROR_NOT_SUPPORTED );
2138 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002139 return( PSA_ERROR_NOT_SUPPORTED );
2140
Gilles Peskined223b522018-06-11 18:12:58 +02002141 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002142 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02002143 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002144 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02002145 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02002146 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002147 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02002148 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02002149 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02002150 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002151 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02002152 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002153 }
Gilles Peskine96889972018-07-12 17:07:03 +02002154 /* A 0-length key is not commonly used in HMAC when used as a MAC,
2155 * but it is permitted. It is common when HMAC is used in HKDF, for
2156 * example. Don't call `memcpy` in the 0-length because `key` could be
2157 * an invalid pointer which would make the behavior undefined. */
2158 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02002159 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002160
Gilles Peskined223b522018-06-11 18:12:58 +02002161 /* ipad contains the key followed by garbage. Xor and fill with 0x36
2162 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002163 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02002164 ipad[i] ^= 0x36;
2165 memset( ipad + key_length, 0x36, block_size - key_length );
2166
2167 /* Copy the key material from ipad to opad, flipping the requisite bits,
2168 * and filling the rest of opad with the requisite constant. */
2169 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02002170 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
2171 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002172
Gilles Peskine01126fa2018-07-12 17:04:55 +02002173 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002174 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002175 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002176
Gilles Peskine01126fa2018-07-12 17:04:55 +02002177 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002178
2179cleanup:
Gilles Peskine3f108122018-12-07 18:14:53 +01002180 mbedtls_platform_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002181
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002182 return( status );
2183}
Gilles Peskine248051a2018-06-20 16:09:38 +02002184#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002185
Gilles Peskine89167cb2018-07-08 20:12:23 +02002186static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002187 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02002188 psa_algorithm_t alg,
2189 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002190{
Gilles Peskine8c9def32018-02-08 10:02:12 +01002191 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +01002192 psa_key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002193 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002194 psa_key_usage_t usage =
2195 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskined911eb72018-08-14 15:18:45 +02002196 unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02002197 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002198
Jaeden Amero36ee5d02019-02-19 09:25:10 +00002199 /* A context must be freshly initialized before it can be set up. */
2200 if( operation->alg != 0 )
2201 {
2202 return( PSA_ERROR_BAD_STATE );
2203 }
2204
Gilles Peskined911eb72018-08-14 15:18:45 +02002205 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002206 if( status != PSA_SUCCESS )
2207 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002208 if( is_sign )
2209 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002210
Gilles Peskinec5487a82018-12-03 18:08:14 +01002211 status = psa_get_key_from_slot( handle, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002212 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002213 goto exit;
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02002214 key_bits = psa_get_key_slot_bits( slot );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002215
Gilles Peskine8c9def32018-02-08 10:02:12 +01002216#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02002217 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002218 {
2219 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02002220 mbedtls_cipher_info_from_psa( full_length_alg,
2221 slot->type, key_bits, NULL );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002222 int ret;
2223 if( cipher_info == NULL )
2224 {
2225 status = PSA_ERROR_NOT_SUPPORTED;
2226 goto exit;
2227 }
2228 operation->mac_size = cipher_info->block_size;
2229 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
2230 status = mbedtls_to_psa_error( ret );
2231 }
2232 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002233#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01002234#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02002235 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02002236 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02002237 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002238 if( hash_alg == 0 )
2239 {
2240 status = PSA_ERROR_NOT_SUPPORTED;
2241 goto exit;
2242 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002243
2244 operation->mac_size = PSA_HASH_SIZE( hash_alg );
2245 /* Sanity check. This shouldn't fail on a valid configuration. */
2246 if( operation->mac_size == 0 ||
2247 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
2248 {
2249 status = PSA_ERROR_NOT_SUPPORTED;
2250 goto exit;
2251 }
2252
Gilles Peskine01126fa2018-07-12 17:04:55 +02002253 if( slot->type != PSA_KEY_TYPE_HMAC )
2254 {
2255 status = PSA_ERROR_INVALID_ARGUMENT;
2256 goto exit;
2257 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02002258
Gilles Peskine01126fa2018-07-12 17:04:55 +02002259 status = psa_hmac_setup_internal( &operation->ctx.hmac,
2260 slot->data.raw.data,
2261 slot->data.raw.bytes,
2262 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002263 }
2264 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01002265#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02002266 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00002267 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02002268 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002269 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002270
Gilles Peskined911eb72018-08-14 15:18:45 +02002271 if( truncated == 0 )
2272 {
2273 /* The "normal" case: untruncated algorithm. Nothing to do. */
2274 }
2275 else if( truncated < 4 )
2276 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02002277 /* A very short MAC is too short for security since it can be
2278 * brute-forced. Ancient protocols with 32-bit MACs do exist,
2279 * so we make this our minimum, even though 32 bits is still
2280 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02002281 status = PSA_ERROR_NOT_SUPPORTED;
2282 }
2283 else if( truncated > operation->mac_size )
2284 {
2285 /* It's impossible to "truncate" to a larger length. */
2286 status = PSA_ERROR_INVALID_ARGUMENT;
2287 }
2288 else
2289 operation->mac_size = truncated;
2290
Gilles Peskinefbfac682018-07-08 20:51:54 +02002291exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002292 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002293 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02002294 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002295 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002296 else
2297 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02002298 operation->key_set = 1;
2299 }
2300 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002301}
2302
Gilles Peskine89167cb2018-07-08 20:12:23 +02002303psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002304 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02002305 psa_algorithm_t alg )
2306{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002307 return( psa_mac_setup( operation, handle, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002308}
2309
2310psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002311 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02002312 psa_algorithm_t alg )
2313{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002314 return( psa_mac_setup( operation, handle, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002315}
2316
Gilles Peskine8c9def32018-02-08 10:02:12 +01002317psa_status_t psa_mac_update( psa_mac_operation_t *operation,
2318 const uint8_t *input,
2319 size_t input_length )
2320{
Gilles Peskinefbfac682018-07-08 20:51:54 +02002321 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01002322 if( ! operation->key_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00002323 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002324 if( operation->iv_required && ! operation->iv_set )
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00002325 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002326 operation->has_input = 1;
2327
Gilles Peskine8c9def32018-02-08 10:02:12 +01002328#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002329 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03002330 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02002331 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
2332 input, input_length );
2333 status = mbedtls_to_psa_error( ret );
2334 }
2335 else
2336#endif /* MBEDTLS_CMAC_C */
2337#if defined(MBEDTLS_MD_C)
2338 if( PSA_ALG_IS_HMAC( operation->alg ) )
2339 {
2340 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
2341 input_length );
2342 }
2343 else
2344#endif /* MBEDTLS_MD_C */
2345 {
2346 /* This shouldn't happen if `operation` was initialized by
2347 * a setup function. */
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00002348 return( PSA_ERROR_BAD_STATE );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03002349 }
2350
Gilles Peskinefbfac682018-07-08 20:51:54 +02002351 if( status != PSA_SUCCESS )
2352 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002353 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002354}
2355
Gilles Peskine01126fa2018-07-12 17:04:55 +02002356#if defined(MBEDTLS_MD_C)
2357static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
2358 uint8_t *mac,
2359 size_t mac_size )
2360{
2361 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
2362 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
2363 size_t hash_size = 0;
2364 size_t block_size = psa_get_hash_block_size( hash_alg );
2365 psa_status_t status;
2366
Gilles Peskine01126fa2018-07-12 17:04:55 +02002367 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
2368 if( status != PSA_SUCCESS )
2369 return( status );
2370 /* From here on, tmp needs to be wiped. */
2371
2372 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
2373 if( status != PSA_SUCCESS )
2374 goto exit;
2375
2376 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
2377 if( status != PSA_SUCCESS )
2378 goto exit;
2379
2380 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
2381 if( status != PSA_SUCCESS )
2382 goto exit;
2383
Gilles Peskined911eb72018-08-14 15:18:45 +02002384 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
2385 if( status != PSA_SUCCESS )
2386 goto exit;
2387
2388 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002389
2390exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01002391 mbedtls_platform_zeroize( tmp, hash_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002392 return( status );
2393}
2394#endif /* MBEDTLS_MD_C */
2395
mohammad16036df908f2018-04-02 08:34:15 -07002396static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02002397 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002398 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002399{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02002400 if( ! operation->key_set )
2401 return( PSA_ERROR_BAD_STATE );
2402 if( operation->iv_required && ! operation->iv_set )
2403 return( PSA_ERROR_BAD_STATE );
2404
Gilles Peskine8c9def32018-02-08 10:02:12 +01002405 if( mac_size < operation->mac_size )
2406 return( PSA_ERROR_BUFFER_TOO_SMALL );
2407
Gilles Peskine8c9def32018-02-08 10:02:12 +01002408#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002409 if( operation->alg == PSA_ALG_CMAC )
2410 {
Gilles Peskined911eb72018-08-14 15:18:45 +02002411 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
2412 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
2413 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02002414 memcpy( mac, tmp, operation->mac_size );
Gilles Peskine3f108122018-12-07 18:14:53 +01002415 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002416 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002417 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02002418 else
2419#endif /* MBEDTLS_CMAC_C */
2420#if defined(MBEDTLS_MD_C)
2421 if( PSA_ALG_IS_HMAC( operation->alg ) )
2422 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002423 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02002424 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002425 }
2426 else
2427#endif /* MBEDTLS_MD_C */
2428 {
2429 /* This shouldn't happen if `operation` was initialized by
2430 * a setup function. */
2431 return( PSA_ERROR_BAD_STATE );
2432 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01002433}
2434
Gilles Peskineacd4be32018-07-08 19:56:25 +02002435psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
2436 uint8_t *mac,
2437 size_t mac_size,
2438 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07002439{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002440 psa_status_t status;
2441
Jaeden Amero252ef282019-02-15 14:05:35 +00002442 if( operation->alg == 0 )
2443 {
2444 return( PSA_ERROR_BAD_STATE );
2445 }
2446
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002447 /* Fill the output buffer with something that isn't a valid mac
2448 * (barring an attack on the mac and deliberately-crafted input),
2449 * in case the caller doesn't check the return status properly. */
2450 *mac_length = mac_size;
2451 /* If mac_size is 0 then mac may be NULL and then the
2452 * call to memset would have undefined behavior. */
2453 if( mac_size != 0 )
2454 memset( mac, '!', mac_size );
2455
Gilles Peskine89167cb2018-07-08 20:12:23 +02002456 if( ! operation->is_sign )
2457 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00002458 return( PSA_ERROR_BAD_STATE );
Gilles Peskine89167cb2018-07-08 20:12:23 +02002459 }
mohammad16036df908f2018-04-02 08:34:15 -07002460
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002461 status = psa_mac_finish_internal( operation, mac, mac_size );
2462
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002463 if( status == PSA_SUCCESS )
2464 {
2465 status = psa_mac_abort( operation );
2466 if( status == PSA_SUCCESS )
2467 *mac_length = operation->mac_size;
2468 else
2469 memset( mac, '!', mac_size );
2470 }
2471 else
2472 psa_mac_abort( operation );
2473 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07002474}
2475
Gilles Peskineacd4be32018-07-08 19:56:25 +02002476psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
2477 const uint8_t *mac,
2478 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002479{
Gilles Peskine828ed142018-06-18 23:25:51 +02002480 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07002481 psa_status_t status;
2482
Jaeden Amero252ef282019-02-15 14:05:35 +00002483 if( operation->alg == 0 )
2484 {
2485 return( PSA_ERROR_BAD_STATE );
2486 }
2487
Gilles Peskine89167cb2018-07-08 20:12:23 +02002488 if( operation->is_sign )
2489 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00002490 return( PSA_ERROR_BAD_STATE );
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002491 }
2492 if( operation->mac_size != mac_length )
2493 {
2494 status = PSA_ERROR_INVALID_SIGNATURE;
2495 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002496 }
mohammad16036df908f2018-04-02 08:34:15 -07002497
2498 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002499 actual_mac, sizeof( actual_mac ) );
2500
2501 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
2502 status = PSA_ERROR_INVALID_SIGNATURE;
2503
2504cleanup:
2505 if( status == PSA_SUCCESS )
2506 status = psa_mac_abort( operation );
2507 else
2508 psa_mac_abort( operation );
2509
Gilles Peskine3f108122018-12-07 18:14:53 +01002510 mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02002511
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002512 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002513}
2514
2515
Gilles Peskine20035e32018-02-03 22:44:14 +01002516
Gilles Peskine20035e32018-02-03 22:44:14 +01002517/****************************************************************/
2518/* Asymmetric cryptography */
2519/****************************************************************/
2520
Gilles Peskine2b450e32018-06-27 15:42:46 +02002521#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002522/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002523 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002524static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
2525 size_t hash_length,
2526 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002527{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02002528 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002529 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002530 *md_alg = mbedtls_md_get_type( md_info );
2531
2532 /* The Mbed TLS RSA module uses an unsigned int for hash length
2533 * parameters. Validate that it fits so that we don't risk an
2534 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002535#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002536 if( hash_length > UINT_MAX )
2537 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002538#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002539
2540#if defined(MBEDTLS_PKCS1_V15)
2541 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
2542 * must be correct. */
2543 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
2544 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002545 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002546 if( md_info == NULL )
2547 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002548 if( mbedtls_md_get_size( md_info ) != hash_length )
2549 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002550 }
2551#endif /* MBEDTLS_PKCS1_V15 */
2552
2553#if defined(MBEDTLS_PKCS1_V21)
2554 /* PSS requires a hash internally. */
2555 if( PSA_ALG_IS_RSA_PSS( alg ) )
2556 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002557 if( md_info == NULL )
2558 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002559 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002560#endif /* MBEDTLS_PKCS1_V21 */
2561
Gilles Peskine61b91d42018-06-08 16:09:36 +02002562 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002563}
2564
Gilles Peskine2b450e32018-06-27 15:42:46 +02002565static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
2566 psa_algorithm_t alg,
2567 const uint8_t *hash,
2568 size_t hash_length,
2569 uint8_t *signature,
2570 size_t signature_size,
2571 size_t *signature_length )
2572{
2573 psa_status_t status;
2574 int ret;
2575 mbedtls_md_type_t md_alg;
2576
2577 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2578 if( status != PSA_SUCCESS )
2579 return( status );
2580
Gilles Peskine630a18a2018-06-29 17:49:35 +02002581 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002582 return( PSA_ERROR_BUFFER_TOO_SMALL );
2583
2584#if defined(MBEDTLS_PKCS1_V15)
2585 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2586 {
2587 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2588 MBEDTLS_MD_NONE );
2589 ret = mbedtls_rsa_pkcs1_sign( rsa,
2590 mbedtls_ctr_drbg_random,
2591 &global_data.ctr_drbg,
2592 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002593 md_alg,
2594 (unsigned int) hash_length,
2595 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002596 signature );
2597 }
2598 else
2599#endif /* MBEDTLS_PKCS1_V15 */
2600#if defined(MBEDTLS_PKCS1_V21)
2601 if( PSA_ALG_IS_RSA_PSS( alg ) )
2602 {
2603 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2604 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
2605 mbedtls_ctr_drbg_random,
2606 &global_data.ctr_drbg,
2607 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002608 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002609 (unsigned int) hash_length,
2610 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002611 signature );
2612 }
2613 else
2614#endif /* MBEDTLS_PKCS1_V21 */
2615 {
2616 return( PSA_ERROR_INVALID_ARGUMENT );
2617 }
2618
2619 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002620 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002621 return( mbedtls_to_psa_error( ret ) );
2622}
2623
2624static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
2625 psa_algorithm_t alg,
2626 const uint8_t *hash,
2627 size_t hash_length,
2628 const uint8_t *signature,
2629 size_t signature_length )
2630{
2631 psa_status_t status;
2632 int ret;
2633 mbedtls_md_type_t md_alg;
2634
2635 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2636 if( status != PSA_SUCCESS )
2637 return( status );
2638
Gilles Peskine630a18a2018-06-29 17:49:35 +02002639 if( signature_length < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002640 return( PSA_ERROR_BUFFER_TOO_SMALL );
2641
2642#if defined(MBEDTLS_PKCS1_V15)
2643 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2644 {
2645 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2646 MBEDTLS_MD_NONE );
2647 ret = mbedtls_rsa_pkcs1_verify( rsa,
2648 mbedtls_ctr_drbg_random,
2649 &global_data.ctr_drbg,
2650 MBEDTLS_RSA_PUBLIC,
2651 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002652 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002653 hash,
2654 signature );
2655 }
2656 else
2657#endif /* MBEDTLS_PKCS1_V15 */
2658#if defined(MBEDTLS_PKCS1_V21)
2659 if( PSA_ALG_IS_RSA_PSS( alg ) )
2660 {
2661 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2662 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
2663 mbedtls_ctr_drbg_random,
2664 &global_data.ctr_drbg,
2665 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002666 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002667 (unsigned int) hash_length,
2668 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002669 signature );
2670 }
2671 else
2672#endif /* MBEDTLS_PKCS1_V21 */
2673 {
2674 return( PSA_ERROR_INVALID_ARGUMENT );
2675 }
Gilles Peskineef12c632018-09-13 20:37:48 +02002676
2677 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
2678 * the rest of the signature is invalid". This has little use in
2679 * practice and PSA doesn't report this distinction. */
2680 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
2681 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002682 return( mbedtls_to_psa_error( ret ) );
2683}
2684#endif /* MBEDTLS_RSA_C */
2685
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002686#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002687/* `ecp` cannot be const because `ecp->grp` needs to be non-const
2688 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
2689 * (even though these functions don't modify it). */
2690static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
2691 psa_algorithm_t alg,
2692 const uint8_t *hash,
2693 size_t hash_length,
2694 uint8_t *signature,
2695 size_t signature_size,
2696 size_t *signature_length )
2697{
2698 int ret;
2699 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002700 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002701 mbedtls_mpi_init( &r );
2702 mbedtls_mpi_init( &s );
2703
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002704 if( signature_size < 2 * curve_bytes )
2705 {
2706 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
2707 goto cleanup;
2708 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002709
Gilles Peskinea05219c2018-11-16 16:02:56 +01002710#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002711 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
2712 {
2713 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
2714 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2715 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2716 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
2717 hash, hash_length,
2718 md_alg ) );
2719 }
2720 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01002721#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002722 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01002723 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002724 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
2725 hash, hash_length,
2726 mbedtls_ctr_drbg_random,
2727 &global_data.ctr_drbg ) );
2728 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002729
2730 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
2731 signature,
2732 curve_bytes ) );
2733 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
2734 signature + curve_bytes,
2735 curve_bytes ) );
2736
2737cleanup:
2738 mbedtls_mpi_free( &r );
2739 mbedtls_mpi_free( &s );
2740 if( ret == 0 )
2741 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002742 return( mbedtls_to_psa_error( ret ) );
2743}
2744
2745static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2746 const uint8_t *hash,
2747 size_t hash_length,
2748 const uint8_t *signature,
2749 size_t signature_length )
2750{
2751 int ret;
2752 mbedtls_mpi r, s;
2753 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2754 mbedtls_mpi_init( &r );
2755 mbedtls_mpi_init( &s );
2756
2757 if( signature_length != 2 * curve_bytes )
2758 return( PSA_ERROR_INVALID_SIGNATURE );
2759
2760 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2761 signature,
2762 curve_bytes ) );
2763 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2764 signature + curve_bytes,
2765 curve_bytes ) );
2766
2767 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2768 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002769
2770cleanup:
2771 mbedtls_mpi_free( &r );
2772 mbedtls_mpi_free( &s );
2773 return( mbedtls_to_psa_error( ret ) );
2774}
2775#endif /* MBEDTLS_ECDSA_C */
2776
Gilles Peskinec5487a82018-12-03 18:08:14 +01002777psa_status_t psa_asymmetric_sign( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002778 psa_algorithm_t alg,
2779 const uint8_t *hash,
2780 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002781 uint8_t *signature,
2782 size_t signature_size,
2783 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002784{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002785 psa_key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002786 psa_status_t status;
2787
2788 *signature_length = signature_size;
2789
Gilles Peskinec5487a82018-12-03 18:08:14 +01002790 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002791 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002792 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002793 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002794 {
2795 status = PSA_ERROR_INVALID_ARGUMENT;
2796 goto exit;
2797 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002798
Gilles Peskine20035e32018-02-03 22:44:14 +01002799#if defined(MBEDTLS_RSA_C)
2800 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2801 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002802 status = psa_rsa_sign( slot->data.rsa,
2803 alg,
2804 hash, hash_length,
2805 signature, signature_size,
2806 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002807 }
2808 else
2809#endif /* defined(MBEDTLS_RSA_C) */
2810#if defined(MBEDTLS_ECP_C)
2811 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2812 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002813#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01002814 if(
2815#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
2816 PSA_ALG_IS_ECDSA( alg )
2817#else
2818 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
2819#endif
2820 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002821 status = psa_ecdsa_sign( slot->data.ecp,
2822 alg,
2823 hash, hash_length,
2824 signature, signature_size,
2825 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002826 else
2827#endif /* defined(MBEDTLS_ECDSA_C) */
2828 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002829 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002830 }
itayzafrir5c753392018-05-08 11:18:38 +03002831 }
2832 else
2833#endif /* defined(MBEDTLS_ECP_C) */
2834 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002835 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002836 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002837
2838exit:
2839 /* Fill the unused part of the output buffer (the whole buffer on error,
2840 * the trailing part on success) with something that isn't a valid mac
2841 * (barring an attack on the mac and deliberately-crafted input),
2842 * in case the caller doesn't check the return status properly. */
2843 if( status == PSA_SUCCESS )
2844 memset( signature + *signature_length, '!',
2845 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002846 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002847 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002848 /* If signature_size is 0 then we have nothing to do. We must not call
2849 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002850 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002851}
2852
Gilles Peskinec5487a82018-12-03 18:08:14 +01002853psa_status_t psa_asymmetric_verify( psa_key_handle_t handle,
itayzafrir5c753392018-05-08 11:18:38 +03002854 psa_algorithm_t alg,
2855 const uint8_t *hash,
2856 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002857 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002858 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002859{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002860 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002861 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002862
Gilles Peskinec5487a82018-12-03 18:08:14 +01002863 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002864 if( status != PSA_SUCCESS )
2865 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002866
Gilles Peskine61b91d42018-06-08 16:09:36 +02002867#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002868 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002869 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002870 return( psa_rsa_verify( slot->data.rsa,
2871 alg,
2872 hash, hash_length,
2873 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002874 }
2875 else
2876#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002877#if defined(MBEDTLS_ECP_C)
2878 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2879 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002880#if defined(MBEDTLS_ECDSA_C)
2881 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002882 return( psa_ecdsa_verify( slot->data.ecp,
2883 hash, hash_length,
2884 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002885 else
2886#endif /* defined(MBEDTLS_ECDSA_C) */
2887 {
2888 return( PSA_ERROR_INVALID_ARGUMENT );
2889 }
itayzafrir5c753392018-05-08 11:18:38 +03002890 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002891 else
2892#endif /* defined(MBEDTLS_ECP_C) */
2893 {
2894 return( PSA_ERROR_NOT_SUPPORTED );
2895 }
2896}
2897
Gilles Peskine072ac562018-06-30 00:21:29 +02002898#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2899static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2900 mbedtls_rsa_context *rsa )
2901{
2902 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2903 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2904 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2905 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2906}
2907#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2908
Gilles Peskinec5487a82018-12-03 18:08:14 +01002909psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002910 psa_algorithm_t alg,
2911 const uint8_t *input,
2912 size_t input_length,
2913 const uint8_t *salt,
2914 size_t salt_length,
2915 uint8_t *output,
2916 size_t output_size,
2917 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002918{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002919 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002920 psa_status_t status;
2921
Darryl Green5cc689a2018-07-24 15:34:10 +01002922 (void) input;
2923 (void) input_length;
2924 (void) salt;
2925 (void) output;
2926 (void) output_size;
2927
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002928 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002929
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002930 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2931 return( PSA_ERROR_INVALID_ARGUMENT );
2932
Gilles Peskinec5487a82018-12-03 18:08:14 +01002933 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002934 if( status != PSA_SUCCESS )
2935 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002936 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2937 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002938 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002939
2940#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002941 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002942 {
2943 mbedtls_rsa_context *rsa = slot->data.rsa;
2944 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002945 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002946 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002947#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002948 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002949 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002950 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2951 mbedtls_ctr_drbg_random,
2952 &global_data.ctr_drbg,
2953 MBEDTLS_RSA_PUBLIC,
2954 input_length,
2955 input,
2956 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002957 }
2958 else
2959#endif /* MBEDTLS_PKCS1_V15 */
2960#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002961 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002962 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002963 psa_rsa_oaep_set_padding_mode( alg, rsa );
2964 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2965 mbedtls_ctr_drbg_random,
2966 &global_data.ctr_drbg,
2967 MBEDTLS_RSA_PUBLIC,
2968 salt, salt_length,
2969 input_length,
2970 input,
2971 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002972 }
2973 else
2974#endif /* MBEDTLS_PKCS1_V21 */
2975 {
2976 return( PSA_ERROR_INVALID_ARGUMENT );
2977 }
2978 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002979 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002980 return( mbedtls_to_psa_error( ret ) );
2981 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002982 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002983#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002984 {
2985 return( PSA_ERROR_NOT_SUPPORTED );
2986 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002987}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002988
Gilles Peskinec5487a82018-12-03 18:08:14 +01002989psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002990 psa_algorithm_t alg,
2991 const uint8_t *input,
2992 size_t input_length,
2993 const uint8_t *salt,
2994 size_t salt_length,
2995 uint8_t *output,
2996 size_t output_size,
2997 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002998{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002999 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003000 psa_status_t status;
3001
Darryl Green5cc689a2018-07-24 15:34:10 +01003002 (void) input;
3003 (void) input_length;
3004 (void) salt;
3005 (void) output;
3006 (void) output_size;
3007
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03003008 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003009
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02003010 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
3011 return( PSA_ERROR_INVALID_ARGUMENT );
3012
Gilles Peskinec5487a82018-12-03 18:08:14 +01003013 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003014 if( status != PSA_SUCCESS )
3015 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003016 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
3017 return( PSA_ERROR_INVALID_ARGUMENT );
3018
3019#if defined(MBEDTLS_RSA_C)
3020 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
3021 {
3022 mbedtls_rsa_context *rsa = slot->data.rsa;
3023 int ret;
3024
Gilles Peskine630a18a2018-06-29 17:49:35 +02003025 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003026 return( PSA_ERROR_INVALID_ARGUMENT );
3027
3028#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02003029 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003030 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02003031 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
3032 mbedtls_ctr_drbg_random,
3033 &global_data.ctr_drbg,
3034 MBEDTLS_RSA_PRIVATE,
3035 output_length,
3036 input,
3037 output,
3038 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003039 }
3040 else
3041#endif /* MBEDTLS_PKCS1_V15 */
3042#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02003043 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003044 {
Gilles Peskine072ac562018-06-30 00:21:29 +02003045 psa_rsa_oaep_set_padding_mode( alg, rsa );
3046 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
3047 mbedtls_ctr_drbg_random,
3048 &global_data.ctr_drbg,
3049 MBEDTLS_RSA_PRIVATE,
3050 salt, salt_length,
3051 output_length,
3052 input,
3053 output,
3054 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003055 }
3056 else
3057#endif /* MBEDTLS_PKCS1_V21 */
3058 {
3059 return( PSA_ERROR_INVALID_ARGUMENT );
3060 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03003061
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003062 return( mbedtls_to_psa_error( ret ) );
3063 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003064 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02003065#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03003066 {
3067 return( PSA_ERROR_NOT_SUPPORTED );
3068 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003069}
Gilles Peskine20035e32018-02-03 22:44:14 +01003070
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003071
3072
mohammad1603503973b2018-03-12 15:59:30 +02003073/****************************************************************/
3074/* Symmetric cryptography */
3075/****************************************************************/
3076
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003077/* Initialize the cipher operation structure. Once this function has been
3078 * called, psa_cipher_abort can run and will do the right thing. */
3079static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
3080 psa_algorithm_t alg )
3081{
Gilles Peskinec06e0712018-06-20 16:21:04 +02003082 if( ! PSA_ALG_IS_CIPHER( alg ) )
3083 {
3084 memset( operation, 0, sizeof( *operation ) );
3085 return( PSA_ERROR_INVALID_ARGUMENT );
3086 }
3087
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003088 operation->alg = alg;
3089 operation->key_set = 0;
3090 operation->iv_set = 0;
3091 operation->iv_required = 1;
3092 operation->iv_size = 0;
3093 operation->block_size = 0;
3094 mbedtls_cipher_init( &operation->ctx.cipher );
3095 return( PSA_SUCCESS );
3096}
3097
Gilles Peskinee553c652018-06-04 16:22:46 +02003098static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003099 psa_key_handle_t handle,
Gilles Peskine7e928852018-06-04 16:23:10 +02003100 psa_algorithm_t alg,
3101 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02003102{
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003103 int ret = 0;
3104 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Gilles Peskine2f060a82018-12-04 17:12:32 +01003105 psa_key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02003106 size_t key_bits;
3107 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003108 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
3109 PSA_KEY_USAGE_ENCRYPT :
3110 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02003111
Jaeden Amero36ee5d02019-02-19 09:25:10 +00003112 /* A context must be freshly initialized before it can be set up. */
3113 if( operation->alg != 0 )
3114 {
3115 return( PSA_ERROR_BAD_STATE );
3116 }
3117
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003118 status = psa_cipher_init( operation, alg );
3119 if( status != PSA_SUCCESS )
3120 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003121
Gilles Peskinec5487a82018-12-03 18:08:14 +01003122 status = psa_get_key_from_slot( handle, &slot, usage, alg);
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003123 if( status != PSA_SUCCESS )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003124 goto exit;
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02003125 key_bits = psa_get_key_slot_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02003126
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02003127 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02003128 if( cipher_info == NULL )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003129 {
3130 status = PSA_ERROR_NOT_SUPPORTED;
3131 goto exit;
3132 }
mohammad1603503973b2018-03-12 15:59:30 +02003133
mohammad1603503973b2018-03-12 15:59:30 +02003134 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03003135 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003136 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02003137
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003138#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02003139 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003140 {
3141 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
3142 unsigned char keys[24];
3143 memcpy( keys, slot->data.raw.data, 16 );
3144 memcpy( keys + 16, slot->data.raw.data, 8 );
3145 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
3146 keys,
3147 192, cipher_operation );
3148 }
3149 else
3150#endif
3151 {
3152 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
3153 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01003154 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02003155 }
Moran Peker41deec42018-04-04 15:43:05 +03003156 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003157 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02003158
mohammad16038481e742018-03-18 13:57:31 +02003159#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003160 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02003161 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003162 case PSA_ALG_CBC_NO_PADDING:
3163 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
3164 MBEDTLS_PADDING_NONE );
3165 break;
3166 case PSA_ALG_CBC_PKCS7:
3167 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
3168 MBEDTLS_PADDING_PKCS7 );
3169 break;
3170 default:
3171 /* The algorithm doesn't involve padding. */
3172 ret = 0;
3173 break;
3174 }
3175 if( ret != 0 )
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003176 goto exit;
mohammad16038481e742018-03-18 13:57:31 +02003177#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
3178
mohammad1603503973b2018-03-12 15:59:30 +02003179 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003180 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
3181 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
3182 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02003183 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02003184 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02003185 }
mohammad1603503973b2018-03-12 15:59:30 +02003186
Gilles Peskine9ab61b62019-02-25 17:43:14 +01003187exit:
3188 if( status == 0 )
3189 status = mbedtls_to_psa_error( ret );
3190 if( status != 0 )
3191 psa_cipher_abort( operation );
3192 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003193}
3194
Gilles Peskinefe119512018-07-08 21:39:34 +02003195psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003196 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02003197 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02003198{
Gilles Peskinec5487a82018-12-03 18:08:14 +01003199 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02003200}
3201
Gilles Peskinefe119512018-07-08 21:39:34 +02003202psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003203 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02003204 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02003205{
Gilles Peskinec5487a82018-12-03 18:08:14 +01003206 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02003207}
3208
Gilles Peskinefe119512018-07-08 21:39:34 +02003209psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
3210 unsigned char *iv,
3211 size_t iv_size,
3212 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02003213{
itayzafrir534bd7c2018-08-02 13:56:32 +03003214 psa_status_t status;
3215 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003216 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03003217 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003218 return( PSA_ERROR_BAD_STATE );
itayzafrir534bd7c2018-08-02 13:56:32 +03003219 }
Moran Peker41deec42018-04-04 15:43:05 +03003220 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02003221 {
itayzafrir534bd7c2018-08-02 13:56:32 +03003222 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03003223 goto exit;
3224 }
Gilles Peskine7e928852018-06-04 16:23:10 +02003225 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
3226 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03003227 if( ret != 0 )
3228 {
itayzafrir534bd7c2018-08-02 13:56:32 +03003229 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02003230 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02003231 }
Gilles Peskinee553c652018-06-04 16:22:46 +02003232
mohammad16038481e742018-03-18 13:57:31 +02003233 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03003234 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03003235
Moran Peker395db872018-05-31 14:07:14 +03003236exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03003237 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03003238 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03003239 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003240}
3241
Gilles Peskinefe119512018-07-08 21:39:34 +02003242psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
3243 const unsigned char *iv,
3244 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02003245{
itayzafrir534bd7c2018-08-02 13:56:32 +03003246 psa_status_t status;
3247 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003248 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03003249 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003250 return( PSA_ERROR_BAD_STATE );
itayzafrir534bd7c2018-08-02 13:56:32 +03003251 }
Moran Pekera28258c2018-05-29 16:25:04 +03003252 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03003253 {
itayzafrir534bd7c2018-08-02 13:56:32 +03003254 status = PSA_ERROR_INVALID_ARGUMENT;
3255 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03003256 }
itayzafrir534bd7c2018-08-02 13:56:32 +03003257 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
3258 status = mbedtls_to_psa_error( ret );
3259exit:
3260 if( status == PSA_SUCCESS )
3261 operation->iv_set = 1;
3262 else
mohammad1603503973b2018-03-12 15:59:30 +02003263 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03003264 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003265}
3266
Gilles Peskinee553c652018-06-04 16:22:46 +02003267psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
3268 const uint8_t *input,
3269 size_t input_length,
3270 unsigned char *output,
3271 size_t output_size,
3272 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02003273{
itayzafrir534bd7c2018-08-02 13:56:32 +03003274 psa_status_t status;
3275 int ret;
Gilles Peskine89d789c2018-06-04 17:17:16 +02003276 size_t expected_output_size;
Jaeden Ameroab439972019-02-15 14:12:05 +00003277
3278 if( operation->alg == 0 )
3279 {
3280 return( PSA_ERROR_BAD_STATE );
3281 }
3282
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003283 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02003284 {
3285 /* Take the unprocessed partial block left over from previous
3286 * update calls, if any, plus the input to this call. Remove
3287 * the last partial block, if any. You get the data that will be
3288 * output in this call. */
3289 expected_output_size =
3290 ( operation->ctx.cipher.unprocessed_len + input_length )
3291 / operation->block_size * operation->block_size;
3292 }
3293 else
3294 {
3295 expected_output_size = input_length;
3296 }
itayzafrir534bd7c2018-08-02 13:56:32 +03003297
Gilles Peskine89d789c2018-06-04 17:17:16 +02003298 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03003299 {
3300 status = PSA_ERROR_BUFFER_TOO_SMALL;
3301 goto exit;
3302 }
mohammad160382759612018-03-12 18:16:40 +02003303
mohammad1603503973b2018-03-12 15:59:30 +02003304 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02003305 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03003306 status = mbedtls_to_psa_error( ret );
3307exit:
3308 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02003309 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03003310 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003311}
3312
Gilles Peskinee553c652018-06-04 16:22:46 +02003313psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
3314 uint8_t *output,
3315 size_t output_size,
3316 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02003317{
David Saadab4ecc272019-02-14 13:48:10 +02003318 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
Janos Follath315b51c2018-07-09 16:04:51 +01003319 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02003320 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03003321
mohammad1603503973b2018-03-12 15:59:30 +02003322 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03003323 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003324 return( PSA_ERROR_BAD_STATE );
Moran Peker7cb22b82018-06-05 11:40:02 +03003325 }
3326 if( operation->iv_required && ! operation->iv_set )
3327 {
Jaeden Ameroe236c2a2019-02-20 15:37:15 +00003328 return( PSA_ERROR_BAD_STATE );
Moran Peker7cb22b82018-06-05 11:40:02 +03003329 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003330
Gilles Peskine2c5219a2018-06-06 15:12:32 +02003331 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003332 operation->alg == PSA_ALG_CBC_NO_PADDING &&
3333 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03003334 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02003335 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01003336 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03003337 }
3338
Janos Follath315b51c2018-07-09 16:04:51 +01003339 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
3340 temp_output_buffer,
3341 output_length );
3342 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02003343 {
Janos Follath315b51c2018-07-09 16:04:51 +01003344 status = mbedtls_to_psa_error( cipher_ret );
3345 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02003346 }
Janos Follath315b51c2018-07-09 16:04:51 +01003347
Gilles Peskine46f1fd72018-06-28 19:31:31 +02003348 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01003349 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02003350 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03003351 memcpy( output, temp_output_buffer, *output_length );
3352 else
3353 {
Janos Follath315b51c2018-07-09 16:04:51 +01003354 status = PSA_ERROR_BUFFER_TOO_SMALL;
3355 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03003356 }
mohammad1603503973b2018-03-12 15:59:30 +02003357
Gilles Peskine3f108122018-12-07 18:14:53 +01003358 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01003359 status = psa_cipher_abort( operation );
3360
3361 return( status );
3362
3363error:
3364
3365 *output_length = 0;
3366
Gilles Peskine3f108122018-12-07 18:14:53 +01003367 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01003368 (void) psa_cipher_abort( operation );
3369
3370 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02003371}
3372
Gilles Peskinee553c652018-06-04 16:22:46 +02003373psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
3374{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003375 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02003376 {
3377 /* The object has (apparently) been initialized but it is not
3378 * in use. It's ok to call abort on such an object, and there's
3379 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003380 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02003381 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02003382
Gilles Peskinef9c2c092018-06-21 16:57:07 +02003383 /* Sanity check (shouldn't happen: operation->alg should
3384 * always have been initialized to a valid value). */
3385 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
3386 return( PSA_ERROR_BAD_STATE );
3387
mohammad1603503973b2018-03-12 15:59:30 +02003388 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02003389
Moran Peker41deec42018-04-04 15:43:05 +03003390 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03003391 operation->key_set = 0;
3392 operation->iv_set = 0;
3393 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03003394 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03003395 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03003396
Moran Peker395db872018-05-31 14:07:14 +03003397 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02003398}
3399
Gilles Peskinea0655c32018-04-30 17:06:50 +02003400
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003401
mohammad16038cc1cee2018-03-28 01:21:33 +03003402/****************************************************************/
3403/* Key Policy */
3404/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003405
mohammad160327010052018-07-03 13:16:15 +03003406#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02003407void psa_key_policy_set_usage( psa_key_policy_t *policy,
3408 psa_key_usage_t usage,
3409 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03003410{
mohammad16034eed7572018-03-28 05:14:59 -07003411 policy->usage = usage;
3412 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03003413}
3414
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003415psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003416{
mohammad16036df908f2018-04-02 08:34:15 -07003417 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03003418}
3419
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003420psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003421{
mohammad16036df908f2018-04-02 08:34:15 -07003422 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03003423}
mohammad160327010052018-07-03 13:16:15 +03003424#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003425
Gilles Peskinec5487a82018-12-03 18:08:14 +01003426psa_status_t psa_set_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003427 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003428{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003429 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003430 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003431
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003432 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003433 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003434
Gilles Peskinec5487a82018-12-03 18:08:14 +01003435 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003436 if( status != PSA_SUCCESS )
3437 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03003438
Gilles Peskine4747d192019-04-17 15:05:45 +02003439 return( psa_set_key_policy_internal( slot, policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03003440}
3441
Gilles Peskinec5487a82018-12-03 18:08:14 +01003442psa_status_t psa_get_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003443 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003444{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003445 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003446 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003447
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003448 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003449 return( PSA_ERROR_INVALID_ARGUMENT );
3450
Gilles Peskinec5487a82018-12-03 18:08:14 +01003451 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003452 if( status != PSA_SUCCESS )
3453 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003454
mohammad16036df908f2018-04-02 08:34:15 -07003455 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003456
3457 return( PSA_SUCCESS );
3458}
Gilles Peskine20035e32018-02-03 22:44:14 +01003459
Gilles Peskinea0655c32018-04-30 17:06:50 +02003460
3461
mohammad1603804cd712018-03-20 22:44:08 +02003462/****************************************************************/
3463/* Key Lifetime */
3464/****************************************************************/
3465
Gilles Peskine87a5e562019-04-17 12:28:25 +02003466psa_status_t psa_get_key_lifetime_from_handle( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003467 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003468{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003469 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003470 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003471
Gilles Peskinec5487a82018-12-03 18:08:14 +01003472 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003473 if( status != PSA_SUCCESS )
3474 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003475
mohammad1603804cd712018-03-20 22:44:08 +02003476 *lifetime = slot->lifetime;
3477
3478 return( PSA_SUCCESS );
3479}
3480
Gilles Peskine20035e32018-02-03 22:44:14 +01003481
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003482
mohammad16035955c982018-04-26 00:53:03 +03003483/****************************************************************/
3484/* AEAD */
3485/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003486
Gilles Peskineedf9a652018-08-17 18:11:56 +02003487typedef struct
3488{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003489 psa_key_slot_t *slot;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003490 const mbedtls_cipher_info_t *cipher_info;
3491 union
3492 {
3493#if defined(MBEDTLS_CCM_C)
3494 mbedtls_ccm_context ccm;
3495#endif /* MBEDTLS_CCM_C */
3496#if defined(MBEDTLS_GCM_C)
3497 mbedtls_gcm_context gcm;
3498#endif /* MBEDTLS_GCM_C */
3499 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003500 psa_algorithm_t core_alg;
3501 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003502 uint8_t tag_length;
3503} aead_operation_t;
3504
Gilles Peskine30a9e412019-01-14 18:36:12 +01003505static void psa_aead_abort_internal( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003506{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003507 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003508 {
3509#if defined(MBEDTLS_CCM_C)
3510 case PSA_ALG_CCM:
3511 mbedtls_ccm_free( &operation->ctx.ccm );
3512 break;
3513#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003514#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02003515 case PSA_ALG_GCM:
3516 mbedtls_gcm_free( &operation->ctx.gcm );
3517 break;
3518#endif /* MBEDTLS_GCM_C */
3519 }
3520}
3521
3522static psa_status_t psa_aead_setup( aead_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003523 psa_key_handle_t handle,
Gilles Peskineedf9a652018-08-17 18:11:56 +02003524 psa_key_usage_t usage,
3525 psa_algorithm_t alg )
3526{
3527 psa_status_t status;
3528 size_t key_bits;
3529 mbedtls_cipher_id_t cipher_id;
3530
Gilles Peskinec5487a82018-12-03 18:08:14 +01003531 status = psa_get_key_from_slot( handle, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003532 if( status != PSA_SUCCESS )
3533 return( status );
3534
Gilles Peskinedb4b3ab2019-04-18 12:53:01 +02003535 key_bits = psa_get_key_slot_bits( operation->slot );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003536
3537 operation->cipher_info =
3538 mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
3539 &cipher_id );
3540 if( operation->cipher_info == NULL )
3541 return( PSA_ERROR_NOT_SUPPORTED );
3542
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003543 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003544 {
3545#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003546 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
3547 operation->core_alg = PSA_ALG_CCM;
3548 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003549 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3550 return( PSA_ERROR_INVALID_ARGUMENT );
3551 mbedtls_ccm_init( &operation->ctx.ccm );
3552 status = mbedtls_to_psa_error(
3553 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
3554 operation->slot->data.raw.data,
3555 (unsigned int) key_bits ) );
3556 if( status != 0 )
3557 goto cleanup;
3558 break;
3559#endif /* MBEDTLS_CCM_C */
3560
3561#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003562 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
3563 operation->core_alg = PSA_ALG_GCM;
3564 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003565 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3566 return( PSA_ERROR_INVALID_ARGUMENT );
3567 mbedtls_gcm_init( &operation->ctx.gcm );
3568 status = mbedtls_to_psa_error(
3569 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
3570 operation->slot->data.raw.data,
3571 (unsigned int) key_bits ) );
3572 break;
3573#endif /* MBEDTLS_GCM_C */
3574
3575 default:
3576 return( PSA_ERROR_NOT_SUPPORTED );
3577 }
3578
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003579 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
3580 {
3581 status = PSA_ERROR_INVALID_ARGUMENT;
3582 goto cleanup;
3583 }
3584 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
3585 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
3586 * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
3587 * In both cases, mbedtls_xxx will validate the tag length below. */
3588
Gilles Peskineedf9a652018-08-17 18:11:56 +02003589 return( PSA_SUCCESS );
3590
3591cleanup:
Gilles Peskine30a9e412019-01-14 18:36:12 +01003592 psa_aead_abort_internal( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003593 return( status );
3594}
3595
Gilles Peskinec5487a82018-12-03 18:08:14 +01003596psa_status_t psa_aead_encrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003597 psa_algorithm_t alg,
3598 const uint8_t *nonce,
3599 size_t nonce_length,
3600 const uint8_t *additional_data,
3601 size_t additional_data_length,
3602 const uint8_t *plaintext,
3603 size_t plaintext_length,
3604 uint8_t *ciphertext,
3605 size_t ciphertext_size,
3606 size_t *ciphertext_length )
3607{
mohammad16035955c982018-04-26 00:53:03 +03003608 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003609 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03003610 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02003611
mohammad1603f08a5502018-06-03 15:05:47 +03003612 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003613
Gilles Peskinec5487a82018-12-03 18:08:14 +01003614 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003615 if( status != PSA_SUCCESS )
3616 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003617
Gilles Peskineedf9a652018-08-17 18:11:56 +02003618 /* For all currently supported modes, the tag is at the end of the
3619 * ciphertext. */
3620 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
3621 {
3622 status = PSA_ERROR_BUFFER_TOO_SMALL;
3623 goto exit;
3624 }
3625 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03003626
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003627#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003628 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003629 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003630 status = mbedtls_to_psa_error(
3631 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
3632 MBEDTLS_GCM_ENCRYPT,
3633 plaintext_length,
3634 nonce, nonce_length,
3635 additional_data, additional_data_length,
3636 plaintext, ciphertext,
3637 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03003638 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003639 else
3640#endif /* MBEDTLS_GCM_C */
3641#if defined(MBEDTLS_CCM_C)
3642 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003643 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003644 status = mbedtls_to_psa_error(
3645 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
3646 plaintext_length,
3647 nonce, nonce_length,
3648 additional_data,
3649 additional_data_length,
3650 plaintext, ciphertext,
3651 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003652 }
mohammad16035c8845f2018-05-09 05:40:09 -07003653 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003654#endif /* MBEDTLS_CCM_C */
mohammad16035c8845f2018-05-09 05:40:09 -07003655 {
mohammad1603554faad2018-06-03 15:07:38 +03003656 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07003657 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003658
Gilles Peskineedf9a652018-08-17 18:11:56 +02003659 if( status != PSA_SUCCESS && ciphertext_size != 0 )
3660 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003661
Gilles Peskineedf9a652018-08-17 18:11:56 +02003662exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01003663 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003664 if( status == PSA_SUCCESS )
3665 *ciphertext_length = plaintext_length + operation.tag_length;
3666 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003667}
3668
Gilles Peskineee652a32018-06-01 19:23:52 +02003669/* Locate the tag in a ciphertext buffer containing the encrypted data
3670 * followed by the tag. Return the length of the part preceding the tag in
3671 * *plaintext_length. This is the size of the plaintext in modes where
3672 * the encrypted data has the same size as the plaintext, such as
3673 * CCM and GCM. */
3674static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
3675 const uint8_t *ciphertext,
3676 size_t ciphertext_length,
3677 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02003678 const uint8_t **p_tag )
3679{
3680 size_t payload_length;
3681 if( tag_length > ciphertext_length )
3682 return( PSA_ERROR_INVALID_ARGUMENT );
3683 payload_length = ciphertext_length - tag_length;
3684 if( payload_length > plaintext_size )
3685 return( PSA_ERROR_BUFFER_TOO_SMALL );
3686 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02003687 return( PSA_SUCCESS );
3688}
3689
Gilles Peskinec5487a82018-12-03 18:08:14 +01003690psa_status_t psa_aead_decrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003691 psa_algorithm_t alg,
3692 const uint8_t *nonce,
3693 size_t nonce_length,
3694 const uint8_t *additional_data,
3695 size_t additional_data_length,
3696 const uint8_t *ciphertext,
3697 size_t ciphertext_length,
3698 uint8_t *plaintext,
3699 size_t plaintext_size,
3700 size_t *plaintext_length )
3701{
mohammad16035955c982018-04-26 00:53:03 +03003702 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003703 aead_operation_t operation;
3704 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02003705
Gilles Peskineee652a32018-06-01 19:23:52 +02003706 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003707
Gilles Peskinec5487a82018-12-03 18:08:14 +01003708 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003709 if( status != PSA_SUCCESS )
3710 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003711
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003712#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003713 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003714 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003715 status = psa_aead_unpadded_locate_tag( operation.tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003716 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003717 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02003718 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003719 goto exit;
Gilles Peskineee652a32018-06-01 19:23:52 +02003720
Gilles Peskineedf9a652018-08-17 18:11:56 +02003721 status = mbedtls_to_psa_error(
3722 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
3723 ciphertext_length - operation.tag_length,
3724 nonce, nonce_length,
3725 additional_data,
3726 additional_data_length,
3727 tag, operation.tag_length,
3728 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03003729 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003730 else
3731#endif /* MBEDTLS_GCM_C */
3732#if defined(MBEDTLS_CCM_C)
3733 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003734 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003735 status = psa_aead_unpadded_locate_tag( operation.tag_length,
mohammad16039375f842018-06-03 14:28:24 +03003736 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003737 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003738 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003739 goto exit;
mohammad16039375f842018-06-03 14:28:24 +03003740
Gilles Peskineedf9a652018-08-17 18:11:56 +02003741 status = mbedtls_to_psa_error(
3742 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
3743 ciphertext_length - operation.tag_length,
3744 nonce, nonce_length,
3745 additional_data,
3746 additional_data_length,
3747 ciphertext, plaintext,
3748 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003749 }
mohammad160339574652018-06-01 04:39:53 -07003750 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003751#endif /* MBEDTLS_CCM_C */
mohammad160339574652018-06-01 04:39:53 -07003752 {
mohammad1603554faad2018-06-03 15:07:38 +03003753 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003754 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003755
Gilles Peskineedf9a652018-08-17 18:11:56 +02003756 if( status != PSA_SUCCESS && plaintext_size != 0 )
3757 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03003758
Gilles Peskineedf9a652018-08-17 18:11:56 +02003759exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01003760 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003761 if( status == PSA_SUCCESS )
3762 *plaintext_length = ciphertext_length - operation.tag_length;
3763 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003764}
3765
Gilles Peskinea0655c32018-04-30 17:06:50 +02003766
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003767
Gilles Peskine20035e32018-02-03 22:44:14 +01003768/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003769/* Generators */
3770/****************************************************************/
3771
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003772#define HKDF_STATE_INIT 0 /* no input yet */
3773#define HKDF_STATE_STARTED 1 /* got salt */
3774#define HKDF_STATE_KEYED 2 /* got key */
3775#define HKDF_STATE_OUTPUT 3 /* output started */
3776
Gilles Peskine969c5d62019-01-16 15:53:06 +01003777static psa_algorithm_t psa_generator_get_kdf_alg(
3778 const psa_crypto_generator_t *generator )
3779{
3780 if ( PSA_ALG_IS_KEY_AGREEMENT( generator->alg ) )
3781 return( PSA_ALG_KEY_AGREEMENT_GET_KDF( generator->alg ) );
3782 else
3783 return( generator->alg );
3784}
3785
3786
Gilles Peskineeab56e42018-07-12 17:12:33 +02003787psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3788{
3789 psa_status_t status = PSA_SUCCESS;
Gilles Peskine969c5d62019-01-16 15:53:06 +01003790 psa_algorithm_t kdf_alg = psa_generator_get_kdf_alg( generator );
3791 if( kdf_alg == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02003792 {
3793 /* The object has (apparently) been initialized but it is not
3794 * in use. It's ok to call abort on such an object, and there's
3795 * nothing to do. */
3796 }
3797 else
Gilles Peskine969c5d62019-01-16 15:53:06 +01003798 if( kdf_alg == PSA_ALG_SELECT_RAW )
Gilles Peskine751d9652018-09-18 12:05:44 +02003799 {
3800 if( generator->ctx.buffer.data != NULL )
3801 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003802 mbedtls_platform_zeroize( generator->ctx.buffer.data,
Gilles Peskine751d9652018-09-18 12:05:44 +02003803 generator->ctx.buffer.size );
3804 mbedtls_free( generator->ctx.buffer.data );
3805 }
3806 }
3807 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003808#if defined(MBEDTLS_MD_C)
Gilles Peskine969c5d62019-01-16 15:53:06 +01003809 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003810 {
3811 mbedtls_free( generator->ctx.hkdf.info );
3812 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3813 }
Gilles Peskine969c5d62019-01-16 15:53:06 +01003814 else if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
Hanno Becker1aaedc02018-11-16 11:35:34 +00003815 /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
Gilles Peskine969c5d62019-01-16 15:53:06 +01003816 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003817 {
3818 if( generator->ctx.tls12_prf.key != NULL )
3819 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003820 mbedtls_platform_zeroize( generator->ctx.tls12_prf.key,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003821 generator->ctx.tls12_prf.key_len );
3822 mbedtls_free( generator->ctx.tls12_prf.key );
3823 }
Hanno Becker580fba12018-11-13 20:50:45 +00003824
3825 if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
3826 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003827 mbedtls_platform_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003828 generator->ctx.tls12_prf.Ai_with_seed_len );
3829 mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
3830 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003831 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003832 else
3833#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003834 {
3835 status = PSA_ERROR_BAD_STATE;
3836 }
3837 memset( generator, 0, sizeof( *generator ) );
3838 return( status );
3839}
3840
Gilles Peskineeab56e42018-07-12 17:12:33 +02003841psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3842 size_t *capacity)
3843{
Jaeden Amerocf2010c2019-02-15 13:05:49 +00003844 if( generator->alg == 0 )
3845 {
3846 /* This is a blank generator. */
3847 return PSA_ERROR_BAD_STATE;
3848 }
3849
Gilles Peskineeab56e42018-07-12 17:12:33 +02003850 *capacity = generator->capacity;
3851 return( PSA_SUCCESS );
3852}
3853
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003854psa_status_t psa_set_generator_capacity( psa_crypto_generator_t *generator,
3855 size_t capacity )
3856{
3857 if( generator->alg == 0 )
3858 return( PSA_ERROR_BAD_STATE );
3859 if( capacity > generator->capacity )
3860 return( PSA_ERROR_INVALID_ARGUMENT );
3861 generator->capacity = capacity;
3862 return( PSA_SUCCESS );
3863}
3864
Gilles Peskinebef7f142018-07-12 17:22:21 +02003865#if defined(MBEDTLS_MD_C)
3866/* Read some bytes from an HKDF-based generator. This performs a chunk
3867 * of the expand phase of the HKDF algorithm. */
3868static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3869 psa_algorithm_t hash_alg,
3870 uint8_t *output,
3871 size_t output_length )
3872{
3873 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3874 psa_status_t status;
3875
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01003876 if( hkdf->state < HKDF_STATE_KEYED || ! hkdf->info_set )
3877 return( PSA_ERROR_BAD_STATE );
3878 hkdf->state = HKDF_STATE_OUTPUT;
3879
Gilles Peskinebef7f142018-07-12 17:22:21 +02003880 while( output_length != 0 )
3881 {
3882 /* Copy what remains of the current block */
3883 uint8_t n = hash_length - hkdf->offset_in_block;
3884 if( n > output_length )
3885 n = (uint8_t) output_length;
3886 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3887 output += n;
3888 output_length -= n;
3889 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003890 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003891 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003892 /* We can't be wanting more output after block 0xff, otherwise
3893 * the capacity check in psa_generator_read() would have
3894 * prevented this call. It could happen only if the generator
3895 * object was corrupted or if this function is called directly
3896 * inside the library. */
3897 if( hkdf->block_number == 0xff )
3898 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003899
3900 /* We need a new block */
3901 ++hkdf->block_number;
3902 hkdf->offset_in_block = 0;
3903 status = psa_hmac_setup_internal( &hkdf->hmac,
3904 hkdf->prk, hash_length,
3905 hash_alg );
3906 if( status != PSA_SUCCESS )
3907 return( status );
3908 if( hkdf->block_number != 1 )
3909 {
3910 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3911 hkdf->output_block,
3912 hash_length );
3913 if( status != PSA_SUCCESS )
3914 return( status );
3915 }
3916 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3917 hkdf->info,
3918 hkdf->info_length );
3919 if( status != PSA_SUCCESS )
3920 return( status );
3921 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3922 &hkdf->block_number, 1 );
3923 if( status != PSA_SUCCESS )
3924 return( status );
3925 status = psa_hmac_finish_internal( &hkdf->hmac,
3926 hkdf->output_block,
3927 sizeof( hkdf->output_block ) );
3928 if( status != PSA_SUCCESS )
3929 return( status );
3930 }
3931
3932 return( PSA_SUCCESS );
3933}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003934
3935static psa_status_t psa_generator_tls12_prf_generate_next_block(
3936 psa_tls12_prf_generator_t *tls12_prf,
3937 psa_algorithm_t alg )
3938{
3939 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3940 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3941 psa_hmac_internal_data hmac;
3942 psa_status_t status, cleanup_status;
3943
Hanno Becker3b339e22018-11-13 20:56:14 +00003944 unsigned char *Ai;
3945 size_t Ai_len;
3946
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003947 /* We can't be wanting more output after block 0xff, otherwise
3948 * the capacity check in psa_generator_read() would have
3949 * prevented this call. It could happen only if the generator
3950 * object was corrupted or if this function is called directly
3951 * inside the library. */
3952 if( tls12_prf->block_number == 0xff )
3953 return( PSA_ERROR_BAD_STATE );
3954
3955 /* We need a new block */
3956 ++tls12_prf->block_number;
3957 tls12_prf->offset_in_block = 0;
3958
3959 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3960 *
3961 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3962 *
3963 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3964 * HMAC_hash(secret, A(2) + seed) +
3965 * HMAC_hash(secret, A(3) + seed) + ...
3966 *
3967 * A(0) = seed
3968 * A(i) = HMAC_hash( secret, A(i-1) )
3969 *
3970 * The `psa_tls12_prf_generator` structures saves the block
3971 * `HMAC_hash(secret, A(i) + seed)` from which the output
3972 * is currently extracted as `output_block`, while
3973 * `A(i) + seed` is stored in `Ai_with_seed`.
3974 *
3975 * Generating a new block means recalculating `Ai_with_seed`
3976 * from the A(i)-part of it, and afterwards recalculating
3977 * `output_block`.
3978 *
3979 * A(0) is computed at setup time.
3980 *
3981 */
3982
3983 psa_hmac_init_internal( &hmac );
3984
3985 /* We must distinguish the calculation of A(1) from those
3986 * of A(2) and higher, because A(0)=seed has a different
3987 * length than the other A(i). */
3988 if( tls12_prf->block_number == 1 )
3989 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003990 Ai = tls12_prf->Ai_with_seed + hash_length;
3991 Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003992 }
3993 else
3994 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003995 Ai = tls12_prf->Ai_with_seed;
3996 Ai_len = hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003997 }
3998
Hanno Becker3b339e22018-11-13 20:56:14 +00003999 /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
4000 status = psa_hmac_setup_internal( &hmac,
4001 tls12_prf->key,
4002 tls12_prf->key_len,
4003 hash_alg );
4004 if( status != PSA_SUCCESS )
4005 goto cleanup;
4006
4007 status = psa_hash_update( &hmac.hash_ctx,
4008 Ai, Ai_len );
4009 if( status != PSA_SUCCESS )
4010 goto cleanup;
4011
4012 status = psa_hmac_finish_internal( &hmac,
4013 tls12_prf->Ai_with_seed,
4014 hash_length );
4015 if( status != PSA_SUCCESS )
4016 goto cleanup;
4017
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004018 /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
4019 status = psa_hmac_setup_internal( &hmac,
4020 tls12_prf->key,
4021 tls12_prf->key_len,
4022 hash_alg );
4023 if( status != PSA_SUCCESS )
4024 goto cleanup;
4025
4026 status = psa_hash_update( &hmac.hash_ctx,
4027 tls12_prf->Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00004028 tls12_prf->Ai_with_seed_len );
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004029 if( status != PSA_SUCCESS )
4030 goto cleanup;
4031
4032 status = psa_hmac_finish_internal( &hmac,
4033 tls12_prf->output_block,
4034 hash_length );
4035 if( status != PSA_SUCCESS )
4036 goto cleanup;
4037
4038cleanup:
4039
4040 cleanup_status = psa_hmac_abort_internal( &hmac );
4041 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
4042 status = cleanup_status;
4043
4044 return( status );
4045}
4046
4047/* Read some bytes from an TLS-1.2-PRF-based generator.
4048 * See Section 5 of RFC 5246. */
4049static psa_status_t psa_generator_tls12_prf_read(
4050 psa_tls12_prf_generator_t *tls12_prf,
4051 psa_algorithm_t alg,
4052 uint8_t *output,
4053 size_t output_length )
4054{
4055 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
4056 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
4057 psa_status_t status;
4058
4059 while( output_length != 0 )
4060 {
4061 /* Copy what remains of the current block */
4062 uint8_t n = hash_length - tls12_prf->offset_in_block;
4063
4064 /* Check if we have fully processed the current block. */
4065 if( n == 0 )
4066 {
4067 status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
4068 alg );
4069 if( status != PSA_SUCCESS )
4070 return( status );
4071
4072 continue;
4073 }
4074
4075 if( n > output_length )
4076 n = (uint8_t) output_length;
4077 memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
4078 n );
4079 output += n;
4080 output_length -= n;
4081 tls12_prf->offset_in_block += n;
4082 }
4083
4084 return( PSA_SUCCESS );
4085}
Gilles Peskinebef7f142018-07-12 17:22:21 +02004086#endif /* MBEDTLS_MD_C */
4087
Gilles Peskineeab56e42018-07-12 17:12:33 +02004088psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
4089 uint8_t *output,
4090 size_t output_length )
4091{
4092 psa_status_t status;
Gilles Peskine969c5d62019-01-16 15:53:06 +01004093 psa_algorithm_t kdf_alg = psa_generator_get_kdf_alg( generator );
Gilles Peskineeab56e42018-07-12 17:12:33 +02004094
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004095 if( generator->alg == 0 )
4096 {
4097 /* This is a blank generator. */
4098 return PSA_ERROR_BAD_STATE;
4099 }
4100
Gilles Peskineeab56e42018-07-12 17:12:33 +02004101 if( output_length > generator->capacity )
4102 {
4103 generator->capacity = 0;
4104 /* Go through the error path to wipe all confidential data now
4105 * that the generator object is useless. */
David Saadab4ecc272019-02-14 13:48:10 +02004106 status = PSA_ERROR_INSUFFICIENT_DATA;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004107 goto exit;
4108 }
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004109 if( output_length == 0 && generator->capacity == 0 )
Gilles Peskineeab56e42018-07-12 17:12:33 +02004110 {
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004111 /* Edge case: this is a finished generator, and 0 bytes
4112 * were requested. The right error in this case could
Gilles Peskineeab56e42018-07-12 17:12:33 +02004113 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
4114 * INSUFFICIENT_CAPACITY, which is right for a finished
4115 * generator, for consistency with the case when
4116 * output_length > 0. */
David Saadab4ecc272019-02-14 13:48:10 +02004117 return( PSA_ERROR_INSUFFICIENT_DATA );
Gilles Peskineeab56e42018-07-12 17:12:33 +02004118 }
4119 generator->capacity -= output_length;
4120
Gilles Peskine969c5d62019-01-16 15:53:06 +01004121 if( kdf_alg == PSA_ALG_SELECT_RAW )
Gilles Peskine751d9652018-09-18 12:05:44 +02004122 {
Gilles Peskine211a4362018-10-25 22:22:31 +02004123 /* Initially, the capacity of a selection generator is always
4124 * the size of the buffer, i.e. `generator->ctx.buffer.size`,
4125 * abbreviated in this comment as `size`. When the remaining
4126 * capacity is `c`, the next bytes to serve start `c` bytes
4127 * from the end of the buffer, i.e. `size - c` from the
4128 * beginning of the buffer. Since `generator->capacity` was just
4129 * decremented above, we need to serve the bytes from
4130 * `size - generator->capacity - output_length` to
4131 * `size - generator->capacity`. */
Gilles Peskine751d9652018-09-18 12:05:44 +02004132 size_t offset =
4133 generator->ctx.buffer.size - generator->capacity - output_length;
4134 memcpy( output, generator->ctx.buffer.data + offset, output_length );
4135 status = PSA_SUCCESS;
4136 }
4137 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02004138#if defined(MBEDTLS_MD_C)
Gilles Peskine969c5d62019-01-16 15:53:06 +01004139 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskinebef7f142018-07-12 17:22:21 +02004140 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01004141 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004142 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
4143 output, output_length );
4144 }
Gilles Peskine969c5d62019-01-16 15:53:06 +01004145 else if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
4146 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004147 {
4148 status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004149 kdf_alg, output,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004150 output_length );
4151 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02004152 else
4153#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02004154 {
4155 return( PSA_ERROR_BAD_STATE );
4156 }
4157
4158exit:
4159 if( status != PSA_SUCCESS )
4160 {
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004161 /* Preserve the algorithm upon errors, but clear all sensitive state.
4162 * This allows us to differentiate between exhausted generators and
4163 * blank generators, so we can return PSA_ERROR_BAD_STATE on blank
4164 * generators. */
4165 psa_algorithm_t alg = generator->alg;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004166 psa_generator_abort( generator );
Jaeden Amerocf2010c2019-02-15 13:05:49 +00004167 generator->alg = alg;
Gilles Peskineeab56e42018-07-12 17:12:33 +02004168 memset( output, '!', output_length );
4169 }
4170 return( status );
4171}
4172
Gilles Peskine08542d82018-07-19 17:05:42 +02004173#if defined(MBEDTLS_DES_C)
4174static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
4175{
4176 if( data_size >= 8 )
4177 mbedtls_des_key_set_parity( data );
4178 if( data_size >= 16 )
4179 mbedtls_des_key_set_parity( data + 8 );
4180 if( data_size >= 24 )
4181 mbedtls_des_key_set_parity( data + 16 );
4182}
4183#endif /* MBEDTLS_DES_C */
4184
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004185static psa_status_t psa_generator_import_key_internal(
4186 psa_key_slot_t *slot,
4187 size_t bits,
4188 psa_crypto_generator_t *generator )
4189{
4190 uint8_t *data = NULL;
4191 size_t bytes = PSA_BITS_TO_BYTES( bits );
4192 psa_status_t status;
4193
4194 if( ! key_type_is_raw_bytes( slot->type ) )
4195 return( PSA_ERROR_INVALID_ARGUMENT );
4196 if( bits % 8 != 0 )
4197 return( PSA_ERROR_INVALID_ARGUMENT );
4198 data = mbedtls_calloc( 1, bytes );
4199 if( data == NULL )
4200 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4201
4202 status = psa_generator_read( generator, data, bytes );
4203 if( status != PSA_SUCCESS )
4204 goto exit;
4205#if defined(MBEDTLS_DES_C)
4206 if( slot->type == PSA_KEY_TYPE_DES )
4207 psa_des_set_key_parity( data, bytes );
4208#endif /* MBEDTLS_DES_C */
4209 status = psa_import_key_into_slot( slot, data, bytes );
4210
4211exit:
4212 mbedtls_free( data );
4213 return( status );
4214}
4215
4216psa_status_t psa_generator_import_key( const psa_key_attributes_t *attributes,
4217 psa_key_handle_t *handle,
4218 size_t bits,
4219 psa_crypto_generator_t *generator )
4220{
4221 psa_status_t status;
4222 psa_key_slot_t *slot = NULL;
4223 status = psa_start_key_creation( attributes, handle, &slot );
4224 if( status == PSA_SUCCESS )
4225 {
4226 status = psa_generator_import_key_internal( slot, bits, generator );
4227 }
4228 if( status == PSA_SUCCESS )
4229 status = psa_finish_key_creation( slot );
4230 if( status != PSA_SUCCESS )
4231 {
4232 psa_fail_key_creation( slot );
4233 *handle = 0;
4234 }
4235 return( status );
4236}
4237
Gilles Peskine87a5e562019-04-17 12:28:25 +02004238psa_status_t psa_generator_import_key_to_handle( psa_key_handle_t handle,
Gilles Peskineeab56e42018-07-12 17:12:33 +02004239 psa_key_type_t type,
4240 size_t bits,
4241 psa_crypto_generator_t *generator )
4242{
4243 uint8_t *data = NULL;
4244 size_t bytes = PSA_BITS_TO_BYTES( bits );
4245 psa_status_t status;
4246
4247 if( ! key_type_is_raw_bytes( type ) )
4248 return( PSA_ERROR_INVALID_ARGUMENT );
4249 if( bits % 8 != 0 )
4250 return( PSA_ERROR_INVALID_ARGUMENT );
4251 data = mbedtls_calloc( 1, bytes );
4252 if( data == NULL )
4253 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4254
4255 status = psa_generator_read( generator, data, bytes );
4256 if( status != PSA_SUCCESS )
4257 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02004258#if defined(MBEDTLS_DES_C)
4259 if( type == PSA_KEY_TYPE_DES )
4260 psa_des_set_key_parity( data, bytes );
4261#endif /* MBEDTLS_DES_C */
Gilles Peskine87a5e562019-04-17 12:28:25 +02004262 status = psa_import_key_to_handle( handle, type, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02004263
4264exit:
4265 mbedtls_free( data );
4266 return( status );
4267}
4268
4269
4270
4271/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02004272/* Key derivation */
4273/****************************************************************/
4274
Gilles Peskinea05219c2018-11-16 16:02:56 +01004275#if defined(MBEDTLS_MD_C)
Gilles Peskinebef7f142018-07-12 17:22:21 +02004276/* Set up an HKDF-based generator. This is exactly the extract phase
Gilles Peskine346797d2018-11-16 16:05:06 +01004277 * of the HKDF algorithm.
4278 *
4279 * Note that if this function fails, you must call psa_generator_abort()
4280 * to potentially free embedded data structures and wipe confidential data.
4281 */
Gilles Peskinebef7f142018-07-12 17:22:21 +02004282static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004283 const uint8_t *secret,
4284 size_t secret_length,
Gilles Peskinebef7f142018-07-12 17:22:21 +02004285 psa_algorithm_t hash_alg,
4286 const uint8_t *salt,
4287 size_t salt_length,
4288 const uint8_t *label,
4289 size_t label_length )
4290{
4291 psa_status_t status;
4292 status = psa_hmac_setup_internal( &hkdf->hmac,
4293 salt, salt_length,
Gilles Peskinef9ee6332019-04-11 21:22:52 +02004294 hash_alg );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004295 if( status != PSA_SUCCESS )
4296 return( status );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004297 status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
Gilles Peskinebef7f142018-07-12 17:22:21 +02004298 if( status != PSA_SUCCESS )
4299 return( status );
4300 status = psa_hmac_finish_internal( &hkdf->hmac,
4301 hkdf->prk,
4302 sizeof( hkdf->prk ) );
4303 if( status != PSA_SUCCESS )
4304 return( status );
4305 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
4306 hkdf->block_number = 0;
4307 hkdf->info_length = label_length;
4308 if( label_length != 0 )
4309 {
4310 hkdf->info = mbedtls_calloc( 1, label_length );
4311 if( hkdf->info == NULL )
4312 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4313 memcpy( hkdf->info, label, label_length );
4314 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004315 hkdf->state = HKDF_STATE_KEYED;
4316 hkdf->info_set = 1;
Gilles Peskinebef7f142018-07-12 17:22:21 +02004317 return( PSA_SUCCESS );
4318}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004319#endif /* MBEDTLS_MD_C */
Gilles Peskinebef7f142018-07-12 17:22:21 +02004320
Gilles Peskinea05219c2018-11-16 16:02:56 +01004321#if defined(MBEDTLS_MD_C)
Gilles Peskine346797d2018-11-16 16:05:06 +01004322/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
4323 *
4324 * Note that if this function fails, you must call psa_generator_abort()
4325 * to potentially free embedded data structures and wipe confidential data.
4326 */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004327static psa_status_t psa_generator_tls12_prf_setup(
4328 psa_tls12_prf_generator_t *tls12_prf,
4329 const unsigned char *key,
4330 size_t key_len,
4331 psa_algorithm_t hash_alg,
4332 const uint8_t *salt,
4333 size_t salt_length,
4334 const uint8_t *label,
4335 size_t label_length )
4336{
4337 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Hanno Becker580fba12018-11-13 20:50:45 +00004338 size_t Ai_with_seed_len = hash_length + salt_length + label_length;
4339 int overflow;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004340
4341 tls12_prf->key = mbedtls_calloc( 1, key_len );
4342 if( tls12_prf->key == NULL )
4343 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4344 tls12_prf->key_len = key_len;
4345 memcpy( tls12_prf->key, key, key_len );
4346
Hanno Becker580fba12018-11-13 20:50:45 +00004347 overflow = ( salt_length + label_length < salt_length ) ||
4348 ( salt_length + label_length + hash_length < hash_length );
4349 if( overflow )
4350 return( PSA_ERROR_INVALID_ARGUMENT );
4351
4352 tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
4353 if( tls12_prf->Ai_with_seed == NULL )
4354 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4355 tls12_prf->Ai_with_seed_len = Ai_with_seed_len;
4356
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004357 /* Write `label + seed' at the end of the `A(i) + seed` buffer,
4358 * leaving the initial `hash_length` bytes unspecified for now. */
Hanno Becker353e4532018-11-15 09:53:57 +00004359 if( label_length != 0 )
4360 {
4361 memcpy( tls12_prf->Ai_with_seed + hash_length,
4362 label, label_length );
4363 }
4364
4365 if( salt_length != 0 )
4366 {
4367 memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
4368 salt, salt_length );
4369 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004370
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004371 /* The first block gets generated when
4372 * psa_generator_read() is called. */
4373 tls12_prf->block_number = 0;
4374 tls12_prf->offset_in_block = hash_length;
4375
4376 return( PSA_SUCCESS );
4377}
Hanno Becker1aaedc02018-11-16 11:35:34 +00004378
4379/* Set up a TLS-1.2-PSK-to-MS-based generator. */
4380static psa_status_t psa_generator_tls12_psk_to_ms_setup(
4381 psa_tls12_prf_generator_t *tls12_prf,
4382 const unsigned char *psk,
4383 size_t psk_len,
4384 psa_algorithm_t hash_alg,
4385 const uint8_t *salt,
4386 size_t salt_length,
4387 const uint8_t *label,
4388 size_t label_length )
4389{
4390 psa_status_t status;
4391 unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
4392
4393 if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
4394 return( PSA_ERROR_INVALID_ARGUMENT );
4395
4396 /* Quoting RFC 4279, Section 2:
4397 *
4398 * The premaster secret is formed as follows: if the PSK is N octets
4399 * long, concatenate a uint16 with the value N, N zero octets, a second
4400 * uint16 with the value N, and the PSK itself.
4401 */
4402
4403 pms[0] = ( psk_len >> 8 ) & 0xff;
4404 pms[1] = ( psk_len >> 0 ) & 0xff;
4405 memset( pms + 2, 0, psk_len );
4406 pms[2 + psk_len + 0] = pms[0];
4407 pms[2 + psk_len + 1] = pms[1];
4408 memcpy( pms + 4 + psk_len, psk, psk_len );
4409
4410 status = psa_generator_tls12_prf_setup( tls12_prf,
4411 pms, 4 + 2 * psk_len,
4412 hash_alg,
4413 salt, salt_length,
4414 label, label_length );
4415
Gilles Peskine3f108122018-12-07 18:14:53 +01004416 mbedtls_platform_zeroize( pms, sizeof( pms ) );
Hanno Becker1aaedc02018-11-16 11:35:34 +00004417 return( status );
4418}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004419#endif /* MBEDTLS_MD_C */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004420
Gilles Peskine346797d2018-11-16 16:05:06 +01004421/* Note that if this function fails, you must call psa_generator_abort()
4422 * to potentially free embedded data structures and wipe confidential data.
4423 */
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004424static psa_status_t psa_key_derivation_internal(
4425 psa_crypto_generator_t *generator,
4426 const uint8_t *secret, size_t secret_length,
4427 psa_algorithm_t alg,
4428 const uint8_t *salt, size_t salt_length,
4429 const uint8_t *label, size_t label_length,
4430 size_t capacity )
4431{
4432 psa_status_t status;
4433 size_t max_capacity;
4434
4435 /* Set generator->alg even on failure so that abort knows what to do. */
4436 generator->alg = alg;
4437
Gilles Peskine751d9652018-09-18 12:05:44 +02004438 if( alg == PSA_ALG_SELECT_RAW )
4439 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01004440 (void) salt;
Gilles Peskine751d9652018-09-18 12:05:44 +02004441 if( salt_length != 0 )
4442 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea05219c2018-11-16 16:02:56 +01004443 (void) label;
Gilles Peskine751d9652018-09-18 12:05:44 +02004444 if( label_length != 0 )
4445 return( PSA_ERROR_INVALID_ARGUMENT );
4446 generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
4447 if( generator->ctx.buffer.data == NULL )
4448 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4449 memcpy( generator->ctx.buffer.data, secret, secret_length );
4450 generator->ctx.buffer.size = secret_length;
4451 max_capacity = secret_length;
4452 status = PSA_SUCCESS;
4453 }
4454 else
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004455#if defined(MBEDTLS_MD_C)
4456 if( PSA_ALG_IS_HKDF( alg ) )
4457 {
4458 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
4459 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4460 if( hash_size == 0 )
4461 return( PSA_ERROR_NOT_SUPPORTED );
4462 max_capacity = 255 * hash_size;
4463 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
4464 secret, secret_length,
4465 hash_alg,
4466 salt, salt_length,
4467 label, label_length );
4468 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00004469 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
4470 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
4471 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004472 {
4473 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
4474 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4475
4476 /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
4477 if( hash_alg != PSA_ALG_SHA_256 &&
4478 hash_alg != PSA_ALG_SHA_384 )
4479 {
4480 return( PSA_ERROR_NOT_SUPPORTED );
4481 }
4482
4483 max_capacity = 255 * hash_size;
Hanno Becker1aaedc02018-11-16 11:35:34 +00004484
4485 if( PSA_ALG_IS_TLS12_PRF( alg ) )
4486 {
4487 status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
4488 secret, secret_length,
4489 hash_alg, salt, salt_length,
4490 label, label_length );
4491 }
4492 else
4493 {
4494 status = psa_generator_tls12_psk_to_ms_setup(
4495 &generator->ctx.tls12_prf,
4496 secret, secret_length,
4497 hash_alg, salt, salt_length,
4498 label, label_length );
4499 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004500 }
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004501 else
4502#endif
4503 {
4504 return( PSA_ERROR_NOT_SUPPORTED );
4505 }
4506
4507 if( status != PSA_SUCCESS )
4508 return( status );
4509
4510 if( capacity <= max_capacity )
4511 generator->capacity = capacity;
Gilles Peskine8feb3a82018-09-18 12:06:11 +02004512 else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
4513 generator->capacity = max_capacity;
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004514 else
4515 return( PSA_ERROR_INVALID_ARGUMENT );
4516
4517 return( PSA_SUCCESS );
4518}
4519
Gilles Peskineea0fb492018-07-12 17:17:20 +02004520psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004521 psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02004522 psa_algorithm_t alg,
4523 const uint8_t *salt,
4524 size_t salt_length,
4525 const uint8_t *label,
4526 size_t label_length,
4527 size_t capacity )
4528{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004529 psa_key_slot_t *slot;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004530 psa_status_t status;
4531
4532 if( generator->alg != 0 )
4533 return( PSA_ERROR_BAD_STATE );
4534
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004535 /* Make sure that alg is a key derivation algorithm. This prevents
4536 * key selection algorithms, which psa_key_derivation_internal
4537 * accepts for the sake of key agreement. */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004538 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
4539 return( PSA_ERROR_INVALID_ARGUMENT );
4540
Gilles Peskinec5487a82018-12-03 18:08:14 +01004541 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004542 if( status != PSA_SUCCESS )
4543 return( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004544
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004545 if( slot->type != PSA_KEY_TYPE_DERIVE )
4546 return( PSA_ERROR_INVALID_ARGUMENT );
4547
4548 status = psa_key_derivation_internal( generator,
4549 slot->data.raw.data,
4550 slot->data.raw.bytes,
4551 alg,
4552 salt, salt_length,
4553 label, label_length,
4554 capacity );
4555 if( status != PSA_SUCCESS )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004556 psa_generator_abort( generator );
4557 return( status );
4558}
4559
Gilles Peskine969c5d62019-01-16 15:53:06 +01004560static psa_status_t psa_key_derivation_setup_kdf(
4561 psa_crypto_generator_t *generator,
4562 psa_algorithm_t kdf_alg )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004563{
Gilles Peskine969c5d62019-01-16 15:53:06 +01004564 /* Make sure that kdf_alg is a supported key derivation algorithm. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004565#if defined(MBEDTLS_MD_C)
Gilles Peskine969c5d62019-01-16 15:53:06 +01004566 if( PSA_ALG_IS_HKDF( kdf_alg ) ||
4567 PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
4568 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004569 {
Gilles Peskine969c5d62019-01-16 15:53:06 +01004570 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004571 size_t hash_size = PSA_HASH_SIZE( hash_alg );
4572 if( hash_size == 0 )
4573 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004574 if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
4575 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) &&
Gilles Peskineab4b2012019-04-12 15:06:27 +02004576 ! ( hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384 ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004577 {
4578 return( PSA_ERROR_NOT_SUPPORTED );
4579 }
4580 generator->capacity = 255 * hash_size;
Gilles Peskine969c5d62019-01-16 15:53:06 +01004581 return( PSA_SUCCESS );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004582 }
4583#endif /* MBEDTLS_MD_C */
Gilles Peskine969c5d62019-01-16 15:53:06 +01004584 else
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004585 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004586}
4587
4588psa_status_t psa_key_derivation_setup( psa_crypto_generator_t *generator,
4589 psa_algorithm_t alg )
4590{
4591 psa_status_t status;
4592
4593 if( generator->alg != 0 )
4594 return( PSA_ERROR_BAD_STATE );
4595
Gilles Peskine6843c292019-01-18 16:44:49 +01004596 if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
4597 return( PSA_ERROR_INVALID_ARGUMENT );
4598 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
Gilles Peskine969c5d62019-01-16 15:53:06 +01004599 {
4600 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
Gilles Peskine6843c292019-01-18 16:44:49 +01004601 status = psa_key_derivation_setup_kdf( generator, kdf_alg );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004602 }
4603 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
4604 {
4605 status = psa_key_derivation_setup_kdf( generator, alg );
4606 }
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004607 else
4608 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004609
4610 if( status == PSA_SUCCESS )
4611 generator->alg = alg;
4612 return( status );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004613}
4614
4615#if defined(MBEDTLS_MD_C)
4616static psa_status_t psa_hkdf_input( psa_hkdf_generator_t *hkdf,
4617 psa_algorithm_t hash_alg,
4618 psa_key_derivation_step_t step,
4619 const uint8_t *data,
4620 size_t data_length )
4621{
4622 psa_status_t status;
4623 switch( step )
4624 {
4625 case PSA_KDF_STEP_SALT:
Gilles Peskine2b522db2019-04-12 15:11:49 +02004626 if( hkdf->state != HKDF_STATE_INIT )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004627 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02004628 status = psa_hmac_setup_internal( &hkdf->hmac,
4629 data, data_length,
4630 hash_alg );
4631 if( status != PSA_SUCCESS )
4632 return( status );
4633 hkdf->state = HKDF_STATE_STARTED;
4634 return( PSA_SUCCESS );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004635 case PSA_KDF_STEP_SECRET:
4636 /* If no salt was provided, use an empty salt. */
4637 if( hkdf->state == HKDF_STATE_INIT )
4638 {
4639 status = psa_hmac_setup_internal( &hkdf->hmac,
4640 NULL, 0,
Gilles Peskinef9ee6332019-04-11 21:22:52 +02004641 hash_alg );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004642 if( status != PSA_SUCCESS )
4643 return( status );
4644 hkdf->state = HKDF_STATE_STARTED;
4645 }
Gilles Peskine2b522db2019-04-12 15:11:49 +02004646 if( hkdf->state != HKDF_STATE_STARTED )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004647 return( PSA_ERROR_BAD_STATE );
Gilles Peskine2b522db2019-04-12 15:11:49 +02004648 status = psa_hash_update( &hkdf->hmac.hash_ctx,
4649 data, data_length );
4650 if( status != PSA_SUCCESS )
4651 return( status );
4652 status = psa_hmac_finish_internal( &hkdf->hmac,
4653 hkdf->prk,
4654 sizeof( hkdf->prk ) );
4655 if( status != PSA_SUCCESS )
4656 return( status );
4657 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
4658 hkdf->block_number = 0;
4659 hkdf->state = HKDF_STATE_KEYED;
4660 return( PSA_SUCCESS );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004661 case PSA_KDF_STEP_INFO:
4662 if( hkdf->state == HKDF_STATE_OUTPUT )
4663 return( PSA_ERROR_BAD_STATE );
4664 if( hkdf->info_set )
4665 return( PSA_ERROR_BAD_STATE );
4666 hkdf->info_length = data_length;
4667 if( data_length != 0 )
4668 {
4669 hkdf->info = mbedtls_calloc( 1, data_length );
4670 if( hkdf->info == NULL )
4671 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4672 memcpy( hkdf->info, data, data_length );
4673 }
4674 hkdf->info_set = 1;
4675 return( PSA_SUCCESS );
4676 default:
4677 return( PSA_ERROR_INVALID_ARGUMENT );
4678 }
4679}
4680#endif /* MBEDTLS_MD_C */
4681
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01004682static psa_status_t psa_key_derivation_input_raw(
4683 psa_crypto_generator_t *generator,
4684 psa_key_derivation_step_t step,
4685 const uint8_t *data,
4686 size_t data_length )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004687{
4688 psa_status_t status;
Gilles Peskine969c5d62019-01-16 15:53:06 +01004689 psa_algorithm_t kdf_alg = psa_generator_get_kdf_alg( generator );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004690
Gilles Peskine969c5d62019-01-16 15:53:06 +01004691 if( kdf_alg == PSA_ALG_SELECT_RAW )
4692 {
4693 if( generator->capacity != 0 )
4694 return( PSA_ERROR_INVALID_ARGUMENT );
4695 generator->ctx.buffer.data = mbedtls_calloc( 1, data_length );
4696 if( generator->ctx.buffer.data == NULL )
4697 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4698 memcpy( generator->ctx.buffer.data, data, data_length );
4699 generator->ctx.buffer.size = data_length;
4700 generator->capacity = data_length;
4701 status = PSA_SUCCESS;
4702 }
4703 else
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004704#if defined(MBEDTLS_MD_C)
Gilles Peskine969c5d62019-01-16 15:53:06 +01004705 if( PSA_ALG_IS_HKDF( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004706 {
4707 status = psa_hkdf_input( &generator->ctx.hkdf,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004708 PSA_ALG_HKDF_GET_HASH( kdf_alg ),
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004709 step, data, data_length );
4710 }
Gilles Peskine969c5d62019-01-16 15:53:06 +01004711 else
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004712#endif /* MBEDTLS_MD_C */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004713#if defined(MBEDTLS_MD_C)
4714 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
Gilles Peskine969c5d62019-01-16 15:53:06 +01004715 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
4716 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004717 {
Gilles Peskinec88644d2019-04-12 15:03:38 +02004718 // To do: implement this
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004719 status = PSA_ERROR_NOT_SUPPORTED;
4720 }
4721 else
4722#endif /* MBEDTLS_MD_C */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004723 {
4724 /* This can't happen unless the generator object was not initialized */
4725 return( PSA_ERROR_BAD_STATE );
4726 }
4727
4728 if( status != PSA_SUCCESS )
4729 psa_generator_abort( generator );
4730 return( status );
4731}
4732
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01004733psa_status_t psa_key_derivation_input_bytes( psa_crypto_generator_t *generator,
4734 psa_key_derivation_step_t step,
4735 const uint8_t *data,
4736 size_t data_length )
4737{
4738 switch( step )
4739 {
4740 case PSA_KDF_STEP_LABEL:
4741 case PSA_KDF_STEP_SALT:
4742 case PSA_KDF_STEP_INFO:
4743 return( psa_key_derivation_input_raw( generator, step,
4744 data, data_length ) );
4745 default:
4746 return( PSA_ERROR_INVALID_ARGUMENT );
4747 }
4748}
4749
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004750psa_status_t psa_key_derivation_input_key( psa_crypto_generator_t *generator,
4751 psa_key_derivation_step_t step,
4752 psa_key_handle_t handle )
4753{
4754 psa_key_slot_t *slot;
4755 psa_status_t status;
4756 status = psa_get_key_from_slot( handle, &slot,
4757 PSA_KEY_USAGE_DERIVE,
4758 generator->alg );
4759 if( status != PSA_SUCCESS )
4760 return( status );
4761 if( slot->type != PSA_KEY_TYPE_DERIVE )
4762 return( PSA_ERROR_INVALID_ARGUMENT );
4763 /* Don't allow a key to be used as an input that is usually public.
4764 * This is debatable. It's ok from a cryptographic perspective to
4765 * use secret material as an input that is usually public. However
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01004766 * the material should be dedicated to a particular input step,
4767 * otherwise this may allow the key to be used in an unintended way
4768 * and leak values derived from the key. So be conservative. */
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004769 if( step != PSA_KDF_STEP_SECRET )
4770 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine6cdfdb72019-01-08 10:31:27 +01004771 return( psa_key_derivation_input_raw( generator,
4772 step,
4773 slot->data.raw.data,
4774 slot->data.raw.bytes ) );
Gilles Peskineb70a0fd2019-01-07 22:59:38 +01004775}
4776
Gilles Peskineea0fb492018-07-12 17:17:20 +02004777
4778
4779/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02004780/* Key agreement */
4781/****************************************************************/
4782
Gilles Peskinea05219c2018-11-16 16:02:56 +01004783#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004784static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
4785 size_t peer_key_length,
4786 const mbedtls_ecp_keypair *our_key,
4787 uint8_t *shared_secret,
4788 size_t shared_secret_size,
4789 size_t *shared_secret_length )
4790{
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004791 mbedtls_ecp_keypair *their_key = NULL;
4792 mbedtls_ecdh_context ecdh;
Jaeden Amero1e5c2bd2019-01-10 19:38:51 +00004793 psa_status_t status;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004794 mbedtls_ecdh_init( &ecdh );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004795
Jaeden Amero0ae445f2019-01-10 11:42:27 +00004796 status = psa_import_ec_public_key(
4797 mbedtls_ecc_group_to_psa( our_key->grp.id ),
4798 peer_key, peer_key_length,
4799 &their_key );
Jaeden Amero1e5c2bd2019-01-10 19:38:51 +00004800 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004801 goto exit;
Gilles Peskineb4086612018-11-14 20:51:23 +01004802
Jaeden Amero1e5c2bd2019-01-10 19:38:51 +00004803 status = mbedtls_to_psa_error(
4804 mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS ) );
4805 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004806 goto exit;
Jaeden Amero1e5c2bd2019-01-10 19:38:51 +00004807 status = mbedtls_to_psa_error(
4808 mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS ) );
4809 if( status != PSA_SUCCESS )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004810 goto exit;
4811
Jaeden Amero1e5c2bd2019-01-10 19:38:51 +00004812 status = mbedtls_to_psa_error(
4813 mbedtls_ecdh_calc_secret( &ecdh,
4814 shared_secret_length,
4815 shared_secret, shared_secret_size,
4816 mbedtls_ctr_drbg_random,
4817 &global_data.ctr_drbg ) );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004818
4819exit:
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004820 mbedtls_ecdh_free( &ecdh );
Jaeden Amero0ae445f2019-01-10 11:42:27 +00004821 mbedtls_ecp_keypair_free( their_key );
4822 mbedtls_free( their_key );
Jaeden Amero1e5c2bd2019-01-10 19:38:51 +00004823 return( status );
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004824}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004825#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004826
Gilles Peskine01d718c2018-09-18 12:01:02 +02004827#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
4828
Gilles Peskine0216fe12019-04-11 21:23:21 +02004829static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg,
4830 psa_key_slot_t *private_key,
4831 const uint8_t *peer_key,
4832 size_t peer_key_length,
4833 uint8_t *shared_secret,
4834 size_t shared_secret_size,
4835 size_t *shared_secret_length )
4836{
4837 switch( alg )
4838 {
4839#if defined(MBEDTLS_ECDH_C)
4840 case PSA_ALG_ECDH:
4841 if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
4842 return( PSA_ERROR_INVALID_ARGUMENT );
4843 return( psa_key_agreement_ecdh( peer_key, peer_key_length,
4844 private_key->data.ecp,
4845 shared_secret, shared_secret_size,
4846 shared_secret_length ) );
Gilles Peskine0216fe12019-04-11 21:23:21 +02004847#endif /* MBEDTLS_ECDH_C */
4848 default:
4849 (void) private_key;
4850 (void) peer_key;
4851 (void) peer_key_length;
4852 (void) shared_secret;
4853 (void) shared_secret_size;
4854 (void) shared_secret_length;
4855 return( PSA_ERROR_NOT_SUPPORTED );
4856 }
4857}
4858
Gilles Peskine346797d2018-11-16 16:05:06 +01004859/* Note that if this function fails, you must call psa_generator_abort()
4860 * to potentially free embedded data structures and wipe confidential data.
4861 */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004862static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004863 psa_key_derivation_step_t step,
Gilles Peskine2f060a82018-12-04 17:12:32 +01004864 psa_key_slot_t *private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004865 const uint8_t *peer_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004866 size_t peer_key_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02004867{
4868 psa_status_t status;
4869 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4870 size_t shared_secret_length = 0;
Gilles Peskine0216fe12019-04-11 21:23:21 +02004871 psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( generator->alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004872
4873 /* Step 1: run the secret agreement algorithm to generate the shared
4874 * secret. */
Gilles Peskine0216fe12019-04-11 21:23:21 +02004875 status = psa_key_agreement_raw_internal( ka_alg,
4876 private_key,
4877 peer_key, peer_key_length,
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004878 shared_secret,
4879 sizeof( shared_secret ),
4880 &shared_secret_length );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004881 if( status != PSA_SUCCESS )
4882 goto exit;
4883
4884 /* Step 2: set up the key derivation to generate key material from
4885 * the shared secret. */
Gilles Peskine969c5d62019-01-16 15:53:06 +01004886 status = psa_key_derivation_input_raw( generator, step,
4887 shared_secret, shared_secret_length );
4888
Gilles Peskine01d718c2018-09-18 12:01:02 +02004889exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01004890 mbedtls_platform_zeroize( shared_secret, shared_secret_length );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004891 return( status );
4892}
4893
4894psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004895 psa_key_derivation_step_t step,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004896 psa_key_handle_t private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004897 const uint8_t *peer_key,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004898 size_t peer_key_length )
Gilles Peskine01d718c2018-09-18 12:01:02 +02004899{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004900 psa_key_slot_t *slot;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004901 psa_status_t status;
Gilles Peskine969c5d62019-01-16 15:53:06 +01004902 if( ! PSA_ALG_IS_KEY_AGREEMENT( generator->alg ) )
Gilles Peskine01d718c2018-09-18 12:01:02 +02004903 return( PSA_ERROR_INVALID_ARGUMENT );
4904 status = psa_get_key_from_slot( private_key, &slot,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004905 PSA_KEY_USAGE_DERIVE, generator->alg );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004906 if( status != PSA_SUCCESS )
4907 return( status );
Gilles Peskine969c5d62019-01-16 15:53:06 +01004908 status = psa_key_agreement_internal( generator, step,
Gilles Peskine346797d2018-11-16 16:05:06 +01004909 slot,
Gilles Peskine969c5d62019-01-16 15:53:06 +01004910 peer_key, peer_key_length );
Gilles Peskine346797d2018-11-16 16:05:06 +01004911 if( status != PSA_SUCCESS )
4912 psa_generator_abort( generator );
4913 return( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004914}
4915
Gilles Peskine0216fe12019-04-11 21:23:21 +02004916psa_status_t psa_key_agreement_raw_shared_secret( psa_algorithm_t alg,
4917 psa_key_handle_t private_key,
4918 const uint8_t *peer_key,
4919 size_t peer_key_length,
4920 uint8_t *output,
4921 size_t output_size,
4922 size_t *output_length )
4923{
4924 psa_key_slot_t *slot;
4925 psa_status_t status;
4926
4927 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4928 {
4929 status = PSA_ERROR_INVALID_ARGUMENT;
4930 goto exit;
4931 }
4932 status = psa_get_key_from_slot( private_key, &slot,
4933 PSA_KEY_USAGE_DERIVE, alg );
4934 if( status != PSA_SUCCESS )
4935 goto exit;
4936
4937 status = psa_key_agreement_raw_internal( alg, slot,
4938 peer_key, peer_key_length,
4939 output, output_size,
4940 output_length );
4941
4942exit:
4943 if( status != PSA_SUCCESS )
4944 {
4945 /* If an error happens and is not handled properly, the output
4946 * may be used as a key to protect sensitive data. Arrange for such
4947 * a key to be random, which is likely to result in decryption or
4948 * verification errors. This is better than filling the buffer with
4949 * some constant data such as zeros, which would result in the data
4950 * being protected with a reproducible, easily knowable key.
4951 */
4952 psa_generate_random( output, output_size );
4953 *output_length = output_size;
4954 }
4955 return( status );
4956}
Gilles Peskine01d718c2018-09-18 12:01:02 +02004957
4958
4959/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004960/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02004961/****************************************************************/
4962
4963psa_status_t psa_generate_random( uint8_t *output,
4964 size_t output_size )
4965{
itayzafrir0adf0fc2018-09-06 16:24:41 +03004966 int ret;
4967 GUARD_MODULE_INITIALIZED;
4968
4969 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
Gilles Peskine05d69892018-06-19 22:00:52 +02004970 return( mbedtls_to_psa_error( ret ) );
4971}
4972
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01004973#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
4974#include "mbedtls/entropy_poll.h"
avolinski13beb102018-11-20 16:51:49 +02004975
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004976psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
4977 size_t seed_size )
4978{
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004979 if( global_data.initialized )
4980 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02004981
4982 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
4983 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
4984 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
4985 return( PSA_ERROR_INVALID_ARGUMENT );
4986
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01004987 return( mbedtls_psa_storage_inject_entropy( seed, seed_size ) );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004988}
Gilles Peskinee3dbdd82019-02-25 11:04:06 +01004989#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004990
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004991static psa_status_t psa_generate_key_internal( psa_key_slot_t *slot,
4992 size_t bits,
4993 const void *extra,
4994 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02004995{
Gilles Peskineff5f0e72019-04-18 12:53:30 +02004996 psa_key_type_t type = slot->type;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004997
Gilles Peskine53d991e2018-07-12 01:14:59 +02004998 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004999 return( PSA_ERROR_INVALID_ARGUMENT );
5000
Gilles Peskine48c0ea12018-06-21 14:15:31 +02005001 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005002 {
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005003 psa_status_t status;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02005004 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005005 if( status != PSA_SUCCESS )
5006 return( status );
5007 status = psa_generate_random( slot->data.raw.data,
5008 slot->data.raw.bytes );
5009 if( status != PSA_SUCCESS )
5010 {
5011 mbedtls_free( slot->data.raw.data );
5012 return( status );
5013 }
5014#if defined(MBEDTLS_DES_C)
5015 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02005016 psa_des_set_key_parity( slot->data.raw.data,
5017 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02005018#endif /* MBEDTLS_DES_C */
5019 }
5020 else
5021
5022#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
5023 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
5024 {
5025 mbedtls_rsa_context *rsa;
5026 int ret;
5027 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02005028 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
5029 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +01005030 /* Accept only byte-aligned keys, for the same reasons as
5031 * in psa_import_rsa_key(). */
5032 if( bits % 8 != 0 )
5033 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02005034 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005035 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02005036 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02005037 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005038 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02005039#if INT_MAX < 0xffffffff
5040 /* Check that the uint32_t value passed by the caller fits
5041 * in the range supported by this implementation. */
5042 if( p->e > INT_MAX )
5043 return( PSA_ERROR_NOT_SUPPORTED );
5044#endif
5045 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02005046 }
5047 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
5048 if( rsa == NULL )
5049 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5050 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
5051 ret = mbedtls_rsa_gen_key( rsa,
5052 mbedtls_ctr_drbg_random,
5053 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01005054 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02005055 exponent );
5056 if( ret != 0 )
5057 {
5058 mbedtls_rsa_free( rsa );
5059 mbedtls_free( rsa );
5060 return( mbedtls_to_psa_error( ret ) );
5061 }
5062 slot->data.rsa = rsa;
5063 }
5064 else
5065#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
5066
5067#if defined(MBEDTLS_ECP_C)
5068 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
5069 {
5070 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
5071 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
5072 const mbedtls_ecp_curve_info *curve_info =
5073 mbedtls_ecp_curve_info_from_grp_id( grp_id );
5074 mbedtls_ecp_keypair *ecp;
5075 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02005076 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02005077 return( PSA_ERROR_NOT_SUPPORTED );
5078 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
5079 return( PSA_ERROR_NOT_SUPPORTED );
5080 if( curve_info->bit_size != bits )
5081 return( PSA_ERROR_INVALID_ARGUMENT );
5082 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
5083 if( ecp == NULL )
5084 return( PSA_ERROR_INSUFFICIENT_MEMORY );
5085 mbedtls_ecp_keypair_init( ecp );
5086 ret = mbedtls_ecp_gen_key( grp_id, ecp,
5087 mbedtls_ctr_drbg_random,
5088 &global_data.ctr_drbg );
5089 if( ret != 0 )
5090 {
5091 mbedtls_ecp_keypair_free( ecp );
5092 mbedtls_free( ecp );
5093 return( mbedtls_to_psa_error( ret ) );
5094 }
5095 slot->data.ecp = ecp;
5096 }
5097 else
5098#endif /* MBEDTLS_ECP_C */
5099
5100 return( PSA_ERROR_NOT_SUPPORTED );
5101
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005102 return( PSA_SUCCESS );
5103}
5104
5105psa_status_t psa_generate_key_to_handle( psa_key_handle_t handle,
5106 psa_key_type_t type,
5107 size_t bits,
5108 const void *extra,
5109 size_t extra_size )
5110{
5111 psa_key_slot_t *slot;
5112 psa_status_t status;
5113
5114 status = psa_get_empty_key_slot( handle, &slot );
5115 if( status != PSA_SUCCESS )
5116 return( status );
5117
Gilles Peskine12313cd2018-06-20 00:20:32 +02005118 slot->type = type;
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005119 status = psa_generate_key_internal( slot, bits, extra, extra_size );
5120 if( status != PSA_SUCCESS )
5121 slot->type = 0;
Darryl Green0c6575a2018-11-07 16:05:30 +00005122
5123#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
5124 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
5125 {
Gilles Peskine69f976b2018-11-30 18:46:56 +01005126 return( psa_save_generated_persistent_key( slot, bits ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00005127 }
5128#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
5129
5130 return( status );
Gilles Peskine05d69892018-06-19 22:00:52 +02005131}
5132
Gilles Peskineff5f0e72019-04-18 12:53:30 +02005133psa_status_t psa_generate_key( const psa_key_attributes_t *attributes,
5134 psa_key_handle_t *handle,
5135 size_t bits,
5136 const void *extra,
5137 size_t extra_size )
5138{
5139 psa_status_t status;
5140 psa_key_slot_t *slot = NULL;
5141 status = psa_start_key_creation( attributes, handle, &slot );
5142 if( status == PSA_SUCCESS )
5143 {
5144 status = psa_generate_key_internal( slot, bits, extra, extra_size );
5145 }
5146 if( status == PSA_SUCCESS )
5147 status = psa_finish_key_creation( slot );
5148 if( status != PSA_SUCCESS )
5149 {
5150 psa_fail_key_creation( slot );
5151 *handle = 0;
5152 }
5153 return( status );
5154}
5155
5156
Gilles Peskine05d69892018-06-19 22:00:52 +02005157
5158/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01005159/* Module setup */
5160/****************************************************************/
5161
Gilles Peskine5e769522018-11-20 21:59:56 +01005162psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
5163 void (* entropy_init )( mbedtls_entropy_context *ctx ),
5164 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
5165{
5166 if( global_data.rng_state != RNG_NOT_INITIALIZED )
5167 return( PSA_ERROR_BAD_STATE );
5168 global_data.entropy_init = entropy_init;
5169 global_data.entropy_free = entropy_free;
5170 return( PSA_SUCCESS );
5171}
5172
Gilles Peskinee59236f2018-01-27 23:32:46 +01005173void mbedtls_psa_crypto_free( void )
5174{
Gilles Peskine66fb1262018-12-10 16:29:04 +01005175 psa_wipe_all_key_slots( );
Gilles Peskinec6b69072018-11-20 21:42:52 +01005176 if( global_data.rng_state != RNG_NOT_INITIALIZED )
5177 {
5178 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
Gilles Peskine5e769522018-11-20 21:59:56 +01005179 global_data.entropy_free( &global_data.entropy );
Gilles Peskinec6b69072018-11-20 21:42:52 +01005180 }
5181 /* Wipe all remaining data, including configuration.
5182 * In particular, this sets all state indicator to the value
5183 * indicating "uninitialized". */
Gilles Peskine3f108122018-12-07 18:14:53 +01005184 mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01005185}
5186
5187psa_status_t psa_crypto_init( void )
5188{
Gilles Peskine66fb1262018-12-10 16:29:04 +01005189 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005190 const unsigned char drbg_seed[] = "PSA";
5191
Gilles Peskinec6b69072018-11-20 21:42:52 +01005192 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01005193 if( global_data.initialized != 0 )
5194 return( PSA_SUCCESS );
5195
Gilles Peskine5e769522018-11-20 21:59:56 +01005196 /* Set default configuration if
5197 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
5198 if( global_data.entropy_init == NULL )
5199 global_data.entropy_init = mbedtls_entropy_init;
5200 if( global_data.entropy_free == NULL )
5201 global_data.entropy_free = mbedtls_entropy_free;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005202
Gilles Peskinec6b69072018-11-20 21:42:52 +01005203 /* Initialize the random generator. */
Gilles Peskine5e769522018-11-20 21:59:56 +01005204 global_data.entropy_init( &global_data.entropy );
Gilles Peskinee59236f2018-01-27 23:32:46 +01005205 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
Gilles Peskinec6b69072018-11-20 21:42:52 +01005206 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskine66fb1262018-12-10 16:29:04 +01005207 status = mbedtls_to_psa_error(
5208 mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
5209 mbedtls_entropy_func,
5210 &global_data.entropy,
5211 drbg_seed, sizeof( drbg_seed ) - 1 ) );
5212 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005213 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01005214 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01005215
Gilles Peskine66fb1262018-12-10 16:29:04 +01005216 status = psa_initialize_key_slots( );
5217 if( status != PSA_SUCCESS )
5218 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01005219
5220 /* All done. */
Gilles Peskinee4ebc122018-03-07 14:16:44 +01005221 global_data.initialized = 1;
5222
Gilles Peskinee59236f2018-01-27 23:32:46 +01005223exit:
Gilles Peskine66fb1262018-12-10 16:29:04 +01005224 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01005225 mbedtls_psa_crypto_free( );
Gilles Peskine66fb1262018-12-10 16:29:04 +01005226 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01005227}
5228
5229#endif /* MBEDTLS_PSA_CRYPTO_C */