diff options
author | Jun Nie <jun.nie@linaro.org> | 2023-06-06 14:03:19 +0800 |
---|---|---|
committer | Jun Nie <jun.nie@linaro.org> | 2023-06-12 16:35:18 +0800 |
commit | 279f19be5d751b4ff271035dc3ef2853ab787338 (patch) | |
tree | d5f72d0c1af1f956f381770c74f036698c1d35ee | |
parent | 967bc85c8318d72864e20c9a47dee6cd0d88dc3f (diff) |
ssl_client: pass build
not linked yet
Signed-off-by: Jun Nie <jun.nie@linaro.org>
-rw-r--r-- | ssl_client/host/main.c | 425 | ||||
-rw-r--r-- | ssl_client/ta/ssl_client_ta.c | 394 |
2 files changed, 432 insertions, 387 deletions
diff --git a/ssl_client/host/main.c b/ssl_client/host/main.c index fb9e90e..ae3f719 100644 --- a/ssl_client/host/main.c +++ b/ssl_client/host/main.c @@ -25,335 +25,25 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#if 0 #include <err.h> #include <stdio.h> #include <string.h> /* OP-TEE TEE client API (built by optee_client) */ -#endif - -#include <assert.h> -#include <err.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/types.h> #include <tee_client_api.h> -#include <tee_isocket.h> -#include <tee_tcpsocket.h> -#include <__tee_tcpsocket_defines_extensions.h> -#include <tee_udpsocket.h> -#include <unistd.h> - -#include "sock_server.h" -#include "rand_stream.h" /* For the UUID (found in the TA's h-file(s)) */ #include <ssl_client_ta.h> -#define TEEC_OPERATION_INITIALIZER { } - -struct socket_handle { - uint64_t buf[2]; - size_t blen; -}; - - -int c = 0; -void Do_ADBG_BeginSubCase(int c, char *info) -{ - printf("begin %s\n", info); -} - -void Do_ADBG_EndSubCase(int c, char *info) -{ - printf("end %s\n", info); -} - -static TEE_Result socket_tcp_open(TEEC_Session *session, uint32_t ip_vers, - const char *addr, uint16_t port, - struct socket_handle *handle, - uint32_t *error, uint32_t *ret_orig) -{ - TEE_Result res = TEE_ERROR_GENERIC; - TEEC_Operation op = TEEC_OPERATION_INITIALIZER; - - memset(handle, 0, sizeof(*handle)); - - op.params[0].value.a = ip_vers; - op.params[0].value.b = port; - op.params[1].tmpref.buffer = (void *)addr; - op.params[1].tmpref.size = strlen(addr) + 1; - op.params[2].tmpref.buffer = handle->buf; - op.params[2].tmpref.size = sizeof(handle->buf); - - op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, - TEEC_MEMREF_TEMP_INPUT, - TEEC_MEMREF_TEMP_OUTPUT, - TEEC_VALUE_OUTPUT); - - res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_TCP_OPEN, - &op, ret_orig); - - handle->blen = op.params[2].tmpref.size; - *error = op.params[3].value.a; - return res; -} - -static TEE_Result socket_udp_open(TEEC_Session *session, uint32_t ip_vers, - const char *addr, uint16_t port, - struct socket_handle *handle, - uint32_t *error, uint32_t *ret_orig) -{ - TEE_Result res = TEE_ERROR_GENERIC; - TEEC_Operation op = TEEC_OPERATION_INITIALIZER; - - memset(handle, 0, sizeof(*handle)); - - op.params[0].value.a = ip_vers; - op.params[0].value.b = port; - op.params[1].tmpref.buffer = (void *)addr; - op.params[1].tmpref.size = strlen(addr) + 1; - op.params[2].tmpref.buffer = handle->buf; - op.params[2].tmpref.size = sizeof(handle->buf); - - op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, - TEEC_MEMREF_TEMP_INPUT, - TEEC_MEMREF_TEMP_OUTPUT, - TEEC_VALUE_OUTPUT); - - res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_UDP_OPEN, - &op, ret_orig); - - handle->blen = op.params[2].tmpref.size; - *error = op.params[3].value.a; - return res; -} - -static TEE_Result socket_send(TEEC_Session *session, - struct socket_handle *handle, - const void *data, size_t *dlen, - uint32_t timeout, uint32_t *ret_orig) -{ - TEE_Result res = TEE_ERROR_GENERIC; - TEEC_Operation op = TEEC_OPERATION_INITIALIZER; - - op.params[0].tmpref.buffer = handle->buf; - op.params[0].tmpref.size = handle->blen; - op.params[1].tmpref.buffer = (void *)data; - op.params[1].tmpref.size = *dlen; - op.params[2].value.a = timeout; - - op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, - TEEC_MEMREF_TEMP_INPUT, - TEEC_VALUE_INOUT, TEEC_NONE); - - res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_SEND, &op, ret_orig); - - *dlen = op.params[2].value.b; - return res; -} - -static TEE_Result socket_recv(TEEC_Session *session, - struct socket_handle *handle, - void *data, size_t *dlen, - uint32_t timeout, uint32_t *ret_orig) -{ - TEE_Result res = TEE_ERROR_GENERIC; - TEEC_Operation op = TEEC_OPERATION_INITIALIZER; - - op.params[0].tmpref.buffer = handle->buf; - op.params[0].tmpref.size = handle->blen; - op.params[1].tmpref.buffer = (void *)data; - op.params[1].tmpref.size = *dlen; - op.params[2].value.a = timeout; - - op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, - TEEC_MEMREF_TEMP_OUTPUT, - TEEC_VALUE_INPUT, TEEC_NONE); - - res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_RECV, &op, ret_orig); - - *dlen = op.params[1].tmpref.size; - return res; -} - -static TEE_Result socket_get_error(TEEC_Session *session, - struct socket_handle *handle, - uint32_t *proto_error, uint32_t *ret_orig) -{ - TEE_Result res = TEE_ERROR_GENERIC; - TEEC_Operation op = TEEC_OPERATION_INITIALIZER; - - op.params[0].tmpref.buffer = handle->buf; - op.params[0].tmpref.size = handle->blen; - - op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, - TEEC_VALUE_OUTPUT, - TEEC_NONE, TEEC_NONE); - - res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_ERROR, &op, ret_orig); - - *proto_error = op.params[1].value.a; - return res; -} - -static TEE_Result socket_close(TEEC_Session *session, - struct socket_handle *handle, uint32_t *ret_orig) -{ - TEEC_Operation op = TEEC_OPERATION_INITIALIZER; - - op.params[0].tmpref.buffer = handle->buf; - op.params[0].tmpref.size = handle->blen; - - op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, - TEEC_NONE, TEEC_NONE, TEEC_NONE); - - return TEEC_InvokeCommand(session, TA_SOCKET_CMD_CLOSE, &op, ret_orig); -} - -static TEE_Result socket_ioctl(TEEC_Session *session, - struct socket_handle *handle, uint32_t ioctl_cmd, - void *data, size_t *dlen, uint32_t *ret_orig) -{ - TEE_Result res = TEE_ERROR_GENERIC; - TEEC_Operation op = TEEC_OPERATION_INITIALIZER; - - op.params[0].tmpref.buffer = handle->buf; - op.params[0].tmpref.size = handle->blen; - op.params[1].tmpref.buffer = data; - op.params[1].tmpref.size = *dlen; - op.params[2].value.a = ioctl_cmd; - - op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, - TEEC_MEMREF_TEMP_INOUT, - TEEC_VALUE_INPUT, TEEC_NONE); - - res = TEEC_InvokeCommand(session, TA_SOCKET_CMD_IOCTL, &op, ret_orig); - - *dlen = op.params[1].tmpref.size; - return res; -} - - - -struct test_200x_io_state { - struct rand_stream *read_rs; - struct rand_stream *write_rs; - bool rfail; -}; - -static void test_200x_init_io_state(struct test_200x_io_state *s, - int read_seed, int write_seed) -{ - memset(s, 0, sizeof(*s)); - s->read_rs = rand_stream_alloc(read_seed, 100); - s->write_rs = rand_stream_alloc(write_seed, 100); - assert(s->read_rs && s->write_rs); -} - -static bool test_200x_tcp_accept_cb(void *ptr, int fd, short *events) -{ - (void)ptr; - (void)fd; - (void)events; - return true; -} - -static bool test_200x_tcp_read_cb(void *ptr, int fd, short *events) -{ - struct test_200x_io_state *iostate = ptr; - ssize_t r = 0; - uint8_t buf[100] = { }; - uint8_t buf2[100] = { }; - - (void)events; - r = read(fd, buf, sizeof(buf)); - if (r <= 0) - return false; - - rand_stream_read(iostate->read_rs, buf2, r); - if (memcmp(buf, buf2, r)) { - iostate->rfail = true; - return false; - } - - return true; -} - -static bool test_200x_tcp_write_cb(void *ptr, int fd, short *events) -{ - struct test_200x_io_state *iostate = ptr; - size_t num_bytes = 100; - const void *bytes = NULL; - ssize_t r = 0; - - (void)events; - - bytes = rand_stream_peek(iostate->write_rs, &num_bytes); - r = write(fd, bytes, num_bytes); - if (r < 0) - return false; - - rand_stream_advance(iostate->write_rs, num_bytes); - return true; -} - -void ADBG_EXPECT_BUFFER(unsigned char *buf2, int len1, unsigned char *buf, int len2) -{ - if (len1 != len2) - goto err_out; - - while(len1--) { - if (*buf - *buf2) - goto err_out; - buf++; - buf2++; - } - return; - -err_out: - printf("===========waring: buffer is not as expected\n"); -} - int main(void) { TEEC_Result res; TEEC_Context ctx; - TEEC_Session session; + TEEC_Session sess; + TEEC_Operation op; TEEC_UUID uuid = TA_SSL_CLIENT_UUID; - uint32_t ret_orig; - - struct sock_server ts = { }; - uint32_t proto_error = 9; - struct socket_handle sh = { }; - uint8_t buf[64] = { }; - uint8_t buf2[64] = { }; - size_t blen = 0; - struct test_200x_io_state server_iostate = { }; - struct test_200x_io_state local_iostate = { }; - struct sock_io_cb cb = { - .accept = test_200x_tcp_accept_cb, - .read = test_200x_tcp_read_cb, - .write = test_200x_tcp_write_cb, - .ptr = &server_iostate, - }; - - test_200x_init_io_state(&server_iostate, 1, 2); - test_200x_init_io_state(&local_iostate, 2, 1); + uint32_t err_origin; - Do_ADBG_BeginSubCase(c, "Start server"); - if (true != sock_server_init_tcp(&ts, &cb)) { - errx(1, "sock_server_init_tcp failed"); - return; - } - Do_ADBG_EndSubCase(c, "Start server"); - - Do_ADBG_BeginSubCase(c, "TCP Socket open"); /* Initialize a context connecting us to the TEE */ res = TEEC_InitializeContext(NULL, &ctx); if (res != TEEC_SUCCESS) @@ -363,87 +53,54 @@ int main(void) * Open a session to the "ssl client" TA, the TA will print "hello * ssl!" in the log when the session is created. */ - res = TEEC_OpenSession(&ctx, &session, &uuid, - TEEC_LOGIN_PUBLIC, NULL, NULL, &ret_orig); - if (res != TEEC_SUCCESS) { + res = TEEC_OpenSession(&ctx, &sess, &uuid, + TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin); + if (res != TEEC_SUCCESS) errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x", - res, ret_orig); - goto out; - } - - res = socket_tcp_open(&session, - TEE_IP_VERSION_DC, ts.bind->host, ts.bind->port, - &sh, &proto_error, &ret_orig); - if (res != TEEC_SUCCESS) { - errx(1, "socket_tcp_open failed with code 0x%x origin 0x%x", - res, ret_orig); - goto out_close_session; - } - - Do_ADBG_EndSubCase(c, "TCP Socket open"); + res, err_origin); - Do_ADBG_BeginSubCase(c, "TCP Socket send"); - blen = sizeof(buf); - rand_stream_read(local_iostate.write_rs, buf, blen); - res = socket_send(&session, &sh, - buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig); - if (res != TEEC_SUCCESS) { - errx(1, "socket_send failed with code 0x%x origin 0x%x", - res, ret_orig); - goto out_close_session; - } - if( blen != sizeof(buf)) - printf("======warning blen %d != %d\n", blen, sizeof(buf)); + /* + * Execute a function in the TA by invoking it, in this case + * we're incrementing a number. + * + * The value of command ID part and how the parameters are + * interpreted is part of the interface provided by the TA. + */ - Do_ADBG_EndSubCase(c, "TCP Socket send"); + /* Clear the TEEC_Operation struct */ + memset(&op, 0, sizeof(op)); - Do_ADBG_BeginSubCase(c, "TCP Socket recv"); - blen = sizeof(buf); - res = socket_recv(&session, &sh, - buf, &blen, TEE_TIMEOUT_INFINITE, &ret_orig); - if (res != TEEC_SUCCESS) { - errx(1, "socket_recv failed with code 0x%x origin 0x%x", - res, ret_orig); - goto out_close_session; - } - if( blen != sizeof(buf)) - printf("======warning blen %d != %d\n", blen, sizeof(buf)); - rand_stream_read(local_iostate.read_rs, buf2, blen); - ADBG_EXPECT_BUFFER(buf2, blen, buf, blen); - Do_ADBG_EndSubCase(c, "TCP Socket recv"); + /* + * Prepare the argument. Pass a value in the first parameter, + * the remaining three parameters are unused. + */ + op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, + TEEC_NONE, TEEC_NONE); + op.params[0].value.a = 42; /* - * All written bytes above (with the TA) is quite likely to have - * hit the tcp server by now. + * TA_SOCKET_CMD_TCP_OPEN is the actual function in the TA to be + * called. */ - /* expect true for !server_iostate.rfail */ - if( true == !server_iostate.rfail) - printf("======!server_iostate.rfail expected to be true %d\n", !server_iostate.rfail); + printf("Invoking TA to increment %d\n", op.params[0].value.a); + res = TEEC_InvokeCommand(&sess, TA_SOCKET_CMD_TCP_OPEN, &op, + &err_origin); + if (res != TEEC_SUCCESS) + errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x", + res, err_origin); + printf("TA incremented value to %d\n", op.params[0].value.a); - Do_ADBG_BeginSubCase(c, "TCP Socket get error"); - res = socket_get_error(&session, &sh, - &proto_error, &ret_orig); - if (res != TEEC_SUCCESS || proto_error != TEEC_SUCCESS) { - errx(1, "socket_get_error failed with code 0x%x origin 0x%x proto_err 0x%x", - res, ret_orig, proto_error); - goto out_close_session; - } - Do_ADBG_EndSubCase(c, "TCP Socket get error"); + /* + * We're done with the TA, close the session and + * destroy the context. + * + * The TA will print "Goodbye!" in the log when the + * session is closed. + */ - Do_ADBG_BeginSubCase(c, "TCP Socket close"); - res = socket_close(&session, &sh, - &ret_orig); - if (res != TEEC_SUCCESS) { - errx(1, "socket_close failed with code 0x%x origin 0x%x", - res, ret_orig); - goto out_close_session; - } - Do_ADBG_EndSubCase(c, "TCP Socket close"); + TEEC_CloseSession(&sess); -out_close_session: - TEEC_CloseSession(&session); TEEC_FinalizeContext(&ctx); -out: - sock_server_uninit(&ts); + return 0; } diff --git a/ssl_client/ta/ssl_client_ta.c b/ssl_client/ta/ssl_client_ta.c index 9fc5fbf..4fb39aa 100644 --- a/ssl_client/ta/ssl_client_ta.c +++ b/ssl_client/ta/ssl_client_ta.c @@ -13,6 +13,135 @@ #include <tee_udpsocket.h> #include <trace.h> +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include <stdio.h> +#include <stdlib.h> +#define mbedtls_time time +#define mbedtls_time_t time_t +#define mbedtls_fprintf fprintf +#define mbedtls_printf EMSG +#define mbedtls_exit exit +#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS +#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE +#endif /* MBEDTLS_PLATFORM_C */ + +#include "mbedtls/net_sockets.h" +#include "mbedtls/debug.h" +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#include "mbedtls/certs.h" + +#include <string.h> + +#define DEBUG_LEVEL 4 + +/* +static int portno = 80; +static const char *host_name = "www.random.org"; +static const char *host_payload = "/cgi-bin/randbyte?nbytes=32&format=h"; +*/ +static int portno = 4433; +static const char *host_name = "localhost"; +//static const char *host_payload = "GET / HTTP/1.0\r\n\r\n"; +#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n" + +/* This is taken from tests/data_files/test-ca-sha256.crt. */ +/* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA256_PEM tests/data_files/test-ca-sha256.crt */ +#define TEST_CA_CRT_RSA_SHA256_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ + "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ + "MTkwMjEwMTQ0NDAwWhcNMjkwMjEwMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ + "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ + "mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ + "50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ + "YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ + "R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ + "KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ + "UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \ + "MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBCwUA\r\n" \ + "A4IBAQA4qFSCth2q22uJIdE4KGHJsJjVEfw2/xn+MkTvCMfxVrvmRvqCtjE4tKDl\r\n" \ + "oK4MxFOek07oDZwvtAT9ijn1hHftTNS7RH9zd/fxNpfcHnMZXVC4w4DNA1fSANtW\r\n" \ + "5sY1JB5Je9jScrsLSS+mAjyv0Ow3Hb2Bix8wu7xNNrV5fIf7Ubm+wt6SqEBxu3Kb\r\n" \ + "+EfObAT4huf3czznhH3C17ed6NSbXwoXfby7stWUDeRJv08RaFOykf/Aae7bY5PL\r\n" \ + "yTVrkAnikMntJ9YI+hNNYt3inqq11A5cN0+rVTst8UKCxzQ4GpvroSwPKTFkbMw4\r\n" \ + "/anT1dVxr/BtwJfiESoK3/4CeXR1\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +/* This is taken from tests/data_files/test-ca-sha1.crt. */ +/* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA1_PEM tests/data_files/test-ca-sha1.crt */ +#define TEST_CA_CRT_RSA_SHA1_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ + "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ + "MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ + "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ + "mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ + "50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ + "YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ + "R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ + "KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ + "UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \ + "MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBBQUA\r\n" \ + "A4IBAQABE3OEPfEd/bcJW5ZdU3/VgPNS4tMzh8gnJP/V2FcvFtGylMpQq6YnEBYI\r\n" \ + "yBHAL4DRvlMY5rnXGBp3ODR8MpqHC6AquRTCLzjS57iYff//4QFQqW9n92zctspv\r\n" \ + "czkaPKgjqo1No3Uq0Xaz10rcxyTUPrf5wNVRZ2V0KvllvAAVSzbI4mpdUXztjhST\r\n" \ + "S5A2BeWQAAOr0zq1F7TSRVJpJs7jmB2ai/igkh1IAjcuwV6VwlP+sbw0gjQ0NpGM\r\n" \ + "iHpnlzRAi/tIbtOvMIGOBU2TIfax/5jq1agUx5aPmT5TWAiJPOOP6l5xXnDwxeYS\r\n" \ + "NWqiX9GyusBZjezaCaHabjDLU0qQ\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +/* This is taken from tests/data_files/test-ca2.crt */ +/* BEGIN FILE string macro TEST_CA_CRT_EC_PEM tests/data_files/test-ca2.crt */ +#define TEST_CA_CRT_EC_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIICBDCCAYigAwIBAgIJAMFD4n5iQ8zoMAwGCCqGSM49BAMCBQAwPjELMAkGA1UE\r\n" \ + "BhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRwwGgYDVQQDDBNQb2xhcnNzbCBUZXN0\r\n" \ + "IEVDIENBMB4XDTE5MDIxMDE0NDQwMFoXDTI5MDIxMDE0NDQwMFowPjELMAkGA1UE\r\n" \ + "BhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRwwGgYDVQQDDBNQb2xhcnNzbCBUZXN0\r\n" \ + "IEVDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEw9orNEE3WC+HVv78ibopQ0tO\r\n" \ + "4G7DDldTMzlY1FK0kZU5CyPfXxckYkj8GpUpziwth8KIUoCv1mqrId240xxuWLjK\r\n" \ + "6LJpjvNBrSnDtF91p0dv1RkpVWmaUzsgtGYWYDMeo1AwTjAMBgNVHRMEBTADAQH/\r\n" \ + "MB0GA1UdDgQWBBSdbSAkSQE/K8t4tRm8fiTJ2/s2fDAfBgNVHSMEGDAWgBSdbSAk\r\n" \ + "SQE/K8t4tRm8fiTJ2/s2fDAMBggqhkjOPQQDAgUAA2gAMGUCMFHKrjAPpHB0BN1a\r\n" \ + "LH8TwcJ3vh0AxeKZj30mRdOKBmg/jLS3rU3g8VQBHpn8sOTTBwIxANxPO5AerimZ\r\n" \ + "hCjMe0d4CTHf1gFZMF70+IqEP+o5VHsIp2Cqvflb0VGWFC5l9a4cQg==\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +#if 0 +const char mbedtls_test_cas_pem[] = + TEST_CA_CRT_RSA_SHA256_PEM + TEST_CA_CRT_RSA_SHA1_PEM + TEST_CA_CRT_EC_PEM + ""; +const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem ); +#endif + +static void my_debug( void *ctx, int level, + const char *file, int line, + const char *str ) +{ + ((void) level); + ctx = ctx; + + EMSG( "%s:%04d: %s", file, line, str ); +} + TEE_Result TA_CreateEntryPoint(void) { return TEE_SUCCESS; @@ -42,6 +171,47 @@ struct sock_handle { TEE_iSocket *socket; }; +/* implement mbedtls callback to call GP backend functions: + TEE_Result (*send)(TEE_iSocketHandle ctx, const void *buf, + uint32_t *length, uint32_t timeout); + + TEE_Result (*recv)(TEE_iSocketHandle ctx, void *buf, uint32_t *length, + uint32_t timeout); +*/ +int gp_net_send( void *handle, const unsigned char *buf, size_t len ) +{ + TEE_Result res; + struct sock_handle *h = (struct sock_handle *)handle; + + res = h->socket->send(h->ctx, buf, + &len, TEE_TIMEOUT_INFINITE); + if (res != TEE_SUCCESS) { + EMSG("gp send ret 0x%x", res); + return -1; + //return MBEDTLS_ERR_NET_SEND_FAILED; + } + + EMSG("gp send %d bytes OK", len); + return len; +} + +int gp_net_recv( void *handle, unsigned char *buf, size_t len ) +{ + TEE_Result res; + struct sock_handle *h = (struct sock_handle *)handle; + + res = h->socket->recv(h->ctx, buf, &len, + TEE_TIMEOUT_INFINITE); + if (res != TEE_SUCCESS) { + EMSG("gp recv ret 0x%x", res); + return -1; + //return MBEDTLS_ERR_NET_RECV_FAILED; + } + + EMSG("gp recv %d bytes", len); + return len; +} + static TEE_Result ta_entry_tcp_open(uint32_t param_types, TEE_Param params[4]) { TEE_Result res = TEE_ERROR_GENERIC; @@ -53,6 +223,65 @@ static TEE_Result ta_entry_tcp_open(uint32_t param_types, TEE_Param params[4]) TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_VALUE_OUTPUT); + int exit_code = TEE_ERROR_GENERIC; + int ret = 1, len; + uint32_t flags; + unsigned char buf[1024]; + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ssl_context ssl; + mbedtls_ssl_config conf; + mbedtls_x509_crt cacert; + const char *pers = "ssl_client1"; + +#if defined(MBEDTLS_DEBUG_C) + mbedtls_debug_set_threshold( DEBUG_LEVEL ); +#endif + + /* + * 0. Initialize the RNG and the session data + */ + mbedtls_ssl_init( &ssl ); + mbedtls_ssl_config_init( &conf ); + mbedtls_x509_crt_init( &cacert ); + mbedtls_ctr_drbg_init( &ctr_drbg ); + + mbedtls_printf( "\n . Seeding the random number generator..." ); + + mbedtls_entropy_init( &entropy ); + if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, + (const unsigned char *) pers, + strlen( pers ) ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); + goto exit; + } + + mbedtls_printf( " ok\n" ); + + /* + * 0. Initialize certificates + */ + mbedtls_printf( " . Loading the CA root certificate ..." ); + + ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem, + mbedtls_test_cas_pem_len ); + if( ret < 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", (unsigned int) -ret ); + goto exit; + } + + mbedtls_printf( " ok (%d skipped)\n", ret ); + + /* + * 1. Start the connection + */ + mbedtls_printf( " . Connecting to tcp/%s/%d...", host_name, portno); + + + + if (param_types != req_param_types) { EMSG("got param_types 0x%x, expected 0x%x", param_types, req_param_types); @@ -77,8 +306,164 @@ static TEE_Result ta_entry_tcp_open(uint32_t param_types, TEE_Param params[4]) if (res == TEE_SUCCESS) { memcpy(params[2].memref.buffer, &h, sizeof(h)); params[2].memref.size = sizeof(h); + EMSG("open success"); + } else { + EMSG("open fail, ret 0x%x", res); + return res; } - return res; + + /* + * 2. Setup stuff + */ + mbedtls_printf( " . Setting up the SSL/TLS structure..." ); + + if( ( ret = mbedtls_ssl_config_defaults( &conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); + goto exit; + } + + mbedtls_printf( " ok\n" ); + + /* OPTIONAL is not optimal for security, + * but makes interop easier in this simplified example */ + mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL ); + mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); + mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); + mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); + + if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret ); + goto exit; + } + + if( ( ret = mbedtls_ssl_set_hostname( &ssl, host_name ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret ); + goto exit; + } + + mbedtls_ssl_set_bio( &ssl, &h, gp_net_send, gp_net_recv, NULL ); + + + /* + * 4. Handshake + */ + mbedtls_printf( " . Performing the SSL/TLS handshake..." ); + + while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 ) + { + if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", (unsigned int) -ret ); + goto exit; + } + } + + mbedtls_printf( " ok\n" ); + + /* + * 5. Verify the server certificate + */ + mbedtls_printf( " . Verifying peer X.509 certificate..." ); + + /* In real life, we probably want to bail out when ret != 0 */ + if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 ) + { + char vrfy_buf[512]; + + mbedtls_printf( " failed\n" ); + + mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags ); + + mbedtls_printf( "%s\n", vrfy_buf ); + } + else + mbedtls_printf( " ok\n" ); + + /* + * 3. Write the GET request + */ + mbedtls_printf( " > Write to server:" ); + + len = sprintf( (char *) buf, GET_REQUEST ); + + while( ( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0 ) + { + if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret ); + goto exit; + } + } + + len = ret; + mbedtls_printf( " %d bytes written\n\n%s", len, (char *) buf ); + + /* + * 7. Read the HTTP response + */ + mbedtls_printf( " < Read from server:" ); + + do + { + len = sizeof( buf ) - 1; + memset( buf, 0, sizeof( buf ) ); + ret = mbedtls_ssl_read( &ssl, buf, len ); + + if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ) + continue; + + if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ) + break; + + if( ret < 0 ) + { + mbedtls_printf( "failed\n ! mbedtls_ssl_read returned %d\n\n", ret ); + break; + } + + if( ret == 0 ) + { + mbedtls_printf( "\n\nEOF\n\n" ); + break; + } + + len = ret; + mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf ); + } + while( 1 ); + + mbedtls_ssl_close_notify( &ssl ); + + exit_code = TEE_SUCCESS; + +exit: + +#ifdef MBEDTLS_ERROR_C + if( exit_code != TEE_SUCCESS ) + { + char error_buf[100]; + mbedtls_strerror( ret, error_buf, 100 ); + mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf ); + } +#endif + + mbedtls_x509_crt_free( &cacert ); + mbedtls_ssl_free( &ssl ); + mbedtls_ssl_config_free( &conf ); + mbedtls_ctr_drbg_free( &ctr_drbg ); + mbedtls_entropy_free( &entropy ); + + //mbedtls_exit( exit_code ); + if( exit_code == TEE_SUCCESS ) + return TEE_SUCCESS; + else + return TEE_ERROR_GENERIC; } static TEE_Result ta_entry_udp_open(uint32_t param_types, TEE_Param params[4]) @@ -244,16 +629,19 @@ static TEE_Result ta_entry_ioctl(uint32_t param_types, TEE_Param params[4]) return res; } - - TEE_Result TA_InvokeCommandEntryPoint(void *session_ctx, uint32_t cmd_id, uint32_t param_types, TEE_Param params[4]) { (void)session_ctx; + params[0].value.b = portno; + params[1].memref.buffer = host_name; + params[1].memref.size = sizeof(*host_name); + switch (cmd_id) { case TA_SOCKET_CMD_TCP_OPEN: + params[0].value.a = TEE_IP_VERSION_DC; return ta_entry_tcp_open(param_types, params); case TA_SOCKET_CMD_UDP_OPEN: return ta_entry_udp_open(param_types, params); |