blob: ca461c20e8ca78497dfb7d36241cd8b3ba4bac6c [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
30#include "psa/crypto.h"
31
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010032#include <stdlib.h>
33#include <string.h>
34#if defined(MBEDTLS_PLATFORM_C)
35#include "mbedtls/platform.h"
36#else
37#define mbedtls_calloc calloc
38#define mbedtls_free free
39#endif
40
Gilles Peskinea5905292018-02-07 20:59:33 +010041#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020042#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020043#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010044#include "mbedtls/blowfish.h"
45#include "mbedtls/camellia.h"
46#include "mbedtls/cipher.h"
47#include "mbedtls/ccm.h"
48#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010049#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010050#include "mbedtls/des.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010051#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010052#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010053#include "mbedtls/error.h"
54#include "mbedtls/gcm.h"
55#include "mbedtls/md2.h"
56#include "mbedtls/md4.h"
57#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010058#include "mbedtls/md.h"
59#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010060#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010061#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010063#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010064#include "mbedtls/sha1.h"
65#include "mbedtls/sha256.h"
66#include "mbedtls/sha512.h"
67#include "mbedtls/xtea.h"
68
Gilles Peskinee59236f2018-01-27 23:32:46 +010069
70
71/* Implementation that should never be optimized out by the compiler */
72static void mbedtls_zeroize( void *v, size_t n )
73{
74 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
75}
76
Gilles Peskine9ef733f2018-02-07 21:05:37 +010077/* constant-time buffer comparison */
78static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
79{
80 size_t i;
81 unsigned char diff = 0;
82
83 for( i = 0; i < n; i++ )
84 diff |= a[i] ^ b[i];
85
86 return( diff );
87}
88
89
90
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010091/****************************************************************/
92/* Global data, support functions and library management */
93/****************************************************************/
94
95/* Number of key slots (plus one because 0 is not used).
96 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +020097#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010098
Gilles Peskine2d277862018-06-18 15:41:12 +020099typedef struct
100{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100101 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300102 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200103 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200104 union
105 {
106 struct raw_data
107 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100108 uint8_t *data;
109 size_t bytes;
110 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100111#if defined(MBEDTLS_RSA_C)
112 mbedtls_rsa_context *rsa;
113#endif /* MBEDTLS_RSA_C */
114#if defined(MBEDTLS_ECP_C)
115 mbedtls_ecp_keypair *ecp;
116#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100117 } data;
118} key_slot_t;
119
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200120static int key_type_is_raw_bytes( psa_key_type_t type )
121{
122 psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
123 return( category == PSA_KEY_TYPE_RAW_DATA ||
124 category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
125}
126
Gilles Peskine2d277862018-06-18 15:41:12 +0200127typedef struct
128{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100129 int initialized;
130 mbedtls_entropy_context entropy;
131 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200132 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100133} psa_global_data_t;
134
135static psa_global_data_t global_data;
136
137static psa_status_t mbedtls_to_psa_error( int ret )
138{
Gilles Peskinea5905292018-02-07 20:59:33 +0100139 /* If there's both a high-level code and low-level code, dispatch on
140 * the high-level code. */
141 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100142 {
143 case 0:
144 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100145
146 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
147 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
148 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
149 return( PSA_ERROR_NOT_SUPPORTED );
150 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
151 return( PSA_ERROR_HARDWARE_FAILURE );
152
153 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
154 return( PSA_ERROR_HARDWARE_FAILURE );
155
Gilles Peskine9a944802018-06-21 09:35:35 +0200156 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
157 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
158 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
159 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
160 case MBEDTLS_ERR_ASN1_INVALID_DATA:
161 return( PSA_ERROR_INVALID_ARGUMENT );
162 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
163 return( PSA_ERROR_INSUFFICIENT_MEMORY );
164 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
165 return( PSA_ERROR_BUFFER_TOO_SMALL );
166
Gilles Peskinea5905292018-02-07 20:59:33 +0100167 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
168 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
169 return( PSA_ERROR_NOT_SUPPORTED );
170 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
171 return( PSA_ERROR_HARDWARE_FAILURE );
172
173 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
174 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
175 return( PSA_ERROR_NOT_SUPPORTED );
176 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
177 return( PSA_ERROR_HARDWARE_FAILURE );
178
179 case MBEDTLS_ERR_CCM_BAD_INPUT:
180 return( PSA_ERROR_INVALID_ARGUMENT );
181 case MBEDTLS_ERR_CCM_AUTH_FAILED:
182 return( PSA_ERROR_INVALID_SIGNATURE );
183 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
187 return( PSA_ERROR_NOT_SUPPORTED );
188 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
189 return( PSA_ERROR_INVALID_ARGUMENT );
190 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
191 return( PSA_ERROR_INSUFFICIENT_MEMORY );
192 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
193 return( PSA_ERROR_INVALID_PADDING );
194 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
195 return( PSA_ERROR_BAD_STATE );
196 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
197 return( PSA_ERROR_INVALID_SIGNATURE );
198 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
199 return( PSA_ERROR_TAMPERING_DETECTED );
200 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
201 return( PSA_ERROR_HARDWARE_FAILURE );
202
203 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
204 return( PSA_ERROR_HARDWARE_FAILURE );
205
206 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
207 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
208 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
209 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
210 return( PSA_ERROR_NOT_SUPPORTED );
211 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
212 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
213
214 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
215 return( PSA_ERROR_NOT_SUPPORTED );
216 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
217 return( PSA_ERROR_HARDWARE_FAILURE );
218
Gilles Peskinee59236f2018-01-27 23:32:46 +0100219 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
220 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
221 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
222 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100223
224 case MBEDTLS_ERR_GCM_AUTH_FAILED:
225 return( PSA_ERROR_INVALID_SIGNATURE );
226 case MBEDTLS_ERR_GCM_BAD_INPUT:
227 return( PSA_ERROR_NOT_SUPPORTED );
228 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
229 return( PSA_ERROR_HARDWARE_FAILURE );
230
231 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
232 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
233 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
234 return( PSA_ERROR_HARDWARE_FAILURE );
235
236 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
237 return( PSA_ERROR_NOT_SUPPORTED );
238 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
239 return( PSA_ERROR_INVALID_ARGUMENT );
240 case MBEDTLS_ERR_MD_ALLOC_FAILED:
241 return( PSA_ERROR_INSUFFICIENT_MEMORY );
242 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
243 return( PSA_ERROR_STORAGE_FAILURE );
244 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
245 return( PSA_ERROR_HARDWARE_FAILURE );
246
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100247 case MBEDTLS_ERR_PK_ALLOC_FAILED:
248 return( PSA_ERROR_INSUFFICIENT_MEMORY );
249 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
250 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
251 return( PSA_ERROR_INVALID_ARGUMENT );
252 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100253 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100254 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
255 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
256 return( PSA_ERROR_INVALID_ARGUMENT );
257 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
258 return( PSA_ERROR_NOT_SUPPORTED );
259 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
260 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
261 return( PSA_ERROR_NOT_PERMITTED );
262 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
263 return( PSA_ERROR_INVALID_ARGUMENT );
264 case MBEDTLS_ERR_PK_INVALID_ALG:
265 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
266 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
267 return( PSA_ERROR_NOT_SUPPORTED );
268 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
269 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100270 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
271 return( PSA_ERROR_HARDWARE_FAILURE );
272
273 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
274 return( PSA_ERROR_HARDWARE_FAILURE );
275
276 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
277 return( PSA_ERROR_INVALID_ARGUMENT );
278 case MBEDTLS_ERR_RSA_INVALID_PADDING:
279 return( PSA_ERROR_INVALID_PADDING );
280 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
281 return( PSA_ERROR_HARDWARE_FAILURE );
282 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
283 return( PSA_ERROR_INVALID_ARGUMENT );
284 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
285 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
286 return( PSA_ERROR_TAMPERING_DETECTED );
287 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
288 return( PSA_ERROR_INVALID_SIGNATURE );
289 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
290 return( PSA_ERROR_BUFFER_TOO_SMALL );
291 case MBEDTLS_ERR_RSA_RNG_FAILED:
292 return( PSA_ERROR_INSUFFICIENT_MEMORY );
293 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
294 return( PSA_ERROR_NOT_SUPPORTED );
295 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
296 return( PSA_ERROR_HARDWARE_FAILURE );
297
298 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
299 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
300 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
301 return( PSA_ERROR_HARDWARE_FAILURE );
302
303 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
304 return( PSA_ERROR_INVALID_ARGUMENT );
305 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
306 return( PSA_ERROR_HARDWARE_FAILURE );
307
itayzafrir5c753392018-05-08 11:18:38 +0300308 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300309 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300310 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300311 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
312 return( PSA_ERROR_BUFFER_TOO_SMALL );
313 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
314 return( PSA_ERROR_NOT_SUPPORTED );
315 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
316 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
317 return( PSA_ERROR_INVALID_SIGNATURE );
318 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
319 return( PSA_ERROR_INSUFFICIENT_MEMORY );
320 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
321 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300322
Gilles Peskinee59236f2018-01-27 23:32:46 +0100323 default:
324 return( PSA_ERROR_UNKNOWN_ERROR );
325 }
326}
327
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200328
329
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100330/****************************************************************/
331/* Key management */
332/****************************************************************/
333
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200334static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
335{
336 switch( grpid )
337 {
338 case MBEDTLS_ECP_DP_SECP192R1:
339 return( PSA_ECC_CURVE_SECP192R1 );
340 case MBEDTLS_ECP_DP_SECP224R1:
341 return( PSA_ECC_CURVE_SECP224R1 );
342 case MBEDTLS_ECP_DP_SECP256R1:
343 return( PSA_ECC_CURVE_SECP256R1 );
344 case MBEDTLS_ECP_DP_SECP384R1:
345 return( PSA_ECC_CURVE_SECP384R1 );
346 case MBEDTLS_ECP_DP_SECP521R1:
347 return( PSA_ECC_CURVE_SECP521R1 );
348 case MBEDTLS_ECP_DP_BP256R1:
349 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
350 case MBEDTLS_ECP_DP_BP384R1:
351 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
352 case MBEDTLS_ECP_DP_BP512R1:
353 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
354 case MBEDTLS_ECP_DP_CURVE25519:
355 return( PSA_ECC_CURVE_CURVE25519 );
356 case MBEDTLS_ECP_DP_SECP192K1:
357 return( PSA_ECC_CURVE_SECP192K1 );
358 case MBEDTLS_ECP_DP_SECP224K1:
359 return( PSA_ECC_CURVE_SECP224K1 );
360 case MBEDTLS_ECP_DP_SECP256K1:
361 return( PSA_ECC_CURVE_SECP256K1 );
362 case MBEDTLS_ECP_DP_CURVE448:
363 return( PSA_ECC_CURVE_CURVE448 );
364 default:
365 return( 0 );
366 }
367}
368
Gilles Peskine12313cd2018-06-20 00:20:32 +0200369static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
370{
371 switch( curve )
372 {
373 case PSA_ECC_CURVE_SECP192R1:
374 return( MBEDTLS_ECP_DP_SECP192R1 );
375 case PSA_ECC_CURVE_SECP224R1:
376 return( MBEDTLS_ECP_DP_SECP224R1 );
377 case PSA_ECC_CURVE_SECP256R1:
378 return( MBEDTLS_ECP_DP_SECP256R1 );
379 case PSA_ECC_CURVE_SECP384R1:
380 return( MBEDTLS_ECP_DP_SECP384R1 );
381 case PSA_ECC_CURVE_SECP521R1:
382 return( MBEDTLS_ECP_DP_SECP521R1 );
383 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
384 return( MBEDTLS_ECP_DP_BP256R1 );
385 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
386 return( MBEDTLS_ECP_DP_BP384R1 );
387 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
388 return( MBEDTLS_ECP_DP_BP512R1 );
389 case PSA_ECC_CURVE_CURVE25519:
390 return( MBEDTLS_ECP_DP_CURVE25519 );
391 case PSA_ECC_CURVE_SECP192K1:
392 return( MBEDTLS_ECP_DP_SECP192K1 );
393 case PSA_ECC_CURVE_SECP224K1:
394 return( MBEDTLS_ECP_DP_SECP224K1 );
395 case PSA_ECC_CURVE_SECP256K1:
396 return( MBEDTLS_ECP_DP_SECP256K1 );
397 case PSA_ECC_CURVE_CURVE448:
398 return( MBEDTLS_ECP_DP_CURVE448 );
399 default:
400 return( MBEDTLS_ECP_DP_NONE );
401 }
402}
403
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200404static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
405 size_t bits,
406 struct raw_data *raw )
407{
408 /* Check that the bit size is acceptable for the key type */
409 switch( type )
410 {
411 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200412 if( bits == 0 )
413 {
414 raw->bytes = 0;
415 raw->data = NULL;
416 return( PSA_SUCCESS );
417 }
418 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200419#if defined(MBEDTLS_MD_C)
420 case PSA_KEY_TYPE_HMAC:
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200421 break;
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200422#endif
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200423#if defined(MBEDTLS_AES_C)
424 case PSA_KEY_TYPE_AES:
425 if( bits != 128 && bits != 192 && bits != 256 )
426 return( PSA_ERROR_INVALID_ARGUMENT );
427 break;
428#endif
429#if defined(MBEDTLS_CAMELLIA_C)
430 case PSA_KEY_TYPE_CAMELLIA:
431 if( bits != 128 && bits != 192 && bits != 256 )
432 return( PSA_ERROR_INVALID_ARGUMENT );
433 break;
434#endif
435#if defined(MBEDTLS_DES_C)
436 case PSA_KEY_TYPE_DES:
437 if( bits != 64 && bits != 128 && bits != 192 )
438 return( PSA_ERROR_INVALID_ARGUMENT );
439 break;
440#endif
441#if defined(MBEDTLS_ARC4_C)
442 case PSA_KEY_TYPE_ARC4:
443 if( bits < 8 || bits > 2048 )
444 return( PSA_ERROR_INVALID_ARGUMENT );
445 break;
446#endif
447 default:
448 return( PSA_ERROR_NOT_SUPPORTED );
449 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200450 if( bits % 8 != 0 )
451 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200452
453 /* Allocate memory for the key */
454 raw->bytes = PSA_BITS_TO_BYTES( bits );
455 raw->data = mbedtls_calloc( 1, raw->bytes );
456 if( raw->data == NULL )
457 {
458 raw->bytes = 0;
459 return( PSA_ERROR_INSUFFICIENT_MEMORY );
460 }
461 return( PSA_SUCCESS );
462}
463
Gilles Peskine2d277862018-06-18 15:41:12 +0200464psa_status_t psa_import_key( psa_key_slot_t key,
465 psa_key_type_t type,
466 const uint8_t *data,
467 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100468{
469 key_slot_t *slot;
470
Gilles Peskine828ed142018-06-18 23:25:51 +0200471 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100472 return( PSA_ERROR_INVALID_ARGUMENT );
473 slot = &global_data.key_slots[key];
474 if( slot->type != PSA_KEY_TYPE_NONE )
475 return( PSA_ERROR_OCCUPIED_SLOT );
476
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200477 if( key_type_is_raw_bytes( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100478 {
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200479 psa_status_t status;
Gilles Peskine6d912132018-03-07 16:41:37 +0100480 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100481 if( data_length > SIZE_MAX / 8 )
482 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200483 status = prepare_raw_data_slot( type,
484 PSA_BYTES_TO_BITS( data_length ),
485 &slot->data.raw );
486 if( status != PSA_SUCCESS )
487 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200488 if( data_length != 0 )
489 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100490 }
491 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100492#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100493 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
494 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
495 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100496 {
497 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100498 mbedtls_pk_context pk;
Gilles Peskinec648d692018-06-28 08:46:13 +0200499 psa_status_t status = PSA_SUCCESS;
Gilles Peskine969ac722018-01-28 18:16:59 +0100500 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100501 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
502 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
503 else
504 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100505 if( ret != 0 )
506 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100507 switch( mbedtls_pk_get_type( &pk ) )
508 {
509#if defined(MBEDTLS_RSA_C)
510 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100511 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
512 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskineaf3baab2018-06-27 22:55:52 +0200513 {
514 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( pk );
515 size_t bits = mbedtls_rsa_get_bitlen( rsa );
516 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
Gilles Peskine1ae05142018-06-30 17:46:59 +0200517 {
518 status = PSA_ERROR_NOT_SUPPORTED;
519 break;
520 }
Gilles Peskineaf3baab2018-06-27 22:55:52 +0200521 slot->data.rsa = rsa;
522 }
Gilles Peskine969ac722018-01-28 18:16:59 +0100523 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200524 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100525 break;
526#endif /* MBEDTLS_RSA_C */
527#if defined(MBEDTLS_ECP_C)
528 case MBEDTLS_PK_ECKEY:
529 if( PSA_KEY_TYPE_IS_ECC( type ) )
530 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200531 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
532 psa_ecc_curve_t actual_curve =
533 mbedtls_ecc_group_to_psa( ecp->grp.id );
534 psa_ecc_curve_t expected_curve =
535 PSA_KEY_TYPE_GET_CURVE( type );
536 if( actual_curve != expected_curve )
Gilles Peskinec648d692018-06-28 08:46:13 +0200537 {
538 status = PSA_ERROR_INVALID_ARGUMENT;
539 break;
540 }
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200541 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100542 }
543 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200544 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100545 break;
546#endif /* MBEDTLS_ECP_C */
547 default:
Gilles Peskinec648d692018-06-28 08:46:13 +0200548 status = PSA_ERROR_INVALID_ARGUMENT;
549 break;
550 }
551 /* Free the content of the pk object only on error. On success,
552 * the content of the object has been stored in the slot. */
553 if( status != PSA_SUCCESS )
554 {
555 mbedtls_pk_free( &pk );
556 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100557 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100558 }
559 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100560#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100561 {
562 return( PSA_ERROR_NOT_SUPPORTED );
563 }
564
565 slot->type = type;
566 return( PSA_SUCCESS );
567}
568
Gilles Peskine2d277862018-06-18 15:41:12 +0200569psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100570{
571 key_slot_t *slot;
572
Gilles Peskine828ed142018-06-18 23:25:51 +0200573 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100574 return( PSA_ERROR_INVALID_ARGUMENT );
575 slot = &global_data.key_slots[key];
576 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200577 {
578 /* No key material to clean, but do zeroize the slot below to wipe
579 * metadata such as policies. */
580 }
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200581 else if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100582 {
583 mbedtls_free( slot->data.raw.data );
584 }
585 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100586#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100587 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
588 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100589 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100590 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100591 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100592 }
593 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100594#endif /* defined(MBEDTLS_RSA_C) */
595#if defined(MBEDTLS_ECP_C)
596 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
597 {
598 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100599 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100600 }
601 else
602#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100603 {
604 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100605 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100606 return( PSA_ERROR_TAMPERING_DETECTED );
607 }
608
609 mbedtls_zeroize( slot, sizeof( *slot ) );
610 return( PSA_SUCCESS );
611}
612
Gilles Peskine2d277862018-06-18 15:41:12 +0200613psa_status_t psa_get_key_information( psa_key_slot_t key,
614 psa_key_type_t *type,
615 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100616{
617 key_slot_t *slot;
618
Gilles Peskine828ed142018-06-18 23:25:51 +0200619 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100620 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100621 slot = &global_data.key_slots[key];
622 if( type != NULL )
623 *type = slot->type;
624 if( bits != NULL )
625 *bits = 0;
626 if( slot->type == PSA_KEY_TYPE_NONE )
627 return( PSA_ERROR_EMPTY_SLOT );
628
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200629 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100630 {
631 if( bits != NULL )
632 *bits = slot->data.raw.bytes * 8;
633 }
634 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100635#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100636 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
637 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100638 {
639 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100640 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100641 }
642 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100643#endif /* defined(MBEDTLS_RSA_C) */
644#if defined(MBEDTLS_ECP_C)
645 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
646 {
647 if( bits != NULL )
648 *bits = slot->data.ecp->grp.pbits;
649 }
650 else
651#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100652 {
653 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100654 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100655 return( PSA_ERROR_TAMPERING_DETECTED );
656 }
657
658 return( PSA_SUCCESS );
659}
660
Gilles Peskine2d277862018-06-18 15:41:12 +0200661static psa_status_t psa_internal_export_key( psa_key_slot_t key,
662 uint8_t *data,
663 size_t data_size,
664 size_t *data_length,
665 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100666{
667 key_slot_t *slot;
668
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100669 /* Set the key to empty now, so that even when there are errors, we always
670 * set data_length to a value between 0 and data_size. On error, setting
671 * the key to empty is a good choice because an empty key representation is
672 * unlikely to be accepted anywhere. */
673 *data_length = 0;
674
Gilles Peskine828ed142018-06-18 23:25:51 +0200675 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100676 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100677 slot = &global_data.key_slots[key];
678 if( slot->type == PSA_KEY_TYPE_NONE )
679 return( PSA_ERROR_EMPTY_SLOT );
680
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200681 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300682 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300683
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200684 if( ! export_public_key &&
685 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
686 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300687 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200688
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200689 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100690 {
691 if( slot->data.raw.bytes > data_size )
692 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200693 if( slot->data.raw.bytes != 0 )
694 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100695 *data_length = slot->data.raw.bytes;
696 return( PSA_SUCCESS );
697 }
698 else
Moran Peker17e36e12018-05-02 12:55:20 +0300699 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100700#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100701 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300702 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
703 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100704 {
Moran Pekera998bc62018-04-16 18:16:20 +0300705 mbedtls_pk_context pk;
706 int ret;
707 mbedtls_pk_init( &pk );
708 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
709 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
710 {
711 pk.pk_info = &mbedtls_rsa_info;
712 pk.pk_ctx = slot->data.rsa;
713 }
714 else
715 {
716 pk.pk_info = &mbedtls_eckey_info;
717 pk.pk_ctx = slot->data.ecp;
718 }
Moran Pekerd7326592018-05-29 16:56:39 +0300719 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300720 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300721 else
722 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300723 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200724 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200725 /* If data_size is 0 then data may be NULL and then the
726 * call to memset would have undefined behavior. */
727 if( data_size != 0 )
728 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300729 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200730 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200731 /* The mbedtls_pk_xxx functions write to the end of the buffer.
732 * Move the data to the beginning and erase remaining data
733 * at the original location. */
734 if( 2 * (size_t) ret <= data_size )
735 {
736 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200737 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200738 }
739 else if( (size_t) ret < data_size )
740 {
741 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200742 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200743 }
Moran Pekera998bc62018-04-16 18:16:20 +0300744 *data_length = ret;
745 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100746 }
747 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100748#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300749 {
750 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200751 it is valid for a special-purpose implementation to omit
752 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300753 return( PSA_ERROR_NOT_SUPPORTED );
754 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100755 }
756}
757
Gilles Peskine2d277862018-06-18 15:41:12 +0200758psa_status_t psa_export_key( psa_key_slot_t key,
759 uint8_t *data,
760 size_t data_size,
761 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300762{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200763 return( psa_internal_export_key( key, data, data_size,
764 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100765}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100766
Gilles Peskine2d277862018-06-18 15:41:12 +0200767psa_status_t psa_export_public_key( psa_key_slot_t key,
768 uint8_t *data,
769 size_t data_size,
770 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300771{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200772 return( psa_internal_export_key( key, data, data_size,
773 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300774}
775
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200776
777
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100778/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100779/* Message digests */
780/****************************************************************/
781
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100782static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100783{
784 switch( alg )
785 {
786#if defined(MBEDTLS_MD2_C)
787 case PSA_ALG_MD2:
788 return( &mbedtls_md2_info );
789#endif
790#if defined(MBEDTLS_MD4_C)
791 case PSA_ALG_MD4:
792 return( &mbedtls_md4_info );
793#endif
794#if defined(MBEDTLS_MD5_C)
795 case PSA_ALG_MD5:
796 return( &mbedtls_md5_info );
797#endif
798#if defined(MBEDTLS_RIPEMD160_C)
799 case PSA_ALG_RIPEMD160:
800 return( &mbedtls_ripemd160_info );
801#endif
802#if defined(MBEDTLS_SHA1_C)
803 case PSA_ALG_SHA_1:
804 return( &mbedtls_sha1_info );
805#endif
806#if defined(MBEDTLS_SHA256_C)
807 case PSA_ALG_SHA_224:
808 return( &mbedtls_sha224_info );
809 case PSA_ALG_SHA_256:
810 return( &mbedtls_sha256_info );
811#endif
812#if defined(MBEDTLS_SHA512_C)
813 case PSA_ALG_SHA_384:
814 return( &mbedtls_sha384_info );
815 case PSA_ALG_SHA_512:
816 return( &mbedtls_sha512_info );
817#endif
818 default:
819 return( NULL );
820 }
821}
822
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100823psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
824{
825 switch( operation->alg )
826 {
Gilles Peskine81736312018-06-26 15:04:31 +0200827 case 0:
828 /* The object has (apparently) been initialized but it is not
829 * in use. It's ok to call abort on such an object, and there's
830 * nothing to do. */
831 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100832#if defined(MBEDTLS_MD2_C)
833 case PSA_ALG_MD2:
834 mbedtls_md2_free( &operation->ctx.md2 );
835 break;
836#endif
837#if defined(MBEDTLS_MD4_C)
838 case PSA_ALG_MD4:
839 mbedtls_md4_free( &operation->ctx.md4 );
840 break;
841#endif
842#if defined(MBEDTLS_MD5_C)
843 case PSA_ALG_MD5:
844 mbedtls_md5_free( &operation->ctx.md5 );
845 break;
846#endif
847#if defined(MBEDTLS_RIPEMD160_C)
848 case PSA_ALG_RIPEMD160:
849 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
850 break;
851#endif
852#if defined(MBEDTLS_SHA1_C)
853 case PSA_ALG_SHA_1:
854 mbedtls_sha1_free( &operation->ctx.sha1 );
855 break;
856#endif
857#if defined(MBEDTLS_SHA256_C)
858 case PSA_ALG_SHA_224:
859 case PSA_ALG_SHA_256:
860 mbedtls_sha256_free( &operation->ctx.sha256 );
861 break;
862#endif
863#if defined(MBEDTLS_SHA512_C)
864 case PSA_ALG_SHA_384:
865 case PSA_ALG_SHA_512:
866 mbedtls_sha512_free( &operation->ctx.sha512 );
867 break;
868#endif
869 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +0200870 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100871 }
872 operation->alg = 0;
873 return( PSA_SUCCESS );
874}
875
876psa_status_t psa_hash_start( psa_hash_operation_t *operation,
877 psa_algorithm_t alg )
878{
879 int ret;
880 operation->alg = 0;
881 switch( alg )
882 {
883#if defined(MBEDTLS_MD2_C)
884 case PSA_ALG_MD2:
885 mbedtls_md2_init( &operation->ctx.md2 );
886 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
887 break;
888#endif
889#if defined(MBEDTLS_MD4_C)
890 case PSA_ALG_MD4:
891 mbedtls_md4_init( &operation->ctx.md4 );
892 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
893 break;
894#endif
895#if defined(MBEDTLS_MD5_C)
896 case PSA_ALG_MD5:
897 mbedtls_md5_init( &operation->ctx.md5 );
898 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
899 break;
900#endif
901#if defined(MBEDTLS_RIPEMD160_C)
902 case PSA_ALG_RIPEMD160:
903 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
904 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
905 break;
906#endif
907#if defined(MBEDTLS_SHA1_C)
908 case PSA_ALG_SHA_1:
909 mbedtls_sha1_init( &operation->ctx.sha1 );
910 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
911 break;
912#endif
913#if defined(MBEDTLS_SHA256_C)
914 case PSA_ALG_SHA_224:
915 mbedtls_sha256_init( &operation->ctx.sha256 );
916 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
917 break;
918 case PSA_ALG_SHA_256:
919 mbedtls_sha256_init( &operation->ctx.sha256 );
920 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
921 break;
922#endif
923#if defined(MBEDTLS_SHA512_C)
924 case PSA_ALG_SHA_384:
925 mbedtls_sha512_init( &operation->ctx.sha512 );
926 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
927 break;
928 case PSA_ALG_SHA_512:
929 mbedtls_sha512_init( &operation->ctx.sha512 );
930 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
931 break;
932#endif
933 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +0200934 return( PSA_ALG_IS_HASH( alg ) ?
935 PSA_ERROR_NOT_SUPPORTED :
936 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100937 }
938 if( ret == 0 )
939 operation->alg = alg;
940 else
941 psa_hash_abort( operation );
942 return( mbedtls_to_psa_error( ret ) );
943}
944
945psa_status_t psa_hash_update( psa_hash_operation_t *operation,
946 const uint8_t *input,
947 size_t input_length )
948{
949 int ret;
950 switch( operation->alg )
951 {
952#if defined(MBEDTLS_MD2_C)
953 case PSA_ALG_MD2:
954 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
955 input, input_length );
956 break;
957#endif
958#if defined(MBEDTLS_MD4_C)
959 case PSA_ALG_MD4:
960 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
961 input, input_length );
962 break;
963#endif
964#if defined(MBEDTLS_MD5_C)
965 case PSA_ALG_MD5:
966 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
967 input, input_length );
968 break;
969#endif
970#if defined(MBEDTLS_RIPEMD160_C)
971 case PSA_ALG_RIPEMD160:
972 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
973 input, input_length );
974 break;
975#endif
976#if defined(MBEDTLS_SHA1_C)
977 case PSA_ALG_SHA_1:
978 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
979 input, input_length );
980 break;
981#endif
982#if defined(MBEDTLS_SHA256_C)
983 case PSA_ALG_SHA_224:
984 case PSA_ALG_SHA_256:
985 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
986 input, input_length );
987 break;
988#endif
989#if defined(MBEDTLS_SHA512_C)
990 case PSA_ALG_SHA_384:
991 case PSA_ALG_SHA_512:
992 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
993 input, input_length );
994 break;
995#endif
996 default:
997 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
998 break;
999 }
1000 if( ret != 0 )
1001 psa_hash_abort( operation );
1002 return( mbedtls_to_psa_error( ret ) );
1003}
1004
1005psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1006 uint8_t *hash,
1007 size_t hash_size,
1008 size_t *hash_length )
1009{
1010 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001011 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001012
1013 /* Fill the output buffer with something that isn't a valid hash
1014 * (barring an attack on the hash and deliberately-crafted input),
1015 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001016 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001017 /* If hash_size is 0 then hash may be NULL and then the
1018 * call to memset would have undefined behavior. */
1019 if( hash_size != 0 )
1020 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001021
1022 if( hash_size < actual_hash_length )
1023 return( PSA_ERROR_BUFFER_TOO_SMALL );
1024
1025 switch( operation->alg )
1026 {
1027#if defined(MBEDTLS_MD2_C)
1028 case PSA_ALG_MD2:
1029 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1030 break;
1031#endif
1032#if defined(MBEDTLS_MD4_C)
1033 case PSA_ALG_MD4:
1034 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1035 break;
1036#endif
1037#if defined(MBEDTLS_MD5_C)
1038 case PSA_ALG_MD5:
1039 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1040 break;
1041#endif
1042#if defined(MBEDTLS_RIPEMD160_C)
1043 case PSA_ALG_RIPEMD160:
1044 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1045 break;
1046#endif
1047#if defined(MBEDTLS_SHA1_C)
1048 case PSA_ALG_SHA_1:
1049 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1050 break;
1051#endif
1052#if defined(MBEDTLS_SHA256_C)
1053 case PSA_ALG_SHA_224:
1054 case PSA_ALG_SHA_256:
1055 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1056 break;
1057#endif
1058#if defined(MBEDTLS_SHA512_C)
1059 case PSA_ALG_SHA_384:
1060 case PSA_ALG_SHA_512:
1061 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1062 break;
1063#endif
1064 default:
1065 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1066 break;
1067 }
1068
1069 if( ret == 0 )
1070 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001071 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001072 return( psa_hash_abort( operation ) );
1073 }
1074 else
1075 {
1076 psa_hash_abort( operation );
1077 return( mbedtls_to_psa_error( ret ) );
1078 }
1079}
1080
Gilles Peskine2d277862018-06-18 15:41:12 +02001081psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1082 const uint8_t *hash,
1083 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001084{
1085 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1086 size_t actual_hash_length;
1087 psa_status_t status = psa_hash_finish( operation,
1088 actual_hash, sizeof( actual_hash ),
1089 &actual_hash_length );
1090 if( status != PSA_SUCCESS )
1091 return( status );
1092 if( actual_hash_length != hash_length )
1093 return( PSA_ERROR_INVALID_SIGNATURE );
1094 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1095 return( PSA_ERROR_INVALID_SIGNATURE );
1096 return( PSA_SUCCESS );
1097}
1098
1099
1100
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001101/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001102/* MAC */
1103/****************************************************************/
1104
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001105static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001106 psa_algorithm_t alg,
1107 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001108 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001109 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001110{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001111 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001112 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001113
1114 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1115 {
1116 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001117 {
1118 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1119 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001120
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001121 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001122 {
1123 case PSA_ALG_STREAM_CIPHER:
1124 mode = MBEDTLS_MODE_STREAM;
1125 break;
1126 case PSA_ALG_CBC_BASE:
1127 mode = MBEDTLS_MODE_CBC;
1128 break;
1129 case PSA_ALG_CFB_BASE:
1130 mode = MBEDTLS_MODE_CFB;
1131 break;
1132 case PSA_ALG_OFB_BASE:
1133 mode = MBEDTLS_MODE_OFB;
1134 break;
1135 case PSA_ALG_CTR:
1136 mode = MBEDTLS_MODE_CTR;
1137 break;
1138 case PSA_ALG_CCM:
1139 mode = MBEDTLS_MODE_CCM;
1140 break;
1141 case PSA_ALG_GCM:
1142 mode = MBEDTLS_MODE_GCM;
1143 break;
1144 default:
1145 return( NULL );
1146 }
1147 }
1148 else if( alg == PSA_ALG_CMAC )
1149 mode = MBEDTLS_MODE_ECB;
1150 else if( alg == PSA_ALG_GMAC )
1151 mode = MBEDTLS_MODE_GCM;
1152 else
1153 return( NULL );
1154
1155 switch( key_type )
1156 {
1157 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001158 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001159 break;
1160 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001161 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1162 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001163 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001164 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001165 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001166 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001167 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1168 * but two-key Triple-DES is functionally three-key Triple-DES
1169 * with K1=K3, so that's how we present it to mbedtls. */
1170 if( key_bits == 128 )
1171 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001172 break;
1173 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001174 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001175 break;
1176 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001177 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001178 break;
1179 default:
1180 return( NULL );
1181 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001182 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001183 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001184
Jaeden Amero23bbb752018-06-26 14:16:54 +01001185 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1186 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001187}
1188
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001189static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001190{
Gilles Peskine2d277862018-06-18 15:41:12 +02001191 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001192 {
1193 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001194 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001195 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001196 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001197 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001198 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001199 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001200 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001201 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001202 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001203 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001204 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001205 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001206 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001207 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001208 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001209 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001210 return( 128 );
1211 default:
1212 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001213 }
1214}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001215
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001216/* Initialize the MAC operation structure. Once this function has been
1217 * called, psa_mac_abort can run and will do the right thing. */
1218static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1219 psa_algorithm_t alg )
1220{
1221 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1222
1223 operation->alg = alg;
1224 operation->key_set = 0;
1225 operation->iv_set = 0;
1226 operation->iv_required = 0;
1227 operation->has_input = 0;
1228 operation->key_usage_sign = 0;
1229 operation->key_usage_verify = 0;
1230
1231#if defined(MBEDTLS_CMAC_C)
1232 if( alg == PSA_ALG_CMAC )
1233 {
1234 operation->iv_required = 0;
1235 mbedtls_cipher_init( &operation->ctx.cmac );
1236 status = PSA_SUCCESS;
1237 }
1238 else
1239#endif /* MBEDTLS_CMAC_C */
1240#if defined(MBEDTLS_MD_C)
1241 if( PSA_ALG_IS_HMAC( operation->alg ) )
1242 {
1243 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1244 PSA_ALG_HMAC_HASH( alg ) );
1245 }
1246 else
1247#endif /* MBEDTLS_MD_C */
1248 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001249 if( ! PSA_ALG_IS_MAC( alg ) )
1250 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001251 }
1252
1253 if( status != PSA_SUCCESS )
1254 memset( operation, 0, sizeof( *operation ) );
1255 return( status );
1256}
1257
Gilles Peskine8c9def32018-02-08 10:02:12 +01001258psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1259{
1260 switch( operation->alg )
1261 {
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001262 case 0:
Gilles Peskine81736312018-06-26 15:04:31 +02001263 /* The object has (apparently) been initialized but it is not
1264 * in use. It's ok to call abort on such an object, and there's
1265 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001266 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001267#if defined(MBEDTLS_CMAC_C)
1268 case PSA_ALG_CMAC:
1269 mbedtls_cipher_free( &operation->ctx.cmac );
1270 break;
1271#endif /* MBEDTLS_CMAC_C */
1272 default:
1273#if defined(MBEDTLS_MD_C)
1274 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001275 {
Jaeden Amero5390f692018-06-26 14:18:50 +01001276 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001277 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001278
Gilles Peskine99bc6492018-06-11 17:13:00 +02001279 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001280 return( PSA_ERROR_NOT_SUPPORTED );
1281
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001282 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001283 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001284 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001285 else
1286#endif /* MBEDTLS_MD_C */
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001287 {
1288 /* Sanity check (shouldn't happen: operation->alg should
1289 * always have been initialized to a valid value). */
1290 return( PSA_ERROR_BAD_STATE );
1291 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001292 }
Moran Peker41deec42018-04-04 15:43:05 +03001293
Gilles Peskine8c9def32018-02-08 10:02:12 +01001294 operation->alg = 0;
1295 operation->key_set = 0;
1296 operation->iv_set = 0;
1297 operation->iv_required = 0;
1298 operation->has_input = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001299 operation->key_usage_sign = 0;
1300 operation->key_usage_verify = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001301
Gilles Peskine8c9def32018-02-08 10:02:12 +01001302 return( PSA_SUCCESS );
1303}
1304
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001305#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001306static int psa_cmac_start( psa_mac_operation_t *operation,
1307 size_t key_bits,
1308 key_slot_t *slot,
1309 const mbedtls_cipher_info_t *cipher_info )
1310{
1311 int ret;
1312
1313 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001314
1315 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1316 if( ret != 0 )
1317 return( ret );
1318
1319 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1320 slot->data.raw.data,
1321 key_bits );
1322 return( ret );
1323}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001324#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001325
Gilles Peskine248051a2018-06-20 16:09:38 +02001326#if defined(MBEDTLS_MD_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001327static int psa_hmac_start( psa_mac_operation_t *operation,
1328 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001329 key_slot_t *slot,
1330 psa_algorithm_t alg )
1331{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001332 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001333 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001334 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001335 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001336 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001337 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001338 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001339 size_t key_length = slot->data.raw.bytes;
1340 psa_status_t status;
1341
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001342 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001343 return( PSA_ERROR_NOT_SUPPORTED );
1344
1345 if( key_type != PSA_KEY_TYPE_HMAC )
1346 return( PSA_ERROR_INVALID_ARGUMENT );
1347
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001348 operation->mac_size = digest_size;
1349
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001350 /* The hash was started earlier in psa_mac_init. */
Gilles Peskined223b522018-06-11 18:12:58 +02001351 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001352 {
1353 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001354 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001355 if( status != PSA_SUCCESS )
1356 return( status );
1357 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001358 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001359 if( status != PSA_SUCCESS )
1360 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001361 }
Gilles Peskined223b522018-06-11 18:12:58 +02001362 else
1363 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001364
Gilles Peskined223b522018-06-11 18:12:58 +02001365 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1366 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001367 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001368 ipad[i] ^= 0x36;
1369 memset( ipad + key_length, 0x36, block_size - key_length );
1370
1371 /* Copy the key material from ipad to opad, flipping the requisite bits,
1372 * and filling the rest of opad with the requisite constant. */
1373 for( i = 0; i < key_length; i++ )
1374 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1375 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001376
1377 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1378 PSA_ALG_HMAC_HASH( alg ) );
1379 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001380 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001381
1382 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1383 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001384
1385cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001386 mbedtls_zeroize( ipad, key_length );
1387 /* opad is in the context. It needs to stay in memory if this function
1388 * succeeds, and it will be wiped by psa_mac_abort() called from
1389 * psa_mac_start in the error case. */
1390
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001391 return( status );
1392}
Gilles Peskine248051a2018-06-20 16:09:38 +02001393#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001394
Gilles Peskine8c9def32018-02-08 10:02:12 +01001395psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1396 psa_key_slot_t key,
1397 psa_algorithm_t alg )
1398{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001399 psa_status_t status;
1400 key_slot_t *slot;
1401 psa_key_type_t key_type;
1402 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001403 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001404
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001405 status = psa_mac_init( operation, alg );
1406 if( status != PSA_SUCCESS )
1407 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001408
1409 status = psa_get_key_information( key, &key_type, &key_bits );
1410 if( status != PSA_SUCCESS )
1411 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001412
Gilles Peskine8c9def32018-02-08 10:02:12 +01001413 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001414 if( slot->type == PSA_KEY_TYPE_NONE )
1415 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001416
Moran Pekerd7326592018-05-29 16:56:39 +03001417 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001418 operation->key_usage_sign = 1;
1419
Moran Pekerd7326592018-05-29 16:56:39 +03001420 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001421 operation->key_usage_verify = 1;
1422
Gilles Peskine8c9def32018-02-08 10:02:12 +01001423 if( ! PSA_ALG_IS_HMAC( alg ) )
1424 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001425 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001426 if( cipher_info == NULL )
1427 return( PSA_ERROR_NOT_SUPPORTED );
1428 operation->mac_size = cipher_info->block_size;
1429 }
1430 switch( alg )
1431 {
1432#if defined(MBEDTLS_CMAC_C)
1433 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001434 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1435 key_bits,
1436 slot,
1437 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001438 break;
1439#endif /* MBEDTLS_CMAC_C */
1440 default:
1441#if defined(MBEDTLS_MD_C)
1442 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001443 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001444 else
1445#endif /* MBEDTLS_MD_C */
1446 return( PSA_ERROR_NOT_SUPPORTED );
1447 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001448
Gilles Peskine8c9def32018-02-08 10:02:12 +01001449 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001450 * context may contain data that needs to be wiped on error. */
1451 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001452 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001453 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001454 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001455 else
1456 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001457 operation->key_set = 1;
1458 }
1459 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001460}
1461
1462psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1463 const uint8_t *input,
1464 size_t input_length )
1465{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001466 int ret = 0 ;
1467 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001468 if( ! operation->key_set )
1469 return( PSA_ERROR_BAD_STATE );
1470 if( operation->iv_required && ! operation->iv_set )
1471 return( PSA_ERROR_BAD_STATE );
1472 operation->has_input = 1;
1473
1474 switch( operation->alg )
1475 {
1476#if defined(MBEDTLS_CMAC_C)
1477 case PSA_ALG_CMAC:
1478 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1479 input, input_length );
1480 break;
1481#endif /* MBEDTLS_CMAC_C */
1482 default:
1483#if defined(MBEDTLS_MD_C)
1484 if( PSA_ALG_IS_HMAC( operation->alg ) )
1485 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001486 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001487 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001488 }
1489 else
1490#endif /* MBEDTLS_MD_C */
1491 {
1492 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1493 }
1494 break;
1495 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001496 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001497 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001498 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001499 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001500 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001501 }
1502
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001503 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001504}
1505
mohammad16036df908f2018-04-02 08:34:15 -07001506static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001507 uint8_t *mac,
1508 size_t mac_size,
1509 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001510{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001511 int ret = 0;
1512 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001513
1514 /* Fill the output buffer with something that isn't a valid mac
1515 * (barring an attack on the mac and deliberately-crafted input),
1516 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001517 *mac_length = mac_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001518 /* If mac_size is 0 then mac may be NULL and then the
1519 * call to memset would have undefined behavior. */
1520 if( mac_size != 0 )
1521 memset( mac, '!', mac_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001522
Gilles Peskine1d96fff2018-07-02 12:15:39 +02001523 if( ! operation->key_set )
1524 return( PSA_ERROR_BAD_STATE );
1525 if( operation->iv_required && ! operation->iv_set )
1526 return( PSA_ERROR_BAD_STATE );
1527
Gilles Peskine8c9def32018-02-08 10:02:12 +01001528 if( mac_size < operation->mac_size )
1529 return( PSA_ERROR_BUFFER_TOO_SMALL );
1530
1531 switch( operation->alg )
1532 {
1533#if defined(MBEDTLS_CMAC_C)
1534 case PSA_ALG_CMAC:
1535 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1536 break;
1537#endif /* MBEDTLS_CMAC_C */
1538 default:
1539#if defined(MBEDTLS_MD_C)
1540 if( PSA_ALG_IS_HMAC( operation->alg ) )
1541 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001542 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001543 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001544 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001545 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001546 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001547
Gilles Peskine99bc6492018-06-11 17:13:00 +02001548 if( block_size == 0 )
1549 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001550
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001551 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001552 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001553 if( status != PSA_SUCCESS )
1554 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001555 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001556
1557 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1558 PSA_ALG_HMAC_HASH( operation->alg ) );
1559 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001560 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001561
1562 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001563 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001564 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001565 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001566
1567 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001568 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001569 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001570 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001571
1572 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1573 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001574 hmac_cleanup:
1575 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001576 }
1577 else
1578#endif /* MBEDTLS_MD_C */
1579 {
1580 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1581 }
1582 break;
1583 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001584cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001585
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001586 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001587 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001588 *mac_length = operation->mac_size;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001589 return( psa_mac_abort( operation ) );
1590 }
1591 else
1592 {
1593 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001594 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001595 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001596
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001597 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001598 }
1599}
1600
mohammad16036df908f2018-04-02 08:34:15 -07001601psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1602 uint8_t *mac,
1603 size_t mac_size,
1604 size_t *mac_length )
1605{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001606 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001607 return( PSA_ERROR_NOT_PERMITTED );
1608
Gilles Peskine99bc6492018-06-11 17:13:00 +02001609 return( psa_mac_finish_internal( operation, mac,
1610 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001611}
1612
Gilles Peskine8c9def32018-02-08 10:02:12 +01001613psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1614 const uint8_t *mac,
1615 size_t mac_length )
1616{
Gilles Peskine828ed142018-06-18 23:25:51 +02001617 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001618 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001619 psa_status_t status;
1620
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001621 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001622 return( PSA_ERROR_NOT_PERMITTED );
1623
1624 status = psa_mac_finish_internal( operation,
1625 actual_mac, sizeof( actual_mac ),
1626 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001627 if( status != PSA_SUCCESS )
1628 return( status );
1629 if( actual_mac_length != mac_length )
1630 return( PSA_ERROR_INVALID_SIGNATURE );
1631 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1632 return( PSA_ERROR_INVALID_SIGNATURE );
1633 return( PSA_SUCCESS );
1634}
1635
1636
Gilles Peskine20035e32018-02-03 22:44:14 +01001637
Gilles Peskine20035e32018-02-03 22:44:14 +01001638/****************************************************************/
1639/* Asymmetric cryptography */
1640/****************************************************************/
1641
Gilles Peskine2b450e32018-06-27 15:42:46 +02001642#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001643/* Decode the hash algorithm from alg and store the mbedtls encoding in
1644 * md_alg. Verify that the hash length is consistent. */
1645static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1646 size_t hash_length,
1647 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001648{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02001649 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001650 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1651 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1652 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001653 {
1654#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001655 if( hash_length > UINT_MAX )
1656 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001657#endif
1658 }
1659 else
1660 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001661 if( mbedtls_md_get_size( md_info ) != hash_length )
1662 return( PSA_ERROR_INVALID_ARGUMENT );
1663 if( md_info == NULL )
1664 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001665 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001666 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001667}
1668
Gilles Peskine2b450e32018-06-27 15:42:46 +02001669static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
1670 psa_algorithm_t alg,
1671 const uint8_t *hash,
1672 size_t hash_length,
1673 uint8_t *signature,
1674 size_t signature_size,
1675 size_t *signature_length )
1676{
1677 psa_status_t status;
1678 int ret;
1679 mbedtls_md_type_t md_alg;
1680
1681 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1682 if( status != PSA_SUCCESS )
1683 return( status );
1684
1685 if( signature_size < rsa->len )
1686 return( PSA_ERROR_BUFFER_TOO_SMALL );
1687
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001688 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1689 * hash_length will fit and return an error if it doesn't. */
1690#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1691#if SIZE_MAX > UINT_MAX
1692 if( hash_length > UINT_MAX )
1693 return( PSA_ERROR_NOT_SUPPORTED );
1694#endif
1695#endif
1696
Gilles Peskine2b450e32018-06-27 15:42:46 +02001697#if defined(MBEDTLS_PKCS1_V15)
1698 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1699 {
1700 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1701 MBEDTLS_MD_NONE );
1702 ret = mbedtls_rsa_pkcs1_sign( rsa,
1703 mbedtls_ctr_drbg_random,
1704 &global_data.ctr_drbg,
1705 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001706 md_alg,
1707 (unsigned int) hash_length,
1708 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001709 signature );
1710 }
1711 else
1712#endif /* MBEDTLS_PKCS1_V15 */
1713#if defined(MBEDTLS_PKCS1_V21)
1714 if( PSA_ALG_IS_RSA_PSS( alg ) )
1715 {
1716 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1717 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1718 mbedtls_ctr_drbg_random,
1719 &global_data.ctr_drbg,
1720 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001721 md_alg,
1722 (unsigned int) hash_length,
1723 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001724 signature );
1725 }
1726 else
1727#endif /* MBEDTLS_PKCS1_V21 */
1728 {
1729 return( PSA_ERROR_INVALID_ARGUMENT );
1730 }
1731
1732 if( ret == 0 )
1733 *signature_length = rsa->len;
1734 return( mbedtls_to_psa_error( ret ) );
1735}
1736
1737static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
1738 psa_algorithm_t alg,
1739 const uint8_t *hash,
1740 size_t hash_length,
1741 const uint8_t *signature,
1742 size_t signature_length )
1743{
1744 psa_status_t status;
1745 int ret;
1746 mbedtls_md_type_t md_alg;
1747
1748 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1749 if( status != PSA_SUCCESS )
1750 return( status );
1751
1752 if( signature_length < rsa->len )
1753 return( PSA_ERROR_BUFFER_TOO_SMALL );
1754
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001755#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1756#if SIZE_MAX > UINT_MAX
1757 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1758 * hash_length will fit and return an error if it doesn't. */
1759 if( hash_length > UINT_MAX )
1760 return( PSA_ERROR_NOT_SUPPORTED );
1761#endif
1762#endif
1763
Gilles Peskine2b450e32018-06-27 15:42:46 +02001764#if defined(MBEDTLS_PKCS1_V15)
1765 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1766 {
1767 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1768 MBEDTLS_MD_NONE );
1769 ret = mbedtls_rsa_pkcs1_verify( rsa,
1770 mbedtls_ctr_drbg_random,
1771 &global_data.ctr_drbg,
1772 MBEDTLS_RSA_PUBLIC,
1773 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001774 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001775 hash,
1776 signature );
1777 }
1778 else
1779#endif /* MBEDTLS_PKCS1_V15 */
1780#if defined(MBEDTLS_PKCS1_V21)
1781 if( PSA_ALG_IS_RSA_PSS( alg ) )
1782 {
1783 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1784 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1785 mbedtls_ctr_drbg_random,
1786 &global_data.ctr_drbg,
1787 MBEDTLS_RSA_PUBLIC,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001788 md_alg,
1789 (unsigned int) hash_length,
1790 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001791 signature );
1792 }
1793 else
1794#endif /* MBEDTLS_PKCS1_V21 */
1795 {
1796 return( PSA_ERROR_INVALID_ARGUMENT );
1797 }
1798 return( mbedtls_to_psa_error( ret ) );
1799}
1800#endif /* MBEDTLS_RSA_C */
1801
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001802#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001803/* `ecp` cannot be const because `ecp->grp` needs to be non-const
1804 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
1805 * (even though these functions don't modify it). */
1806static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
1807 psa_algorithm_t alg,
1808 const uint8_t *hash,
1809 size_t hash_length,
1810 uint8_t *signature,
1811 size_t signature_size,
1812 size_t *signature_length )
1813{
1814 int ret;
1815 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001816 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001817 mbedtls_mpi_init( &r );
1818 mbedtls_mpi_init( &s );
1819
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001820 if( signature_size < 2 * curve_bytes )
1821 {
1822 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
1823 goto cleanup;
1824 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001825
1826 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
1827 {
1828 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
1829 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1830 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
1831 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
1832 hash, hash_length,
1833 md_alg ) );
1834 }
1835 else
1836 {
1837 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
1838 hash, hash_length,
1839 mbedtls_ctr_drbg_random,
1840 &global_data.ctr_drbg ) );
1841 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001842
1843 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
1844 signature,
1845 curve_bytes ) );
1846 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
1847 signature + curve_bytes,
1848 curve_bytes ) );
1849
1850cleanup:
1851 mbedtls_mpi_free( &r );
1852 mbedtls_mpi_free( &s );
1853 if( ret == 0 )
1854 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001855 return( mbedtls_to_psa_error( ret ) );
1856}
1857
1858static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
1859 const uint8_t *hash,
1860 size_t hash_length,
1861 const uint8_t *signature,
1862 size_t signature_length )
1863{
1864 int ret;
1865 mbedtls_mpi r, s;
1866 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
1867 mbedtls_mpi_init( &r );
1868 mbedtls_mpi_init( &s );
1869
1870 if( signature_length != 2 * curve_bytes )
1871 return( PSA_ERROR_INVALID_SIGNATURE );
1872
1873 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
1874 signature,
1875 curve_bytes ) );
1876 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
1877 signature + curve_bytes,
1878 curve_bytes ) );
1879
1880 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
1881 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001882
1883cleanup:
1884 mbedtls_mpi_free( &r );
1885 mbedtls_mpi_free( &s );
1886 return( mbedtls_to_psa_error( ret ) );
1887}
1888#endif /* MBEDTLS_ECDSA_C */
1889
Gilles Peskine61b91d42018-06-08 16:09:36 +02001890psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1891 psa_algorithm_t alg,
1892 const uint8_t *hash,
1893 size_t hash_length,
1894 const uint8_t *salt,
1895 size_t salt_length,
1896 uint8_t *signature,
1897 size_t signature_size,
1898 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001899{
1900 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001901 psa_status_t status;
1902
1903 *signature_length = signature_size;
1904
Gilles Peskine93aa0332018-02-03 23:58:03 +01001905 (void) salt;
1906 (void) salt_length;
1907
Gilles Peskine828ed142018-06-18 23:25:51 +02001908 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001909 {
1910 status = PSA_ERROR_EMPTY_SLOT;
1911 goto exit;
1912 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001913 slot = &global_data.key_slots[key];
1914 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001915 {
1916 status = PSA_ERROR_EMPTY_SLOT;
1917 goto exit;
1918 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001919 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001920 {
1921 status = PSA_ERROR_INVALID_ARGUMENT;
1922 goto exit;
1923 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001924 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001925 {
1926 status = PSA_ERROR_NOT_PERMITTED;
1927 goto exit;
1928 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001929
Gilles Peskine20035e32018-02-03 22:44:14 +01001930#if defined(MBEDTLS_RSA_C)
1931 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1932 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001933 status = psa_rsa_sign( slot->data.rsa,
1934 alg,
1935 hash, hash_length,
1936 signature, signature_size,
1937 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01001938 }
1939 else
1940#endif /* defined(MBEDTLS_RSA_C) */
1941#if defined(MBEDTLS_ECP_C)
1942 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1943 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001944#if defined(MBEDTLS_ECDSA_C)
1945 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001946 status = psa_ecdsa_sign( slot->data.ecp,
1947 alg,
1948 hash, hash_length,
1949 signature, signature_size,
1950 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001951 else
1952#endif /* defined(MBEDTLS_ECDSA_C) */
1953 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001954 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001955 }
itayzafrir5c753392018-05-08 11:18:38 +03001956 }
1957 else
1958#endif /* defined(MBEDTLS_ECP_C) */
1959 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001960 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01001961 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001962
1963exit:
1964 /* Fill the unused part of the output buffer (the whole buffer on error,
1965 * the trailing part on success) with something that isn't a valid mac
1966 * (barring an attack on the mac and deliberately-crafted input),
1967 * in case the caller doesn't check the return status properly. */
1968 if( status == PSA_SUCCESS )
1969 memset( signature + *signature_length, '!',
1970 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001971 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001972 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001973 /* If signature_size is 0 then we have nothing to do. We must not call
1974 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001975 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03001976}
1977
1978psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1979 psa_algorithm_t alg,
1980 const uint8_t *hash,
1981 size_t hash_length,
1982 const uint8_t *salt,
1983 size_t salt_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02001984 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02001985 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03001986{
1987 key_slot_t *slot;
Gilles Peskine2b450e32018-06-27 15:42:46 +02001988
itayzafrir5c753392018-05-08 11:18:38 +03001989 (void) salt;
1990 (void) salt_length;
1991
Gilles Peskine828ed142018-06-18 23:25:51 +02001992 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001993 return( PSA_ERROR_INVALID_ARGUMENT );
1994 slot = &global_data.key_slots[key];
1995 if( slot->type == PSA_KEY_TYPE_NONE )
1996 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001997 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001998 return( PSA_ERROR_NOT_PERMITTED );
1999
Gilles Peskine61b91d42018-06-08 16:09:36 +02002000#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002001 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
2002 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002003 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002004 return( psa_rsa_verify( slot->data.rsa,
2005 alg,
2006 hash, hash_length,
2007 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002008 }
2009 else
2010#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002011#if defined(MBEDTLS_ECP_C)
2012 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2013 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002014#if defined(MBEDTLS_ECDSA_C)
2015 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002016 return( psa_ecdsa_verify( slot->data.ecp,
2017 hash, hash_length,
2018 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002019 else
2020#endif /* defined(MBEDTLS_ECDSA_C) */
2021 {
2022 return( PSA_ERROR_INVALID_ARGUMENT );
2023 }
itayzafrir5c753392018-05-08 11:18:38 +03002024 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002025 else
2026#endif /* defined(MBEDTLS_ECP_C) */
2027 {
2028 return( PSA_ERROR_NOT_SUPPORTED );
2029 }
2030}
2031
Gilles Peskine61b91d42018-06-08 16:09:36 +02002032psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2033 psa_algorithm_t alg,
2034 const uint8_t *input,
2035 size_t input_length,
2036 const uint8_t *salt,
2037 size_t salt_length,
2038 uint8_t *output,
2039 size_t output_size,
2040 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002041{
2042 key_slot_t *slot;
2043 (void) salt;
2044 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002045 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002046
Gilles Peskine828ed142018-06-18 23:25:51 +02002047 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03002048 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002049 slot = &global_data.key_slots[key];
2050 if( slot->type == PSA_KEY_TYPE_NONE )
2051 return( PSA_ERROR_EMPTY_SLOT );
2052 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2053 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002054 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
2055 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002056
2057#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002058 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
2059 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002060 {
2061 mbedtls_rsa_context *rsa = slot->data.rsa;
2062 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002063 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002064 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002065#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002066 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002067 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002068 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2069 mbedtls_ctr_drbg_random,
2070 &global_data.ctr_drbg,
2071 MBEDTLS_RSA_PUBLIC,
2072 input_length,
2073 input,
2074 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002075 }
2076 else
2077#endif /* MBEDTLS_PKCS1_V15 */
2078#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002079 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002080 {
2081 return( PSA_ERROR_NOT_SUPPORTED );
2082 }
2083 else
2084#endif /* MBEDTLS_PKCS1_V21 */
2085 {
2086 return( PSA_ERROR_INVALID_ARGUMENT );
2087 }
2088 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002089 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002090 return( mbedtls_to_psa_error( ret ) );
2091 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002092 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002093#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002094 {
2095 return( PSA_ERROR_NOT_SUPPORTED );
2096 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002097}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002098
Gilles Peskine61b91d42018-06-08 16:09:36 +02002099psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2100 psa_algorithm_t alg,
2101 const uint8_t *input,
2102 size_t input_length,
2103 const uint8_t *salt,
2104 size_t salt_length,
2105 uint8_t *output,
2106 size_t output_size,
2107 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002108{
2109 key_slot_t *slot;
2110 (void) salt;
2111 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002112 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002113
Gilles Peskine828ed142018-06-18 23:25:51 +02002114 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002115 return( PSA_ERROR_EMPTY_SLOT );
2116 slot = &global_data.key_slots[key];
2117 if( slot->type == PSA_KEY_TYPE_NONE )
2118 return( PSA_ERROR_EMPTY_SLOT );
2119 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2120 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002121 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2122 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002123
2124#if defined(MBEDTLS_RSA_C)
2125 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2126 {
2127 mbedtls_rsa_context *rsa = slot->data.rsa;
2128 int ret;
2129
Gilles Peskinec4def2f2018-06-08 17:53:48 +02002130 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002131 return( PSA_ERROR_INVALID_ARGUMENT );
2132
2133#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002134 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002135 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002136 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2137 mbedtls_ctr_drbg_random,
2138 &global_data.ctr_drbg,
2139 MBEDTLS_RSA_PRIVATE,
2140 output_length,
2141 input,
2142 output,
2143 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002144 }
2145 else
2146#endif /* MBEDTLS_PKCS1_V15 */
2147#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002148 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002149 {
2150 return( PSA_ERROR_NOT_SUPPORTED );
2151 }
2152 else
2153#endif /* MBEDTLS_PKCS1_V21 */
2154 {
2155 return( PSA_ERROR_INVALID_ARGUMENT );
2156 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002157
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002158 return( mbedtls_to_psa_error( ret ) );
2159 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002160 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002161#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002162 {
2163 return( PSA_ERROR_NOT_SUPPORTED );
2164 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002165}
Gilles Peskine20035e32018-02-03 22:44:14 +01002166
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002167
2168
mohammad1603503973b2018-03-12 15:59:30 +02002169/****************************************************************/
2170/* Symmetric cryptography */
2171/****************************************************************/
2172
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002173/* Initialize the cipher operation structure. Once this function has been
2174 * called, psa_cipher_abort can run and will do the right thing. */
2175static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2176 psa_algorithm_t alg )
2177{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002178 if( ! PSA_ALG_IS_CIPHER( alg ) )
2179 {
2180 memset( operation, 0, sizeof( *operation ) );
2181 return( PSA_ERROR_INVALID_ARGUMENT );
2182 }
2183
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002184 operation->alg = alg;
2185 operation->key_set = 0;
2186 operation->iv_set = 0;
2187 operation->iv_required = 1;
2188 operation->iv_size = 0;
2189 operation->block_size = 0;
2190 mbedtls_cipher_init( &operation->ctx.cipher );
2191 return( PSA_SUCCESS );
2192}
2193
Gilles Peskinee553c652018-06-04 16:22:46 +02002194static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2195 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002196 psa_algorithm_t alg,
2197 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002198{
2199 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2200 psa_status_t status;
2201 key_slot_t *slot;
2202 psa_key_type_t key_type;
2203 size_t key_bits;
2204 const mbedtls_cipher_info_t *cipher_info = NULL;
2205
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002206 status = psa_cipher_init( operation, alg );
2207 if( status != PSA_SUCCESS )
2208 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002209
2210 status = psa_get_key_information( key, &key_type, &key_bits );
2211 if( status != PSA_SUCCESS )
2212 return( status );
2213 slot = &global_data.key_slots[key];
2214
Gilles Peskinebb1072f2018-06-08 18:46:05 +02002215 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002216 if( cipher_info == NULL )
2217 return( PSA_ERROR_NOT_SUPPORTED );
2218
mohammad1603503973b2018-03-12 15:59:30 +02002219 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002220 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002221 {
2222 psa_cipher_abort( operation );
2223 return( mbedtls_to_psa_error( ret ) );
2224 }
2225
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002226#if defined(MBEDTLS_DES_C)
2227 if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
2228 {
2229 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2230 unsigned char keys[24];
2231 memcpy( keys, slot->data.raw.data, 16 );
2232 memcpy( keys + 16, slot->data.raw.data, 8 );
2233 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2234 keys,
2235 192, cipher_operation );
2236 }
2237 else
2238#endif
2239 {
2240 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2241 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002242 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002243 }
Moran Peker41deec42018-04-04 15:43:05 +03002244 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002245 {
2246 psa_cipher_abort( operation );
2247 return( mbedtls_to_psa_error( ret ) );
2248 }
2249
mohammad16038481e742018-03-18 13:57:31 +02002250#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03002251 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02002252 {
Gilles Peskine53514202018-06-06 15:11:46 +02002253 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
2254 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02002255
Moran Pekera28258c2018-05-29 16:25:04 +03002256 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02002257 {
2258 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
2259 mode = MBEDTLS_PADDING_PKCS7;
2260 break;
2261 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
2262 mode = MBEDTLS_PADDING_NONE;
2263 break;
2264 default:
Moran Pekerae382792018-05-31 14:06:17 +03002265 psa_cipher_abort( operation );
2266 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02002267 }
2268 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03002269 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03002270 {
2271 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02002272 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03002273 }
mohammad16038481e742018-03-18 13:57:31 +02002274 }
2275#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2276
mohammad1603503973b2018-03-12 15:59:30 +02002277 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002278 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
2279 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
2280 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002281 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002282 {
mohammad160389e0f462018-04-12 08:48:45 +03002283 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02002284 }
mohammad1603503973b2018-03-12 15:59:30 +02002285
Moran Peker395db872018-05-31 14:07:14 +03002286 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002287}
2288
Gilles Peskinee553c652018-06-04 16:22:46 +02002289psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
2290 psa_key_slot_t key,
2291 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002292{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002293 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002294}
2295
Gilles Peskinee553c652018-06-04 16:22:46 +02002296psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
2297 psa_key_slot_t key,
2298 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002299{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002300 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002301}
2302
Gilles Peskinee553c652018-06-04 16:22:46 +02002303psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
2304 unsigned char *iv,
2305 size_t iv_size,
2306 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002307{
Moran Peker41deec42018-04-04 15:43:05 +03002308 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002309 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002310 return( PSA_ERROR_BAD_STATE );
2311 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002312 {
Moran Peker41deec42018-04-04 15:43:05 +03002313 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2314 goto exit;
2315 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002316 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2317 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002318 if( ret != 0 )
2319 {
2320 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002321 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002322 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002323
mohammad16038481e742018-03-18 13:57:31 +02002324 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03002325 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002326
Moran Peker395db872018-05-31 14:07:14 +03002327exit:
2328 if( ret != PSA_SUCCESS )
2329 psa_cipher_abort( operation );
2330 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002331}
2332
Gilles Peskinee553c652018-06-04 16:22:46 +02002333psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
2334 const unsigned char *iv,
2335 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002336{
Moran Peker41deec42018-04-04 15:43:05 +03002337 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002338 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002339 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002340 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002341 {
Moran Pekerae382792018-05-31 14:06:17 +03002342 psa_cipher_abort( operation );
2343 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002344 }
mohammad1603503973b2018-03-12 15:59:30 +02002345 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002346 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002347 {
2348 psa_cipher_abort( operation );
2349 return( mbedtls_to_psa_error( ret ) );
2350 }
2351
2352 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002353
Moran Peker395db872018-05-31 14:07:14 +03002354 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002355}
2356
Gilles Peskinee553c652018-06-04 16:22:46 +02002357psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2358 const uint8_t *input,
2359 size_t input_length,
2360 unsigned char *output,
2361 size_t output_size,
2362 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002363{
2364 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002365 size_t expected_output_size;
2366 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2367 {
2368 /* Take the unprocessed partial block left over from previous
2369 * update calls, if any, plus the input to this call. Remove
2370 * the last partial block, if any. You get the data that will be
2371 * output in this call. */
2372 expected_output_size =
2373 ( operation->ctx.cipher.unprocessed_len + input_length )
2374 / operation->block_size * operation->block_size;
2375 }
2376 else
2377 {
2378 expected_output_size = input_length;
2379 }
2380 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002381 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002382
mohammad1603503973b2018-03-12 15:59:30 +02002383 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002384 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002385 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002386 {
2387 psa_cipher_abort( operation );
2388 return( mbedtls_to_psa_error( ret ) );
2389 }
2390
Moran Peker395db872018-05-31 14:07:14 +03002391 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002392}
2393
Gilles Peskinee553c652018-06-04 16:22:46 +02002394psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2395 uint8_t *output,
2396 size_t output_size,
2397 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002398{
2399 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002400 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002401
mohammad1603503973b2018-03-12 15:59:30 +02002402 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002403 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002404 psa_cipher_abort( operation );
2405 return( PSA_ERROR_BAD_STATE );
2406 }
2407 if( operation->iv_required && ! operation->iv_set )
2408 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002409 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002410 return( PSA_ERROR_BAD_STATE );
2411 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002412 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2413 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002414 {
Gilles Peskine53514202018-06-06 15:11:46 +02002415 psa_algorithm_t padding_mode =
2416 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002417 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002418 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002419 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002420 return( PSA_ERROR_TAMPERING_DETECTED );
2421 }
Gilles Peskine53514202018-06-06 15:11:46 +02002422 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002423 {
2424 if( operation->ctx.cipher.unprocessed_len != 0 )
2425 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002426 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002427 return( PSA_ERROR_INVALID_ARGUMENT );
2428 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002429 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002430 }
2431
2432 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002433 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002434 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002435 {
2436 psa_cipher_abort( operation );
2437 return( mbedtls_to_psa_error( ret ) );
2438 }
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002439 if( *output_length == 0 )
2440 /* Nothing to copy. Note that output may be NULL in this case. */ ;
2441 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002442 memcpy( output, temp_output_buffer, *output_length );
2443 else
2444 {
2445 psa_cipher_abort( operation );
2446 return( PSA_ERROR_BUFFER_TOO_SMALL );
2447 }
mohammad1603503973b2018-03-12 15:59:30 +02002448
Moran Peker4c80d832018-04-22 20:15:31 +03002449 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002450}
2451
Gilles Peskinee553c652018-06-04 16:22:46 +02002452psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2453{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002454 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002455 {
2456 /* The object has (apparently) been initialized but it is not
2457 * in use. It's ok to call abort on such an object, and there's
2458 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002459 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002460 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002461
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002462 /* Sanity check (shouldn't happen: operation->alg should
2463 * always have been initialized to a valid value). */
2464 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2465 return( PSA_ERROR_BAD_STATE );
2466
mohammad1603503973b2018-03-12 15:59:30 +02002467 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002468
Moran Peker41deec42018-04-04 15:43:05 +03002469 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002470 operation->key_set = 0;
2471 operation->iv_set = 0;
2472 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002473 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002474 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002475
Moran Peker395db872018-05-31 14:07:14 +03002476 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002477}
2478
Gilles Peskinea0655c32018-04-30 17:06:50 +02002479
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002480
mohammad16038cc1cee2018-03-28 01:21:33 +03002481/****************************************************************/
2482/* Key Policy */
2483/****************************************************************/
2484
Gilles Peskine2d277862018-06-18 15:41:12 +02002485void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002486{
Gilles Peskine803ce742018-06-18 16:07:14 +02002487 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002488}
2489
Gilles Peskine2d277862018-06-18 15:41:12 +02002490void psa_key_policy_set_usage( psa_key_policy_t *policy,
2491 psa_key_usage_t usage,
2492 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002493{
mohammad16034eed7572018-03-28 05:14:59 -07002494 policy->usage = usage;
2495 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002496}
2497
Gilles Peskine2d277862018-06-18 15:41:12 +02002498psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002499{
mohammad16036df908f2018-04-02 08:34:15 -07002500 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002501}
2502
Gilles Peskine2d277862018-06-18 15:41:12 +02002503psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002504{
mohammad16036df908f2018-04-02 08:34:15 -07002505 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002506}
2507
Gilles Peskine2d277862018-06-18 15:41:12 +02002508psa_status_t psa_set_key_policy( psa_key_slot_t key,
2509 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002510{
2511 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002512
Gilles Peskine828ed142018-06-18 23:25:51 +02002513 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002514 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002515
mohammad16038cc1cee2018-03-28 01:21:33 +03002516 slot = &global_data.key_slots[key];
2517 if( slot->type != PSA_KEY_TYPE_NONE )
2518 return( PSA_ERROR_OCCUPIED_SLOT );
2519
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002520 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2521 PSA_KEY_USAGE_ENCRYPT |
2522 PSA_KEY_USAGE_DECRYPT |
2523 PSA_KEY_USAGE_SIGN |
2524 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002525 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002526
mohammad16036df908f2018-04-02 08:34:15 -07002527 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002528
2529 return( PSA_SUCCESS );
2530}
2531
Gilles Peskine2d277862018-06-18 15:41:12 +02002532psa_status_t psa_get_key_policy( psa_key_slot_t key,
2533 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002534{
2535 key_slot_t *slot;
2536
Gilles Peskine828ed142018-06-18 23:25:51 +02002537 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002538 return( PSA_ERROR_INVALID_ARGUMENT );
2539
2540 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002541
mohammad16036df908f2018-04-02 08:34:15 -07002542 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002543
2544 return( PSA_SUCCESS );
2545}
Gilles Peskine20035e32018-02-03 22:44:14 +01002546
Gilles Peskinea0655c32018-04-30 17:06:50 +02002547
2548
mohammad1603804cd712018-03-20 22:44:08 +02002549/****************************************************************/
2550/* Key Lifetime */
2551/****************************************************************/
2552
Gilles Peskine2d277862018-06-18 15:41:12 +02002553psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2554 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002555{
2556 key_slot_t *slot;
2557
Gilles Peskine828ed142018-06-18 23:25:51 +02002558 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002559 return( PSA_ERROR_INVALID_ARGUMENT );
2560
2561 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002562
mohammad1603804cd712018-03-20 22:44:08 +02002563 *lifetime = slot->lifetime;
2564
2565 return( PSA_SUCCESS );
2566}
2567
Gilles Peskine2d277862018-06-18 15:41:12 +02002568psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01002569 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002570{
2571 key_slot_t *slot;
2572
Gilles Peskine828ed142018-06-18 23:25:51 +02002573 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002574 return( PSA_ERROR_INVALID_ARGUMENT );
2575
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002576 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2577 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002578 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2579 return( PSA_ERROR_INVALID_ARGUMENT );
2580
mohammad1603804cd712018-03-20 22:44:08 +02002581 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002582 if( slot->type != PSA_KEY_TYPE_NONE )
2583 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002584
Moran Pekerd7326592018-05-29 16:56:39 +03002585 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002586 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002587
mohammad1603060ad8a2018-03-20 14:28:38 -07002588 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002589
2590 return( PSA_SUCCESS );
2591}
2592
Gilles Peskine20035e32018-02-03 22:44:14 +01002593
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002594
mohammad16035955c982018-04-26 00:53:03 +03002595/****************************************************************/
2596/* AEAD */
2597/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002598
mohammad16035955c982018-04-26 00:53:03 +03002599psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2600 psa_algorithm_t alg,
2601 const uint8_t *nonce,
2602 size_t nonce_length,
2603 const uint8_t *additional_data,
2604 size_t additional_data_length,
2605 const uint8_t *plaintext,
2606 size_t plaintext_length,
2607 uint8_t *ciphertext,
2608 size_t ciphertext_size,
2609 size_t *ciphertext_length )
2610{
2611 int ret;
2612 psa_status_t status;
2613 key_slot_t *slot;
2614 psa_key_type_t key_type;
2615 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002616 uint8_t *tag;
2617 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002618 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002619 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002620
mohammad1603f08a5502018-06-03 15:05:47 +03002621 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002622
mohammad16035955c982018-04-26 00:53:03 +03002623 status = psa_get_key_information( key, &key_type, &key_bits );
2624 if( status != PSA_SUCCESS )
2625 return( status );
2626 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002627 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002628 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002629
mohammad16035ed06212018-06-06 13:09:34 +03002630 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2631 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002632 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002633 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002634
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002635 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002636 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002637
Gilles Peskine2d277862018-06-18 15:41:12 +02002638 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2639 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002640 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002641
mohammad16035955c982018-04-26 00:53:03 +03002642 if( alg == PSA_ALG_GCM )
2643 {
2644 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002645 tag_length = 16;
2646
mohammad160396910d82018-06-04 14:33:00 +03002647 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2648 return( PSA_ERROR_INVALID_ARGUMENT );
2649
mohammad160315223a82018-06-03 17:19:55 +03002650 //make sure we have place to hold the tag in the ciphertext buffer
2651 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002652 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002653
2654 //update the tag pointer to point to the end of the ciphertext_length
2655 tag = ciphertext + plaintext_length;
2656
mohammad16035955c982018-04-26 00:53:03 +03002657 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002658 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002659 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002660 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002661 if( ret != 0 )
2662 {
2663 mbedtls_gcm_free( &gcm );
2664 return( mbedtls_to_psa_error( ret ) );
2665 }
2666 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002667 plaintext_length, nonce,
2668 nonce_length, additional_data,
2669 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002670 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002671 mbedtls_gcm_free( &gcm );
2672 }
2673 else if( alg == PSA_ALG_CCM )
2674 {
2675 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002676 tag_length = 16;
2677
mohammad160396910d82018-06-04 14:33:00 +03002678 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2679 return( PSA_ERROR_INVALID_ARGUMENT );
2680
mohammad160347ddf3d2018-04-26 01:11:21 +03002681 if( nonce_length < 7 || nonce_length > 13 )
2682 return( PSA_ERROR_INVALID_ARGUMENT );
2683
mohammad160315223a82018-06-03 17:19:55 +03002684 //make sure we have place to hold the tag in the ciphertext buffer
2685 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002686 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002687
2688 //update the tag pointer to point to the end of the ciphertext_length
2689 tag = ciphertext + plaintext_length;
2690
mohammad16035955c982018-04-26 00:53:03 +03002691 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002692 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002693 slot->data.raw.data,
2694 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002695 if( ret != 0 )
2696 {
2697 mbedtls_ccm_free( &ccm );
2698 return( mbedtls_to_psa_error( ret ) );
2699 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002700 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002701 nonce, nonce_length,
2702 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002703 additional_data_length,
2704 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002705 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002706 mbedtls_ccm_free( &ccm );
2707 }
mohammad16035c8845f2018-05-09 05:40:09 -07002708 else
2709 {
mohammad1603554faad2018-06-03 15:07:38 +03002710 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002711 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002712
mohammad160315223a82018-06-03 17:19:55 +03002713 if( ret != 0 )
2714 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002715 /* If ciphertext_size is 0 then ciphertext may be NULL and then the
2716 * call to memset would have undefined behavior. */
2717 if( ciphertext_size != 0 )
2718 memset( ciphertext, 0, ciphertext_size );
mohammad160315223a82018-06-03 17:19:55 +03002719 return( mbedtls_to_psa_error( ret ) );
2720 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002721
mohammad160315223a82018-06-03 17:19:55 +03002722 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002723 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002724}
2725
Gilles Peskineee652a32018-06-01 19:23:52 +02002726/* Locate the tag in a ciphertext buffer containing the encrypted data
2727 * followed by the tag. Return the length of the part preceding the tag in
2728 * *plaintext_length. This is the size of the plaintext in modes where
2729 * the encrypted data has the same size as the plaintext, such as
2730 * CCM and GCM. */
2731static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2732 const uint8_t *ciphertext,
2733 size_t ciphertext_length,
2734 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002735 const uint8_t **p_tag )
2736{
2737 size_t payload_length;
2738 if( tag_length > ciphertext_length )
2739 return( PSA_ERROR_INVALID_ARGUMENT );
2740 payload_length = ciphertext_length - tag_length;
2741 if( payload_length > plaintext_size )
2742 return( PSA_ERROR_BUFFER_TOO_SMALL );
2743 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002744 return( PSA_SUCCESS );
2745}
2746
mohammad16035955c982018-04-26 00:53:03 +03002747psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2748 psa_algorithm_t alg,
2749 const uint8_t *nonce,
2750 size_t nonce_length,
2751 const uint8_t *additional_data,
2752 size_t additional_data_length,
2753 const uint8_t *ciphertext,
2754 size_t ciphertext_length,
2755 uint8_t *plaintext,
2756 size_t plaintext_size,
2757 size_t *plaintext_length )
2758{
2759 int ret;
2760 psa_status_t status;
2761 key_slot_t *slot;
2762 psa_key_type_t key_type;
2763 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002764 const uint8_t *tag;
2765 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002766 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002767 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002768
Gilles Peskineee652a32018-06-01 19:23:52 +02002769 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002770
mohammad16035955c982018-04-26 00:53:03 +03002771 status = psa_get_key_information( key, &key_type, &key_bits );
2772 if( status != PSA_SUCCESS )
2773 return( status );
2774 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002775 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002776 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002777
mohammad16035ed06212018-06-06 13:09:34 +03002778 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2779 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002780 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002781 return( PSA_ERROR_NOT_SUPPORTED );
2782
mohammad1603f14394b2018-06-04 14:33:19 +03002783 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2784 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002785
Gilles Peskine2d277862018-06-18 15:41:12 +02002786 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2787 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002788 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002789
mohammad16035955c982018-04-26 00:53:03 +03002790 if( alg == PSA_ALG_GCM )
2791 {
2792 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002793
Gilles Peskineee652a32018-06-01 19:23:52 +02002794 tag_length = 16;
2795 status = psa_aead_unpadded_locate_tag( tag_length,
2796 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002797 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002798 if( status != PSA_SUCCESS )
2799 return( status );
2800
mohammad16035955c982018-04-26 00:53:03 +03002801 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002802 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002803 slot->data.raw.data,
2804 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002805 if( ret != 0 )
2806 {
2807 mbedtls_gcm_free( &gcm );
2808 return( mbedtls_to_psa_error( ret ) );
2809 }
mohammad16035955c982018-04-26 00:53:03 +03002810
Gilles Peskineee652a32018-06-01 19:23:52 +02002811 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002812 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002813 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002814 additional_data,
2815 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002816 tag, tag_length,
2817 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002818 mbedtls_gcm_free( &gcm );
2819 }
2820 else if( alg == PSA_ALG_CCM )
2821 {
2822 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002823
mohammad160347ddf3d2018-04-26 01:11:21 +03002824 if( nonce_length < 7 || nonce_length > 13 )
2825 return( PSA_ERROR_INVALID_ARGUMENT );
2826
mohammad16039375f842018-06-03 14:28:24 +03002827 tag_length = 16;
2828 status = psa_aead_unpadded_locate_tag( tag_length,
2829 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002830 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002831 if( status != PSA_SUCCESS )
2832 return( status );
2833
mohammad16035955c982018-04-26 00:53:03 +03002834 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002835 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002836 slot->data.raw.data,
2837 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002838 if( ret != 0 )
2839 {
2840 mbedtls_ccm_free( &ccm );
2841 return( mbedtls_to_psa_error( ret ) );
2842 }
mohammad160360a64d02018-06-03 17:20:42 +03002843 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002844 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002845 additional_data,
2846 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002847 ciphertext, plaintext,
2848 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002849 mbedtls_ccm_free( &ccm );
2850 }
mohammad160339574652018-06-01 04:39:53 -07002851 else
2852 {
mohammad1603554faad2018-06-03 15:07:38 +03002853 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002854 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002855
Gilles Peskineee652a32018-06-01 19:23:52 +02002856 if( ret != 0 )
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002857 {
2858 /* If plaintext_size is 0 then plaintext may be NULL and then the
2859 * call to memset has undefined behavior. */
2860 if( plaintext_size != 0 )
2861 memset( plaintext, 0, plaintext_size );
2862 }
mohammad160360a64d02018-06-03 17:20:42 +03002863 else
2864 *plaintext_length = ciphertext_length - tag_length;
2865
Gilles Peskineee652a32018-06-01 19:23:52 +02002866 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002867}
2868
Gilles Peskinea0655c32018-04-30 17:06:50 +02002869
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002870
Gilles Peskine20035e32018-02-03 22:44:14 +01002871/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002872/* Key generation */
2873/****************************************************************/
2874
2875psa_status_t psa_generate_random( uint8_t *output,
2876 size_t output_size )
2877{
2878 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2879 output, output_size );
2880 return( mbedtls_to_psa_error( ret ) );
2881}
2882
2883psa_status_t psa_generate_key( psa_key_slot_t key,
2884 psa_key_type_t type,
2885 size_t bits,
2886 const void *parameters,
2887 size_t parameters_size )
2888{
Gilles Peskine12313cd2018-06-20 00:20:32 +02002889 key_slot_t *slot;
2890
2891 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
2892 return( PSA_ERROR_INVALID_ARGUMENT );
2893 slot = &global_data.key_slots[key];
2894 if( slot->type != PSA_KEY_TYPE_NONE )
2895 return( PSA_ERROR_OCCUPIED_SLOT );
2896 if( parameters == NULL && parameters_size != 0 )
2897 return( PSA_ERROR_INVALID_ARGUMENT );
2898
Gilles Peskine48c0ea12018-06-21 14:15:31 +02002899 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02002900 {
2901 psa_status_t status = prepare_raw_data_slot( type, bits,
2902 &slot->data.raw );
2903 if( status != PSA_SUCCESS )
2904 return( status );
2905 status = psa_generate_random( slot->data.raw.data,
2906 slot->data.raw.bytes );
2907 if( status != PSA_SUCCESS )
2908 {
2909 mbedtls_free( slot->data.raw.data );
2910 return( status );
2911 }
2912#if defined(MBEDTLS_DES_C)
2913 if( type == PSA_KEY_TYPE_DES )
2914 {
2915 mbedtls_des_key_set_parity( slot->data.raw.data );
2916 if( slot->data.raw.bytes >= 16 )
2917 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
2918 if( slot->data.raw.bytes == 24 )
2919 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
2920 }
2921#endif /* MBEDTLS_DES_C */
2922 }
2923 else
2924
2925#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
2926 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
2927 {
2928 mbedtls_rsa_context *rsa;
2929 int ret;
2930 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02002931 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
2932 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine12313cd2018-06-20 00:20:32 +02002933 if( parameters != NULL )
2934 {
2935 const unsigned *p = parameters;
2936 if( parameters_size != sizeof( *p ) )
2937 return( PSA_ERROR_INVALID_ARGUMENT );
2938 if( *p > INT_MAX )
2939 return( PSA_ERROR_INVALID_ARGUMENT );
2940 exponent = *p;
2941 }
2942 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
2943 if( rsa == NULL )
2944 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2945 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
2946 ret = mbedtls_rsa_gen_key( rsa,
2947 mbedtls_ctr_drbg_random,
2948 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002949 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02002950 exponent );
2951 if( ret != 0 )
2952 {
2953 mbedtls_rsa_free( rsa );
2954 mbedtls_free( rsa );
2955 return( mbedtls_to_psa_error( ret ) );
2956 }
2957 slot->data.rsa = rsa;
2958 }
2959 else
2960#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
2961
2962#if defined(MBEDTLS_ECP_C)
2963 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
2964 {
2965 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
2966 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
2967 const mbedtls_ecp_curve_info *curve_info =
2968 mbedtls_ecp_curve_info_from_grp_id( grp_id );
2969 mbedtls_ecp_keypair *ecp;
2970 int ret;
2971 if( parameters != NULL )
2972 return( PSA_ERROR_NOT_SUPPORTED );
2973 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
2974 return( PSA_ERROR_NOT_SUPPORTED );
2975 if( curve_info->bit_size != bits )
2976 return( PSA_ERROR_INVALID_ARGUMENT );
2977 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
2978 if( ecp == NULL )
2979 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2980 mbedtls_ecp_keypair_init( ecp );
2981 ret = mbedtls_ecp_gen_key( grp_id, ecp,
2982 mbedtls_ctr_drbg_random,
2983 &global_data.ctr_drbg );
2984 if( ret != 0 )
2985 {
2986 mbedtls_ecp_keypair_free( ecp );
2987 mbedtls_free( ecp );
2988 return( mbedtls_to_psa_error( ret ) );
2989 }
2990 slot->data.ecp = ecp;
2991 }
2992 else
2993#endif /* MBEDTLS_ECP_C */
2994
2995 return( PSA_ERROR_NOT_SUPPORTED );
2996
2997 slot->type = type;
2998 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02002999}
3000
3001
3002/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003003/* Module setup */
3004/****************************************************************/
3005
Gilles Peskinee59236f2018-01-27 23:32:46 +01003006void mbedtls_psa_crypto_free( void )
3007{
Jaeden Amero045bd502018-06-26 14:00:08 +01003008 psa_key_slot_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02003009 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003010 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003011 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
3012 mbedtls_entropy_free( &global_data.entropy );
3013 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3014}
3015
3016psa_status_t psa_crypto_init( void )
3017{
3018 int ret;
3019 const unsigned char drbg_seed[] = "PSA";
3020
3021 if( global_data.initialized != 0 )
3022 return( PSA_SUCCESS );
3023
3024 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3025 mbedtls_entropy_init( &global_data.entropy );
3026 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
3027
3028 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
3029 mbedtls_entropy_func,
3030 &global_data.entropy,
3031 drbg_seed, sizeof( drbg_seed ) - 1 );
3032 if( ret != 0 )
3033 goto exit;
3034
Gilles Peskinee4ebc122018-03-07 14:16:44 +01003035 global_data.initialized = 1;
3036
Gilles Peskinee59236f2018-01-27 23:32:46 +01003037exit:
3038 if( ret != 0 )
3039 mbedtls_psa_crypto_free( );
3040 return( mbedtls_to_psa_error( ret ) );
3041}
3042
3043#endif /* MBEDTLS_PSA_CRYPTO_C */