summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJi Luo <ji.luo@nxp.com>2018-10-29 10:33:45 +0800
committerNitin Garg <nitin.garg@nxp.com>2018-11-02 20:50:08 -0500
commitced616aa4adcde2b4712ff8070cd0f6df9e7bdb5 (patch)
tree3be77fd6c24bebbb88b85a941cccb88b53beb4ce /lib
parent6a2f2e4e07bce45f6244ba1b78731d423dc31440 (diff)
MA-13233 [trusty] Add service 'hwcrypto'
Add new service 'hwcrypto' to handle CAAM related work with Trusty OS. Add tipc interface to accelerate hash calculation with CAAM. Test: Service connect and message exchange with Trusty OS are ok. Change-Id: Ia870c3ad2ff30af987f327a9777a8b32f53593db Signed-off-by: Ji Luo <ji.luo@nxp.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/trusty/ql-tipc/Makefile1
-rw-r--r--lib/trusty/ql-tipc/hwcrypto.c189
-rw-r--r--lib/trusty/ql-tipc/libtipc.c10
3 files changed, 200 insertions, 0 deletions
diff --git a/lib/trusty/ql-tipc/Makefile b/lib/trusty/ql-tipc/Makefile
index df68cc625f..5ee616ba93 100644
--- a/lib/trusty/ql-tipc/Makefile
+++ b/lib/trusty/ql-tipc/Makefile
@@ -33,6 +33,7 @@ ccflags-y += -I$(TRUSTY_DIR)/interface/include
QL_TIPC = .
obj-y += \
$(QL_TIPC)/avb.o \
+ $(QL_TIPC)/hwcrypto.o \
$(QL_TIPC)/keymaster.o \
$(QL_TIPC)/keymaster_serializable.o \
$(QL_TIPC)/ipc.o \
diff --git a/lib/trusty/ql-tipc/hwcrypto.c b/lib/trusty/ql-tipc/hwcrypto.c
new file mode 100644
index 0000000000..1cefdc46fa
--- /dev/null
+++ b/lib/trusty/ql-tipc/hwcrypto.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * Copyright NXP 2018
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <trusty/hwcrypto.h>
+#include <trusty/rpmb.h>
+#include <trusty/trusty_ipc.h>
+#include <trusty/util.h>
+#include "common.h"
+
+#define LOCAL_LOG 0
+
+static bool initialized;
+static struct trusty_ipc_chan hwcrypto_chan;
+
+static int hwcrypto_send_request(struct hwcrypto_message *msg, void *req, size_t req_len)
+{
+ struct trusty_ipc_iovec req_iovs[2] = {
+ { .base = msg, .len = sizeof(*msg) },
+ { .base = req, .len = req_len },
+ };
+
+ return trusty_ipc_send(&hwcrypto_chan, req_iovs, req ? 2 : 1, true);
+}
+
+static int hwcrypto_read_response(struct hwcrypto_message *msg, uint32_t cmd, void *resp,
+ size_t resp_len)
+{
+ int rc;
+ struct trusty_ipc_iovec resp_iovs[2] = {
+ { .base = msg, .len = sizeof(*msg) },
+ { .base = resp, .len = resp_len },
+ };
+
+ rc = trusty_ipc_recv(&hwcrypto_chan, resp_iovs, resp ? 2 : 1, true);
+ if (rc < 0) {
+ trusty_error("failed (%d) to recv response\n", rc);
+ return rc;
+ }
+ if (msg->cmd != (cmd | HWCRYPTO_RESP_BIT)) {
+ trusty_error("malformed response\n");
+ return TRUSTY_ERR_GENERIC;
+ }
+ /* return payload size */
+ return rc - sizeof(*msg);
+}
+
+/*
+ * Convenience function to send a request to the hwcrypto service and read the
+ * response.
+ *
+ * @cmd: the command
+ * @req: the request buffer
+ * @req_size: size of the request buffer
+ * @resp: the response buffer
+ * @resp_size_p: pointer to the size of the response buffer. changed to the
+ actual size of the response read from the secure side
+ * @handle_rpmb: true if the request is expected to invoke RPMB callbacks
+ */
+static int hwcrypto_do_tipc(uint32_t cmd, void *req, uint32_t req_size, void *resp,
+ uint32_t *resp_size_p, bool handle_rpmb)
+{
+ int rc;
+ struct hwcrypto_message msg = { .cmd = cmd };
+
+ if (!initialized) {
+ trusty_error("%s: HWCRYPTO TIPC client not initialized\n", __func__);
+ return TRUSTY_ERR_GENERIC;
+ }
+
+ rc = hwcrypto_send_request(&msg, req, req_size);
+ if (rc < 0) {
+ trusty_error("%s: failed (%d) to send hwcrypto request\n", __func__, rc);
+ return rc;
+ }
+
+ if (handle_rpmb) {
+ /* handle any incoming RPMB requests */
+ rc = rpmb_storage_proxy_poll();
+ if (rc < 0) {
+ trusty_error("%s: failed (%d) to get RPMB requests\n", __func__,
+ rc);
+ return rc;
+ }
+ }
+
+ uint32_t resp_size = resp_size_p ? *resp_size_p : 0;
+ rc = hwcrypto_read_response(&msg, cmd, resp, resp_size);
+ if (rc < 0) {
+ trusty_error("%s: failed (%d) to read HWCRYPTO response\n", __func__, rc);
+ return rc;
+ }
+ /* change response size to actual response size */
+ if (resp_size_p && rc != *resp_size_p) {
+ *resp_size_p = rc;
+ }
+ if (msg.result != HWCRYPTO_ERROR_NONE) {
+ trusty_error("%s: HWCRYPTO service returned error (%d)\n", __func__,
+ msg.result);
+ return TRUSTY_ERR_GENERIC;
+ }
+ return TRUSTY_ERR_NONE;
+}
+
+int hwcrypto_tipc_init(struct trusty_ipc_dev *dev)
+{
+ int rc;
+
+ trusty_assert(dev);
+ trusty_assert(!initialized);
+
+ trusty_ipc_chan_init(&hwcrypto_chan, dev);
+ trusty_debug("Connecting to hwcrypto service\n");
+
+ /* connect to hwcrypto service and wait for connect to complete */
+ rc = trusty_ipc_connect(&hwcrypto_chan, HWCRYPTO_PORT, true);
+ if (rc < 0) {
+ trusty_error("failed (%d) to connect to '%s'\n", rc, HWCRYPTO_PORT);
+ return rc;
+ }
+
+ /* mark as initialized */
+ initialized = true;
+
+ return TRUSTY_ERR_NONE;
+}
+
+void hwcrypto_tipc_shutdown(struct trusty_ipc_dev *dev)
+{
+ if (!initialized)
+ return; /* nothing to do */
+
+ /* close channel */
+ trusty_ipc_close(&hwcrypto_chan);
+
+ initialized = false;
+}
+
+int hwcrypto_hash(uint32_t in_addr, uint32_t in_len, uint32_t out_addr,
+ uint32_t out_len, enum hwcrypto_hash_algo algo)
+{
+ hwcrypto_hash_msg req;
+ unsigned long start, end;
+
+ /* check the address */
+ if (in_addr == 0 || out_addr == 0)
+ return TRUSTY_ERR_INVALID_ARGS;
+ /* fill the request buffer */
+ req.in_addr = in_addr;
+ req.out_addr = out_addr;
+ req.in_len = in_len;
+ req.out_len = out_len;
+ req.algo = algo;
+
+ /* flush dcache for input buffer */
+ start = (unsigned long)in_addr & ~(ARCH_DMA_MINALIGN - 1);
+ end = ALIGN((unsigned long)in_addr + in_len, ARCH_DMA_MINALIGN);
+ flush_dcache_range(start, end);
+
+ /* invalidate dcache for output buffer */
+ start = (unsigned long)out_addr & ~(ARCH_DMA_MINALIGN - 1);
+ end = ALIGN((unsigned long)out_addr + out_len, ARCH_DMA_MINALIGN);
+ invalidate_dcache_range(start, end);
+
+ int rc = hwcrypto_do_tipc(HWCRYPTO_HASH, (void*)&req,
+ sizeof(req), NULL, 0, false);
+ return rc;
+}
diff --git a/lib/trusty/ql-tipc/libtipc.c b/lib/trusty/ql-tipc/libtipc.c
index 0affd4aac2..03e6906de4 100644
--- a/lib/trusty/ql-tipc/libtipc.c
+++ b/lib/trusty/ql-tipc/libtipc.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 The Android Open Source Project
+ * Copyright NXP 2018
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -23,6 +24,7 @@
*/
#include <trusty/avb.h>
+#include <trusty/hwcrypto.h>
#include <trusty/keymaster.h>
#include <trusty/rpmb.h>
#include <trusty/trusty_dev.h>
@@ -45,6 +47,7 @@ void trusty_ipc_shutdown(void)
(void)avb_tipc_shutdown(_ipc_dev);
(void)km_tipc_shutdown(_ipc_dev);
+ (void)hwcrypto_tipc_shutdown(_ipc_dev);
/* shutdown Trusty IPC device */
(void)trusty_ipc_dev_shutdown(_ipc_dev);
@@ -98,5 +101,12 @@ int trusty_ipc_init(void)
return rc;
}
+ trusty_info("Initializing Trusty Hardware Crypto client\n");
+ rc = hwcrypto_tipc_init(_ipc_dev);
+ if (rc != 0) {
+ trusty_error("Initlializing Trusty Keymaster client failed (%d)\n", rc);
+ return rc;
+ }
+
return TRUSTY_ERR_NONE;
}