platform: msm: Add support for MDTP SCM call
Add support for SCM call to encrypt/decrypt the data integrity
partition (DIP) using a HW derived key.
This commit also fixes a bug in scm_call2 function, to support correctly
passing 5 parameters via SCM to TZ.
Change-Id: I04177a3ee72e17ccbac1421db8b9c92363fabb60
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index 03b61c9..b2137f6 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -759,6 +759,64 @@
}
}
+int mdtp_cipher_dip_cmd(uint8_t *in_buf, uint32_t in_buf_size, uint8_t *out_buf,
+ uint32_t out_buf_size, uint32_t direction)
+{
+ uint32_t svc_id;
+ uint32_t cmd_id;
+ void *cmd_buf;
+ void *rsp_buf;
+ size_t cmd_len;
+ size_t rsp_len;
+ mdtp_cipher_dip_req req;
+ scmcall_arg scm_arg = {0};
+ scmcall_ret scm_ret = {0};
+
+ ASSERT(in_buf != NULL);
+ ASSERT(out_buf != NULL);
+
+ req.in_buf = in_buf;
+ req.in_buf_size = in_buf_size;
+ req.out_buf = out_buf;
+ req.out_buf_size = out_buf_size;
+ req.direction = direction;
+
+ if (!scm_arm_support)
+ {
+ svc_id = SCM_SVC_MDTP;
+ cmd_id = SCM_MDTP_CIPHER_DIP;
+ cmd_buf = (void *)&req;
+ cmd_len = sizeof(req);
+ rsp_buf = NULL;
+ rsp_len = 0;
+
+ if (scm_call(svc_id, cmd_id, cmd_buf, cmd_len, rsp_buf, rsp_len))
+ {
+ dprintf(CRITICAL, "Failed to call Cipher DIP SCM\n");
+ return -1;
+ }
+ }
+ else
+ {
+ scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_MDTP, SCM_MDTP_CIPHER_DIP);
+ scm_arg.x1 = MAKE_SCM_ARGS(0x5, SMC_PARAM_TYPE_BUFFER_READ, SMC_PARAM_TYPE_VALUE,
+ SMC_PARAM_TYPE_BUFFER_READWRITE, SMC_PARAM_TYPE_VALUE, SMC_PARAM_TYPE_VALUE);
+ scm_arg.x2 = (uint32_t)req.in_buf;
+ scm_arg.x3 = req.in_buf_size;
+ scm_arg.x4 = (uint32_t)req.out_buf;
+ scm_arg.x5[0] = req.out_buf_size;
+ scm_arg.x5[1] = req.direction;
+
+ if (scm_call2(&scm_arg, &scm_ret))
+ {
+ dprintf(CRITICAL, "Failed in Cipher DIP SCM call\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
/*
* Switches the CE1 channel between ADM and register usage.
* channel : AP_CE_REGISTER_USE, CE1 uses register interface
@@ -996,7 +1054,7 @@
arg->x0 = arg->atomic ? (arg->x0 | SCM_ATOMIC_BIT) : arg->x0;
x5 = arg->x5[0];
- if ((arg->x1 & 0xF) > SCM_MAX_ARG_LEN)
+ if ((arg->x1 & 0xF) > SCM_MAX_ARG_LEN - 1)
{
indir_arg = memalign(CACHE_LINE, (SCM_INDIR_MAX_LEN * sizeof(uint32_t)));
ASSERT(indir_arg);