/src/mbedtls/library/pk.c
Line | Count | Source |
1 | | /* |
2 | | * Public Key abstraction layer |
3 | | * |
4 | | * Copyright The Mbed TLS Contributors |
5 | | * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later |
6 | | */ |
7 | | |
8 | | #include "common.h" |
9 | | |
10 | | #if defined(MBEDTLS_PK_C) |
11 | | #include "mbedtls/pk.h" |
12 | | #include "pk_wrap.h" |
13 | | #include "pkwrite.h" |
14 | | #include "pk_internal.h" |
15 | | |
16 | | #include "mbedtls/platform_util.h" |
17 | | #include "mbedtls/error.h" |
18 | | |
19 | | #if defined(MBEDTLS_RSA_C) |
20 | | #include "mbedtls/rsa.h" |
21 | | #include "rsa_internal.h" |
22 | | #endif |
23 | | #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) |
24 | | #include "mbedtls/ecp.h" |
25 | | #endif |
26 | | #if defined(MBEDTLS_ECDSA_C) |
27 | | #include "mbedtls/ecdsa.h" |
28 | | #endif |
29 | | |
30 | | #if defined(MBEDTLS_PSA_CRYPTO_CLIENT) |
31 | | #include "psa_util_internal.h" |
32 | | #include "mbedtls/psa_util.h" |
33 | | #endif |
34 | | |
35 | | #include <limits.h> |
36 | | #include <stdint.h> |
37 | | |
38 | | #if !defined(PK_EXPORT_KEYS_ON_THE_STACK) |
39 | | #include "mbedtls/platform.h" // for calloc/free |
40 | | #endif |
41 | | |
42 | | #if defined(MBEDTLS_PSA_CRYPTO_CLIENT) |
43 | | #define MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN \ |
44 | | PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) |
45 | | |
46 | | #define MBEDTLS_PK_MAX_RSA_PUBKEY_RAW_LEN \ |
47 | | PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) |
48 | | |
49 | | #define MBEDTLS_PK_MAX_PUBKEY_RAW_LEN 0 |
50 | | #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && \ |
51 | | MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN > MBEDTLS_PK_MAX_PUBKEY_RAW_LEN |
52 | | #undef MBEDTLS_PK_MAX_PUBKEY_RAW_LEN |
53 | | #define MBEDTLS_PK_MAX_PUBKEY_RAW_LEN MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN |
54 | | #endif |
55 | | #if (defined(MBEDTLS_RSA_C) || \ |
56 | | (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))) && \ |
57 | | MBEDTLS_PK_MAX_RSA_PUBKEY_RAW_LEN > MBEDTLS_PK_MAX_PUBKEY_RAW_LEN |
58 | | #undef MBEDTLS_PK_MAX_PUBKEY_RAW_LEN |
59 | | #define MBEDTLS_PK_MAX_PUBKEY_RAW_LEN MBEDTLS_PK_MAX_RSA_PUBKEY_RAW_LEN |
60 | | #endif |
61 | | #endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ |
62 | | |
63 | | /* |
64 | | * Initialise a mbedtls_pk_context |
65 | | */ |
66 | | void mbedtls_pk_init(mbedtls_pk_context *ctx) |
67 | 42.1k | { |
68 | 42.1k | ctx->pk_info = NULL; |
69 | 42.1k | ctx->pk_ctx = NULL; |
70 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
71 | 21.0k | ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT; |
72 | | #endif /* MBEDTLS_USE_PSA_CRYPTO */ |
73 | | #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) |
74 | | memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw)); |
75 | | ctx->pub_raw_len = 0; |
76 | | ctx->ec_family = 0; |
77 | | ctx->ec_bits = 0; |
78 | | #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ |
79 | 42.1k | } Line | Count | Source | 67 | 21.0k | { | 68 | 21.0k | ctx->pk_info = NULL; | 69 | 21.0k | ctx->pk_ctx = NULL; | 70 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) | 71 | | ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT; | 72 | | #endif /* MBEDTLS_USE_PSA_CRYPTO */ | 73 | | #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) | 74 | | memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw)); | 75 | | ctx->pub_raw_len = 0; | 76 | | ctx->ec_family = 0; | 77 | | ctx->ec_bits = 0; | 78 | | #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ | 79 | 21.0k | } |
Line | Count | Source | 67 | 21.0k | { | 68 | 21.0k | ctx->pk_info = NULL; | 69 | 21.0k | ctx->pk_ctx = NULL; | 70 | 21.0k | #if defined(MBEDTLS_USE_PSA_CRYPTO) | 71 | 21.0k | ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT; | 72 | 21.0k | #endif /* MBEDTLS_USE_PSA_CRYPTO */ | 73 | | #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) | 74 | | memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw)); | 75 | | ctx->pub_raw_len = 0; | 76 | | ctx->ec_family = 0; | 77 | | ctx->ec_bits = 0; | 78 | | #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ | 79 | 21.0k | } |
|
80 | | |
81 | | /* |
82 | | * Free (the components of) a mbedtls_pk_context |
83 | | */ |
84 | | void mbedtls_pk_free(mbedtls_pk_context *ctx) |
85 | 117k | { |
86 | 117k | if (ctx == NULL) { |
87 | 0 | return; |
88 | 0 | } |
89 | | |
90 | 117k | if ((ctx->pk_info != NULL) && (ctx->pk_info->ctx_free_func != NULL)) { |
91 | 39.3k | ctx->pk_info->ctx_free_func(ctx->pk_ctx); |
92 | 39.3k | } |
93 | | |
94 | | #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) |
95 | | /* The ownership of the priv_id key for opaque keys is external of the PK |
96 | | * module. It's the user responsibility to clear it after use. */ |
97 | | if ((ctx->pk_info != NULL) && (ctx->pk_info->type != MBEDTLS_PK_OPAQUE)) { |
98 | | psa_destroy_key(ctx->priv_id); |
99 | | } |
100 | | #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ |
101 | | |
102 | 117k | mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context)); |
103 | 117k | } |
104 | | |
105 | | #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
106 | | /* |
107 | | * Initialize a restart context |
108 | | */ |
109 | | void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx) |
110 | 21.4k | { |
111 | 21.4k | ctx->pk_info = NULL; |
112 | 21.4k | ctx->rs_ctx = NULL; |
113 | 21.4k | } |
114 | | |
115 | | /* |
116 | | * Free the components of a restart context |
117 | | */ |
118 | | void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx) |
119 | 10.7k | { |
120 | 10.7k | if (ctx == NULL || ctx->pk_info == NULL || |
121 | 10.7k | ctx->pk_info->rs_free_func == NULL) { |
122 | 10.7k | return; |
123 | 10.7k | } |
124 | | |
125 | 0 | ctx->pk_info->rs_free_func(ctx->rs_ctx); |
126 | |
|
127 | 0 | ctx->pk_info = NULL; |
128 | 0 | ctx->rs_ctx = NULL; |
129 | 0 | } |
130 | | #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
131 | | |
132 | | /* |
133 | | * Get pk_info structure from type |
134 | | */ |
135 | | const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type) |
136 | 39.3k | { |
137 | 39.3k | switch (pk_type) { |
138 | 0 | #if defined(MBEDTLS_RSA_C) |
139 | 11.6k | case MBEDTLS_PK_RSA: |
140 | 11.6k | return &mbedtls_rsa_info; |
141 | 0 | #endif /* MBEDTLS_RSA_C */ |
142 | 0 | #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) |
143 | 27.4k | case MBEDTLS_PK_ECKEY: |
144 | 27.4k | return &mbedtls_eckey_info; |
145 | 196 | case MBEDTLS_PK_ECKEY_DH: |
146 | 196 | return &mbedtls_eckeydh_info; |
147 | 0 | #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ |
148 | 0 | #if defined(MBEDTLS_PK_CAN_ECDSA_SOME) |
149 | 0 | case MBEDTLS_PK_ECDSA: |
150 | 0 | return &mbedtls_ecdsa_info; |
151 | 0 | #endif /* MBEDTLS_PK_CAN_ECDSA_SOME */ |
152 | | /* MBEDTLS_PK_RSA_ALT omitted on purpose */ |
153 | 0 | default: |
154 | 0 | return NULL; |
155 | 39.3k | } |
156 | 39.3k | } |
157 | | |
158 | | /* |
159 | | * Initialise context |
160 | | */ |
161 | | int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info) |
162 | 39.3k | { |
163 | 39.3k | if (info == NULL || ctx->pk_info != NULL) { |
164 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
165 | 0 | } |
166 | | |
167 | 39.3k | if ((info->ctx_alloc_func != NULL) && |
168 | 39.3k | ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)) { |
169 | 0 | return MBEDTLS_ERR_PK_ALLOC_FAILED; |
170 | 0 | } |
171 | | |
172 | 39.3k | ctx->pk_info = info; |
173 | | |
174 | 39.3k | return 0; |
175 | 39.3k | } |
176 | | |
177 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
178 | | /* |
179 | | * Initialise a PSA-wrapping context |
180 | | */ |
181 | | int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, |
182 | | const mbedtls_svc_key_id_t key) |
183 | 0 | { |
184 | 0 | const mbedtls_pk_info_t *info = NULL; |
185 | 0 | psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
186 | 0 | psa_key_type_t type; |
187 | |
|
188 | 0 | if (ctx == NULL || ctx->pk_info != NULL) { |
189 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
190 | 0 | } |
191 | | |
192 | 0 | if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) { |
193 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
194 | 0 | } |
195 | 0 | type = psa_get_key_type(&attributes); |
196 | 0 | psa_reset_key_attributes(&attributes); |
197 | |
|
198 | 0 | #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) |
199 | 0 | if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { |
200 | 0 | info = &mbedtls_ecdsa_opaque_info; |
201 | 0 | } else |
202 | 0 | #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ |
203 | 0 | if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { |
204 | 0 | info = &mbedtls_rsa_opaque_info; |
205 | 0 | } else { |
206 | 0 | return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; |
207 | 0 | } |
208 | | |
209 | 0 | ctx->pk_info = info; |
210 | 0 | ctx->priv_id = key; |
211 | |
|
212 | 0 | return 0; |
213 | 0 | } |
214 | | #endif /* MBEDTLS_USE_PSA_CRYPTO */ |
215 | | |
216 | | #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
217 | | /* |
218 | | * Initialize an RSA-alt context |
219 | | */ |
220 | | int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key, |
221 | | mbedtls_pk_rsa_alt_decrypt_func decrypt_func, |
222 | | mbedtls_pk_rsa_alt_sign_func sign_func, |
223 | | mbedtls_pk_rsa_alt_key_len_func key_len_func) |
224 | 0 | { |
225 | 0 | mbedtls_rsa_alt_context *rsa_alt; |
226 | 0 | const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; |
227 | |
|
228 | 0 | if (ctx->pk_info != NULL) { |
229 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
230 | 0 | } |
231 | | |
232 | 0 | if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) { |
233 | 0 | return MBEDTLS_ERR_PK_ALLOC_FAILED; |
234 | 0 | } |
235 | | |
236 | 0 | ctx->pk_info = info; |
237 | |
|
238 | 0 | rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx; |
239 | |
|
240 | 0 | rsa_alt->key = key; |
241 | 0 | rsa_alt->decrypt_func = decrypt_func; |
242 | 0 | rsa_alt->sign_func = sign_func; |
243 | 0 | rsa_alt->key_len_func = key_len_func; |
244 | |
|
245 | 0 | return 0; |
246 | 0 | } |
247 | | #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ |
248 | | |
249 | | /* |
250 | | * Tell if a PK can do the operations of the given type |
251 | | */ |
252 | | int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type) |
253 | 4.57k | { |
254 | | /* A context with null pk_info is not set up yet and can't do anything. |
255 | | * For backward compatibility, also accept NULL instead of a context |
256 | | * pointer. */ |
257 | 4.57k | if (ctx == NULL || ctx->pk_info == NULL) { |
258 | 3.37k | return 0; |
259 | 3.37k | } |
260 | | |
261 | 1.19k | return ctx->pk_info->can_do(type); |
262 | 4.57k | } |
263 | | |
264 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
265 | | /* |
266 | | * Tell if a PK can do the operations of the given PSA algorithm |
267 | | */ |
268 | | int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, |
269 | | psa_key_usage_t usage) |
270 | 0 | { |
271 | 0 | psa_key_usage_t key_usage; |
272 | | |
273 | | /* A context with null pk_info is not set up yet and can't do anything. |
274 | | * For backward compatibility, also accept NULL instead of a context |
275 | | * pointer. */ |
276 | 0 | if (ctx == NULL || ctx->pk_info == NULL) { |
277 | 0 | return 0; |
278 | 0 | } |
279 | | |
280 | | /* Filter out non allowed algorithms */ |
281 | 0 | if (PSA_ALG_IS_ECDSA(alg) == 0 && |
282 | 0 | PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) == 0 && |
283 | 0 | PSA_ALG_IS_RSA_PSS(alg) == 0 && |
284 | 0 | alg != PSA_ALG_RSA_PKCS1V15_CRYPT && |
285 | 0 | PSA_ALG_IS_ECDH(alg) == 0) { |
286 | 0 | return 0; |
287 | 0 | } |
288 | | |
289 | | /* Filter out non allowed usage flags */ |
290 | 0 | if (usage == 0 || |
291 | 0 | (usage & ~(PSA_KEY_USAGE_SIGN_HASH | |
292 | 0 | PSA_KEY_USAGE_DECRYPT | |
293 | 0 | PSA_KEY_USAGE_DERIVE)) != 0) { |
294 | 0 | return 0; |
295 | 0 | } |
296 | | |
297 | | /* Wildcard hash is not allowed */ |
298 | 0 | if (PSA_ALG_IS_SIGN_HASH(alg) && |
299 | 0 | PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH) { |
300 | 0 | return 0; |
301 | 0 | } |
302 | | |
303 | 0 | if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_OPAQUE) { |
304 | 0 | mbedtls_pk_type_t type; |
305 | |
|
306 | 0 | if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_ECDH(alg)) { |
307 | 0 | type = MBEDTLS_PK_ECKEY; |
308 | 0 | } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || |
309 | 0 | alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { |
310 | 0 | type = MBEDTLS_PK_RSA; |
311 | 0 | } else if (PSA_ALG_IS_RSA_PSS(alg)) { |
312 | 0 | type = MBEDTLS_PK_RSASSA_PSS; |
313 | 0 | } else { |
314 | 0 | return 0; |
315 | 0 | } |
316 | | |
317 | 0 | if (ctx->pk_info->can_do(type) == 0) { |
318 | 0 | return 0; |
319 | 0 | } |
320 | | |
321 | 0 | switch (type) { |
322 | 0 | case MBEDTLS_PK_ECKEY: |
323 | 0 | key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE; |
324 | 0 | break; |
325 | 0 | case MBEDTLS_PK_RSA: |
326 | 0 | case MBEDTLS_PK_RSASSA_PSS: |
327 | 0 | key_usage = PSA_KEY_USAGE_SIGN_HASH | |
328 | 0 | PSA_KEY_USAGE_SIGN_MESSAGE | |
329 | 0 | PSA_KEY_USAGE_DECRYPT; |
330 | 0 | break; |
331 | 0 | default: |
332 | | /* Should never happen */ |
333 | 0 | return 0; |
334 | 0 | } |
335 | | |
336 | 0 | return (key_usage & usage) == usage; |
337 | 0 | } |
338 | | |
339 | 0 | psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
340 | 0 | psa_status_t status; |
341 | |
|
342 | 0 | status = psa_get_key_attributes(ctx->priv_id, &attributes); |
343 | 0 | if (status != PSA_SUCCESS) { |
344 | 0 | return 0; |
345 | 0 | } |
346 | | |
347 | 0 | psa_algorithm_t key_alg = psa_get_key_algorithm(&attributes); |
348 | | /* Key's enrollment is available only when an Mbed TLS implementation of PSA |
349 | | * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. |
350 | | * Even though we don't officially support using other implementations of PSA |
351 | | * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations |
352 | | * separated. */ |
353 | 0 | #if defined(MBEDTLS_PSA_CRYPTO_C) |
354 | 0 | psa_algorithm_t key_alg2 = psa_get_key_enrollment_algorithm(&attributes); |
355 | 0 | #endif /* MBEDTLS_PSA_CRYPTO_C */ |
356 | 0 | key_usage = psa_get_key_usage_flags(&attributes); |
357 | 0 | psa_reset_key_attributes(&attributes); |
358 | |
|
359 | 0 | if ((key_usage & usage) != usage) { |
360 | 0 | return 0; |
361 | 0 | } |
362 | | |
363 | | /* |
364 | | * Common case: the key alg [or alg2] only allows alg. |
365 | | * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH |
366 | | * directly. |
367 | | * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with |
368 | | * a fixed hash on key_alg [or key_alg2]. |
369 | | */ |
370 | 0 | if (alg == key_alg) { |
371 | 0 | return 1; |
372 | 0 | } |
373 | 0 | #if defined(MBEDTLS_PSA_CRYPTO_C) |
374 | 0 | if (alg == key_alg2) { |
375 | 0 | return 1; |
376 | 0 | } |
377 | 0 | #endif /* MBEDTLS_PSA_CRYPTO_C */ |
378 | | |
379 | | /* |
380 | | * If key_alg [or key_alg2] is a hash-and-sign with a wildcard for the hash, |
381 | | * and alg is the same hash-and-sign family with any hash, |
382 | | * then alg is compliant with this key alg |
383 | | */ |
384 | 0 | if (PSA_ALG_IS_SIGN_HASH(alg)) { |
385 | 0 | if (PSA_ALG_IS_SIGN_HASH(key_alg) && |
386 | 0 | PSA_ALG_SIGN_GET_HASH(key_alg) == PSA_ALG_ANY_HASH && |
387 | 0 | (alg & ~PSA_ALG_HASH_MASK) == (key_alg & ~PSA_ALG_HASH_MASK)) { |
388 | 0 | return 1; |
389 | 0 | } |
390 | 0 | #if defined(MBEDTLS_PSA_CRYPTO_C) |
391 | 0 | if (PSA_ALG_IS_SIGN_HASH(key_alg2) && |
392 | 0 | PSA_ALG_SIGN_GET_HASH(key_alg2) == PSA_ALG_ANY_HASH && |
393 | 0 | (alg & ~PSA_ALG_HASH_MASK) == (key_alg2 & ~PSA_ALG_HASH_MASK)) { |
394 | 0 | return 1; |
395 | 0 | } |
396 | 0 | #endif /* MBEDTLS_PSA_CRYPTO_C */ |
397 | 0 | } |
398 | | |
399 | 0 | return 0; |
400 | 0 | } |
401 | | #endif /* MBEDTLS_USE_PSA_CRYPTO */ |
402 | | |
403 | | #if defined(MBEDTLS_PSA_CRYPTO_CLIENT) |
404 | | #if defined(MBEDTLS_RSA_C) |
405 | | static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa, |
406 | | int want_crypt) |
407 | 0 | { |
408 | 0 | if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) { |
409 | 0 | if (want_crypt) { |
410 | 0 | mbedtls_md_type_t md_type = (mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa); |
411 | 0 | return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type)); |
412 | 0 | } else { |
413 | 0 | return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH); |
414 | 0 | } |
415 | 0 | } else { |
416 | 0 | if (want_crypt) { |
417 | 0 | return PSA_ALG_RSA_PKCS1V15_CRYPT; |
418 | 0 | } else { |
419 | 0 | return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH); |
420 | 0 | } |
421 | 0 | } |
422 | 0 | } |
423 | | #endif /* MBEDTLS_RSA_C */ |
424 | | |
425 | | int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, |
426 | | psa_key_usage_t usage, |
427 | | psa_key_attributes_t *attributes) |
428 | 0 | { |
429 | 0 | mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk); |
430 | |
|
431 | 0 | psa_key_usage_t more_usage = usage; |
432 | 0 | if (usage == PSA_KEY_USAGE_SIGN_MESSAGE) { |
433 | 0 | more_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE; |
434 | 0 | } else if (usage == PSA_KEY_USAGE_SIGN_HASH) { |
435 | 0 | more_usage |= PSA_KEY_USAGE_VERIFY_HASH; |
436 | 0 | } else if (usage == PSA_KEY_USAGE_DECRYPT) { |
437 | 0 | more_usage |= PSA_KEY_USAGE_ENCRYPT; |
438 | 0 | } |
439 | 0 | more_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY; |
440 | |
|
441 | 0 | int want_private = !(usage == PSA_KEY_USAGE_VERIFY_MESSAGE || |
442 | 0 | usage == PSA_KEY_USAGE_VERIFY_HASH || |
443 | 0 | usage == PSA_KEY_USAGE_ENCRYPT); |
444 | |
|
445 | 0 | switch (pk_type) { |
446 | 0 | #if defined(MBEDTLS_RSA_C) |
447 | 0 | case MBEDTLS_PK_RSA: |
448 | 0 | { |
449 | 0 | int want_crypt = 0; /* 0: sign/verify; 1: encrypt/decrypt */ |
450 | 0 | switch (usage) { |
451 | 0 | case PSA_KEY_USAGE_SIGN_MESSAGE: |
452 | 0 | case PSA_KEY_USAGE_SIGN_HASH: |
453 | 0 | case PSA_KEY_USAGE_VERIFY_MESSAGE: |
454 | 0 | case PSA_KEY_USAGE_VERIFY_HASH: |
455 | | /* Nothing to do. */ |
456 | 0 | break; |
457 | 0 | case PSA_KEY_USAGE_DECRYPT: |
458 | 0 | case PSA_KEY_USAGE_ENCRYPT: |
459 | 0 | want_crypt = 1; |
460 | 0 | break; |
461 | 0 | default: |
462 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
463 | 0 | } |
464 | | /* Detect the presence of a private key in a way that works both |
465 | | * in CRT and non-CRT configurations. */ |
466 | 0 | mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk); |
467 | 0 | int has_private = (mbedtls_rsa_check_privkey(rsa) == 0); |
468 | 0 | if (want_private && !has_private) { |
469 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
470 | 0 | } |
471 | 0 | psa_set_key_type(attributes, (want_private ? |
472 | 0 | PSA_KEY_TYPE_RSA_KEY_PAIR : |
473 | 0 | PSA_KEY_TYPE_RSA_PUBLIC_KEY)); |
474 | 0 | psa_set_key_bits(attributes, mbedtls_pk_get_bitlen(pk)); |
475 | 0 | psa_set_key_algorithm(attributes, |
476 | 0 | psa_algorithm_for_rsa(rsa, want_crypt)); |
477 | 0 | break; |
478 | 0 | } |
479 | 0 | #endif /* MBEDTLS_RSA_C */ |
480 | | |
481 | 0 | #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) |
482 | 0 | case MBEDTLS_PK_ECKEY: |
483 | 0 | case MBEDTLS_PK_ECKEY_DH: |
484 | 0 | case MBEDTLS_PK_ECDSA: |
485 | 0 | { |
486 | 0 | int sign_ok = (pk_type != MBEDTLS_PK_ECKEY_DH); |
487 | 0 | int derive_ok = (pk_type != MBEDTLS_PK_ECDSA); |
488 | | #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) |
489 | | psa_ecc_family_t family = pk->ec_family; |
490 | | size_t bits = pk->ec_bits; |
491 | | int has_private = 0; |
492 | | if (pk->priv_id != MBEDTLS_SVC_KEY_ID_INIT) { |
493 | | has_private = 1; |
494 | | } |
495 | | #else |
496 | 0 | const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); |
497 | 0 | int has_private = (ec->d.n != 0); |
498 | 0 | size_t bits = 0; |
499 | 0 | psa_ecc_family_t family = |
500 | 0 | mbedtls_ecc_group_to_psa(ec->grp.id, &bits); |
501 | 0 | #endif |
502 | 0 | psa_algorithm_t alg = 0; |
503 | 0 | switch (usage) { |
504 | 0 | case PSA_KEY_USAGE_SIGN_MESSAGE: |
505 | 0 | case PSA_KEY_USAGE_SIGN_HASH: |
506 | 0 | case PSA_KEY_USAGE_VERIFY_MESSAGE: |
507 | 0 | case PSA_KEY_USAGE_VERIFY_HASH: |
508 | 0 | if (!sign_ok) { |
509 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
510 | 0 | } |
511 | 0 | #if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
512 | 0 | alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH); |
513 | | #else |
514 | | alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH); |
515 | | #endif |
516 | 0 | break; |
517 | 0 | case PSA_KEY_USAGE_DERIVE: |
518 | 0 | alg = PSA_ALG_ECDH; |
519 | 0 | if (!derive_ok) { |
520 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
521 | 0 | } |
522 | 0 | break; |
523 | 0 | default: |
524 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
525 | 0 | } |
526 | 0 | if (want_private && !has_private) { |
527 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
528 | 0 | } |
529 | 0 | psa_set_key_type(attributes, (want_private ? |
530 | 0 | PSA_KEY_TYPE_ECC_KEY_PAIR(family) : |
531 | 0 | PSA_KEY_TYPE_ECC_PUBLIC_KEY(family))); |
532 | 0 | psa_set_key_bits(attributes, bits); |
533 | 0 | psa_set_key_algorithm(attributes, alg); |
534 | 0 | break; |
535 | 0 | } |
536 | 0 | #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ |
537 | | |
538 | 0 | #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
539 | 0 | case MBEDTLS_PK_RSA_ALT: |
540 | 0 | return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; |
541 | 0 | #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ |
542 | | |
543 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
544 | 0 | case MBEDTLS_PK_OPAQUE: |
545 | 0 | { |
546 | 0 | psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; |
547 | 0 | psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; |
548 | 0 | status = psa_get_key_attributes(pk->priv_id, &old_attributes); |
549 | 0 | if (status != PSA_SUCCESS) { |
550 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
551 | 0 | } |
552 | 0 | psa_key_type_t old_type = psa_get_key_type(&old_attributes); |
553 | 0 | switch (usage) { |
554 | 0 | case PSA_KEY_USAGE_SIGN_MESSAGE: |
555 | 0 | case PSA_KEY_USAGE_SIGN_HASH: |
556 | 0 | case PSA_KEY_USAGE_VERIFY_MESSAGE: |
557 | 0 | case PSA_KEY_USAGE_VERIFY_HASH: |
558 | 0 | if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type) || |
559 | 0 | old_type == PSA_KEY_TYPE_RSA_KEY_PAIR)) { |
560 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
561 | 0 | } |
562 | 0 | break; |
563 | 0 | case PSA_KEY_USAGE_DECRYPT: |
564 | 0 | case PSA_KEY_USAGE_ENCRYPT: |
565 | 0 | if (old_type != PSA_KEY_TYPE_RSA_KEY_PAIR) { |
566 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
567 | 0 | } |
568 | 0 | break; |
569 | 0 | case PSA_KEY_USAGE_DERIVE: |
570 | 0 | if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type))) { |
571 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
572 | 0 | } |
573 | 0 | break; |
574 | 0 | default: |
575 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
576 | 0 | } |
577 | 0 | psa_key_type_t new_type = old_type; |
578 | | /* Opaque keys are always key pairs, so we don't need a check |
579 | | * on the input if the required usage is private. We just need |
580 | | * to adjust the type correctly if the required usage is public. */ |
581 | 0 | if (!want_private) { |
582 | 0 | new_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(new_type); |
583 | 0 | } |
584 | 0 | more_usage = psa_get_key_usage_flags(&old_attributes); |
585 | 0 | if ((usage & more_usage) == 0) { |
586 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
587 | 0 | } |
588 | 0 | psa_set_key_type(attributes, new_type); |
589 | 0 | psa_set_key_bits(attributes, psa_get_key_bits(&old_attributes)); |
590 | 0 | psa_set_key_algorithm(attributes, psa_get_key_algorithm(&old_attributes)); |
591 | 0 | break; |
592 | 0 | } |
593 | 0 | #endif /* MBEDTLS_USE_PSA_CRYPTO */ |
594 | | |
595 | 0 | default: |
596 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
597 | 0 | } |
598 | | |
599 | 0 | psa_set_key_usage_flags(attributes, more_usage); |
600 | | /* Key's enrollment is available only when an Mbed TLS implementation of PSA |
601 | | * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. |
602 | | * Even though we don't officially support using other implementations of PSA |
603 | | * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations |
604 | | * separated. */ |
605 | 0 | #if defined(MBEDTLS_PSA_CRYPTO_C) |
606 | 0 | psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE); |
607 | 0 | #endif |
608 | |
|
609 | 0 | return 0; |
610 | 0 | } Unexecuted instantiation: mbedtls_pk_get_psa_attributes Unexecuted instantiation: mbedtls_pk_get_psa_attributes |
611 | | |
612 | | #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_USE_PSA_CRYPTO) |
613 | | static psa_status_t export_import_into_psa(mbedtls_svc_key_id_t old_key_id, |
614 | | psa_key_type_t old_type, size_t old_bits, |
615 | | const psa_key_attributes_t *attributes, |
616 | | mbedtls_svc_key_id_t *new_key_id) |
617 | 0 | { |
618 | 0 | #if !defined(PK_EXPORT_KEYS_ON_THE_STACK) |
619 | 0 | unsigned char *key_buffer = NULL; |
620 | 0 | size_t key_buffer_size = 0; |
621 | | #else |
622 | | unsigned char key_buffer[PK_EXPORT_KEY_STACK_BUFFER_SIZE]; |
623 | | const size_t key_buffer_size = sizeof(key_buffer); |
624 | | #endif |
625 | 0 | size_t key_length = 0; |
626 | | |
627 | | /* We are exporting from a PK object, so we know key type is valid for PK */ |
628 | 0 | #if !defined(PK_EXPORT_KEYS_ON_THE_STACK) |
629 | 0 | key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(old_type, old_bits); |
630 | 0 | key_buffer = mbedtls_calloc(1, key_buffer_size); |
631 | 0 | if (key_buffer == NULL) { |
632 | 0 | return MBEDTLS_ERR_PK_ALLOC_FAILED; |
633 | 0 | } |
634 | | #else |
635 | | (void) old_type; |
636 | | (void) old_bits; |
637 | | #endif |
638 | | |
639 | 0 | psa_status_t status = psa_export_key(old_key_id, |
640 | 0 | key_buffer, key_buffer_size, |
641 | 0 | &key_length); |
642 | 0 | if (status != PSA_SUCCESS) { |
643 | 0 | goto cleanup; |
644 | 0 | } |
645 | 0 | status = psa_import_key(attributes, key_buffer, key_length, new_key_id); |
646 | 0 | mbedtls_platform_zeroize(key_buffer, key_length); |
647 | |
|
648 | 0 | cleanup: |
649 | 0 | #if !defined(PK_EXPORT_KEYS_ON_THE_STACK) |
650 | 0 | mbedtls_free(key_buffer); |
651 | 0 | #endif |
652 | 0 | return status; |
653 | 0 | } |
654 | | |
655 | | static int copy_into_psa(mbedtls_svc_key_id_t old_key_id, |
656 | | const psa_key_attributes_t *attributes, |
657 | | mbedtls_svc_key_id_t *new_key_id) |
658 | 0 | { |
659 | | /* Normally, we prefer copying: it's more efficient and works even |
660 | | * for non-exportable keys. */ |
661 | 0 | psa_status_t status = psa_copy_key(old_key_id, attributes, new_key_id); |
662 | 0 | if (status == PSA_ERROR_NOT_PERMITTED /*missing COPY usage*/ || |
663 | 0 | status == PSA_ERROR_INVALID_ARGUMENT /*incompatible policy*/) { |
664 | | /* There are edge cases where copying won't work, but export+import |
665 | | * might: |
666 | | * - If the old key does not allow PSA_KEY_USAGE_COPY. |
667 | | * - If the old key's usage does not allow what attributes wants. |
668 | | * Because the key was intended for use in the pk module, and may |
669 | | * have had a policy chosen solely for what pk needs rather than |
670 | | * based on a detailed understanding of PSA policies, we are a bit |
671 | | * more liberal than psa_copy_key() here. |
672 | | */ |
673 | | /* Here we need to check that the types match, otherwise we risk |
674 | | * importing nonsensical data. */ |
675 | 0 | psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; |
676 | 0 | status = psa_get_key_attributes(old_key_id, &old_attributes); |
677 | 0 | if (status != PSA_SUCCESS) { |
678 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
679 | 0 | } |
680 | 0 | psa_key_type_t old_type = psa_get_key_type(&old_attributes); |
681 | 0 | size_t old_bits = psa_get_key_bits(&old_attributes); |
682 | 0 | psa_reset_key_attributes(&old_attributes); |
683 | 0 | if (old_type != psa_get_key_type(attributes)) { |
684 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
685 | 0 | } |
686 | 0 | status = export_import_into_psa(old_key_id, old_type, old_bits, |
687 | 0 | attributes, new_key_id); |
688 | 0 | } |
689 | 0 | return PSA_PK_TO_MBEDTLS_ERR(status); |
690 | 0 | } |
691 | | #endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_USE_PSA_CRYPTO */ |
692 | | |
693 | | static int import_pair_into_psa(const mbedtls_pk_context *pk, |
694 | | const psa_key_attributes_t *attributes, |
695 | | mbedtls_svc_key_id_t *key_id) |
696 | 0 | { |
697 | 0 | switch (mbedtls_pk_get_type(pk)) { |
698 | 0 | #if defined(MBEDTLS_RSA_C) |
699 | 0 | case MBEDTLS_PK_RSA: |
700 | 0 | { |
701 | 0 | if (psa_get_key_type(attributes) != PSA_KEY_TYPE_RSA_KEY_PAIR) { |
702 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
703 | 0 | } |
704 | 0 | size_t key_bits = psa_get_key_bits(attributes); |
705 | 0 | size_t key_buffer_size = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits); |
706 | 0 | unsigned char *key_buffer = mbedtls_calloc(1, key_buffer_size); |
707 | 0 | if (key_buffer == NULL) { |
708 | 0 | return MBEDTLS_ERR_PK_ALLOC_FAILED; |
709 | 0 | } |
710 | 0 | unsigned char *const key_end = key_buffer + key_buffer_size; |
711 | 0 | unsigned char *key_data = key_end; |
712 | 0 | int ret = mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), |
713 | 0 | key_buffer, &key_data); |
714 | 0 | if (ret < 0) { |
715 | 0 | goto cleanup_rsa; |
716 | 0 | } |
717 | 0 | size_t key_length = key_end - key_data; |
718 | 0 | ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, |
719 | 0 | key_data, key_length, |
720 | 0 | key_id)); |
721 | 0 | cleanup_rsa: |
722 | 0 | mbedtls_zeroize_and_free(key_buffer, key_buffer_size); |
723 | 0 | return ret; |
724 | 0 | } |
725 | 0 | #endif /* MBEDTLS_RSA_C */ |
726 | | |
727 | 0 | #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) |
728 | 0 | case MBEDTLS_PK_ECKEY: |
729 | 0 | case MBEDTLS_PK_ECKEY_DH: |
730 | 0 | case MBEDTLS_PK_ECDSA: |
731 | 0 | { |
732 | | /* We need to check the curve family, otherwise the import could |
733 | | * succeed with nonsensical data. |
734 | | * We don't check the bit-size: it's optional in attributes, |
735 | | * and if it's specified, psa_import_key() will know from the key |
736 | | * data length and will check that the bit-size matches. */ |
737 | 0 | psa_key_type_t to_type = psa_get_key_type(attributes); |
738 | | #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) |
739 | | psa_ecc_family_t from_family = pk->ec_family; |
740 | | #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ |
741 | 0 | const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); |
742 | 0 | size_t from_bits = 0; |
743 | 0 | psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, |
744 | 0 | &from_bits); |
745 | 0 | #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ |
746 | 0 | if (to_type != PSA_KEY_TYPE_ECC_KEY_PAIR(from_family)) { |
747 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
748 | 0 | } |
749 | | |
750 | | #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) |
751 | | if (mbedtls_svc_key_id_is_null(pk->priv_id)) { |
752 | | /* We have a public key and want a key pair. */ |
753 | | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
754 | | } |
755 | | return copy_into_psa(pk->priv_id, attributes, key_id); |
756 | | #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ |
757 | 0 | if (ec->d.n == 0) { |
758 | | /* Private key not set. Assume the input is a public key only. |
759 | | * (The other possibility is that it's an incomplete object |
760 | | * where the group is set but neither the public key nor |
761 | | * the private key. This is not possible through ecp.h |
762 | | * functions, so we don't bother reporting a more suitable |
763 | | * error in that case.) */ |
764 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
765 | 0 | } |
766 | 0 | unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; |
767 | 0 | size_t key_length = 0; |
768 | 0 | int ret = mbedtls_ecp_write_key_ext(ec, &key_length, |
769 | 0 | key_buffer, sizeof(key_buffer)); |
770 | 0 | if (ret < 0) { |
771 | 0 | return ret; |
772 | 0 | } |
773 | 0 | ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, |
774 | 0 | key_buffer, key_length, |
775 | 0 | key_id)); |
776 | 0 | mbedtls_platform_zeroize(key_buffer, key_length); |
777 | 0 | return ret; |
778 | 0 | #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ |
779 | 0 | } |
780 | 0 | #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ |
781 | | |
782 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
783 | | case MBEDTLS_PK_OPAQUE: |
784 | | return copy_into_psa(pk->priv_id, attributes, key_id); |
785 | | #endif /* MBEDTLS_USE_PSA_CRYPTO */ |
786 | | |
787 | 0 | default: |
788 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
789 | 0 | } |
790 | 0 | } |
791 | | |
792 | | static int import_public_into_psa(const mbedtls_pk_context *pk, |
793 | | const psa_key_attributes_t *attributes, |
794 | | mbedtls_svc_key_id_t *key_id) |
795 | 0 | { |
796 | 0 | psa_key_type_t psa_type = psa_get_key_type(attributes); |
797 | |
|
798 | 0 | #if defined(MBEDTLS_RSA_C) || \ |
799 | 0 | (defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)) || \ |
800 | 0 | defined(MBEDTLS_USE_PSA_CRYPTO) |
801 | 0 | unsigned char key_buffer[MBEDTLS_PK_MAX_PUBKEY_RAW_LEN]; |
802 | 0 | #endif |
803 | 0 | unsigned char *key_data = NULL; |
804 | 0 | size_t key_length = 0; |
805 | |
|
806 | 0 | switch (mbedtls_pk_get_type(pk)) { |
807 | 0 | #if defined(MBEDTLS_RSA_C) |
808 | 0 | case MBEDTLS_PK_RSA: |
809 | 0 | { |
810 | 0 | if (psa_type != PSA_KEY_TYPE_RSA_PUBLIC_KEY) { |
811 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
812 | 0 | } |
813 | 0 | unsigned char *const key_end = key_buffer + sizeof(key_buffer); |
814 | 0 | key_data = key_end; |
815 | 0 | int ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*pk), |
816 | 0 | key_buffer, &key_data); |
817 | 0 | if (ret < 0) { |
818 | 0 | return ret; |
819 | 0 | } |
820 | 0 | key_length = (size_t) ret; |
821 | 0 | break; |
822 | 0 | } |
823 | 0 | #endif /*MBEDTLS_RSA_C */ |
824 | | |
825 | 0 | #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) |
826 | 0 | case MBEDTLS_PK_ECKEY: |
827 | 0 | case MBEDTLS_PK_ECKEY_DH: |
828 | 0 | case MBEDTLS_PK_ECDSA: |
829 | 0 | { |
830 | | /* We need to check the curve family, otherwise the import could |
831 | | * succeed with nonsensical data. |
832 | | * We don't check the bit-size: it's optional in attributes, |
833 | | * and if it's specified, psa_import_key() will know from the key |
834 | | * data length and will check that the bit-size matches. */ |
835 | | #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) |
836 | | if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)) { |
837 | | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
838 | | } |
839 | | key_data = (unsigned char *) pk->pub_raw; |
840 | | key_length = pk->pub_raw_len; |
841 | | #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ |
842 | 0 | const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); |
843 | 0 | size_t from_bits = 0; |
844 | 0 | psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, |
845 | 0 | &from_bits); |
846 | 0 | if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(from_family)) { |
847 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
848 | 0 | } |
849 | 0 | int ret = mbedtls_ecp_write_public_key( |
850 | 0 | ec, MBEDTLS_ECP_PF_UNCOMPRESSED, |
851 | 0 | &key_length, key_buffer, sizeof(key_buffer)); |
852 | 0 | if (ret < 0) { |
853 | 0 | return ret; |
854 | 0 | } |
855 | 0 | key_data = key_buffer; |
856 | 0 | #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ |
857 | 0 | break; |
858 | 0 | } |
859 | 0 | #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ |
860 | | |
861 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
862 | 0 | case MBEDTLS_PK_OPAQUE: |
863 | 0 | { |
864 | 0 | psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; |
865 | 0 | psa_status_t status = |
866 | 0 | psa_get_key_attributes(pk->priv_id, &old_attributes); |
867 | 0 | if (status != PSA_SUCCESS) { |
868 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
869 | 0 | } |
870 | 0 | psa_key_type_t old_type = psa_get_key_type(&old_attributes); |
871 | 0 | psa_reset_key_attributes(&old_attributes); |
872 | 0 | if (psa_type != PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(old_type)) { |
873 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
874 | 0 | } |
875 | 0 | status = psa_export_public_key(pk->priv_id, |
876 | 0 | key_buffer, sizeof(key_buffer), |
877 | 0 | &key_length); |
878 | 0 | if (status != PSA_SUCCESS) { |
879 | 0 | return PSA_PK_TO_MBEDTLS_ERR(status); |
880 | 0 | } |
881 | 0 | key_data = key_buffer; |
882 | 0 | break; |
883 | 0 | } |
884 | 0 | #endif /* MBEDTLS_USE_PSA_CRYPTO */ |
885 | | |
886 | 0 | default: |
887 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
888 | 0 | } |
889 | | |
890 | 0 | return PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, |
891 | 0 | key_data, key_length, |
892 | 0 | key_id)); |
893 | 0 | } Unexecuted instantiation: pk.c:import_public_into_psa Unexecuted instantiation: pk.c:import_public_into_psa |
894 | | |
895 | | int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, |
896 | | const psa_key_attributes_t *attributes, |
897 | | mbedtls_svc_key_id_t *key_id) |
898 | 0 | { |
899 | | /* Set the output immediately so that it won't contain garbage even |
900 | | * if we error out before calling psa_import_key(). */ |
901 | 0 | *key_id = MBEDTLS_SVC_KEY_ID_INIT; |
902 | |
|
903 | 0 | #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
904 | 0 | if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA_ALT) { |
905 | 0 | return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; |
906 | 0 | } |
907 | 0 | #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ |
908 | | |
909 | 0 | int want_public = PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(attributes)); |
910 | 0 | if (want_public) { |
911 | 0 | return import_public_into_psa(pk, attributes, key_id); |
912 | 0 | } else { |
913 | 0 | return import_pair_into_psa(pk, attributes, key_id); |
914 | 0 | } |
915 | 0 | } |
916 | | |
917 | | static int is_valid_for_pk(psa_key_type_t key_type) |
918 | 0 | { |
919 | 0 | #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) |
920 | 0 | if (PSA_KEY_TYPE_IS_ECC(key_type)) { |
921 | 0 | return 1; |
922 | 0 | } |
923 | 0 | #endif |
924 | 0 | #if defined(MBEDTLS_RSA_C) |
925 | 0 | if (PSA_KEY_TYPE_IS_RSA(key_type)) { |
926 | 0 | return 1; |
927 | 0 | } |
928 | 0 | #endif |
929 | 0 | return 0; |
930 | 0 | } |
931 | | |
932 | | static int copy_from_psa(mbedtls_svc_key_id_t key_id, |
933 | | mbedtls_pk_context *pk, |
934 | | int public_only) |
935 | 0 | { |
936 | 0 | psa_status_t status; |
937 | 0 | psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; |
938 | 0 | psa_key_type_t key_type; |
939 | 0 | size_t key_bits; |
940 | 0 | #if !defined(PK_EXPORT_KEYS_ON_THE_STACK) |
941 | 0 | unsigned char *exp_key = NULL; |
942 | 0 | size_t exp_key_size = 0; |
943 | | #else |
944 | | unsigned char exp_key[PK_EXPORT_KEY_STACK_BUFFER_SIZE]; |
945 | | const size_t exp_key_size = sizeof(exp_key); |
946 | | #endif |
947 | 0 | size_t exp_key_len; |
948 | 0 | int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
949 | |
|
950 | 0 | if (pk == NULL) { |
951 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
952 | 0 | } |
953 | | |
954 | 0 | status = psa_get_key_attributes(key_id, &key_attr); |
955 | 0 | if (status != PSA_SUCCESS) { |
956 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
957 | 0 | } |
958 | | |
959 | 0 | key_type = psa_get_key_type(&key_attr); |
960 | 0 | if (!is_valid_for_pk(key_type)) { |
961 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
962 | 0 | } |
963 | | |
964 | 0 | if (public_only) { |
965 | 0 | key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); |
966 | 0 | } |
967 | 0 | key_bits = psa_get_key_bits(&key_attr); |
968 | |
|
969 | 0 | #if !defined(PK_EXPORT_KEYS_ON_THE_STACK) |
970 | 0 | exp_key_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits); |
971 | 0 | exp_key = mbedtls_calloc(1, exp_key_size); |
972 | 0 | if (exp_key == NULL) { |
973 | 0 | return MBEDTLS_ERR_PK_ALLOC_FAILED; |
974 | 0 | } |
975 | 0 | #endif |
976 | | |
977 | 0 | if (public_only) { |
978 | 0 | status = psa_export_public_key(key_id, exp_key, exp_key_size, &exp_key_len); |
979 | 0 | } else { |
980 | 0 | status = psa_export_key(key_id, exp_key, exp_key_size, &exp_key_len); |
981 | 0 | } |
982 | 0 | if (status != PSA_SUCCESS) { |
983 | 0 | ret = PSA_PK_TO_MBEDTLS_ERR(status); |
984 | 0 | goto exit; |
985 | 0 | } |
986 | | |
987 | 0 | key_type = psa_get_key_type(&key_attr); |
988 | 0 | if (public_only) { |
989 | 0 | key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); |
990 | 0 | } |
991 | 0 | key_bits = psa_get_key_bits(&key_attr); |
992 | |
|
993 | 0 | #if defined(MBEDTLS_RSA_C) |
994 | 0 | if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) || |
995 | 0 | (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) { |
996 | |
|
997 | 0 | ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); |
998 | 0 | if (ret != 0) { |
999 | 0 | goto exit; |
1000 | 0 | } |
1001 | | |
1002 | 0 | if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { |
1003 | 0 | ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); |
1004 | 0 | } else { |
1005 | 0 | ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); |
1006 | 0 | } |
1007 | 0 | if (ret != 0) { |
1008 | 0 | goto exit; |
1009 | 0 | } |
1010 | | |
1011 | 0 | psa_algorithm_t alg_type = psa_get_key_algorithm(&key_attr); |
1012 | 0 | mbedtls_md_type_t md_type = MBEDTLS_MD_NONE; |
1013 | 0 | if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) { |
1014 | 0 | md_type = mbedtls_md_type_from_psa_alg(alg_type); |
1015 | 0 | } |
1016 | |
|
1017 | 0 | if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) { |
1018 | 0 | ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type); |
1019 | 0 | } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) || |
1020 | 0 | alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) { |
1021 | 0 | ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type); |
1022 | 0 | } |
1023 | 0 | if (ret != 0) { |
1024 | 0 | goto exit; |
1025 | 0 | } |
1026 | 0 | } else |
1027 | 0 | #endif /* MBEDTLS_RSA_C */ |
1028 | 0 | #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) |
1029 | 0 | if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || |
1030 | 0 | PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) { |
1031 | 0 | mbedtls_ecp_group_id grp_id; |
1032 | |
|
1033 | 0 | ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); |
1034 | 0 | if (ret != 0) { |
1035 | 0 | goto exit; |
1036 | 0 | } |
1037 | | |
1038 | 0 | grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits); |
1039 | 0 | ret = mbedtls_pk_ecc_set_group(pk, grp_id); |
1040 | 0 | if (ret != 0) { |
1041 | 0 | goto exit; |
1042 | 0 | } |
1043 | | |
1044 | 0 | if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { |
1045 | 0 | ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len); |
1046 | 0 | if (ret != 0) { |
1047 | 0 | goto exit; |
1048 | 0 | } |
1049 | 0 | ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len, |
1050 | 0 | mbedtls_psa_get_random, |
1051 | 0 | MBEDTLS_PSA_RANDOM_STATE); |
1052 | 0 | } else { |
1053 | 0 | ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len); |
1054 | 0 | } |
1055 | 0 | if (ret != 0) { |
1056 | 0 | goto exit; |
1057 | 0 | } |
1058 | 0 | } else |
1059 | 0 | #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ |
1060 | 0 | { |
1061 | 0 | (void) key_bits; |
1062 | 0 | ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1063 | 0 | goto exit; |
1064 | 0 | } |
1065 | | |
1066 | 0 | exit: |
1067 | 0 | mbedtls_platform_zeroize(exp_key, exp_key_size); |
1068 | 0 | #if !defined(PK_EXPORT_KEYS_ON_THE_STACK) |
1069 | 0 | mbedtls_free(exp_key); |
1070 | 0 | #endif |
1071 | 0 | psa_reset_key_attributes(&key_attr); |
1072 | |
|
1073 | 0 | return ret; |
1074 | 0 | } |
1075 | | |
1076 | | int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, |
1077 | | mbedtls_pk_context *pk) |
1078 | 0 | { |
1079 | 0 | return copy_from_psa(key_id, pk, 0); |
1080 | 0 | } |
1081 | | |
1082 | | int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, |
1083 | | mbedtls_pk_context *pk) |
1084 | 0 | { |
1085 | 0 | return copy_from_psa(key_id, pk, 1); |
1086 | 0 | } |
1087 | | #endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ |
1088 | | |
1089 | | /* |
1090 | | * Helper for mbedtls_pk_sign and mbedtls_pk_verify |
1091 | | */ |
1092 | | static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len) |
1093 | 152 | { |
1094 | 152 | if (*hash_len != 0) { |
1095 | 152 | return 0; |
1096 | 152 | } |
1097 | | |
1098 | 0 | *hash_len = mbedtls_md_get_size_from_type(md_alg); |
1099 | |
|
1100 | 0 | if (*hash_len == 0) { |
1101 | 0 | return -1; |
1102 | 0 | } |
1103 | | |
1104 | 0 | return 0; |
1105 | 0 | } |
1106 | | |
1107 | | #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
1108 | | /* |
1109 | | * Helper to set up a restart context if needed |
1110 | | */ |
1111 | | static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx, |
1112 | | const mbedtls_pk_info_t *info) |
1113 | 0 | { |
1114 | | /* Don't do anything if already set up or invalid */ |
1115 | 0 | if (ctx == NULL || ctx->pk_info != NULL) { |
1116 | 0 | return 0; |
1117 | 0 | } |
1118 | | |
1119 | | /* Should never happen when we're called */ |
1120 | 0 | if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) { |
1121 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1122 | 0 | } |
1123 | | |
1124 | 0 | if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) { |
1125 | 0 | return MBEDTLS_ERR_PK_ALLOC_FAILED; |
1126 | 0 | } |
1127 | | |
1128 | 0 | ctx->pk_info = info; |
1129 | |
|
1130 | 0 | return 0; |
1131 | 0 | } |
1132 | | #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
1133 | | |
1134 | | /* |
1135 | | * Verify a signature (restartable) |
1136 | | */ |
1137 | | int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx, |
1138 | | mbedtls_md_type_t md_alg, |
1139 | | const unsigned char *hash, size_t hash_len, |
1140 | | const unsigned char *sig, size_t sig_len, |
1141 | | mbedtls_pk_restart_ctx *rs_ctx) |
1142 | 152 | { |
1143 | 152 | if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { |
1144 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1145 | 0 | } |
1146 | | |
1147 | 152 | if (ctx->pk_info == NULL || |
1148 | 152 | pk_hashlen_helper(md_alg, &hash_len) != 0) { |
1149 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1150 | 0 | } |
1151 | | |
1152 | 152 | #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
1153 | | /* optimization: use non-restartable version if restart disabled */ |
1154 | 152 | if (rs_ctx != NULL && |
1155 | 96 | mbedtls_ecp_restart_is_enabled() && |
1156 | 0 | ctx->pk_info->verify_rs_func != NULL) { |
1157 | 0 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
1158 | |
|
1159 | 0 | if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { |
1160 | 0 | return ret; |
1161 | 0 | } |
1162 | | |
1163 | 0 | ret = ctx->pk_info->verify_rs_func(ctx, |
1164 | 0 | md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx); |
1165 | |
|
1166 | 0 | if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { |
1167 | 0 | mbedtls_pk_restart_free(rs_ctx); |
1168 | 0 | } |
1169 | |
|
1170 | 0 | return ret; |
1171 | 0 | } |
1172 | | #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
1173 | | (void) rs_ctx; |
1174 | | #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
1175 | | |
1176 | 152 | if (ctx->pk_info->verify_func == NULL) { |
1177 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
1178 | 0 | } |
1179 | | |
1180 | 152 | return ctx->pk_info->verify_func(ctx, md_alg, hash, hash_len, |
1181 | 152 | sig, sig_len); |
1182 | 152 | } |
1183 | | |
1184 | | /* |
1185 | | * Verify a signature |
1186 | | */ |
1187 | | int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
1188 | | const unsigned char *hash, size_t hash_len, |
1189 | | const unsigned char *sig, size_t sig_len) |
1190 | 0 | { |
1191 | 0 | return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len, |
1192 | 0 | sig, sig_len, NULL); |
1193 | 0 | } |
1194 | | |
1195 | | /* |
1196 | | * Verify a signature with options |
1197 | | */ |
1198 | | int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, |
1199 | | mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
1200 | | const unsigned char *hash, size_t hash_len, |
1201 | | const unsigned char *sig, size_t sig_len) |
1202 | 0 | { |
1203 | 0 | if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { |
1204 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1205 | 0 | } |
1206 | | |
1207 | 0 | if (ctx->pk_info == NULL) { |
1208 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1209 | 0 | } |
1210 | | |
1211 | 0 | if (!mbedtls_pk_can_do(ctx, type)) { |
1212 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
1213 | 0 | } |
1214 | | |
1215 | 0 | if (type != MBEDTLS_PK_RSASSA_PSS) { |
1216 | | /* General case: no options */ |
1217 | 0 | if (options != NULL) { |
1218 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1219 | 0 | } |
1220 | | |
1221 | 0 | return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len); |
1222 | 0 | } |
1223 | | |
1224 | | /* Ensure the PK context is of the right type otherwise mbedtls_pk_rsa() |
1225 | | * below would return a NULL pointer. */ |
1226 | 0 | if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_RSA) { |
1227 | 0 | return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; |
1228 | 0 | } |
1229 | | |
1230 | 0 | #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) |
1231 | 0 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
1232 | 0 | const mbedtls_pk_rsassa_pss_options *pss_opts; |
1233 | |
|
1234 | 0 | #if SIZE_MAX > UINT_MAX |
1235 | 0 | if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { |
1236 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1237 | 0 | } |
1238 | 0 | #endif |
1239 | | |
1240 | 0 | if (options == NULL) { |
1241 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1242 | 0 | } |
1243 | | |
1244 | 0 | pss_opts = (const mbedtls_pk_rsassa_pss_options *) options; |
1245 | |
|
1246 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
1247 | 0 | if (pss_opts->mgf1_hash_id == md_alg) { |
1248 | 0 | unsigned char buf[PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; |
1249 | 0 | unsigned char *p; |
1250 | 0 | int key_len; |
1251 | 0 | size_t signature_length; |
1252 | 0 | psa_status_t status = PSA_ERROR_DATA_CORRUPT; |
1253 | 0 | psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT; |
1254 | | |
1255 | | psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); |
1256 | 0 | mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; |
1257 | 0 | psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
1258 | 0 | psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg); |
1259 | | p = buf + sizeof(buf); |
1260 | | key_len = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*ctx), buf, &p); |
1261 | | |
1262 | 0 | if (key_len < 0) { |
1263 | 0 | return key_len; |
1264 | 0 | } |
1265 | | |
1266 | 0 | psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); |
1267 | 0 | psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); |
1268 | 0 | psa_set_key_algorithm(&attributes, psa_sig_alg); |
1269 | |
|
1270 | 0 | status = psa_import_key(&attributes, |
1271 | 0 | buf + sizeof(buf) - key_len, key_len, |
1272 | 0 | &key_id); |
1273 | 0 | if (status != PSA_SUCCESS) { |
1274 | 0 | psa_destroy_key(key_id); |
1275 | 0 | return PSA_PK_TO_MBEDTLS_ERR(status); |
1276 | 0 | } |
1277 | | |
1278 | | /* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH |
1279 | | * on a valid signature with trailing data in a buffer, but |
1280 | | * mbedtls_psa_rsa_verify_hash requires the sig_len to be exact, |
1281 | | * so for this reason the passed sig_len is overwritten. Smaller |
1282 | | * signature lengths should not be accepted for verification. */ |
1283 | 0 | signature_length = sig_len > mbedtls_pk_get_len(ctx) ? |
1284 | 0 | mbedtls_pk_get_len(ctx) : sig_len; |
1285 | 0 | status = psa_verify_hash(key_id, psa_sig_alg, hash, |
1286 | 0 | hash_len, sig, signature_length); |
1287 | 0 | destruction_status = psa_destroy_key(key_id); |
1288 | |
|
1289 | 0 | if (status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len(ctx)) { |
1290 | 0 | return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; |
1291 | 0 | } |
1292 | | |
1293 | 0 | if (status == PSA_SUCCESS) { |
1294 | 0 | status = destruction_status; |
1295 | 0 | } |
1296 | |
|
1297 | 0 | return PSA_PK_RSA_TO_MBEDTLS_ERR(status); |
1298 | 0 | } else |
1299 | 0 | #endif /* MBEDTLS_USE_PSA_CRYPTO */ |
1300 | 0 | { |
1301 | 0 | if (sig_len < mbedtls_pk_get_len(ctx)) { |
1302 | 0 | return MBEDTLS_ERR_RSA_VERIFY_FAILED; |
1303 | 0 | } |
1304 | | |
1305 | 0 | ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx), |
1306 | 0 | md_alg, (unsigned int) hash_len, hash, |
1307 | 0 | pss_opts->mgf1_hash_id, |
1308 | 0 | pss_opts->expected_salt_len, |
1309 | 0 | sig); |
1310 | 0 | if (ret != 0) { |
1311 | 0 | return ret; |
1312 | 0 | } |
1313 | | |
1314 | 0 | if (sig_len > mbedtls_pk_get_len(ctx)) { |
1315 | 0 | return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; |
1316 | 0 | } |
1317 | | |
1318 | 0 | return 0; |
1319 | 0 | } |
1320 | | #else |
1321 | | return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; |
1322 | | #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ |
1323 | 0 | } Unexecuted instantiation: mbedtls_pk_verify_ext Unexecuted instantiation: mbedtls_pk_verify_ext |
1324 | | |
1325 | | /* |
1326 | | * Make a signature (restartable) |
1327 | | */ |
1328 | | int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx, |
1329 | | mbedtls_md_type_t md_alg, |
1330 | | const unsigned char *hash, size_t hash_len, |
1331 | | unsigned char *sig, size_t sig_size, size_t *sig_len, |
1332 | | int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
1333 | | mbedtls_pk_restart_ctx *rs_ctx) |
1334 | 0 | { |
1335 | 0 | if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { |
1336 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1337 | 0 | } |
1338 | | |
1339 | 0 | if (ctx->pk_info == NULL || pk_hashlen_helper(md_alg, &hash_len) != 0) { |
1340 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1341 | 0 | } |
1342 | | |
1343 | 0 | #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
1344 | | /* optimization: use non-restartable version if restart disabled */ |
1345 | 0 | if (rs_ctx != NULL && |
1346 | 0 | mbedtls_ecp_restart_is_enabled() && |
1347 | 0 | ctx->pk_info->sign_rs_func != NULL) { |
1348 | 0 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
1349 | |
|
1350 | 0 | if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { |
1351 | 0 | return ret; |
1352 | 0 | } |
1353 | | |
1354 | 0 | ret = ctx->pk_info->sign_rs_func(ctx, md_alg, |
1355 | 0 | hash, hash_len, |
1356 | 0 | sig, sig_size, sig_len, |
1357 | 0 | f_rng, p_rng, rs_ctx->rs_ctx); |
1358 | |
|
1359 | 0 | if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { |
1360 | 0 | mbedtls_pk_restart_free(rs_ctx); |
1361 | 0 | } |
1362 | |
|
1363 | 0 | return ret; |
1364 | 0 | } |
1365 | | #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
1366 | | (void) rs_ctx; |
1367 | | #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
1368 | | |
1369 | 0 | if (ctx->pk_info->sign_func == NULL) { |
1370 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
1371 | 0 | } |
1372 | | |
1373 | 0 | return ctx->pk_info->sign_func(ctx, md_alg, |
1374 | 0 | hash, hash_len, |
1375 | 0 | sig, sig_size, sig_len, |
1376 | 0 | f_rng, p_rng); |
1377 | 0 | } |
1378 | | |
1379 | | /* |
1380 | | * Make a signature |
1381 | | */ |
1382 | | int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
1383 | | const unsigned char *hash, size_t hash_len, |
1384 | | unsigned char *sig, size_t sig_size, size_t *sig_len, |
1385 | | int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) |
1386 | 0 | { |
1387 | 0 | return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len, |
1388 | 0 | sig, sig_size, sig_len, |
1389 | 0 | f_rng, p_rng, NULL); |
1390 | 0 | } |
1391 | | |
1392 | | /* |
1393 | | * Make a signature given a signature type. |
1394 | | */ |
1395 | | int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, |
1396 | | mbedtls_pk_context *ctx, |
1397 | | mbedtls_md_type_t md_alg, |
1398 | | const unsigned char *hash, size_t hash_len, |
1399 | | unsigned char *sig, size_t sig_size, size_t *sig_len, |
1400 | | int (*f_rng)(void *, unsigned char *, size_t), |
1401 | | void *p_rng) |
1402 | 0 | { |
1403 | 0 | if (ctx->pk_info == NULL) { |
1404 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1405 | 0 | } |
1406 | | |
1407 | 0 | if (!mbedtls_pk_can_do(ctx, pk_type)) { |
1408 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
1409 | 0 | } |
1410 | | |
1411 | 0 | if (pk_type != MBEDTLS_PK_RSASSA_PSS) { |
1412 | 0 | return mbedtls_pk_sign(ctx, md_alg, hash, hash_len, |
1413 | 0 | sig, sig_size, sig_len, f_rng, p_rng); |
1414 | 0 | } |
1415 | | |
1416 | 0 | #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) |
1417 | | |
1418 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
1419 | 0 | const psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); |
1420 | 0 | if (psa_md_alg == 0) { |
1421 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1422 | 0 | } |
1423 | | |
1424 | 0 | if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) { |
1425 | 0 | psa_status_t status; |
1426 | | |
1427 | | /* PSA_ALG_RSA_PSS() behaves the same as PSA_ALG_RSA_PSS_ANY_SALT() when |
1428 | | * performing a signature, but they are encoded differently. Instead of |
1429 | | * extracting the proper one from the wrapped key policy, just try both. */ |
1430 | 0 | status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg), |
1431 | 0 | hash, hash_len, |
1432 | 0 | sig, sig_size, sig_len); |
1433 | 0 | if (status == PSA_ERROR_NOT_PERMITTED) { |
1434 | 0 | status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg), |
1435 | 0 | hash, hash_len, |
1436 | 0 | sig, sig_size, sig_len); |
1437 | 0 | } |
1438 | 0 | return PSA_PK_RSA_TO_MBEDTLS_ERR(status); |
1439 | 0 | } |
1440 | | |
1441 | 0 | return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PSS(psa_md_alg), |
1442 | 0 | ctx->pk_ctx, hash, hash_len, |
1443 | 0 | sig, sig_size, sig_len); |
1444 | | #else /* MBEDTLS_USE_PSA_CRYPTO */ |
1445 | | |
1446 | 0 | if (sig_size < mbedtls_pk_get_len(ctx)) { |
1447 | 0 | return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; |
1448 | 0 | } |
1449 | | |
1450 | 0 | if (pk_hashlen_helper(md_alg, &hash_len) != 0) { |
1451 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1452 | 0 | } |
1453 | | |
1454 | 0 | mbedtls_rsa_context *const rsa_ctx = mbedtls_pk_rsa(*ctx); |
1455 | |
|
1456 | 0 | const int ret = mbedtls_rsa_rsassa_pss_sign_no_mode_check(rsa_ctx, f_rng, p_rng, md_alg, |
1457 | 0 | (unsigned int) hash_len, hash, sig); |
1458 | 0 | if (ret == 0) { |
1459 | 0 | *sig_len = rsa_ctx->len; |
1460 | 0 | } |
1461 | 0 | return ret; |
1462 | |
|
1463 | 0 | #endif /* MBEDTLS_USE_PSA_CRYPTO */ |
1464 | |
|
1465 | | #else |
1466 | | return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; |
1467 | | #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ |
1468 | 0 | } Unexecuted instantiation: mbedtls_pk_sign_ext Unexecuted instantiation: mbedtls_pk_sign_ext |
1469 | | |
1470 | | /* |
1471 | | * Decrypt message |
1472 | | */ |
1473 | | int mbedtls_pk_decrypt(mbedtls_pk_context *ctx, |
1474 | | const unsigned char *input, size_t ilen, |
1475 | | unsigned char *output, size_t *olen, size_t osize, |
1476 | | int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) |
1477 | 0 | { |
1478 | 0 | if (ctx->pk_info == NULL) { |
1479 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1480 | 0 | } |
1481 | | |
1482 | 0 | if (ctx->pk_info->decrypt_func == NULL) { |
1483 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
1484 | 0 | } |
1485 | | |
1486 | 0 | return ctx->pk_info->decrypt_func(ctx, input, ilen, |
1487 | 0 | output, olen, osize, f_rng, p_rng); |
1488 | 0 | } |
1489 | | |
1490 | | /* |
1491 | | * Encrypt message |
1492 | | */ |
1493 | | int mbedtls_pk_encrypt(mbedtls_pk_context *ctx, |
1494 | | const unsigned char *input, size_t ilen, |
1495 | | unsigned char *output, size_t *olen, size_t osize, |
1496 | | int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) |
1497 | 533 | { |
1498 | 533 | if (ctx->pk_info == NULL) { |
1499 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1500 | 0 | } |
1501 | | |
1502 | 533 | if (ctx->pk_info->encrypt_func == NULL) { |
1503 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
1504 | 0 | } |
1505 | | |
1506 | 533 | return ctx->pk_info->encrypt_func(ctx, input, ilen, |
1507 | 533 | output, olen, osize, f_rng, p_rng); |
1508 | 533 | } |
1509 | | |
1510 | | /* |
1511 | | * Check public-private key pair |
1512 | | */ |
1513 | | int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, |
1514 | | const mbedtls_pk_context *prv, |
1515 | | int (*f_rng)(void *, unsigned char *, size_t), |
1516 | | void *p_rng) |
1517 | 0 | { |
1518 | 0 | if (pub->pk_info == NULL || |
1519 | 0 | prv->pk_info == NULL) { |
1520 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1521 | 0 | } |
1522 | | |
1523 | 0 | if (f_rng == NULL) { |
1524 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1525 | 0 | } |
1526 | | |
1527 | 0 | if (prv->pk_info->check_pair_func == NULL) { |
1528 | 0 | return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; |
1529 | 0 | } |
1530 | | |
1531 | 0 | if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) { |
1532 | 0 | if (pub->pk_info->type != MBEDTLS_PK_RSA) { |
1533 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
1534 | 0 | } |
1535 | 0 | } else { |
1536 | 0 | if ((prv->pk_info->type != MBEDTLS_PK_OPAQUE) && |
1537 | 0 | (pub->pk_info != prv->pk_info)) { |
1538 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
1539 | 0 | } |
1540 | 0 | } |
1541 | | |
1542 | 0 | return prv->pk_info->check_pair_func((mbedtls_pk_context *) pub, |
1543 | 0 | (mbedtls_pk_context *) prv, |
1544 | 0 | f_rng, p_rng); |
1545 | 0 | } |
1546 | | |
1547 | | /* |
1548 | | * Get key size in bits |
1549 | | */ |
1550 | | size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx) |
1551 | 598 | { |
1552 | | /* For backward compatibility, accept NULL or a context that |
1553 | | * isn't set up yet, and return a fake value that should be safe. */ |
1554 | 598 | if (ctx == NULL || ctx->pk_info == NULL) { |
1555 | 0 | return 0; |
1556 | 0 | } |
1557 | | |
1558 | 598 | return ctx->pk_info->get_bitlen((mbedtls_pk_context *) ctx); |
1559 | 598 | } |
1560 | | |
1561 | | /* |
1562 | | * Export debug information |
1563 | | */ |
1564 | | int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items) |
1565 | 0 | { |
1566 | 0 | if (ctx->pk_info == NULL) { |
1567 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
1568 | 0 | } |
1569 | | |
1570 | 0 | if (ctx->pk_info->debug_func == NULL) { |
1571 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
1572 | 0 | } |
1573 | | |
1574 | 0 | ctx->pk_info->debug_func((mbedtls_pk_context *) ctx, items); |
1575 | 0 | return 0; |
1576 | 0 | } |
1577 | | |
1578 | | /* |
1579 | | * Access the PK type name |
1580 | | */ |
1581 | | const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx) |
1582 | 598 | { |
1583 | 598 | if (ctx == NULL || ctx->pk_info == NULL) { |
1584 | 0 | return "invalid PK"; |
1585 | 0 | } |
1586 | | |
1587 | 598 | return ctx->pk_info->name; |
1588 | 598 | } |
1589 | | |
1590 | | /* |
1591 | | * Access the PK type |
1592 | | */ |
1593 | | mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) |
1594 | 71.9k | { |
1595 | 71.9k | if (ctx == NULL || ctx->pk_info == NULL) { |
1596 | 0 | return MBEDTLS_PK_NONE; |
1597 | 0 | } |
1598 | | |
1599 | 71.9k | return ctx->pk_info->type; |
1600 | 71.9k | } |
1601 | | |
1602 | | #endif /* MBEDTLS_PK_C */ |