blob: 11621ee8aa04fc25d31ff951ebccfe198cfbfb4a [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)
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +030029/*
30 * In case MBEDTLS_PSA_CRYPTO_SPM is defined the code is built for SPM (Secure
31 * Partition Manager) integration which separate the code into two parts
32 * NSPE (Non-Secure Process Environment) and SPE (Secure Process Environment).
33 * In this mode an additional header file should be included.
34 */
mohammad160327010052018-07-03 13:16:15 +030035#if defined(MBEDTLS_PSA_CRYPTO_SPM)
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +030036/*
37 * PSA_CRYPTO_SECURE means that this file is compiled to the SPE side.
38 * some headers will be affected by this flag.
39 */
mohammad160327010052018-07-03 13:16:15 +030040#define PSA_CRYPTO_SECURE 1
41#include "crypto_spe.h"
42#endif
43
Gilles Peskinee59236f2018-01-27 23:32:46 +010044#include "psa/crypto.h"
45
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010046#include <stdlib.h>
47#include <string.h>
48#if defined(MBEDTLS_PLATFORM_C)
49#include "mbedtls/platform.h"
50#else
51#define mbedtls_calloc calloc
52#define mbedtls_free free
53#endif
54
Gilles Peskinea5905292018-02-07 20:59:33 +010055#include "mbedtls/arc4.h"
Gilles Peskine9a944802018-06-21 09:35:35 +020056#include "mbedtls/asn1.h"
Gilles Peskinea81d85b2018-06-26 16:10:23 +020057#include "mbedtls/bignum.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010058#include "mbedtls/blowfish.h"
59#include "mbedtls/camellia.h"
60#include "mbedtls/cipher.h"
61#include "mbedtls/ccm.h"
62#include "mbedtls/cmac.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010063#include "mbedtls/ctr_drbg.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010064#include "mbedtls/des.h"
Gilles Peskineb7ecdf02018-09-18 12:11:27 +020065#include "mbedtls/ecdh.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010066#include "mbedtls/ecp.h"
Gilles Peskinee59236f2018-01-27 23:32:46 +010067#include "mbedtls/entropy.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010068#include "mbedtls/error.h"
69#include "mbedtls/gcm.h"
70#include "mbedtls/md2.h"
71#include "mbedtls/md4.h"
72#include "mbedtls/md5.h"
Gilles Peskine20035e32018-02-03 22:44:14 +010073#include "mbedtls/md.h"
74#include "mbedtls/md_internal.h"
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +010075#include "mbedtls/pk.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010076#include "mbedtls/pk_internal.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010077#include "mbedtls/ripemd160.h"
Gilles Peskine969ac722018-01-28 18:16:59 +010078#include "mbedtls/rsa.h"
Gilles Peskinea5905292018-02-07 20:59:33 +010079#include "mbedtls/sha1.h"
80#include "mbedtls/sha256.h"
81#include "mbedtls/sha512.h"
82#include "mbedtls/xtea.h"
83
Gilles Peskinee59236f2018-01-27 23:32:46 +010084
85
Gilles Peskine996deb12018-08-01 15:45:45 +020086#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
87
Gilles Peskinee59236f2018-01-27 23:32:46 +010088/* Implementation that should never be optimized out by the compiler */
89static void mbedtls_zeroize( void *v, size_t n )
90{
91 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
92}
93
Gilles Peskine9ef733f2018-02-07 21:05:37 +010094/* constant-time buffer comparison */
95static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
96{
97 size_t i;
98 unsigned char diff = 0;
99
100 for( i = 0; i < n; i++ )
101 diff |= a[i] ^ b[i];
102
103 return( diff );
104}
105
106
107
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100108/****************************************************************/
109/* Global data, support functions and library management */
110/****************************************************************/
111
112/* Number of key slots (plus one because 0 is not used).
113 * The value is a compile-time constant for now, for simplicity. */
Gilles Peskine828ed142018-06-18 23:25:51 +0200114#define PSA_KEY_SLOT_COUNT 32
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100115
Gilles Peskine2d277862018-06-18 15:41:12 +0200116typedef struct
117{
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100118 psa_key_type_t type;
mohammad16038cc1cee2018-03-28 01:21:33 +0300119 psa_key_policy_t policy;
mohammad1603804cd712018-03-20 22:44:08 +0200120 psa_key_lifetime_t lifetime;
Gilles Peskine2d277862018-06-18 15:41:12 +0200121 union
122 {
123 struct raw_data
124 {
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100125 uint8_t *data;
126 size_t bytes;
127 } raw;
Gilles Peskine969ac722018-01-28 18:16:59 +0100128#if defined(MBEDTLS_RSA_C)
129 mbedtls_rsa_context *rsa;
130#endif /* MBEDTLS_RSA_C */
131#if defined(MBEDTLS_ECP_C)
132 mbedtls_ecp_keypair *ecp;
133#endif /* MBEDTLS_ECP_C */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100134 } data;
135} key_slot_t;
136
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200137static int key_type_is_raw_bytes( psa_key_type_t type )
138{
Gilles Peskine78b3bb62018-08-10 16:03:41 +0200139 return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200140}
141
Gilles Peskine2d277862018-06-18 15:41:12 +0200142typedef struct
143{
Gilles Peskinee59236f2018-01-27 23:32:46 +0100144 int initialized;
145 mbedtls_entropy_context entropy;
146 mbedtls_ctr_drbg_context ctr_drbg;
Gilles Peskine828ed142018-06-18 23:25:51 +0200147 key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
Gilles Peskinee59236f2018-01-27 23:32:46 +0100148} psa_global_data_t;
149
150static psa_global_data_t global_data;
151
itayzafrir0adf0fc2018-09-06 16:24:41 +0300152#define GUARD_MODULE_INITIALIZED \
153 if( global_data.initialized == 0 ) \
154 return( PSA_ERROR_BAD_STATE );
155
Gilles Peskinee59236f2018-01-27 23:32:46 +0100156static psa_status_t mbedtls_to_psa_error( int ret )
157{
Gilles Peskinea5905292018-02-07 20:59:33 +0100158 /* If there's both a high-level code and low-level code, dispatch on
159 * the high-level code. */
160 switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
Gilles Peskinee59236f2018-01-27 23:32:46 +0100161 {
162 case 0:
163 return( PSA_SUCCESS );
Gilles Peskinea5905292018-02-07 20:59:33 +0100164
165 case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
166 case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
167 case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
168 return( PSA_ERROR_NOT_SUPPORTED );
169 case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
170 return( PSA_ERROR_HARDWARE_FAILURE );
171
172 case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
173 return( PSA_ERROR_HARDWARE_FAILURE );
174
Gilles Peskine9a944802018-06-21 09:35:35 +0200175 case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
176 case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
177 case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
178 case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
179 case MBEDTLS_ERR_ASN1_INVALID_DATA:
180 return( PSA_ERROR_INVALID_ARGUMENT );
181 case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
182 return( PSA_ERROR_INSUFFICIENT_MEMORY );
183 case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
184 return( PSA_ERROR_BUFFER_TOO_SMALL );
185
Gilles Peskinea5905292018-02-07 20:59:33 +0100186 case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
187 case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
188 return( PSA_ERROR_NOT_SUPPORTED );
189 case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
190 return( PSA_ERROR_HARDWARE_FAILURE );
191
192 case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
193 case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
194 return( PSA_ERROR_NOT_SUPPORTED );
195 case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
196 return( PSA_ERROR_HARDWARE_FAILURE );
197
198 case MBEDTLS_ERR_CCM_BAD_INPUT:
199 return( PSA_ERROR_INVALID_ARGUMENT );
200 case MBEDTLS_ERR_CCM_AUTH_FAILED:
201 return( PSA_ERROR_INVALID_SIGNATURE );
202 case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
203 return( PSA_ERROR_HARDWARE_FAILURE );
204
205 case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
206 return( PSA_ERROR_NOT_SUPPORTED );
207 case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
208 return( PSA_ERROR_INVALID_ARGUMENT );
209 case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
210 return( PSA_ERROR_INSUFFICIENT_MEMORY );
211 case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
212 return( PSA_ERROR_INVALID_PADDING );
213 case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
214 return( PSA_ERROR_BAD_STATE );
215 case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
216 return( PSA_ERROR_INVALID_SIGNATURE );
217 case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
218 return( PSA_ERROR_TAMPERING_DETECTED );
219 case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
220 return( PSA_ERROR_HARDWARE_FAILURE );
221
222 case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
223 return( PSA_ERROR_HARDWARE_FAILURE );
224
225 case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
226 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
227 case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
228 case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
229 return( PSA_ERROR_NOT_SUPPORTED );
230 case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
231 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
232
233 case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
234 return( PSA_ERROR_NOT_SUPPORTED );
235 case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
236 return( PSA_ERROR_HARDWARE_FAILURE );
237
Gilles Peskinee59236f2018-01-27 23:32:46 +0100238 case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
239 case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
240 case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
241 return( PSA_ERROR_INSUFFICIENT_ENTROPY );
Gilles Peskinea5905292018-02-07 20:59:33 +0100242
243 case MBEDTLS_ERR_GCM_AUTH_FAILED:
244 return( PSA_ERROR_INVALID_SIGNATURE );
245 case MBEDTLS_ERR_GCM_BAD_INPUT:
Gilles Peskine8cac2e62018-08-21 15:07:38 +0200246 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea5905292018-02-07 20:59:33 +0100247 case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
248 return( PSA_ERROR_HARDWARE_FAILURE );
249
250 case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
251 case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
252 case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
253 return( PSA_ERROR_HARDWARE_FAILURE );
254
255 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
256 return( PSA_ERROR_NOT_SUPPORTED );
257 case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
258 return( PSA_ERROR_INVALID_ARGUMENT );
259 case MBEDTLS_ERR_MD_ALLOC_FAILED:
260 return( PSA_ERROR_INSUFFICIENT_MEMORY );
261 case MBEDTLS_ERR_MD_FILE_IO_ERROR:
262 return( PSA_ERROR_STORAGE_FAILURE );
263 case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
264 return( PSA_ERROR_HARDWARE_FAILURE );
265
Gilles Peskinef76aa772018-10-29 19:24:33 +0100266 case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
267 return( PSA_ERROR_STORAGE_FAILURE );
268 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
269 return( PSA_ERROR_INVALID_ARGUMENT );
270 case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
271 return( PSA_ERROR_INVALID_ARGUMENT );
272 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
273 return( PSA_ERROR_BUFFER_TOO_SMALL );
274 case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
275 return( PSA_ERROR_INVALID_ARGUMENT );
276 case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
277 return( PSA_ERROR_INVALID_ARGUMENT );
278 case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
279 return( PSA_ERROR_INVALID_ARGUMENT );
280 case MBEDTLS_ERR_MPI_ALLOC_FAILED:
281 return( PSA_ERROR_INSUFFICIENT_MEMORY );
282
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100283 case MBEDTLS_ERR_PK_ALLOC_FAILED:
284 return( PSA_ERROR_INSUFFICIENT_MEMORY );
285 case MBEDTLS_ERR_PK_TYPE_MISMATCH:
286 case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
287 return( PSA_ERROR_INVALID_ARGUMENT );
288 case MBEDTLS_ERR_PK_FILE_IO_ERROR:
Gilles Peskinea5905292018-02-07 20:59:33 +0100289 return( PSA_ERROR_STORAGE_FAILURE );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100290 case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
291 case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
292 return( PSA_ERROR_INVALID_ARGUMENT );
293 case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
294 return( PSA_ERROR_NOT_SUPPORTED );
295 case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
296 case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
297 return( PSA_ERROR_NOT_PERMITTED );
298 case MBEDTLS_ERR_PK_INVALID_PUBKEY:
299 return( PSA_ERROR_INVALID_ARGUMENT );
300 case MBEDTLS_ERR_PK_INVALID_ALG:
301 case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
302 case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
303 return( PSA_ERROR_NOT_SUPPORTED );
304 case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
305 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskinea5905292018-02-07 20:59:33 +0100306 case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
307 return( PSA_ERROR_HARDWARE_FAILURE );
308
309 case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
310 return( PSA_ERROR_HARDWARE_FAILURE );
311
312 case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
313 return( PSA_ERROR_INVALID_ARGUMENT );
314 case MBEDTLS_ERR_RSA_INVALID_PADDING:
315 return( PSA_ERROR_INVALID_PADDING );
316 case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
317 return( PSA_ERROR_HARDWARE_FAILURE );
318 case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
319 return( PSA_ERROR_INVALID_ARGUMENT );
320 case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
321 case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
322 return( PSA_ERROR_TAMPERING_DETECTED );
323 case MBEDTLS_ERR_RSA_VERIFY_FAILED:
324 return( PSA_ERROR_INVALID_SIGNATURE );
325 case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
326 return( PSA_ERROR_BUFFER_TOO_SMALL );
327 case MBEDTLS_ERR_RSA_RNG_FAILED:
328 return( PSA_ERROR_INSUFFICIENT_MEMORY );
329 case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
330 return( PSA_ERROR_NOT_SUPPORTED );
331 case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
332 return( PSA_ERROR_HARDWARE_FAILURE );
333
334 case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
335 case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
336 case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
337 return( PSA_ERROR_HARDWARE_FAILURE );
338
339 case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
340 return( PSA_ERROR_INVALID_ARGUMENT );
341 case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
342 return( PSA_ERROR_HARDWARE_FAILURE );
343
itayzafrir5c753392018-05-08 11:18:38 +0300344 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
itayzafrir7b30f8b2018-05-09 16:07:36 +0300345 case MBEDTLS_ERR_ECP_INVALID_KEY:
itayzafrir5c753392018-05-08 11:18:38 +0300346 return( PSA_ERROR_INVALID_ARGUMENT );
itayzafrir7b30f8b2018-05-09 16:07:36 +0300347 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
348 return( PSA_ERROR_BUFFER_TOO_SMALL );
349 case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
350 return( PSA_ERROR_NOT_SUPPORTED );
351 case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
352 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
353 return( PSA_ERROR_INVALID_SIGNATURE );
354 case MBEDTLS_ERR_ECP_ALLOC_FAILED:
355 return( PSA_ERROR_INSUFFICIENT_MEMORY );
356 case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
357 return( PSA_ERROR_HARDWARE_FAILURE );
itayzafrir5c753392018-05-08 11:18:38 +0300358
Gilles Peskinee59236f2018-01-27 23:32:46 +0100359 default:
360 return( PSA_ERROR_UNKNOWN_ERROR );
361 }
362}
363
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200364
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +0200365
366
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100367/****************************************************************/
368/* Key management */
369/****************************************************************/
370
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100371#if defined(MBEDTLS_ECP_C)
Gilles Peskine34ef7f52018-06-18 20:47:51 +0200372static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
373{
374 switch( grpid )
375 {
376 case MBEDTLS_ECP_DP_SECP192R1:
377 return( PSA_ECC_CURVE_SECP192R1 );
378 case MBEDTLS_ECP_DP_SECP224R1:
379 return( PSA_ECC_CURVE_SECP224R1 );
380 case MBEDTLS_ECP_DP_SECP256R1:
381 return( PSA_ECC_CURVE_SECP256R1 );
382 case MBEDTLS_ECP_DP_SECP384R1:
383 return( PSA_ECC_CURVE_SECP384R1 );
384 case MBEDTLS_ECP_DP_SECP521R1:
385 return( PSA_ECC_CURVE_SECP521R1 );
386 case MBEDTLS_ECP_DP_BP256R1:
387 return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
388 case MBEDTLS_ECP_DP_BP384R1:
389 return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
390 case MBEDTLS_ECP_DP_BP512R1:
391 return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
392 case MBEDTLS_ECP_DP_CURVE25519:
393 return( PSA_ECC_CURVE_CURVE25519 );
394 case MBEDTLS_ECP_DP_SECP192K1:
395 return( PSA_ECC_CURVE_SECP192K1 );
396 case MBEDTLS_ECP_DP_SECP224K1:
397 return( PSA_ECC_CURVE_SECP224K1 );
398 case MBEDTLS_ECP_DP_SECP256K1:
399 return( PSA_ECC_CURVE_SECP256K1 );
400 case MBEDTLS_ECP_DP_CURVE448:
401 return( PSA_ECC_CURVE_CURVE448 );
402 default:
403 return( 0 );
404 }
405}
406
Gilles Peskine12313cd2018-06-20 00:20:32 +0200407static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
408{
409 switch( curve )
410 {
411 case PSA_ECC_CURVE_SECP192R1:
412 return( MBEDTLS_ECP_DP_SECP192R1 );
413 case PSA_ECC_CURVE_SECP224R1:
414 return( MBEDTLS_ECP_DP_SECP224R1 );
415 case PSA_ECC_CURVE_SECP256R1:
416 return( MBEDTLS_ECP_DP_SECP256R1 );
417 case PSA_ECC_CURVE_SECP384R1:
418 return( MBEDTLS_ECP_DP_SECP384R1 );
419 case PSA_ECC_CURVE_SECP521R1:
420 return( MBEDTLS_ECP_DP_SECP521R1 );
421 case PSA_ECC_CURVE_BRAINPOOL_P256R1:
422 return( MBEDTLS_ECP_DP_BP256R1 );
423 case PSA_ECC_CURVE_BRAINPOOL_P384R1:
424 return( MBEDTLS_ECP_DP_BP384R1 );
425 case PSA_ECC_CURVE_BRAINPOOL_P512R1:
426 return( MBEDTLS_ECP_DP_BP512R1 );
427 case PSA_ECC_CURVE_CURVE25519:
428 return( MBEDTLS_ECP_DP_CURVE25519 );
429 case PSA_ECC_CURVE_SECP192K1:
430 return( MBEDTLS_ECP_DP_SECP192K1 );
431 case PSA_ECC_CURVE_SECP224K1:
432 return( MBEDTLS_ECP_DP_SECP224K1 );
433 case PSA_ECC_CURVE_SECP256K1:
434 return( MBEDTLS_ECP_DP_SECP256K1 );
435 case PSA_ECC_CURVE_CURVE448:
436 return( MBEDTLS_ECP_DP_CURVE448 );
437 default:
438 return( MBEDTLS_ECP_DP_NONE );
439 }
440}
Darryl Green8f8aa8f2018-07-24 15:44:51 +0100441#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine12313cd2018-06-20 00:20:32 +0200442
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200443static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
444 size_t bits,
445 struct raw_data *raw )
446{
447 /* Check that the bit size is acceptable for the key type */
448 switch( type )
449 {
450 case PSA_KEY_TYPE_RAW_DATA:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200451 if( bits == 0 )
452 {
453 raw->bytes = 0;
454 raw->data = NULL;
455 return( PSA_SUCCESS );
456 }
457 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200458#if defined(MBEDTLS_MD_C)
459 case PSA_KEY_TYPE_HMAC:
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200460#endif
Gilles Peskineea0fb492018-07-12 17:17:20 +0200461 case PSA_KEY_TYPE_DERIVE:
462 break;
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200463#if defined(MBEDTLS_AES_C)
464 case PSA_KEY_TYPE_AES:
465 if( bits != 128 && bits != 192 && bits != 256 )
466 return( PSA_ERROR_INVALID_ARGUMENT );
467 break;
468#endif
469#if defined(MBEDTLS_CAMELLIA_C)
470 case PSA_KEY_TYPE_CAMELLIA:
471 if( bits != 128 && bits != 192 && bits != 256 )
472 return( PSA_ERROR_INVALID_ARGUMENT );
473 break;
474#endif
475#if defined(MBEDTLS_DES_C)
476 case PSA_KEY_TYPE_DES:
477 if( bits != 64 && bits != 128 && bits != 192 )
478 return( PSA_ERROR_INVALID_ARGUMENT );
479 break;
480#endif
481#if defined(MBEDTLS_ARC4_C)
482 case PSA_KEY_TYPE_ARC4:
483 if( bits < 8 || bits > 2048 )
484 return( PSA_ERROR_INVALID_ARGUMENT );
485 break;
486#endif
487 default:
488 return( PSA_ERROR_NOT_SUPPORTED );
489 }
Gilles Peskineb54979a2018-06-21 09:32:47 +0200490 if( bits % 8 != 0 )
491 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200492
493 /* Allocate memory for the key */
494 raw->bytes = PSA_BITS_TO_BYTES( bits );
495 raw->data = mbedtls_calloc( 1, raw->bytes );
496 if( raw->data == NULL )
497 {
498 raw->bytes = 0;
499 return( PSA_ERROR_INSUFFICIENT_MEMORY );
500 }
501 return( PSA_SUCCESS );
502}
503
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200504#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskine86a440b2018-11-12 18:39:40 +0100505/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
506 * that are not a multiple of 8) well. For example, there is only
507 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
508 * way to return the exact bit size of a key.
509 * To keep things simple, reject non-byte-aligned key sizes. */
510static psa_status_t psa_check_rsa_key_byte_aligned(
511 const mbedtls_rsa_context *rsa )
512{
513 mbedtls_mpi n;
514 psa_status_t status;
515 mbedtls_mpi_init( &n );
516 status = mbedtls_to_psa_error(
517 mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
518 if( status == PSA_SUCCESS )
519 {
520 if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
521 status = PSA_ERROR_NOT_SUPPORTED;
522 }
523 mbedtls_mpi_free( &n );
524 return( status );
525}
526
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200527static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
528 mbedtls_rsa_context **p_rsa )
529{
530 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
531 return( PSA_ERROR_INVALID_ARGUMENT );
532 else
533 {
534 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
Gilles Peskineaac64a22018-11-12 18:37:42 +0100535 /* The size of an RSA key doesn't have to be a multiple of 8.
536 * Mbed TLS supports non-byte-aligned key sizes, but not well.
537 * For example, mbedtls_rsa_get_len() returns the key size in
538 * bytes, not in bits. */
539 size_t bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100540 psa_status_t status;
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200541 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
542 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +0100543 status = psa_check_rsa_key_byte_aligned( rsa );
544 if( status != PSA_SUCCESS )
545 return( status );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200546 *p_rsa = rsa;
547 return( PSA_SUCCESS );
548 }
549}
550#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
551
552#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
Gilles Peskinef76aa772018-10-29 19:24:33 +0100553/* Import an elliptic curve parsed by the mbedtls pk module. */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200554static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
555 mbedtls_pk_context *pk,
556 mbedtls_ecp_keypair **p_ecp )
557{
558 if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
559 return( PSA_ERROR_INVALID_ARGUMENT );
560 else
561 {
562 mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
563 psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
564 if( actual_curve != expected_curve )
565 return( PSA_ERROR_INVALID_ARGUMENT );
566 *p_ecp = ecp;
567 return( PSA_SUCCESS );
568 }
569}
570#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
571
Gilles Peskinef76aa772018-10-29 19:24:33 +0100572#if defined(MBEDTLS_ECP_C)
573/* Import a private key given as a byte string which is the private value
574 * in big-endian order. */
575static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
576 const uint8_t *data,
577 size_t data_length,
578 mbedtls_ecp_keypair **p_ecp )
579{
580 psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
581 mbedtls_ecp_keypair *ecp = NULL;
582 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
583
584 *p_ecp = NULL;
585 ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
586 if( ecp == NULL )
587 return( PSA_ERROR_INSUFFICIENT_MEMORY );
588
589 /* Load the group. */
590 status = mbedtls_to_psa_error(
591 mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
592 if( status != PSA_SUCCESS )
593 goto exit;
594 /* Load the secret value. */
595 status = mbedtls_to_psa_error(
596 mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
597 if( status != PSA_SUCCESS )
598 goto exit;
599 /* Validate the private key. */
600 status = mbedtls_to_psa_error(
601 mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
602 if( status != PSA_SUCCESS )
603 goto exit;
604 /* Calculate the public key from the private key. */
605 status = mbedtls_to_psa_error(
606 mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
607 mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
608 if( status != PSA_SUCCESS )
609 goto exit;
610
611 *p_ecp = ecp;
612 return( PSA_SUCCESS );
613
614exit:
615 if( ecp != NULL )
616 {
617 mbedtls_ecp_keypair_free( ecp );
618 mbedtls_free( ecp );
619 }
620 return( status );
621}
622#endif /* defined(MBEDTLS_ECP_C) */
623
Darryl Green940d72c2018-07-13 13:18:51 +0100624static psa_status_t psa_import_key_into_slot( key_slot_t *slot,
625 const uint8_t *data,
626 size_t data_length )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100627{
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200628 psa_status_t status = PSA_SUCCESS;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100629
Darryl Green940d72c2018-07-13 13:18:51 +0100630 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100631 {
Gilles Peskine6d912132018-03-07 16:41:37 +0100632 /* Ensure that a bytes-to-bit conversion won't overflow. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100633 if( data_length > SIZE_MAX / 8 )
634 return( PSA_ERROR_NOT_SUPPORTED );
Darryl Green940d72c2018-07-13 13:18:51 +0100635 status = prepare_raw_data_slot( slot->type,
Gilles Peskine0ff4b0f2018-06-19 21:31:50 +0200636 PSA_BYTES_TO_BITS( data_length ),
637 &slot->data.raw );
638 if( status != PSA_SUCCESS )
639 return( status );
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200640 if( data_length != 0 )
641 memcpy( slot->data.raw.data, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100642 }
643 else
Gilles Peskinef76aa772018-10-29 19:24:33 +0100644#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100645 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) )
Gilles Peskinef76aa772018-10-29 19:24:33 +0100646 {
Darryl Green940d72c2018-07-13 13:18:51 +0100647 status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskinef76aa772018-10-29 19:24:33 +0100648 data, data_length,
649 &slot->data.ecp );
650 if( status != PSA_SUCCESS )
651 return( status );
652 }
653 else
654#endif /* MBEDTLS_ECP_C */
Gilles Peskine969ac722018-01-28 18:16:59 +0100655#if defined(MBEDTLS_PK_PARSE_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100656 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
657 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100658 {
659 int ret;
Gilles Peskine969ac722018-01-28 18:16:59 +0100660 mbedtls_pk_context pk;
661 mbedtls_pk_init( &pk );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200662
663 /* Parse the data. */
Darryl Green940d72c2018-07-13 13:18:51 +0100664 if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinec66ea6a2018-02-03 22:43:28 +0100665 ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
666 else
667 ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100668 if( ret != 0 )
669 return( mbedtls_to_psa_error( ret ) );
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200670
671 /* We have something that the pkparse module recognizes.
672 * If it has the expected type and passes any type-specific
673 * checks, store it. */
Gilles Peskine969ac722018-01-28 18:16:59 +0100674#if defined(MBEDTLS_RSA_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100675 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200676 status = psa_import_rsa_key( &pk, &slot->data.rsa );
677 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100678#endif /* MBEDTLS_RSA_C */
679#if defined(MBEDTLS_ECP_C)
Darryl Green940d72c2018-07-13 13:18:51 +0100680 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
681 status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200682 &pk, &slot->data.ecp );
683 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100684#endif /* MBEDTLS_ECP_C */
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200685 {
686 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskinec648d692018-06-28 08:46:13 +0200687 }
Gilles Peskineaf89fd72018-06-29 19:52:37 +0200688
Gilles Peskinec648d692018-06-28 08:46:13 +0200689 /* Free the content of the pk object only on error. On success,
690 * the content of the object has been stored in the slot. */
691 if( status != PSA_SUCCESS )
692 {
693 mbedtls_pk_free( &pk );
694 return( status );
Gilles Peskine969ac722018-01-28 18:16:59 +0100695 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100696 }
697 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100698#endif /* defined(MBEDTLS_PK_PARSE_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100699 {
700 return( PSA_ERROR_NOT_SUPPORTED );
701 }
Darryl Green940d72c2018-07-13 13:18:51 +0100702 return( PSA_SUCCESS );
703}
704
Darryl Green06fd18d2018-07-16 11:21:11 +0100705/* Retrieve a key slot, occupied or not. */
706static psa_status_t psa_get_key_slot( psa_key_slot_t key,
707 key_slot_t **p_slot )
708{
709 GUARD_MODULE_INITIALIZED;
710
711 /* 0 is not a valid slot number under any circumstance. This
712 * implementation provides slots number 1 to N where N is the
713 * number of available slots. */
714 if( key == 0 || key > ARRAY_LENGTH( global_data.key_slots ) )
715 return( PSA_ERROR_INVALID_ARGUMENT );
716
717 *p_slot = &global_data.key_slots[key - 1];
718 return( PSA_SUCCESS );
719}
720
721/* Retrieve an empty key slot (slot with no key data, but possibly
722 * with some metadata such as a policy). */
723static psa_status_t psa_get_empty_key_slot( psa_key_slot_t key,
724 key_slot_t **p_slot )
725{
726 psa_status_t status;
727 key_slot_t *slot = NULL;
728
729 *p_slot = NULL;
730
731 status = psa_get_key_slot( key, &slot );
732 if( status != PSA_SUCCESS )
733 return( status );
734
735 if( slot->type != PSA_KEY_TYPE_NONE )
736 return( PSA_ERROR_OCCUPIED_SLOT );
737
738 *p_slot = slot;
739 return( status );
740}
741
742/** Retrieve a slot which must contain a key. The key must have allow all the
743 * usage flags set in \p usage. If \p alg is nonzero, the key must allow
744 * operations with this algorithm. */
745static psa_status_t psa_get_key_from_slot( psa_key_slot_t key,
746 key_slot_t **p_slot,
747 psa_key_usage_t usage,
748 psa_algorithm_t alg )
749{
750 psa_status_t status;
751 key_slot_t *slot = NULL;
752
753 *p_slot = NULL;
754
755 status = psa_get_key_slot( key, &slot );
756 if( status != PSA_SUCCESS )
757 return( status );
758 if( slot->type == PSA_KEY_TYPE_NONE )
759 return( PSA_ERROR_EMPTY_SLOT );
760
761 /* Enforce that usage policy for the key slot contains all the flags
762 * required by the usage parameter. There is one exception: public
763 * keys can always be exported, so we treat public key objects as
764 * if they had the export flag. */
765 if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
766 usage &= ~PSA_KEY_USAGE_EXPORT;
767 if( ( slot->policy.usage & usage ) != usage )
768 return( PSA_ERROR_NOT_PERMITTED );
769 if( alg != 0 && ( alg != slot->policy.alg ) )
770 return( PSA_ERROR_NOT_PERMITTED );
771
772 *p_slot = slot;
773 return( PSA_SUCCESS );
774}
Darryl Green940d72c2018-07-13 13:18:51 +0100775
776psa_status_t psa_import_key( psa_key_slot_t key,
777 psa_key_type_t type,
778 const uint8_t *data,
779 size_t data_length )
780{
781 key_slot_t *slot;
782 psa_status_t status;
783
784 status = psa_get_empty_key_slot( key, &slot );
785 if( status != PSA_SUCCESS )
786 return( status );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100787
788 slot->type = type;
Darryl Green940d72c2018-07-13 13:18:51 +0100789
790 status = psa_import_key_into_slot( slot, data, data_length );
791 if( status != PSA_SUCCESS )
792 {
793 slot->type = PSA_KEY_TYPE_NONE;
794 return( status );
795 }
796
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100797 return( PSA_SUCCESS );
798}
799
Gilles Peskine2d277862018-06-18 15:41:12 +0200800psa_status_t psa_destroy_key( psa_key_slot_t key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100801{
802 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200803 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100804
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200805 status = psa_get_key_slot( key, &slot );
806 if( status != PSA_SUCCESS )
807 return( status );
808
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100809 if( slot->type == PSA_KEY_TYPE_NONE )
Gilles Peskine154bd952018-04-19 08:38:16 +0200810 {
811 /* No key material to clean, but do zeroize the slot below to wipe
812 * metadata such as policies. */
813 }
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200814 else if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100815 {
816 mbedtls_free( slot->data.raw.data );
817 }
818 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100819#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200820 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100821 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100822 mbedtls_rsa_free( slot->data.rsa );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100823 mbedtls_free( slot->data.rsa );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100824 }
825 else
Gilles Peskine969ac722018-01-28 18:16:59 +0100826#endif /* defined(MBEDTLS_RSA_C) */
827#if defined(MBEDTLS_ECP_C)
828 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
829 {
830 mbedtls_ecp_keypair_free( slot->data.ecp );
Gilles Peskine3c6e9702018-03-07 16:42:44 +0100831 mbedtls_free( slot->data.ecp );
Gilles Peskine969ac722018-01-28 18:16:59 +0100832 }
833 else
834#endif /* defined(MBEDTLS_ECP_C) */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100835 {
836 /* Shouldn't happen: the key type is not any type that we
Gilles Peskine6d912132018-03-07 16:41:37 +0100837 * put in. */
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100838 return( PSA_ERROR_TAMPERING_DETECTED );
839 }
840
841 mbedtls_zeroize( slot, sizeof( *slot ) );
842 return( PSA_SUCCESS );
843}
844
Gilles Peskineb870b182018-07-06 16:02:09 +0200845/* Return the size of the key in the given slot, in bits. */
846static size_t psa_get_key_bits( const key_slot_t *slot )
847{
848 if( key_type_is_raw_bytes( slot->type ) )
849 return( slot->data.raw.bytes * 8 );
850#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200851 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Gilles Peskineaac64a22018-11-12 18:37:42 +0100852 return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
Gilles Peskineb870b182018-07-06 16:02:09 +0200853#endif /* defined(MBEDTLS_RSA_C) */
854#if defined(MBEDTLS_ECP_C)
855 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
856 return( slot->data.ecp->grp.pbits );
857#endif /* defined(MBEDTLS_ECP_C) */
858 /* Shouldn't happen except on an empty slot. */
859 return( 0 );
860}
861
Gilles Peskine2d277862018-06-18 15:41:12 +0200862psa_status_t psa_get_key_information( psa_key_slot_t key,
863 psa_key_type_t *type,
864 size_t *bits )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100865{
866 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200867 psa_status_t status;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100868
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100869 if( type != NULL )
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200870 *type = 0;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100871 if( bits != NULL )
872 *bits = 0;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200873 status = psa_get_key_slot( key, &slot );
874 if( status != PSA_SUCCESS )
875 return( status );
Gilles Peskineb870b182018-07-06 16:02:09 +0200876
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100877 if( slot->type == PSA_KEY_TYPE_NONE )
878 return( PSA_ERROR_EMPTY_SLOT );
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200879 if( type != NULL )
880 *type = slot->type;
Gilles Peskineb870b182018-07-06 16:02:09 +0200881 if( bits != NULL )
882 *bits = psa_get_key_bits( slot );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100883 return( PSA_SUCCESS );
884}
885
Gilles Peskine2d277862018-06-18 15:41:12 +0200886static psa_status_t psa_internal_export_key( psa_key_slot_t key,
887 uint8_t *data,
888 size_t data_size,
889 size_t *data_length,
890 int export_public_key )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100891{
892 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200893 psa_status_t status;
894 /* Exporting a public key doesn't require a usage flag. If we're
895 * called by psa_export_public_key(), don't require the EXPORT flag.
896 * If we're called by psa_export_key(), do require the EXPORT flag;
897 * if the key turns out to be public key object, psa_get_key_from_slot()
898 * will ignore this flag. */
899 psa_key_usage_t usage = export_public_key ? 0 : PSA_KEY_USAGE_EXPORT;
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100900
Jaeden Amerof24c7f82018-06-27 17:20:43 +0100901 /* Set the key to empty now, so that even when there are errors, we always
902 * set data_length to a value between 0 and data_size. On error, setting
903 * the key to empty is a good choice because an empty key representation is
904 * unlikely to be accepted anywhere. */
905 *data_length = 0;
906
Gilles Peskineb0b255c2018-07-06 17:01:38 +0200907 status = psa_get_key_from_slot( key, &slot, usage, 0 );
908 if( status != PSA_SUCCESS )
909 return( status );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +0200910 if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300911 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad160306e79202018-03-28 13:17:44 +0300912
Gilles Peskine48c0ea12018-06-21 14:15:31 +0200913 if( key_type_is_raw_bytes( slot->type ) )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100914 {
915 if( slot->data.raw.bytes > data_size )
916 return( PSA_ERROR_BUFFER_TOO_SMALL );
Gilles Peskine52b90182018-10-29 19:26:27 +0100917 if( data_size != 0 )
918 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200919 memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
Gilles Peskine52b90182018-10-29 19:26:27 +0100920 memset( data + slot->data.raw.bytes, 0,
921 data_size - slot->data.raw.bytes );
922 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100923 *data_length = slot->data.raw.bytes;
924 return( PSA_SUCCESS );
925 }
Gilles Peskine188c71e2018-10-29 19:26:02 +0100926#if defined(MBEDTLS_ECP_C)
927 if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
928 {
929 size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( slot ) );
930 if( bytes > data_size )
931 return( PSA_ERROR_BUFFER_TOO_SMALL );
932 status = mbedtls_to_psa_error(
933 mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
934 if( status != PSA_SUCCESS )
935 return( status );
936 memset( data + bytes, 0, data_size - bytes );
937 *data_length = bytes;
938 return( PSA_SUCCESS );
939 }
940#endif
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +0100941 else
Moran Peker17e36e12018-05-02 12:55:20 +0300942 {
Gilles Peskine969ac722018-01-28 18:16:59 +0100943#if defined(MBEDTLS_PK_WRITE_C)
Gilles Peskined8008d62018-06-29 19:51:51 +0200944 if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
Moran Pekera998bc62018-04-16 18:16:20 +0300945 PSA_KEY_TYPE_IS_ECC( slot->type ) )
Gilles Peskine969ac722018-01-28 18:16:59 +0100946 {
Moran Pekera998bc62018-04-16 18:16:20 +0300947 mbedtls_pk_context pk;
948 int ret;
Gilles Peskined8008d62018-06-29 19:51:51 +0200949 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300950 {
Darryl Green9e2d7a02018-07-24 16:33:30 +0100951#if defined(MBEDTLS_RSA_C)
952 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +0300953 pk.pk_info = &mbedtls_rsa_info;
954 pk.pk_ctx = slot->data.rsa;
Darryl Green9e2d7a02018-07-24 16:33:30 +0100955#else
956 return( PSA_ERROR_NOT_SUPPORTED );
957#endif
Moran Pekera998bc62018-04-16 18:16:20 +0300958 }
959 else
960 {
Darryl Green9e2d7a02018-07-24 16:33:30 +0100961#if defined(MBEDTLS_ECP_C)
962 mbedtls_pk_init( &pk );
Moran Pekera998bc62018-04-16 18:16:20 +0300963 pk.pk_info = &mbedtls_eckey_info;
964 pk.pk_ctx = slot->data.ecp;
Darryl Green9e2d7a02018-07-24 16:33:30 +0100965#else
966 return( PSA_ERROR_NOT_SUPPORTED );
967#endif
Moran Pekera998bc62018-04-16 18:16:20 +0300968 }
Moran Pekerd7326592018-05-29 16:56:39 +0300969 if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
Moran Pekera998bc62018-04-16 18:16:20 +0300970 ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
Moran Peker17e36e12018-05-02 12:55:20 +0300971 else
972 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
Moran Peker60364322018-04-29 11:34:58 +0300973 if( ret < 0 )
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200974 {
Gilles Peskine46f1fd72018-06-28 19:31:31 +0200975 /* If data_size is 0 then data may be NULL and then the
976 * call to memset would have undefined behavior. */
977 if( data_size != 0 )
978 memset( data, 0, data_size );
Moran Pekera998bc62018-04-16 18:16:20 +0300979 return( mbedtls_to_psa_error( ret ) );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200980 }
Gilles Peskine0e231582018-06-20 00:11:07 +0200981 /* The mbedtls_pk_xxx functions write to the end of the buffer.
982 * Move the data to the beginning and erase remaining data
983 * at the original location. */
984 if( 2 * (size_t) ret <= data_size )
985 {
986 memcpy( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200987 memset( data + data_size - ret, 0, ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200988 }
989 else if( (size_t) ret < data_size )
990 {
991 memmove( data, data + data_size - ret, ret );
Gilles Peskinee66ca3b2018-06-20 00:11:45 +0200992 memset( data + ret, 0, data_size - ret );
Gilles Peskine0e231582018-06-20 00:11:07 +0200993 }
Moran Pekera998bc62018-04-16 18:16:20 +0300994 *data_length = ret;
995 return( PSA_SUCCESS );
Gilles Peskine969ac722018-01-28 18:16:59 +0100996 }
997 else
Gilles Peskine6d912132018-03-07 16:41:37 +0100998#endif /* defined(MBEDTLS_PK_WRITE_C) */
Moran Pekera998bc62018-04-16 18:16:20 +0300999 {
1000 /* This shouldn't happen in the reference implementation, but
Gilles Peskine785fd552018-06-04 15:08:56 +02001001 it is valid for a special-purpose implementation to omit
1002 support for exporting certain key types. */
Moran Pekera998bc62018-04-16 18:16:20 +03001003 return( PSA_ERROR_NOT_SUPPORTED );
1004 }
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001005 }
1006}
1007
Gilles Peskine2d277862018-06-18 15:41:12 +02001008psa_status_t psa_export_key( psa_key_slot_t key,
1009 uint8_t *data,
1010 size_t data_size,
1011 size_t *data_length )
Moran Pekera998bc62018-04-16 18:16:20 +03001012{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001013 return( psa_internal_export_key( key, data, data_size,
1014 data_length, 0 ) );
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001015}
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001016
Gilles Peskine2d277862018-06-18 15:41:12 +02001017psa_status_t psa_export_public_key( psa_key_slot_t key,
1018 uint8_t *data,
1019 size_t data_size,
1020 size_t *data_length )
Moran Pekerdd4ea382018-04-03 15:30:03 +03001021{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001022 return( psa_internal_export_key( key, data, data_size,
1023 data_length, 1 ) );
Moran Pekerdd4ea382018-04-03 15:30:03 +03001024}
1025
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02001026
1027
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01001028/****************************************************************/
Gilles Peskine20035e32018-02-03 22:44:14 +01001029/* Message digests */
1030/****************************************************************/
1031
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001032static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
Gilles Peskine20035e32018-02-03 22:44:14 +01001033{
1034 switch( alg )
1035 {
1036#if defined(MBEDTLS_MD2_C)
1037 case PSA_ALG_MD2:
1038 return( &mbedtls_md2_info );
1039#endif
1040#if defined(MBEDTLS_MD4_C)
1041 case PSA_ALG_MD4:
1042 return( &mbedtls_md4_info );
1043#endif
1044#if defined(MBEDTLS_MD5_C)
1045 case PSA_ALG_MD5:
1046 return( &mbedtls_md5_info );
1047#endif
1048#if defined(MBEDTLS_RIPEMD160_C)
1049 case PSA_ALG_RIPEMD160:
1050 return( &mbedtls_ripemd160_info );
1051#endif
1052#if defined(MBEDTLS_SHA1_C)
1053 case PSA_ALG_SHA_1:
1054 return( &mbedtls_sha1_info );
1055#endif
1056#if defined(MBEDTLS_SHA256_C)
1057 case PSA_ALG_SHA_224:
1058 return( &mbedtls_sha224_info );
1059 case PSA_ALG_SHA_256:
1060 return( &mbedtls_sha256_info );
1061#endif
1062#if defined(MBEDTLS_SHA512_C)
1063 case PSA_ALG_SHA_384:
1064 return( &mbedtls_sha384_info );
1065 case PSA_ALG_SHA_512:
1066 return( &mbedtls_sha512_info );
1067#endif
1068 default:
1069 return( NULL );
1070 }
1071}
1072
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001073psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
1074{
1075 switch( operation->alg )
1076 {
Gilles Peskine81736312018-06-26 15:04:31 +02001077 case 0:
1078 /* The object has (apparently) been initialized but it is not
1079 * in use. It's ok to call abort on such an object, and there's
1080 * nothing to do. */
1081 break;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001082#if defined(MBEDTLS_MD2_C)
1083 case PSA_ALG_MD2:
1084 mbedtls_md2_free( &operation->ctx.md2 );
1085 break;
1086#endif
1087#if defined(MBEDTLS_MD4_C)
1088 case PSA_ALG_MD4:
1089 mbedtls_md4_free( &operation->ctx.md4 );
1090 break;
1091#endif
1092#if defined(MBEDTLS_MD5_C)
1093 case PSA_ALG_MD5:
1094 mbedtls_md5_free( &operation->ctx.md5 );
1095 break;
1096#endif
1097#if defined(MBEDTLS_RIPEMD160_C)
1098 case PSA_ALG_RIPEMD160:
1099 mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
1100 break;
1101#endif
1102#if defined(MBEDTLS_SHA1_C)
1103 case PSA_ALG_SHA_1:
1104 mbedtls_sha1_free( &operation->ctx.sha1 );
1105 break;
1106#endif
1107#if defined(MBEDTLS_SHA256_C)
1108 case PSA_ALG_SHA_224:
1109 case PSA_ALG_SHA_256:
1110 mbedtls_sha256_free( &operation->ctx.sha256 );
1111 break;
1112#endif
1113#if defined(MBEDTLS_SHA512_C)
1114 case PSA_ALG_SHA_384:
1115 case PSA_ALG_SHA_512:
1116 mbedtls_sha512_free( &operation->ctx.sha512 );
1117 break;
1118#endif
1119 default:
Gilles Peskinef9c2c092018-06-21 16:57:07 +02001120 return( PSA_ERROR_BAD_STATE );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001121 }
1122 operation->alg = 0;
1123 return( PSA_SUCCESS );
1124}
1125
Gilles Peskineda8191d1c2018-07-08 19:46:38 +02001126psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001127 psa_algorithm_t alg )
1128{
1129 int ret;
1130 operation->alg = 0;
1131 switch( alg )
1132 {
1133#if defined(MBEDTLS_MD2_C)
1134 case PSA_ALG_MD2:
1135 mbedtls_md2_init( &operation->ctx.md2 );
1136 ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
1137 break;
1138#endif
1139#if defined(MBEDTLS_MD4_C)
1140 case PSA_ALG_MD4:
1141 mbedtls_md4_init( &operation->ctx.md4 );
1142 ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
1143 break;
1144#endif
1145#if defined(MBEDTLS_MD5_C)
1146 case PSA_ALG_MD5:
1147 mbedtls_md5_init( &operation->ctx.md5 );
1148 ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
1149 break;
1150#endif
1151#if defined(MBEDTLS_RIPEMD160_C)
1152 case PSA_ALG_RIPEMD160:
1153 mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
1154 ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
1155 break;
1156#endif
1157#if defined(MBEDTLS_SHA1_C)
1158 case PSA_ALG_SHA_1:
1159 mbedtls_sha1_init( &operation->ctx.sha1 );
1160 ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
1161 break;
1162#endif
1163#if defined(MBEDTLS_SHA256_C)
1164 case PSA_ALG_SHA_224:
1165 mbedtls_sha256_init( &operation->ctx.sha256 );
1166 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
1167 break;
1168 case PSA_ALG_SHA_256:
1169 mbedtls_sha256_init( &operation->ctx.sha256 );
1170 ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
1171 break;
1172#endif
1173#if defined(MBEDTLS_SHA512_C)
1174 case PSA_ALG_SHA_384:
1175 mbedtls_sha512_init( &operation->ctx.sha512 );
1176 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
1177 break;
1178 case PSA_ALG_SHA_512:
1179 mbedtls_sha512_init( &operation->ctx.sha512 );
1180 ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
1181 break;
1182#endif
1183 default:
Gilles Peskinec06e0712018-06-20 16:21:04 +02001184 return( PSA_ALG_IS_HASH( alg ) ?
1185 PSA_ERROR_NOT_SUPPORTED :
1186 PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001187 }
1188 if( ret == 0 )
1189 operation->alg = alg;
1190 else
1191 psa_hash_abort( operation );
1192 return( mbedtls_to_psa_error( ret ) );
1193}
1194
1195psa_status_t psa_hash_update( psa_hash_operation_t *operation,
1196 const uint8_t *input,
1197 size_t input_length )
1198{
1199 int ret;
Gilles Peskine94e44542018-07-12 16:58:43 +02001200
1201 /* Don't require hash implementations to behave correctly on a
1202 * zero-length input, which may have an invalid pointer. */
1203 if( input_length == 0 )
1204 return( PSA_SUCCESS );
1205
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001206 switch( operation->alg )
1207 {
1208#if defined(MBEDTLS_MD2_C)
1209 case PSA_ALG_MD2:
1210 ret = mbedtls_md2_update_ret( &operation->ctx.md2,
1211 input, input_length );
1212 break;
1213#endif
1214#if defined(MBEDTLS_MD4_C)
1215 case PSA_ALG_MD4:
1216 ret = mbedtls_md4_update_ret( &operation->ctx.md4,
1217 input, input_length );
1218 break;
1219#endif
1220#if defined(MBEDTLS_MD5_C)
1221 case PSA_ALG_MD5:
1222 ret = mbedtls_md5_update_ret( &operation->ctx.md5,
1223 input, input_length );
1224 break;
1225#endif
1226#if defined(MBEDTLS_RIPEMD160_C)
1227 case PSA_ALG_RIPEMD160:
1228 ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
1229 input, input_length );
1230 break;
1231#endif
1232#if defined(MBEDTLS_SHA1_C)
1233 case PSA_ALG_SHA_1:
1234 ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
1235 input, input_length );
1236 break;
1237#endif
1238#if defined(MBEDTLS_SHA256_C)
1239 case PSA_ALG_SHA_224:
1240 case PSA_ALG_SHA_256:
1241 ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
1242 input, input_length );
1243 break;
1244#endif
1245#if defined(MBEDTLS_SHA512_C)
1246 case PSA_ALG_SHA_384:
1247 case PSA_ALG_SHA_512:
1248 ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
1249 input, input_length );
1250 break;
1251#endif
1252 default:
1253 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1254 break;
1255 }
Gilles Peskine94e44542018-07-12 16:58:43 +02001256
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001257 if( ret != 0 )
1258 psa_hash_abort( operation );
1259 return( mbedtls_to_psa_error( ret ) );
1260}
1261
1262psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
1263 uint8_t *hash,
1264 size_t hash_size,
1265 size_t *hash_length )
1266{
itayzafrir40835d42018-08-02 13:14:17 +03001267 psa_status_t status;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001268 int ret;
Gilles Peskine71bb7b72018-04-19 08:29:59 +02001269 size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001270
1271 /* Fill the output buffer with something that isn't a valid hash
1272 * (barring an attack on the hash and deliberately-crafted input),
1273 * in case the caller doesn't check the return status properly. */
Gilles Peskineaee13332018-07-02 12:15:28 +02001274 *hash_length = hash_size;
Gilles Peskine46f1fd72018-06-28 19:31:31 +02001275 /* If hash_size is 0 then hash may be NULL and then the
1276 * call to memset would have undefined behavior. */
1277 if( hash_size != 0 )
1278 memset( hash, '!', hash_size );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001279
1280 if( hash_size < actual_hash_length )
itayzafrir40835d42018-08-02 13:14:17 +03001281 {
1282 status = PSA_ERROR_BUFFER_TOO_SMALL;
1283 goto exit;
1284 }
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001285
1286 switch( operation->alg )
1287 {
1288#if defined(MBEDTLS_MD2_C)
1289 case PSA_ALG_MD2:
1290 ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
1291 break;
1292#endif
1293#if defined(MBEDTLS_MD4_C)
1294 case PSA_ALG_MD4:
1295 ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
1296 break;
1297#endif
1298#if defined(MBEDTLS_MD5_C)
1299 case PSA_ALG_MD5:
1300 ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
1301 break;
1302#endif
1303#if defined(MBEDTLS_RIPEMD160_C)
1304 case PSA_ALG_RIPEMD160:
1305 ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
1306 break;
1307#endif
1308#if defined(MBEDTLS_SHA1_C)
1309 case PSA_ALG_SHA_1:
1310 ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
1311 break;
1312#endif
1313#if defined(MBEDTLS_SHA256_C)
1314 case PSA_ALG_SHA_224:
1315 case PSA_ALG_SHA_256:
1316 ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
1317 break;
1318#endif
1319#if defined(MBEDTLS_SHA512_C)
1320 case PSA_ALG_SHA_384:
1321 case PSA_ALG_SHA_512:
1322 ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
1323 break;
1324#endif
1325 default:
1326 ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
1327 break;
1328 }
itayzafrir40835d42018-08-02 13:14:17 +03001329 status = mbedtls_to_psa_error( ret );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001330
itayzafrir40835d42018-08-02 13:14:17 +03001331exit:
1332 if( status == PSA_SUCCESS )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001333 {
Gilles Peskineaee13332018-07-02 12:15:28 +02001334 *hash_length = actual_hash_length;
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001335 return( psa_hash_abort( operation ) );
1336 }
1337 else
1338 {
1339 psa_hash_abort( operation );
itayzafrir40835d42018-08-02 13:14:17 +03001340 return( status );
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001341 }
1342}
1343
Gilles Peskine2d277862018-06-18 15:41:12 +02001344psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
1345 const uint8_t *hash,
1346 size_t hash_length )
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001347{
1348 uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
1349 size_t actual_hash_length;
1350 psa_status_t status = psa_hash_finish( operation,
1351 actual_hash, sizeof( actual_hash ),
1352 &actual_hash_length );
1353 if( status != PSA_SUCCESS )
1354 return( status );
1355 if( actual_hash_length != hash_length )
1356 return( PSA_ERROR_INVALID_SIGNATURE );
1357 if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
1358 return( PSA_ERROR_INVALID_SIGNATURE );
1359 return( PSA_SUCCESS );
1360}
1361
1362
1363
Gilles Peskine9ef733f2018-02-07 21:05:37 +01001364/****************************************************************/
Gilles Peskine8c9def32018-02-08 10:02:12 +01001365/* MAC */
1366/****************************************************************/
1367
Gilles Peskinedc2fc842018-03-07 16:42:59 +01001368static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
Gilles Peskine8c9def32018-02-08 10:02:12 +01001369 psa_algorithm_t alg,
1370 psa_key_type_t key_type,
Gilles Peskine2d277862018-06-18 15:41:12 +02001371 size_t key_bits,
mohammad1603f4f0d612018-06-03 15:04:51 +03001372 mbedtls_cipher_id_t* cipher_id )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001373{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001374 mbedtls_cipher_mode_t mode;
mohammad1603f4f0d612018-06-03 15:04:51 +03001375 mbedtls_cipher_id_t cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001376
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001377 if( PSA_ALG_IS_AEAD( alg ) )
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001378 alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02001379
Gilles Peskine8c9def32018-02-08 10:02:12 +01001380 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
1381 {
Nir Sonnenscheine9664c32018-06-17 14:41:30 +03001382 switch( alg )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001383 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001384 case PSA_ALG_ARC4:
Gilles Peskine8c9def32018-02-08 10:02:12 +01001385 mode = MBEDTLS_MODE_STREAM;
1386 break;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001387 case PSA_ALG_CTR:
1388 mode = MBEDTLS_MODE_CTR;
1389 break;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02001390 case PSA_ALG_CFB:
1391 mode = MBEDTLS_MODE_CFB;
1392 break;
1393 case PSA_ALG_OFB:
1394 mode = MBEDTLS_MODE_OFB;
1395 break;
1396 case PSA_ALG_CBC_NO_PADDING:
1397 mode = MBEDTLS_MODE_CBC;
1398 break;
1399 case PSA_ALG_CBC_PKCS7:
1400 mode = MBEDTLS_MODE_CBC;
1401 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001402 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001403 mode = MBEDTLS_MODE_CCM;
1404 break;
Gilles Peskine57fbdb12018-10-17 18:29:17 +02001405 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
Gilles Peskine8c9def32018-02-08 10:02:12 +01001406 mode = MBEDTLS_MODE_GCM;
1407 break;
1408 default:
1409 return( NULL );
1410 }
1411 }
1412 else if( alg == PSA_ALG_CMAC )
1413 mode = MBEDTLS_MODE_ECB;
1414 else if( alg == PSA_ALG_GMAC )
1415 mode = MBEDTLS_MODE_GCM;
1416 else
1417 return( NULL );
1418
1419 switch( key_type )
1420 {
1421 case PSA_KEY_TYPE_AES:
mohammad1603f4f0d612018-06-03 15:04:51 +03001422 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001423 break;
1424 case PSA_KEY_TYPE_DES:
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001425 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
1426 * and 192 for three-key Triple-DES. */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001427 if( key_bits == 64 )
mohammad1603f4f0d612018-06-03 15:04:51 +03001428 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001429 else
mohammad1603f4f0d612018-06-03 15:04:51 +03001430 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine9ad29e22018-06-21 09:40:04 +02001431 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
1432 * but two-key Triple-DES is functionally three-key Triple-DES
1433 * with K1=K3, so that's how we present it to mbedtls. */
1434 if( key_bits == 128 )
1435 key_bits = 192;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001436 break;
1437 case PSA_KEY_TYPE_CAMELLIA:
mohammad1603f4f0d612018-06-03 15:04:51 +03001438 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001439 break;
1440 case PSA_KEY_TYPE_ARC4:
mohammad1603f4f0d612018-06-03 15:04:51 +03001441 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001442 break;
1443 default:
1444 return( NULL );
1445 }
mohammad1603f4f0d612018-06-03 15:04:51 +03001446 if( cipher_id != NULL )
mohammad160360a64d02018-06-03 17:20:42 +03001447 *cipher_id = cipher_id_tmp;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001448
Jaeden Amero23bbb752018-06-26 14:16:54 +01001449 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
1450 (int) key_bits, mode ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001451}
1452
Gilles Peskinea05219c2018-11-16 16:02:56 +01001453#if defined(MBEDTLS_MD_C)
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001454static size_t psa_get_hash_block_size( psa_algorithm_t alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001455{
Gilles Peskine2d277862018-06-18 15:41:12 +02001456 switch( alg )
Nir Sonnenschein96272412018-06-17 14:41:10 +03001457 {
1458 case PSA_ALG_MD2:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001459 return( 16 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001460 case PSA_ALG_MD4:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001461 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001462 case PSA_ALG_MD5:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001463 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001464 case PSA_ALG_RIPEMD160:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001465 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001466 case PSA_ALG_SHA_1:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001467 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001468 case PSA_ALG_SHA_224:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001469 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001470 case PSA_ALG_SHA_256:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001471 return( 64 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001472 case PSA_ALG_SHA_384:
Nir Sonnenscheinaa5aea02018-06-18 12:24:33 +03001473 return( 128 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001474 case PSA_ALG_SHA_512:
Gilles Peskine2d277862018-06-18 15:41:12 +02001475 return( 128 );
1476 default:
1477 return( 0 );
Nir Sonnenschein96272412018-06-17 14:41:10 +03001478 }
1479}
Gilles Peskinea05219c2018-11-16 16:02:56 +01001480#endif /* MBEDTLS_MD_C */
Nir Sonnenschein0c9ec532018-06-07 13:27:47 +03001481
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001482/* Initialize the MAC operation structure. Once this function has been
1483 * called, psa_mac_abort can run and will do the right thing. */
1484static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
1485 psa_algorithm_t alg )
1486{
1487 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
1488
1489 operation->alg = alg;
1490 operation->key_set = 0;
1491 operation->iv_set = 0;
1492 operation->iv_required = 0;
1493 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001494 operation->is_sign = 0;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001495
1496#if defined(MBEDTLS_CMAC_C)
1497 if( alg == PSA_ALG_CMAC )
1498 {
1499 operation->iv_required = 0;
1500 mbedtls_cipher_init( &operation->ctx.cmac );
1501 status = PSA_SUCCESS;
1502 }
1503 else
1504#endif /* MBEDTLS_CMAC_C */
1505#if defined(MBEDTLS_MD_C)
1506 if( PSA_ALG_IS_HMAC( operation->alg ) )
1507 {
Gilles Peskineff94abd2018-07-12 17:07:52 +02001508 /* We'll set up the hash operation later in psa_hmac_setup_internal. */
1509 operation->ctx.hmac.hash_ctx.alg = 0;
1510 status = PSA_SUCCESS;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001511 }
1512 else
1513#endif /* MBEDTLS_MD_C */
1514 {
Gilles Peskinec06e0712018-06-20 16:21:04 +02001515 if( ! PSA_ALG_IS_MAC( alg ) )
1516 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001517 }
1518
1519 if( status != PSA_SUCCESS )
1520 memset( operation, 0, sizeof( *operation ) );
1521 return( status );
1522}
1523
Gilles Peskine01126fa2018-07-12 17:04:55 +02001524#if defined(MBEDTLS_MD_C)
1525static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
1526{
1527 mbedtls_zeroize( hmac->opad, sizeof( hmac->opad ) );
1528 return( psa_hash_abort( &hmac->hash_ctx ) );
1529}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01001530
1531static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
1532{
1533 /* Instances of psa_hash_operation_s can be initialized by zeroization. */
1534 memset( hmac, 0, sizeof( *hmac ) );
1535}
Gilles Peskine01126fa2018-07-12 17:04:55 +02001536#endif /* MBEDTLS_MD_C */
1537
Gilles Peskine8c9def32018-02-08 10:02:12 +01001538psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
1539{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001540 if( operation->alg == 0 )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001541 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001542 /* The object has (apparently) been initialized but it is not
1543 * in use. It's ok to call abort on such an object, and there's
1544 * nothing to do. */
1545 return( PSA_SUCCESS );
1546 }
1547 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001548#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001549 if( operation->alg == PSA_ALG_CMAC )
1550 {
1551 mbedtls_cipher_free( &operation->ctx.cmac );
1552 }
1553 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001554#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001555#if defined(MBEDTLS_MD_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001556 if( PSA_ALG_IS_HMAC( operation->alg ) )
1557 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001558 psa_hmac_abort_internal( &operation->ctx.hmac );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001559 }
1560 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001561#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001562 {
1563 /* Sanity check (shouldn't happen: operation->alg should
1564 * always have been initialized to a valid value). */
1565 goto bad_state;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001566 }
Moran Peker41deec42018-04-04 15:43:05 +03001567
Gilles Peskine8c9def32018-02-08 10:02:12 +01001568 operation->alg = 0;
1569 operation->key_set = 0;
1570 operation->iv_set = 0;
1571 operation->iv_required = 0;
1572 operation->has_input = 0;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001573 operation->is_sign = 0;
Moran Peker41deec42018-04-04 15:43:05 +03001574
Gilles Peskine8c9def32018-02-08 10:02:12 +01001575 return( PSA_SUCCESS );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001576
1577bad_state:
1578 /* If abort is called on an uninitialized object, we can't trust
1579 * anything. Wipe the object in case it contains confidential data.
1580 * This may result in a memory leak if a pointer gets overwritten,
1581 * but it's too late to do anything about this. */
1582 memset( operation, 0, sizeof( *operation ) );
1583 return( PSA_ERROR_BAD_STATE );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001584}
1585
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001586#if defined(MBEDTLS_CMAC_C)
Gilles Peskine89167cb2018-07-08 20:12:23 +02001587static int psa_cmac_setup( psa_mac_operation_t *operation,
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001588 size_t key_bits,
1589 key_slot_t *slot,
1590 const mbedtls_cipher_info_t *cipher_info )
1591{
1592 int ret;
1593
1594 operation->mac_size = cipher_info->block_size;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001595
1596 ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
1597 if( ret != 0 )
1598 return( ret );
1599
1600 ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
1601 slot->data.raw.data,
1602 key_bits );
1603 return( ret );
1604}
Gilles Peskinee3b07d82018-06-19 11:57:35 +02001605#endif /* MBEDTLS_CMAC_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001606
Gilles Peskine248051a2018-06-20 16:09:38 +02001607#if defined(MBEDTLS_MD_C)
Gilles Peskine01126fa2018-07-12 17:04:55 +02001608static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
1609 const uint8_t *key,
1610 size_t key_length,
1611 psa_algorithm_t hash_alg )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001612{
Gilles Peskineb3e6e5d2018-06-18 22:16:43 +02001613 unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001614 size_t i;
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001615 size_t hash_size = PSA_HASH_SIZE( hash_alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001616 size_t block_size = psa_get_hash_block_size( hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001617 psa_status_t status;
1618
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001619 /* Sanity checks on block_size, to guarantee that there won't be a buffer
1620 * overflow below. This should never trigger if the hash algorithm
1621 * is implemented correctly. */
1622 /* The size checks against the ipad and opad buffers cannot be written
1623 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
1624 * because that triggers -Wlogical-op on GCC 7.3. */
1625 if( block_size > sizeof( ipad ) )
1626 return( PSA_ERROR_NOT_SUPPORTED );
1627 if( block_size > sizeof( hmac->opad ) )
1628 return( PSA_ERROR_NOT_SUPPORTED );
1629 if( block_size < hash_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001630 return( PSA_ERROR_NOT_SUPPORTED );
1631
Gilles Peskined223b522018-06-11 18:12:58 +02001632 if( key_length > block_size )
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001633 {
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001634 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001635 if( status != PSA_SUCCESS )
Gilles Peskine1e6bfdf2018-07-17 16:22:47 +02001636 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001637 status = psa_hash_update( &hmac->hash_ctx, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001638 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001639 goto cleanup;
Gilles Peskine01126fa2018-07-12 17:04:55 +02001640 status = psa_hash_finish( &hmac->hash_ctx,
Gilles Peskined223b522018-06-11 18:12:58 +02001641 ipad, sizeof( ipad ), &key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001642 if( status != PSA_SUCCESS )
Gilles Peskineb8be2882018-07-17 16:24:34 +02001643 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001644 }
Gilles Peskine96889972018-07-12 17:07:03 +02001645 /* A 0-length key is not commonly used in HMAC when used as a MAC,
1646 * but it is permitted. It is common when HMAC is used in HKDF, for
1647 * example. Don't call `memcpy` in the 0-length because `key` could be
1648 * an invalid pointer which would make the behavior undefined. */
1649 else if( key_length != 0 )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001650 memcpy( ipad, key, key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001651
Gilles Peskined223b522018-06-11 18:12:58 +02001652 /* ipad contains the key followed by garbage. Xor and fill with 0x36
1653 * to create the ipad value. */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001654 for( i = 0; i < key_length; i++ )
Gilles Peskined223b522018-06-11 18:12:58 +02001655 ipad[i] ^= 0x36;
1656 memset( ipad + key_length, 0x36, block_size - key_length );
1657
1658 /* Copy the key material from ipad to opad, flipping the requisite bits,
1659 * and filling the rest of opad with the requisite constant. */
1660 for( i = 0; i < key_length; i++ )
Gilles Peskine01126fa2018-07-12 17:04:55 +02001661 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
1662 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001663
Gilles Peskine01126fa2018-07-12 17:04:55 +02001664 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001665 if( status != PSA_SUCCESS )
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001666 goto cleanup;
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001667
Gilles Peskine01126fa2018-07-12 17:04:55 +02001668 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001669
1670cleanup:
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001671 mbedtls_zeroize( ipad, key_length );
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001672
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001673 return( status );
1674}
Gilles Peskine248051a2018-06-20 16:09:38 +02001675#endif /* MBEDTLS_MD_C */
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001676
Gilles Peskine89167cb2018-07-08 20:12:23 +02001677static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
1678 psa_key_slot_t key,
1679 psa_algorithm_t alg,
1680 int is_sign )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001681{
Gilles Peskine8c9def32018-02-08 10:02:12 +01001682 psa_status_t status;
1683 key_slot_t *slot;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001684 size_t key_bits;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001685 psa_key_usage_t usage =
1686 is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
Gilles Peskined911eb72018-08-14 15:18:45 +02001687 unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
Gilles Peskinee0e9c7c2018-10-17 18:28:05 +02001688 psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001689
Gilles Peskined911eb72018-08-14 15:18:45 +02001690 status = psa_mac_init( operation, full_length_alg );
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02001691 if( status != PSA_SUCCESS )
1692 return( status );
Gilles Peskine89167cb2018-07-08 20:12:23 +02001693 if( is_sign )
1694 operation->is_sign = 1;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001695
Gilles Peskine89167cb2018-07-08 20:12:23 +02001696 status = psa_get_key_from_slot( key, &slot, usage, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02001697 if( status != PSA_SUCCESS )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001698 goto exit;
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02001699 key_bits = psa_get_key_bits( slot );
1700
Gilles Peskine8c9def32018-02-08 10:02:12 +01001701#if defined(MBEDTLS_CMAC_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001702 if( full_length_alg == PSA_ALG_CMAC )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001703 {
1704 const mbedtls_cipher_info_t *cipher_info =
Gilles Peskined911eb72018-08-14 15:18:45 +02001705 mbedtls_cipher_info_from_psa( full_length_alg,
1706 slot->type, key_bits, NULL );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001707 int ret;
1708 if( cipher_info == NULL )
1709 {
1710 status = PSA_ERROR_NOT_SUPPORTED;
1711 goto exit;
1712 }
1713 operation->mac_size = cipher_info->block_size;
1714 ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
1715 status = mbedtls_to_psa_error( ret );
1716 }
1717 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001718#endif /* MBEDTLS_CMAC_C */
Gilles Peskine8c9def32018-02-08 10:02:12 +01001719#if defined(MBEDTLS_MD_C)
Gilles Peskined911eb72018-08-14 15:18:45 +02001720 if( PSA_ALG_IS_HMAC( full_length_alg ) )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001721 {
Gilles Peskine00709fa2018-08-22 18:25:41 +02001722 psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001723 if( hash_alg == 0 )
1724 {
1725 status = PSA_ERROR_NOT_SUPPORTED;
1726 goto exit;
1727 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001728
1729 operation->mac_size = PSA_HASH_SIZE( hash_alg );
1730 /* Sanity check. This shouldn't fail on a valid configuration. */
1731 if( operation->mac_size == 0 ||
1732 operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
1733 {
1734 status = PSA_ERROR_NOT_SUPPORTED;
1735 goto exit;
1736 }
1737
Gilles Peskine01126fa2018-07-12 17:04:55 +02001738 if( slot->type != PSA_KEY_TYPE_HMAC )
1739 {
1740 status = PSA_ERROR_INVALID_ARGUMENT;
1741 goto exit;
1742 }
Gilles Peskine9aa369e2018-07-16 00:36:29 +02001743
Gilles Peskine01126fa2018-07-12 17:04:55 +02001744 status = psa_hmac_setup_internal( &operation->ctx.hmac,
1745 slot->data.raw.data,
1746 slot->data.raw.bytes,
1747 hash_alg );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001748 }
1749 else
Gilles Peskine8c9def32018-02-08 10:02:12 +01001750#endif /* MBEDTLS_MD_C */
Gilles Peskinefbfac682018-07-08 20:51:54 +02001751 {
1752 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001753 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001754
Gilles Peskined911eb72018-08-14 15:18:45 +02001755 if( truncated == 0 )
1756 {
1757 /* The "normal" case: untruncated algorithm. Nothing to do. */
1758 }
1759 else if( truncated < 4 )
1760 {
Gilles Peskine6d72ff92018-08-21 14:55:08 +02001761 /* A very short MAC is too short for security since it can be
1762 * brute-forced. Ancient protocols with 32-bit MACs do exist,
1763 * so we make this our minimum, even though 32 bits is still
1764 * too small for security. */
Gilles Peskined911eb72018-08-14 15:18:45 +02001765 status = PSA_ERROR_NOT_SUPPORTED;
1766 }
1767 else if( truncated > operation->mac_size )
1768 {
1769 /* It's impossible to "truncate" to a larger length. */
1770 status = PSA_ERROR_INVALID_ARGUMENT;
1771 }
1772 else
1773 operation->mac_size = truncated;
1774
Gilles Peskinefbfac682018-07-08 20:51:54 +02001775exit:
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001776 if( status != PSA_SUCCESS )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001777 {
Gilles Peskine6a0a44e2018-06-11 17:42:48 +02001778 psa_mac_abort( operation );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001779 }
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001780 else
1781 {
Gilles Peskine7e454bc2018-06-11 17:26:17 +02001782 operation->key_set = 1;
1783 }
1784 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001785}
1786
Gilles Peskine89167cb2018-07-08 20:12:23 +02001787psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
1788 psa_key_slot_t key,
1789 psa_algorithm_t alg )
1790{
1791 return( psa_mac_setup( operation, key, alg, 1 ) );
1792}
1793
1794psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
1795 psa_key_slot_t key,
1796 psa_algorithm_t alg )
1797{
1798 return( psa_mac_setup( operation, key, alg, 0 ) );
1799}
1800
Gilles Peskine8c9def32018-02-08 10:02:12 +01001801psa_status_t psa_mac_update( psa_mac_operation_t *operation,
1802 const uint8_t *input,
1803 size_t input_length )
1804{
Gilles Peskinefbfac682018-07-08 20:51:54 +02001805 psa_status_t status = PSA_ERROR_BAD_STATE;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001806 if( ! operation->key_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001807 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001808 if( operation->iv_required && ! operation->iv_set )
Gilles Peskinefbfac682018-07-08 20:51:54 +02001809 goto cleanup;
Gilles Peskine8c9def32018-02-08 10:02:12 +01001810 operation->has_input = 1;
1811
Gilles Peskine8c9def32018-02-08 10:02:12 +01001812#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001813 if( operation->alg == PSA_ALG_CMAC )
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001814 {
Gilles Peskinefbfac682018-07-08 20:51:54 +02001815 int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
1816 input, input_length );
1817 status = mbedtls_to_psa_error( ret );
1818 }
1819 else
1820#endif /* MBEDTLS_CMAC_C */
1821#if defined(MBEDTLS_MD_C)
1822 if( PSA_ALG_IS_HMAC( operation->alg ) )
1823 {
1824 status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
1825 input_length );
1826 }
1827 else
1828#endif /* MBEDTLS_MD_C */
1829 {
1830 /* This shouldn't happen if `operation` was initialized by
1831 * a setup function. */
1832 status = PSA_ERROR_BAD_STATE;
Nir Sonnenscheindcd636a2018-06-04 16:03:32 +03001833 }
1834
Gilles Peskinefbfac682018-07-08 20:51:54 +02001835cleanup:
1836 if( status != PSA_SUCCESS )
1837 psa_mac_abort( operation );
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02001838 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001839}
1840
Gilles Peskine01126fa2018-07-12 17:04:55 +02001841#if defined(MBEDTLS_MD_C)
1842static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
1843 uint8_t *mac,
1844 size_t mac_size )
1845{
1846 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
1847 psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
1848 size_t hash_size = 0;
1849 size_t block_size = psa_get_hash_block_size( hash_alg );
1850 psa_status_t status;
1851
Gilles Peskine01126fa2018-07-12 17:04:55 +02001852 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1853 if( status != PSA_SUCCESS )
1854 return( status );
1855 /* From here on, tmp needs to be wiped. */
1856
1857 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
1858 if( status != PSA_SUCCESS )
1859 goto exit;
1860
1861 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
1862 if( status != PSA_SUCCESS )
1863 goto exit;
1864
1865 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
1866 if( status != PSA_SUCCESS )
1867 goto exit;
1868
Gilles Peskined911eb72018-08-14 15:18:45 +02001869 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
1870 if( status != PSA_SUCCESS )
1871 goto exit;
1872
1873 memcpy( mac, tmp, mac_size );
Gilles Peskine01126fa2018-07-12 17:04:55 +02001874
1875exit:
1876 mbedtls_zeroize( tmp, hash_size );
1877 return( status );
1878}
1879#endif /* MBEDTLS_MD_C */
1880
mohammad16036df908f2018-04-02 08:34:15 -07001881static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
Gilles Peskine2d277862018-06-18 15:41:12 +02001882 uint8_t *mac,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001883 size_t mac_size )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001884{
Gilles Peskine1d96fff2018-07-02 12:15:39 +02001885 if( ! operation->key_set )
1886 return( PSA_ERROR_BAD_STATE );
1887 if( operation->iv_required && ! operation->iv_set )
1888 return( PSA_ERROR_BAD_STATE );
1889
Gilles Peskine8c9def32018-02-08 10:02:12 +01001890 if( mac_size < operation->mac_size )
1891 return( PSA_ERROR_BUFFER_TOO_SMALL );
1892
Gilles Peskine8c9def32018-02-08 10:02:12 +01001893#if defined(MBEDTLS_CMAC_C)
Gilles Peskinefbfac682018-07-08 20:51:54 +02001894 if( operation->alg == PSA_ALG_CMAC )
1895 {
Gilles Peskined911eb72018-08-14 15:18:45 +02001896 uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
1897 int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
1898 if( ret == 0 )
Gilles Peskine87b0ac42018-08-21 14:55:49 +02001899 memcpy( mac, tmp, operation->mac_size );
Gilles Peskined911eb72018-08-14 15:18:45 +02001900 mbedtls_zeroize( tmp, sizeof( tmp ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001901 return( mbedtls_to_psa_error( ret ) );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001902 }
Gilles Peskinefbfac682018-07-08 20:51:54 +02001903 else
1904#endif /* MBEDTLS_CMAC_C */
1905#if defined(MBEDTLS_MD_C)
1906 if( PSA_ALG_IS_HMAC( operation->alg ) )
1907 {
Gilles Peskine01126fa2018-07-12 17:04:55 +02001908 return( psa_hmac_finish_internal( &operation->ctx.hmac,
Gilles Peskined911eb72018-08-14 15:18:45 +02001909 mac, operation->mac_size ) );
Gilles Peskinefbfac682018-07-08 20:51:54 +02001910 }
1911 else
1912#endif /* MBEDTLS_MD_C */
1913 {
1914 /* This shouldn't happen if `operation` was initialized by
1915 * a setup function. */
1916 return( PSA_ERROR_BAD_STATE );
1917 }
Gilles Peskine8c9def32018-02-08 10:02:12 +01001918}
1919
Gilles Peskineacd4be32018-07-08 19:56:25 +02001920psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
1921 uint8_t *mac,
1922 size_t mac_size,
1923 size_t *mac_length )
mohammad16036df908f2018-04-02 08:34:15 -07001924{
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001925 psa_status_t status;
1926
1927 /* Fill the output buffer with something that isn't a valid mac
1928 * (barring an attack on the mac and deliberately-crafted input),
1929 * in case the caller doesn't check the return status properly. */
1930 *mac_length = mac_size;
1931 /* If mac_size is 0 then mac may be NULL and then the
1932 * call to memset would have undefined behavior. */
1933 if( mac_size != 0 )
1934 memset( mac, '!', mac_size );
1935
Gilles Peskine89167cb2018-07-08 20:12:23 +02001936 if( ! operation->is_sign )
1937 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001938 status = PSA_ERROR_BAD_STATE;
1939 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001940 }
mohammad16036df908f2018-04-02 08:34:15 -07001941
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001942 status = psa_mac_finish_internal( operation, mac, mac_size );
1943
1944cleanup:
1945 if( status == PSA_SUCCESS )
1946 {
1947 status = psa_mac_abort( operation );
1948 if( status == PSA_SUCCESS )
1949 *mac_length = operation->mac_size;
1950 else
1951 memset( mac, '!', mac_size );
1952 }
1953 else
1954 psa_mac_abort( operation );
1955 return( status );
mohammad16036df908f2018-04-02 08:34:15 -07001956}
1957
Gilles Peskineacd4be32018-07-08 19:56:25 +02001958psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
1959 const uint8_t *mac,
1960 size_t mac_length )
Gilles Peskine8c9def32018-02-08 10:02:12 +01001961{
Gilles Peskine828ed142018-06-18 23:25:51 +02001962 uint8_t actual_mac[PSA_MAC_MAX_SIZE];
mohammad16036df908f2018-04-02 08:34:15 -07001963 psa_status_t status;
1964
Gilles Peskine89167cb2018-07-08 20:12:23 +02001965 if( operation->is_sign )
1966 {
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001967 status = PSA_ERROR_BAD_STATE;
1968 goto cleanup;
1969 }
1970 if( operation->mac_size != mac_length )
1971 {
1972 status = PSA_ERROR_INVALID_SIGNATURE;
1973 goto cleanup;
Gilles Peskine89167cb2018-07-08 20:12:23 +02001974 }
mohammad16036df908f2018-04-02 08:34:15 -07001975
1976 status = psa_mac_finish_internal( operation,
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001977 actual_mac, sizeof( actual_mac ) );
1978
1979 if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
1980 status = PSA_ERROR_INVALID_SIGNATURE;
1981
1982cleanup:
1983 if( status == PSA_SUCCESS )
1984 status = psa_mac_abort( operation );
1985 else
1986 psa_mac_abort( operation );
1987
Gilles Peskine99b7d6b2018-08-21 14:56:19 +02001988 mbedtls_zeroize( actual_mac, sizeof( actual_mac ) );
Gilles Peskined911eb72018-08-14 15:18:45 +02001989
Gilles Peskine5d0b8642018-07-08 20:35:02 +02001990 return( status );
Gilles Peskine8c9def32018-02-08 10:02:12 +01001991}
1992
1993
Gilles Peskine20035e32018-02-03 22:44:14 +01001994
Gilles Peskine20035e32018-02-03 22:44:14 +01001995/****************************************************************/
1996/* Asymmetric cryptography */
1997/****************************************************************/
1998
Gilles Peskine2b450e32018-06-27 15:42:46 +02001999#if defined(MBEDTLS_RSA_C)
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002000/* Decode the hash algorithm from alg and store the mbedtls encoding in
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002001 * md_alg. Verify that the hash length is acceptable. */
Gilles Peskine8b18a4f2018-06-08 16:34:46 +02002002static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
2003 size_t hash_length,
2004 mbedtls_md_type_t *md_alg )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002005{
Gilles Peskine7ed29c52018-06-26 15:50:08 +02002006 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002007 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002008 *md_alg = mbedtls_md_get_type( md_info );
2009
2010 /* The Mbed TLS RSA module uses an unsigned int for hash length
2011 * parameters. Validate that it fits so that we don't risk an
2012 * overflow later. */
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002013#if SIZE_MAX > UINT_MAX
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002014 if( hash_length > UINT_MAX )
2015 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002016#endif
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002017
2018#if defined(MBEDTLS_PKCS1_V15)
2019 /* For PKCS#1 v1.5 signature, if using a hash, the hash length
2020 * must be correct. */
2021 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
2022 alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002023 {
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002024 if( md_info == NULL )
2025 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine61b91d42018-06-08 16:09:36 +02002026 if( mbedtls_md_get_size( md_info ) != hash_length )
2027 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002028 }
2029#endif /* MBEDTLS_PKCS1_V15 */
2030
2031#if defined(MBEDTLS_PKCS1_V21)
2032 /* PSS requires a hash internally. */
2033 if( PSA_ALG_IS_RSA_PSS( alg ) )
2034 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002035 if( md_info == NULL )
2036 return( PSA_ERROR_NOT_SUPPORTED );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002037 }
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002038#endif /* MBEDTLS_PKCS1_V21 */
2039
Gilles Peskine61b91d42018-06-08 16:09:36 +02002040 return( PSA_SUCCESS );
Nir Sonnenschein4db79eb2018-06-04 16:40:31 +03002041}
2042
Gilles Peskine2b450e32018-06-27 15:42:46 +02002043static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
2044 psa_algorithm_t alg,
2045 const uint8_t *hash,
2046 size_t hash_length,
2047 uint8_t *signature,
2048 size_t signature_size,
2049 size_t *signature_length )
2050{
2051 psa_status_t status;
2052 int ret;
2053 mbedtls_md_type_t md_alg;
2054
2055 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2056 if( status != PSA_SUCCESS )
2057 return( status );
2058
Gilles Peskine630a18a2018-06-29 17:49:35 +02002059 if( signature_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002060 return( PSA_ERROR_BUFFER_TOO_SMALL );
2061
2062#if defined(MBEDTLS_PKCS1_V15)
2063 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2064 {
2065 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2066 MBEDTLS_MD_NONE );
2067 ret = mbedtls_rsa_pkcs1_sign( rsa,
2068 mbedtls_ctr_drbg_random,
2069 &global_data.ctr_drbg,
2070 MBEDTLS_RSA_PRIVATE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002071 md_alg,
2072 (unsigned int) hash_length,
2073 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002074 signature );
2075 }
2076 else
2077#endif /* MBEDTLS_PKCS1_V15 */
2078#if defined(MBEDTLS_PKCS1_V21)
2079 if( PSA_ALG_IS_RSA_PSS( alg ) )
2080 {
2081 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2082 ret = mbedtls_rsa_rsassa_pss_sign( rsa,
2083 mbedtls_ctr_drbg_random,
2084 &global_data.ctr_drbg,
2085 MBEDTLS_RSA_PRIVATE,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002086 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002087 (unsigned int) hash_length,
2088 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002089 signature );
2090 }
2091 else
2092#endif /* MBEDTLS_PKCS1_V21 */
2093 {
2094 return( PSA_ERROR_INVALID_ARGUMENT );
2095 }
2096
2097 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002098 *signature_length = mbedtls_rsa_get_len( rsa );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002099 return( mbedtls_to_psa_error( ret ) );
2100}
2101
2102static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
2103 psa_algorithm_t alg,
2104 const uint8_t *hash,
2105 size_t hash_length,
2106 const uint8_t *signature,
2107 size_t signature_length )
2108{
2109 psa_status_t status;
2110 int ret;
2111 mbedtls_md_type_t md_alg;
2112
2113 status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
2114 if( status != PSA_SUCCESS )
2115 return( status );
2116
Gilles Peskine630a18a2018-06-29 17:49:35 +02002117 if( signature_length < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine2b450e32018-06-27 15:42:46 +02002118 return( PSA_ERROR_BUFFER_TOO_SMALL );
2119
2120#if defined(MBEDTLS_PKCS1_V15)
2121 if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
2122 {
2123 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
2124 MBEDTLS_MD_NONE );
2125 ret = mbedtls_rsa_pkcs1_verify( rsa,
2126 mbedtls_ctr_drbg_random,
2127 &global_data.ctr_drbg,
2128 MBEDTLS_RSA_PUBLIC,
2129 md_alg,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002130 (unsigned int) hash_length,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002131 hash,
2132 signature );
2133 }
2134 else
2135#endif /* MBEDTLS_PKCS1_V15 */
2136#if defined(MBEDTLS_PKCS1_V21)
2137 if( PSA_ALG_IS_RSA_PSS( alg ) )
2138 {
2139 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2140 ret = mbedtls_rsa_rsassa_pss_verify( rsa,
2141 mbedtls_ctr_drbg_random,
2142 &global_data.ctr_drbg,
2143 MBEDTLS_RSA_PUBLIC,
Gilles Peskine71ac7b12018-06-29 23:36:35 +02002144 MBEDTLS_MD_NONE,
Jaeden Amerobbf97e32018-06-26 14:20:51 +01002145 (unsigned int) hash_length,
2146 hash,
Gilles Peskine2b450e32018-06-27 15:42:46 +02002147 signature );
2148 }
2149 else
2150#endif /* MBEDTLS_PKCS1_V21 */
2151 {
2152 return( PSA_ERROR_INVALID_ARGUMENT );
2153 }
Gilles Peskineef12c632018-09-13 20:37:48 +02002154
2155 /* Mbed TLS distinguishes "invalid padding" from "valid padding but
2156 * the rest of the signature is invalid". This has little use in
2157 * practice and PSA doesn't report this distinction. */
2158 if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
2159 return( PSA_ERROR_INVALID_SIGNATURE );
Gilles Peskine2b450e32018-06-27 15:42:46 +02002160 return( mbedtls_to_psa_error( ret ) );
2161}
2162#endif /* MBEDTLS_RSA_C */
2163
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002164#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002165/* `ecp` cannot be const because `ecp->grp` needs to be non-const
2166 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
2167 * (even though these functions don't modify it). */
2168static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
2169 psa_algorithm_t alg,
2170 const uint8_t *hash,
2171 size_t hash_length,
2172 uint8_t *signature,
2173 size_t signature_size,
2174 size_t *signature_length )
2175{
2176 int ret;
2177 mbedtls_mpi r, s;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002178 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002179 mbedtls_mpi_init( &r );
2180 mbedtls_mpi_init( &s );
2181
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002182 if( signature_size < 2 * curve_bytes )
2183 {
2184 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
2185 goto cleanup;
2186 }
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002187
Gilles Peskinea05219c2018-11-16 16:02:56 +01002188#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002189 if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
2190 {
2191 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
2192 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2193 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2194 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
2195 hash, hash_length,
2196 md_alg ) );
2197 }
2198 else
Gilles Peskinea05219c2018-11-16 16:02:56 +01002199#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002200 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01002201 (void) alg;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002202 MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
2203 hash, hash_length,
2204 mbedtls_ctr_drbg_random,
2205 &global_data.ctr_drbg ) );
2206 }
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002207
2208 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
2209 signature,
2210 curve_bytes ) );
2211 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
2212 signature + curve_bytes,
2213 curve_bytes ) );
2214
2215cleanup:
2216 mbedtls_mpi_free( &r );
2217 mbedtls_mpi_free( &s );
2218 if( ret == 0 )
2219 *signature_length = 2 * curve_bytes;
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002220 return( mbedtls_to_psa_error( ret ) );
2221}
2222
2223static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
2224 const uint8_t *hash,
2225 size_t hash_length,
2226 const uint8_t *signature,
2227 size_t signature_length )
2228{
2229 int ret;
2230 mbedtls_mpi r, s;
2231 size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
2232 mbedtls_mpi_init( &r );
2233 mbedtls_mpi_init( &s );
2234
2235 if( signature_length != 2 * curve_bytes )
2236 return( PSA_ERROR_INVALID_SIGNATURE );
2237
2238 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
2239 signature,
2240 curve_bytes ) );
2241 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
2242 signature + curve_bytes,
2243 curve_bytes ) );
2244
2245 ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
2246 &ecp->Q, &r, &s );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002247
2248cleanup:
2249 mbedtls_mpi_free( &r );
2250 mbedtls_mpi_free( &s );
2251 return( mbedtls_to_psa_error( ret ) );
2252}
2253#endif /* MBEDTLS_ECDSA_C */
2254
Gilles Peskine61b91d42018-06-08 16:09:36 +02002255psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
2256 psa_algorithm_t alg,
2257 const uint8_t *hash,
2258 size_t hash_length,
Gilles Peskine61b91d42018-06-08 16:09:36 +02002259 uint8_t *signature,
2260 size_t signature_size,
2261 size_t *signature_length )
Gilles Peskine20035e32018-02-03 22:44:14 +01002262{
2263 key_slot_t *slot;
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002264 psa_status_t status;
2265
2266 *signature_length = signature_size;
2267
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002268 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_SIGN, alg );
2269 if( status != PSA_SUCCESS )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002270 goto exit;
Gilles Peskine20035e32018-02-03 22:44:14 +01002271 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002272 {
2273 status = PSA_ERROR_INVALID_ARGUMENT;
2274 goto exit;
2275 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002276
Gilles Peskine20035e32018-02-03 22:44:14 +01002277#if defined(MBEDTLS_RSA_C)
2278 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2279 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002280 status = psa_rsa_sign( slot->data.rsa,
2281 alg,
2282 hash, hash_length,
2283 signature, signature_size,
2284 signature_length );
Gilles Peskine20035e32018-02-03 22:44:14 +01002285 }
2286 else
2287#endif /* defined(MBEDTLS_RSA_C) */
2288#if defined(MBEDTLS_ECP_C)
2289 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2290 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002291#if defined(MBEDTLS_ECDSA_C)
Gilles Peskinea05219c2018-11-16 16:02:56 +01002292 if(
2293#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
2294 PSA_ALG_IS_ECDSA( alg )
2295#else
2296 PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
2297#endif
2298 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002299 status = psa_ecdsa_sign( slot->data.ecp,
2300 alg,
2301 hash, hash_length,
2302 signature, signature_size,
2303 signature_length );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002304 else
2305#endif /* defined(MBEDTLS_ECDSA_C) */
2306 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002307 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002308 }
itayzafrir5c753392018-05-08 11:18:38 +03002309 }
2310 else
2311#endif /* defined(MBEDTLS_ECP_C) */
2312 {
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002313 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine20035e32018-02-03 22:44:14 +01002314 }
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002315
2316exit:
2317 /* Fill the unused part of the output buffer (the whole buffer on error,
2318 * the trailing part on success) with something that isn't a valid mac
2319 * (barring an attack on the mac and deliberately-crafted input),
2320 * in case the caller doesn't check the return status properly. */
2321 if( status == PSA_SUCCESS )
2322 memset( signature + *signature_length, '!',
2323 signature_size - *signature_length );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002324 else if( signature_size != 0 )
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002325 memset( signature, '!', signature_size );
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002326 /* If signature_size is 0 then we have nothing to do. We must not call
2327 * memset because signature may be NULL in this case. */
Gilles Peskinea26ff6a2018-06-28 12:21:19 +02002328 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002329}
2330
2331psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
2332 psa_algorithm_t alg,
2333 const uint8_t *hash,
2334 size_t hash_length,
Gilles Peskinee9191ff2018-06-27 14:58:41 +02002335 const uint8_t *signature,
Gilles Peskine526fab02018-06-27 18:19:40 +02002336 size_t signature_length )
itayzafrir5c753392018-05-08 11:18:38 +03002337{
2338 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002339 psa_status_t status;
Gilles Peskine2b450e32018-06-27 15:42:46 +02002340
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002341 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_VERIFY, alg );
2342 if( status != PSA_SUCCESS )
2343 return( status );
itayzafrir5c753392018-05-08 11:18:38 +03002344
Gilles Peskine61b91d42018-06-08 16:09:36 +02002345#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002346 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002347 {
Gilles Peskine2b450e32018-06-27 15:42:46 +02002348 return( psa_rsa_verify( slot->data.rsa,
2349 alg,
2350 hash, hash_length,
2351 signature, signature_length ) );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002352 }
2353 else
2354#endif /* defined(MBEDTLS_RSA_C) */
itayzafrir5c753392018-05-08 11:18:38 +03002355#if defined(MBEDTLS_ECP_C)
2356 if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
2357 {
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002358#if defined(MBEDTLS_ECDSA_C)
2359 if( PSA_ALG_IS_ECDSA( alg ) )
Gilles Peskineeae6eee2018-06-28 13:56:01 +02002360 return( psa_ecdsa_verify( slot->data.ecp,
2361 hash, hash_length,
2362 signature, signature_length ) );
Gilles Peskinea81d85b2018-06-26 16:10:23 +02002363 else
2364#endif /* defined(MBEDTLS_ECDSA_C) */
2365 {
2366 return( PSA_ERROR_INVALID_ARGUMENT );
2367 }
itayzafrir5c753392018-05-08 11:18:38 +03002368 }
Gilles Peskine20035e32018-02-03 22:44:14 +01002369 else
2370#endif /* defined(MBEDTLS_ECP_C) */
2371 {
2372 return( PSA_ERROR_NOT_SUPPORTED );
2373 }
2374}
2375
Gilles Peskine072ac562018-06-30 00:21:29 +02002376#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
2377static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
2378 mbedtls_rsa_context *rsa )
2379{
2380 psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
2381 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
2382 mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
2383 mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
2384}
2385#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */
2386
Gilles Peskine61b91d42018-06-08 16:09:36 +02002387psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
2388 psa_algorithm_t alg,
2389 const uint8_t *input,
2390 size_t input_length,
2391 const uint8_t *salt,
2392 size_t salt_length,
2393 uint8_t *output,
2394 size_t output_size,
2395 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002396{
2397 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002398 psa_status_t status;
2399
Darryl Green5cc689a2018-07-24 15:34:10 +01002400 (void) input;
2401 (void) input_length;
2402 (void) salt;
2403 (void) output;
2404 (void) output_size;
2405
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002406 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002407
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002408 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2409 return( PSA_ERROR_INVALID_ARGUMENT );
2410
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002411 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
2412 if( status != PSA_SUCCESS )
2413 return( status );
Gilles Peskine35da9a22018-06-29 19:17:49 +02002414 if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
2415 PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002416 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002417
2418#if defined(MBEDTLS_RSA_C)
Gilles Peskined8008d62018-06-29 19:51:51 +02002419 if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002420 {
2421 mbedtls_rsa_context *rsa = slot->data.rsa;
2422 int ret;
Gilles Peskine630a18a2018-06-29 17:49:35 +02002423 if( output_size < mbedtls_rsa_get_len( rsa ) )
Gilles Peskine61b91d42018-06-08 16:09:36 +02002424 return( PSA_ERROR_INVALID_ARGUMENT );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002425#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002426 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002427 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002428 ret = mbedtls_rsa_pkcs1_encrypt( rsa,
2429 mbedtls_ctr_drbg_random,
2430 &global_data.ctr_drbg,
2431 MBEDTLS_RSA_PUBLIC,
2432 input_length,
2433 input,
2434 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002435 }
2436 else
2437#endif /* MBEDTLS_PKCS1_V15 */
2438#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002439 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002440 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002441 psa_rsa_oaep_set_padding_mode( alg, rsa );
2442 ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
2443 mbedtls_ctr_drbg_random,
2444 &global_data.ctr_drbg,
2445 MBEDTLS_RSA_PUBLIC,
2446 salt, salt_length,
2447 input_length,
2448 input,
2449 output );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002450 }
2451 else
2452#endif /* MBEDTLS_PKCS1_V21 */
2453 {
2454 return( PSA_ERROR_INVALID_ARGUMENT );
2455 }
2456 if( ret == 0 )
Gilles Peskine630a18a2018-06-29 17:49:35 +02002457 *output_length = mbedtls_rsa_get_len( rsa );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002458 return( mbedtls_to_psa_error( ret ) );
2459 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002460 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002461#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002462 {
2463 return( PSA_ERROR_NOT_SUPPORTED );
2464 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002465}
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002466
Gilles Peskine61b91d42018-06-08 16:09:36 +02002467psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
2468 psa_algorithm_t alg,
2469 const uint8_t *input,
2470 size_t input_length,
2471 const uint8_t *salt,
2472 size_t salt_length,
2473 uint8_t *output,
2474 size_t output_size,
2475 size_t *output_length )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002476{
2477 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002478 psa_status_t status;
2479
Darryl Green5cc689a2018-07-24 15:34:10 +01002480 (void) input;
2481 (void) input_length;
2482 (void) salt;
2483 (void) output;
2484 (void) output_size;
2485
Nir Sonnenscheinca466c82018-06-04 16:43:12 +03002486 *output_length = 0;
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002487
Gilles Peskineb3fc05d2018-06-30 19:04:35 +02002488 if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
2489 return( PSA_ERROR_INVALID_ARGUMENT );
2490
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002491 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
2492 if( status != PSA_SUCCESS )
2493 return( status );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002494 if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
2495 return( PSA_ERROR_INVALID_ARGUMENT );
2496
2497#if defined(MBEDTLS_RSA_C)
2498 if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
2499 {
2500 mbedtls_rsa_context *rsa = slot->data.rsa;
2501 int ret;
2502
Gilles Peskine630a18a2018-06-29 17:49:35 +02002503 if( input_length != mbedtls_rsa_get_len( rsa ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002504 return( PSA_ERROR_INVALID_ARGUMENT );
2505
2506#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine6afe7892018-05-31 13:16:08 +02002507 if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002508 {
Gilles Peskine61b91d42018-06-08 16:09:36 +02002509 ret = mbedtls_rsa_pkcs1_decrypt( rsa,
2510 mbedtls_ctr_drbg_random,
2511 &global_data.ctr_drbg,
2512 MBEDTLS_RSA_PRIVATE,
2513 output_length,
2514 input,
2515 output,
2516 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002517 }
2518 else
2519#endif /* MBEDTLS_PKCS1_V15 */
2520#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine55bf3d12018-06-26 15:53:48 +02002521 if( PSA_ALG_IS_RSA_OAEP( alg ) )
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002522 {
Gilles Peskine072ac562018-06-30 00:21:29 +02002523 psa_rsa_oaep_set_padding_mode( alg, rsa );
2524 ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
2525 mbedtls_ctr_drbg_random,
2526 &global_data.ctr_drbg,
2527 MBEDTLS_RSA_PRIVATE,
2528 salt, salt_length,
2529 output_length,
2530 input,
2531 output,
2532 output_size );
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002533 }
2534 else
2535#endif /* MBEDTLS_PKCS1_V21 */
2536 {
2537 return( PSA_ERROR_INVALID_ARGUMENT );
2538 }
Nir Sonnenschein717a0402018-06-04 16:36:15 +03002539
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002540 return( mbedtls_to_psa_error( ret ) );
2541 }
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002542 else
Gilles Peskineb75e4f12018-06-08 17:44:47 +02002543#endif /* defined(MBEDTLS_RSA_C) */
Nir Sonnenschein39e59142018-05-02 23:16:26 +03002544 {
2545 return( PSA_ERROR_NOT_SUPPORTED );
2546 }
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002547}
Gilles Peskine20035e32018-02-03 22:44:14 +01002548
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002549
2550
mohammad1603503973b2018-03-12 15:59:30 +02002551/****************************************************************/
2552/* Symmetric cryptography */
2553/****************************************************************/
2554
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002555/* Initialize the cipher operation structure. Once this function has been
2556 * called, psa_cipher_abort can run and will do the right thing. */
2557static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
2558 psa_algorithm_t alg )
2559{
Gilles Peskinec06e0712018-06-20 16:21:04 +02002560 if( ! PSA_ALG_IS_CIPHER( alg ) )
2561 {
2562 memset( operation, 0, sizeof( *operation ) );
2563 return( PSA_ERROR_INVALID_ARGUMENT );
2564 }
2565
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002566 operation->alg = alg;
2567 operation->key_set = 0;
2568 operation->iv_set = 0;
2569 operation->iv_required = 1;
2570 operation->iv_size = 0;
2571 operation->block_size = 0;
2572 mbedtls_cipher_init( &operation->ctx.cipher );
2573 return( PSA_SUCCESS );
2574}
2575
Gilles Peskinee553c652018-06-04 16:22:46 +02002576static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
2577 psa_key_slot_t key,
Gilles Peskine7e928852018-06-04 16:23:10 +02002578 psa_algorithm_t alg,
2579 mbedtls_operation_t cipher_operation )
mohammad1603503973b2018-03-12 15:59:30 +02002580{
2581 int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
2582 psa_status_t status;
2583 key_slot_t *slot;
mohammad1603503973b2018-03-12 15:59:30 +02002584 size_t key_bits;
2585 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002586 psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
2587 PSA_KEY_USAGE_ENCRYPT :
2588 PSA_KEY_USAGE_DECRYPT );
mohammad1603503973b2018-03-12 15:59:30 +02002589
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002590 status = psa_cipher_init( operation, alg );
2591 if( status != PSA_SUCCESS )
2592 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002593
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002594 status = psa_get_key_from_slot( key, &slot, usage, alg);
2595 if( status != PSA_SUCCESS )
2596 return( status );
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002597 key_bits = psa_get_key_bits( slot );
mohammad1603503973b2018-03-12 15:59:30 +02002598
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002599 cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
mohammad1603503973b2018-03-12 15:59:30 +02002600 if( cipher_info == NULL )
2601 return( PSA_ERROR_NOT_SUPPORTED );
2602
mohammad1603503973b2018-03-12 15:59:30 +02002603 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Moran Peker41deec42018-04-04 15:43:05 +03002604 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002605 {
2606 psa_cipher_abort( operation );
2607 return( mbedtls_to_psa_error( ret ) );
2608 }
2609
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002610#if defined(MBEDTLS_DES_C)
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002611 if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002612 {
2613 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
2614 unsigned char keys[24];
2615 memcpy( keys, slot->data.raw.data, 16 );
2616 memcpy( keys + 16, slot->data.raw.data, 8 );
2617 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2618 keys,
2619 192, cipher_operation );
2620 }
2621 else
2622#endif
2623 {
2624 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
2625 slot->data.raw.data,
Jaeden Amero23bbb752018-06-26 14:16:54 +01002626 (int) key_bits, cipher_operation );
Gilles Peskine9ad29e22018-06-21 09:40:04 +02002627 }
Moran Peker41deec42018-04-04 15:43:05 +03002628 if( ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002629 {
2630 psa_cipher_abort( operation );
2631 return( mbedtls_to_psa_error( ret ) );
2632 }
2633
mohammad16038481e742018-03-18 13:57:31 +02002634#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002635 switch( alg )
mohammad16038481e742018-03-18 13:57:31 +02002636 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002637 case PSA_ALG_CBC_NO_PADDING:
2638 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2639 MBEDTLS_PADDING_NONE );
2640 break;
2641 case PSA_ALG_CBC_PKCS7:
2642 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
2643 MBEDTLS_PADDING_PKCS7 );
2644 break;
2645 default:
2646 /* The algorithm doesn't involve padding. */
2647 ret = 0;
2648 break;
2649 }
2650 if( ret != 0 )
2651 {
2652 psa_cipher_abort( operation );
2653 return( mbedtls_to_psa_error( ret ) );
mohammad16038481e742018-03-18 13:57:31 +02002654 }
2655#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
2656
mohammad1603503973b2018-03-12 15:59:30 +02002657 operation->key_set = 1;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002658 operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
2659 PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
2660 if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
mohammad16038481e742018-03-18 13:57:31 +02002661 {
Gilles Peskineab1d7ab2018-07-06 16:07:47 +02002662 operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
mohammad16038481e742018-03-18 13:57:31 +02002663 }
mohammad1603503973b2018-03-12 15:59:30 +02002664
Moran Peker395db872018-05-31 14:07:14 +03002665 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002666}
2667
Gilles Peskinefe119512018-07-08 21:39:34 +02002668psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
2669 psa_key_slot_t key,
2670 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002671{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002672 return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002673}
2674
Gilles Peskinefe119512018-07-08 21:39:34 +02002675psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
2676 psa_key_slot_t key,
2677 psa_algorithm_t alg )
mohammad16038481e742018-03-18 13:57:31 +02002678{
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002679 return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) );
mohammad16038481e742018-03-18 13:57:31 +02002680}
2681
Gilles Peskinefe119512018-07-08 21:39:34 +02002682psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
2683 unsigned char *iv,
2684 size_t iv_size,
2685 size_t *iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002686{
itayzafrir534bd7c2018-08-02 13:56:32 +03002687 psa_status_t status;
2688 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002689 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002690 {
2691 status = PSA_ERROR_BAD_STATE;
2692 goto exit;
2693 }
Moran Peker41deec42018-04-04 15:43:05 +03002694 if( iv_size < operation->iv_size )
mohammad1603503973b2018-03-12 15:59:30 +02002695 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002696 status = PSA_ERROR_BUFFER_TOO_SMALL;
Moran Peker41deec42018-04-04 15:43:05 +03002697 goto exit;
2698 }
Gilles Peskine7e928852018-06-04 16:23:10 +02002699 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
2700 iv, operation->iv_size );
Moran Peker41deec42018-04-04 15:43:05 +03002701 if( ret != 0 )
2702 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002703 status = mbedtls_to_psa_error( ret );
Gilles Peskinee553c652018-06-04 16:22:46 +02002704 goto exit;
mohammad1603503973b2018-03-12 15:59:30 +02002705 }
Gilles Peskinee553c652018-06-04 16:22:46 +02002706
mohammad16038481e742018-03-18 13:57:31 +02002707 *iv_length = operation->iv_size;
itayzafrir534bd7c2018-08-02 13:56:32 +03002708 status = psa_cipher_set_iv( operation, iv, *iv_length );
Moran Peker41deec42018-04-04 15:43:05 +03002709
Moran Peker395db872018-05-31 14:07:14 +03002710exit:
itayzafrir534bd7c2018-08-02 13:56:32 +03002711 if( status != PSA_SUCCESS )
Moran Peker395db872018-05-31 14:07:14 +03002712 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002713 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002714}
2715
Gilles Peskinefe119512018-07-08 21:39:34 +02002716psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
2717 const unsigned char *iv,
2718 size_t iv_length )
mohammad1603503973b2018-03-12 15:59:30 +02002719{
itayzafrir534bd7c2018-08-02 13:56:32 +03002720 psa_status_t status;
2721 int ret;
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002722 if( operation->iv_set || ! operation->iv_required )
itayzafrir534bd7c2018-08-02 13:56:32 +03002723 {
2724 status = PSA_ERROR_BAD_STATE;
2725 goto exit;
2726 }
Moran Pekera28258c2018-05-29 16:25:04 +03002727 if( iv_length != operation->iv_size )
Moran Peker71f19ae2018-04-22 20:23:16 +03002728 {
itayzafrir534bd7c2018-08-02 13:56:32 +03002729 status = PSA_ERROR_INVALID_ARGUMENT;
2730 goto exit;
Moran Peker71f19ae2018-04-22 20:23:16 +03002731 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002732 ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
2733 status = mbedtls_to_psa_error( ret );
2734exit:
2735 if( status == PSA_SUCCESS )
2736 operation->iv_set = 1;
2737 else
mohammad1603503973b2018-03-12 15:59:30 +02002738 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002739 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002740}
2741
Gilles Peskinee553c652018-06-04 16:22:46 +02002742psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
2743 const uint8_t *input,
2744 size_t input_length,
2745 unsigned char *output,
2746 size_t output_size,
2747 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002748{
itayzafrir534bd7c2018-08-02 13:56:32 +03002749 psa_status_t status;
2750 int ret;
Gilles Peskine89d789c2018-06-04 17:17:16 +02002751 size_t expected_output_size;
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002752 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Gilles Peskine89d789c2018-06-04 17:17:16 +02002753 {
2754 /* Take the unprocessed partial block left over from previous
2755 * update calls, if any, plus the input to this call. Remove
2756 * the last partial block, if any. You get the data that will be
2757 * output in this call. */
2758 expected_output_size =
2759 ( operation->ctx.cipher.unprocessed_len + input_length )
2760 / operation->block_size * operation->block_size;
2761 }
2762 else
2763 {
2764 expected_output_size = input_length;
2765 }
itayzafrir534bd7c2018-08-02 13:56:32 +03002766
Gilles Peskine89d789c2018-06-04 17:17:16 +02002767 if( output_size < expected_output_size )
itayzafrir534bd7c2018-08-02 13:56:32 +03002768 {
2769 status = PSA_ERROR_BUFFER_TOO_SMALL;
2770 goto exit;
2771 }
mohammad160382759612018-03-12 18:16:40 +02002772
mohammad1603503973b2018-03-12 15:59:30 +02002773 ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
Gilles Peskinee553c652018-06-04 16:22:46 +02002774 input_length, output, output_length );
itayzafrir534bd7c2018-08-02 13:56:32 +03002775 status = mbedtls_to_psa_error( ret );
2776exit:
2777 if( status != PSA_SUCCESS )
mohammad1603503973b2018-03-12 15:59:30 +02002778 psa_cipher_abort( operation );
itayzafrir534bd7c2018-08-02 13:56:32 +03002779 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002780}
2781
Gilles Peskinee553c652018-06-04 16:22:46 +02002782psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
2783 uint8_t *output,
2784 size_t output_size,
2785 size_t *output_length )
mohammad1603503973b2018-03-12 15:59:30 +02002786{
Janos Follath315b51c2018-07-09 16:04:51 +01002787 psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
2788 int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Gilles Peskinee553c652018-06-04 16:22:46 +02002789 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
Moran Pekerbed71a22018-04-22 20:19:20 +03002790
mohammad1603503973b2018-03-12 15:59:30 +02002791 if( ! operation->key_set )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002792 {
Janos Follath315b51c2018-07-09 16:04:51 +01002793 status = PSA_ERROR_BAD_STATE;
2794 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002795 }
2796 if( operation->iv_required && ! operation->iv_set )
2797 {
Janos Follath315b51c2018-07-09 16:04:51 +01002798 status = PSA_ERROR_BAD_STATE;
2799 goto error;
Moran Peker7cb22b82018-06-05 11:40:02 +03002800 }
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002801
Gilles Peskine2c5219a2018-06-06 15:12:32 +02002802 if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002803 operation->alg == PSA_ALG_CBC_NO_PADDING &&
2804 operation->ctx.cipher.unprocessed_len != 0 )
Moran Peker7cb22b82018-06-05 11:40:02 +03002805 {
Gilles Peskinedaea26f2018-08-21 14:02:45 +02002806 status = PSA_ERROR_INVALID_ARGUMENT;
Janos Follath315b51c2018-07-09 16:04:51 +01002807 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002808 }
2809
Janos Follath315b51c2018-07-09 16:04:51 +01002810 cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
2811 temp_output_buffer,
2812 output_length );
2813 if( cipher_ret != 0 )
mohammad1603503973b2018-03-12 15:59:30 +02002814 {
Janos Follath315b51c2018-07-09 16:04:51 +01002815 status = mbedtls_to_psa_error( cipher_ret );
2816 goto error;
mohammad1603503973b2018-03-12 15:59:30 +02002817 }
Janos Follath315b51c2018-07-09 16:04:51 +01002818
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002819 if( *output_length == 0 )
Janos Follath315b51c2018-07-09 16:04:51 +01002820 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine46f1fd72018-06-28 19:31:31 +02002821 else if( output_size >= *output_length )
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002822 memcpy( output, temp_output_buffer, *output_length );
2823 else
2824 {
Janos Follath315b51c2018-07-09 16:04:51 +01002825 status = PSA_ERROR_BUFFER_TOO_SMALL;
2826 goto error;
Moran Pekerdc38ebc2018-04-30 15:45:34 +03002827 }
mohammad1603503973b2018-03-12 15:59:30 +02002828
Janos Follath279ab8e2018-07-09 16:13:21 +01002829 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002830 status = psa_cipher_abort( operation );
2831
2832 return( status );
2833
2834error:
2835
2836 *output_length = 0;
2837
Janos Follath279ab8e2018-07-09 16:13:21 +01002838 mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
Janos Follath315b51c2018-07-09 16:04:51 +01002839 (void) psa_cipher_abort( operation );
2840
2841 return( status );
mohammad1603503973b2018-03-12 15:59:30 +02002842}
2843
Gilles Peskinee553c652018-06-04 16:22:46 +02002844psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
2845{
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002846 if( operation->alg == 0 )
Gilles Peskine81736312018-06-26 15:04:31 +02002847 {
2848 /* The object has (apparently) been initialized but it is not
2849 * in use. It's ok to call abort on such an object, and there's
2850 * nothing to do. */
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002851 return( PSA_SUCCESS );
Gilles Peskine81736312018-06-26 15:04:31 +02002852 }
Gilles Peskine16c0f4f2018-06-20 16:05:20 +02002853
Gilles Peskinef9c2c092018-06-21 16:57:07 +02002854 /* Sanity check (shouldn't happen: operation->alg should
2855 * always have been initialized to a valid value). */
2856 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
2857 return( PSA_ERROR_BAD_STATE );
2858
mohammad1603503973b2018-03-12 15:59:30 +02002859 mbedtls_cipher_free( &operation->ctx.cipher );
Gilles Peskinee553c652018-06-04 16:22:46 +02002860
Moran Peker41deec42018-04-04 15:43:05 +03002861 operation->alg = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002862 operation->key_set = 0;
2863 operation->iv_set = 0;
2864 operation->iv_size = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002865 operation->block_size = 0;
Moran Pekerad9d82c2018-04-30 12:31:04 +03002866 operation->iv_required = 0;
Moran Peker41deec42018-04-04 15:43:05 +03002867
Moran Peker395db872018-05-31 14:07:14 +03002868 return( PSA_SUCCESS );
mohammad1603503973b2018-03-12 15:59:30 +02002869}
2870
Gilles Peskinea0655c32018-04-30 17:06:50 +02002871
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002872
mohammad16038cc1cee2018-03-28 01:21:33 +03002873/****************************************************************/
2874/* Key Policy */
2875/****************************************************************/
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002876
mohammad160327010052018-07-03 13:16:15 +03002877#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
Gilles Peskine2d277862018-06-18 15:41:12 +02002878void psa_key_policy_init( psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002879{
Gilles Peskine803ce742018-06-18 16:07:14 +02002880 memset( policy, 0, sizeof( *policy ) );
mohammad16038cc1cee2018-03-28 01:21:33 +03002881}
2882
Gilles Peskine2d277862018-06-18 15:41:12 +02002883void psa_key_policy_set_usage( psa_key_policy_t *policy,
2884 psa_key_usage_t usage,
2885 psa_algorithm_t alg )
mohammad16038cc1cee2018-03-28 01:21:33 +03002886{
mohammad16034eed7572018-03-28 05:14:59 -07002887 policy->usage = usage;
2888 policy->alg = alg;
mohammad16038cc1cee2018-03-28 01:21:33 +03002889}
2890
Gilles Peskineaa7bc472018-07-12 00:54:56 +02002891psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002892{
mohammad16036df908f2018-04-02 08:34:15 -07002893 return( policy->usage );
mohammad16038cc1cee2018-03-28 01:21:33 +03002894}
2895
Gilles Peskineaa7bc472018-07-12 00:54:56 +02002896psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002897{
mohammad16036df908f2018-04-02 08:34:15 -07002898 return( policy->alg );
mohammad16038cc1cee2018-03-28 01:21:33 +03002899}
mohammad160327010052018-07-03 13:16:15 +03002900#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
Mohammad Abo Mokha5c7b7d2018-07-04 15:57:00 +03002901
Gilles Peskine2d277862018-06-18 15:41:12 +02002902psa_status_t psa_set_key_policy( psa_key_slot_t key,
2903 const psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002904{
2905 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002906 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03002907
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002908 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002909 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002910
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002911 status = psa_get_empty_key_slot( key, &slot );
2912 if( status != PSA_SUCCESS )
2913 return( status );
mohammad16038cc1cee2018-03-28 01:21:33 +03002914
Gilles Peskinec1bb6c82018-06-18 16:04:39 +02002915 if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
2916 PSA_KEY_USAGE_ENCRYPT |
2917 PSA_KEY_USAGE_DECRYPT |
2918 PSA_KEY_USAGE_SIGN |
Gilles Peskineea0fb492018-07-12 17:17:20 +02002919 PSA_KEY_USAGE_VERIFY |
2920 PSA_KEY_USAGE_DERIVE ) ) != 0 )
mohammad16035feda722018-04-16 04:38:57 -07002921 return( PSA_ERROR_INVALID_ARGUMENT );
mohammad16038cc1cee2018-03-28 01:21:33 +03002922
mohammad16036df908f2018-04-02 08:34:15 -07002923 slot->policy = *policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002924
2925 return( PSA_SUCCESS );
2926}
2927
Gilles Peskine2d277862018-06-18 15:41:12 +02002928psa_status_t psa_get_key_policy( psa_key_slot_t key,
2929 psa_key_policy_t *policy )
mohammad16038cc1cee2018-03-28 01:21:33 +03002930{
2931 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002932 psa_status_t status;
mohammad16038cc1cee2018-03-28 01:21:33 +03002933
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002934 if( policy == NULL )
mohammad16038cc1cee2018-03-28 01:21:33 +03002935 return( PSA_ERROR_INVALID_ARGUMENT );
2936
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002937 status = psa_get_key_slot( key, &slot );
2938 if( status != PSA_SUCCESS )
2939 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002940
mohammad16036df908f2018-04-02 08:34:15 -07002941 *policy = slot->policy;
mohammad16038cc1cee2018-03-28 01:21:33 +03002942
2943 return( PSA_SUCCESS );
2944}
Gilles Peskine20035e32018-02-03 22:44:14 +01002945
Gilles Peskinea0655c32018-04-30 17:06:50 +02002946
2947
mohammad1603804cd712018-03-20 22:44:08 +02002948/****************************************************************/
2949/* Key Lifetime */
2950/****************************************************************/
2951
Gilles Peskine2d277862018-06-18 15:41:12 +02002952psa_status_t psa_get_key_lifetime( psa_key_slot_t key,
2953 psa_key_lifetime_t *lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002954{
2955 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002956 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02002957
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002958 status = psa_get_key_slot( key, &slot );
2959 if( status != PSA_SUCCESS )
2960 return( status );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002961
mohammad1603804cd712018-03-20 22:44:08 +02002962 *lifetime = slot->lifetime;
2963
2964 return( PSA_SUCCESS );
2965}
2966
Gilles Peskine2d277862018-06-18 15:41:12 +02002967psa_status_t psa_set_key_lifetime( psa_key_slot_t key,
Jaeden Amero65fb2362018-06-26 13:55:30 +01002968 psa_key_lifetime_t lifetime )
mohammad1603804cd712018-03-20 22:44:08 +02002969{
2970 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002971 psa_status_t status;
mohammad1603804cd712018-03-20 22:44:08 +02002972
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002973 if( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
2974 lifetime != PSA_KEY_LIFETIME_PERSISTENT &&
mohammad1603ba178512018-03-21 04:35:20 -07002975 lifetime != PSA_KEY_LIFETIME_WRITE_ONCE)
2976 return( PSA_ERROR_INVALID_ARGUMENT );
2977
Gilles Peskineb0b255c2018-07-06 17:01:38 +02002978 status = psa_get_empty_key_slot( key, &slot );
2979 if( status != PSA_SUCCESS )
2980 return( status );
mohammad1603804cd712018-03-20 22:44:08 +02002981
Moran Pekerd7326592018-05-29 16:56:39 +03002982 if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
mohammad1603ba178512018-03-21 04:35:20 -07002983 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine5b051bc2018-05-31 13:25:48 +02002984
mohammad1603060ad8a2018-03-20 14:28:38 -07002985 slot->lifetime = lifetime;
mohammad1603804cd712018-03-20 22:44:08 +02002986
2987 return( PSA_SUCCESS );
2988}
2989
Gilles Peskine20035e32018-02-03 22:44:14 +01002990
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002991
mohammad16035955c982018-04-26 00:53:03 +03002992/****************************************************************/
2993/* AEAD */
2994/****************************************************************/
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02002995
Gilles Peskineedf9a652018-08-17 18:11:56 +02002996typedef struct
2997{
2998 key_slot_t *slot;
2999 const mbedtls_cipher_info_t *cipher_info;
3000 union
3001 {
3002#if defined(MBEDTLS_CCM_C)
3003 mbedtls_ccm_context ccm;
3004#endif /* MBEDTLS_CCM_C */
3005#if defined(MBEDTLS_GCM_C)
3006 mbedtls_gcm_context gcm;
3007#endif /* MBEDTLS_GCM_C */
3008 } ctx;
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003009 psa_algorithm_t core_alg;
3010 uint8_t full_tag_length;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003011 uint8_t tag_length;
3012} aead_operation_t;
3013
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003014static void psa_aead_abort( aead_operation_t *operation )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003015{
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003016 switch( operation->core_alg )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003017 {
3018#if defined(MBEDTLS_CCM_C)
3019 case PSA_ALG_CCM:
3020 mbedtls_ccm_free( &operation->ctx.ccm );
3021 break;
3022#endif /* MBEDTLS_CCM_C */
3023#if defined(MBEDTLS_CCM_C)
3024 case PSA_ALG_GCM:
3025 mbedtls_gcm_free( &operation->ctx.gcm );
3026 break;
3027#endif /* MBEDTLS_GCM_C */
3028 }
3029}
3030
3031static psa_status_t psa_aead_setup( aead_operation_t *operation,
3032 psa_key_slot_t key,
3033 psa_key_usage_t usage,
3034 psa_algorithm_t alg )
3035{
3036 psa_status_t status;
3037 size_t key_bits;
3038 mbedtls_cipher_id_t cipher_id;
3039
3040 status = psa_get_key_from_slot( key, &operation->slot, usage, alg );
3041 if( status != PSA_SUCCESS )
3042 return( status );
3043
3044 key_bits = psa_get_key_bits( operation->slot );
3045
3046 operation->cipher_info =
3047 mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
3048 &cipher_id );
3049 if( operation->cipher_info == NULL )
3050 return( PSA_ERROR_NOT_SUPPORTED );
3051
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003052 switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003053 {
3054#if defined(MBEDTLS_CCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003055 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
3056 operation->core_alg = PSA_ALG_CCM;
3057 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003058 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3059 return( PSA_ERROR_INVALID_ARGUMENT );
3060 mbedtls_ccm_init( &operation->ctx.ccm );
3061 status = mbedtls_to_psa_error(
3062 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
3063 operation->slot->data.raw.data,
3064 (unsigned int) key_bits ) );
3065 if( status != 0 )
3066 goto cleanup;
3067 break;
3068#endif /* MBEDTLS_CCM_C */
3069
3070#if defined(MBEDTLS_GCM_C)
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003071 case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
3072 operation->core_alg = PSA_ALG_GCM;
3073 operation->full_tag_length = 16;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003074 if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
3075 return( PSA_ERROR_INVALID_ARGUMENT );
3076 mbedtls_gcm_init( &operation->ctx.gcm );
3077 status = mbedtls_to_psa_error(
3078 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
3079 operation->slot->data.raw.data,
3080 (unsigned int) key_bits ) );
3081 break;
3082#endif /* MBEDTLS_GCM_C */
3083
3084 default:
3085 return( PSA_ERROR_NOT_SUPPORTED );
3086 }
3087
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003088 if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
3089 {
3090 status = PSA_ERROR_INVALID_ARGUMENT;
3091 goto cleanup;
3092 }
3093 operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
3094 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
3095 * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
3096 * In both cases, mbedtls_xxx will validate the tag length below. */
3097
Gilles Peskineedf9a652018-08-17 18:11:56 +02003098 return( PSA_SUCCESS );
3099
3100cleanup:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003101 psa_aead_abort( operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003102 return( status );
3103}
3104
mohammad16035955c982018-04-26 00:53:03 +03003105psa_status_t psa_aead_encrypt( psa_key_slot_t key,
3106 psa_algorithm_t alg,
3107 const uint8_t *nonce,
3108 size_t nonce_length,
3109 const uint8_t *additional_data,
3110 size_t additional_data_length,
3111 const uint8_t *plaintext,
3112 size_t plaintext_length,
3113 uint8_t *ciphertext,
3114 size_t ciphertext_size,
3115 size_t *ciphertext_length )
3116{
mohammad16035955c982018-04-26 00:53:03 +03003117 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003118 aead_operation_t operation;
mohammad160315223a82018-06-03 17:19:55 +03003119 uint8_t *tag;
Gilles Peskine2d277862018-06-18 15:41:12 +02003120
mohammad1603f08a5502018-06-03 15:05:47 +03003121 *ciphertext_length = 0;
mohammad1603e58e6842018-05-09 04:58:32 -07003122
Gilles Peskineedf9a652018-08-17 18:11:56 +02003123 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003124 if( status != PSA_SUCCESS )
3125 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003126
Gilles Peskineedf9a652018-08-17 18:11:56 +02003127 /* For all currently supported modes, the tag is at the end of the
3128 * ciphertext. */
3129 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
3130 {
3131 status = PSA_ERROR_BUFFER_TOO_SMALL;
3132 goto exit;
3133 }
3134 tag = ciphertext + plaintext_length;
mohammad16035955c982018-04-26 00:53:03 +03003135
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003136 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003137 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003138 status = mbedtls_to_psa_error(
3139 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
3140 MBEDTLS_GCM_ENCRYPT,
3141 plaintext_length,
3142 nonce, nonce_length,
3143 additional_data, additional_data_length,
3144 plaintext, ciphertext,
3145 operation.tag_length, tag ) );
mohammad16035955c982018-04-26 00:53:03 +03003146 }
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003147 else if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003148 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003149 status = mbedtls_to_psa_error(
3150 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
3151 plaintext_length,
3152 nonce, nonce_length,
3153 additional_data,
3154 additional_data_length,
3155 plaintext, ciphertext,
3156 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003157 }
mohammad16035c8845f2018-05-09 05:40:09 -07003158 else
3159 {
mohammad1603554faad2018-06-03 15:07:38 +03003160 return( PSA_ERROR_NOT_SUPPORTED );
mohammad16035c8845f2018-05-09 05:40:09 -07003161 }
Gilles Peskine2d277862018-06-18 15:41:12 +02003162
Gilles Peskineedf9a652018-08-17 18:11:56 +02003163 if( status != PSA_SUCCESS && ciphertext_size != 0 )
3164 memset( ciphertext, 0, ciphertext_size );
Gilles Peskine2d277862018-06-18 15:41:12 +02003165
Gilles Peskineedf9a652018-08-17 18:11:56 +02003166exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003167 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003168 if( status == PSA_SUCCESS )
3169 *ciphertext_length = plaintext_length + operation.tag_length;
3170 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003171}
3172
Gilles Peskineee652a32018-06-01 19:23:52 +02003173/* Locate the tag in a ciphertext buffer containing the encrypted data
3174 * followed by the tag. Return the length of the part preceding the tag in
3175 * *plaintext_length. This is the size of the plaintext in modes where
3176 * the encrypted data has the same size as the plaintext, such as
3177 * CCM and GCM. */
3178static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
3179 const uint8_t *ciphertext,
3180 size_t ciphertext_length,
3181 size_t plaintext_size,
Gilles Peskineee652a32018-06-01 19:23:52 +02003182 const uint8_t **p_tag )
3183{
3184 size_t payload_length;
3185 if( tag_length > ciphertext_length )
3186 return( PSA_ERROR_INVALID_ARGUMENT );
3187 payload_length = ciphertext_length - tag_length;
3188 if( payload_length > plaintext_size )
3189 return( PSA_ERROR_BUFFER_TOO_SMALL );
3190 *p_tag = ciphertext + payload_length;
Gilles Peskineee652a32018-06-01 19:23:52 +02003191 return( PSA_SUCCESS );
3192}
3193
mohammad16035955c982018-04-26 00:53:03 +03003194psa_status_t psa_aead_decrypt( psa_key_slot_t key,
3195 psa_algorithm_t alg,
3196 const uint8_t *nonce,
3197 size_t nonce_length,
3198 const uint8_t *additional_data,
3199 size_t additional_data_length,
3200 const uint8_t *ciphertext,
3201 size_t ciphertext_length,
3202 uint8_t *plaintext,
3203 size_t plaintext_size,
3204 size_t *plaintext_length )
3205{
mohammad16035955c982018-04-26 00:53:03 +03003206 psa_status_t status;
Gilles Peskineedf9a652018-08-17 18:11:56 +02003207 aead_operation_t operation;
3208 const uint8_t *tag = NULL;
Gilles Peskine2d277862018-06-18 15:41:12 +02003209
Gilles Peskineee652a32018-06-01 19:23:52 +02003210 *plaintext_length = 0;
mohammad16039e5a5152018-04-26 12:07:35 +03003211
Gilles Peskineedf9a652018-08-17 18:11:56 +02003212 status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg );
Gilles Peskineb0b255c2018-07-06 17:01:38 +02003213 if( status != PSA_SUCCESS )
3214 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003215
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003216 if( operation.core_alg == PSA_ALG_GCM )
mohammad16035955c982018-04-26 00:53:03 +03003217 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003218 status = psa_aead_unpadded_locate_tag( operation.tag_length,
Gilles Peskineee652a32018-06-01 19:23:52 +02003219 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003220 plaintext_size, &tag );
Gilles Peskineee652a32018-06-01 19:23:52 +02003221 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003222 goto exit;
Gilles Peskineee652a32018-06-01 19:23:52 +02003223
Gilles Peskineedf9a652018-08-17 18:11:56 +02003224 status = mbedtls_to_psa_error(
3225 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
3226 ciphertext_length - operation.tag_length,
3227 nonce, nonce_length,
3228 additional_data,
3229 additional_data_length,
3230 tag, operation.tag_length,
3231 ciphertext, plaintext ) );
mohammad16035955c982018-04-26 00:53:03 +03003232 }
Gilles Peskine23cc2ff2018-08-17 19:47:52 +02003233 else if( operation.core_alg == PSA_ALG_CCM )
mohammad16035955c982018-04-26 00:53:03 +03003234 {
Gilles Peskineedf9a652018-08-17 18:11:56 +02003235 status = psa_aead_unpadded_locate_tag( operation.tag_length,
mohammad16039375f842018-06-03 14:28:24 +03003236 ciphertext, ciphertext_length,
mohammad160360a64d02018-06-03 17:20:42 +03003237 plaintext_size, &tag );
mohammad16039375f842018-06-03 14:28:24 +03003238 if( status != PSA_SUCCESS )
Gilles Peskineedf9a652018-08-17 18:11:56 +02003239 goto exit;
mohammad16039375f842018-06-03 14:28:24 +03003240
Gilles Peskineedf9a652018-08-17 18:11:56 +02003241 status = mbedtls_to_psa_error(
3242 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
3243 ciphertext_length - operation.tag_length,
3244 nonce, nonce_length,
3245 additional_data,
3246 additional_data_length,
3247 ciphertext, plaintext,
3248 tag, operation.tag_length ) );
mohammad16035955c982018-04-26 00:53:03 +03003249 }
mohammad160339574652018-06-01 04:39:53 -07003250 else
3251 {
mohammad1603554faad2018-06-03 15:07:38 +03003252 return( PSA_ERROR_NOT_SUPPORTED );
mohammad160339574652018-06-01 04:39:53 -07003253 }
Gilles Peskinea40d7742018-06-01 16:28:30 +02003254
Gilles Peskineedf9a652018-08-17 18:11:56 +02003255 if( status != PSA_SUCCESS && plaintext_size != 0 )
3256 memset( plaintext, 0, plaintext_size );
mohammad160360a64d02018-06-03 17:20:42 +03003257
Gilles Peskineedf9a652018-08-17 18:11:56 +02003258exit:
Gilles Peskinef8a8fe62018-08-21 16:38:05 +02003259 psa_aead_abort( &operation );
Gilles Peskineedf9a652018-08-17 18:11:56 +02003260 if( status == PSA_SUCCESS )
3261 *plaintext_length = ciphertext_length - operation.tag_length;
3262 return( status );
mohammad16035955c982018-04-26 00:53:03 +03003263}
3264
Gilles Peskinea0655c32018-04-30 17:06:50 +02003265
Gilles Peskine7bcfc0a2018-06-18 21:49:39 +02003266
Gilles Peskine20035e32018-02-03 22:44:14 +01003267/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02003268/* Generators */
3269/****************************************************************/
3270
3271psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
3272{
3273 psa_status_t status = PSA_SUCCESS;
3274 if( generator->alg == 0 )
3275 {
3276 /* The object has (apparently) been initialized but it is not
3277 * in use. It's ok to call abort on such an object, and there's
3278 * nothing to do. */
3279 }
3280 else
Gilles Peskine751d9652018-09-18 12:05:44 +02003281 if( generator->alg == PSA_ALG_SELECT_RAW )
3282 {
3283 if( generator->ctx.buffer.data != NULL )
3284 {
3285 mbedtls_zeroize( generator->ctx.buffer.data,
3286 generator->ctx.buffer.size );
3287 mbedtls_free( generator->ctx.buffer.data );
3288 }
3289 }
3290 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003291#if defined(MBEDTLS_MD_C)
3292 if( PSA_ALG_IS_HKDF( generator->alg ) )
3293 {
3294 mbedtls_free( generator->ctx.hkdf.info );
3295 status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
3296 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003297 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3298 /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
3299 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003300 {
3301 if( generator->ctx.tls12_prf.key != NULL )
3302 {
3303 mbedtls_zeroize( generator->ctx.tls12_prf.key,
3304 generator->ctx.tls12_prf.key_len );
3305 mbedtls_free( generator->ctx.tls12_prf.key );
3306 }
Hanno Becker580fba12018-11-13 20:50:45 +00003307
3308 if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
3309 {
3310 mbedtls_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
3311 generator->ctx.tls12_prf.Ai_with_seed_len );
3312 mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
3313 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003314 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003315 else
3316#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003317 {
3318 status = PSA_ERROR_BAD_STATE;
3319 }
3320 memset( generator, 0, sizeof( *generator ) );
3321 return( status );
3322}
3323
3324
3325psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
3326 size_t *capacity)
3327{
3328 *capacity = generator->capacity;
3329 return( PSA_SUCCESS );
3330}
3331
Gilles Peskinebef7f142018-07-12 17:22:21 +02003332#if defined(MBEDTLS_MD_C)
3333/* Read some bytes from an HKDF-based generator. This performs a chunk
3334 * of the expand phase of the HKDF algorithm. */
3335static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
3336 psa_algorithm_t hash_alg,
3337 uint8_t *output,
3338 size_t output_length )
3339{
3340 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3341 psa_status_t status;
3342
3343 while( output_length != 0 )
3344 {
3345 /* Copy what remains of the current block */
3346 uint8_t n = hash_length - hkdf->offset_in_block;
3347 if( n > output_length )
3348 n = (uint8_t) output_length;
3349 memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
3350 output += n;
3351 output_length -= n;
3352 hkdf->offset_in_block += n;
Gilles Peskined54931c2018-07-17 21:06:59 +02003353 if( output_length == 0 )
Gilles Peskinebef7f142018-07-12 17:22:21 +02003354 break;
Gilles Peskined54931c2018-07-17 21:06:59 +02003355 /* We can't be wanting more output after block 0xff, otherwise
3356 * the capacity check in psa_generator_read() would have
3357 * prevented this call. It could happen only if the generator
3358 * object was corrupted or if this function is called directly
3359 * inside the library. */
3360 if( hkdf->block_number == 0xff )
3361 return( PSA_ERROR_BAD_STATE );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003362
3363 /* We need a new block */
3364 ++hkdf->block_number;
3365 hkdf->offset_in_block = 0;
3366 status = psa_hmac_setup_internal( &hkdf->hmac,
3367 hkdf->prk, hash_length,
3368 hash_alg );
3369 if( status != PSA_SUCCESS )
3370 return( status );
3371 if( hkdf->block_number != 1 )
3372 {
3373 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3374 hkdf->output_block,
3375 hash_length );
3376 if( status != PSA_SUCCESS )
3377 return( status );
3378 }
3379 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3380 hkdf->info,
3381 hkdf->info_length );
3382 if( status != PSA_SUCCESS )
3383 return( status );
3384 status = psa_hash_update( &hkdf->hmac.hash_ctx,
3385 &hkdf->block_number, 1 );
3386 if( status != PSA_SUCCESS )
3387 return( status );
3388 status = psa_hmac_finish_internal( &hkdf->hmac,
3389 hkdf->output_block,
3390 sizeof( hkdf->output_block ) );
3391 if( status != PSA_SUCCESS )
3392 return( status );
3393 }
3394
3395 return( PSA_SUCCESS );
3396}
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003397
3398static psa_status_t psa_generator_tls12_prf_generate_next_block(
3399 psa_tls12_prf_generator_t *tls12_prf,
3400 psa_algorithm_t alg )
3401{
3402 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3403 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3404 psa_hmac_internal_data hmac;
3405 psa_status_t status, cleanup_status;
3406
Hanno Becker3b339e22018-11-13 20:56:14 +00003407 unsigned char *Ai;
3408 size_t Ai_len;
3409
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003410 /* We can't be wanting more output after block 0xff, otherwise
3411 * the capacity check in psa_generator_read() would have
3412 * prevented this call. It could happen only if the generator
3413 * object was corrupted or if this function is called directly
3414 * inside the library. */
3415 if( tls12_prf->block_number == 0xff )
3416 return( PSA_ERROR_BAD_STATE );
3417
3418 /* We need a new block */
3419 ++tls12_prf->block_number;
3420 tls12_prf->offset_in_block = 0;
3421
3422 /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
3423 *
3424 * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
3425 *
3426 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
3427 * HMAC_hash(secret, A(2) + seed) +
3428 * HMAC_hash(secret, A(3) + seed) + ...
3429 *
3430 * A(0) = seed
3431 * A(i) = HMAC_hash( secret, A(i-1) )
3432 *
3433 * The `psa_tls12_prf_generator` structures saves the block
3434 * `HMAC_hash(secret, A(i) + seed)` from which the output
3435 * is currently extracted as `output_block`, while
3436 * `A(i) + seed` is stored in `Ai_with_seed`.
3437 *
3438 * Generating a new block means recalculating `Ai_with_seed`
3439 * from the A(i)-part of it, and afterwards recalculating
3440 * `output_block`.
3441 *
3442 * A(0) is computed at setup time.
3443 *
3444 */
3445
3446 psa_hmac_init_internal( &hmac );
3447
3448 /* We must distinguish the calculation of A(1) from those
3449 * of A(2) and higher, because A(0)=seed has a different
3450 * length than the other A(i). */
3451 if( tls12_prf->block_number == 1 )
3452 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003453 Ai = tls12_prf->Ai_with_seed + hash_length;
3454 Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003455 }
3456 else
3457 {
Hanno Becker3b339e22018-11-13 20:56:14 +00003458 Ai = tls12_prf->Ai_with_seed;
3459 Ai_len = hash_length;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003460 }
3461
Hanno Becker3b339e22018-11-13 20:56:14 +00003462 /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
3463 status = psa_hmac_setup_internal( &hmac,
3464 tls12_prf->key,
3465 tls12_prf->key_len,
3466 hash_alg );
3467 if( status != PSA_SUCCESS )
3468 goto cleanup;
3469
3470 status = psa_hash_update( &hmac.hash_ctx,
3471 Ai, Ai_len );
3472 if( status != PSA_SUCCESS )
3473 goto cleanup;
3474
3475 status = psa_hmac_finish_internal( &hmac,
3476 tls12_prf->Ai_with_seed,
3477 hash_length );
3478 if( status != PSA_SUCCESS )
3479 goto cleanup;
3480
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003481 /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
3482 status = psa_hmac_setup_internal( &hmac,
3483 tls12_prf->key,
3484 tls12_prf->key_len,
3485 hash_alg );
3486 if( status != PSA_SUCCESS )
3487 goto cleanup;
3488
3489 status = psa_hash_update( &hmac.hash_ctx,
3490 tls12_prf->Ai_with_seed,
Hanno Becker580fba12018-11-13 20:50:45 +00003491 tls12_prf->Ai_with_seed_len );
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003492 if( status != PSA_SUCCESS )
3493 goto cleanup;
3494
3495 status = psa_hmac_finish_internal( &hmac,
3496 tls12_prf->output_block,
3497 hash_length );
3498 if( status != PSA_SUCCESS )
3499 goto cleanup;
3500
3501cleanup:
3502
3503 cleanup_status = psa_hmac_abort_internal( &hmac );
3504 if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
3505 status = cleanup_status;
3506
3507 return( status );
3508}
3509
3510/* Read some bytes from an TLS-1.2-PRF-based generator.
3511 * See Section 5 of RFC 5246. */
3512static psa_status_t psa_generator_tls12_prf_read(
3513 psa_tls12_prf_generator_t *tls12_prf,
3514 psa_algorithm_t alg,
3515 uint8_t *output,
3516 size_t output_length )
3517{
3518 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3519 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
3520 psa_status_t status;
3521
3522 while( output_length != 0 )
3523 {
3524 /* Copy what remains of the current block */
3525 uint8_t n = hash_length - tls12_prf->offset_in_block;
3526
3527 /* Check if we have fully processed the current block. */
3528 if( n == 0 )
3529 {
3530 status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
3531 alg );
3532 if( status != PSA_SUCCESS )
3533 return( status );
3534
3535 continue;
3536 }
3537
3538 if( n > output_length )
3539 n = (uint8_t) output_length;
3540 memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
3541 n );
3542 output += n;
3543 output_length -= n;
3544 tls12_prf->offset_in_block += n;
3545 }
3546
3547 return( PSA_SUCCESS );
3548}
Gilles Peskinebef7f142018-07-12 17:22:21 +02003549#endif /* MBEDTLS_MD_C */
3550
Gilles Peskineeab56e42018-07-12 17:12:33 +02003551psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
3552 uint8_t *output,
3553 size_t output_length )
3554{
3555 psa_status_t status;
3556
3557 if( output_length > generator->capacity )
3558 {
3559 generator->capacity = 0;
3560 /* Go through the error path to wipe all confidential data now
3561 * that the generator object is useless. */
3562 status = PSA_ERROR_INSUFFICIENT_CAPACITY;
3563 goto exit;
3564 }
3565 if( output_length == 0 &&
3566 generator->capacity == 0 && generator->alg == 0 )
3567 {
3568 /* Edge case: this is a blank or finished generator, and 0
3569 * bytes were requested. The right error in this case could
3570 * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
3571 * INSUFFICIENT_CAPACITY, which is right for a finished
3572 * generator, for consistency with the case when
3573 * output_length > 0. */
3574 return( PSA_ERROR_INSUFFICIENT_CAPACITY );
3575 }
3576 generator->capacity -= output_length;
3577
Gilles Peskine751d9652018-09-18 12:05:44 +02003578 if( generator->alg == PSA_ALG_SELECT_RAW )
3579 {
Gilles Peskine211a4362018-10-25 22:22:31 +02003580 /* Initially, the capacity of a selection generator is always
3581 * the size of the buffer, i.e. `generator->ctx.buffer.size`,
3582 * abbreviated in this comment as `size`. When the remaining
3583 * capacity is `c`, the next bytes to serve start `c` bytes
3584 * from the end of the buffer, i.e. `size - c` from the
3585 * beginning of the buffer. Since `generator->capacity` was just
3586 * decremented above, we need to serve the bytes from
3587 * `size - generator->capacity - output_length` to
3588 * `size - generator->capacity`. */
Gilles Peskine751d9652018-09-18 12:05:44 +02003589 size_t offset =
3590 generator->ctx.buffer.size - generator->capacity - output_length;
3591 memcpy( output, generator->ctx.buffer.data + offset, output_length );
3592 status = PSA_SUCCESS;
3593 }
3594 else
Gilles Peskinebef7f142018-07-12 17:22:21 +02003595#if defined(MBEDTLS_MD_C)
3596 if( PSA_ALG_IS_HKDF( generator->alg ) )
3597 {
3598 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
3599 status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
3600 output, output_length );
3601 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003602 else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
3603 PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003604 {
3605 status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
3606 generator->alg, output,
3607 output_length );
3608 }
Gilles Peskinebef7f142018-07-12 17:22:21 +02003609 else
3610#endif /* MBEDTLS_MD_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003611 {
3612 return( PSA_ERROR_BAD_STATE );
3613 }
3614
3615exit:
3616 if( status != PSA_SUCCESS )
3617 {
3618 psa_generator_abort( generator );
3619 memset( output, '!', output_length );
3620 }
3621 return( status );
3622}
3623
Gilles Peskine08542d82018-07-19 17:05:42 +02003624#if defined(MBEDTLS_DES_C)
3625static void psa_des_set_key_parity( uint8_t *data, size_t data_size )
3626{
3627 if( data_size >= 8 )
3628 mbedtls_des_key_set_parity( data );
3629 if( data_size >= 16 )
3630 mbedtls_des_key_set_parity( data + 8 );
3631 if( data_size >= 24 )
3632 mbedtls_des_key_set_parity( data + 16 );
3633}
3634#endif /* MBEDTLS_DES_C */
3635
Gilles Peskineeab56e42018-07-12 17:12:33 +02003636psa_status_t psa_generator_import_key( psa_key_slot_t key,
3637 psa_key_type_t type,
3638 size_t bits,
3639 psa_crypto_generator_t *generator )
3640{
3641 uint8_t *data = NULL;
3642 size_t bytes = PSA_BITS_TO_BYTES( bits );
3643 psa_status_t status;
3644
3645 if( ! key_type_is_raw_bytes( type ) )
3646 return( PSA_ERROR_INVALID_ARGUMENT );
3647 if( bits % 8 != 0 )
3648 return( PSA_ERROR_INVALID_ARGUMENT );
3649 data = mbedtls_calloc( 1, bytes );
3650 if( data == NULL )
3651 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3652
3653 status = psa_generator_read( generator, data, bytes );
3654 if( status != PSA_SUCCESS )
3655 goto exit;
Gilles Peskine08542d82018-07-19 17:05:42 +02003656#if defined(MBEDTLS_DES_C)
3657 if( type == PSA_KEY_TYPE_DES )
3658 psa_des_set_key_parity( data, bytes );
3659#endif /* MBEDTLS_DES_C */
Gilles Peskineeab56e42018-07-12 17:12:33 +02003660 status = psa_import_key( key, type, data, bytes );
3661
3662exit:
3663 mbedtls_free( data );
3664 return( status );
3665}
3666
3667
3668
3669/****************************************************************/
Gilles Peskineea0fb492018-07-12 17:17:20 +02003670/* Key derivation */
3671/****************************************************************/
3672
Gilles Peskinea05219c2018-11-16 16:02:56 +01003673#if defined(MBEDTLS_MD_C)
Gilles Peskinebef7f142018-07-12 17:22:21 +02003674/* Set up an HKDF-based generator. This is exactly the extract phase
Gilles Peskine346797d2018-11-16 16:05:06 +01003675 * of the HKDF algorithm.
3676 *
3677 * Note that if this function fails, you must call psa_generator_abort()
3678 * to potentially free embedded data structures and wipe confidential data.
3679 */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003680static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003681 const uint8_t *secret,
3682 size_t secret_length,
Gilles Peskinebef7f142018-07-12 17:22:21 +02003683 psa_algorithm_t hash_alg,
3684 const uint8_t *salt,
3685 size_t salt_length,
3686 const uint8_t *label,
3687 size_t label_length )
3688{
3689 psa_status_t status;
3690 status = psa_hmac_setup_internal( &hkdf->hmac,
3691 salt, salt_length,
Gilles Peskine00709fa2018-08-22 18:25:41 +02003692 PSA_ALG_HMAC_GET_HASH( hash_alg ) );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003693 if( status != PSA_SUCCESS )
3694 return( status );
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003695 status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
Gilles Peskinebef7f142018-07-12 17:22:21 +02003696 if( status != PSA_SUCCESS )
3697 return( status );
3698 status = psa_hmac_finish_internal( &hkdf->hmac,
3699 hkdf->prk,
3700 sizeof( hkdf->prk ) );
3701 if( status != PSA_SUCCESS )
3702 return( status );
3703 hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
3704 hkdf->block_number = 0;
3705 hkdf->info_length = label_length;
3706 if( label_length != 0 )
3707 {
3708 hkdf->info = mbedtls_calloc( 1, label_length );
3709 if( hkdf->info == NULL )
3710 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3711 memcpy( hkdf->info, label, label_length );
3712 }
3713 return( PSA_SUCCESS );
3714}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003715#endif /* MBEDTLS_MD_C */
Gilles Peskinebef7f142018-07-12 17:22:21 +02003716
Gilles Peskinea05219c2018-11-16 16:02:56 +01003717#if defined(MBEDTLS_MD_C)
Gilles Peskine346797d2018-11-16 16:05:06 +01003718/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
3719 *
3720 * Note that if this function fails, you must call psa_generator_abort()
3721 * to potentially free embedded data structures and wipe confidential data.
3722 */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003723static psa_status_t psa_generator_tls12_prf_setup(
3724 psa_tls12_prf_generator_t *tls12_prf,
3725 const unsigned char *key,
3726 size_t key_len,
3727 psa_algorithm_t hash_alg,
3728 const uint8_t *salt,
3729 size_t salt_length,
3730 const uint8_t *label,
3731 size_t label_length )
3732{
3733 uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
Hanno Becker580fba12018-11-13 20:50:45 +00003734 size_t Ai_with_seed_len = hash_length + salt_length + label_length;
3735 int overflow;
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003736
3737 tls12_prf->key = mbedtls_calloc( 1, key_len );
3738 if( tls12_prf->key == NULL )
3739 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3740 tls12_prf->key_len = key_len;
3741 memcpy( tls12_prf->key, key, key_len );
3742
Hanno Becker580fba12018-11-13 20:50:45 +00003743 overflow = ( salt_length + label_length < salt_length ) ||
3744 ( salt_length + label_length + hash_length < hash_length );
3745 if( overflow )
3746 return( PSA_ERROR_INVALID_ARGUMENT );
3747
3748 tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
3749 if( tls12_prf->Ai_with_seed == NULL )
3750 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3751 tls12_prf->Ai_with_seed_len = Ai_with_seed_len;
3752
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003753 /* Write `label + seed' at the end of the `A(i) + seed` buffer,
3754 * leaving the initial `hash_length` bytes unspecified for now. */
Hanno Becker353e4532018-11-15 09:53:57 +00003755 if( label_length != 0 )
3756 {
3757 memcpy( tls12_prf->Ai_with_seed + hash_length,
3758 label, label_length );
3759 }
3760
3761 if( salt_length != 0 )
3762 {
3763 memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
3764 salt, salt_length );
3765 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003766
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003767 /* The first block gets generated when
3768 * psa_generator_read() is called. */
3769 tls12_prf->block_number = 0;
3770 tls12_prf->offset_in_block = hash_length;
3771
3772 return( PSA_SUCCESS );
3773}
Hanno Becker1aaedc02018-11-16 11:35:34 +00003774
3775/* Set up a TLS-1.2-PSK-to-MS-based generator. */
3776static psa_status_t psa_generator_tls12_psk_to_ms_setup(
3777 psa_tls12_prf_generator_t *tls12_prf,
3778 const unsigned char *psk,
3779 size_t psk_len,
3780 psa_algorithm_t hash_alg,
3781 const uint8_t *salt,
3782 size_t salt_length,
3783 const uint8_t *label,
3784 size_t label_length )
3785{
3786 psa_status_t status;
3787 unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
3788
3789 if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
3790 return( PSA_ERROR_INVALID_ARGUMENT );
3791
3792 /* Quoting RFC 4279, Section 2:
3793 *
3794 * The premaster secret is formed as follows: if the PSK is N octets
3795 * long, concatenate a uint16 with the value N, N zero octets, a second
3796 * uint16 with the value N, and the PSK itself.
3797 */
3798
3799 pms[0] = ( psk_len >> 8 ) & 0xff;
3800 pms[1] = ( psk_len >> 0 ) & 0xff;
3801 memset( pms + 2, 0, psk_len );
3802 pms[2 + psk_len + 0] = pms[0];
3803 pms[2 + psk_len + 1] = pms[1];
3804 memcpy( pms + 4 + psk_len, psk, psk_len );
3805
3806 status = psa_generator_tls12_prf_setup( tls12_prf,
3807 pms, 4 + 2 * psk_len,
3808 hash_alg,
3809 salt, salt_length,
3810 label, label_length );
3811
3812 mbedtls_zeroize( pms, sizeof( pms ) );
3813 return( status );
3814}
Gilles Peskinea05219c2018-11-16 16:02:56 +01003815#endif /* MBEDTLS_MD_C */
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003816
Gilles Peskine346797d2018-11-16 16:05:06 +01003817/* Note that if this function fails, you must call psa_generator_abort()
3818 * to potentially free embedded data structures and wipe confidential data.
3819 */
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003820static psa_status_t psa_key_derivation_internal(
3821 psa_crypto_generator_t *generator,
3822 const uint8_t *secret, size_t secret_length,
3823 psa_algorithm_t alg,
3824 const uint8_t *salt, size_t salt_length,
3825 const uint8_t *label, size_t label_length,
3826 size_t capacity )
3827{
3828 psa_status_t status;
3829 size_t max_capacity;
3830
3831 /* Set generator->alg even on failure so that abort knows what to do. */
3832 generator->alg = alg;
3833
Gilles Peskine751d9652018-09-18 12:05:44 +02003834 if( alg == PSA_ALG_SELECT_RAW )
3835 {
Gilles Peskinea05219c2018-11-16 16:02:56 +01003836 (void) salt;
Gilles Peskine751d9652018-09-18 12:05:44 +02003837 if( salt_length != 0 )
3838 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskinea05219c2018-11-16 16:02:56 +01003839 (void) label;
Gilles Peskine751d9652018-09-18 12:05:44 +02003840 if( label_length != 0 )
3841 return( PSA_ERROR_INVALID_ARGUMENT );
3842 generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
3843 if( generator->ctx.buffer.data == NULL )
3844 return( PSA_ERROR_INSUFFICIENT_MEMORY );
3845 memcpy( generator->ctx.buffer.data, secret, secret_length );
3846 generator->ctx.buffer.size = secret_length;
3847 max_capacity = secret_length;
3848 status = PSA_SUCCESS;
3849 }
3850 else
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003851#if defined(MBEDTLS_MD_C)
3852 if( PSA_ALG_IS_HKDF( alg ) )
3853 {
3854 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
3855 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3856 if( hash_size == 0 )
3857 return( PSA_ERROR_NOT_SUPPORTED );
3858 max_capacity = 255 * hash_size;
3859 status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
3860 secret, secret_length,
3861 hash_alg,
3862 salt, salt_length,
3863 label, label_length );
3864 }
Hanno Becker1aaedc02018-11-16 11:35:34 +00003865 /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
3866 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
3867 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003868 {
3869 psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
3870 size_t hash_size = PSA_HASH_SIZE( hash_alg );
3871
3872 /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
3873 if( hash_alg != PSA_ALG_SHA_256 &&
3874 hash_alg != PSA_ALG_SHA_384 )
3875 {
3876 return( PSA_ERROR_NOT_SUPPORTED );
3877 }
3878
3879 max_capacity = 255 * hash_size;
Hanno Becker1aaedc02018-11-16 11:35:34 +00003880
3881 if( PSA_ALG_IS_TLS12_PRF( alg ) )
3882 {
3883 status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
3884 secret, secret_length,
3885 hash_alg, salt, salt_length,
3886 label, label_length );
3887 }
3888 else
3889 {
3890 status = psa_generator_tls12_psk_to_ms_setup(
3891 &generator->ctx.tls12_prf,
3892 secret, secret_length,
3893 hash_alg, salt, salt_length,
3894 label, label_length );
3895 }
Hanno Beckerc8a41d72018-10-09 17:33:01 +01003896 }
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003897 else
3898#endif
3899 {
3900 return( PSA_ERROR_NOT_SUPPORTED );
3901 }
3902
3903 if( status != PSA_SUCCESS )
3904 return( status );
3905
3906 if( capacity <= max_capacity )
3907 generator->capacity = capacity;
Gilles Peskine8feb3a82018-09-18 12:06:11 +02003908 else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
3909 generator->capacity = max_capacity;
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003910 else
3911 return( PSA_ERROR_INVALID_ARGUMENT );
3912
3913 return( PSA_SUCCESS );
3914}
3915
Gilles Peskineea0fb492018-07-12 17:17:20 +02003916psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
Darryl Green88001362018-07-26 13:59:04 +01003917 psa_key_slot_t key,
Gilles Peskineea0fb492018-07-12 17:17:20 +02003918 psa_algorithm_t alg,
3919 const uint8_t *salt,
3920 size_t salt_length,
3921 const uint8_t *label,
3922 size_t label_length,
3923 size_t capacity )
3924{
3925 key_slot_t *slot;
3926 psa_status_t status;
3927
3928 if( generator->alg != 0 )
3929 return( PSA_ERROR_BAD_STATE );
3930
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003931 /* Make sure that alg is a key derivation algorithm. This prevents
3932 * key selection algorithms, which psa_key_derivation_internal
3933 * accepts for the sake of key agreement. */
Gilles Peskineea0fb492018-07-12 17:17:20 +02003934 if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
3935 return( PSA_ERROR_INVALID_ARGUMENT );
3936
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003937 status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DERIVE, alg );
3938 if( status != PSA_SUCCESS )
3939 return( status );
Gilles Peskineea0fb492018-07-12 17:17:20 +02003940
Gilles Peskinecce18ae2018-09-18 12:03:52 +02003941 if( slot->type != PSA_KEY_TYPE_DERIVE )
3942 return( PSA_ERROR_INVALID_ARGUMENT );
3943
3944 status = psa_key_derivation_internal( generator,
3945 slot->data.raw.data,
3946 slot->data.raw.bytes,
3947 alg,
3948 salt, salt_length,
3949 label, label_length,
3950 capacity );
3951 if( status != PSA_SUCCESS )
Gilles Peskineea0fb492018-07-12 17:17:20 +02003952 psa_generator_abort( generator );
3953 return( status );
3954}
3955
3956
3957
3958/****************************************************************/
Gilles Peskine01d718c2018-09-18 12:01:02 +02003959/* Key agreement */
3960/****************************************************************/
3961
Gilles Peskinea05219c2018-11-16 16:02:56 +01003962#if defined(MBEDTLS_ECDH_C)
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02003963static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
3964 size_t peer_key_length,
3965 const mbedtls_ecp_keypair *our_key,
3966 uint8_t *shared_secret,
3967 size_t shared_secret_size,
3968 size_t *shared_secret_length )
3969{
3970 mbedtls_pk_context pk;
3971 mbedtls_ecp_keypair *their_key = NULL;
3972 mbedtls_ecdh_context ecdh;
3973 int ret;
3974 mbedtls_ecdh_init( &ecdh );
3975 mbedtls_pk_init( &pk );
3976
3977 ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
3978 if( ret != 0 )
3979 goto exit;
Gilles Peskine88714d72018-10-25 23:07:25 +02003980 switch( mbedtls_pk_get_type( &pk ) )
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02003981 {
Gilles Peskine88714d72018-10-25 23:07:25 +02003982 case MBEDTLS_PK_ECKEY:
3983 case MBEDTLS_PK_ECKEY_DH:
3984 break;
3985 default:
3986 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
3987 goto exit;
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02003988 }
3989 their_key = mbedtls_pk_ec( pk );
Gilles Peskineb4086612018-11-14 20:51:23 +01003990 if( their_key->grp.id != our_key->grp.id )
3991 {
3992 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
3993 goto exit;
3994 }
3995
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02003996 ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
3997 if( ret != 0 )
3998 goto exit;
3999 ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
4000 if( ret != 0 )
4001 goto exit;
4002
4003 ret = mbedtls_ecdh_calc_secret( &ecdh,
4004 shared_secret_length,
4005 shared_secret, shared_secret_size,
4006 mbedtls_ctr_drbg_random,
4007 &global_data.ctr_drbg );
4008
4009exit:
4010 mbedtls_pk_free( &pk );
4011 mbedtls_ecdh_free( &ecdh );
4012 return( mbedtls_to_psa_error( ret ) );
4013}
Gilles Peskinea05219c2018-11-16 16:02:56 +01004014#endif /* MBEDTLS_ECDH_C */
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004015
Gilles Peskine01d718c2018-09-18 12:01:02 +02004016#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
4017
Gilles Peskine346797d2018-11-16 16:05:06 +01004018/* Note that if this function fails, you must call psa_generator_abort()
4019 * to potentially free embedded data structures and wipe confidential data.
4020 */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004021static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
4022 key_slot_t *private_key,
4023 const uint8_t *peer_key,
4024 size_t peer_key_length,
4025 psa_algorithm_t alg )
4026{
4027 psa_status_t status;
4028 uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
4029 size_t shared_secret_length = 0;
4030
4031 /* Step 1: run the secret agreement algorithm to generate the shared
4032 * secret. */
4033 switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
4034 {
Gilles Peskineb7ecdf02018-09-18 12:11:27 +02004035#if defined(MBEDTLS_ECDH_C)
4036 case PSA_ALG_ECDH_BASE:
4037 if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
4038 return( PSA_ERROR_INVALID_ARGUMENT );
4039 status = psa_key_agreement_ecdh( peer_key, peer_key_length,
4040 private_key->data.ecp,
4041 shared_secret,
4042 sizeof( shared_secret ),
4043 &shared_secret_length );
4044 break;
4045#endif /* MBEDTLS_ECDH_C */
Gilles Peskine01d718c2018-09-18 12:01:02 +02004046 default:
Gilles Peskine93f85002018-11-16 16:43:31 +01004047 (void) private_key;
4048 (void) peer_key;
4049 (void) peer_key_length;
Gilles Peskine01d718c2018-09-18 12:01:02 +02004050 return( PSA_ERROR_NOT_SUPPORTED );
4051 }
4052 if( status != PSA_SUCCESS )
4053 goto exit;
4054
4055 /* Step 2: set up the key derivation to generate key material from
4056 * the shared secret. */
4057 status = psa_key_derivation_internal( generator,
4058 shared_secret, shared_secret_length,
4059 PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
4060 NULL, 0, NULL, 0,
4061 PSA_GENERATOR_UNBRIDLED_CAPACITY );
4062exit:
4063 mbedtls_zeroize( shared_secret, shared_secret_length );
4064 return( status );
4065}
4066
4067psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
4068 psa_key_slot_t private_key,
4069 const uint8_t *peer_key,
4070 size_t peer_key_length,
4071 psa_algorithm_t alg )
4072{
4073 key_slot_t *slot;
4074 psa_status_t status;
4075 if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
4076 return( PSA_ERROR_INVALID_ARGUMENT );
4077 status = psa_get_key_from_slot( private_key, &slot,
4078 PSA_KEY_USAGE_DERIVE, alg );
4079 if( status != PSA_SUCCESS )
4080 return( status );
Gilles Peskine346797d2018-11-16 16:05:06 +01004081 status = psa_key_agreement_internal( generator,
4082 slot,
4083 peer_key, peer_key_length,
4084 alg );
4085 if( status != PSA_SUCCESS )
4086 psa_generator_abort( generator );
4087 return( status );
Gilles Peskine01d718c2018-09-18 12:01:02 +02004088}
4089
4090
4091
4092/****************************************************************/
Gilles Peskineeab56e42018-07-12 17:12:33 +02004093/* Random generation */
Gilles Peskine05d69892018-06-19 22:00:52 +02004094/****************************************************************/
4095
4096psa_status_t psa_generate_random( uint8_t *output,
4097 size_t output_size )
4098{
itayzafrir0adf0fc2018-09-06 16:24:41 +03004099 int ret;
4100 GUARD_MODULE_INITIALIZED;
4101
4102 ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
Gilles Peskine05d69892018-06-19 22:00:52 +02004103 return( mbedtls_to_psa_error( ret ) );
4104}
4105
4106psa_status_t psa_generate_key( psa_key_slot_t key,
4107 psa_key_type_t type,
4108 size_t bits,
Gilles Peskine53d991e2018-07-12 01:14:59 +02004109 const void *extra,
4110 size_t extra_size )
Gilles Peskine05d69892018-06-19 22:00:52 +02004111{
Gilles Peskine12313cd2018-06-20 00:20:32 +02004112 key_slot_t *slot;
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004113 psa_status_t status;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004114
Gilles Peskine53d991e2018-07-12 01:14:59 +02004115 if( extra == NULL && extra_size != 0 )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004116 return( PSA_ERROR_INVALID_ARGUMENT );
4117
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004118 status = psa_get_empty_key_slot( key, &slot );
4119 if( status != PSA_SUCCESS )
4120 return( status );
4121
Gilles Peskine48c0ea12018-06-21 14:15:31 +02004122 if( key_type_is_raw_bytes( type ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004123 {
Gilles Peskineb0b255c2018-07-06 17:01:38 +02004124 status = prepare_raw_data_slot( type, bits, &slot->data.raw );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004125 if( status != PSA_SUCCESS )
4126 return( status );
4127 status = psa_generate_random( slot->data.raw.data,
4128 slot->data.raw.bytes );
4129 if( status != PSA_SUCCESS )
4130 {
4131 mbedtls_free( slot->data.raw.data );
4132 return( status );
4133 }
4134#if defined(MBEDTLS_DES_C)
4135 if( type == PSA_KEY_TYPE_DES )
Gilles Peskine08542d82018-07-19 17:05:42 +02004136 psa_des_set_key_parity( slot->data.raw.data,
4137 slot->data.raw.bytes );
Gilles Peskine12313cd2018-06-20 00:20:32 +02004138#endif /* MBEDTLS_DES_C */
4139 }
4140 else
4141
4142#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
4143 if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
4144 {
4145 mbedtls_rsa_context *rsa;
4146 int ret;
4147 int exponent = 65537;
Gilles Peskineaf3baab2018-06-27 22:55:52 +02004148 if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
4149 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine86a440b2018-11-12 18:39:40 +01004150 /* Accept only byte-aligned keys, for the same reasons as
4151 * in psa_import_rsa_key(). */
4152 if( bits % 8 != 0 )
4153 return( PSA_ERROR_NOT_SUPPORTED );
Gilles Peskine53d991e2018-07-12 01:14:59 +02004154 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004155 {
Gilles Peskine4c317f42018-07-12 01:24:09 +02004156 const psa_generate_key_extra_rsa *p = extra;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004157 if( extra_size != sizeof( *p ) )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004158 return( PSA_ERROR_INVALID_ARGUMENT );
Gilles Peskine4c317f42018-07-12 01:24:09 +02004159#if INT_MAX < 0xffffffff
4160 /* Check that the uint32_t value passed by the caller fits
4161 * in the range supported by this implementation. */
4162 if( p->e > INT_MAX )
4163 return( PSA_ERROR_NOT_SUPPORTED );
4164#endif
4165 exponent = p->e;
Gilles Peskine12313cd2018-06-20 00:20:32 +02004166 }
4167 rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
4168 if( rsa == NULL )
4169 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4170 mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
4171 ret = mbedtls_rsa_gen_key( rsa,
4172 mbedtls_ctr_drbg_random,
4173 &global_data.ctr_drbg,
Jaeden Amero23bbb752018-06-26 14:16:54 +01004174 (unsigned int) bits,
Gilles Peskine12313cd2018-06-20 00:20:32 +02004175 exponent );
4176 if( ret != 0 )
4177 {
4178 mbedtls_rsa_free( rsa );
4179 mbedtls_free( rsa );
4180 return( mbedtls_to_psa_error( ret ) );
4181 }
4182 slot->data.rsa = rsa;
4183 }
4184 else
4185#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
4186
4187#if defined(MBEDTLS_ECP_C)
4188 if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
4189 {
4190 psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
4191 mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
4192 const mbedtls_ecp_curve_info *curve_info =
4193 mbedtls_ecp_curve_info_from_grp_id( grp_id );
4194 mbedtls_ecp_keypair *ecp;
4195 int ret;
Gilles Peskine53d991e2018-07-12 01:14:59 +02004196 if( extra != NULL )
Gilles Peskine12313cd2018-06-20 00:20:32 +02004197 return( PSA_ERROR_NOT_SUPPORTED );
4198 if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
4199 return( PSA_ERROR_NOT_SUPPORTED );
4200 if( curve_info->bit_size != bits )
4201 return( PSA_ERROR_INVALID_ARGUMENT );
4202 ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
4203 if( ecp == NULL )
4204 return( PSA_ERROR_INSUFFICIENT_MEMORY );
4205 mbedtls_ecp_keypair_init( ecp );
4206 ret = mbedtls_ecp_gen_key( grp_id, ecp,
4207 mbedtls_ctr_drbg_random,
4208 &global_data.ctr_drbg );
4209 if( ret != 0 )
4210 {
4211 mbedtls_ecp_keypair_free( ecp );
4212 mbedtls_free( ecp );
4213 return( mbedtls_to_psa_error( ret ) );
4214 }
4215 slot->data.ecp = ecp;
4216 }
4217 else
4218#endif /* MBEDTLS_ECP_C */
4219
4220 return( PSA_ERROR_NOT_SUPPORTED );
4221
4222 slot->type = type;
4223 return( PSA_SUCCESS );
Gilles Peskine05d69892018-06-19 22:00:52 +02004224}
4225
4226
4227/****************************************************************/
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01004228/* Module setup */
4229/****************************************************************/
4230
Gilles Peskinee59236f2018-01-27 23:32:46 +01004231void mbedtls_psa_crypto_free( void )
4232{
Jaeden Amero045bd502018-06-26 14:00:08 +01004233 psa_key_slot_t key;
Gilles Peskine9a056342018-08-01 15:46:54 +02004234 for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
Gilles Peskine2f9c4dc2018-01-28 13:16:24 +01004235 psa_destroy_key( key );
Gilles Peskinee59236f2018-01-27 23:32:46 +01004236 mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
4237 mbedtls_entropy_free( &global_data.entropy );
4238 mbedtls_zeroize( &global_data, sizeof( global_data ) );
4239}
4240
4241psa_status_t psa_crypto_init( void )
4242{
4243 int ret;
4244 const unsigned char drbg_seed[] = "PSA";
4245
4246 if( global_data.initialized != 0 )
4247 return( PSA_SUCCESS );
4248
4249 mbedtls_zeroize( &global_data, sizeof( global_data ) );
4250 mbedtls_entropy_init( &global_data.entropy );
4251 mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
4252
4253 ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
4254 mbedtls_entropy_func,
4255 &global_data.entropy,
4256 drbg_seed, sizeof( drbg_seed ) - 1 );
4257 if( ret != 0 )
4258 goto exit;
4259
Gilles Peskinee4ebc122018-03-07 14:16:44 +01004260 global_data.initialized = 1;
4261
Gilles Peskinee59236f2018-01-27 23:32:46 +01004262exit:
4263 if( ret != 0 )
4264 mbedtls_psa_crypto_free( );
4265 return( mbedtls_to_psa_error( ret ) );
4266}
4267
4268#endif /* MBEDTLS_PSA_CRYPTO_C */