blob: a4fac648e6d3939ac07a7dc6c1c88f51b50b6cd5 [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 Peskinea5905292018-02-07 20:59:33 +010043#include "mbedtls/blowfish.h"
44#include "mbedtls/camellia.h"
45#include "mbedtls/cipher.h"
46#include "mbedtls/ccm.h"
47#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010048#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010049#include "mbedtls/des.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010050#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010051#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010052#include "mbedtls/error.h"
53#include "mbedtls/gcm.h"
54#include "mbedtls/md2.h"
55#include "mbedtls/md4.h"
56#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010057#include "mbedtls/md.h"
58#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010059#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010060#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010061#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010062#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010063#include "mbedtls/sha1.h"
64#include "mbedtls/sha256.h"
65#include "mbedtls/sha512.h"
66#include "mbedtls/xtea.h"
67
Gilles Peskinee59236f2018-01-27 23:32:46 +010068
69
70/* Implementation that should never be optimized out by the compiler */
71static void mbedtls_zeroize( void *v, size_t n )
72{
73 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
74}
75
Gilles Peskine9ef733f2018-02-07 21:05:37 +010076/* constant-time buffer comparison */
77static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
78{
79 size_t i;
80 unsigned char diff = 0;
81
82 for( i = 0; i < n; i++ )
83 diff |= a[i] ^ b[i];
84
85 return( diff );
86}
87
88
89
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010090/****************************************************************/
91/* Global data, support functions and library management */
92/****************************************************************/
93
94/* Number of key slots (plus one because 0 is not used).
95 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +020096#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010097
Gilles Peskine2d277862018-06-18 15:41:12 +020098typedef struct
99{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100100 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300101 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200102 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200103 union
104 {
105 struct raw_data
106 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100107 uint8_t *data;
108 size_t bytes;
109 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100110#if defined(MBEDTLS_RSA_C)
111 mbedtls_rsa_context *rsa;
112#endif /* MBEDTLS_RSA_C */
113#if defined(MBEDTLS_ECP_C)
114 mbedtls_ecp_keypair *ecp;
115#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100116 } data;
117} key_slot_t;
118
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200119static int key_type_is_raw_bytes( psa_key_type_t type )
120{
121 psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
122 return( category == PSA_KEY_TYPE_RAW_DATA ||
123 category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
124}
125
Gilles Peskine2d277862018-06-18 15:41:12 +0200126typedef struct
127{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100128 int initialized;
129 mbedtls_entropy_context entropy;
130 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200131 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100132} psa_global_data_t;
133
134static psa_global_data_t global_data;
135
136static psa_status_t mbedtls_to_psa_error( int ret )
137{
Gilles Peskinea5905292018-02-07 20:59:33 +0100138 /* If there's both a high-level code and low-level code, dispatch on
139 * the high-level code. */
140 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100141 {
142 case 0:
143 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100144
145 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
146 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
147 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
148 return( PSA_ERROR_NOT_SUPPORTED );
149 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
150 return( PSA_ERROR_HARDWARE_FAILURE );
151
152 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
153 return( PSA_ERROR_HARDWARE_FAILURE );
154
Gilles Peskine9a944802018-06-21 09:35:35 +0200155 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
156 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
157 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
158 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
159 case MBEDTLS_ERR_ASN1_INVALID_DATA:
160 return( PSA_ERROR_INVALID_ARGUMENT );
161 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
162 return( PSA_ERROR_INSUFFICIENT_MEMORY );
163 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
164 return( PSA_ERROR_BUFFER_TOO_SMALL );
165
Gilles Peskinea5905292018-02-07 20:59:33 +0100166 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
167 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
168 return( PSA_ERROR_NOT_SUPPORTED );
169 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
170 return( PSA_ERROR_HARDWARE_FAILURE );
171
172 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
173 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
174 return( PSA_ERROR_NOT_SUPPORTED );
175 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
176 return( PSA_ERROR_HARDWARE_FAILURE );
177
178 case MBEDTLS_ERR_CCM_BAD_INPUT:
179 return( PSA_ERROR_INVALID_ARGUMENT );
180 case MBEDTLS_ERR_CCM_AUTH_FAILED:
181 return( PSA_ERROR_INVALID_SIGNATURE );
182 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
183 return( PSA_ERROR_HARDWARE_FAILURE );
184
185 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
186 return( PSA_ERROR_NOT_SUPPORTED );
187 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
188 return( PSA_ERROR_INVALID_ARGUMENT );
189 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
190 return( PSA_ERROR_INSUFFICIENT_MEMORY );
191 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
192 return( PSA_ERROR_INVALID_PADDING );
193 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
194 return( PSA_ERROR_BAD_STATE );
195 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
196 return( PSA_ERROR_INVALID_SIGNATURE );
197 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
198 return( PSA_ERROR_TAMPERING_DETECTED );
199 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
200 return( PSA_ERROR_HARDWARE_FAILURE );
201
202 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
203 return( PSA_ERROR_HARDWARE_FAILURE );
204
205 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
206 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
207 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
208 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
209 return( PSA_ERROR_NOT_SUPPORTED );
210 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
211 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
212
213 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
214 return( PSA_ERROR_NOT_SUPPORTED );
215 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
216 return( PSA_ERROR_HARDWARE_FAILURE );
217
Gilles Peskinee59236f2018-01-27 23:32:46 +0100218 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
219 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
220 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
221 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100222
223 case MBEDTLS_ERR_GCM_AUTH_FAILED:
224 return( PSA_ERROR_INVALID_SIGNATURE );
225 case MBEDTLS_ERR_GCM_BAD_INPUT:
226 return( PSA_ERROR_NOT_SUPPORTED );
227 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
228 return( PSA_ERROR_HARDWARE_FAILURE );
229
230 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
231 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
232 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
233 return( PSA_ERROR_HARDWARE_FAILURE );
234
235 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
236 return( PSA_ERROR_NOT_SUPPORTED );
237 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
238 return( PSA_ERROR_INVALID_ARGUMENT );
239 case MBEDTLS_ERR_MD_ALLOC_FAILED:
240 return( PSA_ERROR_INSUFFICIENT_MEMORY );
241 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
242 return( PSA_ERROR_STORAGE_FAILURE );
243 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
244 return( PSA_ERROR_HARDWARE_FAILURE );
245
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100246 case MBEDTLS_ERR_PK_ALLOC_FAILED:
247 return( PSA_ERROR_INSUFFICIENT_MEMORY );
248 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
249 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
250 return( PSA_ERROR_INVALID_ARGUMENT );
251 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100252 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100253 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
254 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
255 return( PSA_ERROR_INVALID_ARGUMENT );
256 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
257 return( PSA_ERROR_NOT_SUPPORTED );
258 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
259 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
260 return( PSA_ERROR_NOT_PERMITTED );
261 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
262 return( PSA_ERROR_INVALID_ARGUMENT );
263 case MBEDTLS_ERR_PK_INVALID_ALG:
264 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
265 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
266 return( PSA_ERROR_NOT_SUPPORTED );
267 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
268 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100269 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
270 return( PSA_ERROR_HARDWARE_FAILURE );
271
272 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
273 return( PSA_ERROR_HARDWARE_FAILURE );
274
275 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
276 return( PSA_ERROR_INVALID_ARGUMENT );
277 case MBEDTLS_ERR_RSA_INVALID_PADDING:
278 return( PSA_ERROR_INVALID_PADDING );
279 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
280 return( PSA_ERROR_HARDWARE_FAILURE );
281 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
282 return( PSA_ERROR_INVALID_ARGUMENT );
283 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
284 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
285 return( PSA_ERROR_TAMPERING_DETECTED );
286 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
287 return( PSA_ERROR_INVALID_SIGNATURE );
288 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
289 return( PSA_ERROR_BUFFER_TOO_SMALL );
290 case MBEDTLS_ERR_RSA_RNG_FAILED:
291 return( PSA_ERROR_INSUFFICIENT_MEMORY );
292 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
293 return( PSA_ERROR_NOT_SUPPORTED );
294 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
295 return( PSA_ERROR_HARDWARE_FAILURE );
296
297 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
298 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
299 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
300 return( PSA_ERROR_HARDWARE_FAILURE );
301
302 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
303 return( PSA_ERROR_INVALID_ARGUMENT );
304 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
305 return( PSA_ERROR_HARDWARE_FAILURE );
306
itayzafrir5c753392018-05-08 11:18:38 +0300307 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300308 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300309 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300310 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
311 return( PSA_ERROR_BUFFER_TOO_SMALL );
312 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
313 return( PSA_ERROR_NOT_SUPPORTED );
314 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
315 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
316 return( PSA_ERROR_INVALID_SIGNATURE );
317 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
318 return( PSA_ERROR_INSUFFICIENT_MEMORY );
319 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
320 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300321
Gilles Peskinee59236f2018-01-27 23:32:46 +0100322 default:
323 return( PSA_ERROR_UNKNOWN_ERROR );
324 }
325}
326
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200327
328
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100329/****************************************************************/
330/* Key management */
331/****************************************************************/
332
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200333static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
334{
335 switch( grpid )
336 {
337 case MBEDTLS_ECP_DP_SECP192R1:
338 return( PSA_ECC_CURVE_SECP192R1 );
339 case MBEDTLS_ECP_DP_SECP224R1:
340 return( PSA_ECC_CURVE_SECP224R1 );
341 case MBEDTLS_ECP_DP_SECP256R1:
342 return( PSA_ECC_CURVE_SECP256R1 );
343 case MBEDTLS_ECP_DP_SECP384R1:
344 return( PSA_ECC_CURVE_SECP384R1 );
345 case MBEDTLS_ECP_DP_SECP521R1:
346 return( PSA_ECC_CURVE_SECP521R1 );
347 case MBEDTLS_ECP_DP_BP256R1:
348 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
349 case MBEDTLS_ECP_DP_BP384R1:
350 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
351 case MBEDTLS_ECP_DP_BP512R1:
352 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
353 case MBEDTLS_ECP_DP_CURVE25519:
354 return( PSA_ECC_CURVE_CURVE25519 );
355 case MBEDTLS_ECP_DP_SECP192K1:
356 return( PSA_ECC_CURVE_SECP192K1 );
357 case MBEDTLS_ECP_DP_SECP224K1:
358 return( PSA_ECC_CURVE_SECP224K1 );
359 case MBEDTLS_ECP_DP_SECP256K1:
360 return( PSA_ECC_CURVE_SECP256K1 );
361 case MBEDTLS_ECP_DP_CURVE448:
362 return( PSA_ECC_CURVE_CURVE448 );
363 default:
364 return( 0 );
365 }
366}
367
Gilles Peskine12313cd2018-06-20 00:20:32 +0200368static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
369{
370 switch( curve )
371 {
372 case PSA_ECC_CURVE_SECP192R1:
373 return( MBEDTLS_ECP_DP_SECP192R1 );
374 case PSA_ECC_CURVE_SECP224R1:
375 return( MBEDTLS_ECP_DP_SECP224R1 );
376 case PSA_ECC_CURVE_SECP256R1:
377 return( MBEDTLS_ECP_DP_SECP256R1 );
378 case PSA_ECC_CURVE_SECP384R1:
379 return( MBEDTLS_ECP_DP_SECP384R1 );
380 case PSA_ECC_CURVE_SECP521R1:
381 return( MBEDTLS_ECP_DP_SECP521R1 );
382 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
383 return( MBEDTLS_ECP_DP_BP256R1 );
384 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
385 return( MBEDTLS_ECP_DP_BP384R1 );
386 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
387 return( MBEDTLS_ECP_DP_BP512R1 );
388 case PSA_ECC_CURVE_CURVE25519:
389 return( MBEDTLS_ECP_DP_CURVE25519 );
390 case PSA_ECC_CURVE_SECP192K1:
391 return( MBEDTLS_ECP_DP_SECP192K1 );
392 case PSA_ECC_CURVE_SECP224K1:
393 return( MBEDTLS_ECP_DP_SECP224K1 );
394 case PSA_ECC_CURVE_SECP256K1:
395 return( MBEDTLS_ECP_DP_SECP256K1 );
396 case PSA_ECC_CURVE_CURVE448:
397 return( MBEDTLS_ECP_DP_CURVE448 );
398 default:
399 return( MBEDTLS_ECP_DP_NONE );
400 }
401}
402
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200403static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
404 size_t bits,
405 struct raw_data *raw )
406{
407 /* Check that the bit size is acceptable for the key type */
408 switch( type )
409 {
410 case PSA_KEY_TYPE_RAW_DATA:
411#if defined(MBEDTLS_MD_C)
412 case PSA_KEY_TYPE_HMAC:
413#endif
414 break;
415#if defined(MBEDTLS_AES_C)
416 case PSA_KEY_TYPE_AES:
417 if( bits != 128 && bits != 192 && bits != 256 )
418 return( PSA_ERROR_INVALID_ARGUMENT );
419 break;
420#endif
421#if defined(MBEDTLS_CAMELLIA_C)
422 case PSA_KEY_TYPE_CAMELLIA:
423 if( bits != 128 && bits != 192 && bits != 256 )
424 return( PSA_ERROR_INVALID_ARGUMENT );
425 break;
426#endif
427#if defined(MBEDTLS_DES_C)
428 case PSA_KEY_TYPE_DES:
429 if( bits != 64 && bits != 128 && bits != 192 )
430 return( PSA_ERROR_INVALID_ARGUMENT );
431 break;
432#endif
433#if defined(MBEDTLS_ARC4_C)
434 case PSA_KEY_TYPE_ARC4:
435 if( bits < 8 || bits > 2048 )
436 return( PSA_ERROR_INVALID_ARGUMENT );
437 break;
438#endif
439 default:
440 return( PSA_ERROR_NOT_SUPPORTED );
441 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200442 if( bits % 8 != 0 )
443 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200444
445 /* Allocate memory for the key */
446 raw->bytes = PSA_BITS_TO_BYTES( bits );
447 raw->data = mbedtls_calloc( 1, raw->bytes );
448 if( raw->data == NULL )
449 {
450 raw->bytes = 0;
451 return( PSA_ERROR_INSUFFICIENT_MEMORY );
452 }
453 return( PSA_SUCCESS );
454}
455
Gilles Peskine2d277862018-06-18 15:41:12 +0200456psa_status_t psa_import_key( psa_key_slot_t key,
457 psa_key_type_t type,
458 const uint8_t *data,
459 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100460{
461 key_slot_t *slot;
462
Gilles Peskine828ed142018-06-18 23:25:51 +0200463 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100464 return( PSA_ERROR_INVALID_ARGUMENT );
465 slot = &global_data.key_slots[key];
466 if( slot->type != PSA_KEY_TYPE_NONE )
467 return( PSA_ERROR_OCCUPIED_SLOT );
468
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200469 if( key_type_is_raw_bytes( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100470 {
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200471 psa_status_t status;
Gilles Peskine6d912132018-03-07 16:41:37 +0100472 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100473 if( data_length > SIZE_MAX / 8 )
474 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200475 status = prepare_raw_data_slot( type,
476 PSA_BYTES_TO_BITS( data_length ),
477 &slot->data.raw );
478 if( status != PSA_SUCCESS )
479 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100480 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100481 }
482 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100483#if defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100484 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
485 type == PSA_KEY_TYPE_RSA_KEYPAIR ||
486 PSA_KEY_TYPE_IS_ECC( type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100487 {
488 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100489 mbedtls_pk_context pk;
Gilles Peskinec648d692018-06-28 08:46:13 +0200490 psa_status_t status = PSA_SUCCESS;
Gilles Peskine969ac722018-01-28 18:16:59 +0100491 mbedtls_pk_init( &pk );
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100492 if( PSA_KEY_TYPE_IS_KEYPAIR( type ) )
493 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
494 else
495 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100496 if( ret != 0 )
497 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine969ac722018-01-28 18:16:59 +0100498 switch( mbedtls_pk_get_type( &pk ) )
499 {
500#if defined(MBEDTLS_RSA_C)
501 case MBEDTLS_PK_RSA:
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100502 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
503 type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200504 slot->data.rsa = mbedtls_pk_rsa( pk );
Gilles Peskine969ac722018-01-28 18:16:59 +0100505 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200506 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100507 break;
508#endif /* MBEDTLS_RSA_C */
509#if defined(MBEDTLS_ECP_C)
510 case MBEDTLS_PK_ECKEY:
511 if( PSA_KEY_TYPE_IS_ECC( type ) )
512 {
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200513 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( pk );
514 psa_ecc_curve_t actual_curve =
515 mbedtls_ecc_group_to_psa( ecp->grp.id );
516 psa_ecc_curve_t expected_curve =
517 PSA_KEY_TYPE_GET_CURVE( type );
518 if( actual_curve != expected_curve )
Gilles Peskinec648d692018-06-28 08:46:13 +0200519 {
520 status = PSA_ERROR_INVALID_ARGUMENT;
521 break;
522 }
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200523 slot->data.ecp = ecp;
Gilles Peskine969ac722018-01-28 18:16:59 +0100524 }
525 else
Gilles Peskinec648d692018-06-28 08:46:13 +0200526 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine969ac722018-01-28 18:16:59 +0100527 break;
528#endif /* MBEDTLS_ECP_C */
529 default:
Gilles Peskinec648d692018-06-28 08:46:13 +0200530 status = PSA_ERROR_INVALID_ARGUMENT;
531 break;
532 }
533 /* Free the content of the pk object only on error. On success,
534 * the content of the object has been stored in the slot. */
535 if( status != PSA_SUCCESS )
536 {
537 mbedtls_pk_free( &pk );
538 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100539 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100540 }
541 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100542#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100543 {
544 return( PSA_ERROR_NOT_SUPPORTED );
545 }
546
547 slot->type = type;
548 return( PSA_SUCCESS );
549}
550
Gilles Peskine2d277862018-06-18 15:41:12 +0200551psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100552{
553 key_slot_t *slot;
554
Gilles Peskine828ed142018-06-18 23:25:51 +0200555 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100556 return( PSA_ERROR_INVALID_ARGUMENT );
557 slot = &global_data.key_slots[key];
558 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200559 {
560 /* No key material to clean, but do zeroize the slot below to wipe
561 * metadata such as policies. */
562 }
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200563 else if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100564 {
565 mbedtls_free( slot->data.raw.data );
566 }
567 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100568#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100569 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
570 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100571 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100572 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100573 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100574 }
575 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100576#endif /* defined(MBEDTLS_RSA_C) */
577#if defined(MBEDTLS_ECP_C)
578 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
579 {
580 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100581 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100582 }
583 else
584#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100585 {
586 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100587 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100588 return( PSA_ERROR_TAMPERING_DETECTED );
589 }
590
591 mbedtls_zeroize( slot, sizeof( *slot ) );
592 return( PSA_SUCCESS );
593}
594
Gilles Peskine2d277862018-06-18 15:41:12 +0200595psa_status_t psa_get_key_information( psa_key_slot_t key,
596 psa_key_type_t *type,
597 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100598{
599 key_slot_t *slot;
600
Gilles Peskine828ed142018-06-18 23:25:51 +0200601 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100602 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100603 slot = &global_data.key_slots[key];
604 if( type != NULL )
605 *type = slot->type;
606 if( bits != NULL )
607 *bits = 0;
608 if( slot->type == PSA_KEY_TYPE_NONE )
609 return( PSA_ERROR_EMPTY_SLOT );
610
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200611 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100612 {
613 if( bits != NULL )
614 *bits = slot->data.raw.bytes * 8;
615 }
616 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100617#if defined(MBEDTLS_RSA_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100618 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
619 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100620 {
621 if( bits != NULL )
Gilles Peskine969ac722018-01-28 18:16:59 +0100622 *bits = mbedtls_rsa_get_bitlen( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100623 }
624 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100625#endif /* defined(MBEDTLS_RSA_C) */
626#if defined(MBEDTLS_ECP_C)
627 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
628 {
629 if( bits != NULL )
630 *bits = slot->data.ecp->grp.pbits;
631 }
632 else
633#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100634 {
635 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100636 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100637 return( PSA_ERROR_TAMPERING_DETECTED );
638 }
639
640 return( PSA_SUCCESS );
641}
642
Gilles Peskine2d277862018-06-18 15:41:12 +0200643static psa_status_t psa_internal_export_key( psa_key_slot_t key,
644 uint8_t *data,
645 size_t data_size,
646 size_t *data_length,
647 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100648{
649 key_slot_t *slot;
650
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100651 /* Set the key to empty now, so that even when there are errors, we always
652 * set data_length to a value between 0 and data_size. On error, setting
653 * the key to empty is a good choice because an empty key representation is
654 * unlikely to be accepted anywhere. */
655 *data_length = 0;
656
Gilles Peskine828ed142018-06-18 23:25:51 +0200657 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100658 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100659 slot = &global_data.key_slots[key];
660 if( slot->type == PSA_KEY_TYPE_NONE )
661 return( PSA_ERROR_EMPTY_SLOT );
662
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200663 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300664 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300665
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200666 if( ! export_public_key &&
667 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) &&
668 ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
Moran Peker87567632018-06-04 18:41:37 +0300669 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine2d277862018-06-18 15:41:12 +0200670
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200671 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100672 {
673 if( slot->data.raw.bytes > data_size )
674 return( PSA_ERROR_BUFFER_TOO_SMALL );
675 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
676 *data_length = slot->data.raw.bytes;
677 return( PSA_SUCCESS );
678 }
679 else
Moran Peker17e36e12018-05-02 12:55:20 +0300680 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100681#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100682 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
Moran Pekera998bc62018-04-16 18:16:20 +0300683 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
684 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100685 {
Moran Pekera998bc62018-04-16 18:16:20 +0300686 mbedtls_pk_context pk;
687 int ret;
688 mbedtls_pk_init( &pk );
689 if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY ||
690 slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
691 {
692 pk.pk_info = &mbedtls_rsa_info;
693 pk.pk_ctx = slot->data.rsa;
694 }
695 else
696 {
697 pk.pk_info = &mbedtls_eckey_info;
698 pk.pk_ctx = slot->data.ecp;
699 }
Moran Pekerd7326592018-05-29 16:56:39 +0300700 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300701 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300702 else
703 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300704 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200705 {
706 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300707 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200708 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200709 /* The mbedtls_pk_xxx functions write to the end of the buffer.
710 * Move the data to the beginning and erase remaining data
711 * at the original location. */
712 if( 2 * (size_t) ret <= data_size )
713 {
714 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200715 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200716 }
717 else if( (size_t) ret < data_size )
718 {
719 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200720 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200721 }
Moran Pekera998bc62018-04-16 18:16:20 +0300722 *data_length = ret;
723 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100724 }
725 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100726#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300727 {
728 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +0200729 it is valid for a special-purpose implementation to omit
730 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +0300731 return( PSA_ERROR_NOT_SUPPORTED );
732 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100733 }
734}
735
Gilles Peskine2d277862018-06-18 15:41:12 +0200736psa_status_t psa_export_key( psa_key_slot_t key,
737 uint8_t *data,
738 size_t data_size,
739 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +0300740{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200741 return( psa_internal_export_key( key, data, data_size,
742 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100743}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100744
Gilles Peskine2d277862018-06-18 15:41:12 +0200745psa_status_t psa_export_public_key( psa_key_slot_t key,
746 uint8_t *data,
747 size_t data_size,
748 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +0300749{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200750 return( psa_internal_export_key( key, data, data_size,
751 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +0300752}
753
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200754
755
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100756/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +0100757/* Message digests */
758/****************************************************************/
759
Gilles Peskinedc2fc842018-03-07 16:42:59 +0100760static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +0100761{
762 switch( alg )
763 {
764#if defined(MBEDTLS_MD2_C)
765 case PSA_ALG_MD2:
766 return( &mbedtls_md2_info );
767#endif
768#if defined(MBEDTLS_MD4_C)
769 case PSA_ALG_MD4:
770 return( &mbedtls_md4_info );
771#endif
772#if defined(MBEDTLS_MD5_C)
773 case PSA_ALG_MD5:
774 return( &mbedtls_md5_info );
775#endif
776#if defined(MBEDTLS_RIPEMD160_C)
777 case PSA_ALG_RIPEMD160:
778 return( &mbedtls_ripemd160_info );
779#endif
780#if defined(MBEDTLS_SHA1_C)
781 case PSA_ALG_SHA_1:
782 return( &mbedtls_sha1_info );
783#endif
784#if defined(MBEDTLS_SHA256_C)
785 case PSA_ALG_SHA_224:
786 return( &mbedtls_sha224_info );
787 case PSA_ALG_SHA_256:
788 return( &mbedtls_sha256_info );
789#endif
790#if defined(MBEDTLS_SHA512_C)
791 case PSA_ALG_SHA_384:
792 return( &mbedtls_sha384_info );
793 case PSA_ALG_SHA_512:
794 return( &mbedtls_sha512_info );
795#endif
796 default:
797 return( NULL );
798 }
799}
800
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100801psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
802{
803 switch( operation->alg )
804 {
Gilles Peskine81736312018-06-26 15:04:31 +0200805 case 0:
806 /* The object has (apparently) been initialized but it is not
807 * in use. It's ok to call abort on such an object, and there's
808 * nothing to do. */
809 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100810#if defined(MBEDTLS_MD2_C)
811 case PSA_ALG_MD2:
812 mbedtls_md2_free( &operation->ctx.md2 );
813 break;
814#endif
815#if defined(MBEDTLS_MD4_C)
816 case PSA_ALG_MD4:
817 mbedtls_md4_free( &operation->ctx.md4 );
818 break;
819#endif
820#if defined(MBEDTLS_MD5_C)
821 case PSA_ALG_MD5:
822 mbedtls_md5_free( &operation->ctx.md5 );
823 break;
824#endif
825#if defined(MBEDTLS_RIPEMD160_C)
826 case PSA_ALG_RIPEMD160:
827 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
828 break;
829#endif
830#if defined(MBEDTLS_SHA1_C)
831 case PSA_ALG_SHA_1:
832 mbedtls_sha1_free( &operation->ctx.sha1 );
833 break;
834#endif
835#if defined(MBEDTLS_SHA256_C)
836 case PSA_ALG_SHA_224:
837 case PSA_ALG_SHA_256:
838 mbedtls_sha256_free( &operation->ctx.sha256 );
839 break;
840#endif
841#if defined(MBEDTLS_SHA512_C)
842 case PSA_ALG_SHA_384:
843 case PSA_ALG_SHA_512:
844 mbedtls_sha512_free( &operation->ctx.sha512 );
845 break;
846#endif
847 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +0200848 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100849 }
850 operation->alg = 0;
851 return( PSA_SUCCESS );
852}
853
854psa_status_t psa_hash_start( psa_hash_operation_t *operation,
855 psa_algorithm_t alg )
856{
857 int ret;
858 operation->alg = 0;
859 switch( alg )
860 {
861#if defined(MBEDTLS_MD2_C)
862 case PSA_ALG_MD2:
863 mbedtls_md2_init( &operation->ctx.md2 );
864 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
865 break;
866#endif
867#if defined(MBEDTLS_MD4_C)
868 case PSA_ALG_MD4:
869 mbedtls_md4_init( &operation->ctx.md4 );
870 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
871 break;
872#endif
873#if defined(MBEDTLS_MD5_C)
874 case PSA_ALG_MD5:
875 mbedtls_md5_init( &operation->ctx.md5 );
876 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
877 break;
878#endif
879#if defined(MBEDTLS_RIPEMD160_C)
880 case PSA_ALG_RIPEMD160:
881 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
882 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
883 break;
884#endif
885#if defined(MBEDTLS_SHA1_C)
886 case PSA_ALG_SHA_1:
887 mbedtls_sha1_init( &operation->ctx.sha1 );
888 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
889 break;
890#endif
891#if defined(MBEDTLS_SHA256_C)
892 case PSA_ALG_SHA_224:
893 mbedtls_sha256_init( &operation->ctx.sha256 );
894 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
895 break;
896 case PSA_ALG_SHA_256:
897 mbedtls_sha256_init( &operation->ctx.sha256 );
898 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
899 break;
900#endif
901#if defined(MBEDTLS_SHA512_C)
902 case PSA_ALG_SHA_384:
903 mbedtls_sha512_init( &operation->ctx.sha512 );
904 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
905 break;
906 case PSA_ALG_SHA_512:
907 mbedtls_sha512_init( &operation->ctx.sha512 );
908 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
909 break;
910#endif
911 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +0200912 return( PSA_ALG_IS_HASH( alg ) ?
913 PSA_ERROR_NOT_SUPPORTED :
914 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100915 }
916 if( ret == 0 )
917 operation->alg = alg;
918 else
919 psa_hash_abort( operation );
920 return( mbedtls_to_psa_error( ret ) );
921}
922
923psa_status_t psa_hash_update( psa_hash_operation_t *operation,
924 const uint8_t *input,
925 size_t input_length )
926{
927 int ret;
928 switch( operation->alg )
929 {
930#if defined(MBEDTLS_MD2_C)
931 case PSA_ALG_MD2:
932 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
933 input, input_length );
934 break;
935#endif
936#if defined(MBEDTLS_MD4_C)
937 case PSA_ALG_MD4:
938 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
939 input, input_length );
940 break;
941#endif
942#if defined(MBEDTLS_MD5_C)
943 case PSA_ALG_MD5:
944 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
945 input, input_length );
946 break;
947#endif
948#if defined(MBEDTLS_RIPEMD160_C)
949 case PSA_ALG_RIPEMD160:
950 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
951 input, input_length );
952 break;
953#endif
954#if defined(MBEDTLS_SHA1_C)
955 case PSA_ALG_SHA_1:
956 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
957 input, input_length );
958 break;
959#endif
960#if defined(MBEDTLS_SHA256_C)
961 case PSA_ALG_SHA_224:
962 case PSA_ALG_SHA_256:
963 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
964 input, input_length );
965 break;
966#endif
967#if defined(MBEDTLS_SHA512_C)
968 case PSA_ALG_SHA_384:
969 case PSA_ALG_SHA_512:
970 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
971 input, input_length );
972 break;
973#endif
974 default:
975 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
976 break;
977 }
978 if( ret != 0 )
979 psa_hash_abort( operation );
980 return( mbedtls_to_psa_error( ret ) );
981}
982
983psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
984 uint8_t *hash,
985 size_t hash_size,
986 size_t *hash_length )
987{
988 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +0200989 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +0100990
991 /* Fill the output buffer with something that isn't a valid hash
992 * (barring an attack on the hash and deliberately-crafted input),
993 * in case the caller doesn't check the return status properly. */
994 *hash_length = actual_hash_length;
995 memset( hash, '!', hash_size );
996
997 if( hash_size < actual_hash_length )
998 return( PSA_ERROR_BUFFER_TOO_SMALL );
999
1000 switch( operation->alg )
1001 {
1002#if defined(MBEDTLS_MD2_C)
1003 case PSA_ALG_MD2:
1004 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1005 break;
1006#endif
1007#if defined(MBEDTLS_MD4_C)
1008 case PSA_ALG_MD4:
1009 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1010 break;
1011#endif
1012#if defined(MBEDTLS_MD5_C)
1013 case PSA_ALG_MD5:
1014 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1015 break;
1016#endif
1017#if defined(MBEDTLS_RIPEMD160_C)
1018 case PSA_ALG_RIPEMD160:
1019 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1020 break;
1021#endif
1022#if defined(MBEDTLS_SHA1_C)
1023 case PSA_ALG_SHA_1:
1024 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1025 break;
1026#endif
1027#if defined(MBEDTLS_SHA256_C)
1028 case PSA_ALG_SHA_224:
1029 case PSA_ALG_SHA_256:
1030 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1031 break;
1032#endif
1033#if defined(MBEDTLS_SHA512_C)
1034 case PSA_ALG_SHA_384:
1035 case PSA_ALG_SHA_512:
1036 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1037 break;
1038#endif
1039 default:
1040 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1041 break;
1042 }
1043
1044 if( ret == 0 )
1045 {
1046 return( psa_hash_abort( operation ) );
1047 }
1048 else
1049 {
1050 psa_hash_abort( operation );
1051 return( mbedtls_to_psa_error( ret ) );
1052 }
1053}
1054
Gilles Peskine2d277862018-06-18 15:41:12 +02001055psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1056 const uint8_t *hash,
1057 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001058{
1059 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1060 size_t actual_hash_length;
1061 psa_status_t status = psa_hash_finish( operation,
1062 actual_hash, sizeof( actual_hash ),
1063 &actual_hash_length );
1064 if( status != PSA_SUCCESS )
1065 return( status );
1066 if( actual_hash_length != hash_length )
1067 return( PSA_ERROR_INVALID_SIGNATURE );
1068 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1069 return( PSA_ERROR_INVALID_SIGNATURE );
1070 return( PSA_SUCCESS );
1071}
1072
1073
1074
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001075/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001076/* MAC */
1077/****************************************************************/
1078
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001079static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001080 psa_algorithm_t alg,
1081 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001082 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001083 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001084{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001085 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001086 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001087
1088 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1089 {
1090 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
mohammad16038481e742018-03-18 13:57:31 +02001091 {
1092 alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
1093 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001094
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001095 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001096 {
1097 case PSA_ALG_STREAM_CIPHER:
1098 mode = MBEDTLS_MODE_STREAM;
1099 break;
1100 case PSA_ALG_CBC_BASE:
1101 mode = MBEDTLS_MODE_CBC;
1102 break;
1103 case PSA_ALG_CFB_BASE:
1104 mode = MBEDTLS_MODE_CFB;
1105 break;
1106 case PSA_ALG_OFB_BASE:
1107 mode = MBEDTLS_MODE_OFB;
1108 break;
1109 case PSA_ALG_CTR:
1110 mode = MBEDTLS_MODE_CTR;
1111 break;
1112 case PSA_ALG_CCM:
1113 mode = MBEDTLS_MODE_CCM;
1114 break;
1115 case PSA_ALG_GCM:
1116 mode = MBEDTLS_MODE_GCM;
1117 break;
1118 default:
1119 return( NULL );
1120 }
1121 }
1122 else if( alg == PSA_ALG_CMAC )
1123 mode = MBEDTLS_MODE_ECB;
1124 else if( alg == PSA_ALG_GMAC )
1125 mode = MBEDTLS_MODE_GCM;
1126 else
1127 return( NULL );
1128
1129 switch( key_type )
1130 {
1131 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001132 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001133 break;
1134 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001135 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1136 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001137 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001138 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001139 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001140 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001141 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1142 * but two-key Triple-DES is functionally three-key Triple-DES
1143 * with K1=K3, so that's how we present it to mbedtls. */
1144 if( key_bits == 128 )
1145 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001146 break;
1147 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001148 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001149 break;
1150 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001151 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001152 break;
1153 default:
1154 return( NULL );
1155 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001156 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001157 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001158
mohammad1603f4f0d612018-06-03 15:04:51 +03001159 return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001160}
1161
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001162static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001163{
Gilles Peskine2d277862018-06-18 15:41:12 +02001164 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001165 {
1166 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001167 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001168 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001169 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001170 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001171 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001172 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001173 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001174 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001175 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001176 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001177 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001178 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001179 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001180 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001181 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001182 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001183 return( 128 );
1184 default:
1185 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001186 }
1187}
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001188
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001189/* Initialize the MAC operation structure. Once this function has been
1190 * called, psa_mac_abort can run and will do the right thing. */
1191static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1192 psa_algorithm_t alg )
1193{
1194 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1195
1196 operation->alg = alg;
1197 operation->key_set = 0;
1198 operation->iv_set = 0;
1199 operation->iv_required = 0;
1200 operation->has_input = 0;
1201 operation->key_usage_sign = 0;
1202 operation->key_usage_verify = 0;
1203
1204#if defined(MBEDTLS_CMAC_C)
1205 if( alg == PSA_ALG_CMAC )
1206 {
1207 operation->iv_required = 0;
1208 mbedtls_cipher_init( &operation->ctx.cmac );
1209 status = PSA_SUCCESS;
1210 }
1211 else
1212#endif /* MBEDTLS_CMAC_C */
1213#if defined(MBEDTLS_MD_C)
1214 if( PSA_ALG_IS_HMAC( operation->alg ) )
1215 {
1216 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1217 PSA_ALG_HMAC_HASH( alg ) );
1218 }
1219 else
1220#endif /* MBEDTLS_MD_C */
1221 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001222 if( ! PSA_ALG_IS_MAC( alg ) )
1223 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001224 }
1225
1226 if( status != PSA_SUCCESS )
1227 memset( operation, 0, sizeof( *operation ) );
1228 return( status );
1229}
1230
Gilles Peskine8c9def32018-02-08 10:02:12 +01001231psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1232{
1233 switch( operation->alg )
1234 {
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001235 case 0:
Gilles Peskine81736312018-06-26 15:04:31 +02001236 /* The object has (apparently) been initialized but it is not
1237 * in use. It's ok to call abort on such an object, and there's
1238 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001239 return( PSA_SUCCESS );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001240#if defined(MBEDTLS_CMAC_C)
1241 case PSA_ALG_CMAC:
1242 mbedtls_cipher_free( &operation->ctx.cmac );
1243 break;
1244#endif /* MBEDTLS_CMAC_C */
1245 default:
1246#if defined(MBEDTLS_MD_C)
1247 if( PSA_ALG_IS_HMAC( operation->alg ) )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001248 {
Gilles Peskine99bc6492018-06-11 17:13:00 +02001249 unsigned int block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001250 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001251
Gilles Peskine99bc6492018-06-11 17:13:00 +02001252 if( block_size == 0 )
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001253 return( PSA_ERROR_NOT_SUPPORTED );
1254
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001255 psa_hash_abort( &operation->ctx.hmac.hash_ctx );
Gilles Peskine2d277862018-06-18 15:41:12 +02001256 mbedtls_zeroize( operation->ctx.hmac.opad, block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001257 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001258 else
1259#endif /* MBEDTLS_MD_C */
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001260 {
1261 /* Sanity check (shouldn't happen: operation->alg should
1262 * always have been initialized to a valid value). */
1263 return( PSA_ERROR_BAD_STATE );
1264 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001265 }
Moran Peker41deec42018-04-04 15:43:05 +03001266
Gilles Peskine8c9def32018-02-08 10:02:12 +01001267 operation->alg = 0;
1268 operation->key_set = 0;
1269 operation->iv_set = 0;
1270 operation->iv_required = 0;
1271 operation->has_input = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001272 operation->key_usage_sign = 0;
1273 operation->key_usage_verify = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001274
Gilles Peskine8c9def32018-02-08 10:02:12 +01001275 return( PSA_SUCCESS );
1276}
1277
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001278#if defined(MBEDTLS_CMAC_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001279static int psa_cmac_start( psa_mac_operation_t *operation,
1280 size_t key_bits,
1281 key_slot_t *slot,
1282 const mbedtls_cipher_info_t *cipher_info )
1283{
1284 int ret;
1285
1286 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001287
1288 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1289 if( ret != 0 )
1290 return( ret );
1291
1292 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1293 slot->data.raw.data,
1294 key_bits );
1295 return( ret );
1296}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001297#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001298
Gilles Peskine248051a2018-06-20 16:09:38 +02001299#if defined(MBEDTLS_MD_C)
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001300static int psa_hmac_start( psa_mac_operation_t *operation,
1301 psa_key_type_t key_type,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001302 key_slot_t *slot,
1303 psa_algorithm_t alg )
1304{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001305 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001306 unsigned char *opad = operation->ctx.hmac.opad;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001307 size_t i;
Gilles Peskinee1bc6802018-06-11 17:36:05 +02001308 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001309 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001310 unsigned int digest_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001311 PSA_HASH_SIZE( PSA_ALG_HMAC_HASH( alg ) );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001312 size_t key_length = slot->data.raw.bytes;
1313 psa_status_t status;
1314
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001315 if( block_size == 0 || digest_size == 0 )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001316 return( PSA_ERROR_NOT_SUPPORTED );
1317
1318 if( key_type != PSA_KEY_TYPE_HMAC )
1319 return( PSA_ERROR_INVALID_ARGUMENT );
1320
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001321 operation->mac_size = digest_size;
1322
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001323 /* The hash was started earlier in psa_mac_init. */
Gilles Peskined223b522018-06-11 18:12:58 +02001324 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001325 {
1326 status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001327 slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001328 if( status != PSA_SUCCESS )
1329 return( status );
1330 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001331 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001332 if( status != PSA_SUCCESS )
1333 return( status );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001334 }
Gilles Peskined223b522018-06-11 18:12:58 +02001335 else
1336 memcpy( ipad, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001337
Gilles Peskined223b522018-06-11 18:12:58 +02001338 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1339 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001340 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001341 ipad[i] ^= 0x36;
1342 memset( ipad + key_length, 0x36, block_size - key_length );
1343
1344 /* Copy the key material from ipad to opad, flipping the requisite bits,
1345 * and filling the rest of opad with the requisite constant. */
1346 for( i = 0; i < key_length; i++ )
1347 opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1348 memset( opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001349
1350 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1351 PSA_ALG_HMAC_HASH( alg ) );
1352 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001353 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001354
1355 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, ipad,
1356 block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001357
1358cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001359 mbedtls_zeroize( ipad, key_length );
1360 /* opad is in the context. It needs to stay in memory if this function
1361 * succeeds, and it will be wiped by psa_mac_abort() called from
1362 * psa_mac_start in the error case. */
1363
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001364 return( status );
1365}
Gilles Peskine248051a2018-06-20 16:09:38 +02001366#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001367
Gilles Peskine8c9def32018-02-08 10:02:12 +01001368psa_status_t psa_mac_start( psa_mac_operation_t *operation,
1369 psa_key_slot_t key,
1370 psa_algorithm_t alg )
1371{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001372 psa_status_t status;
1373 key_slot_t *slot;
1374 psa_key_type_t key_type;
1375 size_t key_bits;
Gilles Peskine828ed142018-06-18 23:25:51 +02001376 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001377
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001378 status = psa_mac_init( operation, alg );
1379 if( status != PSA_SUCCESS )
1380 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001381
1382 status = psa_get_key_information( key, &key_type, &key_bits );
1383 if( status != PSA_SUCCESS )
1384 return( status );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001385
Gilles Peskine8c9def32018-02-08 10:02:12 +01001386 slot = &global_data.key_slots[key];
Gilles Peskine99bc6492018-06-11 17:13:00 +02001387 if( slot->type == PSA_KEY_TYPE_NONE )
1388 return( PSA_ERROR_EMPTY_SLOT );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001389
Moran Pekerd7326592018-05-29 16:56:39 +03001390 if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001391 operation->key_usage_sign = 1;
1392
Moran Pekerd7326592018-05-29 16:56:39 +03001393 if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 )
mohammad16036df908f2018-04-02 08:34:15 -07001394 operation->key_usage_verify = 1;
1395
Gilles Peskine8c9def32018-02-08 10:02:12 +01001396 if( ! PSA_ALG_IS_HMAC( alg ) )
1397 {
mohammad1603f4f0d612018-06-03 15:04:51 +03001398 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001399 if( cipher_info == NULL )
1400 return( PSA_ERROR_NOT_SUPPORTED );
1401 operation->mac_size = cipher_info->block_size;
1402 }
1403 switch( alg )
1404 {
1405#if defined(MBEDTLS_CMAC_C)
1406 case PSA_ALG_CMAC:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001407 status = mbedtls_to_psa_error( psa_cmac_start( operation,
1408 key_bits,
1409 slot,
1410 cipher_info ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001411 break;
1412#endif /* MBEDTLS_CMAC_C */
1413 default:
1414#if defined(MBEDTLS_MD_C)
1415 if( PSA_ALG_IS_HMAC( alg ) )
Gilles Peskined223b522018-06-11 18:12:58 +02001416 status = psa_hmac_start( operation, key_type, slot, alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001417 else
1418#endif /* MBEDTLS_MD_C */
1419 return( PSA_ERROR_NOT_SUPPORTED );
1420 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001421
Gilles Peskine8c9def32018-02-08 10:02:12 +01001422 /* If we reach this point, then the algorithm-specific part of the
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001423 * context may contain data that needs to be wiped on error. */
1424 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001425 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001426 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001427 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001428 else
1429 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001430 operation->key_set = 1;
1431 }
1432 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001433}
1434
1435psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1436 const uint8_t *input,
1437 size_t input_length )
1438{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001439 int ret = 0 ;
1440 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001441 if( ! operation->key_set )
1442 return( PSA_ERROR_BAD_STATE );
1443 if( operation->iv_required && ! operation->iv_set )
1444 return( PSA_ERROR_BAD_STATE );
1445 operation->has_input = 1;
1446
1447 switch( operation->alg )
1448 {
1449#if defined(MBEDTLS_CMAC_C)
1450 case PSA_ALG_CMAC:
1451 ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1452 input, input_length );
1453 break;
1454#endif /* MBEDTLS_CMAC_C */
1455 default:
1456#if defined(MBEDTLS_MD_C)
1457 if( PSA_ALG_IS_HMAC( operation->alg ) )
1458 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001459 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
Gilles Peskine2d277862018-06-18 15:41:12 +02001460 input_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001461 }
1462 else
1463#endif /* MBEDTLS_MD_C */
1464 {
1465 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1466 }
1467 break;
1468 }
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001469 if( ret != 0 || status != PSA_SUCCESS )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001470 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001471 psa_mac_abort( operation );
Gilles Peskine2d277862018-06-18 15:41:12 +02001472 if( ret != 0 )
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001473 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001474 }
1475
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001476 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001477}
1478
mohammad16036df908f2018-04-02 08:34:15 -07001479static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001480 uint8_t *mac,
1481 size_t mac_size,
1482 size_t *mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001483{
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001484 int ret = 0;
1485 psa_status_t status = PSA_SUCCESS;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001486 if( ! operation->key_set )
1487 return( PSA_ERROR_BAD_STATE );
1488 if( operation->iv_required && ! operation->iv_set )
1489 return( PSA_ERROR_BAD_STATE );
1490
1491 /* Fill the output buffer with something that isn't a valid mac
1492 * (barring an attack on the mac and deliberately-crafted input),
1493 * in case the caller doesn't check the return status properly. */
1494 *mac_length = operation->mac_size;
1495 memset( mac, '!', mac_size );
1496
1497 if( mac_size < operation->mac_size )
1498 return( PSA_ERROR_BUFFER_TOO_SMALL );
1499
1500 switch( operation->alg )
1501 {
1502#if defined(MBEDTLS_CMAC_C)
1503 case PSA_ALG_CMAC:
1504 ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
1505 break;
1506#endif /* MBEDTLS_CMAC_C */
1507 default:
1508#if defined(MBEDTLS_MD_C)
1509 if( PSA_ALG_IS_HMAC( operation->alg ) )
1510 {
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001511 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Nir Sonnenschein5ca65472018-06-17 14:03:40 +03001512 unsigned char *opad = operation->ctx.hmac.opad;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001513 size_t hash_size = 0;
Nir Sonnenschein96272412018-06-17 14:41:10 +03001514 size_t block_size =
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001515 psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) );
Nir Sonnenschein084832d2018-06-08 22:52:24 +03001516
Gilles Peskine99bc6492018-06-11 17:13:00 +02001517 if( block_size == 0 )
1518 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001519
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001520 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine99bc6492018-06-11 17:13:00 +02001521 sizeof( tmp ), &hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001522 if( status != PSA_SUCCESS )
1523 goto cleanup;
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001524 /* From here on, tmp needs to be wiped. */
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001525
1526 status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
1527 PSA_ALG_HMAC_HASH( operation->alg ) );
1528 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001529 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001530
1531 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, opad,
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001532 block_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001533 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001534 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001535
1536 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, tmp,
Gilles Peskine2d277862018-06-18 15:41:12 +02001537 hash_size );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001538 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001539 goto hmac_cleanup;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001540
1541 status = psa_hash_finish( &operation->ctx.hmac.hash_ctx, mac,
1542 mac_size, mac_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001543 hmac_cleanup:
1544 mbedtls_zeroize( tmp, hash_size );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001545 }
1546 else
1547#endif /* MBEDTLS_MD_C */
1548 {
1549 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1550 }
1551 break;
1552 }
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001553cleanup:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001554
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001555 if( ret == 0 && status == PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001556 {
1557 return( psa_mac_abort( operation ) );
1558 }
1559 else
1560 {
1561 psa_mac_abort( operation );
Gilles Peskine99bc6492018-06-11 17:13:00 +02001562 if( ret != 0 )
Gilles Peskine2d277862018-06-18 15:41:12 +02001563 status = mbedtls_to_psa_error( ret );
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001564
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001565 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001566 }
1567}
1568
mohammad16036df908f2018-04-02 08:34:15 -07001569psa_status_t psa_mac_finish( psa_mac_operation_t *operation,
1570 uint8_t *mac,
1571 size_t mac_size,
1572 size_t *mac_length )
1573{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001574 if( ! operation->key_usage_sign )
mohammad16036df908f2018-04-02 08:34:15 -07001575 return( PSA_ERROR_NOT_PERMITTED );
1576
Gilles Peskine99bc6492018-06-11 17:13:00 +02001577 return( psa_mac_finish_internal( operation, mac,
1578 mac_size, mac_length ) );
mohammad16036df908f2018-04-02 08:34:15 -07001579}
1580
Gilles Peskine828ed142018-06-18 23:25:51 +02001581#define PSA_MAC_MAX_SIZE \
Gilles Peskine2d277862018-06-18 15:41:12 +02001582 ( MBEDTLS_MD_MAX_SIZE > MBEDTLS_MAX_BLOCK_LENGTH ? \
1583 MBEDTLS_MD_MAX_SIZE : \
Gilles Peskine8c9def32018-02-08 10:02:12 +01001584 MBEDTLS_MAX_BLOCK_LENGTH )
1585psa_status_t psa_mac_verify( psa_mac_operation_t *operation,
1586 const uint8_t *mac,
1587 size_t mac_length )
1588{
Gilles Peskine828ed142018-06-18 23:25:51 +02001589 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
Gilles Peskine8c9def32018-02-08 10:02:12 +01001590 size_t actual_mac_length;
mohammad16036df908f2018-04-02 08:34:15 -07001591 psa_status_t status;
1592
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001593 if( ! operation->key_usage_verify )
mohammad16036df908f2018-04-02 08:34:15 -07001594 return( PSA_ERROR_NOT_PERMITTED );
1595
1596 status = psa_mac_finish_internal( operation,
1597 actual_mac, sizeof( actual_mac ),
1598 &actual_mac_length );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001599 if( status != PSA_SUCCESS )
1600 return( status );
1601 if( actual_mac_length != mac_length )
1602 return( PSA_ERROR_INVALID_SIGNATURE );
1603 if( safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
1604 return( PSA_ERROR_INVALID_SIGNATURE );
1605 return( PSA_SUCCESS );
1606}
1607
1608
Gilles Peskine20035e32018-02-03 22:44:14 +01001609
Gilles Peskine20035e32018-02-03 22:44:14 +01001610/****************************************************************/
1611/* Asymmetric cryptography */
1612/****************************************************************/
1613
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001614/* Decode the hash algorithm from alg and store the mbedtls encoding in
1615 * md_alg. Verify that the hash length is consistent. */
1616static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
1617 size_t hash_length,
1618 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001619{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02001620 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001621 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
1622 *md_alg = hash_alg == 0 ? MBEDTLS_MD_NONE : mbedtls_md_get_type( md_info );
1623 if( *md_alg == MBEDTLS_MD_NONE )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001624 {
1625#if SIZE_MAX > UINT_MAX
Gilles Peskine61b91d42018-06-08 16:09:36 +02001626 if( hash_length > UINT_MAX )
1627 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001628#endif
1629 }
1630 else
1631 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001632 if( mbedtls_md_get_size( md_info ) != hash_length )
1633 return( PSA_ERROR_INVALID_ARGUMENT );
1634 if( md_info == NULL )
1635 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001636 }
Gilles Peskine61b91d42018-06-08 16:09:36 +02001637 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001638}
1639
Gilles Peskine61b91d42018-06-08 16:09:36 +02001640psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
1641 psa_algorithm_t alg,
1642 const uint8_t *hash,
1643 size_t hash_length,
1644 const uint8_t *salt,
1645 size_t salt_length,
1646 uint8_t *signature,
1647 size_t signature_size,
1648 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01001649{
1650 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001651 psa_status_t status;
Gilles Peskine93aa0332018-02-03 23:58:03 +01001652 *signature_length = 0;
1653 (void) salt;
1654 (void) salt_length;
1655
Gilles Peskine828ed142018-06-18 23:25:51 +02001656 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Gilles Peskine20035e32018-02-03 22:44:14 +01001657 return( PSA_ERROR_EMPTY_SLOT );
1658 slot = &global_data.key_slots[key];
1659 if( slot->type == PSA_KEY_TYPE_NONE )
1660 return( PSA_ERROR_EMPTY_SLOT );
1661 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1662 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001663 if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) )
mohammad160306e79202018-03-28 13:17:44 +03001664 return( PSA_ERROR_NOT_PERMITTED );
Gilles Peskine20035e32018-02-03 22:44:14 +01001665
Gilles Peskine20035e32018-02-03 22:44:14 +01001666#if defined(MBEDTLS_RSA_C)
1667 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1668 {
1669 mbedtls_rsa_context *rsa = slot->data.rsa;
1670 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001671 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001672 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001673 if( status != PSA_SUCCESS )
1674 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001675
Gilles Peskine20035e32018-02-03 22:44:14 +01001676 if( signature_size < rsa->len )
1677 return( PSA_ERROR_BUFFER_TOO_SMALL );
1678#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskinea5926232018-03-28 14:16:50 +02001679 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001680 {
1681 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1682 MBEDTLS_MD_NONE );
1683 ret = mbedtls_rsa_pkcs1_sign( rsa,
1684 mbedtls_ctr_drbg_random,
1685 &global_data.ctr_drbg,
1686 MBEDTLS_RSA_PRIVATE,
1687 md_alg, hash_length, hash,
1688 signature );
1689 }
1690 else
1691#endif /* MBEDTLS_PKCS1_V15 */
1692#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02001693 if( PSA_ALG_IS_RSA_PSS( alg ) )
Gilles Peskine20035e32018-02-03 22:44:14 +01001694 {
1695 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1696 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
1697 mbedtls_ctr_drbg_random,
1698 &global_data.ctr_drbg,
1699 MBEDTLS_RSA_PRIVATE,
1700 md_alg, hash_length, hash,
1701 signature );
1702 }
1703 else
1704#endif /* MBEDTLS_PKCS1_V21 */
1705 {
1706 return( PSA_ERROR_INVALID_ARGUMENT );
1707 }
Gilles Peskine93aa0332018-02-03 23:58:03 +01001708 if( ret == 0 )
1709 *signature_length = rsa->len;
Gilles Peskine20035e32018-02-03 22:44:14 +01001710 return( mbedtls_to_psa_error( ret ) );
1711 }
1712 else
1713#endif /* defined(MBEDTLS_RSA_C) */
1714#if defined(MBEDTLS_ECP_C)
1715 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1716 {
itayzafrir5c753392018-05-08 11:18:38 +03001717 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1718 int ret;
1719 const mbedtls_md_info_t *md_info;
1720 mbedtls_md_type_t md_alg;
1721 if( signature_size < PSA_ECDSA_SIGNATURE_SIZE( ecdsa->grp.pbits ) )
1722 return( PSA_ERROR_BUFFER_TOO_SMALL );
1723 md_info = mbedtls_md_info_from_psa( alg );
1724 md_alg = mbedtls_md_get_type( md_info );
1725 ret = mbedtls_ecdsa_write_signature( ecdsa, md_alg, hash, hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001726 signature, signature_length,
1727 mbedtls_ctr_drbg_random,
1728 &global_data.ctr_drbg );
itayzafrir5c753392018-05-08 11:18:38 +03001729 return( mbedtls_to_psa_error( ret ) );
1730 }
1731 else
1732#endif /* defined(MBEDTLS_ECP_C) */
1733 {
Gilles Peskine20035e32018-02-03 22:44:14 +01001734 return( PSA_ERROR_NOT_SUPPORTED );
1735 }
itayzafrir5c753392018-05-08 11:18:38 +03001736}
1737
1738psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
1739 psa_algorithm_t alg,
1740 const uint8_t *hash,
1741 size_t hash_length,
1742 const uint8_t *salt,
1743 size_t salt_length,
1744 uint8_t *signature,
1745 size_t signature_size )
1746{
1747 key_slot_t *slot;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001748 psa_status_t status;
itayzafrir5c753392018-05-08 11:18:38 +03001749 (void) salt;
1750 (void) salt_length;
1751
Gilles Peskine828ed142018-06-18 23:25:51 +02001752 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
itayzafrir5c753392018-05-08 11:18:38 +03001753 return( PSA_ERROR_INVALID_ARGUMENT );
1754 slot = &global_data.key_slots[key];
1755 if( slot->type == PSA_KEY_TYPE_NONE )
1756 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001757 if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) )
itayzafrir5c753392018-05-08 11:18:38 +03001758 return( PSA_ERROR_NOT_PERMITTED );
1759
Gilles Peskine61b91d42018-06-08 16:09:36 +02001760#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001761 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1762 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001763 {
1764 mbedtls_rsa_context *rsa = slot->data.rsa;
1765 int ret;
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001766 mbedtls_md_type_t md_alg;
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02001767 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001768 if( status != PSA_SUCCESS )
1769 return( status );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03001770
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001771 if( signature_size < rsa->len )
1772 return( PSA_ERROR_BUFFER_TOO_SMALL );
1773#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001774 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001775 {
1776 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
1777 MBEDTLS_MD_NONE );
1778
1779 ret = mbedtls_rsa_pkcs1_verify( rsa,
Gilles Peskine61b91d42018-06-08 16:09:36 +02001780 mbedtls_ctr_drbg_random,
1781 &global_data.ctr_drbg,
1782 MBEDTLS_RSA_PUBLIC,
1783 md_alg,
1784 hash_length,
1785 hash,
1786 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001787
1788 }
1789 else
1790#endif /* MBEDTLS_PKCS1_V15 */
1791#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02001792 if( PSA_ALG_IS_RSA_PSS( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001793 {
Gilles Peskinebeb49482018-06-08 17:44:35 +02001794 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
1795 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
1796 mbedtls_ctr_drbg_random,
1797 &global_data.ctr_drbg,
1798 MBEDTLS_RSA_PUBLIC,
1799 md_alg, hash_length, hash,
1800 signature );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001801 }
1802 else
1803#endif /* MBEDTLS_PKCS1_V21 */
1804 {
1805 return( PSA_ERROR_INVALID_ARGUMENT );
1806 }
1807 return( mbedtls_to_psa_error( ret ) );
1808 }
1809 else
1810#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03001811#if defined(MBEDTLS_ECP_C)
1812 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
1813 {
1814 mbedtls_ecp_keypair *ecdsa = slot->data.ecp;
1815 int ret;
Gilles Peskine2d277862018-06-18 15:41:12 +02001816 (void) alg;
Gilles Peskine61b91d42018-06-08 16:09:36 +02001817 ret = mbedtls_ecdsa_read_signature( ecdsa, hash, hash_length,
1818 signature, signature_size );
itayzafrir5c753392018-05-08 11:18:38 +03001819 return( mbedtls_to_psa_error( ret ) );
1820 }
Gilles Peskine20035e32018-02-03 22:44:14 +01001821 else
1822#endif /* defined(MBEDTLS_ECP_C) */
1823 {
1824 return( PSA_ERROR_NOT_SUPPORTED );
1825 }
1826}
1827
Gilles Peskine61b91d42018-06-08 16:09:36 +02001828psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
1829 psa_algorithm_t alg,
1830 const uint8_t *input,
1831 size_t input_length,
1832 const uint8_t *salt,
1833 size_t salt_length,
1834 uint8_t *output,
1835 size_t output_size,
1836 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001837{
1838 key_slot_t *slot;
1839 (void) salt;
1840 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001841 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001842
Gilles Peskine828ed142018-06-18 23:25:51 +02001843 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein7f5a3192018-05-06 22:26:54 +03001844 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001845 slot = &global_data.key_slots[key];
1846 if( slot->type == PSA_KEY_TYPE_NONE )
1847 return( PSA_ERROR_EMPTY_SLOT );
1848 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1849 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001850 if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) )
1851 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001852
1853#if defined(MBEDTLS_RSA_C)
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001854 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ||
1855 slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001856 {
1857 mbedtls_rsa_context *rsa = slot->data.rsa;
1858 int ret;
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001859 if( output_size < rsa->len )
Gilles Peskine61b91d42018-06-08 16:09:36 +02001860 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001861#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001862 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001863 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001864 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
1865 mbedtls_ctr_drbg_random,
1866 &global_data.ctr_drbg,
1867 MBEDTLS_RSA_PUBLIC,
1868 input_length,
1869 input,
1870 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001871 }
1872 else
1873#endif /* MBEDTLS_PKCS1_V15 */
1874#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02001875 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001876 {
1877 return( PSA_ERROR_NOT_SUPPORTED );
1878 }
1879 else
1880#endif /* MBEDTLS_PKCS1_V21 */
1881 {
1882 return( PSA_ERROR_INVALID_ARGUMENT );
1883 }
1884 if( ret == 0 )
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001885 *output_length = rsa->len;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001886 return( mbedtls_to_psa_error( ret ) );
1887 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001888 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001889#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001890 {
1891 return( PSA_ERROR_NOT_SUPPORTED );
1892 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001893}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001894
Gilles Peskine61b91d42018-06-08 16:09:36 +02001895psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
1896 psa_algorithm_t alg,
1897 const uint8_t *input,
1898 size_t input_length,
1899 const uint8_t *salt,
1900 size_t salt_length,
1901 uint8_t *output,
1902 size_t output_size,
1903 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001904{
1905 key_slot_t *slot;
1906 (void) salt;
1907 (void) salt_length;
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03001908 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001909
Gilles Peskine828ed142018-06-18 23:25:51 +02001910 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001911 return( PSA_ERROR_EMPTY_SLOT );
1912 slot = &global_data.key_slots[key];
1913 if( slot->type == PSA_KEY_TYPE_NONE )
1914 return( PSA_ERROR_EMPTY_SLOT );
1915 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
1916 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine61b91d42018-06-08 16:09:36 +02001917 if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
1918 return( PSA_ERROR_NOT_PERMITTED );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001919
1920#if defined(MBEDTLS_RSA_C)
1921 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
1922 {
1923 mbedtls_rsa_context *rsa = slot->data.rsa;
1924 int ret;
1925
Gilles Peskinec4def2f2018-06-08 17:53:48 +02001926 if( input_length != rsa->len )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001927 return( PSA_ERROR_INVALID_ARGUMENT );
1928
1929#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02001930 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001931 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02001932 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
1933 mbedtls_ctr_drbg_random,
1934 &global_data.ctr_drbg,
1935 MBEDTLS_RSA_PRIVATE,
1936 output_length,
1937 input,
1938 output,
1939 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001940 }
1941 else
1942#endif /* MBEDTLS_PKCS1_V15 */
1943#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02001944 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001945 {
1946 return( PSA_ERROR_NOT_SUPPORTED );
1947 }
1948 else
1949#endif /* MBEDTLS_PKCS1_V21 */
1950 {
1951 return( PSA_ERROR_INVALID_ARGUMENT );
1952 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03001953
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001954 return( mbedtls_to_psa_error( ret ) );
1955 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001956 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02001957#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03001958 {
1959 return( PSA_ERROR_NOT_SUPPORTED );
1960 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02001961}
Gilles Peskine20035e32018-02-03 22:44:14 +01001962
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001963
1964
mohammad1603503973b2018-03-12 15:59:30 +02001965/****************************************************************/
1966/* Symmetric cryptography */
1967/****************************************************************/
1968
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001969/* Initialize the cipher operation structure. Once this function has been
1970 * called, psa_cipher_abort can run and will do the right thing. */
1971static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
1972 psa_algorithm_t alg )
1973{
Gilles Peskinec06e0712018-06-20 16:21:04 +02001974 if( ! PSA_ALG_IS_CIPHER( alg ) )
1975 {
1976 memset( operation, 0, sizeof( *operation ) );
1977 return( PSA_ERROR_INVALID_ARGUMENT );
1978 }
1979
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001980 operation->alg = alg;
1981 operation->key_set = 0;
1982 operation->iv_set = 0;
1983 operation->iv_required = 1;
1984 operation->iv_size = 0;
1985 operation->block_size = 0;
1986 mbedtls_cipher_init( &operation->ctx.cipher );
1987 return( PSA_SUCCESS );
1988}
1989
Gilles Peskinee553c652018-06-04 16:22:46 +02001990static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
1991 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02001992 psa_algorithm_t alg,
1993 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02001994{
1995 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
1996 psa_status_t status;
1997 key_slot_t *slot;
1998 psa_key_type_t key_type;
1999 size_t key_bits;
2000 const mbedtls_cipher_info_t *cipher_info = NULL;
2001
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002002 status = psa_cipher_init( operation, alg );
2003 if( status != PSA_SUCCESS )
2004 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002005
2006 status = psa_get_key_information( key, &key_type, &key_bits );
2007 if( status != PSA_SUCCESS )
2008 return( status );
2009 slot = &global_data.key_slots[key];
2010
Gilles Peskinebb1072f2018-06-08 18:46:05 +02002011 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002012 if( cipher_info == NULL )
2013 return( PSA_ERROR_NOT_SUPPORTED );
2014
mohammad1603503973b2018-03-12 15:59:30 +02002015 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002016 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002017 {
2018 psa_cipher_abort( operation );
2019 return( mbedtls_to_psa_error( ret ) );
2020 }
2021
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002022#if defined(MBEDTLS_DES_C)
2023 if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
2024 {
2025 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2026 unsigned char keys[24];
2027 memcpy( keys, slot->data.raw.data, 16 );
2028 memcpy( keys + 16, slot->data.raw.data, 8 );
2029 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2030 keys,
2031 192, cipher_operation );
2032 }
2033 else
2034#endif
2035 {
2036 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2037 slot->data.raw.data,
2038 key_bits, cipher_operation );
2039 }
Moran Peker41deec42018-04-04 15:43:05 +03002040 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002041 {
2042 psa_cipher_abort( operation );
2043 return( mbedtls_to_psa_error( ret ) );
2044 }
2045
mohammad16038481e742018-03-18 13:57:31 +02002046#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Moran Peker7cb22b82018-06-05 11:40:02 +03002047 if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
mohammad16038481e742018-03-18 13:57:31 +02002048 {
Gilles Peskine53514202018-06-06 15:11:46 +02002049 psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
2050 mbedtls_cipher_padding_t mode;
mohammad16038481e742018-03-18 13:57:31 +02002051
Moran Pekera28258c2018-05-29 16:25:04 +03002052 switch ( padding_mode )
mohammad16038481e742018-03-18 13:57:31 +02002053 {
2054 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
2055 mode = MBEDTLS_PADDING_PKCS7;
2056 break;
2057 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
2058 mode = MBEDTLS_PADDING_NONE;
2059 break;
2060 default:
Moran Pekerae382792018-05-31 14:06:17 +03002061 psa_cipher_abort( operation );
2062 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038481e742018-03-18 13:57:31 +02002063 }
2064 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
Moran Pekera28258c2018-05-29 16:25:04 +03002065 if( ret != 0 )
Moran Peker71f19ae2018-04-22 20:23:16 +03002066 {
2067 psa_cipher_abort( operation );
mohammad16038481e742018-03-18 13:57:31 +02002068 return( mbedtls_to_psa_error( ret ) );
Moran Peker71f19ae2018-04-22 20:23:16 +03002069 }
mohammad16038481e742018-03-18 13:57:31 +02002070 }
2071#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2072
mohammad1603503973b2018-03-12 15:59:30 +02002073 operation->key_set = 1;
Gilles Peskine7e928852018-06-04 16:23:10 +02002074 operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
2075 PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
2076 1 );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002077 if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR )
mohammad16038481e742018-03-18 13:57:31 +02002078 {
mohammad160389e0f462018-04-12 08:48:45 +03002079 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
mohammad16038481e742018-03-18 13:57:31 +02002080 }
mohammad1603503973b2018-03-12 15:59:30 +02002081
Moran Peker395db872018-05-31 14:07:14 +03002082 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002083}
2084
Gilles Peskinee553c652018-06-04 16:22:46 +02002085psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
2086 psa_key_slot_t key,
2087 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002088{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002089 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002090}
2091
Gilles Peskinee553c652018-06-04 16:22:46 +02002092psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
2093 psa_key_slot_t key,
2094 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002095{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002096 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002097}
2098
Gilles Peskinee553c652018-06-04 16:22:46 +02002099psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
2100 unsigned char *iv,
2101 size_t iv_size,
2102 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002103{
Moran Peker41deec42018-04-04 15:43:05 +03002104 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002105 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002106 return( PSA_ERROR_BAD_STATE );
2107 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002108 {
Moran Peker41deec42018-04-04 15:43:05 +03002109 ret = PSA_ERROR_BUFFER_TOO_SMALL;
2110 goto exit;
2111 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002112 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2113 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002114 if( ret != 0 )
2115 {
2116 ret = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002117 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002118 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002119
mohammad16038481e742018-03-18 13:57:31 +02002120 *iv_length = operation->iv_size;
mohammad160389e0f462018-04-12 08:48:45 +03002121 ret = psa_encrypt_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002122
Moran Peker395db872018-05-31 14:07:14 +03002123exit:
2124 if( ret != PSA_SUCCESS )
2125 psa_cipher_abort( operation );
2126 return( ret );
mohammad1603503973b2018-03-12 15:59:30 +02002127}
2128
Gilles Peskinee553c652018-06-04 16:22:46 +02002129psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
2130 const unsigned char *iv,
2131 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002132{
Moran Peker41deec42018-04-04 15:43:05 +03002133 int ret = PSA_SUCCESS;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002134 if( operation->iv_set || ! operation->iv_required )
Moran Peker41deec42018-04-04 15:43:05 +03002135 return( PSA_ERROR_BAD_STATE );
Moran Pekera28258c2018-05-29 16:25:04 +03002136 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002137 {
Moran Pekerae382792018-05-31 14:06:17 +03002138 psa_cipher_abort( operation );
2139 return( PSA_ERROR_INVALID_ARGUMENT );
Moran Peker71f19ae2018-04-22 20:23:16 +03002140 }
mohammad1603503973b2018-03-12 15:59:30 +02002141 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002142 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002143 {
2144 psa_cipher_abort( operation );
2145 return( mbedtls_to_psa_error( ret ) );
2146 }
2147
2148 operation->iv_set = 1;
mohammad1603503973b2018-03-12 15:59:30 +02002149
Moran Peker395db872018-05-31 14:07:14 +03002150 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002151}
2152
Gilles Peskinee553c652018-06-04 16:22:46 +02002153psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2154 const uint8_t *input,
2155 size_t input_length,
2156 unsigned char *output,
2157 size_t output_size,
2158 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002159{
2160 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002161 size_t expected_output_size;
2162 if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
2163 {
2164 /* Take the unprocessed partial block left over from previous
2165 * update calls, if any, plus the input to this call. Remove
2166 * the last partial block, if any. You get the data that will be
2167 * output in this call. */
2168 expected_output_size =
2169 ( operation->ctx.cipher.unprocessed_len + input_length )
2170 / operation->block_size * operation->block_size;
2171 }
2172 else
2173 {
2174 expected_output_size = input_length;
2175 }
2176 if( output_size < expected_output_size )
Moran Peker395db872018-05-31 14:07:14 +03002177 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160382759612018-03-12 18:16:40 +02002178
mohammad1603503973b2018-03-12 15:59:30 +02002179 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002180 input_length, output, output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002181 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002182 {
2183 psa_cipher_abort( operation );
2184 return( mbedtls_to_psa_error( ret ) );
2185 }
2186
Moran Peker395db872018-05-31 14:07:14 +03002187 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002188}
2189
Gilles Peskinee553c652018-06-04 16:22:46 +02002190psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2191 uint8_t *output,
2192 size_t output_size,
2193 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002194{
2195 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002196 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002197
mohammad1603503973b2018-03-12 15:59:30 +02002198 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002199 {
Moran Peker7cb22b82018-06-05 11:40:02 +03002200 psa_cipher_abort( operation );
2201 return( PSA_ERROR_BAD_STATE );
2202 }
2203 if( operation->iv_required && ! operation->iv_set )
2204 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002205 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002206 return( PSA_ERROR_BAD_STATE );
2207 }
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002208 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
2209 PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
Moran Peker7cb22b82018-06-05 11:40:02 +03002210 {
Gilles Peskine53514202018-06-06 15:11:46 +02002211 psa_algorithm_t padding_mode =
2212 operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
Moran Peker7cb22b82018-06-05 11:40:02 +03002213 if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002214 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002215 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002216 return( PSA_ERROR_TAMPERING_DETECTED );
2217 }
Gilles Peskine53514202018-06-06 15:11:46 +02002218 if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
Moran Peker7cb22b82018-06-05 11:40:02 +03002219 {
2220 if( operation->ctx.cipher.unprocessed_len != 0 )
2221 {
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002222 psa_cipher_abort( operation );
Moran Peker7cb22b82018-06-05 11:40:02 +03002223 return( PSA_ERROR_INVALID_ARGUMENT );
2224 }
Gilles Peskine89d789c2018-06-04 17:17:16 +02002225 }
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002226 }
2227
2228 ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
Gilles Peskinee553c652018-06-04 16:22:46 +02002229 output_length );
Moran Peker41deec42018-04-04 15:43:05 +03002230 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002231 {
2232 psa_cipher_abort( operation );
2233 return( mbedtls_to_psa_error( ret ) );
2234 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002235 if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002236 memcpy( output, temp_output_buffer, *output_length );
2237 else
2238 {
2239 psa_cipher_abort( operation );
2240 return( PSA_ERROR_BUFFER_TOO_SMALL );
2241 }
mohammad1603503973b2018-03-12 15:59:30 +02002242
Moran Peker4c80d832018-04-22 20:15:31 +03002243 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002244}
2245
Gilles Peskinee553c652018-06-04 16:22:46 +02002246psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2247{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002248 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002249 {
2250 /* The object has (apparently) been initialized but it is not
2251 * in use. It's ok to call abort on such an object, and there's
2252 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002253 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002254 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002255
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002256 /* Sanity check (shouldn't happen: operation->alg should
2257 * always have been initialized to a valid value). */
2258 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2259 return( PSA_ERROR_BAD_STATE );
2260
mohammad1603503973b2018-03-12 15:59:30 +02002261 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002262
Moran Peker41deec42018-04-04 15:43:05 +03002263 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002264 operation->key_set = 0;
2265 operation->iv_set = 0;
2266 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002267 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002268 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002269
Moran Peker395db872018-05-31 14:07:14 +03002270 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002271}
2272
Gilles Peskinea0655c32018-04-30 17:06:50 +02002273
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002274
mohammad16038cc1cee2018-03-28 01:21:33 +03002275/****************************************************************/
2276/* Key Policy */
2277/****************************************************************/
2278
Gilles Peskine2d277862018-06-18 15:41:12 +02002279void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002280{
Gilles Peskine803ce742018-06-18 16:07:14 +02002281 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002282}
2283
Gilles Peskine2d277862018-06-18 15:41:12 +02002284void psa_key_policy_set_usage( psa_key_policy_t *policy,
2285 psa_key_usage_t usage,
2286 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002287{
mohammad16034eed7572018-03-28 05:14:59 -07002288 policy->usage = usage;
2289 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002290}
2291
Gilles Peskine2d277862018-06-18 15:41:12 +02002292psa_key_usage_t psa_key_policy_get_usage( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002293{
mohammad16036df908f2018-04-02 08:34:15 -07002294 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002295}
2296
Gilles Peskine2d277862018-06-18 15:41:12 +02002297psa_algorithm_t psa_key_policy_get_algorithm( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002298{
mohammad16036df908f2018-04-02 08:34:15 -07002299 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002300}
2301
Gilles Peskine2d277862018-06-18 15:41:12 +02002302psa_status_t psa_set_key_policy( psa_key_slot_t key,
2303 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002304{
2305 key_slot_t *slot;
mohammad16038cc1cee2018-03-28 01:21:33 +03002306
Gilles Peskine828ed142018-06-18 23:25:51 +02002307 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002308 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002309
mohammad16038cc1cee2018-03-28 01:21:33 +03002310 slot = &global_data.key_slots[key];
2311 if( slot->type != PSA_KEY_TYPE_NONE )
2312 return( PSA_ERROR_OCCUPIED_SLOT );
2313
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002314 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2315 PSA_KEY_USAGE_ENCRYPT |
2316 PSA_KEY_USAGE_DECRYPT |
2317 PSA_KEY_USAGE_SIGN |
2318 PSA_KEY_USAGE_VERIFY ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002319 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002320
mohammad16036df908f2018-04-02 08:34:15 -07002321 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002322
2323 return( PSA_SUCCESS );
2324}
2325
Gilles Peskine2d277862018-06-18 15:41:12 +02002326psa_status_t psa_get_key_policy( psa_key_slot_t key,
2327 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002328{
2329 key_slot_t *slot;
2330
Gilles Peskine828ed142018-06-18 23:25:51 +02002331 if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002332 return( PSA_ERROR_INVALID_ARGUMENT );
2333
2334 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002335
mohammad16036df908f2018-04-02 08:34:15 -07002336 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002337
2338 return( PSA_SUCCESS );
2339}
Gilles Peskine20035e32018-02-03 22:44:14 +01002340
Gilles Peskinea0655c32018-04-30 17:06:50 +02002341
2342
mohammad1603804cd712018-03-20 22:44:08 +02002343/****************************************************************/
2344/* Key Lifetime */
2345/****************************************************************/
2346
Gilles Peskine2d277862018-06-18 15:41:12 +02002347psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2348 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002349{
2350 key_slot_t *slot;
2351
Gilles Peskine828ed142018-06-18 23:25:51 +02002352 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002353 return( PSA_ERROR_INVALID_ARGUMENT );
2354
2355 slot = &global_data.key_slots[key];
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002356
mohammad1603804cd712018-03-20 22:44:08 +02002357 *lifetime = slot->lifetime;
2358
2359 return( PSA_SUCCESS );
2360}
2361
Gilles Peskine2d277862018-06-18 15:41:12 +02002362psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
2363 const psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002364{
2365 key_slot_t *slot;
2366
Gilles Peskine828ed142018-06-18 23:25:51 +02002367 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
mohammad1603804cd712018-03-20 22:44:08 +02002368 return( PSA_ERROR_INVALID_ARGUMENT );
2369
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002370 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2371 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002372 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2373 return( PSA_ERROR_INVALID_ARGUMENT );
2374
mohammad1603804cd712018-03-20 22:44:08 +02002375 slot = &global_data.key_slots[key];
mohammad16035d7ec202018-03-28 01:29:41 +03002376 if( slot->type != PSA_KEY_TYPE_NONE )
2377 return( PSA_ERROR_OCCUPIED_SLOT );
mohammad1603804cd712018-03-20 22:44:08 +02002378
Moran Pekerd7326592018-05-29 16:56:39 +03002379 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002380 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002381
mohammad1603060ad8a2018-03-20 14:28:38 -07002382 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002383
2384 return( PSA_SUCCESS );
2385}
2386
Gilles Peskine20035e32018-02-03 22:44:14 +01002387
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002388
mohammad16035955c982018-04-26 00:53:03 +03002389/****************************************************************/
2390/* AEAD */
2391/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002392
mohammad16035955c982018-04-26 00:53:03 +03002393psa_status_t psa_aead_encrypt( psa_key_slot_t key,
2394 psa_algorithm_t alg,
2395 const uint8_t *nonce,
2396 size_t nonce_length,
2397 const uint8_t *additional_data,
2398 size_t additional_data_length,
2399 const uint8_t *plaintext,
2400 size_t plaintext_length,
2401 uint8_t *ciphertext,
2402 size_t ciphertext_size,
2403 size_t *ciphertext_length )
2404{
2405 int ret;
2406 psa_status_t status;
2407 key_slot_t *slot;
2408 psa_key_type_t key_type;
2409 size_t key_bits;
mohammad160315223a82018-06-03 17:19:55 +03002410 uint8_t *tag;
2411 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002412 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002413 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002414
mohammad1603f08a5502018-06-03 15:05:47 +03002415 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07002416
mohammad16035955c982018-04-26 00:53:03 +03002417 status = psa_get_key_information( key, &key_type, &key_bits );
2418 if( status != PSA_SUCCESS )
2419 return( status );
2420 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002421 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002422 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002423
mohammad16035ed06212018-06-06 13:09:34 +03002424 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2425 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002426 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002427 return( PSA_ERROR_NOT_SUPPORTED );
mohammad1603dad36fa2018-05-09 02:24:42 -07002428
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002429 if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 )
mohammad1603f14394b2018-06-04 14:33:19 +03002430 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002431
Gilles Peskine2d277862018-06-18 15:41:12 +02002432 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2433 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603db624732018-04-30 17:21:50 +03002434 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002435
mohammad16035955c982018-04-26 00:53:03 +03002436 if( alg == PSA_ALG_GCM )
2437 {
2438 mbedtls_gcm_context gcm;
mohammad160315223a82018-06-03 17:19:55 +03002439 tag_length = 16;
2440
mohammad160396910d82018-06-04 14:33:00 +03002441 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2442 return( PSA_ERROR_INVALID_ARGUMENT );
2443
mohammad160315223a82018-06-03 17:19:55 +03002444 //make sure we have place to hold the tag in the ciphertext buffer
2445 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002446 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002447
2448 //update the tag pointer to point to the end of the ciphertext_length
2449 tag = ciphertext + plaintext_length;
2450
mohammad16035955c982018-04-26 00:53:03 +03002451 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002452 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad160395893f82018-06-03 15:06:17 +03002453 slot->data.raw.data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002454 key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002455 if( ret != 0 )
2456 {
2457 mbedtls_gcm_free( &gcm );
2458 return( mbedtls_to_psa_error( ret ) );
2459 }
2460 ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002461 plaintext_length, nonce,
2462 nonce_length, additional_data,
2463 additional_data_length, plaintext,
mohammad160315223a82018-06-03 17:19:55 +03002464 ciphertext, tag_length, tag );
mohammad16035955c982018-04-26 00:53:03 +03002465 mbedtls_gcm_free( &gcm );
2466 }
2467 else if( alg == PSA_ALG_CCM )
2468 {
2469 mbedtls_ccm_context ccm;
mohammad160315223a82018-06-03 17:19:55 +03002470 tag_length = 16;
2471
mohammad160396910d82018-06-04 14:33:00 +03002472 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 )
2473 return( PSA_ERROR_INVALID_ARGUMENT );
2474
mohammad160347ddf3d2018-04-26 01:11:21 +03002475 if( nonce_length < 7 || nonce_length > 13 )
2476 return( PSA_ERROR_INVALID_ARGUMENT );
2477
mohammad160315223a82018-06-03 17:19:55 +03002478 //make sure we have place to hold the tag in the ciphertext buffer
2479 if( ciphertext_size < ( plaintext_length + tag_length ) )
mohammad1603e3cb8a82018-06-06 13:45:03 +03002480 return( PSA_ERROR_BUFFER_TOO_SMALL );
mohammad160315223a82018-06-03 17:19:55 +03002481
2482 //update the tag pointer to point to the end of the ciphertext_length
2483 tag = ciphertext + plaintext_length;
2484
mohammad16035955c982018-04-26 00:53:03 +03002485 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002486 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002487 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002488 if( ret != 0 )
2489 {
2490 mbedtls_ccm_free( &ccm );
2491 return( mbedtls_to_psa_error( ret ) );
2492 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002493 ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002494 nonce, nonce_length,
2495 additional_data,
Gilles Peskinea40d7742018-06-01 16:28:30 +02002496 additional_data_length,
2497 plaintext, ciphertext,
mohammad160315223a82018-06-03 17:19:55 +03002498 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002499 mbedtls_ccm_free( &ccm );
2500 }
mohammad16035c8845f2018-05-09 05:40:09 -07002501 else
2502 {
mohammad1603554faad2018-06-03 15:07:38 +03002503 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07002504 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002505
mohammad160315223a82018-06-03 17:19:55 +03002506 if( ret != 0 )
2507 {
2508 memset( ciphertext, 0, ciphertext_size );
2509 return( mbedtls_to_psa_error( ret ) );
2510 }
Gilles Peskine2d277862018-06-18 15:41:12 +02002511
mohammad160315223a82018-06-03 17:19:55 +03002512 *ciphertext_length = plaintext_length + tag_length;
mohammad160347ddf3d2018-04-26 01:11:21 +03002513 return( PSA_SUCCESS );
mohammad16035955c982018-04-26 00:53:03 +03002514}
2515
Gilles Peskineee652a32018-06-01 19:23:52 +02002516/* Locate the tag in a ciphertext buffer containing the encrypted data
2517 * followed by the tag. Return the length of the part preceding the tag in
2518 * *plaintext_length. This is the size of the plaintext in modes where
2519 * the encrypted data has the same size as the plaintext, such as
2520 * CCM and GCM. */
2521static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
2522 const uint8_t *ciphertext,
2523 size_t ciphertext_length,
2524 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02002525 const uint8_t **p_tag )
2526{
2527 size_t payload_length;
2528 if( tag_length > ciphertext_length )
2529 return( PSA_ERROR_INVALID_ARGUMENT );
2530 payload_length = ciphertext_length - tag_length;
2531 if( payload_length > plaintext_size )
2532 return( PSA_ERROR_BUFFER_TOO_SMALL );
2533 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02002534 return( PSA_SUCCESS );
2535}
2536
mohammad16035955c982018-04-26 00:53:03 +03002537psa_status_t psa_aead_decrypt( psa_key_slot_t key,
2538 psa_algorithm_t alg,
2539 const uint8_t *nonce,
2540 size_t nonce_length,
2541 const uint8_t *additional_data,
2542 size_t additional_data_length,
2543 const uint8_t *ciphertext,
2544 size_t ciphertext_length,
2545 uint8_t *plaintext,
2546 size_t plaintext_size,
2547 size_t *plaintext_length )
2548{
2549 int ret;
2550 psa_status_t status;
2551 key_slot_t *slot;
2552 psa_key_type_t key_type;
2553 size_t key_bits;
Gilles Peskineee652a32018-06-01 19:23:52 +02002554 const uint8_t *tag;
2555 size_t tag_length;
mohammad1603dad36fa2018-05-09 02:24:42 -07002556 mbedtls_cipher_id_t cipher_id;
mohammad16030f214652018-06-03 15:10:06 +03002557 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02002558
Gilles Peskineee652a32018-06-01 19:23:52 +02002559 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03002560
mohammad16035955c982018-04-26 00:53:03 +03002561 status = psa_get_key_information( key, &key_type, &key_bits );
2562 if( status != PSA_SUCCESS )
2563 return( status );
2564 slot = &global_data.key_slots[key];
mohammad1603a1d98012018-06-06 13:45:55 +03002565 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine2d277862018-06-18 15:41:12 +02002566 return( PSA_ERROR_EMPTY_SLOT );
mohammad16035955c982018-04-26 00:53:03 +03002567
mohammad16035ed06212018-06-06 13:09:34 +03002568 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
2569 key_bits, &cipher_id );
mohammad16030f214652018-06-03 15:10:06 +03002570 if( cipher_info == NULL )
Gilles Peskine2d277862018-06-18 15:41:12 +02002571 return( PSA_ERROR_NOT_SUPPORTED );
2572
mohammad1603f14394b2018-06-04 14:33:19 +03002573 if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) )
2574 return( PSA_ERROR_NOT_PERMITTED );
mohammad16035955c982018-04-26 00:53:03 +03002575
Gilles Peskine2d277862018-06-18 15:41:12 +02002576 if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
2577 PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
mohammad1603a7e6df72018-04-30 17:25:45 +03002578 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16035955c982018-04-26 00:53:03 +03002579
mohammad16035955c982018-04-26 00:53:03 +03002580 if( alg == PSA_ALG_GCM )
2581 {
2582 mbedtls_gcm_context gcm;
mohammad160347ddf3d2018-04-26 01:11:21 +03002583
Gilles Peskineee652a32018-06-01 19:23:52 +02002584 tag_length = 16;
2585 status = psa_aead_unpadded_locate_tag( tag_length,
2586 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002587 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02002588 if( status != PSA_SUCCESS )
2589 return( status );
2590
mohammad16035955c982018-04-26 00:53:03 +03002591 mbedtls_gcm_init( &gcm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002592 ret = mbedtls_gcm_setkey( &gcm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002593 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002594 if( ret != 0 )
2595 {
2596 mbedtls_gcm_free( &gcm );
2597 return( mbedtls_to_psa_error( ret ) );
2598 }
mohammad16035955c982018-04-26 00:53:03 +03002599
Gilles Peskineee652a32018-06-01 19:23:52 +02002600 ret = mbedtls_gcm_auth_decrypt( &gcm,
mohammad160360a64d02018-06-03 17:20:42 +03002601 ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002602 nonce, nonce_length,
mohammad16035ed06212018-06-06 13:09:34 +03002603 additional_data,
2604 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002605 tag, tag_length,
2606 ciphertext, plaintext );
mohammad16035955c982018-04-26 00:53:03 +03002607 mbedtls_gcm_free( &gcm );
2608 }
2609 else if( alg == PSA_ALG_CCM )
2610 {
2611 mbedtls_ccm_context ccm;
Gilles Peskinea40d7742018-06-01 16:28:30 +02002612
mohammad160347ddf3d2018-04-26 01:11:21 +03002613 if( nonce_length < 7 || nonce_length > 13 )
2614 return( PSA_ERROR_INVALID_ARGUMENT );
2615
mohammad16039375f842018-06-03 14:28:24 +03002616 tag_length = 16;
2617 status = psa_aead_unpadded_locate_tag( tag_length,
2618 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03002619 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03002620 if( status != PSA_SUCCESS )
2621 return( status );
2622
mohammad16035955c982018-04-26 00:53:03 +03002623 mbedtls_ccm_init( &ccm );
Gilles Peskinea40d7742018-06-01 16:28:30 +02002624 ret = mbedtls_ccm_setkey( &ccm, cipher_id,
mohammad16036bbd8c72018-04-30 17:22:52 +03002625 slot->data.raw.data, key_bits );
mohammad16035955c982018-04-26 00:53:03 +03002626 if( ret != 0 )
2627 {
2628 mbedtls_ccm_free( &ccm );
2629 return( mbedtls_to_psa_error( ret ) );
2630 }
mohammad160360a64d02018-06-03 17:20:42 +03002631 ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002632 nonce, nonce_length,
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002633 additional_data,
2634 additional_data_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02002635 ciphertext, plaintext,
2636 tag, tag_length );
mohammad16035955c982018-04-26 00:53:03 +03002637 mbedtls_ccm_free( &ccm );
2638 }
mohammad160339574652018-06-01 04:39:53 -07002639 else
2640 {
mohammad1603554faad2018-06-03 15:07:38 +03002641 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07002642 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02002643
Gilles Peskineee652a32018-06-01 19:23:52 +02002644 if( ret != 0 )
mohammad160360a64d02018-06-03 17:20:42 +03002645 memset( plaintext, 0, plaintext_size );
2646 else
2647 *plaintext_length = ciphertext_length - tag_length;
2648
Gilles Peskineee652a32018-06-01 19:23:52 +02002649 return( mbedtls_to_psa_error( ret ) );
mohammad16035955c982018-04-26 00:53:03 +03002650}
2651
Gilles Peskinea0655c32018-04-30 17:06:50 +02002652
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002653
Gilles Peskine20035e32018-02-03 22:44:14 +01002654/****************************************************************/
Gilles Peskine05d69892018-06-19 22:00:52 +02002655/* Key generation */
2656/****************************************************************/
2657
2658psa_status_t psa_generate_random( uint8_t *output,
2659 size_t output_size )
2660{
2661 int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2662 output, output_size );
2663 return( mbedtls_to_psa_error( ret ) );
2664}
2665
2666psa_status_t psa_generate_key( psa_key_slot_t key,
2667 psa_key_type_t type,
2668 size_t bits,
2669 const void *parameters,
2670 size_t parameters_size )
2671{
Gilles Peskine12313cd2018-06-20 00:20:32 +02002672 key_slot_t *slot;
2673
2674 if( key == 0 || key > PSA_KEY_SLOT_COUNT )
2675 return( PSA_ERROR_INVALID_ARGUMENT );
2676 slot = &global_data.key_slots[key];
2677 if( slot->type != PSA_KEY_TYPE_NONE )
2678 return( PSA_ERROR_OCCUPIED_SLOT );
2679 if( parameters == NULL && parameters_size != 0 )
2680 return( PSA_ERROR_INVALID_ARGUMENT );
2681
Gilles Peskine48c0ea12018-06-21 14:15:31 +02002682 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02002683 {
2684 psa_status_t status = prepare_raw_data_slot( type, bits,
2685 &slot->data.raw );
2686 if( status != PSA_SUCCESS )
2687 return( status );
2688 status = psa_generate_random( slot->data.raw.data,
2689 slot->data.raw.bytes );
2690 if( status != PSA_SUCCESS )
2691 {
2692 mbedtls_free( slot->data.raw.data );
2693 return( status );
2694 }
2695#if defined(MBEDTLS_DES_C)
2696 if( type == PSA_KEY_TYPE_DES )
2697 {
2698 mbedtls_des_key_set_parity( slot->data.raw.data );
2699 if( slot->data.raw.bytes >= 16 )
2700 mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
2701 if( slot->data.raw.bytes == 24 )
2702 mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
2703 }
2704#endif /* MBEDTLS_DES_C */
2705 }
2706 else
2707
2708#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
2709 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
2710 {
2711 mbedtls_rsa_context *rsa;
2712 int ret;
2713 int exponent = 65537;
2714 if( parameters != NULL )
2715 {
2716 const unsigned *p = parameters;
2717 if( parameters_size != sizeof( *p ) )
2718 return( PSA_ERROR_INVALID_ARGUMENT );
2719 if( *p > INT_MAX )
2720 return( PSA_ERROR_INVALID_ARGUMENT );
2721 exponent = *p;
2722 }
2723 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
2724 if( rsa == NULL )
2725 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2726 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
2727 ret = mbedtls_rsa_gen_key( rsa,
2728 mbedtls_ctr_drbg_random,
2729 &global_data.ctr_drbg,
2730 bits,
2731 exponent );
2732 if( ret != 0 )
2733 {
2734 mbedtls_rsa_free( rsa );
2735 mbedtls_free( rsa );
2736 return( mbedtls_to_psa_error( ret ) );
2737 }
2738 slot->data.rsa = rsa;
2739 }
2740 else
2741#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
2742
2743#if defined(MBEDTLS_ECP_C)
2744 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
2745 {
2746 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
2747 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
2748 const mbedtls_ecp_curve_info *curve_info =
2749 mbedtls_ecp_curve_info_from_grp_id( grp_id );
2750 mbedtls_ecp_keypair *ecp;
2751 int ret;
2752 if( parameters != NULL )
2753 return( PSA_ERROR_NOT_SUPPORTED );
2754 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
2755 return( PSA_ERROR_NOT_SUPPORTED );
2756 if( curve_info->bit_size != bits )
2757 return( PSA_ERROR_INVALID_ARGUMENT );
2758 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
2759 if( ecp == NULL )
2760 return( PSA_ERROR_INSUFFICIENT_MEMORY );
2761 mbedtls_ecp_keypair_init( ecp );
2762 ret = mbedtls_ecp_gen_key( grp_id, ecp,
2763 mbedtls_ctr_drbg_random,
2764 &global_data.ctr_drbg );
2765 if( ret != 0 )
2766 {
2767 mbedtls_ecp_keypair_free( ecp );
2768 mbedtls_free( ecp );
2769 return( mbedtls_to_psa_error( ret ) );
2770 }
2771 slot->data.ecp = ecp;
2772 }
2773 else
2774#endif /* MBEDTLS_ECP_C */
2775
2776 return( PSA_ERROR_NOT_SUPPORTED );
2777
2778 slot->type = type;
2779 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02002780}
2781
2782
2783/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002784/* Module setup */
2785/****************************************************************/
2786
Gilles Peskinee59236f2018-01-27 23:32:46 +01002787void mbedtls_psa_crypto_free( void )
2788{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002789 size_t key;
Gilles Peskine828ed142018-06-18 23:25:51 +02002790 for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01002791 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01002792 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
2793 mbedtls_entropy_free( &global_data.entropy );
2794 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2795}
2796
2797psa_status_t psa_crypto_init( void )
2798{
2799 int ret;
2800 const unsigned char drbg_seed[] = "PSA";
2801
2802 if( global_data.initialized != 0 )
2803 return( PSA_SUCCESS );
2804
2805 mbedtls_zeroize( &global_data, sizeof( global_data ) );
2806 mbedtls_entropy_init( &global_data.entropy );
2807 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
2808
2809 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
2810 mbedtls_entropy_func,
2811 &global_data.entropy,
2812 drbg_seed, sizeof( drbg_seed ) - 1 );
2813 if( ret != 0 )
2814 goto exit;
2815
Gilles Peskinee4ebc122018-03-07 14:16:44 +01002816 global_data.initialized = 1;
2817
Gilles Peskinee59236f2018-01-27 23:32:46 +01002818exit:
2819 if( ret != 0 )
2820 mbedtls_psa_crypto_free( );
2821 return( mbedtls_to_psa_error( ret ) );
2822}
2823
2824#endif /* MBEDTLS_PSA_CRYPTO_C */