blob: 68fa0ef675f75e9233da28db14c98709c7f3b2a8 [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)
29
mohammad160327010052018-07-03 13:16:15 +030030//! 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#if defined(MBEDTLS_PSA_CRYPTO_SPM)
35//! PSA_CRYPTO_SECURE means that this file is compiled to the SPE side.
36//! some headers will be affected by this flag.
37#define PSA_CRYPTO_SECURE 1
38#include "crypto_spe.h"
39#endif
40
Gilles Peskinee59236f2018-01-27 23:32:46 +010041#include "psa/crypto.h"
42
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010043#include <stdlib.h>
44#include <string.h>
45#if defined(MBEDTLS_PLATFORM_C)
46#include "mbedtls/platform.h"
47#else
48#define mbedtls_calloc calloc
49#define mbedtls_free free
50#endif
51
Gilles Peskinea5905292018-02-07 20:59:33 +010052#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020053#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020054#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010055#include "mbedtls/blowfish.h"
56#include "mbedtls/camellia.h"
57#include "mbedtls/cipher.h"
58#include "mbedtls/ccm.h"
59#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010060#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010061#include "mbedtls/des.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010062#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010063#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010064#include "mbedtls/error.h"
65#include "mbedtls/gcm.h"
66#include "mbedtls/md2.h"
67#include "mbedtls/md4.h"
68#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010069#include "mbedtls/md.h"
70#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010071#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010072#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010073#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010074#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010075#include "mbedtls/sha1.h"
76#include "mbedtls/sha256.h"
77#include "mbedtls/sha512.h"
78#include "mbedtls/xtea.h"
79
Gilles Peskinee59236f2018-01-27 23:32:46 +010080
81
82/* Implementation that should never be optimized out by the compiler */
83static void mbedtls_zeroize( void *v, size_t n )
84{
85 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
86}
87
Gilles Peskine9ef733f2018-02-07 21:05:37 +010088/* constant-time buffer comparison */
89static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
90{
91 size_t i;
92 unsigned char diff = 0;
93
94 for( i = 0; i < n; i++ )
95 diff |= a[i] ^ b[i];
96
97 return( diff );
98}
99
100
101
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100102/****************************************************************/
103/* Global data, support functions and library management */
104/****************************************************************/
105
106/* Number of key slots (plus one because 0 is not used).
107 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +0200108#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100109
Gilles Peskine2d277862018-06-18 15:41:12 +0200110typedef struct
111{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100112 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300113 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200114 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200115 union
116 {
117 struct raw_data
118 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100119 uint8_t *data;
120 size_t bytes;
121 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100122#if defined(MBEDTLS_RSA_C)
123 mbedtls_rsa_context *rsa;
124#endif /* MBEDTLS_RSA_C */
125#if defined(MBEDTLS_ECP_C)
126 mbedtls_ecp_keypair *ecp;
127#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100128 } data;
129} key_slot_t;
130
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200131static int key_type_is_raw_bytes( psa_key_type_t type )
132{
133 psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
134 return( category == PSA_KEY_TYPE_RAW_DATA ||
135 category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
136}
137
Gilles Peskine2d277862018-06-18 15:41:12 +0200138typedef struct
139{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100140 int initialized;
141 mbedtls_entropy_context entropy;
142 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200143 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100144} psa_global_data_t;
145
146static psa_global_data_t global_data;
147
148static psa_status_t mbedtls_to_psa_error( int ret )
149{
Gilles Peskinea5905292018-02-07 20:59:33 +0100150 /* If there's both a high-level code and low-level code, dispatch on
151 * the high-level code. */
152 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100153 {
154 case 0:
155 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100156
157 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
158 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
159 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
160 return( PSA_ERROR_NOT_SUPPORTED );
161 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
162 return( PSA_ERROR_HARDWARE_FAILURE );
163
164 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
165 return( PSA_ERROR_HARDWARE_FAILURE );
166
Gilles Peskine9a944802018-06-21 09:35:35 +0200167 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
168 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
169 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
170 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
171 case MBEDTLS_ERR_ASN1_INVALID_DATA:
172 return( PSA_ERROR_INVALID_ARGUMENT );
173 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
174 return( PSA_ERROR_INSUFFICIENT_MEMORY );
175 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
176 return( PSA_ERROR_BUFFER_TOO_SMALL );
177
Gilles Peskinea5905292018-02-07 20:59:33 +0100178 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
179 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
180 return( PSA_ERROR_NOT_SUPPORTED );
181 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
182 return( PSA_ERROR_HARDWARE_FAILURE );
183
184 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
185 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
186 return( PSA_ERROR_NOT_SUPPORTED );
187 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
188 return( PSA_ERROR_HARDWARE_FAILURE );
189
190 case MBEDTLS_ERR_CCM_BAD_INPUT:
191 return( PSA_ERROR_INVALID_ARGUMENT );
192 case MBEDTLS_ERR_CCM_AUTH_FAILED:
193 return( PSA_ERROR_INVALID_SIGNATURE );
194 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
195 return( PSA_ERROR_HARDWARE_FAILURE );
196
197 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
198 return( PSA_ERROR_NOT_SUPPORTED );
199 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
200 return( PSA_ERROR_INVALID_ARGUMENT );
201 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
202 return( PSA_ERROR_INSUFFICIENT_MEMORY );
203 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
204 return( PSA_ERROR_INVALID_PADDING );
205 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
206 return( PSA_ERROR_BAD_STATE );
207 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
208 return( PSA_ERROR_INVALID_SIGNATURE );
209 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
210 return( PSA_ERROR_TAMPERING_DETECTED );
211 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
212 return( PSA_ERROR_HARDWARE_FAILURE );
213
214 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
215 return( PSA_ERROR_HARDWARE_FAILURE );
216
217 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
218 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
219 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
220 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
221 return( PSA_ERROR_NOT_SUPPORTED );
222 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
223 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
224
225 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
226 return( PSA_ERROR_NOT_SUPPORTED );
227 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
228 return( PSA_ERROR_HARDWARE_FAILURE );
229
Gilles Peskinee59236f2018-01-27 23:32:46 +0100230 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
231 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
232 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
233 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100234
235 case MBEDTLS_ERR_GCM_AUTH_FAILED:
236 return( PSA_ERROR_INVALID_SIGNATURE );
237 case MBEDTLS_ERR_GCM_BAD_INPUT:
238 return( PSA_ERROR_NOT_SUPPORTED );
239 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
240 return( PSA_ERROR_HARDWARE_FAILURE );
241
242 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
243 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
244 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
245 return( PSA_ERROR_HARDWARE_FAILURE );
246
247 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
248 return( PSA_ERROR_NOT_SUPPORTED );
249 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
250 return( PSA_ERROR_INVALID_ARGUMENT );
251 case MBEDTLS_ERR_MD_ALLOC_FAILED:
252 return( PSA_ERROR_INSUFFICIENT_MEMORY );
253 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
254 return( PSA_ERROR_STORAGE_FAILURE );
255 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
256 return( PSA_ERROR_HARDWARE_FAILURE );
257
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100258 case MBEDTLS_ERR_PK_ALLOC_FAILED:
259 return( PSA_ERROR_INSUFFICIENT_MEMORY );
260 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
261 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
262 return( PSA_ERROR_INVALID_ARGUMENT );
263 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100264 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100265 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
266 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
267 return( PSA_ERROR_INVALID_ARGUMENT );
268 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
269 return( PSA_ERROR_NOT_SUPPORTED );
270 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
271 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
272 return( PSA_ERROR_NOT_PERMITTED );
273 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
274 return( PSA_ERROR_INVALID_ARGUMENT );
275 case MBEDTLS_ERR_PK_INVALID_ALG:
276 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
277 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
278 return( PSA_ERROR_NOT_SUPPORTED );
279 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
280 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100281 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
282 return( PSA_ERROR_HARDWARE_FAILURE );
283
284 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
285 return( PSA_ERROR_HARDWARE_FAILURE );
286
287 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
288 return( PSA_ERROR_INVALID_ARGUMENT );
289 case MBEDTLS_ERR_RSA_INVALID_PADDING:
290 return( PSA_ERROR_INVALID_PADDING );
291 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
292 return( PSA_ERROR_HARDWARE_FAILURE );
293 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
294 return( PSA_ERROR_INVALID_ARGUMENT );
295 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
296 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
297 return( PSA_ERROR_TAMPERING_DETECTED );
298 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
299 return( PSA_ERROR_INVALID_SIGNATURE );
300 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
301 return( PSA_ERROR_BUFFER_TOO_SMALL );
302 case MBEDTLS_ERR_RSA_RNG_FAILED:
303 return( PSA_ERROR_INSUFFICIENT_MEMORY );
304 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
305 return( PSA_ERROR_NOT_SUPPORTED );
306 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
307 return( PSA_ERROR_HARDWARE_FAILURE );
308
309 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
310 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
311 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
312 return( PSA_ERROR_HARDWARE_FAILURE );
313
314 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
315 return( PSA_ERROR_INVALID_ARGUMENT );
316 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
317 return( PSA_ERROR_HARDWARE_FAILURE );
318
itayzafrir5c753392018-05-08 11:18:38 +0300319 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300320 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300321 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300322 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
323 return( PSA_ERROR_BUFFER_TOO_SMALL );
324 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
325 return( PSA_ERROR_NOT_SUPPORTED );
326 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
327 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
328 return( PSA_ERROR_INVALID_SIGNATURE );
329 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
330 return( PSA_ERROR_INSUFFICIENT_MEMORY );
331 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
332 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300333
Gilles Peskinee59236f2018-01-27 23:32:46 +0100334 default:
335 return( PSA_ERROR_UNKNOWN_ERROR );
336 }
337}
338
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200339
340
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100341/****************************************************************/
342/* Key management */
343/****************************************************************/
344
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200345static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
346{
347 switch( grpid )
348 {
349 case MBEDTLS_ECP_DP_SECP192R1:
350 return( PSA_ECC_CURVE_SECP192R1 );
351 case MBEDTLS_ECP_DP_SECP224R1:
352 return( PSA_ECC_CURVE_SECP224R1 );
353 case MBEDTLS_ECP_DP_SECP256R1:
354 return( PSA_ECC_CURVE_SECP256R1 );
355 case MBEDTLS_ECP_DP_SECP384R1:
356 return( PSA_ECC_CURVE_SECP384R1 );
357 case MBEDTLS_ECP_DP_SECP521R1:
358 return( PSA_ECC_CURVE_SECP521R1 );
359 case MBEDTLS_ECP_DP_BP256R1:
360 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
361 case MBEDTLS_ECP_DP_BP384R1:
362 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
363 case MBEDTLS_ECP_DP_BP512R1:
364 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
365 case MBEDTLS_ECP_DP_CURVE25519:
366 return( PSA_ECC_CURVE_CURVE25519 );
367 case MBEDTLS_ECP_DP_SECP192K1:
368 return( PSA_ECC_CURVE_SECP192K1 );
369 case MBEDTLS_ECP_DP_SECP224K1:
370 return( PSA_ECC_CURVE_SECP224K1 );
371 case MBEDTLS_ECP_DP_SECP256K1:
372 return( PSA_ECC_CURVE_SECP256K1 );
373 case MBEDTLS_ECP_DP_CURVE448:
374 return( PSA_ECC_CURVE_CURVE448 );
375 default:
376 return( 0 );
377 }
378}
379
Gilles Peskine12313cd2018-06-20 00:20:32 +0200380static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
381{
382 switch( curve )
383 {
384 case PSA_ECC_CURVE_SECP192R1:
385 return( MBEDTLS_ECP_DP_SECP192R1 );
386 case PSA_ECC_CURVE_SECP224R1:
387 return( MBEDTLS_ECP_DP_SECP224R1 );
388 case PSA_ECC_CURVE_SECP256R1:
389 return( MBEDTLS_ECP_DP_SECP256R1 );
390 case PSA_ECC_CURVE_SECP384R1:
391 return( MBEDTLS_ECP_DP_SECP384R1 );
392 case PSA_ECC_CURVE_SECP521R1:
393 return( MBEDTLS_ECP_DP_SECP521R1 );
394 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
395 return( MBEDTLS_ECP_DP_BP256R1 );
396 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
397 return( MBEDTLS_ECP_DP_BP384R1 );
398 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
399 return( MBEDTLS_ECP_DP_BP512R1 );
400 case PSA_ECC_CURVE_CURVE25519:
401 return( MBEDTLS_ECP_DP_CURVE25519 );
402 case PSA_ECC_CURVE_SECP192K1:
403 return( MBEDTLS_ECP_DP_SECP192K1 );
404 case PSA_ECC_CURVE_SECP224K1:
405 return( MBEDTLS_ECP_DP_SECP224K1 );
406 case PSA_ECC_CURVE_SECP256K1:
407 return( MBEDTLS_ECP_DP_SECP256K1 );
408 case PSA_ECC_CURVE_CURVE448:
409 return( MBEDTLS_ECP_DP_CURVE448 );
410 default:
411 return( MBEDTLS_ECP_DP_NONE );
412 }
413}
414
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200415static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
416 size_t bits,
417 struct raw_data *raw )
418{
419 /* Check that the bit size is acceptable for the key type */
420 switch( type )
421 {
422 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200423 if( bits == 0 )
424 {
425 raw->bytes = 0;
426 raw->data = NULL;
427 return( PSA_SUCCESS );
428 }
429 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200430#if defined(MBEDTLS_MD_C)
431 case PSA_KEY_TYPE_HMAC:
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200432 break;
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200433#endif
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200434#if defined(MBEDTLS_AES_C)
435 case PSA_KEY_TYPE_AES:
436 if( bits != 128 && bits != 192 && bits != 256 )
437 return( PSA_ERROR_INVALID_ARGUMENT );
438 break;
439#endif
440#if defined(MBEDTLS_CAMELLIA_C)
441 case PSA_KEY_TYPE_CAMELLIA:
442 if( bits != 128 && bits != 192 && bits != 256 )
443 return( PSA_ERROR_INVALID_ARGUMENT );
444 break;
445#endif
446#if defined(MBEDTLS_DES_C)
447 case PSA_KEY_TYPE_DES:
448 if( bits != 64 && bits != 128 && bits != 192 )
449 return( PSA_ERROR_INVALID_ARGUMENT );
450 break;
451#endif
452#if defined(MBEDTLS_ARC4_C)
453 case PSA_KEY_TYPE_ARC4:
454 if( bits < 8 || bits > 2048 )
455 return( PSA_ERROR_INVALID_ARGUMENT );
456 break;
457#endif
458 default:
459 return( PSA_ERROR_NOT_SUPPORTED );
460 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200461 if( bits % 8 != 0 )
462 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200463
464 /* Allocate memory for the key */
465 raw->bytes = PSA_BITS_TO_BYTES( bits );
466 raw->data = mbedtls_calloc( 1, raw->bytes );
467 if( raw->data == NULL )
468 {
469 raw->bytes = 0;
470 return( PSA_ERROR_INSUFFICIENT_MEMORY );
471 }
472 return( PSA_SUCCESS );
473}
474
Gilles Peskine2d277862018-06-18 15:41:12 +0200475psa_status_t psa_import_key( psa_key_slot_t key,
476 psa_key_type_t type,
477 const uint8_t *data,
478 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100479{
480 key_slot_t *slot;
481
Gilles Peskine828ed142018-06-18 23:25:51 +0200482 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100483 return( PSA_ERROR_INVALID_ARGUMENT );
484 slot = &global_data.key_slots[key];
485 if( slot->type != PSA_KEY_TYPE_NONE )
486 return( PSA_ERROR_OCCUPIED_SLOT );
487
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200488 if( key_type_is_raw_bytes( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100489 {
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200490 psa_status_t status;
Gilles Peskine6d912132018-03-07 16:41:37 +0100491 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100492 if( data_length > SIZE_MAX / 8 )
493 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200494 status = prepare_raw_data_slot( type,
495 PSA_BYTES_TO_BITS( data_length ),
496 &slot->data.raw );
497 if( status != PSA_SUCCESS )
498 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200499 if( data_length != 0 )
500 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100501 }
502 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100503#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100504 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
505 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
506 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100507 {
508 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100509 mbedtls_pk_context pk;
Gilles Peskinec648d692018-06-28 08:46:13 +0200510 psa_status_t status = PSA_SUCCESS;
Gilles Peskine969ac722018-01-28 18:16:59 +0100511 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100512 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
513 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
514 else
515 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100516 if( ret != 0 )
517 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100518 switch( mbedtls_pk_get_type( &pk ) )
519 {
520#if defined(MBEDTLS_RSA_C)
521 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100522 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
523 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskineaf3baab2018-06-27 22:55:52 +0200524 {
525 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( pk );
526 size_t bits = mbedtls_rsa_get_bitlen( rsa );
527 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
Gilles Peskine1ae05142018-06-30 17:46:59 +0200528 {
529 status = PSA_ERROR_NOT_SUPPORTED;
530 break;
531 }
Gilles Peskineaf3baab2018-06-27 22:55:52 +0200532 slot->data.rsa = rsa;
533 }
Gilles Peskine969ac722018-01-28 18:16:59 +0100534 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200535 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100536 break;
537#endif /* MBEDTLS_RSA_C */
538#if defined(MBEDTLS_ECP_C)
539 case MBEDTLS_PK_ECKEY:
540 if( PSA_KEY_TYPE_IS_ECC( type ) )
541 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200542 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
543 psa_ecc_curve_t actual_curve =
544 mbedtls_ecc_group_to_psa( ecp->grp.id );
545 psa_ecc_curve_t expected_curve =
546 PSA_KEY_TYPE_GET_CURVE( type );
547 if( actual_curve != expected_curve )
Gilles Peskinec648d692018-06-28 08:46:13 +0200548 {
549 status = PSA_ERROR_INVALID_ARGUMENT;
550 break;
551 }
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200552 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100553 }
554 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200555 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100556 break;
557#endif /* MBEDTLS_ECP_C */
558 default:
Gilles Peskinec648d692018-06-28 08:46:13 +0200559 status = PSA_ERROR_INVALID_ARGUMENT;
560 break;
561 }
562 /* Free the content of the pk object only on error. On success,
563 * the content of the object has been stored in the slot. */
564 if( status != PSA_SUCCESS )
565 {
566 mbedtls_pk_free( &pk );
567 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100568 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100569 }
570 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100571#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100572 {
573 return( PSA_ERROR_NOT_SUPPORTED );
574 }
575
576 slot->type = type;
577 return( PSA_SUCCESS );
578}
579
Gilles Peskine2d277862018-06-18 15:41:12 +0200580psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100581{
582 key_slot_t *slot;
583
Gilles Peskine828ed142018-06-18 23:25:51 +0200584 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100585 return( PSA_ERROR_INVALID_ARGUMENT );
586 slot = &global_data.key_slots[key];
587 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200588 {
589 /* No key material to clean, but do zeroize the slot below to wipe
590 * metadata such as policies. */
591 }
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200592 else if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100593 {
594 mbedtls_free( slot->data.raw.data );
595 }
596 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100597#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100598 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
599 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100600 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100601 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100602 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100603 }
604 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100605#endif /* defined(MBEDTLS_RSA_C) */
606#if defined(MBEDTLS_ECP_C)
607 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
608 {
609 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100610 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100611 }
612 else
613#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100614 {
615 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100616 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100617 return( PSA_ERROR_TAMPERING_DETECTED );
618 }
619
620 mbedtls_zeroize( slot, sizeof( *slot ) );
621 return( PSA_SUCCESS );
622}
623
Gilles Peskine2d277862018-06-18 15:41:12 +0200624psa_status_t psa_get_key_information( psa_key_slot_t key,
625 psa_key_type_t *type,
626 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100627{
628 key_slot_t *slot;
629
Gilles Peskine828ed142018-06-18 23:25:51 +0200630 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100631 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100632 slot = &global_data.key_slots[key];
633 if( type != NULL )
634 *type = slot->type;
635 if( bits != NULL )
636 *bits = 0;
637 if( slot->type == PSA_KEY_TYPE_NONE )
638 return( PSA_ERROR_EMPTY_SLOT );
639
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200640 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100641 {
642 if( bits != NULL )
643 *bits = slot->data.raw.bytes * 8;
644 }
645 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100646#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100647 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
648 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100649 {
650 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100651 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100652 }
653 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100654#endif /* defined(MBEDTLS_RSA_C) */
655#if defined(MBEDTLS_ECP_C)
656 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
657 {
658 if( bits != NULL )
659 *bits = slot->data.ecp->grp.pbits;
660 }
661 else
662#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100663 {
664 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100665 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100666 return( PSA_ERROR_TAMPERING_DETECTED );
667 }
668
669 return( PSA_SUCCESS );
670}
671
Gilles Peskine2d277862018-06-18 15:41:12 +0200672static psa_status_t psa_internal_export_key( psa_key_slot_t key,
673 uint8_t *data,
674 size_t data_size,
675 size_t *data_length,
676 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100677{
678 key_slot_t *slot;
679
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100680 /* Set the key to empty now, so that even when there are errors, we always
681 * set data_length to a value between 0 and data_size. On error, setting
682 * the key to empty is a good choice because an empty key representation is
683 * unlikely to be accepted anywhere. */
684 *data_length = 0;
685
Gilles Peskine828ed142018-06-18 23:25:51 +0200686 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100687 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100688 slot = &global_data.key_slots[key];
689 if( slot->type == PSA_KEY_TYPE_NONE )
690 return( PSA_ERROR_EMPTY_SLOT );
691
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200692 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300693 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300694
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200695 if( ! export_public_key &&
696 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
697 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300698 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200699
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200700 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100701 {
702 if( slot->data.raw.bytes > data_size )
703 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200704 if( slot->data.raw.bytes != 0 )
705 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100706 *data_length = slot->data.raw.bytes;
707 return( PSA_SUCCESS );
708 }
709 else
Moran Peker17e36e12018-05-02 12:55:20 +0300710 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100711#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100712 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300713 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
714 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100715 {
Moran Pekera998bc62018-04-16 18:16:20 +0300716 mbedtls_pk_context pk;
717 int ret;
718 mbedtls_pk_init( &pk );
719 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
720 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
721 {
722 pk.pk_info = &mbedtls_rsa_info;
723 pk.pk_ctx = slot->data.rsa;
724 }
725 else
726 {
727 pk.pk_info = &mbedtls_eckey_info;
728 pk.pk_ctx = slot->data.ecp;
729 }
Moran Pekerd7326592018-05-29 16:56:39 +0300730 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300731 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300732 else
733 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300734 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200735 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200736 /* If data_size is 0 then data may be NULL and then the
737 * call to memset would have undefined behavior. */
738 if( data_size != 0 )
739 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300740 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200741 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200742 /* The mbedtls_pk_xxx functions write to the end of the buffer.
743 * Move the data to the beginning and erase remaining data
744 * at the original location. */
745 if( 2 * (size_t) ret <= data_size )
746 {
747 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200748 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200749 }
750 else if( (size_t) ret < data_size )
751 {
752 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200753 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200754 }
Moran Pekera998bc62018-04-16 18:16:20 +0300755 *data_length = ret;
756 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100757 }
758 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100759#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300760 {
761 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200762 it is valid for a special-purpose implementation to omit
763 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300764 return( PSA_ERROR_NOT_SUPPORTED );
765 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100766 }
767}
768
Gilles Peskine2d277862018-06-18 15:41:12 +0200769psa_status_t psa_export_key( psa_key_slot_t key,
770 uint8_t *data,
771 size_t data_size,
772 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300773{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200774 return( psa_internal_export_key( key, data, data_size,
775 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100776}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100777
Gilles Peskine2d277862018-06-18 15:41:12 +0200778psa_status_t psa_export_public_key( psa_key_slot_t key,
779 uint8_t *data,
780 size_t data_size,
781 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300782{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200783 return( psa_internal_export_key( key, data, data_size,
784 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300785}
786
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200787
788
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100789/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100790/* Message digests */
791/****************************************************************/
792
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100793static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100794{
795 switch( alg )
796 {
797#if defined(MBEDTLS_MD2_C)
798 case PSA_ALG_MD2:
799 return( &mbedtls_md2_info );
800#endif
801#if defined(MBEDTLS_MD4_C)
802 case PSA_ALG_MD4:
803 return( &mbedtls_md4_info );
804#endif
805#if defined(MBEDTLS_MD5_C)
806 case PSA_ALG_MD5:
807 return( &mbedtls_md5_info );
808#endif
809#if defined(MBEDTLS_RIPEMD160_C)
810 case PSA_ALG_RIPEMD160:
811 return( &mbedtls_ripemd160_info );
812#endif
813#if defined(MBEDTLS_SHA1_C)
814 case PSA_ALG_SHA_1:
815 return( &mbedtls_sha1_info );
816#endif
817#if defined(MBEDTLS_SHA256_C)
818 case PSA_ALG_SHA_224:
819 return( &mbedtls_sha224_info );
820 case PSA_ALG_SHA_256:
821 return( &mbedtls_sha256_info );
822#endif
823#if defined(MBEDTLS_SHA512_C)
824 case PSA_ALG_SHA_384:
825 return( &mbedtls_sha384_info );
826 case PSA_ALG_SHA_512:
827 return( &mbedtls_sha512_info );
828#endif
829 default:
830 return( NULL );
831 }
832}
833
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100834psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
835{
836 switch( operation->alg )
837 {
Gilles Peskine81736312018-06-26 15:04:31 +0200838 case 0:
839 /* The object has (apparently) been initialized but it is not
840 * in use. It's ok to call abort on such an object, and there's
841 * nothing to do. */
842 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100843#if defined(MBEDTLS_MD2_C)
844 case PSA_ALG_MD2:
845 mbedtls_md2_free( &operation->ctx.md2 );
846 break;
847#endif
848#if defined(MBEDTLS_MD4_C)
849 case PSA_ALG_MD4:
850 mbedtls_md4_free( &operation->ctx.md4 );
851 break;
852#endif
853#if defined(MBEDTLS_MD5_C)
854 case PSA_ALG_MD5:
855 mbedtls_md5_free( &operation->ctx.md5 );
856 break;
857#endif
858#if defined(MBEDTLS_RIPEMD160_C)
859 case PSA_ALG_RIPEMD160:
860 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
861 break;
862#endif
863#if defined(MBEDTLS_SHA1_C)
864 case PSA_ALG_SHA_1:
865 mbedtls_sha1_free( &operation->ctx.sha1 );
866 break;
867#endif
868#if defined(MBEDTLS_SHA256_C)
869 case PSA_ALG_SHA_224:
870 case PSA_ALG_SHA_256:
871 mbedtls_sha256_free( &operation->ctx.sha256 );
872 break;
873#endif
874#if defined(MBEDTLS_SHA512_C)
875 case PSA_ALG_SHA_384:
876 case PSA_ALG_SHA_512:
877 mbedtls_sha512_free( &operation->ctx.sha512 );
878 break;
879#endif
880 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +0200881 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100882 }
883 operation->alg = 0;
884 return( PSA_SUCCESS );
885}
886
887psa_status_t psa_hash_start( psa_hash_operation_t *operation,
888 psa_algorithm_t alg )
889{
890 int ret;
891 operation->alg = 0;
892 switch( alg )
893 {
894#if defined(MBEDTLS_MD2_C)
895 case PSA_ALG_MD2:
896 mbedtls_md2_init( &operation->ctx.md2 );
897 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
898 break;
899#endif
900#if defined(MBEDTLS_MD4_C)
901 case PSA_ALG_MD4:
902 mbedtls_md4_init( &operation->ctx.md4 );
903 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
904 break;
905#endif
906#if defined(MBEDTLS_MD5_C)
907 case PSA_ALG_MD5:
908 mbedtls_md5_init( &operation->ctx.md5 );
909 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
910 break;
911#endif
912#if defined(MBEDTLS_RIPEMD160_C)
913 case PSA_ALG_RIPEMD160:
914 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
915 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
916 break;
917#endif
918#if defined(MBEDTLS_SHA1_C)
919 case PSA_ALG_SHA_1:
920 mbedtls_sha1_init( &operation->ctx.sha1 );
921 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
922 break;
923#endif
924#if defined(MBEDTLS_SHA256_C)
925 case PSA_ALG_SHA_224:
926 mbedtls_sha256_init( &operation->ctx.sha256 );
927 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
928 break;
929 case PSA_ALG_SHA_256:
930 mbedtls_sha256_init( &operation->ctx.sha256 );
931 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
932 break;
933#endif
934#if defined(MBEDTLS_SHA512_C)
935 case PSA_ALG_SHA_384:
936 mbedtls_sha512_init( &operation->ctx.sha512 );
937 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
938 break;
939 case PSA_ALG_SHA_512:
940 mbedtls_sha512_init( &operation->ctx.sha512 );
941 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
942 break;
943#endif
944 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +0200945 return( PSA_ALG_IS_HASH( alg ) ?
946 PSA_ERROR_NOT_SUPPORTED :
947 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100948 }
949 if( ret == 0 )
950 operation->alg = alg;
951 else
952 psa_hash_abort( operation );
953 return( mbedtls_to_psa_error( ret ) );
954}
955
956psa_status_t psa_hash_update( psa_hash_operation_t *operation,
957 const uint8_t *input,
958 size_t input_length )
959{
960 int ret;
961 switch( operation->alg )
962 {
963#if defined(MBEDTLS_MD2_C)
964 case PSA_ALG_MD2:
965 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
966 input, input_length );
967 break;
968#endif
969#if defined(MBEDTLS_MD4_C)
970 case PSA_ALG_MD4:
971 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
972 input, input_length );
973 break;
974#endif
975#if defined(MBEDTLS_MD5_C)
976 case PSA_ALG_MD5:
977 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
978 input, input_length );
979 break;
980#endif
981#if defined(MBEDTLS_RIPEMD160_C)
982 case PSA_ALG_RIPEMD160:
983 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
984 input, input_length );
985 break;
986#endif
987#if defined(MBEDTLS_SHA1_C)
988 case PSA_ALG_SHA_1:
989 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
990 input, input_length );
991 break;
992#endif
993#if defined(MBEDTLS_SHA256_C)
994 case PSA_ALG_SHA_224:
995 case PSA_ALG_SHA_256:
996 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
997 input, input_length );
998 break;
999#endif
1000#if defined(MBEDTLS_SHA512_C)
1001 case PSA_ALG_SHA_384:
1002 case PSA_ALG_SHA_512:
1003 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1004 input, input_length );
1005 break;
1006#endif
1007 default:
1008 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1009 break;
1010 }
1011 if( ret != 0 )
1012 psa_hash_abort( operation );
1013 return( mbedtls_to_psa_error( ret ) );
1014}
1015
1016psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1017 uint8_t *hash,
1018 size_t hash_size,
1019 size_t *hash_length )
1020{
1021 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001022 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001023
1024 /* Fill the output buffer with something that isn't a valid hash
1025 * (barring an attack on the hash and deliberately-crafted input),
1026 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001027 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001028 /* If hash_size is 0 then hash may be NULL and then the
1029 * call to memset would have undefined behavior. */
1030 if( hash_size != 0 )
1031 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001032
1033 if( hash_size < actual_hash_length )
1034 return( PSA_ERROR_BUFFER_TOO_SMALL );
1035
1036 switch( operation->alg )
1037 {
1038#if defined(MBEDTLS_MD2_C)
1039 case PSA_ALG_MD2:
1040 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1041 break;
1042#endif
1043#if defined(MBEDTLS_MD4_C)
1044 case PSA_ALG_MD4:
1045 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1046 break;
1047#endif
1048#if defined(MBEDTLS_MD5_C)
1049 case PSA_ALG_MD5:
1050 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1051 break;
1052#endif
1053#if defined(MBEDTLS_RIPEMD160_C)
1054 case PSA_ALG_RIPEMD160:
1055 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1056 break;
1057#endif
1058#if defined(MBEDTLS_SHA1_C)
1059 case PSA_ALG_SHA_1:
1060 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1061 break;
1062#endif
1063#if defined(MBEDTLS_SHA256_C)
1064 case PSA_ALG_SHA_224:
1065 case PSA_ALG_SHA_256:
1066 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1067 break;
1068#endif
1069#if defined(MBEDTLS_SHA512_C)
1070 case PSA_ALG_SHA_384:
1071 case PSA_ALG_SHA_512:
1072 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1073 break;
1074#endif
1075 default:
1076 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1077 break;
1078 }
1079
1080 if( ret == 0 )
1081 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001082 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001083 return( psa_hash_abort( operation ) );
1084 }
1085 else
1086 {
1087 psa_hash_abort( operation );
1088 return( mbedtls_to_psa_error( ret ) );
1089 }
1090}
1091
Gilles Peskine2d277862018-06-18 15:41:12 +02001092psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1093 const uint8_t *hash,
1094 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001095{
1096 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1097 size_t actual_hash_length;
1098 psa_status_t status = psa_hash_finish( operation,
1099 actual_hash, sizeof( actual_hash ),
1100 &actual_hash_length );
1101 if( status != PSA_SUCCESS )
1102 return( status );
1103 if( actual_hash_length != hash_length )
1104 return( PSA_ERROR_INVALID_SIGNATURE );
1105 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1106 return( PSA_ERROR_INVALID_SIGNATURE );
1107 return( PSA_SUCCESS );
1108}
1109
1110
1111
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001112/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001113/* MAC */
1114/****************************************************************/
1115
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001116static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001117 psa_algorithm_t alg,
1118 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001119 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001120 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001121{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001122 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001123 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001124
1125 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1126 {
1127 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001128 {
1129 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1130 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001131
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001132 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001133 {
1134 case PSA_ALG_STREAM_CIPHER:
1135 mode = MBEDTLS_MODE_STREAM;
1136 break;
1137 case PSA_ALG_CBC_BASE:
1138 mode = MBEDTLS_MODE_CBC;
1139 break;
1140 case PSA_ALG_CFB_BASE:
1141 mode = MBEDTLS_MODE_CFB;
1142 break;
1143 case PSA_ALG_OFB_BASE:
1144 mode = MBEDTLS_MODE_OFB;
1145 break;
1146 case PSA_ALG_CTR:
1147 mode = MBEDTLS_MODE_CTR;
1148 break;
1149 case PSA_ALG_CCM:
1150 mode = MBEDTLS_MODE_CCM;
1151 break;
1152 case PSA_ALG_GCM:
1153 mode = MBEDTLS_MODE_GCM;
1154 break;
1155 default:
1156 return( NULL );
1157 }
1158 }
1159 else if( alg == PSA_ALG_CMAC )
1160 mode = MBEDTLS_MODE_ECB;
1161 else if( alg == PSA_ALG_GMAC )
1162 mode = MBEDTLS_MODE_GCM;
1163 else
1164 return( NULL );
1165
1166 switch( key_type )
1167 {
1168 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001169 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001170 break;
1171 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001172 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1173 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001174 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001175 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001176 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001177 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001178 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1179 * but two-key Triple-DES is functionally three-key Triple-DES
1180 * with K1=K3, so that's how we present it to mbedtls. */
1181 if( key_bits == 128 )
1182 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001183 break;
1184 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001185 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001186 break;
1187 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001188 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001189 break;
1190 default:
1191 return( NULL );
1192 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001193 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001194 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001195
Jaeden Amero23bbb752018-06-26 14:16:54 +01001196 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1197 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001198}
1199
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001200static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001201{
Gilles Peskine2d277862018-06-18 15:41:12 +02001202 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001203 {
1204 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001205 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001206 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001207 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001208 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001209 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001210 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001211 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001212 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001213 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001214 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001215 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001216 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001217 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001218 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001219 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001220 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001221 return( 128 );
1222 default:
1223 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001224 }
1225}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001226
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001227/* Initialize the MAC operation structure. Once this function has been
1228 * called, psa_mac_abort can run and will do the right thing. */
1229static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1230 psa_algorithm_t alg )
1231{
1232 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1233
1234 operation->alg = alg;
1235 operation->key_set = 0;
1236 operation->iv_set = 0;
1237 operation->iv_required = 0;
1238 operation->has_input = 0;
1239 operation->key_usage_sign = 0;
1240 operation->key_usage_verify = 0;
1241
1242#if defined(MBEDTLS_CMAC_C)
1243 if( alg == PSA_ALG_CMAC )
1244 {
1245 operation->iv_required = 0;
1246 mbedtls_cipher_init( &operation->ctx.cmac );
1247 status = PSA_SUCCESS;
1248 }
1249 else
1250#endif /* MBEDTLS_CMAC_C */
1251#if defined(MBEDTLS_MD_C)
1252 if( PSA_ALG_IS_HMAC( operation->alg ) )
1253 {
1254 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1255 PSA_ALG_HMAC_HASH( alg ) );
1256 }
1257 else
1258#endif /* MBEDTLS_MD_C */
1259 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001260 if( ! PSA_ALG_IS_MAC( alg ) )
1261 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001262 }
1263
1264 if( status != PSA_SUCCESS )
1265 memset( operation, 0, sizeof( *operation ) );
1266 return( status );
1267}
1268
Gilles Peskine8c9def32018-02-08 10:02:12 +01001269psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1270{
1271 switch( operation->alg )
1272 {
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001273 case 0:
Gilles Peskine81736312018-06-26 15:04:31 +02001274 /* The object has (apparently) been initialized but it is not
1275 * in use. It's ok to call abort on such an object, and there's
1276 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001277 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001278#if defined(MBEDTLS_CMAC_C)
1279 case PSA_ALG_CMAC:
1280 mbedtls_cipher_free( &operation->ctx.cmac );
1281 break;
1282#endif /* MBEDTLS_CMAC_C */
1283 default:
1284#if defined(MBEDTLS_MD_C)
1285 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001286 {
Jaeden Amero5390f692018-06-26 14:18:50 +01001287 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001288 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001289
Gilles Peskine99bc6492018-06-11 17:13:00 +02001290 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001291 return( PSA_ERROR_NOT_SUPPORTED );
1292
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001293 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001294 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001295 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001296 else
1297#endif /* MBEDTLS_MD_C */
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001298 {
1299 /* Sanity check (shouldn't happen: operation->alg should
1300 * always have been initialized to a valid value). */
1301 return( PSA_ERROR_BAD_STATE );
1302 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001303 }
Moran Peker41deec42018-04-04 15:43:05 +03001304
Gilles Peskine8c9def32018-02-08 10:02:12 +01001305 operation->alg = 0;
1306 operation->key_set = 0;
1307 operation->iv_set = 0;
1308 operation->iv_required = 0;
1309 operation->has_input = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001310 operation->key_usage_sign = 0;
1311 operation->key_usage_verify = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001312
Gilles Peskine8c9def32018-02-08 10:02:12 +01001313 return( PSA_SUCCESS );
1314}
1315
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001316#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001317static int psa_cmac_start( psa_mac_operation_t *operation,
1318 size_t key_bits,
1319 key_slot_t *slot,
1320 const mbedtls_cipher_info_t *cipher_info )
1321{
1322 int ret;
1323
1324 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001325
1326 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1327 if( ret != 0 )
1328 return( ret );
1329
1330 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1331 slot->data.raw.data,
1332 key_bits );
1333 return( ret );
1334}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001335#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001336
Gilles Peskine248051a2018-06-20 16:09:38 +02001337#if defined(MBEDTLS_MD_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001338static int psa_hmac_start( psa_mac_operation_t *operation,
1339 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001340 key_slot_t *slot,
1341 psa_algorithm_t alg )
1342{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001343 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001344 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001345 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001346 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001347 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001348 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001349 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001350 size_t key_length = slot->data.raw.bytes;
1351 psa_status_t status;
1352
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001353 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001354 return( PSA_ERROR_NOT_SUPPORTED );
1355
1356 if( key_type != PSA_KEY_TYPE_HMAC )
1357 return( PSA_ERROR_INVALID_ARGUMENT );
1358
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001359 operation->mac_size = digest_size;
1360
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001361 /* The hash was started earlier in psa_mac_init. */
Gilles Peskined223b522018-06-11 18:12:58 +02001362 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001363 {
1364 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001365 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001366 if( status != PSA_SUCCESS )
1367 return( status );
1368 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001369 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001370 if( status != PSA_SUCCESS )
1371 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001372 }
Gilles Peskined223b522018-06-11 18:12:58 +02001373 else
1374 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001375
Gilles Peskined223b522018-06-11 18:12:58 +02001376 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1377 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001378 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001379 ipad[i] ^= 0x36;
1380 memset( ipad + key_length, 0x36, block_size - key_length );
1381
1382 /* Copy the key material from ipad to opad, flipping the requisite bits,
1383 * and filling the rest of opad with the requisite constant. */
1384 for( i = 0; i < key_length; i++ )
1385 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1386 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001387
1388 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1389 PSA_ALG_HMAC_HASH( alg ) );
1390 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001391 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001392
1393 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1394 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001395
1396cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001397 mbedtls_zeroize( ipad, key_length );
1398 /* opad is in the context. It needs to stay in memory if this function
1399 * succeeds, and it will be wiped by psa_mac_abort() called from
1400 * psa_mac_start in the error case. */
1401
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001402 return( status );
1403}
Gilles Peskine248051a2018-06-20 16:09:38 +02001404#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001405
Gilles Peskine8c9def32018-02-08 10:02:12 +01001406psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1407 psa_key_slot_t key,
1408 psa_algorithm_t alg )
1409{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001410 psa_status_t status;
1411 key_slot_t *slot;
1412 psa_key_type_t key_type;
1413 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001414 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001415
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001416 status = psa_mac_init( operation, alg );
1417 if( status != PSA_SUCCESS )
1418 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001419
1420 status = psa_get_key_information( key, &key_type, &key_bits );
1421 if( status != PSA_SUCCESS )
1422 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001423
Gilles Peskine8c9def32018-02-08 10:02:12 +01001424 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001425 if( slot->type == PSA_KEY_TYPE_NONE )
1426 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001427
Moran Pekerd7326592018-05-29 16:56:39 +03001428 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001429 operation->key_usage_sign = 1;
1430
Moran Pekerd7326592018-05-29 16:56:39 +03001431 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001432 operation->key_usage_verify = 1;
1433
Gilles Peskine8c9def32018-02-08 10:02:12 +01001434 if( ! PSA_ALG_IS_HMAC( alg ) )
1435 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001436 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001437 if( cipher_info == NULL )
1438 return( PSA_ERROR_NOT_SUPPORTED );
1439 operation->mac_size = cipher_info->block_size;
1440 }
1441 switch( alg )
1442 {
1443#if defined(MBEDTLS_CMAC_C)
1444 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001445 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1446 key_bits,
1447 slot,
1448 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001449 break;
1450#endif /* MBEDTLS_CMAC_C */
1451 default:
1452#if defined(MBEDTLS_MD_C)
1453 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001454 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001455 else
1456#endif /* MBEDTLS_MD_C */
1457 return( PSA_ERROR_NOT_SUPPORTED );
1458 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001459
Gilles Peskine8c9def32018-02-08 10:02:12 +01001460 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001461 * context may contain data that needs to be wiped on error. */
1462 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001463 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001464 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001465 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001466 else
1467 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001468 operation->key_set = 1;
1469 }
1470 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001471}
1472
1473psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1474 const uint8_t *input,
1475 size_t input_length )
1476{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001477 int ret = 0 ;
1478 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001479 if( ! operation->key_set )
1480 return( PSA_ERROR_BAD_STATE );
1481 if( operation->iv_required && ! operation->iv_set )
1482 return( PSA_ERROR_BAD_STATE );
1483 operation->has_input = 1;
1484
1485 switch( operation->alg )
1486 {
1487#if defined(MBEDTLS_CMAC_C)
1488 case PSA_ALG_CMAC:
1489 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1490 input, input_length );
1491 break;
1492#endif /* MBEDTLS_CMAC_C */
1493 default:
1494#if defined(MBEDTLS_MD_C)
1495 if( PSA_ALG_IS_HMAC( operation->alg ) )
1496 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001497 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001498 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001499 }
1500 else
1501#endif /* MBEDTLS_MD_C */
1502 {
1503 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1504 }
1505 break;
1506 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001507 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001508 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001509 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001510 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001511 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001512 }
1513
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001514 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001515}
1516
mohammad16036df908f2018-04-02 08:34:15 -07001517static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001518 uint8_t *mac,
1519 size_t mac_size,
1520 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001521{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001522 int ret = 0;
1523 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001524
1525 /* Fill the output buffer with something that isn't a valid mac
1526 * (barring an attack on the mac and deliberately-crafted input),
1527 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001528 *mac_length = mac_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001529 /* If mac_size is 0 then mac may be NULL and then the
1530 * call to memset would have undefined behavior. */
1531 if( mac_size != 0 )
1532 memset( mac, '!', mac_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001533
Gilles Peskine1d96fff2018-07-02 12:15:39 +02001534 if( ! operation->key_set )
1535 return( PSA_ERROR_BAD_STATE );
1536 if( operation->iv_required && ! operation->iv_set )
1537 return( PSA_ERROR_BAD_STATE );
1538
Gilles Peskine8c9def32018-02-08 10:02:12 +01001539 if( mac_size < operation->mac_size )
1540 return( PSA_ERROR_BUFFER_TOO_SMALL );
1541
1542 switch( operation->alg )
1543 {
1544#if defined(MBEDTLS_CMAC_C)
1545 case PSA_ALG_CMAC:
1546 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1547 break;
1548#endif /* MBEDTLS_CMAC_C */
1549 default:
1550#if defined(MBEDTLS_MD_C)
1551 if( PSA_ALG_IS_HMAC( operation->alg ) )
1552 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001553 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001554 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001555 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001556 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001557 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001558
Gilles Peskine99bc6492018-06-11 17:13:00 +02001559 if( block_size == 0 )
1560 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001561
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001562 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001563 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001564 if( status != PSA_SUCCESS )
1565 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001566 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001567
1568 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1569 PSA_ALG_HMAC_HASH( operation->alg ) );
1570 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001571 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001572
1573 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001574 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001575 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001576 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001577
1578 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001579 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001580 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001581 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001582
1583 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1584 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001585 hmac_cleanup:
1586 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001587 }
1588 else
1589#endif /* MBEDTLS_MD_C */
1590 {
1591 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1592 }
1593 break;
1594 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001595cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001596
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001597 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001598 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001599 *mac_length = operation->mac_size;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001600 return( psa_mac_abort( operation ) );
1601 }
1602 else
1603 {
1604 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001605 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001606 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001607
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001608 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001609 }
1610}
1611
mohammad16036df908f2018-04-02 08:34:15 -07001612psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1613 uint8_t *mac,
1614 size_t mac_size,
1615 size_t *mac_length )
1616{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001617 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001618 return( PSA_ERROR_NOT_PERMITTED );
1619
Gilles Peskine99bc6492018-06-11 17:13:00 +02001620 return( psa_mac_finish_internal( operation, mac,
1621 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001622}
1623
Gilles Peskine8c9def32018-02-08 10:02:12 +01001624psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1625 const uint8_t *mac,
1626 size_t mac_length )
1627{
Gilles Peskine828ed142018-06-18 23:25:51 +02001628 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001629 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001630 psa_status_t status;
1631
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001632 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001633 return( PSA_ERROR_NOT_PERMITTED );
1634
1635 status = psa_mac_finish_internal( operation,
1636 actual_mac, sizeof( actual_mac ),
1637 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001638 if( status != PSA_SUCCESS )
1639 return( status );
1640 if( actual_mac_length != mac_length )
1641 return( PSA_ERROR_INVALID_SIGNATURE );
1642 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1643 return( PSA_ERROR_INVALID_SIGNATURE );
1644 return( PSA_SUCCESS );
1645}
1646
1647
Gilles Peskine20035e32018-02-03 22:44:14 +01001648
Gilles Peskine20035e32018-02-03 22:44:14 +01001649/****************************************************************/
1650/* Asymmetric cryptography */
1651/****************************************************************/
1652
Gilles Peskine2b450e32018-06-27 15:42:46 +02001653#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001654/* Decode the hash algorithm from alg and store the mbedtls encoding in
1655 * md_alg. Verify that the hash length is consistent. */
1656static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1657 size_t hash_length,
1658 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001659{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02001660 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001661 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1662 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1663 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001664 {
1665#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001666 if( hash_length > UINT_MAX )
1667 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001668#endif
1669 }
1670 else
1671 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001672 if( mbedtls_md_get_size( md_info ) != hash_length )
1673 return( PSA_ERROR_INVALID_ARGUMENT );
1674 if( md_info == NULL )
1675 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001676 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001677 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001678}
1679
Gilles Peskine2b450e32018-06-27 15:42:46 +02001680static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
1681 psa_algorithm_t alg,
1682 const uint8_t *hash,
1683 size_t hash_length,
1684 uint8_t *signature,
1685 size_t signature_size,
1686 size_t *signature_length )
1687{
1688 psa_status_t status;
1689 int ret;
1690 mbedtls_md_type_t md_alg;
1691
1692 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1693 if( status != PSA_SUCCESS )
1694 return( status );
1695
1696 if( signature_size < rsa->len )
1697 return( PSA_ERROR_BUFFER_TOO_SMALL );
1698
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001699 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1700 * hash_length will fit and return an error if it doesn't. */
1701#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1702#if SIZE_MAX > UINT_MAX
1703 if( hash_length > UINT_MAX )
1704 return( PSA_ERROR_NOT_SUPPORTED );
1705#endif
1706#endif
1707
Gilles Peskine2b450e32018-06-27 15:42:46 +02001708#if defined(MBEDTLS_PKCS1_V15)
1709 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1710 {
1711 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1712 MBEDTLS_MD_NONE );
1713 ret = mbedtls_rsa_pkcs1_sign( rsa,
1714 mbedtls_ctr_drbg_random,
1715 &global_data.ctr_drbg,
1716 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001717 md_alg,
1718 (unsigned int) hash_length,
1719 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001720 signature );
1721 }
1722 else
1723#endif /* MBEDTLS_PKCS1_V15 */
1724#if defined(MBEDTLS_PKCS1_V21)
1725 if( PSA_ALG_IS_RSA_PSS( alg ) )
1726 {
1727 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1728 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1729 mbedtls_ctr_drbg_random,
1730 &global_data.ctr_drbg,
1731 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001732 md_alg,
1733 (unsigned int) hash_length,
1734 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001735 signature );
1736 }
1737 else
1738#endif /* MBEDTLS_PKCS1_V21 */
1739 {
1740 return( PSA_ERROR_INVALID_ARGUMENT );
1741 }
1742
1743 if( ret == 0 )
1744 *signature_length = rsa->len;
1745 return( mbedtls_to_psa_error( ret ) );
1746}
1747
1748static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
1749 psa_algorithm_t alg,
1750 const uint8_t *hash,
1751 size_t hash_length,
1752 const uint8_t *signature,
1753 size_t signature_length )
1754{
1755 psa_status_t status;
1756 int ret;
1757 mbedtls_md_type_t md_alg;
1758
1759 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1760 if( status != PSA_SUCCESS )
1761 return( status );
1762
1763 if( signature_length < rsa->len )
1764 return( PSA_ERROR_BUFFER_TOO_SMALL );
1765
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001766#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1767#if SIZE_MAX > UINT_MAX
1768 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1769 * hash_length will fit and return an error if it doesn't. */
1770 if( hash_length > UINT_MAX )
1771 return( PSA_ERROR_NOT_SUPPORTED );
1772#endif
1773#endif
1774
Gilles Peskine2b450e32018-06-27 15:42:46 +02001775#if defined(MBEDTLS_PKCS1_V15)
1776 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1777 {
1778 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1779 MBEDTLS_MD_NONE );
1780 ret = mbedtls_rsa_pkcs1_verify( rsa,
1781 mbedtls_ctr_drbg_random,
1782 &global_data.ctr_drbg,
1783 MBEDTLS_RSA_PUBLIC,
1784 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001785 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001786 hash,
1787 signature );
1788 }
1789 else
1790#endif /* MBEDTLS_PKCS1_V15 */
1791#if defined(MBEDTLS_PKCS1_V21)
1792 if( PSA_ALG_IS_RSA_PSS( alg ) )
1793 {
1794 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1795 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1796 mbedtls_ctr_drbg_random,
1797 &global_data.ctr_drbg,
1798 MBEDTLS_RSA_PUBLIC,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001799 md_alg,
1800 (unsigned int) hash_length,
1801 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001802 signature );
1803 }
1804 else
1805#endif /* MBEDTLS_PKCS1_V21 */
1806 {
1807 return( PSA_ERROR_INVALID_ARGUMENT );
1808 }
1809 return( mbedtls_to_psa_error( ret ) );
1810}
1811#endif /* MBEDTLS_RSA_C */
1812
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001813#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001814/* `ecp` cannot be const because `ecp->grp` needs to be non-const
1815 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
1816 * (even though these functions don't modify it). */
1817static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
1818 psa_algorithm_t alg,
1819 const uint8_t *hash,
1820 size_t hash_length,
1821 uint8_t *signature,
1822 size_t signature_size,
1823 size_t *signature_length )
1824{
1825 int ret;
1826 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001827 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001828 mbedtls_mpi_init( &r );
1829 mbedtls_mpi_init( &s );
1830
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001831 if( signature_size < 2 * curve_bytes )
1832 {
1833 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
1834 goto cleanup;
1835 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001836
1837 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
1838 {
1839 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
1840 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1841 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
1842 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
1843 hash, hash_length,
1844 md_alg ) );
1845 }
1846 else
1847 {
1848 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
1849 hash, hash_length,
1850 mbedtls_ctr_drbg_random,
1851 &global_data.ctr_drbg ) );
1852 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001853
1854 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
1855 signature,
1856 curve_bytes ) );
1857 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
1858 signature + curve_bytes,
1859 curve_bytes ) );
1860
1861cleanup:
1862 mbedtls_mpi_free( &r );
1863 mbedtls_mpi_free( &s );
1864 if( ret == 0 )
1865 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001866 return( mbedtls_to_psa_error( ret ) );
1867}
1868
1869static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
1870 const uint8_t *hash,
1871 size_t hash_length,
1872 const uint8_t *signature,
1873 size_t signature_length )
1874{
1875 int ret;
1876 mbedtls_mpi r, s;
1877 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
1878 mbedtls_mpi_init( &r );
1879 mbedtls_mpi_init( &s );
1880
1881 if( signature_length != 2 * curve_bytes )
1882 return( PSA_ERROR_INVALID_SIGNATURE );
1883
1884 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
1885 signature,
1886 curve_bytes ) );
1887 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
1888 signature + curve_bytes,
1889 curve_bytes ) );
1890
1891 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
1892 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001893
1894cleanup:
1895 mbedtls_mpi_free( &r );
1896 mbedtls_mpi_free( &s );
1897 return( mbedtls_to_psa_error( ret ) );
1898}
1899#endif /* MBEDTLS_ECDSA_C */
1900
Gilles Peskine61b91d42018-06-08 16:09:36 +02001901psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1902 psa_algorithm_t alg,
1903 const uint8_t *hash,
1904 size_t hash_length,
1905 const uint8_t *salt,
1906 size_t salt_length,
1907 uint8_t *signature,
1908 size_t signature_size,
1909 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001910{
1911 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001912 psa_status_t status;
1913
1914 *signature_length = signature_size;
1915
Gilles Peskine93aa0332018-02-03 23:58:03 +01001916 (void) salt;
1917 (void) salt_length;
1918
Gilles Peskine828ed142018-06-18 23:25:51 +02001919 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001920 {
1921 status = PSA_ERROR_EMPTY_SLOT;
1922 goto exit;
1923 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001924 slot = &global_data.key_slots[key];
1925 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001926 {
1927 status = PSA_ERROR_EMPTY_SLOT;
1928 goto exit;
1929 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001930 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001931 {
1932 status = PSA_ERROR_INVALID_ARGUMENT;
1933 goto exit;
1934 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001935 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001936 {
1937 status = PSA_ERROR_NOT_PERMITTED;
1938 goto exit;
1939 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001940
Gilles Peskine20035e32018-02-03 22:44:14 +01001941#if defined(MBEDTLS_RSA_C)
1942 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1943 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001944 status = psa_rsa_sign( slot->data.rsa,
1945 alg,
1946 hash, hash_length,
1947 signature, signature_size,
1948 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01001949 }
1950 else
1951#endif /* defined(MBEDTLS_RSA_C) */
1952#if defined(MBEDTLS_ECP_C)
1953 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1954 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001955#if defined(MBEDTLS_ECDSA_C)
1956 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001957 status = psa_ecdsa_sign( slot->data.ecp,
1958 alg,
1959 hash, hash_length,
1960 signature, signature_size,
1961 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001962 else
1963#endif /* defined(MBEDTLS_ECDSA_C) */
1964 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001965 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001966 }
itayzafrir5c753392018-05-08 11:18:38 +03001967 }
1968 else
1969#endif /* defined(MBEDTLS_ECP_C) */
1970 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001971 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01001972 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001973
1974exit:
1975 /* Fill the unused part of the output buffer (the whole buffer on error,
1976 * the trailing part on success) with something that isn't a valid mac
1977 * (barring an attack on the mac and deliberately-crafted input),
1978 * in case the caller doesn't check the return status properly. */
1979 if( status == PSA_SUCCESS )
1980 memset( signature + *signature_length, '!',
1981 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001982 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001983 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001984 /* If signature_size is 0 then we have nothing to do. We must not call
1985 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001986 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03001987}
1988
1989psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1990 psa_algorithm_t alg,
1991 const uint8_t *hash,
1992 size_t hash_length,
1993 const uint8_t *salt,
1994 size_t salt_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02001995 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02001996 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03001997{
1998 key_slot_t *slot;
Gilles Peskine2b450e32018-06-27 15:42:46 +02001999
itayzafrir5c753392018-05-08 11:18:38 +03002000 (void) salt;
2001 (void) salt_length;
2002
Gilles Peskine828ed142018-06-18 23:25:51 +02002003 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03002004 return( PSA_ERROR_INVALID_ARGUMENT );
2005 slot = &global_data.key_slots[key];
2006 if( slot->type == PSA_KEY_TYPE_NONE )
2007 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002008 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03002009 return( PSA_ERROR_NOT_PERMITTED );
2010
Gilles Peskine61b91d42018-06-08 16:09:36 +02002011#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002012 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
2013 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002014 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002015 return( psa_rsa_verify( slot->data.rsa,
2016 alg,
2017 hash, hash_length,
2018 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002019 }
2020 else
2021#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002022#if defined(MBEDTLS_ECP_C)
2023 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2024 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002025#if defined(MBEDTLS_ECDSA_C)
2026 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002027 return( psa_ecdsa_verify( slot->data.ecp,
2028 hash, hash_length,
2029 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002030 else
2031#endif /* defined(MBEDTLS_ECDSA_C) */
2032 {
2033 return( PSA_ERROR_INVALID_ARGUMENT );
2034 }
itayzafrir5c753392018-05-08 11:18:38 +03002035 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002036 else
2037#endif /* defined(MBEDTLS_ECP_C) */
2038 {
2039 return( PSA_ERROR_NOT_SUPPORTED );
2040 }
2041}
2042
Gilles Peskine61b91d42018-06-08 16:09:36 +02002043psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2044 psa_algorithm_t alg,
2045 const uint8_t *input,
2046 size_t input_length,
2047 const uint8_t *salt,
2048 size_t salt_length,
2049 uint8_t *output,
2050 size_t output_size,
2051 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002052{
2053 key_slot_t *slot;
2054 (void) salt;
2055 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002056 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002057
Gilles Peskine828ed142018-06-18 23:25:51 +02002058 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03002059 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002060 slot = &global_data.key_slots[key];
2061 if( slot->type == PSA_KEY_TYPE_NONE )
2062 return( PSA_ERROR_EMPTY_SLOT );
2063 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2064 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002065 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
2066 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002067
2068#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002069 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
2070 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002071 {
2072 mbedtls_rsa_context *rsa = slot->data.rsa;
2073 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002074 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002075 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002076#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002077 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002078 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002079 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2080 mbedtls_ctr_drbg_random,
2081 &global_data.ctr_drbg,
2082 MBEDTLS_RSA_PUBLIC,
2083 input_length,
2084 input,
2085 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002086 }
2087 else
2088#endif /* MBEDTLS_PKCS1_V15 */
2089#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002090 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002091 {
2092 return( PSA_ERROR_NOT_SUPPORTED );
2093 }
2094 else
2095#endif /* MBEDTLS_PKCS1_V21 */
2096 {
2097 return( PSA_ERROR_INVALID_ARGUMENT );
2098 }
2099 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002100 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002101 return( mbedtls_to_psa_error( ret ) );
2102 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002103 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002104#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002105 {
2106 return( PSA_ERROR_NOT_SUPPORTED );
2107 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002108}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002109
Gilles Peskine61b91d42018-06-08 16:09:36 +02002110psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2111 psa_algorithm_t alg,
2112 const uint8_t *input,
2113 size_t input_length,
2114 const uint8_t *salt,
2115 size_t salt_length,
2116 uint8_t *output,
2117 size_t output_size,
2118 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002119{
2120 key_slot_t *slot;
2121 (void) salt;
2122 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002123 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002124
Gilles Peskine828ed142018-06-18 23:25:51 +02002125 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002126 return( PSA_ERROR_EMPTY_SLOT );
2127 slot = &global_data.key_slots[key];
2128 if( slot->type == PSA_KEY_TYPE_NONE )
2129 return( PSA_ERROR_EMPTY_SLOT );
2130 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2131 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002132 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2133 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002134
2135#if defined(MBEDTLS_RSA_C)
2136 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2137 {
2138 mbedtls_rsa_context *rsa = slot->data.rsa;
2139 int ret;
2140
Gilles Peskinec4def2f2018-06-08 17:53:48 +02002141 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002142 return( PSA_ERROR_INVALID_ARGUMENT );
2143
2144#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002145 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002146 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002147 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2148 mbedtls_ctr_drbg_random,
2149 &global_data.ctr_drbg,
2150 MBEDTLS_RSA_PRIVATE,
2151 output_length,
2152 input,
2153 output,
2154 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002155 }
2156 else
2157#endif /* MBEDTLS_PKCS1_V15 */
2158#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002159 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002160 {
2161 return( PSA_ERROR_NOT_SUPPORTED );
2162 }
2163 else
2164#endif /* MBEDTLS_PKCS1_V21 */
2165 {
2166 return( PSA_ERROR_INVALID_ARGUMENT );
2167 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002168
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002169 return( mbedtls_to_psa_error( ret ) );
2170 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002171 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002172#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002173 {
2174 return( PSA_ERROR_NOT_SUPPORTED );
2175 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002176}
Gilles Peskine20035e32018-02-03 22:44:14 +01002177
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002178
2179
mohammad1603503973b2018-03-12 15:59:30 +02002180/****************************************************************/
2181/* Symmetric cryptography */
2182/****************************************************************/
2183
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002184/* Initialize the cipher operation structure. Once this function has been
2185 * called, psa_cipher_abort can run and will do the right thing. */
2186static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2187 psa_algorithm_t alg )
2188{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002189 if( ! PSA_ALG_IS_CIPHER( alg ) )
2190 {
2191 memset( operation, 0, sizeof( *operation ) );
2192 return( PSA_ERROR_INVALID_ARGUMENT );
2193 }
2194
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002195 operation->alg = alg;
2196 operation->key_set = 0;
2197 operation->iv_set = 0;
2198 operation->iv_required = 1;
2199 operation->iv_size = 0;
2200 operation->block_size = 0;
2201 mbedtls_cipher_init( &operation->ctx.cipher );
2202 return( PSA_SUCCESS );
2203}
2204
Gilles Peskinee553c652018-06-04 16:22:46 +02002205static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2206 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002207 psa_algorithm_t alg,
2208 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002209{
2210 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2211 psa_status_t status;
2212 key_slot_t *slot;
2213 psa_key_type_t key_type;
2214 size_t key_bits;
2215 const mbedtls_cipher_info_t *cipher_info = NULL;
2216
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002217 status = psa_cipher_init( operation, alg );
2218 if( status != PSA_SUCCESS )
2219 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002220
2221 status = psa_get_key_information( key, &key_type, &key_bits );
2222 if( status != PSA_SUCCESS )
2223 return( status );
2224 slot = &global_data.key_slots[key];
2225
Gilles Peskinebb1072f2018-06-08 18:46:05 +02002226 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002227 if( cipher_info == NULL )
2228 return( PSA_ERROR_NOT_SUPPORTED );
2229
mohammad1603503973b2018-03-12 15:59:30 +02002230 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002231 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002232 {
2233 psa_cipher_abort( operation );
2234 return( mbedtls_to_psa_error( ret ) );
2235 }
2236
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002237#if defined(MBEDTLS_DES_C)
2238 if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
2239 {
2240 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2241 unsigned char keys[24];
2242 memcpy( keys, slot->data.raw.data, 16 );
2243 memcpy( keys + 16, slot->data.raw.data, 8 );
2244 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2245 keys,
2246 192, cipher_operation );
2247 }
2248 else
2249#endif
2250 {
2251 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2252 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002253 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002254 }
Moran Peker41deec42018-04-04 15:43:05 +03002255 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002256 {
2257 psa_cipher_abort( operation );
2258 return( mbedtls_to_psa_error( ret ) );
2259 }
2260
mohammad16038481e742018-03-18 13:57:31 +02002261#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03002262 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02002263 {
Gilles Peskine53514202018-06-06 15:11:46 +02002264 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
2265 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02002266
Moran Pekera28258c2018-05-29 16:25:04 +03002267 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02002268 {
2269 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
2270 mode = MBEDTLS_PADDING_PKCS7;
2271 break;
2272 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
2273 mode = MBEDTLS_PADDING_NONE;
2274 break;
2275 default:
Moran Pekerae382792018-05-31 14:06:17 +03002276 psa_cipher_abort( operation );
2277 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02002278 }
2279 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03002280 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03002281 {
2282 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02002283 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03002284 }
mohammad16038481e742018-03-18 13:57:31 +02002285 }
2286#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2287
mohammad1603503973b2018-03-12 15:59:30 +02002288 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002289 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
2290 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
2291 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002292 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002293 {
mohammad160389e0f462018-04-12 08:48:45 +03002294 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02002295 }
mohammad1603503973b2018-03-12 15:59:30 +02002296
Moran Peker395db872018-05-31 14:07:14 +03002297 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002298}
2299
Gilles Peskinee553c652018-06-04 16:22:46 +02002300psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
2301 psa_key_slot_t key,
2302 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002303{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002304 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002305}
2306
Gilles Peskinee553c652018-06-04 16:22:46 +02002307psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
2308 psa_key_slot_t key,
2309 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002310{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002311 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002312}
2313
Gilles Peskinee553c652018-06-04 16:22:46 +02002314psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
2315 unsigned char *iv,
2316 size_t iv_size,
2317 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002318{
Moran Peker41deec42018-04-04 15:43:05 +03002319 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002320 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002321 return( PSA_ERROR_BAD_STATE );
2322 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002323 {
Moran Peker41deec42018-04-04 15:43:05 +03002324 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2325 goto exit;
2326 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002327 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2328 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002329 if( ret != 0 )
2330 {
2331 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002332 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002333 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002334
mohammad16038481e742018-03-18 13:57:31 +02002335 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03002336 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002337
Moran Peker395db872018-05-31 14:07:14 +03002338exit:
2339 if( ret != PSA_SUCCESS )
2340 psa_cipher_abort( operation );
2341 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002342}
2343
Gilles Peskinee553c652018-06-04 16:22:46 +02002344psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
2345 const unsigned char *iv,
2346 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002347{
Moran Peker41deec42018-04-04 15:43:05 +03002348 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002349 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002350 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002351 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002352 {
Moran Pekerae382792018-05-31 14:06:17 +03002353 psa_cipher_abort( operation );
2354 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002355 }
mohammad1603503973b2018-03-12 15:59:30 +02002356 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002357 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002358 {
2359 psa_cipher_abort( operation );
2360 return( mbedtls_to_psa_error( ret ) );
2361 }
2362
2363 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002364
Moran Peker395db872018-05-31 14:07:14 +03002365 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002366}
2367
Gilles Peskinee553c652018-06-04 16:22:46 +02002368psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2369 const uint8_t *input,
2370 size_t input_length,
2371 unsigned char *output,
2372 size_t output_size,
2373 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002374{
2375 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002376 size_t expected_output_size;
2377 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2378 {
2379 /* Take the unprocessed partial block left over from previous
2380 * update calls, if any, plus the input to this call. Remove
2381 * the last partial block, if any. You get the data that will be
2382 * output in this call. */
2383 expected_output_size =
2384 ( operation->ctx.cipher.unprocessed_len + input_length )
2385 / operation->block_size * operation->block_size;
2386 }
2387 else
2388 {
2389 expected_output_size = input_length;
2390 }
2391 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002392 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002393
mohammad1603503973b2018-03-12 15:59:30 +02002394 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002395 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002396 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002397 {
2398 psa_cipher_abort( operation );
2399 return( mbedtls_to_psa_error( ret ) );
2400 }
2401
Moran Peker395db872018-05-31 14:07:14 +03002402 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002403}
2404
Gilles Peskinee553c652018-06-04 16:22:46 +02002405psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2406 uint8_t *output,
2407 size_t output_size,
2408 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002409{
2410 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002411 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002412
mohammad1603503973b2018-03-12 15:59:30 +02002413 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002414 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002415 psa_cipher_abort( operation );
2416 return( PSA_ERROR_BAD_STATE );
2417 }
2418 if( operation->iv_required && ! operation->iv_set )
2419 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002420 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002421 return( PSA_ERROR_BAD_STATE );
2422 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002423 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2424 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002425 {
Gilles Peskine53514202018-06-06 15:11:46 +02002426 psa_algorithm_t padding_mode =
2427 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002428 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002429 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002430 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002431 return( PSA_ERROR_TAMPERING_DETECTED );
2432 }
Gilles Peskine53514202018-06-06 15:11:46 +02002433 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002434 {
2435 if( operation->ctx.cipher.unprocessed_len != 0 )
2436 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002437 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002438 return( PSA_ERROR_INVALID_ARGUMENT );
2439 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002440 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002441 }
2442
2443 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002444 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002445 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002446 {
2447 psa_cipher_abort( operation );
2448 return( mbedtls_to_psa_error( ret ) );
2449 }
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002450 if( *output_length == 0 )
2451 /* Nothing to copy. Note that output may be NULL in this case. */ ;
2452 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002453 memcpy( output, temp_output_buffer, *output_length );
2454 else
2455 {
2456 psa_cipher_abort( operation );
2457 return( PSA_ERROR_BUFFER_TOO_SMALL );
2458 }
mohammad1603503973b2018-03-12 15:59:30 +02002459
Moran Peker4c80d832018-04-22 20:15:31 +03002460 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002461}
2462
Gilles Peskinee553c652018-06-04 16:22:46 +02002463psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2464{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002465 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002466 {
2467 /* The object has (apparently) been initialized but it is not
2468 * in use. It's ok to call abort on such an object, and there's
2469 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002470 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002471 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002472
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002473 /* Sanity check (shouldn't happen: operation->alg should
2474 * always have been initialized to a valid value). */
2475 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2476 return( PSA_ERROR_BAD_STATE );
2477
mohammad1603503973b2018-03-12 15:59:30 +02002478 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002479
Moran Peker41deec42018-04-04 15:43:05 +03002480 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002481 operation->key_set = 0;
2482 operation->iv_set = 0;
2483 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002484 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002485 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002486
Moran Peker395db872018-05-31 14:07:14 +03002487 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002488}
2489
Gilles Peskinea0655c32018-04-30 17:06:50 +02002490
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002491
mohammad16038cc1cee2018-03-28 01:21:33 +03002492/****************************************************************/
2493/* Key Policy */
2494/****************************************************************/
mohammad160327010052018-07-03 13:16:15 +03002495#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02002496void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002497{
Gilles Peskine803ce742018-06-18 16:07:14 +02002498 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002499}
2500
Gilles Peskine2d277862018-06-18 15:41:12 +02002501void psa_key_policy_set_usage( psa_key_policy_t *policy,
2502 psa_key_usage_t usage,
2503 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002504{
mohammad16034eed7572018-03-28 05:14:59 -07002505 policy->usage = usage;
2506 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002507}
2508
Gilles Peskine2d277862018-06-18 15:41:12 +02002509psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002510{
mohammad16036df908f2018-04-02 08:34:15 -07002511 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002512}
2513
Gilles Peskine2d277862018-06-18 15:41:12 +02002514psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002515{
mohammad16036df908f2018-04-02 08:34:15 -07002516 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002517}
mohammad160327010052018-07-03 13:16:15 +03002518#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Gilles Peskine2d277862018-06-18 15:41:12 +02002519psa_status_t psa_set_key_policy( psa_key_slot_t key,
2520 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002521{
2522 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002523
Gilles Peskine828ed142018-06-18 23:25:51 +02002524 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002525 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002526
mohammad16038cc1cee2018-03-28 01:21:33 +03002527 slot = &global_data.key_slots[key];
2528 if( slot->type != PSA_KEY_TYPE_NONE )
2529 return( PSA_ERROR_OCCUPIED_SLOT );
2530
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002531 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2532 PSA_KEY_USAGE_ENCRYPT |
2533 PSA_KEY_USAGE_DECRYPT |
2534 PSA_KEY_USAGE_SIGN |
2535 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002536 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002537
mohammad16036df908f2018-04-02 08:34:15 -07002538 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002539
2540 return( PSA_SUCCESS );
2541}
2542
Gilles Peskine2d277862018-06-18 15:41:12 +02002543psa_status_t psa_get_key_policy( psa_key_slot_t key,
2544 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002545{
2546 key_slot_t *slot;
2547
Gilles Peskine828ed142018-06-18 23:25:51 +02002548 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002549 return( PSA_ERROR_INVALID_ARGUMENT );
2550
2551 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002552
mohammad16036df908f2018-04-02 08:34:15 -07002553 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002554
2555 return( PSA_SUCCESS );
2556}
Gilles Peskine20035e32018-02-03 22:44:14 +01002557
Gilles Peskinea0655c32018-04-30 17:06:50 +02002558
2559
mohammad1603804cd712018-03-20 22:44:08 +02002560/****************************************************************/
2561/* Key Lifetime */
2562/****************************************************************/
2563
Gilles Peskine2d277862018-06-18 15:41:12 +02002564psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2565 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002566{
2567 key_slot_t *slot;
2568
Gilles Peskine828ed142018-06-18 23:25:51 +02002569 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002570 return( PSA_ERROR_INVALID_ARGUMENT );
2571
2572 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002573
mohammad1603804cd712018-03-20 22:44:08 +02002574 *lifetime = slot->lifetime;
2575
2576 return( PSA_SUCCESS );
2577}
2578
Gilles Peskine2d277862018-06-18 15:41:12 +02002579psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01002580 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002581{
2582 key_slot_t *slot;
2583
Gilles Peskine828ed142018-06-18 23:25:51 +02002584 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002585 return( PSA_ERROR_INVALID_ARGUMENT );
2586
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002587 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2588 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002589 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2590 return( PSA_ERROR_INVALID_ARGUMENT );
2591
mohammad1603804cd712018-03-20 22:44:08 +02002592 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002593 if( slot->type != PSA_KEY_TYPE_NONE )
2594 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002595
Moran Pekerd7326592018-05-29 16:56:39 +03002596 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002597 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002598
mohammad1603060ad8a2018-03-20 14:28:38 -07002599 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002600
2601 return( PSA_SUCCESS );
2602}
2603
Gilles Peskine20035e32018-02-03 22:44:14 +01002604
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002605
mohammad16035955c982018-04-26 00:53:03 +03002606/****************************************************************/
2607/* AEAD */
2608/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002609
mohammad16035955c982018-04-26 00:53:03 +03002610psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2611 psa_algorithm_t alg,
2612 const uint8_t *nonce,
2613 size_t nonce_length,
2614 const uint8_t *additional_data,
2615 size_t additional_data_length,
2616 const uint8_t *plaintext,
2617 size_t plaintext_length,
2618 uint8_t *ciphertext,
2619 size_t ciphertext_size,
2620 size_t *ciphertext_length )
2621{
2622 int ret;
2623 psa_status_t status;
2624 key_slot_t *slot;
2625 psa_key_type_t key_type;
2626 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002627 uint8_t *tag;
2628 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002629 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002630 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002631
mohammad1603f08a5502018-06-03 15:05:47 +03002632 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002633
mohammad16035955c982018-04-26 00:53:03 +03002634 status = psa_get_key_information( key, &key_type, &key_bits );
2635 if( status != PSA_SUCCESS )
2636 return( status );
2637 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002638 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002639 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002640
mohammad16035ed06212018-06-06 13:09:34 +03002641 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2642 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002643 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002644 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002645
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002646 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002647 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002648
Gilles Peskine2d277862018-06-18 15:41:12 +02002649 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2650 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002651 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002652
mohammad16035955c982018-04-26 00:53:03 +03002653 if( alg == PSA_ALG_GCM )
2654 {
2655 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002656 tag_length = 16;
2657
mohammad160396910d82018-06-04 14:33:00 +03002658 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2659 return( PSA_ERROR_INVALID_ARGUMENT );
2660
mohammad160315223a82018-06-03 17:19:55 +03002661 //make sure we have place to hold the tag in the ciphertext buffer
2662 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002663 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002664
2665 //update the tag pointer to point to the end of the ciphertext_length
2666 tag = ciphertext + plaintext_length;
2667
mohammad16035955c982018-04-26 00:53:03 +03002668 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002669 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002670 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002671 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002672 if( ret != 0 )
2673 {
2674 mbedtls_gcm_free( &gcm );
2675 return( mbedtls_to_psa_error( ret ) );
2676 }
2677 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002678 plaintext_length, nonce,
2679 nonce_length, additional_data,
2680 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002681 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002682 mbedtls_gcm_free( &gcm );
2683 }
2684 else if( alg == PSA_ALG_CCM )
2685 {
2686 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002687 tag_length = 16;
2688
mohammad160396910d82018-06-04 14:33:00 +03002689 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2690 return( PSA_ERROR_INVALID_ARGUMENT );
2691
mohammad160347ddf3d2018-04-26 01:11:21 +03002692 if( nonce_length < 7 || nonce_length > 13 )
2693 return( PSA_ERROR_INVALID_ARGUMENT );
2694
mohammad160315223a82018-06-03 17:19:55 +03002695 //make sure we have place to hold the tag in the ciphertext buffer
2696 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002697 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002698
2699 //update the tag pointer to point to the end of the ciphertext_length
2700 tag = ciphertext + plaintext_length;
2701
mohammad16035955c982018-04-26 00:53:03 +03002702 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002703 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002704 slot->data.raw.data,
2705 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002706 if( ret != 0 )
2707 {
2708 mbedtls_ccm_free( &ccm );
2709 return( mbedtls_to_psa_error( ret ) );
2710 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002711 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002712 nonce, nonce_length,
2713 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002714 additional_data_length,
2715 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002716 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002717 mbedtls_ccm_free( &ccm );
2718 }
mohammad16035c8845f2018-05-09 05:40:09 -07002719 else
2720 {
mohammad1603554faad2018-06-03 15:07:38 +03002721 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002722 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002723
mohammad160315223a82018-06-03 17:19:55 +03002724 if( ret != 0 )
2725 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002726 /* If ciphertext_size is 0 then ciphertext may be NULL and then the
2727 * call to memset would have undefined behavior. */
2728 if( ciphertext_size != 0 )
2729 memset( ciphertext, 0, ciphertext_size );
mohammad160315223a82018-06-03 17:19:55 +03002730 return( mbedtls_to_psa_error( ret ) );
2731 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002732
mohammad160315223a82018-06-03 17:19:55 +03002733 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002734 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002735}
2736
Gilles Peskineee652a32018-06-01 19:23:52 +02002737/* Locate the tag in a ciphertext buffer containing the encrypted data
2738 * followed by the tag. Return the length of the part preceding the tag in
2739 * *plaintext_length. This is the size of the plaintext in modes where
2740 * the encrypted data has the same size as the plaintext, such as
2741 * CCM and GCM. */
2742static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2743 const uint8_t *ciphertext,
2744 size_t ciphertext_length,
2745 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002746 const uint8_t **p_tag )
2747{
2748 size_t payload_length;
2749 if( tag_length > ciphertext_length )
2750 return( PSA_ERROR_INVALID_ARGUMENT );
2751 payload_length = ciphertext_length - tag_length;
2752 if( payload_length > plaintext_size )
2753 return( PSA_ERROR_BUFFER_TOO_SMALL );
2754 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002755 return( PSA_SUCCESS );
2756}
2757
mohammad16035955c982018-04-26 00:53:03 +03002758psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2759 psa_algorithm_t alg,
2760 const uint8_t *nonce,
2761 size_t nonce_length,
2762 const uint8_t *additional_data,
2763 size_t additional_data_length,
2764 const uint8_t *ciphertext,
2765 size_t ciphertext_length,
2766 uint8_t *plaintext,
2767 size_t plaintext_size,
2768 size_t *plaintext_length )
2769{
2770 int ret;
2771 psa_status_t status;
2772 key_slot_t *slot;
2773 psa_key_type_t key_type;
2774 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002775 const uint8_t *tag;
2776 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002777 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002778 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002779
Gilles Peskineee652a32018-06-01 19:23:52 +02002780 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002781
mohammad16035955c982018-04-26 00:53:03 +03002782 status = psa_get_key_information( key, &key_type, &key_bits );
2783 if( status != PSA_SUCCESS )
2784 return( status );
2785 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002786 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002787 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002788
mohammad16035ed06212018-06-06 13:09:34 +03002789 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2790 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002791 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002792 return( PSA_ERROR_NOT_SUPPORTED );
2793
mohammad1603f14394b2018-06-04 14:33:19 +03002794 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2795 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002796
Gilles Peskine2d277862018-06-18 15:41:12 +02002797 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2798 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002799 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002800
mohammad16035955c982018-04-26 00:53:03 +03002801 if( alg == PSA_ALG_GCM )
2802 {
2803 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002804
Gilles Peskineee652a32018-06-01 19:23:52 +02002805 tag_length = 16;
2806 status = psa_aead_unpadded_locate_tag( tag_length,
2807 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002808 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002809 if( status != PSA_SUCCESS )
2810 return( status );
2811
mohammad16035955c982018-04-26 00:53:03 +03002812 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002813 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002814 slot->data.raw.data,
2815 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002816 if( ret != 0 )
2817 {
2818 mbedtls_gcm_free( &gcm );
2819 return( mbedtls_to_psa_error( ret ) );
2820 }
mohammad16035955c982018-04-26 00:53:03 +03002821
Gilles Peskineee652a32018-06-01 19:23:52 +02002822 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002823 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002824 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002825 additional_data,
2826 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002827 tag, tag_length,
2828 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002829 mbedtls_gcm_free( &gcm );
2830 }
2831 else if( alg == PSA_ALG_CCM )
2832 {
2833 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002834
mohammad160347ddf3d2018-04-26 01:11:21 +03002835 if( nonce_length < 7 || nonce_length > 13 )
2836 return( PSA_ERROR_INVALID_ARGUMENT );
2837
mohammad16039375f842018-06-03 14:28:24 +03002838 tag_length = 16;
2839 status = psa_aead_unpadded_locate_tag( tag_length,
2840 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002841 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002842 if( status != PSA_SUCCESS )
2843 return( status );
2844
mohammad16035955c982018-04-26 00:53:03 +03002845 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002846 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002847 slot->data.raw.data,
2848 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002849 if( ret != 0 )
2850 {
2851 mbedtls_ccm_free( &ccm );
2852 return( mbedtls_to_psa_error( ret ) );
2853 }
mohammad160360a64d02018-06-03 17:20:42 +03002854 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002855 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002856 additional_data,
2857 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002858 ciphertext, plaintext,
2859 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002860 mbedtls_ccm_free( &ccm );
2861 }
mohammad160339574652018-06-01 04:39:53 -07002862 else
2863 {
mohammad1603554faad2018-06-03 15:07:38 +03002864 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002865 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002866
Gilles Peskineee652a32018-06-01 19:23:52 +02002867 if( ret != 0 )
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002868 {
2869 /* If plaintext_size is 0 then plaintext may be NULL and then the
2870 * call to memset has undefined behavior. */
2871 if( plaintext_size != 0 )
2872 memset( plaintext, 0, plaintext_size );
2873 }
mohammad160360a64d02018-06-03 17:20:42 +03002874 else
2875 *plaintext_length = ciphertext_length - tag_length;
2876
Gilles Peskineee652a32018-06-01 19:23:52 +02002877 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002878}
2879
Gilles Peskinea0655c32018-04-30 17:06:50 +02002880
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002881
Gilles Peskine20035e32018-02-03 22:44:14 +01002882/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002883/* Key generation */
2884/****************************************************************/
2885
2886psa_status_t psa_generate_random( uint8_t *output,
2887 size_t output_size )
2888{
2889 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2890 output, output_size );
2891 return( mbedtls_to_psa_error( ret ) );
2892}
2893
2894psa_status_t psa_generate_key( psa_key_slot_t key,
2895 psa_key_type_t type,
2896 size_t bits,
2897 const void *parameters,
2898 size_t parameters_size )
2899{
Gilles Peskine12313cd2018-06-20 00:20:32 +02002900 key_slot_t *slot;
2901
2902 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
2903 return( PSA_ERROR_INVALID_ARGUMENT );
2904 slot = &global_data.key_slots[key];
2905 if( slot->type != PSA_KEY_TYPE_NONE )
2906 return( PSA_ERROR_OCCUPIED_SLOT );
2907 if( parameters == NULL && parameters_size != 0 )
2908 return( PSA_ERROR_INVALID_ARGUMENT );
2909
Gilles Peskine48c0ea12018-06-21 14:15:31 +02002910 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02002911 {
2912 psa_status_t status = prepare_raw_data_slot( type, bits,
2913 &slot->data.raw );
2914 if( status != PSA_SUCCESS )
2915 return( status );
2916 status = psa_generate_random( slot->data.raw.data,
2917 slot->data.raw.bytes );
2918 if( status != PSA_SUCCESS )
2919 {
2920 mbedtls_free( slot->data.raw.data );
2921 return( status );
2922 }
2923#if defined(MBEDTLS_DES_C)
2924 if( type == PSA_KEY_TYPE_DES )
2925 {
2926 mbedtls_des_key_set_parity( slot->data.raw.data );
2927 if( slot->data.raw.bytes >= 16 )
2928 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
2929 if( slot->data.raw.bytes == 24 )
2930 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
2931 }
2932#endif /* MBEDTLS_DES_C */
2933 }
2934 else
2935
2936#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
2937 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
2938 {
2939 mbedtls_rsa_context *rsa;
2940 int ret;
2941 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02002942 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
2943 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine12313cd2018-06-20 00:20:32 +02002944 if( parameters != NULL )
2945 {
2946 const unsigned *p = parameters;
2947 if( parameters_size != sizeof( *p ) )
2948 return( PSA_ERROR_INVALID_ARGUMENT );
2949 if( *p > INT_MAX )
2950 return( PSA_ERROR_INVALID_ARGUMENT );
2951 exponent = *p;
2952 }
2953 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
2954 if( rsa == NULL )
2955 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2956 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
2957 ret = mbedtls_rsa_gen_key( rsa,
2958 mbedtls_ctr_drbg_random,
2959 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002960 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02002961 exponent );
2962 if( ret != 0 )
2963 {
2964 mbedtls_rsa_free( rsa );
2965 mbedtls_free( rsa );
2966 return( mbedtls_to_psa_error( ret ) );
2967 }
2968 slot->data.rsa = rsa;
2969 }
2970 else
2971#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
2972
2973#if defined(MBEDTLS_ECP_C)
2974 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
2975 {
2976 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
2977 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
2978 const mbedtls_ecp_curve_info *curve_info =
2979 mbedtls_ecp_curve_info_from_grp_id( grp_id );
2980 mbedtls_ecp_keypair *ecp;
2981 int ret;
2982 if( parameters != NULL )
2983 return( PSA_ERROR_NOT_SUPPORTED );
2984 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
2985 return( PSA_ERROR_NOT_SUPPORTED );
2986 if( curve_info->bit_size != bits )
2987 return( PSA_ERROR_INVALID_ARGUMENT );
2988 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
2989 if( ecp == NULL )
2990 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2991 mbedtls_ecp_keypair_init( ecp );
2992 ret = mbedtls_ecp_gen_key( grp_id, ecp,
2993 mbedtls_ctr_drbg_random,
2994 &global_data.ctr_drbg );
2995 if( ret != 0 )
2996 {
2997 mbedtls_ecp_keypair_free( ecp );
2998 mbedtls_free( ecp );
2999 return( mbedtls_to_psa_error( ret ) );
3000 }
3001 slot->data.ecp = ecp;
3002 }
3003 else
3004#endif /* MBEDTLS_ECP_C */
3005
3006 return( PSA_ERROR_NOT_SUPPORTED );
3007
3008 slot->type = type;
3009 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02003010}
3011
3012
3013/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003014/* Module setup */
3015/****************************************************************/
3016
Gilles Peskinee59236f2018-01-27 23:32:46 +01003017void mbedtls_psa_crypto_free( void )
3018{
Jaeden Amero045bd502018-06-26 14:00:08 +01003019 psa_key_slot_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02003020 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003021 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003022 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
3023 mbedtls_entropy_free( &global_data.entropy );
3024 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3025}
3026
3027psa_status_t psa_crypto_init( void )
3028{
3029 int ret;
3030 const unsigned char drbg_seed[] = "PSA";
3031
3032 if( global_data.initialized != 0 )
3033 return( PSA_SUCCESS );
3034
3035 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3036 mbedtls_entropy_init( &global_data.entropy );
3037 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
3038
3039 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
3040 mbedtls_entropy_func,
3041 &global_data.entropy,
3042 drbg_seed, sizeof( drbg_seed ) - 1 );
3043 if( ret != 0 )
3044 goto exit;
3045
Gilles Peskinee4ebc122018-03-07 14:16:44 +01003046 global_data.initialized = 1;
3047
Gilles Peskinee59236f2018-01-27 23:32:46 +01003048exit:
3049 if( ret != 0 )
3050 mbedtls_psa_crypto_free( );
3051 return( mbedtls_to_psa_error( ret ) );
3052}
3053
3054#endif /* MBEDTLS_PSA_CRYPTO_C */