/work/mbedtls-2.28.8/library/pk.c
Line | Count | Source (jump to first uncovered line) |
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 "mbedtls/pk_internal.h" |
13 | | |
14 | | #include "mbedtls/platform_util.h" |
15 | | #include "mbedtls/error.h" |
16 | | |
17 | | #if defined(MBEDTLS_RSA_C) |
18 | | #include "mbedtls/rsa.h" |
19 | | #endif |
20 | | #if defined(MBEDTLS_ECP_C) |
21 | | #include "mbedtls/ecp.h" |
22 | | #endif |
23 | | #if defined(MBEDTLS_ECDSA_C) |
24 | | #include "mbedtls/ecdsa.h" |
25 | | #endif |
26 | | |
27 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
28 | | #include "mbedtls/psa_util.h" |
29 | | #endif |
30 | | |
31 | | #include <limits.h> |
32 | | #include <stdint.h> |
33 | | |
34 | | /* Parameter validation macros based on platform_util.h */ |
35 | | #define PK_VALIDATE_RET(cond) \ |
36 | 0 | MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA) |
37 | | #define PK_VALIDATE(cond) \ |
38 | 0 | MBEDTLS_INTERNAL_VALIDATE(cond) |
39 | | |
40 | | /* |
41 | | * Initialise a mbedtls_pk_context |
42 | | */ |
43 | | void mbedtls_pk_init(mbedtls_pk_context *ctx) |
44 | 0 | { |
45 | 0 | PK_VALIDATE(ctx != NULL); |
46 | |
|
47 | 0 | ctx->pk_info = NULL; |
48 | 0 | ctx->pk_ctx = NULL; |
49 | 0 | } |
50 | | |
51 | | /* |
52 | | * Free (the components of) a mbedtls_pk_context |
53 | | */ |
54 | | void mbedtls_pk_free(mbedtls_pk_context *ctx) |
55 | 0 | { |
56 | 0 | if (ctx == NULL) { |
57 | 0 | return; |
58 | 0 | } |
59 | | |
60 | 0 | if (ctx->pk_info != NULL) { |
61 | 0 | ctx->pk_info->ctx_free_func(ctx->pk_ctx); |
62 | 0 | } |
63 | |
|
64 | 0 | mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context)); |
65 | 0 | } |
66 | | |
67 | | #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
68 | | /* |
69 | | * Initialize a restart context |
70 | | */ |
71 | | void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx) |
72 | | { |
73 | | PK_VALIDATE(ctx != NULL); |
74 | | ctx->pk_info = NULL; |
75 | | ctx->rs_ctx = NULL; |
76 | | } |
77 | | |
78 | | /* |
79 | | * Free the components of a restart context |
80 | | */ |
81 | | void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx) |
82 | | { |
83 | | if (ctx == NULL || ctx->pk_info == NULL || |
84 | | ctx->pk_info->rs_free_func == NULL) { |
85 | | return; |
86 | | } |
87 | | |
88 | | ctx->pk_info->rs_free_func(ctx->rs_ctx); |
89 | | |
90 | | ctx->pk_info = NULL; |
91 | | ctx->rs_ctx = NULL; |
92 | | } |
93 | | #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
94 | | |
95 | | /* |
96 | | * Get pk_info structure from type |
97 | | */ |
98 | | const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type) |
99 | 0 | { |
100 | 0 | switch (pk_type) { |
101 | 0 | #if defined(MBEDTLS_RSA_C) |
102 | 0 | case MBEDTLS_PK_RSA: |
103 | 0 | return &mbedtls_rsa_info; |
104 | 0 | #endif |
105 | 0 | #if defined(MBEDTLS_ECP_C) |
106 | 0 | case MBEDTLS_PK_ECKEY: |
107 | 0 | return &mbedtls_eckey_info; |
108 | 0 | case MBEDTLS_PK_ECKEY_DH: |
109 | 0 | return &mbedtls_eckeydh_info; |
110 | 0 | #endif |
111 | 0 | #if defined(MBEDTLS_ECDSA_C) |
112 | 0 | case MBEDTLS_PK_ECDSA: |
113 | 0 | return &mbedtls_ecdsa_info; |
114 | 0 | #endif |
115 | | /* MBEDTLS_PK_RSA_ALT omitted on purpose */ |
116 | 0 | default: |
117 | 0 | return NULL; |
118 | 0 | } |
119 | 0 | } |
120 | | |
121 | | /* |
122 | | * Initialise context |
123 | | */ |
124 | | int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info) |
125 | 0 | { |
126 | 0 | PK_VALIDATE_RET(ctx != NULL); |
127 | 0 | if (info == NULL || ctx->pk_info != NULL) { |
128 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
129 | 0 | } |
130 | | |
131 | 0 | if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) { |
132 | 0 | return MBEDTLS_ERR_PK_ALLOC_FAILED; |
133 | 0 | } |
134 | | |
135 | 0 | ctx->pk_info = info; |
136 | |
|
137 | 0 | return 0; |
138 | 0 | } |
139 | | |
140 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
141 | | /* |
142 | | * Initialise a PSA-wrapping context |
143 | | */ |
144 | | int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, |
145 | | const psa_key_id_t key) |
146 | | { |
147 | | const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info; |
148 | | psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
149 | | psa_key_id_t *pk_ctx; |
150 | | psa_key_type_t type; |
151 | | |
152 | | if (ctx == NULL || ctx->pk_info != NULL) { |
153 | | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
154 | | } |
155 | | |
156 | | if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) { |
157 | | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
158 | | } |
159 | | type = psa_get_key_type(&attributes); |
160 | | psa_reset_key_attributes(&attributes); |
161 | | |
162 | | /* Current implementation of can_do() relies on this. */ |
163 | | if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { |
164 | | return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; |
165 | | } |
166 | | |
167 | | if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) { |
168 | | return MBEDTLS_ERR_PK_ALLOC_FAILED; |
169 | | } |
170 | | |
171 | | ctx->pk_info = info; |
172 | | |
173 | | pk_ctx = (psa_key_id_t *) ctx->pk_ctx; |
174 | | *pk_ctx = key; |
175 | | |
176 | | return 0; |
177 | | } |
178 | | #endif /* MBEDTLS_USE_PSA_CRYPTO */ |
179 | | |
180 | | #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
181 | | /* |
182 | | * Initialize an RSA-alt context |
183 | | */ |
184 | | int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key, |
185 | | mbedtls_pk_rsa_alt_decrypt_func decrypt_func, |
186 | | mbedtls_pk_rsa_alt_sign_func sign_func, |
187 | | mbedtls_pk_rsa_alt_key_len_func key_len_func) |
188 | 0 | { |
189 | 0 | mbedtls_rsa_alt_context *rsa_alt; |
190 | 0 | const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; |
191 | |
|
192 | 0 | PK_VALIDATE_RET(ctx != NULL); |
193 | 0 | if (ctx->pk_info != NULL) { |
194 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
195 | 0 | } |
196 | | |
197 | 0 | if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) { |
198 | 0 | return MBEDTLS_ERR_PK_ALLOC_FAILED; |
199 | 0 | } |
200 | | |
201 | 0 | ctx->pk_info = info; |
202 | |
|
203 | 0 | rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx; |
204 | |
|
205 | 0 | rsa_alt->key = key; |
206 | 0 | rsa_alt->decrypt_func = decrypt_func; |
207 | 0 | rsa_alt->sign_func = sign_func; |
208 | 0 | rsa_alt->key_len_func = key_len_func; |
209 | |
|
210 | 0 | return 0; |
211 | 0 | } |
212 | | #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ |
213 | | |
214 | | /* |
215 | | * Tell if a PK can do the operations of the given type |
216 | | */ |
217 | | int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type) |
218 | 0 | { |
219 | | /* A context with null pk_info is not set up yet and can't do anything. |
220 | | * For backward compatibility, also accept NULL instead of a context |
221 | | * pointer. */ |
222 | 0 | if (ctx == NULL || ctx->pk_info == NULL) { |
223 | 0 | return 0; |
224 | 0 | } |
225 | | |
226 | 0 | return ctx->pk_info->can_do(type); |
227 | 0 | } |
228 | | |
229 | | /* |
230 | | * Helper for mbedtls_pk_sign and mbedtls_pk_verify |
231 | | */ |
232 | | static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len) |
233 | 0 | { |
234 | 0 | const mbedtls_md_info_t *md_info; |
235 | |
|
236 | 0 | if (*hash_len != 0 && md_alg == MBEDTLS_MD_NONE) { |
237 | 0 | return 0; |
238 | 0 | } |
239 | | |
240 | 0 | if ((md_info = mbedtls_md_info_from_type(md_alg)) == NULL) { |
241 | 0 | return -1; |
242 | 0 | } |
243 | | |
244 | 0 | if (*hash_len != 0 && *hash_len != mbedtls_md_get_size(md_info)) { |
245 | 0 | return -1; |
246 | 0 | } |
247 | | |
248 | 0 | *hash_len = mbedtls_md_get_size(md_info); |
249 | 0 | return 0; |
250 | 0 | } |
251 | | |
252 | | #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
253 | | /* |
254 | | * Helper to set up a restart context if needed |
255 | | */ |
256 | | static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx, |
257 | | const mbedtls_pk_info_t *info) |
258 | | { |
259 | | /* Don't do anything if already set up or invalid */ |
260 | | if (ctx == NULL || ctx->pk_info != NULL) { |
261 | | return 0; |
262 | | } |
263 | | |
264 | | /* Should never happen when we're called */ |
265 | | if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) { |
266 | | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
267 | | } |
268 | | |
269 | | if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) { |
270 | | return MBEDTLS_ERR_PK_ALLOC_FAILED; |
271 | | } |
272 | | |
273 | | ctx->pk_info = info; |
274 | | |
275 | | return 0; |
276 | | } |
277 | | #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
278 | | |
279 | | /* |
280 | | * Verify a signature (restartable) |
281 | | */ |
282 | | int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx, |
283 | | mbedtls_md_type_t md_alg, |
284 | | const unsigned char *hash, size_t hash_len, |
285 | | const unsigned char *sig, size_t sig_len, |
286 | | mbedtls_pk_restart_ctx *rs_ctx) |
287 | 0 | { |
288 | 0 | PK_VALIDATE_RET(ctx != NULL); |
289 | 0 | PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) || |
290 | 0 | hash != NULL); |
291 | 0 | PK_VALIDATE_RET(sig != NULL); |
292 | |
|
293 | 0 | if (ctx->pk_info == NULL || |
294 | 0 | pk_hashlen_helper(md_alg, &hash_len) != 0) { |
295 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
296 | 0 | } |
297 | | |
298 | | #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
299 | | /* optimization: use non-restartable version if restart disabled */ |
300 | | if (rs_ctx != NULL && |
301 | | mbedtls_ecp_restart_is_enabled() && |
302 | | ctx->pk_info->verify_rs_func != NULL) { |
303 | | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
304 | | |
305 | | if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { |
306 | | return ret; |
307 | | } |
308 | | |
309 | | ret = ctx->pk_info->verify_rs_func(ctx->pk_ctx, |
310 | | md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx); |
311 | | |
312 | | if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { |
313 | | mbedtls_pk_restart_free(rs_ctx); |
314 | | } |
315 | | |
316 | | return ret; |
317 | | } |
318 | | #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
319 | 0 | (void) rs_ctx; |
320 | 0 | #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
321 | |
|
322 | 0 | if (ctx->pk_info->verify_func == NULL) { |
323 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
324 | 0 | } |
325 | | |
326 | 0 | return ctx->pk_info->verify_func(ctx->pk_ctx, md_alg, hash, hash_len, |
327 | 0 | sig, sig_len); |
328 | 0 | } |
329 | | |
330 | | /* |
331 | | * Verify a signature |
332 | | */ |
333 | | int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
334 | | const unsigned char *hash, size_t hash_len, |
335 | | const unsigned char *sig, size_t sig_len) |
336 | 0 | { |
337 | 0 | return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len, |
338 | 0 | sig, sig_len, NULL); |
339 | 0 | } |
340 | | |
341 | | /* |
342 | | * Verify a signature with options |
343 | | */ |
344 | | int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, |
345 | | mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
346 | | const unsigned char *hash, size_t hash_len, |
347 | | const unsigned char *sig, size_t sig_len) |
348 | 0 | { |
349 | 0 | PK_VALIDATE_RET(ctx != NULL); |
350 | 0 | PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) || |
351 | 0 | hash != NULL); |
352 | 0 | PK_VALIDATE_RET(sig != NULL); |
353 | |
|
354 | 0 | if (ctx->pk_info == NULL) { |
355 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
356 | 0 | } |
357 | | |
358 | 0 | if (!mbedtls_pk_can_do(ctx, type)) { |
359 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
360 | 0 | } |
361 | | |
362 | 0 | if (type == MBEDTLS_PK_RSASSA_PSS) { |
363 | 0 | #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) |
364 | 0 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
365 | 0 | const mbedtls_pk_rsassa_pss_options *pss_opts; |
366 | |
|
367 | 0 | #if SIZE_MAX > UINT_MAX |
368 | 0 | if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { |
369 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
370 | 0 | } |
371 | 0 | #endif /* SIZE_MAX > UINT_MAX */ |
372 | | |
373 | 0 | if (options == NULL) { |
374 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
375 | 0 | } |
376 | | |
377 | 0 | pss_opts = (const mbedtls_pk_rsassa_pss_options *) options; |
378 | |
|
379 | 0 | if (sig_len < mbedtls_pk_get_len(ctx)) { |
380 | 0 | return MBEDTLS_ERR_RSA_VERIFY_FAILED; |
381 | 0 | } |
382 | | |
383 | 0 | ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx), |
384 | 0 | NULL, NULL, MBEDTLS_RSA_PUBLIC, |
385 | 0 | md_alg, (unsigned int) hash_len, hash, |
386 | 0 | pss_opts->mgf1_hash_id, |
387 | 0 | pss_opts->expected_salt_len, |
388 | 0 | sig); |
389 | 0 | if (ret != 0) { |
390 | 0 | return ret; |
391 | 0 | } |
392 | | |
393 | 0 | if (sig_len > mbedtls_pk_get_len(ctx)) { |
394 | 0 | return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; |
395 | 0 | } |
396 | | |
397 | 0 | return 0; |
398 | | #else |
399 | | return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; |
400 | | #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ |
401 | 0 | } |
402 | | |
403 | | /* General case: no options */ |
404 | 0 | if (options != NULL) { |
405 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
406 | 0 | } |
407 | | |
408 | 0 | return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len); |
409 | 0 | } |
410 | | |
411 | | /* |
412 | | * Make a signature (restartable) |
413 | | */ |
414 | | int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx, |
415 | | mbedtls_md_type_t md_alg, |
416 | | const unsigned char *hash, size_t hash_len, |
417 | | unsigned char *sig, size_t *sig_len, |
418 | | int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
419 | | mbedtls_pk_restart_ctx *rs_ctx) |
420 | 0 | { |
421 | 0 | PK_VALIDATE_RET(ctx != NULL); |
422 | 0 | PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) || |
423 | 0 | hash != NULL); |
424 | 0 | PK_VALIDATE_RET(sig != NULL); |
425 | |
|
426 | 0 | if (ctx->pk_info == NULL || |
427 | 0 | pk_hashlen_helper(md_alg, &hash_len) != 0) { |
428 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
429 | 0 | } |
430 | | |
431 | | #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
432 | | /* optimization: use non-restartable version if restart disabled */ |
433 | | if (rs_ctx != NULL && |
434 | | mbedtls_ecp_restart_is_enabled() && |
435 | | ctx->pk_info->sign_rs_func != NULL) { |
436 | | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
437 | | |
438 | | if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { |
439 | | return ret; |
440 | | } |
441 | | |
442 | | ret = ctx->pk_info->sign_rs_func(ctx->pk_ctx, md_alg, |
443 | | hash, hash_len, sig, sig_len, f_rng, p_rng, |
444 | | rs_ctx->rs_ctx); |
445 | | |
446 | | if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { |
447 | | mbedtls_pk_restart_free(rs_ctx); |
448 | | } |
449 | | |
450 | | return ret; |
451 | | } |
452 | | #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
453 | 0 | (void) rs_ctx; |
454 | 0 | #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
455 | |
|
456 | 0 | if (ctx->pk_info->sign_func == NULL) { |
457 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
458 | 0 | } |
459 | | |
460 | 0 | return ctx->pk_info->sign_func(ctx->pk_ctx, md_alg, hash, hash_len, |
461 | 0 | sig, sig_len, f_rng, p_rng); |
462 | 0 | } |
463 | | |
464 | | /* |
465 | | * Make a signature |
466 | | */ |
467 | | int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
468 | | const unsigned char *hash, size_t hash_len, |
469 | | unsigned char *sig, size_t *sig_len, |
470 | | int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) |
471 | 0 | { |
472 | 0 | return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len, |
473 | 0 | sig, sig_len, f_rng, p_rng, NULL); |
474 | 0 | } |
475 | | |
476 | | /* |
477 | | * Decrypt message |
478 | | */ |
479 | | int mbedtls_pk_decrypt(mbedtls_pk_context *ctx, |
480 | | const unsigned char *input, size_t ilen, |
481 | | unsigned char *output, size_t *olen, size_t osize, |
482 | | int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) |
483 | 0 | { |
484 | 0 | PK_VALIDATE_RET(ctx != NULL); |
485 | 0 | PK_VALIDATE_RET(input != NULL || ilen == 0); |
486 | 0 | PK_VALIDATE_RET(output != NULL || osize == 0); |
487 | 0 | PK_VALIDATE_RET(olen != NULL); |
488 | |
|
489 | 0 | if (ctx->pk_info == NULL) { |
490 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
491 | 0 | } |
492 | | |
493 | 0 | if (ctx->pk_info->decrypt_func == NULL) { |
494 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
495 | 0 | } |
496 | | |
497 | 0 | return ctx->pk_info->decrypt_func(ctx->pk_ctx, input, ilen, |
498 | 0 | output, olen, osize, f_rng, p_rng); |
499 | 0 | } |
500 | | |
501 | | /* |
502 | | * Encrypt message |
503 | | */ |
504 | | int mbedtls_pk_encrypt(mbedtls_pk_context *ctx, |
505 | | const unsigned char *input, size_t ilen, |
506 | | unsigned char *output, size_t *olen, size_t osize, |
507 | | int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) |
508 | 0 | { |
509 | 0 | PK_VALIDATE_RET(ctx != NULL); |
510 | 0 | PK_VALIDATE_RET(input != NULL || ilen == 0); |
511 | 0 | PK_VALIDATE_RET(output != NULL || osize == 0); |
512 | 0 | PK_VALIDATE_RET(olen != NULL); |
513 | |
|
514 | 0 | if (ctx->pk_info == NULL) { |
515 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
516 | 0 | } |
517 | | |
518 | 0 | if (ctx->pk_info->encrypt_func == NULL) { |
519 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
520 | 0 | } |
521 | | |
522 | 0 | return ctx->pk_info->encrypt_func(ctx->pk_ctx, input, ilen, |
523 | 0 | output, olen, osize, f_rng, p_rng); |
524 | 0 | } |
525 | | |
526 | | /* |
527 | | * Check public-private key pair |
528 | | */ |
529 | | int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv) |
530 | 0 | { |
531 | 0 | PK_VALIDATE_RET(pub != NULL); |
532 | 0 | PK_VALIDATE_RET(prv != NULL); |
533 | |
|
534 | 0 | if (pub->pk_info == NULL || |
535 | 0 | prv->pk_info == NULL) { |
536 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
537 | 0 | } |
538 | | |
539 | 0 | if (prv->pk_info->check_pair_func == NULL) { |
540 | 0 | return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; |
541 | 0 | } |
542 | | |
543 | 0 | if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) { |
544 | 0 | if (pub->pk_info->type != MBEDTLS_PK_RSA) { |
545 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
546 | 0 | } |
547 | 0 | } else { |
548 | 0 | if (pub->pk_info != prv->pk_info) { |
549 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
550 | 0 | } |
551 | 0 | } |
552 | | |
553 | 0 | return prv->pk_info->check_pair_func(pub->pk_ctx, prv->pk_ctx); |
554 | 0 | } |
555 | | |
556 | | /* |
557 | | * Get key size in bits |
558 | | */ |
559 | | size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx) |
560 | 0 | { |
561 | | /* For backward compatibility, accept NULL or a context that |
562 | | * isn't set up yet, and return a fake value that should be safe. */ |
563 | 0 | if (ctx == NULL || ctx->pk_info == NULL) { |
564 | 0 | return 0; |
565 | 0 | } |
566 | | |
567 | 0 | return ctx->pk_info->get_bitlen(ctx->pk_ctx); |
568 | 0 | } |
569 | | |
570 | | /* |
571 | | * Export debug information |
572 | | */ |
573 | | int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items) |
574 | 0 | { |
575 | 0 | PK_VALIDATE_RET(ctx != NULL); |
576 | 0 | if (ctx->pk_info == NULL) { |
577 | 0 | return MBEDTLS_ERR_PK_BAD_INPUT_DATA; |
578 | 0 | } |
579 | | |
580 | 0 | if (ctx->pk_info->debug_func == NULL) { |
581 | 0 | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
582 | 0 | } |
583 | | |
584 | 0 | ctx->pk_info->debug_func(ctx->pk_ctx, items); |
585 | 0 | return 0; |
586 | 0 | } |
587 | | |
588 | | /* |
589 | | * Access the PK type name |
590 | | */ |
591 | | const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx) |
592 | 0 | { |
593 | 0 | if (ctx == NULL || ctx->pk_info == NULL) { |
594 | 0 | return "invalid PK"; |
595 | 0 | } |
596 | | |
597 | 0 | return ctx->pk_info->name; |
598 | 0 | } |
599 | | |
600 | | /* |
601 | | * Access the PK type |
602 | | */ |
603 | | mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) |
604 | 0 | { |
605 | 0 | if (ctx == NULL || ctx->pk_info == NULL) { |
606 | 0 | return MBEDTLS_PK_NONE; |
607 | 0 | } |
608 | | |
609 | 0 | return ctx->pk_info->type; |
610 | 0 | } |
611 | | |
612 | | #if defined(MBEDTLS_USE_PSA_CRYPTO) |
613 | | /* |
614 | | * Load the key to a PSA key slot, |
615 | | * then turn the PK context into a wrapper for that key slot. |
616 | | * |
617 | | * Currently only works for EC private keys. |
618 | | */ |
619 | | int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk, |
620 | | psa_key_id_t *key, |
621 | | psa_algorithm_t hash_alg) |
622 | | { |
623 | | #if !defined(MBEDTLS_ECP_C) |
624 | | ((void) pk); |
625 | | ((void) key); |
626 | | ((void) hash_alg); |
627 | | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
628 | | #else |
629 | | const mbedtls_ecp_keypair *ec; |
630 | | unsigned char d[MBEDTLS_ECP_MAX_BYTES]; |
631 | | size_t d_len; |
632 | | psa_ecc_family_t curve_id; |
633 | | psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
634 | | psa_key_type_t key_type; |
635 | | size_t bits; |
636 | | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
637 | | psa_status_t status; |
638 | | |
639 | | /* export the private key material in the format PSA wants */ |
640 | | if (mbedtls_pk_get_type(pk) != MBEDTLS_PK_ECKEY) { |
641 | | return MBEDTLS_ERR_PK_TYPE_MISMATCH; |
642 | | } |
643 | | |
644 | | ec = mbedtls_pk_ec(*pk); |
645 | | d_len = (ec->grp.nbits + 7) / 8; |
646 | | if ((ret = mbedtls_mpi_write_binary(&ec->d, d, d_len)) != 0) { |
647 | | return ret; |
648 | | } |
649 | | |
650 | | curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits); |
651 | | key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id); |
652 | | |
653 | | /* prepare the key attributes */ |
654 | | psa_set_key_type(&attributes, key_type); |
655 | | psa_set_key_bits(&attributes, bits); |
656 | | psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); |
657 | | psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(hash_alg)); |
658 | | |
659 | | /* import private key into PSA */ |
660 | | status = psa_import_key(&attributes, d, d_len, key); |
661 | | mbedtls_platform_zeroize(d, sizeof(d)); |
662 | | if (status != PSA_SUCCESS) { |
663 | | return MBEDTLS_ERR_PK_HW_ACCEL_FAILED; |
664 | | } |
665 | | |
666 | | /* make PK context wrap the key slot */ |
667 | | mbedtls_pk_free(pk); |
668 | | mbedtls_pk_init(pk); |
669 | | |
670 | | return mbedtls_pk_setup_opaque(pk, *key); |
671 | | #endif /* MBEDTLS_ECP_C */ |
672 | | } |
673 | | #endif /* MBEDTLS_USE_PSA_CRYPTO */ |
674 | | #endif /* MBEDTLS_PK_C */ |