Branch data Line data Source code
1 : : /*
2 : : * PSA RSA layer on top of Mbed TLS crypto
3 : : */
4 : : /*
5 : : * Copyright The Mbed TLS Contributors
6 : : * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7 : : */
8 : :
9 : : #include "common.h"
10 : :
11 : : #if defined(MBEDTLS_PSA_CRYPTO_C)
12 : :
13 : : #include <psa/crypto.h>
14 : : #include "psa/crypto_values.h"
15 : : #include "psa_crypto_core.h"
16 : : #include "psa_crypto_random_impl.h"
17 : : #include "psa_crypto_rsa.h"
18 : : #include "psa_crypto_hash.h"
19 : : #include "mbedtls/psa_util.h"
20 : :
21 : : #include <stdlib.h>
22 : : #include <string.h>
23 : : #include "mbedtls/platform.h"
24 : :
25 : : #include <mbedtls/rsa.h>
26 : : #include <mbedtls/error.h>
27 : : #include "rsa_internal.h"
28 : :
29 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
30 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
31 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
32 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
33 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \
34 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
35 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
36 : :
37 : : /* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
38 : : * that are not a multiple of 8) well. For example, there is only
39 : : * mbedtls_rsa_get_len(), which returns a number of bytes, and no
40 : : * way to return the exact bit size of a key.
41 : : * To keep things simple, reject non-byte-aligned key sizes. */
42 : : static psa_status_t psa_check_rsa_key_byte_aligned(
43 : : const mbedtls_rsa_context *rsa)
44 : : {
45 : : mbedtls_mpi n;
46 : : psa_status_t status;
47 : : mbedtls_mpi_init(&n);
48 : : status = mbedtls_to_psa_error(
49 : : mbedtls_rsa_export(rsa, &n, NULL, NULL, NULL, NULL));
50 : : if (status == PSA_SUCCESS) {
51 : : if (mbedtls_mpi_bitlen(&n) % 8 != 0) {
52 : : status = PSA_ERROR_NOT_SUPPORTED;
53 : : }
54 : : }
55 : : mbedtls_mpi_free(&n);
56 : : return status;
57 : : }
58 : :
59 : : psa_status_t mbedtls_psa_rsa_load_representation(
60 : : psa_key_type_t type, const uint8_t *data, size_t data_length,
61 : : mbedtls_rsa_context **p_rsa)
62 : : {
63 : : psa_status_t status;
64 : : size_t bits;
65 : :
66 : : *p_rsa = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
67 : : if (*p_rsa == NULL) {
68 : : return PSA_ERROR_INSUFFICIENT_MEMORY;
69 : : }
70 : : mbedtls_rsa_init(*p_rsa);
71 : :
72 : : /* Parse the data. */
73 : : if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
74 : : status = mbedtls_to_psa_error(mbedtls_rsa_parse_key(*p_rsa, data, data_length));
75 : : } else {
76 : : status = mbedtls_to_psa_error(mbedtls_rsa_parse_pubkey(*p_rsa, data, data_length));
77 : : }
78 : : if (status != PSA_SUCCESS) {
79 : : goto exit;
80 : : }
81 : :
82 : : /* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
83 : : * supports non-byte-aligned key sizes, but not well. For example,
84 : : * mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
85 : : bits = PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(*p_rsa));
86 : : if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) {
87 : : status = PSA_ERROR_NOT_SUPPORTED;
88 : : goto exit;
89 : : }
90 : : status = psa_check_rsa_key_byte_aligned(*p_rsa);
91 : : if (status != PSA_SUCCESS) {
92 : : goto exit;
93 : : }
94 : :
95 : : exit:
96 : : return status;
97 : : }
98 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
99 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
100 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
101 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
102 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) ||
103 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
104 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
105 : :
106 : : #if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && \
107 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || \
108 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
109 : : psa_status_t mbedtls_psa_rsa_import_key(
110 : : const psa_key_attributes_t *attributes,
111 : : const uint8_t *data, size_t data_length,
112 : : uint8_t *key_buffer, size_t key_buffer_size,
113 : : size_t *key_buffer_length, size_t *bits)
114 : : {
115 : : psa_status_t status;
116 : : mbedtls_rsa_context *rsa = NULL;
117 : :
118 : : /* Parse input */
119 : : status = mbedtls_psa_rsa_load_representation(attributes->type,
120 : : data,
121 : : data_length,
122 : : &rsa);
123 : : if (status != PSA_SUCCESS) {
124 : : goto exit;
125 : : }
126 : :
127 : : *bits = (psa_key_bits_t) PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(rsa));
128 : :
129 : : /* Re-export the data to PSA export format, such that we can store export
130 : : * representation in the key slot. Export representation in case of RSA is
131 : : * the smallest representation that's allowed as input, so a straight-up
132 : : * allocation of the same size as the input buffer will be large enough. */
133 : : status = mbedtls_psa_rsa_export_key(attributes->type,
134 : : rsa,
135 : : key_buffer,
136 : : key_buffer_size,
137 : : key_buffer_length);
138 : : exit:
139 : : /* Always free the RSA object */
140 : : mbedtls_rsa_free(rsa);
141 : : mbedtls_free(rsa);
142 : :
143 : : return status;
144 : : }
145 : : #endif /* (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) &&
146 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) ||
147 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
148 : :
149 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
150 : : defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
151 : : psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type,
152 : : mbedtls_rsa_context *rsa,
153 : : uint8_t *data,
154 : : size_t data_size,
155 : : size_t *data_length)
156 : : {
157 : : int ret;
158 : : uint8_t *end = data + data_size;
159 : :
160 : : /* PSA Crypto API defines the format of an RSA key as a DER-encoded
161 : : * representation of the non-encrypted PKCS#1 RSAPrivateKey for a
162 : : * private key and of the RFC3279 RSAPublicKey for a public key. */
163 : : if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
164 : : ret = mbedtls_rsa_write_key(rsa, data, &end);
165 : : } else {
166 : : ret = mbedtls_rsa_write_pubkey(rsa, data, &end);
167 : : }
168 : :
169 : : if (ret < 0) {
170 : : /* Clean up in case pk_write failed halfway through. */
171 : : memset(data, 0, data_size);
172 : : return mbedtls_to_psa_error(ret);
173 : : }
174 : :
175 : : /* The mbedtls_pk_xxx functions write to the end of the buffer.
176 : : * Move the data to the beginning and erase remaining data
177 : : * at the original location. */
178 : : if (2 * (size_t) ret <= data_size) {
179 : : memcpy(data, data + data_size - ret, ret);
180 : : memset(data + data_size - ret, 0, ret);
181 : : } else if ((size_t) ret < data_size) {
182 : : memmove(data, data + data_size - ret, ret);
183 : : memset(data + ret, 0, data_size - ret);
184 : : }
185 : :
186 : : *data_length = ret;
187 : : return PSA_SUCCESS;
188 : : }
189 : :
190 : : psa_status_t mbedtls_psa_rsa_export_public_key(
191 : : const psa_key_attributes_t *attributes,
192 : : const uint8_t *key_buffer, size_t key_buffer_size,
193 : : uint8_t *data, size_t data_size, size_t *data_length)
194 : : {
195 : : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
196 : : mbedtls_rsa_context *rsa = NULL;
197 : :
198 : : status = mbedtls_psa_rsa_load_representation(
199 : : attributes->type, key_buffer, key_buffer_size, &rsa);
200 : : if (status == PSA_SUCCESS) {
201 : : status = mbedtls_psa_rsa_export_key(PSA_KEY_TYPE_RSA_PUBLIC_KEY,
202 : : rsa,
203 : : data,
204 : : data_size,
205 : : data_length);
206 : : }
207 : :
208 : : mbedtls_rsa_free(rsa);
209 : : mbedtls_free(rsa);
210 : :
211 : : return status;
212 : : }
213 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
214 : : * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
215 : :
216 : : #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
217 : : static psa_status_t psa_rsa_read_exponent(const uint8_t *e_bytes,
218 : : size_t e_length,
219 : : int *exponent)
220 : : {
221 : : size_t i;
222 : : uint32_t acc = 0;
223 : :
224 : : /* Mbed TLS encodes the public exponent as an int. For simplicity, only
225 : : * support values that fit in a 32-bit integer, which is larger than
226 : : * int on just about every platform anyway. */
227 : : if (e_length > sizeof(acc)) {
228 : : return PSA_ERROR_NOT_SUPPORTED;
229 : : }
230 : : for (i = 0; i < e_length; i++) {
231 : : acc = (acc << 8) | e_bytes[i];
232 : : }
233 : : if (acc > INT_MAX) {
234 : : return PSA_ERROR_NOT_SUPPORTED;
235 : : }
236 : : *exponent = acc;
237 : : return PSA_SUCCESS;
238 : : }
239 : :
240 : : psa_status_t mbedtls_psa_rsa_generate_key(
241 : : const psa_key_attributes_t *attributes,
242 : : const uint8_t *custom_data, size_t custom_data_length,
243 : : uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
244 : : {
245 : : psa_status_t status;
246 : : mbedtls_rsa_context rsa;
247 : : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
248 : : int exponent = 65537;
249 : :
250 : : if (custom_data_length != 0) {
251 : : status = psa_rsa_read_exponent(custom_data, custom_data_length,
252 : : &exponent);
253 : : if (status != PSA_SUCCESS) {
254 : : return status;
255 : : }
256 : : }
257 : :
258 : : mbedtls_rsa_init(&rsa);
259 : : ret = mbedtls_rsa_gen_key(&rsa,
260 : : mbedtls_psa_get_random,
261 : : MBEDTLS_PSA_RANDOM_STATE,
262 : : (unsigned int) attributes->bits,
263 : : exponent);
264 : : if (ret != 0) {
265 : : mbedtls_rsa_free(&rsa);
266 : : return mbedtls_to_psa_error(ret);
267 : : }
268 : :
269 : : status = mbedtls_psa_rsa_export_key(attributes->type,
270 : : &rsa, key_buffer, key_buffer_size,
271 : : key_buffer_length);
272 : : mbedtls_rsa_free(&rsa);
273 : :
274 : : return status;
275 : : }
276 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */
277 : :
278 : : /****************************************************************/
279 : : /* Sign/verify hashes */
280 : : /****************************************************************/
281 : :
282 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
283 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
284 : :
285 : : /* Decode the hash algorithm from alg and store the mbedtls encoding in
286 : : * md_alg. Verify that the hash length is acceptable. */
287 : : static psa_status_t psa_rsa_decode_md_type(psa_algorithm_t alg,
288 : : size_t hash_length,
289 : : mbedtls_md_type_t *md_alg)
290 : : {
291 : : psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
292 : : *md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
293 : :
294 : : /* The Mbed TLS RSA module uses an unsigned int for hash length
295 : : * parameters. Validate that it fits so that we don't risk an
296 : : * overflow later. */
297 : : #if SIZE_MAX > UINT_MAX
298 : : if (hash_length > UINT_MAX) {
299 : : return PSA_ERROR_INVALID_ARGUMENT;
300 : : }
301 : : #endif
302 : :
303 : : /* For signatures using a hash, the hash length must be correct. */
304 : : if (alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
305 : : if (*md_alg == MBEDTLS_MD_NONE) {
306 : : return PSA_ERROR_NOT_SUPPORTED;
307 : : }
308 : : if (mbedtls_md_get_size_from_type(*md_alg) != hash_length) {
309 : : return PSA_ERROR_INVALID_ARGUMENT;
310 : : }
311 : : }
312 : :
313 : : return PSA_SUCCESS;
314 : : }
315 : :
316 : : psa_status_t mbedtls_psa_rsa_sign_hash(
317 : : const psa_key_attributes_t *attributes,
318 : : const uint8_t *key_buffer, size_t key_buffer_size,
319 : : psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
320 : : uint8_t *signature, size_t signature_size, size_t *signature_length)
321 : : {
322 : : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
323 : : mbedtls_rsa_context *rsa = NULL;
324 : : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
325 : : mbedtls_md_type_t md_alg;
326 : :
327 : : status = mbedtls_psa_rsa_load_representation(attributes->type,
328 : : key_buffer,
329 : : key_buffer_size,
330 : : &rsa);
331 : : if (status != PSA_SUCCESS) {
332 : : goto exit;
333 : : }
334 : :
335 : : status = psa_rsa_decode_md_type(alg, hash_length, &md_alg);
336 : : if (status != PSA_SUCCESS) {
337 : : goto exit;
338 : : }
339 : :
340 : : if (signature_size < mbedtls_rsa_get_len(rsa)) {
341 : : status = PSA_ERROR_BUFFER_TOO_SMALL;
342 : : goto exit;
343 : : }
344 : :
345 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
346 : : if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
347 : : ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15,
348 : : MBEDTLS_MD_NONE);
349 : : if (ret == 0) {
350 : : ret = mbedtls_rsa_pkcs1_sign(rsa,
351 : : mbedtls_psa_get_random,
352 : : MBEDTLS_PSA_RANDOM_STATE,
353 : : md_alg,
354 : : (unsigned int) hash_length,
355 : : hash,
356 : : signature);
357 : : }
358 : : } else
359 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
360 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
361 : : if (PSA_ALG_IS_RSA_PSS(alg)) {
362 : : ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
363 : :
364 : : if (ret == 0) {
365 : : ret = mbedtls_rsa_rsassa_pss_sign(rsa,
366 : : mbedtls_psa_get_random,
367 : : MBEDTLS_PSA_RANDOM_STATE,
368 : : MBEDTLS_MD_NONE,
369 : : (unsigned int) hash_length,
370 : : hash,
371 : : signature);
372 : : }
373 : : } else
374 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
375 : : {
376 : : status = PSA_ERROR_INVALID_ARGUMENT;
377 : : goto exit;
378 : : }
379 : :
380 : : if (ret == 0) {
381 : : *signature_length = mbedtls_rsa_get_len(rsa);
382 : : }
383 : : status = mbedtls_to_psa_error(ret);
384 : :
385 : : exit:
386 : : mbedtls_rsa_free(rsa);
387 : : mbedtls_free(rsa);
388 : :
389 : : return status;
390 : : }
391 : :
392 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
393 : : static int rsa_pss_expected_salt_len(psa_algorithm_t alg,
394 : : const mbedtls_rsa_context *rsa,
395 : : size_t hash_length)
396 : : {
397 : : if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
398 : : return MBEDTLS_RSA_SALT_LEN_ANY;
399 : : }
400 : : /* Otherwise: standard salt length, i.e. largest possible salt length
401 : : * up to the hash length. */
402 : : int klen = (int) mbedtls_rsa_get_len(rsa); // known to fit
403 : : int hlen = (int) hash_length; // known to fit
404 : : int room = klen - 2 - hlen;
405 : : if (room < 0) {
406 : : return 0; // there is no valid signature in this case anyway
407 : : } else if (room > hlen) {
408 : : return hlen;
409 : : } else {
410 : : return room;
411 : : }
412 : : }
413 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
414 : :
415 : : psa_status_t mbedtls_psa_rsa_verify_hash(
416 : : const psa_key_attributes_t *attributes,
417 : : const uint8_t *key_buffer, size_t key_buffer_size,
418 : : psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
419 : : const uint8_t *signature, size_t signature_length)
420 : : {
421 : : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
422 : : mbedtls_rsa_context *rsa = NULL;
423 : : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
424 : : mbedtls_md_type_t md_alg;
425 : :
426 : : status = mbedtls_psa_rsa_load_representation(attributes->type,
427 : : key_buffer,
428 : : key_buffer_size,
429 : : &rsa);
430 : : if (status != PSA_SUCCESS) {
431 : : goto exit;
432 : : }
433 : :
434 : : status = psa_rsa_decode_md_type(alg, hash_length, &md_alg);
435 : : if (status != PSA_SUCCESS) {
436 : : goto exit;
437 : : }
438 : :
439 : : if (signature_length != mbedtls_rsa_get_len(rsa)) {
440 : : status = PSA_ERROR_INVALID_SIGNATURE;
441 : : goto exit;
442 : : }
443 : :
444 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
445 : : if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
446 : : ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15,
447 : : MBEDTLS_MD_NONE);
448 : : if (ret == 0) {
449 : : ret = mbedtls_rsa_pkcs1_verify(rsa,
450 : : md_alg,
451 : : (unsigned int) hash_length,
452 : : hash,
453 : : signature);
454 : : }
455 : : } else
456 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
457 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
458 : : if (PSA_ALG_IS_RSA_PSS(alg)) {
459 : : ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
460 : : if (ret == 0) {
461 : : int slen = rsa_pss_expected_salt_len(alg, rsa, hash_length);
462 : : ret = mbedtls_rsa_rsassa_pss_verify_ext(rsa,
463 : : md_alg,
464 : : (unsigned) hash_length,
465 : : hash,
466 : : md_alg,
467 : : slen,
468 : : signature);
469 : : }
470 : : } else
471 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
472 : : {
473 : : status = PSA_ERROR_INVALID_ARGUMENT;
474 : : goto exit;
475 : : }
476 : :
477 : : /* Mbed TLS distinguishes "invalid padding" from "valid padding but
478 : : * the rest of the signature is invalid". This has little use in
479 : : * practice and PSA doesn't report this distinction. */
480 : : status = (ret == MBEDTLS_ERR_RSA_INVALID_PADDING) ?
481 : : PSA_ERROR_INVALID_SIGNATURE :
482 : : mbedtls_to_psa_error(ret);
483 : :
484 : : exit:
485 : : mbedtls_rsa_free(rsa);
486 : : mbedtls_free(rsa);
487 : :
488 : : return status;
489 : : }
490 : :
491 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
492 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
493 : :
494 : : /****************************************************************/
495 : : /* Asymmetric cryptography */
496 : : /****************************************************************/
497 : :
498 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
499 : : static int psa_rsa_oaep_set_padding_mode(psa_algorithm_t alg,
500 : : mbedtls_rsa_context *rsa)
501 : : {
502 : : psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH(alg);
503 : : mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
504 : :
505 : : /* Just to get the error status right, as rsa_set_padding() doesn't
506 : : * distinguish between "bad RSA algorithm" and "unknown hash". */
507 : : if (mbedtls_md_info_from_type(md_alg) == NULL) {
508 : : return PSA_ERROR_NOT_SUPPORTED;
509 : : }
510 : :
511 : : return mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
512 : : }
513 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
514 : :
515 : 0 : psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attributes,
516 : : const uint8_t *key_buffer,
517 : : size_t key_buffer_size,
518 : : psa_algorithm_t alg,
519 : : const uint8_t *input,
520 : : size_t input_length,
521 : : const uint8_t *salt,
522 : : size_t salt_length,
523 : : uint8_t *output,
524 : : size_t output_size,
525 : : size_t *output_length)
526 : : {
527 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
528 : 0 : (void) key_buffer;
529 : 0 : (void) key_buffer_size;
530 : 0 : (void) input;
531 : 0 : (void) input_length;
532 : 0 : (void) salt;
533 : 0 : (void) salt_length;
534 : 0 : (void) output;
535 : 0 : (void) output_size;
536 : 0 : (void) output_length;
537 : :
538 [ # # ]: 0 : if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
539 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
540 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
541 : : mbedtls_rsa_context *rsa = NULL;
542 : : status = mbedtls_psa_rsa_load_representation(attributes->type,
543 : : key_buffer,
544 : : key_buffer_size,
545 : : &rsa);
546 : : if (status != PSA_SUCCESS) {
547 : : goto rsa_exit;
548 : : }
549 : :
550 : : if (output_size < mbedtls_rsa_get_len(rsa)) {
551 : : status = PSA_ERROR_BUFFER_TOO_SMALL;
552 : : goto rsa_exit;
553 : : }
554 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
555 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
556 [ # # ]: 0 : if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
557 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
558 : : status = mbedtls_to_psa_error(
559 : : mbedtls_rsa_pkcs1_encrypt(rsa,
560 : : mbedtls_psa_get_random,
561 : : MBEDTLS_PSA_RANDOM_STATE,
562 : : input_length,
563 : : input,
564 : : output));
565 : : #else
566 : : status = PSA_ERROR_NOT_SUPPORTED;
567 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
568 : : } else
569 [ # # ]: 0 : if (PSA_ALG_IS_RSA_OAEP(alg)) {
570 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
571 : : status = mbedtls_to_psa_error(
572 : : psa_rsa_oaep_set_padding_mode(alg, rsa));
573 : : if (status != PSA_SUCCESS) {
574 : : goto rsa_exit;
575 : : }
576 : :
577 : : status = mbedtls_to_psa_error(
578 : : mbedtls_rsa_rsaes_oaep_encrypt(rsa,
579 : : mbedtls_psa_get_random,
580 : : MBEDTLS_PSA_RANDOM_STATE,
581 : : salt, salt_length,
582 : : input_length,
583 : : input,
584 : : output));
585 : : #else
586 : : status = PSA_ERROR_NOT_SUPPORTED;
587 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
588 : : } else {
589 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
590 : : }
591 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
592 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
593 : : rsa_exit:
594 : : if (status == PSA_SUCCESS) {
595 : : *output_length = mbedtls_rsa_get_len(rsa);
596 : : }
597 : :
598 : : mbedtls_rsa_free(rsa);
599 : : mbedtls_free(rsa);
600 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
601 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
602 : : } else {
603 : : status = PSA_ERROR_NOT_SUPPORTED;
604 : : }
605 : :
606 : 0 : return status;
607 : : }
608 : :
609 : 0 : psa_status_t mbedtls_psa_asymmetric_decrypt(const psa_key_attributes_t *attributes,
610 : : const uint8_t *key_buffer,
611 : : size_t key_buffer_size,
612 : : psa_algorithm_t alg,
613 : : const uint8_t *input,
614 : : size_t input_length,
615 : : const uint8_t *salt,
616 : : size_t salt_length,
617 : : uint8_t *output,
618 : : size_t output_size,
619 : : size_t *output_length)
620 : : {
621 : 0 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
622 : 0 : (void) key_buffer;
623 : 0 : (void) key_buffer_size;
624 : 0 : (void) input;
625 : 0 : (void) input_length;
626 : 0 : (void) salt;
627 : 0 : (void) salt_length;
628 : 0 : (void) output;
629 : 0 : (void) output_size;
630 : 0 : (void) output_length;
631 : :
632 : 0 : *output_length = 0;
633 : :
634 [ # # ]: 0 : if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
635 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
636 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
637 : : mbedtls_rsa_context *rsa = NULL;
638 : : status = mbedtls_psa_rsa_load_representation(attributes->type,
639 : : key_buffer,
640 : : key_buffer_size,
641 : : &rsa);
642 : : if (status != PSA_SUCCESS) {
643 : : goto rsa_exit;
644 : : }
645 : :
646 : : if (input_length != mbedtls_rsa_get_len(rsa)) {
647 : : status = PSA_ERROR_INVALID_ARGUMENT;
648 : : goto rsa_exit;
649 : : }
650 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
651 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
652 : :
653 [ # # ]: 0 : if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
654 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
655 : : status = mbedtls_to_psa_error(
656 : : mbedtls_rsa_pkcs1_decrypt(rsa,
657 : : mbedtls_psa_get_random,
658 : : MBEDTLS_PSA_RANDOM_STATE,
659 : : output_length,
660 : : input,
661 : : output,
662 : : output_size));
663 : : #else
664 : : status = PSA_ERROR_NOT_SUPPORTED;
665 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
666 : : } else
667 [ # # ]: 0 : if (PSA_ALG_IS_RSA_OAEP(alg)) {
668 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
669 : : status = mbedtls_to_psa_error(
670 : : psa_rsa_oaep_set_padding_mode(alg, rsa));
671 : : if (status != PSA_SUCCESS) {
672 : : goto rsa_exit;
673 : : }
674 : :
675 : : status = mbedtls_to_psa_error(
676 : : mbedtls_rsa_rsaes_oaep_decrypt(rsa,
677 : : mbedtls_psa_get_random,
678 : : MBEDTLS_PSA_RANDOM_STATE,
679 : : salt, salt_length,
680 : : output_length,
681 : : input,
682 : : output,
683 : : output_size));
684 : : #else
685 : : status = PSA_ERROR_NOT_SUPPORTED;
686 : : #endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
687 : : } else {
688 : 0 : status = PSA_ERROR_INVALID_ARGUMENT;
689 : : }
690 : :
691 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
692 : : defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
693 : : rsa_exit:
694 : : mbedtls_rsa_free(rsa);
695 : : mbedtls_free(rsa);
696 : : #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
697 : : * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
698 : : } else {
699 : : status = PSA_ERROR_NOT_SUPPORTED;
700 : : }
701 : :
702 : 0 : return status;
703 : : }
704 : :
705 : : #endif /* MBEDTLS_PSA_CRYPTO_C */
|