blob: 19db5a9ec59976ea984fac4b0643584522833667 [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 )
517 return( PSA_ERROR_NOT_SUPPORTED );
518 slot->data.rsa = rsa;
519 }
Gilles Peskine969ac722018-01-28 18:16:59 +0100520 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200521 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100522 break;
523#endif /* MBEDTLS_RSA_C */
524#if defined(MBEDTLS_ECP_C)
525 case MBEDTLS_PK_ECKEY:
526 if( PSA_KEY_TYPE_IS_ECC( type ) )
527 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200528 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
529 psa_ecc_curve_t actual_curve =
530 mbedtls_ecc_group_to_psa( ecp->grp.id );
531 psa_ecc_curve_t expected_curve =
532 PSA_KEY_TYPE_GET_CURVE( type );
533 if( actual_curve != expected_curve )
Gilles Peskinec648d692018-06-28 08:46:13 +0200534 {
535 status = PSA_ERROR_INVALID_ARGUMENT;
536 break;
537 }
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200538 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100539 }
540 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200541 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100542 break;
543#endif /* MBEDTLS_ECP_C */
544 default:
Gilles Peskinec648d692018-06-28 08:46:13 +0200545 status = PSA_ERROR_INVALID_ARGUMENT;
546 break;
547 }
548 /* Free the content of the pk object only on error. On success,
549 * the content of the object has been stored in the slot. */
550 if( status != PSA_SUCCESS )
551 {
552 mbedtls_pk_free( &pk );
553 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100554 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100555 }
556 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100557#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100558 {
559 return( PSA_ERROR_NOT_SUPPORTED );
560 }
561
562 slot->type = type;
563 return( PSA_SUCCESS );
564}
565
Gilles Peskine2d277862018-06-18 15:41:12 +0200566psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100567{
568 key_slot_t *slot;
569
Gilles Peskine828ed142018-06-18 23:25:51 +0200570 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100571 return( PSA_ERROR_INVALID_ARGUMENT );
572 slot = &global_data.key_slots[key];
573 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200574 {
575 /* No key material to clean, but do zeroize the slot below to wipe
576 * metadata such as policies. */
577 }
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200578 else if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100579 {
580 mbedtls_free( slot->data.raw.data );
581 }
582 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100583#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100584 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
585 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100586 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100587 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100588 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100589 }
590 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100591#endif /* defined(MBEDTLS_RSA_C) */
592#if defined(MBEDTLS_ECP_C)
593 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
594 {
595 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100596 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100597 }
598 else
599#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100600 {
601 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100602 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100603 return( PSA_ERROR_TAMPERING_DETECTED );
604 }
605
606 mbedtls_zeroize( slot, sizeof( *slot ) );
607 return( PSA_SUCCESS );
608}
609
Gilles Peskine2d277862018-06-18 15:41:12 +0200610psa_status_t psa_get_key_information( psa_key_slot_t key,
611 psa_key_type_t *type,
612 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100613{
614 key_slot_t *slot;
615
Gilles Peskine828ed142018-06-18 23:25:51 +0200616 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100617 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100618 slot = &global_data.key_slots[key];
619 if( type != NULL )
620 *type = slot->type;
621 if( bits != NULL )
622 *bits = 0;
623 if( slot->type == PSA_KEY_TYPE_NONE )
624 return( PSA_ERROR_EMPTY_SLOT );
625
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200626 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100627 {
628 if( bits != NULL )
629 *bits = slot->data.raw.bytes * 8;
630 }
631 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100632#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100633 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
634 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100635 {
636 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100637 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100638 }
639 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100640#endif /* defined(MBEDTLS_RSA_C) */
641#if defined(MBEDTLS_ECP_C)
642 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
643 {
644 if( bits != NULL )
645 *bits = slot->data.ecp->grp.pbits;
646 }
647 else
648#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100649 {
650 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100651 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100652 return( PSA_ERROR_TAMPERING_DETECTED );
653 }
654
655 return( PSA_SUCCESS );
656}
657
Gilles Peskine2d277862018-06-18 15:41:12 +0200658static psa_status_t psa_internal_export_key( psa_key_slot_t key,
659 uint8_t *data,
660 size_t data_size,
661 size_t *data_length,
662 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100663{
664 key_slot_t *slot;
665
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100666 /* Set the key to empty now, so that even when there are errors, we always
667 * set data_length to a value between 0 and data_size. On error, setting
668 * the key to empty is a good choice because an empty key representation is
669 * unlikely to be accepted anywhere. */
670 *data_length = 0;
671
Gilles Peskine828ed142018-06-18 23:25:51 +0200672 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100673 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100674 slot = &global_data.key_slots[key];
675 if( slot->type == PSA_KEY_TYPE_NONE )
676 return( PSA_ERROR_EMPTY_SLOT );
677
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200678 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300679 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300680
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200681 if( ! export_public_key &&
682 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
683 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300684 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200685
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200686 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100687 {
688 if( slot->data.raw.bytes > data_size )
689 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200690 if( slot->data.raw.bytes != 0 )
691 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100692 *data_length = slot->data.raw.bytes;
693 return( PSA_SUCCESS );
694 }
695 else
Moran Peker17e36e12018-05-02 12:55:20 +0300696 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100697#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100698 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300699 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
700 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100701 {
Moran Pekera998bc62018-04-16 18:16:20 +0300702 mbedtls_pk_context pk;
703 int ret;
704 mbedtls_pk_init( &pk );
705 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
706 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
707 {
708 pk.pk_info = &mbedtls_rsa_info;
709 pk.pk_ctx = slot->data.rsa;
710 }
711 else
712 {
713 pk.pk_info = &mbedtls_eckey_info;
714 pk.pk_ctx = slot->data.ecp;
715 }
Moran Pekerd7326592018-05-29 16:56:39 +0300716 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300717 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300718 else
719 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300720 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200721 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200722 /* If data_size is 0 then data may be NULL and then the
723 * call to memset would have undefined behavior. */
724 if( data_size != 0 )
725 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300726 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200727 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200728 /* The mbedtls_pk_xxx functions write to the end of the buffer.
729 * Move the data to the beginning and erase remaining data
730 * at the original location. */
731 if( 2 * (size_t) ret <= data_size )
732 {
733 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200734 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200735 }
736 else if( (size_t) ret < data_size )
737 {
738 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200739 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200740 }
Moran Pekera998bc62018-04-16 18:16:20 +0300741 *data_length = ret;
742 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100743 }
744 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100745#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300746 {
747 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200748 it is valid for a special-purpose implementation to omit
749 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300750 return( PSA_ERROR_NOT_SUPPORTED );
751 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100752 }
753}
754
Gilles Peskine2d277862018-06-18 15:41:12 +0200755psa_status_t psa_export_key( psa_key_slot_t key,
756 uint8_t *data,
757 size_t data_size,
758 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300759{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200760 return( psa_internal_export_key( key, data, data_size,
761 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100762}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100763
Gilles Peskine2d277862018-06-18 15:41:12 +0200764psa_status_t psa_export_public_key( psa_key_slot_t key,
765 uint8_t *data,
766 size_t data_size,
767 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300768{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200769 return( psa_internal_export_key( key, data, data_size,
770 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300771}
772
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200773
774
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100775/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100776/* Message digests */
777/****************************************************************/
778
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100779static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100780{
781 switch( alg )
782 {
783#if defined(MBEDTLS_MD2_C)
784 case PSA_ALG_MD2:
785 return( &mbedtls_md2_info );
786#endif
787#if defined(MBEDTLS_MD4_C)
788 case PSA_ALG_MD4:
789 return( &mbedtls_md4_info );
790#endif
791#if defined(MBEDTLS_MD5_C)
792 case PSA_ALG_MD5:
793 return( &mbedtls_md5_info );
794#endif
795#if defined(MBEDTLS_RIPEMD160_C)
796 case PSA_ALG_RIPEMD160:
797 return( &mbedtls_ripemd160_info );
798#endif
799#if defined(MBEDTLS_SHA1_C)
800 case PSA_ALG_SHA_1:
801 return( &mbedtls_sha1_info );
802#endif
803#if defined(MBEDTLS_SHA256_C)
804 case PSA_ALG_SHA_224:
805 return( &mbedtls_sha224_info );
806 case PSA_ALG_SHA_256:
807 return( &mbedtls_sha256_info );
808#endif
809#if defined(MBEDTLS_SHA512_C)
810 case PSA_ALG_SHA_384:
811 return( &mbedtls_sha384_info );
812 case PSA_ALG_SHA_512:
813 return( &mbedtls_sha512_info );
814#endif
815 default:
816 return( NULL );
817 }
818}
819
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100820psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
821{
822 switch( operation->alg )
823 {
Gilles Peskine81736312018-06-26 15:04:31 +0200824 case 0:
825 /* The object has (apparently) been initialized but it is not
826 * in use. It's ok to call abort on such an object, and there's
827 * nothing to do. */
828 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100829#if defined(MBEDTLS_MD2_C)
830 case PSA_ALG_MD2:
831 mbedtls_md2_free( &operation->ctx.md2 );
832 break;
833#endif
834#if defined(MBEDTLS_MD4_C)
835 case PSA_ALG_MD4:
836 mbedtls_md4_free( &operation->ctx.md4 );
837 break;
838#endif
839#if defined(MBEDTLS_MD5_C)
840 case PSA_ALG_MD5:
841 mbedtls_md5_free( &operation->ctx.md5 );
842 break;
843#endif
844#if defined(MBEDTLS_RIPEMD160_C)
845 case PSA_ALG_RIPEMD160:
846 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
847 break;
848#endif
849#if defined(MBEDTLS_SHA1_C)
850 case PSA_ALG_SHA_1:
851 mbedtls_sha1_free( &operation->ctx.sha1 );
852 break;
853#endif
854#if defined(MBEDTLS_SHA256_C)
855 case PSA_ALG_SHA_224:
856 case PSA_ALG_SHA_256:
857 mbedtls_sha256_free( &operation->ctx.sha256 );
858 break;
859#endif
860#if defined(MBEDTLS_SHA512_C)
861 case PSA_ALG_SHA_384:
862 case PSA_ALG_SHA_512:
863 mbedtls_sha512_free( &operation->ctx.sha512 );
864 break;
865#endif
866 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +0200867 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100868 }
869 operation->alg = 0;
870 return( PSA_SUCCESS );
871}
872
873psa_status_t psa_hash_start( psa_hash_operation_t *operation,
874 psa_algorithm_t alg )
875{
876 int ret;
877 operation->alg = 0;
878 switch( alg )
879 {
880#if defined(MBEDTLS_MD2_C)
881 case PSA_ALG_MD2:
882 mbedtls_md2_init( &operation->ctx.md2 );
883 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
884 break;
885#endif
886#if defined(MBEDTLS_MD4_C)
887 case PSA_ALG_MD4:
888 mbedtls_md4_init( &operation->ctx.md4 );
889 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
890 break;
891#endif
892#if defined(MBEDTLS_MD5_C)
893 case PSA_ALG_MD5:
894 mbedtls_md5_init( &operation->ctx.md5 );
895 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
896 break;
897#endif
898#if defined(MBEDTLS_RIPEMD160_C)
899 case PSA_ALG_RIPEMD160:
900 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
901 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
902 break;
903#endif
904#if defined(MBEDTLS_SHA1_C)
905 case PSA_ALG_SHA_1:
906 mbedtls_sha1_init( &operation->ctx.sha1 );
907 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
908 break;
909#endif
910#if defined(MBEDTLS_SHA256_C)
911 case PSA_ALG_SHA_224:
912 mbedtls_sha256_init( &operation->ctx.sha256 );
913 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
914 break;
915 case PSA_ALG_SHA_256:
916 mbedtls_sha256_init( &operation->ctx.sha256 );
917 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
918 break;
919#endif
920#if defined(MBEDTLS_SHA512_C)
921 case PSA_ALG_SHA_384:
922 mbedtls_sha512_init( &operation->ctx.sha512 );
923 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
924 break;
925 case PSA_ALG_SHA_512:
926 mbedtls_sha512_init( &operation->ctx.sha512 );
927 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
928 break;
929#endif
930 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +0200931 return( PSA_ALG_IS_HASH( alg ) ?
932 PSA_ERROR_NOT_SUPPORTED :
933 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100934 }
935 if( ret == 0 )
936 operation->alg = alg;
937 else
938 psa_hash_abort( operation );
939 return( mbedtls_to_psa_error( ret ) );
940}
941
942psa_status_t psa_hash_update( psa_hash_operation_t *operation,
943 const uint8_t *input,
944 size_t input_length )
945{
946 int ret;
947 switch( operation->alg )
948 {
949#if defined(MBEDTLS_MD2_C)
950 case PSA_ALG_MD2:
951 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
952 input, input_length );
953 break;
954#endif
955#if defined(MBEDTLS_MD4_C)
956 case PSA_ALG_MD4:
957 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
958 input, input_length );
959 break;
960#endif
961#if defined(MBEDTLS_MD5_C)
962 case PSA_ALG_MD5:
963 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
964 input, input_length );
965 break;
966#endif
967#if defined(MBEDTLS_RIPEMD160_C)
968 case PSA_ALG_RIPEMD160:
969 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
970 input, input_length );
971 break;
972#endif
973#if defined(MBEDTLS_SHA1_C)
974 case PSA_ALG_SHA_1:
975 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
976 input, input_length );
977 break;
978#endif
979#if defined(MBEDTLS_SHA256_C)
980 case PSA_ALG_SHA_224:
981 case PSA_ALG_SHA_256:
982 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
983 input, input_length );
984 break;
985#endif
986#if defined(MBEDTLS_SHA512_C)
987 case PSA_ALG_SHA_384:
988 case PSA_ALG_SHA_512:
989 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
990 input, input_length );
991 break;
992#endif
993 default:
994 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
995 break;
996 }
997 if( ret != 0 )
998 psa_hash_abort( operation );
999 return( mbedtls_to_psa_error( ret ) );
1000}
1001
1002psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1003 uint8_t *hash,
1004 size_t hash_size,
1005 size_t *hash_length )
1006{
1007 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001008 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001009
1010 /* Fill the output buffer with something that isn't a valid hash
1011 * (barring an attack on the hash and deliberately-crafted input),
1012 * in case the caller doesn't check the return status properly. */
1013 *hash_length = actual_hash_length;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001014 /* If hash_size is 0 then hash may be NULL and then the
1015 * call to memset would have undefined behavior. */
1016 if( hash_size != 0 )
1017 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001018
1019 if( hash_size < actual_hash_length )
1020 return( PSA_ERROR_BUFFER_TOO_SMALL );
1021
1022 switch( operation->alg )
1023 {
1024#if defined(MBEDTLS_MD2_C)
1025 case PSA_ALG_MD2:
1026 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1027 break;
1028#endif
1029#if defined(MBEDTLS_MD4_C)
1030 case PSA_ALG_MD4:
1031 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1032 break;
1033#endif
1034#if defined(MBEDTLS_MD5_C)
1035 case PSA_ALG_MD5:
1036 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1037 break;
1038#endif
1039#if defined(MBEDTLS_RIPEMD160_C)
1040 case PSA_ALG_RIPEMD160:
1041 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1042 break;
1043#endif
1044#if defined(MBEDTLS_SHA1_C)
1045 case PSA_ALG_SHA_1:
1046 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1047 break;
1048#endif
1049#if defined(MBEDTLS_SHA256_C)
1050 case PSA_ALG_SHA_224:
1051 case PSA_ALG_SHA_256:
1052 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1053 break;
1054#endif
1055#if defined(MBEDTLS_SHA512_C)
1056 case PSA_ALG_SHA_384:
1057 case PSA_ALG_SHA_512:
1058 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1059 break;
1060#endif
1061 default:
1062 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1063 break;
1064 }
1065
1066 if( ret == 0 )
1067 {
1068 return( psa_hash_abort( operation ) );
1069 }
1070 else
1071 {
1072 psa_hash_abort( operation );
1073 return( mbedtls_to_psa_error( ret ) );
1074 }
1075}
1076
Gilles Peskine2d277862018-06-18 15:41:12 +02001077psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1078 const uint8_t *hash,
1079 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001080{
1081 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1082 size_t actual_hash_length;
1083 psa_status_t status = psa_hash_finish( operation,
1084 actual_hash, sizeof( actual_hash ),
1085 &actual_hash_length );
1086 if( status != PSA_SUCCESS )
1087 return( status );
1088 if( actual_hash_length != hash_length )
1089 return( PSA_ERROR_INVALID_SIGNATURE );
1090 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1091 return( PSA_ERROR_INVALID_SIGNATURE );
1092 return( PSA_SUCCESS );
1093}
1094
1095
1096
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001097/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001098/* MAC */
1099/****************************************************************/
1100
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001101static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001102 psa_algorithm_t alg,
1103 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001104 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001105 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001106{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001107 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001108 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001109
1110 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1111 {
1112 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001113 {
1114 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1115 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001116
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001117 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001118 {
1119 case PSA_ALG_STREAM_CIPHER:
1120 mode = MBEDTLS_MODE_STREAM;
1121 break;
1122 case PSA_ALG_CBC_BASE:
1123 mode = MBEDTLS_MODE_CBC;
1124 break;
1125 case PSA_ALG_CFB_BASE:
1126 mode = MBEDTLS_MODE_CFB;
1127 break;
1128 case PSA_ALG_OFB_BASE:
1129 mode = MBEDTLS_MODE_OFB;
1130 break;
1131 case PSA_ALG_CTR:
1132 mode = MBEDTLS_MODE_CTR;
1133 break;
1134 case PSA_ALG_CCM:
1135 mode = MBEDTLS_MODE_CCM;
1136 break;
1137 case PSA_ALG_GCM:
1138 mode = MBEDTLS_MODE_GCM;
1139 break;
1140 default:
1141 return( NULL );
1142 }
1143 }
1144 else if( alg == PSA_ALG_CMAC )
1145 mode = MBEDTLS_MODE_ECB;
1146 else if( alg == PSA_ALG_GMAC )
1147 mode = MBEDTLS_MODE_GCM;
1148 else
1149 return( NULL );
1150
1151 switch( key_type )
1152 {
1153 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001154 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001155 break;
1156 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001157 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1158 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001159 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001160 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001161 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001162 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001163 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1164 * but two-key Triple-DES is functionally three-key Triple-DES
1165 * with K1=K3, so that's how we present it to mbedtls. */
1166 if( key_bits == 128 )
1167 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001168 break;
1169 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001170 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001171 break;
1172 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001173 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001174 break;
1175 default:
1176 return( NULL );
1177 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001178 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001179 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001180
Jaeden Amero23bbb752018-06-26 14:16:54 +01001181 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1182 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001183}
1184
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001185static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001186{
Gilles Peskine2d277862018-06-18 15:41:12 +02001187 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001188 {
1189 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001190 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001191 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001192 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001193 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001194 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001195 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001196 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001197 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001198 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001199 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001200 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001201 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001202 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001203 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001204 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001205 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001206 return( 128 );
1207 default:
1208 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001209 }
1210}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001211
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001212/* Initialize the MAC operation structure. Once this function has been
1213 * called, psa_mac_abort can run and will do the right thing. */
1214static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1215 psa_algorithm_t alg )
1216{
1217 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1218
1219 operation->alg = alg;
1220 operation->key_set = 0;
1221 operation->iv_set = 0;
1222 operation->iv_required = 0;
1223 operation->has_input = 0;
1224 operation->key_usage_sign = 0;
1225 operation->key_usage_verify = 0;
1226
1227#if defined(MBEDTLS_CMAC_C)
1228 if( alg == PSA_ALG_CMAC )
1229 {
1230 operation->iv_required = 0;
1231 mbedtls_cipher_init( &operation->ctx.cmac );
1232 status = PSA_SUCCESS;
1233 }
1234 else
1235#endif /* MBEDTLS_CMAC_C */
1236#if defined(MBEDTLS_MD_C)
1237 if( PSA_ALG_IS_HMAC( operation->alg ) )
1238 {
1239 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1240 PSA_ALG_HMAC_HASH( alg ) );
1241 }
1242 else
1243#endif /* MBEDTLS_MD_C */
1244 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001245 if( ! PSA_ALG_IS_MAC( alg ) )
1246 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001247 }
1248
1249 if( status != PSA_SUCCESS )
1250 memset( operation, 0, sizeof( *operation ) );
1251 return( status );
1252}
1253
Gilles Peskine8c9def32018-02-08 10:02:12 +01001254psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1255{
1256 switch( operation->alg )
1257 {
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001258 case 0:
Gilles Peskine81736312018-06-26 15:04:31 +02001259 /* The object has (apparently) been initialized but it is not
1260 * in use. It's ok to call abort on such an object, and there's
1261 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001262 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001263#if defined(MBEDTLS_CMAC_C)
1264 case PSA_ALG_CMAC:
1265 mbedtls_cipher_free( &operation->ctx.cmac );
1266 break;
1267#endif /* MBEDTLS_CMAC_C */
1268 default:
1269#if defined(MBEDTLS_MD_C)
1270 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001271 {
Jaeden Amero5390f692018-06-26 14:18:50 +01001272 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001273 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001274
Gilles Peskine99bc6492018-06-11 17:13:00 +02001275 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001276 return( PSA_ERROR_NOT_SUPPORTED );
1277
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001278 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001279 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001280 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001281 else
1282#endif /* MBEDTLS_MD_C */
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001283 {
1284 /* Sanity check (shouldn't happen: operation->alg should
1285 * always have been initialized to a valid value). */
1286 return( PSA_ERROR_BAD_STATE );
1287 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001288 }
Moran Peker41deec42018-04-04 15:43:05 +03001289
Gilles Peskine8c9def32018-02-08 10:02:12 +01001290 operation->alg = 0;
1291 operation->key_set = 0;
1292 operation->iv_set = 0;
1293 operation->iv_required = 0;
1294 operation->has_input = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001295 operation->key_usage_sign = 0;
1296 operation->key_usage_verify = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001297
Gilles Peskine8c9def32018-02-08 10:02:12 +01001298 return( PSA_SUCCESS );
1299}
1300
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001301#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001302static int psa_cmac_start( psa_mac_operation_t *operation,
1303 size_t key_bits,
1304 key_slot_t *slot,
1305 const mbedtls_cipher_info_t *cipher_info )
1306{
1307 int ret;
1308
1309 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001310
1311 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1312 if( ret != 0 )
1313 return( ret );
1314
1315 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1316 slot->data.raw.data,
1317 key_bits );
1318 return( ret );
1319}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001320#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001321
Gilles Peskine248051a2018-06-20 16:09:38 +02001322#if defined(MBEDTLS_MD_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001323static int psa_hmac_start( psa_mac_operation_t *operation,
1324 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001325 key_slot_t *slot,
1326 psa_algorithm_t alg )
1327{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001328 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001329 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001330 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001331 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001332 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001333 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001334 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001335 size_t key_length = slot->data.raw.bytes;
1336 psa_status_t status;
1337
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001338 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001339 return( PSA_ERROR_NOT_SUPPORTED );
1340
1341 if( key_type != PSA_KEY_TYPE_HMAC )
1342 return( PSA_ERROR_INVALID_ARGUMENT );
1343
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001344 operation->mac_size = digest_size;
1345
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001346 /* The hash was started earlier in psa_mac_init. */
Gilles Peskined223b522018-06-11 18:12:58 +02001347 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001348 {
1349 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001350 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001351 if( status != PSA_SUCCESS )
1352 return( status );
1353 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001354 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001355 if( status != PSA_SUCCESS )
1356 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001357 }
Gilles Peskined223b522018-06-11 18:12:58 +02001358 else
1359 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001360
Gilles Peskined223b522018-06-11 18:12:58 +02001361 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1362 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001363 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001364 ipad[i] ^= 0x36;
1365 memset( ipad + key_length, 0x36, block_size - key_length );
1366
1367 /* Copy the key material from ipad to opad, flipping the requisite bits,
1368 * and filling the rest of opad with the requisite constant. */
1369 for( i = 0; i < key_length; i++ )
1370 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1371 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001372
1373 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1374 PSA_ALG_HMAC_HASH( alg ) );
1375 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001376 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001377
1378 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1379 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001380
1381cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001382 mbedtls_zeroize( ipad, key_length );
1383 /* opad is in the context. It needs to stay in memory if this function
1384 * succeeds, and it will be wiped by psa_mac_abort() called from
1385 * psa_mac_start in the error case. */
1386
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001387 return( status );
1388}
Gilles Peskine248051a2018-06-20 16:09:38 +02001389#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001390
Gilles Peskine8c9def32018-02-08 10:02:12 +01001391psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1392 psa_key_slot_t key,
1393 psa_algorithm_t alg )
1394{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001395 psa_status_t status;
1396 key_slot_t *slot;
1397 psa_key_type_t key_type;
1398 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001399 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001400
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001401 status = psa_mac_init( operation, alg );
1402 if( status != PSA_SUCCESS )
1403 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001404
1405 status = psa_get_key_information( key, &key_type, &key_bits );
1406 if( status != PSA_SUCCESS )
1407 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001408
Gilles Peskine8c9def32018-02-08 10:02:12 +01001409 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001410 if( slot->type == PSA_KEY_TYPE_NONE )
1411 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001412
Moran Pekerd7326592018-05-29 16:56:39 +03001413 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001414 operation->key_usage_sign = 1;
1415
Moran Pekerd7326592018-05-29 16:56:39 +03001416 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001417 operation->key_usage_verify = 1;
1418
Gilles Peskine8c9def32018-02-08 10:02:12 +01001419 if( ! PSA_ALG_IS_HMAC( alg ) )
1420 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001421 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001422 if( cipher_info == NULL )
1423 return( PSA_ERROR_NOT_SUPPORTED );
1424 operation->mac_size = cipher_info->block_size;
1425 }
1426 switch( alg )
1427 {
1428#if defined(MBEDTLS_CMAC_C)
1429 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001430 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1431 key_bits,
1432 slot,
1433 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001434 break;
1435#endif /* MBEDTLS_CMAC_C */
1436 default:
1437#if defined(MBEDTLS_MD_C)
1438 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001439 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001440 else
1441#endif /* MBEDTLS_MD_C */
1442 return( PSA_ERROR_NOT_SUPPORTED );
1443 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001444
Gilles Peskine8c9def32018-02-08 10:02:12 +01001445 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001446 * context may contain data that needs to be wiped on error. */
1447 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001448 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001449 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001450 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001451 else
1452 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001453 operation->key_set = 1;
1454 }
1455 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001456}
1457
1458psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1459 const uint8_t *input,
1460 size_t input_length )
1461{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001462 int ret = 0 ;
1463 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001464 if( ! operation->key_set )
1465 return( PSA_ERROR_BAD_STATE );
1466 if( operation->iv_required && ! operation->iv_set )
1467 return( PSA_ERROR_BAD_STATE );
1468 operation->has_input = 1;
1469
1470 switch( operation->alg )
1471 {
1472#if defined(MBEDTLS_CMAC_C)
1473 case PSA_ALG_CMAC:
1474 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1475 input, input_length );
1476 break;
1477#endif /* MBEDTLS_CMAC_C */
1478 default:
1479#if defined(MBEDTLS_MD_C)
1480 if( PSA_ALG_IS_HMAC( operation->alg ) )
1481 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001482 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001483 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001484 }
1485 else
1486#endif /* MBEDTLS_MD_C */
1487 {
1488 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1489 }
1490 break;
1491 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001492 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001493 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001494 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001495 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001496 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001497 }
1498
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001499 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001500}
1501
mohammad16036df908f2018-04-02 08:34:15 -07001502static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001503 uint8_t *mac,
1504 size_t mac_size,
1505 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001506{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001507 int ret = 0;
1508 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001509 if( ! operation->key_set )
1510 return( PSA_ERROR_BAD_STATE );
1511 if( operation->iv_required && ! operation->iv_set )
1512 return( PSA_ERROR_BAD_STATE );
1513
1514 /* Fill the output buffer with something that isn't a valid mac
1515 * (barring an attack on the mac and deliberately-crafted input),
1516 * in case the caller doesn't check the return status properly. */
1517 *mac_length = operation->mac_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001518 /* If mac_size is 0 then mac may be NULL and then the
1519 * call to memset would have undefined behavior. */
1520 if( mac_size != 0 )
1521 memset( mac, '!', mac_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001522
1523 if( mac_size < operation->mac_size )
1524 return( PSA_ERROR_BUFFER_TOO_SMALL );
1525
1526 switch( operation->alg )
1527 {
1528#if defined(MBEDTLS_CMAC_C)
1529 case PSA_ALG_CMAC:
1530 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1531 break;
1532#endif /* MBEDTLS_CMAC_C */
1533 default:
1534#if defined(MBEDTLS_MD_C)
1535 if( PSA_ALG_IS_HMAC( operation->alg ) )
1536 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001537 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001538 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001539 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001540 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001541 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001542
Gilles Peskine99bc6492018-06-11 17:13:00 +02001543 if( block_size == 0 )
1544 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001545
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001546 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001547 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001548 if( status != PSA_SUCCESS )
1549 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001550 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001551
1552 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1553 PSA_ALG_HMAC_HASH( operation->alg ) );
1554 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001555 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001556
1557 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001558 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001559 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001560 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001561
1562 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001563 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001564 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001565 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001566
1567 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1568 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001569 hmac_cleanup:
1570 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001571 }
1572 else
1573#endif /* MBEDTLS_MD_C */
1574 {
1575 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1576 }
1577 break;
1578 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001579cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001580
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001581 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001582 {
1583 return( psa_mac_abort( operation ) );
1584 }
1585 else
1586 {
1587 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001588 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001589 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001590
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001591 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001592 }
1593}
1594
mohammad16036df908f2018-04-02 08:34:15 -07001595psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1596 uint8_t *mac,
1597 size_t mac_size,
1598 size_t *mac_length )
1599{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001600 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001601 return( PSA_ERROR_NOT_PERMITTED );
1602
Gilles Peskine99bc6492018-06-11 17:13:00 +02001603 return( psa_mac_finish_internal( operation, mac,
1604 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001605}
1606
Gilles Peskine8c9def32018-02-08 10:02:12 +01001607psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1608 const uint8_t *mac,
1609 size_t mac_length )
1610{
Gilles Peskine828ed142018-06-18 23:25:51 +02001611 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001612 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001613 psa_status_t status;
1614
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001615 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001616 return( PSA_ERROR_NOT_PERMITTED );
1617
1618 status = psa_mac_finish_internal( operation,
1619 actual_mac, sizeof( actual_mac ),
1620 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001621 if( status != PSA_SUCCESS )
1622 return( status );
1623 if( actual_mac_length != mac_length )
1624 return( PSA_ERROR_INVALID_SIGNATURE );
1625 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1626 return( PSA_ERROR_INVALID_SIGNATURE );
1627 return( PSA_SUCCESS );
1628}
1629
1630
Gilles Peskine20035e32018-02-03 22:44:14 +01001631
Gilles Peskine20035e32018-02-03 22:44:14 +01001632/****************************************************************/
1633/* Asymmetric cryptography */
1634/****************************************************************/
1635
Gilles Peskine2b450e32018-06-27 15:42:46 +02001636#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001637/* Decode the hash algorithm from alg and store the mbedtls encoding in
1638 * md_alg. Verify that the hash length is consistent. */
1639static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1640 size_t hash_length,
1641 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001642{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02001643 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001644 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1645 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1646 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001647 {
1648#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001649 if( hash_length > UINT_MAX )
1650 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001651#endif
1652 }
1653 else
1654 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001655 if( mbedtls_md_get_size( md_info ) != hash_length )
1656 return( PSA_ERROR_INVALID_ARGUMENT );
1657 if( md_info == NULL )
1658 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001659 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001660 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001661}
1662
Gilles Peskine2b450e32018-06-27 15:42:46 +02001663static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
1664 psa_algorithm_t alg,
1665 const uint8_t *hash,
1666 size_t hash_length,
1667 uint8_t *signature,
1668 size_t signature_size,
1669 size_t *signature_length )
1670{
1671 psa_status_t status;
1672 int ret;
1673 mbedtls_md_type_t md_alg;
1674
1675 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1676 if( status != PSA_SUCCESS )
1677 return( status );
1678
1679 if( signature_size < rsa->len )
1680 return( PSA_ERROR_BUFFER_TOO_SMALL );
1681
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001682 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1683 * hash_length will fit and return an error if it doesn't. */
1684#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1685#if SIZE_MAX > UINT_MAX
1686 if( hash_length > UINT_MAX )
1687 return( PSA_ERROR_NOT_SUPPORTED );
1688#endif
1689#endif
1690
Gilles Peskine2b450e32018-06-27 15:42:46 +02001691#if defined(MBEDTLS_PKCS1_V15)
1692 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1693 {
1694 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1695 MBEDTLS_MD_NONE );
1696 ret = mbedtls_rsa_pkcs1_sign( rsa,
1697 mbedtls_ctr_drbg_random,
1698 &global_data.ctr_drbg,
1699 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001700 md_alg,
1701 (unsigned int) hash_length,
1702 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001703 signature );
1704 }
1705 else
1706#endif /* MBEDTLS_PKCS1_V15 */
1707#if defined(MBEDTLS_PKCS1_V21)
1708 if( PSA_ALG_IS_RSA_PSS( alg ) )
1709 {
1710 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1711 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1712 mbedtls_ctr_drbg_random,
1713 &global_data.ctr_drbg,
1714 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001715 md_alg,
1716 (unsigned int) hash_length,
1717 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001718 signature );
1719 }
1720 else
1721#endif /* MBEDTLS_PKCS1_V21 */
1722 {
1723 return( PSA_ERROR_INVALID_ARGUMENT );
1724 }
1725
1726 if( ret == 0 )
1727 *signature_length = rsa->len;
1728 return( mbedtls_to_psa_error( ret ) );
1729}
1730
1731static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
1732 psa_algorithm_t alg,
1733 const uint8_t *hash,
1734 size_t hash_length,
1735 const uint8_t *signature,
1736 size_t signature_length )
1737{
1738 psa_status_t status;
1739 int ret;
1740 mbedtls_md_type_t md_alg;
1741
1742 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1743 if( status != PSA_SUCCESS )
1744 return( status );
1745
1746 if( signature_length < rsa->len )
1747 return( PSA_ERROR_BUFFER_TOO_SMALL );
1748
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001749#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1750#if SIZE_MAX > UINT_MAX
1751 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1752 * hash_length will fit and return an error if it doesn't. */
1753 if( hash_length > UINT_MAX )
1754 return( PSA_ERROR_NOT_SUPPORTED );
1755#endif
1756#endif
1757
Gilles Peskine2b450e32018-06-27 15:42:46 +02001758#if defined(MBEDTLS_PKCS1_V15)
1759 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1760 {
1761 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1762 MBEDTLS_MD_NONE );
1763 ret = mbedtls_rsa_pkcs1_verify( rsa,
1764 mbedtls_ctr_drbg_random,
1765 &global_data.ctr_drbg,
1766 MBEDTLS_RSA_PUBLIC,
1767 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001768 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001769 hash,
1770 signature );
1771 }
1772 else
1773#endif /* MBEDTLS_PKCS1_V15 */
1774#if defined(MBEDTLS_PKCS1_V21)
1775 if( PSA_ALG_IS_RSA_PSS( alg ) )
1776 {
1777 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1778 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1779 mbedtls_ctr_drbg_random,
1780 &global_data.ctr_drbg,
1781 MBEDTLS_RSA_PUBLIC,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001782 md_alg,
1783 (unsigned int) hash_length,
1784 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001785 signature );
1786 }
1787 else
1788#endif /* MBEDTLS_PKCS1_V21 */
1789 {
1790 return( PSA_ERROR_INVALID_ARGUMENT );
1791 }
1792 return( mbedtls_to_psa_error( ret ) );
1793}
1794#endif /* MBEDTLS_RSA_C */
1795
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001796#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001797/* `ecp` cannot be const because `ecp->grp` needs to be non-const
1798 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
1799 * (even though these functions don't modify it). */
1800static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
1801 psa_algorithm_t alg,
1802 const uint8_t *hash,
1803 size_t hash_length,
1804 uint8_t *signature,
1805 size_t signature_size,
1806 size_t *signature_length )
1807{
1808 int ret;
1809 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001810 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001811 mbedtls_mpi_init( &r );
1812 mbedtls_mpi_init( &s );
1813
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001814 if( signature_size < 2 * curve_bytes )
1815 {
1816 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
1817 goto cleanup;
1818 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001819
1820 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
1821 {
1822 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
1823 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1824 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
1825 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
1826 hash, hash_length,
1827 md_alg ) );
1828 }
1829 else
1830 {
1831 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
1832 hash, hash_length,
1833 mbedtls_ctr_drbg_random,
1834 &global_data.ctr_drbg ) );
1835 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001836
1837 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
1838 signature,
1839 curve_bytes ) );
1840 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
1841 signature + curve_bytes,
1842 curve_bytes ) );
1843
1844cleanup:
1845 mbedtls_mpi_free( &r );
1846 mbedtls_mpi_free( &s );
1847 if( ret == 0 )
1848 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001849 return( mbedtls_to_psa_error( ret ) );
1850}
1851
1852static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
1853 const uint8_t *hash,
1854 size_t hash_length,
1855 const uint8_t *signature,
1856 size_t signature_length )
1857{
1858 int ret;
1859 mbedtls_mpi r, s;
1860 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
1861 mbedtls_mpi_init( &r );
1862 mbedtls_mpi_init( &s );
1863
1864 if( signature_length != 2 * curve_bytes )
1865 return( PSA_ERROR_INVALID_SIGNATURE );
1866
1867 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
1868 signature,
1869 curve_bytes ) );
1870 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
1871 signature + curve_bytes,
1872 curve_bytes ) );
1873
1874 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
1875 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001876
1877cleanup:
1878 mbedtls_mpi_free( &r );
1879 mbedtls_mpi_free( &s );
1880 return( mbedtls_to_psa_error( ret ) );
1881}
1882#endif /* MBEDTLS_ECDSA_C */
1883
Gilles Peskine61b91d42018-06-08 16:09:36 +02001884psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1885 psa_algorithm_t alg,
1886 const uint8_t *hash,
1887 size_t hash_length,
1888 const uint8_t *salt,
1889 size_t salt_length,
1890 uint8_t *signature,
1891 size_t signature_size,
1892 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001893{
1894 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001895 psa_status_t status;
1896
1897 *signature_length = signature_size;
1898
Gilles Peskine93aa0332018-02-03 23:58:03 +01001899 (void) salt;
1900 (void) salt_length;
1901
Gilles Peskine828ed142018-06-18 23:25:51 +02001902 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001903 {
1904 status = PSA_ERROR_EMPTY_SLOT;
1905 goto exit;
1906 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001907 slot = &global_data.key_slots[key];
1908 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001909 {
1910 status = PSA_ERROR_EMPTY_SLOT;
1911 goto exit;
1912 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001913 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001914 {
1915 status = PSA_ERROR_INVALID_ARGUMENT;
1916 goto exit;
1917 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001918 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001919 {
1920 status = PSA_ERROR_NOT_PERMITTED;
1921 goto exit;
1922 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001923
Gilles Peskine20035e32018-02-03 22:44:14 +01001924#if defined(MBEDTLS_RSA_C)
1925 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1926 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001927 status = psa_rsa_sign( slot->data.rsa,
1928 alg,
1929 hash, hash_length,
1930 signature, signature_size,
1931 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01001932 }
1933 else
1934#endif /* defined(MBEDTLS_RSA_C) */
1935#if defined(MBEDTLS_ECP_C)
1936 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1937 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001938#if defined(MBEDTLS_ECDSA_C)
1939 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001940 status = psa_ecdsa_sign( slot->data.ecp,
1941 alg,
1942 hash, hash_length,
1943 signature, signature_size,
1944 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001945 else
1946#endif /* defined(MBEDTLS_ECDSA_C) */
1947 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001948 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001949 }
itayzafrir5c753392018-05-08 11:18:38 +03001950 }
1951 else
1952#endif /* defined(MBEDTLS_ECP_C) */
1953 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001954 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01001955 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001956
1957exit:
1958 /* Fill the unused part of the output buffer (the whole buffer on error,
1959 * the trailing part on success) with something that isn't a valid mac
1960 * (barring an attack on the mac and deliberately-crafted input),
1961 * in case the caller doesn't check the return status properly. */
1962 if( status == PSA_SUCCESS )
1963 memset( signature + *signature_length, '!',
1964 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001965 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001966 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001967 /* If signature_size is 0 then we have nothing to do. We must not call
1968 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001969 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03001970}
1971
1972psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1973 psa_algorithm_t alg,
1974 const uint8_t *hash,
1975 size_t hash_length,
1976 const uint8_t *salt,
1977 size_t salt_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02001978 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02001979 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03001980{
1981 key_slot_t *slot;
Gilles Peskine2b450e32018-06-27 15:42:46 +02001982
itayzafrir5c753392018-05-08 11:18:38 +03001983 (void) salt;
1984 (void) salt_length;
1985
Gilles Peskine828ed142018-06-18 23:25:51 +02001986 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001987 return( PSA_ERROR_INVALID_ARGUMENT );
1988 slot = &global_data.key_slots[key];
1989 if( slot->type == PSA_KEY_TYPE_NONE )
1990 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001991 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001992 return( PSA_ERROR_NOT_PERMITTED );
1993
Gilles Peskine61b91d42018-06-08 16:09:36 +02001994#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001995 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1996 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001997 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02001998 return( psa_rsa_verify( slot->data.rsa,
1999 alg,
2000 hash, hash_length,
2001 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002002 }
2003 else
2004#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002005#if defined(MBEDTLS_ECP_C)
2006 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2007 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002008#if defined(MBEDTLS_ECDSA_C)
2009 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002010 return( psa_ecdsa_verify( slot->data.ecp,
2011 hash, hash_length,
2012 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002013 else
2014#endif /* defined(MBEDTLS_ECDSA_C) */
2015 {
2016 return( PSA_ERROR_INVALID_ARGUMENT );
2017 }
itayzafrir5c753392018-05-08 11:18:38 +03002018 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002019 else
2020#endif /* defined(MBEDTLS_ECP_C) */
2021 {
2022 return( PSA_ERROR_NOT_SUPPORTED );
2023 }
2024}
2025
Gilles Peskine61b91d42018-06-08 16:09:36 +02002026psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2027 psa_algorithm_t alg,
2028 const uint8_t *input,
2029 size_t input_length,
2030 const uint8_t *salt,
2031 size_t salt_length,
2032 uint8_t *output,
2033 size_t output_size,
2034 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002035{
2036 key_slot_t *slot;
2037 (void) salt;
2038 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002039 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002040
Gilles Peskine828ed142018-06-18 23:25:51 +02002041 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03002042 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002043 slot = &global_data.key_slots[key];
2044 if( slot->type == PSA_KEY_TYPE_NONE )
2045 return( PSA_ERROR_EMPTY_SLOT );
2046 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2047 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002048 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
2049 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002050
2051#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002052 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
2053 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002054 {
2055 mbedtls_rsa_context *rsa = slot->data.rsa;
2056 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002057 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002058 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002059#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002060 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002061 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002062 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2063 mbedtls_ctr_drbg_random,
2064 &global_data.ctr_drbg,
2065 MBEDTLS_RSA_PUBLIC,
2066 input_length,
2067 input,
2068 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002069 }
2070 else
2071#endif /* MBEDTLS_PKCS1_V15 */
2072#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002073 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002074 {
2075 return( PSA_ERROR_NOT_SUPPORTED );
2076 }
2077 else
2078#endif /* MBEDTLS_PKCS1_V21 */
2079 {
2080 return( PSA_ERROR_INVALID_ARGUMENT );
2081 }
2082 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002083 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002084 return( mbedtls_to_psa_error( ret ) );
2085 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002086 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002087#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002088 {
2089 return( PSA_ERROR_NOT_SUPPORTED );
2090 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002091}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002092
Gilles Peskine61b91d42018-06-08 16:09:36 +02002093psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2094 psa_algorithm_t alg,
2095 const uint8_t *input,
2096 size_t input_length,
2097 const uint8_t *salt,
2098 size_t salt_length,
2099 uint8_t *output,
2100 size_t output_size,
2101 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002102{
2103 key_slot_t *slot;
2104 (void) salt;
2105 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002106 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002107
Gilles Peskine828ed142018-06-18 23:25:51 +02002108 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002109 return( PSA_ERROR_EMPTY_SLOT );
2110 slot = &global_data.key_slots[key];
2111 if( slot->type == PSA_KEY_TYPE_NONE )
2112 return( PSA_ERROR_EMPTY_SLOT );
2113 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2114 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002115 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2116 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002117
2118#if defined(MBEDTLS_RSA_C)
2119 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2120 {
2121 mbedtls_rsa_context *rsa = slot->data.rsa;
2122 int ret;
2123
Gilles Peskinec4def2f2018-06-08 17:53:48 +02002124 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002125 return( PSA_ERROR_INVALID_ARGUMENT );
2126
2127#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002128 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002129 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002130 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2131 mbedtls_ctr_drbg_random,
2132 &global_data.ctr_drbg,
2133 MBEDTLS_RSA_PRIVATE,
2134 output_length,
2135 input,
2136 output,
2137 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002138 }
2139 else
2140#endif /* MBEDTLS_PKCS1_V15 */
2141#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002142 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002143 {
2144 return( PSA_ERROR_NOT_SUPPORTED );
2145 }
2146 else
2147#endif /* MBEDTLS_PKCS1_V21 */
2148 {
2149 return( PSA_ERROR_INVALID_ARGUMENT );
2150 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002151
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002152 return( mbedtls_to_psa_error( ret ) );
2153 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002154 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002155#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002156 {
2157 return( PSA_ERROR_NOT_SUPPORTED );
2158 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002159}
Gilles Peskine20035e32018-02-03 22:44:14 +01002160
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002161
2162
mohammad1603503973b2018-03-12 15:59:30 +02002163/****************************************************************/
2164/* Symmetric cryptography */
2165/****************************************************************/
2166
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002167/* Initialize the cipher operation structure. Once this function has been
2168 * called, psa_cipher_abort can run and will do the right thing. */
2169static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2170 psa_algorithm_t alg )
2171{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002172 if( ! PSA_ALG_IS_CIPHER( alg ) )
2173 {
2174 memset( operation, 0, sizeof( *operation ) );
2175 return( PSA_ERROR_INVALID_ARGUMENT );
2176 }
2177
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002178 operation->alg = alg;
2179 operation->key_set = 0;
2180 operation->iv_set = 0;
2181 operation->iv_required = 1;
2182 operation->iv_size = 0;
2183 operation->block_size = 0;
2184 mbedtls_cipher_init( &operation->ctx.cipher );
2185 return( PSA_SUCCESS );
2186}
2187
Gilles Peskinee553c652018-06-04 16:22:46 +02002188static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2189 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002190 psa_algorithm_t alg,
2191 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002192{
2193 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2194 psa_status_t status;
2195 key_slot_t *slot;
2196 psa_key_type_t key_type;
2197 size_t key_bits;
2198 const mbedtls_cipher_info_t *cipher_info = NULL;
2199
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002200 status = psa_cipher_init( operation, alg );
2201 if( status != PSA_SUCCESS )
2202 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002203
2204 status = psa_get_key_information( key, &key_type, &key_bits );
2205 if( status != PSA_SUCCESS )
2206 return( status );
2207 slot = &global_data.key_slots[key];
2208
Gilles Peskinebb1072f2018-06-08 18:46:05 +02002209 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002210 if( cipher_info == NULL )
2211 return( PSA_ERROR_NOT_SUPPORTED );
2212
mohammad1603503973b2018-03-12 15:59:30 +02002213 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002214 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002215 {
2216 psa_cipher_abort( operation );
2217 return( mbedtls_to_psa_error( ret ) );
2218 }
2219
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002220#if defined(MBEDTLS_DES_C)
2221 if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
2222 {
2223 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2224 unsigned char keys[24];
2225 memcpy( keys, slot->data.raw.data, 16 );
2226 memcpy( keys + 16, slot->data.raw.data, 8 );
2227 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2228 keys,
2229 192, cipher_operation );
2230 }
2231 else
2232#endif
2233 {
2234 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2235 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002236 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002237 }
Moran Peker41deec42018-04-04 15:43:05 +03002238 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002239 {
2240 psa_cipher_abort( operation );
2241 return( mbedtls_to_psa_error( ret ) );
2242 }
2243
mohammad16038481e742018-03-18 13:57:31 +02002244#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03002245 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02002246 {
Gilles Peskine53514202018-06-06 15:11:46 +02002247 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
2248 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02002249
Moran Pekera28258c2018-05-29 16:25:04 +03002250 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02002251 {
2252 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
2253 mode = MBEDTLS_PADDING_PKCS7;
2254 break;
2255 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
2256 mode = MBEDTLS_PADDING_NONE;
2257 break;
2258 default:
Moran Pekerae382792018-05-31 14:06:17 +03002259 psa_cipher_abort( operation );
2260 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02002261 }
2262 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03002263 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03002264 {
2265 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02002266 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03002267 }
mohammad16038481e742018-03-18 13:57:31 +02002268 }
2269#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2270
mohammad1603503973b2018-03-12 15:59:30 +02002271 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002272 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
2273 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
2274 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002275 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002276 {
mohammad160389e0f462018-04-12 08:48:45 +03002277 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02002278 }
mohammad1603503973b2018-03-12 15:59:30 +02002279
Moran Peker395db872018-05-31 14:07:14 +03002280 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002281}
2282
Gilles Peskinee553c652018-06-04 16:22:46 +02002283psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
2284 psa_key_slot_t key,
2285 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002286{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002287 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002288}
2289
Gilles Peskinee553c652018-06-04 16:22:46 +02002290psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
2291 psa_key_slot_t key,
2292 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002293{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002294 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002295}
2296
Gilles Peskinee553c652018-06-04 16:22:46 +02002297psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
2298 unsigned char *iv,
2299 size_t iv_size,
2300 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002301{
Moran Peker41deec42018-04-04 15:43:05 +03002302 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002303 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002304 return( PSA_ERROR_BAD_STATE );
2305 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002306 {
Moran Peker41deec42018-04-04 15:43:05 +03002307 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2308 goto exit;
2309 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002310 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2311 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002312 if( ret != 0 )
2313 {
2314 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002315 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002316 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002317
mohammad16038481e742018-03-18 13:57:31 +02002318 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03002319 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002320
Moran Peker395db872018-05-31 14:07:14 +03002321exit:
2322 if( ret != PSA_SUCCESS )
2323 psa_cipher_abort( operation );
2324 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002325}
2326
Gilles Peskinee553c652018-06-04 16:22:46 +02002327psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
2328 const unsigned char *iv,
2329 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002330{
Moran Peker41deec42018-04-04 15:43:05 +03002331 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002332 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002333 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002334 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002335 {
Moran Pekerae382792018-05-31 14:06:17 +03002336 psa_cipher_abort( operation );
2337 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002338 }
mohammad1603503973b2018-03-12 15:59:30 +02002339 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002340 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002341 {
2342 psa_cipher_abort( operation );
2343 return( mbedtls_to_psa_error( ret ) );
2344 }
2345
2346 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002347
Moran Peker395db872018-05-31 14:07:14 +03002348 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002349}
2350
Gilles Peskinee553c652018-06-04 16:22:46 +02002351psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2352 const uint8_t *input,
2353 size_t input_length,
2354 unsigned char *output,
2355 size_t output_size,
2356 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002357{
2358 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002359 size_t expected_output_size;
2360 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2361 {
2362 /* Take the unprocessed partial block left over from previous
2363 * update calls, if any, plus the input to this call. Remove
2364 * the last partial block, if any. You get the data that will be
2365 * output in this call. */
2366 expected_output_size =
2367 ( operation->ctx.cipher.unprocessed_len + input_length )
2368 / operation->block_size * operation->block_size;
2369 }
2370 else
2371 {
2372 expected_output_size = input_length;
2373 }
2374 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002375 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002376
mohammad1603503973b2018-03-12 15:59:30 +02002377 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002378 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002379 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002380 {
2381 psa_cipher_abort( operation );
2382 return( mbedtls_to_psa_error( ret ) );
2383 }
2384
Moran Peker395db872018-05-31 14:07:14 +03002385 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002386}
2387
Gilles Peskinee553c652018-06-04 16:22:46 +02002388psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2389 uint8_t *output,
2390 size_t output_size,
2391 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002392{
2393 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002394 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002395
mohammad1603503973b2018-03-12 15:59:30 +02002396 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002397 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002398 psa_cipher_abort( operation );
2399 return( PSA_ERROR_BAD_STATE );
2400 }
2401 if( operation->iv_required && ! operation->iv_set )
2402 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002403 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002404 return( PSA_ERROR_BAD_STATE );
2405 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002406 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2407 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002408 {
Gilles Peskine53514202018-06-06 15:11:46 +02002409 psa_algorithm_t padding_mode =
2410 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002411 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002412 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002413 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002414 return( PSA_ERROR_TAMPERING_DETECTED );
2415 }
Gilles Peskine53514202018-06-06 15:11:46 +02002416 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002417 {
2418 if( operation->ctx.cipher.unprocessed_len != 0 )
2419 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002420 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002421 return( PSA_ERROR_INVALID_ARGUMENT );
2422 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002423 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002424 }
2425
2426 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002427 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002428 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002429 {
2430 psa_cipher_abort( operation );
2431 return( mbedtls_to_psa_error( ret ) );
2432 }
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002433 if( *output_length == 0 )
2434 /* Nothing to copy. Note that output may be NULL in this case. */ ;
2435 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002436 memcpy( output, temp_output_buffer, *output_length );
2437 else
2438 {
2439 psa_cipher_abort( operation );
2440 return( PSA_ERROR_BUFFER_TOO_SMALL );
2441 }
mohammad1603503973b2018-03-12 15:59:30 +02002442
Moran Peker4c80d832018-04-22 20:15:31 +03002443 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002444}
2445
Gilles Peskinee553c652018-06-04 16:22:46 +02002446psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2447{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002448 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002449 {
2450 /* The object has (apparently) been initialized but it is not
2451 * in use. It's ok to call abort on such an object, and there's
2452 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002453 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002454 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002455
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002456 /* Sanity check (shouldn't happen: operation->alg should
2457 * always have been initialized to a valid value). */
2458 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2459 return( PSA_ERROR_BAD_STATE );
2460
mohammad1603503973b2018-03-12 15:59:30 +02002461 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002462
Moran Peker41deec42018-04-04 15:43:05 +03002463 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002464 operation->key_set = 0;
2465 operation->iv_set = 0;
2466 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002467 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002468 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002469
Moran Peker395db872018-05-31 14:07:14 +03002470 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002471}
2472
Gilles Peskinea0655c32018-04-30 17:06:50 +02002473
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002474
mohammad16038cc1cee2018-03-28 01:21:33 +03002475/****************************************************************/
2476/* Key Policy */
2477/****************************************************************/
2478
Gilles Peskine2d277862018-06-18 15:41:12 +02002479void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002480{
Gilles Peskine803ce742018-06-18 16:07:14 +02002481 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002482}
2483
Gilles Peskine2d277862018-06-18 15:41:12 +02002484void psa_key_policy_set_usage( psa_key_policy_t *policy,
2485 psa_key_usage_t usage,
2486 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002487{
mohammad16034eed7572018-03-28 05:14:59 -07002488 policy->usage = usage;
2489 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002490}
2491
Gilles Peskine2d277862018-06-18 15:41:12 +02002492psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002493{
mohammad16036df908f2018-04-02 08:34:15 -07002494 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002495}
2496
Gilles Peskine2d277862018-06-18 15:41:12 +02002497psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002498{
mohammad16036df908f2018-04-02 08:34:15 -07002499 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002500}
2501
Gilles Peskine2d277862018-06-18 15:41:12 +02002502psa_status_t psa_set_key_policy( psa_key_slot_t key,
2503 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002504{
2505 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002506
Gilles Peskine828ed142018-06-18 23:25:51 +02002507 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002508 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002509
mohammad16038cc1cee2018-03-28 01:21:33 +03002510 slot = &global_data.key_slots[key];
2511 if( slot->type != PSA_KEY_TYPE_NONE )
2512 return( PSA_ERROR_OCCUPIED_SLOT );
2513
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002514 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2515 PSA_KEY_USAGE_ENCRYPT |
2516 PSA_KEY_USAGE_DECRYPT |
2517 PSA_KEY_USAGE_SIGN |
2518 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002519 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002520
mohammad16036df908f2018-04-02 08:34:15 -07002521 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002522
2523 return( PSA_SUCCESS );
2524}
2525
Gilles Peskine2d277862018-06-18 15:41:12 +02002526psa_status_t psa_get_key_policy( psa_key_slot_t key,
2527 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002528{
2529 key_slot_t *slot;
2530
Gilles Peskine828ed142018-06-18 23:25:51 +02002531 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002532 return( PSA_ERROR_INVALID_ARGUMENT );
2533
2534 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002535
mohammad16036df908f2018-04-02 08:34:15 -07002536 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002537
2538 return( PSA_SUCCESS );
2539}
Gilles Peskine20035e32018-02-03 22:44:14 +01002540
Gilles Peskinea0655c32018-04-30 17:06:50 +02002541
2542
mohammad1603804cd712018-03-20 22:44:08 +02002543/****************************************************************/
2544/* Key Lifetime */
2545/****************************************************************/
2546
Gilles Peskine2d277862018-06-18 15:41:12 +02002547psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2548 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002549{
2550 key_slot_t *slot;
2551
Gilles Peskine828ed142018-06-18 23:25:51 +02002552 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002553 return( PSA_ERROR_INVALID_ARGUMENT );
2554
2555 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002556
mohammad1603804cd712018-03-20 22:44:08 +02002557 *lifetime = slot->lifetime;
2558
2559 return( PSA_SUCCESS );
2560}
2561
Gilles Peskine2d277862018-06-18 15:41:12 +02002562psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01002563 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002564{
2565 key_slot_t *slot;
2566
Gilles Peskine828ed142018-06-18 23:25:51 +02002567 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002568 return( PSA_ERROR_INVALID_ARGUMENT );
2569
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002570 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2571 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002572 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2573 return( PSA_ERROR_INVALID_ARGUMENT );
2574
mohammad1603804cd712018-03-20 22:44:08 +02002575 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002576 if( slot->type != PSA_KEY_TYPE_NONE )
2577 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002578
Moran Pekerd7326592018-05-29 16:56:39 +03002579 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002580 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002581
mohammad1603060ad8a2018-03-20 14:28:38 -07002582 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002583
2584 return( PSA_SUCCESS );
2585}
2586
Gilles Peskine20035e32018-02-03 22:44:14 +01002587
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002588
mohammad16035955c982018-04-26 00:53:03 +03002589/****************************************************************/
2590/* AEAD */
2591/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002592
mohammad16035955c982018-04-26 00:53:03 +03002593psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2594 psa_algorithm_t alg,
2595 const uint8_t *nonce,
2596 size_t nonce_length,
2597 const uint8_t *additional_data,
2598 size_t additional_data_length,
2599 const uint8_t *plaintext,
2600 size_t plaintext_length,
2601 uint8_t *ciphertext,
2602 size_t ciphertext_size,
2603 size_t *ciphertext_length )
2604{
2605 int ret;
2606 psa_status_t status;
2607 key_slot_t *slot;
2608 psa_key_type_t key_type;
2609 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002610 uint8_t *tag;
2611 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002612 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002613 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002614
mohammad1603f08a5502018-06-03 15:05:47 +03002615 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002616
mohammad16035955c982018-04-26 00:53:03 +03002617 status = psa_get_key_information( key, &key_type, &key_bits );
2618 if( status != PSA_SUCCESS )
2619 return( status );
2620 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002621 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002622 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002623
mohammad16035ed06212018-06-06 13:09:34 +03002624 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2625 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002626 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002627 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002628
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002629 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002630 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002631
Gilles Peskine2d277862018-06-18 15:41:12 +02002632 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2633 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002634 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002635
mohammad16035955c982018-04-26 00:53:03 +03002636 if( alg == PSA_ALG_GCM )
2637 {
2638 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002639 tag_length = 16;
2640
mohammad160396910d82018-06-04 14:33:00 +03002641 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2642 return( PSA_ERROR_INVALID_ARGUMENT );
2643
mohammad160315223a82018-06-03 17:19:55 +03002644 //make sure we have place to hold the tag in the ciphertext buffer
2645 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002646 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002647
2648 //update the tag pointer to point to the end of the ciphertext_length
2649 tag = ciphertext + plaintext_length;
2650
mohammad16035955c982018-04-26 00:53:03 +03002651 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002652 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002653 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002654 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002655 if( ret != 0 )
2656 {
2657 mbedtls_gcm_free( &gcm );
2658 return( mbedtls_to_psa_error( ret ) );
2659 }
2660 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002661 plaintext_length, nonce,
2662 nonce_length, additional_data,
2663 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002664 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002665 mbedtls_gcm_free( &gcm );
2666 }
2667 else if( alg == PSA_ALG_CCM )
2668 {
2669 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002670 tag_length = 16;
2671
mohammad160396910d82018-06-04 14:33:00 +03002672 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2673 return( PSA_ERROR_INVALID_ARGUMENT );
2674
mohammad160347ddf3d2018-04-26 01:11:21 +03002675 if( nonce_length < 7 || nonce_length > 13 )
2676 return( PSA_ERROR_INVALID_ARGUMENT );
2677
mohammad160315223a82018-06-03 17:19:55 +03002678 //make sure we have place to hold the tag in the ciphertext buffer
2679 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002680 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002681
2682 //update the tag pointer to point to the end of the ciphertext_length
2683 tag = ciphertext + plaintext_length;
2684
mohammad16035955c982018-04-26 00:53:03 +03002685 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002686 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002687 slot->data.raw.data,
2688 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002689 if( ret != 0 )
2690 {
2691 mbedtls_ccm_free( &ccm );
2692 return( mbedtls_to_psa_error( ret ) );
2693 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002694 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002695 nonce, nonce_length,
2696 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002697 additional_data_length,
2698 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002699 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002700 mbedtls_ccm_free( &ccm );
2701 }
mohammad16035c8845f2018-05-09 05:40:09 -07002702 else
2703 {
mohammad1603554faad2018-06-03 15:07:38 +03002704 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002705 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002706
mohammad160315223a82018-06-03 17:19:55 +03002707 if( ret != 0 )
2708 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002709 /* If ciphertext_size is 0 then ciphertext may be NULL and then the
2710 * call to memset would have undefined behavior. */
2711 if( ciphertext_size != 0 )
2712 memset( ciphertext, 0, ciphertext_size );
mohammad160315223a82018-06-03 17:19:55 +03002713 return( mbedtls_to_psa_error( ret ) );
2714 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002715
mohammad160315223a82018-06-03 17:19:55 +03002716 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002717 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002718}
2719
Gilles Peskineee652a32018-06-01 19:23:52 +02002720/* Locate the tag in a ciphertext buffer containing the encrypted data
2721 * followed by the tag. Return the length of the part preceding the tag in
2722 * *plaintext_length. This is the size of the plaintext in modes where
2723 * the encrypted data has the same size as the plaintext, such as
2724 * CCM and GCM. */
2725static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2726 const uint8_t *ciphertext,
2727 size_t ciphertext_length,
2728 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002729 const uint8_t **p_tag )
2730{
2731 size_t payload_length;
2732 if( tag_length > ciphertext_length )
2733 return( PSA_ERROR_INVALID_ARGUMENT );
2734 payload_length = ciphertext_length - tag_length;
2735 if( payload_length > plaintext_size )
2736 return( PSA_ERROR_BUFFER_TOO_SMALL );
2737 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002738 return( PSA_SUCCESS );
2739}
2740
mohammad16035955c982018-04-26 00:53:03 +03002741psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2742 psa_algorithm_t alg,
2743 const uint8_t *nonce,
2744 size_t nonce_length,
2745 const uint8_t *additional_data,
2746 size_t additional_data_length,
2747 const uint8_t *ciphertext,
2748 size_t ciphertext_length,
2749 uint8_t *plaintext,
2750 size_t plaintext_size,
2751 size_t *plaintext_length )
2752{
2753 int ret;
2754 psa_status_t status;
2755 key_slot_t *slot;
2756 psa_key_type_t key_type;
2757 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002758 const uint8_t *tag;
2759 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002760 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002761 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002762
Gilles Peskineee652a32018-06-01 19:23:52 +02002763 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002764
mohammad16035955c982018-04-26 00:53:03 +03002765 status = psa_get_key_information( key, &key_type, &key_bits );
2766 if( status != PSA_SUCCESS )
2767 return( status );
2768 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002769 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002770 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002771
mohammad16035ed06212018-06-06 13:09:34 +03002772 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2773 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002774 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002775 return( PSA_ERROR_NOT_SUPPORTED );
2776
mohammad1603f14394b2018-06-04 14:33:19 +03002777 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2778 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002779
Gilles Peskine2d277862018-06-18 15:41:12 +02002780 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2781 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002782 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002783
mohammad16035955c982018-04-26 00:53:03 +03002784 if( alg == PSA_ALG_GCM )
2785 {
2786 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002787
Gilles Peskineee652a32018-06-01 19:23:52 +02002788 tag_length = 16;
2789 status = psa_aead_unpadded_locate_tag( tag_length,
2790 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002791 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002792 if( status != PSA_SUCCESS )
2793 return( status );
2794
mohammad16035955c982018-04-26 00:53:03 +03002795 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002796 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002797 slot->data.raw.data,
2798 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002799 if( ret != 0 )
2800 {
2801 mbedtls_gcm_free( &gcm );
2802 return( mbedtls_to_psa_error( ret ) );
2803 }
mohammad16035955c982018-04-26 00:53:03 +03002804
Gilles Peskineee652a32018-06-01 19:23:52 +02002805 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002806 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002807 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002808 additional_data,
2809 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002810 tag, tag_length,
2811 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002812 mbedtls_gcm_free( &gcm );
2813 }
2814 else if( alg == PSA_ALG_CCM )
2815 {
2816 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002817
mohammad160347ddf3d2018-04-26 01:11:21 +03002818 if( nonce_length < 7 || nonce_length > 13 )
2819 return( PSA_ERROR_INVALID_ARGUMENT );
2820
mohammad16039375f842018-06-03 14:28:24 +03002821 tag_length = 16;
2822 status = psa_aead_unpadded_locate_tag( tag_length,
2823 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002824 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002825 if( status != PSA_SUCCESS )
2826 return( status );
2827
mohammad16035955c982018-04-26 00:53:03 +03002828 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002829 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002830 slot->data.raw.data,
2831 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002832 if( ret != 0 )
2833 {
2834 mbedtls_ccm_free( &ccm );
2835 return( mbedtls_to_psa_error( ret ) );
2836 }
mohammad160360a64d02018-06-03 17:20:42 +03002837 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002838 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002839 additional_data,
2840 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002841 ciphertext, plaintext,
2842 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002843 mbedtls_ccm_free( &ccm );
2844 }
mohammad160339574652018-06-01 04:39:53 -07002845 else
2846 {
mohammad1603554faad2018-06-03 15:07:38 +03002847 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002848 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002849
Gilles Peskineee652a32018-06-01 19:23:52 +02002850 if( ret != 0 )
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002851 {
2852 /* If plaintext_size is 0 then plaintext may be NULL and then the
2853 * call to memset has undefined behavior. */
2854 if( plaintext_size != 0 )
2855 memset( plaintext, 0, plaintext_size );
2856 }
mohammad160360a64d02018-06-03 17:20:42 +03002857 else
2858 *plaintext_length = ciphertext_length - tag_length;
2859
Gilles Peskineee652a32018-06-01 19:23:52 +02002860 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002861}
2862
Gilles Peskinea0655c32018-04-30 17:06:50 +02002863
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002864
Gilles Peskine20035e32018-02-03 22:44:14 +01002865/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002866/* Key generation */
2867/****************************************************************/
2868
2869psa_status_t psa_generate_random( uint8_t *output,
2870 size_t output_size )
2871{
2872 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2873 output, output_size );
2874 return( mbedtls_to_psa_error( ret ) );
2875}
2876
2877psa_status_t psa_generate_key( psa_key_slot_t key,
2878 psa_key_type_t type,
2879 size_t bits,
2880 const void *parameters,
2881 size_t parameters_size )
2882{
Gilles Peskine12313cd2018-06-20 00:20:32 +02002883 key_slot_t *slot;
2884
2885 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
2886 return( PSA_ERROR_INVALID_ARGUMENT );
2887 slot = &global_data.key_slots[key];
2888 if( slot->type != PSA_KEY_TYPE_NONE )
2889 return( PSA_ERROR_OCCUPIED_SLOT );
2890 if( parameters == NULL && parameters_size != 0 )
2891 return( PSA_ERROR_INVALID_ARGUMENT );
2892
Gilles Peskine48c0ea12018-06-21 14:15:31 +02002893 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02002894 {
2895 psa_status_t status = prepare_raw_data_slot( type, bits,
2896 &slot->data.raw );
2897 if( status != PSA_SUCCESS )
2898 return( status );
2899 status = psa_generate_random( slot->data.raw.data,
2900 slot->data.raw.bytes );
2901 if( status != PSA_SUCCESS )
2902 {
2903 mbedtls_free( slot->data.raw.data );
2904 return( status );
2905 }
2906#if defined(MBEDTLS_DES_C)
2907 if( type == PSA_KEY_TYPE_DES )
2908 {
2909 mbedtls_des_key_set_parity( slot->data.raw.data );
2910 if( slot->data.raw.bytes >= 16 )
2911 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
2912 if( slot->data.raw.bytes == 24 )
2913 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
2914 }
2915#endif /* MBEDTLS_DES_C */
2916 }
2917 else
2918
2919#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
2920 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
2921 {
2922 mbedtls_rsa_context *rsa;
2923 int ret;
2924 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02002925 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
2926 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine12313cd2018-06-20 00:20:32 +02002927 if( parameters != NULL )
2928 {
2929 const unsigned *p = parameters;
2930 if( parameters_size != sizeof( *p ) )
2931 return( PSA_ERROR_INVALID_ARGUMENT );
2932 if( *p > INT_MAX )
2933 return( PSA_ERROR_INVALID_ARGUMENT );
2934 exponent = *p;
2935 }
2936 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
2937 if( rsa == NULL )
2938 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2939 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
2940 ret = mbedtls_rsa_gen_key( rsa,
2941 mbedtls_ctr_drbg_random,
2942 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002943 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02002944 exponent );
2945 if( ret != 0 )
2946 {
2947 mbedtls_rsa_free( rsa );
2948 mbedtls_free( rsa );
2949 return( mbedtls_to_psa_error( ret ) );
2950 }
2951 slot->data.rsa = rsa;
2952 }
2953 else
2954#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
2955
2956#if defined(MBEDTLS_ECP_C)
2957 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
2958 {
2959 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
2960 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
2961 const mbedtls_ecp_curve_info *curve_info =
2962 mbedtls_ecp_curve_info_from_grp_id( grp_id );
2963 mbedtls_ecp_keypair *ecp;
2964 int ret;
2965 if( parameters != NULL )
2966 return( PSA_ERROR_NOT_SUPPORTED );
2967 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
2968 return( PSA_ERROR_NOT_SUPPORTED );
2969 if( curve_info->bit_size != bits )
2970 return( PSA_ERROR_INVALID_ARGUMENT );
2971 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
2972 if( ecp == NULL )
2973 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2974 mbedtls_ecp_keypair_init( ecp );
2975 ret = mbedtls_ecp_gen_key( grp_id, ecp,
2976 mbedtls_ctr_drbg_random,
2977 &global_data.ctr_drbg );
2978 if( ret != 0 )
2979 {
2980 mbedtls_ecp_keypair_free( ecp );
2981 mbedtls_free( ecp );
2982 return( mbedtls_to_psa_error( ret ) );
2983 }
2984 slot->data.ecp = ecp;
2985 }
2986 else
2987#endif /* MBEDTLS_ECP_C */
2988
2989 return( PSA_ERROR_NOT_SUPPORTED );
2990
2991 slot->type = type;
2992 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02002993}
2994
2995
2996/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002997/* Module setup */
2998/****************************************************************/
2999
Gilles Peskinee59236f2018-01-27 23:32:46 +01003000void mbedtls_psa_crypto_free( void )
3001{
Jaeden Amero045bd502018-06-26 14:00:08 +01003002 psa_key_slot_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02003003 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003004 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003005 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
3006 mbedtls_entropy_free( &global_data.entropy );
3007 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3008}
3009
3010psa_status_t psa_crypto_init( void )
3011{
3012 int ret;
3013 const unsigned char drbg_seed[] = "PSA";
3014
3015 if( global_data.initialized != 0 )
3016 return( PSA_SUCCESS );
3017
3018 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3019 mbedtls_entropy_init( &global_data.entropy );
3020 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
3021
3022 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
3023 mbedtls_entropy_func,
3024 &global_data.entropy,
3025 drbg_seed, sizeof( drbg_seed ) - 1 );
3026 if( ret != 0 )
3027 goto exit;
3028
Gilles Peskinee4ebc122018-03-07 14:16:44 +01003029 global_data.initialized = 1;
3030
Gilles Peskinee59236f2018-01-27 23:32:46 +01003031exit:
3032 if( ret != 0 )
3033 mbedtls_psa_crypto_free( );
3034 return( mbedtls_to_psa_error( ret ) );
3035}
3036
3037#endif /* MBEDTLS_PSA_CRYPTO_C */