Rust SGX SDK v0.1.0
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..24c7cf2
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,409 @@
+BSD License
+
+Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+  * 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.
+  * Neither the name of Baidu, Inc., nor the names of its
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+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
+OWNER 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.
+
+
+
+===========================================================================================================================================================
+
+Rust SGX SDK software for Linux also uses third-party projects that may be distributed under different licenses. Please see below for details.
+
+
+1. Intel(R) SGX
+
+Copyright (C) 2011-2017 Intel Corporation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+  * 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.
+  * Neither the name of Intel Corporation nor the names of its
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+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
+OWNER 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.
+
+
+
+2. compiler_rt
+
+The compiler_rt library is dual licensed under both the University of Illinois 
+"BSD-Like" license and the MIT license.  As a user of this code you may choose 
+to use it under either license.  As a contributor, you agree to allow your code 
+to be used under both.
+
+Full text of the relevant licenses is included below.
+
+=============================================================================
+
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2009-2013 by the contributors listed in CREDITS.TXT
+
+All rights reserved.
+
+Developed by:
+
+    LLVM Team
+
+    University of Illinois at Urbana-Champaign
+
+    http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this 
+software and associated documentation files (the "Software"), to deal with 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:
+
+-	Redistributions of source code must retain the above copyright notice, 
+this list of conditions and the following disclaimers.
+
+-	Redistributions in binary form must reproduce the above copyright notice, 
+this list of conditions and the following disclaimers in the documentation and/or 
+other materials provided with the distribution.
+
+-	Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, 
+nor the names of its contributors may be used to endorse or romote products derived 
+from this Software without specific prior written permission.
+
+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 CONTRIBUTORS 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 WITH THE SOFTWARE.
+
+=============================================================================
+
+Copyright (c) 2009-2013 by the contributors listed in CREDITS.TXT
+
+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.
+
+=============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+=============================================================================
+The LLVM software contains code written by third parties.  Such software will have its 
+own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License applies to all 
+code in the LLVM Distribution, and nothing in any of the other licenses gives permission to 
+use the names of the LLVM Team or the University of Illinois to endorse or promote products 
+derived from this Software.
+
+The following pieces of software have additional or alternate copyrights, licenses, and/or 
+restrictions:
+
+Program             Directory
+-------             ---------
+mach_override       lib/interception/mach_override
+
+
+
+3. NetBSD
+
+===============================================================================================
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by 
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+________________________________________
+For complete copyright and licensing terms, see: http://www.netbsd.org/about/redistribution.html
+
+ 
+
+
+4. OpenBSD
+
+http://openbsd.org/
+
+OpenBSD* Copyright Policy
+________________________________________
+-	Goal
+Copyright law is complex, OpenBSD* policy is simple - OpenBSD strives to maintain the spirit 
+of the original Berkeley Unix copyrights.
+OpenBSD can exist as it does today because of the example set by the Computer Systems Research 
+Group at Berkeley and the battles which they and others fought to create a relatively 
+un-encumbered Unix source distribution.
+The ability of a freely redistributable "Berkeley" Unix to move forward on a competitive 
+basis with other operating systems depends on the willingness of the various development 
+groups to exchange code amongst themselves and with other projects. Understanding the legal 
+issues surrounding copyright is fundamental to the ability to exchange and re-distribute code, 
+while honoring the spirit of the copyright and concept of attribution is fundamental to 
+promoting the cooperation of the people involved.
+-	The Berkeley* Copyright
+The Berkeley* copyright poses no restrictions on private or commercial use of the software 
+and imposes only simple and uniform requirements for maintaining copyright notices in 
+redistributed versions and crediting the originator of the material only in advertising.
+For instance:
+ * Copyright (c) 1982, 1986, 1990, 1991, 1993
+ *	The Regents of the University of California.  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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+Berkeley rescinded the 3rd term (the advertising term) on 22 July 1999. Verbatim copies 
+of the Berkeley license in the OpenBSD tree have that term removed. In addition, many 
+3rd-party BSD-style licenses consist solely of the first two terms.
+Because the OpenBSD copyright imposes no conditions beyond those imposed by the Berkeley 
+copyright, OpenBSD can hope to share the same wide distribution and applicability as the 
+Berkeley distributions. It follows however, that OpenBSD cannot include material which 
+includes copyrights which are more restrictive than the Berkeley copyright, or must 
+relegate this material to a secondary status, i.e. OpenBSD as a whole is freely 
+redistributable, but some optional components may not be.
+-	Copyright Law
+While the overall subject of copyright law is far beyond the scope of this document, some 
+basics are in order. Under the current copyright law, copyrights are implicit in the 
+creation of a new work and reside with the creator, unless otherwise assigned. In general 
+the copyright applies only to the new work, not the material the work was derived from, 
+nor those portions of the derivative material included in the new work.
+Copyright law admits to three general categories of works:
+Original Work
+A new work that is not derived from an existing work.
+Derivative Work
+Work that is derived from, includes or amends existing works.
+Compilations
+A work that is a compilation of existing new and derivative works.
+The fundamental concept is that there is primacy of the copyright, that is a copyright of a 
+derivative work does not affect the rights held by the owner of the copyright of the original 
+work, rather only the part added. Likewise the copyright of a compilation does not affect the 
+rights of the owner of the included works, only the compilation as an entity.
+It is vitally important to understand that copyrights are broad protections as defined by 
+national and international copyright law. The "copyright notices" usually included in source 
+files are not copyrights, but rather notices that a party asserts that they hold copyright 
+to the material or to part of the material. Typically these notices are associated with 
+license terms which grant permissions subject to copyright law and with disclaimers that 
+state the position of the copyright holder/distributor with respect to liability surrounding 
+use of the material.
+-	Permissions - the flip side
+Because copyrights arise from the creation of a work, rather than through a registration process, 
+there needs to be a practical way to extend permission to use a work beyond what might be allowed 
+by "fair use" provisions of the copyright laws.
+This permission typically takes the form of a "release" or "license" included in the work, which 
+grants the additional uses beyond those granted by copyright law, usually subject to a variety of 
+conditions. At one extreme sits "public domain" where the originator asserts that he imposes no 
+restrictions on use of the material, at the other restrictive clauses that actually grant no 
+additional rights or impose restrictive, discriminatory or impractical conditions on use of the 
+work.
+Again, an important point to note is that the release and conditions can only apply to the 
+portion of the work that was originated by the copyright holder - the holder of a copyright 
+on a derivative work can neither grant additional permissions for use of the original work, 
+nor impose more restrictive conditions for use of that work.
+Because copyright arises from the creation of a work and not the text or a registration process, 
+removing or altering a copyright notice or associated release terms has no bearing on the 
+existence of the copyright, rather all that is accomplished is to cast doubt upon whatever rights 
+the person making the modifications had to use the material in the first place. Likewise, adding 
+terms and conditions in conflict with the original terms and conditions does not supersede them, 
+rather it casts doubts on the rights of the person making the amendments to use the material and 
+creates confusion as to whether anyone can use the amended version or derivatives thereof.
+Finally, releases are generally binding on the material that they are distributed with. This means 
+that if the originator of a work distributes that work with a release granting certain permissions, 
+those permissions apply as stated, without discrimination, to all persons legitimately possessing 
+a copy of the work. That means that having granted a permission, the copyright holder can not 
+retroactively say that an individual or class of individuals are no longer granted those permissions. 
+Likewise should the copyright holder decide to "go commercial" he can not revoke permissions already 
+granted for the use of the work as distributed, though he may impose more restrictive permissions in 
+his future distributions of that work.
+-	Specific Cases
+This section attempts to summarize the position of OpenBSD relative to some commonly encountered 
+copyrights.
+Berkeley*
+The Berkeley copyright is the model for the OpenBSD copyright. It retains the rights of the 
+copyright holder, while imposing minimal conditions on the use of the copyrighted material. 
+Material with Berkeley copyrights, or copyrights closely adhering to the Berkeley model can 
+generally be included in OpenBSD.
+AT&T*
+As part of its settlement with AT&T*, Berkeley included an AT&T copyright notice on some of the 
+files in 4.4BSD lite and lite2. The terms of this license are identical to the standard Berkeley 
+license.
+Additionally, OpenBSD includes some other AT&T code with non-restrictive copyrights, such as the 
+reference implementation of awk.
+Caldera*
+Caldera* (now known as the SCO group) is the current owner of the Unix code copyrights. On 23 
+January 2002, the original Unix code (versions 1 through seven, including 32V) was freed by Caldera. 
+This code is now available under a 4-term BSD-style license. As a result, it is now possible to 
+incorporate real Unix code into OpenBSD (though this code is quite old and generally requires significant 
+changes to bring it up to date).
+DEC*, Sun*, other manufacturers/software houses.
+In general OpenBSD does not include material copyrighted by manufacturers or software houses. 
+Material may be included where the copyright owner has granted general permission for reuse 
+without conditions, with terms similar to the Berkeley copyright, or where the material is the 
+product of an employee and the employer's copyright notice effectively releases any rights they 
+might have to the work.
+Carnegie-Mellon* (CMU, Mach)
+The Carnegie-Mellon copyright is similar to the Berkeley copyright, except that it requests that 
+derivative works be made available to Carnegie-Mellon. Because this is only a request and not a 
+condition, such material can still be included in OpenBSD. It should be noted that existing 
+versions of Mach are still subject to AT&T copyrights, which prevents the general distribution 
+of Mach sources.
+Apache*
+The original Apache* copyright is similar to the Berkeley copyright, except that it stipulates 
+that products derived from the code may not have "Apache" in their name. The purpose of this 
+clause is to avoid a situation in which another party releases a modified version of the code 
+named in such a way to make users think that it is the "official" version. This is not an issue 
+with OpenBSD because OpenBSD is a Compilation, and not a Derived Work. Source code published under 
+version 2 of the Apache license cannot be included into OpenBSD. As a consequence, OpenBSD now 
+maintains its own version of Apache based on version 1.3.29. The OpenBSD version includes many 
+enhancements and bugfixes.
+ISC*
+The ISC* copyright is functionally equivalent to a two-term BSD copyright with language removed 
+that is made unnecessary by the Berne convention. This is the preferred license for new code 
+incorporated into OpenBSD. A sample license is included in the source tree as 
+/usr/src/share/misc/license.template.
+GNU* General Public License, GPL, LGPL, copyleft, etc.
+The GNU* Public License and licenses modeled on it impose the restriction that source code must 
+be distributed or made available for all works that are derivatives of the GNU copyrighted code.
+While this may be a noble strategy in terms of software sharing, it is a condition that is 
+typically unacceptable for commercial use of software. As a consequence, software bound by the 
+GPL terms can not be included in the kernel or "runtime" of OpenBSD, though software subject to
+ GPL terms may be included as development tools or as part of the system that are "optional" as 
+long as such use does not result in OpenBSD as a whole becoming subject to the GPL terms.
+As an example, GCC and other GNU tools are included in the OpenBSD tool chain. However, it is 
+quite possible to distribute a system for many applications without a tool chain, or the 
+distributor can choose to include a tool chain as an optional bundle which conforms to the 
+GPL terms.
+NetBSD*
+Much of OpenBSD is originally based on and evolved from NetBSD*, since some of the OpenBSD 
+developers were involved in the NetBSD project. The general NetBSD license terms are compatible 
+with the Berkeley license and permit such use. Material subject only to the general NetBSD license 
+can generally be included in OpenBSD.
+In the past, NetBSD has included material copyrighted by individuals who have imposed license 
+conditions beyond that of the general NetBSD license, but granted the NetBSD Foundation license 
+to distribute the material. Such material can not be included in OpenBSD as long as the conditions 
+imposed are at odds with the OpenBSD license terms or releases from those terms are offered on a 
+discriminatory basis.
+FreeBSD*
+Most of FreeBSD* is also based on Berkeley licensed material or includes copyright notices based 
+on the Berkeley model. Such material can be included in OpenBSD, while those parts that are subject 
+to GPL or various individual copyright terms that are at odds with the OpenBSD license can not be 
+included in OpenBSD.
+Linux*
+Most of Linux* is subject to GPL style licensing terms and therefore can not be included in 
+OpenBSD. Individual components may be eligible, subject to the terms of the originator's copyright 
+notices. Note that Linux "distributions" may also be subject to additional copyright claims of the 
+distributing organization, either as a compilation or on material included that is not part of the 
+Linux core.
+X*, XFree86*, X.Org*
+X*, X.Org* or XFree86* are not parts of OpenBSD, rather X.Org and parts of XFree86 3.3.6 are 
+distributed with many OpenBSD ports as a convenience to the user, subject to applicable license 
+terms.
+Shareware, Charityware, Freeware, etc.
+Most "shareware" copyright notices impose conditions for redistribution, use or visibility that 
+are at conflict with the OpenBSD project goals. Review on a case-by-case basis is required as to 
+whether the wording of the conditions is acceptable in terms of conditions being requested vs. 
+demanded and whether the spirit of the conditions is compatible with goals of the OpenBSD project.
+Public Domain
+While material that is truly entered into the "Public Domain" can be included in OpenBSD, review 
+is required on a case by case basis. Frequently the "public domain" assertion is made by someone 
+who does not really hold all rights under Copyright law to grant that status or there are a variety
+of conditions imposed on use. For a work to be truly in the "Public Domain" all rights are abandoned 
+and the material is offered without restrictions.
diff --git a/Readme.md b/Readme.md
new file mode 100644
index 0000000..8445d88
--- /dev/null
+++ b/Readme.md
@@ -0,0 +1,106 @@
+# Rust SGX SDK
+This Rust SGX SDK helps developers write Intel SGX enclaves in Rust programming language. 
+
+## Requirement
+Ubuntu 16.04
+
+[Intel SGX SDK 1.8 for Linux](https://01.org/zh/intel-softwareguard-extensions) installed
+
+Docker (Recommended)
+
+## Configuration
+
+### Using docker (Recommended)
+First, make sure Intel SGX Driver 1.8 is installed and functions well. `/dev/isgx` should be appeared.
+
+Second, pull the docker image
+
+`$ docker pull baiduxlab/sgx-rust`
+
+Third, start a docker with sgx device support and the Rust SGX SDK.
+
+`$ docker run -v /your/path/to/rust-sgx:/root/sgx -ti --device /dev/isgx baiduxlab/sgx-rust`
+
+Next, start the aesm service inside the docker
+
+`root@docker:/# /opt/intel/sgxpsw/aesm/aesm_service &`
+
+Finally, check if the sample code works
+
+`root@docker:~/sgx/samplecode/helloworld# make`
+
+`root@docker:~/sgx/samplecode/helloworld# cd bin`
+
+`root@docker:~/sgx/samplecode/helloworld/bin# ./app`
+
+### Native without docker (Not recommended)
+
+Install Intel SGX driver and SDK first. And refer to Dockerfile for detail. 
+
+## Build the docker image by yourself
+
+Make sure Intel SGX SDK is properly installed and service started on the host
+OS. Then `cd dockerfile` and run `docker build -t rust-sgx-docker` to build.
+
+# Sample Codes
+
+We provide five sample codes to help developers understand how to write Enclave
+codes in Rust. These codes are located at `samplecode` directory.
+
+* `helloworld` is a very simple app. It shows some basic usages of argument
+passing, Rust string and ECALL/OCALLs.
+
+* `crypto` shows the usage of crypto APIs provided by Intel SGX libraries. It
+does some crypto calculations inside the enclave, which is recommended in most
+circumstances.
+
+* `localattestation` is a sample ported from the original Intel SGX SDK. It
+shows how to do local attestation in Rust programming language.
+
+* `sealeddata` sample shows how to seal secret data in an enclave and how to
+verify the sealed data. 
+
+* `thread` sample is a sample ported from the original Intel SGX SDK, showing
+some basic usages of threading APIs. 
+
+# Tips for writing enclaves in Rust
+
+## Writing EDL
+
+* For fixed-length array in ECALL/OCALL definition, declare it as an array.  For
+dynamic-length array, use the keyword `size=` to let the Intel SGX knows how
+many bytes should be copied.
+
+## ECALL Function Naming
+
+* Add `#[no_mangle]` for every ECALL function.
+
+## Passing/returning arrays
+
+* For dynamic-length array, the only way is to use raw pointers in Rust. There
+are several functions to get/set data using raw pointers such as
+[`offset`](https://doc.rust-lang.org/1.9.0/std/primitive.pointer.html#method.offset)
+method. One can also use
+[`slice::from_raw_parts`](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html)
+to convert the array to a slice.
+
+* For Fixed-length array, the above method is acceptable. And according to
+discussions in [issue 30382](https://github.com/rust-lang/rust/issues/30382)
+and [issue 31227](https://github.com/rust-lang/rust/issues/31227),
+thin-pointers (such as fixed-length array) are FFI-safe for now, but
+undocumented. In the sample codes, we use fixed-length arrays for passing and
+returning some fixed-length data.
+
+# License
+
+Baidu Rust-SGX SDK is provided under the BSD license. Please refer to the [License file](LICENSE)
+for details.
+
+# Authors
+
+Ran Duan, Long Li, Yu Ding, Lenx Wei, Tanghui Chen
+
+# Contacts
+
+Yu Ding, dingelish@gmail.com
+
diff --git a/buildenv.mk b/buildenv.mk
new file mode 100644
index 0000000..2fb1a80
--- /dev/null
+++ b/buildenv.mk
@@ -0,0 +1,130 @@
+#
+# Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * 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.
+#  * Neither the name of Baidu, Inc., nor the names of its
+#    contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+#
+#
+
+CP    := /bin/cp -f
+MKDIR := mkdir -p
+STRIP := strip
+OBJCOPY := objcopy
+
+# clean the content of 'INCLUDE' - this variable will be set by vcvars32.bat
+# thus it will cause build error when this variable is used by our Makefile,
+# when compiling the code under Cygwin tainted by MSVC environment settings.
+INCLUDE :=
+
+# turn on stack protector for SDK
+COMMON_FLAGS += -fstack-protector
+
+ifdef DEBUG
+    COMMON_FLAGS += -ggdb -DDEBUG -UNDEBUG
+    COMMON_FLAGS += -DSE_DEBUG_LEVEL=SE_TRACE_DEBUG
+else
+    COMMON_FLAGS += -O2   -UDEBUG -DNDEBUG
+endif
+
+ifdef SE_SIM
+    COMMON_FLAGS += -DSE_SIM
+endif
+
+# turn on compiler warnings as much as possible
+COMMON_FLAGS += -Wall -Wextra -Winit-self -Wpointer-arith -Wreturn-type \
+		-Waddress -Wsequence-point -Wformat-security \
+		-Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \
+		-Wcast-align -Wconversion -Wredundant-decls
+
+# additional warnings flags for C
+CFLAGS += -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants
+
+# additional warnings flags for C++
+CXXFLAGS += -Wnon-virtual-dtor
+
+# for static_assert()
+CXXFLAGS += -std=c++0x
+
+.DEFAULT_GOAL := all
+# this turns off the RCS / SCCS implicit rules of GNU Make
+% : RCS/%,v
+% : RCS/%
+% : %,v
+% : s.%
+% : SCCS/s.%
+
+# If a rule fails, delete $@.
+.DELETE_ON_ERROR:
+
+HOST_FILE_PROGRAM := file
+
+UNAME := $(shell uname -m)
+ifneq (,$(findstring 86,$(UNAME)))
+    HOST_ARCH := x86
+    ifneq (,$(shell $(HOST_FILE_PROGRAM) -L $(SHELL) | grep 'x86[_-]64'))
+        HOST_ARCH := x86_64
+    endif
+else
+    $(info Unknown host CPU arhitecture $(UNAME))
+    $(error Aborting)
+endif
+
+
+ifeq "$(findstring __INTEL_COMPILER, $(shell $(CC) -E -dM -xc /dev/null))" "__INTEL_COMPILER"
+  ifeq ($(shell test -f /usr/bin/dpkg; echo $$?), 0)
+    ADDED_INC := -I /usr/include/$(shell dpkg-architecture -qDEB_BUILD_MULTIARCH)
+  endif
+endif
+
+ARCH := $(HOST_ARCH)
+ifeq "$(findstring -m32, $(CXXFLAGS))" "-m32"
+  ARCH := x86
+endif
+
+ifeq ($(ARCH), x86)
+COMMON_FLAGS += -DITT_ARCH_IA32
+else
+COMMON_FLAGS += -DITT_ARCH_IA64
+endif
+
+CFLAGS   += $(COMMON_FLAGS)
+CXXFLAGS += $(COMMON_FLAGS)
+
+# Compiler and linker options for an Enclave
+#
+# We are using '--export-dynamic' so that `g_global_data_sim' etc.
+# will be exported to dynamic symbol table.
+#
+# When `pie' is enabled, the linker (both BFD and Gold) under Ubuntu 14.04
+# will hide all symbols from dynamic symbol table even if they are marked
+# as `global' in the LD version script.
+ENCLAVE_CFLAGS   = -ffreestanding -nostdinc -fvisibility=hidden -fpie
+ENCLAVE_CXXFLAGS = $(ENCLAVE_CFLAGS) -nostdinc++
+ENCLAVE_LDFLAGS  = -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
+                   -Wl,-pie,-eenclave_entry -Wl,--export-dynamic  \
+                   -Wl,--gc-sections \
+                   -Wl,--defsym,__ImageBase=0
+
diff --git a/common/inc/assert.h b/common/inc/assert.h
new file mode 100644
index 0000000..82489e8
--- /dev/null
+++ b/common/inc/assert.h
@@ -0,0 +1,63 @@
+/*	$OpenBSD: assert.h,v 1.12 2006/01/31 10:53:51 hshoexer Exp $	*/
+/*	$NetBSD: assert.h,v 1.6 1994/10/26 00:55:44 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)assert.h	8.2 (Berkeley) 1/21/94
+ */
+
+/*
+ * Unlike other ANSI header files, <assert.h> may usefully be included
+ * multiple times, with and without NDEBUG defined.
+ */
+
+#include <sys/cdefs.h>
+
+#undef assert
+
+#ifdef NDEBUG
+# define assert(e) ((void)0)
+#else
+# define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__, __func__, #e))
+#endif
+
+#ifndef _ASSERT_H_DECLS
+#define _ASSERT_H_DECLS
+__BEGIN_DECLS
+
+void _TLIBC_CDECL_ __assert(const char *, int, const char *, const char *);
+
+__END_DECLS
+#endif /* Not _ASSERT_H_DECLS */
+
diff --git a/common/inc/complex.h b/common/inc/complex.h
new file mode 100644
index 0000000..7d92d63
--- /dev/null
+++ b/common/inc/complex.h
@@ -0,0 +1,134 @@
+/*	$OpenBSD: complex.h,v 1.3 2010/07/24 22:17:03 guenther Exp $	*/
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _COMPLEX_H_
+#define	_COMPLEX_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * C99
+ */
+#ifdef __GNUC__
+#if __STDC_VERSION__ < 199901
+#define _Complex	__complex__
+#endif
+#define _Complex_I	1.0fi
+#elif defined(lint)
+#define _Complex_I	1.0fi
+#endif
+
+#define complex		_Complex
+
+/* XXX switch to _Imaginary_I */
+#undef I
+#define I		_Complex_I
+
+__BEGIN_DECLS
+/* 
+ * Double versions of C99 functions
+ */
+double complex cacos(double complex);
+double complex casin(double complex);
+double complex catan(double complex);
+double complex ccos(double complex);
+double complex csin(double complex);
+double complex ctan(double complex);
+double complex cacosh(double complex);
+double complex casinh(double complex);
+double complex catanh(double complex);
+double complex ccosh(double complex);
+double complex csinh(double complex);
+double complex ctanh(double complex);
+double complex cexp(double complex);
+double complex clog(double complex);
+double cabs(double complex);
+double complex cpow(double complex, double complex);
+double complex csqrt(double complex);
+double carg(double complex);
+double cimag(double complex);
+double complex conj(double complex);
+double complex cproj(double complex);
+double creal(double complex);
+/*
+ * C99 reserved
+ */
+double complex clog10(double complex);
+
+/* 
+ * Float versions of C99 functions
+ */
+float complex cacosf(float complex);
+float complex casinf(float complex);
+float complex catanf(float complex);
+float complex ccosf(float complex);
+float complex csinf(float complex);
+float complex ctanf(float complex);
+float complex cacoshf(float complex);
+float complex casinhf(float complex);
+float complex catanhf(float complex);
+float complex ccoshf(float complex);
+float complex csinhf(float complex);
+float complex ctanhf(float complex);
+float complex cexpf(float complex);
+float complex clogf(float complex);
+float cabsf(float complex);
+float complex cpowf(float complex, float complex);
+float complex csqrtf(float complex);
+float cargf(float complex);
+float cimagf(float complex);
+float complex conjf(float complex);
+float complex cprojf(float complex);
+float crealf(float complex);
+/*
+ * C99 reserved
+ */
+float complex clog10f(float complex);
+
+/* 
+ * Long double versions of C99 functions
+ */
+long double complex cacosl(long double complex);
+long double complex casinl(long double complex);
+long double complex catanl(long double complex);
+long double complex ccosl(long double complex);
+long double complex csinl(long double complex);
+long double complex ctanl(long double complex);
+long double complex cacoshl(long double complex);
+long double complex casinhl(long double complex);
+long double complex catanhl(long double complex);
+long double complex ccoshl(long double complex);
+long double complex csinhl(long double complex);
+long double complex ctanhl(long double complex);
+long double complex cexpl(long double complex);
+long double complex clogl(long double complex);
+long double cabsl(long double complex);
+long double complex cpowl(long double complex, long double complex);
+long double complex csqrtl(long double complex);
+long double cargl(long double complex);
+long double cimagl(long double complex);
+long double complex conjl(long double complex);
+long double complex cprojl(long double complex);
+long double creall(long double complex);
+/*
+ * C99 reserved
+ */
+long double complex clog10l(long double complex);
+
+__END_DECLS
+
+#endif /* !_COMPLEX_H_ */
diff --git a/common/inc/ctype.h b/common/inc/ctype.h
new file mode 100644
index 0000000..1408447
--- /dev/null
+++ b/common/inc/ctype.h
@@ -0,0 +1,64 @@
+/*	$OpenBSD: ctype.h,v 1.22 2010/10/01 20:10:24 guenther Exp $	*/
+/*	$NetBSD: ctype.h,v 1.14 1994/10/26 00:55:47 cgd Exp $	*/
+
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)ctype.h	5.3 (Berkeley) 4/3/91
+ */
+
+#ifndef _CTYPE_H_
+#define _CTYPE_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+int _TLIBC_CDECL_ isalnum(int);
+int _TLIBC_CDECL_ isalpha(int);
+int _TLIBC_CDECL_ iscntrl(int);
+int _TLIBC_CDECL_ isdigit(int);
+int _TLIBC_CDECL_ isgraph(int);
+int _TLIBC_CDECL_ islower(int);
+int _TLIBC_CDECL_ isprint(int);
+int _TLIBC_CDECL_ ispunct(int);
+int _TLIBC_CDECL_ isspace(int);
+int _TLIBC_CDECL_ isupper(int);
+int _TLIBC_CDECL_ isxdigit(int);
+int _TLIBC_CDECL_ tolower(int);
+int _TLIBC_CDECL_ toupper(int);
+int _TLIBC_CDECL_ isblank(int);
+
+__END_DECLS
+
+#endif /* _CTYPE_H_ */
diff --git a/common/inc/endian.h b/common/inc/endian.h
new file mode 100644
index 0000000..fcd74c9
--- /dev/null
+++ b/common/inc/endian.h
@@ -0,0 +1,33 @@
+/*	$OpenBSD: endian.h,v 1.18 2006/03/27 07:09:24 otto Exp $	*/
+
+/*-
+ * Copyright (c) 1997 Niklas Hallqvist.  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 AUTHOR ``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 AUTHOR 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 _ENDIAN_H_
+#define _ENDIAN_H_
+
+#include <sys/endian.h>
+
+#endif /* _ENDIAN_H_ */
+
diff --git a/common/inc/errno.h b/common/inc/errno.h
new file mode 100644
index 0000000..0924d5a
--- /dev/null
+++ b/common/inc/errno.h
@@ -0,0 +1,187 @@
+/*	$OpenBSD: errno.h,v 1.1 2005/12/28 16:33:56 millert Exp $	*/
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)errno.h	8.5 (Berkeley) 1/21/94
+ */
+
+#ifndef	_ERRNO_H_
+#define	_ERRNO_H_
+
+#include <sys/cdefs.h>
+
+#define EPERM 1
+#define ENOENT 2
+#define ESRCH 3
+#define EINTR 4
+#define EIO 5
+#define ENXIO 6
+#define E2BIG 7
+#define ENOEXEC 8
+#define EBADF 9
+#define ECHILD 10
+#define EAGAIN 11
+#define ENOMEM 12
+#define EACCES 13
+#define EFAULT 14
+#define ENOTBLK 15
+#define EBUSY 16
+#define EEXIST 17
+#define EXDEV 18
+#define ENODEV 19
+#define ENOTDIR 20
+#define EISDIR 21
+#define EINVAL 22
+#define ENFILE 23
+#define EMFILE 24
+#define ENOTTY 25
+#define ETXTBSY 26
+#define EFBIG 27
+#define ENOSPC 28
+#define ESPIPE 29
+#define EROFS 30
+#define EMLINK 31
+#define EPIPE 32
+#define EDOM 33
+#define ERANGE 34
+#define EDEADLK 35
+#define ENAMETOOLONG 36
+#define ENOLCK 37
+#define ENOSYS 38
+#define ENOTEMPTY 39
+#define ELOOP 40
+#define EWOULDBLOCK EAGAIN
+#define ENOMSG 42
+#define EIDRM 43
+#define ECHRNG 44
+#define EL2NSYNC 45
+#define EL3HLT 46
+#define EL3RST 47
+#define ELNRNG 48
+#define EUNATCH 49
+#define ENOCSI 50
+#define EL2HLT 51
+#define EBADE 52
+#define EBADR 53
+#define EXFULL 54
+#define ENOANO 55
+#define EBADRQC 56
+#define EBADSLT 57
+#define EDEADLOCK EDEADLK
+#define EBFONT 59
+#define ENOSTR 60
+#define ENODATA 61
+#define ETIME 62
+#define ENOSR 63
+#define ENONET 64
+#define ENOPKG 65
+#define EREMOTE 66
+#define ENOLINK 67
+#define EADV 68
+#define ESRMNT 69
+#define ECOMM 70
+#define EPROTO 71
+#define EMULTIHOP 72
+#define EDOTDOT 73
+#define EBADMSG 74
+#define EOVERFLOW 75
+#define ENOTUNIQ 76
+#define EBADFD 77
+#define EREMCHG 78
+#define ELIBACC 79
+#define ELIBBAD 80
+#define ELIBSCN 81
+#define ELIBMAX 82
+#define ELIBEXEC 83
+#define EILSEQ 84
+#define ERESTART 85
+#define ESTRPIPE 86
+#define EUSERS 87
+#define ENOTSOCK 88
+#define EDESTADDRREQ 89
+#define EMSGSIZE 90
+#define EPROTOTYPE 91
+#define ENOPROTOOPT 92
+#define EPROTONOSUPPORT 93
+#define ESOCKTNOSUPPORT 94
+#define EOPNOTSUPP 95
+#define EPFNOSUPPORT 96
+#define EAFNOSUPPORT 97
+#define EADDRINUSE 98
+#define EADDRNOTAVAIL 99
+#define ENETDOWN 100
+#define ENETUNREACH 101
+#define ENETRESET 102
+#define ECONNABORTED 103
+#define ECONNRESET 104
+#define ENOBUFS 105
+#define EISCONN 106
+#define ENOTCONN 107
+#define ESHUTDOWN 108
+#define ETOOMANYREFS 109
+#define ETIMEDOUT 110
+#define ECONNREFUSED 111
+#define EHOSTDOWN 112
+#define EHOSTUNREACH 113
+#define EALREADY 114
+#define EINPROGRESS 115
+#define ESTALE 116
+#define EUCLEAN 117
+#define ENOTNAM 118
+#define ENAVAIL 119
+#define EISNAM 120
+#define EREMOTEIO 121
+#define EDQUOT 122
+#define ENOMEDIUM 123
+#define EMEDIUMTYPE 124
+#define ECANCELED 125
+#define ENOKEY 126
+#define EKEYEXPIRED 127
+#define EKEYREVOKED 128
+#define EKEYREJECTED 129
+#define EOWNERDEAD 130
+#define ENOTRECOVERABLE 131
+#define ERFKILL 132
+#define EHWPOISON 133
+#define ENOTSUP EOPNOTSUPP
+
+__BEGIN_DECLS
+
+#ifndef errno
+int * _TLIBC_CDECL_ __errno(void);
+#define	errno (*__errno())
+#endif /* errno */
+__END_DECLS
+
+#endif /* _ERRNO_H_ */
diff --git a/common/inc/float.h b/common/inc/float.h
new file mode 100644
index 0000000..99ae58d
--- /dev/null
+++ b/common/inc/float.h
@@ -0,0 +1,84 @@
+/* $OpenBSD: float.h,v 1.3 2008/07/21 20:50:54 martynas Exp $ */
+/* $NetBSD: float.h,v 1.8 1995/06/20 20:45:37 jtc Exp $ */
+
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)float.h 7.1 (Berkeley) 5/8/90
+ */
+
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+
+#include <sys/cdefs.h>
+
+#define FLT_RADIX       2        /* b */
+
+// The rounding direction can be specified by fesetround() in <fenv.h>
+#define FLT_ROUNDS      1        /* addition rounding: near */
+#define DECIMAL_DIG     21       /* max precision in decimal digits */
+
+// NOTE: FLT_EVAL_METHOD is -1 under FREEBSD x86. 
+#ifdef __i386__
+#define FLT_EVAL_METHOD 2        /* long double */
+#else
+#define FLT_EVAL_METHOD 0        /* no promotions */
+#endif
+
+#define DBL_MANT_DIG    53
+#define DBL_EPSILON     2.2204460492503131E-16
+#define DBL_DIG         15
+#define DBL_MIN_EXP     (-1021)
+#define DBL_MIN         2.2250738585072014E-308
+#define DBL_MIN_10_EXP  (-307)
+#define DBL_MAX_EXP     1024
+#define DBL_MAX_10_EXP  308
+
+#define FLT_MANT_DIG    24                      /* p */
+#define FLT_DIG         6                       /* floor((p-1)*log10(b))+(b == 10) */
+#define FLT_MIN_EXP     (-125)                  /* emin */
+#define FLT_MIN_10_EXP  (-37)                   /* ceil(log10(b**(emin-1))) */
+#define FLT_MAX_EXP     128                     /* emax */
+#define FLT_MAX_10_EXP  38                      /* floor(log10((1-b**(-p))*b**emax)) */
+
+#define DBL_MAX         1.7976931348623157E+308
+#define FLT_EPSILON     1.19209290E-07F         /* b**(1-p) */
+#define FLT_MIN         1.17549435E-38F         /* b**(emin-1) */
+#define FLT_MAX         3.40282347E+38F         /* (1-b**(-p))*b**emax */
+
+#define LDBL_MANT_DIG   64
+#define LDBL_EPSILON    1.08420217248550443401e-19L
+#define LDBL_DIG        18
+#define LDBL_MIN_EXP    (-16381)
+#define LDBL_MIN        3.36210314311209350626e-4932L
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_EXP    16384
+#define LDBL_MAX        1.18973149535723176502e+4932L
+#define LDBL_MAX_10_EXP 4932
+
+#endif  /* _FLOAT_H_ */
diff --git a/common/inc/inttypes.h b/common/inc/inttypes.h
new file mode 100644
index 0000000..c4fbcaf
--- /dev/null
+++ b/common/inc/inttypes.h
@@ -0,0 +1,330 @@
+/*  $OpenBSD: inttypes.h,v 1.10 2009/01/13 18:13:51 kettenis Exp $  */
+
+/*
+ * Copyright (c) 1997, 2005 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _INTTYPES_H_
+#define _INTTYPES_H_
+
+#include <sys/stdint.h>
+
+/*
+ * 7.8.1 Macros for format specifiers
+ *
+ * Each of the following object-like macros expands to a string
+ * literal containing a conversion specifier, possibly modified by
+ * a prefix such as hh, h, l, or ll, suitable for use within the
+ * format argument of a formatted input/output function when
+ * converting the corresponding integer type.  These macro names
+ * have the general form of PRI (character string literals for the
+ * fprintf family) or SCN (character string literals for the fscanf
+ * family), followed by the conversion specifier, followed by a
+ * name corresponding to a similar typedef name.  For example,
+ * PRIdFAST32 can be used in a format string to print the value of
+ * an integer of type int_fast32_t.
+ */
+
+/* fprintf macros for signed integers */
+#define PRId8           "d"     /* int8_t */
+#define PRId16          "d"     /* int16_t */
+#define PRId32          "d"     /* int32_t */
+#ifdef __x86_64__
+#define PRId64          "ld"    /* int64_t */
+#else
+#define PRId64          "lld"   /* int64_t */
+#endif
+
+#define PRIdLEAST8      "d"     /* int_least8_t */
+#define PRIdLEAST16     "d"     /* int_least16_t */
+#define PRIdLEAST32     "d"     /* int_least32_t */
+#ifdef __x86_64__
+#define PRIdLEAST64     "ld"    /* int_least64_t */
+#else
+#define PRIdLEAST64     "lld"   /* int_least64_t */
+#endif
+
+#define PRIdFAST8       "d"     /* int_fast8_t */
+#ifdef __x86_64__
+#define PRIdFAST16      "ld"    /* int_fast16_t */
+#define PRIdFAST32      "ld"    /* int_fast32_t */
+#define PRIdFAST64      "ld"    /* int_fast64_t */
+#else
+#define PRIdFAST16      "d"     /* int_fast16_t */
+#define PRIdFAST32      "d"     /* int_fast32_t */
+#define PRIdFAST64      "lld"   /* int_fast64_t */
+#endif
+
+#ifdef __x86_64__
+#define PRIdMAX         "ld"    /* intmax_t */
+#else
+#if defined(__i386__) 
+#define PRIdMAX         "lld"   /* intmax_t */
+#else
+#define PRIdMAX         "jd"    /* intmax_t */
+#endif
+#endif
+
+#ifdef __i386__
+#define PRIdPTR         "d"     /* intptr_t */
+#else
+#define PRIdPTR         "ld"    /* intptr_t */
+#endif
+
+#define PRIi8           "i"     /* int8_t */
+#define PRIi16          "i"     /* int16_t */
+#define PRIi32          "i"     /* int32_t */
+#ifdef __x86_64__
+#define PRIi64          "li"    /* int64_t */
+#else
+#define PRIi64          "lli"   /* int64_t */
+#endif
+
+#define PRIiLEAST8      "i"     /* int_least8_t */
+#define PRIiLEAST16     "i"     /* int_least16_t */
+#define PRIiLEAST32     "i"     /* int_least32_t */
+#ifdef __x86_64__
+#define PRIiLEAST64     "li"    /* int_least64_t */
+#else
+#define PRIiLEAST64     "lli"   /* int_least64_t */
+#endif
+
+#define PRIiFAST8       "i"     /* int_fast8_t */
+#ifdef __x86_64__
+#define PRIiFAST16      "li"    /* int_fast16_t */
+#define PRIiFAST32      "li"    /* int_fast32_t */
+#define PRIiFAST64      "li"    /* int_fast64_t */
+#else
+#define PRIiFAST16      "i"     /* int_fast16_t */
+#define PRIiFAST32      "i"     /* int_fast32_t */
+#define PRIiFAST64      "lli"   /* int_fast64_t */
+#endif
+
+#ifdef __x86_64__
+#define PRIiMAX         "li"    /* intmax_t */
+#else
+#if defined(__i386__) 
+#define PRIiMAX         "lli"   /* intmax_t */
+#else
+#define PRIiMAX         "ji"    /* intmax_t */
+#endif
+#endif
+
+#ifdef __i386__
+#define PRIiPTR         "i"     /* intptr_t */
+#else
+#define PRIiPTR         "li"    /* intptr_t */
+#endif
+
+/* fprintf macros for unsigned integers */
+#define PRIo8           "o"     /* int8_t */
+#define PRIo16          "o"     /* int16_t */
+#define PRIo32          "o"     /* int32_t */
+#ifdef __x86_64__
+#define PRIo64          "lo"    /* int64_t */
+#else
+#define PRIo64          "llo"   /* int64_t */
+#endif
+
+#define PRIoLEAST8      "o"     /* int_least8_t */
+#define PRIoLEAST16     "o"     /* int_least16_t */
+#define PRIoLEAST32     "o"     /* int_least32_t */
+#ifdef __x86_64__
+#define PRIoLEAST64     "lo"    /* int_least64_t */
+#else
+#define PRIoLEAST64     "llo"   /* int_least64_t */
+#endif
+
+#define PRIoFAST8       "o"     /* int_fast8_t */
+#ifdef __x86_64__
+#define PRIoFAST16      "lo"    /* int_fast16_t */
+#define PRIoFAST32      "lo"    /* int_fast32_t */
+#define PRIoFAST64      "lo"    /* int_fast64_t */
+#else
+#define PRIoFAST16      "o"     /* int_fast16_t */
+#define PRIoFAST32      "o"     /* int_fast32_t */
+#define PRIoFAST64      "llo"   /* int_fast64_t */
+#endif
+
+#ifdef __x86_64__
+#define PRIoMAX         "lo"    /* intmax_t */
+#else
+#if defined(__i386__) 
+#define PRIoMAX         "llo"   /* intmax_t */
+#else
+#define PRIoMAX         "jo"    /* intmax_t */
+#endif
+#endif
+
+#ifdef __i386__
+#define PRIoPTR         "o"     /* intptr_t */
+#else
+#define PRIoPTR         "lo"    /* intptr_t */
+#endif
+
+#define PRIu8           "u"     /* uint8_t */
+#define PRIu16          "u"     /* uint16_t */
+#define PRIu32          "u"     /* uint32_t */
+
+#ifdef __x86_64__
+#define PRIu64          "lu"    /* uint64_t */
+#else
+#define PRIu64          "llu"   /* uint64_t */
+#endif
+
+#define PRIuLEAST8      "u"     /* uint_least8_t */
+#define PRIuLEAST16     "u"     /* uint_least16_t */
+#define PRIuLEAST32     "u"     /* uint_least32_t */
+
+#ifdef __x86_64__
+#define PRIuLEAST64     "lu"    /* uint_least64_t */
+#else
+#define PRIuLEAST64     "llu"   /* uint_least64_t */
+#endif
+
+#define PRIuFAST8       "u"     /* uint_fast8_t */
+
+#ifdef __x86_64__
+#define PRIuFAST16      "lu"    /* uint_fast16_t */
+#define PRIuFAST32      "lu"    /* uint_fast32_t */
+#define PRIuFAST64      "lu"    /* uint_fast64_t */
+#else
+#define PRIuFAST16      "u"     /* uint_fast16_t */
+#define PRIuFAST32      "u"     /* uint_fast32_t */
+#define PRIuFAST64      "llu"   /* uint_fast64_t */
+#endif
+
+#ifdef __x86_64__
+#define PRIuMAX         "lu"    /* uintmax_t */
+#else
+#if defined(__i386__) 
+#define PRIuMAX         "llu"   /* uintmax_t */
+#else
+#define PRIuMAX         "ju"    /* uintmax_t */
+#endif
+#endif
+
+#ifdef __i386__
+#define PRIuPTR         "u"     /* uintptr_t */
+#else
+#define PRIuPTR         "lu"    /* uintptr_t */
+#endif
+
+#define PRIx8           "x"     /* uint8_t */
+#define PRIx16          "x"     /* uint16_t */
+#define PRIx32          "x"     /* uint32_t */
+#ifdef __x86_64__
+#define PRIx64          "lx"    /* uint64_t */
+#else
+#define PRIx64          "llx"   /* uint64_t */
+#endif
+
+#define PRIxLEAST8      "x"     /* uint_least8_t */
+#define PRIxLEAST16     "x"     /* uint_least16_t */
+#define PRIxLEAST32     "x"     /* uint_least32_t */
+#ifdef __x86_64__
+#define PRIxLEAST64     "lx"    /* uint_least64_t */
+#else
+#define PRIxLEAST64     "llx"   /* uint_least64_t */
+#endif
+
+#define PRIxFAST8       "x"     /* uint_fast8_t */
+#ifdef __x86_64__
+#define PRIxFAST16      "lx"    /* uint_fast16_t */
+#define PRIxFAST32      "lx"    /* uint_fast32_t */
+#define PRIxFAST64      "lx"    /* uint_fast64_t */
+#else
+#define PRIxFAST16      "x"     /* uint_fast16_t */
+#define PRIxFAST32      "x"     /* uint_fast32_t */
+#define PRIxFAST64      "llx"   /* uint_fast64_t */
+#endif
+
+#ifdef __x86_64__
+#define PRIxMAX         "lx"    /* uintmax_t */
+#else
+#if defined(__i386__) 
+#define PRIxMAX         "llx"   /* uintmax_t */
+#else
+#define PRIxMAX         "jx"    /* uintmax_t */
+#endif
+#endif
+
+#ifdef __i386__
+#define PRIxPTR         "x"     /* uintptr_t */
+#else
+#define PRIxPTR         "lx"    /* uintptr_t */
+#endif
+
+#define PRIX8           "X"     /* uint8_t */
+#define PRIX16          "X"     /* uint16_t */
+#define PRIX32          "X"     /* uint32_t */
+
+#ifdef __x86_64__
+#define PRIX64          "lX"    /* uint64_t */
+#else
+#define PRIX64          "llX"   /* uint64_t */
+#endif
+
+#define PRIXLEAST8      "X"     /* uint_least8_t */
+#define PRIXLEAST16     "X"     /* uint_least16_t */
+#define PRIXLEAST32     "X"     /* uint_least32_t */
+#ifdef __x86_64__
+#define PRIXLEAST64     "lX"    /* uint_least64_t */
+#else
+#define PRIXLEAST64     "llX"   /* uint_least64_t */
+#endif
+
+#define PRIXFAST8       "X"     /* uint_fast8_t */
+#ifdef __x86_64__
+#define PRIXFAST16      "lX"    /* uint_fast16_t */
+#define PRIXFAST32      "lX"    /* uint_fast32_t */
+#define PRIXFAST64      "lX"    /* uint_fast64_t */
+#else
+#define PRIXFAST16      "X"     /* uint_fast16_t */
+#define PRIXFAST32      "X"     /* uint_fast32_t */
+#define PRIXFAST64      "llX"   /* uint_fast64_t */
+#endif
+
+#ifdef __x86_64__
+#define PRIXMAX         "lX"    /* uintmax_t */
+#else
+#if defined(__i386__) 
+#define PRIXMAX         "llX"   /* uintmax_t */
+#else
+#define PRIXMAX         "jX"    /* uintmax_t */
+#endif
+#endif
+
+#ifdef __i386__
+#define PRIXPTR         "X"     /* uintptr_t */
+#else
+#define PRIXPTR         "lX"    /* uintptr_t */
+#endif
+
+typedef struct {
+    intmax_t quot;      /* quotient */
+    intmax_t rem;       /* remainder */
+} imaxdiv_t;
+
+__BEGIN_DECLS
+
+intmax_t _TLIBC_CDECL_ imaxabs(intmax_t);
+imaxdiv_t _TLIBC_CDECL_ imaxdiv(intmax_t, intmax_t);
+intmax_t _TLIBC_CDECL_ strtoimax(const char *, char **, int);
+uintmax_t _TLIBC_CDECL_ strtoumax(const char *, char **, int);
+
+__END_DECLS
+
+#endif /* _INTTYPES_H_ */
diff --git a/common/inc/iso646.h b/common/inc/iso646.h
new file mode 100644
index 0000000..d711cac
--- /dev/null
+++ b/common/inc/iso646.h
@@ -0,0 +1,26 @@
+/*	$OpenBSD: iso646.h,v 1.3 2001/10/11 00:05:21 espie Exp $	*/
+/*	$NetBSD: iso646.h,v 1.1 1995/02/17 09:08:10 jtc Exp $	*/
+
+/* 
+ * Written by J.T. Conklin <jtc@wimsey.com> 02/16/95.
+ * Public domain.
+ */
+
+#ifndef _ISO646_H_
+#define _ISO646_H_
+
+#ifndef __cplusplus
+#define and     &&
+#define and_eq  &=
+#define bitand  &
+#define bitor   |
+#define compl   ~
+#define not     !
+#define not_eq  !=
+#define or      ||
+#define or_eq   |=
+#define xor     ^
+#define xor_eq  ^=
+#endif
+
+#endif  /* !_ISO646_H_ */
diff --git a/common/inc/limits.h b/common/inc/limits.h
new file mode 100644
index 0000000..fab59c9
--- /dev/null
+++ b/common/inc/limits.h
@@ -0,0 +1,41 @@
+/*	$OpenBSD: limits.h,v 1.15 2008/02/10 09:59:54 kettenis Exp $	*/
+/*	$NetBSD: limits.h,v 1.7 1994/10/26 00:56:00 cgd Exp $	*/
+
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)limits.h	5.9 (Berkeley) 4/3/91
+ */
+
+
+#ifndef _LIMITS_H_
+#define _LIMITS_H_
+
+#include <sys/limits.h>
+
+#endif /* !_LIMITS_H_ */
diff --git a/common/inc/math.h b/common/inc/math.h
new file mode 100644
index 0000000..104ac7f
--- /dev/null
+++ b/common/inc/math.h
@@ -0,0 +1,430 @@
+/*	$OpenBSD: math.h,v 1.27 2010/12/14 11:16:15 martynas Exp $	*/
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * from: @(#)fdlibm.h 5.1 93/09/24
+ */
+
+#ifndef _MATH_H_
+#define _MATH_H_
+
+#include <sys/_types.h>
+#include <sys/cdefs.h>
+#include <sys/limits.h>
+
+#include <float.h>
+
+typedef __float_t       float_t;
+typedef __double_t      double_t;
+
+#define FP_NAN         0x00
+#define FP_INFINITE    0x01
+#define FP_ZERO        0x02
+#define FP_SUBNORMAL   0x03
+#define FP_NORMAL      0x04
+
+#define FP_ILOGB0       (-INT_MAX - 1)
+#define FP_ILOGBNAN     (-INT_MAX - 1)
+
+#define fpclassify(x) \
+    ((sizeof (x) == sizeof (float)) ? \
+        __fpclassifyf(x) \
+    : (sizeof (x) == sizeof (double)) ? \
+        __fpclassify(x) \
+    :   __fpclassifyl(x))
+#define isfinite(x) \
+    ((sizeof (x) == sizeof (float)) ? \
+        __isfinitef(x) \
+    : (sizeof (x) == sizeof (double)) ? \
+        __isfinite(x) \
+    :   __isfinitel(x))
+#define isnormal(x) \
+    ((sizeof (x) == sizeof (float)) ? \
+        __isnormalf(x) \
+    : (sizeof (x) == sizeof (double)) ? \
+        __isnormal(x) \
+    :   __isnormall(x))
+#define signbit(x) \
+    ((sizeof (x) == sizeof (float)) ? \
+        __signbitf(x) \
+    : (sizeof (x) == sizeof (double)) ? \
+        __signbit(x) \
+    :   __signbitl(x))
+#define isinf(x) \
+    ((sizeof (x) == sizeof (float)) ? \
+        __isinff(x) \
+    : (sizeof (x) == sizeof (double)) ? \
+        __isinf(x) \
+    :   __isinfl(x))
+#define isnan(x) \
+    ((sizeof (x) == sizeof (float)) ? \
+        __isnanf(x) \
+    : (sizeof (x) == sizeof (double)) ? \
+        __isnan(x) \
+    :   __isnanl(x))
+
+#define isgreater(x, y)         (!isunordered((x), (y)) && (x) > (y))
+#define isgreaterequal(x, y)    (!isunordered((x), (y)) && (x) >= (y))
+#define isless(x, y)            (!isunordered((x), (y)) && (x) < (y))
+#define islessequal(x, y)       (!isunordered((x), (y)) && (x) <= (y))
+#define islessgreater(x, y)     (!isunordered((x), (y)) && ((x) > (y) || (y) > (x)))
+#define isunordered(x, y)       (isnan(x) || isnan(y))
+
+__BEGIN_DECLS
+
+extern char __infinity[];
+#define HUGE_VAL    (*(double *)(void *)__infinity)
+#define HUGE_VALF   ((float)HUGE_VAL)
+#define HUGE_VALL   ((long double)HUGE_VAL)
+#define INFINITY    HUGE_VALF
+extern char __nan[];
+#define NAN         (*(float *)(void *)__nan)
+
+/*
+ * ANSI/POSIX
+ */
+double _TLIBC_CDECL_ acos(double);
+double _TLIBC_CDECL_ asin(double);
+double _TLIBC_CDECL_ atan(double);
+double _TLIBC_CDECL_ atan2(double, double);
+double _TLIBC_CDECL_ cos(double);
+double _TLIBC_CDECL_ sin(double);
+double _TLIBC_CDECL_ tan(double);
+
+double _TLIBC_CDECL_ cosh(double);
+double _TLIBC_CDECL_ sinh(double);
+double _TLIBC_CDECL_ tanh(double);
+
+double _TLIBC_CDECL_ exp(double);
+double _TLIBC_CDECL_ frexp(double, int *);
+double _TLIBC_CDECL_ ldexp(double, int);
+double _TLIBC_CDECL_ log(double);
+double _TLIBC_CDECL_ log10(double);
+double _TLIBC_CDECL_ modf(double, double *);
+
+double _TLIBC_CDECL_ pow(double, double);
+double _TLIBC_CDECL_ sqrt(double);
+
+double _TLIBC_CDECL_ ceil(double);
+double _TLIBC_CDECL_ fabs(double);
+double _TLIBC_CDECL_ floor(double);
+double _TLIBC_CDECL_ fmod(double, double);
+
+/*
+ * C99
+ */
+double _TLIBC_CDECL_ acosh(double);
+double _TLIBC_CDECL_ asinh(double);
+double _TLIBC_CDECL_ atanh(double);
+
+double _TLIBC_CDECL_ exp2(double);  
+double _TLIBC_CDECL_ expm1(double);
+int    _TLIBC_CDECL_ ilogb(double);
+double _TLIBC_CDECL_ log1p(double);
+double _TLIBC_CDECL_ log2(double);
+double _TLIBC_CDECL_ logb(double);
+double _TLIBC_CDECL_ scalbn(double, int);
+double _TLIBC_CDECL_ scalbln(double, long int); 
+
+double _TLIBC_CDECL_ cbrt(double);
+double _TLIBC_CDECL_ hypot(double, double);
+
+double _TLIBC_CDECL_ erf(double);
+double _TLIBC_CDECL_ erfc(double);
+double _TLIBC_CDECL_ lgamma(double);
+double _TLIBC_CDECL_ tgamma(double);
+
+double _TLIBC_CDECL_ nearbyint(double);
+double _TLIBC_CDECL_ rint(double);
+long int _TLIBC_CDECL_ lrint(double); 
+long long int _TLIBC_CDECL_ llrint(double); 
+double _TLIBC_CDECL_ round(double);  
+long int _TLIBC_CDECL_ lround(double); 
+long long int _TLIBC_CDECL_ llround(double);
+double _TLIBC_CDECL_ trunc(double);
+
+double _TLIBC_CDECL_ remainder(double, double);
+double _TLIBC_CDECL_ remquo(double, double, int *); 
+
+double _TLIBC_CDECL_ copysign(double, double);
+double _TLIBC_CDECL_ nan(const char *);
+double _TLIBC_CDECL_ nextafter(double, double);
+
+double _TLIBC_CDECL_ fdim(double, double); 
+double _TLIBC_CDECL_ fmax(double, double); 
+double _TLIBC_CDECL_ fmin(double, double); 
+
+double _TLIBC_CDECL_ fma(double, double, double);
+
+/*
+ * Float versions of C99 functions
+ */
+
+float _TLIBC_CDECL_ acosf(float);
+float _TLIBC_CDECL_ asinf(float);
+float _TLIBC_CDECL_ atanf(float);
+float _TLIBC_CDECL_ atan2f(float, float);
+float _TLIBC_CDECL_ cosf(float);
+float _TLIBC_CDECL_ sinf(float);
+float _TLIBC_CDECL_ tanf(float);
+
+float _TLIBC_CDECL_ acoshf(float);
+float _TLIBC_CDECL_ asinhf(float);
+float _TLIBC_CDECL_ atanhf(float);
+float _TLIBC_CDECL_ coshf(float);
+float _TLIBC_CDECL_ sinhf(float);
+float _TLIBC_CDECL_ tanhf(float);
+
+float _TLIBC_CDECL_ expf(float);
+float _TLIBC_CDECL_ exp2f(float); 
+float _TLIBC_CDECL_ expm1f(float); 
+float _TLIBC_CDECL_ frexpf(float, int *);
+int   _TLIBC_CDECL_ ilogbf(float);
+float _TLIBC_CDECL_ ldexpf(float, int);
+float _TLIBC_CDECL_ logf(float);
+float _TLIBC_CDECL_ log10f(float);
+float _TLIBC_CDECL_ log1pf(float);
+float _TLIBC_CDECL_ log2f(float);
+float _TLIBC_CDECL_ logbf(float);
+float _TLIBC_CDECL_ modff(float, float *);
+float _TLIBC_CDECL_ scalbnf(float, int);
+float _TLIBC_CDECL_ scalblnf(float, long int);
+
+float _TLIBC_CDECL_ cbrtf(float);
+float _TLIBC_CDECL_ fabsf(float);
+float _TLIBC_CDECL_ hypotf(float, float);
+float _TLIBC_CDECL_ powf(float, float);
+float _TLIBC_CDECL_ sqrtf(float);
+
+float _TLIBC_CDECL_ erff(float);
+float _TLIBC_CDECL_ erfcf(float);
+float _TLIBC_CDECL_ lgammaf(float);
+float _TLIBC_CDECL_ tgammaf(float);
+
+float _TLIBC_CDECL_ ceilf(float);
+float _TLIBC_CDECL_ floorf(float);
+float _TLIBC_CDECL_ nearbyintf(float);
+
+float _TLIBC_CDECL_ rintf(float);
+long int _TLIBC_CDECL_ lrintf(float); 
+long long int _TLIBC_CDECL_ llrintf(float); 
+float _TLIBC_CDECL_ roundf(float); 
+long int _TLIBC_CDECL_ lroundf(float);
+long long int _TLIBC_CDECL_ llroundf(float);
+float _TLIBC_CDECL_ truncf(float);
+
+float _TLIBC_CDECL_ fmodf(float, float);
+float _TLIBC_CDECL_ remainderf(float, float);
+float _TLIBC_CDECL_ remquof(float, float, int *);
+
+float _TLIBC_CDECL_ copysignf(float, float);
+float _TLIBC_CDECL_ nanf(const char *);
+float _TLIBC_CDECL_ nextafterf(float, float);
+
+float _TLIBC_CDECL_ fdimf(float, float);
+float _TLIBC_CDECL_ fmaxf(float, float);
+float _TLIBC_CDECL_ fminf(float, float);
+
+float _TLIBC_CDECL_ fmaf(float, float, float);
+
+/*
+ * Long double versions of C99 functions
+ */
+
+/* Macros defining long double functions to be their double counterparts
+ * (long double is synonymous with double in this implementation).
+ */
+
+long double _TLIBC_CDECL_ acosl(long double);
+long double _TLIBC_CDECL_ asinl(long double);
+long double _TLIBC_CDECL_ atanl(long double);
+long double _TLIBC_CDECL_ atan2l(long double, long double);
+long double _TLIBC_CDECL_ cosl(long double);
+long double _TLIBC_CDECL_ sinl(long double);
+long double _TLIBC_CDECL_ tanl(long double);
+
+long double _TLIBC_CDECL_ acoshl(long double);
+long double _TLIBC_CDECL_ asinhl(long double);
+long double _TLIBC_CDECL_ atanhl(long double);
+long double _TLIBC_CDECL_ coshl(long double);
+long double _TLIBC_CDECL_ sinhl(long double);
+long double _TLIBC_CDECL_ tanhl(long double);
+
+long double _TLIBC_CDECL_ expl(long double);
+long double _TLIBC_CDECL_ exp2l(long double);
+long double _TLIBC_CDECL_ expm1l(long double);
+long double _TLIBC_CDECL_ frexpl(long double, int *);
+int         _TLIBC_CDECL_ ilogbl(long double);
+long double _TLIBC_CDECL_ ldexpl(long double, int);
+long double _TLIBC_CDECL_ logl(long double);
+long double _TLIBC_CDECL_ log10l(long double);
+long double _TLIBC_CDECL_ log1pl(long double);
+long double _TLIBC_CDECL_ log2l(long double);
+long double _TLIBC_CDECL_ logbl(long double);
+long double _TLIBC_CDECL_ modfl(long double, long double *);
+long double _TLIBC_CDECL_ scalbnl(long double, int);
+long double _TLIBC_CDECL_ scalblnl(long double, long int);
+
+long double _TLIBC_CDECL_ cbrtl(long double);
+long double _TLIBC_CDECL_ fabsl(long double);
+long double _TLIBC_CDECL_ hypotl(long double, long double);
+long double _TLIBC_CDECL_ powl(long double, long double);
+long double _TLIBC_CDECL_ sqrtl(long double);
+
+long double _TLIBC_CDECL_ erfl(long double);
+long double _TLIBC_CDECL_ erfcl(long double);
+long double _TLIBC_CDECL_ lgammal(long double);
+long double _TLIBC_CDECL_ tgammal(long double);
+
+long double _TLIBC_CDECL_ ceill(long double);
+long double _TLIBC_CDECL_ floorl(long double);
+long double _TLIBC_CDECL_ nearbyintl(long double);
+long double _TLIBC_CDECL_ rintl(long double);
+long int    _TLIBC_CDECL_ lrintl(long double);
+long long int _TLIBC_CDECL_ llrintl(long double);
+long double _TLIBC_CDECL_ roundl(long double);
+long int    _TLIBC_CDECL_ lroundl(long double);
+long long int _TLIBC_CDECL_ llroundl(long double);
+long double _TLIBC_CDECL_ truncl(long double);
+
+long double _TLIBC_CDECL_ fmodl(long double, long double);
+long double _TLIBC_CDECL_ remainderl(long double, long double);
+long double _TLIBC_CDECL_ remquol(long double, long double, int *);
+
+long double _TLIBC_CDECL_ copysignl(long double, long double);
+long double _TLIBC_CDECL_ nanl(const char *);
+long double _TLIBC_CDECL_ nextafterl(long double, long double);
+
+long double _TLIBC_CDECL_ fdiml(long double, long double);
+long double _TLIBC_CDECL_ fmaxl(long double, long double);
+long double _TLIBC_CDECL_ fminl(long double, long double);
+long double _TLIBC_CDECL_ fmal(long double, long double, long double);
+
+/* nexttoward():
+*      The implementation in Intel math library is incompatible with MSVC.
+*      Because sizeof(long double) is 8bytes with MSVC, 
+*      but the expected long double size is 10bytes. 
+*      And by default, MSVC doesn't provide nexttoward(). 
+*      So we only provide Linux version here.
+*/
+double _TLIBC_CDECL_ nexttoward(double, long double);
+float  _TLIBC_CDECL_ nexttowardf(float, long double);
+
+long double _TLIBC_CDECL_ nexttowardl(long double, long double);
+
+/*
+ * Library implementation
+ */
+int _TLIBC_CDECL_ __fpclassify(double);
+int _TLIBC_CDECL_ __fpclassifyf(float);
+int _TLIBC_CDECL_ __isfinite(double);
+int _TLIBC_CDECL_ __isfinitef(float);
+int _TLIBC_CDECL_ __isinf(double);
+int _TLIBC_CDECL_ __isinff(float);
+int _TLIBC_CDECL_ __isnan(double);
+int _TLIBC_CDECL_ __isnanf(float);
+int _TLIBC_CDECL_ __isnormal(double);
+int _TLIBC_CDECL_ __isnormalf(float);
+int _TLIBC_CDECL_ __signbit(double);
+int _TLIBC_CDECL_ __signbitf(float);
+
+int _TLIBC_CDECL_ __fpclassifyl(long double);
+int _TLIBC_CDECL_ __isfinitel(long double);
+int _TLIBC_CDECL_ __isinfl(long double);
+int _TLIBC_CDECL_ __isnanl(long double);
+int _TLIBC_CDECL_ __isnormall(long double);
+int _TLIBC_CDECL_ __signbitl(long double);
+
+/* 
+ * Non-C99 functions.
+ */
+double _TLIBC_CDECL_ drem(double, double);
+double _TLIBC_CDECL_ exp10(double);
+double _TLIBC_CDECL_ gamma(double);
+double _TLIBC_CDECL_ gamma_r(double, int *);
+double _TLIBC_CDECL_ j0(double);
+double _TLIBC_CDECL_ j1(double);
+double _TLIBC_CDECL_ jn(int, double);
+double _TLIBC_CDECL_ lgamma_r(double, int *);
+double _TLIBC_CDECL_ pow10(double);
+double _TLIBC_CDECL_ scalb(double, double);
+/* C99 Macro signbit.*/
+double _TLIBC_CDECL_ significand(double);
+void   _TLIBC_CDECL_ sincos(double, double *, double *);
+double _TLIBC_CDECL_ y0(double);
+double _TLIBC_CDECL_ y1(double);
+double _TLIBC_CDECL_ yn(int, double);
+/* C99 Macro isinf.*/
+/* C99 Macro isnan.*/
+int    _TLIBC_CDECL_ finite(double);
+
+float _TLIBC_CDECL_ dremf(float, float);
+float _TLIBC_CDECL_ exp10f(float);
+float _TLIBC_CDECL_ gammaf(float);
+float _TLIBC_CDECL_ gammaf_r(float, int *);
+float _TLIBC_CDECL_ j0f(float);
+float _TLIBC_CDECL_ j1f(float);
+float _TLIBC_CDECL_ jnf(int, float);
+float _TLIBC_CDECL_ lgammaf_r(float, int *);
+float _TLIBC_CDECL_ pow10f(float);
+float _TLIBC_CDECL_ scalbf(float, float);
+int   _TLIBC_CDECL_ signbitf(float);
+float _TLIBC_CDECL_ significandf(float);
+void  _TLIBC_CDECL_ sincosf(float, float *, float *);
+float _TLIBC_CDECL_ y0f(float);
+float _TLIBC_CDECL_ y1f(float);
+float _TLIBC_CDECL_ ynf(int, float);
+int   _TLIBC_CDECL_ finitef(float);
+int   _TLIBC_CDECL_ isinff(float);
+int   _TLIBC_CDECL_ isnanf(float);
+
+long double _TLIBC_CDECL_ dreml(long double, long double);
+long double _TLIBC_CDECL_ exp10l(long double);
+long double _TLIBC_CDECL_ gammal(long double);
+long double _TLIBC_CDECL_ gammal_r(long double, int *);
+long double _TLIBC_CDECL_ j0l(long double);
+long double _TLIBC_CDECL_ j1l(long double);
+long double _TLIBC_CDECL_ jnl(int, long double);
+long double _TLIBC_CDECL_ lgammal_r(long double, int *);
+long double _TLIBC_CDECL_ pow10l(long double);
+long double _TLIBC_CDECL_ scalbl(long double, long double);
+int         _TLIBC_CDECL_ signbitl(long double);
+long double _TLIBC_CDECL_ significandl(long double);
+void        _TLIBC_CDECL_ sincosl(long double, long double *, long double *);
+long double _TLIBC_CDECL_ y1l(long double);
+long double _TLIBC_CDECL_ y0l(long double);
+long double _TLIBC_CDECL_ ynl(int, long double);
+int         _TLIBC_CDECL_ finitel(long double);
+int         _TLIBC_CDECL_ isinfl(long double);
+int         _TLIBC_CDECL_ isnanl(long double);
+
+/* 
+ * TODO: From Intel Decimal Floating-Point Math Library
+ * signbitd32/signbitd64/signbitd128, finited32/finited64/finited128
+ * isinfd32/isinfd64/isinfd128, isnand32/isnand64/isnand128
+ */
+#if defined(__cplusplus) 
+/* Clang does not support decimal floating point types.
+ *
+ * c.f.:
+ * http://clang.llvm.org/docs/UsersManual.html#gcc-extensions-not-implemented-yet
+ */
+#if !defined(__clang__)
+typedef float _Decimal32 __attribute__((mode(SD)));
+typedef float _Decimal64 __attribute__((mode(DD)));
+typedef float _Decimal128 __attribute__((mode(TD)));
+#endif
+#endif
+
+__END_DECLS
+
+#endif /* !_MATH_H_ */
diff --git a/common/inc/setjmp.h b/common/inc/setjmp.h
new file mode 100644
index 0000000..ac5627f
--- /dev/null
+++ b/common/inc/setjmp.h
@@ -0,0 +1,64 @@
+/*	$NetBSD: setjmp.h,v 1.26 2011/11/05 09:27:06 joerg Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)setjmp.h	8.2 (Berkeley) 1/21/94
+ */
+
+#ifndef _SETJMP_H_
+#define _SETJMP_H_
+
+#ifndef _JB_ATTRIBUTES
+#define _JB_ATTRIBUTES	/**/
+#else
+#endif
+#ifndef _BSD_JBSLOT_T_
+#define	_BSD_JBSLOT_T_	long
+#endif
+
+#define _JBLEN 8 
+
+typedef _BSD_JBSLOT_T_ jmp_buf[_JBLEN] _JB_ATTRIBUTES;
+
+#include <sys/cdefs.h>
+#define __returns_twice __attribute__((__returns_twice__))
+#define __dead 
+
+__BEGIN_DECLS
+int	_setjmp(jmp_buf) __returns_twice;
+void	_longjmp(jmp_buf, int) __dead;
+__END_DECLS
+
+#endif /* !_SETJMP_H_ */
+
diff --git a/common/inc/stdarg.h b/common/inc/stdarg.h
new file mode 100644
index 0000000..ed73e24
--- /dev/null
+++ b/common/inc/stdarg.h
@@ -0,0 +1,48 @@
+/*	$OpenBSD: stdarg.h,v 1.14 2010/12/30 05:01:36 tedu Exp $	*/
+/*	$NetBSD: stdarg.h,v 1.12 1995/12/25 23:15:31 mycroft Exp $	*/
+
+/*-
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)stdarg.h	8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _STDARG_H_
+#define _STDARG_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+typedef __va_list   va_list;
+
+#define va_start(ap, last)  __builtin_va_start((ap), last)
+#define va_end              __builtin_va_end
+#define va_arg              __builtin_va_arg
+#define va_copy(dst, src)   __builtin_va_copy((dst),(src))
+
+#endif /* !_STDARG_H_ */
diff --git a/common/inc/stdbool.h b/common/inc/stdbool.h
new file mode 100644
index 0000000..bd1837e
--- /dev/null
+++ b/common/inc/stdbool.h
@@ -0,0 +1,44 @@
+/* $OpenBSD: stdbool.h,v 1.5 2010/07/24 22:17:03 guenther Exp $ */
+
+/*
+ * Written by Marc Espie, September 25, 1999
+ * Public domain.
+ */
+
+#ifndef _STDBOOL_H_
+#define _STDBOOL_H_
+
+#ifndef __cplusplus
+
+#ifndef __GNUC__
+/* Support for _C99: type _Bool is already built-in. */
+/* `_Bool' type must promote to `int' or `unsigned int'. */
+typedef enum {
+    false = 0,
+    true = 1
+} _Bool;
+
+/* And those constants must also be available as macros. */
+# define false   false
+# define true    true
+#else  /* __GNUC__ */
+# define false   0
+# define true    1
+#endif
+
+/* User visible type `bool' is provided as a macro which may be redefined */
+#define bool _Bool
+
+#else /* __cplusplus */
+
+# define _Bool   bool
+# define bool    bool
+# define false   false
+# define true    true
+
+#endif
+
+/* Inform that everything is fine */
+#define __bool_true_false_are_defined 1
+
+#endif /* _STDBOOL_H_ */
diff --git a/common/inc/stddef.h b/common/inc/stddef.h
new file mode 100644
index 0000000..84509c5
--- /dev/null
+++ b/common/inc/stddef.h
@@ -0,0 +1,70 @@
+/*	$OpenBSD: stddef.h,v 1.10 2009/09/22 21:40:02 jsg Exp $	*/
+/*	$NetBSD: stddef.h,v 1.4 1994/10/26 00:56:26 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)stddef.h	5.5 (Berkeley) 4/3/91
+ */
+
+#ifndef _STDDEF_H_
+#define _STDDEF_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _PTRDIFF_T_DEFINED_
+#define _PTRDIFF_T_DEFINED_
+typedef __ptrdiff_t ptrdiff_t;
+#endif
+
+#ifndef _SIZE_T_DEFINED_
+#define _SIZE_T_DEFINED_
+typedef __size_t    size_t;
+#endif
+
+#if !defined(_WCHAR_T_DEFINED_) && !defined(__cplusplus)
+#define _WCHAR_T_DEFINED_
+#ifndef __WCHAR_TYPE__
+#define __WCHAR_TYPE__ int
+#endif
+typedef __WCHAR_TYPE__ wchar_t;
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL        0
+#else
+#define NULL        ((void *)0)
+#endif
+#endif
+
+#define offsetof(type, member)  ((size_t)(&((type *)0)->member))
+
+#endif /* _STDDEF_H_ */
+
diff --git a/common/inc/stdint.h b/common/inc/stdint.h
new file mode 100644
index 0000000..d283ae9
--- /dev/null
+++ b/common/inc/stdint.h
@@ -0,0 +1,24 @@
+/*	$OpenBSD: stdint.h,v 1.4 2006/12/10 22:17:55 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 1997, 2005 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_STDINT_H_
+#define _STDINT_H_
+
+#include <sys/stdint.h>
+
+#endif /* _STDINT_H_ */
diff --git a/common/inc/stdio.h b/common/inc/stdio.h
new file mode 100644
index 0000000..0175a3a
--- /dev/null
+++ b/common/inc/stdio.h
@@ -0,0 +1,95 @@
+/*	$OpenBSD: stdio.h,v 1.38 2009/11/09 00:18:27 kurt Exp $	*/
+/*	$NetBSD: stdio.h,v 1.18 1996/04/25 18:29:21 jtc Exp $	*/
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)stdio.h	5.17 (Berkeley) 6/3/91
+ */
+
+#ifndef _STDIO_H_
+#define _STDIO_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#include <stdarg.h>
+
+#ifndef _SIZE_T_DEFINED_
+typedef __size_t    size_t;
+#define _SIZE_T_DEFINED_
+#endif
+
+#ifndef NULL
+# ifdef __cplusplus
+#  define NULL      0
+# else
+#  define NULL      ((void *)0)
+# endif
+#endif
+
+# define BUFSIZ  8192
+
+#define EOF     (-1)
+
+__BEGIN_DECLS
+
+int _TLIBC_CDECL_ snprintf(char *, size_t, const char *, ...) _GCC_PRINTF_FORMAT_(3, 4);
+int _TLIBC_CDECL_ vsnprintf(char *, size_t, const char *, __va_list) _GCC_PRINTF_FORMAT_(3, 0);
+
+/*
+ * Deprecated definitions.
+ */
+#if 0 /* No FILE */
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, fprintf, FILE *, const char *, ...);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, putc, int, FILE *);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, fputc, int, FILE *);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, fputs, const char *, FILE *);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, fscanf, FILE *, const char *, ...);
+_TLIBC_DEPRECATED_FUNCTION_(size_t _TLIBC_CDECL_, fwrite, const void *, size_t, size_t, FILE *);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, printf, const char *, ...);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, putchar, int);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, puts, const char *);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, scanf, const char *, ...);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, sprintf, char *, const char *, ...);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, sscanf, const char *, const char *, ...);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, vfprintf, FILE *, const char *, __va_list);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, vfscanf, FILE *, const char *, __va_list);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, vprintf, const char *, __va_list);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, vscanf, const char *, __va_list);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, vsprintf, char *, const char *, __va_list);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, vsscanf, const char *, const char *, __va_list);
+#endif
+
+__END_DECLS
+
+
+#endif /* !_STDIO_H_ */
diff --git a/common/inc/stdlib.h b/common/inc/stdlib.h
new file mode 100644
index 0000000..8a851db
--- /dev/null
+++ b/common/inc/stdlib.h
@@ -0,0 +1,159 @@
+/*	$OpenBSD: stdlib.h,v 1.47 2010/05/18 22:24:55 tedu Exp $	*/
+/*	$NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $	*/
+
+/*-
+* Copyright (c) 1990 The Regents of the University of California.
+* 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.
+* 3. Neither the name of the University nor the names of its contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+*
+*	@(#)stdlib.h	5.13 (Berkeley) 6/4/91
+*/
+
+#ifndef _STDLIB_H_
+#define _STDLIB_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _SIZE_T_DEFINED_
+#define _SIZE_T_DEFINED_
+typedef __size_t    size_t;
+#endif
+
+#ifdef _TLIBC_WIN_
+#if !defined(_WCHAR_T_DEFINED) && !defined (_NATIVE_WCHAR_T_DEFINED)
+#define _WCHAR_T_DEFINED
+typedef unsigned short  wchar_t;
+#endif
+#else
+#if !defined(_WCHAR_T_DEFINED_) && !defined(__cplusplus)
+#define _WCHAR_T_DEFINED_
+#ifndef __WCHAR_TYPE__
+#define __WCHAR_TYPE__ int
+#endif
+typedef __WCHAR_TYPE__ wchar_t;
+#endif
+#endif
+
+#ifndef _DIV_T_DEFINED
+typedef struct {
+    int quot;       /* quotient */
+    int rem;        /* remainder */
+} div_t;
+
+typedef struct {
+    long quot;      /* quotient */
+    long rem;       /* remainder */
+} ldiv_t;
+
+typedef struct {
+    long long quot; /* quotient */
+    long long rem;  /* remainder */
+} lldiv_t;
+#define _DIV_T_DEFINED
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL    0
+#else
+#define NULL    ((void *)0)
+#endif
+#endif
+
+#define EXIT_FAILURE    1
+#define EXIT_SUCCESS    0
+
+#define RAND_MAX        0x7fffffff
+#define MB_CUR_MAX      1
+
+__BEGIN_DECLS
+
+_TLIBC_NORETURN_ void _TLIBC_CDECL_ abort(void);
+int     _TLIBC_CDECL_ abs(int);
+double  _TLIBC_CDECL_ atof(const char *);
+int     _TLIBC_CDECL_ atoi(const char *);
+long    _TLIBC_CDECL_ atol(const char *);
+void *  _TLIBC_CDECL_ bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *));
+void *  _TLIBC_CDECL_ calloc(size_t, size_t);
+div_t   _TLIBC_CDECL_ div(int, int);
+void    _TLIBC_CDECL_ free(void *);
+long    _TLIBC_CDECL_ labs(long);
+ldiv_t  _TLIBC_CDECL_ ldiv(long, long);
+void *  _TLIBC_CDECL_ malloc(size_t);
+void *  _TLIBC_CDECL_ memalign(size_t, size_t);
+void    _TLIBC_CDECL_ qsort(void *, size_t, size_t, int (*)(const void *, const void *));
+void *  _TLIBC_CDECL_ realloc(void *, size_t);
+double  _TLIBC_CDECL_ strtod(const char *, char **);
+long    _TLIBC_CDECL_ strtol(const char *, char **, int);
+float   _TLIBC_CDECL_ strtof(const char *, char **);
+
+long long
+        _TLIBC_CDECL_ atoll(const char *);
+long long
+        _TLIBC_CDECL_ llabs(long long);
+lldiv_t
+        _TLIBC_CDECL_ lldiv(long long, long long);
+long long
+        _TLIBC_CDECL_ strtoll(const char *, char **, int);
+unsigned long
+        _TLIBC_CDECL_ strtoul(const char *, char **, int);
+long double
+        _TLIBC_CDECL_ strtold(const char *, char **);
+unsigned long long
+        _TLIBC_CDECL_ strtoull(const char *, char **, int);
+
+int     _TLIBC_CDECL_ mblen(const char *, size_t);
+size_t  _TLIBC_CDECL_ mbstowcs(wchar_t *, const char *, size_t);
+int     _TLIBC_CDECL_ wctomb(char *, wchar_t);
+int     _TLIBC_CDECL_ mbtowc(wchar_t *, const char *, size_t);
+size_t  _TLIBC_CDECL_ wcstombs(char *, const wchar_t *, size_t);
+
+
+/*
+ * Deprecated C99.
+ */
+_TLIBC_DEPRECATED_FUNCTION_(int     _TLIBC_CDECL_, atexit, void (_TLIBC_CDECL_ *)(void));
+_TLIBC_DEPRECATED_FUNCTION_(int     _TLIBC_CDECL_, rand, void);
+_TLIBC_DEPRECATED_FUNCTION_(void    _TLIBC_CDECL_, srand, unsigned);
+_TLIBC_DEPRECATED_FUNCTION_(void    _TLIBC_CDECL_, exit, int);
+_TLIBC_DEPRECATED_FUNCTION_(void    _TLIBC_CDECL_, _Exit, int);
+_TLIBC_DEPRECATED_FUNCTION_(char *  _TLIBC_CDECL_, getenv, const char *);
+_TLIBC_DEPRECATED_FUNCTION_(int     _TLIBC_CDECL_, system, const char *);
+
+/*
+ * Non-C99 Functions.
+ */
+void *  _TLIBC_CDECL_ alloca(size_t);
+
+/*
+ * Deprecated Non-C99.
+ */
+//_TLIBC_DEPRECATED_FUNCTION_(void _TLIBC_CDECL_, _exit, int);
+
+__END_DECLS
+
+#endif /* !_STDLIB_H_ */
diff --git a/common/inc/string.h b/common/inc/string.h
new file mode 100644
index 0000000..c8e458f
--- /dev/null
+++ b/common/inc/string.h
@@ -0,0 +1,125 @@
+/*	$OpenBSD: string.h,v 1.20 2010/09/24 13:33:00 matthew Exp $	*/
+/*	$NetBSD: string.h,v 1.6 1994/10/26 00:56:30 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)string.h	5.10 (Berkeley) 3/9/91
+ */
+
+#ifndef _STRING_H_
+#define _STRING_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _SIZE_T_DEFINED_
+typedef __size_t    size_t;
+#define _SIZE_T_DEFINED_
+#endif
+
+#ifndef _ERRNO_T_DEFINED
+#define _ERRNO_T_DEFINED
+typedef int errno_t;
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL    0
+#else
+#define NULL    ((void *)0)
+#endif
+#endif
+
+__BEGIN_DECLS
+
+void * _TLIBC_CDECL_ memchr(const void *, int, size_t);
+int    _TLIBC_CDECL_ memcmp(const void *, const void *, size_t);
+void * _TLIBC_CDECL_ memcpy(void *, const void *, size_t);
+void * _TLIBC_CDECL_ memmove(void *, const void *, size_t);
+void * _TLIBC_CDECL_ memset(void *, int, size_t);
+char * _TLIBC_CDECL_ strchr(const char *, int);
+int    _TLIBC_CDECL_ strcmp(const char *, const char *);
+int    _TLIBC_CDECL_ strcoll(const char *, const char *);
+size_t _TLIBC_CDECL_ strcspn(const char *, const char *);
+char * _TLIBC_CDECL_ strerror(int);
+size_t _TLIBC_CDECL_ strlen(const char *);
+char * _TLIBC_CDECL_ strncat(char *, const char *, size_t);
+int    _TLIBC_CDECL_ strncmp(const char *, const char *, size_t);
+char * _TLIBC_CDECL_ strncpy(char *, const char *, size_t);
+char * _TLIBC_CDECL_ strpbrk(const char *, const char *);
+char * _TLIBC_CDECL_ strrchr(const char *, int);
+size_t _TLIBC_CDECL_ strspn(const char *, const char *);
+char * _TLIBC_CDECL_ strstr(const char *, const char *);
+char * _TLIBC_CDECL_ strtok(char *, const char *);
+size_t _TLIBC_CDECL_ strxfrm(char *, const char *, size_t);
+size_t _TLIBC_CDECL_ strlcpy(char *, const char *, size_t);
+errno_t _TLIBC_CDECL_ memset_s(void *s, size_t smax, int c, size_t n);
+
+/*
+ * Deprecated C99.
+ */
+_TLIBC_DEPRECATED_FUNCTION_(char * _TLIBC_CDECL_, strcat, char *, const char *);
+_TLIBC_DEPRECATED_FUNCTION_(char * _TLIBC_CDECL_, strcpy, char *, const char *);
+
+/* 
+ * Common used non-C99 functions.
+ */
+char * _TLIBC_CDECL_ strndup(const char *, size_t);
+size_t _TLIBC_CDECL_ strnlen(const char *, size_t);
+int    _TLIBC_CDECL_ consttime_memequal(const void *b1, const void *b2, size_t len);
+
+/*
+ * Non-C99
+ */
+int    _TLIBC_CDECL_ bcmp(const void *, const void *, size_t);
+void   _TLIBC_CDECL_ bcopy(const void *, void *, size_t);
+void   _TLIBC_CDECL_ bzero(void *, size_t);
+char * _TLIBC_CDECL_ index(const char *, int);
+void * _TLIBC_CDECL_ mempcpy(void *, const void *, size_t);
+char * _TLIBC_CDECL_ rindex(const char *, int);
+char * _TLIBC_CDECL_ stpncpy(char *dest, const char *src, size_t n);
+int    _TLIBC_CDECL_ strcasecmp(const char *, const char *);
+int    _TLIBC_CDECL_ strncasecmp(const char *, const char *, size_t);
+
+int    _TLIBC_CDECL_ ffs(int);
+int    _TLIBC_CDECL_ ffsl(long int);
+int    _TLIBC_CDECL_ ffsll(long long int);
+
+char * _TLIBC_CDECL_ strtok_r(char *, const char *, char **);
+int    _TLIBC_CDECL_ strerror_r(int, char *, size_t);
+
+/*
+ * Deprecated Non-C99.
+ */
+_TLIBC_DEPRECATED_FUNCTION_(char * _TLIBC_CDECL_, strdup, const char *);
+_TLIBC_DEPRECATED_FUNCTION_(char * _TLIBC_CDECL_, stpcpy, char *dest, const char *src);
+
+__END_DECLS
+
+#endif /* _STRING_H_ */
diff --git a/common/inc/sys/_types.h b/common/inc/sys/_types.h
new file mode 100644
index 0000000..b1b315c
--- /dev/null
+++ b/common/inc/sys/_types.h
@@ -0,0 +1,133 @@
+/*	$OpenBSD: _types.h,v 1.2 2008/03/16 19:42:57 otto Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)types.h	8.3 (Berkeley) 1/5/94
+ */
+
+#ifndef _SYS__TYPES_H_
+#define _SYS__TYPES_H_
+
+#include <sys/cdefs.h>
+/* 7.18.1.1 Exact-width integer types */
+typedef signed char         __int8_t;
+typedef unsigned char       __uint8_t;
+typedef short               __int16_t;
+typedef unsigned short      __uint16_t;
+typedef int                 __int32_t;
+typedef unsigned int        __uint32_t;
+typedef long long           __int64_t;
+typedef unsigned long long  __uint64_t;
+
+/* 7.18.1.2 Minimum-width integer types */
+typedef __int8_t            __int_least8_t;
+typedef __uint8_t           __uint_least8_t;
+typedef __int16_t           __int_least16_t;
+typedef __uint16_t          __uint_least16_t;
+typedef __int32_t           __int_least32_t;
+typedef __uint32_t          __uint_least32_t;
+typedef __int64_t           __int_least64_t;
+typedef __uint64_t          __uint_least64_t;
+
+/* 7.18.1.3 Fastest minimum-width integer types */
+typedef __int8_t            __int_fast8_t;
+typedef __uint8_t           __uint_fast8_t;
+#ifdef __x86_64__
+/* Linux x86_64, from stdint.h */
+typedef long int            __int_fast16_t;
+typedef unsigned long int   __uint_fast16_t;
+typedef long int            __int_fast32_t;
+typedef unsigned long int   __uint_fast32_t;
+typedef long int            __int_fast64_t;
+typedef unsigned long int   __uint_fast64_t;
+#else 
+/* Android x86, and Linux x86 */
+typedef __int32_t           __int_fast16_t;
+typedef __uint32_t          __uint_fast16_t;
+typedef __int32_t           __int_fast32_t;
+typedef __uint32_t          __uint_fast32_t;
+typedef __int64_t           __int_fast64_t;
+typedef __uint64_t          __uint_fast64_t;
+#endif
+
+typedef long                __off_t;
+
+/* 7.18.1.4 Integer types capable of holding object pointers */
+#ifdef __i386__
+typedef __int32_t           __intptr_t;
+typedef __uint32_t          __uintptr_t;
+typedef __int32_t           __ptrdiff_t;
+/* Standard system types */
+typedef __uint32_t          __size_t;
+typedef __int32_t           __ssize_t;
+typedef long double         __double_t;
+typedef long double         __float_t;
+#else
+typedef __int64_t           __intptr_t;
+typedef __uint64_t          __uintptr_t;
+typedef __int64_t           __ptrdiff_t;
+
+/* Standard system types */
+typedef unsigned long       __size_t;
+typedef long                __ssize_t;
+typedef double              __double_t;
+typedef float               __float_t;
+
+#endif /* !__i386__ */
+
+typedef long                __clock_t;
+
+typedef long                __time_t;
+typedef __builtin_va_list   __va_list;
+typedef int                 __wint_t;
+/* wctype_t and wctrans_t are defined in wchar.h */
+typedef unsigned long int   __wctype_t;
+typedef int *               __wctrans_t;
+
+/*
+ * mbstate_t is an opaque object to keep conversion state, during multibyte
+ * stream conversions. The content must not be referenced by user programs.
+ */
+/* For Linux, __mbstate_t is defined in wchar.h */
+typedef struct {
+    int __c;
+    union {
+        __wint_t __wc;
+        char __wcb[4];
+    } __v;
+} __mbstate_t;
+
+/* 7.18.1.5 Greatest-width integer types */
+typedef __int64_t           __intmax_t;
+typedef __uint64_t          __uintmax_t;
+
+#endif /* !_SYS__TYPES_H_ */
+
+
+
diff --git a/common/inc/sys/cdefs.h b/common/inc/sys/cdefs.h
new file mode 100644
index 0000000..398a12b
--- /dev/null
+++ b/common/inc/sys/cdefs.h
@@ -0,0 +1,132 @@
+/*	$OpenBSD: cdefs.h,v 1.34 2012/08/14 20:11:37 matthew Exp $	*/
+/*	$NetBSD: cdefs.h,v 1.16 1996/04/03 20:46:39 christos Exp $	*/
+
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Berkeley Software Design, Inc.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)cdefs.h	8.7 (Berkeley) 1/21/94
+ */
+
+#ifndef _SYS_CDEFS_H_
+#define _SYS_CDEFS_H_
+
+/* Declaration field in C/C++ headers */
+#if defined(__cplusplus)
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+#else
+# define __BEGIN_DECLS
+# define __END_DECLS
+#endif
+
+#if defined(__STDC__) || defined(__cplusplus) 
+# define __CONCAT(x,y)  x ## y
+# define __STRING(x)    #x
+#else
+# define __CONCAT(x,y)  x/**/y
+# define __STRING(x)    "x"
+#endif
+/*
+ * Macro to test if we're using a specific version of gcc or later.
+ */
+#if defined __GNUC__ && defined __GNUC_MINOR_
+# define __GNUC_PREREQ__(ma, mi) \
+    ((__GNUC__ > (ma)) || (__GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)))
+#else
+# define __GNUC_PREREQ__(ma, mi) 0
+#endif
+
+/* Calling Convention: cdecl */
+#define _TLIBC_CDECL_      
+
+/* Thread Directive */
+#define _TLIBC_THREAD_     /* __thread */
+
+/* Deprecated Warnings */
+#define _TLIBC_DEPRECATED_MSG(x)    __STRING(x)" is deprecated in tlibc."
+#define _TLIBC_DEPRECATED_(x)       __attribute__((deprecated(_TLIBC_DEPRECATED_MSG(x))))
+
+#ifndef _TLIBC_WARN_DEPRECATED_FUNCTIONS_
+# define _TLIBC_DEPRECATED_FUNCTION_(__ret, __func, ...)
+#else
+# define _TLIBC_DEPRECATED_FUNCTION_(__ret, __func, ...)    \
+    _TLIBC_DEPRECATED_(__func)  \
+    __ret __func(__VA_ARGS__)
+#endif
+
+/* Static analysis for printf format strings.
+ * _MSC_PRINTF_FORMAT_: MSVC SAL annotation for specifying format strings. 
+ * _GCC_PRINTF_FORMAT_(x, y): GCC declaring attribute for checking format strings.
+ *   x - index of the format string. In C++ non-static method, index 1 is reseved for 'this'.
+ *   y - index of first variadic agrument in '...'.
+ */
+#define _GCC_PRINTF_FORMAT_(x, y)  __attribute__((__format__ (printf, x, y)))
+
+/* Attribute - noreturn */
+#define _TLIBC_NORETURN_   __attribute__ ((__noreturn__))
+
+/*
+ * GNU C version 2.96 adds explicit branch prediction so that
+ * the CPU back-end can hint the processor and also so that
+ * code blocks can be reordered such that the predicted path
+ * sees a more linear flow, thus improving cache behavior, etc.
+ *
+ * The following two macros provide us with a way to utilize this
+ * compiler feature.  Use __predict_true() if you expect the expression
+ * to evaluate to true, and __predict_false() if you expect the
+ * expression to evaluate to false.
+ *
+ * A few notes about usage:
+ *
+ *	* Generally, __predict_false() error condition checks (unless
+ *	  you have some _strong_ reason to do otherwise, in which case
+ *	  document it), and/or __predict_true() `no-error' condition
+ *	  checks, assuming you want to optimize for the no-error case.
+ *
+ *	* Other than that, if you don't know the likelihood of a test
+ *	  succeeding from empirical or other `hard' evidence, don't
+ *	  make predictions.
+ *
+ *	* These are meant to be used in places that are run `a lot'.
+ *	  It is wasteful to make predictions in code that is run
+ *	  seldomly (e.g. at subsystem initialization time) as the
+ *	  basic block reordering that this affects can often generate
+ *	  larger code.
+ */
+#if defined(__GNUC__) && __GNUC_PREREQ__(2, 96)
+#define __predict_true(exp)	__builtin_expect(((exp) != 0), 1)
+#define __predict_false(exp)	__builtin_expect(((exp) != 0), 0)
+#else
+#define __predict_true(exp)	((exp) != 0)
+#define __predict_false(exp)	((exp) != 0)
+#endif
+
+#endif /* !_SYS_CDEFS_H_ */
diff --git a/common/inc/sys/endian.h b/common/inc/sys/endian.h
new file mode 100644
index 0000000..29edd81
--- /dev/null
+++ b/common/inc/sys/endian.h
@@ -0,0 +1,54 @@
+/*	$OpenBSD: endian.h,v 1.18 2006/03/27 07:09:24 otto Exp $	*/
+
+/*-
+ * Copyright (c) 1997 Niklas Hallqvist.  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 AUTHOR ``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 AUTHOR 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.
+ */
+
+/*
+ * Generic definitions for little- and big-endian systems.  Other endianesses
+ * has to be dealt with in the specific machine/endian.h file for that port.
+ *
+ * This file is meant to be included from a little- or big-endian port's
+ * machine/endian.h after setting _BYTE_ORDER to either 1234 for little endian
+ * or 4321 for big..
+ */
+
+#ifndef _SYS_ENDIAN_H_
+#define _SYS_ENDIAN_H_
+
+#define _LITTLE_ENDIAN  1234
+#define _BIG_ENDIAN     4321
+#define _PDP_ENDIAN     3412
+#define _BYTE_ORDER     _LITTLE_ENDIAN
+
+#define LITTLE_ENDIAN   _LITTLE_ENDIAN
+#define BIG_ENDIAN      _BIG_ENDIAN
+#define PDP_ENDIAN      _PDP_ENDIAN
+#define BYTE_ORDER      _BYTE_ORDER
+
+#define __BYTE_ORDER    _BYTE_ORDER
+#define __BIG_ENDIAN    _BIG_ENDIAN
+#define __LITTLE_ENDIAN _LITTLE_ENDIAN
+
+#endif /* _SYS_ENDIAN_H_ */
+
diff --git a/common/inc/sys/ieee.h b/common/inc/sys/ieee.h
new file mode 100644
index 0000000..8370cd8
--- /dev/null
+++ b/common/inc/sys/ieee.h
@@ -0,0 +1,145 @@
+/*	$OpenBSD: ieee.h,v 1.2 2008/09/07 20:36:06 martynas Exp $ */
+/*	$NetBSD: ieee.h,v 1.1 1996/09/30 16:34:25 ws Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Lawrence Berkeley Laboratory.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)ieee.h	8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * ieee.h defines the machine-dependent layout of the machine's IEEE
+ * floating point.  It does *not* define (yet?) any of the rounding
+ * mode bits, exceptions, and so forth.
+ */
+
+/*
+ * Define the number of bits in each fraction and exponent.
+ *
+ *		     k	         k+1
+ * Note that  1.0 x 2  == 0.1 x 2      and that denorms are represented
+ *
+ *					  (-exp_bias+1)
+ * as fractions that look like 0.fffff x 2             .  This means that
+ *
+ *			 -126
+ * the number 0.10000 x 2    , for instance, is the same as the normalized
+ *
+ *		-127			   -128
+ * float 1.0 x 2    .  Thus, to represent 2    , we need one leading zero
+ *
+ *				  -129
+ * in the fraction; to represent 2    , we need two, and so on.  This
+ *
+ *						     (-exp_bias-fracbits+1)
+ * implies that the smallest denormalized number is 2
+ *
+ * for whichever format we are talking about: for single precision, for
+ *
+ *						-126		-149
+ * instance, we get .00000000000000000000001 x 2    , or 1.0 x 2    , and
+ *
+ * -149 == -127 - 23 + 1.
+ */
+
+#include <sys/types.h>
+
+#define SNG_EXPBITS     8
+#define SNG_FRACBITS    23
+
+#define DBL_EXPBITS     11
+#define DBL_FRACHBITS   20
+#define DBL_FRACLBITS   32
+#define DBL_FRACBITS    52
+
+#define EXT_EXPBITS     15
+#define EXT_FRACHBITS   32
+#define EXT_FRACLBITS   32
+#define EXT_FRACBITS    64
+
+#define EXT_TO_ARRAY32(p, a) do {       \
+    (a)[0] = (uint32_t)(p)->ext_fracl;  \
+    (a)[1] = (uint32_t)(p)->ext_frach;  \
+} while(0)
+
+struct ieee_single {
+    u_int   sng_frac:23;
+    u_int   sng_exp:8;
+    u_int   sng_sign:1;
+};
+
+struct ieee_double {
+    u_int   dbl_fracl;
+    u_int   dbl_frach:20;
+    u_int   dbl_exp:11;
+    u_int   dbl_sign:1;
+};
+
+struct ieee_ext {
+    u_int   ext_fracl;
+    u_int   ext_frach;
+    u_int   ext_exp:15;
+    u_int   ext_sign:1;
+    u_int   ext_padl:16;
+    u_int   ext_padh;
+};
+
+/*
+ * Floats whose exponent is in [1..INFNAN) (of whatever type) are
+ * `normal'.  Floats whose exponent is INFNAN are either Inf or NaN.
+ * Floats whose exponent is zero are either zero (iff all fraction
+ * bits are zero) or subnormal values.
+ *
+ * A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
+ * high fraction; if the bit is set, it is a `quiet NaN'.
+ */
+#define SNG_EXP_INFNAN  255
+#define DBL_EXP_INFNAN  2047
+#define EXT_EXP_INFNAN  32767
+
+#if 0
+#define SNG_QUIETNAN    (1 << 22)
+#define DBL_QUIETNAN    (1 << 19)
+#define EXT_QUIETNAN    (1 << 15)
+#endif
+
+/*
+ * Exponent biases.
+ */
+#define SNG_EXP_BIAS    127
+#define DBL_EXP_BIAS    1023
+#define EXT_EXP_BIAS    16383
diff --git a/common/inc/sys/limits.h b/common/inc/sys/limits.h
new file mode 100644
index 0000000..3d1f967
--- /dev/null
+++ b/common/inc/sys/limits.h
@@ -0,0 +1,77 @@
+/* $OpenBSD: limits.h,v 1.8 2009/11/27 19:54:35 guenther Exp $ */
+/*
+ * Copyright (c) 2002 Marc Espie.
+ *
+ * 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 OPENBSD PROJECT 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 OPENBSD
+ * PROJECT 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 _SYS_LIMITS_H_
+#define _SYS_LIMITS_H_
+
+#include <sys/cdefs.h>
+
+/* Common definitions for limits.h. */
+
+#define CHAR_BIT    8                           /* number of bits in a char */
+
+#define SCHAR_MAX   0x7f                        /* max value for a signed char */
+#define SCHAR_MIN   (-0x7f - 1)                 /* min value for a signed char */
+
+#define UCHAR_MAX   0xff                        /* max value for an unsigned char */
+#ifdef __CHAR_UNSIGNED__
+# define CHAR_MIN   0                           /* min value for a char */
+# define CHAR_MAX   0xff                        /* max value for a char */
+#else
+# define CHAR_MAX   0x7f
+# define CHAR_MIN   (-0x7f-1)
+#endif
+
+#define MB_LEN_MAX  1                           /* Allow UTF-8 (RFC 3629) */
+
+#define USHRT_MAX   0xffff                      /* max value for an unsigned short */
+#define SHRT_MAX    0x7fff                      /* max value for a short */
+#define SHRT_MIN    (-0x7fff-1)                 /* min value for a short */
+
+#define UINT_MAX    0xffffffffU                 /* max value for an unsigned int */
+#define INT_MAX     0x7fffffff                  /* max value for an int */
+#define INT_MIN     (-0x7fffffff-1)             /* min value for an int */
+
+#ifdef __x86_64__
+# define ULONG_MAX  0xffffffffffffffffUL        /* max value for unsigned long */
+# define LONG_MAX   0x7fffffffffffffffL         /* max value for a signed long */
+# define LONG_MIN   (-0x7fffffffffffffffL-1)    /* min value for a signed long */
+#else
+# define ULONG_MAX  0xffffffffUL                /* max value for an unsigned long */
+# define LONG_MAX   0x7fffffffL                 /* max value for a long */
+# define LONG_MIN   (-0x7fffffffL-1)            /* min value for a long */
+#endif
+
+#define ULLONG_MAX  0xffffffffffffffffULL       /* max value for unsigned long long */
+#define LLONG_MAX   0x7fffffffffffffffLL        /* max value for a signed long long */
+#define LLONG_MIN   (-0x7fffffffffffffffLL-1)   /* min value for a signed long long */
+
+#ifdef __x86_64__
+# define LONG_BIT   64
+#else
+# define LONG_BIT   32
+#endif
+
+#endif /* !_SYS_LIMITS_H_ */
diff --git a/common/inc/sys/stdint.h b/common/inc/sys/stdint.h
new file mode 100644
index 0000000..b76cc52
--- /dev/null
+++ b/common/inc/sys/stdint.h
@@ -0,0 +1,253 @@
+/*	$OpenBSD: stdint.h,v 1.4 2006/12/10 22:17:55 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 1997, 2005 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SYS_STDINT_H_
+#define _SYS_STDINT_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+/* 7.18.1.1 Exact-width integer types (also in sys/types.h) */
+#ifndef _INT8_T_DEFINED_
+#define _INT8_T_DEFINED_
+typedef __int8_t        int8_t;
+#endif
+
+#ifndef _UINT8_T_DEFINED_
+#define _UINT8_T_DEFINED_
+typedef __uint8_t       uint8_t;
+#endif
+
+#ifndef _INT16_T_DEFINED_
+#define _INT16_T_DEFINED_
+typedef __int16_t       int16_t;
+#endif
+
+#ifndef _UINT16_T_DEFINED_
+#define _UINT16_T_DEFINED_
+typedef __uint16_t      uint16_t;
+#endif
+
+#ifndef _INT32_T_DEFINED_
+#define _INT32_T_DEFINED_
+typedef __int32_t       int32_t;
+#endif
+
+#ifndef _UINT32_T_DEFINED_
+#define _UINT32_T_DEFINED_
+typedef __uint32_t      uint32_t;
+#endif
+
+#ifndef _INT64_T_DEFINED_
+#define _INT64_T_DEFINED_
+typedef __int64_t       int64_t;
+#endif
+
+#ifndef _UINT64_T_DEFINED_
+#define _UINT64_T_DEFINED_
+typedef __uint64_t      uint64_t;
+#endif
+
+/* 7.18.1.2 Minimum-width integer types */
+typedef __int_least8_t      int_least8_t;
+typedef __uint_least8_t     uint_least8_t;
+typedef __int_least16_t     int_least16_t;
+typedef __uint_least16_t    uint_least16_t;
+typedef __int_least32_t     int_least32_t;
+typedef __uint_least32_t    uint_least32_t;
+typedef __int_least64_t     int_least64_t;
+typedef __uint_least64_t    uint_least64_t;
+
+/* 7.18.1.3 Fastest minimum-width integer types */
+typedef __int_fast8_t       int_fast8_t;
+typedef __uint_fast8_t      uint_fast8_t;
+typedef __int_fast16_t      int_fast16_t;
+typedef __uint_fast16_t     uint_fast16_t;
+typedef __int_fast32_t      int_fast32_t;
+typedef __uint_fast32_t     uint_fast32_t;
+typedef __int_fast64_t      int_fast64_t;
+typedef __uint_fast64_t     uint_fast64_t;
+
+/* 7.18.1.4 Integer types capable of holding object pointers */
+#ifndef _INTPTR_T_DEFINED_
+#define _INTPTR_T_DEFINED_
+typedef __intptr_t      intptr_t;
+#endif
+
+#ifndef _UINTPTR_T_DEFINED_
+#define _UINTPTR_T_DEFINED_
+typedef __uintptr_t     uintptr_t;
+#endif
+
+/* 7.18.1.5 Greatest-width integer types */
+typedef __intmax_t      intmax_t;
+typedef __uintmax_t     uintmax_t;
+
+//#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
+/*
+ * 7.18.2 Limits of specified-width integer types.
+ *
+ * The following object-like macros specify the minimum and maximum limits
+ * of integer types corresponding to the typedef names defined above.
+ */
+
+/* 7.18.2.1 Limits of exact-width integer types */
+#define INT8_MIN        (-0x7f - 1)
+#define INT16_MIN       (-0x7fff - 1)
+#define INT32_MIN       (-0x7fffffff - 1)
+#define INT64_MIN       (-0x7fffffffffffffffLL - 1)
+
+#define INT8_MAX        0x7f
+#define INT16_MAX       0x7fff
+#define INT32_MAX       0x7fffffff
+#define INT64_MAX       0x7fffffffffffffffLL
+
+#define UINT8_MAX       0xff
+#define UINT16_MAX      0xffff
+#define UINT32_MAX      0xffffffffU
+#define UINT64_MAX      0xffffffffffffffffULL
+
+/* 7.18.2.2 Limits of minimum-width integer types */
+#define INT_LEAST8_MIN      INT8_MIN
+#define INT_LEAST16_MIN     INT16_MIN
+#define INT_LEAST32_MIN     INT32_MIN
+#define INT_LEAST64_MIN     INT64_MIN
+
+#define INT_LEAST8_MAX      INT8_MAX
+#define INT_LEAST16_MAX     INT16_MAX
+#define INT_LEAST32_MAX     INT32_MAX
+#define INT_LEAST64_MAX     INT64_MAX
+
+#define UINT_LEAST8_MAX     UINT8_MAX
+#define UINT_LEAST16_MAX    UINT16_MAX
+#define UINT_LEAST32_MAX    UINT32_MAX
+#define UINT_LEAST64_MAX    UINT64_MAX
+
+/* 7.18.2.3 Limits of fastest minimum-width integer types */
+#define INT_FAST8_MIN       INT8_MIN
+#define INT_FAST16_MIN      INT16_MIN
+#define INT_FAST32_MIN      INT32_MIN
+#define INT_FAST64_MIN      INT64_MIN
+
+#define INT_FAST8_MAX       INT8_MAX
+#ifdef __x86_64__
+#define INT_FAST16_MAX      INT64_MAX
+#define INT_FAST32_MAX      INT64_MAX
+#else
+#define INT_FAST16_MAX      INT32_MAX
+#define INT_FAST32_MAX      INT32_MAX
+#endif
+#define INT_FAST64_MAX      INT64_MAX
+
+#define UINT_FAST8_MAX      UINT8_MAX
+#ifdef __x86_64__
+#define UINT_FAST16_MAX     UINT64_MAX
+#define UINT_FAST32_MAX     UINT64_MAX
+#else
+#define UINT_FAST16_MAX     UINT32_MAX
+#define UINT_FAST32_MAX     UINT32_MAX
+#endif
+#define UINT_FAST64_MAX     UINT64_MAX
+
+/* 7.18.2.4 Limits of integer types capable of holding object pointers */
+#ifdef __x86_64__
+#define INTPTR_MIN      INT64_MIN
+#define INTPTR_MAX      INT64_MAX
+#define UINTPTR_MAX     UINT64_MAX
+#else
+#define INTPTR_MIN      INT32_MIN
+#define INTPTR_MAX      INT32_MAX
+#define UINTPTR_MAX     UINT32_MAX
+#endif
+
+/* 7.18.2.5 Limits of greatest-width integer types */
+#define INTMAX_MIN      INT64_MIN
+#define INTMAX_MAX      INT64_MAX
+#define UINTMAX_MAX     UINT64_MAX
+
+/*
+ * 7.18.3 Limits of other integer types.
+ *
+ * The following object-like macros specify the minimum and maximum limits
+ * of integer types corresponding to types specified in other standard
+ * header files.
+ */
+
+/* Limits of ptrdiff_t */
+#define PTRDIFF_MIN     INTPTR_MIN
+#define PTRDIFF_MAX     INTPTR_MAX
+
+/* Limits of size_t (also in limits.h) */
+#ifndef SIZE_MAX
+#define SIZE_MAX        UINTPTR_MAX
+#endif
+
+/* Limits of wchar_t */
+#ifdef _TLIBC_WIN_
+# define WCHAR_MIN      0x0000
+# define WCHAR_MAX      0xffff
+#else
+# ifdef __WCHAR_MAX__
+#  define WCHAR_MAX __WCHAR_MAX__
+# else
+#  define WCHAR_MAX (2147483647)
+# endif
+# ifdef __WCHAR_MIN__
+#  define WCHAR_MIN __WCHAR_MIN__
+# elif L'\0' - 1 > 0
+#  define WCHAR_MIN L'\0'
+# else
+#  define WCHAR_MIN (-WCHAR_MAX - 1)
+# endif
+#endif
+
+/* Limits of wint_t */
+# define WINT_MIN      (0u)
+# define WINT_MAX      (4294967295u)
+
+//#endif /* __cplusplus || __STDC_LIMIT_MACROS */
+
+//#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
+/*
+ * 7.18.4 Macros for integer constants.
+ *
+ * The following function-like macros expand to integer constants
+ * suitable for initializing objects that have integer types corresponding
+ * to types defined in <stdint.h>.  The argument in any instance of
+ * these macros shall be a decimal, octal, or hexadecimal constant with
+ * a value that does not exceed the limits for the corresponding type.
+ */
+
+/* 7.18.4.1 Macros for minimum-width integer constants. */
+#define INT8_C(_c)      (_c)
+#define INT16_C(_c)     (_c)
+#define INT32_C(_c)     (_c)
+#define INT64_C(_c)     __CONCAT(_c, LL)
+
+#define UINT8_C(_c)     (_c)
+#define UINT16_C(_c)    (_c)
+#define UINT32_C(_c)    __CONCAT(_c, U)
+#define UINT64_C(_c)    __CONCAT(_c, ULL)
+
+/* 7.18.4.2 Macros for greatest-width integer constants. */
+#define INTMAX_C(_c)    __CONCAT(_c, LL)
+#define UINTMAX_C(_c)   __CONCAT(_c, ULL)
+
+//#endif /* __cplusplus || __STDC_CONSTANT_MACROS */
+
+#endif /* _SYS_STDINT_H_ */
diff --git a/common/inc/sys/types.h b/common/inc/sys/types.h
new file mode 100644
index 0000000..474f3e9
--- /dev/null
+++ b/common/inc/sys/types.h
@@ -0,0 +1,128 @@
+/*	$OpenBSD: types.h,v 1.31 2008/03/16 19:42:57 otto Exp $	*/
+/*	$NetBSD: types.h,v 1.29 1996/11/15 22:48:25 jtc Exp $	*/
+
+/*-
+ * Copyright (c) 1982, 1986, 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)types.h	8.4 (Berkeley) 1/21/94
+ */
+
+#ifndef _SYS_TYPES_H_
+#define _SYS_TYPES_H_
+
+#include <sys/_types.h>
+#include <sys/endian.h>
+
+typedef unsigned char   u_char;
+typedef unsigned short  u_short;
+typedef unsigned int    u_int;
+typedef unsigned long   u_long;
+
+typedef unsigned char   unchar;     /* Sys V compatibility */
+typedef unsigned short  ushort;     /* Sys V compatibility */
+typedef unsigned int    uint;       /* Sys V compatibility */
+typedef unsigned long   ulong;      /* Sys V compatibility */
+
+#ifndef _INT8_T_DEFINED_
+#define _INT8_T_DEFINED_
+typedef __int8_t        int8_t;
+#endif
+
+#ifndef _UINT8_T_DEFINED_
+#define _UINT8_T_DEFINED_
+typedef __uint8_t       uint8_t;
+#endif
+
+#ifndef _INT16_T_DEFINED_
+#define _INT16_T_DEFINED_
+typedef __int16_t       int16_t;
+#endif
+
+#ifndef _UINT16_T_DEFINED_
+#define _UINT16_T_DEFINED_
+typedef __uint16_t      uint16_t;
+#endif
+
+#ifndef _INT32_T_DEFINED_
+#define _INT32_T_DEFINED_
+typedef __int32_t       int32_t;
+#endif
+
+#ifndef _UINT32_T_DEFINED_
+#define _UINT32_T_DEFINED_
+typedef __uint32_t      uint32_t;
+#endif
+
+#ifndef _INT64_T_DEFINED_
+#define _INT64_T_DEFINED_
+typedef __int64_t       int64_t;
+#endif
+
+#ifndef _UINT64_T_DEFINED_
+#define _UINT64_T_DEFINED_
+typedef __uint64_t      uint64_t;
+#endif
+
+#ifndef _INTPTR_T_DEFINED_
+#define _INTPTR_T_DEFINED_
+typedef __intptr_t      intptr_t;
+#endif
+
+#ifndef _UINTPTR_T_DEFINED_
+#define _UINTPTR_T_DEFINED_
+typedef __uintptr_t     uintptr_t;
+#endif
+
+/* BSD-style unsigned bits types */
+typedef __uint8_t       u_int8_t;
+typedef __uint16_t      u_int16_t;
+typedef __uint32_t      u_int32_t;
+typedef __uint64_t      u_int64_t;
+
+
+#ifndef _SIZE_T_DEFINED_
+#define _SIZE_T_DEFINED_
+typedef __size_t    size_t;
+#endif
+
+#ifndef _SSIZE_T_DEFINED_
+#define _SSIZE_T_DEFINED_
+typedef __ssize_t   ssize_t;
+#endif
+
+#ifndef _OFF_T_DEFINED_
+#define _OFF_T_DEFINED_
+typedef __off_t     off_t;
+#endif
+
+#endif /* !_SYS_TYPES_H_ */
diff --git a/common/inc/time.h b/common/inc/time.h
new file mode 100644
index 0000000..3880d3e
--- /dev/null
+++ b/common/inc/time.h
@@ -0,0 +1,104 @@
+/*	$OpenBSD: time.h,v 1.18 2006/01/06 18:53:04 millert Exp $	*/
+/*	$NetBSD: time.h,v 1.9 1994/10/26 00:56:35 cgd Exp $	*/
+
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)time.h	5.12 (Berkeley) 3/9/91
+ */
+
+#ifndef _TIME_H_
+#define _TIME_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL    0
+#else
+#define NULL    ((void *)0)
+#endif
+#endif
+
+#if !defined (_CLOCK_T_DEFINED_) && !defined (_CLOCK_T_DEFINED)
+#define _CLOCK_T_DEFINED_
+#define _CLOCK_T_DEFINED
+typedef __clock_t   clock_t;
+#endif
+
+#if !defined (_TIME_T_DEFINED_) && !defined (_TIME_T_DEFINED)
+#define _TIME_T_DEFINED_
+#define _TIME_T_DEFINED
+typedef __time_t    time_t;
+#endif
+
+#if !defined (_SIZE_T_DEFINED_) && !defined (_SIZE_T_DEFINED)
+#define _SIZE_T_DEFINED_
+#define _SIZE_T_DEFINED
+typedef __size_t    size_t;
+#endif
+
+#if !defined (_TM_DEFINED)
+#define _TM_DEFINED
+struct tm {
+    int tm_sec;     /* seconds after the minute [0-60] */
+    int tm_min;     /* minutes after the hour [0-59] */
+    int tm_hour;    /* hours since midnight [0-23] */
+    int tm_mday;    /* day of the month [1-31] */
+    int tm_mon;     /* months since January [0-11] */
+    int tm_year;    /* years since 1900 */
+    int tm_wday;    /* days since Sunday [0-6] */
+    int tm_yday;    /* days since January 1 [0-365] */
+    int tm_isdst;   /* Daylight Saving Time flag */
+    /* FIXME: naming issue exists on Fedora/Ubuntu */
+    long tm_gmtoff; /* offset from UTC in seconds */
+    char *tm_zone;  /* timezone abbreviation */
+};
+#endif
+
+__BEGIN_DECLS
+
+double _TLIBC_CDECL_ difftime(time_t, time_t);
+char * _TLIBC_CDECL_ asctime(const struct tm *);
+size_t _TLIBC_CDECL_ strftime(char *, size_t, const char *, const struct tm *);
+
+/*
+ * Non-C99
+ */
+char * _TLIBC_CDECL_ asctime_r(const struct tm *, char *);
+
+__END_DECLS
+
+#endif /* !_TIME_H_ */
diff --git a/common/inc/unistd.h b/common/inc/unistd.h
new file mode 100644
index 0000000..2958a6c
--- /dev/null
+++ b/common/inc/unistd.h
@@ -0,0 +1,59 @@
+/*	$OpenBSD: unistd.h,v 1.62 2008/06/25 14:58:54 millert Exp $ */
+/*	$NetBSD: unistd.h,v 1.26.4.1 1996/05/28 02:31:51 mrg Exp $	*/
+
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)unistd.h	5.13 (Berkeley) 6/17/91
+ */
+
+#ifndef _UNISTD_H_
+#define	_UNISTD_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+void * _TLIBC_CDECL_ sbrk(intptr_t);
+
+/*
+ * Deprecated Non-C99. 
+ */
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, execl, const char *, const char *, ...);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, execlp, const char *, const char *, ...);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, execle, const char *, const char *, ...);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, execv, const char *, char * const *);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, execve, const char *, char * const *, char * const *);
+_TLIBC_DEPRECATED_FUNCTION_(int _TLIBC_CDECL_, execvp, const char *, char * const *);
+
+//_TLIBC_DEPRECATED_FUNCTION_(pid_t _TLIBC_CDECL_, fork, void); /* no pid_t */
+
+__END_DECLS
+
+#endif /* !_UNISTD_H_ */
diff --git a/common/inc/wchar.h b/common/inc/wchar.h
new file mode 100644
index 0000000..4ca0b39
--- /dev/null
+++ b/common/inc/wchar.h
@@ -0,0 +1,139 @@
+/*	$OpenBSD: wchar.h,v 1.11 2010/07/24 09:58:39 guenther Exp $	*/
+/*	$NetBSD: wchar.h,v 1.16 2003/03/07 07:11:35 tshiozak Exp $	*/
+
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*-
+ * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Julian Coleman.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 _WCHAR_H_
+#define _WCHAR_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+#include <sys/stdint.h> /* WCHAR_MAX/WCHAR_MIN */
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL    0
+#else
+#define NULL    ((void *)0)
+#endif
+#endif
+
+#if !defined(_WCHAR_T_DEFINED_) && !defined(__cplusplus)
+#define _WCHAR_T_DEFINED_
+#ifndef __WCHAR_TYPE__
+#define __WCHAR_TYPE__ int
+#endif
+typedef __WCHAR_TYPE__ wchar_t;
+#endif
+
+#ifndef _MBSTATE_T_DEFINED_
+#define _MBSTATE_T_DEFINED_
+typedef __mbstate_t mbstate_t;
+#endif
+
+#ifndef _WINT_T_DEFINED_
+#define _WINT_T_DEFINED_
+typedef __wint_t    wint_t;
+#endif
+
+#ifndef _SIZE_T_DEFINED_
+#define _SIZE_T_DEFINED_
+typedef __size_t    size_t;
+#endif
+
+#ifndef WEOF
+#define WEOF    ((wint_t)-1)
+#endif
+
+__BEGIN_DECLS
+
+wint_t      _TLIBC_CDECL_ btowc(int);
+int         _TLIBC_CDECL_ wctob(wint_t);
+size_t      _TLIBC_CDECL_ mbrlen(const char *, size_t, mbstate_t *);
+size_t      _TLIBC_CDECL_ mbrtowc(wchar_t *, const char *, size_t, mbstate_t *);
+int         _TLIBC_CDECL_ mbsinit(const mbstate_t *);
+size_t      _TLIBC_CDECL_ mbsrtowcs(wchar_t *, const char **, size_t, mbstate_t *);
+size_t      _TLIBC_CDECL_ wcrtomb(char *, wchar_t, mbstate_t *);
+wchar_t *   _TLIBC_CDECL_ wcschr(const wchar_t *, wchar_t);
+int         _TLIBC_CDECL_ wcscmp(const wchar_t *, const wchar_t *);
+int         _TLIBC_CDECL_ wcscoll(const wchar_t *, const wchar_t *);
+size_t      _TLIBC_CDECL_ wcscspn(const wchar_t *, const wchar_t *);
+size_t      _TLIBC_CDECL_ wcslen(const wchar_t *);
+wchar_t *   _TLIBC_CDECL_ wcsncat(wchar_t *, const wchar_t *, size_t);
+int         _TLIBC_CDECL_ wcsncmp(const wchar_t *, const wchar_t *, size_t);
+wchar_t *   _TLIBC_CDECL_ wcsncpy(wchar_t *, const wchar_t *, size_t);
+wchar_t *   _TLIBC_CDECL_ wcspbrk(const wchar_t *, const wchar_t *);
+wchar_t *   _TLIBC_CDECL_ wcsrchr(const wchar_t *, wchar_t);
+size_t      _TLIBC_CDECL_ wcsrtombs(char *, const wchar_t **, size_t, mbstate_t *);
+size_t      _TLIBC_CDECL_ wcsspn(const wchar_t *, const wchar_t *);
+wchar_t *   _TLIBC_CDECL_ wcsstr(const wchar_t *, const wchar_t *);
+wchar_t *   _TLIBC_CDECL_ wcstok(wchar_t *, const wchar_t *, wchar_t **);
+size_t      _TLIBC_CDECL_ wcsxfrm(wchar_t *, const wchar_t *, size_t);
+wchar_t *   _TLIBC_CDECL_ wmemchr(const wchar_t *, wchar_t, size_t);
+int         _TLIBC_CDECL_ wmemcmp(const wchar_t *, const wchar_t *, size_t);
+wchar_t *   _TLIBC_CDECL_ wmemcpy(wchar_t *, const wchar_t *, size_t);
+wchar_t *   _TLIBC_CDECL_ wmemmove(wchar_t *, const wchar_t *, size_t);
+wchar_t *   _TLIBC_CDECL_ wmemset(wchar_t *, wchar_t, size_t);
+
+int         _TLIBC_CDECL_ swprintf(wchar_t *, size_t, const wchar_t *, ...);
+int         _TLIBC_CDECL_ vswprintf(wchar_t *, size_t, const wchar_t *, __va_list);
+
+/* leagcy version of wcsstr */
+wchar_t *   _TLIBC_CDECL_ wcswcs(const wchar_t *, const wchar_t *);
+
+__END_DECLS
+
+#endif /* !_WCHAR_H_ */
diff --git a/common/inc/wctype.h b/common/inc/wctype.h
new file mode 100644
index 0000000..25466f1
--- /dev/null
+++ b/common/inc/wctype.h
@@ -0,0 +1,83 @@
+/*	$OpenBSD: wctype.h,v 1.5 2006/01/06 18:53:04 millert Exp $	*/
+/*	$NetBSD: wctype.h,v 1.5 2003/03/02 22:18:11 tshiozak Exp $	*/
+
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * 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 AUTHOR 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 AUTHOR 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.
+ *
+ *	citrus Id: wctype.h,v 1.4 2000/12/21 01:50:21 itojun Exp
+ */
+
+#ifndef _WCTYPE_H_
+#define _WCTYPE_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _WINT_T_DEFINED_
+#define _WINT_T_DEFINED_
+typedef __wint_t    wint_t;
+#endif
+
+#ifndef _WCTRANS_T_DEFINED_
+#define _WCTRANS_T_DEFINED_
+typedef __wctrans_t wctrans_t;
+#endif
+
+#ifndef _WCTYPE_T_DEFINED_
+#define _WCTYPE_T_DEFINED_
+typedef __wctype_t  wctype_t;
+#endif
+
+#ifndef WEOF
+#define WEOF    ((wint_t)-1)
+#endif
+
+__BEGIN_DECLS
+
+/*
+ * Deprecated definitions.
+ */
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswalnum, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswalpha, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswblank, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswcntrl, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswdigit, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswgraph, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswlower, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswprint, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswpunct, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswspace, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswupper, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswxdigit, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(int         _TLIBC_CDECL_, iswctype, wint_t, wctype_t);
+_TLIBC_DEPRECATED_FUNCTION_(wint_t      _TLIBC_CDECL_, towctrans, wint_t, wctrans_t);
+_TLIBC_DEPRECATED_FUNCTION_(wint_t      _TLIBC_CDECL_, towlower, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(wint_t      _TLIBC_CDECL_, towupper, wint_t);
+_TLIBC_DEPRECATED_FUNCTION_(wctrans_t   _TLIBC_CDECL_, wctrans, const char *);
+_TLIBC_DEPRECATED_FUNCTION_(wctype_t    _TLIBC_CDECL_, wctype, const char *);
+
+__END_DECLS
+
+#endif /* _WCTYPE_H_ */
diff --git a/compiler-rt/LICENSE.TXT b/compiler-rt/LICENSE.TXT
new file mode 100644
index 0000000..488baf5
--- /dev/null
+++ b/compiler-rt/LICENSE.TXT
@@ -0,0 +1,98 @@
+==============================================================================
+compiler_rt License
+==============================================================================
+
+The compiler_rt library is dual licensed under both the University of Illinois
+"BSD-Like" license and the MIT license.  As a user of this code you may choose
+to use it under either license.  As a contributor, you agree to allow your code
+to be used under both.
+
+Full text of the relevant licenses is included below.
+
+==============================================================================
+
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2009-2010 by the contributors listed in CREDITS.TXT
+
+All rights reserved.
+
+Developed by:
+
+    LLVM Team
+
+    University of Illinois at Urbana-Champaign
+
+    http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+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:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimers in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the names of the LLVM Team, University of Illinois at
+      Urbana-Champaign, nor the names of its contributors may be used to
+      endorse or promote products derived from this Software without specific
+      prior written permission.
+
+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
+CONTRIBUTORS 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 WITH THE
+SOFTWARE.
+
+==============================================================================
+
+Copyright (c) 2009-2010 by the contributors listed in CREDITS.TXT
+
+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.
+
+==============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+==============================================================================
+The LLVM software contains code written by third parties.  Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the LLVM Distribution, and nothing in any of the
+other licenses gives permission to use the names of the LLVM Team or the
+University of Illinois to endorse or promote products derived from this
+Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+sysinfo             lib/asan/sysinfo
+mach_override       lib/asan/mach_override
diff --git a/compiler-rt/Makefile b/compiler-rt/Makefile
new file mode 100644
index 0000000..cfad8ec
--- /dev/null
+++ b/compiler-rt/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#   * 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.
+#   * Neither the name of Intel Corporation nor the names of its
+#     contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# 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
+# OWNER 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 ../buildenv.mk
+COMMON_DIR := ../common
+CFLAGS   += $(ENCLAVE_CFLAGS)
+CPPFLAGS += $(ADDED_INC)                \
+            -I$(COMMON_DIR)/inc/
+
+SRCS := $(wildcard *.c)
+OBJS := $(sort $(SRCS:.c=.o))
+
+TARGET  := libcompiler-rt-patch.a
+
+.PHONY: all
+all: $(TARGET)
+
+$(TARGET): $(OBJS)
+	$(AR) rcsD $@ $^
+
+$(OBJS): %.o: %.c
+	$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
+
+.PHONY: clean
+clean:
+	@$(RM) $(OBJS) $(TARGET)
diff --git a/compiler-rt/int_endianness.h b/compiler-rt/int_endianness.h
new file mode 100644
index 0000000..7ac5056
--- /dev/null
+++ b/compiler-rt/int_endianness.h
@@ -0,0 +1,113 @@
+/* ===-- int_endianness.h - configuration header for compiler-rt ------------===
+ *
+ *		       The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file is a configuration header for compiler-rt.
+ * This file is not part of the interface of this library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#ifndef INT_ENDIANNESS_H
+#define INT_ENDIANNESS_H
+
+#if defined(__SVR4) && defined(__sun)
+#include <sys/byteorder.h>
+
+#if defined(_BIG_ENDIAN)
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN    1
+#elif defined(_LITTLE_ENDIAN)
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+#else /* !_LITTLE_ENDIAN */
+#error "unknown endianness"
+#endif /* !_LITTLE_ENDIAN */
+
+#endif /* Solaris and AuroraUX. */
+
+/* .. */
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) ||   \
+    defined(__minix)
+#include <sys/endian.h>
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN    1
+#elif _BYTE_ORDER == _LITTLE_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+#endif /* _BYTE_ORDER */
+
+#endif /* *BSD */
+
+#if defined(__OpenBSD__) || defined(__Bitrig__)
+#include <machine/endian.h>
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN    1
+#elif _BYTE_ORDER == _LITTLE_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+#endif /* _BYTE_ORDER */
+
+#endif /* OpenBSD and Bitrig. */
+
+/* .. */
+
+/* Mac OSX has __BIG_ENDIAN__ or __LITTLE_ENDIAN__ automatically set by the
+ * compiler (at least with GCC) */
+#if defined(__APPLE__) || defined(__ellcc__ )
+
+#ifdef __BIG_ENDIAN__
+#if __BIG_ENDIAN__
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN    1
+#endif
+#endif /* __BIG_ENDIAN__ */
+
+#ifdef __LITTLE_ENDIAN__
+#if __LITTLE_ENDIAN__
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+#endif
+#endif /* __LITTLE_ENDIAN__ */
+
+#endif /* Mac OSX */
+
+/* .. */
+
+#if defined(__linux__)
+#include <endian.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 0
+#define _YUGA_BIG_ENDIAN    1
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+#endif /* __BYTE_ORDER */
+
+#endif /* GNU/Linux */
+
+#if defined(_WIN32)
+
+#define _YUGA_LITTLE_ENDIAN 1
+#define _YUGA_BIG_ENDIAN    0
+
+#endif /* Windows */
+
+/* . */
+
+#if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN)
+#error Unable to determine endian
+#endif /* Check we found an endianness correctly. */
+
+#endif /* INT_ENDIANNESS_H */
diff --git a/compiler-rt/int_lib.h b/compiler-rt/int_lib.h
new file mode 100644
index 0000000..ff314da
--- /dev/null
+++ b/compiler-rt/int_lib.h
@@ -0,0 +1,70 @@
+/* ===-- int_lib.h - configuration header for compiler-rt  -----------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file is a configuration header for compiler-rt.
+ * This file is not part of the interface of this library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#ifndef INT_LIB_H
+#define INT_LIB_H
+
+/* Assumption: Signed integral is 2's complement. */
+/* Assumption: Right shift of signed negative is arithmetic shift. */
+/* Assumption: Endianness is little or big (not mixed). */
+
+/* ABI macro definitions */
+
+#if __ARM_EABI__
+# define ARM_EABI_FNALIAS(aeabi_name, name)         \
+  void __aeabi_##aeabi_name() __attribute__((alias("__" #name)));
+# define COMPILER_RT_ABI __attribute__((pcs("aapcs")))
+#else
+# define ARM_EABI_FNALIAS(aeabi_name, name)
+# define COMPILER_RT_ABI
+#endif
+
+#if defined(__NetBSD__) && (defined(_KERNEL) || defined(_STANDALONE))
+/*
+ * Kernel and boot environment can't use normal headers,
+ * so use the equivalent system headers.
+ */
+#  include <machine/limits.h>
+#  include <sys/stdint.h>
+#  include <sys/types.h>
+#else
+/* Include the standard compiler builtin headers we use functionality from. */
+#  include <limits.h>
+#  include <stdint.h>
+#  include <stdbool.h>
+#  include <float.h>
+#endif
+
+/* Include the commonly used internal type definitions. */
+#include "int_types.h"
+
+/* Include internal utility function declarations. */
+#include "int_util.h"
+
+COMPILER_RT_ABI si_int __paritysi2(si_int a);
+COMPILER_RT_ABI si_int __paritydi2(di_int a);
+
+COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b);
+COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b);
+COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d);
+
+COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int* rem);
+COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
+#ifdef CRT_HAS_128BIT
+COMPILER_RT_ABI si_int __clzti2(ti_int a);
+COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
+#endif
+
+#endif /* INT_LIB_H */
diff --git a/compiler-rt/int_types.h b/compiler-rt/int_types.h
new file mode 100644
index 0000000..5107f71
--- /dev/null
+++ b/compiler-rt/int_types.h
@@ -0,0 +1,143 @@
+/* ===-- int_lib.h - configuration header for compiler-rt  -----------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file is not part of the interface of this library.
+ *
+ * This file defines various standard types, most importantly a number of unions
+ * used to access parts of larger types.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#ifndef INT_TYPES_H
+#define INT_TYPES_H
+
+#include "int_endianness.h"
+
+typedef      int si_int;
+typedef unsigned su_int;
+
+typedef          long long di_int;
+typedef unsigned long long du_int;
+
+typedef union
+{
+    di_int all;
+    struct
+    {
+#if _YUGA_LITTLE_ENDIAN
+        su_int low;
+        si_int high;
+#else
+        si_int high;
+        su_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+    }s;
+} dwords;
+
+typedef union
+{
+    du_int all;
+    struct
+    {
+#if _YUGA_LITTLE_ENDIAN
+        su_int low;
+        su_int high;
+#else
+        su_int high;
+        su_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+    }s;
+} udwords;
+
+#if __LP64__
+#define CRT_HAS_128BIT
+#endif
+
+#ifdef CRT_HAS_128BIT
+typedef int      ti_int __attribute__ ((mode (TI)));
+typedef unsigned tu_int __attribute__ ((mode (TI)));
+
+typedef union
+{
+    ti_int all;
+    struct
+    {
+#if _YUGA_LITTLE_ENDIAN
+        du_int low;
+        di_int high;
+#else
+        di_int high;
+        du_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+    }s;
+} twords;
+
+typedef union
+{
+    tu_int all;
+    struct
+    {
+#if _YUGA_LITTLE_ENDIAN
+        du_int low;
+        du_int high;
+#else
+        du_int high;
+        du_int low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+    }s;
+} utwords;
+
+static inline ti_int make_ti(di_int h, di_int l) {
+    twords r;
+    r.s.high = h;
+    r.s.low = l;
+    return r.all;
+}
+
+static inline tu_int make_tu(du_int h, du_int l) {
+    utwords r;
+    r.s.high = h;
+    r.s.low = l;
+    return r.all;
+}
+
+#endif /* CRT_HAS_128BIT */
+
+typedef union
+{
+    su_int u;
+    float f;
+} float_bits;
+
+typedef union
+{
+    udwords u;
+    double  f;
+} double_bits;
+
+typedef struct
+{
+#if _YUGA_LITTLE_ENDIAN
+    udwords low;
+    udwords high;
+#else
+    udwords high;
+    udwords low;
+#endif /* _YUGA_LITTLE_ENDIAN */
+} uqwords;
+
+typedef union
+{
+    uqwords     u;
+    long double f;
+} long_double_bits;
+
+#endif /* INT_TYPES_H */
+
diff --git a/compiler-rt/int_util.h b/compiler-rt/int_util.h
new file mode 100644
index 0000000..a9b595d
--- /dev/null
+++ b/compiler-rt/int_util.h
@@ -0,0 +1,29 @@
+/* ===-- int_util.h - internal utility functions ----------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===-----------------------------------------------------------------------===
+ *
+ * This file is not part of the interface of this library.
+ *
+ * This file defines non-inline utilities which are available for use in the
+ * library. The function definitions themselves are all contained in int_util.c
+ * which will always be compiled into any compiler-rt library.
+ *
+ * ===-----------------------------------------------------------------------===
+ */
+
+#ifndef INT_UTIL_H
+#define INT_UTIL_H
+
+/** \brief Trigger a program abort (or panic for kernel code). */
+#define compilerrt_abort() compilerrt_abort_impl(__FILE__, __LINE__, \
+                                                 __func__)
+
+void compilerrt_abort_impl(const char *file, int line,
+                           const char *function) __attribute__((noreturn));
+
+#endif /* INT_UTIL_H */
diff --git a/compiler-rt/muloti4.c b/compiler-rt/muloti4.c
new file mode 100644
index 0000000..16b2189
--- /dev/null
+++ b/compiler-rt/muloti4.c
@@ -0,0 +1,62 @@
+/*===-- muloti4.c - Implement __muloti4 -----------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __muloti4 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+#ifdef CRT_HAS_128BIT
+
+/* Returns: a * b */
+
+/* Effects: sets *overflow to 1  if a * b overflows */
+
+COMPILER_RT_ABI ti_int
+__muloti4(ti_int a, ti_int b, int* overflow)
+{
+    const int N = (int)(sizeof(ti_int) * CHAR_BIT);
+    const ti_int MIN = (ti_int)1 << (N-1);
+    const ti_int MAX = ~MIN;
+    *overflow = 0;
+    ti_int result = a * b;
+    if (a == MIN)
+    {
+        if (b != 0 && b != 1)
+	    *overflow = 1;
+	return result;
+    }
+    if (b == MIN)
+    {
+        if (a != 0 && a != 1)
+	    *overflow = 1;
+        return result;
+    }
+    ti_int sa = a >> (N - 1);
+    ti_int abs_a = (a ^ sa) - sa;
+    ti_int sb = b >> (N - 1);
+    ti_int abs_b = (b ^ sb) - sb;
+    if (abs_a < 2 || abs_b < 2)
+        return result;
+    if (sa == sb)
+    {
+        if (abs_a > MAX / abs_b)
+            *overflow = 1;
+    }
+    else
+    {
+        if (abs_a > MIN / -abs_b)
+            *overflow = 1;
+    }
+    return result;
+}
+
+#endif /* CRT_HAS_128BIT */
diff --git a/dockerfile/Dockerfile b/dockerfile/Dockerfile
new file mode 100644
index 0000000..ac5fba7
--- /dev/null
+++ b/dockerfile/Dockerfile
@@ -0,0 +1,60 @@
+# BSD License
+#
+# Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#   * 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.
+#   * Neither the name of Baidu, Inc., nor the names of its
+#     contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+
+
+FROM ubuntu:16.04
+MAINTAINER Yu Ding
+
+RUN apt-get update
+RUN apt-get install -y build-essential ocaml automake autoconf libtool wget python libssl-dev libcurl4-openssl-dev protobuf-compiler libprotobuf-dev sudo kmod vim curl git-core
+
+RUN mkdir /root/sgx
+RUN wget -O /root/sgx/optimized_libs-1.8.100.37641.tar https://download.01.org/intel-sgx/linux-1.8/optimized_libs-1.8.100.37641.tar
+RUN wget -O /root/sgx/prebuilt-ae-1.8.100.37641.tar  https://download.01.org/intel-sgx/linux-1.8/prebuilt-ae-1.8.100.37641.tar
+RUN wget -O /root/sgx/sgx_linux_ubuntu16.04.1_x64_psw_1.8.100.37689.bin https://download.01.org/intel-sgx/linux-1.8/sgx_linux_ubuntu16.04.1_x64_psw_1.8.100.37689.bin
+RUN wget -O /root/sgx/sgx_linux_ubuntu16.04.1_x64_sdk_1.8.100.37689.bin https://download.01.org/intel-sgx/linux-1.8/sgx_linux_ubuntu16.04.1_x64_sdk_1.8.100.37689.bin
+
+RUN chmod a+x /root/sgx/sgx_linux_ubuntu16.04.1_x64_psw_1.8.100.37689.bin
+RUN /root/sgx/sgx_linux_ubuntu16.04.1_x64_psw_1.8.100.37689.bin
+RUN chmod a+x /root/sgx/sgx_linux_ubuntu16.04.1_x64_sdk_1.8.100.37689.bin
+RUN echo -e 'no\n/opt' | /root/sgx/sgx_linux_ubuntu16.04.1_x64_sdk_1.8.100.37689.bin
+RUN echo 'source /opt/sgxsdk/environment' >> /root/.bashrc
+
+RUN wget 'https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init' -O /root/rustup-init
+RUN chmod +x /root/rustup-init
+RUN echo '1' | /root/rustup-init  --default-toolchain nightly
+RUN echo 'source /root/.cargo/env' >> /root/.bashrc
+
+RUN git clone https://github.com/01org/linux-sgx.git /root/linux-sgx
+ADD patch /root/
+RUN cd /root/linux-sgx && git apply ../patch
+RUN /root/linux-sgx/download_prebuilt.sh
+RUN cd /root/linux-sgx && make
+RUN cp /root/linux-sgx/build/linux/libsgx_tstdc.a /opt/sgxsdk/lib64/libsgx_tstdc.a
diff --git a/dockerfile/patch b/dockerfile/patch
new file mode 100644
index 0000000..28b17ef
--- /dev/null
+++ b/dockerfile/patch
@@ -0,0 +1,13 @@
+diff --git a/sdk/tlibc/Makefile b/sdk/tlibc/Makefile
+index 9aee436..acc73cf 100644
+--- a/sdk/tlibc/Makefile
++++ b/sdk/tlibc/Makefile
+@@ -33,7 +33,7 @@ include ../../buildenv.mk
+ 
+ CFLAGS   += $(ENCLAVE_CFLAGS)
+ ASFLAGS  := $(CFLAGS)
+-CFLAGS   += -std=c99
++CFLAGS   += -std=c99 -D USE_MALLOC_DEPRECATED
+ CXXFLAGS += $(ENCLAVE_CXXFLAGS) -fno-exceptions -fno-rtti
+ 
+ CPPFLAGS += -I.                          \
diff --git a/release_docs/whitepaper.md b/release_docs/whitepaper.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/release_docs/whitepaper.md
diff --git a/release_notes.md b/release_notes.md
new file mode 100644
index 0000000..30d3831
--- /dev/null
+++ b/release_notes.md
@@ -0,0 +1,42 @@
+# Rust SGX SDK v0.1.0
+
+## Introduction
+Baidu X-Lab provides Rust SGX SDK, to help develop Intel SGX enclaves in Rust
+programming language.
+
+### Contents
+
+* Basic Rust SGX SDK libraries
+* A patch to solve Rust's floating point compatibility issue.
+* Sample enclave codes.
+* A well-configured [docker image](https://hub.docker.com/r/baiduxlab/sgx-rust/).
+
+Please refer to our white paper for details.
+
+## What's New
+
+* Support for the latest Intel SGX SDK v1.8 for Linux.
+* Support for the latest Rust nightly build (1.18.0-nightly (c58c928e6 2017-04-11)).
+* Rust style document.
+
+## System Requirements
+
+* Ubuntu 16.04 LTS
+* [Hardware platform supports Intel SGX](https://github.com/ayeks/SGX-hardware)
+* Docker (Strongly recommended)
+* Rust nightly (Tested on rustc 1.18.0-nightly (c58c928e6 2017-04-11))
+
+## Known Issues and Limitations
+
+* Rust stable branch is unsupported.
+* `cargo test` is unsupported.
+
+## Unstable APIs
+
+* `rsgx_get_thread_data`
+
+* `rsgx_get_enclave_base`
+
+* `rsgx_get_heap_base`
+
+* `rsgx_get_heap_size`
diff --git a/samplecode/crypto/Makefile b/samplecode/crypto/Makefile
new file mode 100644
index 0000000..e70d365
--- /dev/null
+++ b/samplecode/crypto/Makefile
@@ -0,0 +1,183 @@
+#
+# Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#   * 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.
+#   * Neither the name of Intel Corporation nor the names of its
+#     contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+#
+#
+
+######## SGX SDK Settings ########
+
+SGX_SDK ?= /opt/intel/sgxsdk
+SGX_MODE ?= HW
+SGX_ARCH ?= x64
+
+ifeq ($(shell getconf LONG_BIT), 32)
+	SGX_ARCH := x86
+else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
+	SGX_ARCH := x86
+endif
+
+ifeq ($(SGX_ARCH), x86)
+	SGX_COMMON_CFLAGS := -m32
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
+else
+	SGX_COMMON_CFLAGS := -m64
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
+endif
+
+ifeq ($(SGX_DEBUG), 1)
+ifeq ($(SGX_PRERELEASE), 1)
+$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
+endif
+endif
+
+
+ifeq ($(SGX_DEBUG), 1)
+	SGX_COMMON_CFLAGS += -O0 -g
+else
+	SGX_COMMON_CFLAGS += -O2
+endif
+
+######## CUSTOM Settings ########
+
+CUSTOM_LIBRARY_PATH := ./lib
+CUSTOM_BIN_PATH := ./bin
+
+######## EDL Settings ########
+
+Enclave_EDL_Files := enclave/Enclave_t.c enclave/Enclave_t.h app/Enclave_u.c app/Enclave_u.h
+
+######## APP Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Urts_Library_Name := sgx_urts_sim
+else
+	Urts_Library_Name := sgx_urts
+endif
+
+App_C_Files := $(wildcard ./app/*.c)
+App_Include_Paths := -I ./app -I./include -I$(SGX_SDK)/include
+App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
+App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread 
+ifneq ($(SGX_MODE), HW)
+	App_Link_Flags += -lsgx_uae_service_sim
+else
+	App_Link_Flags += -lsgx_uae_service
+endif
+
+App_C_Objects := $(App_C_Files:.c=.o)
+
+App_Name := bin/app
+
+######## Enclave Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Trts_Library_Name := sgx_trts_sim
+	Service_Library_Name := sgx_tservice_sim
+else
+	Trts_Library_Name := sgx_trts
+	Service_Library_Name := sgx_tservice
+endif
+Crypto_Library_Name := sgx_tcrypto
+KeyExchange_Library_Name := sgx_tkey_exchange
+
+RustEnclave_C_Files := $(wildcard ./enclave/*.c)
+RustEnclave_C_Objects := $(RustEnclave_C_Files:.c=.o)
+RustEnclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport -I$(SGX_SDK)/include/epid -I ./enclave -I./include
+
+RustEnclave_Link_Libs := -L$(CUSTOM_LIBRARY_PATH) -lcompiler-rt-patch -lenclave
+RustEnclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(RustEnclave_Include_Paths)
+RustEnclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
+	-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
+	-Wl,--start-group -lsgx_tstdc -lsgx_tstdcxx -l$(Crypto_Library_Name) -l$(KeyExchange_Library_Name) -l$(Service_Library_Name) $(RustEnclave_Link_Libs) -Wl,--end-group \
+	-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
+	-Wl,-pie,-eenclave_entry -Wl,--export-dynamic  \
+	-Wl,--defsym,__ImageBase=0 \
+	-Wl,--gc-sections \
+	-Wl,--version-script=enclave/Enclave.lds
+
+
+RustEnclave_Name := enclave/enclave.so
+Signed_RustEnclave_Name := bin/enclave.signed.so
+
+.PHONY: all
+all: $(Enclave_EDL_Files) $(App_Name) $(Signed_RustEnclave_Name)
+
+######## EDL Objects ########
+
+$(Enclave_EDL_Files): $(SGX_EDGER8R) enclave/Enclave.edl
+	$(SGX_EDGER8R) --trusted enclave/Enclave.edl --search-path $(SGX_SDK)/include --trusted-dir enclave
+	$(SGX_EDGER8R) --untrusted enclave/Enclave.edl --search-path $(SGX_SDK)/include --untrusted-dir app
+	@echo "GEN  =>  $(Enclave_EDL_Files)"
+
+######## App Objects ########
+
+app/Enclave_u.o: app/Enclave_u.c
+	@$(CC) $(App_C_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+app/%.o: app/%.c
+	@$(CXX) $(App_C_Flags) -c $< -o $@
+	@echo "CXX  <=  $<"
+
+$(App_Name): app/Enclave_u.o $(App_C_Objects)
+	@$(CXX) $^ -o $@ $(App_Link_Flags)
+	@echo "LINK =>  $@"
+
+######## Enclave Objects ########
+
+enclave/Enclave_t.o: enclave/Enclave_t.c
+	@$(CC) $(RustEnclave_Compile_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+$(RustEnclave_Name): enclave compiler-rt enclave/Enclave_t.o 
+	cp ./enclave/target/release/libenclave.a ./lib
+	cp ../../compiler-rt/libcompiler-rt-patch.a ./lib
+	@$(CXX) enclave/Enclave_t.o -o $@ $(RustEnclave_Link_Flags)
+	@echo "LINK =>  $@"
+
+$(Signed_RustEnclave_Name): $(RustEnclave_Name)
+	@$(SGX_ENCLAVE_SIGNER) sign -key enclave/Enclave_private.pem -enclave $(RustEnclave_Name) -out $@ -config enclave/Enclave.config.xml
+	@echo "SIGN =>  $@"
+
+.PHONY: enclave
+enclave:
+	$(MAKE) -C ./enclave/
+	
+.PHONY: compiler-rt
+compiler-rt:
+	$(MAKE) -C ../../compiler-rt/ 2> /dev/null
+
+.PHONY: clean
+clean:
+	@rm -f $(App_Name) $(RustEnclave_Name) $(Signed_RustEnclave_Name) $(RustEnclave_C_Objects) $(App_C_Objects) enclave/*_t.* app/*_u.* lib/*.a
+	@cd enclave && cargo clean && rm -f Cargo.lock
+	
diff --git a/samplecode/crypto/app/app.c b/samplecode/crypto/app/app.c
new file mode 100644
index 0000000..fb576ec
--- /dev/null
+++ b/samplecode/crypto/app/app.c
@@ -0,0 +1,391 @@
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <unistd.h>
+#include <pwd.h>
+#define MAX_PATH FILENAME_MAX
+
+#include "sgx_urts.h"
+#include "sgx_tseal.h"
+#include "app.h"
+#include "Enclave_u.h"
+
+
+sgx_enclave_id_t global_eid = 0;
+
+typedef struct _sgx_errlist_t {
+    sgx_status_t err;
+    const char *msg;
+    const char *sug; /* Suggestion */
+} sgx_errlist_t;
+
+/* Error code returned by sgx_create_enclave */
+static sgx_errlist_t sgx_errlist[] = {
+    {
+        SGX_ERROR_UNEXPECTED,
+        "Unexpected error occurred.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_PARAMETER,
+        "Invalid parameter.",
+        NULL
+    },
+    {
+        SGX_ERROR_OUT_OF_MEMORY,
+        "Out of memory.",
+        NULL
+    },
+    {
+        SGX_ERROR_ENCLAVE_LOST,
+        "Power transition occurred.",
+        "Please refer to the sample \"PowerTransition\" for details."
+    },
+    {
+        SGX_ERROR_INVALID_ENCLAVE,
+        "Invalid enclave image.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_ENCLAVE_ID,
+        "Invalid enclave identification.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_SIGNATURE,
+        "Invalid enclave signature.",
+        NULL
+    },
+    {
+        SGX_ERROR_OUT_OF_EPC,
+        "Out of EPC memory.",
+        NULL
+    },
+    {
+        SGX_ERROR_NO_DEVICE,
+        "Invalid SGX device.",
+        "Please make sure SGX module is enabled in the BIOS, and install SGX driver afterwards."
+    },
+    {
+        SGX_ERROR_MEMORY_MAP_CONFLICT,
+        "Memory map conflicted.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_METADATA,
+        "Invalid enclave metadata.",
+        NULL
+    },
+    {
+        SGX_ERROR_DEVICE_BUSY,
+        "SGX device was busy.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_VERSION,
+        "Enclave version was invalid.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_ATTRIBUTE,
+        "Enclave was not authorized.",
+        NULL
+    },
+    {
+        SGX_ERROR_ENCLAVE_FILE_ACCESS,
+        "Can't open enclave file.",
+        NULL
+    },
+};
+
+/* Check error conditions for loading enclave */
+void print_error_message(sgx_status_t ret)
+{
+    size_t idx = 0;
+    size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0];
+
+    for (idx = 0; idx < ttl; idx++) {
+        if(ret == sgx_errlist[idx].err) {
+            if(NULL != sgx_errlist[idx].sug)
+                printf("Info: %s\n", sgx_errlist[idx].sug);
+            printf("Error: %s\n", sgx_errlist[idx].msg);
+            break;
+        }
+    }
+    
+    if (idx == ttl)
+        printf("Error: Unexpected error occurred.\n");
+}
+
+/* Initialize the enclave:
+ *   Step 1: try to retrieve the launch token saved by last transaction
+ *   Step 2: call sgx_create_enclave to initialize an enclave instance
+ *   Step 3: save the launch token if it is updated
+ */
+int initialize_enclave(void)
+{
+    char token_path[MAX_PATH] = {'\0'};
+    sgx_launch_token_t token = {0};
+    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
+    int updated = 0;
+    
+    /* Step 1: try to retrieve the launch token saved by last transaction 
+     *         if there is no token, then create a new one.
+     */
+    /* try to get the token saved in $HOME */
+    const char *home_dir = getpwuid(getuid())->pw_dir;
+    
+    if (home_dir != NULL && 
+        (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) {
+        /* compose the token path */
+        strncpy(token_path, home_dir, strlen(home_dir));
+        strncat(token_path, "/", strlen("/"));
+        strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1);
+    } else {
+        /* if token path is too long or $HOME is NULL */
+        strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME));
+    }
+
+    FILE *fp = fopen(token_path, "rb");
+    if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
+        printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
+    }
+
+    if (fp != NULL) {
+        /* read the token from saved file */
+        size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
+        if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
+            /* if token is invalid, clear the buffer */
+            memset(&token, 0x0, sizeof(sgx_launch_token_t));
+            printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
+        }
+    }
+    /* Step 2: call sgx_create_enclave to initialize an enclave instance */
+    /* Debug Support: set 2nd parameter to 1 */
+    ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
+    if (ret != SGX_SUCCESS) {
+        print_error_message(ret);
+        if (fp != NULL) fclose(fp);
+        return -1;
+    }
+    printf("[+] global_eid: %ld\n", global_eid);
+
+    /* Step 3: save the launch token if it is updated */
+    if (updated == FALSE || fp == NULL) {
+        /* if the token is not updated, or file handler is invalid, do not perform saving */
+        if (fp != NULL) fclose(fp);
+        return 0;
+    }
+
+    /* reopen the file with write capablity */
+    fp = freopen(token_path, "wb", fp);
+    if (fp == NULL) return 0;
+    size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
+    if (write_num != sizeof(sgx_launch_token_t))
+        printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
+    fclose(fp);
+    return 0;
+}
+
+/* Application entry */
+int SGX_CDECL main(int argc, char *argv[])
+{
+    sgx_status_t sgx_ret = SGX_SUCCESS;
+    sgx_status_t enclave_ret = SGX_SUCCESS;
+    uint32_t sealed_log_size = 1024;
+    uint8_t sealed_log[1024] = {0};
+    sgx_sealed_data_t * sealed_data = 0;
+    
+    (void)(argc);
+    (void)(argv);
+
+    /* Initialize the enclave */
+    if(initialize_enclave() < 0){
+        printf("Enter a character before exit ...\n");
+        getchar();
+        return -1; 
+    }
+
+    // SHA-256 test case comes from
+    // https://tools.ietf.org/html/rfc4634
+    // TEST1
+    
+    const char* str = "abc";
+    size_t len = strlen(str);
+    uint8_t * output_hash = (uint8_t *) malloc (32 + 1);
+
+    printf("[+] sha256 input string is %s\n", str);
+    printf("[+] Expected SHA256 hash: %s\n",
+           "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
+
+    sgx_ret = calc_sha256(global_eid, 
+                         &enclave_ret, 
+                         (const uint8_t *) str, 
+                         len,
+                         output_hash);
+
+    if(sgx_ret != SGX_SUCCESS) {
+        print_error_message(sgx_ret);
+        return -1;
+    }
+
+    if(enclave_ret != SGX_SUCCESS) {
+        print_error_message(enclave_ret);
+        return -1;
+    }
+
+    printf("[+] SHA256 result is ");
+
+    int i;
+    for(i = 0; i < 32; i ++) {
+        printf("%02x", output_hash[i]);
+    }
+    printf("\n");
+    printf("[+] calc_sha256 success ...\n");
+
+    // AES-GCM-128 test case comes from
+    // http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
+    // Test case 2
+
+    printf("[+] Starting aes-gcm-128 encrypt calculation\n");
+    uint8_t aes_gcm_plaintext[16] = {0};
+    uint8_t aes_gcm_key[16] = {0};
+    uint8_t aes_gcm_iv[12] = {0};
+    uint8_t aes_gcm_ciphertext[16] = {0};
+    uint8_t aes_gcm_mac[16] = {0};
+
+    printf("[+] aes-gcm-128 args prepared!\n");
+    printf("[+] aes-gcm-128 expected ciphertext: %s\n",
+           "0388dace60b6a392f328c2b971b2fe78");
+    sgx_ret = aes_gcm_128_encrypt(global_eid,
+                                  &enclave_ret,                      
+                                  aes_gcm_key,
+                                  aes_gcm_plaintext,
+                                  16,
+                                  aes_gcm_iv,
+                                  aes_gcm_ciphertext,
+                                  aes_gcm_mac);
+
+    printf("[+] aes-gcm-128 returned from enclave!\n");
+
+    if(sgx_ret != SGX_SUCCESS) {
+        print_error_message(sgx_ret);
+        return -1;
+    }
+
+    if(enclave_ret != SGX_SUCCESS) {
+        print_error_message(enclave_ret);
+        return -1;
+    }
+
+    printf("[+] aes-gcm-128 ciphertext is: ");
+    for(i = 0; i < 16; i ++) {
+        printf("%02x", aes_gcm_ciphertext[i]);
+    }
+    printf("\n");
+
+    printf("[+] aes-gcm-128 result mac is: ");
+    for(i = 0; i < 16; i ++) {
+        printf("%02x", aes_gcm_mac[i]);
+    }
+    printf("\n");
+
+    printf("[+] Starting aes-gcm-128 decrypt calculation\n");
+    printf("[+] aes-gcm-128 expected plaintext: %s", aes_gcm_plaintext);
+    
+    uint8_t aes_gcm_decrypted_text[16] = {0};
+    sgx_ret = aes_gcm_128_decrypt(global_eid,
+                                  &enclave_ret,
+                                  aes_gcm_key,
+                                  aes_gcm_ciphertext,
+                                  16,
+                                  aes_gcm_iv,
+                                  aes_gcm_mac,
+                                  aes_gcm_decrypted_text);
+
+    if(sgx_ret != SGX_SUCCESS) {
+        print_error_message(sgx_ret);
+        return -1;
+    }
+    if(enclave_ret != SGX_SUCCESS) {
+        print_error_message(enclave_ret);
+        return -1;
+    }
+
+    printf("[+] aes-gcm-128 decrypted plaintext is: ");
+    for(i = 0; i < 16; i ++) {
+        printf("%02x", aes_gcm_decrypted_text[i]);
+    }
+    printf("\n");
+
+    printf("[+] aes-gcm-128 decrypt complete \n");
+
+    // AES-CMAC test case comes from
+    // https://tools.ietf.org/html/rfc4493
+    // Example 3
+
+    printf("[+] Starting aes-cmac test \n");
+    printf("[+] aes-cmac expected digest: %s\n",
+           "51f0bebf7e3b9d92fc49741779363cfe");
+
+    uint8_t cmac_key[] = {
+		0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+        0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
+	};
+
+	uint8_t cmac_msg[] = {
+        0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+        0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+        0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+        0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+        0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+        0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+        0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+        0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
+    };
+
+    uint8_t cmac_result[16] = {0};
+
+    sgx_ret = aes_cmac(global_eid,
+                       &enclave_ret,
+                       cmac_msg,
+                       sizeof(cmac_msg),
+                       cmac_key,
+                       cmac_result);
+
+    if(sgx_ret != SGX_SUCCESS) {
+        print_error_message(sgx_ret);
+        return -1;
+    }
+    if(enclave_ret != SGX_SUCCESS) {
+        print_error_message(enclave_ret);
+        return -1;
+    }
+
+    printf("[+] aes-cmac result is: ");
+    for(i = 0; i < 16; i ++){
+        printf("%02x", cmac_result[i]);
+    }
+    printf("\n");
+
+    /* Destroy the enclave */
+    sgx_destroy_enclave(global_eid);
+    
+    return 0;
+}
+
+void ocall_print_string(const char *str, size_t len)
+{
+    char * string = (char *)malloc(len + (size_t)sizeof(char));
+    if (string == NULL) {
+        printf("malloc failed\n");
+        return;
+    }
+    
+    memcpy(string, str, len);
+    char * ptr = string + len;
+    * ptr = 0;
+    printf("%s\n", string);
+    free(string);
+}
diff --git a/samplecode/crypto/app/app.h b/samplecode/crypto/app/app.h
new file mode 100644
index 0000000..5e76517
--- /dev/null
+++ b/samplecode/crypto/app/app.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 _APP_H_
+#define _APP_H_
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "sgx_error.h"       /* sgx_status_t */
+#include "sgx_eid.h"     /* sgx_enclave_id_t */
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define TOKEN_FILENAME   "enclave.token"
+#define ENCLAVE_FILENAME "enclave.signed.so"
+
+extern sgx_enclave_id_t global_eid;    /* global enclave id */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_APP_H_ */
diff --git a/samplecode/crypto/bin/readme.txt b/samplecode/crypto/bin/readme.txt
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/samplecode/crypto/bin/readme.txt
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/samplecode/crypto/enclave/Cargo.toml b/samplecode/crypto/enclave/Cargo.toml
new file mode 100644
index 0000000..8d98dd5
--- /dev/null
+++ b/samplecode/crypto/enclave/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "enclave"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[lib]
+name = "enclave"
+crate-type = ["staticlib"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_tcrypto = { path = "../../../sgx_tcrypto" }
diff --git a/samplecode/crypto/enclave/Enclave.config.xml b/samplecode/crypto/enclave/Enclave.config.xml
new file mode 100644
index 0000000..ee4c3f7
--- /dev/null
+++ b/samplecode/crypto/enclave/Enclave.config.xml
@@ -0,0 +1,12 @@
+<!-- Please refer to User's Guide for the explanation of each field -->
+<EnclaveConfiguration>
+  <ProdID>0</ProdID>
+  <ISVSVN>0</ISVSVN>
+  <StackMaxSize>0x40000</StackMaxSize>
+  <HeapMaxSize>0x100000</HeapMaxSize>
+  <TCSNum>1</TCSNum>
+  <TCSPolicy>1</TCSPolicy>
+  <DisableDebug>0</DisableDebug>
+  <MiscSelect>0</MiscSelect>
+  <MiscMask>0xFFFFFFFF</MiscMask>
+</EnclaveConfiguration>
diff --git a/samplecode/crypto/enclave/Enclave.edl b/samplecode/crypto/enclave/Enclave.edl
new file mode 100644
index 0000000..50bec35
--- /dev/null
+++ b/samplecode/crypto/enclave/Enclave.edl
@@ -0,0 +1,36 @@
+enclave {
+	
+    trusted {
+        /* define ECALLs here. */
+		
+        public sgx_status_t calc_sha256([in, size=len] const uint8_t* input_str, 
+                                        size_t len,
+                                        [out] uint8_t hash[32]);
+
+        public sgx_status_t aes_gcm_128_encrypt([in] uint8_t key[16],
+                                                [in, size=len] const uint8_t* plaintext,
+                                                size_t len,
+                                                [in] uint8_t iv[12],
+                                                [out, size=len] uint8_t* ciphertext,
+                                                [out] uint8_t mac[16]);
+
+        public sgx_status_t aes_gcm_128_decrypt([in] uint8_t key[16],
+                                                [in, size=len] const uint8_t* ciphertext,
+                                                size_t len,
+                                                [in] uint8_t iv[12],
+                                                [in] uint8_t mac[16],
+                                                [out, size=len] uint8_t* plaintext);
+
+        public sgx_status_t aes_cmac([in, size=len] const uint8_t* text,
+                                     size_t len,
+                                     [in] uint8_t key[16],
+                                     [out] uint8_t cmac[16]);
+
+    };
+    
+    untrusted {
+        void ocall_print_string([in, size=len] const char *str, size_t len);
+    };
+
+ 
+};
diff --git a/samplecode/crypto/enclave/Enclave.lds b/samplecode/crypto/enclave/Enclave.lds
new file mode 100644
index 0000000..eb09b70
--- /dev/null
+++ b/samplecode/crypto/enclave/Enclave.lds
@@ -0,0 +1,9 @@
+libTestEnclave.so
+{
+    global:
+        g_global_data_sim;
+        g_global_data;
+        enclave_entry;
+    local:
+        *;
+};
diff --git a/samplecode/crypto/enclave/Enclave_private.pem b/samplecode/crypto/enclave/Enclave_private.pem
new file mode 100644
index 0000000..529d07b
--- /dev/null
+++ b/samplecode/crypto/enclave/Enclave_private.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ
+AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ
+ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr
+nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b
+3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H
+ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD
+5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW
+KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC
+1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe
+K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z
+AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q
+ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6
+JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826
+5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02
+wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9
+osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm
+WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i
+Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9
+xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd
+vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD
+Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a
+cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC
+0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ
+gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo
+gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t
+k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz
+Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6
+O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5
+afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom
+e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G
+BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv
+fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN
+t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9
+yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp
+6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg
+WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH
+NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk=
+-----END RSA PRIVATE KEY-----
diff --git a/samplecode/crypto/enclave/Makefile b/samplecode/crypto/enclave/Makefile
new file mode 100644
index 0000000..ec1512d
--- /dev/null
+++ b/samplecode/crypto/enclave/Makefile
@@ -0,0 +1,9 @@
+Rust_Enclave_Name := libenclave.a
+Rust_Enclave_Files := $(wildcard src/*.rs)
+
+.PHONY: all
+
+all: $(Rust_Enclave_Name)
+
+$(Rust_Enclave_Name): $(Rust_Enclave_Files)  
+	cargo build --release
diff --git a/samplecode/crypto/enclave/src/lib.rs b/samplecode/crypto/enclave/src/lib.rs
new file mode 100644
index 0000000..3c5d9e7
--- /dev/null
+++ b/samplecode/crypto/enclave/src/lib.rs
@@ -0,0 +1,403 @@
+#![crate_name = "enclave"]
+#![crate_type = "staticlib"]
+
+#![no_std]
+#![feature(collections)]
+
+#[macro_use]
+extern crate collections;
+
+extern crate sgx_types;
+extern crate sgx_tcrypto;
+
+use sgx_types::*;
+use sgx_tcrypto::*;
+use collections::vec::Vec;
+use collections::slice;
+use core::ptr;
+
+/// The Ocall declared in Enclave.edl and implemented in app.c
+///
+/// # Parameters
+///
+/// **str**
+///
+/// A pointer to the string to be printed
+///
+/// **len**
+///
+/// An unsigned int indicates the length of str
+///
+/// # Return value
+///
+/// None
+extern "C" {
+    fn ocall_print_string(str: *const c_uchar, len: size_t);
+}
+
+/// A Ecall function takes a string and output its SHA256 digest.
+///
+/// # Parameters
+///
+/// **input_str**
+///
+/// A raw pointer to the string to be calculated.
+///
+/// **some_len**
+///
+/// An unsigned int indicates the length of input string
+///
+/// **hash**
+///
+/// A const reference to [u8;32] array, which is the destination buffer which contains the SHA256 digest, caller allocated.
+///
+/// # Return value
+///
+/// **SGX_SUCCESS** on success. The SHA256 digest is stored in the destination buffer.
+///
+/// # Requirements
+///
+/// Caller allocates the input buffer and output buffer.
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Indicates the parameter is invalid
+#[no_mangle]
+pub extern "C" fn calc_sha256(input_str: *const u8,
+                              some_len: u32,
+                              hash: &mut [u8;32]) -> sgx_status_t {
+    let rust_raw_string = "calc_sha256 invoked!";
+
+    unsafe {
+        ocall_print_string(rust_raw_string.as_ptr() as *const c_uchar,
+                           rust_raw_string.len() as size_t);
+    }
+
+    // First, build a slice for input_str
+    let input_slice;
+
+    unsafe {
+        input_slice = slice::from_raw_parts(input_str, some_len as usize);
+    }
+
+    // slice::from_raw_parts does not guarantee the length, we need a check
+    if input_slice.len() != some_len as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    let debug_str = format!("Input string len = {}, input len = {}",
+                            input_slice.len(),
+                            some_len);
+
+    unsafe {
+        ocall_print_string(debug_str.as_ptr() as *const c_uchar,
+                           debug_str.len() as size_t);
+    }
+
+    // Second, convert the vector to a slice and calculate its SHA256
+    let result = rsgx_sha256_slice(&input_slice);
+
+    // Third, copy back the result
+    match result {
+        Ok(output_hash) => *hash = output_hash,
+        Err(x) => return x
+    }
+
+    sgx_status_t::SGX_SUCCESS
+}
+
+/// An AES-GCM-128 encrypt function sample.
+///
+/// # Parameters
+///
+/// **key**
+///
+/// Key used in AES encryption, typed as &[u8;16].
+///
+/// **plaintext**
+///
+/// Plain text to be encrypted.
+///
+/// **text_len**
+///
+/// Length of plain text, unsigned int.
+///
+/// **iv**
+///
+/// Initialization vector of AES encryption, typed as &[u8;12].
+///
+/// **ciphertext**
+///
+/// A pointer to destination ciphertext buffer.
+///
+/// **mac**
+///
+/// A pointer to destination mac buffer, typed as &mut [u8;16].
+///
+/// # Return value
+///
+/// **SGX_SUCCESS** on success
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER** Indicates the parameter is invalid.
+///
+/// **SGX_ERROR_UNEXPECTED** Indicates that encryption failed.
+///
+/// # Requirements
+///
+/// The caller should allocate the ciphertext buffer. This buffer should be
+/// at least same length as plaintext buffer. The caller should allocate the
+/// mac buffer, at least 16 bytes.
+#[no_mangle]
+pub extern "C" fn aes_gcm_128_encrypt(key: &[u8;16],
+                                      plaintext: *const u8,
+                                      text_len: u32,
+                                      iv: &[u8;12],
+                                      ciphertext: *mut u8,
+                                      mac: &mut [u8;16]) -> sgx_status_t {
+
+    let rust_raw_string = "aes_gcm_128_encrypt invoked!";
+
+    unsafe {
+        ocall_print_string(rust_raw_string.as_ptr() as *const c_uchar,
+                           rust_raw_string.len() as size_t);
+    }
+
+    // First, we need slices for input
+    let plaintext_slice;
+
+    // Here we need to initiate the ciphertext buffer, though nothing in it.
+    // Thus show the length of ciphertext buffer is equal to plaintext buffer.
+    // If not, the length of ciphertext_vec will be 0, which leads to argument
+    // illegal.
+    let mut ciphertext_vec: Vec<u8> = vec![0; text_len as usize];
+
+    // Second, for data with known length, we use array with fixed length.
+    // Here we cannot use slice::from_raw_parts because it provides &[u8]
+    // instead of &[u8,16].
+    let aad_array: [u8; 0] = [0; 0];
+    let mut mac_array: [u8; SGX_AESGCM_MAC_SIZE] = [0; SGX_AESGCM_MAC_SIZE];
+
+    unsafe {
+        plaintext_slice = slice::from_raw_parts(plaintext, text_len as usize);
+    }
+
+    // Always check the length after slice::from_raw_parts
+    if plaintext_slice.len() != text_len as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    let mut ciphertext_slice = &mut ciphertext_vec[..];
+    let rust_raw_string = format!("aes_gcm_128_encrypt parameter prepared! {}, {}",
+                                  plaintext_slice.len(),
+                                  ciphertext_slice.len());
+
+    unsafe {
+        ocall_print_string(rust_raw_string.as_ptr() as *const c_uchar,
+                           rust_raw_string.len() as size_t);
+    }
+
+    // After everything has been set, call API
+    let result = rsgx_rijndael128GCM_encrypt(key,
+                                             &plaintext_slice,
+                                             iv,
+                                             &aad_array,
+                                             ciphertext_slice,
+                                             &mut mac_array);
+
+    let rust_raw_string = "rsgx calling returned!";
+
+    unsafe {
+        ocall_print_string(rust_raw_string.as_ptr() as *const c_uchar,
+                           rust_raw_string.len() as size_t);
+    }
+
+    // Match the result and copy result back to normal world.
+    match result {
+        Err(x) => {
+            return x;
+        }
+        Ok(()) => {
+            unsafe{
+                ptr::copy_nonoverlapping(ciphertext_slice.as_ptr(),
+                                         ciphertext,
+                                         text_len as usize);
+            }
+            *mac = mac_array;
+        }
+    }
+
+    sgx_status_t::SGX_SUCCESS
+}
+
+/// An AES-GCM-128 decrypt function sample.
+///
+/// # Parameters
+///
+/// **key**
+///
+/// Key used in AES encryption, typed as &[u8;16].
+///
+/// **ciphertext**
+///
+/// Cipher text to be encrypted.
+///
+/// **text_len**
+///
+/// Length of cipher text.
+///
+/// **iv**
+///
+/// Initialization vector of AES encryption, typed as &[u8;12].
+///
+/// **mac**
+///
+/// A pointer to source mac buffer, typed as &[u8;16].
+///
+/// **plaintext**
+///
+/// A pointer to destination plaintext buffer.
+///
+/// # Return value
+///
+/// **SGX_SUCCESS** on success
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER** Indicates the parameter is invalid.
+/// 
+/// **SGX_ERROR_UNEXPECTED** means that decryption failed.
+///
+/// # Requirements
+//
+/// The caller should allocate the plaintext buffer. This buffer should be
+/// at least same length as ciphertext buffer.
+#[no_mangle]
+pub extern "C" fn aes_gcm_128_decrypt(key: &[u8;16],
+                                      ciphertext: *const u8,
+                                      text_len: u32,
+                                      iv: &[u8;12],
+                                      mac: &[u8;16],
+                                      plaintext: *mut u8) -> sgx_status_t {
+
+    let rust_raw_string = "aes_gcm_128_decrypt invoked!";
+
+    unsafe {
+        ocall_print_string(rust_raw_string.as_ptr() as *const c_uchar,
+                           rust_raw_string.len() as size_t);
+    }
+
+    // First, for data with unknown length, we use vector as builder.
+    let ciphertext_slice;
+    let mut plaintext_vec: Vec<u8> = vec![0; text_len as usize];
+
+    // Second, for data with known length, we use array with fixed length.
+    let aad_array: [u8; 0] = [0; 0];
+
+    unsafe {
+        ciphertext_slice = slice::from_raw_parts(ciphertext, text_len as usize);
+    }
+
+    if ciphertext_slice.len() != text_len as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    let mut plaintext_slice = &mut plaintext_vec[..];
+    let rust_raw_string = format!("aes_gcm_128_decrypt parameter prepared! {},{}",
+                                  ciphertext_slice.len(),
+                                  plaintext_slice.len());
+
+    unsafe {
+        ocall_print_string(rust_raw_string.as_ptr() as *const c_uchar,
+                           rust_raw_string.len() as size_t);
+    }
+
+    // After everything has been set, call API
+    let result = rsgx_rijndael128GCM_decrypt(key,
+                                             &ciphertext_slice,
+                                             iv,
+                                             &aad_array,
+                                             mac,
+                                             plaintext_slice);
+
+    let rust_raw_string = "rsgx calling returned!";
+
+    unsafe {
+        ocall_print_string(rust_raw_string.as_ptr() as *const c_uchar,
+                           rust_raw_string.len() as size_t);
+    }
+    // Match the result and copy result back to normal world.
+    match result {
+        Err(x) => {
+            return x;
+        }
+        Ok(()) => {
+            unsafe {
+                ptr::copy_nonoverlapping(plaintext_slice.as_ptr(),
+                                         plaintext,
+                                         text_len as usize);
+            }
+        }
+    }
+
+    sgx_status_t::SGX_SUCCESS
+}
+
+/// A sample aes-cmac function.
+///
+/// # Parameters
+///
+/// **text**
+///
+/// The text message to be calculated.
+///
+/// **text_len**
+///
+/// An unsigned int indicate the length of input text message.
+///
+/// **key**
+///
+/// The key used in AES-CMAC, 16 bytes sized.
+///
+/// **cmac**
+///
+/// The output buffer, at least 16 bytes available.
+///
+/// # Return value
+///
+/// **SGX_SUCCESS** on success.
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER** indicates invalid input parameters
+///
+/// # Requirement
+///
+/// The caller should allocate the output cmac buffer.
+#[no_mangle]
+pub extern "C" fn aes_cmac(text: *const u8,
+                           text_len: u32,
+                           key: &[u8;16],
+                           cmac: &mut [u8;16]) -> sgx_status_t {
+    let text_slice;
+
+    unsafe {
+        text_slice = slice::from_raw_parts(text, text_len as usize);
+    }
+
+    if text_slice.len() != text_len as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    let result = rsgx_rijndael128_cmac_slice(key, &text_slice);
+
+    match result {
+        Err(x) => return x,
+        Ok(m) => *cmac = m
+    }
+
+    sgx_status_t::SGX_SUCCESS
+}
diff --git a/samplecode/crypto/lib/readme.txt b/samplecode/crypto/lib/readme.txt
new file mode 100644
index 0000000..7951405
--- /dev/null
+++ b/samplecode/crypto/lib/readme.txt
@@ -0,0 +1 @@
+lib
\ No newline at end of file
diff --git a/samplecode/helloworld/Makefile b/samplecode/helloworld/Makefile
new file mode 100644
index 0000000..e70d365
--- /dev/null
+++ b/samplecode/helloworld/Makefile
@@ -0,0 +1,183 @@
+#
+# Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#   * 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.
+#   * Neither the name of Intel Corporation nor the names of its
+#     contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+#
+#
+
+######## SGX SDK Settings ########
+
+SGX_SDK ?= /opt/intel/sgxsdk
+SGX_MODE ?= HW
+SGX_ARCH ?= x64
+
+ifeq ($(shell getconf LONG_BIT), 32)
+	SGX_ARCH := x86
+else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
+	SGX_ARCH := x86
+endif
+
+ifeq ($(SGX_ARCH), x86)
+	SGX_COMMON_CFLAGS := -m32
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
+else
+	SGX_COMMON_CFLAGS := -m64
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
+endif
+
+ifeq ($(SGX_DEBUG), 1)
+ifeq ($(SGX_PRERELEASE), 1)
+$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
+endif
+endif
+
+
+ifeq ($(SGX_DEBUG), 1)
+	SGX_COMMON_CFLAGS += -O0 -g
+else
+	SGX_COMMON_CFLAGS += -O2
+endif
+
+######## CUSTOM Settings ########
+
+CUSTOM_LIBRARY_PATH := ./lib
+CUSTOM_BIN_PATH := ./bin
+
+######## EDL Settings ########
+
+Enclave_EDL_Files := enclave/Enclave_t.c enclave/Enclave_t.h app/Enclave_u.c app/Enclave_u.h
+
+######## APP Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Urts_Library_Name := sgx_urts_sim
+else
+	Urts_Library_Name := sgx_urts
+endif
+
+App_C_Files := $(wildcard ./app/*.c)
+App_Include_Paths := -I ./app -I./include -I$(SGX_SDK)/include
+App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
+App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread 
+ifneq ($(SGX_MODE), HW)
+	App_Link_Flags += -lsgx_uae_service_sim
+else
+	App_Link_Flags += -lsgx_uae_service
+endif
+
+App_C_Objects := $(App_C_Files:.c=.o)
+
+App_Name := bin/app
+
+######## Enclave Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Trts_Library_Name := sgx_trts_sim
+	Service_Library_Name := sgx_tservice_sim
+else
+	Trts_Library_Name := sgx_trts
+	Service_Library_Name := sgx_tservice
+endif
+Crypto_Library_Name := sgx_tcrypto
+KeyExchange_Library_Name := sgx_tkey_exchange
+
+RustEnclave_C_Files := $(wildcard ./enclave/*.c)
+RustEnclave_C_Objects := $(RustEnclave_C_Files:.c=.o)
+RustEnclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport -I$(SGX_SDK)/include/epid -I ./enclave -I./include
+
+RustEnclave_Link_Libs := -L$(CUSTOM_LIBRARY_PATH) -lcompiler-rt-patch -lenclave
+RustEnclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(RustEnclave_Include_Paths)
+RustEnclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
+	-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
+	-Wl,--start-group -lsgx_tstdc -lsgx_tstdcxx -l$(Crypto_Library_Name) -l$(KeyExchange_Library_Name) -l$(Service_Library_Name) $(RustEnclave_Link_Libs) -Wl,--end-group \
+	-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
+	-Wl,-pie,-eenclave_entry -Wl,--export-dynamic  \
+	-Wl,--defsym,__ImageBase=0 \
+	-Wl,--gc-sections \
+	-Wl,--version-script=enclave/Enclave.lds
+
+
+RustEnclave_Name := enclave/enclave.so
+Signed_RustEnclave_Name := bin/enclave.signed.so
+
+.PHONY: all
+all: $(Enclave_EDL_Files) $(App_Name) $(Signed_RustEnclave_Name)
+
+######## EDL Objects ########
+
+$(Enclave_EDL_Files): $(SGX_EDGER8R) enclave/Enclave.edl
+	$(SGX_EDGER8R) --trusted enclave/Enclave.edl --search-path $(SGX_SDK)/include --trusted-dir enclave
+	$(SGX_EDGER8R) --untrusted enclave/Enclave.edl --search-path $(SGX_SDK)/include --untrusted-dir app
+	@echo "GEN  =>  $(Enclave_EDL_Files)"
+
+######## App Objects ########
+
+app/Enclave_u.o: app/Enclave_u.c
+	@$(CC) $(App_C_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+app/%.o: app/%.c
+	@$(CXX) $(App_C_Flags) -c $< -o $@
+	@echo "CXX  <=  $<"
+
+$(App_Name): app/Enclave_u.o $(App_C_Objects)
+	@$(CXX) $^ -o $@ $(App_Link_Flags)
+	@echo "LINK =>  $@"
+
+######## Enclave Objects ########
+
+enclave/Enclave_t.o: enclave/Enclave_t.c
+	@$(CC) $(RustEnclave_Compile_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+$(RustEnclave_Name): enclave compiler-rt enclave/Enclave_t.o 
+	cp ./enclave/target/release/libenclave.a ./lib
+	cp ../../compiler-rt/libcompiler-rt-patch.a ./lib
+	@$(CXX) enclave/Enclave_t.o -o $@ $(RustEnclave_Link_Flags)
+	@echo "LINK =>  $@"
+
+$(Signed_RustEnclave_Name): $(RustEnclave_Name)
+	@$(SGX_ENCLAVE_SIGNER) sign -key enclave/Enclave_private.pem -enclave $(RustEnclave_Name) -out $@ -config enclave/Enclave.config.xml
+	@echo "SIGN =>  $@"
+
+.PHONY: enclave
+enclave:
+	$(MAKE) -C ./enclave/
+	
+.PHONY: compiler-rt
+compiler-rt:
+	$(MAKE) -C ../../compiler-rt/ 2> /dev/null
+
+.PHONY: clean
+clean:
+	@rm -f $(App_Name) $(RustEnclave_Name) $(Signed_RustEnclave_Name) $(RustEnclave_C_Objects) $(App_C_Objects) enclave/*_t.* app/*_u.* lib/*.a
+	@cd enclave && cargo clean && rm -f Cargo.lock
+	
diff --git a/samplecode/helloworld/app/app.c b/samplecode/helloworld/app/app.c
new file mode 100644
index 0000000..de309ab
--- /dev/null
+++ b/samplecode/helloworld/app/app.c
@@ -0,0 +1,249 @@
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <unistd.h>
+#include <pwd.h>
+#define MAX_PATH FILENAME_MAX
+
+#include "sgx_urts.h"
+#include "sgx_tseal.h"
+#include "app.h"
+#include "Enclave_u.h"
+
+
+sgx_enclave_id_t global_eid = 0;
+
+typedef struct _sgx_errlist_t {
+    sgx_status_t err;
+    const char *msg;
+    const char *sug; /* Suggestion */
+} sgx_errlist_t;
+
+/* Error code returned by sgx_create_enclave */
+static sgx_errlist_t sgx_errlist[] = {
+    {
+        SGX_ERROR_UNEXPECTED,
+        "Unexpected error occurred.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_PARAMETER,
+        "Invalid parameter.",
+        NULL
+    },
+    {
+        SGX_ERROR_OUT_OF_MEMORY,
+        "Out of memory.",
+        NULL
+    },
+    {
+        SGX_ERROR_ENCLAVE_LOST,
+        "Power transition occurred.",
+        "Please refer to the sample \"PowerTransition\" for details."
+    },
+    {
+        SGX_ERROR_INVALID_ENCLAVE,
+        "Invalid enclave image.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_ENCLAVE_ID,
+        "Invalid enclave identification.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_SIGNATURE,
+        "Invalid enclave signature.",
+        NULL
+    },
+    {
+        SGX_ERROR_OUT_OF_EPC,
+        "Out of EPC memory.",
+        NULL
+    },
+    {
+        SGX_ERROR_NO_DEVICE,
+        "Invalid SGX device.",
+        "Please make sure SGX module is enabled in the BIOS, and install SGX driver afterwards."
+    },
+    {
+        SGX_ERROR_MEMORY_MAP_CONFLICT,
+        "Memory map conflicted.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_METADATA,
+        "Invalid enclave metadata.",
+        NULL
+    },
+    {
+        SGX_ERROR_DEVICE_BUSY,
+        "SGX device was busy.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_VERSION,
+        "Enclave version was invalid.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_ATTRIBUTE,
+        "Enclave was not authorized.",
+        NULL
+    },
+    {
+        SGX_ERROR_ENCLAVE_FILE_ACCESS,
+        "Can't open enclave file.",
+        NULL
+    },
+};
+
+/* Check error conditions for loading enclave */
+void print_error_message(sgx_status_t ret)
+{
+    size_t idx = 0;
+    size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0];
+
+    for (idx = 0; idx < ttl; idx++) {
+        if(ret == sgx_errlist[idx].err) {
+            if(NULL != sgx_errlist[idx].sug)
+                printf("Info: %s\n", sgx_errlist[idx].sug);
+            printf("Error: %s\n", sgx_errlist[idx].msg);
+            break;
+        }
+    }
+    
+    if (idx == ttl)
+        printf("Error: Unexpected error occurred.\n");
+}
+
+/* Initialize the enclave:
+ *   Step 1: try to retrieve the launch token saved by last transaction
+ *   Step 2: call sgx_create_enclave to initialize an enclave instance
+ *   Step 3: save the launch token if it is updated
+ */
+int initialize_enclave(void)
+{
+    char token_path[MAX_PATH] = {'\0'};
+    sgx_launch_token_t token = {0};
+    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
+    int updated = 0;
+    
+    /* Step 1: try to retrieve the launch token saved by last transaction 
+     *         if there is no token, then create a new one.
+     */
+    /* try to get the token saved in $HOME */
+    const char *home_dir = getpwuid(getuid())->pw_dir;
+    
+    if (home_dir != NULL && 
+        (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) {
+        /* compose the token path */
+        strncpy(token_path, home_dir, strlen(home_dir));
+        strncat(token_path, "/", strlen("/"));
+        strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1);
+    } else {
+        /* if token path is too long or $HOME is NULL */
+        strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME));
+    }
+
+    FILE *fp = fopen(token_path, "rb");
+    if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
+        printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
+    }
+
+    if (fp != NULL) {
+        /* read the token from saved file */
+        size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
+        if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
+            /* if token is invalid, clear the buffer */
+            memset(&token, 0x0, sizeof(sgx_launch_token_t));
+            printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
+        }
+    }
+    /* Step 2: call sgx_create_enclave to initialize an enclave instance */
+    /* Debug Support: set 2nd parameter to 1 */
+    ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
+    if (ret != SGX_SUCCESS) {
+        print_error_message(ret);
+        if (fp != NULL) fclose(fp);
+        return -1;
+    }
+    printf("[+] global_eid: %ld\n", global_eid);
+
+    /* Step 3: save the launch token if it is updated */
+    if (updated == FALSE || fp == NULL) {
+        /* if the token is not updated, or file handler is invalid, do not perform saving */
+        if (fp != NULL) fclose(fp);
+        return 0;
+    }
+
+    /* reopen the file with write capablity */
+    fp = freopen(token_path, "wb", fp);
+    if (fp == NULL) return 0;
+    size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
+    if (write_num != sizeof(sgx_launch_token_t))
+        printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
+    fclose(fp);
+    return 0;
+}
+
+/* Application entry */
+int SGX_CDECL main(int argc, char *argv[])
+{
+    sgx_status_t sgx_ret = SGX_SUCCESS;
+    sgx_status_t enclave_ret = SGX_SUCCESS;
+    uint32_t sealed_log_size = 1024;
+    uint8_t sealed_log[1024] = {0};
+    sgx_sealed_data_t * sealed_data = 0;
+	
+    (void)(argc);
+    (void)(argv);
+
+    /* Initialize the enclave */
+    if(initialize_enclave() < 0){
+        printf("Enter a character before exit ...\n");
+        getchar();
+        return -1; 
+    }
+ 	
+    const char* str = "This is c str passed into enclave!";
+    size_t len = strlen(str);
+
+    sgx_ret = say_something(global_eid, 
+	                        &enclave_ret, 
+							(const uint8_t *) str, 
+							len);
+
+    if(sgx_ret != SGX_SUCCESS) {
+        print_error_message(sgx_ret);
+        return -1;
+    }
+
+    if(enclave_ret != SGX_SUCCESS) {
+        print_error_message(enclave_ret);
+        return -1;
+    }
+
+    printf("[+] say_something success ...\n");
+
+    /* Destroy the enclave */
+    sgx_destroy_enclave(global_eid);
+    
+    return 0;
+}
+
+void ocall_print_string(const char *str, size_t len)
+{
+    char * string = (char *)malloc(len + (size_t)sizeof(char));
+    if (string == NULL) {
+    	printf("malloc failed\n");
+    	return;
+    }
+    
+    memcpy(string, str, len);
+    char * ptr = string + len;
+    * ptr = 0;
+    printf("%s\n", string);
+    free(string);
+}
diff --git a/samplecode/helloworld/app/app.h b/samplecode/helloworld/app/app.h
new file mode 100644
index 0000000..8ec36fb
--- /dev/null
+++ b/samplecode/helloworld/app/app.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 _APP_H_
+#define _APP_H_
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "sgx_error.h"       /* sgx_status_t */
+#include "sgx_eid.h"     /* sgx_enclave_id_t */
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define TOKEN_FILENAME   "enclave.token"
+#define ENCLAVE_FILENAME "enclave.signed.so"
+
+extern sgx_enclave_id_t global_eid;    /* global enclave id */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_APP_H_ */
diff --git a/samplecode/helloworld/bin/readme.txt b/samplecode/helloworld/bin/readme.txt
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/samplecode/helloworld/bin/readme.txt
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/samplecode/helloworld/enclave/Cargo.toml b/samplecode/helloworld/enclave/Cargo.toml
new file mode 100644
index 0000000..b339e06
--- /dev/null
+++ b/samplecode/helloworld/enclave/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "enclave"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[lib]
+name = "enclave"
+crate-type = ["staticlib"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_tstdc = { path = "../../../sgx_tstdc" }
\ No newline at end of file
diff --git a/samplecode/helloworld/enclave/Enclave.config.xml b/samplecode/helloworld/enclave/Enclave.config.xml
new file mode 100644
index 0000000..ee4c3f7
--- /dev/null
+++ b/samplecode/helloworld/enclave/Enclave.config.xml
@@ -0,0 +1,12 @@
+<!-- Please refer to User's Guide for the explanation of each field -->
+<EnclaveConfiguration>
+  <ProdID>0</ProdID>
+  <ISVSVN>0</ISVSVN>
+  <StackMaxSize>0x40000</StackMaxSize>
+  <HeapMaxSize>0x100000</HeapMaxSize>
+  <TCSNum>1</TCSNum>
+  <TCSPolicy>1</TCSPolicy>
+  <DisableDebug>0</DisableDebug>
+  <MiscSelect>0</MiscSelect>
+  <MiscMask>0xFFFFFFFF</MiscMask>
+</EnclaveConfiguration>
diff --git a/samplecode/helloworld/enclave/Enclave.edl b/samplecode/helloworld/enclave/Enclave.edl
new file mode 100644
index 0000000..45e1e59
--- /dev/null
+++ b/samplecode/helloworld/enclave/Enclave.edl
@@ -0,0 +1,14 @@
+enclave {
+	
+    trusted {
+        /* define ECALLs here. */
+		
+        public sgx_status_t say_something([in, size=len] const uint8_t* some_string, size_t len);
+    };
+    
+    untrusted {
+        void ocall_print_string([in, size=len] const char *str, size_t len);
+    };
+
+ 
+};
diff --git a/samplecode/helloworld/enclave/Enclave.lds b/samplecode/helloworld/enclave/Enclave.lds
new file mode 100644
index 0000000..eb09b70
--- /dev/null
+++ b/samplecode/helloworld/enclave/Enclave.lds
@@ -0,0 +1,9 @@
+libTestEnclave.so
+{
+    global:
+        g_global_data_sim;
+        g_global_data;
+        enclave_entry;
+    local:
+        *;
+};
diff --git a/samplecode/helloworld/enclave/Enclave_private.pem b/samplecode/helloworld/enclave/Enclave_private.pem
new file mode 100644
index 0000000..529d07b
--- /dev/null
+++ b/samplecode/helloworld/enclave/Enclave_private.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ
+AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ
+ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr
+nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b
+3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H
+ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD
+5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW
+KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC
+1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe
+K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z
+AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q
+ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6
+JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826
+5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02
+wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9
+osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm
+WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i
+Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9
+xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd
+vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD
+Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a
+cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC
+0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ
+gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo
+gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t
+k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz
+Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6
+O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5
+afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom
+e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G
+BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv
+fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN
+t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9
+yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp
+6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg
+WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH
+NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk=
+-----END RSA PRIVATE KEY-----
diff --git a/samplecode/helloworld/enclave/Makefile b/samplecode/helloworld/enclave/Makefile
new file mode 100644
index 0000000..ec1512d
--- /dev/null
+++ b/samplecode/helloworld/enclave/Makefile
@@ -0,0 +1,9 @@
+Rust_Enclave_Name := libenclave.a
+Rust_Enclave_Files := $(wildcard src/*.rs)
+
+.PHONY: all
+
+all: $(Rust_Enclave_Name)
+
+$(Rust_Enclave_Name): $(Rust_Enclave_Files)  
+	cargo build --release
diff --git a/samplecode/helloworld/enclave/src/lib.rs b/samplecode/helloworld/enclave/src/lib.rs
new file mode 100644
index 0000000..f30c6d2
--- /dev/null
+++ b/samplecode/helloworld/enclave/src/lib.rs
@@ -0,0 +1,82 @@
+#![crate_name = "enclave"]
+#![crate_type = "staticlib"]
+
+#![no_std]
+#![feature(collections)]
+
+#[macro_use]
+extern crate collections;
+
+extern crate sgx_types;
+
+use sgx_types::*;
+use collections::string::String;
+use collections::vec::Vec;
+
+/// The Ocall declared in Enclave.edl and implemented in app.c
+///
+/// # Parameters
+///
+/// **str**
+///
+/// A pointer to the string to be printed
+///
+/// **len**
+///
+/// An unsigned int indicates the length of str
+///
+/// # Return value
+///
+/// None
+extern "C" {
+    fn ocall_print_string(str: *const c_uchar, len: size_t);
+}
+
+/// A function simply invokes ocall print to print the incoming string
+///
+/// # Parameters
+///
+/// **some_string**
+///
+/// A pointer to the string to be printed
+///
+/// **len**
+///
+/// An unsigned int indicates the length of str
+///
+/// # Return value
+///
+/// Always returns SGX_SUCCESS
+#[no_mangle]
+pub extern "C" fn say_something(some_string: *const u8, some_len: u32) -> sgx_status_t {
+    unsafe {
+        ocall_print_string(some_string as *const c_uchar, some_len as size_t);
+    }
+
+    // A sample &'static string
+    let rust_raw_string = "This is a ";
+    // An array
+    let word:[u8;4] = [82, 117, 115, 116];
+    // An vector
+    let word_vec:Vec<u8> = vec![32, 115, 116, 114, 105, 110, 103, 33];
+
+    // Construct a string from &'static string
+    let mut hello_string = String::from(rust_raw_string);
+
+    // Iterate on word array
+    for c in word.iter() {
+        hello_string.push(*c as char);
+    }
+
+    // Rust style convertion
+    hello_string += String::from_utf8(word_vec).expect("Invalid UTF-8")
+                                               .as_str();
+
+    // Ocall to normal world for output
+    unsafe {
+        ocall_print_string(hello_string.as_ptr() as *const c_uchar,
+                           hello_string.len() as size_t);
+    }
+
+    sgx_status_t::SGX_SUCCESS
+}
diff --git a/samplecode/helloworld/lib/readme.txt b/samplecode/helloworld/lib/readme.txt
new file mode 100644
index 0000000..7951405
--- /dev/null
+++ b/samplecode/helloworld/lib/readme.txt
@@ -0,0 +1 @@
+lib
\ No newline at end of file
diff --git a/samplecode/localattestation/Makefile b/samplecode/localattestation/Makefile
new file mode 100644
index 0000000..a9a4276
--- /dev/null
+++ b/samplecode/localattestation/Makefile
@@ -0,0 +1,246 @@
+# Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * 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.
+#  * Neither the name of Baidu, Inc., nor the names of its
+#    contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+
+######## SGX SDK Settings ########
+
+SGX_SDK ?= /opt/intel/sgxsdk
+SGX_MODE ?= HW
+SGX_ARCH ?= x64
+
+ifeq ($(shell getconf LONG_BIT), 32)
+	SGX_ARCH := x86
+else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
+	SGX_ARCH := x86
+endif
+
+ifeq ($(SGX_ARCH), x86)
+	SGX_COMMON_CFLAGS := -m32
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
+else
+	SGX_COMMON_CFLAGS := -m64
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
+endif
+
+ifeq ($(SGX_DEBUG), 1)
+ifeq ($(SGX_PRERELEASE), 1)
+$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
+endif
+endif
+
+
+ifeq ($(SGX_DEBUG), 1)
+	SGX_COMMON_CFLAGS += -O0 -g
+else
+	SGX_COMMON_CFLAGS += -O2
+endif
+
+######## CUSTOM Settings ########
+
+CUSTOM_LIBRARY_PATH := ./lib
+CUSTOM_BIN_PATH := ./bin
+
+######## EDL Settings ########
+
+Enclave_EDL_Files := enclave1/Enclave1_t.c enclave1/Enclave1_t.h enclave2/Enclave2_t.c enclave2/Enclave2_t.h enclave3/Enclave3_t.c enclave3/Enclave3_t.h app/Enclave_u.c app/Enclave_u.h
+
+######## APP Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Urts_Library_Name := sgx_urts_sim
+else
+	Urts_Library_Name := sgx_urts
+endif
+
+App_Cpp_Files := $(wildcard ./app/*.cpp)
+App_Include_Paths := -I ./app -I./include -I$(SGX_SDK)/include -I./attestation -I./Include
+App_Cpp_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
+App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread 
+ifneq ($(SGX_MODE), HW)
+	App_Link_Flags += -lsgx_uae_service_sim
+else
+	App_Link_Flags += -lsgx_uae_service
+endif
+
+App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
+
+App_Name := bin/app
+
+######## Enclave Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Trts_Library_Name := sgx_trts_sim
+	Service_Library_Name := sgx_tservice_sim
+else
+	Trts_Library_Name := sgx_trts
+	Service_Library_Name := sgx_tservice
+endif
+Crypto_Library_Name := sgx_tcrypto
+KeyExchange_Library_Name := sgx_tkey_exchange
+
+RustEnclave_C_Files := $(wildcard ./enclave1/*.c ./enclave2/*.c ./enclave3/*.c ./attestation/*.c)
+RustEnclave_C_Objects := $(RustEnclave_C_Files:.c=.o)
+RustEnclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport -I$(SGX_SDK)/include/epid
+
+
+RustEnclave_Link_Libs := -L$(CUSTOM_LIBRARY_PATH) -lcompiler-rt-patch
+RustEnclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(RustEnclave_Include_Paths)
+RustEnclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
+	-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
+	-Wl,--start-group -lsgx_tstdc -lsgx_tstdcxx -l$(Crypto_Library_Name) -l$(KeyExchange_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \
+	-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
+	-Wl,-pie,-eenclave_entry -Wl,--export-dynamic  \
+	-Wl,--defsym,__ImageBase=0 \
+	-Wl,--gc-sections \
+	-Wl,--version-script=enclave1/Enclave1.lds
+
+
+RustEnclave1_Name := enclave1/enclave1.so
+RustEnclave2_Name := enclave2/enclave2.so
+RustEnclave3_Name := enclave3/enclave3.so
+
+Signed_RustEnclave1_Name := bin/enclave1.signed.so
+Signed_RustEnclave2_Name := bin/enclave2.signed.so
+Signed_RustEnclave3_Name := bin/enclave3.signed.so
+
+.PHONY: all
+all: $(Enclave_EDL_Files) $(App_Name) $(Signed_RustEnclave1_Name) $(Signed_RustEnclave2_Name) $(Signed_RustEnclave3_Name)
+
+######## EDL Objects ########
+
+$(Enclave_EDL_Files): $(SGX_EDGER8R) enclave1/Enclave1.edl enclave2/Enclave2.edl enclave3/Enclave3.edl 
+	$(SGX_EDGER8R) --use-prefix --trusted enclave1/Enclave1.edl --search-path $(SGX_SDK)/include --trusted-dir enclave1
+	$(SGX_EDGER8R) --use-prefix --untrusted enclave1/Enclave1.edl --search-path $(SGX_SDK)/include --untrusted-dir app
+
+	$(SGX_EDGER8R) --use-prefix --trusted enclave2/Enclave2.edl --search-path $(SGX_SDK)/include --trusted-dir enclave2
+	$(SGX_EDGER8R) --use-prefix --untrusted enclave2/Enclave2.edl --search-path $(SGX_SDK)/include --untrusted-dir app
+
+	$(SGX_EDGER8R) --use-prefix --trusted enclave3/Enclave3.edl --search-path $(SGX_SDK)/include --trusted-dir enclave3
+	$(SGX_EDGER8R) --use-prefix --untrusted enclave3/Enclave3.edl --search-path $(SGX_SDK)/include --untrusted-dir app
+
+	@echo "GEN  =>  $(Enclave_EDL_Files)"
+
+######## App Objects ########
+
+app/%.o: app/%.cpp
+	@$(CXX) $(App_Cpp_Flags) -c $< -o $@
+	@echo "CXX  <=  $<"
+
+app/Enclave1_u.o: app/Enclave1_u.c
+	@$(CC) $(App_Cpp_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+app/Enclave2_u.o: app/Enclave2_u.c
+	@$(CC) $(App_Cpp_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+app/Enclave3_u.o: app/Enclave3_u.c
+	@$(CC) $(App_Cpp_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+app/UntrustedEnclaveMessageExchange.o: app/UntrustedEnclaveMessageExchange.cpp
+	@$(CXX) $(App_Cpp_Flags) -c $< -o $@
+
+$(App_Name): app/Enclave1_u.o app/Enclave2_u.o app/Enclave3_u.o $(App_Cpp_Objects) app/UntrustedEnclaveMessageExchange.o
+	@$(CXX) $^ -o $@ $(App_Link_Flags)
+	@echo "LINK =>  $@"
+
+######## Enclave Objects ########
+
+##### Enclave 1 ###########
+
+enclave1/Enclave1_t.o: enclave1/Enclave1_t.c
+	@$(CC) $(RustEnclave_Compile_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+$(RustEnclave1_Name): enclave1 compiler-rt enclave1/Enclave1_t.o
+	cp ./enclave1/target/release/libenclave1.a ./lib
+	cp ../../compiler-rt/libcompiler-rt-patch.a ./lib
+	@$(CXX) enclave1/Enclave1_t.o -o $@ $(RustEnclave_Link_Libs) -lenclave1 $(RustEnclave_Link_Flags) 
+	@echo "LINK =>  $@"
+
+$(Signed_RustEnclave1_Name): $(RustEnclave1_Name)
+	@$(SGX_ENCLAVE_SIGNER) sign -key enclave1/Enclave1_private.pem -enclave $(RustEnclave1_Name) -out $@ -config enclave1/Enclave1.config.xml
+	@echo "SIGN =>  $@"
+
+
+##### Enclave 2 ###########
+
+enclave2/Enclave2_t.o: enclave2/Enclave2_t.c
+	@$(CC) $(RustEnclave_Compile_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+$(RustEnclave2_Name): enclave2 compiler-rt enclave2/Enclave2_t.o
+	cp ./enclave2/target/release/libenclave2.a ./lib
+	cp ../../compiler-rt/libcompiler-rt-patch.a ./lib
+	@$(CXX) enclave2/Enclave2_t.o -o $@ $(RustEnclave_Link_Libs) -lenclave2 $(RustEnclave_Link_Flags) 
+	@echo "LINK =>  $@"
+
+$(Signed_RustEnclave2_Name): $(RustEnclave2_Name)
+	@$(SGX_ENCLAVE_SIGNER) sign -key enclave2/Enclave2_private.pem -enclave $(RustEnclave2_Name) -out $@ -config enclave2/Enclave2.config.xml
+	@echo "SIGN =>  $@"
+
+##### Enclave 3 ###########
+
+enclave3/Enclave3_t.o: enclave3/Enclave3_t.c
+	@$(CC) $(RustEnclave_Compile_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+$(RustEnclave3_Name): enclave3 compiler-rt enclave3/Enclave3_t.o
+	cp ./enclave3/target/release/libenclave3.a ./lib
+	cp ../../compiler-rt/libcompiler-rt-patch.a ./lib
+	@$(CXX) enclave3/Enclave3_t.o -o $@ $(RustEnclave_Link_Libs) -lenclave3 $(RustEnclave_Link_Flags) 
+	@echo "LINK =>  $@"
+
+$(Signed_RustEnclave3_Name): $(RustEnclave3_Name)
+	@$(SGX_ENCLAVE_SIGNER) sign -key enclave3/Enclave3_private.pem -enclave $(RustEnclave3_Name) -out $@ -config enclave3/Enclave3.config.xml
+	@echo "SIGN =>  $@"
+
+.PHONY: enclave1
+enclave1:
+	$(MAKE) -C ./enclave1/
+	
+.PHONY: enclave2
+enclave2:
+	$(MAKE) -C ./enclave2/
+	
+.PHONY: enclave3
+enclave3:
+	$(MAKE) -C ./enclave3/
+	
+.PHONY: compiler-rt
+compiler-rt:
+	$(MAKE) -C ../../compiler-rt/ 2> /dev/null
+	
+.PHONY: clean
+clean:
+	@rm -f $(App_Name) $(RustEnclave1_Name) $(Signed_RustEnclave1_Name) $(RustEnclave2_Name) $(Signed_RustEnclave2_Name) $(RustEnclave3_Name) $(Signed_RustEnclave3_Name) $(RustEnclave_C_Objects) $(App_Cpp_Objects) enclave1/*_t.* enclave2/*_t.* enclave3/*_t.* app/*_u.* lib/*.a
+	
diff --git a/samplecode/localattestation/app/App.cpp b/samplecode/localattestation/app/App.cpp
new file mode 100644
index 0000000..c147436
--- /dev/null
+++ b/samplecode/localattestation/app/App.cpp
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2011-2016 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *
+ */
+
+
+// App.cpp : Defines the entry point for the console application.
+#include <stdio.h>
+#include <map>
+#include "Enclave1_u.h"
+#include "Enclave2_u.h"
+#include "Enclave3_u.h"
+#include "sgx_eid.h"
+#include "sgx_urts.h"
+
+#define UNUSED(val) (void)(val)
+#define TCHAR   char
+#define _TCHAR  char
+#define _T(str) str
+#define scanf_s scanf
+#define _tmain  main
+
+extern std::map<sgx_enclave_id_t, uint32_t>g_enclave_id_map;
+
+
+sgx_enclave_id_t e1_enclave_id = 0;
+sgx_enclave_id_t e2_enclave_id = 0;
+sgx_enclave_id_t e3_enclave_id = 0;
+
+#define ENCLAVE1_PATH "enclave1.signed.so"
+#define ENCLAVE2_PATH "enclave2.signed.so"
+#define ENCLAVE3_PATH "enclave3.signed.so"
+
+void waitForKeyPress()
+{
+    printf("\n\nHit a key....\n");
+    getchar();
+}
+
+void ocall_print_string(const char *str, size_t len)
+{
+    char * string = (char *)malloc(len + (size_t)sizeof(char));
+    if (string == NULL) {
+    	printf("malloc failed\n");
+    	return;
+    }
+    
+    memcpy(string, str, len);
+    char * ptr = string + len;
+    * ptr = 0;
+    printf("%s\n", string);
+    free(string);
+}
+
+uint32_t load_enclaves()
+{
+    uint32_t enclave_temp_no;
+    int ret, launch_token_updated;
+    sgx_launch_token_t launch_token;
+
+    enclave_temp_no = 0;
+
+    ret = sgx_create_enclave(ENCLAVE1_PATH, SGX_DEBUG_FLAG, &launch_token, &launch_token_updated, &e1_enclave_id, NULL);
+    if (ret != SGX_SUCCESS) {
+                return ret;
+    }
+
+    enclave_temp_no++;
+    g_enclave_id_map.insert(std::pair<sgx_enclave_id_t, uint32_t>(e1_enclave_id, enclave_temp_no));
+
+    ret = sgx_create_enclave(ENCLAVE2_PATH, SGX_DEBUG_FLAG, &launch_token, &launch_token_updated, &e2_enclave_id, NULL);
+    if (ret != SGX_SUCCESS) {
+                return ret;
+    }
+
+    enclave_temp_no++;
+    g_enclave_id_map.insert(std::pair<sgx_enclave_id_t, uint32_t>(e2_enclave_id, enclave_temp_no));
+
+    ret = sgx_create_enclave(ENCLAVE3_PATH, SGX_DEBUG_FLAG, &launch_token, &launch_token_updated, &e3_enclave_id, NULL);
+    if (ret != SGX_SUCCESS) {
+                return ret;
+    }
+
+    enclave_temp_no++;
+    g_enclave_id_map.insert(std::pair<sgx_enclave_id_t, uint32_t>(e3_enclave_id, enclave_temp_no));
+
+
+
+    return SGX_SUCCESS;
+}
+
+int _tmain(int argc, _TCHAR* argv[])
+{
+    uint32_t ret_status;
+    sgx_status_t status;
+
+    UNUSED(argc);
+    UNUSED(argv);
+
+    if(load_enclaves() != SGX_SUCCESS)
+    {
+        printf("\nLoad Enclave Failure");
+    }
+    
+    do
+    {
+        Enclave1_test_enclave_init(e1_enclave_id);
+        Enclave2_test_enclave_init(e2_enclave_id);
+        Enclave3_test_enclave_init(e3_enclave_id);
+
+        //Test Create session between Enclave1(Source) and Enclave2(Destination)
+        status = Enclave1_test_create_session(e1_enclave_id, &ret_status, e1_enclave_id, e2_enclave_id);
+        if (status!=SGX_SUCCESS)
+        {
+            printf("Enclave1_test_create_session Ecall failed: Error code is %x", status);
+            break;
+        }
+        else
+        {
+            if(ret_status==0)
+            {
+                printf("\n\nSecure Channel Establishment between Source (E1) and Destination (E2) Enclaves successful !!!");
+            }
+            else
+            {
+                printf("\nSession establishment and key exchange failure between Source (E1) and Destination (E2): Error code is %x", ret_status);
+                break;
+            }
+        }
+
+        //Test Create session between Enclave1(Source) and Enclave3(Destination)
+        status = Enclave1_test_create_session(e1_enclave_id, &ret_status, e1_enclave_id, e3_enclave_id);
+        if (status!=SGX_SUCCESS)
+        {
+            printf("Enclave1_test_create_session Ecall failed: Error code is %x", status);
+            break;
+        }
+        else
+        {
+            if(ret_status==0)
+            {
+                printf("\n\nSecure Channel Establishment between Source (E1) and Destination (E3) Enclaves successful !!!");
+            }
+            else
+            {
+                printf("\n\nSession establishment and key exchange failure between Source (E1) and Destination (E3): Error code is %x", ret_status);
+                break;
+            }
+        }
+
+        //Test Create session between Enclave2(Source) and Enclave3(Destination)
+        status = Enclave2_test_create_session(e2_enclave_id, &ret_status, e2_enclave_id, e3_enclave_id);
+        if (status!=SGX_SUCCESS)
+        {
+            printf("Enclave2_test_create_session Ecall failed: Error code is %x", status);
+            break;
+        }
+        else
+        {
+            if(ret_status==0)
+            {
+                printf("\n\nSecure Channel Establishment between Source (E2) and Destination (E3) Enclaves successful !!!");
+            }
+            else
+            {
+                printf("\n\nSession establishment and key exchange failure between Source (E2) and Destination (E3): Error code is %x", ret_status);
+                break;
+            }
+        }
+
+        //Test Create session between Enclave3(Source) and Enclave1(Destination)
+        status = Enclave3_test_create_session(e3_enclave_id, &ret_status, e3_enclave_id, e1_enclave_id);
+        if (status!=SGX_SUCCESS)
+        {
+            printf("Enclave3_test_create_session Ecall failed: Error code is %x", status);
+            break;
+        }
+        else
+        {
+            if(ret_status==0)
+            {
+                printf("\n\nSecure Channel Establishment between Source (E3) and Destination (E1) Enclaves successful !!!");
+            }
+            else
+            {
+                printf("\n\nSession establishment and key exchange failure between Source (E3) and Destination (E1): Error code is %x", ret_status);
+                break;
+            }
+        }
+
+        //Test Closing Session between Enclave1(Source) and Enclave2(Destination)
+        status = Enclave1_test_close_session(e1_enclave_id, &ret_status, e1_enclave_id, e2_enclave_id);
+        if (status!=SGX_SUCCESS)
+        {
+            printf("Enclave1_test_close_session Ecall failed: Error code is %x", status);
+            break;
+        }
+        else
+        {
+            if(ret_status==0)
+            {
+                printf("\n\nClose Session between Source (E1) and Destination (E2) Enclaves successful !!!");
+            }
+            else
+            {
+                printf("\n\nClose session failure between Source (E1) and Destination (E2): Error code is %x", ret_status);
+                break;
+            }
+        }
+        //Test Closing Session between Enclave1(Source) and Enclave3(Destination)
+        status = Enclave1_test_close_session(e1_enclave_id, &ret_status, e1_enclave_id, e3_enclave_id);
+        if (status!=SGX_SUCCESS)
+        {
+            printf("Enclave1_test_close_session Ecall failed: Error code is %x", status);
+            break;
+        }
+        else
+        {
+            if(ret_status==0)
+            {
+                printf("\n\nClose Session between Source (E1) and Destination (E3) Enclaves successful !!!");
+            }
+            else
+            {
+                printf("\n\nClose session failure between Source (E1) and Destination (E3): Error code is %x", ret_status);
+                break;
+            }
+        }
+        //Test Closing Session between Enclave2(Source) and Enclave3(Destination)
+        status = Enclave2_test_close_session(e2_enclave_id, &ret_status, e2_enclave_id, e3_enclave_id);
+        if (status!=SGX_SUCCESS)
+        {
+            printf("Enclave2_test_close_session Ecall failed: Error code is %x", status);
+            break;
+        }
+        else
+        {
+            if(ret_status==0)
+            {
+                printf("\n\nClose Session between Source (E2) and Destination (E3) Enclaves successful !!!");
+            }
+            else
+            {
+                printf("\n\nClose session failure between Source (E2) and Destination (E3): Error code is %x", ret_status);
+                break;
+            }
+        }
+        //Test Closing Session between Enclave3(Source) and Enclave1(Destination)
+        status = Enclave3_test_close_session(e3_enclave_id, &ret_status, e3_enclave_id, e1_enclave_id);
+        if (status!=SGX_SUCCESS)
+        {
+            printf("Enclave3_test_close_session Ecall failed: Error code is %x", status);
+            break;
+        }
+        else
+        {
+            if(ret_status==0)
+            {
+                printf("\n\nClose Session between Source (E3) and Destination (E1) Enclaves successful !!!");
+            }
+            else
+            {
+                printf("\n\nClose session failure between Source (E3) and Destination (E1): Error code is %x", ret_status);
+                break;
+            }
+        }
+
+#pragma warning (push)
+#pragma warning (disable : 4127)    
+    }while(0);
+#pragma warning (pop)
+
+    sgx_destroy_enclave(e1_enclave_id);
+    sgx_destroy_enclave(e2_enclave_id);
+    sgx_destroy_enclave(e3_enclave_id);
+
+    waitForKeyPress();
+
+    return 0;
+}
diff --git a/samplecode/localattestation/app/UntrustedEnclaveMessageExchange.cpp b/samplecode/localattestation/app/UntrustedEnclaveMessageExchange.cpp
new file mode 100644
index 0000000..b703b3f
--- /dev/null
+++ b/samplecode/localattestation/app/UntrustedEnclaveMessageExchange.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2011-2016 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 <stdio.h>
+#include "sgx_eid.h"
+#include "error_codes.h"
+#include "sgx_urts.h"
+#include "UntrustedEnclaveMessageExchange.h"
+#include "sgx_dh.h"
+#include <map>
+
+std::map<sgx_enclave_id_t, uint32_t>g_enclave_id_map;
+std::map<sgx_enclave_id_t, std::map<sgx_enclave_id_t, size_t> >g_session_ptr_map;
+
+//Makes an sgx_ecall to the destination enclave to get session id and message1
+ATTESTATION_STATUS session_request_ocall(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id, sgx_dh_msg1_t* dh_msg1)
+{
+	uint32_t status = 0;
+	sgx_status_t ret = SGX_SUCCESS;
+	uint32_t temp_enclave_no;
+	size_t session_ptr = 0;
+
+	std::map<sgx_enclave_id_t, uint32_t>::iterator it = g_enclave_id_map.find(dest_enclave_id);
+    if(it != g_enclave_id_map.end())
+	{
+		temp_enclave_no = it->second;
+	}
+    else
+	{
+		return INVALID_SESSION;
+	}
+
+	switch(temp_enclave_no)
+	{
+		case 1:
+			ret = Enclave1_session_request(dest_enclave_id, &status, src_enclave_id, dh_msg1, &session_ptr);
+			break;
+		case 2:
+			ret = Enclave2_session_request(dest_enclave_id, &status, src_enclave_id, dh_msg1, &session_ptr);
+			break;
+		case 3:
+			ret = Enclave3_session_request(dest_enclave_id, &status, src_enclave_id, dh_msg1, &session_ptr);
+			break;
+	}
+	if (ret == SGX_SUCCESS) 
+	{
+		std::map<sgx_enclave_id_t, std::map<sgx_enclave_id_t, size_t> >::iterator it_ptr = g_session_ptr_map.find(dest_enclave_id);
+		if(it_ptr != g_session_ptr_map.end())
+		{
+			it_ptr->second.insert(std::pair<sgx_enclave_id_t, size_t>(src_enclave_id, session_ptr));
+		}
+		else
+		{
+			std::map<sgx_enclave_id_t, size_t> sub_map;
+			sub_map.insert(std::pair<sgx_enclave_id_t, size_t>(src_enclave_id, session_ptr));
+			g_session_ptr_map.insert(std::pair<sgx_enclave_id_t, std::map<sgx_enclave_id_t, size_t> >(dest_enclave_id, sub_map));
+		}
+
+		return (ATTESTATION_STATUS)status;
+	}
+	else	
+	    return INVALID_SESSION;
+
+}
+//Makes an sgx_ecall to the destination enclave sends message2 from the source enclave and gets message 3 from the destination enclave
+ATTESTATION_STATUS exchange_report_ocall(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id, sgx_dh_msg2_t *dh_msg2, sgx_dh_msg3_t *dh_msg3)
+{
+	uint32_t status = 0;
+	sgx_status_t ret = SGX_SUCCESS;
+	uint32_t temp_enclave_no;
+	size_t session_ptr = 0;
+
+	std::map<sgx_enclave_id_t, uint32_t>::iterator it = g_enclave_id_map.find(dest_enclave_id);
+    if(it != g_enclave_id_map.end())
+	{
+		temp_enclave_no = it->second;
+	}
+    else
+	{
+		return INVALID_SESSION;
+	}
+
+	std::map<sgx_enclave_id_t, std::map<sgx_enclave_id_t, size_t> >::iterator it_ptr = g_session_ptr_map.find(dest_enclave_id);
+    if(it_ptr != g_session_ptr_map.end())
+	{
+		std::map<sgx_enclave_id_t, size_t>::iterator it_ptr_sub = it_ptr->second.find(src_enclave_id);
+		if(it_ptr_sub != it_ptr->second.end())
+		{
+			session_ptr = it_ptr_sub->second;
+		}
+	}
+    else
+	{
+		return INVALID_SESSION;
+	}
+
+	switch(temp_enclave_no)
+	{
+		case 1:
+			ret = Enclave1_exchange_report(dest_enclave_id, &status, src_enclave_id, dh_msg2, dh_msg3, (size_t*)session_ptr);
+			break;
+		case 2:
+			ret = Enclave2_exchange_report(dest_enclave_id, &status, src_enclave_id, dh_msg2, dh_msg3, (size_t*)session_ptr);
+			break;
+		case 3:
+			ret = Enclave3_exchange_report(dest_enclave_id, &status, src_enclave_id, dh_msg2, dh_msg3, (size_t*)session_ptr);
+			break;
+	}
+	if (ret == SGX_SUCCESS)
+		return (ATTESTATION_STATUS)status;
+	else	
+	    return INVALID_SESSION;
+
+}
+
+//Make an sgx_ecall to the destination enclave to close the session
+ATTESTATION_STATUS end_session_ocall(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id)
+{
+	uint32_t status = 0;
+	sgx_status_t ret = SGX_SUCCESS;
+	uint32_t temp_enclave_no;
+	size_t session_ptr = 0;
+
+	std::map<sgx_enclave_id_t, uint32_t>::iterator it = g_enclave_id_map.find(dest_enclave_id);
+    if(it != g_enclave_id_map.end())
+	{
+		temp_enclave_no = it->second;
+	}
+    else
+	{
+		return INVALID_SESSION;
+	}
+
+	std::map<sgx_enclave_id_t, std::map<sgx_enclave_id_t, size_t> >::iterator it_ptr = g_session_ptr_map.find(dest_enclave_id);
+    if(it_ptr != g_session_ptr_map.end())
+	{
+		std::map<sgx_enclave_id_t, size_t>::iterator it_ptr_sub = it_ptr->second.find(src_enclave_id);
+		if(it_ptr_sub != it_ptr->second.end())
+		{
+			session_ptr = it_ptr_sub->second;
+		}
+	}
+    else
+	{
+		return INVALID_SESSION;
+	}
+
+	switch(temp_enclave_no)
+	{
+		case 1:
+			ret = Enclave1_end_session(dest_enclave_id, &status, src_enclave_id, (size_t*)session_ptr);
+			break;
+		case 2:
+			ret = Enclave2_end_session(dest_enclave_id, &status, src_enclave_id, (size_t*)session_ptr);
+			break;
+		case 3:
+			ret = Enclave3_end_session(dest_enclave_id, &status, src_enclave_id, (size_t*)session_ptr);
+			break;
+	}
+	if (ret == SGX_SUCCESS) 
+		return (ATTESTATION_STATUS)status;
+	else	
+	    return INVALID_SESSION;
+
+}
diff --git a/samplecode/localattestation/app/UntrustedEnclaveMessageExchange.h b/samplecode/localattestation/app/UntrustedEnclaveMessageExchange.h
new file mode 100644
index 0000000..b58e7f2
--- /dev/null
+++ b/samplecode/localattestation/app/UntrustedEnclaveMessageExchange.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011-2016 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 "sgx_eid.h"
+#include "error_codes.h"
+#include "sgx_urts.h"
+#include "sgx_dh.h"
+#include <cstddef>
+
+
+#ifndef ULOCALATTESTATION_H_
+#define ULOCALATTESTATION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+sgx_status_t Enclave1_session_request(sgx_enclave_id_t eid, uint32_t* retval, sgx_enclave_id_t src_enclave_id, sgx_dh_msg1_t* dh_msg1, size_t* session_ptr);
+sgx_status_t Enclave1_exchange_report(sgx_enclave_id_t eid, uint32_t* retval, sgx_enclave_id_t src_enclave_id, sgx_dh_msg2_t* dh_msg2, sgx_dh_msg3_t* dh_msg3, size_t* session_ptr);
+sgx_status_t Enclave1_end_session(sgx_enclave_id_t eid, uint32_t* retval, sgx_enclave_id_t src_enclave_id, size_t* session_ptr);
+
+sgx_status_t Enclave2_session_request(sgx_enclave_id_t eid, uint32_t* retval, sgx_enclave_id_t src_enclave_id, sgx_dh_msg1_t* dh_msg1, size_t* session_ptr);
+sgx_status_t Enclave2_exchange_report(sgx_enclave_id_t eid, uint32_t* retval, sgx_enclave_id_t src_enclave_id, sgx_dh_msg2_t* dh_msg2, sgx_dh_msg3_t* dh_msg3, size_t* session_ptr);
+sgx_status_t Enclave2_end_session(sgx_enclave_id_t eid, uint32_t* retval, sgx_enclave_id_t src_enclave_id, size_t* session_ptr);
+
+sgx_status_t Enclave3_session_request(sgx_enclave_id_t eid, uint32_t* retval, sgx_enclave_id_t src_enclave_id, sgx_dh_msg1_t* dh_msg1, size_t* session_ptr);
+sgx_status_t Enclave3_exchange_report(sgx_enclave_id_t eid, uint32_t* retval, sgx_enclave_id_t src_enclave_id, sgx_dh_msg2_t* dh_msg2, sgx_dh_msg3_t* dh_msg3, size_t* session_ptr);
+sgx_status_t Enclave3_end_session(sgx_enclave_id_t eid, uint32_t* retval, sgx_enclave_id_t src_enclave_id, size_t* session_ptr);
+
+uint32_t session_request_ocall(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id, sgx_dh_msg1_t* dh_msg1);
+uint32_t exchange_report_ocall(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id, sgx_dh_msg2_t* dh_msg2, sgx_dh_msg3_t* dh_msg3);
+uint32_t end_session_ocall(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/samplecode/localattestation/app/error_codes.h b/samplecode/localattestation/app/error_codes.h
new file mode 100644
index 0000000..746bc09
--- /dev/null
+++ b/samplecode/localattestation/app/error_codes.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011-2016 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 ERROR_CODES_H_
+#define ERROR_CODES_H_
+
+typedef uint32_t ATTESTATION_STATUS;
+
+#define SUCCESS                          0x00
+#define INVALID_PARAMETER                0xE1
+#define VALID_SESSION                    0xE2
+#define INVALID_SESSION                  0xE3
+#define ATTESTATION_ERROR                0xE4
+#define ATTESTATION_SE_ERROR             0xE5
+#define IPP_ERROR                        0xE6
+#define NO_AVAILABLE_SESSION_ERROR       0xE7
+#define MALLOC_ERROR                     0xE8
+#define ERROR_TAG_MISMATCH               0xE9
+#define OUT_BUFFER_LENGTH_ERROR          0xEA
+#define INVALID_REQUEST_TYPE_ERROR       0xEB
+#define INVALID_PARAMETER_ERROR          0xEC
+#define ENCLAVE_TRUST_ERROR              0xED
+#define ENCRYPT_DECRYPT_ERROR            0xEE
+#define DUPLICATE_SESSION                0xEF
+#endif
diff --git a/samplecode/localattestation/attestation/Cargo.toml b/samplecode/localattestation/attestation/Cargo.toml
new file mode 100644
index 0000000..836ed53
--- /dev/null
+++ b/samplecode/localattestation/attestation/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "attestation"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_tstdc = { path = "../../../sgx_tstdc" }
+sgx_tdh = { path = "../../../sgx_tdh" }
+sgx_trts = { path = "../../../sgx_trts" }
diff --git a/samplecode/localattestation/attestation/attestation.edl b/samplecode/localattestation/attestation/attestation.edl
new file mode 100644
index 0000000..f5f0cda
--- /dev/null
+++ b/samplecode/localattestation/attestation/attestation.edl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *
+ */
+ 
+enclave  {
+    include "sgx_eid.h"
+    include "sgx_dh.h"
+    trusted{
+        public uint32_t session_request(sgx_enclave_id_t src_enclave_id, [out] sgx_dh_msg1_t *dh_msg1, [out] size_t* session_ptr);
+        public uint32_t exchange_report(sgx_enclave_id_t src_enclave_id, [in] sgx_dh_msg2_t *dh_msg2, [out] sgx_dh_msg3_t *dh_msg3, [user_check]size_t* session_ptr);
+        public uint32_t end_session(sgx_enclave_id_t src_enclave_id, [user_check]size_t* session_ptr);        
+    };
+
+    untrusted{
+        uint32_t session_request_ocall(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id, [out] sgx_dh_msg1_t *dh_msg1,[out] uint32_t *session_id);
+        uint32_t exchange_report_ocall(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id, [in] sgx_dh_msg2_t *dh_msg2, [out] sgx_dh_msg3_t *dh_msg3, uint32_t session_id);
+        uint32_t end_session_ocall(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id);
+        void ocall_print_string([in, size=len] const char *str, size_t len);
+    };
+};
diff --git a/samplecode/localattestation/attestation/src/err.rs b/samplecode/localattestation/attestation/src/err.rs
new file mode 100644
index 0000000..ffc00f2
--- /dev/null
+++ b/samplecode/localattestation/attestation/src/err.rs
@@ -0,0 +1,51 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+impl_enum! {
+    #[repr(u32)]
+    #[derive(Copy, Clone, PartialEq, Eq)]
+    pub enum ATTESTATION_STATUS {
+        SUCCESS                 = 0x00,
+        INVALID_PARAMETER       = 0xE1,
+        VALID_SESSION           = 0xE2,
+        INVALID_SESSION         = 0xE3,
+        ATTESTATION_ERROR       = 0xE4,
+        ATTESTATION_SE_ERROR    = 0xE5,
+        IPP_ERROR               = 0xE6,
+        NO_AVAILABLE_SESSION_ERROR = 0xE7,
+        MALLOC_ERROR            = 0xE8,
+        ERROR_TAG_MISMATCH      =  0xE9,
+        OUT_BUFFER_LENGTH_ERROR = 0xEA,
+        INVALID_REQUEST_TYPE_ERROR = 0xEB,
+        INVALID_PARAMETER_ERROR = 0xEC,
+        ENCLAVE_TRUST_ERROR     = 0xED,
+        ENCRYPT_DECRYPT_ERROR   = 0xEE,
+        DUPLICATE_SESSION       = 0xEF,
+        UNKNOWN_ERROR           = 0xF0,
+    }
+}
\ No newline at end of file
diff --git a/samplecode/localattestation/attestation/src/func.rs b/samplecode/localattestation/attestation/src/func.rs
new file mode 100644
index 0000000..1edc498
--- /dev/null
+++ b/samplecode/localattestation/attestation/src/func.rs
@@ -0,0 +1,223 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+use alloc::boxed::Box;
+
+use core::mem;
+use core::sync::atomic::{AtomicPtr, Ordering};
+
+use sgx_types::*;
+use sgx_tdh::*;
+
+use types::*;
+use err::*;
+
+extern {
+    pub fn session_request_ocall(ret: *mut u32, 
+                                 src_enclave_id: sgx_enclave_id_t, 
+                                 dest_enclave_id: sgx_enclave_id_t, 
+                                 dh_msg1: *mut sgx_dh_msg1_t) -> sgx_status_t;
+
+    pub fn exchange_report_ocall(ret: *mut u32, 
+                                 src_enclave_id: sgx_enclave_id_t, 
+                                 dest_enclave_id: sgx_enclave_id_t, 
+                                 dh_msg2: *mut sgx_dh_msg2_t, 
+                                 dh_msg3: *mut sgx_dh_msg3_t) -> sgx_status_t;
+
+    pub fn end_session_ocall(ret: *mut u32, 
+                             src_enclave_id:sgx_enclave_id_t, 
+                             dest_enclave_id:sgx_enclave_id_t) -> sgx_status_t;
+
+    pub fn ocall_print_string(str: *const c_uchar, len: size_t);
+}
+
+static CALLBACK_FN: AtomicPtr<()> = AtomicPtr::new(0 as * mut ());
+
+pub fn init(cb: Callback) {
+    let ptr = CALLBACK_FN.load(Ordering::SeqCst);
+    if ptr.is_null() {
+        let ptr: * mut Callback = Box::into_raw(Box::new(cb));
+        CALLBACK_FN.store(ptr as * mut (), Ordering::SeqCst);
+    }
+}
+
+fn get_callback() -> Option<&'static Callback>{
+    let ptr = CALLBACK_FN.load(Ordering::SeqCst) as *mut Callback;
+    if ptr.is_null() {
+         return None;
+    }
+    unsafe { Some( &* ptr ) }
+}
+
+pub fn create_session(src_enclave_id: sgx_enclave_id_t, dest_enclave_id: sgx_enclave_id_t) -> ATTESTATION_STATUS {
+
+    let mut dh_msg1: SgxDhMsg1 = SgxDhMsg1::default(); //Diffie-Hellman Message 1
+    let mut dh_msg2: SgxDhMsg2 = SgxDhMsg2::default(); //Diffie-Hellman Message 2
+    let mut dh_aek: sgx_key_128bit_t = sgx_key_128bit_t::default(); // Session Key
+    let mut responder_identity: sgx_dh_session_enclave_identity_t = sgx_dh_session_enclave_identity_t::default();
+    let mut ret = 0;
+
+    let mut initiator: SgxDhInitiator = SgxDhInitiator::init_session();
+    
+    let status = unsafe { session_request_ocall(&mut ret, src_enclave_id, dest_enclave_id, &mut dh_msg1) };
+    if status != sgx_status_t::SGX_SUCCESS {
+        return ATTESTATION_STATUS::ATTESTATION_SE_ERROR;
+    }
+    let err = ATTESTATION_STATUS::from_repr(ret).unwrap();
+    if err != ATTESTATION_STATUS::SUCCESS{
+        return err;
+    }
+
+    let status = initiator.proc_msg1(&dh_msg1, &mut dh_msg2);
+    if status.is_err() {
+        return ATTESTATION_STATUS::ATTESTATION_ERROR;
+    }
+
+    let mut dh_msg3_raw = sgx_dh_msg3_t::default();
+    let status = unsafe { exchange_report_ocall(&mut ret, src_enclave_id, dest_enclave_id, &mut dh_msg2, &mut dh_msg3_raw as *mut sgx_dh_msg3_t) };
+    if status != sgx_status_t::SGX_SUCCESS {
+        return ATTESTATION_STATUS::ATTESTATION_SE_ERROR;
+    }
+    if ret != ATTESTATION_STATUS::SUCCESS as u32 {
+        return ATTESTATION_STATUS::from_repr(ret).unwrap();
+    }
+
+    let dh_msg3_raw_len = mem::size_of::<sgx_dh_msg3_t>() as u32 + dh_msg3_raw.msg3_body.additional_prop_length;
+    let dh_msg3 = unsafe{ SgxDhMsg3::from_raw_dh_msg3_t(&mut dh_msg3_raw, dh_msg3_raw_len ) };
+    if dh_msg3.is_none() {
+        return ATTESTATION_STATUS::ATTESTATION_SE_ERROR;
+    }
+    let dh_msg3 = dh_msg3.unwrap();
+
+    let status = initiator.proc_msg3(&dh_msg3, &mut dh_aek, &mut responder_identity);
+    if status.is_err() {
+        return ATTESTATION_STATUS::ATTESTATION_ERROR;
+    }
+
+    let cb = get_callback();
+    if cb.is_some() {
+        let ret = (cb.unwrap().verify)(&responder_identity);
+        if ret != ATTESTATION_STATUS::SUCCESS as u32{
+            return ATTESTATION_STATUS::INVALID_SESSION;
+        }
+    }
+
+    ATTESTATION_STATUS::SUCCESS
+}
+
+pub fn close_session(src_enclave_id: sgx_enclave_id_t, dest_enclave_id: sgx_enclave_id_t) -> ATTESTATION_STATUS {
+    let mut ret = 0;
+    let status = unsafe { end_session_ocall(&mut ret, src_enclave_id, dest_enclave_id) };
+    if status != sgx_status_t::SGX_SUCCESS {
+        return ATTESTATION_STATUS::ATTESTATION_SE_ERROR;
+    }
+    ATTESTATION_STATUS::from_repr(ret as u32).unwrap()
+}
+
+fn session_request_safe(src_enclave_id: sgx_enclave_id_t, dh_msg1: &mut sgx_dh_msg1_t, session_ptr: &mut usize) -> ATTESTATION_STATUS {
+    
+    let mut responder = SgxDhResponder::init_session();
+
+    let status = responder.gen_msg1(dh_msg1);
+    if status.is_err() {
+        return ATTESTATION_STATUS::INVALID_SESSION;
+    }
+
+    let mut session_info = DhSessionInfo::default();
+    session_info.enclave_id = src_enclave_id;
+    session_info.session.session_status = DhSessionStatus::InProgress(responder);
+
+    let ptr = Box::into_raw(Box::new(session_info));
+    *session_ptr = ptr as * mut _ as usize;
+
+    ATTESTATION_STATUS::SUCCESS
+}
+
+//Handle the request from Source Enclave for a session
+#[no_mangle]
+pub extern "C" fn session_request(src_enclave_id: sgx_enclave_id_t, dh_msg1: *mut sgx_dh_msg1_t, session_ptr: *mut usize) -> ATTESTATION_STATUS {
+    unsafe {
+        session_request_safe(src_enclave_id, &mut *dh_msg1, &mut *session_ptr)
+    }    
+}
+
+#[allow(unused_variables)]
+fn exchange_report_safe(src_enclave_id: sgx_enclave_id_t, dh_msg2: &mut sgx_dh_msg2_t , dh_msg3: &mut sgx_dh_msg3_t, session_info: &mut DhSessionInfo) -> ATTESTATION_STATUS {
+
+    let mut dh_aek = sgx_key_128bit_t::default() ;   // Session key
+    let mut initiator_identity = sgx_dh_session_enclave_identity_t::default();
+
+    let mut responder = match session_info.session.session_status {
+        DhSessionStatus::InProgress(res) => {res},
+        _ => {
+            return ATTESTATION_STATUS::INVALID_SESSION;
+        }
+    };
+
+    let mut dh_msg3_r = SgxDhMsg3::default();
+    let status = responder.proc_msg2(dh_msg2, &mut dh_msg3_r, &mut dh_aek, &mut initiator_identity);
+    if status.is_err() {
+        return ATTESTATION_STATUS::ATTESTATION_ERROR;
+    }
+
+    unsafe{ dh_msg3_r.to_raw_dh_msg3_t(dh_msg3, (dh_msg3.msg3_body.additional_prop_length as usize + mem::size_of::<sgx_dh_msg3_t>() ) as u32); };
+
+    let cb = get_callback();
+    if cb.is_some() {
+        let ret = (cb.unwrap().verify)(&initiator_identity);
+        if ret != ATTESTATION_STATUS::SUCCESS as u32 {
+            return ATTESTATION_STATUS::INVALID_SESSION;
+        }
+    }
+
+    session_info.session.session_status = DhSessionStatus::Active(dh_aek);
+
+    ATTESTATION_STATUS::SUCCESS
+}
+//Verify Message 2, generate Message3 and exchange Message 3 with Source Enclave
+#[no_mangle]
+pub extern "C" fn exchange_report(src_enclave_id: sgx_enclave_id_t, dh_msg2: *mut sgx_dh_msg2_t , dh_msg3: *mut sgx_dh_msg3_t, session_ptr: *mut usize) -> ATTESTATION_STATUS {
+    unsafe {
+        exchange_report_safe(src_enclave_id, &mut *dh_msg2, &mut *dh_msg3, &mut *(session_ptr as *mut DhSessionInfo))
+    }  
+}
+
+//Respond to the request from the Source Enclave to close the session
+#[no_mangle]
+#[allow(unused_variables)]
+pub extern "C" fn end_session(src_enclave_id: sgx_enclave_id_t, session_ptr: *mut usize) -> ATTESTATION_STATUS {
+    let _ = unsafe { Box::from_raw(session_ptr as *mut DhSessionInfo) };
+    return ATTESTATION_STATUS::SUCCESS;
+}
+
+#[allow(dead_code)] 
+fn output(outstr: &str) {
+    unsafe {
+        ocall_print_string(outstr.as_ptr() as *const c_uchar, outstr.len() as size_t);
+    }
+}
\ No newline at end of file
diff --git a/samplecode/localattestation/attestation/src/lib.rs b/samplecode/localattestation/attestation/src/lib.rs
new file mode 100644
index 0000000..ff0e4a0
--- /dev/null
+++ b/samplecode/localattestation/attestation/src/lib.rs
@@ -0,0 +1,51 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+#![crate_name = "attestation"]
+#![crate_type = "rlib"]
+
+#![no_std]
+#![feature(const_fn, alloc)]
+#![allow(improper_ctypes)]
+#![allow(non_camel_case_types)]
+
+extern crate alloc;
+
+#[macro_use]
+extern crate sgx_types;
+extern crate sgx_tdh;
+extern crate sgx_trts;
+
+pub mod err;
+pub use self::err::*;
+
+pub mod types;
+pub use self::types::*;
+
+pub mod func;
+pub use self::func::*;
\ No newline at end of file
diff --git a/samplecode/localattestation/attestation/src/types.rs b/samplecode/localattestation/attestation/src/types.rs
new file mode 100644
index 0000000..0392a44
--- /dev/null
+++ b/samplecode/localattestation/attestation/src/types.rs
@@ -0,0 +1,89 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+use sgx_types::*;
+use sgx_tdh::dh::*;
+
+use core::default::Default;
+
+pub const DH_KEY_SIZE: i32  = 20;
+pub const NONCE_SIZE : i32  = 16;
+pub const MAC_SIZE: i32     = 16;
+pub const MAC_KEY_SIZE: i32 = 16;
+pub const PADDING_SIZE: i32 = 16;
+
+pub const TAG_SIZE: i32     = 16;
+pub const IV_SIZE: i32      = 12;
+
+pub const DERIVE_MAC_KEY: i32 = 0x0;
+pub const DERIVE_SESSION_KEY: i32 = 0x1;
+pub const DERIVE_VK1_KEY: i32 = 0x3;
+pub const DERIVE_VK2_KEY: i32 = 0x4;
+
+pub const CLOSED: u32 = 0x0;
+pub const IN_PROGRESS: u32 = 0x1;
+pub const ACTIVE: u32 = 0x2;
+
+pub const MESSAGE_EXCHANGE: i32 = 0x0;
+pub const ENCLAVE_TO_ENCLAVE_CALL: i32 = 0x1;
+
+pub const INVALID_ARGUMENT: i32 = -2;   ///< Invalid function argument
+pub const LOGIC_ERROR: i32 = -3 ;  ///< Functional logic error
+pub const FILE_NOT_FOUND : i32 =  -4 ;  ///< File not found
+
+pub const VMC_ATTRIBUTE_MASK: u64 = 0xFFFFFFFFFFFFFFCB;
+
+pub const MAX_SESSION_COUNT: i32 = 16;
+
+pub struct Callback {
+    pub verify: fn(&sgx_dh_session_enclave_identity_t) -> u32,
+}
+
+pub enum DhSessionStatus {
+    Closed,
+    InProgress(SgxDhResponder),
+    Active(sgx_key_128bit_t),
+}
+
+impl Default for DhSessionStatus {
+    fn default() -> DhSessionStatus {
+        DhSessionStatus::Closed
+    }
+}
+
+#[derive(Default)]
+pub struct DhSession {
+    pub session_id: u32,
+    pub session_status: DhSessionStatus
+}
+
+#[derive(Default)]
+pub struct DhSessionInfo {
+    pub enclave_id: sgx_enclave_id_t,
+    pub session: DhSession,
+}
\ No newline at end of file
diff --git a/samplecode/localattestation/bin/readme.txt b/samplecode/localattestation/bin/readme.txt
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/samplecode/localattestation/bin/readme.txt
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/samplecode/localattestation/enclave1/Cargo.toml b/samplecode/localattestation/enclave1/Cargo.toml
new file mode 100644
index 0000000..49ee239
--- /dev/null
+++ b/samplecode/localattestation/enclave1/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "enclave1"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[lib]
+name = "enclave1"
+crate-type = ["staticlib"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_tdh = { path = "../../../sgx_tdh" }
+attestation = {path = "../attestation/"}
\ No newline at end of file
diff --git a/samplecode/localattestation/enclave1/Enclave1.config.xml b/samplecode/localattestation/enclave1/Enclave1.config.xml
new file mode 100644
index 0000000..942b839
--- /dev/null
+++ b/samplecode/localattestation/enclave1/Enclave1.config.xml
@@ -0,0 +1,11 @@
+<EnclaveConfiguration> 
+  <ProdID>0</ProdID> 
+  <ISVSVN>0</ISVSVN> 
+  <StackMaxSize>0x40000</StackMaxSize> 
+  <HeapMaxSize>0x100000</HeapMaxSize> 
+  <TCSNum>1</TCSNum> 
+  <TCSPolicy>1</TCSPolicy> 
+  <DisableDebug>0</DisableDebug> 
+  <MiscSelect>0</MiscSelect>
+  <MiscMask>0xFFFFFFFF</MiscMask>
+</EnclaveConfiguration>
diff --git a/samplecode/localattestation/enclave1/Enclave1.edl b/samplecode/localattestation/enclave1/Enclave1.edl
new file mode 100644
index 0000000..721bdb1
--- /dev/null
+++ b/samplecode/localattestation/enclave1/Enclave1.edl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *
+ */
+
+enclave {
+    include "sgx_eid.h"
+    from "attestation/attestation.edl" import *;
+    trusted{
+            public void test_enclave_init();
+            public uint32_t test_create_session(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id);
+            public uint32_t test_close_session(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id);
+    };
+
+};
diff --git a/samplecode/localattestation/enclave1/Enclave1.lds b/samplecode/localattestation/enclave1/Enclave1.lds
new file mode 100644
index 0000000..eb09b70
--- /dev/null
+++ b/samplecode/localattestation/enclave1/Enclave1.lds
@@ -0,0 +1,9 @@
+libTestEnclave.so
+{
+    global:
+        g_global_data_sim;
+        g_global_data;
+        enclave_entry;
+    local:
+        *;
+};
diff --git a/samplecode/localattestation/enclave1/Enclave1_private.pem b/samplecode/localattestation/enclave1/Enclave1_private.pem
new file mode 100644
index 0000000..75d7f88
--- /dev/null
+++ b/samplecode/localattestation/enclave1/Enclave1_private.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4wIBAAKCAYEAuJh4w/KzndQhzEqwH6Ut/3BmOom5CN117KT1/cemEbDLPhn0
+c5yjAfe4NL1qtGqz0RTK9X9BBSi89b6BrsM9S6c2cUJaeYAPrAtJ+IuzN/5BAmmf
+RXbPccETd7rHvDdQ9KBRjCipTx+H0D5nOB76S5PZPVrduwrCmSqVFmLNVWWfPYQx
+YewbJ2QfEfioICZFYR0Jou38mJqDTl+CH0gLAuQ4n1kdpQ3VGymzt3oUiPzf5ImJ
+oZh5HjarRRiWV+cyNyXYJTnx0dOtFQDgd8HhniagbRB0ZOIt6599JjMkWGkVP0Ni
+U/NIlXG5musU35GfLB8MbTcxblMNm9sMYz1R8y/eAreoPTXUhtK8NG2TEywRh3UP
+RF9/jM9WczjQXxJ3RznKOwNVwg4cRY2AOqD2vb1iGSqyc/WMzVULgfclkcScp75/
+Auz9Y6473CQvaxyrseSWHGwCG7KG1GxYE8Bg8T6OlYD4mzKggoMdwVLAzUepRaPZ
+5hqRDZzbTGUxJ+GLAgEDAoIBgHsQUIKhzRPiwTLcdWpuHqpK7tGxJgXo+Uht+VPa
+brZ13NQRTaJobKv6es3TnHhHIotjMfj/gK4bKKPUVnSCKN0aJEuBkaZVX8gHhqWy
+d3qpgKxGai5PNPaAt6UnL9LPi03ANl1wcN9qWorURNAUpt0NO348k9IHLGYcY2RB
+3jjuaikCy5adZ2+YFLalxWrELkC+BmyeqGW8V4mVAWowB1dC0Go7aRiz42dxInpR
+YwX96phbsRZlphQkci4QZDqaIFg3ndzTO5bo704zaMcbWtEjmFrYRyb519tRoDkN
+Y0rGwOxFANeRV5dSfGGLm7K5JztiuHN0nMu3PhY4LOV0SeZ4+5sYn0LzB2nyKqgy
+/c3AA2OG34DEdGxxh94kD66iKFVPyJG38/gnu9CsGmrLl3n4fgutPEVIbPdSSjex
+4Y9EQfcnqImPxTrpP9CqD208VPcQHD/uy8s9q3961Ew3RPdHMZ8amIJdXkOmPEme
+KZ7SG+VENBaj8r038iq1mPzcWwKBwQDcvJg75LfVuKX+cWMrTO2+MFVcEFiZ/NB/
+gh7mgL6lCleROVa9P6iR2Wn6vHq8nP5BkChehm/rXEG78fgXEMoArimF7FrrICfI
+4yB0opDJz/tWrE/62impN7OR8Ce+RQThFj4RTnibQEEVt++JMUXFiMKLdWDSpC2i
+tNWnlTOb7d89bk0yk62IoLElCZK/MIMxkCHBKW6YgrmvlPJKQwpA6Z3wQbUpE6Rb
+9f8xJfxZGEJPH0s3Ds9A0CVuEt8OOXcCgcEA1hXTHhhgmb2gIUJgIcvrpkDmiLux
+EG6ZoyLt6h5QwzScS6KKU1mcoJyVDd0wlt7mEXrPYYHWUWPuvpTQ8/4ZGMw7FCZe
+bakhnwRbw36FlLwRG35wCF6nQO1XFBKRGto15ivfTyDvMpJBdtNpET5NwT/ifDF3
+OWS7t6TGhtcfnvBad5S1AgGoAq+q/huFiBGpDbxJ+1xh0lNL5Z8nVypvPWomNpde
+rpLuwRPEIb+GBfQ9Hp5AjRXVsPjKnkHsnl2NAoHBAJMoZX1DJTklw/72Qhzd89Qg
+OOgK5bv94FUBae8Afxixj7YmOdN/xbaQ8VHS/H29/tZgGumu9UeS1n1L+roLMVXJ
+cQPy50dqxTCXavhsYIaKp48diqc8G8YlImFKxSmDWJYO1AuJpbzVgLklSlt2LoOw
+gbJOQIxtc8HN48UOImfz6ij0M3cNHlsVy24GYdTLAiEKwStw9GWse8pjTDGCBtXx
+E/WBI3C3wuf5VMtuqDtlgYoU3M9fNNXgGPQMlLQmTwKBwQCOuTdpZZW708AWLEAW
+h/Ju1e8F0nYK9GZswfPxaYsszb2HwbGM5mhrEw4JPiBklJlg/IpBATmLl/R/DeCi
+qWYQiCdixD7zxhZqAufXqa5jKAtnqaAFlG+AnjoNYbYR5s6ZcpTfa0ohttZPN5tg
+1DPWKpb9dk97mH0lGIRZ5L+/Sub6YyNWq8VXH8dUElkFYRtefYankuvhjN1Dv2+P
+cZ9+RsQkZOnJt0nWDS1r1QQD+Ci/FCsIuTkgpdxpgUhpk7MCgcEAkfkmaBDb7DG2
+Kc39R6ZZuPnV10w+WOpph7ugwcguG/E0wGq+jFWv6HFckCPeHT4BNtOk8Dem/kPp
+teF51eAuFWEefj2tScvlSBBPcnla+WzMWXrlxVnajTt73w+oT2Ql//WhgREpsNfx
+SvU80YPVu4GJfl+hhxBifLx+0FM20OESW93qFRc3p040bNrDY9JIZuly/y5zaiBa
+mRZF9H8P+x3Lu5AJpdXQEOMZ/XJ/xkoWWjbTojkmgOmmZSMLd5Te
+-----END RSA PRIVATE KEY-----
diff --git a/samplecode/localattestation/enclave1/Makefile b/samplecode/localattestation/enclave1/Makefile
new file mode 100644
index 0000000..a807f7e
--- /dev/null
+++ b/samplecode/localattestation/enclave1/Makefile
@@ -0,0 +1,37 @@
+# Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * 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.
+#  * Neither the name of Baidu, Inc., nor the names of its
+#    contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+
+Rust_Enclave_Name := libenclave1.a
+Rust_Enclave_Files := $(wildcard src/*.rs)
+
+.PHONY: all
+
+all: $(Rust_Enclave_Name)
+
+$(Rust_Enclave_Name): $(Rust_Enclave_Files)  
+	cargo build --release
diff --git a/samplecode/localattestation/enclave1/src/lib.rs b/samplecode/localattestation/enclave1/src/lib.rs
new file mode 100644
index 0000000..2feaef8
--- /dev/null
+++ b/samplecode/localattestation/enclave1/src/lib.rs
@@ -0,0 +1,70 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+#![crate_name = "enclave1"]
+#![crate_type = "staticlib"]
+
+#![no_std]
+
+extern crate sgx_types;
+extern crate sgx_tdh;
+use sgx_types::*;
+
+extern crate attestation;
+use attestation::types::*;
+use attestation::err::*;
+use attestation::func::*;
+
+fn verify_peer_enclave_trust(peer_enclave_identity: &sgx_dh_session_enclave_identity_t )-> u32 {
+
+    if peer_enclave_identity.isv_prod_id != 0 || peer_enclave_identity.attributes.flags & SGX_FLAGS_INITTED == 0 {
+        // || peer_enclave_identity->attributes.xfrm !=3)// || peer_enclave_identity->mr_signer != xx //TODO: To be hardcoded with values to check
+        ATTESTATION_STATUS::ENCLAVE_TRUST_ERROR as u32
+    } else {
+        ATTESTATION_STATUS::SUCCESS as u32
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn test_enclave_init() {
+    let cb = Callback{
+        verify: verify_peer_enclave_trust,
+    };
+    init(cb);
+}
+
+#[no_mangle]
+pub extern "C" fn test_create_session(src_enclave_id: sgx_enclave_id_t, dest_enclave_id: sgx_enclave_id_t) -> u32 {
+    create_session(src_enclave_id, dest_enclave_id) as u32
+}
+
+#[no_mangle]
+#[allow(unused_variables)]
+pub extern "C" fn test_close_session(src_enclave_id: sgx_enclave_id_t, dest_enclave_id: sgx_enclave_id_t) -> u32 {
+    close_session(src_enclave_id, dest_enclave_id) as u32
+}
\ No newline at end of file
diff --git a/samplecode/localattestation/enclave2/Cargo.toml b/samplecode/localattestation/enclave2/Cargo.toml
new file mode 100644
index 0000000..46868a5
--- /dev/null
+++ b/samplecode/localattestation/enclave2/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "enclave2"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[lib]
+name = "enclave2"
+crate-type = ["staticlib"]
+
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_tdh = { path = "../../../sgx_tdh" }
+attestation = {path = "../attestation/"}
\ No newline at end of file
diff --git a/samplecode/localattestation/enclave2/Enclave2.config.xml b/samplecode/localattestation/enclave2/Enclave2.config.xml
new file mode 100644
index 0000000..89a7ab5
--- /dev/null
+++ b/samplecode/localattestation/enclave2/Enclave2.config.xml
@@ -0,0 +1,11 @@
+<EnclaveConfiguration> 
+  <ProdID>0</ProdID> 
+  <ISVSVN>0</ISVSVN> 
+  <StackMaxSize>0x40000</StackMaxSize> 
+  <HeapMaxSize>0x100000</HeapMaxSize> 
+  <TCSNum>1</TCSNum> 
+  <TCSPolicy>1</TCSPolicy> 
+  <DisableDebug>0</DisableDebug>
+  <MiscSelect>0</MiscSelect>
+  <MiscMask>0xFFFFFFFF</MiscMask>
+</EnclaveConfiguration>
diff --git a/samplecode/localattestation/enclave2/Enclave2.edl b/samplecode/localattestation/enclave2/Enclave2.edl
new file mode 100644
index 0000000..4e9ac6f
--- /dev/null
+++ b/samplecode/localattestation/enclave2/Enclave2.edl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *
+ */
+
+
+enclave {
+    include "sgx_eid.h"
+    from "attestation/attestation.edl" import *;
+    trusted{
+            public void test_enclave_init();
+            public uint32_t test_create_session(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id);
+            public uint32_t test_close_session(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id);
+    };
+};
diff --git a/samplecode/localattestation/enclave2/Enclave2_private.pem b/samplecode/localattestation/enclave2/Enclave2_private.pem
new file mode 100644
index 0000000..529d07b
--- /dev/null
+++ b/samplecode/localattestation/enclave2/Enclave2_private.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ
+AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ
+ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr
+nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b
+3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H
+ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD
+5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW
+KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC
+1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe
+K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z
+AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q
+ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6
+JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826
+5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02
+wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9
+osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm
+WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i
+Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9
+xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd
+vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD
+Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a
+cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC
+0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ
+gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo
+gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t
+k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz
+Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6
+O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5
+afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom
+e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G
+BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv
+fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN
+t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9
+yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp
+6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg
+WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH
+NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk=
+-----END RSA PRIVATE KEY-----
diff --git a/samplecode/localattestation/enclave2/Makefile b/samplecode/localattestation/enclave2/Makefile
new file mode 100644
index 0000000..3bd5488
--- /dev/null
+++ b/samplecode/localattestation/enclave2/Makefile
@@ -0,0 +1,37 @@
+# Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * 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.
+#  * Neither the name of Baidu, Inc., nor the names of its
+#    contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+
+Rust_Enclave_Name := libenclave2.a
+Rust_Enclave_Files := $(wildcard src/*.rs)
+
+.PHONY: all
+
+all: $(Rust_Enclave_Name)
+
+$(Rust_Enclave_Name): $(Rust_Enclave_Files)  
+	cargo build --release
diff --git a/samplecode/localattestation/enclave2/src/lib.rs b/samplecode/localattestation/enclave2/src/lib.rs
new file mode 100644
index 0000000..5d8c36e
--- /dev/null
+++ b/samplecode/localattestation/enclave2/src/lib.rs
@@ -0,0 +1,70 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+#![crate_name = "enclave2"]
+#![crate_type = "staticlib"]
+
+#![no_std]
+
+extern crate sgx_types;
+extern crate sgx_tdh;
+use sgx_types::*;
+
+extern crate attestation;
+use attestation::types::*;
+use attestation::err::*;
+use attestation::func::*;
+
+fn verify_peer_enclave_trust(peer_enclave_identity: &sgx_dh_session_enclave_identity_t )-> u32 {
+
+    if peer_enclave_identity.isv_prod_id != 0 || peer_enclave_identity.attributes.flags & SGX_FLAGS_INITTED == 0 {
+        // || peer_enclave_identity->attributes.xfrm !=3)// || peer_enclave_identity->mr_signer != xx //TODO: To be hardcoded with values to check
+        ATTESTATION_STATUS::ENCLAVE_TRUST_ERROR as u32
+    } else {
+        ATTESTATION_STATUS::SUCCESS as u32
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn test_enclave_init() {
+    let cb = Callback{
+        verify: verify_peer_enclave_trust,
+    };
+    init(cb);
+}
+
+#[no_mangle]
+pub extern "C" fn test_create_session(src_enclave_id: sgx_enclave_id_t, dest_enclave_id: sgx_enclave_id_t) -> u32 {
+    create_session(src_enclave_id, dest_enclave_id) as u32
+}
+
+#[no_mangle]
+#[allow(unused_variables)]
+pub extern "C" fn test_close_session(src_enclave_id: sgx_enclave_id_t, dest_enclave_id: sgx_enclave_id_t) -> u32 {
+    close_session(src_enclave_id, dest_enclave_id) as u32
+}
\ No newline at end of file
diff --git a/samplecode/localattestation/enclave3/Cargo.toml b/samplecode/localattestation/enclave3/Cargo.toml
new file mode 100644
index 0000000..d371814
--- /dev/null
+++ b/samplecode/localattestation/enclave3/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "enclave3"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[lib]
+name = "enclave3"
+crate-type = ["staticlib"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_tdh = { path = "../../../sgx_tdh" }
+attestation = {path = "../attestation/"}
\ No newline at end of file
diff --git a/samplecode/localattestation/enclave3/Enclave3.config.xml b/samplecode/localattestation/enclave3/Enclave3.config.xml
new file mode 100644
index 0000000..942b839
--- /dev/null
+++ b/samplecode/localattestation/enclave3/Enclave3.config.xml
@@ -0,0 +1,11 @@
+<EnclaveConfiguration> 
+  <ProdID>0</ProdID> 
+  <ISVSVN>0</ISVSVN> 
+  <StackMaxSize>0x40000</StackMaxSize> 
+  <HeapMaxSize>0x100000</HeapMaxSize> 
+  <TCSNum>1</TCSNum> 
+  <TCSPolicy>1</TCSPolicy> 
+  <DisableDebug>0</DisableDebug> 
+  <MiscSelect>0</MiscSelect>
+  <MiscMask>0xFFFFFFFF</MiscMask>
+</EnclaveConfiguration>
diff --git a/samplecode/localattestation/enclave3/Enclave3.edl b/samplecode/localattestation/enclave3/Enclave3.edl
new file mode 100644
index 0000000..7f17424
--- /dev/null
+++ b/samplecode/localattestation/enclave3/Enclave3.edl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *
+ */
+
+enclave {
+    include "sgx_eid.h"
+    from "attestation/attestation.edl" import *;
+    trusted{
+        public void test_enclave_init();
+        public uint32_t test_create_session(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id);
+        public uint32_t test_close_session(sgx_enclave_id_t src_enclave_id, sgx_enclave_id_t dest_enclave_id);
+    };
+};
diff --git a/samplecode/localattestation/enclave3/Enclave3_private.pem b/samplecode/localattestation/enclave3/Enclave3_private.pem
new file mode 100644
index 0000000..b8ace89
--- /dev/null
+++ b/samplecode/localattestation/enclave3/Enclave3_private.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4wIBAAKCAYEA0MvI9NpdP4GEqCvtlJQv00OybzTXzxBhPu/257VYt9cYw/ph
+BN1WRyxBBcrZs15xmcvlb3xNmFGWs4w5oUgrFBNgi6g+CUOCsj0cM8xw7P/y3K0H
+XaZUf+T3CXCp8NvlkZHzfdWAFA5lGGR9g6kmuk7SojE3h87Zm1KjPU/PvAe+BaMU
+trlRr4gPNVnu19Vho60xwuswPxfl/pBFUIk7qWEUR3l2hiqWMeLgf3Ays/WSnkXA
+uijwPt5g0hxsgIlyDrI3jKbf0zkFB56jvPwSykfU8aw4Gkbo5qSZxUAKnwH2L8Uf
+yM6inBaaYtM79icRwsu45Yt6X0GAt7CSb/1TKBrnm5exmK1sug3YSQ/YuK1FYawU
+vIaDD0YfzOndTNVBewA+Hr5xNPvqGJoRKHuGbyu2lI9jrKYpVxQWsmx38wnxF6kE
+zX6N4m7KZiLeLpDdBVQtLuOzIdIE4wT3t/ckeqElxO/1Ut9bj765GcTTrYwMKHRw
+ukWIH7ZtHtAjj0KzAgEDAoIBgQCLMoX4kZN/q63Fcp5jDXU3gnb0zeU0tZYp9U9F
+I5B6j2XX/ECt6OQvctYD3JEiPvZmh+5KUt5li7nNCCZrhXINYkBdGtQGLQHMKL13
+3aCd//c9yK+TxDhVQ09boHFLPUO2YUz+jlVitENlmFOtG28m3zcWy3paieZnjGzT
+iop9Wn6ubLh50OEfsAojkUnlOOvCc3aB8iAqD+6ptYOLBifGQLgvpk8EHGQhQer/
+oCHNTmG+2SsmxfV/Pus2vZ2rBkrUbZU0hwrnvKOIPhnt3Qwtmx9xsC67jF+MpWko
+UisJXC27FAGz2gpIGMhBp35HEppwG9hhCuMQdK2g62bvweyr1tC4qOVdQrKvhksN
+r6CMjS9eSXvmWdF7lU4oxStN0V56/LICSIsLbggUaxTPKhAVEgfTSqwEJoQuFA3Q
+4GmgTydPhcRH1L/lhbWJqZQm7V1Gt+5i5J6iATD32uNQQ2iZi5GsUhr+jZC+WlE5
+6lS813cRNiaK52HIk62bG7IXOksCgcEA+6RxZhQ5GaCPYZNsk7TqxqsKopXKoYAr
+2R4KWuexJTd+1kcNMk0ETX8OSgpY2cYL2uPFWmdutxPpLfpr8S2u92Da/Wxs70Ti
+QSb0426ybTmnS5L7nOnGOHiddXILhW175liAszTeoR7nQ6vpr9YjfcnrXiB8bKIm
+akft2DQoxrBPzEe9tA8gfkyDTsSG2j7kncSbvYRtkKcJOmmypotVU6uhRPSrSXCc
+J59uBQkg6Bk4CKA1mz8ctG07MluFY0/ZAoHBANRpZlfIFl39gFmuEER7lb80GySO
+J190LbqOca3dGOvAMsDgEAi6juJyX7ZNpbHFHj++LvmTtw9+kxhVDBcswS7304kt
+7J2EfnGdctEZtXif1wiq30YWAp1tjRpQENKtt9wssmgcwgK39rZNiEHmStHGv3l+
+5TnKPKeuFCDnsLvi5lQYoK2wTYvZtsjf+Rnt7H17q90IV54pMjTS8BkGskCkKf2A
+IYuaZkqX0T3cM6ovoYYDAU6rWL5rrYPLEwkbawKBwQCnwvZEDXtmawpBDPMNI0cv
+HLHBuTHBAB07aVw8mnYYz6nkL14hiK2I/17cBuXmhAfnQoORmknPYptz/Ef2HnSk
+6zyo8vNKLewrb03s9Hbze8TdDKe98S7QUGj49rJY86fu5asiIz8WFJotHUZ1OWz+
+hpzpav2dwW7xhUk6zXCEdYqIL9PNX2r+3azfLa88Ke2+gxJ+WEkLGgYm8SHEXOON
+HRYt+HIw9b1vv56uBhXwENAFwCO81L3Nnid2565CNTsCgcEAjZuZj9q5k/5VkR61
+gv0Of3gSGF7E6k1z0bRLyT4QnSrMgJVgBdG0lvbqeYkZIS4UKn7J+7fPX6m3ZY4I
+D3MrdKU3sMlIaQL+9mj3NhEjpb/ksHHqLrlXE55eEYq14cklPXMhmr3WrHqkeYkF
+gUQx4S8qUP9De9wob8liwJp10pdEOBBrHnWJB+Z52z/7Zp6dqP0dPgWPvsYheIyg
+EK8hgG1xU6rBB7xEMbqLfpLNHB/BBAIA3xzl1EfJAodiBhJHAoHAeTS2znDHYayI
+TvK86tBAPVORiBVTSdRUONdGF3dipo24hyeyrI5MtiOoMc3sKWXnSTkDQWa3WiPx
+qStBmmO/SbGTuz7T6+oOwGeMiYzYBe87Ayn8Y0KYYshFikieJbGusHjUlIGmCVPy
+UHrDMYGwFGUGBwW47gBsnZa+YPHtxWCPDe/U80et2Trx0RXJJQPmupAVMSiJWObI
+9k5gRU+xDqkHanyD1gkGGwhFTUNX94EJEOdQEWw3hxLnVtePoke/
+-----END RSA PRIVATE KEY-----
diff --git a/samplecode/localattestation/enclave3/Makefile b/samplecode/localattestation/enclave3/Makefile
new file mode 100644
index 0000000..32af18e
--- /dev/null
+++ b/samplecode/localattestation/enclave3/Makefile
@@ -0,0 +1,37 @@
+# Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * 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.
+#  * Neither the name of Baidu, Inc., nor the names of its
+#    contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+
+Rust_Enclave_Name := libenclave3.a
+Rust_Enclave_Files := $(wildcard src/*.rs)
+
+.PHONY: all
+
+all: $(Rust_Enclave_Name)
+
+$(Rust_Enclave_Name): $(Rust_Enclave_Files)  
+	cargo build --release
diff --git a/samplecode/localattestation/enclave3/src/lib.rs b/samplecode/localattestation/enclave3/src/lib.rs
new file mode 100644
index 0000000..2f08a74
--- /dev/null
+++ b/samplecode/localattestation/enclave3/src/lib.rs
@@ -0,0 +1,70 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+#![crate_name = "enclave3"]
+#![crate_type = "staticlib"]
+
+#![no_std]
+
+extern crate sgx_types;
+extern crate sgx_tdh;
+use sgx_types::*;
+
+extern crate attestation;
+use attestation::types::*;
+use attestation::err::*;
+use attestation::func::*;
+
+fn verify_peer_enclave_trust(peer_enclave_identity: &sgx_dh_session_enclave_identity_t )-> u32 {
+
+    if peer_enclave_identity.isv_prod_id != 0 || peer_enclave_identity.attributes.flags & SGX_FLAGS_INITTED == 0 {
+        // || peer_enclave_identity->attributes.xfrm !=3)// || peer_enclave_identity->mr_signer != xx //TODO: To be hardcoded with values to check
+        ATTESTATION_STATUS::ENCLAVE_TRUST_ERROR as u32
+    } else {
+        ATTESTATION_STATUS::SUCCESS as u32
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn test_enclave_init() {
+    let cb = Callback{
+        verify: verify_peer_enclave_trust,
+    };
+    init(cb);
+}
+
+#[no_mangle]
+pub extern "C" fn test_create_session(src_enclave_id: sgx_enclave_id_t, dest_enclave_id: sgx_enclave_id_t) -> u32 {
+    create_session(src_enclave_id, dest_enclave_id) as u32
+}
+
+#[no_mangle]
+#[allow(unused_variables)]
+pub extern "C" fn test_close_session(src_enclave_id: sgx_enclave_id_t, dest_enclave_id: sgx_enclave_id_t) -> u32 {
+    close_session(src_enclave_id, dest_enclave_id) as u32
+}
\ No newline at end of file
diff --git a/samplecode/localattestation/lib/readme.txt b/samplecode/localattestation/lib/readme.txt
new file mode 100644
index 0000000..7951405
--- /dev/null
+++ b/samplecode/localattestation/lib/readme.txt
@@ -0,0 +1 @@
+lib
\ No newline at end of file
diff --git a/samplecode/sealeddata/Makefile b/samplecode/sealeddata/Makefile
new file mode 100644
index 0000000..e2fbb1e
--- /dev/null
+++ b/samplecode/sealeddata/Makefile
@@ -0,0 +1,179 @@
+# Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * 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.
+#  * Neither the name of Baidu, Inc., nor the names of its
+#    contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+
+######## SGX SDK Settings ########
+
+SGX_SDK ?= /opt/intel/sgxsdk
+SGX_MODE ?= HW
+SGX_ARCH ?= x64
+
+ifeq ($(shell getconf LONG_BIT), 32)
+	SGX_ARCH := x86
+else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
+	SGX_ARCH := x86
+endif
+
+ifeq ($(SGX_ARCH), x86)
+	SGX_COMMON_CFLAGS := -m32
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
+else
+	SGX_COMMON_CFLAGS := -m64
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
+endif
+
+ifeq ($(SGX_DEBUG), 1)
+ifeq ($(SGX_PRERELEASE), 1)
+$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
+endif
+endif
+
+
+ifeq ($(SGX_DEBUG), 1)
+	SGX_COMMON_CFLAGS += -O0 -g
+else
+	SGX_COMMON_CFLAGS += -O2
+endif
+
+######## CUSTOM Settings ########
+
+CUSTOM_LIBRARY_PATH := ./lib
+CUSTOM_BIN_PATH := ./bin
+
+######## EDL Settings ########
+
+Enclave_EDL_Files := enclave/Enclave_t.c enclave/Enclave_t.h app/Enclave_u.c app/Enclave_u.h
+
+######## APP Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Urts_Library_Name := sgx_urts_sim
+else
+	Urts_Library_Name := sgx_urts
+endif
+
+App_C_Files := $(wildcard ./app/*.c)
+App_Include_Paths := -I ./app -I./include -I$(SGX_SDK)/include
+App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
+App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread 
+ifneq ($(SGX_MODE), HW)
+	App_Link_Flags += -lsgx_uae_service_sim
+else
+	App_Link_Flags += -lsgx_uae_service
+endif
+
+App_C_Objects := $(App_C_Files:.c=.o)
+
+App_Name := bin/app
+
+######## Enclave Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Trts_Library_Name := sgx_trts_sim
+	Service_Library_Name := sgx_tservice_sim
+else
+	Trts_Library_Name := sgx_trts
+	Service_Library_Name := sgx_tservice
+endif
+Crypto_Library_Name := sgx_tcrypto
+KeyExchange_Library_Name := sgx_tkey_exchange
+
+RustEnclave_C_Files := $(wildcard ./enclave/*.c)
+RustEnclave_C_Objects := $(RustEnclave_C_Files:.c=.o)
+RustEnclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport -I$(SGX_SDK)/include/epid -I ./enclave -I./include
+
+RustEnclave_Link_Libs := -L$(CUSTOM_LIBRARY_PATH) -lcompiler-rt-patch -lenclave
+RustEnclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(RustEnclave_Include_Paths)
+RustEnclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
+	-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
+	-Wl,--start-group -lsgx_tstdc -lsgx_tstdcxx -l$(Crypto_Library_Name) -l$(KeyExchange_Library_Name) -l$(Service_Library_Name) $(RustEnclave_Link_Libs) -Wl,--end-group \
+	-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
+	-Wl,-pie,-eenclave_entry -Wl,--export-dynamic  \
+	-Wl,--defsym,__ImageBase=0 \
+	-Wl,--gc-sections \
+	-Wl,--version-script=enclave/Enclave.lds
+
+
+RustEnclave_Name := enclave/enclave.so
+Signed_RustEnclave_Name := bin/enclave.signed.so
+
+.PHONY: all
+all: $(Enclave_EDL_Files) $(App_Name) $(Signed_RustEnclave_Name)
+
+######## EDL Objects ########
+
+$(Enclave_EDL_Files): $(SGX_EDGER8R) enclave/Enclave.edl
+	$(SGX_EDGER8R) --trusted enclave/Enclave.edl --search-path $(SGX_SDK)/include --trusted-dir enclave
+	$(SGX_EDGER8R) --untrusted enclave/Enclave.edl --search-path $(SGX_SDK)/include --untrusted-dir app
+	@echo "GEN  =>  $(Enclave_EDL_Files)"
+
+######## App Objects ########
+
+app/Enclave_u.o: app/Enclave_u.c
+	@$(CC) $(App_C_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+app/%.o: app/%.c
+	@$(CXX) $(App_C_Flags) -c $< -o $@
+	@echo "CXX  <=  $<"
+
+$(App_Name): app/Enclave_u.o $(App_C_Objects)
+	@$(CXX) $^ -o $@ $(App_Link_Flags)
+	@echo "LINK =>  $@"
+
+######## Enclave Objects ########
+
+enclave/Enclave_t.o: enclave/Enclave_t.c
+	@$(CC) $(RustEnclave_Compile_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+$(RustEnclave_Name): enclave compiler-rt enclave/Enclave_t.o 
+	cp ./enclave/target/release/libenclave.a ./lib
+	cp ../../compiler-rt/libcompiler-rt-patch.a ./lib
+	@$(CXX) enclave/Enclave_t.o -o $@ $(RustEnclave_Link_Flags)
+	@echo "LINK =>  $@"
+
+$(Signed_RustEnclave_Name): $(RustEnclave_Name)
+	@$(SGX_ENCLAVE_SIGNER) sign -key enclave/Enclave_private.pem -enclave $(RustEnclave_Name) -out $@ -config enclave/Enclave.config.xml
+	@echo "SIGN =>  $@"
+
+.PHONY: enclave
+enclave:
+	$(MAKE) -C ./enclave/
+	
+.PHONY: compiler-rt
+compiler-rt:
+	$(MAKE) -C ../../compiler-rt/ 2> /dev/null
+
+.PHONY: clean
+clean:
+	@rm -f $(App_Name) $(RustEnclave_Name) $(Signed_RustEnclave_Name) $(RustEnclave_C_Objects) $(App_C_Objects) enclave/*_t.* app/*_u.* lib/*.a
+	
diff --git a/samplecode/sealeddata/app/app.c b/samplecode/sealeddata/app/app.c
new file mode 100644
index 0000000..f64128a
--- /dev/null
+++ b/samplecode/sealeddata/app/app.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2011-2016 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <unistd.h>
+#include <pwd.h>
+#define MAX_PATH FILENAME_MAX
+
+#include "sgx_urts.h"
+#include "sgx_tseal.h"
+#include "app.h"
+#include "Enclave_u.h"
+
+
+sgx_enclave_id_t global_eid = 0;
+
+typedef struct _sgx_errlist_t {
+    sgx_status_t err;
+    const char *msg;
+    const char *sug; /* Suggestion */
+} sgx_errlist_t;
+
+/* Error code returned by sgx_create_enclave */
+static sgx_errlist_t sgx_errlist[] = {
+    {
+        SGX_ERROR_UNEXPECTED,
+        "Unexpected error occurred.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_PARAMETER,
+        "Invalid parameter.",
+        NULL
+    },
+    {
+        SGX_ERROR_OUT_OF_MEMORY,
+        "Out of memory.",
+        NULL
+    },
+    {
+        SGX_ERROR_ENCLAVE_LOST,
+        "Power transition occurred.",
+        "Please refer to the sample \"PowerTransition\" for details."
+    },
+    {
+        SGX_ERROR_INVALID_ENCLAVE,
+        "Invalid enclave image.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_ENCLAVE_ID,
+        "Invalid enclave identification.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_SIGNATURE,
+        "Invalid enclave signature.",
+        NULL
+    },
+    {
+        SGX_ERROR_OUT_OF_EPC,
+        "Out of EPC memory.",
+        NULL
+    },
+    {
+        SGX_ERROR_NO_DEVICE,
+        "Invalid SGX device.",
+        "Please make sure SGX module is enabled in the BIOS, and install SGX driver afterwards."
+    },
+    {
+        SGX_ERROR_MEMORY_MAP_CONFLICT,
+        "Memory map conflicted.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_METADATA,
+        "Invalid enclave metadata.",
+        NULL
+    },
+    {
+        SGX_ERROR_DEVICE_BUSY,
+        "SGX device was busy.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_VERSION,
+        "Enclave version was invalid.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_ATTRIBUTE,
+        "Enclave was not authorized.",
+        NULL
+    },
+    {
+        SGX_ERROR_ENCLAVE_FILE_ACCESS,
+        "Can't open enclave file.",
+        NULL
+    },
+};
+
+/* Check error conditions for loading enclave */
+void print_error_message(sgx_status_t ret)
+{
+    size_t idx = 0;
+    size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0];
+
+    for (idx = 0; idx < ttl; idx++) {
+        if(ret == sgx_errlist[idx].err) {
+            if(NULL != sgx_errlist[idx].sug)
+                printf("Info: %s\n", sgx_errlist[idx].sug);
+            printf("Error: %s\n", sgx_errlist[idx].msg);
+            break;
+        }
+    }
+    
+    if (idx == ttl)
+        printf("Error: Unexpected error occurred.\n");
+}
+
+/* Initialize the enclave:
+ *   Step 1: try to retrieve the launch token saved by last transaction
+ *   Step 2: call sgx_create_enclave to initialize an enclave instance
+ *   Step 3: save the launch token if it is updated
+ */
+int initialize_enclave(void)
+{
+    char token_path[MAX_PATH] = {'\0'};
+    sgx_launch_token_t token = {0};
+    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
+    int updated = 0;
+    
+    /* Step 1: try to retrieve the launch token saved by last transaction 
+     *         if there is no token, then create a new one.
+     */
+    /* try to get the token saved in $HOME */
+    const char *home_dir = getpwuid(getuid())->pw_dir;
+    
+    if (home_dir != NULL && 
+        (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) {
+        /* compose the token path */
+        strncpy(token_path, home_dir, strlen(home_dir));
+        strncat(token_path, "/", strlen("/"));
+        strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1);
+    } else {
+        /* if token path is too long or $HOME is NULL */
+        strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME));
+    }
+
+    FILE *fp = fopen(token_path, "rb");
+    if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
+        printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
+    }
+
+    if (fp != NULL) {
+        /* read the token from saved file */
+        size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
+        if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
+            /* if token is invalid, clear the buffer */
+            memset(&token, 0x0, sizeof(sgx_launch_token_t));
+            printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
+        }
+    }
+    /* Step 2: call sgx_create_enclave to initialize an enclave instance */
+    /* Debug Support: set 2nd parameter to 1 */
+    ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
+    if (ret != SGX_SUCCESS) {
+        print_error_message(ret);
+        if (fp != NULL) fclose(fp);
+        return -1;
+    }
+    printf("global_eid: %ld\n", global_eid);
+
+    /* Step 3: save the launch token if it is updated */
+    if (updated == FALSE || fp == NULL) {
+        /* if the token is not updated, or file handler is invalid, do not perform saving */
+        if (fp != NULL) fclose(fp);
+        return 0;
+    }
+
+    /* reopen the file with write capablity */
+    fp = freopen(token_path, "wb", fp);
+    if (fp == NULL) return 0;
+    size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
+    if (write_num != sizeof(sgx_launch_token_t))
+        printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
+    fclose(fp);
+    return 0;
+}
+
+/* Application entry */
+int SGX_CDECL main(int argc, char *argv[])
+{
+	sgx_status_t sgx_ret = SGX_SUCCESS;
+	sgx_status_t enclave_ret = SGX_SUCCESS;
+	uint32_t sealed_log_size = 1024;
+	uint8_t sealed_log[1024] = {0};
+    sgx_sealed_data_t * sealed_data = 0;
+	
+    (void)(argc);
+    (void)(argv);
+
+    /* Initialize the enclave */
+    if(initialize_enclave() < 0){
+        printf("Enter a character before exit ...\n");
+        getchar();
+        return -1; 
+    }
+ 	
+ 	sgx_ret = create_sealeddata(global_eid, &enclave_ret, sealed_log, sealed_log_size);
+ 	if(sgx_ret != SGX_SUCCESS) {
+        print_error_message(sgx_ret);
+        return -1;
+    }
+    if(enclave_ret != SGX_SUCCESS) {
+        print_error_message(enclave_ret);
+        return -1;
+    }
+    printf("create_sealeddata success ...\n");
+
+    sealed_data = (sgx_sealed_data_t *)sealed_log;
+    printf("sealed_data.key_request.key_name 0x%x\n", sealed_data->key_request.key_name);
+    printf("sealed_data.key_request.key_policy 0x%x\n", sealed_data->key_request.key_policy);
+    printf("sealed_data.plain_text_offset 0x%x\n", sealed_data->plain_text_offset);
+    printf("sealed_data.aes_data.payload_size 0x%x\n", sealed_data->aes_data.payload_size);
+
+    sgx_ret = verify_sealeddata(global_eid, &enclave_ret, sealed_log, sealed_log_size);
+    if(sgx_ret != SGX_SUCCESS) {
+        print_error_message(sgx_ret);
+        return -1;
+    }
+    if(enclave_ret != SGX_SUCCESS) {
+        print_error_message(sgx_ret);
+        return -1;
+    }
+
+    printf("verify_sealeddata success ...\n");
+
+    /* Destroy the enclave */
+    sgx_destroy_enclave(global_eid);
+    
+    printf("Enter a character before exit ...\n");
+    getchar();
+    return 0;
+}
+
+void ocall_print_string(const char *str, size_t len)
+{
+    char * string = (char *)malloc(len + (size_t)sizeof(char));
+    if (string == NULL) {
+    	printf("malloc failed\n");
+    	return;
+    }
+    
+    memcpy(string, str, len);
+    char * ptr = string + len;
+    * ptr = 0;
+    printf("%s\n", string);
+    free(string);
+}
\ No newline at end of file
diff --git a/samplecode/sealeddata/app/app.h b/samplecode/sealeddata/app/app.h
new file mode 100644
index 0000000..d2ef2d8
--- /dev/null
+++ b/samplecode/sealeddata/app/app.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011-2016 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 _APP_H_
+#define _APP_H_
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "sgx_error.h"       /* sgx_status_t */
+#include "sgx_eid.h"     /* sgx_enclave_id_t */
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define TOKEN_FILENAME   "enclave.token"
+#define ENCLAVE_FILENAME "enclave.signed.so"
+
+extern sgx_enclave_id_t global_eid;    /* global enclave id */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_APP_H_ */
diff --git a/samplecode/sealeddata/bin/readme.txt b/samplecode/sealeddata/bin/readme.txt
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/samplecode/sealeddata/bin/readme.txt
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/samplecode/sealeddata/enclave/Cargo.toml b/samplecode/sealeddata/enclave/Cargo.toml
new file mode 100644
index 0000000..39db74b
--- /dev/null
+++ b/samplecode/sealeddata/enclave/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "enclave"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[lib]
+name = "enclave"
+crate-type = ["staticlib"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_tseal = { path = "../../../sgx_tseal" }
+sgx_trts = { path = "../../../sgx_trts" }
diff --git a/samplecode/sealeddata/enclave/Enclave.config.xml b/samplecode/sealeddata/enclave/Enclave.config.xml
new file mode 100644
index 0000000..ee4c3f7
--- /dev/null
+++ b/samplecode/sealeddata/enclave/Enclave.config.xml
@@ -0,0 +1,12 @@
+<!-- Please refer to User's Guide for the explanation of each field -->
+<EnclaveConfiguration>
+  <ProdID>0</ProdID>
+  <ISVSVN>0</ISVSVN>
+  <StackMaxSize>0x40000</StackMaxSize>
+  <HeapMaxSize>0x100000</HeapMaxSize>
+  <TCSNum>1</TCSNum>
+  <TCSPolicy>1</TCSPolicy>
+  <DisableDebug>0</DisableDebug>
+  <MiscSelect>0</MiscSelect>
+  <MiscMask>0xFFFFFFFF</MiscMask>
+</EnclaveConfiguration>
diff --git a/samplecode/sealeddata/enclave/Enclave.edl b/samplecode/sealeddata/enclave/Enclave.edl
new file mode 100644
index 0000000..93bb206
--- /dev/null
+++ b/samplecode/sealeddata/enclave/Enclave.edl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *
+ */
+ 
+enclave {
+	
+	trusted {
+        /* define ECALLs here. */
+		
+        public sgx_status_t create_sealeddata([out, size=sealed_log_size]
+            uint8_t* sealed_log, uint32_t sealed_log_size );
+
+        public sgx_status_t verify_sealeddata([in, size=sealed_log_size]
+            uint8_t* sealed_log, uint32_t sealed_log_size);
+    };
+    
+    untrusted {
+        void ocall_print_string([in, size=len] const char *str, size_t len);
+    };
+
+ 
+};
\ No newline at end of file
diff --git a/samplecode/sealeddata/enclave/Enclave.lds b/samplecode/sealeddata/enclave/Enclave.lds
new file mode 100644
index 0000000..eb09b70
--- /dev/null
+++ b/samplecode/sealeddata/enclave/Enclave.lds
@@ -0,0 +1,9 @@
+libTestEnclave.so
+{
+    global:
+        g_global_data_sim;
+        g_global_data;
+        enclave_entry;
+    local:
+        *;
+};
diff --git a/samplecode/sealeddata/enclave/Enclave_private.pem b/samplecode/sealeddata/enclave/Enclave_private.pem
new file mode 100644
index 0000000..529d07b
--- /dev/null
+++ b/samplecode/sealeddata/enclave/Enclave_private.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ
+AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ
+ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr
+nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b
+3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H
+ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD
+5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW
+KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC
+1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe
+K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z
+AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q
+ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6
+JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826
+5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02
+wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9
+osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm
+WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i
+Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9
+xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd
+vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD
+Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a
+cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC
+0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ
+gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo
+gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t
+k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz
+Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6
+O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5
+afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom
+e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G
+BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv
+fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN
+t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9
+yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp
+6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg
+WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH
+NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk=
+-----END RSA PRIVATE KEY-----
diff --git a/samplecode/sealeddata/enclave/Makefile b/samplecode/sealeddata/enclave/Makefile
new file mode 100644
index 0000000..3953ca0
--- /dev/null
+++ b/samplecode/sealeddata/enclave/Makefile
@@ -0,0 +1,37 @@
+# Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * 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.
+#  * Neither the name of Baidu, Inc., nor the names of its
+#    contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+
+Rust_Enclave_Name := libenclave.a
+Rust_Enclave_Files := $(wildcard src/*.rs)
+
+.PHONY: all
+
+all: $(Rust_Enclave_Name)
+
+$(Rust_Enclave_Name): $(Rust_Enclave_Files)  
+	cargo build --release
diff --git a/samplecode/sealeddata/enclave/src/lib.rs b/samplecode/sealeddata/enclave/src/lib.rs
new file mode 100644
index 0000000..7cd0192
--- /dev/null
+++ b/samplecode/sealeddata/enclave/src/lib.rs
@@ -0,0 +1,127 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+#![crate_name = "enclave"]
+#![crate_type = "staticlib"]
+
+#![no_std]
+#![feature(collections)]
+
+#[macro_use]
+extern crate collections;
+
+extern crate sgx_types;
+extern crate sgx_tseal;
+extern crate sgx_trts;
+
+use sgx_types::*;
+use sgx_tseal::*;
+use sgx_trts::*;
+
+#[derive(Copy, Clone, Default, Debug)]
+struct RandData {
+    key: u32,
+    rand: [u8; 16],
+}
+
+extern {
+    fn ocall_print_string(str: * const c_uchar, len: size_t);
+}
+
+#[no_mangle]
+pub extern "C" fn create_sealeddata(sealed_log: * mut u8, sealed_log_size: u32) -> sgx_status_t {
+
+    let mut data = RandData::default();
+    data.key = 0x1234;
+    let error = rsgx_read_rand(&mut data.rand);
+    if error.is_err() {
+        return error.unwrap_err();
+    } 
+
+    let aad: [u8; 0] = [0_u8; 0];
+    let result = SgxSealedData::<RandData>::seal_data(&aad, &data);
+    let sealed_data = match result {
+        Ok(x) => x,
+        Err(ret) => {
+            return ret;
+        }, 
+    };
+
+    let opt = to_sealed_log(&sealed_data, sealed_log, sealed_log_size);
+    if opt.is_none() {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    
+    let outstring = format!("{:?}", data);
+    output(&outstring);
+    
+    sgx_status_t::SGX_SUCCESS
+}
+
+#[no_mangle]
+pub extern "C" fn verify_sealeddata(sealed_log: * mut u8, sealed_log_size: u32) -> sgx_status_t {
+
+    let opt = from_sealed_log::<RandData>(sealed_log, sealed_log_size);
+    let sealed_data = match opt {
+        Some(x) => x,
+        None => {
+            return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+        },
+    };
+    
+    let result = sealed_data.unseal_data();
+    let unsealed_data = match result {
+        Ok(x) => x,
+        Err(ret) => {
+            return ret;
+        }, 
+    };
+
+    let data = unsealed_data.get_decrypt_txt();
+    let outstring = format!("{:?}", data);
+    output(&outstring);
+
+    sgx_status_t::SGX_SUCCESS
+}
+
+fn output(outstr: &str) {
+    unsafe {
+        ocall_print_string(outstr.as_ptr() as *const c_uchar, outstr.len() as size_t);
+    }
+}
+
+fn to_sealed_log<T>(sealed_data: &SgxSealedData<T>, sealed_log: * mut u8, sealed_log_size: u32) -> Option<* mut sgx_sealed_data_t> {
+    unsafe {
+        sealed_data.to_raw_sealed_data_t(sealed_log as * mut sgx_sealed_data_t, sealed_log_size)
+    }
+}
+fn from_sealed_log<T: Copy>(sealed_log: * mut u8, sealed_log_size: u32) -> Option<SgxSealedData<T>> {
+    unsafe {
+        SgxSealedData::<T>::from_raw_sealed_data_t(sealed_log as * mut sgx_sealed_data_t, sealed_log_size)
+    }
+}
\ No newline at end of file
diff --git a/samplecode/sealeddata/lib/readme.txt b/samplecode/sealeddata/lib/readme.txt
new file mode 100644
index 0000000..7951405
--- /dev/null
+++ b/samplecode/sealeddata/lib/readme.txt
@@ -0,0 +1 @@
+lib
\ No newline at end of file
diff --git a/samplecode/thread/Makefile b/samplecode/thread/Makefile
new file mode 100644
index 0000000..eceee66
--- /dev/null
+++ b/samplecode/thread/Makefile
@@ -0,0 +1,180 @@
+# Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * 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.
+#  * Neither the name of Baidu, Inc., nor the names of its
+#    contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+
+######## SGX SDK Settings ########
+
+SGX_SDK ?= /opt/intel/sgxsdk
+SGX_MODE ?= HW
+SGX_ARCH ?= x64
+
+ifeq ($(shell getconf LONG_BIT), 32)
+	SGX_ARCH := x86
+else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
+	SGX_ARCH := x86
+endif
+
+ifeq ($(SGX_ARCH), x86)
+	SGX_COMMON_CFLAGS := -m32
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
+else
+	SGX_COMMON_CFLAGS := -m64
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
+endif
+
+ifeq ($(SGX_DEBUG), 1)
+ifeq ($(SGX_PRERELEASE), 1)
+$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
+endif
+endif
+
+
+ifeq ($(SGX_DEBUG), 1)
+	SGX_COMMON_CFLAGS += -O0 -g
+else
+	SGX_COMMON_CFLAGS += -O2
+endif
+
+######## CUSTOM Settings ########
+
+CUSTOM_LIBRARY_PATH := ./lib
+CUSTOM_BIN_PATH := ./bin
+
+######## EDL Settings ########
+
+Enclave_EDL_Files := enclave/Enclave_t.c enclave/Enclave_t.h app/Enclave_u.c app/Enclave_u.h
+
+######## APP Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Urts_Library_Name := sgx_urts_sim
+else
+	Urts_Library_Name := sgx_urts
+endif
+
+App_Cpp_Files := $(wildcard ./app/*.cpp)
+App_Include_Paths := -I ./app -I./include -I$(SGX_SDK)/include
+App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
+App_Cpp_Flags := $(App_C_Flags) -std=c++11
+App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread 
+ifneq ($(SGX_MODE), HW)
+	App_Link_Flags += -lsgx_uae_service_sim
+else
+	App_Link_Flags += -lsgx_uae_service
+endif
+
+App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
+
+App_Name := bin/app
+
+######## Enclave Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Trts_Library_Name := sgx_trts_sim
+	Service_Library_Name := sgx_tservice_sim
+else
+	Trts_Library_Name := sgx_trts
+	Service_Library_Name := sgx_tservice
+endif
+Crypto_Library_Name := sgx_tcrypto
+KeyExchange_Library_Name := sgx_tkey_exchange
+
+RustEnclave_C_Files := $(wildcard ./enclave/*.c)
+RustEnclave_C_Objects := $(RustEnclave_C_Files:.c=.o)
+RustEnclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport -I$(SGX_SDK)/include/epid -I ./enclave -I./include
+
+RustEnclave_Link_Libs := -L$(CUSTOM_LIBRARY_PATH) -lcompiler-rt-patch -lenclave
+RustEnclave_Compile_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(RustEnclave_Include_Paths)
+RustEnclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
+	-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
+	-Wl,--start-group -lsgx_tstdc -lsgx_tstdcxx -l$(Crypto_Library_Name) -l$(KeyExchange_Library_Name) -l$(Service_Library_Name) $(RustEnclave_Link_Libs) -Wl,--end-group \
+	-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
+	-Wl,-pie,-eenclave_entry -Wl,--export-dynamic  \
+	-Wl,--defsym,__ImageBase=0 \
+	-Wl,--gc-sections \
+	-Wl,--version-script=enclave/Enclave.lds
+
+
+RustEnclave_Name := enclave/enclave.so
+Signed_RustEnclave_Name := bin/enclave.signed.so
+
+.PHONY: all
+all: $(Enclave_EDL_Files) $(App_Name) $(Signed_RustEnclave_Name)
+
+######## EDL Objects ########
+
+$(Enclave_EDL_Files): $(SGX_EDGER8R) enclave/Enclave.edl
+	$(SGX_EDGER8R) --trusted enclave/Enclave.edl --search-path $(SGX_SDK)/include --trusted-dir enclave
+	$(SGX_EDGER8R) --untrusted enclave/Enclave.edl --search-path $(SGX_SDK)/include --untrusted-dir app
+	@echo "GEN  =>  $(Enclave_EDL_Files)"
+
+######## App Objects ########
+
+app/Enclave_u.o: app/Enclave_u.c
+	@$(CC) $(App_C_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+app/%.o: app/%.cpp
+	@$(CXX) $(App_Cpp_Flags) -c $< -o $@
+	@echo "CXX  <=  $<"
+
+$(App_Name): app/Enclave_u.o $(App_Cpp_Objects)
+	@$(CXX) $^ -o $@ $(App_Link_Flags)
+	@echo "LINK =>  $@"
+
+######## Enclave Objects ########
+
+enclave/Enclave_t.o: enclave/Enclave_t.c
+	@$(CC) $(RustEnclave_Compile_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+$(RustEnclave_Name): enclave compiler-rt enclave/Enclave_t.o 
+	cp ./enclave/target/release/libenclave.a ./lib
+	cp ../../compiler-rt/libcompiler-rt-patch.a ./lib
+	@$(CXX) enclave/Enclave_t.o -o $@ $(RustEnclave_Link_Flags)
+	@echo "LINK =>  $@"
+
+$(Signed_RustEnclave_Name): $(RustEnclave_Name)
+	@$(SGX_ENCLAVE_SIGNER) sign -key enclave/Enclave_private.pem -enclave $(RustEnclave_Name) -out $@ -config enclave/Enclave.config.xml
+	@echo "SIGN =>  $@"
+
+.PHONY: enclave
+enclave:
+	$(MAKE) -C ./enclave/
+	
+.PHONY: compiler-rt
+compiler-rt:
+	$(MAKE) -C ../../compiler-rt/ 2> /dev/null
+	
+.PHONY: clean
+clean:
+	@rm -f $(App_Name) $(RustEnclave_Name) $(Signed_RustEnclave_Name) $(RustEnclave_C_Objects) $(App_Cpp_Objects) enclave/*_t.* app/*_u.* lib/*.a
+	
diff --git a/samplecode/thread/app/App.cpp b/samplecode/thread/app/App.cpp
new file mode 100644
index 0000000..76359ab
--- /dev/null
+++ b/samplecode/thread/app/App.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2011-2016 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+# include <unistd.h>
+# include <pwd.h>
+# define MAX_PATH FILENAME_MAX
+
+#include "sgx_urts.h"
+#include "App.h"
+#include "Enclave_u.h"
+
+/* Global EID shared by multiple threads */
+sgx_enclave_id_t global_eid = 0;
+
+typedef struct _sgx_errlist_t {
+    sgx_status_t err;
+    const char *msg;
+    const char *sug; /* Suggestion */
+} sgx_errlist_t;
+
+/* Error code returned by sgx_create_enclave */
+static sgx_errlist_t sgx_errlist[] = {
+    {
+        SGX_ERROR_UNEXPECTED,
+        "Unexpected error occurred.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_PARAMETER,
+        "Invalid parameter.",
+        NULL
+    },
+    {
+        SGX_ERROR_OUT_OF_MEMORY,
+        "Out of memory.",
+        NULL
+    },
+    {
+        SGX_ERROR_ENCLAVE_LOST,
+        "Power transition occurred.",
+        "Please refer to the sample \"PowerTransition\" for details."
+    },
+    {
+        SGX_ERROR_INVALID_ENCLAVE,
+        "Invalid enclave image.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_ENCLAVE_ID,
+        "Invalid enclave identification.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_SIGNATURE,
+        "Invalid enclave signature.",
+        NULL
+    },
+    {
+        SGX_ERROR_OUT_OF_EPC,
+        "Out of EPC memory.",
+        NULL
+    },
+    {
+        SGX_ERROR_NO_DEVICE,
+        "Invalid SGX device.",
+        "Please make sure SGX module is enabled in the BIOS, and install SGX driver afterwards."
+    },
+    {
+        SGX_ERROR_MEMORY_MAP_CONFLICT,
+        "Memory map conflicted.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_METADATA,
+        "Invalid enclave metadata.",
+        NULL
+    },
+    {
+        SGX_ERROR_DEVICE_BUSY,
+        "SGX device was busy.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_VERSION,
+        "Enclave version was invalid.",
+        NULL
+    },
+    {
+        SGX_ERROR_INVALID_ATTRIBUTE,
+        "Enclave was not authorized.",
+        NULL
+    },
+    {
+        SGX_ERROR_ENCLAVE_FILE_ACCESS,
+        "Can't open enclave file.",
+        NULL
+    },
+};
+
+/* Check error conditions for loading enclave */
+void print_error_message(sgx_status_t ret)
+{
+    size_t idx = 0;
+    size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0];
+
+    for (idx = 0; idx < ttl; idx++) {
+        if(ret == sgx_errlist[idx].err) {
+            if(NULL != sgx_errlist[idx].sug)
+                printf("Info: %s\n", sgx_errlist[idx].sug);
+            printf("Error: %s\n", sgx_errlist[idx].msg);
+            break;
+        }
+    }
+    
+    if (idx == ttl)
+        printf("Error: Unexpected error occurred.\n");
+}
+
+/* Initialize the enclave:
+ *   Step 1: try to retrieve the launch token saved by last transaction
+ *   Step 2: call sgx_create_enclave to initialize an enclave instance
+ *   Step 3: save the launch token if it is updated
+ */
+int initialize_enclave(void)
+{
+    char token_path[MAX_PATH] = {'\0'};
+    sgx_launch_token_t token = {0};
+    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
+    int updated = 0;
+    
+    /* Step 1: try to retrieve the launch token saved by last transaction 
+     *         if there is no token, then create a new one.
+     */
+    /* try to get the token saved in $HOME */
+    const char *home_dir = getpwuid(getuid())->pw_dir;
+    
+    if (home_dir != NULL && 
+        (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) {
+        /* compose the token path */
+        strncpy(token_path, home_dir, strlen(home_dir));
+        strncat(token_path, "/", strlen("/"));
+        strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1);
+    } else {
+        /* if token path is too long or $HOME is NULL */
+        strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME));
+    }
+
+    FILE *fp = fopen(token_path, "rb");
+    if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
+        printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
+    }
+
+    if (fp != NULL) {
+        /* read the token from saved file */
+        size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
+        if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
+            /* if token is invalid, clear the buffer */
+            memset(&token, 0x0, sizeof(sgx_launch_token_t));
+            printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
+        }
+    }
+    /* Step 2: call sgx_create_enclave to initialize an enclave instance */
+    /* Debug Support: set 2nd parameter to 1 */
+    ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
+    if (ret != SGX_SUCCESS) {
+        print_error_message(ret);
+        if (fp != NULL) fclose(fp);
+        return -1;
+    }
+
+    /* Step 3: save the launch token if it is updated */
+    if (updated == FALSE || fp == NULL) {
+        /* if the token is not updated, or file handler is invalid, do not perform saving */
+        if (fp != NULL) fclose(fp);
+        return 0;
+    }
+
+    /* reopen the file with write capablity */
+    fp = freopen(token_path, "wb", fp);
+    if (fp == NULL) return 0;
+    size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
+    if (write_num != sizeof(sgx_launch_token_t))
+        printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
+    fclose(fp);
+    return 0;
+}
+
+/* OCall functions */
+void ocall_print_string(const char *str, size_t len)
+{
+    char * string = (char *)malloc(len + (size_t)sizeof(char));
+    if (string == NULL) {
+    	printf("malloc failed\n");
+    	return;
+    }
+    
+    memcpy(string, str, len);
+    char * ptr = string + len;
+    * ptr = 0;
+    printf("%s\n", string);
+    free(string);
+}
+
+/* Application entry */
+int SGX_CDECL main(int argc, char *argv[])
+{
+    (void)(argc);
+    (void)(argv);
+
+
+    /* Initialize the enclave */
+    if(initialize_enclave() < 0){
+        printf("Enter a character before exit ...\n");
+        getchar();
+        return -1; 
+    }
+ 
+    ecall_thread_functions();
+
+    /* Destroy the enclave */
+    sgx_destroy_enclave(global_eid);
+    
+    printf("Info: SampleEnclave successfully returned.\n");
+
+    printf("Enter a character before exit ...\n");
+    getchar();
+    return 0;
+}
+
diff --git a/samplecode/thread/app/App.h b/samplecode/thread/app/App.h
new file mode 100644
index 0000000..2be16e0
--- /dev/null
+++ b/samplecode/thread/app/App.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011-2016 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 _APP_H_
+#define _APP_H_
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "sgx_error.h"       /* sgx_status_t */
+#include "sgx_eid.h"     /* sgx_enclave_id_t */
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+# define TOKEN_FILENAME   "enclave.token"
+# define ENCLAVE_FILENAME "enclave.signed.so"
+
+extern sgx_enclave_id_t global_eid;    /* global enclave id */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void ecall_thread_functions(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_APP_H_ */
diff --git a/samplecode/thread/app/Thread.cpp b/samplecode/thread/app/Thread.cpp
new file mode 100644
index 0000000..396ee9e
--- /dev/null
+++ b/samplecode/thread/app/Thread.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2011-2016 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 <thread>
+#include <stdio.h>
+using namespace std;
+
+#include "App.h"
+#include "Enclave_u.h"
+
+void data_producer(void)
+{
+    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
+    ret = ecall_producer(global_eid);
+    if (ret != SGX_SUCCESS)
+        abort();
+}
+
+void data_consumer(void)
+{
+    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
+    ret = ecall_consumer(global_eid);
+    if (ret != SGX_SUCCESS)
+        abort();
+}
+
+void data_init(void)
+{
+    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
+    ret = ecall_initialize(global_eid);
+    if (ret != SGX_SUCCESS)
+        abort();
+}
+
+void data_uninit(void)
+{
+    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
+    ret = ecall_uninitialize(global_eid);
+    if (ret != SGX_SUCCESS)
+        abort();
+}
+
+/* ecall_thread_functions:
+ *   Invokes thread functions including mutex, condition variable, etc.
+ */
+void ecall_thread_functions(void)
+{
+    data_init();
+
+    printf("Info: executing thread synchronization, please wait...  \n");
+    /* condition variable */
+    thread consumer1(data_consumer);
+    thread producer0(data_producer);
+    thread producer1(data_producer);
+    thread producer2(data_producer);
+    thread producer3(data_producer);
+    thread consumer2(data_consumer);
+    thread consumer3(data_consumer);
+    thread consumer4(data_consumer);
+    
+    consumer1.join();
+    consumer2.join();
+    consumer3.join();
+    consumer4.join();
+    producer0.join();
+    producer1.join();
+    producer2.join();
+    producer3.join();
+
+    printf("Info: thread finish...  \n");
+
+    data_uninit();
+}
diff --git a/samplecode/thread/bin/readme.txt b/samplecode/thread/bin/readme.txt
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/samplecode/thread/bin/readme.txt
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/samplecode/thread/enclave/Cargo.toml b/samplecode/thread/enclave/Cargo.toml
new file mode 100644
index 0000000..b339e06
--- /dev/null
+++ b/samplecode/thread/enclave/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "enclave"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[lib]
+name = "enclave"
+crate-type = ["staticlib"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_tstdc = { path = "../../../sgx_tstdc" }
\ No newline at end of file
diff --git a/samplecode/thread/enclave/Enclave.config.xml b/samplecode/thread/enclave/Enclave.config.xml
new file mode 100644
index 0000000..a94d12f
--- /dev/null
+++ b/samplecode/thread/enclave/Enclave.config.xml
@@ -0,0 +1,12 @@
+<!-- Please refer to User's Guide for the explanation of each field -->
+<EnclaveConfiguration>
+  <ProdID>0</ProdID>
+  <ISVSVN>0</ISVSVN>
+  <StackMaxSize>0x40000</StackMaxSize>
+  <HeapMaxSize>0x100000</HeapMaxSize>
+  <TCSNum>10</TCSNum>
+  <TCSPolicy>1</TCSPolicy>
+  <DisableDebug>0</DisableDebug>
+  <MiscSelect>0</MiscSelect>
+  <MiscMask>0xFFFFFFFF</MiscMask>
+</EnclaveConfiguration>
diff --git a/samplecode/thread/enclave/Enclave.edl b/samplecode/thread/enclave/Enclave.edl
new file mode 100644
index 0000000..dbcdf7e
--- /dev/null
+++ b/samplecode/thread/enclave/Enclave.edl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Baidu, Inc., nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *
+ */
+
+/* Thread.edl - EDL sample for trusted thread library. */
+
+enclave {
+
+    /*
+    from "sgx_tstdc.edl" import sgx_thread_wait_untrusted_event_ocall, sgx_thread_set_untrusted_event_ocall, sgx_thread_setwait_untrusted_events_ocall, sgx_thread_set_multiple_untrusted_events_ocall;
+    */
+    from "sgx_tstdc.edl" import *;
+
+    trusted {
+        public void ecall_initialize();
+        public void ecall_uninitialize();
+
+        /*
+         * Use SGX condition variables.
+         */
+        public void ecall_producer();
+        public void ecall_consumer();
+
+    };
+
+    untrusted {
+        void ocall_print_string([in, size=len] const char* str, size_t len);
+    };
+};
diff --git a/samplecode/thread/enclave/Enclave.lds b/samplecode/thread/enclave/Enclave.lds
new file mode 100644
index 0000000..eb09b70
--- /dev/null
+++ b/samplecode/thread/enclave/Enclave.lds
@@ -0,0 +1,9 @@
+libTestEnclave.so
+{
+    global:
+        g_global_data_sim;
+        g_global_data;
+        enclave_entry;
+    local:
+        *;
+};
diff --git a/samplecode/thread/enclave/Enclave_private.pem b/samplecode/thread/enclave/Enclave_private.pem
new file mode 100644
index 0000000..529d07b
--- /dev/null
+++ b/samplecode/thread/enclave/Enclave_private.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ
+AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ
+ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr
+nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b
+3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H
+ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD
+5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW
+KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC
+1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe
+K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z
+AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q
+ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6
+JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826
+5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02
+wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9
+osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm
+WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i
+Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9
+xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd
+vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD
+Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a
+cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC
+0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ
+gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo
+gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t
+k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz
+Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6
+O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5
+afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom
+e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G
+BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv
+fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN
+t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9
+yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp
+6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg
+WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH
+NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk=
+-----END RSA PRIVATE KEY-----
diff --git a/samplecode/thread/enclave/Makefile b/samplecode/thread/enclave/Makefile
new file mode 100644
index 0000000..3953ca0
--- /dev/null
+++ b/samplecode/thread/enclave/Makefile
@@ -0,0 +1,37 @@
+# Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#  * 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.
+#  * Neither the name of Baidu, Inc., nor the names of its
+#    contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+#
+# 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
+# OWNER 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.
+
+Rust_Enclave_Name := libenclave.a
+Rust_Enclave_Files := $(wildcard src/*.rs)
+
+.PHONY: all
+
+all: $(Rust_Enclave_Name)
+
+$(Rust_Enclave_Name): $(Rust_Enclave_Files)  
+	cargo build --release
diff --git a/samplecode/thread/enclave/src/lib.rs b/samplecode/thread/enclave/src/lib.rs
new file mode 100644
index 0000000..79f2d8e
--- /dev/null
+++ b/samplecode/thread/enclave/src/lib.rs
@@ -0,0 +1,153 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+#![crate_name = "enclave"]
+#![crate_type = "staticlib"]
+
+#![no_std]
+#![feature(const_fn, alloc)]
+
+extern crate alloc;
+use alloc::boxed::Box;
+use core::sync::atomic::{AtomicPtr, Ordering};
+
+extern crate sgx_types;
+extern crate sgx_tstdc;
+
+use sgx_types::*;
+use sgx_tstdc::*;
+
+extern {
+    fn ocall_print_string(str: *const c_uchar, len: size_t);
+}
+
+const BUFFER_SIZE: usize      = 50;
+const LOOPS_PER_THREAD: usize = 500;
+
+struct CondBuffer{
+    buf: [usize; BUFFER_SIZE],
+    occupied: i32,
+    nextin: usize,
+    nextout: usize,
+}
+
+impl Default for CondBuffer {
+    fn default() -> CondBuffer {
+        CondBuffer {
+            buf: [0; BUFFER_SIZE],
+            occupied: 0,
+            nextin: 0,
+            nextout: 0,
+        }
+    }
+}
+
+static GLOBAL_COND_BUFFER: AtomicPtr<()> = AtomicPtr::new(0 as * mut ());
+
+#[no_mangle]
+pub extern "C" fn ecall_initialize() {
+
+    let lock = Box::new((SgxMutex::<CondBuffer>::new(CondBuffer::default()), SgxCond::new(), SgxCond::new()));
+    let ptr = Box::into_raw(lock);
+    GLOBAL_COND_BUFFER.store(ptr as *mut (), Ordering::SeqCst);
+}
+
+#[no_mangle]
+pub extern "C" fn ecall_uninitialize() {
+
+    let ptr = GLOBAL_COND_BUFFER.swap(0 as * mut (), Ordering::SeqCst) as * mut (SgxMutex<CondBuffer>, SgxCond, SgxCond);
+    if ptr.is_null() {
+       return;
+    } 
+    let _ = unsafe { Box::from_raw(ptr) };
+}
+
+fn get_ref_cond_buffer() -> Option<&'static (SgxMutex<CondBuffer>, SgxCond, SgxCond)>
+{
+    let ptr = GLOBAL_COND_BUFFER.load(Ordering::SeqCst) as * mut (SgxMutex<CondBuffer>, SgxCond, SgxCond);
+    if ptr.is_null() {
+        None
+    } else {
+        Some(unsafe { &* ptr })  
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn ecall_producer() {
+
+    let max_index = 4 * LOOPS_PER_THREAD;
+    let &(ref mutex, ref more, ref less) = get_ref_cond_buffer().unwrap();
+
+    for _ in 0..max_index {
+            
+        let mut guard = mutex.lock().unwrap();
+
+        while guard.occupied >= BUFFER_SIZE as i32 {
+            guard = less.wait(guard).unwrap();
+        }
+            
+        let index = guard.nextin;
+        guard.buf[index] = guard.nextin;
+        guard.nextin += 1;
+        guard.nextin %= BUFFER_SIZE;
+        guard.occupied += 1;
+
+        let _ = more.signal();
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn ecall_consumer() {
+
+    let max_index = 4 * LOOPS_PER_THREAD;
+    let &(ref mutex, ref more, ref less) = get_ref_cond_buffer().unwrap();
+
+    for _ in 0..max_index {
+            
+        let mut guard = mutex.lock().unwrap();
+
+        while guard.occupied <= 0 {
+            guard = more.wait(guard).unwrap();
+        }
+
+        let index = guard.nextout;
+        guard.buf[index] = 0;
+        guard.nextout += 1;
+        guard.nextout %= BUFFER_SIZE;
+        guard.occupied -= 1;
+
+        let _ = less.signal();
+    }
+}
+
+#[allow(dead_code)]
+fn output(outstr: &str) {
+    unsafe {
+        ocall_print_string(outstr.as_ptr() as *const c_uchar, outstr.len() as size_t);
+    }
+}
diff --git a/samplecode/thread/lib/readme.txt b/samplecode/thread/lib/readme.txt
new file mode 100644
index 0000000..7951405
--- /dev/null
+++ b/samplecode/thread/lib/readme.txt
@@ -0,0 +1 @@
+lib
\ No newline at end of file
diff --git a/sgx_tcrypto/Cargo.toml b/sgx_tcrypto/Cargo.toml
new file mode 100644
index 0000000..e401c2c
--- /dev/null
+++ b/sgx_tcrypto/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "sgx_tcrypto"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../sgx_types" }
diff --git a/sgx_tcrypto/src/crypto.rs b/sgx_tcrypto/src/crypto.rs
new file mode 100644
index 0000000..7e528af
--- /dev/null
+++ b/sgx_tcrypto/src/crypto.rs
@@ -0,0 +1,1991 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//!
+//! Cryptographic Functions
+//!
+use sgx_types::*;
+use core::ops::{Drop, DerefMut};
+use core::ptr;
+use core::mem;
+use core::cell::{Cell, RefCell};
+
+///
+/// The rsgx_sha256_msg function performs a standard SHA256 hash over the input data buffer.
+///
+/// # Description
+/// 
+/// The rsgx_sha256_msg function performs a standard SHA256 hash over the input data buffer. 
+/// Only a 256-bit version of the SHA hash is supported. (Other sizes, for example 512, are 
+/// not supported in this minimal cryptography library).
+///
+/// The function should be used if the complete input data stream is available.
+/// Otherwise, the Init, Update… Update, Final procedure should be used to compute
+/// a SHA256 bit hash over multiple input data sets.
+/// 
+/// # Parameters
+///
+/// **src**
+///
+/// A pointer to the input data stream to be hashed.
+///
+/// # Requirements
+///
+/// Library: libsgx_tcrypto.a
+///
+/// # Return value
+///
+/// The 256-bit hash that has been SHA256 calculated
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Input pointers are invalid.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Not enough memory is available to complete this operation.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// The SHA256 hash calculation failed.
+///
+pub fn rsgx_sha256_msg<T: Copy>(src: &T) -> SgxResult<sgx_sha256_hash_t> {
+    
+    let size = mem::size_of::<T>();
+    if size == 0 {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    if size > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+
+    let mut hash = sgx_sha256_hash_t::default();
+    let ret = unsafe { sgx_sha256_msg(src as * const _ as * const u8, size as u32, &mut hash as * mut sgx_sha256_hash_t) };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(hash),
+        _ => Err(ret),
+    }
+}
+
+///
+/// The rsgx_sha256_slice function performs a standard SHA256 hash over the input data buffer.
+///
+pub fn rsgx_sha256_slice<T: Copy>(src: &[T]) -> SgxResult<sgx_sha256_hash_t> {
+    
+    let size = mem::size_of::<T>() * src.len();
+    if size == 0 {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    if size > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+
+    let mut hash = sgx_sha256_hash_t::default();
+    let ret = unsafe { sgx_sha256_msg(src.as_ptr() as * const u8, size as u32, &mut hash as * mut sgx_sha256_hash_t) };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(hash),
+        _ => Err(ret),
+    }
+}
+
+fn rsgx_sha256_init(sha_handle: &mut sgx_sha_state_handle_t) -> sgx_status_t {
+
+    unsafe { 
+        sgx_sha256_init(sha_handle as * mut _ as * mut sgx_sha_state_handle_t) 
+    }
+}
+
+fn rsgx_sha256_update_msg<T: Copy>(src: &T, sha_handle: sgx_sha_state_handle_t) -> sgx_status_t {
+
+    let size = mem::size_of::<T>();
+    if size == 0 {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    if size > u32::max_value() as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    unsafe { 
+        sgx_sha256_update(src as * const _ as * const u8, size as u32, sha_handle) 
+    }
+}
+
+fn rsgx_sha256_update_slice<T: Copy>(src: &[T], sha_handle: sgx_sha_state_handle_t) -> sgx_status_t {
+
+    let size = mem::size_of::<T>() * src.len();
+    if size == 0 {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    if size > u32::max_value() as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    unsafe {
+        sgx_sha256_update(src.as_ptr() as * const u8, size as u32, sha_handle)
+    }
+}
+
+fn rsgx_sha256_get_hash(sha_handle: sgx_sha_state_handle_t, hash: &mut sgx_sha256_hash_t) -> sgx_status_t {
+    
+    unsafe { sgx_sha256_get_hash(sha_handle, hash as * mut sgx_sha256_hash_t) }
+}
+
+fn rsgx_sha256_close(sha_handle: sgx_sha_state_handle_t) -> sgx_status_t {
+     
+     unsafe { sgx_sha256_close(sha_handle) }
+}
+
+///
+/// SHA algorithm context state.
+///
+/// This is a handle to the context state used by the cryptography library to perform an iterative SHA256 hash. 
+/// The algorithm stores the intermediate results of performing the hash calculation over data sets.
+///
+pub struct SgxShaHandle {
+    handle: RefCell<sgx_sha_state_handle_t>, 
+    initflag: Cell<bool>,
+}
+
+impl SgxShaHandle {
+
+    ///
+    /// Constructs a new, empty SgxShaHandle.
+    ///
+    pub fn new() -> Self {
+        SgxShaHandle{
+            handle: RefCell::new(ptr::null_mut() as sgx_sha_state_handle_t), 
+            initflag: Cell::new(false),
+            }
+    }
+
+    ///
+    /// init returns an allocated and initialized SHA algorithm context state.
+    ///
+    /// This should be part of the Init, Update … Update, Final process when the SHA hash is to be performed 
+    /// over multiple datasets. If a complete dataset is available, the recommend call is rsgx_sha256_msg to 
+    /// perform the hash in a single call.
+    ///
+    /// # Description
+    ///
+    /// Calling init is the first set in performing a SHA256 hash over multiple datasets. The caller does not 
+    /// allocate memory for the SHA256 state that this function returns. The state is specific to the implementation 
+    /// of the cryptography library; thus the allocation is performed by the library itself. If the hash over the 
+    /// desired datasets is completed or any error occurs during the hash calculation process, sgx_sha256_close should 
+    /// be called to free the state allocated by this algorithm.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// The SHA256 state is not initialized properly due to an internal cryptography library failure.
+    ///
+    pub fn init(&self) -> SgxError {
+
+        if self.initflag.get() == true {
+            return Ok(());
+        }
+
+        let ret = rsgx_sha256_init(self.handle.borrow_mut().deref_mut());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                self.initflag.set(true);
+                Ok(())
+            },
+            _ => Err(ret),
+        }
+    }
+    
+    ///
+    /// update_msg performs a SHA256 hash over the input dataset provided. 
+    ///
+    /// This function supports an iterative calculation of the hash over multiple datasets where the 
+    /// sha_handle contains the intermediate results of the hash calculation over previous datasets.
+    ///
+    /// # Description
+    ///
+    /// This function should be used as part of a SHA256 calculation over multiple datasets. 
+    /// If a SHA256 hash is needed over a single data set, function rsgx_sha256_msg should be used instead. 
+    /// Prior to calling this function on the first dataset, the init function must be called first to allocate 
+    /// and initialize the SHA256 state structure which will hold intermediate hash results over earlier datasets. 
+    /// The function get_hash should be used to obtain the hash after the final dataset has been processed 
+    /// by this function.
+    ///
+    /// # Parameters
+    ///
+    /// **src**
+    ///
+    /// A pointer to the input data stream to be hashed. 
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_INVALID_STATE**
+    ///
+    /// The SHA256 state is not initialized.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// An internal cryptography library failure occurred while performing the SHA256 hash calculation.
+    ///
+    pub fn update_msg<T: Copy>(&self, src: &T) -> SgxError {
+
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let ret = rsgx_sha256_update_msg(src, *self.handle.borrow());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(()),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// update_slice performs a SHA256 hash over the input dataset provided. 
+    ///
+    pub fn update_slice<T: Copy>(&self, src: &[T]) -> SgxError {
+
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let ret = rsgx_sha256_update_slice(src, *self.handle.borrow());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(()),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// get_hash obtains the SHA256 hash after the final dataset has been processed.
+    ///
+    /// # Description
+    ///
+    /// This function returns the hash after performing the SHA256 calculation over one or more datasets 
+    /// using the update function.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Return value
+    ///
+    /// The 256-bit hash that has been SHA256 calculated
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_INVALID_STATE**
+    ///
+    /// The SHA256 state is not initialized.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// The SHA256 state passed in is likely problematic causing an internal cryptography library failure.
+    ///
+    pub fn get_hash(&self) -> SgxResult<sgx_sha256_hash_t> {
+
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let mut hash = sgx_sha256_hash_t::default();
+        let ret = rsgx_sha256_get_hash(*self.handle.borrow(), &mut hash); 
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(hash),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// close cleans up and deallocates the SHA256 state that was allocated in function init.
+    ///
+    /// # Description
+    ///
+    /// Calling close is the last step after performing a SHA256 hash over multiple datasets. 
+    /// The caller uses this function to deallocate memory used to store the SHA256 calculation state.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The input handle is invalid.
+    ///
+    pub fn close(&self) -> SgxError {
+
+        if self.initflag.get() == false {
+            return Ok(());
+        }
+
+        let ret = {
+            let handle = *self.handle.borrow();
+            if handle.is_null() == true {
+                sgx_status_t::SGX_SUCCESS
+            } else {
+                rsgx_sha256_close(handle)
+            }
+        };
+         
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                self.initflag.set(false);
+                *self.handle.borrow_mut() = ptr::null_mut();
+                Ok(())
+            },
+            _ => Err(ret),
+        }
+    }
+}
+
+impl Default for SgxShaHandle {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl Drop for SgxShaHandle {
+
+    ///
+    /// drop cleans up and deallocates the SHA256 state that was allocated in function init.
+    ///
+    fn drop(&mut self) {
+        let _ = self.close();
+    }
+}
+
+///
+/// rsgx_rijndael128GCM_encrypt performs a Rijndael AES-GCM encryption operation.
+/// 
+/// Only a 128bit key size is supported by this Intel(R) SGX SDK cryptography library.
+///
+/// # Description
+/// 
+/// The Galois/Counter Mode (GCM) is a mode of operation of the AES algorithm.
+/// GCM [NIST SP 800-38D] uses a variation of the counter mode of operation for
+/// encryption. GCM assures authenticity of the confidential data (of up to about
+/// 64 GB per invocation) using a universal hash function defined over a binary
+/// finite field (the Galois field).
+///
+/// GCM can also provide authentication assurance for additional data (of practically
+/// unlimited length per invocation) that is not encrypted. GCM provides
+/// stronger authentication assurance than a (non-cryptographic) checksum or
+/// error detecting code. In particular, GCM can detect both accidental modifications
+/// of the data and intentional, unauthorized modifications.
+///
+/// It is recommended that the source and destination data buffers are allocated
+/// within the enclave. The AAD buffer could be allocated within or outside
+/// enclave memory. The use of AAD data buffer could be information identifying
+/// the encrypted data since it will remain in clear text.
+/// 
+/// # Parameters
+///
+/// **key**
+///
+/// A pointer to key to be used in the AES-GCM encryption operation. The size must be 128 bits.
+///
+/// **src**
+///
+/// A pointer to the input data stream to be encrypted. Buffer content could be empty if there is AAD text.
+///
+/// **iv**
+///
+/// A pointer to the initialization vector to be used in the AES-GCM calculation. NIST AES-GCM recommended 
+/// IV size is 96 bits (12 bytes).
+///
+/// **aad**
+///
+/// A pointer to an optional additional authentication data buffer which is used in the GCM MAC calculation. 
+/// The data in this buffer will not be encrypted. The field is optional and content could be empty.
+///
+/// **dst**
+///
+/// A pointer to the output encrypted data buffer. This buffer should be allocated by the calling code.
+///
+/// **mac**
+///
+/// This is the output GCM MAC performed over the input data buffer (data to be encrypted) as well as 
+/// the additional authentication data (this is optional data). The calling code should allocate this buffer.
+///
+/// # Requirements
+///
+/// Library: libsgx_tcrypto.a
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// If both source buffer and AAD buffer content are empty.
+///
+/// If IV Length is not equal to 12 (bytes).
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Not enough memory is available to complete this operation.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// An internal cryptography library failure occurred.
+///
+pub fn rsgx_rijndael128GCM_encrypt(key: &sgx_aes_gcm_128bit_key_t,
+                                   src: &[u8],
+                                   iv: &[u8],
+                                   aad: &[u8],
+                                   dst: &mut [u8],
+                                   mac: &mut sgx_aes_gcm_128bit_tag_t) -> SgxError {
+    
+    let src_len = src.len();
+    if src_len > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    let iv_len = iv.len();
+    if iv_len != SGX_AESGCM_IV_SIZE {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    let aad_len = aad.len();
+    if aad_len > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    let dst_len = dst.len();
+    if dst_len > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    if dst_len < src_len {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+
+    let ret = unsafe {
+        let mut p_aad: * const u8 = ptr::null();
+        if aad_len != 0 {
+            p_aad = aad.as_ptr();
+        }
+
+        let mut p_src: * const u8 = ptr::null();
+        let mut p_dst: * mut u8 = ptr::null_mut();
+        if src_len != 0 {
+            p_src = src.as_ptr();
+            p_dst = dst.as_mut_ptr();
+        }
+
+        sgx_rijndael128GCM_encrypt(key as * const sgx_aes_gcm_128bit_key_t,
+                                   p_src,
+                                   src_len as u32,
+                                   p_dst,
+                                   iv.as_ptr(),
+                                   iv_len as u32,
+                                   p_aad,
+                                   aad_len as u32,
+                                   mac as * mut sgx_aes_gcm_128bit_tag_t)
+    };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
+
+///
+/// rsgx_rijndael128GCM_decrypt performs a Rijndael AES-GCM decryption operation. 
+/// 
+/// Only a 128bit key size is supported by this Intel(R) SGX SDK cryptography library.
+///
+/// # Description
+/// 
+/// The Galois/Counter Mode (GCM) is a mode of operation of the AES algorithm.
+/// GCM [NIST SP 800-38D] uses a variation of the counter mode of operation for
+/// encryption. GCM assures authenticity of the confidential data (of up to about
+/// 64 GB per invocation) using a universal hash function defined over a binary
+/// finite field (the Galois field).
+///
+/// GCM can also provide authentication assurance for additional data (of practically
+/// unlimited length per invocation) that is not encrypted. GCM provides
+/// stronger authentication assurance than a (non-cryptographic) checksum or
+/// error detecting code. In particular, GCM can detect both accidental modifications
+/// of the data and intentional, unauthorized modifications.
+///
+/// It is recommended that the destination data buffer is allocated within the
+/// enclave. The AAD buffer could be allocated within or outside enclave memory.
+///
+/// # Parameters
+///
+/// **key**
+///
+/// A pointer to key to be used in the AES-GCM decryption operation. The size must be 128 bits.
+///
+/// **src**
+///
+/// A pointer to the input data stream to be decrypted. Buffer content could be empty if there is AAD text.
+///
+/// **iv**
+///
+/// A pointer to the initialization vector to be used in the AES-GCM calculation. NIST AES-GCM recommended 
+/// IV size is 96 bits (12 bytes).
+///
+/// **aad**
+///
+/// A pointer to an optional additional authentication data buffer which is provided for the GCM MAC calculation 
+/// when encrypting. The data in this buffer was not encrypted. The field is optional and content could be empty.
+///
+/// **mac**
+///
+/// This is the GCM MAC that was performed over the input data buffer (data to be encrypted) as well as 
+/// the additional authentication data (this is optional data) during the encryption process (call to 
+/// rsgx_rijndael128GCM_encrypt).
+///
+/// **dst**
+///
+/// A pointer to the output decrypted data buffer. This buffer should be allocated by the calling code.
+///
+/// # Requirements
+///
+/// Library: libsgx_tcrypto.a
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// If both source buffer and AAD buffer content are empty.
+///
+/// If IV Length is not equal to 12 (bytes).
+///
+/// **SGX_ERROR_MAC_MISMATCH**
+///
+/// The input MAC does not match the MAC calculated.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Not enough memory is available to complete this operation.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// An internal cryptography library failure occurred.
+///
+pub fn rsgx_rijndael128GCM_decrypt(key: &sgx_aes_gcm_128bit_key_t,
+                                   src: &[u8],
+                                   iv: &[u8],
+                                   aad: &[u8],
+                                   mac: &sgx_aes_gcm_128bit_tag_t,
+                                   dst: &mut [u8]) -> SgxError {
+
+    let src_len = src.len();
+    if src_len > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    let iv_len = iv.len();
+    if iv_len != SGX_AESGCM_IV_SIZE {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    let aad_len = aad.len();
+    if aad_len > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    let dst_len = dst.len();
+    if dst_len > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    if dst_len < src_len {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+
+    let ret = unsafe {
+        let mut p_aad: * const u8 =  ptr::null();
+        if aad.len() != 0 {
+            p_aad = aad.as_ptr();
+        }
+
+        let mut p_src: * const u8 = ptr::null();
+        let mut p_dst: * mut u8 = ptr::null_mut();
+        if src.len() != 0 {
+            p_src = src.as_ptr();
+            p_dst = dst.as_mut_ptr();
+        }
+
+        sgx_rijndael128GCM_decrypt(key as * const sgx_aes_gcm_128bit_key_t,
+                                   p_src,
+                                   src_len as u32,
+                                   p_dst,
+                                   iv.as_ptr(),
+                                   iv_len as u32,
+                                   p_aad,
+                                   aad_len as u32,
+                                   mac as * const sgx_aes_gcm_128bit_tag_t)
+    };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
+
+///
+/// The rsgx_rijndael128_cmac_msg function performs a standard 128bit CMAC hash over the input data buffer.
+///
+/// # Description
+/// 
+/// The rsgx_rijndael128_cmac_msg function performs a standard CMAC hash over the input data buffer. 
+/// Only a 128-bit version of the CMAC hash is supported.
+///
+/// The function should be used if the complete input data stream is available.
+/// Otherwise, the Init, Update… Update, Final procedure should be used to compute
+/// a CMAC hash over multiple input data sets.
+///
+/// # Parameters
+///
+/// **key**
+///
+/// A pointer to key to be used in the CMAC hash operation. The size must be 128 bits.
+///
+/// **src**
+///
+/// A pointer to the input data stream to be hashed.
+///
+/// # Requirements
+///
+/// Library: libsgx_tcrypto.a
+///
+/// # Return value
+///
+/// The 128-bit hash that has been CMAC calculated
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// The pointer is invalid.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Not enough memory is available to complete this operation.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// An internal cryptography library failure occurred.
+///
+pub fn rsgx_rijndael128_cmac_msg<T: Copy>(key: &sgx_cmac_128bit_key_t, src: &T) -> SgxResult<sgx_cmac_128bit_tag_t> {
+    
+    let size = mem::size_of::<T>();
+    if size == 0 {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    if size > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+
+    let mut mac = sgx_cmac_128bit_tag_t::default();
+    let ret = unsafe {
+        sgx_rijndael128_cmac_msg(key as * const sgx_cmac_128bit_key_t, 
+                                 src as * const _ as * const u8, 
+                                 size as u32, 
+                                 &mut mac as * mut sgx_cmac_128bit_tag_t)
+    };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(mac),
+        _ => Err(ret),
+    }
+}
+
+///
+/// The rsgx_rijndael128_cmac_slice function performs a standard 128bit CMAC hash over the input data buffer.
+///
+pub fn rsgx_rijndael128_cmac_slice<T: Copy>(key: &sgx_cmac_128bit_key_t, src: &[T]) -> SgxResult<sgx_cmac_128bit_tag_t> {
+    
+    let size = mem::size_of::<T>() * src.len();
+    if size == 0 {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    if size > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+
+    let mut mac = sgx_cmac_128bit_tag_t::default();
+    let ret = unsafe {
+        sgx_rijndael128_cmac_msg(key as * const sgx_cmac_128bit_key_t, 
+                                 src.as_ptr() as * const u8,
+                                 size as u32, 
+                                 &mut mac as * mut sgx_cmac_128bit_tag_t)
+    }; 
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(mac),
+        _ => Err(ret),
+    }
+}
+
+fn rsgx_cmac128_init(key: &sgx_cmac_128bit_key_t, cmac_handle: &mut sgx_cmac_state_handle_t) -> sgx_status_t {
+    
+    unsafe {
+        sgx_cmac128_init(key as * const sgx_cmac_128bit_key_t, 
+                         cmac_handle as * mut _ as * mut sgx_cmac_state_handle_t)
+    }
+}
+
+fn rsgx_cmac128_update_msg<T: Copy>(src: &T, cmac_handle: sgx_cmac_state_handle_t) -> sgx_status_t {
+
+    let size = mem::size_of::<T>();
+    if size == 0 {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    if size > u32::max_value() as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    unsafe {
+        sgx_cmac128_update(src as * const _ as * const u8, size as u32, cmac_handle)
+    }
+}
+
+fn rsgx_cmac128_update_slice<T: Copy>(src: &[T], cmac_handle: sgx_cmac_state_handle_t) -> sgx_status_t {
+
+    let size = mem::size_of::<T>() * src.len();
+    if size == 0 {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    if size > u32::max_value() as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    unsafe {
+        sgx_cmac128_update(src.as_ptr() as * const _ as * const u8, size as u32, cmac_handle)
+    }
+}
+
+fn rsgx_cmac128_final(cmac_handle: sgx_cmac_state_handle_t, hash: &mut sgx_cmac_128bit_tag_t) -> sgx_status_t {
+    
+    unsafe { sgx_cmac128_final(cmac_handle, hash as * mut sgx_cmac_128bit_tag_t) }
+}
+
+fn rsgx_cmac128_close(cmac_handle: sgx_cmac_state_handle_t) -> sgx_status_t {
+    
+    unsafe { sgx_cmac128_close(cmac_handle) }
+}
+
+///
+/// CMAC algorithm context state.
+///
+/// This is a handle to the context state used by the cryptography library to perform an 
+/// iterative CMAC 128-bit hash. The algorithm stores the intermediate results of performing 
+/// the hash calculation over data sets.
+///
+pub struct SgxCmacHandle {
+    handle: RefCell<sgx_cmac_state_handle_t>, 
+    initflag: Cell<bool>,
+}
+
+impl SgxCmacHandle {
+
+    ///
+    /// Constructs a new, empty SgxCmacHandle.
+    ///
+    pub fn new() -> Self {
+        SgxCmacHandle{
+            handle: RefCell::new(ptr::null_mut() as sgx_cmac_state_handle_t), 
+            initflag: Cell::new(false),
+            }
+    }
+
+    ///
+    /// init returns an allocated and initialized CMAC algorithm context state. 
+    ///
+    /// This should be part of the Init, Update … Update, Final process when the CMAC hash is to be 
+    /// performed over multiple datasets. If a complete dataset is available, the recommended call 
+    /// is rsgx_rijndael128_cmac_msg to perform the hash in a single call.
+    ///
+    /// # Description
+    ///
+    /// Calling init is the first set in performing a CMAC 128-bit hash over multiple datasets. 
+    /// The caller does not allocate memory for the CMAC state that this function returns. 
+    /// The state is specific to the implementation of the cryptography library and thus the 
+    /// allocation is performed by the library itself. If the hash over the desired datasets is 
+    /// completed or any error occurs during the hash calculation process, sgx_cmac128_close should
+    /// be called to free the state allocated by this algorithm.
+    ///
+    /// # Parameters
+    ///
+    /// **key**
+    /// 
+    /// A pointer to key to be used in the CMAC hash operation. The size must be 128 bits.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// An internal cryptography library failure occurred.
+    ///
+    pub fn init(&self, key: &sgx_cmac_128bit_key_t) -> SgxError {
+        
+        if self.initflag.get() == true {
+            return Ok(());
+        }
+
+        let ret = rsgx_cmac128_init(key, self.handle.borrow_mut().deref_mut());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                self.initflag.set(true);
+                Ok(())
+            },
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// update_msg performs a CMAC 128-bit hash over the input dataset provided. 
+    ///
+    /// This function supports an iterative calculation of the hash over multiple datasets where the 
+    /// cmac_handle contains the intermediate results of the hash calculation over previous datasets.
+    ///
+    /// # Description
+    ///
+    /// This function should be used as part of a CMAC 128-bit hash calculation over
+    /// multiple datasets. If a CMAC hash is needed over a single data set, function
+    /// rsgx_rijndael128_cmac128_msg should be used instead. Prior to calling
+    /// this function on the first dataset, the init function must be called first to 
+    /// allocate and initialize the CMAC state structure which will hold intermediate 
+    /// hash results over earlier datasets. The function get_hash should be used 
+    /// to obtain the hash after the final dataset has been processed by this function.
+    ///
+    /// # Parameters
+    ///
+    /// **src**
+    /// 
+    /// A pointer to the input data stream to be hashed.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_INVALID_STATE**
+    ///
+    /// The CMAC state is not initialized.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// An internal cryptography library failure occurred while performing the CMAC hash calculation.
+    ///
+    pub fn update_msg<T: Copy>(&self, src: &T) -> SgxError {
+        
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let ret = rsgx_cmac128_update_msg(src, *self.handle.borrow());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(()),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// update_slice performs a CMAC 128-bit hash over the input dataset provided. 
+    ///
+    pub fn update_slice<T: Copy>(&self, src: &[T]) -> SgxError {
+        
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let ret = rsgx_cmac128_update_slice(src, *self.handle.borrow());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(()),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// get_hash obtains the CMAC 128-bit hash after the final dataset has been processed.
+    ///
+    /// # Description
+    ///
+    /// This function returns the hash after performing the CMAC 128-bit hash calculation
+    /// over one or more datasets using the update function.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Return value
+    ///
+    /// The 128-bit hash that has been CMAC calculated
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_INVALID_STATE**
+    ///
+    /// The CMAC state is not initialized.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// The CMAC state passed in is likely problematic causing an internal cryptography library failure.
+    ///
+    pub fn get_hash(&self) -> SgxResult<sgx_cmac_128bit_tag_t> {
+
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let mut hash = sgx_cmac_128bit_tag_t::default();
+        let ret = rsgx_cmac128_final(*self.handle.borrow(), &mut hash);
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(hash),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// close cleans up and deallocates the CMAC algorithm context state that was allocated in function init.
+    ///
+    /// # Description
+    ///
+    /// Calling close is the last step after performing a CMAC hash over multiple datasets. 
+    /// The caller uses this function to deallocate memory used for storing the CMAC algorithm context state.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The input handle is invalid.
+    ///
+    pub fn close(&self) -> SgxError {
+
+        if self.initflag.get() == false {
+            return Ok(());
+        }
+
+        let ret = {
+            let handle = *self.handle.borrow();
+            if handle.is_null() == true {
+                sgx_status_t::SGX_SUCCESS
+            } else {
+                rsgx_cmac128_close(handle)
+            }
+        };
+         
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                self.initflag.set(false);
+                *self.handle.borrow_mut() = ptr::null_mut();
+                Ok(())
+            },
+            _ => Err(ret),
+        }
+    }
+}
+
+impl Default for SgxCmacHandle {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl Drop for SgxCmacHandle {
+    ///
+    /// drop cleans up and deallocates the CMAC algorithm context state that was allocated in function init.
+    ///
+    fn drop(&mut self) {
+       let _ = self.close();
+    }
+}
+
+pub const SGX_AESCTR_CTR_SIZE: size_t = 16;
+pub type sgx_aes_ctr_128bit_ctr_t = [uint8_t; SGX_AESCTR_CTR_SIZE];
+
+///
+/// rsgx_aes_ctr_encrypt performs a Rijndael AES-CTR encryption operation.
+/// 
+/// Only a 128bit key size is supported by this Intel(R) SGX SDK cryptography library.
+///
+/// # Description
+/// 
+/// This function encrypts the input data stream of a variable length according to
+/// the CTR mode as specified in [NIST SP 800-38A]. The counter can be thought
+/// of as an IV which increments on successive encryption or decryption calls. For
+/// a given dataset or data stream, the incremented counter block should be used
+/// on successive calls of the encryption process for that given stream. However,
+/// for new or different datasets/streams, the same counter should not be reused,
+/// instead initialize the counter for the new data set.
+///
+/// It is recommended that the source, destination and counter data buffers are
+/// allocated within the enclave.
+/// 
+/// # Parameters
+///
+/// **key**
+///
+/// A pointer to key to be used in the AES-CTR encryption operation. The size must be 128 bits.
+///
+/// **src**
+///
+/// A pointer to the input data stream to be encrypted.
+///
+/// **ctr**
+///
+/// A pointer to the initialization vector to be used in the AES-CTR calculation.
+///
+/// **ctr_inc_bits**
+///
+/// Specifies the number of bits in the counter to be incremented.
+///
+/// **dst**
+///
+/// A pointer to the output encrypted data buffer. This buffer should be allocated by the calling code.
+///
+/// # Requirements
+///
+/// Library: libsgx_tcrypto.a
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// The pointer is invalid.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Not enough memory is available to complete this operation.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// An internal cryptography library failure occurred.
+///
+pub fn rsgx_aes_ctr_encrypt(key: &sgx_aes_ctr_128bit_key_t, 
+                            src: &[u8], 
+                            ctr: &sgx_aes_ctr_128bit_ctr_t, 
+                            ctr_inc_bits: u32,
+                            dst: &mut [u8]) -> SgxError {
+    
+    let src_len = src.len();
+    if src_len > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    if src_len < 1 {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    let dst_len = dst.len();
+    if dst_len > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    if dst_len < src_len {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+
+    let ret = unsafe {        
+        sgx_aes_ctr_encrypt(key as * const sgx_aes_ctr_128bit_key_t,
+                            src.as_ptr(),
+                            src_len as u32,
+                            ctr as * const sgx_aes_ctr_128bit_ctr_t as * const u8,
+                            ctr_inc_bits,
+                            dst.as_mut_ptr())
+    };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
+
+///
+/// rsgx_aes_ctr_decrypt performs a Rijndael AES-CTR decryption operation.
+/// 
+/// Only a 128bit key size is supported by this Intel(R) SGX SDK cryptography library.
+///
+/// # Description
+/// 
+/// This function decrypts the input data stream of a variable length according to
+/// the CTR mode as specified in [NIST SP 800-38A]. The counter can be thought
+/// of as an IV which increments on successive encryption or decryption calls. For
+/// a given dataset or data stream, the incremented counter block should be used
+/// on successive calls of the decryption process for that given stream. However,
+/// for new or different datasets/streams, the same counter should not be reused,
+/// instead initialize the counter for the new data set.
+///
+/// It is recommended that the source, destination and counter data buffers are
+/// allocated within the enclave.
+/// 
+/// # Parameters
+///
+/// **key**
+///
+/// A pointer to key to be used in the AES-CTR encryption operation. The size must be 128 bits.
+///
+/// **src**
+///
+/// A pointer to the input data stream to be decrypted.
+///
+/// **ctr**
+///
+/// A pointer to the initialization vector to be used in the AES-CTR calculation.
+///
+/// **ctr_inc_bits**
+///
+/// Specifies the number of bits in the counter to be incremented.
+///
+/// **dst**
+///
+/// A pointer to the output decrypted data buffer. This buffer should be allocated by the calling code.
+///
+/// # Requirements
+///
+/// Library: libsgx_tcrypto.a
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// The pointer is invalid.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Not enough memory is available to complete this operation.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// An internal cryptography library failure occurred.
+///
+pub fn rsgx_aes_ctr_decrypt(key: &sgx_aes_ctr_128bit_key_t,
+                            src: &[u8],
+                            ctr: &sgx_aes_ctr_128bit_ctr_t,
+                            ctr_inc_bits: u32,
+                            dst: &mut [u8]) -> SgxError {
+
+    let src_len = src.len();
+    if src_len > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    if src_len < 1 {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    let dst_len = dst.len();
+    if dst_len > u32::max_value() as usize {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+    if dst_len < src_len {
+        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+    }
+
+    let ret = unsafe {     
+        sgx_aes_ctr_decrypt(key as * const sgx_aes_ctr_128bit_key_t,
+                            src.as_ptr(),
+                            src.len() as u32,
+                            ctr as * const sgx_aes_ctr_128bit_ctr_t as * const u8,
+                            ctr_inc_bits,
+                            dst.as_mut_ptr())
+    };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
+
+fn rsgx_ecc256_open_context(ecc_handle: &mut sgx_ecc_state_handle_t) -> sgx_status_t {
+    
+    unsafe { sgx_ecc256_open_context(ecc_handle as * mut _ as * mut sgx_ecc_state_handle_t) }
+}
+
+fn rsgx_ecc256_close_context(ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {
+
+    unsafe { sgx_ecc256_close_context(ecc_handle) }
+}
+
+fn rsgx_ecc256_create_key_pair(private: &mut sgx_ec256_private_t, 
+                               public: &mut sgx_ec256_public_t, 
+                               ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {
+    unsafe {
+        sgx_ecc256_create_key_pair(private as * mut sgx_ec256_private_t,
+                                   public as * mut sgx_ec256_public_t,
+                                   ecc_handle)
+    }
+}
+
+fn rsgx_ecc256_check_point(point: &sgx_ec256_public_t, ecc_handle: sgx_ecc_state_handle_t, valid: &mut i32) -> sgx_status_t {
+
+    unsafe { sgx_ecc256_check_point(point as * const sgx_ec256_public_t, ecc_handle, valid as * mut i32) }
+}
+
+fn rsgx_ecc256_compute_shared_dhkey(private_b: &sgx_ec256_private_t,
+                                    public_ga: &sgx_ec256_public_t,
+                                    shared_key: &mut sgx_ec256_dh_shared_t,
+                                    ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {
+    unsafe {
+        sgx_ecc256_compute_shared_dhkey(private_b as * const _ as * mut sgx_ec256_private_t,
+                                        public_ga as * const _ as * mut sgx_ec256_public_t,
+                                        shared_key as * mut sgx_ec256_dh_shared_t,
+                                        ecc_handle)
+    }
+}
+
+fn rsgx_ecdsa_sign_msg<T: Copy>(data: &T, 
+                                private: &sgx_ec256_private_t, 
+                                signature: &mut sgx_ec256_signature_t, 
+                                ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {
+    
+    let size = mem::size_of::<T>();
+    if size == 0 {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    if size > u32::max_value() as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    unsafe {
+        sgx_ecdsa_sign(data as * const _  as * const u8, 
+                       size as u32, 
+                       private as * const _ as * mut sgx_ec256_private_t,
+                       signature as * mut sgx_ec256_signature_t,
+                       ecc_handle)
+    }
+}
+
+fn rsgx_ecdsa_sign_slice<T: Copy>(data: &[T], 
+                                  private: &sgx_ec256_private_t, 
+                                  signature: &mut sgx_ec256_signature_t, 
+                                  ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {
+    
+    let size = mem::size_of::<T>() * data.len();
+    if size == 0 {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    if size > u32::max_value() as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    unsafe {
+        sgx_ecdsa_sign(data.as_ptr() as * const _  as * const u8, 
+                       size as u32, 
+                       private as * const _ as * mut sgx_ec256_private_t,
+                       signature as * mut sgx_ec256_signature_t,
+                       ecc_handle)
+    }
+}
+
+fn rsgx_ecdsa_verify_msg<T: Copy>(data: &T, 
+                                  public: &sgx_ec256_public_t, 
+                                  signature: &sgx_ec256_signature_t, 
+                                  result: &mut sgx_generic_ecresult_t, 
+                                  ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {
+
+    let size = mem::size_of::<T>();
+    if size == 0 {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    if size > u32::max_value() as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    unsafe {
+
+        let mut verify: u8 = 0;
+        let ret = sgx_ecdsa_verify(data as * const _ as * const u8,
+                                   size as u32,
+                                   public as * const sgx_ec256_public_t,
+                                   signature as * const _ as * mut sgx_ec256_signature_t,
+                                   &mut verify as * mut u8,
+                                   ecc_handle);
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                let ecresult = sgx_generic_ecresult_t::from_repr(verify as u32);
+                *result = ecresult.unwrap_or(sgx_generic_ecresult_t::SGX_EC_INVALID_SIGNATURE);
+            },
+            _ => { *result = sgx_generic_ecresult_t::SGX_EC_INVALID_SIGNATURE; },
+        };
+        ret
+    }
+}
+
+fn rsgx_ecdsa_verify_slice<T: Copy>(data: &[T], 
+                                    public: &sgx_ec256_public_t, 
+                                    signature: &sgx_ec256_signature_t, 
+                                    result: &mut sgx_generic_ecresult_t, 
+                                    ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {
+
+    let size = mem::size_of::<T>() * data.len();
+    if size == 0 {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+    if size > u32::max_value() as usize {
+        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    unsafe {
+
+        let mut verify: u8 = 0;
+        let ret = sgx_ecdsa_verify(data.as_ptr() as * const _ as * const u8,
+                                   size as u32,
+                                   public as * const sgx_ec256_public_t,
+                                   signature as * const _ as * mut sgx_ec256_signature_t,
+                                   &mut verify as * mut u8,
+                                   ecc_handle);
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                let ecresult = sgx_generic_ecresult_t::from_repr(verify as u32);
+                *result = ecresult.unwrap_or(sgx_generic_ecresult_t::SGX_EC_INVALID_SIGNATURE);
+            },
+            _ => { *result = sgx_generic_ecresult_t::SGX_EC_INVALID_SIGNATURE; },
+        };
+        ret
+    }
+}
+
+///
+/// ECC GF(p) context state.
+///
+/// This is a handle to the ECC GF(p) context state allocated and initialized used to perform 
+/// elliptic curve cryptosystem standard functions. The algorithm stores the intermediate results 
+/// of calculations performed using this context.
+///
+pub struct SgxEccHandle{
+    handle: RefCell<sgx_ecc_state_handle_t>, 
+    initflag: Cell<bool>,
+}
+
+impl SgxEccHandle {
+
+    ///
+    /// Constructs a new, empty SgxEccHandle.
+    ///
+    pub fn new() -> Self {
+        SgxEccHandle{
+            handle: RefCell::new(ptr::null_mut() as sgx_ecc_state_handle_t), 
+            initflag: Cell::new(false),
+            }
+    }
+
+    ///
+    /// open returns an allocated and initialized context for the elliptic curve cryptosystem 
+    /// over a prime finite field, GF(p).
+    ///
+    /// This context must be created prior to calling create_key_pair or compute_shared_dhkey. 
+    /// When the calling code has completed its set of ECC operations, close should be called to
+    /// cleanup and deallocate the ECC context.
+    ///
+    /// # Description
+    ///
+    /// open is utilized to allocate and initialize a 256-bit
+    /// GF(p) cryptographic system. The caller does not allocate memory for the ECC
+    /// state that this function returns. The state is specific to the implementation of
+    /// the cryptography library and thus the allocation is performed by the library
+    /// itself. If the ECC cryptographic function using this cryptographic system is completed
+    /// or any error occurs, close should be called to free the state allocated by this algorithm.
+    ///
+    /// Public key cryptography successfully allows to solving problems of information
+    /// safety by enabling trusted communication over insecure channels. Although
+    /// elliptic curves are well studied as a branch of mathematics, an interest to the
+    /// cryptographic schemes based on elliptic curves is constantly rising due to the
+    /// advantages that the elliptic curve algorithms provide in the wireless communications:
+    /// shorter processing time and key length.
+    ///
+    /// Elliptic curve cryptosystems (ECCs) implement a different way of creating public
+    /// keys. As elliptic curve calculation is based on the addition of the rational
+    /// points in the (x,y) plane and it is difficult to solve a discrete logarithm from
+    /// these points, a higher level of safety is achieved through the cryptographic
+    /// schemes that use the elliptic curves. The cryptographic systems that encrypt
+    /// messages by using the properties of elliptic curves are hard to attack due to
+    /// the extreme complexity of deciphering the private key.
+    ///
+    /// Using of elliptic curves allows shorter public key length and encourages cryptographers
+    /// to create cryptosystems with the same or higher encryption
+    /// strength as the RSA or DSA cryptosystems. Because of the relatively short key
+    /// length, ECCs do encryption and decryption faster on the hardware that
+    /// requires less computation processing volumes.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// The ECC context state was not initialized properly due to an internal cryptography library failure.
+    ///
+    pub fn open(&self) -> SgxError {
+        
+        if self.initflag.get() == true {
+            return Ok(());
+        }
+
+        let ret = rsgx_ecc256_open_context(self.handle.borrow_mut().deref_mut());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                self.initflag.set(true);
+                Ok(())
+            },
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// create_key_pair generates a private/public key pair on the ECC curve for the given 
+    /// cryptographic system. 
+    ///
+    /// open must be called to allocate and initialize the ECC context prior to making this call.
+    ///
+    /// # Description
+    ///
+    /// This function populates private/public key pair. The calling code allocates
+    /// memory for the private and public key pointers to be populated. The function
+    /// generates a private key p_private and computes a public key p_public of
+    /// the elliptic cryptosystem over a finite field GF(p).
+    ///
+    /// The private key p_private is a number that lies in the range of [1, n-1]
+    /// where n is the order of the elliptic curve base point.
+    /// The public key p_public is an elliptic curve point such that p_public =
+    /// p_private *G, where G is the base point of the elliptic curve.
+    /// The context of the point p_public as an elliptic curve point must be created
+    /// by using the function open.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Return value
+    ///
+    /// **sgx_ec256_private_t**
+    ///
+    /// The private key which is a number that lies in the range of [1, n-1] where n is the order 
+    /// of the elliptic curve base point.
+    ///
+    /// **sgx_ec256_public_t**
+    ///
+    /// The public key which is an elliptic curve point such that:
+    ///
+    /// public key = private key * G, where G is the base point of the elliptic curve.
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_INVALID_STATE**
+    ///
+    /// The ECC state is not initialized.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// The key creation process failed due to an internal cryptography library failure.
+    ///
+    pub fn create_key_pair(&self) -> SgxResult<(sgx_ec256_private_t, sgx_ec256_public_t)> {
+        
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let mut private = sgx_ec256_private_t::default();
+        let mut public = sgx_ec256_public_t::default();
+        let ret = rsgx_ecc256_create_key_pair(&mut private, &mut public, *self.handle.borrow());
+
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok((private, public)),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// check_point checks whether the input point is a valid point on the ECC curve for the given cryptographic system. 
+    ///
+    /// open context must be called to allocate and initialize the ECC context prior to making this call.
+    ///
+    /// # Description
+    ///
+    /// check_point validates whether the input point is a valid point on the ECC curve for the given cryptographic system.
+    ///
+    /// # Parameters
+    ///
+    /// **point**
+    ///
+    /// A pointer to the point to perform validity check on.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Return value
+    ///
+    /// **true**
+    ///
+    /// The input point is valid
+    ///
+    /// **false**
+    ///
+    /// The input point is not valid
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_INVALID_STATE**
+    ///
+    /// The ECC state is not initialized.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// An internal cryptography library failure occurred.
+    ///
+    pub fn check_point(&self, point: &sgx_ec256_public_t) -> SgxResult<bool> {
+
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let mut valid: i32 = 0;
+        let ret = rsgx_ecc256_check_point(point, *self.handle.borrow(), &mut valid);
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                if valid > 0 {
+                    Ok(true)
+                } else if valid == 0 {
+                    Ok(false)
+                } else {
+                    Ok(false)
+                }
+            },
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// compute_shared_dhkey generates a secret key shared between two participants of the cryptosystem. 
+    ///
+    /// # Description
+    ///
+    /// This function computes the Diffie-Hellman shared key based on the enclave’s
+    /// own (local) private key and remote enclave’s public Ga Key. 
+    ///
+    /// The function computes a secret number sharedKey, which is a secret key
+    /// shared between two participants of the cryptosystem.
+    ///
+    /// In cryptography, metasyntactic names such as Alice as Bob are normally used
+    /// as examples and in discussions and stand for participant A and participant B.
+    ///
+    /// Both participants (Alice and Bob) use the cryptosystem for receiving a common
+    /// secret point on the elliptic curve called a secret key (sharedKey). To
+    /// receive a secret key, participants apply the Diffie-Hellman key-agreement
+    /// scheme involving public key exchange. The value of the secret key entirely
+    /// depends on participants.
+    ///
+    /// According to the scheme, Alice and Bob perform the following operations:
+    ///
+    /// 1. Alice calculates her own public key pubKeyA by using her private key
+    /// privKeyA: pubKeyA = privKeyA * G, where G is the base point of the
+    /// elliptic curve.
+    ///
+    /// 2. Alice passes the public key to Bob.
+    ///
+    /// 3. Bob calculates his own public key pubKeyB by using his private key
+    /// privKeyB: pubKeyB = privKeyB * G, where G is a base point of the elliptic curve.
+    ///
+    /// 4. Bob passes the public key to Alice.
+    /// 
+    /// 5. Alice gets Bob's public key and calculates the secret point shareKeyA. When
+    /// calculating, she uses her own private key and Bob's public key and applies the
+    /// following formula:
+    ///
+    /// shareKeyA = privKeyA * pubKeyB = privKeyA * privKeyB * G.
+    ///
+    /// 6. Bob gets Alice's public key and calculates the secret point shareKeyB. When
+    /// calculating, he uses his own private key and Alice's public key and applies the
+    /// following formula:
+    ///
+    /// shareKeyB = privKeyB * pubKeyA = privKeyB * privKeyA * G.
+    ///
+    /// As the following equation is true privKeyA * privKeyB * G =
+    /// privKeyB * privKeyA * G, the result of both calculations is the same,
+    /// that is, the equation shareKeyA = shareKeyB is true. The secret point serves as
+    /// a secret key.
+    ///
+    /// Shared secret shareKey is an x-coordinate of the secret point on the elliptic
+    /// curve. The elliptic curve domain parameters must be hitherto defined by the
+    /// function: open.
+    ///
+    /// # Parameters
+    ///
+    /// **private_b**
+    ///
+    /// A pointer to the local private key.
+    ///
+    /// **public_ga**
+    ///
+    /// A pointer to the remote public key.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Return value
+    ///
+    /// The secret key generated by this function which is a common point on the elliptic curve.
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_INVALID_STATE**
+    ///
+    /// The ECC state is not initialized.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// The key creation process failed due to an internal cryptography library failure.
+    ///
+    pub fn compute_shared_dhkey(&self, private_b: &sgx_ec256_private_t, public_ga: &sgx_ec256_public_t) -> SgxResult<sgx_ec256_dh_shared_t> {
+        
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let mut shared_key = sgx_ec256_dh_shared_t::default();
+        let ret = rsgx_ecc256_compute_shared_dhkey(private_b, public_ga, &mut shared_key, *self.handle.borrow());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(shared_key),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// ecdsa_sign_msg computes a digital signature with a given private key over an input dataset. 
+    ///
+    /// # Description
+    ///
+    /// This function computes a digital signature over the input dataset based on the
+    /// put private key.
+    ///
+    /// A message digest is a fixed size number derived from the original message
+    // with an applied hash function over the binary code of the message. (SHA256
+    /// in this case)
+    ///
+    /// The signer's private key and the message digest are used to create a signature.
+    ///
+    /// A digital signature over a message consists of a pair of large numbers, 256-bits
+    /// each, which the given function computes.
+    ///
+    /// The scheme used for computing a digital signature is of the ECDSA scheme, an
+    /// elliptic curve of the DSA scheme.
+    ///
+    /// The keys can be generated and set up by the function: create_key_pair.
+    ///
+    /// The elliptic curve domain parameters must be created by function: open.
+    ///
+    /// # Parameters
+    ///
+    /// **data**
+    ///
+    /// A pointer to the data to calculate the signature over.
+    ///
+    /// **private**
+    ///
+    /// A pointer to the private key to be used in the calculation of the signature.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Return value
+    ///
+    /// The signature generated by this function.
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_INVALID_STATE**
+    ///
+    /// The ECC state is not initialized.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// The signature generation process failed due to an internal cryptography library failure.
+    ///
+    pub fn ecdsa_sign_msg<T: Copy>(&self, data: &T, private: &sgx_ec256_private_t) -> SgxResult<sgx_ec256_signature_t> {
+        
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let mut signature = sgx_ec256_signature_t::default();
+        let ret = rsgx_ecdsa_sign_msg(data, private, &mut signature, *self.handle.borrow());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(signature),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// ecdsa_sign_slice computes a digital signature with a given private key over an input dataset. 
+    ///
+    pub fn ecdsa_sign_slice<T: Copy>(&self, data: &[T], private: &sgx_ec256_private_t) -> SgxResult<sgx_ec256_signature_t> {
+        
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let mut signature = sgx_ec256_signature_t::default();
+        let ret = rsgx_ecdsa_sign_slice(data, private, &mut signature, *self.handle.borrow());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(signature),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// ecdsa_verify_msg verifies the input digital signature with a given public key over an input dataset. 
+    ///
+    /// # Description
+    ///
+    /// This function verifies the signature for the given data set based on the input public key.
+    ///
+    /// A digital signature over a message consists of a pair of large numbers, 256-bits
+    /// each, which could be created by function: sgx_ecdsa_sign. The scheme
+    /// used for computing a digital signature is of the ECDSA scheme, an elliptic
+    /// curve of the DSA scheme.
+    ///
+    /// The elliptic curve domain parameters must be created by function: open.
+    ///
+    /// # Parameters
+    ///
+    /// **data**
+    ///
+    /// A pointer to the signed dataset to verify.
+    ///
+    /// **public**
+    ///
+    /// A pointer to the public key to be used in the calculation of the signature.
+    ///
+    /// **signature**
+    ///
+    /// A pointer to the signature to be verified.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Return value
+    ///
+    /// **true**
+    ///
+    /// Digital signature is valid.
+    ///
+    /// **false**
+    ///
+    /// Digital signature is not valid.
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The pointer is invalid.
+    ///
+    /// **SGX_ERROR_INVALID_STATE**
+    ///
+    /// The ECC state is not initialized.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// The verification process failed due to an internal cryptography library failure.
+    ///
+    pub fn ecdsa_verify_msg<T: Copy>(&self, data: &T, public: &sgx_ec256_public_t, signature: &sgx_ec256_signature_t) -> SgxResult<bool> {
+        
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+        
+        let mut result = sgx_generic_ecresult_t::default();
+        let ret = rsgx_ecdsa_verify_msg(data, public, signature, &mut result, *self.handle.borrow());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                match result {
+                    sgx_generic_ecresult_t::SGX_EC_VALID => Ok(true),
+                    _ => Ok(false),
+                }
+            },
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// ecdsa_verify_slice verifies the input digital signature with a given public key over an input dataset. 
+    ///
+    pub fn ecdsa_verify_slice<T: Copy>(&self, data: &[T], public: &sgx_ec256_public_t, signature: &sgx_ec256_signature_t) -> SgxResult<bool> {
+        
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+        
+        let mut result = sgx_generic_ecresult_t::default();
+        let ret = rsgx_ecdsa_verify_slice(data, public, signature, &mut result, *self.handle.borrow());
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                match result {
+                    sgx_generic_ecresult_t::SGX_EC_VALID => Ok(true),
+                    _ => Ok(false),
+                }
+            },
+            _ => Err(ret),
+        }
+    }
+     
+    ///
+    /// close cleans up and deallocates the ECC 256 GF(p) state that was allocated in function open.
+    ///
+    /// # Description
+    ///
+    /// close is used by calling code to deallocate memory used for storing the ECC 256 GF(p) state used 
+    /// in ECC cryptographic calculations.
+    ///
+    /// # Requirements
+    ///
+    /// Library: libsgx_tcrypto.a
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// The input handle is invalid.
+    ///
+    pub fn close(&self) -> SgxError {
+
+        if self.initflag.get() == false {
+            return Ok(());
+        }
+
+        let ret = {
+            let handle = *self.handle.borrow();
+            if handle.is_null() == true {
+                sgx_status_t::SGX_SUCCESS
+            } else {
+                rsgx_ecc256_close_context(handle)
+            }
+        };
+         
+        match ret {
+            sgx_status_t::SGX_SUCCESS => {
+                self.initflag.set(false);
+                *self.handle.borrow_mut() = ptr::null_mut();
+                Ok(())
+            },
+            _ => Err(ret),
+        }
+    }
+}
+
+impl Default for SgxEccHandle {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl Drop for SgxEccHandle {
+    ///
+    /// close cleans up and deallocates the ECC 256 GF(p) state that was allocated in function open.
+    ///
+    fn drop(&mut self) {
+        let _ = self.close();
+    }
+}
\ No newline at end of file
diff --git a/sgx_tcrypto/src/lib.rs b/sgx_tcrypto/src/lib.rs
new file mode 100644
index 0000000..cd87880
--- /dev/null
+++ b/sgx_tcrypto/src/lib.rs
@@ -0,0 +1,48 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//! # Cryptography Library
+//!
+//! The Intel(R) Software Guard Extensions SDK includes a trusted cryptography library named sgx_tcrypto. 
+//! It includes the cryptographic functions used by other trusted libraries included in the SDK
+//!
+#![crate_name = "sgx_tcrypto"]
+#![crate_type = "rlib"]
+
+#![cfg_attr(not(feature = "use_std"), no_std)]
+
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+#[cfg(feature = "use_std")]
+extern crate std as core;
+
+extern crate sgx_types;
+
+pub mod crypto;
+pub use self::crypto::*;
\ No newline at end of file
diff --git a/sgx_tdh/Cargo.toml b/sgx_tdh/Cargo.toml
new file mode 100644
index 0000000..88eed37
--- /dev/null
+++ b/sgx_tdh/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "sgx_tdh"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../sgx_types" }
+sgx_trts = { path = "../sgx_trts" }
+sgx_tcrypto = { path = "../sgx_tcrypto" }
+sgx_tse = { path = "../sgx_tse" }
\ No newline at end of file
diff --git a/sgx_tdh/src/dh.rs b/sgx_tdh/src/dh.rs
new file mode 100644
index 0000000..368a136
--- /dev/null
+++ b/sgx_tdh/src/dh.rs
@@ -0,0 +1,816 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//! # Diffie–Hellman (DH) Session Establishment Functions
+//! 
+//! These functions allow an ISV to establish secure session between two enclaves using the EC DH Key exchange protocol.
+//! 
+use sgx_types::*;
+use sgx_trts::*;
+use sgx_tcrypto::*;
+use sgx_tse::*;
+use core::mem;
+use core::ptr;
+use core::slice;
+use super::ecp::*;
+#[cfg(not(feature = "use_std"))]
+use alloc::boxed::Box;
+#[cfg(not(feature = "use_std"))]
+use collections::vec::Vec;
+
+const AES_CMAC_KDF_ID: [u8; 2] = [1, 0];
+
+pub type SgxDhMsg1 = sgx_dh_msg1_t;
+pub type SgxDhMsg2 = sgx_dh_msg2_t;
+
+/// Type for message body of the MSG3 structure used in DH secure session establishment.
+#[derive(Clone, Default)]
+pub struct SgxDhMsg3Body {
+    pub report: sgx_report_t,
+    pub additional_prop: Box<[u8]>,
+}
+
+/// Type for MSG3 used in DH secure session establishment.
+#[derive(Clone, Default)]
+pub struct SgxDhMsg3 {
+    pub cmac: [u8; SGX_DH_MAC_SIZE],
+    pub msg3_body: SgxDhMsg3Body,
+}
+
+impl SgxDhMsg3 {
+    /// 
+    /// Create a SgxDhMsg3 with default values.
+    /// 
+    pub fn new() -> Self {
+        let dh_msg3 = SgxDhMsg3::default();
+        dh_msg3
+    }
+
+    /// 
+    /// Calculate the size of sgx_dh_msg3_t converted from SgxDhMsg3, really add the size of struct sgx_dh_msg3_t and msg3_body.additional_prop.
+    /// 
+    /// # Return value
+    ///
+    /// The size of sgx_dh_msg3_t needed.
+    ///
+    pub fn calc_raw_sealed_data_size(&self) -> u32 {
+
+        let max = u32::max_value();
+        let dh_msg3_size = mem::size_of::<sgx_dh_msg3_t>();
+        let additional_prop_len = self.msg3_body.additional_prop.len();
+
+        if additional_prop_len > (max as usize) - dh_msg3_size {
+            return max;
+        }
+     
+        (dh_msg3_size + additional_prop_len) as u32
+    }
+
+    ///
+    /// Convert SgxDhMsg3 to sgx_dh_msg3_t, this is an unsafe function.
+    /// 
+    /// # Parameters
+    /// 
+    /// **p**
+    /// 
+    /// The pointer of a sgx_dh_msg3_t buffer to save the buffer of SgxDhMsg3.
+    /// 
+    /// **len**
+    /// 
+    /// The size of the sgx_dh_msg3_t buffer.
+    ///
+    /// # Return value
+    ///
+    /// **Some(*mut sgx_dh_msg3_t)**
+    ///
+    /// Indicates the conversion is successfully. The return value is the mutable pointer of sgx_dh_msg3_t.
+    ///
+    /// **None**
+    ///
+    /// The parameters p and len are not available for the conversion.
+    ///
+    pub unsafe fn to_raw_dh_msg3_t(&self, p: * mut sgx_dh_msg3_t, len: u32) -> Option<* mut sgx_dh_msg3_t> {
+
+        if p.is_null() {
+            return None;
+        }
+        if rsgx_raw_is_within_enclave(p as * mut u8, len as usize) == false {
+            return None;
+        }
+
+        let additional_prop_len = self.msg3_body.additional_prop.len();
+        let dh_msg3_size = mem::size_of::<sgx_dh_msg3_t>();
+        if additional_prop_len > u32::max_value() as usize - dh_msg3_size {
+            return None;
+        }
+        if len < (dh_msg3_size + additional_prop_len) as u32 {
+            return None;
+        }
+
+        let mut dh_msg3 = Box::from_raw(p);
+        dh_msg3.cmac = self.cmac;
+        dh_msg3.msg3_body.report = self.msg3_body.report;
+        dh_msg3.msg3_body.additional_prop_length = additional_prop_len as u32;
+
+        if additional_prop_len > 0 {
+            let raw_msg3 = slice::from_raw_parts_mut(p as * mut u8, len as usize);
+            raw_msg3[dh_msg3_size..].copy_from_slice(&self.msg3_body.additional_prop); 
+        }
+
+        mem::forget(dh_msg3); 
+        Some(p)
+    }
+
+    /// 
+    /// Convert sgx_dh_msg3_t to SgxDhMsg3, this is an unsafe function.
+    /// 
+    /// # Parameters
+    /// 
+    /// **p**
+    /// 
+    /// The pointer of a sgx_dh_msg3_t buffer.
+    ///
+    /// **len**
+    /// 
+    /// The size of the sgx_dh_msg3_t buffer.
+    /// 
+    /// # Return value
+    /// 
+    /// **Some(SgxDhMsg3)**
+    ///
+    /// Indicates the conversion is successfully. The return value is SgxDhMsg3.
+    /// 
+    /// **None**
+    /// 
+    /// The parameters p and len are not available for the conversion.
+    ///
+    pub unsafe fn from_raw_dh_msg3_t(p: * mut sgx_dh_msg3_t, len: u32) -> Option<Self> {
+
+        if p.is_null() {
+            return None;
+        }
+        if rsgx_raw_is_within_enclave(p as * mut u8, len as usize) == false {
+            return None;
+        }
+        
+        let raw_msg3 = Box::from_raw(p);
+        let additional_prop_len = raw_msg3.msg3_body.additional_prop_length;
+        let dh_msg3_size = mem::size_of::<sgx_dh_msg3_t>() as u32;
+        if additional_prop_len > u32::max_value() - dh_msg3_size {
+            return None;
+        }
+        if len < dh_msg3_size + additional_prop_len {
+            return None;
+        }
+
+        let mut dh_msg3 = SgxDhMsg3::default();
+        dh_msg3.cmac = raw_msg3.cmac;
+        dh_msg3.msg3_body.report = raw_msg3.msg3_body.report;
+
+        if additional_prop_len > 0 {
+            let mut additional_prop: Vec<u8> = vec![0_u8; additional_prop_len as usize];
+            let ptr_additional_prop = p.offset(1) as * const u8;
+            ptr::copy_nonoverlapping(ptr_additional_prop, additional_prop.as_mut_ptr(), additional_prop_len as usize); 
+            dh_msg3.msg3_body.additional_prop = additional_prop.into_boxed_slice();
+        }
+
+        mem::forget(raw_msg3);
+        Some(dh_msg3)
+    }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+enum SgxDhSessionState {
+    SGX_DH_SESSION_STATE_ERROR,
+    SGX_DH_SESSION_STATE_RESET,
+    SGX_DH_SESSION_RESPONDER_WAIT_M2,
+    SGX_DH_SESSION_INITIATOR_WAIT_M1,
+    SGX_DH_SESSION_INITIATOR_WAIT_M3,
+    SGX_DH_SESSION_ACTIVE,
+}
+
+/// DH secure session responder
+#[derive(Copy, Clone)]
+pub struct SgxDhResponder {
+    state: SgxDhSessionState,
+    prv_key: sgx_ec256_private_t,
+    pub_key: sgx_ec256_public_t, 
+    smk_aek: sgx_key_128bit_t,
+    shared_key: sgx_ec256_dh_shared_t,
+}
+
+impl Default for SgxDhResponder {
+    fn default() -> Self {
+        SgxDhResponder {
+           state: SgxDhSessionState::SGX_DH_SESSION_STATE_RESET,
+           prv_key: sgx_ec256_private_t::default(),
+           pub_key: sgx_ec256_public_t::default(),
+           smk_aek: sgx_key_128bit_t::default(),
+           shared_key: sgx_ec256_dh_shared_t::default(),
+        }
+    }
+}
+
+impl SgxDhResponder {
+    /// 
+    /// Initialize DH secure session responder.
+    /// 
+    /// Indicates role of responder  the caller plays in the secure session establishment.
+    /// 
+    /// The value of role of the responder of the session establishment must be `SGX_DH_SESSION_RESPONDER`.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    pub fn init_session() -> Self {
+        Self::default()
+    }
+    ///
+    /// Generates MSG1 for the responder of DH secure session establishment and records ECC key pair in session structure. 
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    ///
+    /// **msg1**
+    ///
+    /// A pointer to an SgxDhMsg1 msg1 buffer. The buffer holding the msg1
+    /// message, which is referenced by this parameter, must be within the enclave.
+    /// The DH msg1 contains the responder’s public key and report based target
+    /// info.
+    /// 
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// Any of the input parameters is incorrect.
+    /// 
+    /// **SGX_ERROR_INVALID_STATE**
+    /// 
+    /// The API is invoked in incorrect order or state.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    /// 
+    /// An unexpected error occurred.
+    /// 
+    pub fn gen_msg1(&mut self, msg1: &mut SgxDhMsg1) -> SgxError {
+
+        if rsgx_data_is_within_enclave(self) == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if rsgx_data_is_within_enclave(msg1) == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+
+        if self.state != SgxDhSessionState::SGX_DH_SESSION_STATE_RESET {
+            *self = Self::default();
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let error = self.dh_generate_message1(msg1);
+        match error {
+            Err(mut ret) => {
+                *self = Self::default();
+                if ret != sgx_status_t::SGX_ERROR_OUT_OF_MEMORY {
+                    ret = sgx_status_t::SGX_ERROR_UNEXPECTED;
+                }
+                return Err(ret);
+            },
+            _ => (),
+        };
+        
+        self.state = SgxDhSessionState::SGX_DH_SESSION_RESPONDER_WAIT_M2;
+        Ok(())
+    }
+    
+    /// 
+    /// The responder handles msg2 sent by initiator and then derives AEK, updates session information and generates msg3.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    ///
+    /// **msg2**
+    ///
+    /// Point to dh message 2 buffer generated by session initiator, and the buffer must be in enclave address space.
+    /// 
+    /// **msg3**
+    /// 
+    /// Point to dh message 3 buffer generated by session responder in this function, and the buffer must be in enclave address space.
+    /// 
+    /// **aek**
+    ///
+    /// A pointer that points to instance of sgx_key_128bit_t. The aek is derived as follows:
+    /// 
+    /// ```
+    /// KDK := CMAC(key0, LittleEndian(gab x-coordinate))
+    /// AEK = AES-CMAC(KDK, 0x01||"AEK"||0x00||0x80||0x00)
+    /// ```
+    /// The key0 used in the key extraction operation is 16 bytes of 0x00. The plain
+    /// text used in the AES-CMAC calculation of the KDK is the Diffie-Hellman shared
+    /// secret elliptic curve field element in Little Endian format.The plain text used 
+    /// in the AEK calculation includes:
+    /// 
+    /// * a counter (0x01)
+    /// 
+    /// * a label: the ASCII representation of the string 'AEK' in Little Endian format
+    /// 
+    /// * a bit length (0x80)
+    /// 
+    /// **initiator_identity**
+    ///
+    /// A pointer that points to instance of sgx_dh_session_enclave_identity_t. 
+    /// Identity information of initiator includes isv svn, isv product id, the
+    /// enclave attributes, MRSIGNER, and MRENCLAVE. The buffer must be in
+    /// enclave address space. The caller should check the identity of the peer and
+    /// decide whether to trust the peer and use the aek.
+    /// 
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// Any of the input parameters is incorrect.
+    /// 
+    /// **SGX_ERROR_INVALID_STATE**
+    /// 
+    /// The API is invoked in incorrect order or state.
+    /// 
+    /// **SGX_ERROR_KDF_MISMATCH**
+    /// 
+    /// Indicates the key derivation function does not match.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    /// 
+    /// An unexpected error occurred.
+    /// 
+    pub fn proc_msg2(&mut self, 
+                     msg2: &SgxDhMsg2,
+                     msg3: &mut SgxDhMsg3,
+                     aek: &mut sgx_key_128bit_t,
+                     initiator_identity: &mut sgx_dh_session_enclave_identity_t) -> SgxError {
+
+        if rsgx_data_is_within_enclave(self) == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if (rsgx_data_is_within_enclave(msg2) == false) ||
+           (rsgx_data_is_within_enclave(aek) == false) ||
+           (rsgx_data_is_within_enclave(initiator_identity) == false) ||
+           (rsgx_raw_is_within_enclave(msg3 as * const _ as * const u8, mem::size_of::<SgxDhMsg3>()) == false) {
+            *self = Self::default();
+            self.state = SgxDhSessionState::SGX_DH_SESSION_STATE_ERROR;
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if msg3.msg3_body.additional_prop.len() > 0 {
+            if (rsgx_slice_is_within_enclave(&msg3.msg3_body.additional_prop) == false) ||
+               (msg3.msg3_body.additional_prop.len() > (u32::max_value() as usize) - mem::size_of::<sgx_dh_msg3_t>()) {
+                *self = Self::default();
+                self.state = SgxDhSessionState::SGX_DH_SESSION_STATE_ERROR;
+                return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+            }
+        }
+
+        if self.state != SgxDhSessionState::SGX_DH_SESSION_RESPONDER_WAIT_M2 {
+            *self = Self::default();
+            self.state = SgxDhSessionState::SGX_DH_SESSION_STATE_ERROR;
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+   
+        let ecc_state = SgxEccHandle::new();
+        try!(ecc_state.open().map_err(|ret| self.set_error(ret)));
+        self.shared_key = try!(ecc_state.compute_shared_dhkey(&self.prv_key, &msg2.g_b).map_err(|ret| self.set_error(ret)));
+
+        self.smk_aek = try!(derive_key(&self.shared_key, &EC_SMK_LABEL).map_err(|ret| self.set_error(ret)));
+
+        try!(self.dh_verify_message2(msg2).map_err(|ret| self.set_error(ret)));
+
+        initiator_identity.isv_svn = msg2.report.body.isv_svn;
+        initiator_identity.isv_prod_id = msg2.report.body.isv_prod_id;
+        initiator_identity.attributes = msg2.report.body.attributes;
+        initiator_identity.mr_signer = msg2.report.body.mr_signer;
+        initiator_identity.mr_enclave = msg2.report.body.mr_enclave;
+
+        try!(self.dh_generate_message3(msg2, msg3).map_err(|ret| self.set_error(ret)));
+
+        * aek = try!(derive_key(&self.shared_key, &EC_AEK_LABEL).map_err(|ret| self.set_error(ret)));
+
+        *self = Self::default();
+        self.state = SgxDhSessionState::SGX_DH_SESSION_ACTIVE;
+
+        Ok(())
+    }
+
+    fn dh_generate_message1(&mut self, msg1: &mut SgxDhMsg1) -> SgxError {
+
+        let target = sgx_target_info_t::default();
+        let report_data = sgx_report_data_t::default(); 
+
+        let report = try!(rsgx_create_report(&target, &report_data));
+
+        msg1.target.mr_enclave = report.body.mr_enclave;
+        msg1.target.attributes = report.body.attributes;
+        msg1.target.misc_select = report.body.misc_select;
+
+        let ecc_state = SgxEccHandle::new();
+        try!(ecc_state.open());
+        let (prv_key, pub_key) = try!(ecc_state.create_key_pair());
+
+        self.prv_key = prv_key;                                                                    
+        self.pub_key = pub_key;
+        msg1.g_a = pub_key; 
+
+        Ok(())
+    }
+    
+    fn dh_verify_message2(&self, msg2: &SgxDhMsg2) -> SgxError {
+
+        let kdf_id = &msg2.report.body.report_data.d[SGX_SHA256_HASH_SIZE..SGX_SHA256_HASH_SIZE + 2];
+        let data_hash = &msg2.report.body.report_data.d[..SGX_SHA256_HASH_SIZE];
+
+        if kdf_id.eq(&AES_CMAC_KDF_ID) == false {
+            return Err(sgx_status_t::SGX_ERROR_KDF_MISMATCH);
+        }
+
+        let data_mac = try!(rsgx_rijndael128_cmac_msg(&self.smk_aek, &msg2.report));
+        if data_mac.eq(&msg2.cmac) == false {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+
+        try!(rsgx_verify_report(&msg2.report));
+
+        let sha_handle = SgxShaHandle::new();
+        try!(sha_handle.init());
+        try!(sha_handle.update_msg(&self.pub_key));
+        try!(sha_handle.update_msg(&msg2.g_b));
+        let msg_hash = try!(sha_handle.get_hash());
+
+        if msg_hash.eq(data_hash) == false {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        
+        Ok(())
+    }
+
+    fn dh_generate_message3(&self, msg2: &SgxDhMsg2, msg3: &mut SgxDhMsg3) -> SgxError {
+
+        msg3.cmac = Default::default();
+        msg3.msg3_body.report = Default::default();
+
+        let sha_handle = SgxShaHandle::new();
+        try!(sha_handle.init());
+        try!(sha_handle.update_msg(&msg2.g_b));
+        try!(sha_handle.update_msg(&self.pub_key));
+        let msg_hash = try!(sha_handle.get_hash());
+
+        let mut target = sgx_target_info_t::default();
+        let mut report_data = sgx_report_data_t::default();
+
+        report_data.d[..SGX_SHA256_HASH_SIZE].copy_from_slice(&msg_hash);
+        target.attributes = msg2.report.body.attributes;
+        target.mr_enclave = msg2.report.body.mr_enclave;
+        target.misc_select = msg2.report.body.misc_select;
+        msg3.msg3_body.report = try!(rsgx_create_report(&target, &report_data));
+        
+        let add_prop_len = msg3.msg3_body.additional_prop.len() as u32;
+        let cmac_handle = SgxCmacHandle::new();
+        try!(cmac_handle.init(&self.smk_aek));
+        try!(cmac_handle.update_msg(&msg3.msg3_body.report));
+        try!(cmac_handle.update_msg(&add_prop_len));
+        if add_prop_len > 0 { 
+            try!(cmac_handle.update_slice(&msg3.msg3_body.additional_prop));
+        }
+        msg3.cmac = try!(cmac_handle.get_hash());
+        
+        Ok(())
+    }
+    
+    fn set_error(&mut self, sgx_ret: sgx_status_t) -> sgx_status_t {
+
+        *self = Self::default();
+        self.state = SgxDhSessionState::SGX_DH_SESSION_STATE_ERROR;
+        let ret = match sgx_ret {
+            sgx_status_t::SGX_ERROR_OUT_OF_MEMORY => sgx_status_t::SGX_ERROR_OUT_OF_MEMORY,
+            sgx_status_t::SGX_ERROR_KDF_MISMATCH => sgx_status_t::SGX_ERROR_KDF_MISMATCH,
+            _ => sgx_status_t::SGX_ERROR_UNEXPECTED,
+        };
+        ret   
+    }
+}
+
+/// DH secure session Initiator
+#[derive(Copy, Clone)]
+pub struct SgxDhInitiator {
+    state: SgxDhSessionState,
+    smk_aek: sgx_key_128bit_t,
+    pub_key: sgx_ec256_public_t, 
+    peer_pub_key: sgx_ec256_public_t,
+    shared_key: sgx_ec256_dh_shared_t,
+}
+
+impl Default for SgxDhInitiator {
+    fn default() -> Self {
+        SgxDhInitiator {
+           state: SgxDhSessionState::SGX_DH_SESSION_INITIATOR_WAIT_M1,
+           smk_aek: sgx_key_128bit_t::default(),
+           pub_key: sgx_ec256_public_t::default(),
+           peer_pub_key: sgx_ec256_public_t::default(),
+           shared_key: sgx_ec256_dh_shared_t::default(),
+        }
+    }
+}
+
+impl SgxDhInitiator {
+    /// 
+    /// Initialize DH secure session Initiator.
+    /// 
+    /// Indicates role of initiator the caller plays in the secure session establishment.
+    /// 
+    /// The value of role of the initiator of the session establishment must be `SGX_DH_SESSION_INITIATOR`.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    /// 
+    pub fn init_session() -> Self {
+        Self::default()
+    }
+
+    /// 
+    /// The initiator of DH secure session establishment handles msg1 sent by responder and then generates msg2, 
+    /// and records initiator’s ECC key pair in DH session structure.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    /// 
+    /// **msg1**
+    ///
+    /// Point to dh message 1 buffer generated by session responder, and the buffer must be in enclave address space.
+    /// 
+    /// **msg2**
+    /// 
+    /// Point to dh message 2 buffer, and the buffer must be in enclave address space.
+    /// 
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// Any of the input parameters is incorrect.
+    /// 
+    /// **SGX_ERROR_INVALID_STATE**
+    ///
+    /// The API is invoked in incorrect order or state.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// An unexpected error occurred.
+    ///
+    pub fn proc_msg1(&mut self, msg1: &SgxDhMsg1, msg2: &mut SgxDhMsg2) -> SgxError {
+
+        if rsgx_data_is_within_enclave(self) == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if (rsgx_data_is_within_enclave(msg1) == false) ||
+           (rsgx_data_is_within_enclave(msg2) == false) {
+            *self = Self::default();
+            self.state = SgxDhSessionState::SGX_DH_SESSION_STATE_ERROR;
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+
+        if self.state != SgxDhSessionState::SGX_DH_SESSION_INITIATOR_WAIT_M1 {
+            *self = Self::default();
+            self.state = SgxDhSessionState::SGX_DH_SESSION_STATE_ERROR;
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        let ecc_state = SgxEccHandle::new();
+        try!(ecc_state.open().map_err(|ret| self.set_error(ret)));
+        let (mut prv_key, pub_key) = try!(ecc_state.create_key_pair().map_err(|ret| self.set_error(ret)));
+        self.shared_key = try!(ecc_state.compute_shared_dhkey(&prv_key, &msg1.g_a).map_err(|ret| self.set_error(ret)));
+
+        prv_key = sgx_ec256_private_t::default();
+        self.pub_key = pub_key;
+        self.smk_aek = try!(derive_key(&self.shared_key, &EC_SMK_LABEL).map_err(|ret| self.set_error(ret)));
+        try!(self.dh_generate_message2(msg1, msg2).map_err(|ret| self.set_error(ret)));
+
+        self.peer_pub_key = msg1.g_a;
+        self.state = SgxDhSessionState::SGX_DH_SESSION_INITIATOR_WAIT_M3;
+
+        Ok(())
+    }
+
+    ///
+    /// The initiator handles msg3 sent by responder and then derives AEK, updates
+    /// session information and gets responder’s identity information.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    /// 
+    /// **msg3**
+    /// 
+    /// Point to dh message 3 buffer generated by session responder, and the buffer must be in enclave address space.
+    /// 
+    /// **aek**
+    /// 
+    /// A pointer that points to instance of sgx_key_128bit_t. The aek is derived as follows:
+    /// 
+    /// ```
+    /// KDK:= CMAC(key0, LittleEndian(gab x-coordinate))
+    /// AEK = AES-CMAC(KDK, 0x01||"AEK"||0x00||0x80||0x00)
+    /// ```
+    /// 
+    /// The key0 used in the key extraction operation is 16 bytes of 0x00. The plain
+    /// text used in the AES-CMAC calculation of the KDK is the Diffie-Hellman shared
+    /// secret elliptic curve field element in Little Endian format.
+    /// The plain text used in the AEK calculation includes:
+    /// 
+    /// * a counter (0x01)
+    /// 
+    /// * a label: the ASCII representation of the string 'AEK' in Little Endian format
+    /// 
+    /// * a bit length (0x80)
+    /// 
+    /// **responder_identity**
+    /// 
+    /// Identity information of responder including isv svn, isv product id, the enclave
+    /// attributes, MRSIGNER, and MRENCLAVE. The buffer must be in enclave address space. 
+    /// The caller should check the identity of the peer and decide whether to trust the 
+    /// peer and use the aek or the msg3_body.additional_prop field of msg3.
+    /// 
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// Any of the input parameters is incorrect.
+    /// 
+    /// **SGX_ERROR_INVALID_STATE**
+    /// 
+    /// The API is invoked in incorrect order or state.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    /// 
+    /// An unexpected error occurred.
+    /// 
+    pub fn proc_msg3(&mut self, 
+                     msg3: &SgxDhMsg3, 
+                     aek: &mut sgx_key_128bit_t,
+                     responder_identity: &mut sgx_dh_session_enclave_identity_t) -> SgxError {
+        
+        if rsgx_data_is_within_enclave(self) == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if (rsgx_raw_is_within_enclave(msg3 as * const _ as * const u8, mem::size_of::<SgxDhMsg3>()) == false) ||
+           (rsgx_data_is_within_enclave(aek) == false) ||
+           (rsgx_data_is_within_enclave(responder_identity) == false) {
+            *self = Self::default();
+            self.state = SgxDhSessionState::SGX_DH_SESSION_STATE_ERROR;
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if msg3.msg3_body.additional_prop.len() > 0 {
+            if (rsgx_slice_is_within_enclave(&msg3.msg3_body.additional_prop) == false) ||
+               (msg3.msg3_body.additional_prop.len() > (u32::max_value() as usize) - mem::size_of::<sgx_dh_msg3_t>()) {
+                *self = Self::default();
+                self.state = SgxDhSessionState::SGX_DH_SESSION_STATE_ERROR;
+                return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+            }
+        }
+
+        if self.state != SgxDhSessionState::SGX_DH_SESSION_INITIATOR_WAIT_M3 {
+            *self = Self::default();
+            self.state = SgxDhSessionState::SGX_DH_SESSION_STATE_ERROR;
+            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
+        }
+
+        try!(self.dh_verify_message3(msg3).map_err(|ret| self.set_error(ret)));
+        * aek = try!(derive_key(&self.shared_key, &EC_AEK_LABEL).map_err(|ret| self.set_error(ret)));
+       
+        *self = Self::default();
+        self.state = SgxDhSessionState::SGX_DH_SESSION_ACTIVE;
+
+        responder_identity.cpu_svn = msg3.msg3_body.report.body.cpu_svn;
+        responder_identity.misc_select = msg3.msg3_body.report.body.misc_select;
+        responder_identity.isv_svn = msg3.msg3_body.report.body.isv_svn;
+        responder_identity.isv_prod_id = msg3.msg3_body.report.body.isv_prod_id;
+        responder_identity.attributes = msg3.msg3_body.report.body.attributes;
+        responder_identity.mr_signer = msg3.msg3_body.report.body.mr_signer;
+        responder_identity.mr_enclave = msg3.msg3_body.report.body.mr_enclave;
+
+        Ok(())
+    }
+
+    fn dh_generate_message2(&self, msg1: &SgxDhMsg1, msg2: &mut SgxDhMsg2) -> SgxError {
+
+        msg2.report = Default::default();
+        msg2.cmac = Default::default();
+        msg2.g_b = self.pub_key;
+
+        let sha_handle = SgxShaHandle::new();
+        try!(sha_handle.init());
+        try!(sha_handle.update_msg(&msg1.g_a));
+        try!(sha_handle.update_msg(&msg2.g_b));
+        let msg_hash = try!(sha_handle.get_hash());
+
+        let mut report_data = sgx_report_data_t::default();
+        report_data.d[..SGX_SHA256_HASH_SIZE].copy_from_slice(&msg_hash);
+        report_data.d[SGX_SHA256_HASH_SIZE..SGX_SHA256_HASH_SIZE + 2].copy_from_slice(&AES_CMAC_KDF_ID);
+        
+        msg2.report = try!(rsgx_create_report(&msg1.target, &report_data));
+        msg2.cmac = try!(rsgx_rijndael128_cmac_msg(&self.smk_aek, &msg2.report));
+
+        Ok(())
+    }
+
+    fn dh_verify_message3(&self, msg3: &SgxDhMsg3) -> SgxError {
+
+        let add_prop_len = msg3.msg3_body.additional_prop.len() as u32;
+
+        let cmac_handle = SgxCmacHandle::new();
+        try!(cmac_handle.init(&self.smk_aek));
+        try!(cmac_handle.update_msg(&msg3.msg3_body.report));
+        try!(cmac_handle.update_msg(&add_prop_len));
+        if add_prop_len > 0 {
+            try!(cmac_handle.update_slice(&msg3.msg3_body.additional_prop));
+        }
+        let data_mac = try!(cmac_handle.get_hash());
+
+        if data_mac.eq(&msg3.cmac) == false {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+
+        try!(rsgx_verify_report(&msg3.msg3_body.report));
+    
+        let sha_handle = SgxShaHandle::new();
+        try!(sha_handle.init());
+        try!(sha_handle.update_msg(&self.pub_key));
+        try!(sha_handle.update_msg(&self.peer_pub_key));
+        let msg_hash = try!(sha_handle.get_hash());
+        
+        let data_hash = &msg3.msg3_body.report.body.report_data.d[..SGX_SHA256_HASH_SIZE];
+        if msg_hash.eq(data_hash) == false {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+
+        Ok(())
+    }
+
+    fn set_error(&mut self, sgx_ret: sgx_status_t) -> sgx_status_t {
+
+        *self = Self::default();
+        self.state = SgxDhSessionState::SGX_DH_SESSION_STATE_ERROR;
+        let ret = match sgx_ret {
+            sgx_status_t::SGX_ERROR_OUT_OF_MEMORY => sgx_status_t::SGX_ERROR_OUT_OF_MEMORY,
+            _ => sgx_status_t::SGX_ERROR_UNEXPECTED,
+        };
+        ret   
+    }
+}
diff --git a/sgx_tdh/src/ecp.rs b/sgx_tdh/src/ecp.rs
new file mode 100644
index 0000000..dfe2459
--- /dev/null
+++ b/sgx_tdh/src/ecp.rs
@@ -0,0 +1,66 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+use sgx_types::*;
+use sgx_tcrypto::*;
+
+
+pub const EC_LABEL_LENGTH: usize = 3;
+pub const EC_SMK_LABEL: [u8; EC_LABEL_LENGTH] = [0x53, 0x4D, 0x4B];
+pub const EC_AEK_LABEL: [u8; EC_LABEL_LENGTH] = [0x41, 0x45, 0x4B];
+pub const EC_DERIVATION_BUFFER_SIZE: usize = 7;
+
+pub fn derive_key(shared_key: &sgx_ec256_dh_shared_t, 
+                  label: &[u8; EC_LABEL_LENGTH]) -> SgxResult<sgx_ec_key_128bit_t> {
+
+    let cmac_key = sgx_cmac_128bit_key_t::default();
+    let mut key_derive_key = try!(rsgx_rijndael128_cmac_msg(&cmac_key, shared_key).map_err(set_error));
+
+    //derivation_buffer = counter(0x01) || label || 0x00 || output_key_len(0x0080)
+    let mut derivation_buffer = [0_u8; EC_DERIVATION_BUFFER_SIZE];
+    derivation_buffer[0] = 0x01;
+    derivation_buffer[1] = label[0];
+    derivation_buffer[2] = label[1];
+    derivation_buffer[3] = label[2];
+    derivation_buffer[4] = 0x00;
+    derivation_buffer[5] = 0x80;
+    derivation_buffer[6] = 0x00;
+
+    let result = rsgx_rijndael128_cmac_slice(&key_derive_key, &derivation_buffer).map_err(set_error);
+    key_derive_key = Default::default();
+    result
+}
+
+fn set_error(sgx_ret: sgx_status_t) -> sgx_status_t {
+
+    let ret = match sgx_ret {
+        sgx_status_t::SGX_ERROR_OUT_OF_MEMORY => sgx_status_t::SGX_ERROR_OUT_OF_MEMORY,
+        _ => sgx_status_t::SGX_ERROR_UNEXPECTED,
+    };
+    ret   
+}
\ No newline at end of file
diff --git a/sgx_tdh/src/lib.rs b/sgx_tdh/src/lib.rs
new file mode 100644
index 0000000..f63c926
--- /dev/null
+++ b/sgx_tdh/src/lib.rs
@@ -0,0 +1,64 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//! # Diffie–Hellman (DH) Session Establishment Functions
+//! 
+//! These functions allow an ISV to establish secure session between two enclaves using the EC DH Key exchange protocol.
+//! 
+#![crate_name = "sgx_tdh"]
+#![crate_type = "rlib"]
+
+#![cfg_attr(not(feature = "use_std"), no_std)]
+
+#![cfg_attr(not(feature = "use_std"), feature(alloc, collections))]
+
+#![allow(non_camel_case_types)]
+#![allow(unused_assignments)]
+
+#[cfg(feature = "use_std")]
+#[macro_use]
+extern crate std as core;
+
+#[cfg(not(feature = "use_std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "use_std"))]
+#[macro_use]
+extern crate collections;
+
+extern crate sgx_types;
+extern crate sgx_trts;
+extern crate sgx_tcrypto;
+extern crate sgx_tse;
+
+pub mod dh;
+pub use self::dh::*;
+
+mod ecp;
+
+
diff --git a/sgx_tkey_exchange/Cargo.toml b/sgx_tkey_exchange/Cargo.toml
new file mode 100644
index 0000000..dfe672c
--- /dev/null
+++ b/sgx_tkey_exchange/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "sgx_tkey_exchange"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../sgx_types" }
\ No newline at end of file
diff --git a/sgx_tkey_exchange/src/lib.rs b/sgx_tkey_exchange/src/lib.rs
new file mode 100644
index 0000000..355bd2a
--- /dev/null
+++ b/sgx_tkey_exchange/src/lib.rs
@@ -0,0 +1,268 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//! # Trusted Key Exchange Library
+//!
+//! The library allow an ISV to exchange secrets between its server and its enclaves. They are used in 
+//! concert with untrusted Key Exchange functions. 
+//!
+#![crate_name = "sgx_tkey_exchange"]
+#![crate_type = "rlib"]
+
+#![cfg_attr(not(feature = "use_std"), no_std)]
+
+extern crate sgx_types;
+use sgx_types::*;
+
+///
+/// The rsgx_ra_init function creates a context for the remote attestation and key exchange process.
+///
+/// # Description
+///
+/// This is the first API user should call for a key exchange process. The context returned from this 
+/// function is used as a handle for other APIs in the key exchange library.
+///
+/// # Parameters
+///
+/// **p_pub_key**
+///
+/// The EC public key of the service provider based on the NIST P-256 elliptic curve.
+///
+/// **b_pse**
+///
+/// If true, platform service information is needed in message 3. The caller should make sure a PSE session 
+/// has been established using rsgx_create_pse_session before attempting to establish a remote attestation 
+/// and key exchange session involving platform service information.
+///
+/// # Requirements
+///
+/// Header: sgx_tkey_exchange.edl
+///
+/// Library: libsgx_tkey_exchange.a
+///
+/// # Return value
+///
+/// The output context for the subsequent remote attestation and key exchange process, to be used in 
+/// sgx_ra_get_msg1 and sgx_ra_proc_msg2.
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Indicates an error that the input parameters are invalid.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Not enough memory is available to complete this operation, or contexts reach the limits.
+///
+/// **SGX_ERROR_AE_SESSION_INVALID**
+///
+/// The session is invalid or ended by the server.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// Indicates that an unexpected error occurred.
+///
+pub fn rsgx_ra_init(p_pub_key: &sgx_ec256_public_t, b_pse: i32) -> SgxResult<sgx_ra_context_t> {    
+    
+    let mut context: sgx_ra_context_t = 0;
+    let ret = unsafe {
+        sgx_ra_init(p_pub_key as * const sgx_ec256_public_t, 
+                    b_pse, 
+                    &mut context as * mut sgx_ra_context_t)
+    };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(context),
+        _ => Err(ret),
+    }
+}
+
+///
+/// The rsgx_ra_init_ex function creates a context for the remote attestation and key exchange process 
+/// while it allows the use of a custom defined Key Derivation Function (KDF).
+///
+/// # Description
+///
+/// This is the first API user should call for a key exchange process. The context returned from this 
+/// function is used as a handle for other APIs in the key exchange library.
+///
+/// # Parameters
+///
+/// **p_pub_key**
+///
+/// The EC public key of the service provider based on the NIST P-256 elliptic curve.
+///
+/// **b_pse**
+///
+/// If true, platform service information is needed in message 3. The caller should make sure a PSE session 
+/// has been established using rsgx_create_pse_session before attempting to establish a remote attestation 
+/// and key exchange session involving platform service information.
+///
+/// **derive_key_cb**
+///
+/// This a pointer to a call back routine matching the funtion prototype of sgx_ra_derive_secret_keys_t. 
+/// This function takes the Diffie-Hellman shared secret as input to allow the ISV enclave to generate 
+/// their own derived shared keys (SMK, SK, MK and VK).
+///
+/// # Requirements
+///
+/// Header: sgx_tkey_exchange.edl
+///
+/// Library: libsgx_tkey_exchange.a
+///
+/// # Return value
+///
+/// The output context for the subsequent remote attestation and key exchange process, to be used in 
+/// sgx_ra_get_msg1 and sgx_ra_proc_msg2.
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Indicates an error that the input parameters are invalid.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Not enough memory is available to complete this operation, or contexts reach the limits.
+///
+/// **SGX_ERROR_AE_SESSION_INVALID**
+///
+/// The session is invalid or ended by the server.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// Indicates that an unexpected error occurred.
+///
+pub fn rsgx_ra_init_ex(p_pub_key: &sgx_ec256_public_t,
+                       b_pse: i32,
+                       derive_key_cb: sgx_ra_derive_secret_keys_t) -> SgxResult<sgx_ra_context_t> {  
+
+    let mut context: sgx_ra_context_t = 0;
+    let ret = unsafe {
+        sgx_ra_init_ex(p_pub_key as * const sgx_ec256_public_t,
+                       b_pse,
+                       derive_key_cb,
+                       &mut context as * mut sgx_ra_context_t)
+    };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(context),
+        _ => Err(ret),
+    }  
+}
+
+///
+/// The sgx_ra_get_keys function is used to get the negotiated keys of a remote attestation and key exchange session. 
+///
+/// This function should only be called after the service provider accepts the remote attestation and key exchange 
+/// protocol message 3 produced by sgx_ra_proc_msg2.
+///
+/// # Description
+///
+/// After a successful key exchange process, this API can be used in the enclave to get specific key associated 
+/// with this remote attestation and key exchange session.
+///
+/// # Parameters
+///
+/// **context**
+///
+/// Context returned by rsgx_ra_init.
+///
+/// **keytype**
+///
+/// The type of the keys, which can be SGX_RA_KEY_MK, SGX_RA_KEY_SK, or SGX_RA_VK.
+///
+/// # Requirements
+///
+/// Header: sgx_tkey_exchange.edl
+///
+/// Library: libsgx_tkey_exchange.a
+///
+/// # Return value
+///
+/// The key returned.
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Indicates an error that the input parameters are invalid.
+///
+/// **SGX_ERROR_INVALID_STATE**
+///
+/// Indicates this API is invoked in incorrect order, it can be called only after a success session has been established. 
+/// In other words, sgx_ra_proc_msg2 should have been called and no error returned.
+///
+pub fn rsgx_ra_get_keys(context: sgx_ra_context_t, keytype: sgx_ra_key_type_t) -> SgxResult<sgx_ra_key_128_t> {
+
+    let mut key = sgx_ra_key_128_t::default();
+    let ret = unsafe {
+        sgx_ra_get_keys(context, keytype, &mut key as * mut sgx_ra_key_128_t)
+    };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(key),
+        _ => Err(ret),
+    }
+}
+
+///
+/// rsgx_ra_close release context created by rsgx_ra_init or rsgx_ra_init_ex.
+///
+/// Call the rsgx_ra_close function to release the remote attestation and key exchange context after 
+/// the process is done and the context isn’t needed anymore.
+///
+/// # Description
+///
+/// At the end of a key exchange process, the caller needs to use this API in an enclave to clear and 
+/// free memory associated with this remote attestation session.
+///
+/// # Parameters
+///
+/// **context**
+///
+/// Context returned by rsgx_ra_init.
+///
+/// # Requirements
+///
+/// Header: sgx_tkey_exchange.edl
+///
+/// Library: libsgx_tkey_exchange.a
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Indicates an error that the input parameters are invalid.
+///
+pub fn rsgx_ra_close(context: sgx_ra_context_t) -> SgxError {
+
+    let ret = unsafe { sgx_ra_close(context) };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
diff --git a/sgx_trts/Cargo.toml b/sgx_trts/Cargo.toml
new file mode 100644
index 0000000..fd1e9df
--- /dev/null
+++ b/sgx_trts/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "sgx_trts"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../sgx_types" }
diff --git a/sgx_trts/src/lib.rs b/sgx_trts/src/lib.rs
new file mode 100644
index 0000000..e815cba
--- /dev/null
+++ b/sgx_trts/src/lib.rs
@@ -0,0 +1,392 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//! # Trusted Runtime System
+//!
+//! The Intel(R) SGX trusted runtime system (tRTS) is a key component of the Intel(R) Software Guard Extensions SDK. 
+//! It provides the enclave entry point logic as well as other functions to be used by enclave developers.
+//!
+//! **Intel(R) Software Guard Extensions Helper Functions**
+//!
+//! **CustomExceptionHandling**
+//!
+//! # Intel(R) Software Guard Extensions Helper Functions
+//! 
+//! The tRTS provides the helper functions for you to determine whether a given address is within or outside 
+//! enclave memory.
+//!
+//! The tRTS provides a wrapper to the RDRAND instruction to generate a true random number from hardware.
+//! enclave developers should use the rsgx_read_rand function to get true random numbers.
+//!
+//! # CustomExceptionHandling
+//!
+//! The Intel(R) Software Guard Extensions SDK provides an API to allow you to register functions, or exception handlers, 
+//! to handle a limited set of hardware exceptions. When one of the enclave supported hardware exceptions occurs within 
+//! the enclave, the registered exception handlers will be called in a specific order until an exception handler reports 
+//! that it has handled the exception. For example, issuing a CPUID instruction inside an Enclave will result in a #UD fault 
+//! (Invalid Opcode Exception). ISV enclave code can call rsgx_register_exception_handler to register a function of type 
+//! sgx_exception_handler_t to respond to this exception. To check a list of enclave supported exceptions, see Intel(R) 
+//! Software Guard Extensions Programming Reference.
+//! 
+//! **Note**
+//!
+//! Custom exception handling is only supported in HW mode. Although the exception handlers can be registered in simulation mode, 
+//! the exceptions cannot be caught and handled within the enclave.
+//!
+//! **Note**
+//!
+//! OCALLs are not allowed in the exception handler.
+//!
+//! **Note**
+//!
+//! Custom exception handing only saves general purpose registers in sgx_ exception_info_t. You should be careful when touching 
+//! other registers in the exception handlers.
+//!
+//! **Note**
+//!
+//! If the exception handlers can not handle the exceptions, abort() is called.
+//! abort() makes the enclave unusable and generates another exception.
+//!
+#![crate_name = "sgx_trts"]
+#![crate_type = "rlib"]
+
+#![cfg_attr(not(feature = "use_std"), no_std)]
+#![allow(non_camel_case_types)]
+
+#[cfg(feature = "use_std")]
+extern crate std as core;
+
+extern crate sgx_types;
+use sgx_types::*;
+use core::mem;
+
+///
+/// rsgx_read_rand function is used to generate a random number inside the enclave.
+///
+/// # Description
+///
+/// The rsgx_read_rand function is provided to replace the standard pseudo-random sequence generation functions 
+/// inside the enclave, since these standard functions are not supported in the enclave, such as rand, srand, etc. 
+/// For HW mode, the function generates a real-random sequence; while for simulation mode, the function generates 
+/// a pseudo-random sequence.
+///
+/// # Parameters
+///
+/// **rand**
+///
+/// A pointer to the buffer that receives the random number. The rand buffer can be either within or outside the enclave, 
+/// but it is not allowed to be across the enclave boundary or wrapped around.
+///
+/// # Requirements
+///
+/// Library: libsgx_trts.a
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Invalid input parameters detected.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// Indicates an unexpected error occurs during the valid random number gen- eration process.
+///
+pub fn rsgx_read_rand(rand: &mut [u8]) -> SgxError {
+
+    let ret = unsafe { sgx_read_rand(rand.as_mut_ptr(), rand.len()) };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
+
+
+pub type exception_handle = * const c_void;
+
+///
+/// rsgx_register_exception_handler register an exception handler.
+///
+/// rsgx_register_exception_handler allows developers to register an exception handler, and specify whether to prepend 
+/// (when is_first_handler is equal to 1) or append the handler to the handler chain.
+///
+/// # Description
+///
+/// The Intel(R) SGX SDK supports the registration of custom exception handler functions. You can write your own code to 
+/// handle a limited set of hardware exceptions. For example, a CPUID instruction inside an enclave will effectively result 
+/// in a #UD fault (Invalid Opcode Exception). ISV enclave code can have an exception handler to prevent the enclave from 
+/// being trapped into an exception condition. 
+///
+/// Calling rsgx_register_exception_handler allows you to register an exception handler, and specify whether to prepend 
+/// (when is_first_handler is nonzero) or append the handler to the handler chain.
+///
+/// After calling rsgx_register_exception_handler to prepend an exception handler, a subsequent call to this function may 
+/// add another exception handler at the beginning of the handler chain. Therefore the order in which exception handlers 
+/// are called does not only depend on the value of the is_first_handler parameter, but more importantly depends on the order 
+/// in which exception handlers are registered.
+///
+/// # Parameters
+///
+/// **is_first_handler**
+///
+/// Specify the order in which the handler should be called. If the parameter is nonzero, the handler is the first handler 
+/// to be called. If the parameter is zero, the handler is the last handler to be called.
+///
+/// **exception_handler**
+///
+/// The exception handler to be called
+///
+/// # Requirements
+///
+/// Library: libsgx_trts.a
+///
+/// # Return value
+///
+/// **Some(exception_handle)**
+///
+/// Indicates the exception handler is registered successfully. The return value is an open handle to the custom exception handler.
+///
+/// **None**
+///
+/// The exception handler was not registered.
+///
+pub fn rsgx_register_exception_handler(is_first_handler: u32, exception_handler: sgx_exception_handler_t) -> Option<exception_handle> {
+    
+    let handle = unsafe {
+        sgx_register_exception_handler(is_first_handler, exception_handler)
+    };
+
+    if handle.is_null() { None } else { Some(handle) }
+}
+
+///
+/// rsgx_unregister_exception_handler is used to unregister a custom exception handler.
+///
+/// # Description
+///
+/// The Intel(R) SGX SDK supports the registration of custom exception handler functions. An enclave developer 
+/// can write their own code to handle a limited set of hardware exceptions. 
+///
+/// Calling rsgx_unregister_exception_handler allows developers to unregister an exception handler that was registered earlier.
+///
+/// # Parameters
+///
+/// **handle**
+///
+/// A handle to the custom exception handler previously registered using the rsgx_register_exception_handler function.
+///
+/// # Requirements
+///
+/// Library: libsgx_trts.a
+///
+/// # Return value
+///
+/// **true**
+///
+/// The custom exception handler is unregistered successfully.
+///
+/// **false**
+///
+/// The exception handler was not unregistered (not a valid pointer, handler not found).
+///
+pub fn rsgx_unregister_exception_handler(handle: exception_handle) -> bool {
+
+    let ret = unsafe { sgx_unregister_exception_handler(handle) };
+    if ret == 0 { false } else { true }
+}
+
+///
+/// rsgx_data_is_within_enclave checks whether a given address is within enclave memory. 
+///
+#[inline]
+pub fn rsgx_data_is_within_enclave<T: Copy>(data: &T) -> bool {
+
+    rsgx_raw_is_within_enclave(data as * const _ as * const u8, mem::size_of::<T>())
+}
+
+///
+/// rsgx_slice_is_within_enclave checks whether a given address is within enclave memory. 
+///
+#[inline]
+pub fn rsgx_slice_is_within_enclave<T: Copy>(data: &[T]) -> bool {
+
+    rsgx_raw_is_within_enclave(data.as_ptr() as * const u8, mem::size_of::<T>() * data.len())
+}
+
+///
+/// rsgx_raw_is_within_enclave checks whether a given address is within enclave memory. 
+///
+/// The rsgx_raw_is_within_enclave function checks that the buffer located at the pointer addr with its 
+/// length of size is an address that is strictly within the calling enclave address space.
+///
+/// # Description
+/// 
+/// rsgx_raw_is_within_enclave simply compares the start and end address of the buffer with the calling 
+/// enclave address space. It does not check the property of the address. Given a function pointer, you 
+/// sometimes need to confirm whether such a function is within the enclave. In this case, it is recommended
+/// to use rsgx_raw_is_within_enclave with a size of 1.
+/// 
+/// # Parameters
+///
+/// **addr**
+///
+/// The start address of the buffer.
+///
+/// **size**
+///
+/// The size of the buffer.
+///
+/// # Requirements
+///
+/// Library: libsgx_trts.a
+///
+/// # Return value
+///
+/// **true**
+///
+/// The buffer is strictly within the enclave address space.
+///
+/// **false**
+///
+/// The whole buffer or part of the buffer is not within the enclave, or the buffer is wrapped around.
+///
+pub fn rsgx_raw_is_within_enclave(addr: * const u8, size: usize) -> bool {
+
+    let ret = unsafe { sgx_is_within_enclave(addr as * const c_void, size) };
+    if ret == 0 { false } else { true }
+}
+
+///
+/// rsgx_data_is_outside_enclave checks whether a given address is outside enclave memory. 
+///
+#[inline]
+pub fn rsgx_data_is_outside_enclave<T: Copy>(data: &T) -> bool {
+
+    rsgx_raw_is_outside_enclave(data as * const _ as * const u8,  mem::size_of::<T>())
+}
+
+///
+/// rsgx_slice_is_outside_enclave checks whether a given address is outside enclave memory. 
+///
+#[inline]
+pub fn rsgx_slice_is_outside_enclave<T: Copy>(data: &[T]) -> bool {
+
+    rsgx_raw_is_outside_enclave(data.as_ptr() as * const u8, mem::size_of::<T>() * data.len())
+}
+
+///
+/// rsgx_raw_is_outside_enclave checks whether a given address is outside enclave memory. 
+///
+/// The rsgx_raw_is_outside_enclave function checks that the buffer located at the pointer addr with its 
+/// length of size is an address that is strictly outside the calling enclave address space.
+///
+/// # Description
+/// 
+/// rsgx_raw_is_outside_enclave simply compares the start and end address of the buffer with the calling 
+/// enclave address space. It does not check the property of the address.
+/// 
+/// # Parameters
+///
+/// **addr**
+///
+/// The start address of the buffer.
+///
+/// **size**
+///
+/// The size of the buffer.
+///
+/// # Requirements
+///
+/// Library: libsgx_trts.a
+///
+/// # Return value
+///
+/// **true**
+///
+/// The buffer is strictly outside the enclave address space.
+///
+/// **false**
+///
+/// The whole buffer or part of the buffer is not outside the enclave, or the buffer is wrapped around.
+///
+pub fn rsgx_raw_is_outside_enclave(addr: * const u8, size: usize) -> bool {
+
+    let ret = unsafe { sgx_is_outside_enclave(addr as * const c_void, size) };
+    if ret == 0 { false } else { true }
+}
+
+///
+/// rsgx_get_thread_data is to get TD base address per thread.
+/// 
+/// **Note**
+///
+/// This API is only an experimental funtion.
+///
+#[inline]
+pub fn rsgx_get_thread_data() -> * const u8 {
+
+    unsafe { get_thread_data() as * const u8 }
+}
+
+///
+/// rsgx_get_enclave_base is to get enclave image base address.
+/// 
+/// **Note**
+///
+/// This API is only an experimental funtion.
+///
+#[inline]
+pub fn rsgx_get_enclave_base() -> * const u8 {
+
+    unsafe { get_enclave_base() as * const u8 }
+}
+
+///
+/// rsgx_get_heap_base is to get enclave heap base address.
+/// 
+/// **Note**
+///
+/// This API is only an experimental funtion.
+///
+#[inline]
+pub fn rsgx_get_heap_base() -> * const u8 {
+
+    unsafe { get_heap_base() as * const u8 }
+}
+
+///
+/// rsgx_get_heap_size is to get enclave heap size.
+/// 
+/// **Note**
+///
+/// This API is only an experimental funtion.
+///
+#[inline]
+pub fn rsgx_get_heap_size() -> usize {
+
+    unsafe { get_heap_size() }
+}
\ No newline at end of file
diff --git a/sgx_tse/Cargo.toml b/sgx_tse/Cargo.toml
new file mode 100644
index 0000000..d83690d
--- /dev/null
+++ b/sgx_tse/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "sgx_tse"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../sgx_types" }
\ No newline at end of file
diff --git a/sgx_tse/src/lib.rs b/sgx_tse/src/lib.rs
new file mode 100644
index 0000000..1511363
--- /dev/null
+++ b/sgx_tse/src/lib.rs
@@ -0,0 +1,221 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//! # Trusted SE Library
+//!
+//! The library provides functions for getting specific keys and for creating and verifying an enclave report. 
+//!
+#![crate_name = "sgx_tse"]
+#![crate_type = "rlib"]
+
+#![cfg_attr(not(feature = "use_std"), no_std)]
+
+extern crate sgx_types;
+use sgx_types::*;
+
+///
+/// The rsgx_create_report function tries to use the information of the target enclave and other information 
+/// to create a cryptographic report of the enclave.
+///
+/// This function is a wrapper for the SGX EREPORT instruction.
+///
+/// # Description
+/// 
+/// Use the function rsgx_create_report to create a cryptographic report that describes the contents of the 
+/// calling enclave. The report can be used by other enclaves to verify that the enclave is running on the 
+/// same platform. When an enclave calls rsgx_verify_report to verify a report, it will succeed only if
+/// the report was generated using the target_info for said enclave. This function is a wrapper for the SGX EREPORT 
+/// instruction.
+///
+/// Before the source enclave calls rsgx_create_report to generate a report, it needs to populate target_info with 
+/// information about the target enclave that will verify the report. The target enclave may obtain this information 
+/// calling rsgx_create_report with a default value for target_info and pass it to the source enclave at the beginning 
+/// of the inter-enclave attestation process.
+///
+/// # Parameters
+///
+/// **target_info**
+///
+/// A pointer to the sgx_target_info_t object that contains the information of the target enclave, 
+/// which will be able to cryptographically verify the report calling rsgx_verify_report.efore calling this function.
+///
+/// If value is default, sgx_create_report retrieves information about the calling enclave, 
+/// but the generated report cannot be verified by any enclave.
+///
+/// **report_data**
+///
+/// A pointer to the sgx_report_data_t object which contains a set of data used for communication between the enclaves.
+///
+/// # Requirements
+///
+/// Library: libsgx_tservice.a
+///
+/// # Return value
+///
+/// Cryptographic report of the enclave
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// An error is reported if any of the parameters memory is not within the enclave or the reserved fields 
+/// of the data structure are not set to zero.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Indicates that the enclave is out of memory.
+///
+pub fn rsgx_create_report(target_info: &sgx_target_info_t, report_data: &sgx_report_data_t) -> SgxResult<sgx_report_t> {
+
+    let mut report = sgx_report_t::default();
+    let ret = unsafe {
+        sgx_create_report(target_info as * const sgx_target_info_t,
+                          report_data as * const sgx_report_data_t,
+                          &mut report as * mut sgx_report_t)
+
+    };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(report),
+        _ => Err(ret),
+    }  
+}
+
+///
+/// The rsgx_verify_report function provides software verification for the report which is expected to be 
+/// generated by the rsgx_create_report function.
+///
+/// # Description
+/// 
+/// The rsgx_verify_report performs a cryptographic CMAC function of the input sgx_report_data_t object 
+/// in the report using the report key. Then the function compares the input report MAC value with the 
+/// calculated MAC value to determine whether the report is valid or not.
+///
+/// # Parameters
+///
+/// **report**
+///
+/// A pointer to an sgx_report_t object that contains the cryptographic report to be verified. 
+/// The report buffer must be within the enclave.
+///
+/// # Requirements
+///
+/// Library: libsgx_tservice.a
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// The report object is invalid.
+///
+/// **SGX_ERROR_MAC_MISMATCH**
+///
+/// Indicates report verification error.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// Indicates an unexpected error occurs during the report verification process.
+///
+pub fn rsgx_verify_report(report: &sgx_report_t) -> SgxError {
+
+    let ret = unsafe { sgx_verify_report(report as * const sgx_report_t) };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
+
+///
+/// The rsgx_get_key function generates a 128-bit secret key using the input information.
+///
+/// This function is a wrapper for the SGX EGETKEY instruction.
+///
+/// # Description
+/// 
+/// The rsgx_get_key function generates a 128-bit secret key from the processor specific key hierarchy with 
+/// the key_request information. If the function fails with an error code, the key buffer will be filled with 
+/// random numbers. The key_request structure needs to be initialized properly to obtain the requested key type. 
+/// See sgx_key_request_t for structure details.
+///
+/// # Parameters
+///
+/// **key_request**
+///
+/// A pointer to a sgx_key_request_t object used for selecting the appropriate key and any additional parameters 
+/// required in the derivation of that key. The pointer must be located within the enclave.
+///
+/// See details on the sgx_key_request_t to understand initializing this structure before calling this function.
+///
+/// # Requirements
+///
+/// Library: libsgx_tservice.a
+///
+/// # Return value
+///
+/// Cryptographic key
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Indicates an error that the input parameters are invalid.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Indicates an error that the enclave is out of memory.
+///
+/// **SGX_ERROR_INVALID_ATTRIBUTE**
+///
+/// Indicates the key_request requests a key for a KEYNAME which the enclave is not authorized.
+///
+/// **SGX_ERROR_INVALID_CPUSVN**
+///
+/// Indicates key_request->cpu_svn is beyond platform CPUSVN value
+///
+/// **SGX_ERROR_INVALID_ISVSVN**
+///
+/// Indicates key_request->isv_svn is greater than the enclave’s ISVSVN
+///
+/// **SGX_ERROR_INVALID_KEYNAME**
+///
+/// Indicates key_request->key_name is an unsupported value
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// Indicates an unexpected error occurs during the key generation process.
+///
+pub fn rsgx_get_key(key_request: &sgx_key_request_t) -> SgxResult<sgx_key_128bit_t> {
+
+    let mut key = sgx_key_128bit_t::default();
+    let ret = unsafe { sgx_get_key(key_request as * const sgx_key_request_t, &mut key as * mut sgx_key_128bit_t) };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(key),
+        _ => Err(ret),
+    }
+}
+
+
diff --git a/sgx_tseal/Cargo.toml b/sgx_tseal/Cargo.toml
new file mode 100644
index 0000000..f2ea399
--- /dev/null
+++ b/sgx_tseal/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "sgx_tseal"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../sgx_types" }
+sgx_trts = { path = "../sgx_trts" }
+sgx_tcrypto = { path = "../sgx_tcrypto" }
+sgx_tse = { path = "../sgx_tse" }
diff --git a/sgx_tseal/src/aad.rs b/sgx_tseal/src/aad.rs
new file mode 100644
index 0000000..351278e
--- /dev/null
+++ b/sgx_tseal/src/aad.rs
@@ -0,0 +1,480 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//! 
+//! Provides APIs to authenticate and verify the input data with AES-GMAC.
+//!
+use sgx_types::*;
+use core::mem;
+use core::ptr;
+use core::slice;
+use super::internal::*;
+#[cfg(not(feature = "use_std"))]
+use alloc::boxed::Box;
+
+/// The structure about sealed data, for authenticate and verify.
+pub struct SgxMacAadata<T: ?Sized> {
+    inner: SgxInternalSealedData,
+    marker: * const T,
+}
+
+impl<T> Default for SgxMacAadata<T> {
+    fn default() -> SgxMacAadata<T> {
+        SgxMacAadata {
+            inner: SgxInternalSealedData::new(),
+            marker: ptr::null(), 
+        }
+    }
+}
+
+impl<T> Default for SgxMacAadata<[T]> {
+    fn default() -> SgxMacAadata<[T]> {
+        let p = Box::<[T]>::default();
+        SgxMacAadata {
+            inner: SgxInternalSealedData::new(),
+            marker: Box::into_raw(p),
+        }
+    }
+}
+
+impl<T: ?Sized> Clone for SgxMacAadata<T> {
+    fn clone(&self) -> SgxMacAadata<T> {
+        SgxMacAadata {
+           inner: self.inner.clone(),
+           marker: self.marker,
+        }
+    }
+}
+
+impl<T> SgxMacAadata<T> {
+    ///
+    /// Create a SgxMacAadata with default values.
+    /// 
+    pub fn new() -> Self {
+        SgxMacAadata::default()
+    }
+
+    /// 
+    /// Convert a pointer of sgx_sealed_data_t buffer to SgxMacAadata.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    ///
+    /// **p**
+    ///
+    /// The mutable pointer of sgx_sealed_data_t buffer.
+    ///
+    /// **len**
+    ///
+    /// The size of the parameter `p`.
+    ///
+    /// # Return value 
+    ///
+    /// **Some(SgxMacAadata)**
+    ///
+    /// Indicates the conversion is successfully. The return value is SgxMacAadata.
+    ///
+    /// **None**
+    /// 
+    /// Maybe the size of T is zero.
+    /// 
+    pub unsafe fn from_raw_sealed_data_t(p: * mut sgx_sealed_data_t, len: u32) -> Option<Self> {
+        
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return None;
+        } 
+        SgxInternalSealedData::from_raw_sealed_data_t(p, len).map(|x| SgxMacAadata{inner: x, marker: ptr::null()})
+    }
+
+    /// 
+    /// This function is used to authenticate the input data with AES-GMAC.
+    ///
+    /// # Descryption
+    /// 
+    /// The mac_aadata function retrieves a key unique to the enclave and
+    /// uses that key to generate the authentication tag based on the input data buffer. This function can be utilized to provide authentication assurance for additional data (of practically unlimited length per invocation) that is not
+    /// encrypted. The data origin authentication can be demonstrated on future
+    /// instantiations of the enclave using the MAC stored into the data blob.
+    /// Use `calc_raw_sealed_data_size` to calculate the number of bytes to
+    /// allocate for the SgxMacAadata structure. The input sealed data buffer
+    /// must be allocated within the enclave
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    ///
+    /// **additional_text**
+    ///
+    /// Pointer to the plain text to provide authentication for.
+    ///
+    /// # Return value 
+    ///
+    /// The sealed data in SgxMacAadata.
+    ///
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// Indicates an error if the parameters do not meet any of the following conditions:
+    /// 
+    /// * additional_text buffer can be within or outside the enclave, but cannot cross the enclave boundary.
+    /// * encrypt_text must be non-zero.
+    /// * encrypt_text buffer must be within the enclave.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates a crypto library failure or the RDRAND instruction fails to generate a
+    /// random number.
+    /// 
+    pub fn mac_aadata(additional_text: &T) -> SgxResult<Self> {
+
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        } 
+        let aad_slice: &[u8] = unsafe{slice::from_raw_parts(additional_text as * const _ as * const u8, size)};      
+        let result = SgxInternalSealedData::mac_aadata(aad_slice);
+        result.map(|x| SgxMacAadata {inner: x, marker: ptr::null()})
+    }
+
+    /// 
+    /// This function is used to authenticate the input data with AES-GMAC. This is
+    /// the expert mode version of the function mac_aadata.
+    ///
+    /// # Descryption
+    /// 
+    /// The mac_aadata_ex is an extended version of mac_aadata. It
+    /// provides parameters for you to identify how to derive the sealing key (key
+    /// policy and attributes_mask). Typical callers of the seal library should be
+    /// able to use mac_aadata and the default values provided for key_policy (MR_SIGNER) and an attribute mask which includes the RESERVED,
+    /// INITED and DEBUG bits. Before you use this function, you should have a clear
+    /// understanding of the impact of using a policy and/or attribute_mask that
+    /// is different from that in mac_aadata.
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    /// 
+    /// **key_policy**
+    /// 
+    /// Specifies the policy to use in the key derivation. Function sgx_seal_data uses the MRSIGNER policy. 
+    ///
+    /// Key policy name | Value | Description 
+    /// ---|---|---
+    /// KEYPOLICY_MRENCLAVE | 0x0001 | -Derive key using the enclave??s ENCLAVE measurement register  
+    /// KEYPOLICY_MRSIGNER |0x0002 | -Derive key using the enclave??s SIGNER measurement register 
+    /// 
+    /// **attribute_mask**
+    /// 
+    /// Identifies which platform/enclave attributes to use in the key derivation. See  
+    /// the definition of sgx_attributes_t to determine which attributes will be  
+    /// checked.  Function sgx_seal_data uses flags=0xfffffffffffffff3,?xfrm=0. 
+    /// 
+    /// **misc_mask**
+    ///
+    /// The misc mask bits for the enclave. Reserved for future function extension.
+    ///
+    /// **additional_text**
+    ///
+    /// Pointer to the additional Message Authentication Code (MAC) data. 
+    /// This additional data is optional and no data is necessary.
+    ///
+    /// # Return value 
+    ///
+    /// The sealed data in SgxSealedData.
+    ///
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// Indicates an error if the parameters do not meet any of the following conditions:
+    /// 
+    /// * additional_text buffer can be within or outside the enclave, but cannot cross the enclave boundary.
+    /// * encrypt_text must be non-zero.
+    /// * encrypt_text buffer must be within the enclave.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates a crypto library failure or the RDRAND instruction fails to generate a
+    /// random number.
+    /// 
+    pub fn mac_aadata_ex(key_policy: u16,
+                         attribute_mask: sgx_attributes_t,
+                         misc_mask: sgx_misc_select_t,
+                         additional_text: &T) -> SgxResult<Self> {
+
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        } 
+        let aad_slice: &[u8] = unsafe{slice::from_raw_parts(additional_text as * const _ as * const u8, size)};
+        let result = SgxInternalSealedData::mac_aadata_ex(key_policy, 
+                                                          attribute_mask, 
+                                                          misc_mask, 
+                                                          aad_slice);
+        result.map(|x| SgxMacAadata {inner: x, marker: ptr::null()})
+    }
+
+    ///
+    /// This function is used to verify the authenticity of the input sealed data structure using AES-GMAC. This function verifies the MAC generated with sgx_mac_aadataorsgx_mac_aadata_ex.
+    ///
+    /// # Descryption
+    /// 
+    /// The sgx_unmac_aadata function verifies the tag with AES-GMAC. Use this
+    /// function to demonstrate the authenticity of data that was preserved by an
+    /// earlier instantiation of this enclave.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///
+    /// # Return value 
+    ///
+    /// The pointer of the additional data.
+    ///
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// The size of T may be zero.
+    /// 
+    /// **SGX_ERROR_INVALID_CPUSVN**
+    /// 
+    /// The CPUSVN in the data blob is beyond the CPUSVN value of the platform.
+    /// 
+    /// **SGX_ERROR_INVALID_ISVSVN**
+    /// 
+    /// The ISVSVN in the data blob is greater than the ISVSVN value of the enclave.
+    /// 
+    /// **SGX_ERROR_MAC_MISMATCH**
+    /// 
+    /// The tag verification fails. The error may be caused by a platform update, software update, or corruption of the sealed_data_t structure.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates a crypto library failure or the RDRAND instruction fails to generate a
+    /// random number.
+    /// 
+    pub fn unmac_aadata(&self) -> SgxResult<Box<T>> {
+
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        let aad_len = self.get_add_mac_txt_len() as usize;
+        if size != aad_len {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        self.inner.unmac_aadata().map(|x| {
+            let ptr = Box::into_raw(x.additional);
+            unsafe{Box::from_raw(ptr as * mut _ as * mut T)}
+        })
+    }
+}
+
+impl<T> SgxMacAadata<[T]> {
+    ///
+    /// Create a SgxMacAadata with default values.
+    /// 
+    pub fn new() -> Self {
+        SgxMacAadata::default()
+    }
+
+    /// 
+    /// Convert a pointer of sgx_sealed_data_t buffer to SgxMacAadata.
+    ///
+    pub unsafe fn from_raw_sealed_data_t(p: * mut sgx_sealed_data_t, len: u32) -> Option<Self> {
+        
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return None;
+        } 
+        let opt = SgxInternalSealedData::from_raw_sealed_data_t(p, len);
+        opt.map(|x| {
+            let p = Box::<[T]>::default();
+            SgxMacAadata{inner: x, marker: Box::into_raw(p)}
+        })
+    }
+
+    /// 
+    /// This function is used to authenticate the input data with AES-GMAC.
+    ///
+    pub fn mac_aadata(additional_text: &[T]) -> SgxResult<Self> {
+
+        let size = mem::size_of::<T>() * additional_text.len();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        let aad_slice: &[u8] = unsafe{slice::from_raw_parts(additional_text.as_ptr() as * const _ as * const u8, size)};      
+        let result = SgxInternalSealedData::mac_aadata(aad_slice);
+        result.map(|x| {
+            let p = Box::<[T]>::default();
+            SgxMacAadata {
+                inner: x,
+                marker: Box::into_raw(p),
+            }
+        })
+    }
+
+    /// 
+    /// This function is used to authenticate the input data with AES-GMAC. This is
+    /// the expert mode version of the function mac_aadata.
+    ///
+    pub fn mac_aadata_ex(key_policy: u16,
+                         attribute_mask: sgx_attributes_t,
+                         misc_mask: sgx_misc_select_t,
+                         additional_text: &[T]) -> SgxResult<Self> {
+
+        let size = mem::size_of::<T>() * additional_text.len();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        let aad_slice: &[u8] = unsafe{slice::from_raw_parts(additional_text.as_ptr() as * const _ as * const u8, size)};
+        let result = SgxInternalSealedData::mac_aadata_ex(key_policy, 
+                                                          attribute_mask, 
+                                                          misc_mask, 
+                                                          aad_slice);
+        result.map(|x| {
+            let p = Box::<[T]>::default();
+            SgxMacAadata {
+                inner: x,
+                marker: Box::into_raw(p),
+            }
+        })
+    }
+
+    ///
+    /// This function is used to verify the authenticity of the input sealed data structure using AES-GMAC. This function verifies the MAC generated with sgx_mac_aadataorsgx_mac_aadata_ex.
+    ///
+    pub fn unmac_aadata(&self) -> SgxResult<Box<[T]>> {
+
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        let aad_len = self.get_add_mac_txt_len() as usize;
+        if size > aad_len {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        if (aad_len % size) != 0 {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        self.inner.unmac_aadata().map(|x| {
+            let ptr = Box::into_raw(x.additional);
+            unsafe{Box::from_raw(ptr as * mut _ as * mut [T])}
+        })
+    }
+}
+
+impl<T: ?Sized> SgxMacAadata<T> {
+    ///
+    /// Get the size of payload in SgxMacAadata.
+    ///
+    pub fn get_payload_size(&self) -> u32 {
+        self.inner.get_payload_size()
+    }
+    ///
+    /// Get a slice of payload in SgxMacAadata.
+    ///
+    pub fn get_payload_tag(&self) -> &[u8; SGX_SEAL_TAG_SIZE] {
+        self.inner.get_payload_tag()
+    }
+    ///
+    /// Get the pointer of sgx_key_request_t in SgxMacAadata.
+    ///
+    pub fn get_key_request(&self) -> &sgx_key_request_t {
+        self.inner.get_key_request()
+    }
+
+    ///
+    /// Get a slice of additional text in SgxMacAadata.
+    ///
+    pub fn get_additional_txt(&self) -> &[u8] {
+        self.inner.get_additional_txt()
+    }
+
+    ///
+    /// Calculate the size of the sealed data in SgxMacAadata.
+    ///
+    pub fn calc_raw_sealed_data_size(add_mac_txt_size: u32, encrypt_txt_size: u32) -> u32  {
+        SgxInternalSealedData::calc_raw_sealed_data_size(add_mac_txt_size, encrypt_txt_size)
+    }
+
+    ///
+    /// Get the size of the additional mactext in SgxMacAadata.
+    ///
+    pub fn get_add_mac_txt_len(&self) -> u32 {
+        self.inner.get_add_mac_txt_len()
+    } 
+
+    ///
+    /// Convert SgxMacAadata to the pointer of sgx_sealed_data_t.
+    ///
+    /// # Parameters
+    ///
+    /// **p**
+    ///
+    /// The pointer of sgx_sealed_data_t to save the data in SgxMacAadata.
+    ///
+    /// **len**
+    ///
+    /// The size of the pointer of sgx_sealed_data_t.
+    ///
+    /// # Error
+    ///
+    /// **Some(* mut sgx_sealed_data_t)**
+    ///
+    /// Indicates the conversion is successfully. The return value is the pointer of sgx_sealed_data_t.
+    ///
+    /// **None**
+    ///
+    /// May be the parameter p and len is not avaliable.
+    ///
+    pub unsafe fn to_raw_sealed_data_t(&self, p: * mut sgx_sealed_data_t, len: u32) -> Option<* mut sgx_sealed_data_t> {
+        self.inner.to_raw_sealed_data_t(p, len)
+    }
+}
\ No newline at end of file
diff --git a/sgx_tseal/src/internal.rs b/sgx_tseal/src/internal.rs
new file mode 100644
index 0000000..087607e
--- /dev/null
+++ b/sgx_tseal/src/internal.rs
@@ -0,0 +1,532 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+use sgx_types::*;
+use sgx_trts::*;
+use sgx_tcrypto::*;
+use sgx_tse::*;
+use core::mem;
+use core::ptr;
+use super::seal::SgxUnsealedData;
+#[cfg(not(feature = "use_std"))]
+use alloc::boxed::Box;
+#[cfg(not(feature = "use_std"))]
+use collections::vec::Vec;
+
+const SGX_MISCSEL_EXINFO: uint32_t     = 0x00000001;
+const TSEAL_DEFAULT_MISCMASK: uint32_t = (!SGX_MISCSEL_EXINFO);
+
+
+#[derive(Clone, Default)]
+struct SgxPayload {
+    payload_size: u32,
+    reserved: [u8; 12],
+    payload_tag: [u8; SGX_SEAL_TAG_SIZE],
+    encrypt: Box<[u8]>,
+    additional: Box<[u8]>,
+}
+
+#[derive(Clone, Default)]
+pub struct SgxInternalSealedData {
+    key_request: sgx_key_request_t,
+    payload_data: SgxPayload,
+}
+
+impl SgxInternalSealedData {
+
+    pub fn new() -> Self {
+        SgxInternalSealedData::default()
+    }
+    pub fn get_payload_size(&self) -> u32 {
+        self.payload_data.payload_size
+    }
+    pub fn get_payload_tag(&self) -> &[u8; SGX_SEAL_TAG_SIZE] {
+        &self.payload_data.payload_tag
+    }
+    pub fn get_key_request(&self) -> &sgx_key_request_t {
+        &self.key_request
+    }
+    pub fn get_encrypt_txt(&self) -> &[u8] {
+        &*self.payload_data.encrypt
+    }
+    pub fn get_additional_txt(&self) -> &[u8] {
+        &*self.payload_data.additional
+    }
+    
+    pub fn calc_raw_sealed_data_size(add_mac_txt_size: u32, encrypt_txt_size: u32) -> u32 {
+
+        let max = u32::max_value();
+        let sealed_data_size = mem::size_of::<sgx_sealed_data_t>() as u32;
+
+        if add_mac_txt_size > max - encrypt_txt_size {
+            return max;
+        }
+        let payload_size: u32 = add_mac_txt_size + encrypt_txt_size;
+        if payload_size > max - sealed_data_size {
+            return max;
+        }           
+        sealed_data_size + payload_size
+    }
+
+    pub fn get_add_mac_txt_len(&self) -> u32 {
+
+        let data_size = self.payload_data.additional.len();
+        if data_size > self.payload_data.payload_size as usize {
+            u32::max_value()
+        } else if data_size >= u32::max_value() as usize {
+            u32::max_value()
+        } else {
+            data_size as u32
+        }
+    }
+    
+    pub fn get_encrypt_txt_len(&self) -> u32 {
+        
+        let data_size = self.payload_data.encrypt.len();
+        if data_size > self.payload_data.payload_size as usize {
+            u32::max_value()
+        } else if data_size >= u32::max_value() as usize {
+            u32::max_value()
+        } else {
+            data_size as u32
+        }
+    }
+
+    pub unsafe fn to_raw_sealed_data_t(&self, p: * mut sgx_sealed_data_t, len: u32) -> Option<* mut sgx_sealed_data_t> {
+
+        if p.is_null() {
+            return None;
+        }
+        if rsgx_raw_is_within_enclave(p as * mut u8, len as usize) == false && 
+           rsgx_raw_is_outside_enclave(p as * mut u8, len as usize) == false {
+            return None;
+        }
+
+        let additional_len = self.get_add_mac_txt_len();
+        let encrypt_len = self.get_encrypt_txt_len();
+        if (additional_len == u32::max_value()) || (encrypt_len == u32::max_value()) {
+            return None;
+        }
+        if (additional_len + encrypt_len) != self.get_payload_size() {
+            return None;
+        }
+
+        let sealed_data_size = sgx_calc_sealed_data_size(additional_len, encrypt_len);
+        if sealed_data_size == u32::max_value() {
+            return None;
+        }  
+        if len < sealed_data_size {
+            return None;
+        }
+
+        let ptr_sealed_data = p as *mut u8;
+        let ptr_encrypt = ptr_sealed_data.offset(mem::size_of::<sgx_sealed_data_t>() as isize);
+        if encrypt_len > 0 {
+            ptr::copy_nonoverlapping(self.payload_data.encrypt.as_ptr(), ptr_encrypt, encrypt_len as usize);
+        }
+        if additional_len > 0 {
+            let ptr_additional = ptr_encrypt.offset(encrypt_len as isize);
+            ptr::copy_nonoverlapping(self.payload_data.additional.as_ptr(), ptr_additional, additional_len as usize);
+        }
+        
+        let mut raw_sealed_data = Box::from_raw(p);
+        raw_sealed_data.key_request = self.key_request;
+        raw_sealed_data.plain_text_offset = encrypt_len;
+        raw_sealed_data.aes_data.payload_size = self.payload_data.payload_size;
+        raw_sealed_data.aes_data.payload_tag = self.payload_data.payload_tag;
+        mem::forget(raw_sealed_data); 
+
+        Some(p)
+    }
+
+    pub unsafe fn from_raw_sealed_data_t(p: * mut sgx_sealed_data_t, len: u32) -> Option<Self> {
+
+        if p.is_null() {
+            return None;
+        }
+        if rsgx_raw_is_within_enclave(p as * mut u8, len as usize) == false && 
+           rsgx_raw_is_outside_enclave(p as * mut u8, len as usize) == false {
+            return None;
+        }
+
+        if (len as usize) < mem::size_of::<sgx_sealed_data_t>() {
+            return None;
+        }
+
+        let raw_sealed_data = Box::from_raw(p);
+        if raw_sealed_data.plain_text_offset > raw_sealed_data.aes_data.payload_size {
+            return None;
+        }
+
+        let ptr_sealed_data = p as * mut u8;
+        let additional_len = sgx_get_add_mac_txt_len(ptr_sealed_data as * const sgx_sealed_data_t);
+        let encrypt_len = sgx_get_encrypt_txt_len(ptr_sealed_data as * const sgx_sealed_data_t);
+        if (additional_len == u32::max_value()) || (encrypt_len == u32::max_value()) {
+            return None;
+        }
+        if (additional_len + encrypt_len) != raw_sealed_data.aes_data.payload_size {
+            return None;
+        }
+
+        let sealed_data_size = sgx_calc_sealed_data_size(additional_len, encrypt_len);
+        if sealed_data_size == u32::max_value() {
+            return None;
+        }
+        if len < sealed_data_size {
+            return None;
+        }
+         
+        let ptr_encrypt = ptr_sealed_data.offset(mem::size_of::<sgx_sealed_data_t>() as isize);
+        let mut encrypt: Vec<u8> =  Vec::new();
+        if encrypt_len > 0 {
+            let mut temp: Vec<u8> = Vec::with_capacity(encrypt_len as usize);
+            temp.set_len(encrypt_len as usize);
+            ptr::copy_nonoverlapping(ptr_encrypt as * const u8, temp.as_mut_ptr(), encrypt_len as usize);
+            encrypt = temp;
+        } 
+
+        let mut additional: Vec<u8> = Vec::new();
+        if additional_len > 0 {
+            let ptr_additional = ptr_encrypt.offset(encrypt_len as isize);
+            let mut temp: Vec<u8> = Vec::with_capacity(additional_len as usize);
+            temp.set_len(additional_len as usize);
+            ptr::copy_nonoverlapping(ptr_additional as * const u8, temp.as_mut_ptr(), additional_len as usize);
+            additional = temp;
+        } 
+
+        let mut sealed_data = Self::default();
+        sealed_data.key_request = raw_sealed_data.key_request;
+        sealed_data.payload_data.payload_size = raw_sealed_data.aes_data.payload_size;
+        sealed_data.payload_data.payload_tag = raw_sealed_data.aes_data.payload_tag;
+        sealed_data.payload_data.additional = additional.into_boxed_slice();
+        sealed_data.payload_data.encrypt = encrypt.into_boxed_slice();
+
+        mem::forget(raw_sealed_data);
+
+        Some(sealed_data)
+    }
+    
+    pub fn seal_data(additional_text: &[u8], encrypt_text: &[u8]) -> SgxResult<Self> {
+        
+        let attribute_mask = sgx_attributes_t{flags: SGX_FLAGS_RESERVED | SGX_FLAGS_INITTED | SGX_FLAGS_DEBUG, xfrm: 0};
+
+        Self::seal_data_ex(SGX_KEYPOLICY_MRSIGNER, 
+                           attribute_mask,
+                           TSEAL_DEFAULT_MISCMASK,
+                           additional_text,
+                           encrypt_text)
+    }
+
+    pub fn seal_data_ex(key_policy: u16,
+                        attribute_mask: sgx_attributes_t,
+                        misc_mask: sgx_misc_select_t,
+                        additional_text: &[u8], 
+                        encrypt_text: &[u8]) -> SgxResult<Self> {
+        
+        let additional_len = additional_text.len();
+        let encrypt_len = encrypt_text.len();
+
+        if (additional_len >= u32::max_value() as usize) || (encrypt_len >= u32::max_value() as usize) {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if Self::calc_raw_sealed_data_size(additional_len as u32, encrypt_len as u32) == u32::max_value() {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if encrypt_len == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        
+        if (key_policy & (!(SGX_KEYPOLICY_MRENCLAVE | SGX_KEYPOLICY_MRSIGNER)) != 0) ||
+           ((key_policy &  (SGX_KEYPOLICY_MRENCLAVE | SGX_KEYPOLICY_MRSIGNER)) == 0) {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if ((attribute_mask.flags & SGX_FLAGS_INITTED) == 0) || 
+           ((attribute_mask.flags & SGX_FLAGS_DEBUG) == 0) {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+
+        if rsgx_slice_is_within_enclave(encrypt_text) == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+
+        if additional_len > 0 {
+            if (rsgx_slice_is_within_enclave(additional_text) == false) &&
+               (rsgx_slice_is_outside_enclave(additional_text) == false) {
+                return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+            }
+        }
+
+        let target_info = sgx_target_info_t::default();
+        let report_data = sgx_report_data_t::default();
+        let mut key_id = sgx_key_id_t::default(); 
+
+        let mut report = try!(rsgx_create_report(&target_info, &report_data));
+        
+        let error = rsgx_read_rand(&mut key_id.id);
+        if error.is_err() {
+            report = sgx_report_t::default();
+            key_id = sgx_key_id_t::default();
+            return Err(error.unwrap_err());
+        }
+       
+        let key_request = sgx_key_request_t{key_name: SGX_KEYSELECT_SEAL,
+                                            key_policy: key_policy,
+                                            isv_svn: report.body.isv_svn,
+                                            reserved1: 0_u16,
+                                            cpu_svn: report.body.cpu_svn,
+                                            attribute_mask: attribute_mask,
+                                            key_id: key_id,
+                                            misc_mask: misc_mask,
+                                            reserved2: [0_u8; SGX_KEY_REQUEST_RESERVED2_BYTES]};
+
+        let payload_iv = [0_u8; SGX_SEAL_IV_SIZE];
+        let mut result = Self::seal_data_iv(additional_text, encrypt_text, &payload_iv, &key_request);
+        match result {
+            Ok(ref mut sealed_data) => sealed_data.key_request = key_request,
+            _ => {},
+        };
+
+        report = sgx_report_t::default();
+        key_id = sgx_key_id_t::default();
+
+        result
+    }
+ 
+    pub fn unseal_data(&self) -> SgxResult<SgxUnsealedData<[u8]>> {
+        
+        let additional_len = self.get_add_mac_txt_len();
+        let encrypt_len = self.get_encrypt_txt_len();
+
+        if (additional_len == u32::max_value()) || (encrypt_len == u32::max_value()) {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        if Self::calc_raw_sealed_data_size(additional_len, encrypt_len) == u32::max_value() {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        if encrypt_len < 1 {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        if (additional_len + encrypt_len) != self.get_payload_size() {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        if rsgx_raw_is_within_enclave(self as * const _ as * const u8,  mem::size_of::<Self>()) == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if rsgx_slice_is_within_enclave(self.get_encrypt_txt()) == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if additional_len > 0 {
+            if rsgx_slice_is_within_enclave(self.get_additional_txt()) == false {
+                return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+            }
+        }
+        
+        self.unseal_data_helper()
+    }
+
+    pub fn mac_aadata(additional_text: &[u8]) -> SgxResult<Self> {
+        
+        let attribute_mask = sgx_attributes_t{flags: SGX_FLAGS_RESERVED | SGX_FLAGS_INITTED | SGX_FLAGS_DEBUG, xfrm: 0};
+
+        Self::mac_aadata_ex(SGX_KEYPOLICY_MRSIGNER, 
+                            attribute_mask,
+                            TSEAL_DEFAULT_MISCMASK,
+                            additional_text)
+    }
+
+    pub fn mac_aadata_ex(key_policy: u16,
+                         attribute_mask: sgx_attributes_t,
+                         misc_mask: sgx_misc_select_t,
+                         additional_text: &[u8]) -> SgxResult<Self> {
+        
+        let additional_len = additional_text.len();
+        if additional_len >= u32::max_value() as usize {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if Self::calc_raw_sealed_data_size(additional_len as u32, 0_u32) == u32::max_value() {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if additional_len == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        
+        if (key_policy & (!(SGX_KEYPOLICY_MRENCLAVE | SGX_KEYPOLICY_MRSIGNER)) != 0) ||
+           ((key_policy &  (SGX_KEYPOLICY_MRENCLAVE | SGX_KEYPOLICY_MRSIGNER)) == 0) {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if (attribute_mask.flags & 0x3) != 0x3 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+
+        if (rsgx_slice_is_within_enclave(additional_text) == false) &&
+           (rsgx_slice_is_outside_enclave(additional_text) == false) {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        
+        let target_info = sgx_target_info_t::default();
+        let report_data = sgx_report_data_t::default();
+        let mut key_id = sgx_key_id_t::default(); 
+
+        let mut report = try!(rsgx_create_report(&target_info, &report_data));
+        
+        let error = rsgx_read_rand(&mut key_id.id);
+        if error.is_err() {
+            report = sgx_report_t::default();
+            key_id = sgx_key_id_t::default();
+            return Err(error.unwrap_err());
+        }
+        
+        let key_request = sgx_key_request_t{key_name: SGX_KEYSELECT_SEAL,
+                                            key_policy: key_policy,
+                                            isv_svn: report.body.isv_svn,
+                                            reserved1: 0_u16,
+                                            cpu_svn: report.body.cpu_svn,
+                                            attribute_mask: attribute_mask,
+                                            key_id: key_id,
+                                            misc_mask: misc_mask,
+                                            reserved2: [0_u8; SGX_KEY_REQUEST_RESERVED2_BYTES]};
+
+        let payload_iv = [0_u8; SGX_SEAL_IV_SIZE];
+        let mut result = Self::seal_data_iv(additional_text, &[0_u8; 0], &payload_iv, &key_request);
+        match result {
+            Ok(ref mut sealed_data) => sealed_data.key_request = key_request,
+            _ => {},
+        };
+
+        report = sgx_report_t::default();
+        key_id = sgx_key_id_t::default();
+
+        result
+    }
+
+    pub fn unmac_aadata(&self) -> SgxResult<SgxUnsealedData<[u8]>> {
+        
+        let additional_len = self.get_add_mac_txt_len();
+        let encrypt_len = self.get_encrypt_txt_len();
+
+        if (additional_len == u32::max_value()) || (encrypt_len == u32::max_value()) {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        if additional_len < 1 {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        if encrypt_len != 0 {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        if Self::calc_raw_sealed_data_size(additional_len, encrypt_len) == u32::max_value() {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        if (additional_len + encrypt_len) != self.get_payload_size() {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+
+        if rsgx_raw_is_within_enclave(self as * const _ as * const u8,  mem::size_of::<Self>()) == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        if rsgx_slice_is_within_enclave(self.get_additional_txt()) == false {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+
+        self.unseal_data_helper()
+    }
+  
+    fn seal_data_iv(additional_text: &[u8], 
+                    encrypt_text: &[u8],
+                    payload_iv: &[u8],
+                    key_request: &sgx_key_request_t) -> SgxResult<Self>  {
+
+        
+        let mut seal_key = try!(rsgx_get_key(key_request).map_err(|ret| {
+            if ret != sgx_status_t::SGX_ERROR_OUT_OF_MEMORY {
+                sgx_status_t::SGX_ERROR_UNEXPECTED
+            } else {
+                ret
+            }
+        }));
+    
+        let mut sealed_data = SgxInternalSealedData::default();
+        sealed_data.payload_data.encrypt = vec![0_u8; encrypt_text.len()].into_boxed_slice();
+
+        let error = rsgx_rijndael128GCM_encrypt(&seal_key, 
+                                              encrypt_text, 
+                                              payload_iv, 
+                                              &additional_text, 
+                                              &mut sealed_data.payload_data.encrypt,
+                                              &mut sealed_data.payload_data.payload_tag);
+        if error.is_err() {
+            seal_key = sgx_key_128bit_t::default();
+            return Err(error.unwrap_err());
+        }
+
+        sealed_data.payload_data.payload_size = (encrypt_text.len() + additional_text.len()) as u32;
+        if additional_text.len() > 0 {
+            sealed_data.payload_data.additional = additional_text.to_vec().into_boxed_slice();
+        }
+
+        seal_key = sgx_key_128bit_t::default();
+
+        Ok(sealed_data)
+    }
+
+    fn unseal_data_helper(&self) -> SgxResult<SgxUnsealedData<[u8]>> {
+
+        let mut seal_key = try!(rsgx_get_key(self.get_key_request()).map_err(|ret| {
+            if (ret == sgx_status_t::SGX_ERROR_INVALID_CPUSVN) || 
+               (ret == sgx_status_t::SGX_ERROR_INVALID_ISVSVN) || 
+               (ret == sgx_status_t::SGX_ERROR_OUT_OF_MEMORY) {
+                ret
+            } else {
+                sgx_status_t::SGX_ERROR_MAC_MISMATCH
+            }
+        }));
+
+        let payload_iv = [0_u8; SGX_SEAL_IV_SIZE];
+        let mut unsealed_data: SgxUnsealedData<[u8]> = SgxUnsealedData::default();
+        unsealed_data.decrypt = vec![0_u8; self.payload_data.encrypt.len()].into_boxed_slice();
+
+        let error = rsgx_rijndael128GCM_decrypt(&seal_key, 
+                                              self.get_encrypt_txt(), 
+                                              &payload_iv,
+                                              self.get_additional_txt(),
+                                              self.get_payload_tag(),
+                                              &mut unsealed_data.decrypt);
+        if error.is_err() {
+            seal_key = sgx_key_128bit_t::default();
+            return Err(error.unwrap_err());
+        }
+
+        if self.payload_data.additional.len() > 0 {
+            unsealed_data.additional = self.get_additional_txt().to_vec().into_boxed_slice();
+        }
+        unsealed_data.payload_size = self.get_payload_size();
+
+        seal_key = sgx_key_128bit_t::default();
+
+        Ok(unsealed_data)
+    }
+}
\ No newline at end of file
diff --git a/sgx_tseal/src/lib.rs b/sgx_tseal/src/lib.rs
new file mode 100644
index 0000000..6ef75ed
--- /dev/null
+++ b/sgx_tseal/src/lib.rs
@@ -0,0 +1,114 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//! # Intel(R) Software Guard Extensions Sealing and Unsealing Functions
+//! 
+//! The library provides the following functions:
+//! 
+//! * Exposes APIs to create sealed data which is both confidentiality andintegrity protected.
+//! * Exposes an API to unseal sealed data inside the enclave.
+//! * Provides APIs to authenticate and verify the input data with AES-GMAC.
+//! 
+//! The library also provides APIs to help calculate the sealed data size, encrypt text length, and Message Authentication Code (MAC) text length.
+//! 
+//! # Descryption 
+//!
+//! When an enclave is instantiated, it provides protections (confidentiality and
+//! integrity) to the data by keeping it within the boundary of the enclave. Enclave
+//! developers should identify enclave data and/or state that is considered secret
+//! and potentially needs preservation across the following enclave destruction
+//! events:
+//!
+//! * Application is done with the enclave and closes it.
+//! * Application itself is closed.
+//! * The platform is hibernated or shutdown.
+//!
+//! In general, the secrets provisioned within an enclave are lost when the enclave
+//! is closed. However if the secret data needs to be preserved during one of
+//! these events for future use within an enclave, it must be stored outside the
+//! enclave boundary before closing the enclave. In order to protect and preserve
+//! the data, a mechanism is in place which allows enclave software to retrieve a
+//! key unique to that enclave. This key can only be generated by that enclave on
+//! that particular platform. Enclave software uses that key to encrypt data to the
+//! platform or to decrypt data already on the platform. Refer to these encrypt
+//! and decrypt operations as sealing and unsealing respectively as the data is
+//! cryptographically sealed to the enclave and platform.
+//!
+//! To provide strong protection against potential key-wear-out attacks, a unique
+//! seal key is generated for each data blob encrypted with the seal_data
+//! API call. A key ID for each encrypted data blob is stored in clear alongside the
+//! encrypted data blob. The key ID is used to re-generate the seal key to decrypt
+//! the data blob.
+//!
+//! AES-GCM (AES – Advanced Encryption Standard) is utilized to encrypt and
+//! MAC-protect the payload. To protect against software-based side channel
+//! attacks, the crypto implementation of AES-GCM utilizes AES-NI, which is
+//! immune to software-based side channel attacks. The Galois/Counter Mode
+//! (GCM) is a mode of operation of the AES algorithm. GCM assures authenticity
+//! of the confidential data (of up to about 64 GB per invocation) using a universal
+//! hash function. GCM can also provide authentication assurance for additional
+//! data (of practically unlimited length per invocation) that is not encrypted. GCM
+//! can also provide authentication assurance for additional data (of practically
+//! unlimited length per invocation) that is not encrypted. If the GCM input contains 
+//! only data that is not to be encrypted, the resulting specialization of GCM,
+//! called GMAC (Galois Message Authentication Code), is simply an authentication
+//! mode for the input data. The mac_aadata API call restricts the input to
+//! non-confidential data to provide data origin authentication only. The single
+//! output of this function is the authentication tag.
+//!
+#![crate_name = "sgx_tseal"]
+#![crate_type = "rlib"]
+
+#![cfg_attr(not(feature = "use_std"), no_std)]
+#![cfg_attr(not(feature = "use_std"), feature(alloc, collections))]
+
+#![allow(non_camel_case_types)]
+#![allow(unused_assignments)]
+#[cfg(feature = "use_std")]
+#[macro_use]
+extern crate std as core;
+
+#[cfg(not(feature = "use_std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "use_std"))]
+#[macro_use]
+extern crate collections;
+
+extern crate sgx_types;
+extern crate sgx_trts;
+extern crate sgx_tcrypto;
+extern crate sgx_tse;
+
+pub mod seal;
+pub use self::seal::*;
+
+pub mod aad;
+pub use self::aad::*;
+
+mod internal;
\ No newline at end of file
diff --git a/sgx_tseal/src/seal.rs b/sgx_tseal/src/seal.rs
new file mode 100644
index 0000000..bcd8a5b
--- /dev/null
+++ b/sgx_tseal/src/seal.rs
@@ -0,0 +1,785 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//!
+//! Intel(R) Software Guard Extensions Sealing and Unsealing Functions
+//!
+//! # Intel(R) Software Guard Extensions Sealing and Unsealing Functions
+//! 
+//! The API of the model provides the following functions:
+//! 
+//! * Exposes APIs to create sealed data which is both confidentiality andintegrity protected.
+//! * Exposes an API to unseal sealed data inside the enclave.
+//!
+//! The library also provides APIs to help calculate the sealed data size, encrypt text length, and Message Authentication Code (MAC) text length.
+//!
+use sgx_types::*;
+use core::mem;
+use core::ptr;
+use core::slice;
+use super::internal::*;
+#[cfg(not(feature = "use_std"))]
+use alloc::boxed::Box;
+
+/// The structure about the unsealed data.
+pub struct SgxUnsealedData<T: ?Sized> {
+    pub payload_size: u32,
+    pub decrypt: Box<T>,
+    pub additional: Box<[u8]>,
+}
+
+impl<T: ?Sized> SgxUnsealedData<T> {
+    /// 
+    /// Get the payload size of the SgxUnsealedData.
+    /// 
+    pub fn get_payload_size(&self) -> u32 {
+        self.payload_size
+    }
+    ///
+    /// Get the pointer of decrypt buffer in SgxUnsealedData.
+    ///  
+    pub fn get_decrypt_txt(&self) -> &T {
+        &*self.decrypt
+    }
+    ///
+    /// Get the pointer of additional buffer in SgxUnsealedData.
+    /// 
+    pub fn get_additional_txt(&self) -> &[u8] {
+        &*self.additional
+    }
+}
+
+impl<T: Default> Default for SgxUnsealedData<T> {
+    fn default() -> SgxUnsealedData<T> {
+        SgxUnsealedData {
+            payload_size: 0_u32,
+            decrypt: Box::<T>::default(),
+            additional: Box::<[u8]>::default()
+        }
+    }
+}
+
+impl<T> Default for SgxUnsealedData<[T]> {
+    fn default() -> SgxUnsealedData<[T]> {
+        SgxUnsealedData {
+            payload_size: 0_u32,
+            decrypt: Box::<[T]>::default(),
+            additional: Box::<[u8]>::default()
+        }
+    }
+}
+
+impl<T: Clone + ?Sized> Clone for SgxUnsealedData<T> {
+    fn clone(&self) -> SgxUnsealedData<T> {
+        SgxUnsealedData {
+           payload_size: self.payload_size,
+           decrypt: self.decrypt.clone(),
+           additional: self.additional.clone()
+        }
+    }
+}
+
+/// The structure about the sealed data. 
+pub struct SgxSealedData<T: ?Sized> {
+    inner: SgxInternalSealedData,
+    marker: * const T,
+}
+
+impl<T> Default for SgxSealedData<T> {
+    fn default() -> SgxSealedData<T> {
+        SgxSealedData {
+            inner: SgxInternalSealedData::new(),
+            marker: ptr::null(), 
+        }
+    }
+}
+
+impl<T> Default for SgxSealedData<[T]> {
+    fn default() -> SgxSealedData<[T]> {
+        let p = Box::<[T]>::default();
+        SgxSealedData {
+            inner: SgxInternalSealedData::new(),
+            marker: Box::into_raw(p),
+        }
+    }
+}
+
+impl<T: ?Sized> Clone for SgxSealedData<T> {
+    fn clone(&self) -> SgxSealedData<T> {
+        SgxSealedData {
+           inner: self.inner.clone(),
+           marker: self.marker,
+        }
+    }
+}
+
+/// The encrypt_text to seal is T, and T must have Copy trait. 
+impl<T: Copy> SgxSealedData<T> {
+    ///
+    /// Create a SgxSealedData with default values.
+    /// 
+    pub fn new() -> Self {
+        SgxSealedData::default()
+    }
+
+    /// 
+    /// Convert a pointer of sgx_sealed_data_t buffer to SgxSealedData.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    ///
+    /// **p**
+    ///
+    /// The mutable pointer of sgx_sealed_data_t buffer.
+    ///
+    /// **len**
+    ///
+    /// The size of the parameter `p`.
+    ///
+    /// # Return value 
+    ///
+    /// **Some(SgxSealedData)**
+    ///
+    /// Indicates the conversion is successfully. The return value is SgxSealedData.
+    ///
+    /// **None**
+    /// 
+    /// Maybe the size of T is zero.
+    /// 
+    pub unsafe fn from_raw_sealed_data_t(p: * mut sgx_sealed_data_t, len: u32) -> Option<Self> {
+        
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return None;
+        } 
+        SgxInternalSealedData::from_raw_sealed_data_t(p, len).map(|x| SgxSealedData{inner: x, marker: ptr::null()})
+    }
+
+    /// 
+    /// This function is used to AES-GCM encrypt the input data. Two input data sets
+    /// are provided: one is the data to be encrypted; the second is optional additional data 
+    /// that will not be encrypted but will be part of the GCM MAC calculation which also covers the data to be encrypted.
+    ///
+    /// # Descryption
+    ///
+    /// The seal_data function retrieves a key unique to the enclave and uses
+    /// that key to encrypt the input data buffer. This function can be utilized to preserve secret 
+    /// data after the enclave is destroyed. The sealed data blob can be
+    /// unsealed on future instantiations of the enclave.
+    /// The additional data buffer will not be encrypted but will be part of the MAC
+    /// calculation that covers the encrypted data as well. This data may include
+    /// information about the application, version, data, etc which can be utilized to
+    /// identify the sealed data blob since it will remain plain text
+    /// Use `calc_raw_sealed_data_size` to calculate the number of bytes to
+    /// allocate for the `SgxSealedData` structure. The input sealed data buffer and
+    /// text2encrypt buffers must be allocated within the enclave.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    ///
+    /// **additional_text**
+    ///
+    /// Pointer to the additional Message Authentication Code (MAC) data. 
+    /// This additional data is optional and no data is necessary.
+    ///
+    /// **encrypt_text**
+    ///
+    /// Pointer to the data stream to be encrypted, which is &T. Must be within the enclave.
+    ///
+    /// # Return value 
+    ///
+    /// The sealed data in SgxSealedData.
+    ///
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// Indicates an error if the parameters do not meet any of the following conditions:
+    /// 
+    /// * additional_text buffer can be within or outside the enclave, but cannot cross the enclave boundary.
+    /// * encrypt_text must be non-zero.
+    /// * encrypt_text buffer must be within the enclave.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates a crypto library failure or the RDRAND instruction fails to generate a
+    /// random number.
+    /// 
+    pub fn seal_data(additional_text: &[u8], encrypt_text: &T) -> SgxResult<Self> {
+
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        } 
+        let encrypt_slice: &[u8] = unsafe{slice::from_raw_parts(encrypt_text as * const _ as * const u8, size)};      
+        let result = SgxInternalSealedData::seal_data(additional_text, encrypt_slice);
+        result.map(|x| SgxSealedData {inner: x, marker: ptr::null()})
+    }
+
+    /// 
+    /// This function is used to AES-GCM encrypt the input data. Two input data sets
+    /// are provided: one is the data to be encrypted; the second is optional additional 
+    /// data that will not be encrypted but will be part of the GCM MAC calculation 
+    /// which also covers the data to be encrypted. This is the expert mode
+    /// version of function `seal_data`.
+    ///
+    /// # Descryption
+    ///
+    /// The `seal_data_ex` is an extended version of `seal_data`. It
+    /// provides parameters for you to identify how to derive the sealing key (key
+    /// policy and attributes_mask). Typical callers of the seal library should be
+    /// able to use `seal_data` and the default values provided for key_
+    /// policy (MR_SIGNER) and an attribute mask which includes the RESERVED,
+    /// INITED and DEBUG bits. Users of this function should have a clear understanding 
+    /// of the impact on using a policy and/or attribute_mask that is different from that in seal_data.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    /// 
+    /// **key_policy**
+    /// 
+    /// Specifies the policy to use in the key derivation. Function sgx_seal_data uses the MRSIGNER policy. 
+    ///
+    /// Key policy name | Value | Description 
+    /// ---|---|---
+    /// KEYPOLICY_MRENCLAVE | 0x0001 | -Derive key using the enclave??s ENCLAVE measurement register  
+    /// KEYPOLICY_MRSIGNER |0x0002 | -Derive key using the enclave??s SIGNER measurement register 
+    /// 
+    /// **attribute_mask**
+    /// 
+    /// Identifies which platform/enclave attributes to use in the key derivation. See  
+    /// the definition of sgx_attributes_t to determine which attributes will be  
+    /// checked.  Function sgx_seal_data uses flags=0xfffffffffffffff3,?xfrm=0. 
+    /// 
+    /// **misc_mask**
+    ///
+    /// The misc mask bits for the enclave. Reserved for future function extension.
+    ///
+    /// **additional_text**
+    ///
+    /// Pointer to the additional Message Authentication Code (MAC) data. 
+    /// This additional data is optional and no data is necessary.
+    ///
+    /// **encrypt_text**
+    ///
+    /// Pointer to the data stream to be encrypted, which is &T. Must not be NULL. Must be within the enclave.
+    ///
+    /// # Return value 
+    ///
+    /// The sealed data in SgxSealedData.
+    ///
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// Indicates an error if the parameters do not meet any of the following conditions:
+    /// 
+    /// * additional_text buffer can be within or outside the enclave, but cannot cross the enclave boundary.
+    /// * encrypt_text must be non-zero.
+    /// * encrypt_text buffer must be within the enclave.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates a crypto library failure or the RDRAND instruction fails to generate a
+    /// random number.
+    /// 
+    pub fn seal_data_ex(key_policy: u16,
+                        attribute_mask: sgx_attributes_t,
+                        misc_mask: sgx_misc_select_t,
+                        additional_text: &[u8], 
+                        encrypt_text: &T) -> SgxResult<Self> {
+
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        } 
+        let encrypt_slice: &[u8] = unsafe{slice::from_raw_parts(encrypt_text as * const _ as * const u8, size)};
+        let result = SgxInternalSealedData::seal_data_ex(key_policy, 
+                                                         attribute_mask, 
+                                                         misc_mask, 
+                                                         additional_text, 
+                                                         encrypt_slice);
+        result.map(|x| SgxSealedData {inner: x, marker: ptr::null()})
+    }
+
+    ///
+    /// This function is used to AES-GCM decrypt the input sealed data structure.
+    /// Two output data sets result: one is the decrypted data; the second is the
+    /// optional additional data that was part of the GCM MAC calculation but was not
+    /// encrypted. This function provides the converse of seal_data and
+    /// seal_data_ex.
+    /// 
+    /// # Descryption
+    /// 
+    /// The unseal_data function AES-GCM decrypts the sealed data so that
+    /// the enclave data can be restored. This function can be utilized to restore
+    /// secret data that was preserved after an earlier instantiation of this enclave
+    /// saved this data.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///
+    /// # Return value 
+    ///
+    /// The unsealed data in SgxUnsealedData.
+    ///
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// The size of T may be zero.
+    /// 
+    /// **SGX_ERROR_INVALID_CPUSVN**
+    /// 
+    /// The CPUSVN in the sealed data blob is beyond the CPUSVN value of the platform.
+    /// SGX_ERROR_INVALID_ISVSVN The ISVSVN in the sealed data blob is greater than the ISVSVN value of the enclave.
+    /// 
+    /// **SGX_ERROR_MAC_MISMATCH**
+    /// 
+    /// The tag verification failed during unsealing. The error may be caused by a platform update, 
+    /// software update, or sealed data blob corruption. This error is also reported if other corruption 
+    /// of the sealed data structure is detected.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates a crypto library failure or the RDRAND instruction fails to generate a
+    /// random number.
+    /// 
+    pub fn unseal_data(&self) -> SgxResult<SgxUnsealedData<T>> {
+
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        let encrypt_len = self.get_encrypt_txt_len() as usize;
+        if size != encrypt_len {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        self.inner.unseal_data().map(|x| {
+            let ptr = Box::into_raw(x.decrypt);
+            SgxUnsealedData {
+                payload_size: x.payload_size,
+                decrypt: unsafe{Box::from_raw(ptr as * mut _ as * mut T)},
+                additional: x.additional,
+            }
+        })
+    }
+}
+
+/// The encrypt_text to seal is [T], and T must have Copy trait. 
+impl<T: Copy> SgxSealedData<[T]> {
+    ///
+    /// Create a SgxSealedData with default values.
+    /// 
+    pub fn new() -> Self {
+        SgxSealedData::default()
+    }
+
+    /// 
+    /// Convert a pointer of sgx_sealed_data_t buffer to SgxSealedData.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    ///
+    /// **p**
+    ///
+    /// The mutable pointer of sgx_sealed_data_t buffer.
+    ///
+    /// **len**
+    ///
+    /// The size of the parameter `p`.
+    ///
+    /// # Return value 
+    ///
+    /// **Some(SgxSealedData)**
+    ///
+    /// Indicates the conversion is successfully. The return value is SgxSealedData.
+    ///
+    /// **None**
+    /// 
+    /// Maybe the size of T is zero.
+    /// 
+    pub unsafe fn from_raw_sealed_data_t(p: * mut sgx_sealed_data_t, len: u32) -> Option<Self> {
+        
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return None;
+        } 
+        let opt = SgxInternalSealedData::from_raw_sealed_data_t(p, len);
+        opt.map(|x| {
+            let p = Box::<[T]>::default();
+            SgxSealedData{inner: x, marker: Box::into_raw(p)}
+        })
+    }
+
+    /// 
+    /// This function is used to AES-GCM encrypt the input data. Two input data sets
+    /// are provided: one is the data to be encrypted; the second is optional additional data 
+    /// that will not be encrypted but will be part of the GCM MAC calculation which also covers the data to be encrypted.
+    ///
+    /// # Descryption
+    ///
+    /// The seal_data function retrieves a key unique to the enclave and uses
+    /// that key to encrypt the input data buffer. This function can be utilized to preserve secret 
+    /// data after the enclave is destroyed. The sealed data blob can be
+    /// unsealed on future instantiations of the enclave.
+    /// The additional data buffer will not be encrypted but will be part of the MAC
+    /// calculation that covers the encrypted data as well. This data may include
+    /// information about the application, version, data, etc which can be utilized to
+    /// identify the sealed data blob since it will remain plain text
+    /// Use `calc_raw_sealed_data_size` to calculate the number of bytes to
+    /// allocate for the `SgxSealedData` structure. The input sealed data buffer and
+    /// text2encrypt buffers must be allocated within the enclave.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    ///
+    /// **additional_text**
+    ///
+    /// Pointer to the additional Message Authentication Code (MAC) data. 
+    /// This additional data is optional and no data is necessary.
+    ///
+    /// **encrypt_text**
+    ///
+    /// Pointer to the data stream to be encrypted, which is &[T]. Must be within the enclave.
+    ///
+    /// # Return value 
+    ///
+    /// The sealed data in SgxSealedData.
+    ///
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// Indicates an error if the parameters do not meet any of the following conditions:
+    /// 
+    /// * additional_text buffer can be within or outside the enclave, but cannot cross the enclave boundary.
+    /// * encrypt_text must be non-zero.
+    /// * encrypt_text buffer must be within the enclave.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates a crypto library failure or the RDRAND instruction fails to generate a
+    /// random number.
+    /// 
+    pub fn seal_data(additional_text: &[u8], encrypt_text: &[T]) -> SgxResult<Self> {
+
+        let size = mem::size_of::<T>() * encrypt_text.len();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        let encrypt_slice: &[u8] = unsafe{slice::from_raw_parts(encrypt_text.as_ptr() as * const _ as * const u8, size)};      
+        let result = SgxInternalSealedData::seal_data(additional_text, encrypt_slice);
+        result.map(|x| {
+            let p = Box::<[T]>::default();
+            SgxSealedData {
+                inner: x,
+                marker: Box::into_raw(p),
+            }
+        })
+    }
+
+    /// 
+    /// This function is used to AES-GCM encrypt the input data. Two input data sets
+    /// are provided: one is the data to be encrypted; the second is optional additional 
+    /// data that will not be encrypted but will be part of the GCM MAC calculation 
+    /// which also covers the data to be encrypted. This is the expert mode
+    /// version of function `seal_data`.
+    ///
+    /// # Descryption
+    ///
+    /// The `seal_data_ex` is an extended version of `seal_data`. It
+    /// provides parameters for you to identify how to derive the sealing key (key
+    /// policy and attributes_mask). Typical callers of the seal library should be
+    /// able to use `seal_data` and the default values provided for key_
+    /// policy (MR_SIGNER) and an attribute mask which includes the RESERVED,
+    /// INITED and DEBUG bits. Users of this function should have a clear understanding 
+    /// of the impact on using a policy and/or attribute_mask that is different from that in seal_data.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///  
+    /// # Parameters
+    /// 
+    /// **key_policy**
+    /// 
+    /// Specifies the policy to use in the key derivation. Function sgx_seal_data uses the MRSIGNER policy. 
+    ///
+    /// Key policy name | Value | Description 
+    /// ---|---|---
+    /// KEYPOLICY_MRENCLAVE | 0x0001 | -Derive key using the enclave??s ENCLAVE measurement register  
+    /// KEYPOLICY_MRSIGNER |0x0002 | -Derive key using the enclave??s SIGNER measurement register 
+    /// 
+    /// **attribute_mask**
+    /// 
+    /// Identifies which platform/enclave attributes to use in the key derivation. See  
+    /// the definition of sgx_attributes_t to determine which attributes will be  
+    /// checked.  Function sgx_seal_data uses flags=0xfffffffffffffff3,?xfrm=0. 
+    /// 
+    /// **misc_mask**
+    ///
+    /// The misc mask bits for the enclave. Reserved for future function extension.
+    ///
+    /// **additional_text**
+    ///
+    /// Pointer to the additional Message Authentication Code (MAC) data. 
+    /// This additional data is optional and no data is necessary.
+    ///
+    /// **encrypt_text**
+    ///
+    /// Pointer to the data stream to be encrypted, which is &[T]. Must not be NULL. Must be within the enclave.
+    ///
+    /// # Return value 
+    ///
+    /// The sealed data in SgxSealedData.
+    ///
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// Indicates an error if the parameters do not meet any of the following conditions:
+    /// 
+    /// * additional_text buffer can be within or outside the enclave, but cannot cross the enclave boundary.
+    /// * encrypt_text must be non-zero.
+    /// * encrypt_text buffer must be within the enclave.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates a crypto library failure or the RDRAND instruction fails to generate a
+    /// random number.
+    /// 
+    pub fn seal_data_ex(key_policy: u16,
+                        attribute_mask: sgx_attributes_t,
+                        misc_mask: sgx_misc_select_t,
+                        additional_text: &[u8], 
+                        encrypt_text: &[T]) -> SgxResult<Self> {
+
+        let size = mem::size_of::<T>() * encrypt_text.len();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        let encrypt_slice: &[u8] = unsafe{slice::from_raw_parts(encrypt_text.as_ptr() as * const _ as * const u8, size)};
+        let result = SgxInternalSealedData::seal_data_ex(key_policy, 
+                                                         attribute_mask, 
+                                                         misc_mask, 
+                                                         additional_text, 
+                                                         encrypt_slice);
+        result.map(|x| {
+            let p = Box::<[T]>::default();
+            SgxSealedData {
+                inner: x,
+                marker: Box::into_raw(p),
+            }
+        })
+    }
+
+    ///
+    /// This function is used to AES-GCM decrypt the input sealed data structure.
+    /// Two output data sets result: one is the decrypted data; the second is the
+    /// optional additional data that was part of the GCM MAC calculation but was not
+    /// encrypted. This function provides the converse of seal_data and
+    /// seal_data_ex.
+    /// 
+    /// # Descryption
+    /// 
+    /// The unseal_data function AES-GCM decrypts the sealed data so that
+    /// the enclave data can be restored. This function can be utilized to restore
+    /// secret data that was preserved after an earlier instantiation of this enclave
+    /// saved this data.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tservice.a or libsgx_tservice_sim.a (simulation)
+    ///
+    /// # Return value 
+    ///
+    /// The unsealed data in SgxUnsealedData.
+    ///
+    /// # Errors
+    /// 
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    /// 
+    /// The size of T may be zero.
+    /// 
+    /// **SGX_ERROR_INVALID_CPUSVN**
+    /// 
+    /// The CPUSVN in the sealed data blob is beyond the CPUSVN value of the platform.
+    /// SGX_ERROR_INVALID_ISVSVN The ISVSVN in the sealed data blob is greater than the ISVSVN value of the enclave.
+    /// 
+    /// **SGX_ERROR_MAC_MISMATCH**
+    /// 
+    /// The tag verification failed during unsealing. The error may be caused by a platform update, 
+    /// software update, or sealed data blob corruption. This error is also reported if other corruption 
+    /// of the sealed data structure is detected.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// The enclave is out of memory.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates a crypto library failure or the RDRAND instruction fails to generate a
+    /// random number.
+    /// 
+    pub fn unseal_data(&self) -> SgxResult<SgxUnsealedData<[T]>> {
+
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
+        }
+        let encrypt_len = self.get_encrypt_txt_len() as usize;
+        if size > encrypt_len {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        if (encrypt_len % size) != 0 {
+            return Err(sgx_status_t::SGX_ERROR_MAC_MISMATCH);
+        }
+        self.inner.unseal_data().map(|x| {
+            let ptr = Box::into_raw(x.decrypt);
+            SgxUnsealedData {
+                payload_size: x.payload_size,
+                decrypt: unsafe{Box::from_raw(ptr as * mut _ as * mut [T])},
+                additional: x.additional,
+            }
+        })
+    }
+}
+
+impl<T: ?Sized> SgxSealedData<T> {
+    ///
+    /// Get the size of payload in SgxSealedData.
+    ///
+    pub fn get_payload_size(&self) -> u32 {
+        self.inner.get_payload_size()
+    }
+    ///
+    /// Get a slice of payload in SgxSealedData.
+    ///
+    pub fn get_payload_tag(&self) -> &[u8; SGX_SEAL_TAG_SIZE] {
+        self.inner.get_payload_tag()
+    }
+    ///
+    /// Get the pointer of sgx_key_request_t in SgxSealedData.
+    ///
+    pub fn get_key_request(&self) -> &sgx_key_request_t {
+        self.inner.get_key_request()
+    }
+    ///
+    /// Get a slice of encrypt text in SgxSealedData.
+    ///
+    pub fn get_encrypt_txt(&self) -> &[u8] {
+        self.inner.get_encrypt_txt()
+    }
+    ///
+    /// Get a slice of additional text in SgxSealedData.
+    ///
+    pub fn get_additional_txt(&self) -> &[u8] {
+        self.inner.get_additional_txt()
+    }
+    ///
+    /// Calculate the size of the sealed data in SgxSealedData.
+    ///
+    pub fn calc_raw_sealed_data_size(add_mac_txt_size: u32, encrypt_txt_size: u32) -> u32  {
+        SgxInternalSealedData::calc_raw_sealed_data_size(add_mac_txt_size, encrypt_txt_size)
+    }
+    ///
+    /// Get the size of the additional mactext in SgxSealedData.
+    ///
+    pub fn get_add_mac_txt_len(&self) -> u32 {
+        self.inner.get_add_mac_txt_len()
+    } 
+    ///
+    /// Get the size of the encrypt text in SgxSealedData.
+    ///
+    pub fn get_encrypt_txt_len(&self) -> u32 {
+        self.inner.get_encrypt_txt_len()
+    }
+    ///
+    /// Convert SgxSealedData to the pointer of sgx_sealed_data_t.
+    ///
+    /// # Parameters
+    ///
+    /// **p**
+    ///
+    /// The pointer of sgx_sealed_data_t to save the data in SgxSealedData.
+    ///
+    /// **len**
+    ///
+    /// The size of the pointer of sgx_sealed_data_t.
+    ///
+    /// # Error
+    ///
+    /// **Some(* mut sgx_sealed_data_t)**
+    ///
+    /// Indicates the conversion is successfully. The return value is the pointer of sgx_sealed_data_t.
+    ///
+    /// **None**
+    ///
+    /// May be the parameter p and len is not avaliable.
+    ///
+    pub unsafe fn to_raw_sealed_data_t(&self, p: * mut sgx_sealed_data_t, len: u32) -> Option<* mut sgx_sealed_data_t> {
+        self.inner.to_raw_sealed_data_t(p, len)
+    }
+}
\ No newline at end of file
diff --git a/sgx_tservice/Cargo.toml b/sgx_tservice/Cargo.toml
new file mode 100644
index 0000000..c5fe694
--- /dev/null
+++ b/sgx_tservice/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "sgx_tservice"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../sgx_types" }
diff --git a/sgx_tservice/src/lib.rs b/sgx_tservice/src/lib.rs
new file mode 100644
index 0000000..983fbfc
--- /dev/null
+++ b/sgx_tservice/src/lib.rs
@@ -0,0 +1,51 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//! # Trust Service Library
+//!
+//! The Intel(R) Software Guard Extensions SDK provides a trusted library named 
+//! sgx_tservice for secure data manipulation and protection. The sgx_tservice library 
+//! provides the following modules:
+//!
+//! **Trust Platform Service Functions**
+//!
+#![crate_name = "sgx_tservice"]
+#![crate_type = "rlib"]
+
+#![cfg_attr(not(feature = "use_std"), no_std)]
+
+#![allow(non_camel_case_types)]
+
+#[cfg(feature = "use_std")]
+extern crate std as core;
+
+extern crate sgx_types;
+
+pub mod tae;
+pub use self::tae::*;
+
diff --git a/sgx_tservice/src/tae.rs b/sgx_tservice/src/tae.rs
new file mode 100644
index 0000000..7f8bc45
--- /dev/null
+++ b/sgx_tservice/src/tae.rs
@@ -0,0 +1,771 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//! Trust Platform Service Functions
+//!
+//! The sgx_tservice library provides the following functions that allow an ISV 
+//! to use platform services and get platform services security property.
+//!
+//! This API is only available in simulation mode.
+//!
+use sgx_types::*;
+use core::cell::Cell;
+
+///
+/// rsgx_create_pse_session creates a session with the PSE. 
+///
+/// This API is only available in simulation mode.
+///
+/// # Description
+///
+/// An Intel(R) SGX enclave first calls rsgx_create_pse_session() in the process to request platform service.
+///
+/// It's suggested that the caller should wait (typically several seconds to tens of seconds) and retry 
+/// this API if SGX_ERROR_BUSY is returned.
+///
+/// # Requirements
+///
+/// Header: sgx_tae_service.edl
+///
+/// Library: libsgx_tservice_sim.a (simulation)
+///
+/// # Errors
+///
+/// **SGX_ERROR_SERVICE_UNAVAILABLE**
+///
+/// The AE service did not respond or the requested service is not supported.
+///
+/// **SGX_ERROR_SERVICE_TIMEOUT**
+///
+/// A request to the AE service timed out.
+///
+/// **SGX_ERROR_BUSY**
+///
+/// The requested service is temporarily not available.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Not enough memory is available to complete this operation.
+///
+/// **SGX_ERROR_NETWORK_FAILURE**
+///
+/// Network connecting or proxy setting issue was encountered.
+///
+/// **SGX_ERROR_OUT_OF_EPC**
+///
+/// There is not enough EPC memory to load one of the Architecture Enclaves needed to complete this operation.
+///
+/// **SGX_ERROR_UPDATE_NEEDED**
+///
+/// Intel(R) SGX needs to be updated.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// Indicates an unexpected error occurred.
+///
+pub fn rsgx_create_pse_session() -> SgxError {
+
+    let ret = unsafe { sgx_create_pse_session() };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
+
+///
+/// rsgx_close_pse_session closes a session created by rsgx_create_pse_ session.
+///
+/// This API is only available in simulation mode.
+///
+/// # Description
+///
+/// An Intel(R) SGX enclave calls rsgx_close_pse_session() when there is no need to request platform service.
+///
+/// # Requirements
+///
+/// Header: sgx_tae_service.edl
+///
+/// Library: libsgx_tservice_sim.a (simulation)
+///
+/// # Errors
+///
+/// **SGX_ERROR_SERVICE_UNAVAILABLE**
+///
+/// The AE service did not respond or the requested service is not supported.
+///
+/// **SGX_ERROR_SERVICE_TIMEOUT**
+///
+/// A request to the AE service timed out.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// Indicates an unexpected error occurs.
+///
+pub fn rsgx_close_pse_session() -> SgxError {
+
+    let ret = unsafe { sgx_close_pse_session() };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
+
+///
+/// rsgx_get_ps_sec_prop gets a data structure describing the security property of the platform service.
+///
+/// This API is only available in simulation mode.
+///
+/// # Description
+///
+/// Gets a data structure that describes the security property of the platform service.
+///
+/// The caller should call rsgx_create_pse_session to establish a session with the platform service enclave 
+/// before calling this API.
+///
+/// # Parameters
+///
+/// **security_property**
+///
+/// A pointer to the buffer that receives the security property descriptor of the platform service. 
+///
+/// # Requirements
+///
+/// Header: sgx_tae_service.edl
+///
+/// Library: libsgx_tservice_sim.a (simulation)
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Any of the pointers is invalid.
+///
+/// **SGX_ERROR_AE_SESSION_INVALID**
+///
+/// Session is not created or has been closed by architectural enclave service.
+///
+pub fn rsgx_get_ps_sec_prop(security_property: &mut sgx_ps_sec_prop_desc_t) -> SgxError {
+
+    let ret = unsafe { sgx_get_ps_sec_prop(security_property as * mut sgx_ps_sec_prop_desc_t) };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
+
+///
+/// rsgx_get_trusted_time gets trusted time from the AE service.
+///
+/// This API is only available in simulation mode.
+///
+/// # Description
+///
+/// current_time contains time in seconds and time_source_nonce contains nonce associate with the time. 
+/// The caller should compare time_ source_nonce against the value returned from the previous call of 
+/// this API if it needs to calculate the time passed between two readings of the Trusted Timer. If the 
+/// time_source_nonce of the two readings do not match, the difference between the two readings does not 
+/// necessarily reflect time passed.
+///
+/// The caller should call rsgx_create_pse_session to establish a session with the platform service enclave 
+/// before calling this API.
+///
+/// # Parameters
+///
+/// **current_time**
+///
+/// Trusted Time Stamp in seconds relative to a reference point. The reference point does not change as long as 
+/// the time_source_nonce has not changed.
+///
+/// **time_source_nonce**
+///
+/// A pointer to the buffer that receives the nonce which indicates time source.
+///
+/// # Requirements
+///
+/// Header: sgx_tae_service.edl
+///
+/// Library: libsgx_tservice_sim.a (simulation)
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Any of the pointers is invalid.
+///
+/// **SGX_ERROR_AE_SESSION_INVALID**
+///
+/// Session is not created or has been closed by architectural enclave service.
+///
+/// **SGX_ERROR_SERVICE_UNAVAILABLE**
+///
+/// The AE service did not respond or the requested service is not supported.
+///
+/// **SGX_ERROR_SERVICE_TIMEOUT**
+///
+/// A request to the AE service timed out.
+///
+/// **SGX_ERROR_NETWORK_FAILURE**
+///
+/// Network connecting or proxy setting issue was encountered.
+///
+/// **SGX_ERROR_OUT_OF_MEMORY**
+///
+/// Not enough memory is available to complete this operation.
+///
+/// **SGX_ERROR_OUT_OF_EPC**
+///
+/// There is not enough EPC memory to load one of the Architecture Enclaves needed to complete this operation.
+///
+/// **SGX_ERROR_UNEXPECTED**
+///
+/// Indicates an unexpected error occurs.
+///
+pub fn rsgx_get_trusted_time(current_time: &mut sgx_time_t, 
+                             time_source_nonce: &mut sgx_time_source_nonce_t) -> SgxError {
+
+    let ret = unsafe { sgx_get_trusted_time(current_time as * mut sgx_time_t, time_source_nonce as * mut sgx_time_source_nonce_t) };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(()),
+        _ => Err(ret),
+    }
+}
+
+fn rsgx_create_monotonic_counter_ex(owner_policy: u16,
+                                    owner_attribute_mask: &sgx_attributes_t,
+                                    counter_uuid: &mut sgx_mc_uuid_t,
+                                    counter_value: &mut u32) -> sgx_status_t {
+
+    unsafe {
+        sgx_create_monotonic_counter_ex(owner_policy,
+                                        owner_attribute_mask as * const sgx_attributes_t,
+                                        counter_uuid as * mut sgx_mc_uuid_t,                                                  
+                                        counter_value as * mut u32)
+    }
+}
+
+fn rsgx_create_monotonic_counter(counter_uuid: &mut sgx_mc_uuid_t, counter_value: &mut u32) -> sgx_status_t {
+
+    unsafe {
+        sgx_create_monotonic_counter(counter_uuid as * mut sgx_mc_uuid_t, counter_value as * mut u32)
+    }
+}
+
+fn rsgx_destroy_monotonic_counter(counter_uuid: &sgx_mc_uuid_t) -> sgx_status_t {
+
+    unsafe {
+        sgx_destroy_monotonic_counter(counter_uuid as * const sgx_mc_uuid_t)
+    }
+}
+
+fn rsgx_increment_monotonic_counter(counter_uuid: &sgx_mc_uuid_t, counter_value: &mut u32) -> sgx_status_t {
+
+    unsafe {
+        sgx_increment_monotonic_counter(counter_uuid as * const sgx_mc_uuid_t, counter_value as * mut u32)
+    }
+}
+
+fn rsgx_read_monotonic_counter(counter_uuid: &sgx_mc_uuid_t, counter_value: &mut u32) -> sgx_status_t {
+    
+    unsafe {
+        sgx_read_monotonic_counter(counter_uuid as * const sgx_mc_uuid_t, counter_value as * mut u32)
+    }
+}
+
+/// Monotonic counter ID
+pub struct SgxMonotonicCounter {
+    counter_uuid: sgx_mc_uuid_t,
+    initflag: Cell<bool>,
+}
+
+impl SgxMonotonicCounter {
+
+    ///
+    /// creates a monotonic counter with default owner policy and default user attribute mask.
+    ///
+    /// This API is only available in simulation mode.
+    ///
+    /// # Description
+    ///
+    /// Call new to create a monotonic counter with the default owner policy 0x1, which means enclaves 
+    /// with same signing key can access the monotonic counter and default owner_attribute_mask 0xFFFFFFFFFFFFFFCB.
+    ///
+    /// The caller should call rsgx_create_pse_session to establish a session with the platform service enclave 
+    /// before calling this API.
+    ///
+    /// Creating a monotonic counter (MC) involves writing to the non-volatile memory available in the platform. 
+    /// Repeated write operations could cause the memory to wear out during the normal lifecycle of the platform. 
+    /// Intel(R) SGX prevents this by limiting the rate at which MC operations can be performed. If you exceed 
+    /// the limit, the MC operation may return SGX_ERROR_BUSY for several minutes.
+    ///
+    /// Intel(R) SGX limits the number of MCs an enclave can create. To avoid exhausting the available quota, 
+    /// an SGX application should record the MC UUID that rsgx_create_monotonic_counter returns and destroy a MC 
+    /// when it is not needed any more. If an enclave reaches its quota and previously created MC UUIDs have not 
+    /// been recorded, you may restore the MC service after uninstalling the SGX PSW and installing it again. 
+    /// This procedure deletes all MCs created by any enclave in that system.
+    ///
+    /// # Parameters
+    ///
+    /// **counter_value**
+    ///
+    /// A pointer to the buffer that receives the monotonic counter value.
+    ///
+    /// # Requirements
+    ///
+    /// Header: sgx_tae_service.edl
+    ///
+    /// Library: libsgx_tservice_sim.a (simulation)
+    ///
+    /// # Return value
+    ///
+    /// Monotonic counter ID
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// Any of the pointers is invalid.
+    ///
+    /// **SGX_ERROR_BUSY**
+    ///
+    /// The requested service is temporarily not available.
+    ///
+    /// **SGX_ERROR_MC_OVER_QUOTA**
+    ///
+    /// The enclave has reached the quota of Monotonic Counters it can maintain.
+    ///
+    /// **SGX_ERROR_MC_USED_UP**
+    ///
+    /// Monotonic counters are used out.
+    ///
+    /// **SGX_ERROR_AE_SESSION_INVALID**
+    ///
+    /// Session is not created or has been closed by architectural enclave service.
+    ///
+    /// **SGX_ERROR_SERVICE_UNAVAILABLE**
+    ///
+    /// The AE service did not respond or the requested service is not supported.
+    ///
+    /// **SGX_ERROR_SERVICE_TIMEOUT**
+    ///
+    /// A request to the AE service timed out.
+    ///
+    /// **SGX_ERROR_NETWORK_FAILURE**
+    ///
+    /// Network connecting or proxy setting issue was encountered.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_OUT_OF_EPC**
+    ///
+    /// There is not enough EPC memory to load one of the Architecture Enclaves needed to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates an unexpected error occurs.
+    ///
+    pub fn new(counter_value: &mut u32) -> SgxResult<Self> {
+         
+        let mut counter_uuid = sgx_mc_uuid_t::default();
+        let ret = rsgx_create_monotonic_counter(&mut counter_uuid, counter_value);
+
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(SgxMonotonicCounter{counter_uuid: counter_uuid, initflag: Cell::new(true)}),
+            _ => Err(ret),
+         }
+    }
+
+    ///
+    /// creates a monotonic counter.
+    ///
+    /// This API is only available in simulation mode.
+    ///
+    /// # Description
+    ///
+    /// Call new_ex to create a monotonic counter with the given owner_policy and owner_attribute_mask.
+    ///
+    /// The caller should call rsgx_create_pse_session to establish a session with the platform service enclave 
+    /// before calling this API.
+    ///
+    /// Creating a monotonic counter (MC) involves writing to the non-volatile memory available in the platform. 
+    /// Repeated write operations could cause the memory to wear out during the normal lifecycle of the platform. 
+    /// Intel(R) SGX prevents this by limiting the rate at which MC operations can be performed. If you exceed 
+    /// the limit, the MC operation may return SGX_ERROR_BUSY for several minutes.
+    ///
+    /// Intel(R) SGX limits the number of MCs an enclave can create. To avoid exhausting the available quota, 
+    /// an SGX application should record the MC UUID that rsgx_create_monotonic_counter_ex returns and destroy a MC 
+    /// when it is not needed any more. If an enclave reaches its quota and previously created MC UUIDs have not 
+    /// been recorded, you may restore the MC service after uninstalling the SGX PSW and installing it again. 
+    /// This procedure deletes all MCs created by any enclave in that system.
+    ///
+    /// # Parameters
+    ///
+    /// **owner_policy**
+    ///
+    /// The owner policy of the monotonic counter.
+    ///
+    /// * 0x1 means enclave with same signing key can access the monotonic counter
+    /// * 0x2 means enclave with same measurement can access the monotonic counter
+    /// * 0x3 means enclave with same measurement as well as signing key can access the monotonic counter.
+    /// * Owner policy values of 0x0 or any bits set beyond bits 0 and 1 will cause SGX_ERROR_INVALID_PARAMETER
+    ///
+    /// **owner_attribute_mask**
+    ///
+    /// Mask of owner attribute, in the format of sgx_attributes_t.
+    ///
+    /// **counter_value**
+    ///
+    /// A pointer to the buffer that receives the monotonic counter value.
+    /// 
+    /// # Requirements
+    ///
+    /// Header: sgx_tae_service.edl
+    ///
+    /// Library: libsgx_tservice_sim.a (simulation)
+    ///
+    /// # Return value
+    ///
+    /// Monotonic counter ID
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// Any of the pointers is invalid.
+    ///
+    /// **SGX_ERROR_BUSY**
+    ///
+    /// The requested service is temporarily not available.
+    ///
+    /// **SGX_ERROR_MC_OVER_QUOTA**
+    ///
+    /// The enclave has reached the quota of Monotonic Counters it can maintain.
+    ///
+    /// **SGX_ERROR_MC_USED_UP**
+    ///
+    /// Monotonic counters are used out.
+    ///
+    /// **SGX_ERROR_AE_SESSION_INVALID**
+    ///
+    /// Session is not created or has been closed by architectural enclave service.
+    ///
+    /// **SGX_ERROR_SERVICE_UNAVAILABLE**
+    ///
+    /// The AE service did not respond or the requested service is not supported.
+    ///
+    /// **SGX_ERROR_SERVICE_TIMEOUT**
+    ///
+    /// A request to the AE service timed out.
+    ///
+    /// **SGX_ERROR_NETWORK_FAILURE**
+    ///
+    /// Network connecting or proxy setting issue was encountered.
+    ///
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    ///
+    /// Not enough memory is available to complete this operation.
+    ///
+    /// **SGX_ERROR_OUT_OF_EPC**
+    ///
+    /// There is not enough EPC memory to load one of the Architecture Enclaves needed to complete this operation.
+    ///
+    /// **SGX_ERROR_UNEXPECTED**
+    ///
+    /// Indicates an unexpected error occurs.
+    ///
+    pub fn new_ex(owner_policy: u16, owner_attribute_mask: &sgx_attributes_t, counter_value: &mut u32) -> SgxResult<Self> {
+
+        let mut counter_uuid = sgx_mc_uuid_t::default();
+        let ret = rsgx_create_monotonic_counter_ex(owner_policy, owner_attribute_mask, &mut counter_uuid, counter_value);
+
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(SgxMonotonicCounter{counter_uuid: counter_uuid, initflag: Cell::new(true)}),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// destroys a monotonic counter created by new or new_ex.
+    /// 
+    /// This API is only available in simulation mode.
+    ///
+    /// # Description
+    ///
+    /// Calling destory after a monotonic counter is not needed anymore.
+    ///
+    /// The caller should call rsgx_create_pse_session to establish a session with the platform service enclave 
+    /// before calling this API.
+    ///
+    /// destory fails if the calling enclave does not match the owner policy and the attributes specified in the
+    /// call that created the monotonic counter.
+    ///
+    /// Destroying a Monotonic Counter (MC) involves writing to the non-volatile memory available in the platform. 
+    /// Repeated write operations could cause the memory to wear out during the normal lifecycle of the platform. 
+    /// Intel(R) SGX prevents this by limiting the rate at which MC operations can be performed. If you exceed the 
+    /// limit, the MC operation may return SGX_ERROR_BUSY for several minutes.
+    ///
+    /// # Requirements
+    ///
+    /// Header: sgx_tae_service.edl
+    ///
+    /// Library: libsgx_tservice_sim.a (simulation)
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// Any of the pointers is invalid.
+    ///
+    /// **SGX_ERROR_BUSY**
+    ///
+    /// The requested service is temporarily not available.
+    ///
+    /// **SGX_ERROR_MC_NOT_FOUND**
+    ///
+    /// The Monotonic Counter does not exist or has been invalidated.
+    ///
+    /// **SGX_ERROR_MC_NO_ACCESS_RIGHT**
+    ///
+    /// The enclave doesn't have the access right to specified Monotonic Counter.
+    ///
+    /// **SGX_ERROR_AE_SESSION_INVALID**
+    /// 
+    /// Session is not created or has been closed by architectural enclave service.
+    ///
+    /// **SGX_ERROR_SERVICE_UNAVAILABLE**
+    ///
+    /// The AE service did not respond or the requested service is not supported.
+    ///
+    /// **SGX_ERROR_SERVICE_TIMEOUT**
+    ///
+    /// A request to the AE service timed out.
+    /// 
+    /// **SGX_ERROR_NETWORK_FAILURE**
+    /// 
+    /// Network connecting or proxy setting issue was encountered.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// Not enough memory is available to complete this operation.
+    /// 
+    /// **SGX_ERROR_OUT_OF_EPC**
+    /// 
+    /// There is not enough EPC memory to load one of the Architecture Enclaves needed to complete this operation.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    /// 
+    /// Indicates an unexpected error occurs.
+    ///
+    pub fn destory(&self) -> SgxError {
+
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_MC_NOT_FOUND);
+        }
+
+        let ret = rsgx_destroy_monotonic_counter(&self.counter_uuid);
+        if ret == sgx_status_t::SGX_SUCCESS {
+            self.initflag.set(false);
+            Ok(())
+        } else {
+            Err(ret)
+        }
+    }
+
+    ///
+    /// increments a monotonic counter value by 1.
+    /// 
+    /// This API is only available in simulation mode.
+    ///
+    /// # Description
+    ///
+    /// Call increment to increase a monotonic counter value by 1.
+    ///
+    /// The caller should call rsgx_create_pse_session to establish a session with the platform service enclave 
+    /// before calling this API.
+    ///
+    /// increment fails if the calling enclave does not match the owner policy and the attributes specified in the 
+    /// call that created the monotonic counter.
+    ///
+    /// Incrementing a monotonic counter (MC) involves writing to the non-volatile memory available in the platform. 
+    /// Repeated write operations could cause the memory to wear out during the normal lifecycle of the platform. 
+    /// Intel(R) SGX prevents this by limiting the rate at which MC operations can be performed. If you exceed the limit, 
+    /// the MC operation may return SGX_ERROR_BUSY for several minutes.
+    ///
+    /// # Requirements
+    ///
+    /// Header: sgx_tae_service.edl
+    ///
+    /// Library: libsgx_tservice_sim.a (simulation)
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// Any of the pointers is invalid.
+    ///
+    /// **SGX_ERROR_BUSY**
+    ///
+    /// The requested service is temporarily not available.
+    ///
+    /// **SGX_ERROR_MC_NOT_FOUND**
+    ///
+    /// The Monotonic Counter does not exist or has been invalidated.
+    ///
+    /// **SGX_ERROR_MC_NO_ACCESS_RIGHT**
+    ///
+    /// The enclave doesn't have the access right to specified Monotonic Counter.
+    ///
+    /// **SGX_ERROR_AE_SESSION_INVALID**
+    /// 
+    /// Session is not created or has been closed by architectural enclave service.
+    ///
+    /// **SGX_ERROR_SERVICE_UNAVAILABLE**
+    ///
+    /// The AE service did not respond or the requested service is not supported.
+    ///
+    /// **SGX_ERROR_SERVICE_TIMEOUT**
+    ///
+    /// A request to the AE service timed out.
+    /// 
+    /// **SGX_ERROR_NETWORK_FAILURE**
+    /// 
+    /// Network connecting or proxy setting issue was encountered.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// Not enough memory is available to complete this operation.
+    /// 
+    /// **SGX_ERROR_OUT_OF_EPC**
+    /// 
+    /// There is not enough EPC memory to load one of the Architecture Enclaves needed to complete this operation.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    /// 
+    /// Indicates an unexpected error occurs.
+    ///
+    pub fn increment(&self) -> SgxResult<u32> {
+
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_MC_NOT_FOUND);
+        }
+
+        let mut counter_value: u32 = 0;
+        let ret = rsgx_increment_monotonic_counter(&self.counter_uuid, &mut counter_value);
+         match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(counter_value),
+            _ => Err(ret),
+        }
+    }
+
+    ///
+    /// returns the value of a monotonic counter.
+    /// 
+    /// This API is only available in simulation mode.
+    ///
+    /// # Description
+    ///
+    /// Call read to read the value of a monotonic counter.
+    ///
+    /// The caller should call rsgx_create_pse_session to establish a session with the platform service enclave 
+    /// before calling this API.
+    ///
+    /// read fails if the calling enclave does not match the owner policy and the attributes specified in the 
+    /// call that created the monotonic counter.
+    ///
+    /// # Requirements
+    ///
+    /// Header: sgx_tae_service.edl
+    ///
+    /// Library: libsgx_tservice_sim.a (simulation)
+    ///
+    /// # Return value
+    ///
+    /// Monotonic counter value
+    ///
+    /// # Errors
+    ///
+    /// **SGX_ERROR_INVALID_PARAMETER**
+    ///
+    /// Any of the pointers is invalid.
+    ///
+    /// **SGX_ERROR_MC_NOT_FOUND**
+    ///
+    /// The Monotonic Counter does not exist or has been invalidated.
+    ///
+    /// **SGX_ERROR_AE_SESSION_INVALID**
+    /// 
+    /// Session is not created or has been closed by architectural enclave service.
+    ///
+    /// **SGX_ERROR_SERVICE_UNAVAILABLE**
+    ///
+    /// The AE service did not respond or the requested service is not supported.
+    ///
+    /// **SGX_ERROR_SERVICE_TIMEOUT**
+    ///
+    /// A request to the AE service timed out.
+    /// 
+    /// **SGX_ERROR_NETWORK_FAILURE**
+    /// 
+    /// Network connecting or proxy setting issue was encountered.
+    /// 
+    /// **SGX_ERROR_OUT_OF_MEMORY**
+    /// 
+    /// Not enough memory is available to complete this operation.
+    /// 
+    /// **SGX_ERROR_OUT_OF_EPC**
+    /// 
+    /// There is not enough EPC memory to load one of the Architecture Enclaves needed to complete this operation.
+    /// 
+    /// **SGX_ERROR_UNEXPECTED**
+    /// 
+    /// Indicates an unexpected error occurs.
+    /// 
+    pub fn read(&self) -> SgxResult<u32> {
+
+        if self.initflag.get() == false {
+            return Err(sgx_status_t::SGX_ERROR_MC_NOT_FOUND);
+        }
+
+        let mut counter_value: u32 = 0;
+        let ret = rsgx_read_monotonic_counter(&self.counter_uuid, &mut counter_value);
+        match ret {
+            sgx_status_t::SGX_SUCCESS => Ok(counter_value),
+            _ => Err(ret),
+        }
+    }
+}
+
+impl Drop for SgxMonotonicCounter {
+    ///
+    /// destroys a monotonic counter created by new or new_ex.
+    ///
+    fn drop(&mut self) {
+        let _ = self.destory();
+    }
+}
\ No newline at end of file
diff --git a/sgx_tstdc/Cargo.toml b/sgx_tstdc/Cargo.toml
new file mode 100644
index 0000000..873199f
--- /dev/null
+++ b/sgx_tstdc/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "sgx_tstdc"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
+sgx_types = { path = "../sgx_types" }
diff --git a/sgx_tstdc/src/cond.rs b/sgx_tstdc/src/cond.rs
new file mode 100644
index 0000000..a6e439e
--- /dev/null
+++ b/sgx_tstdc/src/cond.rs
@@ -0,0 +1,346 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//!
+//! The Intel(R) Software Guard Extensions SDK already supports mutex and conditional 
+//! variable synchronization mechanisms by means of the following APIand data types 
+//! defined in the Types and Enumerations section. Some functions included in the 
+//! trusted Thread Synchronization library may make calls outside the enclave (OCALLs).
+//! If you use any of the APIs below, you must first import the needed OCALL functions
+//! from sgx_tstdc.edl. Otherwise, you will get a linker error when the enclave is
+//! being built; see Calling Functions outside the Enclave for additional details. 
+//! The table below illustrates the primitives that the Intel(R) SGX Thread 
+//! Synchronization library supports, as well as the OCALLs that each API function needs.
+//!
+use sgx_types::*;
+use super::mutex::*;
+use core::sync::atomic::{AtomicUsize, Ordering};
+
+#[cfg(not(feature = "use_std"))]
+use alloc::boxed::Box;
+
+pub unsafe fn raw_cond(lock: &sgx_thread_cond_t) -> * mut sgx_thread_cond_t {
+    lock as *const _ as *mut _
+}
+
+#[allow(dead_code)]
+fn rsgx_thread_cond_init(cond: &sgx_thread_cond_t, unused: &sgx_thread_condattr_t ) -> sys_error_t {
+    
+    unsafe { sgx_thread_cond_init(raw_cond(cond), unused as * const sgx_thread_condattr_t) }
+}
+
+fn rsgx_thread_cond_destroy(cond: &sgx_thread_cond_t) -> sys_error_t {
+    
+    unsafe { sgx_thread_cond_destroy(raw_cond(cond)) }
+}
+
+fn rsgx_thread_cond_wait(cond: &sgx_thread_cond_t, mutex: &sgx_thread_mutex_t) -> sys_error_t {
+    
+    unsafe { sgx_thread_cond_wait(raw_cond(cond), raw_mutex(mutex)) }
+}
+
+fn rsgx_thread_cond_signal(cond: &sgx_thread_cond_t) -> sys_error_t {
+    
+    unsafe { sgx_thread_cond_signal(raw_cond(cond)) }
+}
+
+fn rsgx_thread_cond_broadcast(cond: &sgx_thread_cond_t) -> sys_error_t {
+    
+    unsafe { sgx_thread_cond_broadcast(raw_cond(cond)) }
+}
+
+/// The structure of sgx condition.
+pub struct SgxThreadCond {
+    cond: sgx_thread_cond_t,
+}
+
+unsafe impl Send for SgxThreadCond {}
+unsafe impl Sync for SgxThreadCond {}
+
+impl SgxThreadCond {
+    /// 
+    /// The function initializes a trusted condition variable within the enclave.
+    /// 
+    /// # Description
+    /// 
+    /// When a thread creates a condition variable within an enclave, it simply initializes the various
+    /// fields of the object to indicate that the condition variable is available. The results of using 
+    /// a condition variable in a wait, signal or broadcast operation before it has been fully initialized
+    /// are undefined. To avoid race conditions in the initialization of a condition variable, it is 
+    /// recommended statically initializing the condition variable with the macro SGX_THREAD_COND_INITIALIZER.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tstdc.a
+    ///
+    pub fn new() -> Self {
+        SgxThreadCond{cond: SGX_THREAD_COND_INITIALIZER}
+    }
+
+    /// 
+    /// The function waits on a condition variable within an enclave.
+    ///
+    /// # Description
+    /// 
+    /// A condition variable is always used in conjunction with a mutex. To wait on a
+    /// condition variable, a thread first needs to acquire the condition variable spin
+    /// lock. After the spin lock is acquired, the thread updates the condition variable
+    /// waiting queue. To avoid the lost wake-up signal problem, the condition variable 
+    /// spin lock is released after the mutex. This order ensures the function atomically
+    /// releases the mutex and causes the calling thread to block on the condition variable, 
+    /// with respect to other threads accessing the mutex and the condition variable. 
+    /// After releasing the condition variable spin lock, the thread makes an OCALL to 
+    /// get suspended. When the thread is awakened, it acquires the condition variable 
+    /// spin lock. The thread then searches the condition variable queue. If the thread 
+    /// is in the queue, it means that the thread was already waiting on the condition 
+    /// variable outside the enclave, and it has been awakened unexpectedly. When this 
+    /// happens, the thread releases the condition variable spin lock, makes an OCALL 
+    /// and simply goes back to sleep. Otherwise, another thread has signaled or broadcasted
+    /// the condition variable and this thread may proceed. Before returning, the thread
+    /// releases the condition variable spin lock and acquires the mutex, ensuring that 
+    /// upon returning from the function call the thread still owns the mutex.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tstdc.a
+    ///
+    /// # Parameters
+    ///
+    /// **mutex**
+    ///
+    /// The trusted mutex object that will be unlocked when the thread is blocked inthe condition variable
+    ///
+    /// # Errors
+    ///
+    /// **EINVAL**
+    /// 
+    /// The trusted condition variable or mutex object is invalid or the mutex is not locked.
+    /// 
+    /// **EPERM**
+    /// 
+    /// The trusted mutex is locked by another thread.
+    /// 
+    pub fn wait(&self, mutex: &SgxThreadMutex) -> SysError {
+        
+        let ret = rsgx_thread_cond_wait(&self.cond, mutex.get_raw());
+        if ret == 0 { Ok(()) } else { Err(ret) }
+    }
+
+    ///
+    /// The function wakes a pending thread waiting on the condition variable.
+    ///
+    /// # Description
+    /// 
+    /// To signal a condition variable, a thread starts acquiring the condition variable
+    /// spin-lock. Then it inspects the status of the condition variable queue. If the
+    /// queue is empty it means that there are not any threads waiting on the condition
+    /// variable. When that happens, the thread releases the condition variable and returns. 
+    /// However, if the queue is not empty, the thread removes the first thread waiting 
+    /// in the queue. The thread then makes an OCALL to wake up the thread that is suspended
+    /// outside the enclave, but first the thread releases the condition variable spin-lock.
+    /// Upon returning from the OCALL, the thread continues normal execution.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tstdc.a
+    ///
+    /// # Errors 
+    ///
+    /// **EINVAL**
+    ///
+    /// The trusted condition variable is invalid.
+    ///
+    pub fn signal(&self) -> SysError {
+        
+        let ret = rsgx_thread_cond_signal(&self.cond);
+        if ret == 0 { Ok(()) } else { Err(ret) }
+    }
+
+    /// 
+    /// The function wakes all pending threads waiting on the condition variable.
+    ///
+    /// # Description
+    /// 
+    /// Broadcast and signal operations on a condition variable are analogous. The
+    /// only difference is that during a broadcast operation, the thread removes all
+    /// the threads waiting on the condition variable queue and wakes up all the
+    /// threads suspended outside the enclave in a single OCALL.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tstdc.a
+    ///
+    /// # Errors
+    /// 
+    /// **EINVAL**
+    /// 
+    /// The trusted condition variable is invalid.
+    /// 
+    /// **ENOMEM**
+    /// 
+    /// Internal memory allocation failed.
+    /// 
+    pub fn broadcast(&self) -> SysError {
+
+        let ret = rsgx_thread_cond_broadcast(&self.cond);
+        if ret == 0 { Ok(()) } else { Err(ret) }
+    }
+
+    ///
+    /// The function destroys a trusted condition variable within an enclave.
+    ///
+    /// # Description
+    ///
+    /// The procedure first confirms that there are no threads waiting on the condition 
+    /// variable before it is destroyed. The destroy operation acquires the spin lock at
+    /// the beginning of the operation to prevent other threads from signaling to or 
+    /// waiting on the condition variable.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tstdc.a
+    ///
+    /// # Errors
+    /// 
+    /// **EINVAL**
+    /// 
+    /// The trusted condition variable is invalid.
+    /// 
+    /// **EBUSY**
+    /// 
+    /// The condition variable has pending threads waiting on it.
+    /// 
+    pub fn destory(&self) -> SysError {
+        
+        let ret = rsgx_thread_cond_destroy(&self.cond);
+        if ret == 0 { Ok(()) } else { Err(ret) }
+    }
+
+    /// Get the pointer of sgx_thread_cond_t in SgxThreadCond.
+    pub fn get_raw(&self) -> &sgx_thread_cond_t {
+        &self.cond
+    }
+}
+
+/// The structure wrapped of SgxThreadCond.
+pub struct SgxCond {
+    inner: Box<SgxThreadCond>,
+    mutex: AtomicUsize,
+}
+
+impl SgxCond {
+    /// 
+    /// Creates a new condition variable which is ready to be waited on and notified.
+    ///
+    pub fn new() -> Self {
+        SgxCond {
+            inner: Box::new(SgxThreadCond::new()),
+            mutex: AtomicUsize::new(0),
+        }
+    }
+
+    /// 
+    /// The function waits on a condition variable within an enclave.
+    /// 
+    /// Blocks the current thread until this condition variable receives a
+    /// notification.
+    ///
+    /// This function will atomically unlock the mutex specified (represented by
+    /// `guard`) and block the current thread. This means that any calls
+    /// to [`broadcast`] which happen logically after the
+    /// mutex is unlocked are candidates to wake this thread up. When this
+    /// function call returns, the lock specified will have been re-acquired.
+    ///
+    /// # Parameters
+    /// 
+    /// **guard**
+    ///
+    /// The SgxMutexGuard warpped of sgx_thread_mutex_t. The trusted mutex object that will be atomically unlocked.
+    ///
+    /// # Return value
+    ///
+    /// Indicates wait success. Return the guard.
+    ///
+    /// # Errors
+    /// 
+    /// **EINVAL**
+    ///
+    /// The trusted condition variable is invalid.
+    ///
+    pub fn wait<'a, T>(&self, guard: SgxMutexGuard<'a, T>) -> SysResult<SgxMutexGuard<'a, T>> {
+
+        let lock = guard_lock(&guard);
+
+        let error = self.verify(lock);
+        if error.is_err() {
+            return Err(error.unwrap_err());
+        }
+
+        self.inner.wait(lock).map(|_| guard)
+    }
+
+    ///
+    /// The function wakes a pending thread waiting on the condition variable.
+    ///
+    pub fn signal(&self) -> SysError {
+       self.inner.signal()
+    }
+
+    ///
+    /// Wakes up all blocked threads on this SgxCond.
+    ///
+    /// This method will ensure that any current waiters on the condition
+    /// variable are awoken. Calls to `broadcast()` are not buffered in any
+    /// way.
+    ///
+    pub fn broadcast(&self) -> SysError {   
+       self.inner.broadcast()
+    }
+
+    fn verify(&self, mutex: &SgxThreadMutex) -> SysError {
+        
+        let addr = mutex as *const _ as usize;
+        match self.mutex.compare_and_swap(0, addr, Ordering::SeqCst) {
+            0 => Ok(()),
+            n if n == addr => Ok(()),
+            _ => Err(EINVAL),
+        }
+    } 
+}
+
+impl Drop for SgxCond {
+    fn drop(&mut self) {
+        let _ = self.inner.destory();
+    }
+}
+
+impl Default for SgxCond {
+    fn default() -> Self {
+        SgxCond::new()
+    }
+}
diff --git a/sgx_tstdc/src/lib.rs b/sgx_tstdc/src/lib.rs
new file mode 100644
index 0000000..a72eed2
--- /dev/null
+++ b/sgx_tstdc/src/lib.rs
@@ -0,0 +1,273 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//!
+//! The library is named sgx_tstdc, provides the following functions:
+//! 
+//! * Mutex
+//! * Condition
+//! * Query CPUID inside Enclave
+//! * Spin lock
+//!
+#![crate_name = "sgx_tstdc"]
+#![crate_type = "rlib"]
+
+#![cfg_attr(not(feature = "use_std"), no_std)]
+#![cfg_attr(not(feature = "use_std"), feature(alloc, optin_builtin_traits))]
+
+#![allow(non_camel_case_types)]
+
+#[cfg(feature = "use_std")]
+extern crate std as core;
+
+#[cfg(not(feature = "use_std"))]
+extern crate alloc;
+
+extern crate sgx_types;
+use sgx_types::*;
+
+pub mod mutex;
+pub use self::mutex::*;
+
+pub mod cond;
+pub use self::cond::*;
+
+///
+/// The rsgx_cpuid function performs the equivalent of a cpuid() function call or
+/// intrinisic which executes the CPUID instruction to query the host processor for
+/// the information about supported features.
+///
+/// **Note**
+///
+/// This function performs an OCALL to execute the CPUID instruction.
+///
+/// # Description
+///
+/// This function provides the equivalent of the cpuid() function or intrinsic. The
+/// function executes the CPUID instruction for the given leaf (input). The CPUID
+/// instruction provides processor feature and type information that is returned in
+/// cpuinfo, an array of 4 integers to specify the values of EAX, EBX, ECX and EDX
+/// registers. rsgx_cpuid performs an OCALL by invoking oc_cpuidex to get the
+/// info from untrusted side because the CPUID instruction is an illegal instruction
+/// in the enclave domain.
+///
+/// **Note**
+///
+/// As the CPUID instruction is executed by an OCALL, the results should not
+/// be trusted. Code should verify the results and perform a threat evaluation
+/// to determine the impact on trusted code if the results were
+/// spoofed.
+///
+/// The implementation of this function performs an OCALL and therefore,
+/// this function will not have the same serializing or fencing behavior of
+/// executing a CPUID instruction in an untrusted domain code flow.
+///
+/// # Parameters
+///
+/// **leaf**
+///
+/// The leaf specified for retrieved CPU info.
+///
+/// # Requirements
+///
+/// Library: libsgx_tstdc.a
+///
+/// # Return value
+///
+/// The information returned in an array of four integers.
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Indicates the parameter is invalid.
+///
+pub fn rsgx_cpuid(leaf: i32) -> SgxResult<sgx_cpuinfo_t> {
+    
+    let cpuinfo = [0_i32; 4];
+    let ret = unsafe { sgx_cpuid(cpuinfo, leaf) };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(cpuinfo),
+        _ => Err(ret),
+    }
+}
+
+///
+/// The rsgx_cpuidex function performs the equivalent of a cpuid_ex() function call or
+/// intrinisic which executes the CPUID instruction to query the host processor for
+/// the information about supported features.
+///
+/// **Note**
+///
+/// This function performs an OCALL to execute the CPUID instruction.
+///
+/// # Description
+///
+/// This function provides the equivalent of the cpuid_ex() function or intrinsic. The
+/// function executes the CPUID instruction for the given leaf (input). The CPUID
+/// instruction provides processor feature and type information that is returned in
+/// cpuinfo, an array of 4 integers to specify the values of EAX, EBX, ECX and EDX
+/// registers. rsgx_cpuidex performs an OCALL by invoking oc_cpuidex to get the
+/// info from untrusted side because the CPUID instruction is an illegal instruction
+/// in the enclave domain.
+///
+/// **Note**
+///
+/// As the CPUID instruction is executed by an OCALL, the results should not
+/// be trusted. Code should verify the results and perform a threat evaluation
+/// to determine the impact on trusted code if the results were
+/// spoofed.
+///
+/// The implementation of this function performs an OCALL and therefore,
+/// this function will not have the same serializing or fencing behavior of
+/// executing a CPUID instruction in an untrusted domain code flow.
+///
+/// # Parameters
+///
+/// **leaf**
+///
+/// The leaf specified for retrieved CPU info.
+///
+/// **subleaf**
+///
+/// The sub-leaf specified for retrieved CPU info.
+///
+/// # Requirements
+///
+/// Library: libsgx_tstdc.a
+///
+/// # Return value
+///
+/// The information returned in an array of four integers.
+///
+/// # Errors
+///
+/// **SGX_ERROR_INVALID_PARAMETER**
+///
+/// Indicates the parameter is invalid.
+///
+pub fn rsgx_cpuidex(leaf: i32, subleaf: i32) -> SgxResult<sgx_cpuinfo_t> {
+
+    let cpuinfo = [0_i32; 4];
+    let ret = unsafe { sgx_cpuidex(cpuinfo, leaf, subleaf) };
+    match ret {
+        sgx_status_t::SGX_SUCCESS => Ok(cpuinfo),
+        _ => Err(ret),
+    }
+}
+
+/// 
+/// The rsgx_spin_lock function acquires a spin lock within the enclave.
+///
+/// # Description
+///
+/// rsgx_spin_lock modifies the value of the spin lock by using compiler atomic
+/// operations. If the lock is not available to be acquired, the thread will always
+/// wait on the lock until it can be acquired successfully.
+///
+/// # Parameters
+///
+/// **lock**
+///
+/// The trusted spin lock object to be acquired.
+///
+/// # Requirements
+///
+/// Library: libsgx_tstdc.a
+///
+pub fn rsgx_spin_lock(lock: &mut sgx_spinlock_t) {
+
+    unsafe { sgx_spin_lock(lock as * mut sgx_spinlock_t); }
+}
+
+/// 
+/// The rsgx_spin_unlock function releases a spin lock within the enclave.
+///
+/// # Description
+///
+/// rsgx_spin_unlock resets the value of the spin lock, regardless of its current
+/// state. This function simply assigns a value of zero to the lock, which indicates
+/// the lock is released.
+///
+/// # Parameters
+///
+/// **lock**
+///
+/// The trusted spin lock object to be released.
+///
+/// # Requirements
+///
+/// Library: libsgx_tstdc.a
+///
+pub fn rsgx_spin_unlock(lock: &mut sgx_spinlock_t) {
+
+    unsafe { sgx_spin_unlock(lock as * mut sgx_spinlock_t); }
+}
+
+///
+/// The rsgx_thread_self function returns the unique thread identification.
+///
+/// # Description
+///
+/// The function is a simple wrap of get_thread_data() provided in the tRTS,
+/// which provides a trusted thread unique identifier.
+///
+/// # Requirements
+///
+/// Library: libsgx_tstdc.a
+///
+/// # Return value
+///
+/// The return value cannot be NULL and is always valid as long as it is invoked by a thread inside the enclave.
+///
+pub fn rsgx_thread_self() -> sgx_thread_t {
+    
+    unsafe { sgx_thread_self() }
+}
+
+///
+/// The rsgx_thread_equal function compares two thread identifiers.
+///
+/// # Description
+///
+/// The function compares two thread identifiers provided by sgx_thread_
+/// self to determine if the IDs refer to the same trusted thread.
+///
+/// # Requirements
+///
+/// Library: libsgx_tstdc.a
+///
+/// # Return value
+///
+/// **true**
+///
+/// The two thread IDs are equal.
+///
+pub fn rsgx_thread_equal(a: sgx_thread_t, b: sgx_thread_t) -> bool {
+    a == b
+}
diff --git a/sgx_tstdc/src/mutex.rs b/sgx_tstdc/src/mutex.rs
new file mode 100644
index 0000000..7a1b4f4
--- /dev/null
+++ b/sgx_tstdc/src/mutex.rs
@@ -0,0 +1,399 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+//!
+//! The Intel(R) Software Guard Extensions SDK already supports mutex and conditional 
+//! variable synchronization mechanisms by means of the following APIand data types 
+//! defined in the Types and Enumerations section. Some functions included in the 
+//! trusted Thread Synchronization library may make calls outside the enclave (OCALLs).
+//! If you use any of the APIs below, you must first import the needed OCALL functions
+//! from sgx_tstdc.edl. Otherwise, you will get a linker error when the enclave is
+//! being built; see Calling Functions outside the Enclave for additional details. 
+//! The table below illustrates the primitives that the Intel(R) SGX Thread 
+//! Synchronization library supports, as well as the OCALLs that each API function needs.
+//!
+use sgx_types::*;
+use core::cell::UnsafeCell;
+use core::mem;
+use core::ptr;
+use core::ops::{Deref, DerefMut};
+#[cfg(not(feature = "use_std"))]
+use core::marker;
+#[cfg(not(feature = "use_std"))]
+use alloc::boxed::Box;
+
+
+pub unsafe fn raw_mutex(lock: &sgx_thread_mutex_t) -> * mut sgx_thread_mutex_t {
+    lock as *const _ as *mut _
+}
+
+#[allow(dead_code)]
+fn rsgx_thread_mutex_init(mutex: &sgx_thread_mutex_t, unused: &sgx_thread_mutexattr_t) -> sys_error_t {
+
+    unsafe { sgx_thread_mutex_init(raw_mutex(mutex), unused as * const sgx_thread_mutexattr_t) }
+}
+
+fn rsgx_thread_mutex_destroy(mutex: &sgx_thread_mutex_t) -> sys_error_t {
+    
+    unsafe { sgx_thread_mutex_destroy(raw_mutex(mutex)) }
+}
+
+fn rsgx_thread_mutex_lock(mutex: &sgx_thread_mutex_t) -> sys_error_t {
+    
+    unsafe { sgx_thread_mutex_lock(raw_mutex(mutex)) }
+}
+
+fn rsgx_thread_mutex_trylock(mutex: &sgx_thread_mutex_t) -> sys_error_t {
+    
+    unsafe { sgx_thread_mutex_trylock(raw_mutex(mutex)) }
+}
+
+fn rsgx_thread_mutex_unlock(mutex: &sgx_thread_mutex_t) -> sys_error_t {
+    
+    unsafe { sgx_thread_mutex_unlock(raw_mutex(mutex)) }
+}
+
+/// The structure of sgx mutex.
+pub struct SgxThreadMutex {
+    lock: sgx_thread_mutex_t,
+}
+
+unsafe impl Send for SgxThreadMutex {}
+unsafe impl Sync for SgxThreadMutex {}
+
+impl SgxThreadMutex {
+    
+    ///
+    /// The function initializes a trusted mutex object within the enclave.
+    ///
+    /// # Description
+    /// 
+    /// When a thread creates a mutex within an enclave, sgx_thread_mutex_
+    /// init simply initializes the various fields of the mutex object to indicate that
+    /// the mutex is available. rsgx_thread_mutex_init creates a non-recursive
+    /// mutex. The results of using a mutex in a lock or unlock operation before it has
+    /// been fully initialized (for example, the function call to rsgx_thread_mutex_
+    /// init returns) are undefined. To avoid race conditions in the initialization of a
+    /// trusted mutex, it is recommended statically initializing the mutex with the
+    /// macro SGX_THREAD_MUTEX_INITIALIZER, SGX_THREAD_NON_RECURSIVE_MUTEX_INITIALIZER ,
+    /// of, or SGX_THREAD_RECURSIVE_MUTEX_INITIALIZER instead.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tstdc.a
+    ///
+    /// # Return value
+    ///
+    /// The trusted mutex object to be initialized.
+    ///
+    pub fn new() -> Self {
+        SgxThreadMutex{lock: SGX_THREAD_NONRECURSIVE_MUTEX_INITIALIZER}
+    }
+    
+    ///
+    /// The function locks a trusted mutex object within an enclave.
+    ///
+    /// # Description
+    /// 
+    /// To acquire a mutex, a thread first needs to acquire the corresponding spin
+    /// lock. After the spin lock is acquired, the thread checks whether the mutex is
+    /// available. If the queue is empty or the thread is at the head of the queue the
+    /// thread will now become the owner of the mutex. To confirm its ownership, the
+    /// thread updates the refcount and owner fields. If the mutex is not available, the
+    /// thread searches the queue. If the thread is already in the queue, but not at the
+    /// head, it means that the thread has previously tried to lock the mutex, but it
+    /// did not succeed and had to wait outside the enclave and it has been
+    /// awakened unexpectedly. When this happens, the thread makes an OCALL and
+    /// simply goes back to sleep. If the thread is trying to lock the mutex for the first
+    /// time, it will update the waiting queue and make an OCALL to get suspended.
+    /// Note that threads release the spin lock after acquiring the mutex or before
+    /// leaving the enclave.
+    ///
+    /// **Note**
+    ///
+    /// A thread should not exit an enclave returning from a root ECALL after acquiring
+    /// the ownership of a mutex. Do not split the critical section protected by a
+    /// mutex across root ECALLs.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tstdc.a
+    ///
+    /// # Errors
+    ///
+    /// **EINVAL**
+    /// 
+    /// The trusted mutex object is invalid.
+    /// 
+    pub fn lock(&self) -> SysError {
+
+        let ret = rsgx_thread_mutex_lock(&self.lock);
+        if ret == 0 { Ok(()) } else { Err(ret) }
+    }
+    
+    ///
+    /// The function tries to lock a trusted mutex object within an enclave.
+    ///
+    /// # Description
+    /// 
+    /// A thread may check the status of the mutex, which implies acquiring the spin
+    /// lock and verifying that the mutex is available and that the queue is empty or
+    /// the thread is at the head of the queue. When this happens, the thread
+    /// acquires the mutex, releases the spin lock and returns 0. Otherwise, the
+    /// thread releases the spin lock and returns EINVAL/EBUSY. The thread is not suspended
+    /// in this case.
+    ///
+    /// **Note**
+    ///
+    /// A thread should not exit an enclave returning from a root ECALL after acquiring
+    /// the ownership of a mutex. Do not split the critical section protected by a
+    /// mutex across root ECALLs.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tstdc.a
+    ///
+    /// # Errors
+    ///
+    /// **EINVAL**
+    /// 
+    /// The trusted mutex object is invalid.
+    /// 
+    /// **EBUSY**
+    /// 
+    /// The mutex is locked by another thread or has pending threads to acquire the mutex
+    ///
+    pub fn trylock(&self) -> SysError {
+
+        let ret = rsgx_thread_mutex_trylock(&self.lock);
+        if ret == 0 { Ok(()) } else { Err(ret) }
+    }
+
+    ///
+    /// The function unlocks a trusted mutex object within an enclave.
+    ///
+    /// # Description
+    /// 
+    /// Before a thread releases a mutex, it has to verify it is the owner of the mutex. If
+    /// that is the case, the thread decreases the refcount by 1 and then may either
+    /// continue normal execution or wakeup the first thread in the queue. Note that
+    /// to ensure the state of the mutex remains consistent, the thread that is
+    /// awakened by the thread releasing the mutex will then try to acquire the
+    /// mutex almost as in the initial call to the rsgx_thread_mutex_lock routine.
+    /// 
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tstdc.a
+    ///
+    /// # Errors
+    ///
+    /// **EINVAL**
+    /// 
+    /// The trusted mutex object is invalid or it is not locked by any thread.
+    /// 
+    /// **EPERM**
+    /// 
+    /// The mutex is locked by another thread.
+    ///
+    pub fn unlock(&self) -> SysError {
+
+        let ret = rsgx_thread_mutex_unlock(&self.lock);
+        if ret == 0 { Ok(()) } else { Err(ret) }
+    }
+
+    ///
+    /// The function destroys a trusted mutex object within an enclave.
+    ///
+    /// # Description
+    /// 
+    /// rsgx_thread_mutex_destroy resets the mutex, which brings it to its initial
+    /// status. In this process, certain fields are checked to prevent releasing a mutex
+    /// that is still owned by a thread or on which threads are still waiting.
+    /// 
+    /// **Note**
+    ///
+    /// Locking or unlocking a mutex after it has been destroyed results in undefined
+    /// behavior. After a mutex is destroyed, it must be re-created before it can be
+    /// used again.
+    ///
+    /// # Requirements
+    /// 
+    /// Library: libsgx_tstdc.a
+    ///
+    /// # Errors
+    ///
+    /// **EINVAL**
+    /// 
+    /// The trusted mutex object is invalid.
+    /// 
+    /// **EBUSY**
+    /// 
+    /// The mutex is locked by another thread or has pending threads to acquire the mutex.
+    ///
+    pub fn destory(&self) -> SysError {
+
+        let ret = rsgx_thread_mutex_destroy(&self.lock);
+        if ret == 0 { Ok(()) } else { Err(ret) }
+    }
+
+    /// Get the pointer of sgx_thread_mutex_t in SgxThreadMutex.
+    pub fn get_raw(&self) -> &sgx_thread_mutex_t {
+        &self.lock
+    }
+}
+
+/// The structure wrapped of SgxThreadMutex.
+pub struct SgxMutex<T: ?Sized> {
+    inner: Box<SgxThreadMutex>,
+    data: UnsafeCell<T>
+}
+
+unsafe impl<T: ?Sized + Send> Send for SgxMutex<T> { }
+unsafe impl<T: ?Sized + Send> Sync for SgxMutex<T> { }
+
+impl<T> SgxMutex<T> {
+    ///
+    /// Creates a new mutex in an unlocked state ready for use.
+    ///
+    pub fn new(t: T) -> SgxMutex<T> {
+        SgxMutex{
+            inner: Box::new(SgxThreadMutex::new()),
+            data: UnsafeCell::new(t),
+        }
+    }
+}
+
+impl<T: ?Sized> SgxMutex<T> {
+
+    ///
+    /// The function locks a trusted mutex object within an enclave.
+    ///
+    /// An RAII guard is returned to allow scoped unlock of the lock. When
+    /// the guard goes out of scope, the mutex will be unlocked.
+    ///
+    pub fn lock(&self) -> SysResult<SgxMutexGuard<T>> {
+        self.inner.lock().map(|_| SgxMutexGuard::new(self))
+    }
+
+    ///
+    /// The function tries to lock a trusted mutex object within an enclave.
+    ///
+    /// If the lock could not be acquired at this time, then `Err` is returned.
+    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
+    /// guard is dropped.
+    ///
+    /// This function does not block.
+    ///
+    pub fn try_lock(&self) -> SysResult<SgxMutexGuard<T>> {
+        self.inner.trylock().map(|_| SgxMutexGuard::new(self))
+    }
+
+    /// Consumes this mutex, returning the underlying data.
+    pub fn into_inner(self) -> SysResult<T> where T: Sized {
+
+        unsafe {
+            let (inner, data) = {
+                let SgxMutex {ref inner, ref data } = self;
+                (ptr::read(inner), ptr::read(data))
+            };
+            mem::forget(self);
+            let result = inner.destory();
+            drop(inner);
+            result.map(|_| data.into_inner())
+        }
+    }
+
+    /// Returns a mutable reference to the underlying data.
+    pub fn get_mut(&mut self) -> SysResult<&mut T> {
+      
+        let data = unsafe { &mut *self.data.get() };
+        Ok(data)
+    }
+}
+
+impl<T: ?Sized> Drop for SgxMutex<T> {
+    fn drop(&mut self) {
+       let _ = self.inner.destory();
+    }
+}
+
+impl<T: ?Sized + Default> Default for SgxMutex<T> {
+    fn default() -> SgxMutex<T> {
+        SgxMutex::new(Default::default())
+    }
+}
+
+///
+/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
+/// dropped (falls out of scope), the lock will be unlocked.
+///
+/// The data protected by the mutex can be accessed through this guard via its
+/// Deref and DerefMut implementations.
+///
+/// This structure is created by the lock and try_lock methods on Mutex.
+///
+pub struct SgxMutexGuard<'a, T: ?Sized + 'a> {
+    lock: &'a SgxMutex<T>,
+}
+
+#[cfg(not(feature = "use_std"))]
+impl<'a, T: ?Sized> !marker::Send for SgxMutexGuard<'a, T> {}
+
+impl<'mutex, T: ?Sized> SgxMutexGuard<'mutex, T> {
+
+    fn new(lock: &'mutex SgxMutex<T>) -> SgxMutexGuard<'mutex, T> {
+        SgxMutexGuard {
+            lock: lock,
+        }
+    }
+}
+
+impl<'mutex, T: ?Sized> Deref for SgxMutexGuard<'mutex, T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe { &*self.lock.data.get() }
+    }
+}
+
+impl<'mutex, T: ?Sized> DerefMut for SgxMutexGuard<'mutex, T> {
+    fn deref_mut(&mut self) -> &mut T {
+        unsafe { &mut *self.lock.data.get() }
+    }
+}
+
+impl<'a, T: ?Sized> Drop for SgxMutexGuard<'a, T> {
+    #[inline]
+    fn drop(&mut self) {
+       let _ = self.lock.inner.unlock();
+    }
+}
+
+pub fn guard_lock<'a, T: ?Sized>(guard: &SgxMutexGuard<'a, T>) -> &'a SgxThreadMutex {
+    &guard.lock.inner
+}
diff --git a/sgx_types/Cargo.toml b/sgx_types/Cargo.toml
new file mode 100644
index 0000000..8c12968
--- /dev/null
+++ b/sgx_types/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "sgx_types"
+version = "0.1.0"
+authors = ["Baidu"]
+
+[features]
+default = []
+use_std = []
+
+[dependencies]
\ No newline at end of file
diff --git a/sgx_types/src/error.rs b/sgx_types/src/error.rs
new file mode 100644
index 0000000..fb0e04c
--- /dev/null
+++ b/sgx_types/src/error.rs
@@ -0,0 +1,230 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+use core::result;
+//
+// sgx_error.h
+//
+impl_enum! {
+
+    #[repr(u32)]
+    #[derive(Copy, Clone, PartialEq, Eq)]
+    pub enum sgx_status_t {
+        SGX_SUCCESS                  = 0x00000000,
+
+        SGX_ERROR_UNEXPECTED         = 0x00000001,      /* Unexpected error */
+        SGX_ERROR_INVALID_PARAMETER  = 0x00000002,      /* The parameter is incorrect */
+        SGX_ERROR_OUT_OF_MEMORY      = 0x00000003,      /* Not enough memory is available to complete this operation */
+        SGX_ERROR_ENCLAVE_LOST       = 0x00000004,      /* Enclave lost after power transition or used in child process created by linux:fork() */
+        SGX_ERROR_INVALID_STATE      = 0x00000005,      /* SGX API is invoked in incorrect order or state */
+
+        SGX_ERROR_INVALID_FUNCTION   = 0x00001001,      /* The ecall/ocall index is invalid */
+        SGX_ERROR_OUT_OF_TCS         = 0x00001003,      /* The enclave is out of TCS */
+        SGX_ERROR_ENCLAVE_CRASHED    = 0x00001006,      /* The enclave is crashed */
+        SGX_ERROR_ECALL_NOT_ALLOWED  = 0x00001007,      /* The ECALL is not allowed at this time, e.g. ecall is blocked by the dynamic entry table, or nested ecall is not allowed during initialization */
+        SGX_ERROR_OCALL_NOT_ALLOWED  = 0x00001008,      /* The OCALL is not allowed at this time, e.g. ocall is not allowed during exception handling */
+        SGX_ERROR_STACK_OVERRUN      = 0x00001009,      /* The enclave is running out of stack */
+
+        SGX_ERROR_UNDEFINED_SYMBOL   = 0x00002000,      /* The enclave image has undefined symbol. */
+        SGX_ERROR_INVALID_ENCLAVE    = 0x00002001,      /* The enclave image is not correct. */
+        SGX_ERROR_INVALID_ENCLAVE_ID = 0x00002002,      /* The enclave id is invalid */
+        SGX_ERROR_INVALID_SIGNATURE  = 0x00002003,      /* The signature is invalid */
+        SGX_ERROR_NDEBUG_ENCLAVE     = 0x00002004,      /* The enclave is signed as product enclave, and can not be created as debuggable enclave. */
+        SGX_ERROR_OUT_OF_EPC         = 0x00002005,      /* Not enough EPC is available to load the enclave */
+        SGX_ERROR_NO_DEVICE          = 0x00002006,      /* Can't open SGX device */
+        SGX_ERROR_MEMORY_MAP_CONFLICT= 0x00002007,      /* Page mapping failed in driver */
+        SGX_ERROR_INVALID_METADATA   = 0x00002009,      /* The metadata is incorrect. */
+        SGX_ERROR_DEVICE_BUSY        = 0x0000200c,      /* Device is busy, mostly EINIT failed. */
+        SGX_ERROR_INVALID_VERSION    = 0x0000200d,      /* Metadata version is inconsistent between uRTS and sgx_sign or uRTS is incompatible with current platform. */
+        SGX_ERROR_MODE_INCOMPATIBLE  = 0x0000200e,      /* The target enclave 32/64 bit mode or sim/hw mode is incompatible with the mode of current uRTS. */
+        SGX_ERROR_ENCLAVE_FILE_ACCESS = 0x0000200f,     /* Can't open enclave file. */
+        SGX_ERROR_INVALID_MISC        = 0x00002010,     /* The MiscSelct/MiscMask settings are not correct.*/
+
+        SGX_ERROR_MAC_MISMATCH       = 0x00003001,      /* Indicates verification error for reports, sealed datas, etc */
+        SGX_ERROR_INVALID_ATTRIBUTE  = 0x00003002,      /* The enclave is not authorized */
+        SGX_ERROR_INVALID_CPUSVN     = 0x00003003,      /* The cpu svn is beyond platform's cpu svn value */
+        SGX_ERROR_INVALID_ISVSVN     = 0x00003004,      /* The isv svn is greater than the enclave's isv svn */
+        SGX_ERROR_INVALID_KEYNAME    = 0x00003005,      /* The key name is an unsupported value */
+
+        SGX_ERROR_SERVICE_UNAVAILABLE       = 0x00004001,   /* Indicates aesm didn't response or the requested service is not supported */
+        SGX_ERROR_SERVICE_TIMEOUT           = 0x00004002,   /* The request to aesm time out */
+        SGX_ERROR_AE_INVALID_EPIDBLOB       = 0x00004003,   /* Indicates epid blob verification error */
+        SGX_ERROR_SERVICE_INVALID_PRIVILEGE = 0x00004004,   /* Enclave has no privilege to get launch token */
+        SGX_ERROR_EPID_MEMBER_REVOKED       = 0x00004005,   /* The EPID group membership is revoked. */
+        SGX_ERROR_UPDATE_NEEDED             = 0x00004006,   /* SGX needs to be updated */
+        SGX_ERROR_NETWORK_FAILURE           = 0x00004007,   /* Network connecting or proxy setting issue is encountered */
+        SGX_ERROR_AE_SESSION_INVALID        = 0x00004008,   /* Session is invalid or ended by server */
+        SGX_ERROR_BUSY                      = 0x0000400a,   /* The requested service is temporarily not availabe */
+        SGX_ERROR_MC_NOT_FOUND              = 0x0000400c,   /* The Monotonic Counter doesn't exist or has been invalided */
+        SGX_ERROR_MC_NO_ACCESS_RIGHT        = 0x0000400d,   /* Caller doesn't have the access right to specified VMC */
+        SGX_ERROR_MC_USED_UP                = 0x0000400e,   /* Monotonic counters are used out */
+        SGX_ERROR_MC_OVER_QUOTA             = 0x0000400f,   /* Monotonic counters exceeds quota limitation */
+        SGX_ERROR_KDF_MISMATCH              = 0x00004011,   /* Key derivation function doesn't match during key exchange */
+    }
+}
+
+pub type sys_error_t = ::int32_t;
+pub type SgxResult<T> = result::Result<T, sgx_status_t>;
+pub type SgxError = result::Result<(), sgx_status_t>;
+pub type SysResult<T> = result::Result<T, sys_error_t>;
+pub type SysError = result::Result<(), sys_error_t>;
+
+pub const EPERM: ::int32_t              = 1;
+pub const ENOENT: ::int32_t             = 2;
+pub const ESRCH: ::int32_t              = 3;
+pub const EINTR: ::int32_t              = 4;
+pub const EIO: ::int32_t                = 5;
+pub const ENXIO: ::int32_t              = 6;
+pub const E2BIG: ::int32_t              = 7;
+pub const ENOEXEC: ::int32_t            = 8;
+pub const EBADF: ::int32_t              = 9;
+pub const ECHILD: ::int32_t             = 10;
+pub const EAGAIN: ::int32_t             = 11;
+pub const ENOMEM: ::int32_t             = 12;
+pub const EACCES: ::int32_t             = 13;
+pub const EFAULT: ::int32_t             = 14;
+pub const ENOTBLK: ::int32_t            = 15;
+pub const EBUSY: ::int32_t              = 16;
+pub const EEXIST: ::int32_t             = 17;
+pub const EXDEV: ::int32_t              = 18;
+pub const ENODEV: ::int32_t             = 19;
+pub const ENOTDIR: ::int32_t            = 20;
+pub const EISDIR: ::int32_t             = 21;
+pub const EINVAL: ::int32_t             = 22;
+pub const ENFILE: ::int32_t             = 23;
+pub const EMFILE: ::int32_t             = 24;
+pub const ENOTTY: ::int32_t             = 25;
+pub const ETXTBSY: ::int32_t            = 26;
+pub const EFBIG: ::int32_t              = 27;
+pub const ENOSPC: ::int32_t             = 28;
+pub const ESPIPE: ::int32_t             = 29;
+pub const EROFS: ::int32_t              = 30;
+pub const EMLINK: ::int32_t             = 31;
+pub const EPIPE: ::int32_t              = 32;
+pub const EDOM: ::int32_t               = 33;
+pub const ERANGE: ::int32_t             = 34;
+pub const EDEADLK: ::int32_t            = 35;
+pub const ENAMETOOLONG: ::int32_t       = 36;
+pub const ENOLCK: ::int32_t             = 37;
+pub const ENOSYS: ::int32_t             = 38;
+pub const ENOTEMPTY: ::int32_t          = 39;
+pub const ELOOP: ::int32_t              = 40;
+pub const EWOULDBLOCK: ::int32_t        = EAGAIN;
+pub const ENOMSG: ::int32_t             = 42;
+pub const EIDRM: ::int32_t              = 43;
+pub const ECHRNG: ::int32_t             = 44;
+pub const EL2NSYNC: ::int32_t           = 45;
+pub const EL3HLT: ::int32_t             = 46;
+pub const EL3RST: ::int32_t             = 47;
+pub const ELNRNG: ::int32_t             = 48;
+pub const EUNATCH: ::int32_t            = 49;
+pub const ENOCSI: ::int32_t             = 50;
+pub const EL2HLT: ::int32_t             = 51;
+pub const EBADE: ::int32_t              = 52;
+pub const EBADR: ::int32_t              = 53;
+pub const EXFULL: ::int32_t             = 54;
+pub const ENOANO: ::int32_t             = 55;
+pub const EBADRQC: ::int32_t            = 56;
+pub const EBADSLT: ::int32_t            = 57;
+pub const EDEADLOCK: ::int32_t          = EDEADLK;
+pub const EBFONT: ::int32_t             = 59;
+pub const ENOSTR: ::int32_t             = 60;
+pub const ENODATA: ::int32_t            = 61;
+pub const ETIME: ::int32_t              = 62;
+pub const ENOSR: ::int32_t              = 63;
+pub const ENONET: ::int32_t             = 64;
+pub const ENOPKG: ::int32_t             = 65;
+pub const EREMOTE: ::int32_t            = 66;
+pub const ENOLINK: ::int32_t            = 67;
+pub const EADV: ::int32_t               = 68;
+pub const ESRMNT: ::int32_t             = 69;
+pub const ECOMM: ::int32_t              = 70;
+pub const EPROTO: ::int32_t             = 71;
+pub const EMULTIHOP: ::int32_t          = 72;
+pub const EDOTDOT: ::int32_t            = 73;
+pub const EBADMSG: ::int32_t            = 74;
+pub const EOVERFLOW: ::int32_t          = 75;
+pub const ENOTUNIQ: ::int32_t           = 76;
+pub const EBADFD: ::int32_t             = 77;
+pub const EREMCHG: ::int32_t            = 78;
+pub const ELIBACC: ::int32_t            = 79;
+pub const ELIBBAD: ::int32_t            = 80;
+pub const ELIBSCN: ::int32_t            = 81;
+pub const ELIBMAX: ::int32_t            = 82;
+pub const ELIBEXEC: ::int32_t           = 83;
+pub const EILSEQ: ::int32_t             = 84;
+pub const ERESTART: ::int32_t           = 85;
+pub const ESTRPIPE: ::int32_t           = 86;
+pub const EUSERS: ::int32_t             = 87;
+pub const ENOTSOCK: ::int32_t           = 88;
+pub const EDESTADDRREQ: ::int32_t       = 89;
+pub const EMSGSIZE: ::int32_t           = 90;
+pub const EPROTOTYPE: ::int32_t         = 91;
+pub const ENOPROTOOPT: ::int32_t        = 92;
+pub const EPROTONOSUPPORT: ::int32_t    = 93;
+pub const ESOCKTNOSUPPORT: ::int32_t    = 94;
+pub const EOPNOTSUPP: ::int32_t         = 95;
+pub const EPFNOSUPPORT: ::int32_t       = 96;
+pub const EAFNOSUPPORT: ::int32_t       = 97;
+pub const EADDRINUSE: ::int32_t         = 98;
+pub const EADDRNOTAVAIL: ::int32_t      = 99;
+pub const ENETDOWN: ::int32_t           = 100;
+pub const ENETUNREACH: ::int32_t        = 101;
+pub const ENETRESET: ::int32_t          = 102;
+pub const ECONNABORTED: ::int32_t       = 103;
+pub const ECONNRESET: ::int32_t         = 104;
+pub const ENOBUFS: ::int32_t            = 105;
+pub const EISCONN: ::int32_t            = 106;
+pub const ENOTCONN: ::int32_t           = 107;
+pub const ESHUTDOWN: ::int32_t          = 108;
+pub const ETOOMANYREFS: ::int32_t       = 109;
+pub const ETIMEDOUT: ::int32_t          = 110;
+pub const ECONNREFUSED: ::int32_t       = 111;
+pub const EHOSTDOWN: ::int32_t          = 112;
+pub const EHOSTUNREACH: ::int32_t       = 113;
+pub const EALREADY: ::int32_t           = 114;
+pub const EINPROGRESS: ::int32_t        = 115;
+pub const ESTALE: ::int32_t             = 116;
+pub const EUCLEAN: ::int32_t            = 117;
+pub const ENOTNAM: ::int32_t            = 118;
+pub const ENAVAIL: ::int32_t            = 119;
+pub const EISNAM: ::int32_t             = 120;
+pub const EREMOTEIO: ::int32_t          = 121;
+pub const EDQUOT: ::int32_t             = 122;
+pub const ENOMEDIUM: ::int32_t          = 123;
+pub const EMEDIUMTYPE: ::int32_t        = 124;
+pub const ECANCELED: ::int32_t          = 125;
+pub const ENOKEY: ::int32_t             = 126;
+pub const EKEYEXPIRED: ::int32_t        = 127;
+pub const EKEYREVOKED: ::int32_t        = 128;
+pub const EKEYREJECTED: ::int32_t       = 129;
+pub const EOWNERDEAD: ::int32_t         = 130;
+pub const ENOTRECOVERABLE: ::int32_t    = 131;
+pub const ERFKILL: ::int32_t            = 132;
+pub const EHWPOISON: ::int32_t          = 133;
+pub const ENOTSUP: ::int32_t            = EOPNOTSUPP;
diff --git a/sgx_types/src/function.rs b/sgx_types/src/function.rs
new file mode 100644
index 0000000..f07476a
--- /dev/null
+++ b/sgx_types/src/function.rs
@@ -0,0 +1,377 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+use error::*;
+use types::*;
+
+#[link(name = "sgx_tstdc")]
+extern {
+    //
+    // sgx_cpuid.h
+    //
+    pub fn sgx_cpuid(cpuinfo: [::int32_t; 4], leaf: ::int32_t) -> sgx_status_t;
+    pub fn sgx_cpuidex(cpuinfo: [::int32_t; 4], leaf: ::int32_t, subleaf: ::int32_t) -> sgx_status_t;
+
+    //
+    // sgx_spinlock.h
+    //
+    pub fn sgx_spin_lock(lock: * const sgx_spinlock_t) -> ::uint32_t;
+    pub fn sgx_spin_unlock(lock: * const sgx_spinlock_t) -> ::uint32_t;
+
+    //
+    // sgx_thread.h
+    //
+    pub fn sgx_thread_mutex_init(mutex: * mut sgx_thread_mutex_t, unused: * const sgx_thread_mutexattr_t) -> ::int32_t;
+    pub fn sgx_thread_mutex_destroy(mutex: * mut sgx_thread_mutex_t) -> ::int32_t;
+    
+    pub fn sgx_thread_mutex_lock(mutex: * mut sgx_thread_mutex_t) -> ::int32_t;
+    pub fn sgx_thread_mutex_trylock(mutex: * mut sgx_thread_mutex_t) -> ::int32_t;
+    pub fn sgx_thread_mutex_unlock(mutex: * mut sgx_thread_mutex_t) -> ::int32_t;
+    
+    pub fn sgx_thread_cond_init(cond: * mut sgx_thread_cond_t, unused: * const sgx_thread_condattr_t) -> ::int32_t;
+    pub fn sgx_thread_cond_destroy(cond: * mut sgx_thread_cond_t) -> ::int32_t;
+    
+    pub fn sgx_thread_cond_wait(cond: * mut sgx_thread_cond_t, mutex: * mut sgx_thread_mutex_t) -> ::int32_t;
+    pub fn sgx_thread_cond_signal(cond: * mut sgx_thread_cond_t) -> ::int32_t;
+    pub fn sgx_thread_cond_broadcast(cond: * mut sgx_thread_cond_t) -> ::int32_t;
+
+    pub fn sgx_thread_self() -> sgx_thread_t;
+    pub fn sgx_thread_equal(a: sgx_thread_t, b: sgx_thread_t)  -> ::int32_t;
+}
+
+
+#[link(name = "sgx_tservice")]
+extern {
+
+    //
+    // sgx_dh.h
+    //
+    pub fn sgx_dh_init_session(role: sgx_dh_session_role_t, session: * mut sgx_dh_session_t) -> sgx_status_t;
+
+    pub fn sgx_dh_responder_gen_msg1(msg1: * mut sgx_dh_msg1_t, 
+                                     dh_session: * mut sgx_dh_session_t) -> sgx_status_t;
+
+    pub fn sgx_dh_initiator_proc_msg1(msg1: * const sgx_dh_msg1_t, 
+                                      msg2: * mut sgx_dh_msg2_t, 
+                                      dh_session: * mut sgx_dh_session_t) -> sgx_status_t;
+    
+    pub fn sgx_dh_responder_proc_msg2(msg2: * const sgx_dh_msg2_t,
+                                      msg3: * mut sgx_dh_msg3_t,
+                                      dh_session: * mut sgx_dh_session_t,
+                                      aek: * mut sgx_key_128bit_t,
+                                      initiator_identity: * mut sgx_dh_session_enclave_identity_t) -> sgx_status_t;
+
+    pub fn sgx_dh_initiator_proc_msg3(msg3: * const sgx_dh_msg3_t,
+                                      dh_session: * mut sgx_dh_session_t,
+                                      aek: * mut sgx_key_128bit_t,
+                                      responder_identity: * mut sgx_dh_session_enclave_identity_t) -> sgx_status_t;
+
+    //
+    // sgx_tae_service.h
+    //
+    pub fn sgx_create_pse_session() -> sgx_status_t;
+    pub fn sgx_close_pse_session() -> sgx_status_t;
+    pub fn sgx_get_ps_sec_prop(security_property: * mut sgx_ps_sec_prop_desc_t) -> sgx_status_t;
+    pub fn sgx_get_trusted_time(current_time: * mut sgx_time_t, time_source_nonce: * mut sgx_time_source_nonce_t) -> sgx_status_t;
+
+    pub fn sgx_create_monotonic_counter_ex(owner_policy: ::uint16_t,
+                                           owner_attribute_mask: * const sgx_attributes_t,
+                                           counter_uuid: * mut sgx_mc_uuid_t,
+                                           counter_value: * mut ::uint32_t) -> sgx_status_t;
+
+    pub fn sgx_create_monotonic_counter(counter_uuid: * mut sgx_mc_uuid_t, counter_value: * mut ::uint32_t) -> sgx_status_t;
+    pub fn sgx_destroy_monotonic_counter(counter_uuid: * const sgx_mc_uuid_t) -> sgx_status_t;
+    pub fn sgx_increment_monotonic_counter(counter_uuid: * const sgx_mc_uuid_t, counter_value: * mut ::uint32_t) -> sgx_status_t;
+    pub fn sgx_read_monotonic_counter(counter_uuid: * const sgx_mc_uuid_t, counter_value: * mut ::uint32_t) -> sgx_status_t;
+
+    
+    //
+    // sgx_tseal.h
+    //
+    pub fn sgx_calc_sealed_data_size(add_mac_txt_size: ::uint32_t, txt_encrypt_size: ::uint32_t) -> ::uint32_t;
+    pub fn sgx_get_add_mac_txt_len(p_sealed_data: * const sgx_sealed_data_t) -> ::uint32_t;
+    pub fn sgx_get_encrypt_txt_len(p_sealed_data: * const sgx_sealed_data_t) -> ::uint32_t;
+
+    pub fn sgx_seal_data(additional_MACtext_length: ::uint32_t,
+                         p_additional_MACtext: * const ::uint8_t,
+                         text2encrypt_length: ::uint32_t,
+                         p_text2encrypt: * const ::uint8_t,
+                         sealed_data_size: ::uint32_t,
+                         p_sealed_data: * mut sgx_sealed_data_t) -> sgx_status_t;
+
+    pub fn sgx_seal_data_ex(key_policy: ::uint16_t,
+                            attribute_mask: sgx_attributes_t,
+                            misc_mask: sgx_misc_select_t,
+                            additional_MACtext_length: ::uint32_t,
+                            p_additional_MACtext: * const ::uint8_t,
+                            text2encrypt_length: ::uint32_t,
+                            p_text2encrypt: * const ::uint8_t,
+                            sealed_data_size: ::uint32_t,
+                            p_sealed_data: * mut sgx_sealed_data_t) -> sgx_status_t;
+
+    pub fn sgx_unseal_data(p_sealed_data: * const sgx_sealed_data_t,
+                           p_additional_MACtext: * mut ::uint8_t,
+                           p_additional_MACtext_length: * mut ::uint32_t,
+                           p_decrypted_text: * mut ::uint8_t,
+                           p_decrypted_text_length: * mut ::uint32_t) -> sgx_status_t;
+
+    pub fn sgx_mac_aadata(additional_MACtext_length: ::uint32_t,
+                          p_additional_MACtext: * const ::uint8_t,
+                          sealed_data_size: ::uint32_t,
+                          p_sealed_data: * mut sgx_sealed_data_t) -> sgx_status_t;
+
+    pub fn sgx_mac_aadata_ex(key_policy: ::uint16_t,
+                             attribute_mask: sgx_attributes_t,
+                             misc_mask: sgx_misc_select_t,
+                             additional_MACtext_length: ::uint32_t,
+                             p_additional_MACtext: * const ::uint8_t,
+                             sealed_data_size: ::uint32_t,
+                             p_sealed_data: * mut sgx_sealed_data_t) -> sgx_status_t;
+
+    pub fn sgx_unmac_aadata(p_sealed_data: * const sgx_sealed_data_t, 
+                            p_additional_MACtext: * mut ::uint8_t, 
+                            p_additional_MACtext_length: * mut ::uint32_t) -> sgx_status_t;
+
+
+    //
+    // sgx_utils.h
+    //
+    pub fn sgx_create_report(target_info : * const sgx_target_info_t, 
+                             report_data: * const sgx_report_data_t, 
+                             report: * mut sgx_report_t) -> sgx_status_t;
+
+    pub fn sgx_verify_report(report: * const sgx_report_t) -> sgx_status_t;
+    pub fn sgx_get_key(key_request: * const sgx_key_request_t, key: * mut sgx_key_128bit_t) -> sgx_status_t;
+}
+
+
+#[link(name = "sgx_tcrypto")]
+extern {
+
+    //
+    // sgx_tcrypto.h
+    //
+    pub fn sgx_sha256_msg(p_src: * const ::uint8_t, src_len: ::uint32_t, p_hash: * mut sgx_sha256_hash_t) -> sgx_status_t;
+    pub fn sgx_sha256_init(p_sha_handle: * mut sgx_sha_state_handle_t) -> sgx_status_t;
+    pub fn sgx_sha256_update(p_src: * const ::uint8_t, src_len: ::uint32_t, sha_handle: sgx_sha_state_handle_t) -> sgx_status_t;
+    pub fn sgx_sha256_get_hash(sha_handle: sgx_sha_state_handle_t, p_hash: * mut sgx_sha256_hash_t) -> sgx_status_t;
+    pub fn sgx_sha256_close(sha_handle: sgx_sha_state_handle_t) -> sgx_status_t;
+    
+    pub fn sgx_rijndael128GCM_encrypt(p_key: * const sgx_aes_gcm_128bit_key_t,
+                                      p_src: * const ::uint8_t,
+                                      src_len: ::uint32_t,
+                                      p_dst: * mut ::uint8_t,
+                                      p_iv: * const ::uint8_t,
+                                      iv_len: ::uint32_t,
+                                      p_aad: * const ::uint8_t,
+                                      aad_len: ::uint32_t,
+                                      p_out_mac: * mut sgx_aes_gcm_128bit_tag_t) -> sgx_status_t;
+
+    pub fn sgx_rijndael128GCM_decrypt(p_key: * const sgx_aes_gcm_128bit_key_t,
+                                      p_src: * const ::uint8_t,
+                                      src_len: ::uint32_t,
+                                      p_dst: * mut ::uint8_t,
+                                      p_iv: * const ::uint8_t,
+                                      iv_len: ::uint32_t,
+                                      p_aad: * const ::uint8_t,
+                                      aad_len: ::uint32_t,
+                                      p_in_mac: * const sgx_aes_gcm_128bit_tag_t) -> sgx_status_t;
+
+    pub fn sgx_rijndael128_cmac_msg(p_key: * const sgx_cmac_128bit_key_t, p_src: * const ::uint8_t, src_len: ::uint32_t, p_mac: * mut sgx_cmac_128bit_tag_t) -> sgx_status_t;
+    pub fn sgx_cmac128_init(p_key: * const sgx_cmac_128bit_key_t, p_cmac_handle: * mut sgx_cmac_state_handle_t) -> sgx_status_t;
+    pub fn sgx_cmac128_update(p_src: * const ::uint8_t, src_len: ::uint32_t, cmac_handle: sgx_cmac_state_handle_t) -> sgx_status_t;
+    pub fn sgx_cmac128_final(cmac_handle: sgx_cmac_state_handle_t, p_hash: * mut sgx_cmac_128bit_tag_t) -> sgx_status_t;
+    pub fn sgx_cmac128_close(cmac_handle: sgx_cmac_state_handle_t) -> sgx_status_t;
+    
+    pub fn sgx_aes_ctr_encrypt(p_key: * const sgx_aes_ctr_128bit_key_t,
+                               p_src: * const ::uint8_t,
+                               src_len: ::uint32_t,
+                               p_ctr: * const ::uint8_t,
+                               ctr_inc_bits: ::uint32_t,
+                               p_dst: * mut ::uint8_t) -> sgx_status_t;
+
+    pub fn sgx_aes_ctr_decrypt(p_key: * const sgx_aes_ctr_128bit_key_t,
+                               p_src: * const ::uint8_t,
+                               src_len: ::uint32_t,
+                               p_ctr: * const ::uint8_t,
+                               ctr_inc_bits: ::uint32_t,
+                               p_dst: * mut ::uint8_t) -> sgx_status_t;
+
+    pub fn sgx_ecc256_open_context(p_ecc_handle: * mut sgx_ecc_state_handle_t) -> sgx_status_t;
+    pub fn sgx_ecc256_close_context(ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t;
+
+    pub fn sgx_ecc256_create_key_pair(p_private: * mut sgx_ec256_private_t, p_public: * mut sgx_ec256_public_t, ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t;
+    pub fn sgx_ecc256_check_point(p_point: * const sgx_ec256_public_t, ecc_handle: sgx_ecc_state_handle_t, p_valid: * mut ::int32_t) -> sgx_status_t;
+
+    pub fn sgx_ecc256_compute_shared_dhkey(p_private_b: * mut sgx_ec256_private_t,
+                                           p_public_ga: * mut sgx_ec256_public_t,
+                                           p_shared_key: * mut sgx_ec256_dh_shared_t,
+                                           ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t;
+
+    pub fn sgx_ecdsa_sign(p_data: * const ::uint8_t,
+                          data_size: ::uint32_t,
+                          p_private: * mut sgx_ec256_private_t,
+                          p_signature: * mut sgx_ec256_signature_t,
+                          ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t;
+
+    pub fn sgx_ecdsa_verify(p_data: * const ::uint8_t, 
+                            data_size: :: uint32_t, 
+                            p_public: * const sgx_ec256_public_t, 
+                            p_signature: * mut sgx_ec256_signature_t,
+                            p_result: * mut ::uint8_t, 
+                            ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t;
+}
+
+
+
+#[link(name = "sgx_tkey_exchange")]
+extern {
+
+    //
+    // sgx_tkey_exchange.h
+    //
+    pub fn sgx_ra_init(p_pub_key: * const sgx_ec256_public_t, b_pse: ::int32_t, p_context: * mut sgx_ra_context_t) -> sgx_status_t;
+
+    pub fn sgx_ra_init_ex(p_pub_key: * const sgx_ec256_public_t,
+                          b_pse: ::int32_t,
+                          derive_key_cb: sgx_ra_derive_secret_keys_t,
+                          p_context: * mut sgx_ra_context_t) -> sgx_status_t;
+
+    pub fn sgx_ra_get_keys(context: sgx_ra_context_t,
+                           keytype: sgx_ra_key_type_t,
+                           p_key: * mut sgx_ra_key_128_t) -> sgx_status_t;
+
+    pub fn sgx_ra_close(context: sgx_ra_context_t) -> sgx_status_t;
+}
+
+
+#[link(name = "sgx_trts")]
+extern {
+
+    //
+    // sgx_trts.h
+    //
+    pub fn sgx_is_within_enclave(addr: * const ::c_void, size: ::size_t) -> ::int32_t;
+    pub fn sgx_is_outside_enclave(addr: * const ::c_void, size: ::size_t) -> ::int32_t;
+    pub fn sgx_read_rand(rand: * mut u8, length_in_bytes: ::size_t) -> sgx_status_t;
+
+
+    //
+    // sgx_trts_exception.h
+    //
+    pub fn sgx_register_exception_handler(is_first_handler: ::uint32_t, 
+                                          exception_handler: sgx_exception_handler_t) -> * const ::c_void;
+                                          
+    pub fn sgx_unregister_exception_handler(handler: * const ::c_void) -> ::uint32_t;
+
+    //
+    // sgx_edger8r.h
+    //
+    pub fn sgx_ocalloc(size: ::size_t) -> * mut ::c_void;
+    pub fn sgx_sgx_ocfree();
+ 
+    //
+    // trts_pic.S
+    //
+    pub fn abort() -> !;
+
+    pub fn get_thread_data() -> * const ::c_void;
+    pub fn get_enclave_base() -> * const ::c_void;
+    pub fn get_heap_base() -> * const ::c_void;
+    pub fn get_heap_size() -> ::size_t;
+}
+
+
+#[link(name = "sgx_uae_service")]
+extern {
+
+    //
+    // sgx_uae_service.h
+    //
+    pub fn sgx_init_quote(p_target_info: * mut sgx_target_info_t, p_gid: * mut sgx_epid_group_id_t) -> sgx_status_t;
+    pub fn sgx_get_quote_size(p_sig_rl: * const ::uint8_t, p_quote_size: * mut ::uint32_t) -> sgx_status_t;
+
+    pub fn sgx_get_quote(p_report: * const sgx_report_t,
+                         quote_type: sgx_quote_sign_type_t,
+                         p_spid: * const sgx_spid_t,
+                         p_nonce: * const sgx_quote_nonce_t,
+                         p_sig_rl: * const ::uint8_t,
+                         sig_rl_size: ::uint32_t,
+                         p_qe_report: * mut sgx_report_t,
+                         p_quote: * mut sgx_quote_t,
+                         quote_size: ::uint32_t) -> sgx_status_t;
+
+    pub fn sgx_get_ps_cap(p_sgx_ps_cap: * mut sgx_ps_cap_t) -> sgx_status_t;
+    pub fn sgx_get_whitelist_size(p_whitelist_size: * mut ::uint32_t) -> sgx_status_t;
+    pub fn sgx_get_whitelist(p_whitelist: * mut ::uint8_t, whitelist_size: ::uint32_t) -> sgx_status_t;
+    pub fn sgx_get_extended_epid_group_id(p_extended_epid_group_id: * mut ::uint32_t) -> sgx_status_t;
+    
+    pub fn sgx_report_attestation_status(p_platform_info: * const sgx_platform_info_t, 
+                                         attestation_status: i32, 
+                                         p_update_info: * mut sgx_update_info_bit_t) -> sgx_status_t;
+}
+
+
+#[link(name = "sgx_ukey_exchange")]
+extern {
+
+    //
+    // sgx_ukey_exchange.h
+    //
+    pub fn sgx_ra_get_msg1(context: sgx_ra_context_t,
+                           eid: sgx_enclave_id_t,
+                           p_get_ga: sgx_ecall_get_ga_trusted_t,
+                           p_msg1: * mut sgx_ra_msg1_t
+                           ) -> sgx_status_t;
+
+    pub fn sgx_ra_proc_msg2(context: sgx_ra_context_t,
+                            eid: sgx_enclave_id_t,
+                            p_proc_msg2: sgx_ecall_proc_msg2_trusted_t,
+                            p_get_msg3: sgx_ecall_get_msg3_trusted_t,
+                            p_msg2: * const sgx_ra_msg2_t,
+                            msg2_size: ::uint32_t,
+                            pp_msg3: * mut &sgx_ra_msg3_t,
+                            p_msg3_size: ::uint32_t) -> sgx_status_t;
+}
+
+
+#[link(name = "sgx_urts")]
+extern {
+
+    //
+    // sgx_urts.h
+    //
+    pub fn sgx_create_enclave(file_name: * const ::c_schar,
+                              debug: ::int32_t,
+                              launch_token: * mut sgx_launch_token_t,
+                              launch_token_updated: * mut ::int32_t,
+                              enclave_id: * mut sgx_enclave_id_t,
+                              misc_attr: * mut sgx_misc_attribute_t) -> sgx_status_t;
+
+    pub fn sgx_destroy_enclave(enclave_id: sgx_enclave_id_t);
+}
\ No newline at end of file
diff --git a/sgx_types/src/lib.rs b/sgx_types/src/lib.rs
new file mode 100644
index 0000000..1067737
--- /dev/null
+++ b/sgx_types/src/lib.rs
@@ -0,0 +1,94 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+#![crate_name = "sgx_types"]
+#![crate_type = "rlib"]
+
+#![cfg_attr(not(feature = "use_std"), no_std)]
+#![cfg_attr(not(feature = "use_std"), feature(lang_items, const_fn))]
+
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(improper_ctypes)]
+#![allow(unused_variables)]
+
+#[cfg(feature = "use_std")]
+extern crate std as core;
+
+#[macro_use]
+mod macros;
+
+#[repr(u8)]
+pub enum c_void {
+    // Two dummy variants so the #[repr] attribute can be used.
+    #[doc(hidden)]
+    __variant1,
+    #[doc(hidden)]
+    __variant2,
+}
+
+pub type int8_t = i8;
+pub type int16_t = i16;
+pub type int32_t = i32;
+pub type int64_t = i64;
+pub type uint8_t = u8;
+pub type uint16_t = u16;
+pub type uint32_t = u32;
+pub type uint64_t = u64;
+
+pub type c_schar = i8;
+pub type c_uchar = u8;
+pub type c_short = i16;
+pub type c_ushort = u16;
+pub type c_int = i32;
+pub type c_uint = u32;
+pub type c_float = f32;
+pub type c_double = f64;
+pub type c_longlong = i64;
+pub type c_ulonglong = u64;
+pub type intmax_t = i64;
+pub type uintmax_t = u64;
+
+pub type size_t = usize;
+pub type ptrdiff_t = isize;
+pub type intptr_t = isize;
+pub type uintptr_t = usize;
+pub type ssize_t = isize;
+
+
+pub mod types;
+pub use self::types::*;
+
+pub mod error;
+pub use self::error::*;
+
+pub mod function;
+pub use self::function::*;
+
+pub mod oom;
+pub use self::oom::*;
\ No newline at end of file
diff --git a/sgx_types/src/macros.rs b/sgx_types/src/macros.rs
new file mode 100644
index 0000000..51e1fb3
--- /dev/null
+++ b/sgx_types/src/macros.rs
@@ -0,0 +1,163 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+pub use core::clone::Clone;
+pub use core::marker::Copy;
+pub use core::default::Default;
+pub use core::ptr;
+pub use core::mem::transmute;
+
+macro_rules! cfg_if {
+    ($(
+        if #[cfg($($meta:meta),*)] { $($it:item)* }
+    ) else * else {
+        $($it2:item)*
+    }) => {
+        __cfg_if_items! {
+            () ;
+            $( ( ($($meta),*) ($($it)*) ), )*
+            ( () ($($it2)*) ),
+        }
+    }
+}
+
+macro_rules! __cfg_if_items {
+    (($($not:meta,)*) ; ) => {};
+    (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
+        __cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* }
+        __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* }
+    }
+}
+
+macro_rules! __cfg_if_apply {
+    ($m:meta, $($it:item)*) => {
+        $(#[$m] $it)*
+    }
+}
+
+macro_rules! __item {
+    ($i:item) => ($i)
+}
+
+
+macro_rules! impl_copy_clone{
+    ($($(#[$attr:meta])* pub struct $i:ident { $($field:tt)* })*) => ($(
+        __item! {
+            #[repr(C)]
+            $(#[$attr])*
+            pub struct $i { $($field)* }
+        }
+        impl Copy for $i {}
+        impl Clone for $i {
+            fn clone(&self) -> $i { *self }
+        }
+    )*)
+}
+
+#[macro_export]
+macro_rules! impl_struct {
+    ($($(#[$attr:meta])* pub struct $i:ident { $(pub $name:ident: $field:ty,)* })*) => ($(
+        __item! {
+            #[repr(C)]
+            $(#[$attr])*
+            pub struct $i { $(pub $name: $field,)* }
+        }
+        impl Copy for $i {}
+        impl Clone for $i {
+            fn clone(&self) -> $i { *self }
+        }
+        impl Default for $i {
+            fn default()->$i {
+                $i{$($name: Default::default(),)*}
+            }
+        }
+    )*)
+}
+
+macro_rules! impl_struct_default {
+	($($t:ty, $size:expr;)*) => {$(
+		impl Default for $t {
+			fn default() -> $t {
+				unsafe{::macros::transmute([0u8; $size])}
+			}
+		}
+	)*}
+}
+
+macro_rules! impl_struct_clone {
+	($($t:ty;)*) => {$(
+		impl Clone for $t {
+			fn clone(&self) -> $t {
+				unsafe{::macros::ptr::read(self)}
+			}
+		}
+	)*}
+}
+
+#[macro_export]
+macro_rules! impl_enum {
+	(
+        #[repr($repr:ident)]
+        #[derive($($derive:meta),*)]
+		pub enum $name:ident {
+            $key:ident = $val:expr,
+			$($keys:ident = $vals:expr,)*
+		}
+	) => (
+        #[repr(C)]
+        #[repr($repr)]
+		#[derive($($derive),*)]	
+		pub enum $name {
+            $key = $val,
+			$($keys = $vals,)*
+		}
+
+        impl Default for $name {
+			fn default() -> $name {
+				 $name::$key
+			}
+		}
+
+		impl $name {
+			pub fn from_repr(v: $repr) -> Option<Self> {
+				match v {
+                    $val => Some($name::$key),
+					$($vals => Some($name::$keys),)*
+					_ => None,
+				}
+			}
+
+            pub fn from_key(self) -> $repr {
+                match self {
+                    $name::$key => $val,
+                    $($name::$keys => $vals,)*
+                }
+            }
+		}
+	)
+}
diff --git a/sgx_types/src/oom.rs b/sgx_types/src/oom.rs
new file mode 100644
index 0000000..70e7b4c
--- /dev/null
+++ b/sgx_types/src/oom.rs
@@ -0,0 +1,72 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+#[cfg(not(feature = "use_std"))]
+use core::sync::atomic::{AtomicPtr, Ordering};
+#[cfg(not(feature = "use_std"))]
+use core::{mem, fmt};
+use super::function;
+
+#[cfg(not(feature = "use_std"))]
+static PANIC_HANDLER: AtomicPtr<()> = AtomicPtr::new(default_panic_handler as * mut ());
+
+#[cfg(not(feature = "use_std"))]
+fn default_panic_handler(msg: fmt::Arguments) {
+
+}
+
+#[cfg(not(feature = "use_std"))]
+pub fn set_panic_handler(handler: fn(fmt::Arguments)) {
+    PANIC_HANDLER.store(handler as * mut (), Ordering::SeqCst);
+}
+
+pub fn rsgx_abort() -> ! {
+    unsafe { function::abort() }
+}
+
+#[cfg(not(feature = "use_std"))]
+#[lang = "panic_fmt"] 
+#[no_mangle]
+pub extern fn rust_begin_panic(msg: fmt::Arguments, file: &'static str, line: u32) -> ! { 
+
+    let value = PANIC_HANDLER.load(Ordering::SeqCst);
+    let handler: fn(fmt::Arguments) = unsafe { mem::transmute(value) };
+    handler(msg);
+
+    rsgx_abort()
+}
+
+#[cfg(not(feature = "use_std"))]
+#[lang = "eh_personality"]
+#[no_mangle]
+pub extern fn rust_eh_personality() {}
+
+#[cfg(not(feature = "use_std"))]
+#[lang = "eh_unwind_resume"]
+#[no_mangle]
+pub extern fn rust_eh_unwind_resume() {}
\ No newline at end of file
diff --git a/sgx_types/src/types.rs b/sgx_types/src/types.rs
new file mode 100644
index 0000000..97696c6
--- /dev/null
+++ b/sgx_types/src/types.rs
@@ -0,0 +1,831 @@
+// Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * 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.
+//  * Neither the name of Baidu, Inc., nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// 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
+// OWNER 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.
+
+use error::*;
+
+//
+// sgx_attributes.h
+//
+
+
+pub type sgx_misc_select_t = ::uint32_t;
+
+// Enclave Flags Bit Masks 
+pub const SGX_FLAGS_INITTED: ::uint64_t         = 0x0000000000000001;    //If set, then the enclave is initialized 
+pub const SGX_FLAGS_DEBUG: ::uint64_t           = 0x0000000000000002;    //If set, then the enclave is debug
+pub const SGX_FLAGS_MODE64BIT: ::uint64_t       = 0x0000000000000004;    //If set, then the enclave is 64 bit
+pub const SGX_FLAGS_PROVISION_KEY: ::uint64_t   = 0x0000000000000010;    //If set, then the enclave has access to provision key
+pub const SGX_FLAGS_LICENSE_KEY: ::uint64_t     = 0x0000000000000020;    //If set, then the enclave has access to License key
+pub const SGX_FLAGS_RESERVED: ::uint64_t        = (!(SGX_FLAGS_INITTED 
+                                                | SGX_FLAGS_DEBUG 
+                                                | SGX_FLAGS_MODE64BIT 
+                                                | SGX_FLAGS_PROVISION_KEY 
+                                                | SGX_FLAGS_LICENSE_KEY));
+
+// XSAVE Feature Request Mask
+pub const SGX_XFRM_LEGACY: ::uint64_t           = 0x0000000000000003;  //Legacy XFRM
+pub const SGX_XFRM_AVX: ::uint64_t              = 0x0000000000000006;  // AVX
+pub const SGX_XFRM_AVX512: ::uint64_t           = 0x00000000000000E6;  // AVX-512 - not supported
+pub const SGX_XFRM_MPX: ::uint64_t              = 0x0000000000000018;  // MPX - not supported
+
+pub const SGX_XFRM_RESERVED: ::uint64_t         = (!(SGX_XFRM_LEGACY | SGX_XFRM_AVX));
+
+impl_struct! {
+    pub struct sgx_attributes_t {
+        pub flags: ::uint64_t,
+        pub xfrm: ::uint64_t,
+    }  
+
+    pub struct sgx_misc_attribute_t {
+        pub secs_attr: sgx_attributes_t,
+        pub misc_select: sgx_misc_select_t,
+    } 
+}
+
+//
+// sgx_dh.h
+//
+
+pub const SGX_DH_MAC_SIZE: ::size_t           = 16;
+pub const SGX_DH_SESSION_DATA_SIZE: ::size_t  = 200;
+
+impl_struct! {
+
+    #[repr(packed)]
+    pub struct sgx_dh_msg1_t {
+        pub g_a: sgx_ec256_public_t, 
+        pub target: sgx_target_info_t,
+    } 
+}
+
+impl_copy_clone! {
+
+    #[repr(packed)]
+    pub struct sgx_dh_msg2_t {
+        pub g_b: sgx_ec256_public_t,
+        pub report: sgx_report_t,
+        pub cmac: [::uint8_t; SGX_DH_MAC_SIZE],
+    }
+
+    #[repr(packed)]
+    pub struct sgx_dh_msg3_body_t {
+        pub report: sgx_report_t,
+        pub additional_prop_length: ::uint32_t,
+        pub additional_prop: [::uint8_t; 0],
+    }
+
+    #[repr(packed)]
+    pub struct sgx_dh_msg3_t {
+        pub cmac: [::uint8_t; SGX_DH_MAC_SIZE],
+        pub msg3_body: sgx_dh_msg3_body_t,
+    }
+
+    #[repr(packed)]
+    pub struct sgx_dh_session_enclave_identity_t {
+        pub cpu_svn: sgx_cpu_svn_t,
+        pub misc_select: ::sgx_misc_select_t,
+        pub reserved_1: [::uint8_t; 28],
+        pub attributes: sgx_attributes_t,
+        pub mr_enclave: sgx_measurement_t,
+        pub reserved_2: [::uint8_t; 32],
+        pub mr_signer: sgx_measurement_t,
+        pub reserved_3: [::uint8_t; 96], 
+        pub isv_prod_id: ::sgx_prod_id_t,
+        pub isv_svn: ::sgx_isv_svn_t,
+    }
+
+    #[repr(packed)]
+    pub struct sgx_dh_session_t {
+        pub sgx_dh_session: [::uint8_t; SGX_DH_SESSION_DATA_SIZE],
+    }
+}
+
+impl_struct_default! {
+    sgx_dh_msg2_t, 512;
+    sgx_dh_msg3_body_t, 436;
+    sgx_dh_msg3_t, 452;
+    sgx_dh_session_enclave_identity_t, 260;
+    sgx_dh_session_t, 200;
+}
+
+
+impl_enum! {
+
+    #[repr(u32)]
+    #[derive(Copy, Clone, PartialEq, Eq)]
+    pub enum sgx_dh_session_role_t {
+        SGX_DH_SESSION_INITIATOR = 0,
+        SGX_DH_SESSION_RESPONDER = 1,
+    }
+}
+
+//
+// sgx_ecp_types.h
+//
+
+
+pub const SGX_FEBITSIZE: ::uint32_t = 256;
+
+impl_struct!{
+
+    #[repr(packed)]
+    pub struct ecc_param_t {
+        pub eccP: [::uint32_t; SGX_NISTP_ECP256_KEY_SIZE],      /* EC prime field */
+        pub eccA: [::uint32_t; SGX_NISTP_ECP256_KEY_SIZE],      /* EC curve coefficient A */
+        pub eccB: [::uint32_t; SGX_NISTP_ECP256_KEY_SIZE],      /* EC curve coefficient B */
+        pub eccG: [[::uint32_t; SGX_NISTP_ECP256_KEY_SIZE]; 2], /* ECC base point */
+        pub eccR: [::uint32_t; SGX_NISTP_ECP256_KEY_SIZE],      /* ECC base point order */
+    }
+}
+
+pub type sgx_ec_key_128bit_t = [::uint8_t; SGX_CMAC_KEY_SIZE];
+
+//
+// sgx_eid.h
+//
+
+
+pub type sgx_enclave_id_t = ::uint64_t;
+
+//
+// sgx_key.h
+//
+
+
+// Key Name
+pub const SGX_KEYSELECT_LICENSE: ::uint16_t          = 0x0000;
+pub const SGX_KEYSELECT_PROVISION: ::uint16_t        = 0x0001;
+pub const SGX_KEYSELECT_PROVISION_SEAL: ::uint16_t   = 0x0002;
+pub const SGX_KEYSELECT_REPORT: ::uint16_t           = 0x0003;
+pub const SGX_KEYSELECT_SEAL: ::uint16_t             = 0x0004;
+
+// Key Policy
+pub const SGX_KEYPOLICY_MRENCLAVE: ::uint16_t        = 0x0001;      /* Derive key using the enclave's ENCLAVE measurement register */
+pub const SGX_KEYPOLICY_MRSIGNER: ::uint16_t         = 0x0002;      /* Derive key using the enclave's SINGER measurement register */
+
+pub const SGX_KEYID_SIZE: ::size_t                    = 32;
+pub const SGX_CPUSVN_SIZE: ::size_t                   = 16;
+pub const SGX_KEY_REQUEST_RESERVED2_BYTES: ::size_t   = 436;
+
+pub type sgx_key_128bit_t = [::uint8_t; 16];
+pub type sgx_isv_svn_t = ::uint16_t;
+
+impl_struct! {
+
+    pub struct sgx_cpu_svn_t {
+        pub svn: [::uint8_t; SGX_CPUSVN_SIZE],
+    }
+
+    pub struct sgx_key_id_t {
+        pub id: [::uint8_t; SGX_KEYID_SIZE],
+    }
+}
+
+impl_copy_clone! {
+
+    pub struct sgx_key_request_t {
+        pub key_name: ::uint16_t,
+        pub key_policy: ::uint16_t,
+        pub isv_svn: sgx_isv_svn_t,
+        pub reserved1: ::uint16_t,
+        pub cpu_svn: sgx_cpu_svn_t,
+        pub attribute_mask: sgx_attributes_t,
+        pub key_id: sgx_key_id_t,
+        pub misc_mask: sgx_misc_select_t,
+        pub reserved2: [::uint8_t; SGX_KEY_REQUEST_RESERVED2_BYTES],
+    }
+}
+
+impl_struct_default! {
+    sgx_key_request_t, 512;
+}
+
+//
+// sgx_key_exchange.h
+//
+
+
+pub type sgx_ra_context_t = ::uint32_t;
+pub type sgx_ra_key_128_t = sgx_key_128bit_t;
+
+impl_enum! {
+
+    #[repr(u32)]
+    #[derive(Copy, Clone, PartialEq, Eq)]
+    pub enum sgx_ra_key_type_t {
+        SGX_RA_KEY_SK = 1,
+        SGX_RA_KEY_MK = 2,
+        SGX_RA_KEY_VK = 3,
+    }
+}
+
+impl_struct! {
+
+    pub struct sgx_ra_msg1_t {
+        pub g_a: sgx_ec256_public_t,
+        pub gid: sgx_epid_group_id_t,
+    }
+
+    pub struct sgx_ra_msg2_t {
+        pub g_b: sgx_ec256_public_t,
+        pub spid: sgx_spid_t,
+        pub quote_type: ::uint16_t,
+        pub kdf_id: ::uint16_t,
+        pub sign_gb_ga: sgx_ec256_signature_t,
+        pub mac: sgx_mac_t,
+        pub sig_rl_size: ::uint32_t,
+        pub sig_rl: [::uint8_t; 0],
+    }
+}
+
+impl_copy_clone! {
+
+    pub struct sgx_ra_msg3_t {
+        pub mac: sgx_mac_t,
+        pub g_a: sgx_ec256_public_t,
+        pub ps_sec_prop: sgx_ps_sec_prop_desc_t,
+        pub quote: [::uint8_t; 0],
+    }
+}
+
+impl_struct_default! {
+    sgx_ra_msg3_t, 336;
+}
+
+//
+// sgx_quote.h
+//
+
+
+pub type sgx_epid_group_id_t = [::uint8_t; 4];
+pub const SGX_PLATFORM_INFO_SIZE: ::size_t = 101;
+
+impl_struct! {
+
+    #[repr(packed)]
+    pub struct sgx_spid_t {
+        pub id: [::uint8_t ; 16],
+    }
+
+    #[repr(packed)]
+    pub struct sgx_basename_t {
+        pub name: [::uint8_t ; 32],
+    }
+
+    #[repr(packed)]
+    pub struct sgx_quote_nonce_t {
+        pub rand: [::uint8_t ; 16],
+    }
+
+    #[repr(packed)]
+    pub struct sgx_update_info_bit_t {
+        pub ucodeUpdate: ::int32_t,
+        pub csmeFwUpdate: ::int32_t,
+        pub pswUpdate: ::int32_t,
+    }
+}
+
+impl_enum! {
+
+    #[repr(u32)]
+    #[derive(Copy, Clone, PartialEq, Eq)]
+    pub enum sgx_quote_sign_type_t {
+        SGX_UNLINKABLE_SIGNATURE    = 0,
+        SGX_LINKABLE_SIGNATURE      = 1,
+    }
+}
+
+impl_copy_clone! {
+
+    #[repr(packed)]
+    pub struct sgx_quote_t {
+        pub version: ::uint16_t,                    /* 0   */
+        pub sign_type: ::uint16_t,                  /* 2   */
+        pub epid_group_id: sgx_epid_group_id_t,     /* 4   */
+        pub qe_svn: sgx_isv_svn_t,                  /* 8   */
+        pub pce_svn: sgx_isv_svn_t,                 /* 10  */
+        pub xeid: ::uint32_t,                       /* 12  */
+        pub basename: sgx_basename_t,               /* 16  */
+        pub report_body: sgx_report_body_t,         /* 48  */
+        pub signature_len: ::uint32_t,              /* 432 */
+        pub signature: [::uint8_t; 0],              /* 436 */
+    }
+
+    #[repr(packed)]
+    pub struct sgx_platform_info_t {
+        pub platform_info: [::uint8_t; SGX_PLATFORM_INFO_SIZE],
+    }
+}
+
+impl_struct_default! {
+    sgx_quote_t, 436;
+    sgx_platform_info_t, 101;
+}
+
+//
+// sgx_report.h
+//
+
+
+pub const SGX_HASH_SIZE: ::size_t   = 32;
+pub const SGX_MAC_SIZE: ::size_t    = 16;
+
+pub const SGX_REPORT_DATA_SIZE: ::size_t   = 64;
+
+impl_struct! {
+
+    pub struct sgx_measurement_t {
+        pub m: [::uint8_t; SGX_HASH_SIZE],
+    }
+}
+
+pub type sgx_mac_t = [::uint8_t; SGX_MAC_SIZE];
+
+impl_copy_clone! {
+    
+    pub struct sgx_report_data_t {
+        pub d: [::uint8_t; SGX_REPORT_DATA_SIZE],
+    }
+}
+
+impl_struct_default! {
+    sgx_report_data_t, 64;
+}
+
+pub type sgx_prod_id_t = ::uint16_t;
+
+pub const SGX_TARGET_INFO_RESERVED1_BYTES: ::size_t = 4;
+pub const SGX_TARGET_INFO_RESERVED2_BYTES: ::size_t = 456;
+
+impl_copy_clone! {
+
+    pub struct sgx_target_info_t {
+        pub mr_enclave: sgx_measurement_t,
+        pub attributes: sgx_attributes_t,
+        pub reserved1: [::uint8_t; SGX_TARGET_INFO_RESERVED1_BYTES],
+        pub misc_select: sgx_misc_select_t,
+        pub reserved2: [::uint8_t; SGX_TARGET_INFO_RESERVED2_BYTES],
+    }
+
+    pub struct sgx_report_body_t {
+        pub cpu_svn: sgx_cpu_svn_t,
+        pub misc_select: sgx_misc_select_t,
+        pub reserved1: [::uint8_t; 28],
+        pub attributes: sgx_attributes_t,
+        pub mr_enclave: sgx_measurement_t,
+        pub reserved2: [::uint8_t; 32],
+        pub mr_signer: sgx_measurement_t,
+        pub reserved3: [::uint8_t; 96],
+        pub isv_prod_id: sgx_prod_id_t,
+        pub isv_svn: sgx_isv_svn_t,
+        pub reserved4: [::uint8_t; 60],
+        pub report_data: sgx_report_data_t,
+    }
+
+    pub struct sgx_report_t {
+        pub body: sgx_report_body_t,
+        pub key_id: sgx_key_id_t,
+        pub mac: sgx_mac_t,
+    }
+}
+
+impl_struct_default! {
+    sgx_target_info_t, 512;
+    sgx_report_body_t, 384;
+    sgx_report_t, 432;
+}
+
+//
+// sgx_spinlock.h
+//
+
+// typedef volatile uint32_t sgx_spinlock_t;
+pub type sgx_spinlock_t = ::uint32_t;
+
+pub const SGX_SPINLOCK_INITIALIZER: ::uint32_t    = 0;
+
+//
+// sgx_tae_service.h
+//
+
+pub type sgx_time_t = ::uint64_t;
+
+pub type sgx_time_source_nonce_t = [::uint8_t; 32];
+
+pub const SGX_MC_UUID_COUNTER_ID_SIZE: ::size_t    = 3;
+pub const SGX_MC_UUID_NONCE_SIZE: ::size_t         = 13;
+
+impl_struct! {
+
+    #[repr(packed)]
+    pub struct sgx_mc_uuid_t {
+        pub counter_id: [::uint8_t; SGX_MC_UUID_COUNTER_ID_SIZE],
+        pub nonce: [::uint8_t; SGX_MC_UUID_NONCE_SIZE],
+    }
+}
+
+impl_copy_clone! {
+
+    #[repr(packed)]
+    pub struct sgx_ps_sec_prop_desc_t {
+        pub sgx_ps_sec_prop_desc: [::uint8_t; 256],
+    }
+}
+
+impl_struct_default! {
+    sgx_ps_sec_prop_desc_t, 256;
+}
+
+pub const SGX_MC_POLICY_SIGNER: ::uint16_t   = 0x01;
+pub const SGX_MC_POLICY_ENCLAVE: ::uint16_t  = 0x02;
+
+//
+// sgx_tcrypto.h
+//
+
+
+pub const SGX_SHA256_HASH_SIZE: ::size_t       = 32;
+pub const SGX_ECP256_KEY_SIZE: ::size_t        = 32;
+pub const SGX_NISTP_ECP256_KEY_SIZE: ::size_t  = (SGX_ECP256_KEY_SIZE / 4);
+pub const SGX_AESGCM_IV_SIZE: ::size_t         = 12;
+pub const SGX_AESGCM_KEY_SIZE: ::size_t        = 16;
+pub const SGX_AESGCM_MAC_SIZE: ::size_t        = 16;
+pub const SGX_CMAC_KEY_SIZE: ::size_t          = 16;
+pub const SGX_CMAC_MAC_SIZE: ::size_t          = 16;
+pub const SGX_AESCTR_KEY_SIZE: ::size_t        = 16;
+
+impl_struct! {
+
+    pub struct sgx_ec256_dh_shared_t {
+        pub s: [::uint8_t; SGX_ECP256_KEY_SIZE],
+    }
+
+    pub struct sgx_ec256_private_t {
+        pub r: [::uint8_t; SGX_ECP256_KEY_SIZE],
+    }
+
+    pub struct sgx_ec256_public_t {
+        pub gx: [::uint8_t; SGX_ECP256_KEY_SIZE],
+        pub gy: [::uint8_t; SGX_ECP256_KEY_SIZE],
+    }
+
+    pub struct sgx_ec256_signature_t {
+        pub x: [::uint32_t; SGX_NISTP_ECP256_KEY_SIZE],
+        pub y: [::uint32_t; SGX_NISTP_ECP256_KEY_SIZE],
+    }
+}
+
+pub type sgx_sha_state_handle_t     = * mut ::c_void;
+pub type sgx_cmac_state_handle_t    = * mut ::c_void;
+pub type sgx_ecc_state_handle_t     = * mut ::c_void;
+
+pub type sgx_sha256_hash_t = [::uint8_t; SGX_SHA256_HASH_SIZE];
+
+pub type sgx_aes_gcm_128bit_key_t   = [::uint8_t; SGX_AESGCM_KEY_SIZE];
+pub type sgx_aes_gcm_128bit_tag_t   = [::uint8_t; SGX_AESGCM_MAC_SIZE];
+pub type sgx_cmac_128bit_key_t      = [::uint8_t; SGX_CMAC_KEY_SIZE];
+pub type sgx_cmac_128bit_tag_t      = [::uint8_t; SGX_CMAC_MAC_SIZE];
+pub type sgx_aes_ctr_128bit_key_t   = [::uint8_t; SGX_AESCTR_KEY_SIZE];
+
+impl_enum! {
+    #[repr(u32)]
+    #[derive(Copy, Clone, PartialEq, Eq)]
+    pub enum sgx_generic_ecresult_t {
+        SGX_EC_VALID                = 0x00000000,   /* validation pass successfully     */
+
+        SGX_EC_COMPOSITE_BASE       = 0x00000001,   /* field based on composite         */
+        SGX_EC_COMPLICATED_BASE     = 0x00000002,   /* number of non-zero terms in the polynomial (> PRIME_ARR_MAX) */
+        SGX_EC_IS_ZERO_DISCRIMINANT = 0x00000003,   /* zero discriminant */
+        SGX_EC_COMPOSITE_ORDER      = 0x00000004,   /* composite order of base point    */
+        SGX_EC_INVALID_ORDER        = 0x00000005,   /* invalid base point order         */
+        SGX_EC_IS_WEAK_MOV          = 0x00000006,   /* weak Meneze-Okamoto-Vanstone  reduction attack */
+        SGX_EC_IS_WEAK_SSA          = 0x00000007,   /* weak Semaev-Smart,Satoh-Araki reduction attack */
+        SGX_EC_IS_SUPER_SINGULAR    = 0x00000008,   /* supersingular curve */
+
+        SGX_EC_INVALID_PRIVATE_KEY  = 0x00000009,   /* !(0 < Private < order) */
+        SGX_EC_INVALID_PUBLIC_KEY   = 0x0000000a,   /* (order*PublicKey != Infinity)    */
+        SGX_EC_INVALID_KEY_PAIR     = 0x0000000b,   /* (Private*BasePoint != PublicKey) */
+
+        SGX_EC_POINT_OUT_OF_GROUP   = 0x0000000c,   /* out of group (order*P != Infinity)  */
+        SGX_EC_POINT_IS_AT_INFINITY = 0x0000000d,   /* point (P=(Px,Py)) at Infinity  */
+        SGX_EC_POINT_IS_NOT_VALID   = 0x0000000e,   /* point (P=(Px,Py)) out-of EC    */
+
+        SGX_EC_POINT_IS_EQUAL       = 0x0000000f,   /* compared points are equal     */
+        SGX_EC_POINT_IS_NOT_EQUAL   = 0x00000010,   /* compared points are different  */
+
+        SGX_EC_INVALID_SIGNATURE    = 0x00000011,   /* invalid signature */
+    }
+}
+
+//
+// sgx_thread.h
+//
+
+
+pub type sgx_thread_t = ::uintptr_t;
+
+cfg_if! {
+    if #[cfg(target_arch = "x86")] {
+        pub const SE_WORDSIZE: ::size_t = 4;
+    } else {
+        pub const SE_WORDSIZE: ::size_t = 8;
+    }
+}
+
+pub const THREAD_SELF_ADDR:         ::size_t = 0;
+pub const THREAD_LAST_SP_ADDR:      ::size_t = (SE_WORDSIZE * 1);
+pub const THREAD_STACK_BASE_ADDR:   ::size_t = (SE_WORDSIZE * 2);
+pub const THREAD_STACK_LIMIT_ADDR:  ::size_t = (SE_WORDSIZE * 3);
+pub const THREAD_STACK_SSA_GPR:     ::size_t = (SE_WORDSIZE * 4);
+
+pub struct sgx_thread_queue_t {
+    pub m_first: sgx_thread_t,
+    pub m_last: sgx_thread_t,
+}
+
+pub struct sgx_thread_mutex_t {
+    pub m_refcount: ::size_t,
+    pub m_control: ::uint32_t,
+    pub m_lock: ::uint32_t,
+    pub m_owner: sgx_thread_t,
+    pub m_queue: sgx_thread_queue_t,
+}
+
+pub const SGX_THREAD_T_NULL: sgx_thread_t   = 0 ;
+
+pub const SGX_THREAD_MUTEX_NONRECURSIVE: ::uint32_t = 0x01;
+pub const SGX_THREAD_MUTEX_RECURSIVE: ::uint32_t    = 0x02;
+
+pub const SGX_THREAD_NONRECURSIVE_MUTEX_INITIALIZER: sgx_thread_mutex_t = sgx_thread_mutex_t {
+    m_refcount: 0,
+    m_control: SGX_THREAD_MUTEX_NONRECURSIVE,
+    m_lock: 0,
+    m_owner: SGX_THREAD_T_NULL,
+    m_queue: sgx_thread_queue_t {
+        m_first: SGX_THREAD_T_NULL,
+        m_last: SGX_THREAD_T_NULL
+        }
+    };
+
+pub const SGX_THREAD_RECURSIVE_MUTEX_INITIALIZER: sgx_thread_mutex_t = sgx_thread_mutex_t {
+    m_refcount: 0,
+    m_control: SGX_THREAD_MUTEX_RECURSIVE,
+    m_lock: 0,
+    m_owner: SGX_THREAD_T_NULL,
+    m_queue: sgx_thread_queue_t {
+        m_first: SGX_THREAD_T_NULL,
+        m_last: SGX_THREAD_T_NULL
+        }
+    };
+
+pub const SGX_THREAD_MUTEX_INITIALIZER: sgx_thread_mutex_t = SGX_THREAD_NONRECURSIVE_MUTEX_INITIALIZER;
+
+impl_struct! {
+
+    pub struct sgx_thread_mutexattr_t {
+        pub m_dummy: ::c_uchar,
+    }
+
+    pub struct sgx_thread_condattr_t {
+        pub m_dummy: ::c_uchar,
+    }
+}
+
+pub struct sgx_thread_cond_t {
+    pub m_lock: ::uint32_t,
+    pub m_queue: sgx_thread_queue_t,
+}
+
+pub const SGX_THREAD_COND_INITIALIZER: sgx_thread_cond_t = sgx_thread_cond_t {
+    m_lock: 0,
+    m_queue: sgx_thread_queue_t {
+        m_first: SGX_THREAD_T_NULL,
+        m_last: SGX_THREAD_T_NULL
+    }
+};
+
+//
+// sgx_tkey_exchange.h
+//
+
+
+pub type sgx_ra_derive_secret_keys_t = extern "C" fn(p_shared_key: * const sgx_ec256_dh_shared_t,
+                                                     kdf_id: ::uint16_t,
+                                                     p_smk_key: * mut sgx_ec_key_128bit_t,
+                                                     p_sk_key: * mut sgx_ec_key_128bit_t,
+                                                     p_mk_key: * mut sgx_ec_key_128bit_t,
+                                                     p_vk_key: * mut sgx_ec_key_128bit_t) -> sgx_status_t;
+
+//
+// sgx_trts_exception.h
+//
+
+pub const EXCEPTION_CONTINUE_SEARCH: ::uint32_t      = 0;
+pub const EXCEPTION_CONTINUE_EXECUTION: ::uint32_t   = 0xFFFFFFFF;
+
+impl_enum! {
+    
+    #[repr(u32)]
+    #[derive(Copy, Clone, PartialEq, Eq)]
+    pub enum sgx_exception_vector_t {
+        SGX_EXCEPTION_VECTOR_DE = 0,  /* DIV and DIV instructions */
+        SGX_EXCEPTION_VECTOR_DB = 1,  /* For Intel use only */
+        SGX_EXCEPTION_VECTOR_BP = 3,  /* INT 3 instruction */
+        SGX_EXCEPTION_VECTOR_BR = 5,  /* BOUND instruction */
+        SGX_EXCEPTION_VECTOR_UD = 6,  /* UD2 instruction or reserved opcode */
+        SGX_EXCEPTION_VECTOR_MF = 16, /* x87 FPU floating-point or WAIT/FWAIT instruction */
+        SGX_EXCEPTION_VECTOR_AC = 17, /* Any data reference in memory */
+        SGX_EXCEPTION_VECTOR_XM = 19, /* SSE/SSE2/SSE3 floating-point instruction */
+    }
+}
+
+impl_enum!{
+    
+    #[repr(u32)]
+    #[derive(Copy, Clone, PartialEq, Eq)]
+    pub enum sgx_exception_type_t {
+        SGX_EXCEPTION_HARDWARE = 3,
+        SGX_EXCEPTION_SOFTWARE = 6,
+    }
+}
+
+
+cfg_if! {
+    if #[cfg(target_arch = "x86")] {
+        impl_struct! {
+
+            pub struct sgx_cpu_context_t {
+                pub eax: ::uint32_t,
+                pub ecx: ::uint32_t,
+                pub edx: ::uint32_t,
+                pub ebx: ::uint32_t,
+                pub esp: ::uint32_t,
+                pub ebp: ::uint32_t,
+                pub esi: ::uint32_t,
+                pub edi: ::uint32_t,
+                pub eflags: ::uint32_t,
+                pub eip: ::uint32_t,
+            }
+        }
+    } else {
+        impl_struct! {
+
+            pub struct sgx_cpu_context_t {
+                pub rax: ::uint64_t,
+                pub rcx: ::uint64_t,
+                pub rdx: ::uint64_t,
+                pub rbx: ::uint64_t,
+                pub rsp: ::uint64_t,
+                pub rbp: ::uint64_t,
+                pub rsi: ::uint64_t,
+                pub rdi: ::uint64_t,
+                pub r8: ::uint64_t,
+                pub r9: ::uint64_t,
+                pub r10: ::uint64_t,
+                pub r11: ::uint64_t,
+                pub r12: ::uint64_t,
+                pub r13: ::uint64_t,
+                pub r14: ::uint64_t,
+                pub r15: ::uint64_t,
+                pub rflags: ::uint64_t,
+                pub rip: ::uint64_t,
+            }
+        }
+    }
+}
+
+impl_struct! {
+
+    pub struct sgx_exception_info_t {
+        pub cpu_context: sgx_cpu_context_t,
+        pub exception_vector: sgx_exception_vector_t,
+        pub exception_type: sgx_exception_type_t,
+    }
+}
+
+pub type sgx_exception_handler_t = extern "C" fn(info: * mut sgx_exception_info_t) -> ::uint32_t;
+
+//
+// sgx_tseal.h
+//
+
+pub const SGX_SEAL_TAG_SIZE: ::size_t  = SGX_AESGCM_MAC_SIZE;
+pub const SGX_SEAL_IV_SIZE: ::size_t   = 12;
+
+impl_struct! {
+
+    pub struct sgx_aes_gcm_data_t {
+        pub payload_size: ::uint32_t,
+        pub reserved: [::uint8_t; 12],
+        pub payload_tag: [::uint8_t; SGX_SEAL_TAG_SIZE],
+        pub payload: [::uint8_t; 0],
+    }
+
+    pub struct sgx_sealed_data_t {
+        pub key_request: sgx_key_request_t,
+        pub plain_text_offset: ::uint32_t,
+        pub reserved: [::uint8_t; 12],
+        pub aes_data: sgx_aes_gcm_data_t,
+    }
+}
+
+//
+// sgx_uae_service.h
+//
+
+
+pub const PS_CAP_TRUSTED_TIME: ::size_t        = 0x1;
+pub const PS_CAP_MONOTONIC_COUNTER: ::size_t   = 0x2;
+
+impl_struct! {
+
+    pub struct sgx_ps_cap_t {
+        pub ps_cap0: ::uint32_t,
+        pub ps_cap1: ::uint32_t,
+    }
+}
+
+//
+// sgx_ukey_exchange.h
+//
+
+
+pub type sgx_ecall_get_ga_trusted_t = fn(eid: sgx_enclave_id_t,
+                                         retval: * mut sgx_status_t,
+                                         context: sgx_ra_context_t,
+                                         g_a: * mut sgx_ec256_public_t) -> sgx_status_t;
+
+pub type sgx_ecall_proc_msg2_trusted_t = fn(eid: sgx_enclave_id_t,
+                                            retval: * mut sgx_status_t,
+                                            context: sgx_ra_context_t,
+                                            p_msg2: * const sgx_ra_msg2_t,
+                                            p_qe_target: * const sgx_target_info_t,
+                                            p_report: * mut sgx_report_t,
+                                            nonce: * mut sgx_quote_nonce_t) -> sgx_status_t;
+
+pub type sgx_ecall_get_msg3_trusted_t = fn(eid: sgx_enclave_id_t,
+                                           retval: * mut sgx_status_t,
+                                           context: sgx_ra_context_t,
+                                           quote_size: ::uint32_t,
+                                           qe_report: * mut sgx_report_t,
+                                           p_msg3: * mut sgx_ra_msg3_t,
+                                           msg3_size: ::uint32_t) -> sgx_status_t;
+
+//
+// sgx_urts.h
+//
+
+
+pub type sgx_launch_token_t = [::uint8_t; 1024];
+
+
+
+//
+// trts.pic.h
+//
+pub const ENCLAVE_INIT_NOT_STARTED: u32 = 0;
+pub const ENCLAVE_INIT_IN_PROGRESS: u32 = 1;
+pub const ENCLAVE_INIT_DONE: u32        = 2;
+pub const ENCLAVE_CRASHED: u32          = 3;
+
+//
+// sgx_cpuid.h
+//
+pub type sgx_cpuinfo_t = [::int32_t; 4];
+
+//
+//
+//
+//
+//cfg_if! {
+//    if #[cfg(any(not(feature = "NDEBUG"), feature = "EDEBUG"))] {
+//        pub const SGX_DEBUG_FLAG: ::int32_t   = 1;
+//    } else {
+//        pub const SGX_DEBUG_FLAG: ::int32_t   = 0;
+//    }
+//}
\ No newline at end of file