blob: 1d5337bfb0243959f64ab0471d2c5847f5e666da [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. */
1016 *hash_length = actual_hash_length;
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 {
1071 return( psa_hash_abort( operation ) );
1072 }
1073 else
1074 {
1075 psa_hash_abort( operation );
1076 return( mbedtls_to_psa_error( ret ) );
1077 }
1078}
1079
Gilles Peskine2d277862018-06-18 15:41:12 +02001080psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1081 const uint8_t *hash,
1082 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001083{
1084 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1085 size_t actual_hash_length;
1086 psa_status_t status = psa_hash_finish( operation,
1087 actual_hash, sizeof( actual_hash ),
1088 &actual_hash_length );
1089 if( status != PSA_SUCCESS )
1090 return( status );
1091 if( actual_hash_length != hash_length )
1092 return( PSA_ERROR_INVALID_SIGNATURE );
1093 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1094 return( PSA_ERROR_INVALID_SIGNATURE );
1095 return( PSA_SUCCESS );
1096}
1097
1098
1099
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001100/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001101/* MAC */
1102/****************************************************************/
1103
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001104static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001105 psa_algorithm_t alg,
1106 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001107 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001108 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001109{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001110 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001111 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001112
1113 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1114 {
1115 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001116 {
1117 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1118 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001119
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001120 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001121 {
1122 case PSA_ALG_STREAM_CIPHER:
1123 mode = MBEDTLS_MODE_STREAM;
1124 break;
1125 case PSA_ALG_CBC_BASE:
1126 mode = MBEDTLS_MODE_CBC;
1127 break;
1128 case PSA_ALG_CFB_BASE:
1129 mode = MBEDTLS_MODE_CFB;
1130 break;
1131 case PSA_ALG_OFB_BASE:
1132 mode = MBEDTLS_MODE_OFB;
1133 break;
1134 case PSA_ALG_CTR:
1135 mode = MBEDTLS_MODE_CTR;
1136 break;
1137 case PSA_ALG_CCM:
1138 mode = MBEDTLS_MODE_CCM;
1139 break;
1140 case PSA_ALG_GCM:
1141 mode = MBEDTLS_MODE_GCM;
1142 break;
1143 default:
1144 return( NULL );
1145 }
1146 }
1147 else if( alg == PSA_ALG_CMAC )
1148 mode = MBEDTLS_MODE_ECB;
1149 else if( alg == PSA_ALG_GMAC )
1150 mode = MBEDTLS_MODE_GCM;
1151 else
1152 return( NULL );
1153
1154 switch( key_type )
1155 {
1156 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001157 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001158 break;
1159 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001160 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1161 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001162 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001163 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001164 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001165 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001166 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1167 * but two-key Triple-DES is functionally three-key Triple-DES
1168 * with K1=K3, so that's how we present it to mbedtls. */
1169 if( key_bits == 128 )
1170 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001171 break;
1172 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001173 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001174 break;
1175 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001176 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001177 break;
1178 default:
1179 return( NULL );
1180 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001181 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001182 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001183
Jaeden Amero23bbb752018-06-26 14:16:54 +01001184 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1185 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001186}
1187
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001188static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001189{
Gilles Peskine2d277862018-06-18 15:41:12 +02001190 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001191 {
1192 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001193 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001194 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001195 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001196 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001197 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001198 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001199 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001200 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001201 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001202 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001203 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001204 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001205 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001206 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001207 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001208 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001209 return( 128 );
1210 default:
1211 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001212 }
1213}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001214
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001215/* Initialize the MAC operation structure. Once this function has been
1216 * called, psa_mac_abort can run and will do the right thing. */
1217static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1218 psa_algorithm_t alg )
1219{
1220 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1221
1222 operation->alg = alg;
1223 operation->key_set = 0;
1224 operation->iv_set = 0;
1225 operation->iv_required = 0;
1226 operation->has_input = 0;
1227 operation->key_usage_sign = 0;
1228 operation->key_usage_verify = 0;
1229
1230#if defined(MBEDTLS_CMAC_C)
1231 if( alg == PSA_ALG_CMAC )
1232 {
1233 operation->iv_required = 0;
1234 mbedtls_cipher_init( &operation->ctx.cmac );
1235 status = PSA_SUCCESS;
1236 }
1237 else
1238#endif /* MBEDTLS_CMAC_C */
1239#if defined(MBEDTLS_MD_C)
1240 if( PSA_ALG_IS_HMAC( operation->alg ) )
1241 {
1242 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1243 PSA_ALG_HMAC_HASH( alg ) );
1244 }
1245 else
1246#endif /* MBEDTLS_MD_C */
1247 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001248 if( ! PSA_ALG_IS_MAC( alg ) )
1249 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001250 }
1251
1252 if( status != PSA_SUCCESS )
1253 memset( operation, 0, sizeof( *operation ) );
1254 return( status );
1255}
1256
Gilles Peskine8c9def32018-02-08 10:02:12 +01001257psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1258{
1259 switch( operation->alg )
1260 {
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001261 case 0:
Gilles Peskine81736312018-06-26 15:04:31 +02001262 /* The object has (apparently) been initialized but it is not
1263 * in use. It's ok to call abort on such an object, and there's
1264 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001265 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001266#if defined(MBEDTLS_CMAC_C)
1267 case PSA_ALG_CMAC:
1268 mbedtls_cipher_free( &operation->ctx.cmac );
1269 break;
1270#endif /* MBEDTLS_CMAC_C */
1271 default:
1272#if defined(MBEDTLS_MD_C)
1273 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001274 {
Jaeden Amero5390f692018-06-26 14:18:50 +01001275 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001276 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001277
Gilles Peskine99bc6492018-06-11 17:13:00 +02001278 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001279 return( PSA_ERROR_NOT_SUPPORTED );
1280
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001281 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001282 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001283 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001284 else
1285#endif /* MBEDTLS_MD_C */
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001286 {
1287 /* Sanity check (shouldn't happen: operation->alg should
1288 * always have been initialized to a valid value). */
1289 return( PSA_ERROR_BAD_STATE );
1290 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001291 }
Moran Peker41deec42018-04-04 15:43:05 +03001292
Gilles Peskine8c9def32018-02-08 10:02:12 +01001293 operation->alg = 0;
1294 operation->key_set = 0;
1295 operation->iv_set = 0;
1296 operation->iv_required = 0;
1297 operation->has_input = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001298 operation->key_usage_sign = 0;
1299 operation->key_usage_verify = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001300
Gilles Peskine8c9def32018-02-08 10:02:12 +01001301 return( PSA_SUCCESS );
1302}
1303
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001304#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001305static int psa_cmac_start( psa_mac_operation_t *operation,
1306 size_t key_bits,
1307 key_slot_t *slot,
1308 const mbedtls_cipher_info_t *cipher_info )
1309{
1310 int ret;
1311
1312 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001313
1314 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1315 if( ret != 0 )
1316 return( ret );
1317
1318 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1319 slot->data.raw.data,
1320 key_bits );
1321 return( ret );
1322}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001323#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001324
Gilles Peskine248051a2018-06-20 16:09:38 +02001325#if defined(MBEDTLS_MD_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001326static int psa_hmac_start( psa_mac_operation_t *operation,
1327 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001328 key_slot_t *slot,
1329 psa_algorithm_t alg )
1330{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001331 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001332 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001333 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001334 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001335 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001336 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001337 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001338 size_t key_length = slot->data.raw.bytes;
1339 psa_status_t status;
1340
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001341 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001342 return( PSA_ERROR_NOT_SUPPORTED );
1343
1344 if( key_type != PSA_KEY_TYPE_HMAC )
1345 return( PSA_ERROR_INVALID_ARGUMENT );
1346
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001347 operation->mac_size = digest_size;
1348
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001349 /* The hash was started earlier in psa_mac_init. */
Gilles Peskined223b522018-06-11 18:12:58 +02001350 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001351 {
1352 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001353 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001354 if( status != PSA_SUCCESS )
1355 return( status );
1356 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001357 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001358 if( status != PSA_SUCCESS )
1359 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001360 }
Gilles Peskined223b522018-06-11 18:12:58 +02001361 else
1362 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001363
Gilles Peskined223b522018-06-11 18:12:58 +02001364 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1365 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001366 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001367 ipad[i] ^= 0x36;
1368 memset( ipad + key_length, 0x36, block_size - key_length );
1369
1370 /* Copy the key material from ipad to opad, flipping the requisite bits,
1371 * and filling the rest of opad with the requisite constant. */
1372 for( i = 0; i < key_length; i++ )
1373 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1374 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001375
1376 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1377 PSA_ALG_HMAC_HASH( alg ) );
1378 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001379 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001380
1381 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1382 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001383
1384cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001385 mbedtls_zeroize( ipad, key_length );
1386 /* opad is in the context. It needs to stay in memory if this function
1387 * succeeds, and it will be wiped by psa_mac_abort() called from
1388 * psa_mac_start in the error case. */
1389
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001390 return( status );
1391}
Gilles Peskine248051a2018-06-20 16:09:38 +02001392#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001393
Gilles Peskine8c9def32018-02-08 10:02:12 +01001394psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1395 psa_key_slot_t key,
1396 psa_algorithm_t alg )
1397{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001398 psa_status_t status;
1399 key_slot_t *slot;
1400 psa_key_type_t key_type;
1401 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001402 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001403
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001404 status = psa_mac_init( operation, alg );
1405 if( status != PSA_SUCCESS )
1406 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001407
1408 status = psa_get_key_information( key, &key_type, &key_bits );
1409 if( status != PSA_SUCCESS )
1410 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001411
Gilles Peskine8c9def32018-02-08 10:02:12 +01001412 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001413 if( slot->type == PSA_KEY_TYPE_NONE )
1414 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001415
Moran Pekerd7326592018-05-29 16:56:39 +03001416 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001417 operation->key_usage_sign = 1;
1418
Moran Pekerd7326592018-05-29 16:56:39 +03001419 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001420 operation->key_usage_verify = 1;
1421
Gilles Peskine8c9def32018-02-08 10:02:12 +01001422 if( ! PSA_ALG_IS_HMAC( alg ) )
1423 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001424 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001425 if( cipher_info == NULL )
1426 return( PSA_ERROR_NOT_SUPPORTED );
1427 operation->mac_size = cipher_info->block_size;
1428 }
1429 switch( alg )
1430 {
1431#if defined(MBEDTLS_CMAC_C)
1432 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001433 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1434 key_bits,
1435 slot,
1436 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001437 break;
1438#endif /* MBEDTLS_CMAC_C */
1439 default:
1440#if defined(MBEDTLS_MD_C)
1441 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001442 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001443 else
1444#endif /* MBEDTLS_MD_C */
1445 return( PSA_ERROR_NOT_SUPPORTED );
1446 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001447
Gilles Peskine8c9def32018-02-08 10:02:12 +01001448 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001449 * context may contain data that needs to be wiped on error. */
1450 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001451 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001452 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001453 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001454 else
1455 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001456 operation->key_set = 1;
1457 }
1458 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001459}
1460
1461psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1462 const uint8_t *input,
1463 size_t input_length )
1464{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001465 int ret = 0 ;
1466 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001467 if( ! operation->key_set )
1468 return( PSA_ERROR_BAD_STATE );
1469 if( operation->iv_required && ! operation->iv_set )
1470 return( PSA_ERROR_BAD_STATE );
1471 operation->has_input = 1;
1472
1473 switch( operation->alg )
1474 {
1475#if defined(MBEDTLS_CMAC_C)
1476 case PSA_ALG_CMAC:
1477 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1478 input, input_length );
1479 break;
1480#endif /* MBEDTLS_CMAC_C */
1481 default:
1482#if defined(MBEDTLS_MD_C)
1483 if( PSA_ALG_IS_HMAC( operation->alg ) )
1484 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001485 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001486 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001487 }
1488 else
1489#endif /* MBEDTLS_MD_C */
1490 {
1491 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1492 }
1493 break;
1494 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001495 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001496 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001497 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001498 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001499 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001500 }
1501
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001502 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001503}
1504
mohammad16036df908f2018-04-02 08:34:15 -07001505static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001506 uint8_t *mac,
1507 size_t mac_size,
1508 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001509{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001510 int ret = 0;
1511 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001512 if( ! operation->key_set )
1513 return( PSA_ERROR_BAD_STATE );
1514 if( operation->iv_required && ! operation->iv_set )
1515 return( PSA_ERROR_BAD_STATE );
1516
1517 /* Fill the output buffer with something that isn't a valid mac
1518 * (barring an attack on the mac and deliberately-crafted input),
1519 * in case the caller doesn't check the return status properly. */
1520 *mac_length = operation->mac_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001521 /* If mac_size is 0 then mac may be NULL and then the
1522 * call to memset would have undefined behavior. */
1523 if( mac_size != 0 )
1524 memset( mac, '!', mac_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001525
1526 if( mac_size < operation->mac_size )
1527 return( PSA_ERROR_BUFFER_TOO_SMALL );
1528
1529 switch( operation->alg )
1530 {
1531#if defined(MBEDTLS_CMAC_C)
1532 case PSA_ALG_CMAC:
1533 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1534 break;
1535#endif /* MBEDTLS_CMAC_C */
1536 default:
1537#if defined(MBEDTLS_MD_C)
1538 if( PSA_ALG_IS_HMAC( operation->alg ) )
1539 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001540 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001541 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001542 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001543 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001544 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001545
Gilles Peskine99bc6492018-06-11 17:13:00 +02001546 if( block_size == 0 )
1547 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001548
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001549 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001550 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001551 if( status != PSA_SUCCESS )
1552 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001553 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001554
1555 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1556 PSA_ALG_HMAC_HASH( operation->alg ) );
1557 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001558 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001559
1560 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001561 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001562 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001563 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001564
1565 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001566 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001567 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001568 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001569
1570 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1571 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001572 hmac_cleanup:
1573 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001574 }
1575 else
1576#endif /* MBEDTLS_MD_C */
1577 {
1578 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1579 }
1580 break;
1581 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001582cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001583
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001584 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001585 {
1586 return( psa_mac_abort( operation ) );
1587 }
1588 else
1589 {
1590 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001591 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001592 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001593
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001594 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001595 }
1596}
1597
mohammad16036df908f2018-04-02 08:34:15 -07001598psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1599 uint8_t *mac,
1600 size_t mac_size,
1601 size_t *mac_length )
1602{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001603 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001604 return( PSA_ERROR_NOT_PERMITTED );
1605
Gilles Peskine99bc6492018-06-11 17:13:00 +02001606 return( psa_mac_finish_internal( operation, mac,
1607 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001608}
1609
Gilles Peskine8c9def32018-02-08 10:02:12 +01001610psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1611 const uint8_t *mac,
1612 size_t mac_length )
1613{
Gilles Peskine828ed142018-06-18 23:25:51 +02001614 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001615 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001616 psa_status_t status;
1617
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001618 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001619 return( PSA_ERROR_NOT_PERMITTED );
1620
1621 status = psa_mac_finish_internal( operation,
1622 actual_mac, sizeof( actual_mac ),
1623 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001624 if( status != PSA_SUCCESS )
1625 return( status );
1626 if( actual_mac_length != mac_length )
1627 return( PSA_ERROR_INVALID_SIGNATURE );
1628 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1629 return( PSA_ERROR_INVALID_SIGNATURE );
1630 return( PSA_SUCCESS );
1631}
1632
1633
Gilles Peskine20035e32018-02-03 22:44:14 +01001634
Gilles Peskine20035e32018-02-03 22:44:14 +01001635/****************************************************************/
1636/* Asymmetric cryptography */
1637/****************************************************************/
1638
Gilles Peskine2b450e32018-06-27 15:42:46 +02001639#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001640/* Decode the hash algorithm from alg and store the mbedtls encoding in
1641 * md_alg. Verify that the hash length is consistent. */
1642static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1643 size_t hash_length,
1644 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001645{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02001646 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001647 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1648 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1649 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001650 {
1651#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001652 if( hash_length > UINT_MAX )
1653 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001654#endif
1655 }
1656 else
1657 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001658 if( mbedtls_md_get_size( md_info ) != hash_length )
1659 return( PSA_ERROR_INVALID_ARGUMENT );
1660 if( md_info == NULL )
1661 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001662 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001663 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001664}
1665
Gilles Peskine2b450e32018-06-27 15:42:46 +02001666static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
1667 psa_algorithm_t alg,
1668 const uint8_t *hash,
1669 size_t hash_length,
1670 uint8_t *signature,
1671 size_t signature_size,
1672 size_t *signature_length )
1673{
1674 psa_status_t status;
1675 int ret;
1676 mbedtls_md_type_t md_alg;
1677
1678 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1679 if( status != PSA_SUCCESS )
1680 return( status );
1681
1682 if( signature_size < rsa->len )
1683 return( PSA_ERROR_BUFFER_TOO_SMALL );
1684
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001685 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1686 * hash_length will fit and return an error if it doesn't. */
1687#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1688#if SIZE_MAX > UINT_MAX
1689 if( hash_length > UINT_MAX )
1690 return( PSA_ERROR_NOT_SUPPORTED );
1691#endif
1692#endif
1693
Gilles Peskine2b450e32018-06-27 15:42:46 +02001694#if defined(MBEDTLS_PKCS1_V15)
1695 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1696 {
1697 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1698 MBEDTLS_MD_NONE );
1699 ret = mbedtls_rsa_pkcs1_sign( rsa,
1700 mbedtls_ctr_drbg_random,
1701 &global_data.ctr_drbg,
1702 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001703 md_alg,
1704 (unsigned int) hash_length,
1705 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001706 signature );
1707 }
1708 else
1709#endif /* MBEDTLS_PKCS1_V15 */
1710#if defined(MBEDTLS_PKCS1_V21)
1711 if( PSA_ALG_IS_RSA_PSS( alg ) )
1712 {
1713 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1714 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1715 mbedtls_ctr_drbg_random,
1716 &global_data.ctr_drbg,
1717 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001718 md_alg,
1719 (unsigned int) hash_length,
1720 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001721 signature );
1722 }
1723 else
1724#endif /* MBEDTLS_PKCS1_V21 */
1725 {
1726 return( PSA_ERROR_INVALID_ARGUMENT );
1727 }
1728
1729 if( ret == 0 )
1730 *signature_length = rsa->len;
1731 return( mbedtls_to_psa_error( ret ) );
1732}
1733
1734static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
1735 psa_algorithm_t alg,
1736 const uint8_t *hash,
1737 size_t hash_length,
1738 const uint8_t *signature,
1739 size_t signature_length )
1740{
1741 psa_status_t status;
1742 int ret;
1743 mbedtls_md_type_t md_alg;
1744
1745 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1746 if( status != PSA_SUCCESS )
1747 return( status );
1748
1749 if( signature_length < rsa->len )
1750 return( PSA_ERROR_BUFFER_TOO_SMALL );
1751
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001752#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1753#if SIZE_MAX > UINT_MAX
1754 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1755 * hash_length will fit and return an error if it doesn't. */
1756 if( hash_length > UINT_MAX )
1757 return( PSA_ERROR_NOT_SUPPORTED );
1758#endif
1759#endif
1760
Gilles Peskine2b450e32018-06-27 15:42:46 +02001761#if defined(MBEDTLS_PKCS1_V15)
1762 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1763 {
1764 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1765 MBEDTLS_MD_NONE );
1766 ret = mbedtls_rsa_pkcs1_verify( rsa,
1767 mbedtls_ctr_drbg_random,
1768 &global_data.ctr_drbg,
1769 MBEDTLS_RSA_PUBLIC,
1770 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001771 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001772 hash,
1773 signature );
1774 }
1775 else
1776#endif /* MBEDTLS_PKCS1_V15 */
1777#if defined(MBEDTLS_PKCS1_V21)
1778 if( PSA_ALG_IS_RSA_PSS( alg ) )
1779 {
1780 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1781 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1782 mbedtls_ctr_drbg_random,
1783 &global_data.ctr_drbg,
1784 MBEDTLS_RSA_PUBLIC,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001785 md_alg,
1786 (unsigned int) hash_length,
1787 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001788 signature );
1789 }
1790 else
1791#endif /* MBEDTLS_PKCS1_V21 */
1792 {
1793 return( PSA_ERROR_INVALID_ARGUMENT );
1794 }
1795 return( mbedtls_to_psa_error( ret ) );
1796}
1797#endif /* MBEDTLS_RSA_C */
1798
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001799#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001800/* `ecp` cannot be const because `ecp->grp` needs to be non-const
1801 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
1802 * (even though these functions don't modify it). */
1803static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
1804 psa_algorithm_t alg,
1805 const uint8_t *hash,
1806 size_t hash_length,
1807 uint8_t *signature,
1808 size_t signature_size,
1809 size_t *signature_length )
1810{
1811 int ret;
1812 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001813 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001814 mbedtls_mpi_init( &r );
1815 mbedtls_mpi_init( &s );
1816
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001817 if( signature_size < 2 * curve_bytes )
1818 {
1819 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
1820 goto cleanup;
1821 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001822
1823 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
1824 {
1825 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
1826 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1827 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
1828 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
1829 hash, hash_length,
1830 md_alg ) );
1831 }
1832 else
1833 {
1834 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
1835 hash, hash_length,
1836 mbedtls_ctr_drbg_random,
1837 &global_data.ctr_drbg ) );
1838 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001839
1840 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
1841 signature,
1842 curve_bytes ) );
1843 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
1844 signature + curve_bytes,
1845 curve_bytes ) );
1846
1847cleanup:
1848 mbedtls_mpi_free( &r );
1849 mbedtls_mpi_free( &s );
1850 if( ret == 0 )
1851 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001852 return( mbedtls_to_psa_error( ret ) );
1853}
1854
1855static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
1856 const uint8_t *hash,
1857 size_t hash_length,
1858 const uint8_t *signature,
1859 size_t signature_length )
1860{
1861 int ret;
1862 mbedtls_mpi r, s;
1863 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
1864 mbedtls_mpi_init( &r );
1865 mbedtls_mpi_init( &s );
1866
1867 if( signature_length != 2 * curve_bytes )
1868 return( PSA_ERROR_INVALID_SIGNATURE );
1869
1870 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
1871 signature,
1872 curve_bytes ) );
1873 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
1874 signature + curve_bytes,
1875 curve_bytes ) );
1876
1877 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
1878 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001879
1880cleanup:
1881 mbedtls_mpi_free( &r );
1882 mbedtls_mpi_free( &s );
1883 return( mbedtls_to_psa_error( ret ) );
1884}
1885#endif /* MBEDTLS_ECDSA_C */
1886
Gilles Peskine61b91d42018-06-08 16:09:36 +02001887psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1888 psa_algorithm_t alg,
1889 const uint8_t *hash,
1890 size_t hash_length,
1891 const uint8_t *salt,
1892 size_t salt_length,
1893 uint8_t *signature,
1894 size_t signature_size,
1895 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001896{
1897 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001898 psa_status_t status;
1899
1900 *signature_length = signature_size;
1901
Gilles Peskine93aa0332018-02-03 23:58:03 +01001902 (void) salt;
1903 (void) salt_length;
1904
Gilles Peskine828ed142018-06-18 23:25:51 +02001905 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001906 {
1907 status = PSA_ERROR_EMPTY_SLOT;
1908 goto exit;
1909 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001910 slot = &global_data.key_slots[key];
1911 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001912 {
1913 status = PSA_ERROR_EMPTY_SLOT;
1914 goto exit;
1915 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001916 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001917 {
1918 status = PSA_ERROR_INVALID_ARGUMENT;
1919 goto exit;
1920 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001921 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001922 {
1923 status = PSA_ERROR_NOT_PERMITTED;
1924 goto exit;
1925 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001926
Gilles Peskine20035e32018-02-03 22:44:14 +01001927#if defined(MBEDTLS_RSA_C)
1928 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1929 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001930 status = psa_rsa_sign( slot->data.rsa,
1931 alg,
1932 hash, hash_length,
1933 signature, signature_size,
1934 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01001935 }
1936 else
1937#endif /* defined(MBEDTLS_RSA_C) */
1938#if defined(MBEDTLS_ECP_C)
1939 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1940 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001941#if defined(MBEDTLS_ECDSA_C)
1942 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001943 status = psa_ecdsa_sign( slot->data.ecp,
1944 alg,
1945 hash, hash_length,
1946 signature, signature_size,
1947 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001948 else
1949#endif /* defined(MBEDTLS_ECDSA_C) */
1950 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001951 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001952 }
itayzafrir5c753392018-05-08 11:18:38 +03001953 }
1954 else
1955#endif /* defined(MBEDTLS_ECP_C) */
1956 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001957 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01001958 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001959
1960exit:
1961 /* Fill the unused part of the output buffer (the whole buffer on error,
1962 * the trailing part on success) with something that isn't a valid mac
1963 * (barring an attack on the mac and deliberately-crafted input),
1964 * in case the caller doesn't check the return status properly. */
1965 if( status == PSA_SUCCESS )
1966 memset( signature + *signature_length, '!',
1967 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001968 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001969 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001970 /* If signature_size is 0 then we have nothing to do. We must not call
1971 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001972 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03001973}
1974
1975psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1976 psa_algorithm_t alg,
1977 const uint8_t *hash,
1978 size_t hash_length,
1979 const uint8_t *salt,
1980 size_t salt_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02001981 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02001982 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03001983{
1984 key_slot_t *slot;
Gilles Peskine2b450e32018-06-27 15:42:46 +02001985
itayzafrir5c753392018-05-08 11:18:38 +03001986 (void) salt;
1987 (void) salt_length;
1988
Gilles Peskine828ed142018-06-18 23:25:51 +02001989 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001990 return( PSA_ERROR_INVALID_ARGUMENT );
1991 slot = &global_data.key_slots[key];
1992 if( slot->type == PSA_KEY_TYPE_NONE )
1993 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001994 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001995 return( PSA_ERROR_NOT_PERMITTED );
1996
Gilles Peskine61b91d42018-06-08 16:09:36 +02001997#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001998 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1999 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002000 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002001 return( psa_rsa_verify( slot->data.rsa,
2002 alg,
2003 hash, hash_length,
2004 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002005 }
2006 else
2007#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002008#if defined(MBEDTLS_ECP_C)
2009 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2010 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002011#if defined(MBEDTLS_ECDSA_C)
2012 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002013 return( psa_ecdsa_verify( slot->data.ecp,
2014 hash, hash_length,
2015 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002016 else
2017#endif /* defined(MBEDTLS_ECDSA_C) */
2018 {
2019 return( PSA_ERROR_INVALID_ARGUMENT );
2020 }
itayzafrir5c753392018-05-08 11:18:38 +03002021 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002022 else
2023#endif /* defined(MBEDTLS_ECP_C) */
2024 {
2025 return( PSA_ERROR_NOT_SUPPORTED );
2026 }
2027}
2028
Gilles Peskine61b91d42018-06-08 16:09:36 +02002029psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2030 psa_algorithm_t alg,
2031 const uint8_t *input,
2032 size_t input_length,
2033 const uint8_t *salt,
2034 size_t salt_length,
2035 uint8_t *output,
2036 size_t output_size,
2037 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002038{
2039 key_slot_t *slot;
2040 (void) salt;
2041 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002042 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002043
Gilles Peskine828ed142018-06-18 23:25:51 +02002044 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03002045 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002046 slot = &global_data.key_slots[key];
2047 if( slot->type == PSA_KEY_TYPE_NONE )
2048 return( PSA_ERROR_EMPTY_SLOT );
2049 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2050 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002051 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
2052 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002053
2054#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002055 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
2056 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002057 {
2058 mbedtls_rsa_context *rsa = slot->data.rsa;
2059 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002060 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002061 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002062#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002063 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002064 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002065 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2066 mbedtls_ctr_drbg_random,
2067 &global_data.ctr_drbg,
2068 MBEDTLS_RSA_PUBLIC,
2069 input_length,
2070 input,
2071 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002072 }
2073 else
2074#endif /* MBEDTLS_PKCS1_V15 */
2075#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002076 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002077 {
2078 return( PSA_ERROR_NOT_SUPPORTED );
2079 }
2080 else
2081#endif /* MBEDTLS_PKCS1_V21 */
2082 {
2083 return( PSA_ERROR_INVALID_ARGUMENT );
2084 }
2085 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002086 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002087 return( mbedtls_to_psa_error( ret ) );
2088 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002089 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002090#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002091 {
2092 return( PSA_ERROR_NOT_SUPPORTED );
2093 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002094}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002095
Gilles Peskine61b91d42018-06-08 16:09:36 +02002096psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2097 psa_algorithm_t alg,
2098 const uint8_t *input,
2099 size_t input_length,
2100 const uint8_t *salt,
2101 size_t salt_length,
2102 uint8_t *output,
2103 size_t output_size,
2104 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002105{
2106 key_slot_t *slot;
2107 (void) salt;
2108 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002109 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002110
Gilles Peskine828ed142018-06-18 23:25:51 +02002111 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002112 return( PSA_ERROR_EMPTY_SLOT );
2113 slot = &global_data.key_slots[key];
2114 if( slot->type == PSA_KEY_TYPE_NONE )
2115 return( PSA_ERROR_EMPTY_SLOT );
2116 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2117 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002118 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2119 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002120
2121#if defined(MBEDTLS_RSA_C)
2122 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2123 {
2124 mbedtls_rsa_context *rsa = slot->data.rsa;
2125 int ret;
2126
Gilles Peskinec4def2f2018-06-08 17:53:48 +02002127 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002128 return( PSA_ERROR_INVALID_ARGUMENT );
2129
2130#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002131 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002132 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002133 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2134 mbedtls_ctr_drbg_random,
2135 &global_data.ctr_drbg,
2136 MBEDTLS_RSA_PRIVATE,
2137 output_length,
2138 input,
2139 output,
2140 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002141 }
2142 else
2143#endif /* MBEDTLS_PKCS1_V15 */
2144#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002145 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002146 {
2147 return( PSA_ERROR_NOT_SUPPORTED );
2148 }
2149 else
2150#endif /* MBEDTLS_PKCS1_V21 */
2151 {
2152 return( PSA_ERROR_INVALID_ARGUMENT );
2153 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002154
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002155 return( mbedtls_to_psa_error( ret ) );
2156 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002157 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002158#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002159 {
2160 return( PSA_ERROR_NOT_SUPPORTED );
2161 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002162}
Gilles Peskine20035e32018-02-03 22:44:14 +01002163
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002164
2165
mohammad1603503973b2018-03-12 15:59:30 +02002166/****************************************************************/
2167/* Symmetric cryptography */
2168/****************************************************************/
2169
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002170/* Initialize the cipher operation structure. Once this function has been
2171 * called, psa_cipher_abort can run and will do the right thing. */
2172static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2173 psa_algorithm_t alg )
2174{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002175 if( ! PSA_ALG_IS_CIPHER( alg ) )
2176 {
2177 memset( operation, 0, sizeof( *operation ) );
2178 return( PSA_ERROR_INVALID_ARGUMENT );
2179 }
2180
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002181 operation->alg = alg;
2182 operation->key_set = 0;
2183 operation->iv_set = 0;
2184 operation->iv_required = 1;
2185 operation->iv_size = 0;
2186 operation->block_size = 0;
2187 mbedtls_cipher_init( &operation->ctx.cipher );
2188 return( PSA_SUCCESS );
2189}
2190
Gilles Peskinee553c652018-06-04 16:22:46 +02002191static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2192 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002193 psa_algorithm_t alg,
2194 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002195{
2196 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2197 psa_status_t status;
2198 key_slot_t *slot;
2199 psa_key_type_t key_type;
2200 size_t key_bits;
2201 const mbedtls_cipher_info_t *cipher_info = NULL;
2202
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002203 status = psa_cipher_init( operation, alg );
2204 if( status != PSA_SUCCESS )
2205 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002206
2207 status = psa_get_key_information( key, &key_type, &key_bits );
2208 if( status != PSA_SUCCESS )
2209 return( status );
2210 slot = &global_data.key_slots[key];
2211
Gilles Peskinebb1072f2018-06-08 18:46:05 +02002212 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002213 if( cipher_info == NULL )
2214 return( PSA_ERROR_NOT_SUPPORTED );
2215
mohammad1603503973b2018-03-12 15:59:30 +02002216 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002217 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002218 {
2219 psa_cipher_abort( operation );
2220 return( mbedtls_to_psa_error( ret ) );
2221 }
2222
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002223#if defined(MBEDTLS_DES_C)
2224 if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
2225 {
2226 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2227 unsigned char keys[24];
2228 memcpy( keys, slot->data.raw.data, 16 );
2229 memcpy( keys + 16, slot->data.raw.data, 8 );
2230 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2231 keys,
2232 192, cipher_operation );
2233 }
2234 else
2235#endif
2236 {
2237 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2238 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002239 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002240 }
Moran Peker41deec42018-04-04 15:43:05 +03002241 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002242 {
2243 psa_cipher_abort( operation );
2244 return( mbedtls_to_psa_error( ret ) );
2245 }
2246
mohammad16038481e742018-03-18 13:57:31 +02002247#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03002248 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02002249 {
Gilles Peskine53514202018-06-06 15:11:46 +02002250 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
2251 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02002252
Moran Pekera28258c2018-05-29 16:25:04 +03002253 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02002254 {
2255 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
2256 mode = MBEDTLS_PADDING_PKCS7;
2257 break;
2258 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
2259 mode = MBEDTLS_PADDING_NONE;
2260 break;
2261 default:
Moran Pekerae382792018-05-31 14:06:17 +03002262 psa_cipher_abort( operation );
2263 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02002264 }
2265 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03002266 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03002267 {
2268 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02002269 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03002270 }
mohammad16038481e742018-03-18 13:57:31 +02002271 }
2272#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2273
mohammad1603503973b2018-03-12 15:59:30 +02002274 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002275 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
2276 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
2277 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002278 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002279 {
mohammad160389e0f462018-04-12 08:48:45 +03002280 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02002281 }
mohammad1603503973b2018-03-12 15:59:30 +02002282
Moran Peker395db872018-05-31 14:07:14 +03002283 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002284}
2285
Gilles Peskinee553c652018-06-04 16:22:46 +02002286psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
2287 psa_key_slot_t key,
2288 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002289{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002290 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002291}
2292
Gilles Peskinee553c652018-06-04 16:22:46 +02002293psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
2294 psa_key_slot_t key,
2295 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002296{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002297 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002298}
2299
Gilles Peskinee553c652018-06-04 16:22:46 +02002300psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
2301 unsigned char *iv,
2302 size_t iv_size,
2303 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002304{
Moran Peker41deec42018-04-04 15:43:05 +03002305 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002306 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002307 return( PSA_ERROR_BAD_STATE );
2308 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002309 {
Moran Peker41deec42018-04-04 15:43:05 +03002310 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2311 goto exit;
2312 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002313 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2314 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002315 if( ret != 0 )
2316 {
2317 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002318 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002319 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002320
mohammad16038481e742018-03-18 13:57:31 +02002321 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03002322 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002323
Moran Peker395db872018-05-31 14:07:14 +03002324exit:
2325 if( ret != PSA_SUCCESS )
2326 psa_cipher_abort( operation );
2327 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002328}
2329
Gilles Peskinee553c652018-06-04 16:22:46 +02002330psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
2331 const unsigned char *iv,
2332 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002333{
Moran Peker41deec42018-04-04 15:43:05 +03002334 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002335 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002336 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002337 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002338 {
Moran Pekerae382792018-05-31 14:06:17 +03002339 psa_cipher_abort( operation );
2340 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002341 }
mohammad1603503973b2018-03-12 15:59:30 +02002342 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002343 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002344 {
2345 psa_cipher_abort( operation );
2346 return( mbedtls_to_psa_error( ret ) );
2347 }
2348
2349 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002350
Moran Peker395db872018-05-31 14:07:14 +03002351 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002352}
2353
Gilles Peskinee553c652018-06-04 16:22:46 +02002354psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2355 const uint8_t *input,
2356 size_t input_length,
2357 unsigned char *output,
2358 size_t output_size,
2359 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002360{
2361 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002362 size_t expected_output_size;
2363 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2364 {
2365 /* Take the unprocessed partial block left over from previous
2366 * update calls, if any, plus the input to this call. Remove
2367 * the last partial block, if any. You get the data that will be
2368 * output in this call. */
2369 expected_output_size =
2370 ( operation->ctx.cipher.unprocessed_len + input_length )
2371 / operation->block_size * operation->block_size;
2372 }
2373 else
2374 {
2375 expected_output_size = input_length;
2376 }
2377 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002378 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002379
mohammad1603503973b2018-03-12 15:59:30 +02002380 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002381 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002382 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002383 {
2384 psa_cipher_abort( operation );
2385 return( mbedtls_to_psa_error( ret ) );
2386 }
2387
Moran Peker395db872018-05-31 14:07:14 +03002388 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002389}
2390
Gilles Peskinee553c652018-06-04 16:22:46 +02002391psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2392 uint8_t *output,
2393 size_t output_size,
2394 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002395{
2396 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002397 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002398
mohammad1603503973b2018-03-12 15:59:30 +02002399 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002400 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002401 psa_cipher_abort( operation );
2402 return( PSA_ERROR_BAD_STATE );
2403 }
2404 if( operation->iv_required && ! operation->iv_set )
2405 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002406 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002407 return( PSA_ERROR_BAD_STATE );
2408 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002409 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2410 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002411 {
Gilles Peskine53514202018-06-06 15:11:46 +02002412 psa_algorithm_t padding_mode =
2413 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002414 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002415 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002416 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002417 return( PSA_ERROR_TAMPERING_DETECTED );
2418 }
Gilles Peskine53514202018-06-06 15:11:46 +02002419 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002420 {
2421 if( operation->ctx.cipher.unprocessed_len != 0 )
2422 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002423 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002424 return( PSA_ERROR_INVALID_ARGUMENT );
2425 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002426 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002427 }
2428
2429 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002430 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002431 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002432 {
2433 psa_cipher_abort( operation );
2434 return( mbedtls_to_psa_error( ret ) );
2435 }
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002436 if( *output_length == 0 )
2437 /* Nothing to copy. Note that output may be NULL in this case. */ ;
2438 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002439 memcpy( output, temp_output_buffer, *output_length );
2440 else
2441 {
2442 psa_cipher_abort( operation );
2443 return( PSA_ERROR_BUFFER_TOO_SMALL );
2444 }
mohammad1603503973b2018-03-12 15:59:30 +02002445
Moran Peker4c80d832018-04-22 20:15:31 +03002446 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002447}
2448
Gilles Peskinee553c652018-06-04 16:22:46 +02002449psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2450{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002451 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002452 {
2453 /* The object has (apparently) been initialized but it is not
2454 * in use. It's ok to call abort on such an object, and there's
2455 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002456 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002457 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002458
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002459 /* Sanity check (shouldn't happen: operation->alg should
2460 * always have been initialized to a valid value). */
2461 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2462 return( PSA_ERROR_BAD_STATE );
2463
mohammad1603503973b2018-03-12 15:59:30 +02002464 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002465
Moran Peker41deec42018-04-04 15:43:05 +03002466 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002467 operation->key_set = 0;
2468 operation->iv_set = 0;
2469 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002470 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002471 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002472
Moran Peker395db872018-05-31 14:07:14 +03002473 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002474}
2475
Gilles Peskinea0655c32018-04-30 17:06:50 +02002476
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002477
mohammad16038cc1cee2018-03-28 01:21:33 +03002478/****************************************************************/
2479/* Key Policy */
2480/****************************************************************/
2481
Gilles Peskine2d277862018-06-18 15:41:12 +02002482void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002483{
Gilles Peskine803ce742018-06-18 16:07:14 +02002484 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002485}
2486
Gilles Peskine2d277862018-06-18 15:41:12 +02002487void psa_key_policy_set_usage( psa_key_policy_t *policy,
2488 psa_key_usage_t usage,
2489 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002490{
mohammad16034eed7572018-03-28 05:14:59 -07002491 policy->usage = usage;
2492 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002493}
2494
Gilles Peskine2d277862018-06-18 15:41:12 +02002495psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002496{
mohammad16036df908f2018-04-02 08:34:15 -07002497 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002498}
2499
Gilles Peskine2d277862018-06-18 15:41:12 +02002500psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002501{
mohammad16036df908f2018-04-02 08:34:15 -07002502 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002503}
2504
Gilles Peskine2d277862018-06-18 15:41:12 +02002505psa_status_t psa_set_key_policy( psa_key_slot_t key,
2506 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002507{
2508 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002509
Gilles Peskine828ed142018-06-18 23:25:51 +02002510 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002511 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002512
mohammad16038cc1cee2018-03-28 01:21:33 +03002513 slot = &global_data.key_slots[key];
2514 if( slot->type != PSA_KEY_TYPE_NONE )
2515 return( PSA_ERROR_OCCUPIED_SLOT );
2516
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002517 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2518 PSA_KEY_USAGE_ENCRYPT |
2519 PSA_KEY_USAGE_DECRYPT |
2520 PSA_KEY_USAGE_SIGN |
2521 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002522 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002523
mohammad16036df908f2018-04-02 08:34:15 -07002524 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002525
2526 return( PSA_SUCCESS );
2527}
2528
Gilles Peskine2d277862018-06-18 15:41:12 +02002529psa_status_t psa_get_key_policy( psa_key_slot_t key,
2530 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002531{
2532 key_slot_t *slot;
2533
Gilles Peskine828ed142018-06-18 23:25:51 +02002534 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002535 return( PSA_ERROR_INVALID_ARGUMENT );
2536
2537 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002538
mohammad16036df908f2018-04-02 08:34:15 -07002539 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002540
2541 return( PSA_SUCCESS );
2542}
Gilles Peskine20035e32018-02-03 22:44:14 +01002543
Gilles Peskinea0655c32018-04-30 17:06:50 +02002544
2545
mohammad1603804cd712018-03-20 22:44:08 +02002546/****************************************************************/
2547/* Key Lifetime */
2548/****************************************************************/
2549
Gilles Peskine2d277862018-06-18 15:41:12 +02002550psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2551 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002552{
2553 key_slot_t *slot;
2554
Gilles Peskine828ed142018-06-18 23:25:51 +02002555 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002556 return( PSA_ERROR_INVALID_ARGUMENT );
2557
2558 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002559
mohammad1603804cd712018-03-20 22:44:08 +02002560 *lifetime = slot->lifetime;
2561
2562 return( PSA_SUCCESS );
2563}
2564
Gilles Peskine2d277862018-06-18 15:41:12 +02002565psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01002566 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002567{
2568 key_slot_t *slot;
2569
Gilles Peskine828ed142018-06-18 23:25:51 +02002570 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002571 return( PSA_ERROR_INVALID_ARGUMENT );
2572
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002573 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2574 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002575 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2576 return( PSA_ERROR_INVALID_ARGUMENT );
2577
mohammad1603804cd712018-03-20 22:44:08 +02002578 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002579 if( slot->type != PSA_KEY_TYPE_NONE )
2580 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002581
Moran Pekerd7326592018-05-29 16:56:39 +03002582 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002583 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002584
mohammad1603060ad8a2018-03-20 14:28:38 -07002585 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002586
2587 return( PSA_SUCCESS );
2588}
2589
Gilles Peskine20035e32018-02-03 22:44:14 +01002590
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002591
mohammad16035955c982018-04-26 00:53:03 +03002592/****************************************************************/
2593/* AEAD */
2594/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002595
mohammad16035955c982018-04-26 00:53:03 +03002596psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2597 psa_algorithm_t alg,
2598 const uint8_t *nonce,
2599 size_t nonce_length,
2600 const uint8_t *additional_data,
2601 size_t additional_data_length,
2602 const uint8_t *plaintext,
2603 size_t plaintext_length,
2604 uint8_t *ciphertext,
2605 size_t ciphertext_size,
2606 size_t *ciphertext_length )
2607{
2608 int ret;
2609 psa_status_t status;
2610 key_slot_t *slot;
2611 psa_key_type_t key_type;
2612 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002613 uint8_t *tag;
2614 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002615 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002616 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002617
mohammad1603f08a5502018-06-03 15:05:47 +03002618 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002619
mohammad16035955c982018-04-26 00:53:03 +03002620 status = psa_get_key_information( key, &key_type, &key_bits );
2621 if( status != PSA_SUCCESS )
2622 return( status );
2623 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002624 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002625 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002626
mohammad16035ed06212018-06-06 13:09:34 +03002627 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2628 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002629 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002630 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002631
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002632 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002633 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002634
Gilles Peskine2d277862018-06-18 15:41:12 +02002635 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2636 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002637 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002638
mohammad16035955c982018-04-26 00:53:03 +03002639 if( alg == PSA_ALG_GCM )
2640 {
2641 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002642 tag_length = 16;
2643
mohammad160396910d82018-06-04 14:33:00 +03002644 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2645 return( PSA_ERROR_INVALID_ARGUMENT );
2646
mohammad160315223a82018-06-03 17:19:55 +03002647 //make sure we have place to hold the tag in the ciphertext buffer
2648 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002649 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002650
2651 //update the tag pointer to point to the end of the ciphertext_length
2652 tag = ciphertext + plaintext_length;
2653
mohammad16035955c982018-04-26 00:53:03 +03002654 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002655 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002656 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002657 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002658 if( ret != 0 )
2659 {
2660 mbedtls_gcm_free( &gcm );
2661 return( mbedtls_to_psa_error( ret ) );
2662 }
2663 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002664 plaintext_length, nonce,
2665 nonce_length, additional_data,
2666 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002667 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002668 mbedtls_gcm_free( &gcm );
2669 }
2670 else if( alg == PSA_ALG_CCM )
2671 {
2672 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002673 tag_length = 16;
2674
mohammad160396910d82018-06-04 14:33:00 +03002675 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2676 return( PSA_ERROR_INVALID_ARGUMENT );
2677
mohammad160347ddf3d2018-04-26 01:11:21 +03002678 if( nonce_length < 7 || nonce_length > 13 )
2679 return( PSA_ERROR_INVALID_ARGUMENT );
2680
mohammad160315223a82018-06-03 17:19:55 +03002681 //make sure we have place to hold the tag in the ciphertext buffer
2682 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002683 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002684
2685 //update the tag pointer to point to the end of the ciphertext_length
2686 tag = ciphertext + plaintext_length;
2687
mohammad16035955c982018-04-26 00:53:03 +03002688 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002689 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002690 slot->data.raw.data,
2691 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002692 if( ret != 0 )
2693 {
2694 mbedtls_ccm_free( &ccm );
2695 return( mbedtls_to_psa_error( ret ) );
2696 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002697 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002698 nonce, nonce_length,
2699 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002700 additional_data_length,
2701 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002702 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002703 mbedtls_ccm_free( &ccm );
2704 }
mohammad16035c8845f2018-05-09 05:40:09 -07002705 else
2706 {
mohammad1603554faad2018-06-03 15:07:38 +03002707 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002708 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002709
mohammad160315223a82018-06-03 17:19:55 +03002710 if( ret != 0 )
2711 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002712 /* If ciphertext_size is 0 then ciphertext may be NULL and then the
2713 * call to memset would have undefined behavior. */
2714 if( ciphertext_size != 0 )
2715 memset( ciphertext, 0, ciphertext_size );
mohammad160315223a82018-06-03 17:19:55 +03002716 return( mbedtls_to_psa_error( ret ) );
2717 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002718
mohammad160315223a82018-06-03 17:19:55 +03002719 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002720 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002721}
2722
Gilles Peskineee652a32018-06-01 19:23:52 +02002723/* Locate the tag in a ciphertext buffer containing the encrypted data
2724 * followed by the tag. Return the length of the part preceding the tag in
2725 * *plaintext_length. This is the size of the plaintext in modes where
2726 * the encrypted data has the same size as the plaintext, such as
2727 * CCM and GCM. */
2728static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2729 const uint8_t *ciphertext,
2730 size_t ciphertext_length,
2731 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002732 const uint8_t **p_tag )
2733{
2734 size_t payload_length;
2735 if( tag_length > ciphertext_length )
2736 return( PSA_ERROR_INVALID_ARGUMENT );
2737 payload_length = ciphertext_length - tag_length;
2738 if( payload_length > plaintext_size )
2739 return( PSA_ERROR_BUFFER_TOO_SMALL );
2740 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002741 return( PSA_SUCCESS );
2742}
2743
mohammad16035955c982018-04-26 00:53:03 +03002744psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2745 psa_algorithm_t alg,
2746 const uint8_t *nonce,
2747 size_t nonce_length,
2748 const uint8_t *additional_data,
2749 size_t additional_data_length,
2750 const uint8_t *ciphertext,
2751 size_t ciphertext_length,
2752 uint8_t *plaintext,
2753 size_t plaintext_size,
2754 size_t *plaintext_length )
2755{
2756 int ret;
2757 psa_status_t status;
2758 key_slot_t *slot;
2759 psa_key_type_t key_type;
2760 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002761 const uint8_t *tag;
2762 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002763 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002764 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002765
Gilles Peskineee652a32018-06-01 19:23:52 +02002766 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002767
mohammad16035955c982018-04-26 00:53:03 +03002768 status = psa_get_key_information( key, &key_type, &key_bits );
2769 if( status != PSA_SUCCESS )
2770 return( status );
2771 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002772 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002773 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002774
mohammad16035ed06212018-06-06 13:09:34 +03002775 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2776 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002777 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002778 return( PSA_ERROR_NOT_SUPPORTED );
2779
mohammad1603f14394b2018-06-04 14:33:19 +03002780 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2781 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002782
Gilles Peskine2d277862018-06-18 15:41:12 +02002783 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2784 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002785 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002786
mohammad16035955c982018-04-26 00:53:03 +03002787 if( alg == PSA_ALG_GCM )
2788 {
2789 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002790
Gilles Peskineee652a32018-06-01 19:23:52 +02002791 tag_length = 16;
2792 status = psa_aead_unpadded_locate_tag( tag_length,
2793 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002794 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002795 if( status != PSA_SUCCESS )
2796 return( status );
2797
mohammad16035955c982018-04-26 00:53:03 +03002798 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002799 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002800 slot->data.raw.data,
2801 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002802 if( ret != 0 )
2803 {
2804 mbedtls_gcm_free( &gcm );
2805 return( mbedtls_to_psa_error( ret ) );
2806 }
mohammad16035955c982018-04-26 00:53:03 +03002807
Gilles Peskineee652a32018-06-01 19:23:52 +02002808 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002809 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002810 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002811 additional_data,
2812 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002813 tag, tag_length,
2814 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002815 mbedtls_gcm_free( &gcm );
2816 }
2817 else if( alg == PSA_ALG_CCM )
2818 {
2819 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002820
mohammad160347ddf3d2018-04-26 01:11:21 +03002821 if( nonce_length < 7 || nonce_length > 13 )
2822 return( PSA_ERROR_INVALID_ARGUMENT );
2823
mohammad16039375f842018-06-03 14:28:24 +03002824 tag_length = 16;
2825 status = psa_aead_unpadded_locate_tag( tag_length,
2826 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002827 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002828 if( status != PSA_SUCCESS )
2829 return( status );
2830
mohammad16035955c982018-04-26 00:53:03 +03002831 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002832 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002833 slot->data.raw.data,
2834 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002835 if( ret != 0 )
2836 {
2837 mbedtls_ccm_free( &ccm );
2838 return( mbedtls_to_psa_error( ret ) );
2839 }
mohammad160360a64d02018-06-03 17:20:42 +03002840 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002841 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002842 additional_data,
2843 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002844 ciphertext, plaintext,
2845 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002846 mbedtls_ccm_free( &ccm );
2847 }
mohammad160339574652018-06-01 04:39:53 -07002848 else
2849 {
mohammad1603554faad2018-06-03 15:07:38 +03002850 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002851 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002852
Gilles Peskineee652a32018-06-01 19:23:52 +02002853 if( ret != 0 )
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002854 {
2855 /* If plaintext_size is 0 then plaintext may be NULL and then the
2856 * call to memset has undefined behavior. */
2857 if( plaintext_size != 0 )
2858 memset( plaintext, 0, plaintext_size );
2859 }
mohammad160360a64d02018-06-03 17:20:42 +03002860 else
2861 *plaintext_length = ciphertext_length - tag_length;
2862
Gilles Peskineee652a32018-06-01 19:23:52 +02002863 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002864}
2865
Gilles Peskinea0655c32018-04-30 17:06:50 +02002866
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002867
Gilles Peskine20035e32018-02-03 22:44:14 +01002868/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002869/* Key generation */
2870/****************************************************************/
2871
2872psa_status_t psa_generate_random( uint8_t *output,
2873 size_t output_size )
2874{
2875 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2876 output, output_size );
2877 return( mbedtls_to_psa_error( ret ) );
2878}
2879
2880psa_status_t psa_generate_key( psa_key_slot_t key,
2881 psa_key_type_t type,
2882 size_t bits,
2883 const void *parameters,
2884 size_t parameters_size )
2885{
Gilles Peskine12313cd2018-06-20 00:20:32 +02002886 key_slot_t *slot;
2887
2888 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
2889 return( PSA_ERROR_INVALID_ARGUMENT );
2890 slot = &global_data.key_slots[key];
2891 if( slot->type != PSA_KEY_TYPE_NONE )
2892 return( PSA_ERROR_OCCUPIED_SLOT );
2893 if( parameters == NULL && parameters_size != 0 )
2894 return( PSA_ERROR_INVALID_ARGUMENT );
2895
Gilles Peskine48c0ea12018-06-21 14:15:31 +02002896 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02002897 {
2898 psa_status_t status = prepare_raw_data_slot( type, bits,
2899 &slot->data.raw );
2900 if( status != PSA_SUCCESS )
2901 return( status );
2902 status = psa_generate_random( slot->data.raw.data,
2903 slot->data.raw.bytes );
2904 if( status != PSA_SUCCESS )
2905 {
2906 mbedtls_free( slot->data.raw.data );
2907 return( status );
2908 }
2909#if defined(MBEDTLS_DES_C)
2910 if( type == PSA_KEY_TYPE_DES )
2911 {
2912 mbedtls_des_key_set_parity( slot->data.raw.data );
2913 if( slot->data.raw.bytes >= 16 )
2914 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
2915 if( slot->data.raw.bytes == 24 )
2916 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
2917 }
2918#endif /* MBEDTLS_DES_C */
2919 }
2920 else
2921
2922#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
2923 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
2924 {
2925 mbedtls_rsa_context *rsa;
2926 int ret;
2927 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02002928 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
2929 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine12313cd2018-06-20 00:20:32 +02002930 if( parameters != NULL )
2931 {
2932 const unsigned *p = parameters;
2933 if( parameters_size != sizeof( *p ) )
2934 return( PSA_ERROR_INVALID_ARGUMENT );
2935 if( *p > INT_MAX )
2936 return( PSA_ERROR_INVALID_ARGUMENT );
2937 exponent = *p;
2938 }
2939 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
2940 if( rsa == NULL )
2941 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2942 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
2943 ret = mbedtls_rsa_gen_key( rsa,
2944 mbedtls_ctr_drbg_random,
2945 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002946 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02002947 exponent );
2948 if( ret != 0 )
2949 {
2950 mbedtls_rsa_free( rsa );
2951 mbedtls_free( rsa );
2952 return( mbedtls_to_psa_error( ret ) );
2953 }
2954 slot->data.rsa = rsa;
2955 }
2956 else
2957#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
2958
2959#if defined(MBEDTLS_ECP_C)
2960 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
2961 {
2962 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
2963 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
2964 const mbedtls_ecp_curve_info *curve_info =
2965 mbedtls_ecp_curve_info_from_grp_id( grp_id );
2966 mbedtls_ecp_keypair *ecp;
2967 int ret;
2968 if( parameters != NULL )
2969 return( PSA_ERROR_NOT_SUPPORTED );
2970 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
2971 return( PSA_ERROR_NOT_SUPPORTED );
2972 if( curve_info->bit_size != bits )
2973 return( PSA_ERROR_INVALID_ARGUMENT );
2974 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
2975 if( ecp == NULL )
2976 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2977 mbedtls_ecp_keypair_init( ecp );
2978 ret = mbedtls_ecp_gen_key( grp_id, ecp,
2979 mbedtls_ctr_drbg_random,
2980 &global_data.ctr_drbg );
2981 if( ret != 0 )
2982 {
2983 mbedtls_ecp_keypair_free( ecp );
2984 mbedtls_free( ecp );
2985 return( mbedtls_to_psa_error( ret ) );
2986 }
2987 slot->data.ecp = ecp;
2988 }
2989 else
2990#endif /* MBEDTLS_ECP_C */
2991
2992 return( PSA_ERROR_NOT_SUPPORTED );
2993
2994 slot->type = type;
2995 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02002996}
2997
2998
2999/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003000/* Module setup */
3001/****************************************************************/
3002
Gilles Peskinee59236f2018-01-27 23:32:46 +01003003void mbedtls_psa_crypto_free( void )
3004{
Jaeden Amero045bd502018-06-26 14:00:08 +01003005 psa_key_slot_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02003006 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003007 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003008 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
3009 mbedtls_entropy_free( &global_data.entropy );
3010 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3011}
3012
3013psa_status_t psa_crypto_init( void )
3014{
3015 int ret;
3016 const unsigned char drbg_seed[] = "PSA";
3017
3018 if( global_data.initialized != 0 )
3019 return( PSA_SUCCESS );
3020
3021 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3022 mbedtls_entropy_init( &global_data.entropy );
3023 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
3024
3025 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
3026 mbedtls_entropy_func,
3027 &global_data.entropy,
3028 drbg_seed, sizeof( drbg_seed ) - 1 );
3029 if( ret != 0 )
3030 goto exit;
3031
Gilles Peskinee4ebc122018-03-07 14:16:44 +01003032 global_data.initialized = 1;
3033
Gilles Peskinee59236f2018-01-27 23:32:46 +01003034exit:
3035 if( ret != 0 )
3036 mbedtls_psa_crypto_free( );
3037 return( mbedtls_to_psa_error( ret ) );
3038}
3039
3040#endif /* MBEDTLS_PSA_CRYPTO_C */