aboutsummaryrefslogtreecommitdiff
path: root/components/service/crypto/client/psa/psa_asymmetric_encrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'components/service/crypto/client/psa/psa_asymmetric_encrypt.c')
-rw-r--r--components/service/crypto/client/psa/psa_asymmetric_encrypt.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/components/service/crypto/client/psa/psa_asymmetric_encrypt.c b/components/service/crypto/client/psa/psa_asymmetric_encrypt.c
new file mode 100644
index 000000000..881ef7b20
--- /dev/null
+++ b/components/service/crypto/client/psa/psa_asymmetric_encrypt.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <psa/crypto.h>
+#include "psa_crypto_client.h"
+#include <protocols/rpc/common/packed-c/status.h>
+#include <protocols/service/crypto/packed-c/opcodes.h>
+#include <protocols/service/crypto/packed-c/asymmetric_encrypt.h>
+#include <common/tlv/tlv.h>
+
+
+psa_status_t psa_asymmetric_encrypt(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length)
+{
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_asymmetric_encrypt_in req_msg;
+ size_t req_fixed_len = sizeof(struct ts_crypto_asymmetric_encrypt_in);
+ size_t req_len = req_fixed_len;
+
+ *output_length = 0; /* For failure case */
+
+ req_msg.id = id;
+ req_msg.alg = alg;
+
+ /* Mandatory parameter */
+ struct tlv_record plaintext_record;
+ plaintext_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_PLAINTEXT;
+ plaintext_record.length = input_length;
+ plaintext_record.value = input;
+ req_len += tlv_required_space(plaintext_record.length);
+
+ /* Optional parameter */
+ struct tlv_record salt_record;
+ salt_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_SALT;
+ salt_record.length = (salt) ? salt_length : 0;
+ salt_record.value = salt;
+ if (salt) req_len += tlv_required_space(salt_record.length);
+
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus = PSA_ERROR_GENERIC_ERROR;
+ struct tlv_iterator req_iter;
+
+ memcpy(req_buf, &req_msg, req_fixed_len);
+
+ tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
+ tlv_encode(&req_iter, &plaintext_record);
+ if (salt) tlv_encode(&req_iter, &salt_record);
+
+ psa_crypto_client_instance.rpc_status =
+ rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
+ TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, &opstatus, &resp_buf, &resp_len);
+
+ if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ psa_status = opstatus;
+
+ if (psa_status == PSA_SUCCESS) {
+
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+ tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+
+ if (tlv_find_decode(&resp_iter,
+ TS_CRYPTO_ASYMMETRIC_ENCRYPT_OUT_TAG_CIPHERTEXT, &decoded_record)) {
+
+ if (decoded_record.length <= output_size) {
+
+ memcpy(output, decoded_record.value, decoded_record.length);
+ *output_length = decoded_record.length;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Mandatory response parameter missing */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
+
+ rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
+ }
+
+ return psa_status;
+}