Skip to content

Commit

Permalink
Documentation: sync with new crypto.h
Browse files Browse the repository at this point in the history
Update documentation of the Crypto API with the new <crypto/crypto.h>
replacing the old crypto_ops based API.

Acked-by: Jerome Forissier <[email protected]>
Reviewed-by: Etienne Carriere <[email protected]>
Signed-off-by: Jens Wiklander <[email protected]>
  • Loading branch information
jenswi-linaro authored and jforissier committed Nov 14, 2017
1 parent d0620b0 commit 6d9e638
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 73 deletions.
116 changes: 50 additions & 66 deletions documentation/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ algorithms. Most of the crypto code runs in kernel mode inside the TEE core.
Here is a schematic view of a typical call to the crypto API. The numbers in
square brackets ([1], [2]...) refer to the sections below.

some_function() (Trusted App)
[1] TEE_*() User space (libutee.a)
------- utee_*() -----------------------------------------------
[2] tee_svc_*() Kernel space
[3] crypto_ops.*() (libtomcrypt.a)
[4] /* LibTomCrypt */ (libtomcrypt.a)
some_function() (Trusted App)
[1] TEE_*() User space (libutee.a)
------- utee_*() ----------------------------------------------
[2] tee_svc_*() Kernel space
[3] crypto_*() (libtomcrypt.a and crypto.c)
[4] /* LibTomCrypt */ (libtomcrypt.a)

## The TEE Cryptographic Operations API [1]

Expand Down Expand Up @@ -51,68 +51,62 @@ All cryptography-related system calls are declared in
[tee_svc_cryp.c](../core/tee/tee_svc_cryp.c).
In addition to dealing with the usual work required at the user/kernel interface
(checking parameters and copying memory buffers between user and kernel space),
the system calls invoke a private abstraction layer: the **crypto_ops**
structure, which is declared in
[tee_cryp_provider.h](../core/include/tee/tee_cryp_provider.h).
the system calls invoke a private abstraction layer: the **Crypto API**,
which is declared in [crypto.h](core/include/crypto/crypto.h).
It serves two main purposes:

1. Allow for alternative implementations, such as hardware-accelerated versions.
2. Provide an easy way to disable some families of algorithms at compile-time
to save space. See *LibTomCrypt* below.

## struct crypto_ops [3]
## crypto_*() [3]

The **crypto_ops** structure contains pointer to functions that implement the
actual algorithms and helper functions. The TEE Core has one global instance of
this structure. The default implementation, based on
The **crypto_*()** functions implement the actual algorithms and helper
functions. The TEE Core has one global active implementeation of this interface.
The default implementation, mostly based on
[LibTomCrypt](https://github.com/libtom/libtomcrypt), is as follows:

```c
/* core/lib/libtomcrypt/tee_ltc_provider.c */
/* core/crypto/crypto.c */

/*
* static functions: tee_ltc_init(), hash_get_ctx_size(), etc.
* ...
* Default implementation for all functions in crypto.h
*/

struct crypto_ops crypto_ops = {
.name = "LibTomCrypt provider",
.init = tee_ltc_init,
#if !defined(_CFG_CRYPTO_WITH_HASH)
TEE_Result crypto_hash_get_ctx_size(uint32_t algo __unused,
size_t *size __unused)
{
return TEE_ERROR_NOT_IMPLEMENTED;
}
...
#endif /*_CFG_CRYPTO_WITH_HASH*/

/* core/lib/libtomcrypt/tee_ltc_provider.c */

#if defined(_CFG_CRYPTO_WITH_HASH)
.hash = {
.get_ctx_size = hash_get_ctx_size,
.init = hash_init,
.update = hash_update,
.final = hash_final,
},
#endif
#if defined(_CFG_CRYPTO_WITH_CIPHER)
.cipher = {
.final = cipher_final,
.get_block_size = cipher_get_block_size,
.get_ctx_size = cipher_get_ctx_size,
.init = cipher_init,
.update = cipher_update,
},
#endif
TEE_Result crypto_hash_get_ctx_size(uint32_t algo, size_t *size)
{
/* ... */
return TEE_SUCCESS;
}

#endif /*_CFG_CRYPTO_WITH_HASH*/

```

As shown above, it is allowed to omit some pointers, in which case they will be
set to NULL by the compiler and not used by the system service layer.
When a Trusted Application calls **TEE_AllocateOperation()** to request an
operation that is not available, it receives an error status
(**TEE_ERROR_NOT_IMPLEMENTED**) but it will not panic.
As shown above, families of algorithms can be disabled and
[crypto.c]((core/include/crypto/crypto.h)) will provide default null
implementations that will return **TEE_ERROR_NOT_IMPLEMENTED**.

## Public/private key format

**crypto_ops** uses implementation-specific types to hold key data
**<crypto/crypto.h>** uses implementation-specific types to hold key data
for asymmetric algorithms. For instance, here is how a public RSA key is
represented:

```c
/* core/include/tee/tee_cryp_provider.h */
/* core/include/crypt/crypt.h */

struct rsa_public_key {
struct bignum *e; /* Public exponent */
Expand All @@ -130,20 +124,14 @@ conversion to or from the big endian binary format.


```c
/* core/include/tee/tee_cryp_provider.h */
/* core/include/core/core.h */

struct bignum_ops {
/* ... */
struct bignum *(*allocate)(size_t size_bits);
TEE_Result (*bin2bn)(const uint8_t *from, size_t fromsize,
struct bignum *to);
void (*bn2bin)(const struct bignum *from, uint8_t *to);
};
struct bignum *crypto_bignum_allocate(size_t size_bits);
TEE_Result crypto_bignum_bin2bn(const uint8_t *from, size_t fromsize,
struct bignum *to);
void crypto_bignum_bn2bin(const struct bignum *from, uint8_t *to);
/*...*/

struct crypto_ops {
/* ... */
struct bignum_ops bignum;
};
```
## LibTomCrypt [4]
Expand All @@ -169,22 +157,18 @@ return **TEE_ERROR_NOT_IMPLEMENTED**).
## How to add a new crypto implementation
To add a new implementation, the default one in
[core/lib/libtomcrypt](../core/lib/libtomcrypt) should
be used as a reference. A proof-of-concept implementation based on OpenSSL was
developed when the `crypto_ops` abstraction layer was introduced. It is not
included in the main branch of the OP-TEE repository essentially due to
licensing concerns; however it is available in the
[poc/openssl_cryptolib](https://github.com/OP-TEE/optee_os/tree/poc/openssl_cryptolib)
branch.
[core/lib/libtomcrypt](../core/lib/libtomcrypt) in combination with what is
in [core/crypto](../core/crypto) should be used as a reference.
Here are the main things to consider when adding a new crypto provider:
- Put all the new code in its own directory under `core/lib`.
- Put all the new code in its own directory under `core/lib` unless it is
code that will be used regardless of which crypto provider is in use.
How we are dealing with AES-GCM in [core/crypto](../core/crypto) could
serve as an example.
- Avoid modifying [tee_svc_cryp.c](../core/tee/tee_svc_cryp.c). It should not be
needed.
- Your own **struct crypto_ops crypto_ops = ...** should be defined in a file at
the top level of your new directory.
- Although not all pointers in **crypto_ops** need to be defined, all are
required for compliance to the GlobalPlatform specification.
- Although not all crypto families need to be defined, all are required for
compliance to the GlobalPlatform specification.
- If you intend to make some algorithms optional, please try to re-use the same
names for configuration variables as the default implementation.
15 changes: 8 additions & 7 deletions documentation/porting_guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,14 @@ have the ability to enable Crypto Extensions that were introduced with ARMv8-A
have hardware crypto IP's, but due to NDA's etc it has not been possible to
enable it. If you have a device capable of doing crypto operations on a
dedicated crypto block and you prefer to use that in favor for the software
implementation, then you will need to implement a new `crypto_ops` structure and
write the low level driver that communicates with the device. Our [crypto.md]
file describes how to add and implement a new `struct crypto_ops`. Since the
communication with crypto blocks tends to be quite different depending on what
kind of crypto block you have, we have not written how that should be done. It
might be that we do that in the future when get hold of a device where we can
use the crypto block.
implementation, then you will need to implement relevant functions defined in
`core/include/crypto/crypto.h`, the Crypto API, and write the low level
driver that communicates with the device. Our [crypto.md] file describes
how the Crypto API is integrated. Since the communication with crypto
blocks tends to be quite different depending on what kind of crypto block
you have, we have not written how that should be done. It might be that we
do that in the future when get hold of a device where we can use the crypto
block.

## 7. Power Management / PSCI
In section 2 when we talked about the file `main.c`, we added a couple of
Expand Down

0 comments on commit 6d9e638

Please sign in to comment.