blob: 57c7f9295c776ae0b497da03e183781219189ec7 [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
11/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
12 * 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{
32 if ((in_len != 2) || (out_len != 1)) {
33 return PSA_CONNECTION_REFUSED;
34 }
35
36 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
37 return PSA_CONNECTION_REFUSED;
38 }
39 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
40
41 psa_key_handle_t handle = iov->key_handle;
42 psa_algorithm_t alg = iov->alg;
43 const uint8_t *hash = in_vec[1].base;
44 size_t hash_length = in_vec[1].len;
45 uint8_t *signature = out_vec[0].base;
46 size_t signature_size = out_vec[0].len;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010047 psa_status_t status = tfm_crypto_check_handle_owner(handle, NULL);
48
49 if (status != PSA_SUCCESS) {
50 return status;
51 }
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010052
53 return psa_asymmetric_sign(handle, alg, hash, hash_length,
54 signature, signature_size, &(out_vec[0].len));
55}
56
57psa_status_t tfm_crypto_asymmetric_verify(psa_invec in_vec[],
58 size_t in_len,
59 psa_outvec out_vec[],
60 size_t out_len)
61{
62 if ((in_len != 3) || (out_len != 0)) {
63 return PSA_CONNECTION_REFUSED;
64 }
65
66 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
67 return PSA_CONNECTION_REFUSED;
68 }
69 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
70
71 psa_key_handle_t handle = iov->key_handle;
72 psa_algorithm_t alg = iov->alg;
73 const uint8_t *hash = in_vec[1].base;
74 size_t hash_length = in_vec[1].len;
75 const uint8_t *signature = in_vec[2].base;
76 size_t signature_length = in_vec[2].len;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010077 psa_status_t status = tfm_crypto_check_handle_owner(handle, NULL);
78
79 if (status != PSA_SUCCESS) {
80 return status;
81 }
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010082
83 return psa_asymmetric_verify(handle, alg, hash, hash_length,
84 signature, signature_length);
85}
86
87psa_status_t tfm_crypto_asymmetric_encrypt(psa_invec in_vec[],
88 size_t in_len,
89 psa_outvec out_vec[],
90 size_t out_len)
91{
Jamie Fox707caf72019-05-29 15:14:18 +010092 psa_status_t status;
93
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010094 if (!((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
95 return PSA_CONNECTION_REFUSED;
96 }
97
98 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
99 return PSA_CONNECTION_REFUSED;
100 }
101 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
102
103 psa_key_handle_t handle = iov->key_handle;
104 psa_algorithm_t alg = iov->alg;
105 const uint8_t *input = in_vec[1].base;
106 size_t input_length = in_vec[1].len;
107 const uint8_t *salt = NULL;
108 size_t salt_length = 0;
109 uint8_t *output = out_vec[0].base;
110 size_t output_size = out_vec[0].len;
Jamie Fox707caf72019-05-29 15:14:18 +0100111 psa_key_type_t type;
112 size_t key_bits;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100113
114 if (in_len == 3) {
115 salt = in_vec[2].base;
116 salt_length = in_vec[2].len;
117 }
118
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100119 status = tfm_crypto_check_handle_owner(handle, NULL);
120 if (status != PSA_SUCCESS) {
121 return status;
122 }
123
Jamie Fox707caf72019-05-29 15:14:18 +0100124 status = psa_get_key_information(handle, &type, &key_bits);
125 if (status != PSA_SUCCESS) {
126 return status;
127 }
128
129 /* Check that the output buffer is large enough */
130 if (output_size < PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(type, key_bits, alg)) {
131 return PSA_ERROR_BUFFER_TOO_SMALL;
132 }
133
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100134 return psa_asymmetric_encrypt(handle, alg, input, input_length,
135 salt, salt_length,
136 output, output_size, &(out_vec[0].len));
137}
138
139psa_status_t tfm_crypto_asymmetric_decrypt(psa_invec in_vec[],
140 size_t in_len,
141 psa_outvec out_vec[],
142 size_t out_len)
143{
144 if (!((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
145 return PSA_CONNECTION_REFUSED;
146 }
147
148 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
149 return PSA_CONNECTION_REFUSED;
150 }
151 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
152
153 psa_key_handle_t handle = iov->key_handle;
154 psa_algorithm_t alg = iov->alg;
155 const uint8_t *input = in_vec[1].base;
156 size_t input_length = in_vec[1].len;
157 const uint8_t *salt = NULL;
158 size_t salt_length = 0;
159 uint8_t *output = out_vec[0].base;
160 size_t output_size = out_vec[0].len;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100161 psa_status_t status;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100162
163 if (in_len == 3) {
164 salt = in_vec[2].base;
165 salt_length = in_vec[2].len;
166 }
167
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100168 status = tfm_crypto_check_handle_owner(handle, NULL);
169 if (status != PSA_SUCCESS) {
170 return status;
171 }
172
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100173 return psa_asymmetric_decrypt(handle, alg, input, input_length,
174 salt, salt_length,
175 output, output_size, &(out_vec[0].len));
176}
177/*!@}*/