blob: bfca5462f7b491b67da5604f00133d4b80477e9e [file] [log] [blame]
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +01001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <stddef.h>
9#include <stdint.h>
10
Summer Qin4b1d03b2019-07-02 14:56:08 +080011/* FixMe: Use PSA_ERROR_CONNECTION_REFUSED when performing parameter
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010012 * integrity checks but this will have to be revised
13 * when the full set of error codes mandated by PSA FF
14 * is available.
15 */
16#include "tfm_mbedcrypto_include.h"
17
18#include "tfm_crypto_api.h"
19#include "tfm_crypto_defs.h"
20
21/*!
22 * \defgroup public_psa Public functions, PSA
23 *
24 */
25
26/*!@{*/
27psa_status_t tfm_crypto_asymmetric_sign(psa_invec in_vec[],
28 size_t in_len,
29 psa_outvec out_vec[],
30 size_t out_len)
31{
Kevin Peng96f802e2019-12-26 16:10:25 +080032#ifdef TFM_CRYPTO_ASYMMETRIC_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +010033 return PSA_ERROR_NOT_SUPPORTED;
34#else
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010035 if ((in_len != 2) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +080036 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010037 }
38
39 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +080040 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010041 }
42 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
43
44 psa_key_handle_t handle = iov->key_handle;
45 psa_algorithm_t alg = iov->alg;
46 const uint8_t *hash = in_vec[1].base;
47 size_t hash_length = in_vec[1].len;
48 uint8_t *signature = out_vec[0].base;
49 size_t signature_size = out_vec[0].len;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010050 psa_status_t status = tfm_crypto_check_handle_owner(handle, NULL);
51
52 if (status != PSA_SUCCESS) {
53 return status;
54 }
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010055
56 return psa_asymmetric_sign(handle, alg, hash, hash_length,
57 signature, signature_size, &(out_vec[0].len));
Antonio de Angelis7740b382019-07-16 10:59:25 +010058#endif /* TFM_CRYPTO_ASYMMETRIC_MODULE_DISABLED */
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010059}
60
61psa_status_t tfm_crypto_asymmetric_verify(psa_invec in_vec[],
62 size_t in_len,
63 psa_outvec out_vec[],
64 size_t out_len)
65{
Kevin Peng96f802e2019-12-26 16:10:25 +080066#ifdef TFM_CRYPTO_ASYMMETRIC_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +010067 return PSA_ERROR_NOT_SUPPORTED;
68#else
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010069 if ((in_len != 3) || (out_len != 0)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +080070 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010071 }
72
73 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +080074 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010075 }
76 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
77
78 psa_key_handle_t handle = iov->key_handle;
79 psa_algorithm_t alg = iov->alg;
80 const uint8_t *hash = in_vec[1].base;
81 size_t hash_length = in_vec[1].len;
82 const uint8_t *signature = in_vec[2].base;
83 size_t signature_length = in_vec[2].len;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010084 psa_status_t status = tfm_crypto_check_handle_owner(handle, NULL);
85
86 if (status != PSA_SUCCESS) {
87 return status;
88 }
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010089
90 return psa_asymmetric_verify(handle, alg, hash, hash_length,
91 signature, signature_length);
Antonio de Angelis7740b382019-07-16 10:59:25 +010092#endif /* TFM_CRYPTO_ASYMMETRIC_MODULE_DISABLED */
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010093}
94
95psa_status_t tfm_crypto_asymmetric_encrypt(psa_invec in_vec[],
96 size_t in_len,
97 psa_outvec out_vec[],
98 size_t out_len)
99{
Kevin Peng96f802e2019-12-26 16:10:25 +0800100#ifdef TFM_CRYPTO_ASYMMETRIC_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100101 return PSA_ERROR_NOT_SUPPORTED;
102#else
Jamie Fox707caf72019-05-29 15:14:18 +0100103 psa_status_t status;
104
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100105 if (!((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800106 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100107 }
108
109 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800110 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100111 }
112 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
113
114 psa_key_handle_t handle = iov->key_handle;
115 psa_algorithm_t alg = iov->alg;
116 const uint8_t *input = in_vec[1].base;
117 size_t input_length = in_vec[1].len;
118 const uint8_t *salt = NULL;
119 size_t salt_length = 0;
120 uint8_t *output = out_vec[0].base;
121 size_t output_size = out_vec[0].len;
Jamie Fox707caf72019-05-29 15:14:18 +0100122 psa_key_type_t type;
123 size_t key_bits;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100124
125 if (in_len == 3) {
126 salt = in_vec[2].base;
127 salt_length = in_vec[2].len;
128 }
129
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100130 status = tfm_crypto_check_handle_owner(handle, NULL);
131 if (status != PSA_SUCCESS) {
132 return status;
133 }
134
Jamie Fox707caf72019-05-29 15:14:18 +0100135 status = psa_get_key_information(handle, &type, &key_bits);
136 if (status != PSA_SUCCESS) {
137 return status;
138 }
139
140 /* Check that the output buffer is large enough */
141 if (output_size < PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(type, key_bits, alg)) {
142 return PSA_ERROR_BUFFER_TOO_SMALL;
143 }
144
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100145 return psa_asymmetric_encrypt(handle, alg, input, input_length,
146 salt, salt_length,
147 output, output_size, &(out_vec[0].len));
Antonio de Angelis7740b382019-07-16 10:59:25 +0100148#endif /* TFM_CRYPTO_ASYMMETRIC_MODULE_DISABLED */
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100149}
150
151psa_status_t tfm_crypto_asymmetric_decrypt(psa_invec in_vec[],
152 size_t in_len,
153 psa_outvec out_vec[],
154 size_t out_len)
155{
Kevin Peng96f802e2019-12-26 16:10:25 +0800156#ifdef TFM_CRYPTO_ASYMMETRIC_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100157 return PSA_ERROR_NOT_SUPPORTED;
158#else
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100159 if (!((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800160 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100161 }
162
163 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800164 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100165 }
166 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
167
168 psa_key_handle_t handle = iov->key_handle;
169 psa_algorithm_t alg = iov->alg;
170 const uint8_t *input = in_vec[1].base;
171 size_t input_length = in_vec[1].len;
172 const uint8_t *salt = NULL;
173 size_t salt_length = 0;
174 uint8_t *output = out_vec[0].base;
175 size_t output_size = out_vec[0].len;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100176 psa_status_t status;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100177
178 if (in_len == 3) {
179 salt = in_vec[2].base;
180 salt_length = in_vec[2].len;
181 }
182
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100183 status = tfm_crypto_check_handle_owner(handle, NULL);
184 if (status != PSA_SUCCESS) {
185 return status;
186 }
187
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100188 return psa_asymmetric_decrypt(handle, alg, input, input_length,
189 salt, salt_length,
190 output, output_size, &(out_vec[0].len));
Antonio de Angelis7740b382019-07-16 10:59:25 +0100191#endif /* TFM_CRYPTO_ASYMMETRIC_MODULE_DISABLED */
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100192}
193/*!@}*/