blob: 034b028ce5a52a810b971fafa83a12982d2cb2e0 [file] [log] [blame]
Joakim Bech8e5c5b32018-10-25 08:18:32 +02001.. _cryptographic_implementation:
2
3############################
4Cryptographic implementation
5############################
6This document describes how the TEE Cryptographic Operations API is implemented,
7how the default crypto provider may be configured at compile time, and how it
8may be replaced by another implementation.
9
10Overview
11********
12There are several layers from the Trusted Application to the actual crypto
13algorithms. Most of the crypto code runs in kernel mode inside the TEE core.
14Here is a schematic view of a typical call to the crypto API. The numbers in
15square brackets ([1], [2]...) refer to the sections below.
16
17.. code-block:: none
18
19 - some_function() (Trusted App) -
20 [1] TEE_*() User space (libutee.a)
21 ------- utee_*() ----------------------------------------------
22 [2] tee_svc_*() Kernel space
23 [3] crypto_*() (libtomcrypt.a and crypto.c)
24 [4] /* LibTomCrypt */ (libtomcrypt.a)
25
26[1] The TEE Cryptographic Operations API
27****************************************
28OP-TEE implements the Cryptographic Operations API defined by the GlobalPlatform
29association in the :ref:`tee_internal_core_api`. This includes cryptographic
30functions that span various cryptographic needs: message digests, symmetric
31ciphers, message authentication codes (MAC), authenticated encryption,
32asymmetric operations (encryption/decryption or signing/verifying), key
33derivation, and random data generation. These functions make up the TEE
34Cryptographic Operations API.
35
36The Internal API is implemented in tee_api_operations.c_, which is compiled into
37a static library: ``${O}/ta_arm{32,64}-lib/libutee/libutee.a``.
38
39Most API functions perform some parameter checking and manipulations, then
40invoke some *utee\_\** function to switch to kernel mode and perform the
41low-level work.
42
43The *utee\_\** functions are declared in utee_syscalls.h_ and implemented in
44utee_syscalls_asm.S_ They are simple system call wrappers which use the *SVC*
45instruction to switch to the appropriate system service in the OP-TEE kernel.
46
47[2] The crypto services
48***********************
49All cryptography-related system calls are declared in tee_svc_cryp.h_ and
50implemented in tee_svc_cryp.c_. In addition to dealing with the usual work
51required at the user/kernel interface (checking parameters and copying memory
52buffers between user and kernel space), the system calls invoke a private
53abstraction layer: the **Crypto API**, which is declared in crypto.h_. It serves
54two main purposes:
55
56 1. Allow for alternative implementations, such as hardware-accelerated
57 versions.
58
59 2. Provide an easy way to disable some families of algorithms at
60 compile-time to save space. See `LibTomCrypt` below.
61
62[3] crypto_*()
63**************
64The ``crypto_*()`` functions implement the actual algorithms and helper
65functions. TEE Core has one global active implementation of this interface. The
66default implementation, mostly based on LibTomCrypt_, is as follows:
67
68.. code-block:: c
69 :caption: File: core/crypto/crypto.c
70
71 /*
72 * Default implementation for all functions in crypto.h
73 */
74
75 #if !defined(_CFG_CRYPTO_WITH_HASH)
76 TEE_Result crypto_hash_get_ctx_size(uint32_t algo __unused,
77 size_t *size __unused)
78 {
79 return TEE_ERROR_NOT_IMPLEMENTED;
80 }
81 ...
82 #endif /*_CFG_CRYPTO_WITH_HASH*/
83
84.. code-block:: c
85 :caption: File: core/lib/libtomcrypt/tee_ltc_provider.c
86
87 #if defined(_CFG_CRYPTO_WITH_HASH)
88 TEE_Result crypto_hash_get_ctx_size(uint32_t algo, size_t *size)
89 {
90 /* ... */
91 return TEE_SUCCESS;
92 }
93
94 #endif /*_CFG_CRYPTO_WITH_HASH*/
95
96As shown above, families of algorithms can be disabled and crypto.c_ will
97provide default null implementations that will return
98``TEE_ERROR_NOT_IMPLEMENTED``.
99
100Public/private key format
101*************************
102crypto.h_ uses implementation-specific types to hold key data for asymmetric
103algorithms. For instance, here is how a public RSA key is represented:
104
105.. code-block:: c
106 :caption: File: core/include/crypto/crypto.h
107
108 struct rsa_public_key {
109 struct bignum *e; /* Public exponent */
110 struct bignum *n; /* Modulus */
111 };
112
113This is also how such keys are stored inside the TEE object attributes
114(``TEE_ATTR_RSA_PUBLIC_KEY`` in this case). ``struct bignum`` is an opaque type,
115known to the underlying implementation only. ``struct bignum_ops`` provides
116functions so that the system services can manipulate data of this type. This
117includes allocation/deallocation, copy, and conversion to or from the big endian
118binary format.
119
120.. code-block:: c
121 :caption: File: core/include/crypto/crypto.h
122
123 struct bignum *crypto_bignum_allocate(size_t size_bits);
124
125 TEE_Result crypto_bignum_bin2bn(const uint8_t *from, size_t fromsize,
126 struct bignum *to);
127
128 void crypto_bignum_bn2bin(const struct bignum *from, uint8_t *to);
129 /*...*/
130
131
132[4] LibTomCrypt
133***************
134Some algorithms may be disabled at compile time if they are not needed, in order
135to reduce the size of the OP-TEE image and reduces its memory usage. This is
136done by setting the appropriate configuration variable. For example:
137
138.. code-block:: bash
139
140 $ make CFG_CRYPTO_AES=n # disable AES only
141 $ make CFG_CRYPTO_{AES,DES}=n # disable symmetric ciphers
142 $ make CFG_CRYPTO_{DSA,RSA,DH,ECC}=n # disable public key algorithms
143 $ make CFG_CRYPTO=n # disable all algorithms
144
145Please refer to `core/lib/libtomcrypt/sub.mk`_ for the list of all supported
146variables.
147
148Note that the application interface is **not** modified when algorithms are
149disabled. This means, for instance, that the functions ``TEE_CipherInit()``,
150``TEE_CipherUpdate()`` and ``TEE_CipherFinal()`` would remain present in
151``libutee.a`` even if all symmetric ciphers are disabled (they would simply
152return ``TEE_ERROR_NOT_IMPLEMENTED``).
153
154Add a new crypto implementation
155*******************************
156To add a new implementation, the default one in `core/lib/libtomcrypt`_ in
157combination with what is in `core/crypto`_ should be used as a reference. Here
158are the main things to consider when adding a new crypto provider:
159
160 - Put all the new code in its own directory under ``core/lib`` unless it is
161 code that will be used regardless of which crypto provider is in use. How
162 we are dealing with AES-GCM in `core/crypto`_ could serve as an example.
163
164 - Avoid modifying tee_svc_cryp.c_. It should not be needed.
165
166 - Although not all crypto families need to be defined, all are required for
167 compliance to the GlobalPlatform specification.
168
169 - If you intend to make some algorithms optional, please try to re-use the
170 same names for configuration variables as the default implementation.
171
172.. Source files
173.. _core/crypto: https://github.com/OP-TEE/optee_os/blob/master/core/crypto
174.. _crypto.c: https://github.com/OP-TEE/optee_os/blob/master/core/crypto/crypto.c
175.. _crypto.h: https://github.com/OP-TEE/optee_os/blob/master/core/include/crypto/crypto.h
176.. _core/lib/libtomcrypt: https://github.com/OP-TEE/optee_os/blob/master/core/lib/libtomcrypt
177.. _core/lib/libtomcrypt/sub.mk: https://github.com/OP-TEE/optee_os/blob/master/core/lib/libtomcrypt/sub.mk
178.. _tee_api_operations.c: https://github.com/OP-TEE/optee_os/blob/master/lib/libutee/tee_api_operations.c
179.. _tee_svc_cryp.c: https://github.com/OP-TEE/optee_os/blob/master/core/tee/tee_svc_cryp.c
180.. _tee_svc_cryp.h: https://github.com/OP-TEE/optee_os/blob/master/core/include/tee/tee_svc_cryp.h
181.. _utee_syscalls.h: https://github.com/OP-TEE/optee_os/blob/master/lib/libutee/include/utee_syscalls.h
182.. _utee_syscalls_asm.S: https://github.com/OP-TEE/optee_os/blob/master/lib/libutee/arch/arm/utee_syscalls_asm.S
183
184.. Other links:
185.. _LibTomCrypt: https://github.com/libtom/libtomcrypt