blob: a2f68975b79f806aaecb1842189239d320a49e02 [file] [log] [blame]
Gilles Peskinee59236f2018-01-27 23:32:46 +01001/*
2 * PSA crypto layer on top of Mbed TLS crypto
3 */
4/* Copyright (C) 2018, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PSA_CRYPTO_C)
29
30#include "psa/crypto.h"
31
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010032#include <stdlib.h>
33#include <string.h>
34#if defined(MBEDTLS_PLATFORM_C)
35#include "mbedtls/platform.h"
36#else
37#define mbedtls_calloc calloc
38#define mbedtls_free free
39#endif
40
Gilles Peskinea5905292018-02-07 20:59:33 +010041#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020042#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020043#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010044#include "mbedtls/blowfish.h"
45#include "mbedtls/camellia.h"
46#include "mbedtls/cipher.h"
47#include "mbedtls/ccm.h"
48#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010049#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010050#include "mbedtls/des.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010051#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010052#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010053#include "mbedtls/error.h"
54#include "mbedtls/gcm.h"
55#include "mbedtls/md2.h"
56#include "mbedtls/md4.h"
57#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010058#include "mbedtls/md.h"
59#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010060#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010061#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010062#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010063#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010064#include "mbedtls/sha1.h"
65#include "mbedtls/sha256.h"
66#include "mbedtls/sha512.h"
67#include "mbedtls/xtea.h"
68
Gilles Peskinee59236f2018-01-27 23:32:46 +010069
70
71/* Implementation that should never be optimized out by the compiler */
72static void mbedtls_zeroize( void *v, size_t n )
73{
74 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
75}
76
Gilles Peskine9ef733f2018-02-07 21:05:37 +010077/* constant-time buffer comparison */
78static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
79{
80 size_t i;
81 unsigned char diff = 0;
82
83 for( i = 0; i < n; i++ )
84 diff |= a[i] ^ b[i];
85
86 return( diff );
87}
88
89
90
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010091/****************************************************************/
92/* Global data, support functions and library management */
93/****************************************************************/
94
95/* Number of key slots (plus one because 0 is not used).
96 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +020097#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010098
Gilles Peskine2d277862018-06-18 15:41:12 +020099typedef struct
100{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100101 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300102 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200103 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200104 union
105 {
106 struct raw_data
107 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100108 uint8_t *data;
109 size_t bytes;
110 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100111#if defined(MBEDTLS_RSA_C)
112 mbedtls_rsa_context *rsa;
113#endif /* MBEDTLS_RSA_C */
114#if defined(MBEDTLS_ECP_C)
115 mbedtls_ecp_keypair *ecp;
116#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100117 } data;
118} key_slot_t;
119
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200120static int key_type_is_raw_bytes( psa_key_type_t type )
121{
122 psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
123 return( category == PSA_KEY_TYPE_RAW_DATA ||
124 category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
125}
126
Gilles Peskine2d277862018-06-18 15:41:12 +0200127typedef struct
128{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100129 int initialized;
130 mbedtls_entropy_context entropy;
131 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200132 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100133} psa_global_data_t;
134
135static psa_global_data_t global_data;
136
137static psa_status_t mbedtls_to_psa_error( int ret )
138{
Gilles Peskinea5905292018-02-07 20:59:33 +0100139 /* If there's both a high-level code and low-level code, dispatch on
140 * the high-level code. */
141 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100142 {
143 case 0:
144 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100145
146 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
147 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
148 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
149 return( PSA_ERROR_NOT_SUPPORTED );
150 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
151 return( PSA_ERROR_HARDWARE_FAILURE );
152
153 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
154 return( PSA_ERROR_HARDWARE_FAILURE );
155
Gilles Peskine9a944802018-06-21 09:35:35 +0200156 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
157 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
158 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
159 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
160 case MBEDTLS_ERR_ASN1_INVALID_DATA:
161 return( PSA_ERROR_INVALID_ARGUMENT );
162 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
163 return( PSA_ERROR_INSUFFICIENT_MEMORY );
164 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
165 return( PSA_ERROR_BUFFER_TOO_SMALL );
166
Gilles Peskinea5905292018-02-07 20:59:33 +0100167 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
168 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
169 return( PSA_ERROR_NOT_SUPPORTED );
170 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
171 return( PSA_ERROR_HARDWARE_FAILURE );
172
173 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
174 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
175 return( PSA_ERROR_NOT_SUPPORTED );
176 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
177 return( PSA_ERROR_HARDWARE_FAILURE );
178
179 case MBEDTLS_ERR_CCM_BAD_INPUT:
180 return( PSA_ERROR_INVALID_ARGUMENT );
181 case MBEDTLS_ERR_CCM_AUTH_FAILED:
182 return( PSA_ERROR_INVALID_SIGNATURE );
183 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
184 return( PSA_ERROR_HARDWARE_FAILURE );
185
186 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
187 return( PSA_ERROR_NOT_SUPPORTED );
188 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
189 return( PSA_ERROR_INVALID_ARGUMENT );
190 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
191 return( PSA_ERROR_INSUFFICIENT_MEMORY );
192 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
193 return( PSA_ERROR_INVALID_PADDING );
194 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
195 return( PSA_ERROR_BAD_STATE );
196 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
197 return( PSA_ERROR_INVALID_SIGNATURE );
198 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
199 return( PSA_ERROR_TAMPERING_DETECTED );
200 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
201 return( PSA_ERROR_HARDWARE_FAILURE );
202
203 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
204 return( PSA_ERROR_HARDWARE_FAILURE );
205
206 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
207 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
208 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
209 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
210 return( PSA_ERROR_NOT_SUPPORTED );
211 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
212 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
213
214 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
215 return( PSA_ERROR_NOT_SUPPORTED );
216 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
217 return( PSA_ERROR_HARDWARE_FAILURE );
218
Gilles Peskinee59236f2018-01-27 23:32:46 +0100219 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
220 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
221 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
222 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100223
224 case MBEDTLS_ERR_GCM_AUTH_FAILED:
225 return( PSA_ERROR_INVALID_SIGNATURE );
226 case MBEDTLS_ERR_GCM_BAD_INPUT:
227 return( PSA_ERROR_NOT_SUPPORTED );
228 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
229 return( PSA_ERROR_HARDWARE_FAILURE );
230
231 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
232 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
233 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
234 return( PSA_ERROR_HARDWARE_FAILURE );
235
236 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
237 return( PSA_ERROR_NOT_SUPPORTED );
238 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
239 return( PSA_ERROR_INVALID_ARGUMENT );
240 case MBEDTLS_ERR_MD_ALLOC_FAILED:
241 return( PSA_ERROR_INSUFFICIENT_MEMORY );
242 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
243 return( PSA_ERROR_STORAGE_FAILURE );
244 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
245 return( PSA_ERROR_HARDWARE_FAILURE );
246
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100247 case MBEDTLS_ERR_PK_ALLOC_FAILED:
248 return( PSA_ERROR_INSUFFICIENT_MEMORY );
249 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
250 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
251 return( PSA_ERROR_INVALID_ARGUMENT );
252 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100253 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100254 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
255 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
256 return( PSA_ERROR_INVALID_ARGUMENT );
257 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
258 return( PSA_ERROR_NOT_SUPPORTED );
259 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
260 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
261 return( PSA_ERROR_NOT_PERMITTED );
262 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
263 return( PSA_ERROR_INVALID_ARGUMENT );
264 case MBEDTLS_ERR_PK_INVALID_ALG:
265 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
266 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
267 return( PSA_ERROR_NOT_SUPPORTED );
268 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
269 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100270 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
271 return( PSA_ERROR_HARDWARE_FAILURE );
272
273 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
274 return( PSA_ERROR_HARDWARE_FAILURE );
275
276 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
277 return( PSA_ERROR_INVALID_ARGUMENT );
278 case MBEDTLS_ERR_RSA_INVALID_PADDING:
279 return( PSA_ERROR_INVALID_PADDING );
280 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
281 return( PSA_ERROR_HARDWARE_FAILURE );
282 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
283 return( PSA_ERROR_INVALID_ARGUMENT );
284 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
285 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
286 return( PSA_ERROR_TAMPERING_DETECTED );
287 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
288 return( PSA_ERROR_INVALID_SIGNATURE );
289 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
290 return( PSA_ERROR_BUFFER_TOO_SMALL );
291 case MBEDTLS_ERR_RSA_RNG_FAILED:
292 return( PSA_ERROR_INSUFFICIENT_MEMORY );
293 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
294 return( PSA_ERROR_NOT_SUPPORTED );
295 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
296 return( PSA_ERROR_HARDWARE_FAILURE );
297
298 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
299 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
300 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
301 return( PSA_ERROR_HARDWARE_FAILURE );
302
303 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
304 return( PSA_ERROR_INVALID_ARGUMENT );
305 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
306 return( PSA_ERROR_HARDWARE_FAILURE );
307
itayzafrir5c753392018-05-08 11:18:38 +0300308 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300309 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300310 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300311 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
312 return( PSA_ERROR_BUFFER_TOO_SMALL );
313 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
314 return( PSA_ERROR_NOT_SUPPORTED );
315 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
316 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
317 return( PSA_ERROR_INVALID_SIGNATURE );
318 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
319 return( PSA_ERROR_INSUFFICIENT_MEMORY );
320 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
321 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300322
Gilles Peskinee59236f2018-01-27 23:32:46 +0100323 default:
324 return( PSA_ERROR_UNKNOWN_ERROR );
325 }
326}
327
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200328
329
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100330/****************************************************************/
331/* Key management */
332/****************************************************************/
333
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200334static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
335{
336 switch( grpid )
337 {
338 case MBEDTLS_ECP_DP_SECP192R1:
339 return( PSA_ECC_CURVE_SECP192R1 );
340 case MBEDTLS_ECP_DP_SECP224R1:
341 return( PSA_ECC_CURVE_SECP224R1 );
342 case MBEDTLS_ECP_DP_SECP256R1:
343 return( PSA_ECC_CURVE_SECP256R1 );
344 case MBEDTLS_ECP_DP_SECP384R1:
345 return( PSA_ECC_CURVE_SECP384R1 );
346 case MBEDTLS_ECP_DP_SECP521R1:
347 return( PSA_ECC_CURVE_SECP521R1 );
348 case MBEDTLS_ECP_DP_BP256R1:
349 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
350 case MBEDTLS_ECP_DP_BP384R1:
351 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
352 case MBEDTLS_ECP_DP_BP512R1:
353 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
354 case MBEDTLS_ECP_DP_CURVE25519:
355 return( PSA_ECC_CURVE_CURVE25519 );
356 case MBEDTLS_ECP_DP_SECP192K1:
357 return( PSA_ECC_CURVE_SECP192K1 );
358 case MBEDTLS_ECP_DP_SECP224K1:
359 return( PSA_ECC_CURVE_SECP224K1 );
360 case MBEDTLS_ECP_DP_SECP256K1:
361 return( PSA_ECC_CURVE_SECP256K1 );
362 case MBEDTLS_ECP_DP_CURVE448:
363 return( PSA_ECC_CURVE_CURVE448 );
364 default:
365 return( 0 );
366 }
367}
368
Gilles Peskine12313cd2018-06-20 00:20:32 +0200369static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
370{
371 switch( curve )
372 {
373 case PSA_ECC_CURVE_SECP192R1:
374 return( MBEDTLS_ECP_DP_SECP192R1 );
375 case PSA_ECC_CURVE_SECP224R1:
376 return( MBEDTLS_ECP_DP_SECP224R1 );
377 case PSA_ECC_CURVE_SECP256R1:
378 return( MBEDTLS_ECP_DP_SECP256R1 );
379 case PSA_ECC_CURVE_SECP384R1:
380 return( MBEDTLS_ECP_DP_SECP384R1 );
381 case PSA_ECC_CURVE_SECP521R1:
382 return( MBEDTLS_ECP_DP_SECP521R1 );
383 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
384 return( MBEDTLS_ECP_DP_BP256R1 );
385 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
386 return( MBEDTLS_ECP_DP_BP384R1 );
387 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
388 return( MBEDTLS_ECP_DP_BP512R1 );
389 case PSA_ECC_CURVE_CURVE25519:
390 return( MBEDTLS_ECP_DP_CURVE25519 );
391 case PSA_ECC_CURVE_SECP192K1:
392 return( MBEDTLS_ECP_DP_SECP192K1 );
393 case PSA_ECC_CURVE_SECP224K1:
394 return( MBEDTLS_ECP_DP_SECP224K1 );
395 case PSA_ECC_CURVE_SECP256K1:
396 return( MBEDTLS_ECP_DP_SECP256K1 );
397 case PSA_ECC_CURVE_CURVE448:
398 return( MBEDTLS_ECP_DP_CURVE448 );
399 default:
400 return( MBEDTLS_ECP_DP_NONE );
401 }
402}
403
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200404static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
405 size_t bits,
406 struct raw_data *raw )
407{
408 /* Check that the bit size is acceptable for the key type */
409 switch( type )
410 {
411 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200412 if( bits == 0 )
413 {
414 raw->bytes = 0;
415 raw->data = NULL;
416 return( PSA_SUCCESS );
417 }
418 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200419#if defined(MBEDTLS_MD_C)
420 case PSA_KEY_TYPE_HMAC:
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200421 break;
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200422#endif
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200423#if defined(MBEDTLS_AES_C)
424 case PSA_KEY_TYPE_AES:
425 if( bits != 128 && bits != 192 && bits != 256 )
426 return( PSA_ERROR_INVALID_ARGUMENT );
427 break;
428#endif
429#if defined(MBEDTLS_CAMELLIA_C)
430 case PSA_KEY_TYPE_CAMELLIA:
431 if( bits != 128 && bits != 192 && bits != 256 )
432 return( PSA_ERROR_INVALID_ARGUMENT );
433 break;
434#endif
435#if defined(MBEDTLS_DES_C)
436 case PSA_KEY_TYPE_DES:
437 if( bits != 64 && bits != 128 && bits != 192 )
438 return( PSA_ERROR_INVALID_ARGUMENT );
439 break;
440#endif
441#if defined(MBEDTLS_ARC4_C)
442 case PSA_KEY_TYPE_ARC4:
443 if( bits < 8 || bits > 2048 )
444 return( PSA_ERROR_INVALID_ARGUMENT );
445 break;
446#endif
447 default:
448 return( PSA_ERROR_NOT_SUPPORTED );
449 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200450 if( bits % 8 != 0 )
451 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200452
453 /* Allocate memory for the key */
454 raw->bytes = PSA_BITS_TO_BYTES( bits );
455 raw->data = mbedtls_calloc( 1, raw->bytes );
456 if( raw->data == NULL )
457 {
458 raw->bytes = 0;
459 return( PSA_ERROR_INSUFFICIENT_MEMORY );
460 }
461 return( PSA_SUCCESS );
462}
463
Gilles Peskine2d277862018-06-18 15:41:12 +0200464psa_status_t psa_import_key( psa_key_slot_t key,
465 psa_key_type_t type,
466 const uint8_t *data,
467 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100468{
469 key_slot_t *slot;
470
Gilles Peskine828ed142018-06-18 23:25:51 +0200471 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100472 return( PSA_ERROR_INVALID_ARGUMENT );
473 slot = &global_data.key_slots[key];
474 if( slot->type != PSA_KEY_TYPE_NONE )
475 return( PSA_ERROR_OCCUPIED_SLOT );
476
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200477 if( key_type_is_raw_bytes( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100478 {
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200479 psa_status_t status;
Gilles Peskine6d912132018-03-07 16:41:37 +0100480 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100481 if( data_length > SIZE_MAX / 8 )
482 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200483 status = prepare_raw_data_slot( type,
484 PSA_BYTES_TO_BITS( data_length ),
485 &slot->data.raw );
486 if( status != PSA_SUCCESS )
487 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200488 if( data_length != 0 )
489 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100490 }
491 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100492#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100493 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
494 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
495 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100496 {
497 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100498 mbedtls_pk_context pk;
Gilles Peskinec648d692018-06-28 08:46:13 +0200499 psa_status_t status = PSA_SUCCESS;
Gilles Peskine969ac722018-01-28 18:16:59 +0100500 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100501 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
502 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
503 else
504 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100505 if( ret != 0 )
506 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100507 switch( mbedtls_pk_get_type( &pk ) )
508 {
509#if defined(MBEDTLS_RSA_C)
510 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100511 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
512 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskineaf3baab2018-06-27 22:55:52 +0200513 {
514 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( pk );
515 size_t bits = mbedtls_rsa_get_bitlen( rsa );
516 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
Gilles Peskine1ae05142018-06-30 17:46:59 +0200517 {
518 status = PSA_ERROR_NOT_SUPPORTED;
519 break;
520 }
Gilles Peskineaf3baab2018-06-27 22:55:52 +0200521 slot->data.rsa = rsa;
522 }
Gilles Peskine969ac722018-01-28 18:16:59 +0100523 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200524 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100525 break;
526#endif /* MBEDTLS_RSA_C */
527#if defined(MBEDTLS_ECP_C)
528 case MBEDTLS_PK_ECKEY:
529 if( PSA_KEY_TYPE_IS_ECC( type ) )
530 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200531 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
532 psa_ecc_curve_t actual_curve =
533 mbedtls_ecc_group_to_psa( ecp->grp.id );
534 psa_ecc_curve_t expected_curve =
535 PSA_KEY_TYPE_GET_CURVE( type );
536 if( actual_curve != expected_curve )
Gilles Peskinec648d692018-06-28 08:46:13 +0200537 {
538 status = PSA_ERROR_INVALID_ARGUMENT;
539 break;
540 }
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200541 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100542 }
543 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200544 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100545 break;
546#endif /* MBEDTLS_ECP_C */
547 default:
Gilles Peskinec648d692018-06-28 08:46:13 +0200548 status = PSA_ERROR_INVALID_ARGUMENT;
549 break;
550 }
551 /* Free the content of the pk object only on error. On success,
552 * the content of the object has been stored in the slot. */
553 if( status != PSA_SUCCESS )
554 {
555 mbedtls_pk_free( &pk );
556 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100557 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100558 }
559 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100560#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100561 {
562 return( PSA_ERROR_NOT_SUPPORTED );
563 }
564
565 slot->type = type;
566 return( PSA_SUCCESS );
567}
568
Gilles Peskine2d277862018-06-18 15:41:12 +0200569psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100570{
571 key_slot_t *slot;
572
Gilles Peskine828ed142018-06-18 23:25:51 +0200573 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100574 return( PSA_ERROR_INVALID_ARGUMENT );
575 slot = &global_data.key_slots[key];
576 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200577 {
578 /* No key material to clean, but do zeroize the slot below to wipe
579 * metadata such as policies. */
580 }
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200581 else if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100582 {
583 mbedtls_free( slot->data.raw.data );
584 }
585 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100586#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100587 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
588 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100589 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100590 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100591 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100592 }
593 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100594#endif /* defined(MBEDTLS_RSA_C) */
595#if defined(MBEDTLS_ECP_C)
596 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
597 {
598 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100599 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100600 }
601 else
602#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100603 {
604 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100605 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100606 return( PSA_ERROR_TAMPERING_DETECTED );
607 }
608
609 mbedtls_zeroize( slot, sizeof( *slot ) );
610 return( PSA_SUCCESS );
611}
612
Gilles Peskine2d277862018-06-18 15:41:12 +0200613psa_status_t psa_get_key_information( psa_key_slot_t key,
614 psa_key_type_t *type,
615 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100616{
617 key_slot_t *slot;
618
Gilles Peskine828ed142018-06-18 23:25:51 +0200619 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100620 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100621 slot = &global_data.key_slots[key];
622 if( type != NULL )
623 *type = slot->type;
624 if( bits != NULL )
625 *bits = 0;
626 if( slot->type == PSA_KEY_TYPE_NONE )
627 return( PSA_ERROR_EMPTY_SLOT );
628
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200629 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100630 {
631 if( bits != NULL )
632 *bits = slot->data.raw.bytes * 8;
633 }
634 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100635#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100636 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
637 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100638 {
639 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100640 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100641 }
642 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100643#endif /* defined(MBEDTLS_RSA_C) */
644#if defined(MBEDTLS_ECP_C)
645 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
646 {
647 if( bits != NULL )
648 *bits = slot->data.ecp->grp.pbits;
649 }
650 else
651#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100652 {
653 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100654 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100655 return( PSA_ERROR_TAMPERING_DETECTED );
656 }
657
658 return( PSA_SUCCESS );
659}
660
Gilles Peskine2d277862018-06-18 15:41:12 +0200661static psa_status_t psa_internal_export_key( psa_key_slot_t key,
662 uint8_t *data,
663 size_t data_size,
664 size_t *data_length,
665 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100666{
667 key_slot_t *slot;
668
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100669 /* Set the key to empty now, so that even when there are errors, we always
670 * set data_length to a value between 0 and data_size. On error, setting
671 * the key to empty is a good choice because an empty key representation is
672 * unlikely to be accepted anywhere. */
673 *data_length = 0;
674
Gilles Peskine828ed142018-06-18 23:25:51 +0200675 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100676 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100677 slot = &global_data.key_slots[key];
678 if( slot->type == PSA_KEY_TYPE_NONE )
679 return( PSA_ERROR_EMPTY_SLOT );
680
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200681 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300682 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300683
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200684 if( ! export_public_key &&
685 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
686 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300687 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200688
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200689 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100690 {
691 if( slot->data.raw.bytes > data_size )
692 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200693 if( slot->data.raw.bytes != 0 )
694 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100695 *data_length = slot->data.raw.bytes;
696 return( PSA_SUCCESS );
697 }
698 else
Moran Peker17e36e12018-05-02 12:55:20 +0300699 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100700#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100701 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300702 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
703 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100704 {
Moran Pekera998bc62018-04-16 18:16:20 +0300705 mbedtls_pk_context pk;
706 int ret;
707 mbedtls_pk_init( &pk );
708 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
709 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
710 {
711 pk.pk_info = &mbedtls_rsa_info;
712 pk.pk_ctx = slot->data.rsa;
713 }
714 else
715 {
716 pk.pk_info = &mbedtls_eckey_info;
717 pk.pk_ctx = slot->data.ecp;
718 }
Moran Pekerd7326592018-05-29 16:56:39 +0300719 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300720 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300721 else
722 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300723 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200724 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200725 /* If data_size is 0 then data may be NULL and then the
726 * call to memset would have undefined behavior. */
727 if( data_size != 0 )
728 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300729 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200730 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200731 /* The mbedtls_pk_xxx functions write to the end of the buffer.
732 * Move the data to the beginning and erase remaining data
733 * at the original location. */
734 if( 2 * (size_t) ret <= data_size )
735 {
736 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200737 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200738 }
739 else if( (size_t) ret < data_size )
740 {
741 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200742 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200743 }
Moran Pekera998bc62018-04-16 18:16:20 +0300744 *data_length = ret;
745 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100746 }
747 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100748#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300749 {
750 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200751 it is valid for a special-purpose implementation to omit
752 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300753 return( PSA_ERROR_NOT_SUPPORTED );
754 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100755 }
756}
757
Gilles Peskine2d277862018-06-18 15:41:12 +0200758psa_status_t psa_export_key( psa_key_slot_t key,
759 uint8_t *data,
760 size_t data_size,
761 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300762{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200763 return( psa_internal_export_key( key, data, data_size,
764 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100765}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100766
Gilles Peskine2d277862018-06-18 15:41:12 +0200767psa_status_t psa_export_public_key( psa_key_slot_t key,
768 uint8_t *data,
769 size_t data_size,
770 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300771{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200772 return( psa_internal_export_key( key, data, data_size,
773 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300774}
775
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200776
777
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100778/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100779/* Message digests */
780/****************************************************************/
781
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100782static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100783{
784 switch( alg )
785 {
786#if defined(MBEDTLS_MD2_C)
787 case PSA_ALG_MD2:
788 return( &mbedtls_md2_info );
789#endif
790#if defined(MBEDTLS_MD4_C)
791 case PSA_ALG_MD4:
792 return( &mbedtls_md4_info );
793#endif
794#if defined(MBEDTLS_MD5_C)
795 case PSA_ALG_MD5:
796 return( &mbedtls_md5_info );
797#endif
798#if defined(MBEDTLS_RIPEMD160_C)
799 case PSA_ALG_RIPEMD160:
800 return( &mbedtls_ripemd160_info );
801#endif
802#if defined(MBEDTLS_SHA1_C)
803 case PSA_ALG_SHA_1:
804 return( &mbedtls_sha1_info );
805#endif
806#if defined(MBEDTLS_SHA256_C)
807 case PSA_ALG_SHA_224:
808 return( &mbedtls_sha224_info );
809 case PSA_ALG_SHA_256:
810 return( &mbedtls_sha256_info );
811#endif
812#if defined(MBEDTLS_SHA512_C)
813 case PSA_ALG_SHA_384:
814 return( &mbedtls_sha384_info );
815 case PSA_ALG_SHA_512:
816 return( &mbedtls_sha512_info );
817#endif
818 default:
819 return( NULL );
820 }
821}
822
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100823psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
824{
825 switch( operation->alg )
826 {
Gilles Peskine81736312018-06-26 15:04:31 +0200827 case 0:
828 /* The object has (apparently) been initialized but it is not
829 * in use. It's ok to call abort on such an object, and there's
830 * nothing to do. */
831 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100832#if defined(MBEDTLS_MD2_C)
833 case PSA_ALG_MD2:
834 mbedtls_md2_free( &operation->ctx.md2 );
835 break;
836#endif
837#if defined(MBEDTLS_MD4_C)
838 case PSA_ALG_MD4:
839 mbedtls_md4_free( &operation->ctx.md4 );
840 break;
841#endif
842#if defined(MBEDTLS_MD5_C)
843 case PSA_ALG_MD5:
844 mbedtls_md5_free( &operation->ctx.md5 );
845 break;
846#endif
847#if defined(MBEDTLS_RIPEMD160_C)
848 case PSA_ALG_RIPEMD160:
849 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
850 break;
851#endif
852#if defined(MBEDTLS_SHA1_C)
853 case PSA_ALG_SHA_1:
854 mbedtls_sha1_free( &operation->ctx.sha1 );
855 break;
856#endif
857#if defined(MBEDTLS_SHA256_C)
858 case PSA_ALG_SHA_224:
859 case PSA_ALG_SHA_256:
860 mbedtls_sha256_free( &operation->ctx.sha256 );
861 break;
862#endif
863#if defined(MBEDTLS_SHA512_C)
864 case PSA_ALG_SHA_384:
865 case PSA_ALG_SHA_512:
866 mbedtls_sha512_free( &operation->ctx.sha512 );
867 break;
868#endif
869 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +0200870 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100871 }
872 operation->alg = 0;
873 return( PSA_SUCCESS );
874}
875
876psa_status_t psa_hash_start( psa_hash_operation_t *operation,
877 psa_algorithm_t alg )
878{
879 int ret;
880 operation->alg = 0;
881 switch( alg )
882 {
883#if defined(MBEDTLS_MD2_C)
884 case PSA_ALG_MD2:
885 mbedtls_md2_init( &operation->ctx.md2 );
886 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
887 break;
888#endif
889#if defined(MBEDTLS_MD4_C)
890 case PSA_ALG_MD4:
891 mbedtls_md4_init( &operation->ctx.md4 );
892 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
893 break;
894#endif
895#if defined(MBEDTLS_MD5_C)
896 case PSA_ALG_MD5:
897 mbedtls_md5_init( &operation->ctx.md5 );
898 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
899 break;
900#endif
901#if defined(MBEDTLS_RIPEMD160_C)
902 case PSA_ALG_RIPEMD160:
903 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
904 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
905 break;
906#endif
907#if defined(MBEDTLS_SHA1_C)
908 case PSA_ALG_SHA_1:
909 mbedtls_sha1_init( &operation->ctx.sha1 );
910 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
911 break;
912#endif
913#if defined(MBEDTLS_SHA256_C)
914 case PSA_ALG_SHA_224:
915 mbedtls_sha256_init( &operation->ctx.sha256 );
916 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
917 break;
918 case PSA_ALG_SHA_256:
919 mbedtls_sha256_init( &operation->ctx.sha256 );
920 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
921 break;
922#endif
923#if defined(MBEDTLS_SHA512_C)
924 case PSA_ALG_SHA_384:
925 mbedtls_sha512_init( &operation->ctx.sha512 );
926 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
927 break;
928 case PSA_ALG_SHA_512:
929 mbedtls_sha512_init( &operation->ctx.sha512 );
930 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
931 break;
932#endif
933 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +0200934 return( PSA_ALG_IS_HASH( alg ) ?
935 PSA_ERROR_NOT_SUPPORTED :
936 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100937 }
938 if( ret == 0 )
939 operation->alg = alg;
940 else
941 psa_hash_abort( operation );
942 return( mbedtls_to_psa_error( ret ) );
943}
944
945psa_status_t psa_hash_update( psa_hash_operation_t *operation,
946 const uint8_t *input,
947 size_t input_length )
948{
949 int ret;
950 switch( operation->alg )
951 {
952#if defined(MBEDTLS_MD2_C)
953 case PSA_ALG_MD2:
954 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
955 input, input_length );
956 break;
957#endif
958#if defined(MBEDTLS_MD4_C)
959 case PSA_ALG_MD4:
960 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
961 input, input_length );
962 break;
963#endif
964#if defined(MBEDTLS_MD5_C)
965 case PSA_ALG_MD5:
966 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
967 input, input_length );
968 break;
969#endif
970#if defined(MBEDTLS_RIPEMD160_C)
971 case PSA_ALG_RIPEMD160:
972 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
973 input, input_length );
974 break;
975#endif
976#if defined(MBEDTLS_SHA1_C)
977 case PSA_ALG_SHA_1:
978 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
979 input, input_length );
980 break;
981#endif
982#if defined(MBEDTLS_SHA256_C)
983 case PSA_ALG_SHA_224:
984 case PSA_ALG_SHA_256:
985 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
986 input, input_length );
987 break;
988#endif
989#if defined(MBEDTLS_SHA512_C)
990 case PSA_ALG_SHA_384:
991 case PSA_ALG_SHA_512:
992 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
993 input, input_length );
994 break;
995#endif
996 default:
997 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
998 break;
999 }
1000 if( ret != 0 )
1001 psa_hash_abort( operation );
1002 return( mbedtls_to_psa_error( ret ) );
1003}
1004
1005psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1006 uint8_t *hash,
1007 size_t hash_size,
1008 size_t *hash_length )
1009{
1010 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001011 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001012
1013 /* Fill the output buffer with something that isn't a valid hash
1014 * (barring an attack on the hash and deliberately-crafted input),
1015 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001016 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001017 /* If hash_size is 0 then hash may be NULL and then the
1018 * call to memset would have undefined behavior. */
1019 if( hash_size != 0 )
1020 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001021
1022 if( hash_size < actual_hash_length )
1023 return( PSA_ERROR_BUFFER_TOO_SMALL );
1024
1025 switch( operation->alg )
1026 {
1027#if defined(MBEDTLS_MD2_C)
1028 case PSA_ALG_MD2:
1029 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1030 break;
1031#endif
1032#if defined(MBEDTLS_MD4_C)
1033 case PSA_ALG_MD4:
1034 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1035 break;
1036#endif
1037#if defined(MBEDTLS_MD5_C)
1038 case PSA_ALG_MD5:
1039 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1040 break;
1041#endif
1042#if defined(MBEDTLS_RIPEMD160_C)
1043 case PSA_ALG_RIPEMD160:
1044 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1045 break;
1046#endif
1047#if defined(MBEDTLS_SHA1_C)
1048 case PSA_ALG_SHA_1:
1049 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1050 break;
1051#endif
1052#if defined(MBEDTLS_SHA256_C)
1053 case PSA_ALG_SHA_224:
1054 case PSA_ALG_SHA_256:
1055 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1056 break;
1057#endif
1058#if defined(MBEDTLS_SHA512_C)
1059 case PSA_ALG_SHA_384:
1060 case PSA_ALG_SHA_512:
1061 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1062 break;
1063#endif
1064 default:
1065 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1066 break;
1067 }
1068
1069 if( ret == 0 )
1070 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001071 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001072 return( psa_hash_abort( operation ) );
1073 }
1074 else
1075 {
1076 psa_hash_abort( operation );
1077 return( mbedtls_to_psa_error( ret ) );
1078 }
1079}
1080
Gilles Peskine2d277862018-06-18 15:41:12 +02001081psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1082 const uint8_t *hash,
1083 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001084{
1085 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1086 size_t actual_hash_length;
1087 psa_status_t status = psa_hash_finish( operation,
1088 actual_hash, sizeof( actual_hash ),
1089 &actual_hash_length );
1090 if( status != PSA_SUCCESS )
1091 return( status );
1092 if( actual_hash_length != hash_length )
1093 return( PSA_ERROR_INVALID_SIGNATURE );
1094 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1095 return( PSA_ERROR_INVALID_SIGNATURE );
1096 return( PSA_SUCCESS );
1097}
1098
1099
1100
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001101/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001102/* MAC */
1103/****************************************************************/
1104
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001105static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001106 psa_algorithm_t alg,
1107 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001108 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001109 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001110{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001111 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001112 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001113
1114 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1115 {
1116 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001117 {
1118 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1119 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001120
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001121 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001122 {
1123 case PSA_ALG_STREAM_CIPHER:
1124 mode = MBEDTLS_MODE_STREAM;
1125 break;
1126 case PSA_ALG_CBC_BASE:
1127 mode = MBEDTLS_MODE_CBC;
1128 break;
1129 case PSA_ALG_CFB_BASE:
1130 mode = MBEDTLS_MODE_CFB;
1131 break;
1132 case PSA_ALG_OFB_BASE:
1133 mode = MBEDTLS_MODE_OFB;
1134 break;
1135 case PSA_ALG_CTR:
1136 mode = MBEDTLS_MODE_CTR;
1137 break;
1138 case PSA_ALG_CCM:
1139 mode = MBEDTLS_MODE_CCM;
1140 break;
1141 case PSA_ALG_GCM:
1142 mode = MBEDTLS_MODE_GCM;
1143 break;
1144 default:
1145 return( NULL );
1146 }
1147 }
1148 else if( alg == PSA_ALG_CMAC )
1149 mode = MBEDTLS_MODE_ECB;
1150 else if( alg == PSA_ALG_GMAC )
1151 mode = MBEDTLS_MODE_GCM;
1152 else
1153 return( NULL );
1154
1155 switch( key_type )
1156 {
1157 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001158 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001159 break;
1160 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001161 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1162 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001163 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001164 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001165 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001166 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001167 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1168 * but two-key Triple-DES is functionally three-key Triple-DES
1169 * with K1=K3, so that's how we present it to mbedtls. */
1170 if( key_bits == 128 )
1171 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001172 break;
1173 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001174 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001175 break;
1176 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001177 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001178 break;
1179 default:
1180 return( NULL );
1181 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001182 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001183 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001184
Jaeden Amero23bbb752018-06-26 14:16:54 +01001185 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1186 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001187}
1188
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001189static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001190{
Gilles Peskine2d277862018-06-18 15:41:12 +02001191 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001192 {
1193 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001194 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001195 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001196 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001197 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001198 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001199 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001200 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001201 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001202 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001203 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001204 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001205 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001206 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001207 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001208 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001209 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001210 return( 128 );
1211 default:
1212 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001213 }
1214}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001215
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001216/* Initialize the MAC operation structure. Once this function has been
1217 * called, psa_mac_abort can run and will do the right thing. */
1218static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1219 psa_algorithm_t alg )
1220{
1221 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1222
1223 operation->alg = alg;
1224 operation->key_set = 0;
1225 operation->iv_set = 0;
1226 operation->iv_required = 0;
1227 operation->has_input = 0;
1228 operation->key_usage_sign = 0;
1229 operation->key_usage_verify = 0;
1230
1231#if defined(MBEDTLS_CMAC_C)
1232 if( alg == PSA_ALG_CMAC )
1233 {
1234 operation->iv_required = 0;
1235 mbedtls_cipher_init( &operation->ctx.cmac );
1236 status = PSA_SUCCESS;
1237 }
1238 else
1239#endif /* MBEDTLS_CMAC_C */
1240#if defined(MBEDTLS_MD_C)
1241 if( PSA_ALG_IS_HMAC( operation->alg ) )
1242 {
1243 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1244 PSA_ALG_HMAC_HASH( alg ) );
1245 }
1246 else
1247#endif /* MBEDTLS_MD_C */
1248 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001249 if( ! PSA_ALG_IS_MAC( alg ) )
1250 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001251 }
1252
1253 if( status != PSA_SUCCESS )
1254 memset( operation, 0, sizeof( *operation ) );
1255 return( status );
1256}
1257
Gilles Peskine8c9def32018-02-08 10:02:12 +01001258psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1259{
1260 switch( operation->alg )
1261 {
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001262 case 0:
Gilles Peskine81736312018-06-26 15:04:31 +02001263 /* The object has (apparently) been initialized but it is not
1264 * in use. It's ok to call abort on such an object, and there's
1265 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001266 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001267#if defined(MBEDTLS_CMAC_C)
1268 case PSA_ALG_CMAC:
1269 mbedtls_cipher_free( &operation->ctx.cmac );
1270 break;
1271#endif /* MBEDTLS_CMAC_C */
1272 default:
1273#if defined(MBEDTLS_MD_C)
1274 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001275 {
Jaeden Amero5390f692018-06-26 14:18:50 +01001276 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001277 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001278
Gilles Peskine99bc6492018-06-11 17:13:00 +02001279 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001280 return( PSA_ERROR_NOT_SUPPORTED );
1281
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001282 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001283 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001284 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001285 else
1286#endif /* MBEDTLS_MD_C */
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001287 {
1288 /* Sanity check (shouldn't happen: operation->alg should
1289 * always have been initialized to a valid value). */
1290 return( PSA_ERROR_BAD_STATE );
1291 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001292 }
Moran Peker41deec42018-04-04 15:43:05 +03001293
Gilles Peskine8c9def32018-02-08 10:02:12 +01001294 operation->alg = 0;
1295 operation->key_set = 0;
1296 operation->iv_set = 0;
1297 operation->iv_required = 0;
1298 operation->has_input = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001299 operation->key_usage_sign = 0;
1300 operation->key_usage_verify = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001301
Gilles Peskine8c9def32018-02-08 10:02:12 +01001302 return( PSA_SUCCESS );
1303}
1304
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001305#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001306static int psa_cmac_start( psa_mac_operation_t *operation,
1307 size_t key_bits,
1308 key_slot_t *slot,
1309 const mbedtls_cipher_info_t *cipher_info )
1310{
1311 int ret;
1312
1313 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001314
1315 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1316 if( ret != 0 )
1317 return( ret );
1318
1319 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1320 slot->data.raw.data,
1321 key_bits );
1322 return( ret );
1323}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001324#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001325
Gilles Peskine248051a2018-06-20 16:09:38 +02001326#if defined(MBEDTLS_MD_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001327static int psa_hmac_start( psa_mac_operation_t *operation,
1328 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001329 key_slot_t *slot,
1330 psa_algorithm_t alg )
1331{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001332 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001333 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001334 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001335 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001336 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001337 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001338 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001339 size_t key_length = slot->data.raw.bytes;
1340 psa_status_t status;
1341
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001342 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001343 return( PSA_ERROR_NOT_SUPPORTED );
1344
1345 if( key_type != PSA_KEY_TYPE_HMAC )
1346 return( PSA_ERROR_INVALID_ARGUMENT );
1347
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001348 operation->mac_size = digest_size;
1349
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001350 /* The hash was started earlier in psa_mac_init. */
Gilles Peskined223b522018-06-11 18:12:58 +02001351 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001352 {
1353 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001354 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001355 if( status != PSA_SUCCESS )
1356 return( status );
1357 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001358 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001359 if( status != PSA_SUCCESS )
1360 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001361 }
Gilles Peskined223b522018-06-11 18:12:58 +02001362 else
1363 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001364
Gilles Peskined223b522018-06-11 18:12:58 +02001365 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1366 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001367 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001368 ipad[i] ^= 0x36;
1369 memset( ipad + key_length, 0x36, block_size - key_length );
1370
1371 /* Copy the key material from ipad to opad, flipping the requisite bits,
1372 * and filling the rest of opad with the requisite constant. */
1373 for( i = 0; i < key_length; i++ )
1374 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1375 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001376
1377 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1378 PSA_ALG_HMAC_HASH( alg ) );
1379 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001380 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001381
1382 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1383 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001384
1385cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001386 mbedtls_zeroize( ipad, key_length );
1387 /* opad is in the context. It needs to stay in memory if this function
1388 * succeeds, and it will be wiped by psa_mac_abort() called from
1389 * psa_mac_start in the error case. */
1390
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001391 return( status );
1392}
Gilles Peskine248051a2018-06-20 16:09:38 +02001393#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001394
Gilles Peskine8c9def32018-02-08 10:02:12 +01001395psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1396 psa_key_slot_t key,
1397 psa_algorithm_t alg )
1398{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001399 psa_status_t status;
1400 key_slot_t *slot;
1401 psa_key_type_t key_type;
1402 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001403 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001404
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001405 status = psa_mac_init( operation, alg );
1406 if( status != PSA_SUCCESS )
1407 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001408
1409 status = psa_get_key_information( key, &key_type, &key_bits );
1410 if( status != PSA_SUCCESS )
1411 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001412
Gilles Peskine8c9def32018-02-08 10:02:12 +01001413 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001414 if( slot->type == PSA_KEY_TYPE_NONE )
1415 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001416
Moran Pekerd7326592018-05-29 16:56:39 +03001417 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001418 operation->key_usage_sign = 1;
1419
Moran Pekerd7326592018-05-29 16:56:39 +03001420 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001421 operation->key_usage_verify = 1;
1422
Gilles Peskine8c9def32018-02-08 10:02:12 +01001423 if( ! PSA_ALG_IS_HMAC( alg ) )
1424 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001425 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001426 if( cipher_info == NULL )
1427 return( PSA_ERROR_NOT_SUPPORTED );
1428 operation->mac_size = cipher_info->block_size;
1429 }
1430 switch( alg )
1431 {
1432#if defined(MBEDTLS_CMAC_C)
1433 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001434 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1435 key_bits,
1436 slot,
1437 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001438 break;
1439#endif /* MBEDTLS_CMAC_C */
1440 default:
1441#if defined(MBEDTLS_MD_C)
1442 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001443 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001444 else
1445#endif /* MBEDTLS_MD_C */
1446 return( PSA_ERROR_NOT_SUPPORTED );
1447 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001448
Gilles Peskine8c9def32018-02-08 10:02:12 +01001449 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001450 * context may contain data that needs to be wiped on error. */
1451 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001452 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001453 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001454 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001455 else
1456 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001457 operation->key_set = 1;
1458 }
1459 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001460}
1461
1462psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1463 const uint8_t *input,
1464 size_t input_length )
1465{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001466 int ret = 0 ;
1467 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001468 if( ! operation->key_set )
1469 return( PSA_ERROR_BAD_STATE );
1470 if( operation->iv_required && ! operation->iv_set )
1471 return( PSA_ERROR_BAD_STATE );
1472 operation->has_input = 1;
1473
1474 switch( operation->alg )
1475 {
1476#if defined(MBEDTLS_CMAC_C)
1477 case PSA_ALG_CMAC:
1478 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1479 input, input_length );
1480 break;
1481#endif /* MBEDTLS_CMAC_C */
1482 default:
1483#if defined(MBEDTLS_MD_C)
1484 if( PSA_ALG_IS_HMAC( operation->alg ) )
1485 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001486 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001487 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001488 }
1489 else
1490#endif /* MBEDTLS_MD_C */
1491 {
1492 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1493 }
1494 break;
1495 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001496 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001497 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001498 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001499 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001500 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001501 }
1502
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001503 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001504}
1505
mohammad16036df908f2018-04-02 08:34:15 -07001506static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001507 uint8_t *mac,
1508 size_t mac_size,
1509 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001510{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001511 int ret = 0;
1512 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001513 if( ! operation->key_set )
1514 return( PSA_ERROR_BAD_STATE );
1515 if( operation->iv_required && ! operation->iv_set )
1516 return( PSA_ERROR_BAD_STATE );
1517
1518 /* Fill the output buffer with something that isn't a valid mac
1519 * (barring an attack on the mac and deliberately-crafted input),
1520 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001521 *mac_length = mac_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001522 /* If mac_size is 0 then mac may be NULL and then the
1523 * call to memset would have undefined behavior. */
1524 if( mac_size != 0 )
1525 memset( mac, '!', mac_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001526
1527 if( mac_size < operation->mac_size )
1528 return( PSA_ERROR_BUFFER_TOO_SMALL );
1529
1530 switch( operation->alg )
1531 {
1532#if defined(MBEDTLS_CMAC_C)
1533 case PSA_ALG_CMAC:
1534 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1535 break;
1536#endif /* MBEDTLS_CMAC_C */
1537 default:
1538#if defined(MBEDTLS_MD_C)
1539 if( PSA_ALG_IS_HMAC( operation->alg ) )
1540 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001541 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001542 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001543 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001544 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001545 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001546
Gilles Peskine99bc6492018-06-11 17:13:00 +02001547 if( block_size == 0 )
1548 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001549
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001550 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001551 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001552 if( status != PSA_SUCCESS )
1553 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001554 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001555
1556 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1557 PSA_ALG_HMAC_HASH( operation->alg ) );
1558 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001559 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001560
1561 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001562 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001563 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001564 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001565
1566 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001567 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001568 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001569 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001570
1571 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1572 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001573 hmac_cleanup:
1574 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001575 }
1576 else
1577#endif /* MBEDTLS_MD_C */
1578 {
1579 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1580 }
1581 break;
1582 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001583cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001584
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001585 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001586 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001587 *mac_length = operation->mac_size;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001588 return( psa_mac_abort( operation ) );
1589 }
1590 else
1591 {
1592 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001593 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001594 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001595
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001596 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001597 }
1598}
1599
mohammad16036df908f2018-04-02 08:34:15 -07001600psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1601 uint8_t *mac,
1602 size_t mac_size,
1603 size_t *mac_length )
1604{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001605 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001606 return( PSA_ERROR_NOT_PERMITTED );
1607
Gilles Peskine99bc6492018-06-11 17:13:00 +02001608 return( psa_mac_finish_internal( operation, mac,
1609 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001610}
1611
Gilles Peskine8c9def32018-02-08 10:02:12 +01001612psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1613 const uint8_t *mac,
1614 size_t mac_length )
1615{
Gilles Peskine828ed142018-06-18 23:25:51 +02001616 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001617 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001618 psa_status_t status;
1619
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001620 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001621 return( PSA_ERROR_NOT_PERMITTED );
1622
1623 status = psa_mac_finish_internal( operation,
1624 actual_mac, sizeof( actual_mac ),
1625 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001626 if( status != PSA_SUCCESS )
1627 return( status );
1628 if( actual_mac_length != mac_length )
1629 return( PSA_ERROR_INVALID_SIGNATURE );
1630 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1631 return( PSA_ERROR_INVALID_SIGNATURE );
1632 return( PSA_SUCCESS );
1633}
1634
1635
Gilles Peskine20035e32018-02-03 22:44:14 +01001636
Gilles Peskine20035e32018-02-03 22:44:14 +01001637/****************************************************************/
1638/* Asymmetric cryptography */
1639/****************************************************************/
1640
Gilles Peskine2b450e32018-06-27 15:42:46 +02001641#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001642/* Decode the hash algorithm from alg and store the mbedtls encoding in
1643 * md_alg. Verify that the hash length is consistent. */
1644static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1645 size_t hash_length,
1646 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001647{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02001648 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001649 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1650 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1651 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001652 {
1653#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001654 if( hash_length > UINT_MAX )
1655 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001656#endif
1657 }
1658 else
1659 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001660 if( mbedtls_md_get_size( md_info ) != hash_length )
1661 return( PSA_ERROR_INVALID_ARGUMENT );
1662 if( md_info == NULL )
1663 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001664 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001665 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001666}
1667
Gilles Peskine2b450e32018-06-27 15:42:46 +02001668static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
1669 psa_algorithm_t alg,
1670 const uint8_t *hash,
1671 size_t hash_length,
1672 uint8_t *signature,
1673 size_t signature_size,
1674 size_t *signature_length )
1675{
1676 psa_status_t status;
1677 int ret;
1678 mbedtls_md_type_t md_alg;
1679
1680 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1681 if( status != PSA_SUCCESS )
1682 return( status );
1683
1684 if( signature_size < rsa->len )
1685 return( PSA_ERROR_BUFFER_TOO_SMALL );
1686
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001687 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1688 * hash_length will fit and return an error if it doesn't. */
1689#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1690#if SIZE_MAX > UINT_MAX
1691 if( hash_length > UINT_MAX )
1692 return( PSA_ERROR_NOT_SUPPORTED );
1693#endif
1694#endif
1695
Gilles Peskine2b450e32018-06-27 15:42:46 +02001696#if defined(MBEDTLS_PKCS1_V15)
1697 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1698 {
1699 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1700 MBEDTLS_MD_NONE );
1701 ret = mbedtls_rsa_pkcs1_sign( rsa,
1702 mbedtls_ctr_drbg_random,
1703 &global_data.ctr_drbg,
1704 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001705 md_alg,
1706 (unsigned int) hash_length,
1707 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001708 signature );
1709 }
1710 else
1711#endif /* MBEDTLS_PKCS1_V15 */
1712#if defined(MBEDTLS_PKCS1_V21)
1713 if( PSA_ALG_IS_RSA_PSS( alg ) )
1714 {
1715 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1716 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1717 mbedtls_ctr_drbg_random,
1718 &global_data.ctr_drbg,
1719 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001720 md_alg,
1721 (unsigned int) hash_length,
1722 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001723 signature );
1724 }
1725 else
1726#endif /* MBEDTLS_PKCS1_V21 */
1727 {
1728 return( PSA_ERROR_INVALID_ARGUMENT );
1729 }
1730
1731 if( ret == 0 )
1732 *signature_length = rsa->len;
1733 return( mbedtls_to_psa_error( ret ) );
1734}
1735
1736static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
1737 psa_algorithm_t alg,
1738 const uint8_t *hash,
1739 size_t hash_length,
1740 const uint8_t *signature,
1741 size_t signature_length )
1742{
1743 psa_status_t status;
1744 int ret;
1745 mbedtls_md_type_t md_alg;
1746
1747 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
1748 if( status != PSA_SUCCESS )
1749 return( status );
1750
1751 if( signature_length < rsa->len )
1752 return( PSA_ERROR_BUFFER_TOO_SMALL );
1753
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001754#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21)
1755#if SIZE_MAX > UINT_MAX
1756 /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if
1757 * hash_length will fit and return an error if it doesn't. */
1758 if( hash_length > UINT_MAX )
1759 return( PSA_ERROR_NOT_SUPPORTED );
1760#endif
1761#endif
1762
Gilles Peskine2b450e32018-06-27 15:42:46 +02001763#if defined(MBEDTLS_PKCS1_V15)
1764 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
1765 {
1766 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1767 MBEDTLS_MD_NONE );
1768 ret = mbedtls_rsa_pkcs1_verify( rsa,
1769 mbedtls_ctr_drbg_random,
1770 &global_data.ctr_drbg,
1771 MBEDTLS_RSA_PUBLIC,
1772 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001773 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001774 hash,
1775 signature );
1776 }
1777 else
1778#endif /* MBEDTLS_PKCS1_V15 */
1779#if defined(MBEDTLS_PKCS1_V21)
1780 if( PSA_ALG_IS_RSA_PSS( alg ) )
1781 {
1782 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1783 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1784 mbedtls_ctr_drbg_random,
1785 &global_data.ctr_drbg,
1786 MBEDTLS_RSA_PUBLIC,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01001787 md_alg,
1788 (unsigned int) hash_length,
1789 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02001790 signature );
1791 }
1792 else
1793#endif /* MBEDTLS_PKCS1_V21 */
1794 {
1795 return( PSA_ERROR_INVALID_ARGUMENT );
1796 }
1797 return( mbedtls_to_psa_error( ret ) );
1798}
1799#endif /* MBEDTLS_RSA_C */
1800
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001801#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001802/* `ecp` cannot be const because `ecp->grp` needs to be non-const
1803 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
1804 * (even though these functions don't modify it). */
1805static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
1806 psa_algorithm_t alg,
1807 const uint8_t *hash,
1808 size_t hash_length,
1809 uint8_t *signature,
1810 size_t signature_size,
1811 size_t *signature_length )
1812{
1813 int ret;
1814 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001815 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001816 mbedtls_mpi_init( &r );
1817 mbedtls_mpi_init( &s );
1818
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001819 if( signature_size < 2 * curve_bytes )
1820 {
1821 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
1822 goto cleanup;
1823 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001824
1825 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
1826 {
1827 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
1828 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1829 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
1830 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
1831 hash, hash_length,
1832 md_alg ) );
1833 }
1834 else
1835 {
1836 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
1837 hash, hash_length,
1838 mbedtls_ctr_drbg_random,
1839 &global_data.ctr_drbg ) );
1840 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001841
1842 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
1843 signature,
1844 curve_bytes ) );
1845 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
1846 signature + curve_bytes,
1847 curve_bytes ) );
1848
1849cleanup:
1850 mbedtls_mpi_free( &r );
1851 mbedtls_mpi_free( &s );
1852 if( ret == 0 )
1853 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02001854 return( mbedtls_to_psa_error( ret ) );
1855}
1856
1857static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
1858 const uint8_t *hash,
1859 size_t hash_length,
1860 const uint8_t *signature,
1861 size_t signature_length )
1862{
1863 int ret;
1864 mbedtls_mpi r, s;
1865 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
1866 mbedtls_mpi_init( &r );
1867 mbedtls_mpi_init( &s );
1868
1869 if( signature_length != 2 * curve_bytes )
1870 return( PSA_ERROR_INVALID_SIGNATURE );
1871
1872 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
1873 signature,
1874 curve_bytes ) );
1875 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
1876 signature + curve_bytes,
1877 curve_bytes ) );
1878
1879 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
1880 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001881
1882cleanup:
1883 mbedtls_mpi_free( &r );
1884 mbedtls_mpi_free( &s );
1885 return( mbedtls_to_psa_error( ret ) );
1886}
1887#endif /* MBEDTLS_ECDSA_C */
1888
Gilles Peskine61b91d42018-06-08 16:09:36 +02001889psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1890 psa_algorithm_t alg,
1891 const uint8_t *hash,
1892 size_t hash_length,
1893 const uint8_t *salt,
1894 size_t salt_length,
1895 uint8_t *signature,
1896 size_t signature_size,
1897 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001898{
1899 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001900 psa_status_t status;
1901
1902 *signature_length = signature_size;
1903
Gilles Peskine93aa0332018-02-03 23:58:03 +01001904 (void) salt;
1905 (void) salt_length;
1906
Gilles Peskine828ed142018-06-18 23:25:51 +02001907 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001908 {
1909 status = PSA_ERROR_EMPTY_SLOT;
1910 goto exit;
1911 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001912 slot = &global_data.key_slots[key];
1913 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001914 {
1915 status = PSA_ERROR_EMPTY_SLOT;
1916 goto exit;
1917 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001918 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001919 {
1920 status = PSA_ERROR_INVALID_ARGUMENT;
1921 goto exit;
1922 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001923 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001924 {
1925 status = PSA_ERROR_NOT_PERMITTED;
1926 goto exit;
1927 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001928
Gilles Peskine20035e32018-02-03 22:44:14 +01001929#if defined(MBEDTLS_RSA_C)
1930 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1931 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001932 status = psa_rsa_sign( slot->data.rsa,
1933 alg,
1934 hash, hash_length,
1935 signature, signature_size,
1936 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01001937 }
1938 else
1939#endif /* defined(MBEDTLS_RSA_C) */
1940#if defined(MBEDTLS_ECP_C)
1941 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1942 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001943#if defined(MBEDTLS_ECDSA_C)
1944 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001945 status = psa_ecdsa_sign( slot->data.ecp,
1946 alg,
1947 hash, hash_length,
1948 signature, signature_size,
1949 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001950 else
1951#endif /* defined(MBEDTLS_ECDSA_C) */
1952 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001953 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02001954 }
itayzafrir5c753392018-05-08 11:18:38 +03001955 }
1956 else
1957#endif /* defined(MBEDTLS_ECP_C) */
1958 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001959 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01001960 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001961
1962exit:
1963 /* Fill the unused part of the output buffer (the whole buffer on error,
1964 * the trailing part on success) with something that isn't a valid mac
1965 * (barring an attack on the mac and deliberately-crafted input),
1966 * in case the caller doesn't check the return status properly. */
1967 if( status == PSA_SUCCESS )
1968 memset( signature + *signature_length, '!',
1969 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001970 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001971 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001972 /* If signature_size is 0 then we have nothing to do. We must not call
1973 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02001974 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03001975}
1976
1977psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1978 psa_algorithm_t alg,
1979 const uint8_t *hash,
1980 size_t hash_length,
1981 const uint8_t *salt,
1982 size_t salt_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02001983 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02001984 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03001985{
1986 key_slot_t *slot;
Gilles Peskine2b450e32018-06-27 15:42:46 +02001987
itayzafrir5c753392018-05-08 11:18:38 +03001988 (void) salt;
1989 (void) salt_length;
1990
Gilles Peskine828ed142018-06-18 23:25:51 +02001991 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001992 return( PSA_ERROR_INVALID_ARGUMENT );
1993 slot = &global_data.key_slots[key];
1994 if( slot->type == PSA_KEY_TYPE_NONE )
1995 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001996 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001997 return( PSA_ERROR_NOT_PERMITTED );
1998
Gilles Peskine61b91d42018-06-08 16:09:36 +02001999#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002000 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
2001 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002002 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002003 return( psa_rsa_verify( slot->data.rsa,
2004 alg,
2005 hash, hash_length,
2006 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002007 }
2008 else
2009#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002010#if defined(MBEDTLS_ECP_C)
2011 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2012 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002013#if defined(MBEDTLS_ECDSA_C)
2014 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002015 return( psa_ecdsa_verify( slot->data.ecp,
2016 hash, hash_length,
2017 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002018 else
2019#endif /* defined(MBEDTLS_ECDSA_C) */
2020 {
2021 return( PSA_ERROR_INVALID_ARGUMENT );
2022 }
itayzafrir5c753392018-05-08 11:18:38 +03002023 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002024 else
2025#endif /* defined(MBEDTLS_ECP_C) */
2026 {
2027 return( PSA_ERROR_NOT_SUPPORTED );
2028 }
2029}
2030
Gilles Peskine61b91d42018-06-08 16:09:36 +02002031psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2032 psa_algorithm_t alg,
2033 const uint8_t *input,
2034 size_t input_length,
2035 const uint8_t *salt,
2036 size_t salt_length,
2037 uint8_t *output,
2038 size_t output_size,
2039 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002040{
2041 key_slot_t *slot;
2042 (void) salt;
2043 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002044 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002045
Gilles Peskine828ed142018-06-18 23:25:51 +02002046 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03002047 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002048 slot = &global_data.key_slots[key];
2049 if( slot->type == PSA_KEY_TYPE_NONE )
2050 return( PSA_ERROR_EMPTY_SLOT );
2051 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2052 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002053 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
2054 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002055
2056#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002057 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
2058 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002059 {
2060 mbedtls_rsa_context *rsa = slot->data.rsa;
2061 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002062 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002063 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002064#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002065 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002066 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002067 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2068 mbedtls_ctr_drbg_random,
2069 &global_data.ctr_drbg,
2070 MBEDTLS_RSA_PUBLIC,
2071 input_length,
2072 input,
2073 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002074 }
2075 else
2076#endif /* MBEDTLS_PKCS1_V15 */
2077#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002078 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002079 {
2080 return( PSA_ERROR_NOT_SUPPORTED );
2081 }
2082 else
2083#endif /* MBEDTLS_PKCS1_V21 */
2084 {
2085 return( PSA_ERROR_INVALID_ARGUMENT );
2086 }
2087 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002088 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002089 return( mbedtls_to_psa_error( ret ) );
2090 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002091 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002092#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002093 {
2094 return( PSA_ERROR_NOT_SUPPORTED );
2095 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002096}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002097
Gilles Peskine61b91d42018-06-08 16:09:36 +02002098psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2099 psa_algorithm_t alg,
2100 const uint8_t *input,
2101 size_t input_length,
2102 const uint8_t *salt,
2103 size_t salt_length,
2104 uint8_t *output,
2105 size_t output_size,
2106 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002107{
2108 key_slot_t *slot;
2109 (void) salt;
2110 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002111 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002112
Gilles Peskine828ed142018-06-18 23:25:51 +02002113 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002114 return( PSA_ERROR_EMPTY_SLOT );
2115 slot = &global_data.key_slots[key];
2116 if( slot->type == PSA_KEY_TYPE_NONE )
2117 return( PSA_ERROR_EMPTY_SLOT );
2118 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2119 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002120 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2121 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002122
2123#if defined(MBEDTLS_RSA_C)
2124 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2125 {
2126 mbedtls_rsa_context *rsa = slot->data.rsa;
2127 int ret;
2128
Gilles Peskinec4def2f2018-06-08 17:53:48 +02002129 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002130 return( PSA_ERROR_INVALID_ARGUMENT );
2131
2132#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002133 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002134 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002135 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2136 mbedtls_ctr_drbg_random,
2137 &global_data.ctr_drbg,
2138 MBEDTLS_RSA_PRIVATE,
2139 output_length,
2140 input,
2141 output,
2142 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002143 }
2144 else
2145#endif /* MBEDTLS_PKCS1_V15 */
2146#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002147 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002148 {
2149 return( PSA_ERROR_NOT_SUPPORTED );
2150 }
2151 else
2152#endif /* MBEDTLS_PKCS1_V21 */
2153 {
2154 return( PSA_ERROR_INVALID_ARGUMENT );
2155 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002156
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002157 return( mbedtls_to_psa_error( ret ) );
2158 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002159 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002160#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002161 {
2162 return( PSA_ERROR_NOT_SUPPORTED );
2163 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002164}
Gilles Peskine20035e32018-02-03 22:44:14 +01002165
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002166
2167
mohammad1603503973b2018-03-12 15:59:30 +02002168/****************************************************************/
2169/* Symmetric cryptography */
2170/****************************************************************/
2171
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002172/* Initialize the cipher operation structure. Once this function has been
2173 * called, psa_cipher_abort can run and will do the right thing. */
2174static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2175 psa_algorithm_t alg )
2176{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002177 if( ! PSA_ALG_IS_CIPHER( alg ) )
2178 {
2179 memset( operation, 0, sizeof( *operation ) );
2180 return( PSA_ERROR_INVALID_ARGUMENT );
2181 }
2182
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002183 operation->alg = alg;
2184 operation->key_set = 0;
2185 operation->iv_set = 0;
2186 operation->iv_required = 1;
2187 operation->iv_size = 0;
2188 operation->block_size = 0;
2189 mbedtls_cipher_init( &operation->ctx.cipher );
2190 return( PSA_SUCCESS );
2191}
2192
Gilles Peskinee553c652018-06-04 16:22:46 +02002193static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2194 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002195 psa_algorithm_t alg,
2196 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002197{
2198 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2199 psa_status_t status;
2200 key_slot_t *slot;
2201 psa_key_type_t key_type;
2202 size_t key_bits;
2203 const mbedtls_cipher_info_t *cipher_info = NULL;
2204
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002205 status = psa_cipher_init( operation, alg );
2206 if( status != PSA_SUCCESS )
2207 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002208
2209 status = psa_get_key_information( key, &key_type, &key_bits );
2210 if( status != PSA_SUCCESS )
2211 return( status );
2212 slot = &global_data.key_slots[key];
2213
Gilles Peskinebb1072f2018-06-08 18:46:05 +02002214 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002215 if( cipher_info == NULL )
2216 return( PSA_ERROR_NOT_SUPPORTED );
2217
mohammad1603503973b2018-03-12 15:59:30 +02002218 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002219 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002220 {
2221 psa_cipher_abort( operation );
2222 return( mbedtls_to_psa_error( ret ) );
2223 }
2224
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002225#if defined(MBEDTLS_DES_C)
2226 if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
2227 {
2228 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2229 unsigned char keys[24];
2230 memcpy( keys, slot->data.raw.data, 16 );
2231 memcpy( keys + 16, slot->data.raw.data, 8 );
2232 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2233 keys,
2234 192, cipher_operation );
2235 }
2236 else
2237#endif
2238 {
2239 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2240 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002241 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002242 }
Moran Peker41deec42018-04-04 15:43:05 +03002243 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002244 {
2245 psa_cipher_abort( operation );
2246 return( mbedtls_to_psa_error( ret ) );
2247 }
2248
mohammad16038481e742018-03-18 13:57:31 +02002249#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03002250 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02002251 {
Gilles Peskine53514202018-06-06 15:11:46 +02002252 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
2253 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02002254
Moran Pekera28258c2018-05-29 16:25:04 +03002255 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02002256 {
2257 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
2258 mode = MBEDTLS_PADDING_PKCS7;
2259 break;
2260 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
2261 mode = MBEDTLS_PADDING_NONE;
2262 break;
2263 default:
Moran Pekerae382792018-05-31 14:06:17 +03002264 psa_cipher_abort( operation );
2265 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02002266 }
2267 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03002268 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03002269 {
2270 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02002271 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03002272 }
mohammad16038481e742018-03-18 13:57:31 +02002273 }
2274#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2275
mohammad1603503973b2018-03-12 15:59:30 +02002276 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002277 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
2278 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
2279 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002280 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002281 {
mohammad160389e0f462018-04-12 08:48:45 +03002282 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02002283 }
mohammad1603503973b2018-03-12 15:59:30 +02002284
Moran Peker395db872018-05-31 14:07:14 +03002285 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002286}
2287
Gilles Peskinee553c652018-06-04 16:22:46 +02002288psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
2289 psa_key_slot_t key,
2290 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002291{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002292 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002293}
2294
Gilles Peskinee553c652018-06-04 16:22:46 +02002295psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
2296 psa_key_slot_t key,
2297 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002298{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002299 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002300}
2301
Gilles Peskinee553c652018-06-04 16:22:46 +02002302psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
2303 unsigned char *iv,
2304 size_t iv_size,
2305 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002306{
Moran Peker41deec42018-04-04 15:43:05 +03002307 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002308 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002309 return( PSA_ERROR_BAD_STATE );
2310 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002311 {
Moran Peker41deec42018-04-04 15:43:05 +03002312 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2313 goto exit;
2314 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002315 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2316 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002317 if( ret != 0 )
2318 {
2319 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002320 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002321 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002322
mohammad16038481e742018-03-18 13:57:31 +02002323 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03002324 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002325
Moran Peker395db872018-05-31 14:07:14 +03002326exit:
2327 if( ret != PSA_SUCCESS )
2328 psa_cipher_abort( operation );
2329 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002330}
2331
Gilles Peskinee553c652018-06-04 16:22:46 +02002332psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
2333 const unsigned char *iv,
2334 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002335{
Moran Peker41deec42018-04-04 15:43:05 +03002336 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002337 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002338 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002339 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002340 {
Moran Pekerae382792018-05-31 14:06:17 +03002341 psa_cipher_abort( operation );
2342 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002343 }
mohammad1603503973b2018-03-12 15:59:30 +02002344 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002345 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002346 {
2347 psa_cipher_abort( operation );
2348 return( mbedtls_to_psa_error( ret ) );
2349 }
2350
2351 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002352
Moran Peker395db872018-05-31 14:07:14 +03002353 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002354}
2355
Gilles Peskinee553c652018-06-04 16:22:46 +02002356psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2357 const uint8_t *input,
2358 size_t input_length,
2359 unsigned char *output,
2360 size_t output_size,
2361 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002362{
2363 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002364 size_t expected_output_size;
2365 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2366 {
2367 /* Take the unprocessed partial block left over from previous
2368 * update calls, if any, plus the input to this call. Remove
2369 * the last partial block, if any. You get the data that will be
2370 * output in this call. */
2371 expected_output_size =
2372 ( operation->ctx.cipher.unprocessed_len + input_length )
2373 / operation->block_size * operation->block_size;
2374 }
2375 else
2376 {
2377 expected_output_size = input_length;
2378 }
2379 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002380 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002381
mohammad1603503973b2018-03-12 15:59:30 +02002382 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002383 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002384 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002385 {
2386 psa_cipher_abort( operation );
2387 return( mbedtls_to_psa_error( ret ) );
2388 }
2389
Moran Peker395db872018-05-31 14:07:14 +03002390 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002391}
2392
Gilles Peskinee553c652018-06-04 16:22:46 +02002393psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2394 uint8_t *output,
2395 size_t output_size,
2396 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002397{
2398 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002399 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002400
mohammad1603503973b2018-03-12 15:59:30 +02002401 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002402 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002403 psa_cipher_abort( operation );
2404 return( PSA_ERROR_BAD_STATE );
2405 }
2406 if( operation->iv_required && ! operation->iv_set )
2407 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002408 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002409 return( PSA_ERROR_BAD_STATE );
2410 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002411 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2412 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002413 {
Gilles Peskine53514202018-06-06 15:11:46 +02002414 psa_algorithm_t padding_mode =
2415 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002416 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002417 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002418 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002419 return( PSA_ERROR_TAMPERING_DETECTED );
2420 }
Gilles Peskine53514202018-06-06 15:11:46 +02002421 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002422 {
2423 if( operation->ctx.cipher.unprocessed_len != 0 )
2424 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002425 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002426 return( PSA_ERROR_INVALID_ARGUMENT );
2427 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002428 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002429 }
2430
2431 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002432 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002433 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002434 {
2435 psa_cipher_abort( operation );
2436 return( mbedtls_to_psa_error( ret ) );
2437 }
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002438 if( *output_length == 0 )
2439 /* Nothing to copy. Note that output may be NULL in this case. */ ;
2440 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002441 memcpy( output, temp_output_buffer, *output_length );
2442 else
2443 {
2444 psa_cipher_abort( operation );
2445 return( PSA_ERROR_BUFFER_TOO_SMALL );
2446 }
mohammad1603503973b2018-03-12 15:59:30 +02002447
Moran Peker4c80d832018-04-22 20:15:31 +03002448 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002449}
2450
Gilles Peskinee553c652018-06-04 16:22:46 +02002451psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2452{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002453 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002454 {
2455 /* The object has (apparently) been initialized but it is not
2456 * in use. It's ok to call abort on such an object, and there's
2457 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002458 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002459 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002460
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002461 /* Sanity check (shouldn't happen: operation->alg should
2462 * always have been initialized to a valid value). */
2463 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2464 return( PSA_ERROR_BAD_STATE );
2465
mohammad1603503973b2018-03-12 15:59:30 +02002466 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002467
Moran Peker41deec42018-04-04 15:43:05 +03002468 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002469 operation->key_set = 0;
2470 operation->iv_set = 0;
2471 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002472 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002473 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002474
Moran Peker395db872018-05-31 14:07:14 +03002475 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002476}
2477
Gilles Peskinea0655c32018-04-30 17:06:50 +02002478
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002479
mohammad16038cc1cee2018-03-28 01:21:33 +03002480/****************************************************************/
2481/* Key Policy */
2482/****************************************************************/
2483
Gilles Peskine2d277862018-06-18 15:41:12 +02002484void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002485{
Gilles Peskine803ce742018-06-18 16:07:14 +02002486 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002487}
2488
Gilles Peskine2d277862018-06-18 15:41:12 +02002489void psa_key_policy_set_usage( psa_key_policy_t *policy,
2490 psa_key_usage_t usage,
2491 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002492{
mohammad16034eed7572018-03-28 05:14:59 -07002493 policy->usage = usage;
2494 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002495}
2496
Gilles Peskine2d277862018-06-18 15:41:12 +02002497psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002498{
mohammad16036df908f2018-04-02 08:34:15 -07002499 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002500}
2501
Gilles Peskine2d277862018-06-18 15:41:12 +02002502psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002503{
mohammad16036df908f2018-04-02 08:34:15 -07002504 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002505}
2506
Gilles Peskine2d277862018-06-18 15:41:12 +02002507psa_status_t psa_set_key_policy( psa_key_slot_t key,
2508 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002509{
2510 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002511
Gilles Peskine828ed142018-06-18 23:25:51 +02002512 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002513 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002514
mohammad16038cc1cee2018-03-28 01:21:33 +03002515 slot = &global_data.key_slots[key];
2516 if( slot->type != PSA_KEY_TYPE_NONE )
2517 return( PSA_ERROR_OCCUPIED_SLOT );
2518
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002519 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2520 PSA_KEY_USAGE_ENCRYPT |
2521 PSA_KEY_USAGE_DECRYPT |
2522 PSA_KEY_USAGE_SIGN |
2523 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002524 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002525
mohammad16036df908f2018-04-02 08:34:15 -07002526 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002527
2528 return( PSA_SUCCESS );
2529}
2530
Gilles Peskine2d277862018-06-18 15:41:12 +02002531psa_status_t psa_get_key_policy( psa_key_slot_t key,
2532 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002533{
2534 key_slot_t *slot;
2535
Gilles Peskine828ed142018-06-18 23:25:51 +02002536 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002537 return( PSA_ERROR_INVALID_ARGUMENT );
2538
2539 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002540
mohammad16036df908f2018-04-02 08:34:15 -07002541 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002542
2543 return( PSA_SUCCESS );
2544}
Gilles Peskine20035e32018-02-03 22:44:14 +01002545
Gilles Peskinea0655c32018-04-30 17:06:50 +02002546
2547
mohammad1603804cd712018-03-20 22:44:08 +02002548/****************************************************************/
2549/* Key Lifetime */
2550/****************************************************************/
2551
Gilles Peskine2d277862018-06-18 15:41:12 +02002552psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2553 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002554{
2555 key_slot_t *slot;
2556
Gilles Peskine828ed142018-06-18 23:25:51 +02002557 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002558 return( PSA_ERROR_INVALID_ARGUMENT );
2559
2560 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002561
mohammad1603804cd712018-03-20 22:44:08 +02002562 *lifetime = slot->lifetime;
2563
2564 return( PSA_SUCCESS );
2565}
2566
Gilles Peskine2d277862018-06-18 15:41:12 +02002567psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01002568 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002569{
2570 key_slot_t *slot;
2571
Gilles Peskine828ed142018-06-18 23:25:51 +02002572 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002573 return( PSA_ERROR_INVALID_ARGUMENT );
2574
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002575 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2576 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002577 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2578 return( PSA_ERROR_INVALID_ARGUMENT );
2579
mohammad1603804cd712018-03-20 22:44:08 +02002580 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002581 if( slot->type != PSA_KEY_TYPE_NONE )
2582 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002583
Moran Pekerd7326592018-05-29 16:56:39 +03002584 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002585 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002586
mohammad1603060ad8a2018-03-20 14:28:38 -07002587 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002588
2589 return( PSA_SUCCESS );
2590}
2591
Gilles Peskine20035e32018-02-03 22:44:14 +01002592
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002593
mohammad16035955c982018-04-26 00:53:03 +03002594/****************************************************************/
2595/* AEAD */
2596/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002597
mohammad16035955c982018-04-26 00:53:03 +03002598psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2599 psa_algorithm_t alg,
2600 const uint8_t *nonce,
2601 size_t nonce_length,
2602 const uint8_t *additional_data,
2603 size_t additional_data_length,
2604 const uint8_t *plaintext,
2605 size_t plaintext_length,
2606 uint8_t *ciphertext,
2607 size_t ciphertext_size,
2608 size_t *ciphertext_length )
2609{
2610 int ret;
2611 psa_status_t status;
2612 key_slot_t *slot;
2613 psa_key_type_t key_type;
2614 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002615 uint8_t *tag;
2616 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002617 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002618 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002619
mohammad1603f08a5502018-06-03 15:05:47 +03002620 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002621
mohammad16035955c982018-04-26 00:53:03 +03002622 status = psa_get_key_information( key, &key_type, &key_bits );
2623 if( status != PSA_SUCCESS )
2624 return( status );
2625 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002626 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002627 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002628
mohammad16035ed06212018-06-06 13:09:34 +03002629 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2630 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002631 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002632 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002633
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002634 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002635 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002636
Gilles Peskine2d277862018-06-18 15:41:12 +02002637 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2638 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002639 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002640
mohammad16035955c982018-04-26 00:53:03 +03002641 if( alg == PSA_ALG_GCM )
2642 {
2643 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002644 tag_length = 16;
2645
mohammad160396910d82018-06-04 14:33:00 +03002646 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2647 return( PSA_ERROR_INVALID_ARGUMENT );
2648
mohammad160315223a82018-06-03 17:19:55 +03002649 //make sure we have place to hold the tag in the ciphertext buffer
2650 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002651 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002652
2653 //update the tag pointer to point to the end of the ciphertext_length
2654 tag = ciphertext + plaintext_length;
2655
mohammad16035955c982018-04-26 00:53:03 +03002656 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002657 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002658 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002659 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002660 if( ret != 0 )
2661 {
2662 mbedtls_gcm_free( &gcm );
2663 return( mbedtls_to_psa_error( ret ) );
2664 }
2665 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002666 plaintext_length, nonce,
2667 nonce_length, additional_data,
2668 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002669 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002670 mbedtls_gcm_free( &gcm );
2671 }
2672 else if( alg == PSA_ALG_CCM )
2673 {
2674 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002675 tag_length = 16;
2676
mohammad160396910d82018-06-04 14:33:00 +03002677 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2678 return( PSA_ERROR_INVALID_ARGUMENT );
2679
mohammad160347ddf3d2018-04-26 01:11:21 +03002680 if( nonce_length < 7 || nonce_length > 13 )
2681 return( PSA_ERROR_INVALID_ARGUMENT );
2682
mohammad160315223a82018-06-03 17:19:55 +03002683 //make sure we have place to hold the tag in the ciphertext buffer
2684 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002685 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002686
2687 //update the tag pointer to point to the end of the ciphertext_length
2688 tag = ciphertext + plaintext_length;
2689
mohammad16035955c982018-04-26 00:53:03 +03002690 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002691 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002692 slot->data.raw.data,
2693 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002694 if( ret != 0 )
2695 {
2696 mbedtls_ccm_free( &ccm );
2697 return( mbedtls_to_psa_error( ret ) );
2698 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002699 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002700 nonce, nonce_length,
2701 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002702 additional_data_length,
2703 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002704 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002705 mbedtls_ccm_free( &ccm );
2706 }
mohammad16035c8845f2018-05-09 05:40:09 -07002707 else
2708 {
mohammad1603554faad2018-06-03 15:07:38 +03002709 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002710 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002711
mohammad160315223a82018-06-03 17:19:55 +03002712 if( ret != 0 )
2713 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002714 /* If ciphertext_size is 0 then ciphertext may be NULL and then the
2715 * call to memset would have undefined behavior. */
2716 if( ciphertext_size != 0 )
2717 memset( ciphertext, 0, ciphertext_size );
mohammad160315223a82018-06-03 17:19:55 +03002718 return( mbedtls_to_psa_error( ret ) );
2719 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002720
mohammad160315223a82018-06-03 17:19:55 +03002721 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002722 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002723}
2724
Gilles Peskineee652a32018-06-01 19:23:52 +02002725/* Locate the tag in a ciphertext buffer containing the encrypted data
2726 * followed by the tag. Return the length of the part preceding the tag in
2727 * *plaintext_length. This is the size of the plaintext in modes where
2728 * the encrypted data has the same size as the plaintext, such as
2729 * CCM and GCM. */
2730static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2731 const uint8_t *ciphertext,
2732 size_t ciphertext_length,
2733 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002734 const uint8_t **p_tag )
2735{
2736 size_t payload_length;
2737 if( tag_length > ciphertext_length )
2738 return( PSA_ERROR_INVALID_ARGUMENT );
2739 payload_length = ciphertext_length - tag_length;
2740 if( payload_length > plaintext_size )
2741 return( PSA_ERROR_BUFFER_TOO_SMALL );
2742 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002743 return( PSA_SUCCESS );
2744}
2745
mohammad16035955c982018-04-26 00:53:03 +03002746psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2747 psa_algorithm_t alg,
2748 const uint8_t *nonce,
2749 size_t nonce_length,
2750 const uint8_t *additional_data,
2751 size_t additional_data_length,
2752 const uint8_t *ciphertext,
2753 size_t ciphertext_length,
2754 uint8_t *plaintext,
2755 size_t plaintext_size,
2756 size_t *plaintext_length )
2757{
2758 int ret;
2759 psa_status_t status;
2760 key_slot_t *slot;
2761 psa_key_type_t key_type;
2762 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002763 const uint8_t *tag;
2764 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002765 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002766 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002767
Gilles Peskineee652a32018-06-01 19:23:52 +02002768 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002769
mohammad16035955c982018-04-26 00:53:03 +03002770 status = psa_get_key_information( key, &key_type, &key_bits );
2771 if( status != PSA_SUCCESS )
2772 return( status );
2773 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002774 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002775 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002776
mohammad16035ed06212018-06-06 13:09:34 +03002777 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2778 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002779 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002780 return( PSA_ERROR_NOT_SUPPORTED );
2781
mohammad1603f14394b2018-06-04 14:33:19 +03002782 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2783 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002784
Gilles Peskine2d277862018-06-18 15:41:12 +02002785 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2786 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002787 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002788
mohammad16035955c982018-04-26 00:53:03 +03002789 if( alg == PSA_ALG_GCM )
2790 {
2791 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002792
Gilles Peskineee652a32018-06-01 19:23:52 +02002793 tag_length = 16;
2794 status = psa_aead_unpadded_locate_tag( tag_length,
2795 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002796 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002797 if( status != PSA_SUCCESS )
2798 return( status );
2799
mohammad16035955c982018-04-26 00:53:03 +03002800 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002801 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002802 slot->data.raw.data,
2803 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002804 if( ret != 0 )
2805 {
2806 mbedtls_gcm_free( &gcm );
2807 return( mbedtls_to_psa_error( ret ) );
2808 }
mohammad16035955c982018-04-26 00:53:03 +03002809
Gilles Peskineee652a32018-06-01 19:23:52 +02002810 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002811 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002812 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002813 additional_data,
2814 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002815 tag, tag_length,
2816 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002817 mbedtls_gcm_free( &gcm );
2818 }
2819 else if( alg == PSA_ALG_CCM )
2820 {
2821 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002822
mohammad160347ddf3d2018-04-26 01:11:21 +03002823 if( nonce_length < 7 || nonce_length > 13 )
2824 return( PSA_ERROR_INVALID_ARGUMENT );
2825
mohammad16039375f842018-06-03 14:28:24 +03002826 tag_length = 16;
2827 status = psa_aead_unpadded_locate_tag( tag_length,
2828 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002829 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002830 if( status != PSA_SUCCESS )
2831 return( status );
2832
mohammad16035955c982018-04-26 00:53:03 +03002833 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002834 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002835 slot->data.raw.data,
2836 (unsigned int) key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002837 if( ret != 0 )
2838 {
2839 mbedtls_ccm_free( &ccm );
2840 return( mbedtls_to_psa_error( ret ) );
2841 }
mohammad160360a64d02018-06-03 17:20:42 +03002842 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002843 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002844 additional_data,
2845 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002846 ciphertext, plaintext,
2847 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002848 mbedtls_ccm_free( &ccm );
2849 }
mohammad160339574652018-06-01 04:39:53 -07002850 else
2851 {
mohammad1603554faad2018-06-03 15:07:38 +03002852 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002853 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002854
Gilles Peskineee652a32018-06-01 19:23:52 +02002855 if( ret != 0 )
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002856 {
2857 /* If plaintext_size is 0 then plaintext may be NULL and then the
2858 * call to memset has undefined behavior. */
2859 if( plaintext_size != 0 )
2860 memset( plaintext, 0, plaintext_size );
2861 }
mohammad160360a64d02018-06-03 17:20:42 +03002862 else
2863 *plaintext_length = ciphertext_length - tag_length;
2864
Gilles Peskineee652a32018-06-01 19:23:52 +02002865 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002866}
2867
Gilles Peskinea0655c32018-04-30 17:06:50 +02002868
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002869
Gilles Peskine20035e32018-02-03 22:44:14 +01002870/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002871/* Key generation */
2872/****************************************************************/
2873
2874psa_status_t psa_generate_random( uint8_t *output,
2875 size_t output_size )
2876{
2877 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2878 output, output_size );
2879 return( mbedtls_to_psa_error( ret ) );
2880}
2881
2882psa_status_t psa_generate_key( psa_key_slot_t key,
2883 psa_key_type_t type,
2884 size_t bits,
2885 const void *parameters,
2886 size_t parameters_size )
2887{
Gilles Peskine12313cd2018-06-20 00:20:32 +02002888 key_slot_t *slot;
2889
2890 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
2891 return( PSA_ERROR_INVALID_ARGUMENT );
2892 slot = &global_data.key_slots[key];
2893 if( slot->type != PSA_KEY_TYPE_NONE )
2894 return( PSA_ERROR_OCCUPIED_SLOT );
2895 if( parameters == NULL && parameters_size != 0 )
2896 return( PSA_ERROR_INVALID_ARGUMENT );
2897
Gilles Peskine48c0ea12018-06-21 14:15:31 +02002898 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02002899 {
2900 psa_status_t status = prepare_raw_data_slot( type, bits,
2901 &slot->data.raw );
2902 if( status != PSA_SUCCESS )
2903 return( status );
2904 status = psa_generate_random( slot->data.raw.data,
2905 slot->data.raw.bytes );
2906 if( status != PSA_SUCCESS )
2907 {
2908 mbedtls_free( slot->data.raw.data );
2909 return( status );
2910 }
2911#if defined(MBEDTLS_DES_C)
2912 if( type == PSA_KEY_TYPE_DES )
2913 {
2914 mbedtls_des_key_set_parity( slot->data.raw.data );
2915 if( slot->data.raw.bytes >= 16 )
2916 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
2917 if( slot->data.raw.bytes == 24 )
2918 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
2919 }
2920#endif /* MBEDTLS_DES_C */
2921 }
2922 else
2923
2924#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
2925 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
2926 {
2927 mbedtls_rsa_context *rsa;
2928 int ret;
2929 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02002930 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
2931 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine12313cd2018-06-20 00:20:32 +02002932 if( parameters != NULL )
2933 {
2934 const unsigned *p = parameters;
2935 if( parameters_size != sizeof( *p ) )
2936 return( PSA_ERROR_INVALID_ARGUMENT );
2937 if( *p > INT_MAX )
2938 return( PSA_ERROR_INVALID_ARGUMENT );
2939 exponent = *p;
2940 }
2941 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
2942 if( rsa == NULL )
2943 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2944 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
2945 ret = mbedtls_rsa_gen_key( rsa,
2946 mbedtls_ctr_drbg_random,
2947 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002948 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02002949 exponent );
2950 if( ret != 0 )
2951 {
2952 mbedtls_rsa_free( rsa );
2953 mbedtls_free( rsa );
2954 return( mbedtls_to_psa_error( ret ) );
2955 }
2956 slot->data.rsa = rsa;
2957 }
2958 else
2959#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
2960
2961#if defined(MBEDTLS_ECP_C)
2962 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
2963 {
2964 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
2965 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
2966 const mbedtls_ecp_curve_info *curve_info =
2967 mbedtls_ecp_curve_info_from_grp_id( grp_id );
2968 mbedtls_ecp_keypair *ecp;
2969 int ret;
2970 if( parameters != NULL )
2971 return( PSA_ERROR_NOT_SUPPORTED );
2972 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
2973 return( PSA_ERROR_NOT_SUPPORTED );
2974 if( curve_info->bit_size != bits )
2975 return( PSA_ERROR_INVALID_ARGUMENT );
2976 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
2977 if( ecp == NULL )
2978 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2979 mbedtls_ecp_keypair_init( ecp );
2980 ret = mbedtls_ecp_gen_key( grp_id, ecp,
2981 mbedtls_ctr_drbg_random,
2982 &global_data.ctr_drbg );
2983 if( ret != 0 )
2984 {
2985 mbedtls_ecp_keypair_free( ecp );
2986 mbedtls_free( ecp );
2987 return( mbedtls_to_psa_error( ret ) );
2988 }
2989 slot->data.ecp = ecp;
2990 }
2991 else
2992#endif /* MBEDTLS_ECP_C */
2993
2994 return( PSA_ERROR_NOT_SUPPORTED );
2995
2996 slot->type = type;
2997 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02002998}
2999
3000
3001/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003002/* Module setup */
3003/****************************************************************/
3004
Gilles Peskinee59236f2018-01-27 23:32:46 +01003005void mbedtls_psa_crypto_free( void )
3006{
Jaeden Amero045bd502018-06-26 14:00:08 +01003007 psa_key_slot_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02003008 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01003009 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01003010 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
3011 mbedtls_entropy_free( &global_data.entropy );
3012 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3013}
3014
3015psa_status_t psa_crypto_init( void )
3016{
3017 int ret;
3018 const unsigned char drbg_seed[] = "PSA";
3019
3020 if( global_data.initialized != 0 )
3021 return( PSA_SUCCESS );
3022
3023 mbedtls_zeroize( &global_data, sizeof( global_data ) );
3024 mbedtls_entropy_init( &global_data.entropy );
3025 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
3026
3027 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
3028 mbedtls_entropy_func,
3029 &global_data.entropy,
3030 drbg_seed, sizeof( drbg_seed ) - 1 );
3031 if( ret != 0 )
3032 goto exit;
3033
Gilles Peskinee4ebc122018-03-07 14:16:44 +01003034 global_data.initialized = 1;
3035
Gilles Peskinee59236f2018-01-27 23:32:46 +01003036exit:
3037 if( ret != 0 )
3038 mbedtls_psa_crypto_free( );
3039 return( mbedtls_to_psa_error( ret ) );
3040}
3041
3042#endif /* MBEDTLS_PSA_CRYPTO_C */