blob: 1dda49bb4ce43e53a6d9f116712d4ab8c7f152ab [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)
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +030029/*
30 * In case MBEDTLS_PSA_CRYPTO_SPM is defined the code is built for SPM (Secure
31 * Partition Manager) integration which separate the code into two parts
32 * NSPE (Non-Secure Process Environment) and SPE (Secure Process Environment).
33 * In this mode an additional header file should be included.
34 */
mohammad160327010052018-07-03 13:16:15 +030035#if defined(MBEDTLS_PSA_CRYPTO_SPM)
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +030036/*
37 * PSA_CRYPTO_SECURE means that this file is compiled to the SPE side.
38 * some headers will be affected by this flag.
39 */
mohammad160327010052018-07-03 13:16:15 +030040#define PSA_CRYPTO_SECURE 1
41#include "crypto_spe.h"
42#endif
43
Gilles Peskinee59236f2018-01-27 23:32:46 +010044#include "psa/crypto.h"
45
Gilles Peskine039b90c2018-12-07 18:24:41 +010046#include "psa_crypto_core.h"
Gilles Peskine5e769522018-11-20 21:59:56 +010047#include "psa_crypto_invasive.h"
Gilles Peskine961849f2018-11-30 18:54:54 +010048#include "psa_crypto_slot_management.h"
Darryl Greend49a4992018-06-18 17:27:26 +010049/* Include internal declarations that are useful for implementing persistently
50 * stored keys. */
51#include "psa_crypto_storage.h"
52
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010053#include <stdlib.h>
54#include <string.h>
55#if defined(MBEDTLS_PLATFORM_C)
56#include "mbedtls/platform.h"
57#else
58#define mbedtls_calloc calloc
59#define mbedtls_free free
60#endif
61
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020063#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020064#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010065#include "mbedtls/blowfish.h"
66#include "mbedtls/camellia.h"
67#include "mbedtls/cipher.h"
68#include "mbedtls/ccm.h"
69#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010070#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010071#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020072#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010073#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010074#include "mbedtls/entropy.h"
Netanel Gonen2bcd3122018-11-19 11:53:02 +020075#include "mbedtls/entropy_poll.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010076#include "mbedtls/error.h"
77#include "mbedtls/gcm.h"
78#include "mbedtls/md2.h"
79#include "mbedtls/md4.h"
80#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010081#include "mbedtls/md.h"
82#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010083#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010084#include "mbedtls/pk_internal.h"
Gilles Peskine3f108122018-12-07 18:14:53 +010085#include "mbedtls/platform_util.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010086#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010087#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010088#include "mbedtls/sha1.h"
89#include "mbedtls/sha256.h"
90#include "mbedtls/sha512.h"
91#include "mbedtls/xtea.h"
92
Netanel Gonen2bcd3122018-11-19 11:53:02 +020093#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
94#include "psa_prot_internal_storage.h"
95#endif
Gilles Peskinee59236f2018-01-27 23:32:46 +010096
Gilles Peskine996deb12018-08-01 15:45:45 +020097#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
98
Gilles Peskine9ef733f2018-02-07 21:05:37 +010099/* constant-time buffer comparison */
100static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
101{
102 size_t i;
103 unsigned char diff = 0;
104
105 for( i = 0; i < n; i++ )
106 diff |= a[i] ^ b[i];
107
108 return( diff );
109}
110
111
112
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100113/****************************************************************/
114/* Global data, support functions and library management */
115/****************************************************************/
116
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200117static int key_type_is_raw_bytes( psa_key_type_t type )
118{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200119 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200120}
121
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100122/* Values for psa_global_data_t::rng_state */
123#define RNG_NOT_INITIALIZED 0
124#define RNG_INITIALIZED 1
125#define RNG_SEEDED 2
Gilles Peskinec6b69072018-11-20 21:42:52 +0100126
Gilles Peskine2d277862018-06-18 15:41:12 +0200127typedef struct
128{
Gilles Peskine5e769522018-11-20 21:59:56 +0100129 void (* entropy_init )( mbedtls_entropy_context *ctx );
130 void (* entropy_free )( mbedtls_entropy_context *ctx );
Gilles Peskinee59236f2018-01-27 23:32:46 +0100131 mbedtls_entropy_context entropy;
132 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskinec6b69072018-11-20 21:42:52 +0100133 unsigned initialized : 1;
Gilles Peskine5a3c50e2018-12-04 12:27:09 +0100134 unsigned rng_state : 2;
Gilles Peskinee59236f2018-01-27 23:32:46 +0100135} psa_global_data_t;
136
137static psa_global_data_t global_data;
138
itayzafrir0adf0fc2018-09-06 16:24:41 +0300139#define GUARD_MODULE_INITIALIZED \
140 if( global_data.initialized == 0 ) \
141 return( PSA_ERROR_BAD_STATE );
142
Gilles Peskinee59236f2018-01-27 23:32:46 +0100143static psa_status_t mbedtls_to_psa_error( int ret )
144{
Gilles Peskinea5905292018-02-07 20:59:33 +0100145 /* If there's both a high-level code and low-level code, dispatch on
146 * the high-level code. */
147 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100148 {
149 case 0:
150 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100151
152 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
153 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
154 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
155 return( PSA_ERROR_NOT_SUPPORTED );
156 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
157 return( PSA_ERROR_HARDWARE_FAILURE );
158
159 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
160 return( PSA_ERROR_HARDWARE_FAILURE );
161
Gilles Peskine9a944802018-06-21 09:35:35 +0200162 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
163 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
164 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
165 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
166 case MBEDTLS_ERR_ASN1_INVALID_DATA:
167 return( PSA_ERROR_INVALID_ARGUMENT );
168 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
169 return( PSA_ERROR_INSUFFICIENT_MEMORY );
170 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
171 return( PSA_ERROR_BUFFER_TOO_SMALL );
172
Gilles Peskinea5905292018-02-07 20:59:33 +0100173 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
174 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
175 return( PSA_ERROR_NOT_SUPPORTED );
176 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
177 return( PSA_ERROR_HARDWARE_FAILURE );
178
179 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
180 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
181 return( PSA_ERROR_NOT_SUPPORTED );
182 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
183 return( PSA_ERROR_HARDWARE_FAILURE );
184
185 case MBEDTLS_ERR_CCM_BAD_INPUT:
186 return( PSA_ERROR_INVALID_ARGUMENT );
187 case MBEDTLS_ERR_CCM_AUTH_FAILED:
188 return( PSA_ERROR_INVALID_SIGNATURE );
189 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
190 return( PSA_ERROR_HARDWARE_FAILURE );
191
192 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
193 return( PSA_ERROR_NOT_SUPPORTED );
194 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
195 return( PSA_ERROR_INVALID_ARGUMENT );
196 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
197 return( PSA_ERROR_INSUFFICIENT_MEMORY );
198 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
199 return( PSA_ERROR_INVALID_PADDING );
200 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
201 return( PSA_ERROR_BAD_STATE );
202 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
203 return( PSA_ERROR_INVALID_SIGNATURE );
204 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
205 return( PSA_ERROR_TAMPERING_DETECTED );
206 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
207 return( PSA_ERROR_HARDWARE_FAILURE );
208
209 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
210 return( PSA_ERROR_HARDWARE_FAILURE );
211
212 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
213 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
214 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
215 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
216 return( PSA_ERROR_NOT_SUPPORTED );
217 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
218 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
219
220 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
221 return( PSA_ERROR_NOT_SUPPORTED );
222 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
223 return( PSA_ERROR_HARDWARE_FAILURE );
224
Gilles Peskinee59236f2018-01-27 23:32:46 +0100225 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
226 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
227 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
228 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100229
230 case MBEDTLS_ERR_GCM_AUTH_FAILED:
231 return( PSA_ERROR_INVALID_SIGNATURE );
232 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200233 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100234 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
235 return( PSA_ERROR_HARDWARE_FAILURE );
236
237 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
238 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
239 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
240 return( PSA_ERROR_HARDWARE_FAILURE );
241
242 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
243 return( PSA_ERROR_NOT_SUPPORTED );
244 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
245 return( PSA_ERROR_INVALID_ARGUMENT );
246 case MBEDTLS_ERR_MD_ALLOC_FAILED:
247 return( PSA_ERROR_INSUFFICIENT_MEMORY );
248 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
249 return( PSA_ERROR_STORAGE_FAILURE );
250 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
251 return( PSA_ERROR_HARDWARE_FAILURE );
252
Gilles Peskinef76aa772018-10-29 19:24:33 +0100253 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
254 return( PSA_ERROR_STORAGE_FAILURE );
255 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
256 return( PSA_ERROR_INVALID_ARGUMENT );
257 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
258 return( PSA_ERROR_INVALID_ARGUMENT );
259 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
260 return( PSA_ERROR_BUFFER_TOO_SMALL );
261 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
262 return( PSA_ERROR_INVALID_ARGUMENT );
263 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
264 return( PSA_ERROR_INVALID_ARGUMENT );
265 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
266 return( PSA_ERROR_INVALID_ARGUMENT );
267 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
268 return( PSA_ERROR_INSUFFICIENT_MEMORY );
269
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100270 case MBEDTLS_ERR_PK_ALLOC_FAILED:
271 return( PSA_ERROR_INSUFFICIENT_MEMORY );
272 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
273 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
274 return( PSA_ERROR_INVALID_ARGUMENT );
275 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100276 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100277 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
278 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
279 return( PSA_ERROR_INVALID_ARGUMENT );
280 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
281 return( PSA_ERROR_NOT_SUPPORTED );
282 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
283 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
284 return( PSA_ERROR_NOT_PERMITTED );
285 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
286 return( PSA_ERROR_INVALID_ARGUMENT );
287 case MBEDTLS_ERR_PK_INVALID_ALG:
288 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
289 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
290 return( PSA_ERROR_NOT_SUPPORTED );
291 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
292 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100293 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
294 return( PSA_ERROR_HARDWARE_FAILURE );
295
296 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
297 return( PSA_ERROR_HARDWARE_FAILURE );
298
299 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
300 return( PSA_ERROR_INVALID_ARGUMENT );
301 case MBEDTLS_ERR_RSA_INVALID_PADDING:
302 return( PSA_ERROR_INVALID_PADDING );
303 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
304 return( PSA_ERROR_HARDWARE_FAILURE );
305 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
306 return( PSA_ERROR_INVALID_ARGUMENT );
307 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
308 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
309 return( PSA_ERROR_TAMPERING_DETECTED );
310 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
311 return( PSA_ERROR_INVALID_SIGNATURE );
312 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
313 return( PSA_ERROR_BUFFER_TOO_SMALL );
314 case MBEDTLS_ERR_RSA_RNG_FAILED:
315 return( PSA_ERROR_INSUFFICIENT_MEMORY );
316 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
317 return( PSA_ERROR_NOT_SUPPORTED );
318 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
319 return( PSA_ERROR_HARDWARE_FAILURE );
320
321 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
322 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
323 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
324 return( PSA_ERROR_HARDWARE_FAILURE );
325
326 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
327 return( PSA_ERROR_INVALID_ARGUMENT );
328 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
329 return( PSA_ERROR_HARDWARE_FAILURE );
330
itayzafrir5c753392018-05-08 11:18:38 +0300331 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300332 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300333 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300334 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
335 return( PSA_ERROR_BUFFER_TOO_SMALL );
336 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
337 return( PSA_ERROR_NOT_SUPPORTED );
338 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
339 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
340 return( PSA_ERROR_INVALID_SIGNATURE );
341 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
342 return( PSA_ERROR_INSUFFICIENT_MEMORY );
343 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
344 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300345
Gilles Peskinee59236f2018-01-27 23:32:46 +0100346 default:
347 return( PSA_ERROR_UNKNOWN_ERROR );
348 }
349}
350
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200351
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200352
353
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100354/****************************************************************/
355/* Key management */
356/****************************************************************/
357
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100358#if defined(MBEDTLS_ECP_C)
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200359static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
360{
361 switch( grpid )
362 {
363 case MBEDTLS_ECP_DP_SECP192R1:
364 return( PSA_ECC_CURVE_SECP192R1 );
365 case MBEDTLS_ECP_DP_SECP224R1:
366 return( PSA_ECC_CURVE_SECP224R1 );
367 case MBEDTLS_ECP_DP_SECP256R1:
368 return( PSA_ECC_CURVE_SECP256R1 );
369 case MBEDTLS_ECP_DP_SECP384R1:
370 return( PSA_ECC_CURVE_SECP384R1 );
371 case MBEDTLS_ECP_DP_SECP521R1:
372 return( PSA_ECC_CURVE_SECP521R1 );
373 case MBEDTLS_ECP_DP_BP256R1:
374 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
375 case MBEDTLS_ECP_DP_BP384R1:
376 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
377 case MBEDTLS_ECP_DP_BP512R1:
378 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
379 case MBEDTLS_ECP_DP_CURVE25519:
380 return( PSA_ECC_CURVE_CURVE25519 );
381 case MBEDTLS_ECP_DP_SECP192K1:
382 return( PSA_ECC_CURVE_SECP192K1 );
383 case MBEDTLS_ECP_DP_SECP224K1:
384 return( PSA_ECC_CURVE_SECP224K1 );
385 case MBEDTLS_ECP_DP_SECP256K1:
386 return( PSA_ECC_CURVE_SECP256K1 );
387 case MBEDTLS_ECP_DP_CURVE448:
388 return( PSA_ECC_CURVE_CURVE448 );
389 default:
390 return( 0 );
391 }
392}
393
Gilles Peskine12313cd2018-06-20 00:20:32 +0200394static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
395{
396 switch( curve )
397 {
398 case PSA_ECC_CURVE_SECP192R1:
399 return( MBEDTLS_ECP_DP_SECP192R1 );
400 case PSA_ECC_CURVE_SECP224R1:
401 return( MBEDTLS_ECP_DP_SECP224R1 );
402 case PSA_ECC_CURVE_SECP256R1:
403 return( MBEDTLS_ECP_DP_SECP256R1 );
404 case PSA_ECC_CURVE_SECP384R1:
405 return( MBEDTLS_ECP_DP_SECP384R1 );
406 case PSA_ECC_CURVE_SECP521R1:
407 return( MBEDTLS_ECP_DP_SECP521R1 );
408 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
409 return( MBEDTLS_ECP_DP_BP256R1 );
410 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
411 return( MBEDTLS_ECP_DP_BP384R1 );
412 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
413 return( MBEDTLS_ECP_DP_BP512R1 );
414 case PSA_ECC_CURVE_CURVE25519:
415 return( MBEDTLS_ECP_DP_CURVE25519 );
416 case PSA_ECC_CURVE_SECP192K1:
417 return( MBEDTLS_ECP_DP_SECP192K1 );
418 case PSA_ECC_CURVE_SECP224K1:
419 return( MBEDTLS_ECP_DP_SECP224K1 );
420 case PSA_ECC_CURVE_SECP256K1:
421 return( MBEDTLS_ECP_DP_SECP256K1 );
422 case PSA_ECC_CURVE_CURVE448:
423 return( MBEDTLS_ECP_DP_CURVE448 );
424 default:
425 return( MBEDTLS_ECP_DP_NONE );
426 }
427}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100428#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200429
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200430static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
431 size_t bits,
432 struct raw_data *raw )
433{
434 /* Check that the bit size is acceptable for the key type */
435 switch( type )
436 {
437 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200438 if( bits == 0 )
439 {
440 raw->bytes = 0;
441 raw->data = NULL;
442 return( PSA_SUCCESS );
443 }
444 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200445#if defined(MBEDTLS_MD_C)
446 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200447#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200448 case PSA_KEY_TYPE_DERIVE:
449 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200450#if defined(MBEDTLS_AES_C)
451 case PSA_KEY_TYPE_AES:
452 if( bits != 128 && bits != 192 && bits != 256 )
453 return( PSA_ERROR_INVALID_ARGUMENT );
454 break;
455#endif
456#if defined(MBEDTLS_CAMELLIA_C)
457 case PSA_KEY_TYPE_CAMELLIA:
458 if( bits != 128 && bits != 192 && bits != 256 )
459 return( PSA_ERROR_INVALID_ARGUMENT );
460 break;
461#endif
462#if defined(MBEDTLS_DES_C)
463 case PSA_KEY_TYPE_DES:
464 if( bits != 64 && bits != 128 && bits != 192 )
465 return( PSA_ERROR_INVALID_ARGUMENT );
466 break;
467#endif
468#if defined(MBEDTLS_ARC4_C)
469 case PSA_KEY_TYPE_ARC4:
470 if( bits < 8 || bits > 2048 )
471 return( PSA_ERROR_INVALID_ARGUMENT );
472 break;
473#endif
474 default:
475 return( PSA_ERROR_NOT_SUPPORTED );
476 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200477 if( bits % 8 != 0 )
478 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200479
480 /* Allocate memory for the key */
481 raw->bytes = PSA_BITS_TO_BYTES( bits );
482 raw->data = mbedtls_calloc( 1, raw->bytes );
483 if( raw->data == NULL )
484 {
485 raw->bytes = 0;
486 return( PSA_ERROR_INSUFFICIENT_MEMORY );
487 }
488 return( PSA_SUCCESS );
489}
490
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200491#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine86a440b2018-11-12 18:39:40 +0100492/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
493 * that are not a multiple of 8) well. For example, there is only
494 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
495 * way to return the exact bit size of a key.
496 * To keep things simple, reject non-byte-aligned key sizes. */
497static psa_status_t psa_check_rsa_key_byte_aligned(
498 const mbedtls_rsa_context *rsa )
499{
500 mbedtls_mpi n;
501 psa_status_t status;
502 mbedtls_mpi_init( &n );
503 status = mbedtls_to_psa_error(
504 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
505 if( status == PSA_SUCCESS )
506 {
507 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
508 status = PSA_ERROR_NOT_SUPPORTED;
509 }
510 mbedtls_mpi_free( &n );
511 return( status );
512}
513
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200514static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
515 mbedtls_rsa_context **p_rsa )
516{
517 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
518 return( PSA_ERROR_INVALID_ARGUMENT );
519 else
520 {
521 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
Gilles Peskineaac64a22018-11-12 18:37:42 +0100522 /* The size of an RSA key doesn't have to be a multiple of 8.
523 * Mbed TLS supports non-byte-aligned key sizes, but not well.
524 * For example, mbedtls_rsa_get_len() returns the key size in
525 * bytes, not in bits. */
526 size_t bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100527 psa_status_t status;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200528 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
529 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100530 status = psa_check_rsa_key_byte_aligned( rsa );
531 if( status != PSA_SUCCESS )
532 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200533 *p_rsa = rsa;
534 return( PSA_SUCCESS );
535 }
536}
537#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
538
539#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinef76aa772018-10-29 19:24:33 +0100540/* Import an elliptic curve parsed by the mbedtls pk module. */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200541static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
542 mbedtls_pk_context *pk,
543 mbedtls_ecp_keypair **p_ecp )
544{
545 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
546 return( PSA_ERROR_INVALID_ARGUMENT );
547 else
548 {
549 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
550 psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
551 if( actual_curve != expected_curve )
552 return( PSA_ERROR_INVALID_ARGUMENT );
553 *p_ecp = ecp;
554 return( PSA_SUCCESS );
555 }
556}
557#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
558
Gilles Peskinef76aa772018-10-29 19:24:33 +0100559#if defined(MBEDTLS_ECP_C)
560/* Import a private key given as a byte string which is the private value
561 * in big-endian order. */
562static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
563 const uint8_t *data,
564 size_t data_length,
565 mbedtls_ecp_keypair **p_ecp )
566{
567 psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
568 mbedtls_ecp_keypair *ecp = NULL;
569 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
570
571 *p_ecp = NULL;
572 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
573 if( ecp == NULL )
574 return( PSA_ERROR_INSUFFICIENT_MEMORY );
575
576 /* Load the group. */
577 status = mbedtls_to_psa_error(
578 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
579 if( status != PSA_SUCCESS )
580 goto exit;
581 /* Load the secret value. */
582 status = mbedtls_to_psa_error(
583 mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
584 if( status != PSA_SUCCESS )
585 goto exit;
586 /* Validate the private key. */
587 status = mbedtls_to_psa_error(
588 mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
589 if( status != PSA_SUCCESS )
590 goto exit;
591 /* Calculate the public key from the private key. */
592 status = mbedtls_to_psa_error(
593 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
594 mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
595 if( status != PSA_SUCCESS )
596 goto exit;
597
598 *p_ecp = ecp;
599 return( PSA_SUCCESS );
600
601exit:
602 if( ecp != NULL )
603 {
604 mbedtls_ecp_keypair_free( ecp );
605 mbedtls_free( ecp );
606 }
607 return( status );
608}
609#endif /* defined(MBEDTLS_ECP_C) */
610
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100611/** Import key data into a slot. `slot->type` must have been set
612 * previously. This function assumes that the slot does not contain
613 * any key material yet. On failure, the slot content is unchanged. */
Gilles Peskinefa4135b2018-12-10 16:48:53 +0100614psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
615 const uint8_t *data,
616 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100617{
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200618 psa_status_t status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100619
Darryl Green940d72c2018-07-13 13:18:51 +0100620 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100621 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100622 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100623 if( data_length > SIZE_MAX / 8 )
624 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green940d72c2018-07-13 13:18:51 +0100625 status = prepare_raw_data_slot( slot->type,
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200626 PSA_BYTES_TO_BITS( data_length ),
627 &slot->data.raw );
628 if( status != PSA_SUCCESS )
629 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200630 if( data_length != 0 )
631 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100632 }
633 else
Gilles Peskinef76aa772018-10-29 19:24:33 +0100634#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100635 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100636 {
Darryl Green940d72c2018-07-13 13:18:51 +0100637 status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskinef76aa772018-10-29 19:24:33 +0100638 data, data_length,
639 &slot->data.ecp );
640 if( status != PSA_SUCCESS )
641 return( status );
642 }
643 else
644#endif /* MBEDTLS_ECP_C */
Gilles Peskine969ac722018-01-28 18:16:59 +0100645#if defined(MBEDTLS_PK_PARSE_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100646 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
647 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100648 {
649 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100650 mbedtls_pk_context pk;
651 mbedtls_pk_init( &pk );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200652
653 /* Parse the data. */
Darryl Green940d72c2018-07-13 13:18:51 +0100654 if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100655 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
656 else
657 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100658 if( ret != 0 )
659 return( mbedtls_to_psa_error( ret ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200660
661 /* We have something that the pkparse module recognizes.
662 * If it has the expected type and passes any type-specific
663 * checks, store it. */
Gilles Peskine969ac722018-01-28 18:16:59 +0100664#if defined(MBEDTLS_RSA_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100665 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200666 status = psa_import_rsa_key( &pk, &slot->data.rsa );
667 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100668#endif /* MBEDTLS_RSA_C */
669#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100670 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
671 status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200672 &pk, &slot->data.ecp );
673 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100674#endif /* MBEDTLS_ECP_C */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200675 {
676 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinec648d692018-06-28 08:46:13 +0200677 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200678
Gilles Peskinec648d692018-06-28 08:46:13 +0200679 /* Free the content of the pk object only on error. On success,
680 * the content of the object has been stored in the slot. */
681 if( status != PSA_SUCCESS )
682 {
683 mbedtls_pk_free( &pk );
684 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100685 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100686 }
687 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100688#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100689 {
690 return( PSA_ERROR_NOT_SUPPORTED );
691 }
Darryl Green940d72c2018-07-13 13:18:51 +0100692 return( PSA_SUCCESS );
693}
694
Darryl Green06fd18d2018-07-16 11:21:11 +0100695/* Retrieve an empty key slot (slot with no key data, but possibly
696 * with some metadata such as a policy). */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100697static psa_status_t psa_get_empty_key_slot( psa_key_handle_t handle,
Gilles Peskine2f060a82018-12-04 17:12:32 +0100698 psa_key_slot_t **p_slot )
Darryl Green06fd18d2018-07-16 11:21:11 +0100699{
700 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +0100701 psa_key_slot_t *slot = NULL;
Darryl Green06fd18d2018-07-16 11:21:11 +0100702
703 *p_slot = NULL;
704
Gilles Peskinec5487a82018-12-03 18:08:14 +0100705 status = psa_get_key_slot( handle, &slot );
Darryl Green06fd18d2018-07-16 11:21:11 +0100706 if( status != PSA_SUCCESS )
707 return( status );
708
709 if( slot->type != PSA_KEY_TYPE_NONE )
710 return( PSA_ERROR_OCCUPIED_SLOT );
711
712 *p_slot = slot;
713 return( status );
714}
715
716/** Retrieve a slot which must contain a key. The key must have allow all the
717 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
718 * operations with this algorithm. */
Gilles Peskinec5487a82018-12-03 18:08:14 +0100719static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle,
Gilles Peskine2f060a82018-12-04 17:12:32 +0100720 psa_key_slot_t **p_slot,
Darryl Green06fd18d2018-07-16 11:21:11 +0100721 psa_key_usage_t usage,
722 psa_algorithm_t alg )
723{
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 if( slot->type == PSA_KEY_TYPE_NONE )
733 return( PSA_ERROR_EMPTY_SLOT );
734
735 /* Enforce that usage policy for the key slot contains all the flags
736 * required by the usage parameter. There is one exception: public
737 * keys can always be exported, so we treat public key objects as
738 * if they had the export flag. */
739 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
740 usage &= ~PSA_KEY_USAGE_EXPORT;
741 if( ( slot->policy.usage & usage ) != usage )
742 return( PSA_ERROR_NOT_PERMITTED );
743 if( alg != 0 && ( alg != slot->policy.alg ) )
744 return( PSA_ERROR_NOT_PERMITTED );
745
746 *p_slot = slot;
747 return( PSA_SUCCESS );
748}
Darryl Green940d72c2018-07-13 13:18:51 +0100749
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100750/** Wipe key data from a slot. Preserve metadata such as the policy. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100751static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
Darryl Green40225ba2018-11-15 14:48:15 +0000752{
753 if( slot->type == PSA_KEY_TYPE_NONE )
754 {
755 /* No key material to clean. */
756 }
757 else if( key_type_is_raw_bytes( slot->type ) )
758 {
759 mbedtls_free( slot->data.raw.data );
760 }
761 else
762#if defined(MBEDTLS_RSA_C)
763 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
764 {
765 mbedtls_rsa_free( slot->data.rsa );
766 mbedtls_free( slot->data.rsa );
767 }
768 else
769#endif /* defined(MBEDTLS_RSA_C) */
770#if defined(MBEDTLS_ECP_C)
771 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
772 {
773 mbedtls_ecp_keypair_free( slot->data.ecp );
774 mbedtls_free( slot->data.ecp );
775 }
776 else
777#endif /* defined(MBEDTLS_ECP_C) */
778 {
779 /* Shouldn't happen: the key type is not any type that we
780 * put in. */
781 return( PSA_ERROR_TAMPERING_DETECTED );
782 }
783
784 return( PSA_SUCCESS );
785}
786
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100787/** Completely wipe a slot in memory, including its policy.
788 * Persistent storage is not affected. */
Gilles Peskine66fb1262018-12-10 16:29:04 +0100789psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100790{
791 psa_status_t status = psa_remove_key_data_from_memory( slot );
792 /* At this point, key material and other type-specific content has
793 * been wiped. Clear remaining metadata. We can call memset and not
794 * zeroize because the metadata is not particularly sensitive. */
795 memset( slot, 0, sizeof( *slot ) );
796 return( status );
797}
798
Gilles Peskinec5487a82018-12-03 18:08:14 +0100799psa_status_t psa_import_key( psa_key_handle_t handle,
Darryl Green940d72c2018-07-13 13:18:51 +0100800 psa_key_type_t type,
801 const uint8_t *data,
802 size_t data_length )
803{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100804 psa_key_slot_t *slot;
Darryl Green940d72c2018-07-13 13:18:51 +0100805 psa_status_t status;
806
Gilles Peskinec5487a82018-12-03 18:08:14 +0100807 status = psa_get_empty_key_slot( handle, &slot );
Darryl Green940d72c2018-07-13 13:18:51 +0100808 if( status != PSA_SUCCESS )
809 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100810
811 slot->type = type;
Darryl Green940d72c2018-07-13 13:18:51 +0100812
813 status = psa_import_key_into_slot( slot, data, data_length );
814 if( status != PSA_SUCCESS )
815 {
816 slot->type = PSA_KEY_TYPE_NONE;
817 return( status );
818 }
819
Darryl Greend49a4992018-06-18 17:27:26 +0100820#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
821 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
822 {
823 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +0100824 status = psa_save_persistent_key( slot->persistent_storage_id,
825 slot->type, &slot->policy, data,
Darryl Greend49a4992018-06-18 17:27:26 +0100826 data_length );
827 if( status != PSA_SUCCESS )
828 {
829 (void) psa_remove_key_data_from_memory( slot );
830 slot->type = PSA_KEY_TYPE_NONE;
831 }
832 }
833#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
834
835 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100836}
837
Gilles Peskinec5487a82018-12-03 18:08:14 +0100838psa_status_t psa_destroy_key( psa_key_handle_t handle )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100839{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100840 psa_key_slot_t *slot;
Darryl Greend49a4992018-06-18 17:27:26 +0100841 psa_status_t status = PSA_SUCCESS;
842 psa_status_t storage_status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100843
Gilles Peskinec5487a82018-12-03 18:08:14 +0100844 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200845 if( status != PSA_SUCCESS )
846 return( status );
Darryl Greend49a4992018-06-18 17:27:26 +0100847#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
848 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
849 {
Gilles Peskine69f976b2018-11-30 18:46:56 +0100850 storage_status =
851 psa_destroy_persistent_key( slot->persistent_storage_id );
Darryl Greend49a4992018-06-18 17:27:26 +0100852 }
853#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100854 status = psa_wipe_key_slot( slot );
Darryl Greend49a4992018-06-18 17:27:26 +0100855 if( status != PSA_SUCCESS )
856 return( status );
857 return( storage_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100858}
859
Gilles Peskineb870b182018-07-06 16:02:09 +0200860/* Return the size of the key in the given slot, in bits. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100861static size_t psa_get_key_bits( const psa_key_slot_t *slot )
Gilles Peskineb870b182018-07-06 16:02:09 +0200862{
863 if( key_type_is_raw_bytes( slot->type ) )
864 return( slot->data.raw.bytes * 8 );
865#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200866 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaac64a22018-11-12 18:37:42 +0100867 return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
Gilles Peskineb870b182018-07-06 16:02:09 +0200868#endif /* defined(MBEDTLS_RSA_C) */
869#if defined(MBEDTLS_ECP_C)
870 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
871 return( slot->data.ecp->grp.pbits );
872#endif /* defined(MBEDTLS_ECP_C) */
873 /* Shouldn't happen except on an empty slot. */
874 return( 0 );
875}
876
Gilles Peskinec5487a82018-12-03 18:08:14 +0100877psa_status_t psa_get_key_information( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +0200878 psa_key_type_t *type,
879 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100880{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100881 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200882 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100883
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100884 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200885 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100886 if( bits != NULL )
887 *bits = 0;
Gilles Peskinec5487a82018-12-03 18:08:14 +0100888 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200889 if( status != PSA_SUCCESS )
890 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +0200891
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100892 if( slot->type == PSA_KEY_TYPE_NONE )
893 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200894 if( type != NULL )
895 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +0200896 if( bits != NULL )
897 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100898 return( PSA_SUCCESS );
899}
900
Gilles Peskine2f060a82018-12-04 17:12:32 +0100901static psa_status_t psa_internal_export_key( psa_key_slot_t *slot,
Gilles Peskine2d277862018-06-18 15:41:12 +0200902 uint8_t *data,
903 size_t data_size,
904 size_t *data_length,
905 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100906{
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100907 *data_length = 0;
908
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200909 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300910 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300911
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200912 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100913 {
914 if( slot->data.raw.bytes > data_size )
915 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine52b90182018-10-29 19:26:27 +0100916 if( data_size != 0 )
917 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200918 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine52b90182018-10-29 19:26:27 +0100919 memset( data + slot->data.raw.bytes, 0,
920 data_size - slot->data.raw.bytes );
921 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100922 *data_length = slot->data.raw.bytes;
923 return( PSA_SUCCESS );
924 }
Gilles Peskine188c71e2018-10-29 19:26:02 +0100925#if defined(MBEDTLS_ECP_C)
926 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
927 {
Darryl Greendd8fb772018-11-07 16:00:44 +0000928 psa_status_t status;
929
Gilles Peskine188c71e2018-10-29 19:26:02 +0100930 size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( slot ) );
931 if( bytes > data_size )
932 return( PSA_ERROR_BUFFER_TOO_SMALL );
933 status = mbedtls_to_psa_error(
934 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
935 if( status != PSA_SUCCESS )
936 return( status );
937 memset( data + bytes, 0, data_size - bytes );
938 *data_length = bytes;
939 return( PSA_SUCCESS );
940 }
941#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100942 else
Moran Peker17e36e12018-05-02 12:55:20 +0300943 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100944#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200945 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +0300946 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100947 {
Moran Pekera998bc62018-04-16 18:16:20 +0300948 mbedtls_pk_context pk;
949 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +0200950 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300951 {
Darryl Green9e2d7a02018-07-24 16:33:30 +0100952#if defined(MBEDTLS_RSA_C)
953 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +0300954 pk.pk_info = &mbedtls_rsa_info;
955 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +0100956#else
957 return( PSA_ERROR_NOT_SUPPORTED );
958#endif
Moran Pekera998bc62018-04-16 18:16:20 +0300959 }
960 else
961 {
Darryl Green9e2d7a02018-07-24 16:33:30 +0100962#if defined(MBEDTLS_ECP_C)
963 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +0300964 pk.pk_info = &mbedtls_eckey_info;
965 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +0100966#else
967 return( PSA_ERROR_NOT_SUPPORTED );
968#endif
Moran Pekera998bc62018-04-16 18:16:20 +0300969 }
Moran Pekerd7326592018-05-29 16:56:39 +0300970 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300971 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300972 else
973 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300974 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200975 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200976 /* If data_size is 0 then data may be NULL and then the
977 * call to memset would have undefined behavior. */
978 if( data_size != 0 )
979 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300980 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200981 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200982 /* The mbedtls_pk_xxx functions write to the end of the buffer.
983 * Move the data to the beginning and erase remaining data
984 * at the original location. */
985 if( 2 * (size_t) ret <= data_size )
986 {
987 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200988 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200989 }
990 else if( (size_t) ret < data_size )
991 {
992 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200993 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200994 }
Moran Pekera998bc62018-04-16 18:16:20 +0300995 *data_length = ret;
996 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100997 }
998 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100999#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +03001000 {
1001 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001002 it is valid for a special-purpose implementation to omit
1003 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001004 return( PSA_ERROR_NOT_SUPPORTED );
1005 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001006 }
1007}
1008
Gilles Peskinec5487a82018-12-03 18:08:14 +01001009psa_status_t psa_export_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001010 uint8_t *data,
1011 size_t data_size,
1012 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001013{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001014 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001015 psa_status_t status;
1016
1017 /* Set the key to empty now, so that even when there are errors, we always
1018 * set data_length to a value between 0 and data_size. On error, setting
1019 * the key to empty is a good choice because an empty key representation is
1020 * unlikely to be accepted anywhere. */
1021 *data_length = 0;
1022
1023 /* Export requires the EXPORT flag. There is an exception for public keys,
1024 * which don't require any flag, but psa_get_key_from_slot takes
1025 * care of this. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001026 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_EXPORT, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001027 if( status != PSA_SUCCESS )
1028 return( status );
1029 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001030 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001031}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001032
Gilles Peskinec5487a82018-12-03 18:08:14 +01001033psa_status_t psa_export_public_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001034 uint8_t *data,
1035 size_t data_size,
1036 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001037{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001038 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001039 psa_status_t status;
1040
1041 /* Set the key to empty now, so that even when there are errors, we always
1042 * set data_length to a value between 0 and data_size. On error, setting
1043 * the key to empty is a good choice because an empty key representation is
1044 * unlikely to be accepted anywhere. */
1045 *data_length = 0;
1046
1047 /* Exporting a public key doesn't require a usage flag. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001048 status = psa_get_key_from_slot( handle, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001049 if( status != PSA_SUCCESS )
1050 return( status );
1051 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001052 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001053}
1054
Darryl Green0c6575a2018-11-07 16:05:30 +00001055#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine2f060a82018-12-04 17:12:32 +01001056static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t *slot,
Darryl Green0c6575a2018-11-07 16:05:30 +00001057 size_t bits )
1058{
1059 psa_status_t status;
1060 uint8_t *data;
1061 size_t key_length;
1062 size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits );
1063 data = mbedtls_calloc( 1, data_size );
itayzafrir910c76b2018-11-21 16:03:21 +02001064 if( data == NULL )
1065 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Darryl Green0c6575a2018-11-07 16:05:30 +00001066 /* Get key data in export format */
1067 status = psa_internal_export_key( slot, data, data_size, &key_length, 0 );
1068 if( status != PSA_SUCCESS )
1069 {
1070 slot->type = PSA_KEY_TYPE_NONE;
1071 goto exit;
1072 }
1073 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +01001074 status = psa_save_persistent_key( slot->persistent_storage_id,
1075 slot->type, &slot->policy,
Darryl Green0c6575a2018-11-07 16:05:30 +00001076 data, key_length );
1077 if( status != PSA_SUCCESS )
1078 {
1079 slot->type = PSA_KEY_TYPE_NONE;
1080 }
1081exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01001082 mbedtls_platform_zeroize( data, key_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00001083 mbedtls_free( data );
1084 return( status );
1085}
1086#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1087
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001088
1089
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001090/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001091/* Message digests */
1092/****************************************************************/
1093
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001094static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01001095{
1096 switch( alg )
1097 {
1098#if defined(MBEDTLS_MD2_C)
1099 case PSA_ALG_MD2:
1100 return( &mbedtls_md2_info );
1101#endif
1102#if defined(MBEDTLS_MD4_C)
1103 case PSA_ALG_MD4:
1104 return( &mbedtls_md4_info );
1105#endif
1106#if defined(MBEDTLS_MD5_C)
1107 case PSA_ALG_MD5:
1108 return( &mbedtls_md5_info );
1109#endif
1110#if defined(MBEDTLS_RIPEMD160_C)
1111 case PSA_ALG_RIPEMD160:
1112 return( &mbedtls_ripemd160_info );
1113#endif
1114#if defined(MBEDTLS_SHA1_C)
1115 case PSA_ALG_SHA_1:
1116 return( &mbedtls_sha1_info );
1117#endif
1118#if defined(MBEDTLS_SHA256_C)
1119 case PSA_ALG_SHA_224:
1120 return( &mbedtls_sha224_info );
1121 case PSA_ALG_SHA_256:
1122 return( &mbedtls_sha256_info );
1123#endif
1124#if defined(MBEDTLS_SHA512_C)
1125 case PSA_ALG_SHA_384:
1126 return( &mbedtls_sha384_info );
1127 case PSA_ALG_SHA_512:
1128 return( &mbedtls_sha512_info );
1129#endif
1130 default:
1131 return( NULL );
1132 }
1133}
1134
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001135psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
1136{
1137 switch( operation->alg )
1138 {
Gilles Peskine81736312018-06-26 15:04:31 +02001139 case 0:
1140 /* The object has (apparently) been initialized but it is not
1141 * in use. It's ok to call abort on such an object, and there's
1142 * nothing to do. */
1143 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001144#if defined(MBEDTLS_MD2_C)
1145 case PSA_ALG_MD2:
1146 mbedtls_md2_free( &operation->ctx.md2 );
1147 break;
1148#endif
1149#if defined(MBEDTLS_MD4_C)
1150 case PSA_ALG_MD4:
1151 mbedtls_md4_free( &operation->ctx.md4 );
1152 break;
1153#endif
1154#if defined(MBEDTLS_MD5_C)
1155 case PSA_ALG_MD5:
1156 mbedtls_md5_free( &operation->ctx.md5 );
1157 break;
1158#endif
1159#if defined(MBEDTLS_RIPEMD160_C)
1160 case PSA_ALG_RIPEMD160:
1161 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
1162 break;
1163#endif
1164#if defined(MBEDTLS_SHA1_C)
1165 case PSA_ALG_SHA_1:
1166 mbedtls_sha1_free( &operation->ctx.sha1 );
1167 break;
1168#endif
1169#if defined(MBEDTLS_SHA256_C)
1170 case PSA_ALG_SHA_224:
1171 case PSA_ALG_SHA_256:
1172 mbedtls_sha256_free( &operation->ctx.sha256 );
1173 break;
1174#endif
1175#if defined(MBEDTLS_SHA512_C)
1176 case PSA_ALG_SHA_384:
1177 case PSA_ALG_SHA_512:
1178 mbedtls_sha512_free( &operation->ctx.sha512 );
1179 break;
1180#endif
1181 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001182 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001183 }
1184 operation->alg = 0;
1185 return( PSA_SUCCESS );
1186}
1187
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02001188psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001189 psa_algorithm_t alg )
1190{
1191 int ret;
1192 operation->alg = 0;
1193 switch( alg )
1194 {
1195#if defined(MBEDTLS_MD2_C)
1196 case PSA_ALG_MD2:
1197 mbedtls_md2_init( &operation->ctx.md2 );
1198 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
1199 break;
1200#endif
1201#if defined(MBEDTLS_MD4_C)
1202 case PSA_ALG_MD4:
1203 mbedtls_md4_init( &operation->ctx.md4 );
1204 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
1205 break;
1206#endif
1207#if defined(MBEDTLS_MD5_C)
1208 case PSA_ALG_MD5:
1209 mbedtls_md5_init( &operation->ctx.md5 );
1210 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
1211 break;
1212#endif
1213#if defined(MBEDTLS_RIPEMD160_C)
1214 case PSA_ALG_RIPEMD160:
1215 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
1216 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
1217 break;
1218#endif
1219#if defined(MBEDTLS_SHA1_C)
1220 case PSA_ALG_SHA_1:
1221 mbedtls_sha1_init( &operation->ctx.sha1 );
1222 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1223 break;
1224#endif
1225#if defined(MBEDTLS_SHA256_C)
1226 case PSA_ALG_SHA_224:
1227 mbedtls_sha256_init( &operation->ctx.sha256 );
1228 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1229 break;
1230 case PSA_ALG_SHA_256:
1231 mbedtls_sha256_init( &operation->ctx.sha256 );
1232 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1233 break;
1234#endif
1235#if defined(MBEDTLS_SHA512_C)
1236 case PSA_ALG_SHA_384:
1237 mbedtls_sha512_init( &operation->ctx.sha512 );
1238 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1239 break;
1240 case PSA_ALG_SHA_512:
1241 mbedtls_sha512_init( &operation->ctx.sha512 );
1242 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1243 break;
1244#endif
1245 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001246 return( PSA_ALG_IS_HASH( alg ) ?
1247 PSA_ERROR_NOT_SUPPORTED :
1248 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001249 }
1250 if( ret == 0 )
1251 operation->alg = alg;
1252 else
1253 psa_hash_abort( operation );
1254 return( mbedtls_to_psa_error( ret ) );
1255}
1256
1257psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1258 const uint8_t *input,
1259 size_t input_length )
1260{
1261 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001262
1263 /* Don't require hash implementations to behave correctly on a
1264 * zero-length input, which may have an invalid pointer. */
1265 if( input_length == 0 )
1266 return( PSA_SUCCESS );
1267
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001268 switch( operation->alg )
1269 {
1270#if defined(MBEDTLS_MD2_C)
1271 case PSA_ALG_MD2:
1272 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1273 input, input_length );
1274 break;
1275#endif
1276#if defined(MBEDTLS_MD4_C)
1277 case PSA_ALG_MD4:
1278 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1279 input, input_length );
1280 break;
1281#endif
1282#if defined(MBEDTLS_MD5_C)
1283 case PSA_ALG_MD5:
1284 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1285 input, input_length );
1286 break;
1287#endif
1288#if defined(MBEDTLS_RIPEMD160_C)
1289 case PSA_ALG_RIPEMD160:
1290 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1291 input, input_length );
1292 break;
1293#endif
1294#if defined(MBEDTLS_SHA1_C)
1295 case PSA_ALG_SHA_1:
1296 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1297 input, input_length );
1298 break;
1299#endif
1300#if defined(MBEDTLS_SHA256_C)
1301 case PSA_ALG_SHA_224:
1302 case PSA_ALG_SHA_256:
1303 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1304 input, input_length );
1305 break;
1306#endif
1307#if defined(MBEDTLS_SHA512_C)
1308 case PSA_ALG_SHA_384:
1309 case PSA_ALG_SHA_512:
1310 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1311 input, input_length );
1312 break;
1313#endif
1314 default:
1315 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1316 break;
1317 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001318
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001319 if( ret != 0 )
1320 psa_hash_abort( operation );
1321 return( mbedtls_to_psa_error( ret ) );
1322}
1323
1324psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1325 uint8_t *hash,
1326 size_t hash_size,
1327 size_t *hash_length )
1328{
itayzafrir40835d42018-08-02 13:14:17 +03001329 psa_status_t status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001330 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001331 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001332
1333 /* Fill the output buffer with something that isn't a valid hash
1334 * (barring an attack on the hash and deliberately-crafted input),
1335 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001336 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001337 /* If hash_size is 0 then hash may be NULL and then the
1338 * call to memset would have undefined behavior. */
1339 if( hash_size != 0 )
1340 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001341
1342 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03001343 {
1344 status = PSA_ERROR_BUFFER_TOO_SMALL;
1345 goto exit;
1346 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001347
1348 switch( operation->alg )
1349 {
1350#if defined(MBEDTLS_MD2_C)
1351 case PSA_ALG_MD2:
1352 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1353 break;
1354#endif
1355#if defined(MBEDTLS_MD4_C)
1356 case PSA_ALG_MD4:
1357 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1358 break;
1359#endif
1360#if defined(MBEDTLS_MD5_C)
1361 case PSA_ALG_MD5:
1362 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1363 break;
1364#endif
1365#if defined(MBEDTLS_RIPEMD160_C)
1366 case PSA_ALG_RIPEMD160:
1367 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1368 break;
1369#endif
1370#if defined(MBEDTLS_SHA1_C)
1371 case PSA_ALG_SHA_1:
1372 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1373 break;
1374#endif
1375#if defined(MBEDTLS_SHA256_C)
1376 case PSA_ALG_SHA_224:
1377 case PSA_ALG_SHA_256:
1378 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1379 break;
1380#endif
1381#if defined(MBEDTLS_SHA512_C)
1382 case PSA_ALG_SHA_384:
1383 case PSA_ALG_SHA_512:
1384 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1385 break;
1386#endif
1387 default:
1388 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1389 break;
1390 }
itayzafrir40835d42018-08-02 13:14:17 +03001391 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001392
itayzafrir40835d42018-08-02 13:14:17 +03001393exit:
1394 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001395 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001396 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001397 return( psa_hash_abort( operation ) );
1398 }
1399 else
1400 {
1401 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03001402 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001403 }
1404}
1405
Gilles Peskine2d277862018-06-18 15:41:12 +02001406psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1407 const uint8_t *hash,
1408 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001409{
1410 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1411 size_t actual_hash_length;
1412 psa_status_t status = psa_hash_finish( operation,
1413 actual_hash, sizeof( actual_hash ),
1414 &actual_hash_length );
1415 if( status != PSA_SUCCESS )
1416 return( status );
1417 if( actual_hash_length != hash_length )
1418 return( PSA_ERROR_INVALID_SIGNATURE );
1419 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1420 return( PSA_ERROR_INVALID_SIGNATURE );
1421 return( PSA_SUCCESS );
1422}
1423
Gilles Peskineebb2c3e2019-01-19 12:03:41 +01001424psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
1425 psa_hash_operation_t *target_operation)
1426{
1427 if( target_operation->alg != 0 )
1428 return( PSA_ERROR_BAD_STATE );
1429
1430 switch( source_operation->alg )
1431 {
1432 case 0:
1433 return( PSA_ERROR_BAD_STATE );
1434#if defined(MBEDTLS_MD2_C)
1435 case PSA_ALG_MD2:
1436 mbedtls_md2_clone( &target_operation->ctx.md2,
1437 &source_operation->ctx.md2 );
1438 break;
1439#endif
1440#if defined(MBEDTLS_MD4_C)
1441 case PSA_ALG_MD4:
1442 mbedtls_md4_clone( &target_operation->ctx.md4,
1443 &source_operation->ctx.md4 );
1444 break;
1445#endif
1446#if defined(MBEDTLS_MD5_C)
1447 case PSA_ALG_MD5:
1448 mbedtls_md5_clone( &target_operation->ctx.md5,
1449 &source_operation->ctx.md5 );
1450 break;
1451#endif
1452#if defined(MBEDTLS_RIPEMD160_C)
1453 case PSA_ALG_RIPEMD160:
1454 mbedtls_ripemd160_clone( &target_operation->ctx.ripemd160,
1455 &source_operation->ctx.ripemd160 );
1456 break;
1457#endif
1458#if defined(MBEDTLS_SHA1_C)
1459 case PSA_ALG_SHA_1:
1460 mbedtls_sha1_clone( &target_operation->ctx.sha1,
1461 &source_operation->ctx.sha1 );
1462 break;
1463#endif
1464#if defined(MBEDTLS_SHA256_C)
1465 case PSA_ALG_SHA_224:
1466 case PSA_ALG_SHA_256:
1467 mbedtls_sha256_clone( &target_operation->ctx.sha256,
1468 &source_operation->ctx.sha256 );
1469 break;
1470#endif
1471#if defined(MBEDTLS_SHA512_C)
1472 case PSA_ALG_SHA_384:
1473 case PSA_ALG_SHA_512:
1474 mbedtls_sha512_clone( &target_operation->ctx.sha512,
1475 &source_operation->ctx.sha512 );
1476 break;
1477#endif
1478 default:
1479 return( PSA_ERROR_NOT_SUPPORTED );
1480 }
1481
1482 target_operation->alg = source_operation->alg;
1483 return( PSA_SUCCESS );
1484}
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001485
1486
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001487/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001488/* MAC */
1489/****************************************************************/
1490
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001491static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001492 psa_algorithm_t alg,
1493 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001494 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001495 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001496{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001497 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001498 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001499
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001500 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001501 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001502
Gilles Peskine8c9def32018-02-08 10:02:12 +01001503 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1504 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001505 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001506 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001507 case PSA_ALG_ARC4:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001508 mode = MBEDTLS_MODE_STREAM;
1509 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001510 case PSA_ALG_CTR:
1511 mode = MBEDTLS_MODE_CTR;
1512 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001513 case PSA_ALG_CFB:
1514 mode = MBEDTLS_MODE_CFB;
1515 break;
1516 case PSA_ALG_OFB:
1517 mode = MBEDTLS_MODE_OFB;
1518 break;
1519 case PSA_ALG_CBC_NO_PADDING:
1520 mode = MBEDTLS_MODE_CBC;
1521 break;
1522 case PSA_ALG_CBC_PKCS7:
1523 mode = MBEDTLS_MODE_CBC;
1524 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001525 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001526 mode = MBEDTLS_MODE_CCM;
1527 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001528 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001529 mode = MBEDTLS_MODE_GCM;
1530 break;
1531 default:
1532 return( NULL );
1533 }
1534 }
1535 else if( alg == PSA_ALG_CMAC )
1536 mode = MBEDTLS_MODE_ECB;
1537 else if( alg == PSA_ALG_GMAC )
1538 mode = MBEDTLS_MODE_GCM;
1539 else
1540 return( NULL );
1541
1542 switch( key_type )
1543 {
1544 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001545 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001546 break;
1547 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001548 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1549 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001550 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001551 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001552 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001553 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001554 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1555 * but two-key Triple-DES is functionally three-key Triple-DES
1556 * with K1=K3, so that's how we present it to mbedtls. */
1557 if( key_bits == 128 )
1558 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001559 break;
1560 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001561 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001562 break;
1563 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001564 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001565 break;
1566 default:
1567 return( NULL );
1568 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001569 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001570 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001571
Jaeden Amero23bbb752018-06-26 14:16:54 +01001572 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1573 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001574}
1575
Gilles Peskinea05219c2018-11-16 16:02:56 +01001576#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001577static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001578{
Gilles Peskine2d277862018-06-18 15:41:12 +02001579 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001580 {
1581 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001582 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001583 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001584 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001585 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001586 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001587 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001588 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001589 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001590 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001591 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001592 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001593 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001594 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001595 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001596 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001597 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001598 return( 128 );
1599 default:
1600 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001601 }
1602}
Gilles Peskinea05219c2018-11-16 16:02:56 +01001603#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001604
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001605/* Initialize the MAC operation structure. Once this function has been
1606 * called, psa_mac_abort can run and will do the right thing. */
1607static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1608 psa_algorithm_t alg )
1609{
1610 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1611
1612 operation->alg = alg;
1613 operation->key_set = 0;
1614 operation->iv_set = 0;
1615 operation->iv_required = 0;
1616 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001617 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001618
1619#if defined(MBEDTLS_CMAC_C)
1620 if( alg == PSA_ALG_CMAC )
1621 {
1622 operation->iv_required = 0;
1623 mbedtls_cipher_init( &operation->ctx.cmac );
1624 status = PSA_SUCCESS;
1625 }
1626 else
1627#endif /* MBEDTLS_CMAC_C */
1628#if defined(MBEDTLS_MD_C)
1629 if( PSA_ALG_IS_HMAC( operation->alg ) )
1630 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001631 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1632 operation->ctx.hmac.hash_ctx.alg = 0;
1633 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001634 }
1635 else
1636#endif /* MBEDTLS_MD_C */
1637 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001638 if( ! PSA_ALG_IS_MAC( alg ) )
1639 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001640 }
1641
1642 if( status != PSA_SUCCESS )
1643 memset( operation, 0, sizeof( *operation ) );
1644 return( status );
1645}
1646
Gilles Peskine01126fa2018-07-12 17:04:55 +02001647#if defined(MBEDTLS_MD_C)
1648static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1649{
Gilles Peskine3f108122018-12-07 18:14:53 +01001650 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001651 return( psa_hash_abort( &hmac->hash_ctx ) );
1652}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01001653
1654static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
1655{
1656 /* Instances of psa_hash_operation_s can be initialized by zeroization. */
1657 memset( hmac, 0, sizeof( *hmac ) );
1658}
Gilles Peskine01126fa2018-07-12 17:04:55 +02001659#endif /* MBEDTLS_MD_C */
1660
Gilles Peskine8c9def32018-02-08 10:02:12 +01001661psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1662{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001663 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001664 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001665 /* The object has (apparently) been initialized but it is not
1666 * in use. It's ok to call abort on such an object, and there's
1667 * nothing to do. */
1668 return( PSA_SUCCESS );
1669 }
1670 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001671#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001672 if( operation->alg == PSA_ALG_CMAC )
1673 {
1674 mbedtls_cipher_free( &operation->ctx.cmac );
1675 }
1676 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001677#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001678#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001679 if( PSA_ALG_IS_HMAC( operation->alg ) )
1680 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001681 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001682 }
1683 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001684#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001685 {
1686 /* Sanity check (shouldn't happen: operation->alg should
1687 * always have been initialized to a valid value). */
1688 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001689 }
Moran Peker41deec42018-04-04 15:43:05 +03001690
Gilles Peskine8c9def32018-02-08 10:02:12 +01001691 operation->alg = 0;
1692 operation->key_set = 0;
1693 operation->iv_set = 0;
1694 operation->iv_required = 0;
1695 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001696 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001697
Gilles Peskine8c9def32018-02-08 10:02:12 +01001698 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001699
1700bad_state:
1701 /* If abort is called on an uninitialized object, we can't trust
1702 * anything. Wipe the object in case it contains confidential data.
1703 * This may result in a memory leak if a pointer gets overwritten,
1704 * but it's too late to do anything about this. */
1705 memset( operation, 0, sizeof( *operation ) );
1706 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001707}
1708
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001709#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001710static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001711 size_t key_bits,
Gilles Peskine2f060a82018-12-04 17:12:32 +01001712 psa_key_slot_t *slot,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001713 const mbedtls_cipher_info_t *cipher_info )
1714{
1715 int ret;
1716
1717 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001718
1719 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1720 if( ret != 0 )
1721 return( ret );
1722
1723 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1724 slot->data.raw.data,
1725 key_bits );
1726 return( ret );
1727}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001728#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001729
Gilles Peskine248051a2018-06-20 16:09:38 +02001730#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001731static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1732 const uint8_t *key,
1733 size_t key_length,
1734 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001735{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001736 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001737 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001738 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001739 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001740 psa_status_t status;
1741
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001742 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1743 * overflow below. This should never trigger if the hash algorithm
1744 * is implemented correctly. */
1745 /* The size checks against the ipad and opad buffers cannot be written
1746 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1747 * because that triggers -Wlogical-op on GCC 7.3. */
1748 if( block_size > sizeof( ipad ) )
1749 return( PSA_ERROR_NOT_SUPPORTED );
1750 if( block_size > sizeof( hmac->opad ) )
1751 return( PSA_ERROR_NOT_SUPPORTED );
1752 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001753 return( PSA_ERROR_NOT_SUPPORTED );
1754
Gilles Peskined223b522018-06-11 18:12:58 +02001755 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001756 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001757 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001758 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001759 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001760 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001761 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001762 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001763 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001764 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001765 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001766 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001767 }
Gilles Peskine96889972018-07-12 17:07:03 +02001768 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1769 * but it is permitted. It is common when HMAC is used in HKDF, for
1770 * example. Don't call `memcpy` in the 0-length because `key` could be
1771 * an invalid pointer which would make the behavior undefined. */
1772 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001773 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001774
Gilles Peskined223b522018-06-11 18:12:58 +02001775 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1776 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001777 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001778 ipad[i] ^= 0x36;
1779 memset( ipad + key_length, 0x36, block_size - key_length );
1780
1781 /* Copy the key material from ipad to opad, flipping the requisite bits,
1782 * and filling the rest of opad with the requisite constant. */
1783 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001784 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1785 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001786
Gilles Peskine01126fa2018-07-12 17:04:55 +02001787 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001788 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001789 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001790
Gilles Peskine01126fa2018-07-12 17:04:55 +02001791 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001792
1793cleanup:
Gilles Peskine3f108122018-12-07 18:14:53 +01001794 mbedtls_platform_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001795
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001796 return( status );
1797}
Gilles Peskine248051a2018-06-20 16:09:38 +02001798#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001799
Gilles Peskine89167cb2018-07-08 20:12:23 +02001800static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001801 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001802 psa_algorithm_t alg,
1803 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001804{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001805 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001806 psa_key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001807 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001808 psa_key_usage_t usage =
1809 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskined911eb72018-08-14 15:18:45 +02001810 unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02001811 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001812
Gilles Peskined911eb72018-08-14 15:18:45 +02001813 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001814 if( status != PSA_SUCCESS )
1815 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001816 if( is_sign )
1817 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001818
Gilles Peskinec5487a82018-12-03 18:08:14 +01001819 status = psa_get_key_from_slot( handle, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001820 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001821 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001822 key_bits = psa_get_key_bits( slot );
1823
Gilles Peskine8c9def32018-02-08 10:02:12 +01001824#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001825 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001826 {
1827 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02001828 mbedtls_cipher_info_from_psa( full_length_alg,
1829 slot->type, key_bits, NULL );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001830 int ret;
1831 if( cipher_info == NULL )
1832 {
1833 status = PSA_ERROR_NOT_SUPPORTED;
1834 goto exit;
1835 }
1836 operation->mac_size = cipher_info->block_size;
1837 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1838 status = mbedtls_to_psa_error( ret );
1839 }
1840 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001841#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001842#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001843 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001844 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02001845 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001846 if( hash_alg == 0 )
1847 {
1848 status = PSA_ERROR_NOT_SUPPORTED;
1849 goto exit;
1850 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001851
1852 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1853 /* Sanity check. This shouldn't fail on a valid configuration. */
1854 if( operation->mac_size == 0 ||
1855 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1856 {
1857 status = PSA_ERROR_NOT_SUPPORTED;
1858 goto exit;
1859 }
1860
Gilles Peskine01126fa2018-07-12 17:04:55 +02001861 if( slot->type != PSA_KEY_TYPE_HMAC )
1862 {
1863 status = PSA_ERROR_INVALID_ARGUMENT;
1864 goto exit;
1865 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001866
Gilles Peskine01126fa2018-07-12 17:04:55 +02001867 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1868 slot->data.raw.data,
1869 slot->data.raw.bytes,
1870 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001871 }
1872 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001873#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001874 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00001875 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02001876 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001877 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001878
Gilles Peskined911eb72018-08-14 15:18:45 +02001879 if( truncated == 0 )
1880 {
1881 /* The "normal" case: untruncated algorithm. Nothing to do. */
1882 }
1883 else if( truncated < 4 )
1884 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02001885 /* A very short MAC is too short for security since it can be
1886 * brute-forced. Ancient protocols with 32-bit MACs do exist,
1887 * so we make this our minimum, even though 32 bits is still
1888 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02001889 status = PSA_ERROR_NOT_SUPPORTED;
1890 }
1891 else if( truncated > operation->mac_size )
1892 {
1893 /* It's impossible to "truncate" to a larger length. */
1894 status = PSA_ERROR_INVALID_ARGUMENT;
1895 }
1896 else
1897 operation->mac_size = truncated;
1898
Gilles Peskinefbfac682018-07-08 20:51:54 +02001899exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001900 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001901 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001902 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001903 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001904 else
1905 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001906 operation->key_set = 1;
1907 }
1908 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001909}
1910
Gilles Peskine89167cb2018-07-08 20:12:23 +02001911psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001912 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001913 psa_algorithm_t alg )
1914{
Gilles Peskinec5487a82018-12-03 18:08:14 +01001915 return( psa_mac_setup( operation, handle, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001916}
1917
1918psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001919 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001920 psa_algorithm_t alg )
1921{
Gilles Peskinec5487a82018-12-03 18:08:14 +01001922 return( psa_mac_setup( operation, handle, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001923}
1924
Gilles Peskine8c9def32018-02-08 10:02:12 +01001925psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1926 const uint8_t *input,
1927 size_t input_length )
1928{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001929 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001930 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001931 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001932 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001933 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001934 operation->has_input = 1;
1935
Gilles Peskine8c9def32018-02-08 10:02:12 +01001936#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001937 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001938 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001939 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1940 input, input_length );
1941 status = mbedtls_to_psa_error( ret );
1942 }
1943 else
1944#endif /* MBEDTLS_CMAC_C */
1945#if defined(MBEDTLS_MD_C)
1946 if( PSA_ALG_IS_HMAC( operation->alg ) )
1947 {
1948 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
1949 input_length );
1950 }
1951 else
1952#endif /* MBEDTLS_MD_C */
1953 {
1954 /* This shouldn't happen if `operation` was initialized by
1955 * a setup function. */
1956 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001957 }
1958
Gilles Peskinefbfac682018-07-08 20:51:54 +02001959cleanup:
1960 if( status != PSA_SUCCESS )
1961 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001962 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001963}
1964
Gilles Peskine01126fa2018-07-12 17:04:55 +02001965#if defined(MBEDTLS_MD_C)
1966static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
1967 uint8_t *mac,
1968 size_t mac_size )
1969{
1970 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
1971 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
1972 size_t hash_size = 0;
1973 size_t block_size = psa_get_hash_block_size( hash_alg );
1974 psa_status_t status;
1975
Gilles Peskine01126fa2018-07-12 17:04:55 +02001976 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1977 if( status != PSA_SUCCESS )
1978 return( status );
1979 /* From here on, tmp needs to be wiped. */
1980
1981 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
1982 if( status != PSA_SUCCESS )
1983 goto exit;
1984
1985 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
1986 if( status != PSA_SUCCESS )
1987 goto exit;
1988
1989 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
1990 if( status != PSA_SUCCESS )
1991 goto exit;
1992
Gilles Peskined911eb72018-08-14 15:18:45 +02001993 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1994 if( status != PSA_SUCCESS )
1995 goto exit;
1996
1997 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001998
1999exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01002000 mbedtls_platform_zeroize( tmp, hash_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02002001 return( status );
2002}
2003#endif /* MBEDTLS_MD_C */
2004
mohammad16036df908f2018-04-02 08:34:15 -07002005static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02002006 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002007 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002008{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02002009 if( ! operation->key_set )
2010 return( PSA_ERROR_BAD_STATE );
2011 if( operation->iv_required && ! operation->iv_set )
2012 return( PSA_ERROR_BAD_STATE );
2013
Gilles Peskine8c9def32018-02-08 10:02:12 +01002014 if( mac_size < operation->mac_size )
2015 return( PSA_ERROR_BUFFER_TOO_SMALL );
2016
Gilles Peskine8c9def32018-02-08 10:02:12 +01002017#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02002018 if( operation->alg == PSA_ALG_CMAC )
2019 {
Gilles Peskined911eb72018-08-14 15:18:45 +02002020 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
2021 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
2022 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02002023 memcpy( mac, tmp, operation->mac_size );
Gilles Peskine3f108122018-12-07 18:14:53 +01002024 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002025 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002026 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02002027 else
2028#endif /* MBEDTLS_CMAC_C */
2029#if defined(MBEDTLS_MD_C)
2030 if( PSA_ALG_IS_HMAC( operation->alg ) )
2031 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02002032 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02002033 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02002034 }
2035 else
2036#endif /* MBEDTLS_MD_C */
2037 {
2038 /* This shouldn't happen if `operation` was initialized by
2039 * a setup function. */
2040 return( PSA_ERROR_BAD_STATE );
2041 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01002042}
2043
Gilles Peskineacd4be32018-07-08 19:56:25 +02002044psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
2045 uint8_t *mac,
2046 size_t mac_size,
2047 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07002048{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002049 psa_status_t status;
2050
2051 /* Fill the output buffer with something that isn't a valid mac
2052 * (barring an attack on the mac and deliberately-crafted input),
2053 * in case the caller doesn't check the return status properly. */
2054 *mac_length = mac_size;
2055 /* If mac_size is 0 then mac may be NULL and then the
2056 * call to memset would have undefined behavior. */
2057 if( mac_size != 0 )
2058 memset( mac, '!', mac_size );
2059
Gilles Peskine89167cb2018-07-08 20:12:23 +02002060 if( ! operation->is_sign )
2061 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002062 status = PSA_ERROR_BAD_STATE;
2063 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002064 }
mohammad16036df908f2018-04-02 08:34:15 -07002065
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002066 status = psa_mac_finish_internal( operation, mac, mac_size );
2067
2068cleanup:
2069 if( status == PSA_SUCCESS )
2070 {
2071 status = psa_mac_abort( operation );
2072 if( status == PSA_SUCCESS )
2073 *mac_length = operation->mac_size;
2074 else
2075 memset( mac, '!', mac_size );
2076 }
2077 else
2078 psa_mac_abort( operation );
2079 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07002080}
2081
Gilles Peskineacd4be32018-07-08 19:56:25 +02002082psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
2083 const uint8_t *mac,
2084 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002085{
Gilles Peskine828ed142018-06-18 23:25:51 +02002086 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07002087 psa_status_t status;
2088
Gilles Peskine89167cb2018-07-08 20:12:23 +02002089 if( operation->is_sign )
2090 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002091 status = PSA_ERROR_BAD_STATE;
2092 goto cleanup;
2093 }
2094 if( operation->mac_size != mac_length )
2095 {
2096 status = PSA_ERROR_INVALID_SIGNATURE;
2097 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002098 }
mohammad16036df908f2018-04-02 08:34:15 -07002099
2100 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002101 actual_mac, sizeof( actual_mac ) );
2102
2103 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
2104 status = PSA_ERROR_INVALID_SIGNATURE;
2105
2106cleanup:
2107 if( status == PSA_SUCCESS )
2108 status = psa_mac_abort( operation );
2109 else
2110 psa_mac_abort( operation );
2111
Gilles Peskine3f108122018-12-07 18:14:53 +01002112 mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02002113
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002114 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002115}
2116
2117
Gilles Peskine20035e32018-02-03 22:44:14 +01002118
Gilles Peskine20035e32018-02-03 22:44:14 +01002119/****************************************************************/
2120/* Asymmetric cryptography */
2121/****************************************************************/
2122
Gilles Peskine2b450e32018-06-27 15:42:46 +02002123#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002124/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002125 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002126static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
2127 size_t hash_length,
2128 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002129{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02002130 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002131 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002132 *md_alg = mbedtls_md_get_type( md_info );
2133
2134 /* The Mbed TLS RSA module uses an unsigned int for hash length
2135 * parameters. Validate that it fits so that we don't risk an
2136 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002137#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002138 if( hash_length > UINT_MAX )
2139 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002140#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002141
2142#if defined(MBEDTLS_PKCS1_V15)
2143 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
2144 * must be correct. */
2145 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
2146 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002147 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002148 if( md_info == NULL )
2149 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002150 if( mbedtls_md_get_size( md_info ) != hash_length )
2151 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002152 }
2153#endif /* MBEDTLS_PKCS1_V15 */
2154
2155#if defined(MBEDTLS_PKCS1_V21)
2156 /* PSS requires a hash internally. */
2157 if( PSA_ALG_IS_RSA_PSS( alg ) )
2158 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002159 if( md_info == NULL )
2160 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002161 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002162#endif /* MBEDTLS_PKCS1_V21 */
2163
Gilles Peskine61b91d42018-06-08 16:09:36 +02002164 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002165}
2166
Gilles Peskine2b450e32018-06-27 15:42:46 +02002167static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
2168 psa_algorithm_t alg,
2169 const uint8_t *hash,
2170 size_t hash_length,
2171 uint8_t *signature,
2172 size_t signature_size,
2173 size_t *signature_length )
2174{
2175 psa_status_t status;
2176 int ret;
2177 mbedtls_md_type_t md_alg;
2178
2179 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2180 if( status != PSA_SUCCESS )
2181 return( status );
2182
Gilles Peskine630a18a2018-06-29 17:49:35 +02002183 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002184 return( PSA_ERROR_BUFFER_TOO_SMALL );
2185
2186#if defined(MBEDTLS_PKCS1_V15)
2187 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2188 {
2189 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2190 MBEDTLS_MD_NONE );
2191 ret = mbedtls_rsa_pkcs1_sign( rsa,
2192 mbedtls_ctr_drbg_random,
2193 &global_data.ctr_drbg,
2194 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002195 md_alg,
2196 (unsigned int) hash_length,
2197 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002198 signature );
2199 }
2200 else
2201#endif /* MBEDTLS_PKCS1_V15 */
2202#if defined(MBEDTLS_PKCS1_V21)
2203 if( PSA_ALG_IS_RSA_PSS( alg ) )
2204 {
2205 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2206 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
2207 mbedtls_ctr_drbg_random,
2208 &global_data.ctr_drbg,
2209 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002210 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002211 (unsigned int) hash_length,
2212 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002213 signature );
2214 }
2215 else
2216#endif /* MBEDTLS_PKCS1_V21 */
2217 {
2218 return( PSA_ERROR_INVALID_ARGUMENT );
2219 }
2220
2221 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002222 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002223 return( mbedtls_to_psa_error( ret ) );
2224}
2225
2226static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
2227 psa_algorithm_t alg,
2228 const uint8_t *hash,
2229 size_t hash_length,
2230 const uint8_t *signature,
2231 size_t signature_length )
2232{
2233 psa_status_t status;
2234 int ret;
2235 mbedtls_md_type_t md_alg;
2236
2237 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2238 if( status != PSA_SUCCESS )
2239 return( status );
2240
Gilles Peskine630a18a2018-06-29 17:49:35 +02002241 if( signature_length < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002242 return( PSA_ERROR_BUFFER_TOO_SMALL );
2243
2244#if defined(MBEDTLS_PKCS1_V15)
2245 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2246 {
2247 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2248 MBEDTLS_MD_NONE );
2249 ret = mbedtls_rsa_pkcs1_verify( rsa,
2250 mbedtls_ctr_drbg_random,
2251 &global_data.ctr_drbg,
2252 MBEDTLS_RSA_PUBLIC,
2253 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002254 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002255 hash,
2256 signature );
2257 }
2258 else
2259#endif /* MBEDTLS_PKCS1_V15 */
2260#if defined(MBEDTLS_PKCS1_V21)
2261 if( PSA_ALG_IS_RSA_PSS( alg ) )
2262 {
2263 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2264 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
2265 mbedtls_ctr_drbg_random,
2266 &global_data.ctr_drbg,
2267 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002268 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002269 (unsigned int) hash_length,
2270 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002271 signature );
2272 }
2273 else
2274#endif /* MBEDTLS_PKCS1_V21 */
2275 {
2276 return( PSA_ERROR_INVALID_ARGUMENT );
2277 }
Gilles Peskineef12c632018-09-13 20:37:48 +02002278
2279 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
2280 * the rest of the signature is invalid". This has little use in
2281 * practice and PSA doesn't report this distinction. */
2282 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
2283 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002284 return( mbedtls_to_psa_error( ret ) );
2285}
2286#endif /* MBEDTLS_RSA_C */
2287
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002288#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002289/* `ecp` cannot be const because `ecp->grp` needs to be non-const
2290 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
2291 * (even though these functions don't modify it). */
2292static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
2293 psa_algorithm_t alg,
2294 const uint8_t *hash,
2295 size_t hash_length,
2296 uint8_t *signature,
2297 size_t signature_size,
2298 size_t *signature_length )
2299{
2300 int ret;
2301 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002302 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002303 mbedtls_mpi_init( &r );
2304 mbedtls_mpi_init( &s );
2305
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002306 if( signature_size < 2 * curve_bytes )
2307 {
2308 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
2309 goto cleanup;
2310 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002311
Gilles Peskinea05219c2018-11-16 16:02:56 +01002312#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002313 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
2314 {
2315 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
2316 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2317 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2318 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
2319 hash, hash_length,
2320 md_alg ) );
2321 }
2322 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01002323#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002324 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01002325 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002326 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
2327 hash, hash_length,
2328 mbedtls_ctr_drbg_random,
2329 &global_data.ctr_drbg ) );
2330 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002331
2332 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
2333 signature,
2334 curve_bytes ) );
2335 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
2336 signature + curve_bytes,
2337 curve_bytes ) );
2338
2339cleanup:
2340 mbedtls_mpi_free( &r );
2341 mbedtls_mpi_free( &s );
2342 if( ret == 0 )
2343 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002344 return( mbedtls_to_psa_error( ret ) );
2345}
2346
2347static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2348 const uint8_t *hash,
2349 size_t hash_length,
2350 const uint8_t *signature,
2351 size_t signature_length )
2352{
2353 int ret;
2354 mbedtls_mpi r, s;
2355 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2356 mbedtls_mpi_init( &r );
2357 mbedtls_mpi_init( &s );
2358
2359 if( signature_length != 2 * curve_bytes )
2360 return( PSA_ERROR_INVALID_SIGNATURE );
2361
2362 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2363 signature,
2364 curve_bytes ) );
2365 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2366 signature + curve_bytes,
2367 curve_bytes ) );
2368
2369 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2370 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002371
2372cleanup:
2373 mbedtls_mpi_free( &r );
2374 mbedtls_mpi_free( &s );
2375 return( mbedtls_to_psa_error( ret ) );
2376}
2377#endif /* MBEDTLS_ECDSA_C */
2378
Gilles Peskinec5487a82018-12-03 18:08:14 +01002379psa_status_t psa_asymmetric_sign( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002380 psa_algorithm_t alg,
2381 const uint8_t *hash,
2382 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002383 uint8_t *signature,
2384 size_t signature_size,
2385 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002386{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002387 psa_key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002388 psa_status_t status;
2389
2390 *signature_length = signature_size;
2391
Gilles Peskinec5487a82018-12-03 18:08:14 +01002392 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002393 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002394 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002395 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002396 {
2397 status = PSA_ERROR_INVALID_ARGUMENT;
2398 goto exit;
2399 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002400
Gilles Peskine20035e32018-02-03 22:44:14 +01002401#if defined(MBEDTLS_RSA_C)
2402 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2403 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002404 status = psa_rsa_sign( slot->data.rsa,
2405 alg,
2406 hash, hash_length,
2407 signature, signature_size,
2408 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002409 }
2410 else
2411#endif /* defined(MBEDTLS_RSA_C) */
2412#if defined(MBEDTLS_ECP_C)
2413 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2414 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002415#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01002416 if(
2417#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
2418 PSA_ALG_IS_ECDSA( alg )
2419#else
2420 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
2421#endif
2422 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002423 status = psa_ecdsa_sign( slot->data.ecp,
2424 alg,
2425 hash, hash_length,
2426 signature, signature_size,
2427 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002428 else
2429#endif /* defined(MBEDTLS_ECDSA_C) */
2430 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002431 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002432 }
itayzafrir5c753392018-05-08 11:18:38 +03002433 }
2434 else
2435#endif /* defined(MBEDTLS_ECP_C) */
2436 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002437 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002438 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002439
2440exit:
2441 /* Fill the unused part of the output buffer (the whole buffer on error,
2442 * the trailing part on success) with something that isn't a valid mac
2443 * (barring an attack on the mac and deliberately-crafted input),
2444 * in case the caller doesn't check the return status properly. */
2445 if( status == PSA_SUCCESS )
2446 memset( signature + *signature_length, '!',
2447 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002448 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002449 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002450 /* If signature_size is 0 then we have nothing to do. We must not call
2451 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002452 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002453}
2454
Gilles Peskinec5487a82018-12-03 18:08:14 +01002455psa_status_t psa_asymmetric_verify( psa_key_handle_t handle,
itayzafrir5c753392018-05-08 11:18:38 +03002456 psa_algorithm_t alg,
2457 const uint8_t *hash,
2458 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002459 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002460 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002461{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002462 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002463 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002464
Gilles Peskinec5487a82018-12-03 18:08:14 +01002465 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002466 if( status != PSA_SUCCESS )
2467 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002468
Gilles Peskine61b91d42018-06-08 16:09:36 +02002469#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002470 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002471 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002472 return( psa_rsa_verify( slot->data.rsa,
2473 alg,
2474 hash, hash_length,
2475 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002476 }
2477 else
2478#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002479#if defined(MBEDTLS_ECP_C)
2480 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2481 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002482#if defined(MBEDTLS_ECDSA_C)
2483 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002484 return( psa_ecdsa_verify( slot->data.ecp,
2485 hash, hash_length,
2486 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002487 else
2488#endif /* defined(MBEDTLS_ECDSA_C) */
2489 {
2490 return( PSA_ERROR_INVALID_ARGUMENT );
2491 }
itayzafrir5c753392018-05-08 11:18:38 +03002492 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002493 else
2494#endif /* defined(MBEDTLS_ECP_C) */
2495 {
2496 return( PSA_ERROR_NOT_SUPPORTED );
2497 }
2498}
2499
Gilles Peskine072ac562018-06-30 00:21:29 +02002500#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2501static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2502 mbedtls_rsa_context *rsa )
2503{
2504 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2505 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2506 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2507 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2508}
2509#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2510
Gilles Peskinec5487a82018-12-03 18:08:14 +01002511psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002512 psa_algorithm_t alg,
2513 const uint8_t *input,
2514 size_t input_length,
2515 const uint8_t *salt,
2516 size_t salt_length,
2517 uint8_t *output,
2518 size_t output_size,
2519 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002520{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002521 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002522 psa_status_t status;
2523
Darryl Green5cc689a2018-07-24 15:34:10 +01002524 (void) input;
2525 (void) input_length;
2526 (void) salt;
2527 (void) output;
2528 (void) output_size;
2529
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002530 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002531
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002532 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2533 return( PSA_ERROR_INVALID_ARGUMENT );
2534
Gilles Peskinec5487a82018-12-03 18:08:14 +01002535 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002536 if( status != PSA_SUCCESS )
2537 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002538 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2539 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002540 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002541
2542#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002543 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002544 {
2545 mbedtls_rsa_context *rsa = slot->data.rsa;
2546 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002547 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002548 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002549#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002550 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002551 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002552 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2553 mbedtls_ctr_drbg_random,
2554 &global_data.ctr_drbg,
2555 MBEDTLS_RSA_PUBLIC,
2556 input_length,
2557 input,
2558 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002559 }
2560 else
2561#endif /* MBEDTLS_PKCS1_V15 */
2562#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002563 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002564 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002565 psa_rsa_oaep_set_padding_mode( alg, rsa );
2566 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2567 mbedtls_ctr_drbg_random,
2568 &global_data.ctr_drbg,
2569 MBEDTLS_RSA_PUBLIC,
2570 salt, salt_length,
2571 input_length,
2572 input,
2573 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002574 }
2575 else
2576#endif /* MBEDTLS_PKCS1_V21 */
2577 {
2578 return( PSA_ERROR_INVALID_ARGUMENT );
2579 }
2580 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002581 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002582 return( mbedtls_to_psa_error( ret ) );
2583 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002584 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002585#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002586 {
2587 return( PSA_ERROR_NOT_SUPPORTED );
2588 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002589}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002590
Gilles Peskinec5487a82018-12-03 18:08:14 +01002591psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002592 psa_algorithm_t alg,
2593 const uint8_t *input,
2594 size_t input_length,
2595 const uint8_t *salt,
2596 size_t salt_length,
2597 uint8_t *output,
2598 size_t output_size,
2599 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002600{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002601 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002602 psa_status_t status;
2603
Darryl Green5cc689a2018-07-24 15:34:10 +01002604 (void) input;
2605 (void) input_length;
2606 (void) salt;
2607 (void) output;
2608 (void) output_size;
2609
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002610 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002611
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002612 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2613 return( PSA_ERROR_INVALID_ARGUMENT );
2614
Gilles Peskinec5487a82018-12-03 18:08:14 +01002615 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002616 if( status != PSA_SUCCESS )
2617 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002618 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2619 return( PSA_ERROR_INVALID_ARGUMENT );
2620
2621#if defined(MBEDTLS_RSA_C)
2622 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2623 {
2624 mbedtls_rsa_context *rsa = slot->data.rsa;
2625 int ret;
2626
Gilles Peskine630a18a2018-06-29 17:49:35 +02002627 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002628 return( PSA_ERROR_INVALID_ARGUMENT );
2629
2630#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002631 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002632 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002633 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2634 mbedtls_ctr_drbg_random,
2635 &global_data.ctr_drbg,
2636 MBEDTLS_RSA_PRIVATE,
2637 output_length,
2638 input,
2639 output,
2640 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002641 }
2642 else
2643#endif /* MBEDTLS_PKCS1_V15 */
2644#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002645 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002646 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002647 psa_rsa_oaep_set_padding_mode( alg, rsa );
2648 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
2649 mbedtls_ctr_drbg_random,
2650 &global_data.ctr_drbg,
2651 MBEDTLS_RSA_PRIVATE,
2652 salt, salt_length,
2653 output_length,
2654 input,
2655 output,
2656 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002657 }
2658 else
2659#endif /* MBEDTLS_PKCS1_V21 */
2660 {
2661 return( PSA_ERROR_INVALID_ARGUMENT );
2662 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002663
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002664 return( mbedtls_to_psa_error( ret ) );
2665 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002666 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002667#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002668 {
2669 return( PSA_ERROR_NOT_SUPPORTED );
2670 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002671}
Gilles Peskine20035e32018-02-03 22:44:14 +01002672
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002673
2674
mohammad1603503973b2018-03-12 15:59:30 +02002675/****************************************************************/
2676/* Symmetric cryptography */
2677/****************************************************************/
2678
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002679/* Initialize the cipher operation structure. Once this function has been
2680 * called, psa_cipher_abort can run and will do the right thing. */
2681static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2682 psa_algorithm_t alg )
2683{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002684 if( ! PSA_ALG_IS_CIPHER( alg ) )
2685 {
2686 memset( operation, 0, sizeof( *operation ) );
2687 return( PSA_ERROR_INVALID_ARGUMENT );
2688 }
2689
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002690 operation->alg = alg;
2691 operation->key_set = 0;
2692 operation->iv_set = 0;
2693 operation->iv_required = 1;
2694 operation->iv_size = 0;
2695 operation->block_size = 0;
2696 mbedtls_cipher_init( &operation->ctx.cipher );
2697 return( PSA_SUCCESS );
2698}
2699
Gilles Peskinee553c652018-06-04 16:22:46 +02002700static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002701 psa_key_handle_t handle,
Gilles Peskine7e928852018-06-04 16:23:10 +02002702 psa_algorithm_t alg,
2703 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002704{
2705 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2706 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +01002707 psa_key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002708 size_t key_bits;
2709 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002710 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2711 PSA_KEY_USAGE_ENCRYPT :
2712 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002713
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002714 status = psa_cipher_init( operation, alg );
2715 if( status != PSA_SUCCESS )
2716 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002717
Gilles Peskinec5487a82018-12-03 18:08:14 +01002718 status = psa_get_key_from_slot( handle, &slot, usage, alg);
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002719 if( status != PSA_SUCCESS )
2720 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002721 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002722
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002723 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002724 if( cipher_info == NULL )
2725 return( PSA_ERROR_NOT_SUPPORTED );
2726
mohammad1603503973b2018-03-12 15:59:30 +02002727 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002728 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002729 {
2730 psa_cipher_abort( operation );
2731 return( mbedtls_to_psa_error( ret ) );
2732 }
2733
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002734#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002735 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002736 {
2737 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2738 unsigned char keys[24];
2739 memcpy( keys, slot->data.raw.data, 16 );
2740 memcpy( keys + 16, slot->data.raw.data, 8 );
2741 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2742 keys,
2743 192, cipher_operation );
2744 }
2745 else
2746#endif
2747 {
2748 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2749 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002750 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002751 }
Moran Peker41deec42018-04-04 15:43:05 +03002752 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002753 {
2754 psa_cipher_abort( operation );
2755 return( mbedtls_to_psa_error( ret ) );
2756 }
2757
mohammad16038481e742018-03-18 13:57:31 +02002758#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002759 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02002760 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002761 case PSA_ALG_CBC_NO_PADDING:
2762 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2763 MBEDTLS_PADDING_NONE );
2764 break;
2765 case PSA_ALG_CBC_PKCS7:
2766 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2767 MBEDTLS_PADDING_PKCS7 );
2768 break;
2769 default:
2770 /* The algorithm doesn't involve padding. */
2771 ret = 0;
2772 break;
2773 }
2774 if( ret != 0 )
2775 {
2776 psa_cipher_abort( operation );
2777 return( mbedtls_to_psa_error( ret ) );
mohammad16038481e742018-03-18 13:57:31 +02002778 }
2779#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2780
mohammad1603503973b2018-03-12 15:59:30 +02002781 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002782 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
2783 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
2784 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02002785 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002786 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002787 }
mohammad1603503973b2018-03-12 15:59:30 +02002788
Moran Peker395db872018-05-31 14:07:14 +03002789 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002790}
2791
Gilles Peskinefe119512018-07-08 21:39:34 +02002792psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002793 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02002794 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002795{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002796 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002797}
2798
Gilles Peskinefe119512018-07-08 21:39:34 +02002799psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002800 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02002801 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002802{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002803 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002804}
2805
Gilles Peskinefe119512018-07-08 21:39:34 +02002806psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2807 unsigned char *iv,
2808 size_t iv_size,
2809 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002810{
itayzafrir534bd7c2018-08-02 13:56:32 +03002811 psa_status_t status;
2812 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002813 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002814 {
2815 status = PSA_ERROR_BAD_STATE;
2816 goto exit;
2817 }
Moran Peker41deec42018-04-04 15:43:05 +03002818 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002819 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002820 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03002821 goto exit;
2822 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002823 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2824 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002825 if( ret != 0 )
2826 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002827 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002828 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002829 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002830
mohammad16038481e742018-03-18 13:57:31 +02002831 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03002832 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002833
Moran Peker395db872018-05-31 14:07:14 +03002834exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03002835 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03002836 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002837 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002838}
2839
Gilles Peskinefe119512018-07-08 21:39:34 +02002840psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2841 const unsigned char *iv,
2842 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002843{
itayzafrir534bd7c2018-08-02 13:56:32 +03002844 psa_status_t status;
2845 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002846 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002847 {
2848 status = PSA_ERROR_BAD_STATE;
2849 goto exit;
2850 }
Moran Pekera28258c2018-05-29 16:25:04 +03002851 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002852 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002853 status = PSA_ERROR_INVALID_ARGUMENT;
2854 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03002855 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002856 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
2857 status = mbedtls_to_psa_error( ret );
2858exit:
2859 if( status == PSA_SUCCESS )
2860 operation->iv_set = 1;
2861 else
mohammad1603503973b2018-03-12 15:59:30 +02002862 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002863 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002864}
2865
Gilles Peskinee553c652018-06-04 16:22:46 +02002866psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2867 const uint8_t *input,
2868 size_t input_length,
2869 unsigned char *output,
2870 size_t output_size,
2871 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002872{
itayzafrir534bd7c2018-08-02 13:56:32 +03002873 psa_status_t status;
2874 int ret;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002875 size_t expected_output_size;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002876 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002877 {
2878 /* Take the unprocessed partial block left over from previous
2879 * update calls, if any, plus the input to this call. Remove
2880 * the last partial block, if any. You get the data that will be
2881 * output in this call. */
2882 expected_output_size =
2883 ( operation->ctx.cipher.unprocessed_len + input_length )
2884 / operation->block_size * operation->block_size;
2885 }
2886 else
2887 {
2888 expected_output_size = input_length;
2889 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002890
Gilles Peskine89d789c2018-06-04 17:17:16 +02002891 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03002892 {
2893 status = PSA_ERROR_BUFFER_TOO_SMALL;
2894 goto exit;
2895 }
mohammad160382759612018-03-12 18:16:40 +02002896
mohammad1603503973b2018-03-12 15:59:30 +02002897 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002898 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03002899 status = mbedtls_to_psa_error( ret );
2900exit:
2901 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02002902 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002903 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002904}
2905
Gilles Peskinee553c652018-06-04 16:22:46 +02002906psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2907 uint8_t *output,
2908 size_t output_size,
2909 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002910{
Janos Follath315b51c2018-07-09 16:04:51 +01002911 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2912 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002913 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002914
mohammad1603503973b2018-03-12 15:59:30 +02002915 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002916 {
Janos Follath315b51c2018-07-09 16:04:51 +01002917 status = PSA_ERROR_BAD_STATE;
2918 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002919 }
2920 if( operation->iv_required && ! operation->iv_set )
2921 {
Janos Follath315b51c2018-07-09 16:04:51 +01002922 status = PSA_ERROR_BAD_STATE;
2923 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002924 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002925
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002926 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002927 operation->alg == PSA_ALG_CBC_NO_PADDING &&
2928 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03002929 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002930 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01002931 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002932 }
2933
Janos Follath315b51c2018-07-09 16:04:51 +01002934 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
2935 temp_output_buffer,
2936 output_length );
2937 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002938 {
Janos Follath315b51c2018-07-09 16:04:51 +01002939 status = mbedtls_to_psa_error( cipher_ret );
2940 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02002941 }
Janos Follath315b51c2018-07-09 16:04:51 +01002942
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002943 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01002944 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002945 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002946 memcpy( output, temp_output_buffer, *output_length );
2947 else
2948 {
Janos Follath315b51c2018-07-09 16:04:51 +01002949 status = PSA_ERROR_BUFFER_TOO_SMALL;
2950 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002951 }
mohammad1603503973b2018-03-12 15:59:30 +02002952
Gilles Peskine3f108122018-12-07 18:14:53 +01002953 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002954 status = psa_cipher_abort( operation );
2955
2956 return( status );
2957
2958error:
2959
2960 *output_length = 0;
2961
Gilles Peskine3f108122018-12-07 18:14:53 +01002962 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002963 (void) psa_cipher_abort( operation );
2964
2965 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002966}
2967
Gilles Peskinee553c652018-06-04 16:22:46 +02002968psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2969{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002970 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002971 {
2972 /* The object has (apparently) been initialized but it is not
2973 * in use. It's ok to call abort on such an object, and there's
2974 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002975 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002976 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002977
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002978 /* Sanity check (shouldn't happen: operation->alg should
2979 * always have been initialized to a valid value). */
2980 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2981 return( PSA_ERROR_BAD_STATE );
2982
mohammad1603503973b2018-03-12 15:59:30 +02002983 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002984
Moran Peker41deec42018-04-04 15:43:05 +03002985 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002986 operation->key_set = 0;
2987 operation->iv_set = 0;
2988 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002989 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002990 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002991
Moran Peker395db872018-05-31 14:07:14 +03002992 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002993}
2994
Gilles Peskinea0655c32018-04-30 17:06:50 +02002995
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002996
mohammad16038cc1cee2018-03-28 01:21:33 +03002997/****************************************************************/
2998/* Key Policy */
2999/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003000
mohammad160327010052018-07-03 13:16:15 +03003001#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02003002void psa_key_policy_set_usage( psa_key_policy_t *policy,
3003 psa_key_usage_t usage,
3004 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03003005{
mohammad16034eed7572018-03-28 05:14:59 -07003006 policy->usage = usage;
3007 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03003008}
3009
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003010psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003011{
mohammad16036df908f2018-04-02 08:34:15 -07003012 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03003013}
3014
Gilles Peskineaa7bc472018-07-12 00:54:56 +02003015psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003016{
mohammad16036df908f2018-04-02 08:34:15 -07003017 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03003018}
mohammad160327010052018-07-03 13:16:15 +03003019#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03003020
Gilles Peskinec5487a82018-12-03 18:08:14 +01003021psa_status_t psa_set_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003022 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003023{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003024 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003025 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003026
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003027 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003028 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003029
Gilles Peskinec5487a82018-12-03 18:08:14 +01003030 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003031 if( status != PSA_SUCCESS )
3032 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03003033
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02003034 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
3035 PSA_KEY_USAGE_ENCRYPT |
3036 PSA_KEY_USAGE_DECRYPT |
3037 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02003038 PSA_KEY_USAGE_VERIFY |
3039 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07003040 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03003041
mohammad16036df908f2018-04-02 08:34:15 -07003042 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003043
3044 return( PSA_SUCCESS );
3045}
3046
Gilles Peskinec5487a82018-12-03 18:08:14 +01003047psa_status_t psa_get_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003048 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03003049{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003050 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003051 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03003052
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003053 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003054 return( PSA_ERROR_INVALID_ARGUMENT );
3055
Gilles Peskinec5487a82018-12-03 18:08:14 +01003056 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003057 if( status != PSA_SUCCESS )
3058 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003059
mohammad16036df908f2018-04-02 08:34:15 -07003060 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003061
3062 return( PSA_SUCCESS );
3063}
Gilles Peskine20035e32018-02-03 22:44:14 +01003064
Gilles Peskinea0655c32018-04-30 17:06:50 +02003065
3066
mohammad1603804cd712018-03-20 22:44:08 +02003067/****************************************************************/
3068/* Key Lifetime */
3069/****************************************************************/
3070
Gilles Peskinec5487a82018-12-03 18:08:14 +01003071psa_status_t psa_get_key_lifetime( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003072 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003073{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003074 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003075 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003076
Gilles Peskinec5487a82018-12-03 18:08:14 +01003077 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003078 if( status != PSA_SUCCESS )
3079 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003080
mohammad1603804cd712018-03-20 22:44:08 +02003081 *lifetime = slot->lifetime;
3082
3083 return( PSA_SUCCESS );
3084}
3085
Gilles Peskine20035e32018-02-03 22:44:14 +01003086
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003087
mohammad16035955c982018-04-26 00:53:03 +03003088/****************************************************************/
3089/* AEAD */
3090/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003091
Gilles Peskineedf9a652018-08-17 18:11:56 +02003092typedef struct
3093{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003094 psa_key_slot_t *slot;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003095 const mbedtls_cipher_info_t *cipher_info;
3096 union
3097 {
3098#if defined(MBEDTLS_CCM_C)
3099 mbedtls_ccm_context ccm;
3100#endif /* MBEDTLS_CCM_C */
3101#if defined(MBEDTLS_GCM_C)
3102 mbedtls_gcm_context gcm;
3103#endif /* MBEDTLS_GCM_C */
3104 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003105 psa_algorithm_t core_alg;
3106 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003107 uint8_t tag_length;
3108} aead_operation_t;
3109
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003110static void psa_aead_abort( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003111{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003112 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003113 {
3114#if defined(MBEDTLS_CCM_C)
3115 case PSA_ALG_CCM:
3116 mbedtls_ccm_free( &operation->ctx.ccm );
3117 break;
3118#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003119#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02003120 case PSA_ALG_GCM:
3121 mbedtls_gcm_free( &operation->ctx.gcm );
3122 break;
3123#endif /* MBEDTLS_GCM_C */
3124 }
3125}
3126
3127static psa_status_t psa_aead_setup( aead_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003128 psa_key_handle_t handle,
Gilles Peskineedf9a652018-08-17 18:11:56 +02003129 psa_key_usage_t usage,
3130 psa_algorithm_t alg )
3131{
3132 psa_status_t status;
3133 size_t key_bits;
3134 mbedtls_cipher_id_t cipher_id;
3135
Gilles Peskinec5487a82018-12-03 18:08:14 +01003136 status = psa_get_key_from_slot( handle, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003137 if( status != PSA_SUCCESS )
3138 return( status );
3139
3140 key_bits = psa_get_key_bits( operation->slot );
3141
3142 operation->cipher_info =
3143 mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
3144 &cipher_id );
3145 if( operation->cipher_info == NULL )
3146 return( PSA_ERROR_NOT_SUPPORTED );
3147
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003148 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003149 {
3150#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003151 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
3152 operation->core_alg = PSA_ALG_CCM;
3153 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003154 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3155 return( PSA_ERROR_INVALID_ARGUMENT );
3156 mbedtls_ccm_init( &operation->ctx.ccm );
3157 status = mbedtls_to_psa_error(
3158 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
3159 operation->slot->data.raw.data,
3160 (unsigned int) key_bits ) );
3161 if( status != 0 )
3162 goto cleanup;
3163 break;
3164#endif /* MBEDTLS_CCM_C */
3165
3166#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003167 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
3168 operation->core_alg = PSA_ALG_GCM;
3169 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003170 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3171 return( PSA_ERROR_INVALID_ARGUMENT );
3172 mbedtls_gcm_init( &operation->ctx.gcm );
3173 status = mbedtls_to_psa_error(
3174 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
3175 operation->slot->data.raw.data,
3176 (unsigned int) key_bits ) );
3177 break;
3178#endif /* MBEDTLS_GCM_C */
3179
3180 default:
3181 return( PSA_ERROR_NOT_SUPPORTED );
3182 }
3183
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003184 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
3185 {
3186 status = PSA_ERROR_INVALID_ARGUMENT;
3187 goto cleanup;
3188 }
3189 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
3190 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
3191 * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
3192 * In both cases, mbedtls_xxx will validate the tag length below. */
3193
Gilles Peskineedf9a652018-08-17 18:11:56 +02003194 return( PSA_SUCCESS );
3195
3196cleanup:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003197 psa_aead_abort( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003198 return( status );
3199}
3200
Gilles Peskinec5487a82018-12-03 18:08:14 +01003201psa_status_t psa_aead_encrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003202 psa_algorithm_t alg,
3203 const uint8_t *nonce,
3204 size_t nonce_length,
3205 const uint8_t *additional_data,
3206 size_t additional_data_length,
3207 const uint8_t *plaintext,
3208 size_t plaintext_length,
3209 uint8_t *ciphertext,
3210 size_t ciphertext_size,
3211 size_t *ciphertext_length )
3212{
mohammad16035955c982018-04-26 00:53:03 +03003213 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003214 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03003215 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02003216
mohammad1603f08a5502018-06-03 15:05:47 +03003217 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003218
Gilles Peskinec5487a82018-12-03 18:08:14 +01003219 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003220 if( status != PSA_SUCCESS )
3221 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003222
Gilles Peskineedf9a652018-08-17 18:11:56 +02003223 /* For all currently supported modes, the tag is at the end of the
3224 * ciphertext. */
3225 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
3226 {
3227 status = PSA_ERROR_BUFFER_TOO_SMALL;
3228 goto exit;
3229 }
3230 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03003231
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003232#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003233 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003234 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003235 status = mbedtls_to_psa_error(
3236 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
3237 MBEDTLS_GCM_ENCRYPT,
3238 plaintext_length,
3239 nonce, nonce_length,
3240 additional_data, additional_data_length,
3241 plaintext, ciphertext,
3242 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03003243 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003244 else
3245#endif /* MBEDTLS_GCM_C */
3246#if defined(MBEDTLS_CCM_C)
3247 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003248 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003249 status = mbedtls_to_psa_error(
3250 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
3251 plaintext_length,
3252 nonce, nonce_length,
3253 additional_data,
3254 additional_data_length,
3255 plaintext, ciphertext,
3256 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003257 }
mohammad16035c8845f2018-05-09 05:40:09 -07003258 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003259#endif /* MBEDTLS_CCM_C */
mohammad16035c8845f2018-05-09 05:40:09 -07003260 {
mohammad1603554faad2018-06-03 15:07:38 +03003261 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07003262 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003263
Gilles Peskineedf9a652018-08-17 18:11:56 +02003264 if( status != PSA_SUCCESS && ciphertext_size != 0 )
3265 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003266
Gilles Peskineedf9a652018-08-17 18:11:56 +02003267exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003268 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003269 if( status == PSA_SUCCESS )
3270 *ciphertext_length = plaintext_length + operation.tag_length;
3271 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003272}
3273
Gilles Peskineee652a32018-06-01 19:23:52 +02003274/* Locate the tag in a ciphertext buffer containing the encrypted data
3275 * followed by the tag. Return the length of the part preceding the tag in
3276 * *plaintext_length. This is the size of the plaintext in modes where
3277 * the encrypted data has the same size as the plaintext, such as
3278 * CCM and GCM. */
3279static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
3280 const uint8_t *ciphertext,
3281 size_t ciphertext_length,
3282 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02003283 const uint8_t **p_tag )
3284{
3285 size_t payload_length;
3286 if( tag_length > ciphertext_length )
3287 return( PSA_ERROR_INVALID_ARGUMENT );
3288 payload_length = ciphertext_length - tag_length;
3289 if( payload_length > plaintext_size )
3290 return( PSA_ERROR_BUFFER_TOO_SMALL );
3291 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02003292 return( PSA_SUCCESS );
3293}
3294
Gilles Peskinec5487a82018-12-03 18:08:14 +01003295psa_status_t psa_aead_decrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003296 psa_algorithm_t alg,
3297 const uint8_t *nonce,
3298 size_t nonce_length,
3299 const uint8_t *additional_data,
3300 size_t additional_data_length,
3301 const uint8_t *ciphertext,
3302 size_t ciphertext_length,
3303 uint8_t *plaintext,
3304 size_t plaintext_size,
3305 size_t *plaintext_length )
3306{
mohammad16035955c982018-04-26 00:53:03 +03003307 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003308 aead_operation_t operation;
3309 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02003310
Gilles Peskineee652a32018-06-01 19:23:52 +02003311 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003312
Gilles Peskinec5487a82018-12-03 18:08:14 +01003313 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003314 if( status != PSA_SUCCESS )
3315 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003316
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003317#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003318 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003319 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003320 status = psa_aead_unpadded_locate_tag( operation.tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003321 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003322 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02003323 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003324 goto exit;
Gilles Peskineee652a32018-06-01 19:23:52 +02003325
Gilles Peskineedf9a652018-08-17 18:11:56 +02003326 status = mbedtls_to_psa_error(
3327 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
3328 ciphertext_length - operation.tag_length,
3329 nonce, nonce_length,
3330 additional_data,
3331 additional_data_length,
3332 tag, operation.tag_length,
3333 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03003334 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003335 else
3336#endif /* MBEDTLS_GCM_C */
3337#if defined(MBEDTLS_CCM_C)
3338 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003339 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003340 status = psa_aead_unpadded_locate_tag( operation.tag_length,
mohammad16039375f842018-06-03 14:28:24 +03003341 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003342 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003343 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003344 goto exit;
mohammad16039375f842018-06-03 14:28:24 +03003345
Gilles Peskineedf9a652018-08-17 18:11:56 +02003346 status = mbedtls_to_psa_error(
3347 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
3348 ciphertext_length - operation.tag_length,
3349 nonce, nonce_length,
3350 additional_data,
3351 additional_data_length,
3352 ciphertext, plaintext,
3353 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003354 }
mohammad160339574652018-06-01 04:39:53 -07003355 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003356#endif /* MBEDTLS_CCM_C */
mohammad160339574652018-06-01 04:39:53 -07003357 {
mohammad1603554faad2018-06-03 15:07:38 +03003358 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003359 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003360
Gilles Peskineedf9a652018-08-17 18:11:56 +02003361 if( status != PSA_SUCCESS && plaintext_size != 0 )
3362 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03003363
Gilles Peskineedf9a652018-08-17 18:11:56 +02003364exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003365 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003366 if( status == PSA_SUCCESS )
3367 *plaintext_length = ciphertext_length - operation.tag_length;
3368 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003369}
3370
Gilles Peskinea0655c32018-04-30 17:06:50 +02003371
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003372
Gilles Peskine20035e32018-02-03 22:44:14 +01003373/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003374/* Generators */
3375/****************************************************************/
3376
3377psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3378{
3379 psa_status_t status = PSA_SUCCESS;
3380 if( generator->alg == 0 )
3381 {
3382 /* The object has (apparently) been initialized but it is not
3383 * in use. It's ok to call abort on such an object, and there's
3384 * nothing to do. */
3385 }
3386 else
Gilles Peskine751d9652018-09-18 12:05:44 +02003387 if( generator->alg == PSA_ALG_SELECT_RAW )
3388 {
3389 if( generator->ctx.buffer.data != NULL )
3390 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003391 mbedtls_platform_zeroize( generator->ctx.buffer.data,
Gilles Peskine751d9652018-09-18 12:05:44 +02003392 generator->ctx.buffer.size );
3393 mbedtls_free( generator->ctx.buffer.data );
3394 }
3395 }
3396 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003397#if defined(MBEDTLS_MD_C)
3398 if( PSA_ALG_IS_HKDF( generator->alg ) )
3399 {
3400 mbedtls_free( generator->ctx.hkdf.info );
3401 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3402 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003403 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3404 /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
3405 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003406 {
3407 if( generator->ctx.tls12_prf.key != NULL )
3408 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003409 mbedtls_platform_zeroize( generator->ctx.tls12_prf.key,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003410 generator->ctx.tls12_prf.key_len );
3411 mbedtls_free( generator->ctx.tls12_prf.key );
3412 }
Hanno Becker580fba12018-11-13 20:50:45 +00003413
3414 if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
3415 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003416 mbedtls_platform_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003417 generator->ctx.tls12_prf.Ai_with_seed_len );
3418 mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
3419 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003420 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003421 else
3422#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003423 {
3424 status = PSA_ERROR_BAD_STATE;
3425 }
3426 memset( generator, 0, sizeof( *generator ) );
3427 return( status );
3428}
3429
3430
3431psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3432 size_t *capacity)
3433{
3434 *capacity = generator->capacity;
3435 return( PSA_SUCCESS );
3436}
3437
Gilles Peskinebef7f142018-07-12 17:22:21 +02003438#if defined(MBEDTLS_MD_C)
3439/* Read some bytes from an HKDF-based generator. This performs a chunk
3440 * of the expand phase of the HKDF algorithm. */
3441static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3442 psa_algorithm_t hash_alg,
3443 uint8_t *output,
3444 size_t output_length )
3445{
3446 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3447 psa_status_t status;
3448
3449 while( output_length != 0 )
3450 {
3451 /* Copy what remains of the current block */
3452 uint8_t n = hash_length - hkdf->offset_in_block;
3453 if( n > output_length )
3454 n = (uint8_t) output_length;
3455 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3456 output += n;
3457 output_length -= n;
3458 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003459 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003460 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003461 /* We can't be wanting more output after block 0xff, otherwise
3462 * the capacity check in psa_generator_read() would have
3463 * prevented this call. It could happen only if the generator
3464 * object was corrupted or if this function is called directly
3465 * inside the library. */
3466 if( hkdf->block_number == 0xff )
3467 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003468
3469 /* We need a new block */
3470 ++hkdf->block_number;
3471 hkdf->offset_in_block = 0;
3472 status = psa_hmac_setup_internal( &hkdf->hmac,
3473 hkdf->prk, hash_length,
3474 hash_alg );
3475 if( status != PSA_SUCCESS )
3476 return( status );
3477 if( hkdf->block_number != 1 )
3478 {
3479 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3480 hkdf->output_block,
3481 hash_length );
3482 if( status != PSA_SUCCESS )
3483 return( status );
3484 }
3485 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3486 hkdf->info,
3487 hkdf->info_length );
3488 if( status != PSA_SUCCESS )
3489 return( status );
3490 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3491 &hkdf->block_number, 1 );
3492 if( status != PSA_SUCCESS )
3493 return( status );
3494 status = psa_hmac_finish_internal( &hkdf->hmac,
3495 hkdf->output_block,
3496 sizeof( hkdf->output_block ) );
3497 if( status != PSA_SUCCESS )
3498 return( status );
3499 }
3500
3501 return( PSA_SUCCESS );
3502}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003503
3504static psa_status_t psa_generator_tls12_prf_generate_next_block(
3505 psa_tls12_prf_generator_t *tls12_prf,
3506 psa_algorithm_t alg )
3507{
3508 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3509 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3510 psa_hmac_internal_data hmac;
3511 psa_status_t status, cleanup_status;
3512
Hanno Becker3b339e22018-11-13 20:56:14 +00003513 unsigned char *Ai;
3514 size_t Ai_len;
3515
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003516 /* We can't be wanting more output after block 0xff, otherwise
3517 * the capacity check in psa_generator_read() would have
3518 * prevented this call. It could happen only if the generator
3519 * object was corrupted or if this function is called directly
3520 * inside the library. */
3521 if( tls12_prf->block_number == 0xff )
3522 return( PSA_ERROR_BAD_STATE );
3523
3524 /* We need a new block */
3525 ++tls12_prf->block_number;
3526 tls12_prf->offset_in_block = 0;
3527
3528 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3529 *
3530 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3531 *
3532 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3533 * HMAC_hash(secret, A(2) + seed) +
3534 * HMAC_hash(secret, A(3) + seed) + ...
3535 *
3536 * A(0) = seed
3537 * A(i) = HMAC_hash( secret, A(i-1) )
3538 *
3539 * The `psa_tls12_prf_generator` structures saves the block
3540 * `HMAC_hash(secret, A(i) + seed)` from which the output
3541 * is currently extracted as `output_block`, while
3542 * `A(i) + seed` is stored in `Ai_with_seed`.
3543 *
3544 * Generating a new block means recalculating `Ai_with_seed`
3545 * from the A(i)-part of it, and afterwards recalculating
3546 * `output_block`.
3547 *
3548 * A(0) is computed at setup time.
3549 *
3550 */
3551
3552 psa_hmac_init_internal( &hmac );
3553
3554 /* We must distinguish the calculation of A(1) from those
3555 * of A(2) and higher, because A(0)=seed has a different
3556 * length than the other A(i). */
3557 if( tls12_prf->block_number == 1 )
3558 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003559 Ai = tls12_prf->Ai_with_seed + hash_length;
3560 Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003561 }
3562 else
3563 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003564 Ai = tls12_prf->Ai_with_seed;
3565 Ai_len = hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003566 }
3567
Hanno Becker3b339e22018-11-13 20:56:14 +00003568 /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
3569 status = psa_hmac_setup_internal( &hmac,
3570 tls12_prf->key,
3571 tls12_prf->key_len,
3572 hash_alg );
3573 if( status != PSA_SUCCESS )
3574 goto cleanup;
3575
3576 status = psa_hash_update( &hmac.hash_ctx,
3577 Ai, Ai_len );
3578 if( status != PSA_SUCCESS )
3579 goto cleanup;
3580
3581 status = psa_hmac_finish_internal( &hmac,
3582 tls12_prf->Ai_with_seed,
3583 hash_length );
3584 if( status != PSA_SUCCESS )
3585 goto cleanup;
3586
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003587 /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
3588 status = psa_hmac_setup_internal( &hmac,
3589 tls12_prf->key,
3590 tls12_prf->key_len,
3591 hash_alg );
3592 if( status != PSA_SUCCESS )
3593 goto cleanup;
3594
3595 status = psa_hash_update( &hmac.hash_ctx,
3596 tls12_prf->Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003597 tls12_prf->Ai_with_seed_len );
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003598 if( status != PSA_SUCCESS )
3599 goto cleanup;
3600
3601 status = psa_hmac_finish_internal( &hmac,
3602 tls12_prf->output_block,
3603 hash_length );
3604 if( status != PSA_SUCCESS )
3605 goto cleanup;
3606
3607cleanup:
3608
3609 cleanup_status = psa_hmac_abort_internal( &hmac );
3610 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
3611 status = cleanup_status;
3612
3613 return( status );
3614}
3615
3616/* Read some bytes from an TLS-1.2-PRF-based generator.
3617 * See Section 5 of RFC 5246. */
3618static psa_status_t psa_generator_tls12_prf_read(
3619 psa_tls12_prf_generator_t *tls12_prf,
3620 psa_algorithm_t alg,
3621 uint8_t *output,
3622 size_t output_length )
3623{
3624 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3625 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3626 psa_status_t status;
3627
3628 while( output_length != 0 )
3629 {
3630 /* Copy what remains of the current block */
3631 uint8_t n = hash_length - tls12_prf->offset_in_block;
3632
3633 /* Check if we have fully processed the current block. */
3634 if( n == 0 )
3635 {
3636 status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
3637 alg );
3638 if( status != PSA_SUCCESS )
3639 return( status );
3640
3641 continue;
3642 }
3643
3644 if( n > output_length )
3645 n = (uint8_t) output_length;
3646 memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
3647 n );
3648 output += n;
3649 output_length -= n;
3650 tls12_prf->offset_in_block += n;
3651 }
3652
3653 return( PSA_SUCCESS );
3654}
Gilles Peskinebef7f142018-07-12 17:22:21 +02003655#endif /* MBEDTLS_MD_C */
3656
Gilles Peskineeab56e42018-07-12 17:12:33 +02003657psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3658 uint8_t *output,
3659 size_t output_length )
3660{
3661 psa_status_t status;
3662
3663 if( output_length > generator->capacity )
3664 {
3665 generator->capacity = 0;
3666 /* Go through the error path to wipe all confidential data now
3667 * that the generator object is useless. */
3668 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3669 goto exit;
3670 }
3671 if( output_length == 0 &&
3672 generator->capacity == 0 && generator->alg == 0 )
3673 {
3674 /* Edge case: this is a blank or finished generator, and 0
3675 * bytes were requested. The right error in this case could
3676 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3677 * INSUFFICIENT_CAPACITY, which is right for a finished
3678 * generator, for consistency with the case when
3679 * output_length > 0. */
3680 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3681 }
3682 generator->capacity -= output_length;
3683
Gilles Peskine751d9652018-09-18 12:05:44 +02003684 if( generator->alg == PSA_ALG_SELECT_RAW )
3685 {
Gilles Peskine211a4362018-10-25 22:22:31 +02003686 /* Initially, the capacity of a selection generator is always
3687 * the size of the buffer, i.e. `generator->ctx.buffer.size`,
3688 * abbreviated in this comment as `size`. When the remaining
3689 * capacity is `c`, the next bytes to serve start `c` bytes
3690 * from the end of the buffer, i.e. `size - c` from the
3691 * beginning of the buffer. Since `generator->capacity` was just
3692 * decremented above, we need to serve the bytes from
3693 * `size - generator->capacity - output_length` to
3694 * `size - generator->capacity`. */
Gilles Peskine751d9652018-09-18 12:05:44 +02003695 size_t offset =
3696 generator->ctx.buffer.size - generator->capacity - output_length;
3697 memcpy( output, generator->ctx.buffer.data + offset, output_length );
3698 status = PSA_SUCCESS;
3699 }
3700 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003701#if defined(MBEDTLS_MD_C)
3702 if( PSA_ALG_IS_HKDF( generator->alg ) )
3703 {
3704 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
3705 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
3706 output, output_length );
3707 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003708 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3709 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003710 {
3711 status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
3712 generator->alg, output,
3713 output_length );
3714 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003715 else
3716#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003717 {
3718 return( PSA_ERROR_BAD_STATE );
3719 }
3720
3721exit:
3722 if( status != PSA_SUCCESS )
3723 {
3724 psa_generator_abort( generator );
3725 memset( output, '!', output_length );
3726 }
3727 return( status );
3728}
3729
Gilles Peskine08542d82018-07-19 17:05:42 +02003730#if defined(MBEDTLS_DES_C)
3731static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
3732{
3733 if( data_size >= 8 )
3734 mbedtls_des_key_set_parity( data );
3735 if( data_size >= 16 )
3736 mbedtls_des_key_set_parity( data + 8 );
3737 if( data_size >= 24 )
3738 mbedtls_des_key_set_parity( data + 16 );
3739}
3740#endif /* MBEDTLS_DES_C */
3741
Gilles Peskinec5487a82018-12-03 18:08:14 +01003742psa_status_t psa_generator_import_key( psa_key_handle_t handle,
Gilles Peskineeab56e42018-07-12 17:12:33 +02003743 psa_key_type_t type,
3744 size_t bits,
3745 psa_crypto_generator_t *generator )
3746{
3747 uint8_t *data = NULL;
3748 size_t bytes = PSA_BITS_TO_BYTES( bits );
3749 psa_status_t status;
3750
3751 if( ! key_type_is_raw_bytes( type ) )
3752 return( PSA_ERROR_INVALID_ARGUMENT );
3753 if( bits % 8 != 0 )
3754 return( PSA_ERROR_INVALID_ARGUMENT );
3755 data = mbedtls_calloc( 1, bytes );
3756 if( data == NULL )
3757 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3758
3759 status = psa_generator_read( generator, data, bytes );
3760 if( status != PSA_SUCCESS )
3761 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02003762#if defined(MBEDTLS_DES_C)
3763 if( type == PSA_KEY_TYPE_DES )
3764 psa_des_set_key_parity( data, bytes );
3765#endif /* MBEDTLS_DES_C */
Gilles Peskinec5487a82018-12-03 18:08:14 +01003766 status = psa_import_key( handle, type, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02003767
3768exit:
3769 mbedtls_free( data );
3770 return( status );
3771}
3772
3773
3774
3775/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003776/* Key derivation */
3777/****************************************************************/
3778
Gilles Peskinea05219c2018-11-16 16:02:56 +01003779#if defined(MBEDTLS_MD_C)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003780/* Set up an HKDF-based generator. This is exactly the extract phase
Gilles Peskine346797d2018-11-16 16:05:06 +01003781 * of the HKDF algorithm.
3782 *
3783 * Note that if this function fails, you must call psa_generator_abort()
3784 * to potentially free embedded data structures and wipe confidential data.
3785 */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003786static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003787 const uint8_t *secret,
3788 size_t secret_length,
Gilles Peskinebef7f142018-07-12 17:22:21 +02003789 psa_algorithm_t hash_alg,
3790 const uint8_t *salt,
3791 size_t salt_length,
3792 const uint8_t *label,
3793 size_t label_length )
3794{
3795 psa_status_t status;
3796 status = psa_hmac_setup_internal( &hkdf->hmac,
3797 salt, salt_length,
Gilles Peskine00709fa2018-08-22 18:25:41 +02003798 PSA_ALG_HMAC_GET_HASH( hash_alg ) );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003799 if( status != PSA_SUCCESS )
3800 return( status );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003801 status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003802 if( status != PSA_SUCCESS )
3803 return( status );
3804 status = psa_hmac_finish_internal( &hkdf->hmac,
3805 hkdf->prk,
3806 sizeof( hkdf->prk ) );
3807 if( status != PSA_SUCCESS )
3808 return( status );
3809 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
3810 hkdf->block_number = 0;
3811 hkdf->info_length = label_length;
3812 if( label_length != 0 )
3813 {
3814 hkdf->info = mbedtls_calloc( 1, label_length );
3815 if( hkdf->info == NULL )
3816 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3817 memcpy( hkdf->info, label, label_length );
3818 }
3819 return( PSA_SUCCESS );
3820}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003821#endif /* MBEDTLS_MD_C */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003822
Gilles Peskinea05219c2018-11-16 16:02:56 +01003823#if defined(MBEDTLS_MD_C)
Gilles Peskine346797d2018-11-16 16:05:06 +01003824/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
3825 *
3826 * Note that if this function fails, you must call psa_generator_abort()
3827 * to potentially free embedded data structures and wipe confidential data.
3828 */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003829static psa_status_t psa_generator_tls12_prf_setup(
3830 psa_tls12_prf_generator_t *tls12_prf,
3831 const unsigned char *key,
3832 size_t key_len,
3833 psa_algorithm_t hash_alg,
3834 const uint8_t *salt,
3835 size_t salt_length,
3836 const uint8_t *label,
3837 size_t label_length )
3838{
3839 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Hanno Becker580fba12018-11-13 20:50:45 +00003840 size_t Ai_with_seed_len = hash_length + salt_length + label_length;
3841 int overflow;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003842
3843 tls12_prf->key = mbedtls_calloc( 1, key_len );
3844 if( tls12_prf->key == NULL )
3845 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3846 tls12_prf->key_len = key_len;
3847 memcpy( tls12_prf->key, key, key_len );
3848
Hanno Becker580fba12018-11-13 20:50:45 +00003849 overflow = ( salt_length + label_length < salt_length ) ||
3850 ( salt_length + label_length + hash_length < hash_length );
3851 if( overflow )
3852 return( PSA_ERROR_INVALID_ARGUMENT );
3853
3854 tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
3855 if( tls12_prf->Ai_with_seed == NULL )
3856 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3857 tls12_prf->Ai_with_seed_len = Ai_with_seed_len;
3858
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003859 /* Write `label + seed' at the end of the `A(i) + seed` buffer,
3860 * leaving the initial `hash_length` bytes unspecified for now. */
Hanno Becker353e4532018-11-15 09:53:57 +00003861 if( label_length != 0 )
3862 {
3863 memcpy( tls12_prf->Ai_with_seed + hash_length,
3864 label, label_length );
3865 }
3866
3867 if( salt_length != 0 )
3868 {
3869 memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
3870 salt, salt_length );
3871 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003872
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003873 /* The first block gets generated when
3874 * psa_generator_read() is called. */
3875 tls12_prf->block_number = 0;
3876 tls12_prf->offset_in_block = hash_length;
3877
3878 return( PSA_SUCCESS );
3879}
Hanno Becker1aaedc02018-11-16 11:35:34 +00003880
3881/* Set up a TLS-1.2-PSK-to-MS-based generator. */
3882static psa_status_t psa_generator_tls12_psk_to_ms_setup(
3883 psa_tls12_prf_generator_t *tls12_prf,
3884 const unsigned char *psk,
3885 size_t psk_len,
3886 psa_algorithm_t hash_alg,
3887 const uint8_t *salt,
3888 size_t salt_length,
3889 const uint8_t *label,
3890 size_t label_length )
3891{
3892 psa_status_t status;
3893 unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
3894
3895 if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
3896 return( PSA_ERROR_INVALID_ARGUMENT );
3897
3898 /* Quoting RFC 4279, Section 2:
3899 *
3900 * The premaster secret is formed as follows: if the PSK is N octets
3901 * long, concatenate a uint16 with the value N, N zero octets, a second
3902 * uint16 with the value N, and the PSK itself.
3903 */
3904
3905 pms[0] = ( psk_len >> 8 ) & 0xff;
3906 pms[1] = ( psk_len >> 0 ) & 0xff;
3907 memset( pms + 2, 0, psk_len );
3908 pms[2 + psk_len + 0] = pms[0];
3909 pms[2 + psk_len + 1] = pms[1];
3910 memcpy( pms + 4 + psk_len, psk, psk_len );
3911
3912 status = psa_generator_tls12_prf_setup( tls12_prf,
3913 pms, 4 + 2 * psk_len,
3914 hash_alg,
3915 salt, salt_length,
3916 label, label_length );
3917
Gilles Peskine3f108122018-12-07 18:14:53 +01003918 mbedtls_platform_zeroize( pms, sizeof( pms ) );
Hanno Becker1aaedc02018-11-16 11:35:34 +00003919 return( status );
3920}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003921#endif /* MBEDTLS_MD_C */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003922
Gilles Peskine346797d2018-11-16 16:05:06 +01003923/* Note that if this function fails, you must call psa_generator_abort()
3924 * to potentially free embedded data structures and wipe confidential data.
3925 */
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003926static psa_status_t psa_key_derivation_internal(
3927 psa_crypto_generator_t *generator,
3928 const uint8_t *secret, size_t secret_length,
3929 psa_algorithm_t alg,
3930 const uint8_t *salt, size_t salt_length,
3931 const uint8_t *label, size_t label_length,
3932 size_t capacity )
3933{
3934 psa_status_t status;
3935 size_t max_capacity;
3936
3937 /* Set generator->alg even on failure so that abort knows what to do. */
3938 generator->alg = alg;
3939
Gilles Peskine751d9652018-09-18 12:05:44 +02003940 if( alg == PSA_ALG_SELECT_RAW )
3941 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003942 (void) salt;
Gilles Peskine751d9652018-09-18 12:05:44 +02003943 if( salt_length != 0 )
3944 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea05219c2018-11-16 16:02:56 +01003945 (void) label;
Gilles Peskine751d9652018-09-18 12:05:44 +02003946 if( label_length != 0 )
3947 return( PSA_ERROR_INVALID_ARGUMENT );
3948 generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
3949 if( generator->ctx.buffer.data == NULL )
3950 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3951 memcpy( generator->ctx.buffer.data, secret, secret_length );
3952 generator->ctx.buffer.size = secret_length;
3953 max_capacity = secret_length;
3954 status = PSA_SUCCESS;
3955 }
3956 else
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003957#if defined(MBEDTLS_MD_C)
3958 if( PSA_ALG_IS_HKDF( alg ) )
3959 {
3960 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3961 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3962 if( hash_size == 0 )
3963 return( PSA_ERROR_NOT_SUPPORTED );
3964 max_capacity = 255 * hash_size;
3965 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
3966 secret, secret_length,
3967 hash_alg,
3968 salt, salt_length,
3969 label, label_length );
3970 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003971 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
3972 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
3973 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003974 {
3975 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3976 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3977
3978 /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
3979 if( hash_alg != PSA_ALG_SHA_256 &&
3980 hash_alg != PSA_ALG_SHA_384 )
3981 {
3982 return( PSA_ERROR_NOT_SUPPORTED );
3983 }
3984
3985 max_capacity = 255 * hash_size;
Hanno Becker1aaedc02018-11-16 11:35:34 +00003986
3987 if( PSA_ALG_IS_TLS12_PRF( alg ) )
3988 {
3989 status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
3990 secret, secret_length,
3991 hash_alg, salt, salt_length,
3992 label, label_length );
3993 }
3994 else
3995 {
3996 status = psa_generator_tls12_psk_to_ms_setup(
3997 &generator->ctx.tls12_prf,
3998 secret, secret_length,
3999 hash_alg, salt, salt_length,
4000 label, label_length );
4001 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01004002 }
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004003 else
4004#endif
4005 {
4006 return( PSA_ERROR_NOT_SUPPORTED );
4007 }
4008
4009 if( status != PSA_SUCCESS )
4010 return( status );
4011
4012 if( capacity <= max_capacity )
4013 generator->capacity = capacity;
Gilles Peskine8feb3a82018-09-18 12:06:11 +02004014 else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
4015 generator->capacity = max_capacity;
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004016 else
4017 return( PSA_ERROR_INVALID_ARGUMENT );
4018
4019 return( PSA_SUCCESS );
4020}
4021
Gilles Peskineea0fb492018-07-12 17:17:20 +02004022psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004023 psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02004024 psa_algorithm_t alg,
4025 const uint8_t *salt,
4026 size_t salt_length,
4027 const uint8_t *label,
4028 size_t label_length,
4029 size_t capacity )
4030{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004031 psa_key_slot_t *slot;
Gilles Peskineea0fb492018-07-12 17:17:20 +02004032 psa_status_t status;
4033
4034 if( generator->alg != 0 )
4035 return( PSA_ERROR_BAD_STATE );
4036
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004037 /* Make sure that alg is a key derivation algorithm. This prevents
4038 * key selection algorithms, which psa_key_derivation_internal
4039 * accepts for the sake of key agreement. */
Gilles Peskineea0fb492018-07-12 17:17:20 +02004040 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
4041 return( PSA_ERROR_INVALID_ARGUMENT );
4042
Gilles Peskinec5487a82018-12-03 18:08:14 +01004043 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004044 if( status != PSA_SUCCESS )
4045 return( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02004046
Gilles Peskinecce18ae2018-09-18 12:03:52 +02004047 if( slot->type != PSA_KEY_TYPE_DERIVE )
4048 return( PSA_ERROR_INVALID_ARGUMENT );
4049
4050 status = psa_key_derivation_internal( generator,
4051 slot->data.raw.data,
4052 slot->data.raw.bytes,
4053 alg,
4054 salt, salt_length,
4055 label, label_length,
4056 capacity );
4057 if( status != PSA_SUCCESS )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004058 psa_generator_abort( generator );
4059 return( status );
4060}
4061
4062
4063
4064/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02004065/* Key agreement */
4066/****************************************************************/
4067
Gilles Peskinea05219c2018-11-16 16:02:56 +01004068#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004069static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
4070 size_t peer_key_length,
4071 const mbedtls_ecp_keypair *our_key,
4072 uint8_t *shared_secret,
4073 size_t shared_secret_size,
4074 size_t *shared_secret_length )
4075{
4076 mbedtls_pk_context pk;
4077 mbedtls_ecp_keypair *their_key = NULL;
4078 mbedtls_ecdh_context ecdh;
4079 int ret;
4080 mbedtls_ecdh_init( &ecdh );
4081 mbedtls_pk_init( &pk );
4082
4083 ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
4084 if( ret != 0 )
4085 goto exit;
Gilles Peskine88714d72018-10-25 23:07:25 +02004086 switch( mbedtls_pk_get_type( &pk ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004087 {
Gilles Peskine88714d72018-10-25 23:07:25 +02004088 case MBEDTLS_PK_ECKEY:
4089 case MBEDTLS_PK_ECKEY_DH:
4090 break;
4091 default:
4092 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4093 goto exit;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004094 }
4095 their_key = mbedtls_pk_ec( pk );
Gilles Peskineb4086612018-11-14 20:51:23 +01004096 if( their_key->grp.id != our_key->grp.id )
4097 {
4098 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4099 goto exit;
4100 }
4101
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004102 ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
4103 if( ret != 0 )
4104 goto exit;
4105 ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
4106 if( ret != 0 )
4107 goto exit;
4108
4109 ret = mbedtls_ecdh_calc_secret( &ecdh,
4110 shared_secret_length,
4111 shared_secret, shared_secret_size,
4112 mbedtls_ctr_drbg_random,
4113 &global_data.ctr_drbg );
4114
4115exit:
4116 mbedtls_pk_free( &pk );
4117 mbedtls_ecdh_free( &ecdh );
4118 return( mbedtls_to_psa_error( ret ) );
4119}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004120#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004121
Gilles Peskine01d718c2018-09-18 12:01:02 +02004122#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
4123
Gilles Peskine346797d2018-11-16 16:05:06 +01004124/* Note that if this function fails, you must call psa_generator_abort()
4125 * to potentially free embedded data structures and wipe confidential data.
4126 */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004127static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
Gilles Peskine2f060a82018-12-04 17:12:32 +01004128 psa_key_slot_t *private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004129 const uint8_t *peer_key,
4130 size_t peer_key_length,
4131 psa_algorithm_t alg )
4132{
4133 psa_status_t status;
4134 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4135 size_t shared_secret_length = 0;
4136
4137 /* Step 1: run the secret agreement algorithm to generate the shared
4138 * secret. */
4139 switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
4140 {
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004141#if defined(MBEDTLS_ECDH_C)
4142 case PSA_ALG_ECDH_BASE:
4143 if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
4144 return( PSA_ERROR_INVALID_ARGUMENT );
4145 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
4146 private_key->data.ecp,
4147 shared_secret,
4148 sizeof( shared_secret ),
4149 &shared_secret_length );
4150 break;
4151#endif /* MBEDTLS_ECDH_C */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004152 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01004153 (void) private_key;
4154 (void) peer_key;
4155 (void) peer_key_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004156 return( PSA_ERROR_NOT_SUPPORTED );
4157 }
4158 if( status != PSA_SUCCESS )
4159 goto exit;
4160
4161 /* Step 2: set up the key derivation to generate key material from
4162 * the shared secret. */
4163 status = psa_key_derivation_internal( generator,
4164 shared_secret, shared_secret_length,
4165 PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
4166 NULL, 0, NULL, 0,
4167 PSA_GENERATOR_UNBRIDLED_CAPACITY );
4168exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01004169 mbedtls_platform_zeroize( shared_secret, shared_secret_length );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004170 return( status );
4171}
4172
4173psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004174 psa_key_handle_t private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004175 const uint8_t *peer_key,
4176 size_t peer_key_length,
4177 psa_algorithm_t alg )
4178{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004179 psa_key_slot_t *slot;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004180 psa_status_t status;
4181 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4182 return( PSA_ERROR_INVALID_ARGUMENT );
4183 status = psa_get_key_from_slot( private_key, &slot,
4184 PSA_KEY_USAGE_DERIVE, alg );
4185 if( status != PSA_SUCCESS )
4186 return( status );
Gilles Peskine346797d2018-11-16 16:05:06 +01004187 status = psa_key_agreement_internal( generator,
4188 slot,
4189 peer_key, peer_key_length,
4190 alg );
4191 if( status != PSA_SUCCESS )
4192 psa_generator_abort( generator );
4193 return( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004194}
4195
4196
4197
4198/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004199/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02004200/****************************************************************/
4201
4202psa_status_t psa_generate_random( uint8_t *output,
4203 size_t output_size )
4204{
itayzafrir0adf0fc2018-09-06 16:24:41 +03004205 int ret;
4206 GUARD_MODULE_INITIALIZED;
4207
4208 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
Gilles Peskine05d69892018-06-19 22:00:52 +02004209 return( mbedtls_to_psa_error( ret ) );
4210}
4211
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004212#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
avolinski13beb102018-11-20 16:51:49 +02004213
4214/* Support function for error conversion between psa_its error codes to psa crypto */
4215static psa_status_t its_to_psa_error( psa_its_status_t ret )
4216{
4217 switch( ret )
4218 {
4219 case PSA_ITS_SUCCESS:
4220 return( PSA_SUCCESS );
4221
4222 case PSA_ITS_ERROR_KEY_NOT_FOUND:
4223 return( PSA_ERROR_EMPTY_SLOT );
4224
4225 case PSA_ITS_ERROR_STORAGE_FAILURE:
4226 return( PSA_ERROR_STORAGE_FAILURE );
4227
4228 case PSA_ITS_ERROR_INSUFFICIENT_SPACE:
4229 return( PSA_ERROR_INSUFFICIENT_STORAGE );
4230
4231 case PSA_ITS_ERROR_INVALID_KEY:
Jaeden Amero58600552018-11-30 12:04:38 +00004232 case PSA_ITS_ERROR_OFFSET_INVALID:
avolinski13beb102018-11-20 16:51:49 +02004233 case PSA_ITS_ERROR_INCORRECT_SIZE:
4234 case PSA_ITS_ERROR_BAD_POINTER:
4235 return( PSA_ERROR_INVALID_ARGUMENT );
4236
4237 case PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED:
4238 return( PSA_ERROR_NOT_SUPPORTED );
4239
4240 case PSA_ITS_ERROR_WRITE_ONCE:
4241 return( PSA_ERROR_OCCUPIED_SLOT );
4242
4243 default:
4244 return( PSA_ERROR_UNKNOWN_ERROR );
4245 }
4246}
4247
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004248psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
4249 size_t seed_size )
4250{
4251 psa_status_t status;
avolinski13beb102018-11-20 16:51:49 +02004252 psa_its_status_t its_status;
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004253 struct psa_its_info_t p_info;
4254 if( global_data.initialized )
4255 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02004256
4257 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
4258 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
4259 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
4260 return( PSA_ERROR_INVALID_ARGUMENT );
4261
avolinski0d2c2662018-11-21 17:31:07 +02004262 its_status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
avolinski13beb102018-11-20 16:51:49 +02004263 status = its_to_psa_error( its_status );
4264
4265 if( PSA_ITS_ERROR_KEY_NOT_FOUND == its_status ) /* No seed exists */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004266 {
avolinski0d2c2662018-11-21 17:31:07 +02004267 its_status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
avolinski13beb102018-11-20 16:51:49 +02004268 status = its_to_psa_error( its_status );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004269 }
avolinski13beb102018-11-20 16:51:49 +02004270 else if( PSA_ITS_SUCCESS == its_status )
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004271 {
4272 /* You should not be here. Seed needs to be injected only once */
4273 status = PSA_ERROR_NOT_PERMITTED;
4274 }
4275 return( status );
4276}
4277#endif
4278
Gilles Peskinec5487a82018-12-03 18:08:14 +01004279psa_status_t psa_generate_key( psa_key_handle_t handle,
Gilles Peskine05d69892018-06-19 22:00:52 +02004280 psa_key_type_t type,
4281 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02004282 const void *extra,
4283 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02004284{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004285 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004286 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004287
Gilles Peskine53d991e2018-07-12 01:14:59 +02004288 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004289 return( PSA_ERROR_INVALID_ARGUMENT );
4290
Gilles Peskinec5487a82018-12-03 18:08:14 +01004291 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004292 if( status != PSA_SUCCESS )
4293 return( status );
4294
Gilles Peskine48c0ea12018-06-21 14:15:31 +02004295 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004296 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004297 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004298 if( status != PSA_SUCCESS )
4299 return( status );
4300 status = psa_generate_random( slot->data.raw.data,
4301 slot->data.raw.bytes );
4302 if( status != PSA_SUCCESS )
4303 {
4304 mbedtls_free( slot->data.raw.data );
4305 return( status );
4306 }
4307#if defined(MBEDTLS_DES_C)
4308 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02004309 psa_des_set_key_parity( slot->data.raw.data,
4310 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004311#endif /* MBEDTLS_DES_C */
4312 }
4313 else
4314
4315#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
4316 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
4317 {
4318 mbedtls_rsa_context *rsa;
4319 int ret;
4320 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02004321 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
4322 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +01004323 /* Accept only byte-aligned keys, for the same reasons as
4324 * in psa_import_rsa_key(). */
4325 if( bits % 8 != 0 )
4326 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02004327 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004328 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02004329 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004330 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004331 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02004332#if INT_MAX < 0xffffffff
4333 /* Check that the uint32_t value passed by the caller fits
4334 * in the range supported by this implementation. */
4335 if( p->e > INT_MAX )
4336 return( PSA_ERROR_NOT_SUPPORTED );
4337#endif
4338 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004339 }
4340 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
4341 if( rsa == NULL )
4342 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4343 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
4344 ret = mbedtls_rsa_gen_key( rsa,
4345 mbedtls_ctr_drbg_random,
4346 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004347 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02004348 exponent );
4349 if( ret != 0 )
4350 {
4351 mbedtls_rsa_free( rsa );
4352 mbedtls_free( rsa );
4353 return( mbedtls_to_psa_error( ret ) );
4354 }
4355 slot->data.rsa = rsa;
4356 }
4357 else
4358#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
4359
4360#if defined(MBEDTLS_ECP_C)
4361 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
4362 {
4363 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
4364 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
4365 const mbedtls_ecp_curve_info *curve_info =
4366 mbedtls_ecp_curve_info_from_grp_id( grp_id );
4367 mbedtls_ecp_keypair *ecp;
4368 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004369 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004370 return( PSA_ERROR_NOT_SUPPORTED );
4371 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
4372 return( PSA_ERROR_NOT_SUPPORTED );
4373 if( curve_info->bit_size != bits )
4374 return( PSA_ERROR_INVALID_ARGUMENT );
4375 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
4376 if( ecp == NULL )
4377 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4378 mbedtls_ecp_keypair_init( ecp );
4379 ret = mbedtls_ecp_gen_key( grp_id, ecp,
4380 mbedtls_ctr_drbg_random,
4381 &global_data.ctr_drbg );
4382 if( ret != 0 )
4383 {
4384 mbedtls_ecp_keypair_free( ecp );
4385 mbedtls_free( ecp );
4386 return( mbedtls_to_psa_error( ret ) );
4387 }
4388 slot->data.ecp = ecp;
4389 }
4390 else
4391#endif /* MBEDTLS_ECP_C */
4392
4393 return( PSA_ERROR_NOT_SUPPORTED );
4394
4395 slot->type = type;
Darryl Green0c6575a2018-11-07 16:05:30 +00004396
4397#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
4398 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
4399 {
Gilles Peskine69f976b2018-11-30 18:46:56 +01004400 return( psa_save_generated_persistent_key( slot, bits ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004401 }
4402#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
4403
4404 return( status );
Gilles Peskine05d69892018-06-19 22:00:52 +02004405}
4406
4407
4408/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01004409/* Module setup */
4410/****************************************************************/
4411
Gilles Peskine5e769522018-11-20 21:59:56 +01004412psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
4413 void (* entropy_init )( mbedtls_entropy_context *ctx ),
4414 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
4415{
4416 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4417 return( PSA_ERROR_BAD_STATE );
4418 global_data.entropy_init = entropy_init;
4419 global_data.entropy_free = entropy_free;
4420 return( PSA_SUCCESS );
4421}
4422
Gilles Peskinee59236f2018-01-27 23:32:46 +01004423void mbedtls_psa_crypto_free( void )
4424{
Gilles Peskine66fb1262018-12-10 16:29:04 +01004425 psa_wipe_all_key_slots( );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004426 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4427 {
4428 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
Gilles Peskine5e769522018-11-20 21:59:56 +01004429 global_data.entropy_free( &global_data.entropy );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004430 }
4431 /* Wipe all remaining data, including configuration.
4432 * In particular, this sets all state indicator to the value
4433 * indicating "uninitialized". */
Gilles Peskine3f108122018-12-07 18:14:53 +01004434 mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004435}
4436
4437psa_status_t psa_crypto_init( void )
4438{
Gilles Peskine66fb1262018-12-10 16:29:04 +01004439 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004440 const unsigned char drbg_seed[] = "PSA";
4441
Gilles Peskinec6b69072018-11-20 21:42:52 +01004442 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004443 if( global_data.initialized != 0 )
4444 return( PSA_SUCCESS );
4445
Gilles Peskine5e769522018-11-20 21:59:56 +01004446 /* Set default configuration if
4447 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
4448 if( global_data.entropy_init == NULL )
4449 global_data.entropy_init = mbedtls_entropy_init;
4450 if( global_data.entropy_free == NULL )
4451 global_data.entropy_free = mbedtls_entropy_free;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004452
Gilles Peskinec6b69072018-11-20 21:42:52 +01004453 /* Initialize the random generator. */
Gilles Peskine5e769522018-11-20 21:59:56 +01004454 global_data.entropy_init( &global_data.entropy );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004455 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004456 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskine66fb1262018-12-10 16:29:04 +01004457 status = mbedtls_to_psa_error(
4458 mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
4459 mbedtls_entropy_func,
4460 &global_data.entropy,
4461 drbg_seed, sizeof( drbg_seed ) - 1 ) );
4462 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01004463 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004464 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004465
Gilles Peskine66fb1262018-12-10 16:29:04 +01004466 status = psa_initialize_key_slots( );
4467 if( status != PSA_SUCCESS )
4468 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004469
4470 /* All done. */
Gilles Peskinee4ebc122018-03-07 14:16:44 +01004471 global_data.initialized = 1;
4472
Gilles Peskinee59236f2018-01-27 23:32:46 +01004473exit:
Gilles Peskine66fb1262018-12-10 16:29:04 +01004474 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01004475 mbedtls_psa_crypto_free( );
Gilles Peskine66fb1262018-12-10 16:29:04 +01004476 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004477}
4478
4479#endif /* MBEDTLS_PSA_CRYPTO_C */