aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorSY Chiu <sy.chiu@linaro.org>2014-12-16 14:15:09 +0800
committerSY Chiu <sy.chiu@linaro.org>2015-01-23 18:11:33 +0800
commite4d3a4a68ce893f79ca024530d71c281af16041f (patch)
treee4d4dd9b859188e2abccfa3c318fb55a727135d5 /core
parent197d17e77afc49bd75fd35ebfd335c30d6855e3d (diff)
SE API: hide private interfaces
- Split each headers into module.h and module_priv.h, move the methods that is only used internally by SE implementation to module_priv.h, and export module_priv.h to rest of TEE Core - Added new include path to se_api_self_tests.c for which needs to include private headers - Split aid.c and apdu.c from iso7816.c. Originally they have to be wriiten in the same file since they share some private data structures. Now, the private data structure can be shared via private headers. - Split reader.c from manager.c for the same reason above. Signed-off-by: SY Chiu <sy.chiu@linaro.org> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Joakim Bech <joakim.bech@linaro.org> Tested-by: SY Chiu <sy.chiu@linaro.org> (Modified QEMU + jcardsim)
Diffstat (limited to 'core')
-rw-r--r--core/arch/arm32/sta/se_api_self_tests.c4
-rw-r--r--core/arch/arm32/sta/sub.mk1
-rw-r--r--core/include/tee/se/aid.h6
-rw-r--r--core/include/tee/se/apdu.h3
-rw-r--r--core/include/tee/se/channel.h22
-rw-r--r--core/include/tee/se/manager.h3
-rw-r--r--core/include/tee/se/reader.h21
-rw-r--r--core/include/tee/se/service.h12
-rw-r--r--core/include/tee/se/session.h16
-rw-r--r--core/include/tee/se/svc.h2
-rw-r--r--core/tee/se/aid.c90
-rw-r--r--core/tee/se/aid_priv.h43
-rw-r--r--core/tee/se/apdu.c183
-rw-r--r--core/tee/se/apdu_priv.h69
-rw-r--r--core/tee/se/channel.c3
-rw-r--r--core/tee/se/channel_priv.h47
-rw-r--r--core/tee/se/iso7816.c242
-rw-r--r--core/tee/se/manager.c186
-rw-r--r--core/tee/se/reader.c216
-rw-r--r--core/tee/se/reader_priv.h49
-rw-r--r--core/tee/se/service.c4
-rw-r--r--core/tee/se/service_priv.h42
-rw-r--r--core/tee/se/session.c3
-rw-r--r--core/tee/se/session_priv.h46
-rw-r--r--core/tee/se/sub.mk2
25 files changed, 819 insertions, 496 deletions
diff --git a/core/arch/arm32/sta/se_api_self_tests.c b/core/arch/arm32/sta/se_api_self_tests.c
index 47acba4..ecd5243 100644
--- a/core/arch/arm32/sta/se_api_self_tests.c
+++ b/core/arch/arm32/sta/se_api_self_tests.c
@@ -43,6 +43,10 @@
#include <stdlib.h>
#include <string.h>
+#include "aid_priv.h"
+#include "apdu_priv.h"
+#include "reader_priv.h"
+
#define TA_NAME "se_api_self_tests.ta"
diff --git a/core/arch/arm32/sta/sub.mk b/core/arch/arm32/sta/sub.mk
index f68db86..38300aa 100644
--- a/core/arch/arm32/sta/sub.mk
+++ b/core/arch/arm32/sta/sub.mk
@@ -3,4 +3,5 @@ srcs-y += core_self_tests.c
ifeq ($(WITH_SE_API),y)
srcs-${WITH_SE_API_SELF_TEST} += se_api_self_tests.c
+cppflags-se_api_self_tests.c-y += -Icore/tee/se
endif
diff --git a/core/include/tee/se/aid.h b/core/include/tee/se/aid.h
index e5fe233..ca5fb19 100644
--- a/core/include/tee/se/aid.h
+++ b/core/include/tee/se/aid.h
@@ -32,15 +32,9 @@
struct tee_se_aid;
-TEE_Result tee_se_aid_create(const char *name, struct tee_se_aid **aid);
-
TEE_Result tee_se_aid_create_from_buffer(uint8_t *id, size_t length,
struct tee_se_aid **aid);
-void tee_se_aid_acquire(struct tee_se_aid *aid);
-
void tee_se_aid_release(struct tee_se_aid *aid);
-int tee_se_aid_get_refcnt(struct tee_se_aid *aid);
-
#endif
diff --git a/core/include/tee/se/apdu.h b/core/include/tee/se/apdu.h
index 7262188..d923ea5 100644
--- a/core/include/tee/se/apdu.h
+++ b/core/include/tee/se/apdu.h
@@ -52,10 +52,9 @@ uint8_t *apdu_get_data(struct apdu_base *apdu);
size_t apdu_get_length(struct apdu_base *apdu);
-int apdu_get_refcnt(struct apdu_base *apdu);
-
void apdu_acquire(struct apdu_base *apdu);
void apdu_release(struct apdu_base *apdu);
+
#endif
diff --git a/core/include/tee/se/channel.h b/core/include/tee/se/channel.h
index 19c9db3..be6d986 100644
--- a/core/include/tee/se/channel.h
+++ b/core/include/tee/se/channel.h
@@ -28,31 +28,14 @@
#ifndef TEE_SE_CHANNEL_H
#define TEE_SE_CHANNEL_H
+struct tee_se_aid;
+
/*
* GP Card API define the maximum logical channel number is 20,
* Numbered from 0 ~ 19, number 0 is basic logical channel
*/
#define MAX_LOGICAL_CHANNEL 20
-struct tee_se_aid;
-
-struct tee_se_channel {
- int channel_id;
- struct tee_se_session *session;
- struct tee_se_aid *aid;
- struct resp_apdu *select_resp;
-
- TAILQ_ENTRY(tee_se_channel) link;
-};
-
-/* Channel allocator */
-struct tee_se_channel *tee_se_channel_alloc(struct tee_se_session *s,
- int channel_id);
-
-void tee_se_channel_free(struct tee_se_channel *c);
-
-
-/* Channel operators */
struct tee_se_session *tee_se_channel_get_session(struct tee_se_channel *c);
int tee_se_channel_get_id(struct tee_se_channel *c);
@@ -62,7 +45,6 @@ TEE_Result tee_se_channel_select_next(struct tee_se_channel *c);
TEE_Result tee_se_channel_select(struct tee_se_channel *c,
struct tee_se_aid *aid);
-
void tee_se_channel_set_aid(struct tee_se_channel *c,
struct tee_se_aid *aid);
diff --git a/core/include/tee/se/manager.h b/core/include/tee/se/manager.h
index c20b6b9..9c35f47 100644
--- a/core/include/tee/se/manager.h
+++ b/core/include/tee/se/manager.h
@@ -36,6 +36,9 @@ TEE_Result tee_se_manager_get_readers(
struct tee_se_reader_proxy **proxy_list,
size_t *proxy_list_size);
+bool tee_se_manager_is_reader_proxy_valid(
+ struct tee_se_reader_proxy *proxy);
+
size_t tee_se_manager_get_reader_count(void);
#endif
diff --git a/core/include/tee/se/reader.h b/core/include/tee/se/reader.h
index 3de5ae8..ac361dc 100644
--- a/core/include/tee/se/reader.h
+++ b/core/include/tee/se/reader.h
@@ -32,30 +32,15 @@
#include <kernel/mutex.h>
#include <sys/queue.h>
+struct tee_se_reader_proxy;
struct tee_se_session;
-/*
- * Reader Proxy is used to serialize access from multiple seesions,
- * and maintain reference counter. All access to the reader should
- * go through Reader Proxy
- */
-struct tee_se_reader_proxy {
- struct tee_se_reader *reader;
- int refcnt;
- bool basic_channel_locked;
- struct mutex mutex;
-
- TAILQ_ENTRY(tee_se_reader_proxy) link;
-};
-
TEE_Result tee_se_reader_get_name(struct tee_se_reader_proxy *proxy,
char **reader_name, size_t *reader_name_len);
void tee_se_reader_get_properties(struct tee_se_reader_proxy *proxy,
TEE_SEReaderProperties *prop);
-int tee_se_reader_get_refcnt(struct tee_se_reader_proxy *proxy);
-
TEE_Result tee_se_reader_attach(struct tee_se_reader_proxy *proxy);
void tee_se_reader_detach(struct tee_se_reader_proxy *proxy);
@@ -71,14 +56,10 @@ TEE_Result tee_se_reader_get_atr(struct tee_se_reader_proxy *proxy,
TEE_Result tee_se_reader_transmit(struct tee_se_reader_proxy *proxy,
uint8_t *tx_buf, size_t tx_buf_len, uint8_t *rx_buf, size_t *rx_buf_len);
-TEE_Result tee_se_reader_check_state(struct tee_se_reader_proxy *proxy);
-
void tee_se_reader_lock_basic_channel(struct tee_se_reader_proxy *proxy);
void tee_se_reader_unlock_basic_channel(struct tee_se_reader_proxy *proxy);
bool tee_se_reader_is_basic_channel_locked(struct tee_se_reader_proxy *proxy);
-bool tee_se_reader_is_proxy_valid(struct tee_se_reader_proxy *proxy);
-
#endif
diff --git a/core/include/tee/se/service.h b/core/include/tee/se/service.h
index 2e35da7..49d2084 100644
--- a/core/include/tee/se/service.h
+++ b/core/include/tee/se/service.h
@@ -31,21 +31,11 @@
#include <tee_api_types.h>
#include <kernel/mutex.h>
+struct tee_se_service;
struct tee_se_session;
struct tee_se_channel;
struct tee_se_reader_proxy;
-TAILQ_HEAD(se_session_head, tee_se_session);
-
-struct tee_se_service {
- /* list of sessions opened on the service */
- struct se_session_head opened_sessions;
- /* list of sessions closed on the service */
- struct se_session_head closed_sessions;
- /* mutex to pretect the session lists */
- struct mutex mutex;
-};
-
TEE_Result tee_se_service_open(
struct tee_se_service **service);
diff --git a/core/include/tee/se/session.h b/core/include/tee/se/session.h
index 98df69b..8ebc0e8 100644
--- a/core/include/tee/se/session.h
+++ b/core/include/tee/se/session.h
@@ -35,25 +35,11 @@
struct tee_se_reader_proxy;
struct tee_se_channel;
+struct tee_se_session;
struct tee_se_aid;
struct cmd_apdu;
struct resp_apdu;
-TAILQ_HEAD(channel_list, tee_se_channel);
-
-struct tee_se_session {
- struct tee_se_reader_proxy *reader_proxy;
-
- /* list of channels opened on the session*/
- struct channel_list channels;
-
- TAILQ_ENTRY(tee_se_session) link;
-};
-
-struct tee_se_session *tee_se_session_alloc(struct tee_se_reader_proxy *proxy);
-
-void tee_se_session_free(struct tee_se_session *s);
-
TEE_Result tee_se_session_open_basic_channel(struct tee_se_session *s,
struct tee_se_aid *aid, struct tee_se_channel **channel);
diff --git a/core/include/tee/se/svc.h b/core/include/tee/se/svc.h
index 08deebc..d8f2f38 100644
--- a/core/include/tee/se/svc.h
+++ b/core/include/tee/se/svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, STMicroelectronics International N.V.
+ * Copyright (c) 2014, Linaro Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/core/tee/se/aid.c b/core/tee/se/aid.c
new file mode 100644
index 0000000..d90e255
--- /dev/null
+++ b/core/tee/se/aid.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <tee_api_types.h>
+#include <trace.h>
+
+#include <kernel/tee_common_unpg.h>
+#include <tee/se/aid.h>
+#include <tee/se/util.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "aid_priv.h"
+
+TEE_Result tee_se_aid_create(const char *name, struct tee_se_aid **aid)
+{
+ size_t str_length = strlen(name);
+ size_t aid_length = str_length / 2;
+
+ TEE_ASSERT(aid != NULL && *aid == NULL);
+ if (str_length < MIN_AID_LENGTH || str_length > MAX_AID_LENGTH)
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ *aid = malloc(sizeof(struct tee_se_aid));
+ if (!(*aid))
+ return TEE_ERROR_OUT_OF_MEMORY;
+
+ hex_decode(name, str_length, (*aid)->aid);
+ (*aid)->length = aid_length;
+ (*aid)->refcnt = 1;
+ return TEE_SUCCESS;
+}
+
+TEE_Result tee_se_aid_create_from_buffer(uint8_t *id, size_t length,
+ struct tee_se_aid **aid)
+{
+ *aid = malloc(sizeof(struct tee_se_aid));
+ if (!(*aid))
+ return TEE_ERROR_OUT_OF_MEMORY;
+
+ memcpy((*aid)->aid, id, length);
+ (*aid)->length = length;
+ (*aid)->refcnt = 1;
+ return TEE_SUCCESS;
+}
+
+void tee_se_aid_acquire(struct tee_se_aid *aid)
+{
+ TEE_ASSERT(aid != NULL);
+ aid->refcnt++;
+}
+
+int tee_se_aid_get_refcnt(struct tee_se_aid *aid)
+{
+ TEE_ASSERT(aid != NULL);
+ return aid->refcnt;
+}
+
+void tee_se_aid_release(struct tee_se_aid *aid)
+{
+ TEE_ASSERT(aid != NULL && aid->refcnt > 0);
+ aid->refcnt--;
+ if (aid->refcnt == 0)
+ free(aid);
+}
diff --git a/core/tee/se/aid_priv.h b/core/tee/se/aid_priv.h
new file mode 100644
index 0000000..555246f
--- /dev/null
+++ b/core/tee/se/aid_priv.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEE_SE_AID_PRIV_H
+#define TEE_SE_AID_PRIV_H
+
+struct tee_se_aid {
+ uint8_t aid[MAX_AID_LENGTH];
+ size_t length;
+ int refcnt;
+};
+
+int tee_se_aid_get_refcnt(struct tee_se_aid *aid);
+
+TEE_Result tee_se_aid_create(const char *name, struct tee_se_aid **aid);
+
+void tee_se_aid_acquire(struct tee_se_aid *aid);
+
+#endif
diff --git a/core/tee/se/apdu.c b/core/tee/se/apdu.c
new file mode 100644
index 0000000..7276c5f
--- /dev/null
+++ b/core/tee/se/apdu.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <tee_api_types.h>
+#include <trace.h>
+
+#include <kernel/tee_common_unpg.h>
+#include <tee/se/apdu.h>
+#include <tee/se/util.h>
+
+#include <stdlib.h>
+
+#include "apdu_priv.h"
+
+/*
+ * APDU format, [..] means optional fields
+ *
+ * CMD_APDU: CLA, INS, P1, P2, [LC, DATA, LE]
+ * RESP_APDU: [DATA], SW1, SW2
+ *
+ */
+#define CMD_APDU_SIZE(lc) ((lc) + 4)
+#define RESP_APDU_SIZE(le) ((le) + 2)
+
+struct cmd_apdu *alloc_cmd_apdu(uint8_t cla, uint8_t ins, uint8_t p1,
+ uint8_t p2, uint8_t lc, uint8_t le, uint8_t *data)
+{
+ size_t apdu_length = CMD_APDU_SIZE(lc);
+ size_t total_length;
+ struct cmd_apdu *apdu;
+ uint8_t *buf;
+
+ /*
+ * check if we need to reserve space for LC/LE
+ * (both fields are optional)
+ */
+ if (lc)
+ apdu_length++;
+ if (le)
+ apdu_length++;
+
+ total_length = sizeof(struct cmd_apdu) + apdu_length;
+ apdu = malloc(total_length);
+
+ if (!apdu)
+ return NULL;
+
+ apdu->base.length = apdu_length;
+ apdu->base.data_buf = (uint8_t *)(apdu + 1);
+ apdu->base.refcnt = 1;
+
+ buf = apdu->base.data_buf;
+ buf[CLA] = cla;
+ buf[INS] = ins;
+ buf[P1] = p1;
+ buf[P2] = p2;
+ if (lc)
+ buf[LC] = lc;
+ if (data != NULL)
+ memmove(&buf[CDATA], data, lc);
+ if (le)
+ buf[CDATA + lc + OFF_LE] = le;
+
+ return apdu;
+}
+
+struct cmd_apdu *alloc_cmd_apdu_from_buf(uint8_t *buf, size_t length)
+{
+ struct cmd_apdu *apdu = malloc(sizeof(struct cmd_apdu));
+
+ if (!apdu)
+ return NULL;
+ apdu->base.length = length;
+ apdu->base.data_buf = buf;
+ apdu->base.refcnt = 1;
+ return apdu;
+}
+
+struct resp_apdu *alloc_resp_apdu(uint8_t le)
+{
+ size_t total_length = sizeof(struct resp_apdu) + RESP_APDU_SIZE(le);
+ struct resp_apdu *apdu;
+
+ apdu = malloc(total_length);
+
+ if (!apdu)
+ return NULL;
+
+ apdu->base.length = RESP_APDU_SIZE(le);
+ apdu->base.data_buf = (uint8_t *)(apdu + 1);
+ apdu->base.refcnt = 1;
+
+ return apdu;
+}
+
+uint8_t *resp_apdu_get_data(struct resp_apdu *apdu)
+{
+ TEE_ASSERT(apdu != NULL);
+ return apdu->resp_data;
+}
+
+size_t resp_apdu_get_data_len(struct resp_apdu *apdu)
+{
+ TEE_ASSERT(apdu != NULL);
+ return apdu->resp_data_len;
+}
+
+uint8_t resp_apdu_get_sw1(struct resp_apdu *apdu)
+{
+ TEE_ASSERT(apdu != NULL);
+ return apdu->sw1;
+}
+
+uint8_t resp_apdu_get_sw2(struct resp_apdu *apdu)
+{
+ TEE_ASSERT(apdu != NULL);
+ return apdu->sw2;
+}
+
+uint8_t *apdu_get_data(struct apdu_base *apdu)
+{
+ TEE_ASSERT(apdu != NULL);
+ return apdu->data_buf;
+}
+size_t apdu_get_length(struct apdu_base *apdu)
+{
+ TEE_ASSERT(apdu != NULL);
+ return apdu->length;
+}
+int apdu_get_refcnt(struct apdu_base *apdu)
+{
+ TEE_ASSERT(apdu != NULL);
+ return apdu->refcnt;
+}
+void apdu_acquire(struct apdu_base *apdu)
+{
+ TEE_ASSERT(apdu != NULL);
+ apdu->refcnt++;
+}
+void apdu_release(struct apdu_base *apdu)
+{
+ TEE_ASSERT(apdu != NULL);
+ apdu->refcnt--;
+ if (apdu->refcnt == 0)
+ free(apdu);
+}
+
+void parse_resp_apdu(struct resp_apdu *apdu)
+{
+ uint8_t *buf = apdu->base.data_buf;
+ /* resp data length = resp buf length - SW1 - SW2 */
+ apdu->resp_data_len = apdu->base.length - 2;
+ if (apdu->resp_data_len > 0)
+ apdu->resp_data = &buf[RDATA];
+ else
+ apdu->resp_data = NULL;
+ apdu->sw1 = buf[RDATA + apdu->resp_data_len + OFF_SW1];
+ apdu->sw2 = buf[RDATA + apdu->resp_data_len + OFF_SW2];
+}
diff --git a/core/tee/se/apdu_priv.h b/core/tee/se/apdu_priv.h
new file mode 100644
index 0000000..3d30050
--- /dev/null
+++ b/core/tee/se/apdu_priv.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEE_SE_APDU_PRIV_H
+#define TEE_SE_APDU_PRIV_H
+
+enum {
+ /* command APDU */
+ CLA = 0,
+ INS = 1,
+ P1 = 2,
+ P2 = 3,
+ LC = 4,
+ CDATA = 5,
+ OFF_LE = 0,
+
+ /* response APDU */
+ RDATA = 0,
+ OFF_SW1 = 0,
+ OFF_SW2 = 1,
+};
+
+struct apdu_base {
+ uint8_t *data_buf;
+ size_t length;
+ int refcnt;
+};
+
+struct cmd_apdu {
+ struct apdu_base base;
+};
+
+struct resp_apdu {
+ struct apdu_base base;
+ uint8_t sw1;
+ uint8_t sw2;
+ uint8_t *resp_data;
+ size_t resp_data_len;
+};
+
+void parse_resp_apdu(struct resp_apdu *apdu);
+
+int apdu_get_refcnt(struct apdu_base *apdu);
+
+#endif
diff --git a/core/tee/se/channel.c b/core/tee/se/channel.c
index 3cfe514..82cb0ad 100644
--- a/core/tee/se/channel.c
+++ b/core/tee/se/channel.c
@@ -38,6 +38,9 @@
#include <stdlib.h>
#include <string.h>
+#include "aid_priv.h"
+#include "channel_priv.h"
+
struct tee_se_channel *tee_se_channel_alloc(struct tee_se_session *s,
int channel_id)
{
diff --git a/core/tee/se/channel_priv.h b/core/tee/se/channel_priv.h
new file mode 100644
index 0000000..984a365
--- /dev/null
+++ b/core/tee/se/channel_priv.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEE_SE_CHANNEL_PRIV_H
+#define TEE_SE_CHANNEL_PRIV_H
+
+struct tee_se_aid;
+
+struct tee_se_channel {
+ int channel_id;
+ struct tee_se_session *session;
+ struct tee_se_aid *aid;
+ struct resp_apdu *select_resp;
+
+ TAILQ_ENTRY(tee_se_channel) link;
+};
+
+struct tee_se_channel *tee_se_channel_alloc(struct tee_se_session *s,
+ int channel_id);
+
+void tee_se_channel_free(struct tee_se_channel *c);
+
+#endif
diff --git a/core/tee/se/iso7816.c b/core/tee/se/iso7816.c
index 7c1eb9a..c007f10 100644
--- a/core/tee/se/iso7816.c
+++ b/core/tee/se/iso7816.c
@@ -41,245 +41,9 @@
#include <stdlib.h>
#include <string.h>
-enum {
- /* command APDU */
- CLA = 0,
- INS = 1,
- P1 = 2,
- P2 = 3,
- LC = 4,
- CDATA = 5,
- OFF_LE = 0,
-
- /* response APDU */
- RDATA = 0,
- OFF_SW1 = 0,
- OFF_SW2 = 1,
-};
-
-struct apdu_base {
- uint8_t *data_buf;
- size_t length;
- int refcnt;
-};
-
-struct cmd_apdu {
- struct apdu_base base;
-};
-
-struct resp_apdu {
- struct apdu_base base;
- uint8_t sw1;
- uint8_t sw2;
- uint8_t *resp_data;
- size_t resp_data_len;
-};
-
-struct tee_se_aid {
- uint8_t aid[MAX_AID_LENGTH];
- size_t length;
- int refcnt;
-};
-
-/*
- * APDU format, [..] means optional fields
- *
- * CMD_APDU: CLA, INS, P1, P2, [LC, DATA, LE]
- * RESP_APDU: [DATA], SW1, SW2
- *
- */
-#define CMD_APDU_SIZE(lc) ((lc) + 4)
-#define RESP_APDU_SIZE(le) ((le) + 2)
-
-struct cmd_apdu *alloc_cmd_apdu(uint8_t cla, uint8_t ins, uint8_t p1,
- uint8_t p2, uint8_t lc, uint8_t le, uint8_t *data)
-{
- size_t apdu_length = CMD_APDU_SIZE(lc);
- size_t total_length;
- struct cmd_apdu *apdu;
- uint8_t *buf;
-
- /*
- * check if we need to reserve space for LC/LE
- * (both fields are optional)
- */
- if (lc)
- apdu_length++;
- if (le)
- apdu_length++;
-
- total_length = sizeof(struct cmd_apdu) + apdu_length;
- apdu = malloc(total_length);
-
- if (!apdu)
- return NULL;
-
- apdu->base.length = apdu_length;
- apdu->base.data_buf = (uint8_t *)(apdu + 1);
- apdu->base.refcnt = 1;
-
- buf = apdu->base.data_buf;
- buf[CLA] = cla;
- buf[INS] = ins;
- buf[P1] = p1;
- buf[P2] = p2;
- if (lc)
- buf[LC] = lc;
- if (data != NULL)
- memmove(&buf[CDATA], data, lc);
- if (le)
- buf[CDATA + lc + OFF_LE] = le;
-
- return apdu;
-}
-
-struct cmd_apdu *alloc_cmd_apdu_from_buf(uint8_t *buf, size_t length)
-{
- struct cmd_apdu *apdu = malloc(sizeof(struct cmd_apdu));
-
- if (!apdu)
- return NULL;
- apdu->base.length = length;
- apdu->base.data_buf = buf;
- apdu->base.refcnt = 1;
- return apdu;
-}
-
-struct resp_apdu *alloc_resp_apdu(uint8_t le)
-{
- size_t total_length = sizeof(struct resp_apdu) + RESP_APDU_SIZE(le);
- struct resp_apdu *apdu;
-
- apdu = malloc(total_length);
-
- if (!apdu)
- return NULL;
-
- apdu->base.length = RESP_APDU_SIZE(le);
- apdu->base.data_buf = (uint8_t *)(apdu + 1);
- apdu->base.refcnt = 1;
-
- return apdu;
-}
-
-uint8_t *resp_apdu_get_data(struct resp_apdu *apdu)
-{
- TEE_ASSERT(apdu != NULL);
- return apdu->resp_data;
-}
-
-size_t resp_apdu_get_data_len(struct resp_apdu *apdu)
-{
- TEE_ASSERT(apdu != NULL);
- return apdu->resp_data_len;
-}
-
-uint8_t resp_apdu_get_sw1(struct resp_apdu *apdu)
-{
- TEE_ASSERT(apdu != NULL);
- return apdu->sw1;
-}
-
-uint8_t resp_apdu_get_sw2(struct resp_apdu *apdu)
-{
- TEE_ASSERT(apdu != NULL);
- return apdu->sw2;
-}
-
-uint8_t *apdu_get_data(struct apdu_base *apdu)
-{
- TEE_ASSERT(apdu != NULL);
- return apdu->data_buf;
-}
-size_t apdu_get_length(struct apdu_base *apdu)
-{
- TEE_ASSERT(apdu != NULL);
- return apdu->length;
-}
-int apdu_get_refcnt(struct apdu_base *apdu)
-{
- TEE_ASSERT(apdu != NULL);
- return apdu->refcnt;
-}
-void apdu_acquire(struct apdu_base *apdu)
-{
- TEE_ASSERT(apdu != NULL);
- apdu->refcnt++;
-}
-void apdu_release(struct apdu_base *apdu)
-{
- TEE_ASSERT(apdu != NULL);
- apdu->refcnt--;
- if (apdu->refcnt == 0)
- free(apdu);
-}
-
-
-
-TEE_Result tee_se_aid_create(const char *name, struct tee_se_aid **aid)
-{
- size_t str_length = strlen(name);
- size_t aid_length = str_length / 2;
-
- TEE_ASSERT(aid != NULL && *aid == NULL);
- if (str_length < MIN_AID_LENGTH || str_length > MAX_AID_LENGTH)
- return TEE_ERROR_BAD_PARAMETERS;
-
- *aid = malloc(sizeof(struct tee_se_aid));
- if (!(*aid))
- return TEE_ERROR_OUT_OF_MEMORY;
-
- hex_decode(name, str_length, (*aid)->aid);
- (*aid)->length = aid_length;
- (*aid)->refcnt = 1;
- return TEE_SUCCESS;
-}
-
-TEE_Result tee_se_aid_create_from_buffer(uint8_t *id, size_t length,
- struct tee_se_aid **aid)
-{
- *aid = malloc(sizeof(struct tee_se_aid));
- if (!(*aid))
- return TEE_ERROR_OUT_OF_MEMORY;
-
- memcpy((*aid)->aid, id, length);
- (*aid)->length = length;
- (*aid)->refcnt = 1;
- return TEE_SUCCESS;
-}
-
-void tee_se_aid_acquire(struct tee_se_aid *aid)
-{
- TEE_ASSERT(aid != NULL);
- aid->refcnt++;
-}
-
-int tee_se_aid_get_refcnt(struct tee_se_aid *aid)
-{
- TEE_ASSERT(aid != NULL);
- return aid->refcnt;
-}
-
-void tee_se_aid_release(struct tee_se_aid *aid)
-{
- TEE_ASSERT(aid != NULL && aid->refcnt > 0);
- aid->refcnt--;
- if (aid->refcnt == 0)
- free(aid);
-}
-
-static void parse_resp_apdu(struct resp_apdu *apdu)
-{
- uint8_t *buf = apdu->base.data_buf;
- /* resp data length = resp buf length - SW1 - SW2 */
- apdu->resp_data_len = apdu->base.length - 2;
- if (apdu->resp_data_len > 0)
- apdu->resp_data = &buf[RDATA];
- else
- apdu->resp_data = NULL;
- apdu->sw1 = buf[RDATA + apdu->resp_data_len + OFF_SW1];
- apdu->sw2 = buf[RDATA + apdu->resp_data_len + OFF_SW2];
-}
+#include "session_priv.h"
+#include "aid_priv.h"
+#include "apdu_priv.h"
TEE_Result iso7816_exchange_apdu(struct tee_se_reader_proxy *proxy,
struct cmd_apdu *cmd, struct resp_apdu *resp)
diff --git a/core/tee/se/manager.c b/core/tee/se/manager.c
index cffa311..144ea02 100644
--- a/core/tee/se/manager.c
+++ b/core/tee/se/manager.c
@@ -35,9 +35,11 @@
#include <tee/se/reader/interface.h>
#include <stdlib.h>
-#include <string.h>
#include <sys/queue.h>
+#include "reader_priv.h"
+#include "session_priv.h"
+
TAILQ_HEAD(reader_proxy_head, tee_se_reader_proxy);
struct tee_se_manager_ctx {
@@ -119,140 +121,8 @@ TEE_Result tee_se_manager_get_readers(
return TEE_SUCCESS;
}
-TEE_Result tee_se_reader_check_state(struct tee_se_reader_proxy *proxy)
-{
- struct tee_se_reader *r;
-
- if (proxy->refcnt == 0)
- return TEE_ERROR_BAD_STATE;
-
- r = proxy->reader;
- if (r->ops->get_state) {
- enum tee_se_reader_state state;
-
- mutex_lock(&proxy->mutex);
- state = r->ops->get_state(r);
- mutex_unlock(&proxy->mutex);
-
- if (state != READER_STATE_SE_INSERTED)
- return TEE_ERROR_COMMUNICATION;
- }
-
- return TEE_SUCCESS;
-}
-
-TEE_Result tee_se_reader_get_name(struct tee_se_reader_proxy *proxy,
- char **reader_name, size_t *reader_name_len)
-{
- size_t name_len;
-
- TEE_ASSERT(proxy != NULL && proxy->reader != NULL);
-
- name_len = strlen(proxy->reader->name);
- *reader_name = proxy->reader->name;
- *reader_name_len = name_len;
-
- return TEE_SUCCESS;
-}
-
-void tee_se_reader_get_properties(struct tee_se_reader_proxy *proxy,
- TEE_SEReaderProperties *prop)
-{
- TEE_ASSERT(proxy != NULL && proxy->reader != NULL);
- *prop = proxy->reader->prop;
-}
-
-int tee_se_reader_get_refcnt(struct tee_se_reader_proxy *proxy)
-{
- TEE_ASSERT(proxy != NULL && proxy->reader != NULL);
- return proxy->refcnt;
-}
-
-TEE_Result tee_se_reader_attach(struct tee_se_reader_proxy *proxy)
-{
- TEE_Result ret;
-
- mutex_lock(&proxy->mutex);
- if (proxy->refcnt == 0) {
- struct tee_se_reader *r = proxy->reader;
-
- if (r->ops->open) {
- ret = r->ops->open(r);
- if (ret != TEE_SUCCESS) {
- mutex_unlock(&proxy->mutex);
- return ret;
- }
- }
- }
- proxy->refcnt++;
- mutex_unlock(&proxy->mutex);
- return TEE_SUCCESS;
-}
-
-void tee_se_reader_detach(struct tee_se_reader_proxy *proxy)
-{
- TEE_ASSERT(proxy->refcnt > 0);
-
- mutex_lock(&proxy->mutex);
- proxy->refcnt--;
- if (proxy->refcnt == 0) {
- struct tee_se_reader *r = proxy->reader;
-
- if (r->ops->close)
- r->ops->close(r);
- }
- mutex_unlock(&proxy->mutex);
-
-}
-
-TEE_Result tee_se_reader_transmit(struct tee_se_reader_proxy *proxy,
- uint8_t *tx_buf, size_t tx_buf_len,
- uint8_t *rx_buf, size_t *rx_buf_len)
-{
- struct tee_se_reader *r;
- TEE_Result ret;
-
- TEE_ASSERT(proxy != NULL && proxy->reader != NULL);
- ret = tee_se_reader_check_state(proxy);
- if (ret != TEE_SUCCESS)
- return ret;
-
- mutex_lock(&proxy->mutex);
- r = proxy->reader;
-
- TEE_ASSERT(r->ops->transmit);
- ret = r->ops->transmit(r, tx_buf, tx_buf_len, rx_buf, rx_buf_len);
-
- mutex_unlock(&proxy->mutex);
-
- return ret;
-}
-
-void tee_se_reader_lock_basic_channel(struct tee_se_reader_proxy *proxy)
-{
- TEE_ASSERT(proxy != NULL);
-
- mutex_lock(&proxy->mutex);
- proxy->basic_channel_locked = true;
- mutex_unlock(&proxy->mutex);
-}
-
-void tee_se_reader_unlock_basic_channel(struct tee_se_reader_proxy *proxy)
-{
- TEE_ASSERT(proxy != NULL);
-
- mutex_lock(&proxy->mutex);
- proxy->basic_channel_locked = false;
- mutex_unlock(&proxy->mutex);
-}
-
-bool tee_se_reader_is_basic_channel_locked(struct tee_se_reader_proxy *proxy)
-{
- TEE_ASSERT(proxy != NULL);
- return proxy->basic_channel_locked;
-}
-
-bool tee_se_reader_is_proxy_valid(struct tee_se_reader_proxy *proxy)
+bool tee_se_manager_is_reader_proxy_valid(
+ struct tee_se_reader_proxy *proxy)
{
struct tee_se_manager_ctx *ctx = &se_manager_ctx;
struct tee_se_reader_proxy *h;
@@ -265,52 +135,6 @@ bool tee_se_reader_is_proxy_valid(struct tee_se_reader_proxy *proxy)
return false;
}
-TEE_Result tee_se_reader_get_atr(struct tee_se_reader_proxy *proxy,
- uint8_t **atr, size_t *atr_len)
-{
- TEE_Result ret;
- struct tee_se_reader *r;
-
- TEE_ASSERT(proxy != NULL && atr != NULL && atr_len != NULL);
- ret = tee_se_reader_check_state(proxy);
- if (ret != TEE_SUCCESS)
- return ret;
-
- mutex_lock(&proxy->mutex);
- r = proxy->reader;
-
- TEE_ASSERT(r->ops->get_atr);
- ret = r->ops->get_atr(r, atr, atr_len);
-
- mutex_unlock(&proxy->mutex);
- return ret;
-}
-
-TEE_Result tee_se_reader_open_session(struct tee_se_reader_proxy *proxy,
- struct tee_se_session **session)
-{
- TEE_Result ret;
- struct tee_se_session *s;
-
- TEE_ASSERT(session != NULL && *session == NULL);
- TEE_ASSERT(proxy != NULL && proxy->reader != NULL);
-
- s = tee_se_session_alloc(proxy);
- if (!s)
- return TEE_ERROR_OUT_OF_MEMORY;
-
- ret = tee_se_reader_attach(proxy);
- if (ret != TEE_SUCCESS)
- goto err_free_session;
-
- *session = s;
-
- return TEE_SUCCESS;
-err_free_session:
- tee_se_session_free(s);
- return ret;
-}
-
static void context_init(struct tee_se_manager_ctx *ctx)
{
TAILQ_INIT(&ctx->reader_proxies);
diff --git a/core/tee/se/reader.c b/core/tee/se/reader.c
new file mode 100644
index 0000000..46bb06b
--- /dev/null
+++ b/core/tee/se/reader.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <tee_api_types.h>
+#include <trace.h>
+
+#include <kernel/tee_common_unpg.h>
+#include <kernel/mutex.h>
+#include <tee/se/reader.h>
+#include <tee/se/reader/interface.h>
+
+#include "reader_priv.h"
+#include "session_priv.h"
+
+TEE_Result tee_se_reader_check_state(struct tee_se_reader_proxy *proxy)
+{
+ struct tee_se_reader *r;
+
+ if (proxy->refcnt == 0)
+ return TEE_ERROR_BAD_STATE;
+
+ r = proxy->reader;
+ if (r->ops->get_state) {
+ enum tee_se_reader_state state;
+
+ mutex_lock(&proxy->mutex);
+ state = r->ops->get_state(r);
+ mutex_unlock(&proxy->mutex);
+
+ if (state != READER_STATE_SE_INSERTED)
+ return TEE_ERROR_COMMUNICATION;
+ }
+
+ return TEE_SUCCESS;
+}
+
+TEE_Result tee_se_reader_get_name(struct tee_se_reader_proxy *proxy,
+ char **reader_name, size_t *reader_name_len)
+{
+ size_t name_len;
+
+ TEE_ASSERT(proxy != NULL && proxy->reader != NULL);
+
+ name_len = strlen(proxy->reader->name);
+ *reader_name = proxy->reader->name;
+ *reader_name_len = name_len;
+
+ return TEE_SUCCESS;
+}
+
+void tee_se_reader_get_properties(struct tee_se_reader_proxy *proxy,
+ TEE_SEReaderProperties *prop)
+{
+ TEE_ASSERT(proxy != NULL && proxy->reader != NULL);
+ *prop = proxy->reader->prop;
+}
+
+int tee_se_reader_get_refcnt(struct tee_se_reader_proxy *proxy)
+{
+ TEE_ASSERT(proxy != NULL && proxy->reader != NULL);
+ return proxy->refcnt;
+}
+
+TEE_Result tee_se_reader_attach(struct tee_se_reader_proxy *proxy)
+{
+ TEE_Result ret;
+
+ mutex_lock(&proxy->mutex);
+ if (proxy->refcnt == 0) {
+ struct tee_se_reader *r = proxy->reader;
+
+ if (r->ops->open) {
+ ret = r->ops->open(r);
+ if (ret != TEE_SUCCESS) {
+ mutex_unlock(&proxy->mutex);
+ return ret;
+ }
+ }
+ }
+ proxy->refcnt++;
+ mutex_unlock(&proxy->mutex);
+ return TEE_SUCCESS;
+}
+
+void tee_se_reader_detach(struct tee_se_reader_proxy *proxy)
+{
+ TEE_ASSERT(proxy->refcnt > 0);
+
+ mutex_lock(&proxy->mutex);
+ proxy->refcnt--;
+ if (proxy->refcnt == 0) {
+ struct tee_se_reader *r = proxy->reader;
+
+ if (r->ops->close)
+ r->ops->close(r);
+ }
+ mutex_unlock(&proxy->mutex);
+
+}
+
+TEE_Result tee_se_reader_transmit(struct tee_se_reader_proxy *proxy,
+ uint8_t *tx_buf, size_t tx_buf_len,
+ uint8_t *rx_buf, size_t *rx_buf_len)
+{
+ struct tee_se_reader *r;
+ TEE_Result ret;
+
+ TEE_ASSERT(proxy != NULL && proxy->reader != NULL);
+ ret = tee_se_reader_check_state(proxy);
+ if (ret != TEE_SUCCESS)
+ return ret;
+
+ mutex_lock(&proxy->mutex);
+ r = proxy->reader;
+
+ TEE_ASSERT(r->ops->transmit);
+ ret = r->ops->transmit(r, tx_buf, tx_buf_len, rx_buf, rx_buf_len);
+
+ mutex_unlock(&proxy->mutex);
+
+ return ret;
+}
+
+void tee_se_reader_lock_basic_channel(struct tee_se_reader_proxy *proxy)
+{
+ TEE_ASSERT(proxy != NULL);
+
+ mutex_lock(&proxy->mutex);
+ proxy->basic_channel_locked = true;
+ mutex_unlock(&proxy->mutex);
+}
+
+void tee_se_reader_unlock_basic_channel(struct tee_se_reader_proxy *proxy)
+{
+ TEE_ASSERT(proxy != NULL);
+
+ mutex_lock(&proxy->mutex);
+ proxy->basic_channel_locked = false;
+ mutex_unlock(&proxy->mutex);
+}
+
+bool tee_se_reader_is_basic_channel_locked(struct tee_se_reader_proxy *proxy)
+{
+ TEE_ASSERT(proxy != NULL);
+ return proxy->basic_channel_locked;
+}
+
+TEE_Result tee_se_reader_get_atr(struct tee_se_reader_proxy *proxy,
+ uint8_t **atr, size_t *atr_len)
+{
+ TEE_Result ret;
+ struct tee_se_reader *r;
+
+ TEE_ASSERT(proxy != NULL && atr != NULL && atr_len != NULL);
+ ret = tee_se_reader_check_state(proxy);
+ if (ret != TEE_SUCCESS)
+ return ret;
+
+ mutex_lock(&proxy->mutex);
+ r = proxy->reader;
+
+ TEE_ASSERT(r->ops->get_atr);
+ ret = r->ops->get_atr(r, atr, atr_len);
+
+ mutex_unlock(&proxy->mutex);
+ return ret;
+}
+
+TEE_Result tee_se_reader_open_session(struct tee_se_reader_proxy *proxy,
+ struct tee_se_session **session)
+{
+ TEE_Result ret;
+ struct tee_se_session *s;
+
+ TEE_ASSERT(session != NULL && *session == NULL);
+ TEE_ASSERT(proxy != NULL && proxy->reader != NULL);
+
+ s = tee_se_session_alloc(proxy);
+ if (!s)
+ return TEE_ERROR_OUT_OF_MEMORY;
+
+ ret = tee_se_reader_attach(proxy);
+ if (ret != TEE_SUCCESS)
+ goto err_free_session;
+
+ *session = s;
+
+ return TEE_SUCCESS;
+err_free_session:
+ tee_se_session_free(s);
+ return ret;
+}
diff --git a/core/tee/se/reader_priv.h b/core/tee/se/reader_priv.h
new file mode 100644
index 0000000..00e139e
--- /dev/null
+++ b/core/tee/se/reader_priv.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEE_SE_READER_PRIV_H
+#define TEE_SE_READER_PRIV_H
+
+/*
+ * Reader Proxy is used to serialize access from multiple seesions,
+ * and maintain reference counter. All access to the reader should
+ * go through Reader Proxy
+ */
+struct tee_se_reader_proxy {
+ struct tee_se_reader *reader;
+ int refcnt;
+ bool basic_channel_locked;
+ struct mutex mutex;
+
+ TAILQ_ENTRY(tee_se_reader_proxy) link;
+};
+
+TEE_Result tee_se_reader_check_state(struct tee_se_reader_proxy *proxy);
+
+int tee_se_reader_get_refcnt(struct tee_se_reader_proxy *proxy);
+
+#endif
diff --git a/core/tee/se/service.c b/core/tee/se/service.c
index bb518a2..70dd03e 100644
--- a/core/tee/se/service.c
+++ b/core/tee/se/service.c
@@ -35,6 +35,10 @@
#include <tee/se/session.h>
#include <tee/se/reader.h>
+#include "service_priv.h"
+#include "reader_priv.h"
+#include "session_priv.h"
+
TEE_Result tee_se_service_open(
struct tee_se_service **service)
{
diff --git a/core/tee/se/service_priv.h b/core/tee/se/service_priv.h
new file mode 100644
index 0000000..9ad155a
--- /dev/null
+++ b/core/tee/se/service_priv.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEE_SE_SERVICE_PRIV_H
+#define TEE_SE_SERVICE_PRIV_H
+
+TAILQ_HEAD(se_session_head, tee_se_session);
+
+struct tee_se_service {
+ /* list of sessions opened on the service */
+ struct se_session_head opened_sessions;
+ /* list of sessions closed on the service */
+ struct se_session_head closed_sessions;
+ /* mutex to pretect the session lists */
+ struct mutex mutex;
+};
+
+#endif
diff --git a/core/tee/se/session.c b/core/tee/se/session.c
index 68cbb67..3bfa273 100644
--- a/core/tee/se/session.c
+++ b/core/tee/se/session.c
@@ -37,6 +37,9 @@
#include <stdlib.h>
#include <sys/queue.h>
+#include "session_priv.h"
+#include "channel_priv.h"
+
struct tee_se_session *tee_se_session_alloc(
struct tee_se_reader_proxy *proxy)
{
diff --git a/core/tee/se/session_priv.h b/core/tee/se/session_priv.h
new file mode 100644
index 0000000..81b28b4
--- /dev/null
+++ b/core/tee/se/session_priv.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEE_SE_SESSION_PRIV_H
+#define TEE_SE_SESSION_PRIV_H
+
+TAILQ_HEAD(channel_list, tee_se_channel);
+
+struct tee_se_session {
+ struct tee_se_reader_proxy *reader_proxy;
+
+ /* list of channels opened on the session*/
+ struct channel_list channels;
+
+ TAILQ_ENTRY(tee_se_session) link;
+};
+
+struct tee_se_session *tee_se_session_alloc(struct tee_se_reader_proxy *proxy);
+
+void tee_se_session_free(struct tee_se_session *s);
+
+#endif
diff --git a/core/tee/se/sub.mk b/core/tee/se/sub.mk
index 4a64056..f5ebdd8 100644
--- a/core/tee/se/sub.mk
+++ b/core/tee/se/sub.mk
@@ -1,3 +1,3 @@
-srcs-y += service.c manager.c iso7816.c session.c channel.c util.c svc.c
+srcs-y += service.c manager.c reader.c iso7816.c session.c channel.c aid.c apdu.c util.c svc.c
subdirs-y += reader