blob: da3321eff69f2fe28914794b73ed6a8d7204eb3a [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 Peskine5f25dd02019-01-14 18:24:53 +0100787static void psa_abort_operations_using_key( psa_key_slot_t *slot )
788{
789 /*TODO*/
790 (void) slot;
791}
792
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100793/** Completely wipe a slot in memory, including its policy.
794 * Persistent storage is not affected. */
Gilles Peskine66fb1262018-12-10 16:29:04 +0100795psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot )
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100796{
797 psa_status_t status = psa_remove_key_data_from_memory( slot );
Gilles Peskine5f25dd02019-01-14 18:24:53 +0100798 psa_abort_operations_using_key( slot );
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100799 /* At this point, key material and other type-specific content has
800 * been wiped. Clear remaining metadata. We can call memset and not
801 * zeroize because the metadata is not particularly sensitive. */
802 memset( slot, 0, sizeof( *slot ) );
803 return( status );
804}
805
Gilles Peskinec5487a82018-12-03 18:08:14 +0100806psa_status_t psa_import_key( psa_key_handle_t handle,
Darryl Green940d72c2018-07-13 13:18:51 +0100807 psa_key_type_t type,
808 const uint8_t *data,
809 size_t data_length )
810{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100811 psa_key_slot_t *slot;
Darryl Green940d72c2018-07-13 13:18:51 +0100812 psa_status_t status;
813
Gilles Peskinec5487a82018-12-03 18:08:14 +0100814 status = psa_get_empty_key_slot( handle, &slot );
Darryl Green940d72c2018-07-13 13:18:51 +0100815 if( status != PSA_SUCCESS )
816 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100817
818 slot->type = type;
Darryl Green940d72c2018-07-13 13:18:51 +0100819
820 status = psa_import_key_into_slot( slot, data, data_length );
821 if( status != PSA_SUCCESS )
822 {
823 slot->type = PSA_KEY_TYPE_NONE;
824 return( status );
825 }
826
Darryl Greend49a4992018-06-18 17:27:26 +0100827#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
828 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
829 {
830 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +0100831 status = psa_save_persistent_key( slot->persistent_storage_id,
832 slot->type, &slot->policy, data,
Darryl Greend49a4992018-06-18 17:27:26 +0100833 data_length );
834 if( status != PSA_SUCCESS )
835 {
836 (void) psa_remove_key_data_from_memory( slot );
837 slot->type = PSA_KEY_TYPE_NONE;
838 }
839 }
840#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
841
842 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100843}
844
Gilles Peskinec5487a82018-12-03 18:08:14 +0100845psa_status_t psa_destroy_key( psa_key_handle_t handle )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100846{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100847 psa_key_slot_t *slot;
Darryl Greend49a4992018-06-18 17:27:26 +0100848 psa_status_t status = PSA_SUCCESS;
849 psa_status_t storage_status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100850
Gilles Peskinec5487a82018-12-03 18:08:14 +0100851 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200852 if( status != PSA_SUCCESS )
853 return( status );
Darryl Greend49a4992018-06-18 17:27:26 +0100854#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
855 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
856 {
Gilles Peskine69f976b2018-11-30 18:46:56 +0100857 storage_status =
858 psa_destroy_persistent_key( slot->persistent_storage_id );
Darryl Greend49a4992018-06-18 17:27:26 +0100859 }
860#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
Gilles Peskinef77ed1f2018-12-03 11:58:46 +0100861 status = psa_wipe_key_slot( slot );
Darryl Greend49a4992018-06-18 17:27:26 +0100862 if( status != PSA_SUCCESS )
863 return( status );
864 return( storage_status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100865}
866
Gilles Peskineb870b182018-07-06 16:02:09 +0200867/* Return the size of the key in the given slot, in bits. */
Gilles Peskine2f060a82018-12-04 17:12:32 +0100868static size_t psa_get_key_bits( const psa_key_slot_t *slot )
Gilles Peskineb870b182018-07-06 16:02:09 +0200869{
870 if( key_type_is_raw_bytes( slot->type ) )
871 return( slot->data.raw.bytes * 8 );
872#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200873 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaac64a22018-11-12 18:37:42 +0100874 return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
Gilles Peskineb870b182018-07-06 16:02:09 +0200875#endif /* defined(MBEDTLS_RSA_C) */
876#if defined(MBEDTLS_ECP_C)
877 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
878 return( slot->data.ecp->grp.pbits );
879#endif /* defined(MBEDTLS_ECP_C) */
880 /* Shouldn't happen except on an empty slot. */
881 return( 0 );
882}
883
Gilles Peskinec5487a82018-12-03 18:08:14 +0100884psa_status_t psa_get_key_information( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +0200885 psa_key_type_t *type,
886 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100887{
Gilles Peskine2f060a82018-12-04 17:12:32 +0100888 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200889 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100890
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100891 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200892 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100893 if( bits != NULL )
894 *bits = 0;
Gilles Peskinec5487a82018-12-03 18:08:14 +0100895 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200896 if( status != PSA_SUCCESS )
897 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +0200898
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100899 if( slot->type == PSA_KEY_TYPE_NONE )
900 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200901 if( type != NULL )
902 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +0200903 if( bits != NULL )
904 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100905 return( PSA_SUCCESS );
906}
907
Gilles Peskine2f060a82018-12-04 17:12:32 +0100908static psa_status_t psa_internal_export_key( psa_key_slot_t *slot,
Gilles Peskine2d277862018-06-18 15:41:12 +0200909 uint8_t *data,
910 size_t data_size,
911 size_t *data_length,
912 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100913{
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100914 *data_length = 0;
915
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200916 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300917 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300918
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200919 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100920 {
921 if( slot->data.raw.bytes > data_size )
922 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine52b90182018-10-29 19:26:27 +0100923 if( data_size != 0 )
924 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200925 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine52b90182018-10-29 19:26:27 +0100926 memset( data + slot->data.raw.bytes, 0,
927 data_size - slot->data.raw.bytes );
928 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100929 *data_length = slot->data.raw.bytes;
930 return( PSA_SUCCESS );
931 }
Gilles Peskine188c71e2018-10-29 19:26:02 +0100932#if defined(MBEDTLS_ECP_C)
933 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
934 {
Darryl Greendd8fb772018-11-07 16:00:44 +0000935 psa_status_t status;
936
Gilles Peskine188c71e2018-10-29 19:26:02 +0100937 size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( slot ) );
938 if( bytes > data_size )
939 return( PSA_ERROR_BUFFER_TOO_SMALL );
940 status = mbedtls_to_psa_error(
941 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
942 if( status != PSA_SUCCESS )
943 return( status );
944 memset( data + bytes, 0, data_size - bytes );
945 *data_length = bytes;
946 return( PSA_SUCCESS );
947 }
948#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100949 else
Moran Peker17e36e12018-05-02 12:55:20 +0300950 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100951#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200952 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +0300953 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100954 {
Moran Pekera998bc62018-04-16 18:16:20 +0300955 mbedtls_pk_context pk;
956 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +0200957 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300958 {
Darryl Green9e2d7a02018-07-24 16:33:30 +0100959#if defined(MBEDTLS_RSA_C)
960 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +0300961 pk.pk_info = &mbedtls_rsa_info;
962 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +0100963#else
964 return( PSA_ERROR_NOT_SUPPORTED );
965#endif
Moran Pekera998bc62018-04-16 18:16:20 +0300966 }
967 else
968 {
Darryl Green9e2d7a02018-07-24 16:33:30 +0100969#if defined(MBEDTLS_ECP_C)
970 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +0300971 pk.pk_info = &mbedtls_eckey_info;
972 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +0100973#else
974 return( PSA_ERROR_NOT_SUPPORTED );
975#endif
Moran Pekera998bc62018-04-16 18:16:20 +0300976 }
Moran Pekerd7326592018-05-29 16:56:39 +0300977 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300978 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300979 else
980 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300981 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200982 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200983 /* If data_size is 0 then data may be NULL and then the
984 * call to memset would have undefined behavior. */
985 if( data_size != 0 )
986 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300987 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200988 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200989 /* The mbedtls_pk_xxx functions write to the end of the buffer.
990 * Move the data to the beginning and erase remaining data
991 * at the original location. */
992 if( 2 * (size_t) ret <= data_size )
993 {
994 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200995 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200996 }
997 else if( (size_t) ret < data_size )
998 {
999 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +02001000 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +02001001 }
Moran Pekera998bc62018-04-16 18:16:20 +03001002 *data_length = ret;
1003 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +01001004 }
1005 else
Gilles Peskine6d912132018-03-07 16:41:37 +01001006#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +03001007 {
1008 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001009 it is valid for a special-purpose implementation to omit
1010 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001011 return( PSA_ERROR_NOT_SUPPORTED );
1012 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001013 }
1014}
1015
Gilles Peskinec5487a82018-12-03 18:08:14 +01001016psa_status_t psa_export_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001017 uint8_t *data,
1018 size_t data_size,
1019 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001020{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001021 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001022 psa_status_t status;
1023
1024 /* Set the key to empty now, so that even when there are errors, we always
1025 * set data_length to a value between 0 and data_size. On error, setting
1026 * the key to empty is a good choice because an empty key representation is
1027 * unlikely to be accepted anywhere. */
1028 *data_length = 0;
1029
1030 /* Export requires the EXPORT flag. There is an exception for public keys,
1031 * which don't require any flag, but psa_get_key_from_slot takes
1032 * care of this. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001033 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_EXPORT, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001034 if( status != PSA_SUCCESS )
1035 return( status );
1036 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001037 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001038}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001039
Gilles Peskinec5487a82018-12-03 18:08:14 +01001040psa_status_t psa_export_public_key( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02001041 uint8_t *data,
1042 size_t data_size,
1043 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001044{
Gilles Peskine2f060a82018-12-04 17:12:32 +01001045 psa_key_slot_t *slot;
Darryl Greendd8fb772018-11-07 16:00:44 +00001046 psa_status_t status;
1047
1048 /* Set the key to empty now, so that even when there are errors, we always
1049 * set data_length to a value between 0 and data_size. On error, setting
1050 * the key to empty is a good choice because an empty key representation is
1051 * unlikely to be accepted anywhere. */
1052 *data_length = 0;
1053
1054 /* Exporting a public key doesn't require a usage flag. */
Gilles Peskinec5487a82018-12-03 18:08:14 +01001055 status = psa_get_key_from_slot( handle, &slot, 0, 0 );
Darryl Greendd8fb772018-11-07 16:00:44 +00001056 if( status != PSA_SUCCESS )
1057 return( status );
1058 return( psa_internal_export_key( slot, data, data_size,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001059 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001060}
1061
Darryl Green0c6575a2018-11-07 16:05:30 +00001062#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
Gilles Peskine2f060a82018-12-04 17:12:32 +01001063static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t *slot,
Darryl Green0c6575a2018-11-07 16:05:30 +00001064 size_t bits )
1065{
1066 psa_status_t status;
1067 uint8_t *data;
1068 size_t key_length;
1069 size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits );
1070 data = mbedtls_calloc( 1, data_size );
itayzafrir910c76b2018-11-21 16:03:21 +02001071 if( data == NULL )
1072 return( PSA_ERROR_INSUFFICIENT_MEMORY );
Darryl Green0c6575a2018-11-07 16:05:30 +00001073 /* Get key data in export format */
1074 status = psa_internal_export_key( slot, data, data_size, &key_length, 0 );
1075 if( status != PSA_SUCCESS )
1076 {
1077 slot->type = PSA_KEY_TYPE_NONE;
1078 goto exit;
1079 }
1080 /* Store in file location */
Gilles Peskine69f976b2018-11-30 18:46:56 +01001081 status = psa_save_persistent_key( slot->persistent_storage_id,
1082 slot->type, &slot->policy,
Darryl Green0c6575a2018-11-07 16:05:30 +00001083 data, key_length );
1084 if( status != PSA_SUCCESS )
1085 {
1086 slot->type = PSA_KEY_TYPE_NONE;
1087 }
1088exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01001089 mbedtls_platform_zeroize( data, key_length );
Darryl Green0c6575a2018-11-07 16:05:30 +00001090 mbedtls_free( data );
1091 return( status );
1092}
1093#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1094
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001095
1096
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001097/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001098/* Message digests */
1099/****************************************************************/
1100
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001101static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01001102{
1103 switch( alg )
1104 {
1105#if defined(MBEDTLS_MD2_C)
1106 case PSA_ALG_MD2:
1107 return( &mbedtls_md2_info );
1108#endif
1109#if defined(MBEDTLS_MD4_C)
1110 case PSA_ALG_MD4:
1111 return( &mbedtls_md4_info );
1112#endif
1113#if defined(MBEDTLS_MD5_C)
1114 case PSA_ALG_MD5:
1115 return( &mbedtls_md5_info );
1116#endif
1117#if defined(MBEDTLS_RIPEMD160_C)
1118 case PSA_ALG_RIPEMD160:
1119 return( &mbedtls_ripemd160_info );
1120#endif
1121#if defined(MBEDTLS_SHA1_C)
1122 case PSA_ALG_SHA_1:
1123 return( &mbedtls_sha1_info );
1124#endif
1125#if defined(MBEDTLS_SHA256_C)
1126 case PSA_ALG_SHA_224:
1127 return( &mbedtls_sha224_info );
1128 case PSA_ALG_SHA_256:
1129 return( &mbedtls_sha256_info );
1130#endif
1131#if defined(MBEDTLS_SHA512_C)
1132 case PSA_ALG_SHA_384:
1133 return( &mbedtls_sha384_info );
1134 case PSA_ALG_SHA_512:
1135 return( &mbedtls_sha512_info );
1136#endif
1137 default:
1138 return( NULL );
1139 }
1140}
1141
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001142psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
1143{
1144 switch( operation->alg )
1145 {
Gilles Peskine81736312018-06-26 15:04:31 +02001146 case 0:
1147 /* The object has (apparently) been initialized but it is not
1148 * in use. It's ok to call abort on such an object, and there's
1149 * nothing to do. */
1150 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001151#if defined(MBEDTLS_MD2_C)
1152 case PSA_ALG_MD2:
1153 mbedtls_md2_free( &operation->ctx.md2 );
1154 break;
1155#endif
1156#if defined(MBEDTLS_MD4_C)
1157 case PSA_ALG_MD4:
1158 mbedtls_md4_free( &operation->ctx.md4 );
1159 break;
1160#endif
1161#if defined(MBEDTLS_MD5_C)
1162 case PSA_ALG_MD5:
1163 mbedtls_md5_free( &operation->ctx.md5 );
1164 break;
1165#endif
1166#if defined(MBEDTLS_RIPEMD160_C)
1167 case PSA_ALG_RIPEMD160:
1168 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
1169 break;
1170#endif
1171#if defined(MBEDTLS_SHA1_C)
1172 case PSA_ALG_SHA_1:
1173 mbedtls_sha1_free( &operation->ctx.sha1 );
1174 break;
1175#endif
1176#if defined(MBEDTLS_SHA256_C)
1177 case PSA_ALG_SHA_224:
1178 case PSA_ALG_SHA_256:
1179 mbedtls_sha256_free( &operation->ctx.sha256 );
1180 break;
1181#endif
1182#if defined(MBEDTLS_SHA512_C)
1183 case PSA_ALG_SHA_384:
1184 case PSA_ALG_SHA_512:
1185 mbedtls_sha512_free( &operation->ctx.sha512 );
1186 break;
1187#endif
1188 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001189 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001190 }
1191 operation->alg = 0;
1192 return( PSA_SUCCESS );
1193}
1194
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02001195psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001196 psa_algorithm_t alg )
1197{
1198 int ret;
1199 operation->alg = 0;
1200 switch( alg )
1201 {
1202#if defined(MBEDTLS_MD2_C)
1203 case PSA_ALG_MD2:
1204 mbedtls_md2_init( &operation->ctx.md2 );
1205 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
1206 break;
1207#endif
1208#if defined(MBEDTLS_MD4_C)
1209 case PSA_ALG_MD4:
1210 mbedtls_md4_init( &operation->ctx.md4 );
1211 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
1212 break;
1213#endif
1214#if defined(MBEDTLS_MD5_C)
1215 case PSA_ALG_MD5:
1216 mbedtls_md5_init( &operation->ctx.md5 );
1217 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
1218 break;
1219#endif
1220#if defined(MBEDTLS_RIPEMD160_C)
1221 case PSA_ALG_RIPEMD160:
1222 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
1223 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
1224 break;
1225#endif
1226#if defined(MBEDTLS_SHA1_C)
1227 case PSA_ALG_SHA_1:
1228 mbedtls_sha1_init( &operation->ctx.sha1 );
1229 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1230 break;
1231#endif
1232#if defined(MBEDTLS_SHA256_C)
1233 case PSA_ALG_SHA_224:
1234 mbedtls_sha256_init( &operation->ctx.sha256 );
1235 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1236 break;
1237 case PSA_ALG_SHA_256:
1238 mbedtls_sha256_init( &operation->ctx.sha256 );
1239 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1240 break;
1241#endif
1242#if defined(MBEDTLS_SHA512_C)
1243 case PSA_ALG_SHA_384:
1244 mbedtls_sha512_init( &operation->ctx.sha512 );
1245 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1246 break;
1247 case PSA_ALG_SHA_512:
1248 mbedtls_sha512_init( &operation->ctx.sha512 );
1249 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1250 break;
1251#endif
1252 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001253 return( PSA_ALG_IS_HASH( alg ) ?
1254 PSA_ERROR_NOT_SUPPORTED :
1255 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001256 }
1257 if( ret == 0 )
1258 operation->alg = alg;
1259 else
1260 psa_hash_abort( operation );
1261 return( mbedtls_to_psa_error( ret ) );
1262}
1263
1264psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1265 const uint8_t *input,
1266 size_t input_length )
1267{
1268 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001269
1270 /* Don't require hash implementations to behave correctly on a
1271 * zero-length input, which may have an invalid pointer. */
1272 if( input_length == 0 )
1273 return( PSA_SUCCESS );
1274
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001275 switch( operation->alg )
1276 {
1277#if defined(MBEDTLS_MD2_C)
1278 case PSA_ALG_MD2:
1279 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1280 input, input_length );
1281 break;
1282#endif
1283#if defined(MBEDTLS_MD4_C)
1284 case PSA_ALG_MD4:
1285 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1286 input, input_length );
1287 break;
1288#endif
1289#if defined(MBEDTLS_MD5_C)
1290 case PSA_ALG_MD5:
1291 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1292 input, input_length );
1293 break;
1294#endif
1295#if defined(MBEDTLS_RIPEMD160_C)
1296 case PSA_ALG_RIPEMD160:
1297 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1298 input, input_length );
1299 break;
1300#endif
1301#if defined(MBEDTLS_SHA1_C)
1302 case PSA_ALG_SHA_1:
1303 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1304 input, input_length );
1305 break;
1306#endif
1307#if defined(MBEDTLS_SHA256_C)
1308 case PSA_ALG_SHA_224:
1309 case PSA_ALG_SHA_256:
1310 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1311 input, input_length );
1312 break;
1313#endif
1314#if defined(MBEDTLS_SHA512_C)
1315 case PSA_ALG_SHA_384:
1316 case PSA_ALG_SHA_512:
1317 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1318 input, input_length );
1319 break;
1320#endif
1321 default:
1322 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1323 break;
1324 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001325
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001326 if( ret != 0 )
1327 psa_hash_abort( operation );
1328 return( mbedtls_to_psa_error( ret ) );
1329}
1330
1331psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1332 uint8_t *hash,
1333 size_t hash_size,
1334 size_t *hash_length )
1335{
itayzafrir40835d42018-08-02 13:14:17 +03001336 psa_status_t status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001337 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001338 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001339
1340 /* Fill the output buffer with something that isn't a valid hash
1341 * (barring an attack on the hash and deliberately-crafted input),
1342 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001343 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001344 /* If hash_size is 0 then hash may be NULL and then the
1345 * call to memset would have undefined behavior. */
1346 if( hash_size != 0 )
1347 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001348
1349 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03001350 {
1351 status = PSA_ERROR_BUFFER_TOO_SMALL;
1352 goto exit;
1353 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001354
1355 switch( operation->alg )
1356 {
1357#if defined(MBEDTLS_MD2_C)
1358 case PSA_ALG_MD2:
1359 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1360 break;
1361#endif
1362#if defined(MBEDTLS_MD4_C)
1363 case PSA_ALG_MD4:
1364 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1365 break;
1366#endif
1367#if defined(MBEDTLS_MD5_C)
1368 case PSA_ALG_MD5:
1369 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1370 break;
1371#endif
1372#if defined(MBEDTLS_RIPEMD160_C)
1373 case PSA_ALG_RIPEMD160:
1374 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1375 break;
1376#endif
1377#if defined(MBEDTLS_SHA1_C)
1378 case PSA_ALG_SHA_1:
1379 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1380 break;
1381#endif
1382#if defined(MBEDTLS_SHA256_C)
1383 case PSA_ALG_SHA_224:
1384 case PSA_ALG_SHA_256:
1385 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1386 break;
1387#endif
1388#if defined(MBEDTLS_SHA512_C)
1389 case PSA_ALG_SHA_384:
1390 case PSA_ALG_SHA_512:
1391 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1392 break;
1393#endif
1394 default:
1395 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1396 break;
1397 }
itayzafrir40835d42018-08-02 13:14:17 +03001398 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001399
itayzafrir40835d42018-08-02 13:14:17 +03001400exit:
1401 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001402 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001403 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001404 return( psa_hash_abort( operation ) );
1405 }
1406 else
1407 {
1408 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03001409 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001410 }
1411}
1412
Gilles Peskine2d277862018-06-18 15:41:12 +02001413psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1414 const uint8_t *hash,
1415 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001416{
1417 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1418 size_t actual_hash_length;
1419 psa_status_t status = psa_hash_finish( operation,
1420 actual_hash, sizeof( actual_hash ),
1421 &actual_hash_length );
1422 if( status != PSA_SUCCESS )
1423 return( status );
1424 if( actual_hash_length != hash_length )
1425 return( PSA_ERROR_INVALID_SIGNATURE );
1426 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1427 return( PSA_ERROR_INVALID_SIGNATURE );
1428 return( PSA_SUCCESS );
1429}
1430
1431
1432
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001433/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001434/* MAC */
1435/****************************************************************/
1436
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001437static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001438 psa_algorithm_t alg,
1439 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001440 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001441 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001442{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001443 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001444 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001445
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001446 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001447 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001448
Gilles Peskine8c9def32018-02-08 10:02:12 +01001449 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1450 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001451 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001452 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001453 case PSA_ALG_ARC4:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001454 mode = MBEDTLS_MODE_STREAM;
1455 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001456 case PSA_ALG_CTR:
1457 mode = MBEDTLS_MODE_CTR;
1458 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001459 case PSA_ALG_CFB:
1460 mode = MBEDTLS_MODE_CFB;
1461 break;
1462 case PSA_ALG_OFB:
1463 mode = MBEDTLS_MODE_OFB;
1464 break;
1465 case PSA_ALG_CBC_NO_PADDING:
1466 mode = MBEDTLS_MODE_CBC;
1467 break;
1468 case PSA_ALG_CBC_PKCS7:
1469 mode = MBEDTLS_MODE_CBC;
1470 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001471 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001472 mode = MBEDTLS_MODE_CCM;
1473 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001474 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001475 mode = MBEDTLS_MODE_GCM;
1476 break;
1477 default:
1478 return( NULL );
1479 }
1480 }
1481 else if( alg == PSA_ALG_CMAC )
1482 mode = MBEDTLS_MODE_ECB;
1483 else if( alg == PSA_ALG_GMAC )
1484 mode = MBEDTLS_MODE_GCM;
1485 else
1486 return( NULL );
1487
1488 switch( key_type )
1489 {
1490 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001491 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001492 break;
1493 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001494 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1495 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001496 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001497 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001498 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001499 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001500 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1501 * but two-key Triple-DES is functionally three-key Triple-DES
1502 * with K1=K3, so that's how we present it to mbedtls. */
1503 if( key_bits == 128 )
1504 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001505 break;
1506 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001507 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001508 break;
1509 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001510 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001511 break;
1512 default:
1513 return( NULL );
1514 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001515 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001516 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001517
Jaeden Amero23bbb752018-06-26 14:16:54 +01001518 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1519 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001520}
1521
Gilles Peskinea05219c2018-11-16 16:02:56 +01001522#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001523static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001524{
Gilles Peskine2d277862018-06-18 15:41:12 +02001525 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001526 {
1527 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001528 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001529 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001530 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001531 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001532 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001533 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001534 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001535 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001536 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001537 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001538 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001539 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001540 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001541 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001542 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001543 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001544 return( 128 );
1545 default:
1546 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001547 }
1548}
Gilles Peskinea05219c2018-11-16 16:02:56 +01001549#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001550
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001551/* Initialize the MAC operation structure. Once this function has been
1552 * called, psa_mac_abort can run and will do the right thing. */
1553static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1554 psa_algorithm_t alg )
1555{
1556 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1557
1558 operation->alg = alg;
1559 operation->key_set = 0;
1560 operation->iv_set = 0;
1561 operation->iv_required = 0;
1562 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001563 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001564
1565#if defined(MBEDTLS_CMAC_C)
1566 if( alg == PSA_ALG_CMAC )
1567 {
1568 operation->iv_required = 0;
1569 mbedtls_cipher_init( &operation->ctx.cmac );
1570 status = PSA_SUCCESS;
1571 }
1572 else
1573#endif /* MBEDTLS_CMAC_C */
1574#if defined(MBEDTLS_MD_C)
1575 if( PSA_ALG_IS_HMAC( operation->alg ) )
1576 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001577 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1578 operation->ctx.hmac.hash_ctx.alg = 0;
1579 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001580 }
1581 else
1582#endif /* MBEDTLS_MD_C */
1583 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001584 if( ! PSA_ALG_IS_MAC( alg ) )
1585 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001586 }
1587
1588 if( status != PSA_SUCCESS )
1589 memset( operation, 0, sizeof( *operation ) );
1590 return( status );
1591}
1592
Gilles Peskine01126fa2018-07-12 17:04:55 +02001593#if defined(MBEDTLS_MD_C)
1594static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1595{
Gilles Peskine3f108122018-12-07 18:14:53 +01001596 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001597 return( psa_hash_abort( &hmac->hash_ctx ) );
1598}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01001599
1600static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
1601{
1602 /* Instances of psa_hash_operation_s can be initialized by zeroization. */
1603 memset( hmac, 0, sizeof( *hmac ) );
1604}
Gilles Peskine01126fa2018-07-12 17:04:55 +02001605#endif /* MBEDTLS_MD_C */
1606
Gilles Peskine8c9def32018-02-08 10:02:12 +01001607psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1608{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001609 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001610 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001611 /* The object has (apparently) been initialized but it is not
1612 * in use. It's ok to call abort on such an object, and there's
1613 * nothing to do. */
1614 return( PSA_SUCCESS );
1615 }
1616 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001617#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001618 if( operation->alg == PSA_ALG_CMAC )
1619 {
1620 mbedtls_cipher_free( &operation->ctx.cmac );
1621 }
1622 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001623#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001624#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001625 if( PSA_ALG_IS_HMAC( operation->alg ) )
1626 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001627 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001628 }
1629 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001630#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001631 {
1632 /* Sanity check (shouldn't happen: operation->alg should
1633 * always have been initialized to a valid value). */
1634 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001635 }
Moran Peker41deec42018-04-04 15:43:05 +03001636
Gilles Peskine8c9def32018-02-08 10:02:12 +01001637 operation->alg = 0;
1638 operation->key_set = 0;
1639 operation->iv_set = 0;
1640 operation->iv_required = 0;
1641 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001642 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001643
Gilles Peskine8c9def32018-02-08 10:02:12 +01001644 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001645
1646bad_state:
1647 /* If abort is called on an uninitialized object, we can't trust
1648 * anything. Wipe the object in case it contains confidential data.
1649 * This may result in a memory leak if a pointer gets overwritten,
1650 * but it's too late to do anything about this. */
1651 memset( operation, 0, sizeof( *operation ) );
1652 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001653}
1654
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001655#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001656static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001657 size_t key_bits,
Gilles Peskine2f060a82018-12-04 17:12:32 +01001658 psa_key_slot_t *slot,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001659 const mbedtls_cipher_info_t *cipher_info )
1660{
1661 int ret;
1662
1663 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001664
1665 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1666 if( ret != 0 )
1667 return( ret );
1668
1669 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1670 slot->data.raw.data,
1671 key_bits );
1672 return( ret );
1673}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001674#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001675
Gilles Peskine248051a2018-06-20 16:09:38 +02001676#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001677static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1678 const uint8_t *key,
1679 size_t key_length,
1680 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001681{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001682 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001683 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001684 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001685 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001686 psa_status_t status;
1687
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001688 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1689 * overflow below. This should never trigger if the hash algorithm
1690 * is implemented correctly. */
1691 /* The size checks against the ipad and opad buffers cannot be written
1692 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1693 * because that triggers -Wlogical-op on GCC 7.3. */
1694 if( block_size > sizeof( ipad ) )
1695 return( PSA_ERROR_NOT_SUPPORTED );
1696 if( block_size > sizeof( hmac->opad ) )
1697 return( PSA_ERROR_NOT_SUPPORTED );
1698 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001699 return( PSA_ERROR_NOT_SUPPORTED );
1700
Gilles Peskined223b522018-06-11 18:12:58 +02001701 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001702 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001703 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001704 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001705 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001706 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001707 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001708 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001709 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001710 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001711 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001712 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001713 }
Gilles Peskine96889972018-07-12 17:07:03 +02001714 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1715 * but it is permitted. It is common when HMAC is used in HKDF, for
1716 * example. Don't call `memcpy` in the 0-length because `key` could be
1717 * an invalid pointer which would make the behavior undefined. */
1718 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001719 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001720
Gilles Peskined223b522018-06-11 18:12:58 +02001721 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1722 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001723 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001724 ipad[i] ^= 0x36;
1725 memset( ipad + key_length, 0x36, block_size - key_length );
1726
1727 /* Copy the key material from ipad to opad, flipping the requisite bits,
1728 * and filling the rest of opad with the requisite constant. */
1729 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001730 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1731 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001732
Gilles Peskine01126fa2018-07-12 17:04:55 +02001733 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001734 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001735 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001736
Gilles Peskine01126fa2018-07-12 17:04:55 +02001737 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001738
1739cleanup:
Gilles Peskine3f108122018-12-07 18:14:53 +01001740 mbedtls_platform_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001741
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001742 return( status );
1743}
Gilles Peskine248051a2018-06-20 16:09:38 +02001744#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001745
Gilles Peskine89167cb2018-07-08 20:12:23 +02001746static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001747 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001748 psa_algorithm_t alg,
1749 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001750{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001751 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +01001752 psa_key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001753 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001754 psa_key_usage_t usage =
1755 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskined911eb72018-08-14 15:18:45 +02001756 unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02001757 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001758
Gilles Peskined911eb72018-08-14 15:18:45 +02001759 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001760 if( status != PSA_SUCCESS )
1761 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001762 if( is_sign )
1763 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001764
Gilles Peskinec5487a82018-12-03 18:08:14 +01001765 status = psa_get_key_from_slot( handle, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001766 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001767 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001768 key_bits = psa_get_key_bits( slot );
1769
Gilles Peskine8c9def32018-02-08 10:02:12 +01001770#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001771 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001772 {
1773 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02001774 mbedtls_cipher_info_from_psa( full_length_alg,
1775 slot->type, key_bits, NULL );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001776 int ret;
1777 if( cipher_info == NULL )
1778 {
1779 status = PSA_ERROR_NOT_SUPPORTED;
1780 goto exit;
1781 }
1782 operation->mac_size = cipher_info->block_size;
1783 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1784 status = mbedtls_to_psa_error( ret );
1785 }
1786 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001787#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001788#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001789 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001790 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02001791 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001792 if( hash_alg == 0 )
1793 {
1794 status = PSA_ERROR_NOT_SUPPORTED;
1795 goto exit;
1796 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001797
1798 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1799 /* Sanity check. This shouldn't fail on a valid configuration. */
1800 if( operation->mac_size == 0 ||
1801 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1802 {
1803 status = PSA_ERROR_NOT_SUPPORTED;
1804 goto exit;
1805 }
1806
Gilles Peskine01126fa2018-07-12 17:04:55 +02001807 if( slot->type != PSA_KEY_TYPE_HMAC )
1808 {
1809 status = PSA_ERROR_INVALID_ARGUMENT;
1810 goto exit;
1811 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001812
Gilles Peskine01126fa2018-07-12 17:04:55 +02001813 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1814 slot->data.raw.data,
1815 slot->data.raw.bytes,
1816 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001817 }
1818 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001819#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001820 {
Jaeden Amero82df32e2018-11-23 15:11:20 +00001821 (void) key_bits;
Gilles Peskinefbfac682018-07-08 20:51:54 +02001822 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001823 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001824
Gilles Peskined911eb72018-08-14 15:18:45 +02001825 if( truncated == 0 )
1826 {
1827 /* The "normal" case: untruncated algorithm. Nothing to do. */
1828 }
1829 else if( truncated < 4 )
1830 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02001831 /* A very short MAC is too short for security since it can be
1832 * brute-forced. Ancient protocols with 32-bit MACs do exist,
1833 * so we make this our minimum, even though 32 bits is still
1834 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02001835 status = PSA_ERROR_NOT_SUPPORTED;
1836 }
1837 else if( truncated > operation->mac_size )
1838 {
1839 /* It's impossible to "truncate" to a larger length. */
1840 status = PSA_ERROR_INVALID_ARGUMENT;
1841 }
1842 else
1843 operation->mac_size = truncated;
1844
Gilles Peskinefbfac682018-07-08 20:51:54 +02001845exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001846 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001847 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001848 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001849 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001850 else
1851 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001852 operation->key_set = 1;
1853 }
1854 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001855}
1856
Gilles Peskine89167cb2018-07-08 20:12:23 +02001857psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001858 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001859 psa_algorithm_t alg )
1860{
Gilles Peskinec5487a82018-12-03 18:08:14 +01001861 return( psa_mac_setup( operation, handle, alg, 1 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001862}
1863
1864psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01001865 psa_key_handle_t handle,
Gilles Peskine89167cb2018-07-08 20:12:23 +02001866 psa_algorithm_t alg )
1867{
Gilles Peskinec5487a82018-12-03 18:08:14 +01001868 return( psa_mac_setup( operation, handle, alg, 0 ) );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001869}
1870
Gilles Peskine8c9def32018-02-08 10:02:12 +01001871psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1872 const uint8_t *input,
1873 size_t input_length )
1874{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001875 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001876 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001877 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001878 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001879 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001880 operation->has_input = 1;
1881
Gilles Peskine8c9def32018-02-08 10:02:12 +01001882#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001883 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001884 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001885 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1886 input, input_length );
1887 status = mbedtls_to_psa_error( ret );
1888 }
1889 else
1890#endif /* MBEDTLS_CMAC_C */
1891#if defined(MBEDTLS_MD_C)
1892 if( PSA_ALG_IS_HMAC( operation->alg ) )
1893 {
1894 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
1895 input_length );
1896 }
1897 else
1898#endif /* MBEDTLS_MD_C */
1899 {
1900 /* This shouldn't happen if `operation` was initialized by
1901 * a setup function. */
1902 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001903 }
1904
Gilles Peskinefbfac682018-07-08 20:51:54 +02001905cleanup:
1906 if( status != PSA_SUCCESS )
1907 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001908 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001909}
1910
Gilles Peskine01126fa2018-07-12 17:04:55 +02001911#if defined(MBEDTLS_MD_C)
1912static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
1913 uint8_t *mac,
1914 size_t mac_size )
1915{
1916 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
1917 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
1918 size_t hash_size = 0;
1919 size_t block_size = psa_get_hash_block_size( hash_alg );
1920 psa_status_t status;
1921
Gilles Peskine01126fa2018-07-12 17:04:55 +02001922 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1923 if( status != PSA_SUCCESS )
1924 return( status );
1925 /* From here on, tmp needs to be wiped. */
1926
1927 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
1928 if( status != PSA_SUCCESS )
1929 goto exit;
1930
1931 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
1932 if( status != PSA_SUCCESS )
1933 goto exit;
1934
1935 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
1936 if( status != PSA_SUCCESS )
1937 goto exit;
1938
Gilles Peskined911eb72018-08-14 15:18:45 +02001939 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1940 if( status != PSA_SUCCESS )
1941 goto exit;
1942
1943 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001944
1945exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01001946 mbedtls_platform_zeroize( tmp, hash_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001947 return( status );
1948}
1949#endif /* MBEDTLS_MD_C */
1950
mohammad16036df908f2018-04-02 08:34:15 -07001951static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001952 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001953 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001954{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02001955 if( ! operation->key_set )
1956 return( PSA_ERROR_BAD_STATE );
1957 if( operation->iv_required && ! operation->iv_set )
1958 return( PSA_ERROR_BAD_STATE );
1959
Gilles Peskine8c9def32018-02-08 10:02:12 +01001960 if( mac_size < operation->mac_size )
1961 return( PSA_ERROR_BUFFER_TOO_SMALL );
1962
Gilles Peskine8c9def32018-02-08 10:02:12 +01001963#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001964 if( operation->alg == PSA_ALG_CMAC )
1965 {
Gilles Peskined911eb72018-08-14 15:18:45 +02001966 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
1967 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
1968 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02001969 memcpy( mac, tmp, operation->mac_size );
Gilles Peskine3f108122018-12-07 18:14:53 +01001970 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001971 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001972 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02001973 else
1974#endif /* MBEDTLS_CMAC_C */
1975#if defined(MBEDTLS_MD_C)
1976 if( PSA_ALG_IS_HMAC( operation->alg ) )
1977 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001978 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02001979 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001980 }
1981 else
1982#endif /* MBEDTLS_MD_C */
1983 {
1984 /* This shouldn't happen if `operation` was initialized by
1985 * a setup function. */
1986 return( PSA_ERROR_BAD_STATE );
1987 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001988}
1989
Gilles Peskineacd4be32018-07-08 19:56:25 +02001990psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
1991 uint8_t *mac,
1992 size_t mac_size,
1993 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07001994{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001995 psa_status_t status;
1996
1997 /* Fill the output buffer with something that isn't a valid mac
1998 * (barring an attack on the mac and deliberately-crafted input),
1999 * in case the caller doesn't check the return status properly. */
2000 *mac_length = mac_size;
2001 /* If mac_size is 0 then mac may be NULL and then the
2002 * call to memset would have undefined behavior. */
2003 if( mac_size != 0 )
2004 memset( mac, '!', mac_size );
2005
Gilles Peskine89167cb2018-07-08 20:12:23 +02002006 if( ! operation->is_sign )
2007 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002008 status = PSA_ERROR_BAD_STATE;
2009 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002010 }
mohammad16036df908f2018-04-02 08:34:15 -07002011
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002012 status = psa_mac_finish_internal( operation, mac, mac_size );
2013
2014cleanup:
2015 if( status == PSA_SUCCESS )
2016 {
2017 status = psa_mac_abort( operation );
2018 if( status == PSA_SUCCESS )
2019 *mac_length = operation->mac_size;
2020 else
2021 memset( mac, '!', mac_size );
2022 }
2023 else
2024 psa_mac_abort( operation );
2025 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07002026}
2027
Gilles Peskineacd4be32018-07-08 19:56:25 +02002028psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
2029 const uint8_t *mac,
2030 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01002031{
Gilles Peskine828ed142018-06-18 23:25:51 +02002032 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07002033 psa_status_t status;
2034
Gilles Peskine89167cb2018-07-08 20:12:23 +02002035 if( operation->is_sign )
2036 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002037 status = PSA_ERROR_BAD_STATE;
2038 goto cleanup;
2039 }
2040 if( operation->mac_size != mac_length )
2041 {
2042 status = PSA_ERROR_INVALID_SIGNATURE;
2043 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02002044 }
mohammad16036df908f2018-04-02 08:34:15 -07002045
2046 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002047 actual_mac, sizeof( actual_mac ) );
2048
2049 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
2050 status = PSA_ERROR_INVALID_SIGNATURE;
2051
2052cleanup:
2053 if( status == PSA_SUCCESS )
2054 status = psa_mac_abort( operation );
2055 else
2056 psa_mac_abort( operation );
2057
Gilles Peskine3f108122018-12-07 18:14:53 +01002058 mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02002059
Gilles Peskine5d0b8642018-07-08 20:35:02 +02002060 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01002061}
2062
2063
Gilles Peskine20035e32018-02-03 22:44:14 +01002064
Gilles Peskine20035e32018-02-03 22:44:14 +01002065/****************************************************************/
2066/* Asymmetric cryptography */
2067/****************************************************************/
2068
Gilles Peskine2b450e32018-06-27 15:42:46 +02002069#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002070/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002071 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002072static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
2073 size_t hash_length,
2074 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002075{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02002076 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002077 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002078 *md_alg = mbedtls_md_get_type( md_info );
2079
2080 /* The Mbed TLS RSA module uses an unsigned int for hash length
2081 * parameters. Validate that it fits so that we don't risk an
2082 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002083#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002084 if( hash_length > UINT_MAX )
2085 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002086#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002087
2088#if defined(MBEDTLS_PKCS1_V15)
2089 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
2090 * must be correct. */
2091 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
2092 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002093 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002094 if( md_info == NULL )
2095 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002096 if( mbedtls_md_get_size( md_info ) != hash_length )
2097 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002098 }
2099#endif /* MBEDTLS_PKCS1_V15 */
2100
2101#if defined(MBEDTLS_PKCS1_V21)
2102 /* PSS requires a hash internally. */
2103 if( PSA_ALG_IS_RSA_PSS( alg ) )
2104 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002105 if( md_info == NULL )
2106 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002107 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002108#endif /* MBEDTLS_PKCS1_V21 */
2109
Gilles Peskine61b91d42018-06-08 16:09:36 +02002110 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002111}
2112
Gilles Peskine2b450e32018-06-27 15:42:46 +02002113static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
2114 psa_algorithm_t alg,
2115 const uint8_t *hash,
2116 size_t hash_length,
2117 uint8_t *signature,
2118 size_t signature_size,
2119 size_t *signature_length )
2120{
2121 psa_status_t status;
2122 int ret;
2123 mbedtls_md_type_t md_alg;
2124
2125 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2126 if( status != PSA_SUCCESS )
2127 return( status );
2128
Gilles Peskine630a18a2018-06-29 17:49:35 +02002129 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002130 return( PSA_ERROR_BUFFER_TOO_SMALL );
2131
2132#if defined(MBEDTLS_PKCS1_V15)
2133 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2134 {
2135 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2136 MBEDTLS_MD_NONE );
2137 ret = mbedtls_rsa_pkcs1_sign( rsa,
2138 mbedtls_ctr_drbg_random,
2139 &global_data.ctr_drbg,
2140 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002141 md_alg,
2142 (unsigned int) hash_length,
2143 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002144 signature );
2145 }
2146 else
2147#endif /* MBEDTLS_PKCS1_V15 */
2148#if defined(MBEDTLS_PKCS1_V21)
2149 if( PSA_ALG_IS_RSA_PSS( alg ) )
2150 {
2151 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2152 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
2153 mbedtls_ctr_drbg_random,
2154 &global_data.ctr_drbg,
2155 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002156 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002157 (unsigned int) hash_length,
2158 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002159 signature );
2160 }
2161 else
2162#endif /* MBEDTLS_PKCS1_V21 */
2163 {
2164 return( PSA_ERROR_INVALID_ARGUMENT );
2165 }
2166
2167 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002168 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002169 return( mbedtls_to_psa_error( ret ) );
2170}
2171
2172static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
2173 psa_algorithm_t alg,
2174 const uint8_t *hash,
2175 size_t hash_length,
2176 const uint8_t *signature,
2177 size_t signature_length )
2178{
2179 psa_status_t status;
2180 int ret;
2181 mbedtls_md_type_t md_alg;
2182
2183 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2184 if( status != PSA_SUCCESS )
2185 return( status );
2186
Gilles Peskine630a18a2018-06-29 17:49:35 +02002187 if( signature_length < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002188 return( PSA_ERROR_BUFFER_TOO_SMALL );
2189
2190#if defined(MBEDTLS_PKCS1_V15)
2191 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2192 {
2193 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2194 MBEDTLS_MD_NONE );
2195 ret = mbedtls_rsa_pkcs1_verify( rsa,
2196 mbedtls_ctr_drbg_random,
2197 &global_data.ctr_drbg,
2198 MBEDTLS_RSA_PUBLIC,
2199 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002200 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002201 hash,
2202 signature );
2203 }
2204 else
2205#endif /* MBEDTLS_PKCS1_V15 */
2206#if defined(MBEDTLS_PKCS1_V21)
2207 if( PSA_ALG_IS_RSA_PSS( alg ) )
2208 {
2209 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2210 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
2211 mbedtls_ctr_drbg_random,
2212 &global_data.ctr_drbg,
2213 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002214 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002215 (unsigned int) hash_length,
2216 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002217 signature );
2218 }
2219 else
2220#endif /* MBEDTLS_PKCS1_V21 */
2221 {
2222 return( PSA_ERROR_INVALID_ARGUMENT );
2223 }
Gilles Peskineef12c632018-09-13 20:37:48 +02002224
2225 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
2226 * the rest of the signature is invalid". This has little use in
2227 * practice and PSA doesn't report this distinction. */
2228 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
2229 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002230 return( mbedtls_to_psa_error( ret ) );
2231}
2232#endif /* MBEDTLS_RSA_C */
2233
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002234#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002235/* `ecp` cannot be const because `ecp->grp` needs to be non-const
2236 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
2237 * (even though these functions don't modify it). */
2238static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
2239 psa_algorithm_t alg,
2240 const uint8_t *hash,
2241 size_t hash_length,
2242 uint8_t *signature,
2243 size_t signature_size,
2244 size_t *signature_length )
2245{
2246 int ret;
2247 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002248 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002249 mbedtls_mpi_init( &r );
2250 mbedtls_mpi_init( &s );
2251
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002252 if( signature_size < 2 * curve_bytes )
2253 {
2254 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
2255 goto cleanup;
2256 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002257
Gilles Peskinea05219c2018-11-16 16:02:56 +01002258#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002259 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
2260 {
2261 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
2262 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2263 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2264 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
2265 hash, hash_length,
2266 md_alg ) );
2267 }
2268 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01002269#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002270 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01002271 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002272 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
2273 hash, hash_length,
2274 mbedtls_ctr_drbg_random,
2275 &global_data.ctr_drbg ) );
2276 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002277
2278 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
2279 signature,
2280 curve_bytes ) );
2281 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
2282 signature + curve_bytes,
2283 curve_bytes ) );
2284
2285cleanup:
2286 mbedtls_mpi_free( &r );
2287 mbedtls_mpi_free( &s );
2288 if( ret == 0 )
2289 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002290 return( mbedtls_to_psa_error( ret ) );
2291}
2292
2293static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2294 const uint8_t *hash,
2295 size_t hash_length,
2296 const uint8_t *signature,
2297 size_t signature_length )
2298{
2299 int ret;
2300 mbedtls_mpi r, s;
2301 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2302 mbedtls_mpi_init( &r );
2303 mbedtls_mpi_init( &s );
2304
2305 if( signature_length != 2 * curve_bytes )
2306 return( PSA_ERROR_INVALID_SIGNATURE );
2307
2308 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2309 signature,
2310 curve_bytes ) );
2311 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2312 signature + curve_bytes,
2313 curve_bytes ) );
2314
2315 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2316 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002317
2318cleanup:
2319 mbedtls_mpi_free( &r );
2320 mbedtls_mpi_free( &s );
2321 return( mbedtls_to_psa_error( ret ) );
2322}
2323#endif /* MBEDTLS_ECDSA_C */
2324
Gilles Peskinec5487a82018-12-03 18:08:14 +01002325psa_status_t psa_asymmetric_sign( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002326 psa_algorithm_t alg,
2327 const uint8_t *hash,
2328 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002329 uint8_t *signature,
2330 size_t signature_size,
2331 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002332{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002333 psa_key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002334 psa_status_t status;
2335
2336 *signature_length = signature_size;
2337
Gilles Peskinec5487a82018-12-03 18:08:14 +01002338 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002339 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002340 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002341 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002342 {
2343 status = PSA_ERROR_INVALID_ARGUMENT;
2344 goto exit;
2345 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002346
Gilles Peskine20035e32018-02-03 22:44:14 +01002347#if defined(MBEDTLS_RSA_C)
2348 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2349 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002350 status = psa_rsa_sign( slot->data.rsa,
2351 alg,
2352 hash, hash_length,
2353 signature, signature_size,
2354 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002355 }
2356 else
2357#endif /* defined(MBEDTLS_RSA_C) */
2358#if defined(MBEDTLS_ECP_C)
2359 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2360 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002361#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01002362 if(
2363#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
2364 PSA_ALG_IS_ECDSA( alg )
2365#else
2366 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
2367#endif
2368 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002369 status = psa_ecdsa_sign( slot->data.ecp,
2370 alg,
2371 hash, hash_length,
2372 signature, signature_size,
2373 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002374 else
2375#endif /* defined(MBEDTLS_ECDSA_C) */
2376 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002377 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002378 }
itayzafrir5c753392018-05-08 11:18:38 +03002379 }
2380 else
2381#endif /* defined(MBEDTLS_ECP_C) */
2382 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002383 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002384 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002385
2386exit:
2387 /* Fill the unused part of the output buffer (the whole buffer on error,
2388 * the trailing part on success) with something that isn't a valid mac
2389 * (barring an attack on the mac and deliberately-crafted input),
2390 * in case the caller doesn't check the return status properly. */
2391 if( status == PSA_SUCCESS )
2392 memset( signature + *signature_length, '!',
2393 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002394 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002395 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002396 /* If signature_size is 0 then we have nothing to do. We must not call
2397 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002398 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002399}
2400
Gilles Peskinec5487a82018-12-03 18:08:14 +01002401psa_status_t psa_asymmetric_verify( psa_key_handle_t handle,
itayzafrir5c753392018-05-08 11:18:38 +03002402 psa_algorithm_t alg,
2403 const uint8_t *hash,
2404 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002405 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002406 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002407{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002408 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002409 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002410
Gilles Peskinec5487a82018-12-03 18:08:14 +01002411 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002412 if( status != PSA_SUCCESS )
2413 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002414
Gilles Peskine61b91d42018-06-08 16:09:36 +02002415#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002416 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002417 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002418 return( psa_rsa_verify( slot->data.rsa,
2419 alg,
2420 hash, hash_length,
2421 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002422 }
2423 else
2424#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002425#if defined(MBEDTLS_ECP_C)
2426 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2427 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002428#if defined(MBEDTLS_ECDSA_C)
2429 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002430 return( psa_ecdsa_verify( slot->data.ecp,
2431 hash, hash_length,
2432 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002433 else
2434#endif /* defined(MBEDTLS_ECDSA_C) */
2435 {
2436 return( PSA_ERROR_INVALID_ARGUMENT );
2437 }
itayzafrir5c753392018-05-08 11:18:38 +03002438 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002439 else
2440#endif /* defined(MBEDTLS_ECP_C) */
2441 {
2442 return( PSA_ERROR_NOT_SUPPORTED );
2443 }
2444}
2445
Gilles Peskine072ac562018-06-30 00:21:29 +02002446#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2447static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2448 mbedtls_rsa_context *rsa )
2449{
2450 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2451 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2452 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2453 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2454}
2455#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2456
Gilles Peskinec5487a82018-12-03 18:08:14 +01002457psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002458 psa_algorithm_t alg,
2459 const uint8_t *input,
2460 size_t input_length,
2461 const uint8_t *salt,
2462 size_t salt_length,
2463 uint8_t *output,
2464 size_t output_size,
2465 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002466{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002467 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002468 psa_status_t status;
2469
Darryl Green5cc689a2018-07-24 15:34:10 +01002470 (void) input;
2471 (void) input_length;
2472 (void) salt;
2473 (void) output;
2474 (void) output_size;
2475
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002476 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002477
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002478 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2479 return( PSA_ERROR_INVALID_ARGUMENT );
2480
Gilles Peskinec5487a82018-12-03 18:08:14 +01002481 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002482 if( status != PSA_SUCCESS )
2483 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002484 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2485 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002486 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002487
2488#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002489 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002490 {
2491 mbedtls_rsa_context *rsa = slot->data.rsa;
2492 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002493 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002494 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002495#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002496 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002497 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002498 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2499 mbedtls_ctr_drbg_random,
2500 &global_data.ctr_drbg,
2501 MBEDTLS_RSA_PUBLIC,
2502 input_length,
2503 input,
2504 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002505 }
2506 else
2507#endif /* MBEDTLS_PKCS1_V15 */
2508#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002509 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002510 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002511 psa_rsa_oaep_set_padding_mode( alg, rsa );
2512 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2513 mbedtls_ctr_drbg_random,
2514 &global_data.ctr_drbg,
2515 MBEDTLS_RSA_PUBLIC,
2516 salt, salt_length,
2517 input_length,
2518 input,
2519 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002520 }
2521 else
2522#endif /* MBEDTLS_PKCS1_V21 */
2523 {
2524 return( PSA_ERROR_INVALID_ARGUMENT );
2525 }
2526 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002527 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002528 return( mbedtls_to_psa_error( ret ) );
2529 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002530 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002531#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002532 {
2533 return( PSA_ERROR_NOT_SUPPORTED );
2534 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002535}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002536
Gilles Peskinec5487a82018-12-03 18:08:14 +01002537psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002538 psa_algorithm_t alg,
2539 const uint8_t *input,
2540 size_t input_length,
2541 const uint8_t *salt,
2542 size_t salt_length,
2543 uint8_t *output,
2544 size_t output_size,
2545 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002546{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002547 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002548 psa_status_t status;
2549
Darryl Green5cc689a2018-07-24 15:34:10 +01002550 (void) input;
2551 (void) input_length;
2552 (void) salt;
2553 (void) output;
2554 (void) output_size;
2555
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002556 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002557
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002558 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2559 return( PSA_ERROR_INVALID_ARGUMENT );
2560
Gilles Peskinec5487a82018-12-03 18:08:14 +01002561 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002562 if( status != PSA_SUCCESS )
2563 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002564 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2565 return( PSA_ERROR_INVALID_ARGUMENT );
2566
2567#if defined(MBEDTLS_RSA_C)
2568 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2569 {
2570 mbedtls_rsa_context *rsa = slot->data.rsa;
2571 int ret;
2572
Gilles Peskine630a18a2018-06-29 17:49:35 +02002573 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002574 return( PSA_ERROR_INVALID_ARGUMENT );
2575
2576#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002577 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002578 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002579 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2580 mbedtls_ctr_drbg_random,
2581 &global_data.ctr_drbg,
2582 MBEDTLS_RSA_PRIVATE,
2583 output_length,
2584 input,
2585 output,
2586 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002587 }
2588 else
2589#endif /* MBEDTLS_PKCS1_V15 */
2590#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002591 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002592 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002593 psa_rsa_oaep_set_padding_mode( alg, rsa );
2594 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
2595 mbedtls_ctr_drbg_random,
2596 &global_data.ctr_drbg,
2597 MBEDTLS_RSA_PRIVATE,
2598 salt, salt_length,
2599 output_length,
2600 input,
2601 output,
2602 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002603 }
2604 else
2605#endif /* MBEDTLS_PKCS1_V21 */
2606 {
2607 return( PSA_ERROR_INVALID_ARGUMENT );
2608 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002609
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002610 return( mbedtls_to_psa_error( ret ) );
2611 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002612 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002613#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002614 {
2615 return( PSA_ERROR_NOT_SUPPORTED );
2616 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002617}
Gilles Peskine20035e32018-02-03 22:44:14 +01002618
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002619
2620
mohammad1603503973b2018-03-12 15:59:30 +02002621/****************************************************************/
2622/* Symmetric cryptography */
2623/****************************************************************/
2624
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002625/* Initialize the cipher operation structure. Once this function has been
2626 * called, psa_cipher_abort can run and will do the right thing. */
2627static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2628 psa_algorithm_t alg )
2629{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002630 if( ! PSA_ALG_IS_CIPHER( alg ) )
2631 {
2632 memset( operation, 0, sizeof( *operation ) );
2633 return( PSA_ERROR_INVALID_ARGUMENT );
2634 }
2635
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002636 operation->alg = alg;
2637 operation->key_set = 0;
2638 operation->iv_set = 0;
2639 operation->iv_required = 1;
2640 operation->iv_size = 0;
2641 operation->block_size = 0;
2642 mbedtls_cipher_init( &operation->ctx.cipher );
2643 return( PSA_SUCCESS );
2644}
2645
Gilles Peskinee553c652018-06-04 16:22:46 +02002646static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002647 psa_key_handle_t handle,
Gilles Peskine7e928852018-06-04 16:23:10 +02002648 psa_algorithm_t alg,
2649 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002650{
2651 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2652 psa_status_t status;
Gilles Peskine2f060a82018-12-04 17:12:32 +01002653 psa_key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002654 size_t key_bits;
2655 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002656 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2657 PSA_KEY_USAGE_ENCRYPT :
2658 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002659
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002660 status = psa_cipher_init( operation, alg );
2661 if( status != PSA_SUCCESS )
2662 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002663
Gilles Peskinec5487a82018-12-03 18:08:14 +01002664 status = psa_get_key_from_slot( handle, &slot, usage, alg);
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002665 if( status != PSA_SUCCESS )
2666 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002667 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002668
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002669 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002670 if( cipher_info == NULL )
2671 return( PSA_ERROR_NOT_SUPPORTED );
2672
mohammad1603503973b2018-03-12 15:59:30 +02002673 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002674 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002675 {
2676 psa_cipher_abort( operation );
2677 return( mbedtls_to_psa_error( ret ) );
2678 }
2679
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002680#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002681 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002682 {
2683 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2684 unsigned char keys[24];
2685 memcpy( keys, slot->data.raw.data, 16 );
2686 memcpy( keys + 16, slot->data.raw.data, 8 );
2687 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2688 keys,
2689 192, cipher_operation );
2690 }
2691 else
2692#endif
2693 {
2694 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2695 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002696 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002697 }
Moran Peker41deec42018-04-04 15:43:05 +03002698 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002699 {
2700 psa_cipher_abort( operation );
2701 return( mbedtls_to_psa_error( ret ) );
2702 }
2703
mohammad16038481e742018-03-18 13:57:31 +02002704#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002705 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02002706 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002707 case PSA_ALG_CBC_NO_PADDING:
2708 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2709 MBEDTLS_PADDING_NONE );
2710 break;
2711 case PSA_ALG_CBC_PKCS7:
2712 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2713 MBEDTLS_PADDING_PKCS7 );
2714 break;
2715 default:
2716 /* The algorithm doesn't involve padding. */
2717 ret = 0;
2718 break;
2719 }
2720 if( ret != 0 )
2721 {
2722 psa_cipher_abort( operation );
2723 return( mbedtls_to_psa_error( ret ) );
mohammad16038481e742018-03-18 13:57:31 +02002724 }
2725#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2726
mohammad1603503973b2018-03-12 15:59:30 +02002727 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002728 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
2729 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
2730 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02002731 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002732 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002733 }
mohammad1603503973b2018-03-12 15:59:30 +02002734
Moran Peker395db872018-05-31 14:07:14 +03002735 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002736}
2737
Gilles Peskinefe119512018-07-08 21:39:34 +02002738psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002739 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02002740 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002741{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002742 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002743}
2744
Gilles Peskinefe119512018-07-08 21:39:34 +02002745psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01002746 psa_key_handle_t handle,
Gilles Peskinefe119512018-07-08 21:39:34 +02002747 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002748{
Gilles Peskinec5487a82018-12-03 18:08:14 +01002749 return( psa_cipher_setup( operation, handle, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002750}
2751
Gilles Peskinefe119512018-07-08 21:39:34 +02002752psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2753 unsigned char *iv,
2754 size_t iv_size,
2755 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002756{
itayzafrir534bd7c2018-08-02 13:56:32 +03002757 psa_status_t status;
2758 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002759 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002760 {
2761 status = PSA_ERROR_BAD_STATE;
2762 goto exit;
2763 }
Moran Peker41deec42018-04-04 15:43:05 +03002764 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002765 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002766 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03002767 goto exit;
2768 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002769 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2770 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002771 if( ret != 0 )
2772 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002773 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002774 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002775 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002776
mohammad16038481e742018-03-18 13:57:31 +02002777 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03002778 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002779
Moran Peker395db872018-05-31 14:07:14 +03002780exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03002781 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03002782 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002783 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002784}
2785
Gilles Peskinefe119512018-07-08 21:39:34 +02002786psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2787 const unsigned char *iv,
2788 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002789{
itayzafrir534bd7c2018-08-02 13:56:32 +03002790 psa_status_t status;
2791 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002792 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002793 {
2794 status = PSA_ERROR_BAD_STATE;
2795 goto exit;
2796 }
Moran Pekera28258c2018-05-29 16:25:04 +03002797 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002798 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002799 status = PSA_ERROR_INVALID_ARGUMENT;
2800 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03002801 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002802 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
2803 status = mbedtls_to_psa_error( ret );
2804exit:
2805 if( status == PSA_SUCCESS )
2806 operation->iv_set = 1;
2807 else
mohammad1603503973b2018-03-12 15:59:30 +02002808 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002809 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002810}
2811
Gilles Peskinee553c652018-06-04 16:22:46 +02002812psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2813 const uint8_t *input,
2814 size_t input_length,
2815 unsigned char *output,
2816 size_t output_size,
2817 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002818{
itayzafrir534bd7c2018-08-02 13:56:32 +03002819 psa_status_t status;
2820 int ret;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002821 size_t expected_output_size;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002822 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002823 {
2824 /* Take the unprocessed partial block left over from previous
2825 * update calls, if any, plus the input to this call. Remove
2826 * the last partial block, if any. You get the data that will be
2827 * output in this call. */
2828 expected_output_size =
2829 ( operation->ctx.cipher.unprocessed_len + input_length )
2830 / operation->block_size * operation->block_size;
2831 }
2832 else
2833 {
2834 expected_output_size = input_length;
2835 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002836
Gilles Peskine89d789c2018-06-04 17:17:16 +02002837 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03002838 {
2839 status = PSA_ERROR_BUFFER_TOO_SMALL;
2840 goto exit;
2841 }
mohammad160382759612018-03-12 18:16:40 +02002842
mohammad1603503973b2018-03-12 15:59:30 +02002843 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002844 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03002845 status = mbedtls_to_psa_error( ret );
2846exit:
2847 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02002848 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002849 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002850}
2851
Gilles Peskinee553c652018-06-04 16:22:46 +02002852psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2853 uint8_t *output,
2854 size_t output_size,
2855 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002856{
Janos Follath315b51c2018-07-09 16:04:51 +01002857 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2858 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002859 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002860
mohammad1603503973b2018-03-12 15:59:30 +02002861 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002862 {
Janos Follath315b51c2018-07-09 16:04:51 +01002863 status = PSA_ERROR_BAD_STATE;
2864 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002865 }
2866 if( operation->iv_required && ! operation->iv_set )
2867 {
Janos Follath315b51c2018-07-09 16:04:51 +01002868 status = PSA_ERROR_BAD_STATE;
2869 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002870 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002871
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002872 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002873 operation->alg == PSA_ALG_CBC_NO_PADDING &&
2874 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03002875 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002876 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01002877 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002878 }
2879
Janos Follath315b51c2018-07-09 16:04:51 +01002880 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
2881 temp_output_buffer,
2882 output_length );
2883 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002884 {
Janos Follath315b51c2018-07-09 16:04:51 +01002885 status = mbedtls_to_psa_error( cipher_ret );
2886 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02002887 }
Janos Follath315b51c2018-07-09 16:04:51 +01002888
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002889 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01002890 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002891 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002892 memcpy( output, temp_output_buffer, *output_length );
2893 else
2894 {
Janos Follath315b51c2018-07-09 16:04:51 +01002895 status = PSA_ERROR_BUFFER_TOO_SMALL;
2896 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002897 }
mohammad1603503973b2018-03-12 15:59:30 +02002898
Gilles Peskine3f108122018-12-07 18:14:53 +01002899 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002900 status = psa_cipher_abort( operation );
2901
2902 return( status );
2903
2904error:
2905
2906 *output_length = 0;
2907
Gilles Peskine3f108122018-12-07 18:14:53 +01002908 mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002909 (void) psa_cipher_abort( operation );
2910
2911 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002912}
2913
Gilles Peskinee553c652018-06-04 16:22:46 +02002914psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2915{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002916 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002917 {
2918 /* The object has (apparently) been initialized but it is not
2919 * in use. It's ok to call abort on such an object, and there's
2920 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002921 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002922 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002923
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002924 /* Sanity check (shouldn't happen: operation->alg should
2925 * always have been initialized to a valid value). */
2926 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2927 return( PSA_ERROR_BAD_STATE );
2928
mohammad1603503973b2018-03-12 15:59:30 +02002929 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002930
Moran Peker41deec42018-04-04 15:43:05 +03002931 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002932 operation->key_set = 0;
2933 operation->iv_set = 0;
2934 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002935 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002936 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002937
Moran Peker395db872018-05-31 14:07:14 +03002938 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002939}
2940
Gilles Peskinea0655c32018-04-30 17:06:50 +02002941
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002942
mohammad16038cc1cee2018-03-28 01:21:33 +03002943/****************************************************************/
2944/* Key Policy */
2945/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002946
mohammad160327010052018-07-03 13:16:15 +03002947#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02002948void psa_key_policy_set_usage( psa_key_policy_t *policy,
2949 psa_key_usage_t usage,
2950 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002951{
mohammad16034eed7572018-03-28 05:14:59 -07002952 policy->usage = usage;
2953 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002954}
2955
Gilles Peskineaa7bc472018-07-12 00:54:56 +02002956psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002957{
mohammad16036df908f2018-04-02 08:34:15 -07002958 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002959}
2960
Gilles Peskineaa7bc472018-07-12 00:54:56 +02002961psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002962{
mohammad16036df908f2018-04-02 08:34:15 -07002963 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002964}
mohammad160327010052018-07-03 13:16:15 +03002965#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002966
Gilles Peskinec5487a82018-12-03 18:08:14 +01002967psa_status_t psa_set_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02002968 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002969{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002970 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002971 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03002972
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002973 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002974 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002975
Gilles Peskinec5487a82018-12-03 18:08:14 +01002976 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002977 if( status != PSA_SUCCESS )
2978 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03002979
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002980 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2981 PSA_KEY_USAGE_ENCRYPT |
2982 PSA_KEY_USAGE_DECRYPT |
2983 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02002984 PSA_KEY_USAGE_VERIFY |
2985 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002986 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002987
mohammad16036df908f2018-04-02 08:34:15 -07002988 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002989
2990 return( PSA_SUCCESS );
2991}
2992
Gilles Peskinec5487a82018-12-03 18:08:14 +01002993psa_status_t psa_get_key_policy( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02002994 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002995{
Gilles Peskine2f060a82018-12-04 17:12:32 +01002996 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002997 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03002998
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002999 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03003000 return( PSA_ERROR_INVALID_ARGUMENT );
3001
Gilles Peskinec5487a82018-12-03 18:08:14 +01003002 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003003 if( status != PSA_SUCCESS )
3004 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003005
mohammad16036df908f2018-04-02 08:34:15 -07003006 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03003007
3008 return( PSA_SUCCESS );
3009}
Gilles Peskine20035e32018-02-03 22:44:14 +01003010
Gilles Peskinea0655c32018-04-30 17:06:50 +02003011
3012
mohammad1603804cd712018-03-20 22:44:08 +02003013/****************************************************************/
3014/* Key Lifetime */
3015/****************************************************************/
3016
Gilles Peskinec5487a82018-12-03 18:08:14 +01003017psa_status_t psa_get_key_lifetime( psa_key_handle_t handle,
Gilles Peskine2d277862018-06-18 15:41:12 +02003018 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02003019{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003020 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003021 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02003022
Gilles Peskinec5487a82018-12-03 18:08:14 +01003023 status = psa_get_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003024 if( status != PSA_SUCCESS )
3025 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02003026
mohammad1603804cd712018-03-20 22:44:08 +02003027 *lifetime = slot->lifetime;
3028
3029 return( PSA_SUCCESS );
3030}
3031
Gilles Peskine20035e32018-02-03 22:44:14 +01003032
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003033
mohammad16035955c982018-04-26 00:53:03 +03003034/****************************************************************/
3035/* AEAD */
3036/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003037
Gilles Peskineedf9a652018-08-17 18:11:56 +02003038typedef struct
3039{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003040 psa_key_slot_t *slot;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003041 const mbedtls_cipher_info_t *cipher_info;
3042 union
3043 {
3044#if defined(MBEDTLS_CCM_C)
3045 mbedtls_ccm_context ccm;
3046#endif /* MBEDTLS_CCM_C */
3047#if defined(MBEDTLS_GCM_C)
3048 mbedtls_gcm_context gcm;
3049#endif /* MBEDTLS_GCM_C */
3050 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003051 psa_algorithm_t core_alg;
3052 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003053 uint8_t tag_length;
3054} aead_operation_t;
3055
Gilles Peskine30a9e412019-01-14 18:36:12 +01003056static void psa_aead_abort_internal( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003057{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003058 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003059 {
3060#if defined(MBEDTLS_CCM_C)
3061 case PSA_ALG_CCM:
3062 mbedtls_ccm_free( &operation->ctx.ccm );
3063 break;
3064#endif /* MBEDTLS_CCM_C */
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003065#if defined(MBEDTLS_GCM_C)
Gilles Peskineedf9a652018-08-17 18:11:56 +02003066 case PSA_ALG_GCM:
3067 mbedtls_gcm_free( &operation->ctx.gcm );
3068 break;
3069#endif /* MBEDTLS_GCM_C */
3070 }
3071}
3072
3073static psa_status_t psa_aead_setup( aead_operation_t *operation,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003074 psa_key_handle_t handle,
Gilles Peskineedf9a652018-08-17 18:11:56 +02003075 psa_key_usage_t usage,
3076 psa_algorithm_t alg )
3077{
3078 psa_status_t status;
3079 size_t key_bits;
3080 mbedtls_cipher_id_t cipher_id;
3081
Gilles Peskinec5487a82018-12-03 18:08:14 +01003082 status = psa_get_key_from_slot( handle, &operation->slot, usage, alg );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003083 if( status != PSA_SUCCESS )
3084 return( status );
3085
3086 key_bits = psa_get_key_bits( operation->slot );
3087
3088 operation->cipher_info =
3089 mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
3090 &cipher_id );
3091 if( operation->cipher_info == NULL )
3092 return( PSA_ERROR_NOT_SUPPORTED );
3093
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003094 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003095 {
3096#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003097 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
3098 operation->core_alg = PSA_ALG_CCM;
3099 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003100 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3101 return( PSA_ERROR_INVALID_ARGUMENT );
3102 mbedtls_ccm_init( &operation->ctx.ccm );
3103 status = mbedtls_to_psa_error(
3104 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
3105 operation->slot->data.raw.data,
3106 (unsigned int) key_bits ) );
3107 if( status != 0 )
3108 goto cleanup;
3109 break;
3110#endif /* MBEDTLS_CCM_C */
3111
3112#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003113 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
3114 operation->core_alg = PSA_ALG_GCM;
3115 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003116 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3117 return( PSA_ERROR_INVALID_ARGUMENT );
3118 mbedtls_gcm_init( &operation->ctx.gcm );
3119 status = mbedtls_to_psa_error(
3120 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
3121 operation->slot->data.raw.data,
3122 (unsigned int) key_bits ) );
3123 break;
3124#endif /* MBEDTLS_GCM_C */
3125
3126 default:
3127 return( PSA_ERROR_NOT_SUPPORTED );
3128 }
3129
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003130 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
3131 {
3132 status = PSA_ERROR_INVALID_ARGUMENT;
3133 goto cleanup;
3134 }
3135 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
3136 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
3137 * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
3138 * In both cases, mbedtls_xxx will validate the tag length below. */
3139
Gilles Peskineedf9a652018-08-17 18:11:56 +02003140 return( PSA_SUCCESS );
3141
3142cleanup:
Gilles Peskine30a9e412019-01-14 18:36:12 +01003143 psa_aead_abort_internal( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003144 return( status );
3145}
3146
Gilles Peskinec5487a82018-12-03 18:08:14 +01003147psa_status_t psa_aead_encrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003148 psa_algorithm_t alg,
3149 const uint8_t *nonce,
3150 size_t nonce_length,
3151 const uint8_t *additional_data,
3152 size_t additional_data_length,
3153 const uint8_t *plaintext,
3154 size_t plaintext_length,
3155 uint8_t *ciphertext,
3156 size_t ciphertext_size,
3157 size_t *ciphertext_length )
3158{
mohammad16035955c982018-04-26 00:53:03 +03003159 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003160 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03003161 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02003162
mohammad1603f08a5502018-06-03 15:05:47 +03003163 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003164
Gilles Peskinec5487a82018-12-03 18:08:14 +01003165 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003166 if( status != PSA_SUCCESS )
3167 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003168
Gilles Peskineedf9a652018-08-17 18:11:56 +02003169 /* For all currently supported modes, the tag is at the end of the
3170 * ciphertext. */
3171 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
3172 {
3173 status = PSA_ERROR_BUFFER_TOO_SMALL;
3174 goto exit;
3175 }
3176 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03003177
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003178#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003179 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003180 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003181 status = mbedtls_to_psa_error(
3182 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
3183 MBEDTLS_GCM_ENCRYPT,
3184 plaintext_length,
3185 nonce, nonce_length,
3186 additional_data, additional_data_length,
3187 plaintext, ciphertext,
3188 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03003189 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003190 else
3191#endif /* MBEDTLS_GCM_C */
3192#if defined(MBEDTLS_CCM_C)
3193 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003194 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003195 status = mbedtls_to_psa_error(
3196 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
3197 plaintext_length,
3198 nonce, nonce_length,
3199 additional_data,
3200 additional_data_length,
3201 plaintext, ciphertext,
3202 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003203 }
mohammad16035c8845f2018-05-09 05:40:09 -07003204 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003205#endif /* MBEDTLS_CCM_C */
mohammad16035c8845f2018-05-09 05:40:09 -07003206 {
mohammad1603554faad2018-06-03 15:07:38 +03003207 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07003208 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003209
Gilles Peskineedf9a652018-08-17 18:11:56 +02003210 if( status != PSA_SUCCESS && ciphertext_size != 0 )
3211 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003212
Gilles Peskineedf9a652018-08-17 18:11:56 +02003213exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01003214 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003215 if( status == PSA_SUCCESS )
3216 *ciphertext_length = plaintext_length + operation.tag_length;
3217 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003218}
3219
Gilles Peskineee652a32018-06-01 19:23:52 +02003220/* Locate the tag in a ciphertext buffer containing the encrypted data
3221 * followed by the tag. Return the length of the part preceding the tag in
3222 * *plaintext_length. This is the size of the plaintext in modes where
3223 * the encrypted data has the same size as the plaintext, such as
3224 * CCM and GCM. */
3225static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
3226 const uint8_t *ciphertext,
3227 size_t ciphertext_length,
3228 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02003229 const uint8_t **p_tag )
3230{
3231 size_t payload_length;
3232 if( tag_length > ciphertext_length )
3233 return( PSA_ERROR_INVALID_ARGUMENT );
3234 payload_length = ciphertext_length - tag_length;
3235 if( payload_length > plaintext_size )
3236 return( PSA_ERROR_BUFFER_TOO_SMALL );
3237 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02003238 return( PSA_SUCCESS );
3239}
3240
Gilles Peskinec5487a82018-12-03 18:08:14 +01003241psa_status_t psa_aead_decrypt( psa_key_handle_t handle,
mohammad16035955c982018-04-26 00:53:03 +03003242 psa_algorithm_t alg,
3243 const uint8_t *nonce,
3244 size_t nonce_length,
3245 const uint8_t *additional_data,
3246 size_t additional_data_length,
3247 const uint8_t *ciphertext,
3248 size_t ciphertext_length,
3249 uint8_t *plaintext,
3250 size_t plaintext_size,
3251 size_t *plaintext_length )
3252{
mohammad16035955c982018-04-26 00:53:03 +03003253 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003254 aead_operation_t operation;
3255 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02003256
Gilles Peskineee652a32018-06-01 19:23:52 +02003257 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003258
Gilles Peskinec5487a82018-12-03 18:08:14 +01003259 status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003260 if( status != PSA_SUCCESS )
3261 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003262
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003263#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003264 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003265 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003266 status = psa_aead_unpadded_locate_tag( operation.tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003267 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003268 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02003269 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003270 goto exit;
Gilles Peskineee652a32018-06-01 19:23:52 +02003271
Gilles Peskineedf9a652018-08-17 18:11:56 +02003272 status = mbedtls_to_psa_error(
3273 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
3274 ciphertext_length - operation.tag_length,
3275 nonce, nonce_length,
3276 additional_data,
3277 additional_data_length,
3278 tag, operation.tag_length,
3279 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03003280 }
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003281 else
3282#endif /* MBEDTLS_GCM_C */
3283#if defined(MBEDTLS_CCM_C)
3284 if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003285 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003286 status = psa_aead_unpadded_locate_tag( operation.tag_length,
mohammad16039375f842018-06-03 14:28:24 +03003287 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003288 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003289 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003290 goto exit;
mohammad16039375f842018-06-03 14:28:24 +03003291
Gilles Peskineedf9a652018-08-17 18:11:56 +02003292 status = mbedtls_to_psa_error(
3293 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
3294 ciphertext_length - operation.tag_length,
3295 nonce, nonce_length,
3296 additional_data,
3297 additional_data_length,
3298 ciphertext, plaintext,
3299 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003300 }
mohammad160339574652018-06-01 04:39:53 -07003301 else
Gilles Peskineb0b189f2018-11-28 17:30:58 +01003302#endif /* MBEDTLS_CCM_C */
mohammad160339574652018-06-01 04:39:53 -07003303 {
mohammad1603554faad2018-06-03 15:07:38 +03003304 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003305 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003306
Gilles Peskineedf9a652018-08-17 18:11:56 +02003307 if( status != PSA_SUCCESS && plaintext_size != 0 )
3308 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03003309
Gilles Peskineedf9a652018-08-17 18:11:56 +02003310exit:
Gilles Peskine30a9e412019-01-14 18:36:12 +01003311 psa_aead_abort_internal( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003312 if( status == PSA_SUCCESS )
3313 *plaintext_length = ciphertext_length - operation.tag_length;
3314 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003315}
3316
Gilles Peskinea0655c32018-04-30 17:06:50 +02003317
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003318
Gilles Peskine20035e32018-02-03 22:44:14 +01003319/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003320/* Generators */
3321/****************************************************************/
3322
3323psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3324{
3325 psa_status_t status = PSA_SUCCESS;
3326 if( generator->alg == 0 )
3327 {
3328 /* The object has (apparently) been initialized but it is not
3329 * in use. It's ok to call abort on such an object, and there's
3330 * nothing to do. */
3331 }
3332 else
Gilles Peskine751d9652018-09-18 12:05:44 +02003333 if( generator->alg == PSA_ALG_SELECT_RAW )
3334 {
3335 if( generator->ctx.buffer.data != NULL )
3336 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003337 mbedtls_platform_zeroize( generator->ctx.buffer.data,
Gilles Peskine751d9652018-09-18 12:05:44 +02003338 generator->ctx.buffer.size );
3339 mbedtls_free( generator->ctx.buffer.data );
3340 }
3341 }
3342 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003343#if defined(MBEDTLS_MD_C)
3344 if( PSA_ALG_IS_HKDF( generator->alg ) )
3345 {
3346 mbedtls_free( generator->ctx.hkdf.info );
3347 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3348 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003349 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3350 /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
3351 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003352 {
3353 if( generator->ctx.tls12_prf.key != NULL )
3354 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003355 mbedtls_platform_zeroize( generator->ctx.tls12_prf.key,
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003356 generator->ctx.tls12_prf.key_len );
3357 mbedtls_free( generator->ctx.tls12_prf.key );
3358 }
Hanno Becker580fba12018-11-13 20:50:45 +00003359
3360 if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
3361 {
Gilles Peskine3f108122018-12-07 18:14:53 +01003362 mbedtls_platform_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003363 generator->ctx.tls12_prf.Ai_with_seed_len );
3364 mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
3365 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003366 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003367 else
3368#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003369 {
3370 status = PSA_ERROR_BAD_STATE;
3371 }
3372 memset( generator, 0, sizeof( *generator ) );
3373 return( status );
3374}
3375
3376
3377psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3378 size_t *capacity)
3379{
3380 *capacity = generator->capacity;
3381 return( PSA_SUCCESS );
3382}
3383
Gilles Peskinebef7f142018-07-12 17:22:21 +02003384#if defined(MBEDTLS_MD_C)
3385/* Read some bytes from an HKDF-based generator. This performs a chunk
3386 * of the expand phase of the HKDF algorithm. */
3387static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3388 psa_algorithm_t hash_alg,
3389 uint8_t *output,
3390 size_t output_length )
3391{
3392 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3393 psa_status_t status;
3394
3395 while( output_length != 0 )
3396 {
3397 /* Copy what remains of the current block */
3398 uint8_t n = hash_length - hkdf->offset_in_block;
3399 if( n > output_length )
3400 n = (uint8_t) output_length;
3401 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3402 output += n;
3403 output_length -= n;
3404 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003405 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003406 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003407 /* We can't be wanting more output after block 0xff, otherwise
3408 * the capacity check in psa_generator_read() would have
3409 * prevented this call. It could happen only if the generator
3410 * object was corrupted or if this function is called directly
3411 * inside the library. */
3412 if( hkdf->block_number == 0xff )
3413 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003414
3415 /* We need a new block */
3416 ++hkdf->block_number;
3417 hkdf->offset_in_block = 0;
3418 status = psa_hmac_setup_internal( &hkdf->hmac,
3419 hkdf->prk, hash_length,
3420 hash_alg );
3421 if( status != PSA_SUCCESS )
3422 return( status );
3423 if( hkdf->block_number != 1 )
3424 {
3425 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3426 hkdf->output_block,
3427 hash_length );
3428 if( status != PSA_SUCCESS )
3429 return( status );
3430 }
3431 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3432 hkdf->info,
3433 hkdf->info_length );
3434 if( status != PSA_SUCCESS )
3435 return( status );
3436 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3437 &hkdf->block_number, 1 );
3438 if( status != PSA_SUCCESS )
3439 return( status );
3440 status = psa_hmac_finish_internal( &hkdf->hmac,
3441 hkdf->output_block,
3442 sizeof( hkdf->output_block ) );
3443 if( status != PSA_SUCCESS )
3444 return( status );
3445 }
3446
3447 return( PSA_SUCCESS );
3448}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003449
3450static psa_status_t psa_generator_tls12_prf_generate_next_block(
3451 psa_tls12_prf_generator_t *tls12_prf,
3452 psa_algorithm_t alg )
3453{
3454 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3455 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3456 psa_hmac_internal_data hmac;
3457 psa_status_t status, cleanup_status;
3458
Hanno Becker3b339e22018-11-13 20:56:14 +00003459 unsigned char *Ai;
3460 size_t Ai_len;
3461
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003462 /* We can't be wanting more output after block 0xff, otherwise
3463 * the capacity check in psa_generator_read() would have
3464 * prevented this call. It could happen only if the generator
3465 * object was corrupted or if this function is called directly
3466 * inside the library. */
3467 if( tls12_prf->block_number == 0xff )
3468 return( PSA_ERROR_BAD_STATE );
3469
3470 /* We need a new block */
3471 ++tls12_prf->block_number;
3472 tls12_prf->offset_in_block = 0;
3473
3474 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3475 *
3476 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3477 *
3478 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3479 * HMAC_hash(secret, A(2) + seed) +
3480 * HMAC_hash(secret, A(3) + seed) + ...
3481 *
3482 * A(0) = seed
3483 * A(i) = HMAC_hash( secret, A(i-1) )
3484 *
3485 * The `psa_tls12_prf_generator` structures saves the block
3486 * `HMAC_hash(secret, A(i) + seed)` from which the output
3487 * is currently extracted as `output_block`, while
3488 * `A(i) + seed` is stored in `Ai_with_seed`.
3489 *
3490 * Generating a new block means recalculating `Ai_with_seed`
3491 * from the A(i)-part of it, and afterwards recalculating
3492 * `output_block`.
3493 *
3494 * A(0) is computed at setup time.
3495 *
3496 */
3497
3498 psa_hmac_init_internal( &hmac );
3499
3500 /* We must distinguish the calculation of A(1) from those
3501 * of A(2) and higher, because A(0)=seed has a different
3502 * length than the other A(i). */
3503 if( tls12_prf->block_number == 1 )
3504 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003505 Ai = tls12_prf->Ai_with_seed + hash_length;
3506 Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003507 }
3508 else
3509 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003510 Ai = tls12_prf->Ai_with_seed;
3511 Ai_len = hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003512 }
3513
Hanno Becker3b339e22018-11-13 20:56:14 +00003514 /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
3515 status = psa_hmac_setup_internal( &hmac,
3516 tls12_prf->key,
3517 tls12_prf->key_len,
3518 hash_alg );
3519 if( status != PSA_SUCCESS )
3520 goto cleanup;
3521
3522 status = psa_hash_update( &hmac.hash_ctx,
3523 Ai, Ai_len );
3524 if( status != PSA_SUCCESS )
3525 goto cleanup;
3526
3527 status = psa_hmac_finish_internal( &hmac,
3528 tls12_prf->Ai_with_seed,
3529 hash_length );
3530 if( status != PSA_SUCCESS )
3531 goto cleanup;
3532
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003533 /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
3534 status = psa_hmac_setup_internal( &hmac,
3535 tls12_prf->key,
3536 tls12_prf->key_len,
3537 hash_alg );
3538 if( status != PSA_SUCCESS )
3539 goto cleanup;
3540
3541 status = psa_hash_update( &hmac.hash_ctx,
3542 tls12_prf->Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003543 tls12_prf->Ai_with_seed_len );
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003544 if( status != PSA_SUCCESS )
3545 goto cleanup;
3546
3547 status = psa_hmac_finish_internal( &hmac,
3548 tls12_prf->output_block,
3549 hash_length );
3550 if( status != PSA_SUCCESS )
3551 goto cleanup;
3552
3553cleanup:
3554
3555 cleanup_status = psa_hmac_abort_internal( &hmac );
3556 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
3557 status = cleanup_status;
3558
3559 return( status );
3560}
3561
3562/* Read some bytes from an TLS-1.2-PRF-based generator.
3563 * See Section 5 of RFC 5246. */
3564static psa_status_t psa_generator_tls12_prf_read(
3565 psa_tls12_prf_generator_t *tls12_prf,
3566 psa_algorithm_t alg,
3567 uint8_t *output,
3568 size_t output_length )
3569{
3570 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3571 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3572 psa_status_t status;
3573
3574 while( output_length != 0 )
3575 {
3576 /* Copy what remains of the current block */
3577 uint8_t n = hash_length - tls12_prf->offset_in_block;
3578
3579 /* Check if we have fully processed the current block. */
3580 if( n == 0 )
3581 {
3582 status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
3583 alg );
3584 if( status != PSA_SUCCESS )
3585 return( status );
3586
3587 continue;
3588 }
3589
3590 if( n > output_length )
3591 n = (uint8_t) output_length;
3592 memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
3593 n );
3594 output += n;
3595 output_length -= n;
3596 tls12_prf->offset_in_block += n;
3597 }
3598
3599 return( PSA_SUCCESS );
3600}
Gilles Peskinebef7f142018-07-12 17:22:21 +02003601#endif /* MBEDTLS_MD_C */
3602
Gilles Peskineeab56e42018-07-12 17:12:33 +02003603psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3604 uint8_t *output,
3605 size_t output_length )
3606{
3607 psa_status_t status;
3608
3609 if( output_length > generator->capacity )
3610 {
3611 generator->capacity = 0;
3612 /* Go through the error path to wipe all confidential data now
3613 * that the generator object is useless. */
3614 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3615 goto exit;
3616 }
3617 if( output_length == 0 &&
3618 generator->capacity == 0 && generator->alg == 0 )
3619 {
3620 /* Edge case: this is a blank or finished generator, and 0
3621 * bytes were requested. The right error in this case could
3622 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3623 * INSUFFICIENT_CAPACITY, which is right for a finished
3624 * generator, for consistency with the case when
3625 * output_length > 0. */
3626 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3627 }
3628 generator->capacity -= output_length;
3629
Gilles Peskine751d9652018-09-18 12:05:44 +02003630 if( generator->alg == PSA_ALG_SELECT_RAW )
3631 {
Gilles Peskine211a4362018-10-25 22:22:31 +02003632 /* Initially, the capacity of a selection generator is always
3633 * the size of the buffer, i.e. `generator->ctx.buffer.size`,
3634 * abbreviated in this comment as `size`. When the remaining
3635 * capacity is `c`, the next bytes to serve start `c` bytes
3636 * from the end of the buffer, i.e. `size - c` from the
3637 * beginning of the buffer. Since `generator->capacity` was just
3638 * decremented above, we need to serve the bytes from
3639 * `size - generator->capacity - output_length` to
3640 * `size - generator->capacity`. */
Gilles Peskine751d9652018-09-18 12:05:44 +02003641 size_t offset =
3642 generator->ctx.buffer.size - generator->capacity - output_length;
3643 memcpy( output, generator->ctx.buffer.data + offset, output_length );
3644 status = PSA_SUCCESS;
3645 }
3646 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003647#if defined(MBEDTLS_MD_C)
3648 if( PSA_ALG_IS_HKDF( generator->alg ) )
3649 {
3650 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
3651 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
3652 output, output_length );
3653 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003654 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3655 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003656 {
3657 status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
3658 generator->alg, output,
3659 output_length );
3660 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003661 else
3662#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003663 {
3664 return( PSA_ERROR_BAD_STATE );
3665 }
3666
3667exit:
3668 if( status != PSA_SUCCESS )
3669 {
3670 psa_generator_abort( generator );
3671 memset( output, '!', output_length );
3672 }
3673 return( status );
3674}
3675
Gilles Peskine08542d82018-07-19 17:05:42 +02003676#if defined(MBEDTLS_DES_C)
3677static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
3678{
3679 if( data_size >= 8 )
3680 mbedtls_des_key_set_parity( data );
3681 if( data_size >= 16 )
3682 mbedtls_des_key_set_parity( data + 8 );
3683 if( data_size >= 24 )
3684 mbedtls_des_key_set_parity( data + 16 );
3685}
3686#endif /* MBEDTLS_DES_C */
3687
Gilles Peskinec5487a82018-12-03 18:08:14 +01003688psa_status_t psa_generator_import_key( psa_key_handle_t handle,
Gilles Peskineeab56e42018-07-12 17:12:33 +02003689 psa_key_type_t type,
3690 size_t bits,
3691 psa_crypto_generator_t *generator )
3692{
3693 uint8_t *data = NULL;
3694 size_t bytes = PSA_BITS_TO_BYTES( bits );
3695 psa_status_t status;
3696
3697 if( ! key_type_is_raw_bytes( type ) )
3698 return( PSA_ERROR_INVALID_ARGUMENT );
3699 if( bits % 8 != 0 )
3700 return( PSA_ERROR_INVALID_ARGUMENT );
3701 data = mbedtls_calloc( 1, bytes );
3702 if( data == NULL )
3703 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3704
3705 status = psa_generator_read( generator, data, bytes );
3706 if( status != PSA_SUCCESS )
3707 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02003708#if defined(MBEDTLS_DES_C)
3709 if( type == PSA_KEY_TYPE_DES )
3710 psa_des_set_key_parity( data, bytes );
3711#endif /* MBEDTLS_DES_C */
Gilles Peskinec5487a82018-12-03 18:08:14 +01003712 status = psa_import_key( handle, type, data, bytes );
Gilles Peskineeab56e42018-07-12 17:12:33 +02003713
3714exit:
3715 mbedtls_free( data );
3716 return( status );
3717}
3718
3719
3720
3721/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003722/* Key derivation */
3723/****************************************************************/
3724
Gilles Peskinea05219c2018-11-16 16:02:56 +01003725#if defined(MBEDTLS_MD_C)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003726/* Set up an HKDF-based generator. This is exactly the extract phase
Gilles Peskine346797d2018-11-16 16:05:06 +01003727 * of the HKDF algorithm.
3728 *
3729 * Note that if this function fails, you must call psa_generator_abort()
3730 * to potentially free embedded data structures and wipe confidential data.
3731 */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003732static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003733 const uint8_t *secret,
3734 size_t secret_length,
Gilles Peskinebef7f142018-07-12 17:22:21 +02003735 psa_algorithm_t hash_alg,
3736 const uint8_t *salt,
3737 size_t salt_length,
3738 const uint8_t *label,
3739 size_t label_length )
3740{
3741 psa_status_t status;
3742 status = psa_hmac_setup_internal( &hkdf->hmac,
3743 salt, salt_length,
Gilles Peskine00709fa2018-08-22 18:25:41 +02003744 PSA_ALG_HMAC_GET_HASH( hash_alg ) );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003745 if( status != PSA_SUCCESS )
3746 return( status );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003747 status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003748 if( status != PSA_SUCCESS )
3749 return( status );
3750 status = psa_hmac_finish_internal( &hkdf->hmac,
3751 hkdf->prk,
3752 sizeof( hkdf->prk ) );
3753 if( status != PSA_SUCCESS )
3754 return( status );
3755 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
3756 hkdf->block_number = 0;
3757 hkdf->info_length = label_length;
3758 if( label_length != 0 )
3759 {
3760 hkdf->info = mbedtls_calloc( 1, label_length );
3761 if( hkdf->info == NULL )
3762 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3763 memcpy( hkdf->info, label, label_length );
3764 }
3765 return( PSA_SUCCESS );
3766}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003767#endif /* MBEDTLS_MD_C */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003768
Gilles Peskinea05219c2018-11-16 16:02:56 +01003769#if defined(MBEDTLS_MD_C)
Gilles Peskine346797d2018-11-16 16:05:06 +01003770/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
3771 *
3772 * Note that if this function fails, you must call psa_generator_abort()
3773 * to potentially free embedded data structures and wipe confidential data.
3774 */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003775static psa_status_t psa_generator_tls12_prf_setup(
3776 psa_tls12_prf_generator_t *tls12_prf,
3777 const unsigned char *key,
3778 size_t key_len,
3779 psa_algorithm_t hash_alg,
3780 const uint8_t *salt,
3781 size_t salt_length,
3782 const uint8_t *label,
3783 size_t label_length )
3784{
3785 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Hanno Becker580fba12018-11-13 20:50:45 +00003786 size_t Ai_with_seed_len = hash_length + salt_length + label_length;
3787 int overflow;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003788
3789 tls12_prf->key = mbedtls_calloc( 1, key_len );
3790 if( tls12_prf->key == NULL )
3791 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3792 tls12_prf->key_len = key_len;
3793 memcpy( tls12_prf->key, key, key_len );
3794
Hanno Becker580fba12018-11-13 20:50:45 +00003795 overflow = ( salt_length + label_length < salt_length ) ||
3796 ( salt_length + label_length + hash_length < hash_length );
3797 if( overflow )
3798 return( PSA_ERROR_INVALID_ARGUMENT );
3799
3800 tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
3801 if( tls12_prf->Ai_with_seed == NULL )
3802 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3803 tls12_prf->Ai_with_seed_len = Ai_with_seed_len;
3804
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003805 /* Write `label + seed' at the end of the `A(i) + seed` buffer,
3806 * leaving the initial `hash_length` bytes unspecified for now. */
Hanno Becker353e4532018-11-15 09:53:57 +00003807 if( label_length != 0 )
3808 {
3809 memcpy( tls12_prf->Ai_with_seed + hash_length,
3810 label, label_length );
3811 }
3812
3813 if( salt_length != 0 )
3814 {
3815 memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
3816 salt, salt_length );
3817 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003818
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003819 /* The first block gets generated when
3820 * psa_generator_read() is called. */
3821 tls12_prf->block_number = 0;
3822 tls12_prf->offset_in_block = hash_length;
3823
3824 return( PSA_SUCCESS );
3825}
Hanno Becker1aaedc02018-11-16 11:35:34 +00003826
3827/* Set up a TLS-1.2-PSK-to-MS-based generator. */
3828static psa_status_t psa_generator_tls12_psk_to_ms_setup(
3829 psa_tls12_prf_generator_t *tls12_prf,
3830 const unsigned char *psk,
3831 size_t psk_len,
3832 psa_algorithm_t hash_alg,
3833 const uint8_t *salt,
3834 size_t salt_length,
3835 const uint8_t *label,
3836 size_t label_length )
3837{
3838 psa_status_t status;
3839 unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
3840
3841 if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
3842 return( PSA_ERROR_INVALID_ARGUMENT );
3843
3844 /* Quoting RFC 4279, Section 2:
3845 *
3846 * The premaster secret is formed as follows: if the PSK is N octets
3847 * long, concatenate a uint16 with the value N, N zero octets, a second
3848 * uint16 with the value N, and the PSK itself.
3849 */
3850
3851 pms[0] = ( psk_len >> 8 ) & 0xff;
3852 pms[1] = ( psk_len >> 0 ) & 0xff;
3853 memset( pms + 2, 0, psk_len );
3854 pms[2 + psk_len + 0] = pms[0];
3855 pms[2 + psk_len + 1] = pms[1];
3856 memcpy( pms + 4 + psk_len, psk, psk_len );
3857
3858 status = psa_generator_tls12_prf_setup( tls12_prf,
3859 pms, 4 + 2 * psk_len,
3860 hash_alg,
3861 salt, salt_length,
3862 label, label_length );
3863
Gilles Peskine3f108122018-12-07 18:14:53 +01003864 mbedtls_platform_zeroize( pms, sizeof( pms ) );
Hanno Becker1aaedc02018-11-16 11:35:34 +00003865 return( status );
3866}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003867#endif /* MBEDTLS_MD_C */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003868
Gilles Peskine346797d2018-11-16 16:05:06 +01003869/* Note that if this function fails, you must call psa_generator_abort()
3870 * to potentially free embedded data structures and wipe confidential data.
3871 */
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003872static psa_status_t psa_key_derivation_internal(
3873 psa_crypto_generator_t *generator,
3874 const uint8_t *secret, size_t secret_length,
3875 psa_algorithm_t alg,
3876 const uint8_t *salt, size_t salt_length,
3877 const uint8_t *label, size_t label_length,
3878 size_t capacity )
3879{
3880 psa_status_t status;
3881 size_t max_capacity;
3882
3883 /* Set generator->alg even on failure so that abort knows what to do. */
3884 generator->alg = alg;
3885
Gilles Peskine751d9652018-09-18 12:05:44 +02003886 if( alg == PSA_ALG_SELECT_RAW )
3887 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003888 (void) salt;
Gilles Peskine751d9652018-09-18 12:05:44 +02003889 if( salt_length != 0 )
3890 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea05219c2018-11-16 16:02:56 +01003891 (void) label;
Gilles Peskine751d9652018-09-18 12:05:44 +02003892 if( label_length != 0 )
3893 return( PSA_ERROR_INVALID_ARGUMENT );
3894 generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
3895 if( generator->ctx.buffer.data == NULL )
3896 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3897 memcpy( generator->ctx.buffer.data, secret, secret_length );
3898 generator->ctx.buffer.size = secret_length;
3899 max_capacity = secret_length;
3900 status = PSA_SUCCESS;
3901 }
3902 else
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003903#if defined(MBEDTLS_MD_C)
3904 if( PSA_ALG_IS_HKDF( alg ) )
3905 {
3906 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3907 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3908 if( hash_size == 0 )
3909 return( PSA_ERROR_NOT_SUPPORTED );
3910 max_capacity = 255 * hash_size;
3911 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
3912 secret, secret_length,
3913 hash_alg,
3914 salt, salt_length,
3915 label, label_length );
3916 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003917 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
3918 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
3919 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003920 {
3921 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3922 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3923
3924 /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
3925 if( hash_alg != PSA_ALG_SHA_256 &&
3926 hash_alg != PSA_ALG_SHA_384 )
3927 {
3928 return( PSA_ERROR_NOT_SUPPORTED );
3929 }
3930
3931 max_capacity = 255 * hash_size;
Hanno Becker1aaedc02018-11-16 11:35:34 +00003932
3933 if( PSA_ALG_IS_TLS12_PRF( alg ) )
3934 {
3935 status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
3936 secret, secret_length,
3937 hash_alg, salt, salt_length,
3938 label, label_length );
3939 }
3940 else
3941 {
3942 status = psa_generator_tls12_psk_to_ms_setup(
3943 &generator->ctx.tls12_prf,
3944 secret, secret_length,
3945 hash_alg, salt, salt_length,
3946 label, label_length );
3947 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003948 }
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003949 else
3950#endif
3951 {
3952 return( PSA_ERROR_NOT_SUPPORTED );
3953 }
3954
3955 if( status != PSA_SUCCESS )
3956 return( status );
3957
3958 if( capacity <= max_capacity )
3959 generator->capacity = capacity;
Gilles Peskine8feb3a82018-09-18 12:06:11 +02003960 else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
3961 generator->capacity = max_capacity;
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003962 else
3963 return( PSA_ERROR_INVALID_ARGUMENT );
3964
3965 return( PSA_SUCCESS );
3966}
3967
Gilles Peskineea0fb492018-07-12 17:17:20 +02003968psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01003969 psa_key_handle_t handle,
Gilles Peskineea0fb492018-07-12 17:17:20 +02003970 psa_algorithm_t alg,
3971 const uint8_t *salt,
3972 size_t salt_length,
3973 const uint8_t *label,
3974 size_t label_length,
3975 size_t capacity )
3976{
Gilles Peskine2f060a82018-12-04 17:12:32 +01003977 psa_key_slot_t *slot;
Gilles Peskineea0fb492018-07-12 17:17:20 +02003978 psa_status_t status;
3979
3980 if( generator->alg != 0 )
3981 return( PSA_ERROR_BAD_STATE );
3982
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003983 /* Make sure that alg is a key derivation algorithm. This prevents
3984 * key selection algorithms, which psa_key_derivation_internal
3985 * accepts for the sake of key agreement. */
Gilles Peskineea0fb492018-07-12 17:17:20 +02003986 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
3987 return( PSA_ERROR_INVALID_ARGUMENT );
3988
Gilles Peskinec5487a82018-12-03 18:08:14 +01003989 status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DERIVE, alg );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003990 if( status != PSA_SUCCESS )
3991 return( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003992
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003993 if( slot->type != PSA_KEY_TYPE_DERIVE )
3994 return( PSA_ERROR_INVALID_ARGUMENT );
3995
3996 status = psa_key_derivation_internal( generator,
3997 slot->data.raw.data,
3998 slot->data.raw.bytes,
3999 alg,
4000 salt, salt_length,
4001 label, label_length,
4002 capacity );
4003 if( status != PSA_SUCCESS )
Gilles Peskineea0fb492018-07-12 17:17:20 +02004004 psa_generator_abort( generator );
4005 return( status );
4006}
4007
4008
4009
4010/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02004011/* Key agreement */
4012/****************************************************************/
4013
Gilles Peskinea05219c2018-11-16 16:02:56 +01004014#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004015static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
4016 size_t peer_key_length,
4017 const mbedtls_ecp_keypair *our_key,
4018 uint8_t *shared_secret,
4019 size_t shared_secret_size,
4020 size_t *shared_secret_length )
4021{
4022 mbedtls_pk_context pk;
4023 mbedtls_ecp_keypair *their_key = NULL;
4024 mbedtls_ecdh_context ecdh;
4025 int ret;
4026 mbedtls_ecdh_init( &ecdh );
4027 mbedtls_pk_init( &pk );
4028
4029 ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
4030 if( ret != 0 )
4031 goto exit;
Gilles Peskine88714d72018-10-25 23:07:25 +02004032 switch( mbedtls_pk_get_type( &pk ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004033 {
Gilles Peskine88714d72018-10-25 23:07:25 +02004034 case MBEDTLS_PK_ECKEY:
4035 case MBEDTLS_PK_ECKEY_DH:
4036 break;
4037 default:
4038 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4039 goto exit;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004040 }
4041 their_key = mbedtls_pk_ec( pk );
Gilles Peskineb4086612018-11-14 20:51:23 +01004042 if( their_key->grp.id != our_key->grp.id )
4043 {
4044 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
4045 goto exit;
4046 }
4047
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004048 ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
4049 if( ret != 0 )
4050 goto exit;
4051 ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
4052 if( ret != 0 )
4053 goto exit;
4054
4055 ret = mbedtls_ecdh_calc_secret( &ecdh,
4056 shared_secret_length,
4057 shared_secret, shared_secret_size,
4058 mbedtls_ctr_drbg_random,
4059 &global_data.ctr_drbg );
4060
4061exit:
4062 mbedtls_pk_free( &pk );
4063 mbedtls_ecdh_free( &ecdh );
4064 return( mbedtls_to_psa_error( ret ) );
4065}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004066#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004067
Gilles Peskine01d718c2018-09-18 12:01:02 +02004068#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
4069
Gilles Peskine346797d2018-11-16 16:05:06 +01004070/* Note that if this function fails, you must call psa_generator_abort()
4071 * to potentially free embedded data structures and wipe confidential data.
4072 */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004073static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
Gilles Peskine2f060a82018-12-04 17:12:32 +01004074 psa_key_slot_t *private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004075 const uint8_t *peer_key,
4076 size_t peer_key_length,
4077 psa_algorithm_t alg )
4078{
4079 psa_status_t status;
4080 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4081 size_t shared_secret_length = 0;
4082
4083 /* Step 1: run the secret agreement algorithm to generate the shared
4084 * secret. */
4085 switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
4086 {
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004087#if defined(MBEDTLS_ECDH_C)
4088 case PSA_ALG_ECDH_BASE:
4089 if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
4090 return( PSA_ERROR_INVALID_ARGUMENT );
4091 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
4092 private_key->data.ecp,
4093 shared_secret,
4094 sizeof( shared_secret ),
4095 &shared_secret_length );
4096 break;
4097#endif /* MBEDTLS_ECDH_C */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004098 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01004099 (void) private_key;
4100 (void) peer_key;
4101 (void) peer_key_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004102 return( PSA_ERROR_NOT_SUPPORTED );
4103 }
4104 if( status != PSA_SUCCESS )
4105 goto exit;
4106
4107 /* Step 2: set up the key derivation to generate key material from
4108 * the shared secret. */
4109 status = psa_key_derivation_internal( generator,
4110 shared_secret, shared_secret_length,
4111 PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
4112 NULL, 0, NULL, 0,
4113 PSA_GENERATOR_UNBRIDLED_CAPACITY );
4114exit:
Gilles Peskine3f108122018-12-07 18:14:53 +01004115 mbedtls_platform_zeroize( shared_secret, shared_secret_length );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004116 return( status );
4117}
4118
4119psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
Gilles Peskinec5487a82018-12-03 18:08:14 +01004120 psa_key_handle_t private_key,
Gilles Peskine01d718c2018-09-18 12:01:02 +02004121 const uint8_t *peer_key,
4122 size_t peer_key_length,
4123 psa_algorithm_t alg )
4124{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004125 psa_key_slot_t *slot;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004126 psa_status_t status;
4127 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4128 return( PSA_ERROR_INVALID_ARGUMENT );
4129 status = psa_get_key_from_slot( private_key, &slot,
4130 PSA_KEY_USAGE_DERIVE, alg );
4131 if( status != PSA_SUCCESS )
4132 return( status );
Gilles Peskine346797d2018-11-16 16:05:06 +01004133 status = psa_key_agreement_internal( generator,
4134 slot,
4135 peer_key, peer_key_length,
4136 alg );
4137 if( status != PSA_SUCCESS )
4138 psa_generator_abort( generator );
4139 return( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004140}
4141
4142
4143
4144/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004145/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02004146/****************************************************************/
4147
4148psa_status_t psa_generate_random( uint8_t *output,
4149 size_t output_size )
4150{
itayzafrir0adf0fc2018-09-06 16:24:41 +03004151 int ret;
4152 GUARD_MODULE_INITIALIZED;
4153
4154 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
Gilles Peskine05d69892018-06-19 22:00:52 +02004155 return( mbedtls_to_psa_error( ret ) );
4156}
4157
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004158#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
avolinski13beb102018-11-20 16:51:49 +02004159
4160/* Support function for error conversion between psa_its error codes to psa crypto */
4161static psa_status_t its_to_psa_error( psa_its_status_t ret )
4162{
4163 switch( ret )
4164 {
4165 case PSA_ITS_SUCCESS:
4166 return( PSA_SUCCESS );
4167
4168 case PSA_ITS_ERROR_KEY_NOT_FOUND:
4169 return( PSA_ERROR_EMPTY_SLOT );
4170
4171 case PSA_ITS_ERROR_STORAGE_FAILURE:
4172 return( PSA_ERROR_STORAGE_FAILURE );
4173
4174 case PSA_ITS_ERROR_INSUFFICIENT_SPACE:
4175 return( PSA_ERROR_INSUFFICIENT_STORAGE );
4176
4177 case PSA_ITS_ERROR_INVALID_KEY:
Jaeden Amero58600552018-11-30 12:04:38 +00004178 case PSA_ITS_ERROR_OFFSET_INVALID:
avolinski13beb102018-11-20 16:51:49 +02004179 case PSA_ITS_ERROR_INCORRECT_SIZE:
4180 case PSA_ITS_ERROR_BAD_POINTER:
4181 return( PSA_ERROR_INVALID_ARGUMENT );
4182
4183 case PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED:
4184 return( PSA_ERROR_NOT_SUPPORTED );
4185
4186 case PSA_ITS_ERROR_WRITE_ONCE:
4187 return( PSA_ERROR_OCCUPIED_SLOT );
4188
4189 default:
4190 return( PSA_ERROR_UNKNOWN_ERROR );
4191 }
4192}
4193
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004194psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
4195 size_t seed_size )
4196{
4197 psa_status_t status;
avolinski13beb102018-11-20 16:51:49 +02004198 psa_its_status_t its_status;
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004199 struct psa_its_info_t p_info;
4200 if( global_data.initialized )
4201 return( PSA_ERROR_NOT_PERMITTED );
Netanel Gonen21f37cb2018-11-19 11:53:55 +02004202
4203 if( ( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) ||
4204 ( seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE ) ) ||
4205 ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
4206 return( PSA_ERROR_INVALID_ARGUMENT );
4207
avolinski0d2c2662018-11-21 17:31:07 +02004208 its_status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
avolinski13beb102018-11-20 16:51:49 +02004209 status = its_to_psa_error( its_status );
4210
4211 if( PSA_ITS_ERROR_KEY_NOT_FOUND == its_status ) /* No seed exists */
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004212 {
avolinski0d2c2662018-11-21 17:31:07 +02004213 its_status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
avolinski13beb102018-11-20 16:51:49 +02004214 status = its_to_psa_error( its_status );
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004215 }
avolinski13beb102018-11-20 16:51:49 +02004216 else if( PSA_ITS_SUCCESS == its_status )
Netanel Gonen2bcd3122018-11-19 11:53:02 +02004217 {
4218 /* You should not be here. Seed needs to be injected only once */
4219 status = PSA_ERROR_NOT_PERMITTED;
4220 }
4221 return( status );
4222}
4223#endif
4224
Gilles Peskinec5487a82018-12-03 18:08:14 +01004225psa_status_t psa_generate_key( psa_key_handle_t handle,
Gilles Peskine05d69892018-06-19 22:00:52 +02004226 psa_key_type_t type,
4227 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02004228 const void *extra,
4229 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02004230{
Gilles Peskine2f060a82018-12-04 17:12:32 +01004231 psa_key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004232 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004233
Gilles Peskine53d991e2018-07-12 01:14:59 +02004234 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004235 return( PSA_ERROR_INVALID_ARGUMENT );
4236
Gilles Peskinec5487a82018-12-03 18:08:14 +01004237 status = psa_get_empty_key_slot( handle, &slot );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004238 if( status != PSA_SUCCESS )
4239 return( status );
4240
Gilles Peskine48c0ea12018-06-21 14:15:31 +02004241 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004242 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004243 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004244 if( status != PSA_SUCCESS )
4245 return( status );
4246 status = psa_generate_random( slot->data.raw.data,
4247 slot->data.raw.bytes );
4248 if( status != PSA_SUCCESS )
4249 {
4250 mbedtls_free( slot->data.raw.data );
4251 return( status );
4252 }
4253#if defined(MBEDTLS_DES_C)
4254 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02004255 psa_des_set_key_parity( slot->data.raw.data,
4256 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004257#endif /* MBEDTLS_DES_C */
4258 }
4259 else
4260
4261#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
4262 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
4263 {
4264 mbedtls_rsa_context *rsa;
4265 int ret;
4266 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02004267 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
4268 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +01004269 /* Accept only byte-aligned keys, for the same reasons as
4270 * in psa_import_rsa_key(). */
4271 if( bits % 8 != 0 )
4272 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02004273 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004274 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02004275 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004276 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004277 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02004278#if INT_MAX < 0xffffffff
4279 /* Check that the uint32_t value passed by the caller fits
4280 * in the range supported by this implementation. */
4281 if( p->e > INT_MAX )
4282 return( PSA_ERROR_NOT_SUPPORTED );
4283#endif
4284 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004285 }
4286 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
4287 if( rsa == NULL )
4288 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4289 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
4290 ret = mbedtls_rsa_gen_key( rsa,
4291 mbedtls_ctr_drbg_random,
4292 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004293 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02004294 exponent );
4295 if( ret != 0 )
4296 {
4297 mbedtls_rsa_free( rsa );
4298 mbedtls_free( rsa );
4299 return( mbedtls_to_psa_error( ret ) );
4300 }
4301 slot->data.rsa = rsa;
4302 }
4303 else
4304#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
4305
4306#if defined(MBEDTLS_ECP_C)
4307 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
4308 {
4309 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
4310 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
4311 const mbedtls_ecp_curve_info *curve_info =
4312 mbedtls_ecp_curve_info_from_grp_id( grp_id );
4313 mbedtls_ecp_keypair *ecp;
4314 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004315 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004316 return( PSA_ERROR_NOT_SUPPORTED );
4317 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
4318 return( PSA_ERROR_NOT_SUPPORTED );
4319 if( curve_info->bit_size != bits )
4320 return( PSA_ERROR_INVALID_ARGUMENT );
4321 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
4322 if( ecp == NULL )
4323 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4324 mbedtls_ecp_keypair_init( ecp );
4325 ret = mbedtls_ecp_gen_key( grp_id, ecp,
4326 mbedtls_ctr_drbg_random,
4327 &global_data.ctr_drbg );
4328 if( ret != 0 )
4329 {
4330 mbedtls_ecp_keypair_free( ecp );
4331 mbedtls_free( ecp );
4332 return( mbedtls_to_psa_error( ret ) );
4333 }
4334 slot->data.ecp = ecp;
4335 }
4336 else
4337#endif /* MBEDTLS_ECP_C */
4338
4339 return( PSA_ERROR_NOT_SUPPORTED );
4340
4341 slot->type = type;
Darryl Green0c6575a2018-11-07 16:05:30 +00004342
4343#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
4344 if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
4345 {
Gilles Peskine69f976b2018-11-30 18:46:56 +01004346 return( psa_save_generated_persistent_key( slot, bits ) );
Darryl Green0c6575a2018-11-07 16:05:30 +00004347 }
4348#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
4349
4350 return( status );
Gilles Peskine05d69892018-06-19 22:00:52 +02004351}
4352
4353
4354/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01004355/* Module setup */
4356/****************************************************************/
4357
Gilles Peskine5e769522018-11-20 21:59:56 +01004358psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
4359 void (* entropy_init )( mbedtls_entropy_context *ctx ),
4360 void (* entropy_free )( mbedtls_entropy_context *ctx ) )
4361{
4362 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4363 return( PSA_ERROR_BAD_STATE );
4364 global_data.entropy_init = entropy_init;
4365 global_data.entropy_free = entropy_free;
4366 return( PSA_SUCCESS );
4367}
4368
Gilles Peskinee59236f2018-01-27 23:32:46 +01004369void mbedtls_psa_crypto_free( void )
4370{
Gilles Peskine66fb1262018-12-10 16:29:04 +01004371 psa_wipe_all_key_slots( );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004372 if( global_data.rng_state != RNG_NOT_INITIALIZED )
4373 {
4374 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
Gilles Peskine5e769522018-11-20 21:59:56 +01004375 global_data.entropy_free( &global_data.entropy );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004376 }
4377 /* Wipe all remaining data, including configuration.
4378 * In particular, this sets all state indicator to the value
4379 * indicating "uninitialized". */
Gilles Peskine3f108122018-12-07 18:14:53 +01004380 mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004381}
4382
4383psa_status_t psa_crypto_init( void )
4384{
Gilles Peskine66fb1262018-12-10 16:29:04 +01004385 psa_status_t status;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004386 const unsigned char drbg_seed[] = "PSA";
4387
Gilles Peskinec6b69072018-11-20 21:42:52 +01004388 /* Double initialization is explicitly allowed. */
Gilles Peskinee59236f2018-01-27 23:32:46 +01004389 if( global_data.initialized != 0 )
4390 return( PSA_SUCCESS );
4391
Gilles Peskine5e769522018-11-20 21:59:56 +01004392 /* Set default configuration if
4393 * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
4394 if( global_data.entropy_init == NULL )
4395 global_data.entropy_init = mbedtls_entropy_init;
4396 if( global_data.entropy_free == NULL )
4397 global_data.entropy_free = mbedtls_entropy_free;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004398
Gilles Peskinec6b69072018-11-20 21:42:52 +01004399 /* Initialize the random generator. */
Gilles Peskine5e769522018-11-20 21:59:56 +01004400 global_data.entropy_init( &global_data.entropy );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004401 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
Gilles Peskinec6b69072018-11-20 21:42:52 +01004402 global_data.rng_state = RNG_INITIALIZED;
Gilles Peskine66fb1262018-12-10 16:29:04 +01004403 status = mbedtls_to_psa_error(
4404 mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
4405 mbedtls_entropy_func,
4406 &global_data.entropy,
4407 drbg_seed, sizeof( drbg_seed ) - 1 ) );
4408 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01004409 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004410 global_data.rng_state = RNG_SEEDED;
Gilles Peskinee59236f2018-01-27 23:32:46 +01004411
Gilles Peskine66fb1262018-12-10 16:29:04 +01004412 status = psa_initialize_key_slots( );
4413 if( status != PSA_SUCCESS )
4414 goto exit;
Gilles Peskinec6b69072018-11-20 21:42:52 +01004415
4416 /* All done. */
Gilles Peskinee4ebc122018-03-07 14:16:44 +01004417 global_data.initialized = 1;
4418
Gilles Peskinee59236f2018-01-27 23:32:46 +01004419exit:
Gilles Peskine66fb1262018-12-10 16:29:04 +01004420 if( status != PSA_SUCCESS )
Gilles Peskinee59236f2018-01-27 23:32:46 +01004421 mbedtls_psa_crypto_free( );
Gilles Peskine66fb1262018-12-10 16:29:04 +01004422 return( status );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004423}
4424
4425#endif /* MBEDTLS_PSA_CRYPTO_C */