blob: 9ab4f8f6c3b9e7a58c258527b7f2beada27b0847 [file] [log] [blame] [view]
mohammad160387a7eeb2018-11-01 11:25:49 +02001## Getting started with Mbed Crypto
2
3### What is Mbed Crypto?
4
5Mbed Crypto is an open source cryptographic library that supports a wide range of cryptographic operations, including:
6* Key management
7* Hashing
8* Symmetric cryptography
9* Asymmetric cryptography
10* Message authentication (MAC)
11* Key generation and derivation
12* Authenticated encryption with associated data (AEAD)
13
14The Mbed Crypto library is a reference implementation of the cryptography interface of the Arm Platform Security Architecture (PSA). It is written in portable C.
15
16The Mbed Crypto library is distributed under the Apache License, version 2.0.
17
18#### Platform Security Architecture (PSA)
19
20Arm's Platform Security Architecture (PSA) is a holistic set of threat models,
21security analyses, hardware and firmware architecture specifications, and an open source firmware reference implementation. PSA provides a recipe, based on industry best practice, that allows security to be consistently designed in, at both a hardware and firmware level. Part of the API provided by PSA is the cryptography interface, which provides access to a set of primitives.
22
23### Using Mbed Crypto
24
25* [Getting the Mbed Crypto library](#getting-the-mbed-crypto-library)
26* [Building the Mbed Crypto library](#building-the-mbed-crypto-library)
27* [Using the Mbed Crypto library](#using-the-mbed-crypto-library)
28* [Importing a key](#importing-a-key)
29* [Signing a message using RSA](#signing-a-message-using-RSA)
30* [Encrypting or decrypting using symmetric ciphers](#encrypting-or-decrypting-using-symmetric-ciphers)
31* [Hashing a message](#hashing-a-message)
32* [Deriving a new key from an existing key](#deriving-a-new-key-from-an-existing-key)
33* [Generating a random value](#generating-a-random-value)
34* [Authenticating and encrypting or decrypting a message](#authenticating-and-encrypting-or-decrypting-a-message)
35* [Generating and exporting keys](#generating-and-exporting-keys)
36* [More about the Mbed Crypto library](#more-about-the-mbed-crypto-library)
37
38### Getting the Mbed Crypto library
39
40Mbed Crypto releases are available in the [public Github repository]( https://github.com/ARMmbed/mbed-crypto).
41
42### Building the Mbed Crypto library
43
44You need the following tools to build the library with the provided makefiles:
45* GNU Make.
46* A C toolchain (compiler, linker, archiver).
47* Python 2 or Python 3 (either works) to generate the test code.
48* Perl to run the tests.
49
50If you have a C compiler such as GCC or Clang, just run `make` in the top-level directory to build the library, a set of unit tests and some sample programs.
51
52To select a different compiler, set the `CC` variable to name or path of the compiler and linker (default: `cc`) and set `AR` to a compatible archiver (default: `ar`), such as:
53```
54make CC=arm-linux-gnueabi-gcc AR=arm-linux-gnueabi-ar
55```
56The provided makefiles pass options to the compiler that assume a GCC-like command line syntax. To use a different compiler, you may need to pass different values for `CFLAGS`, `WARNINGS_CFLAGS` and `LDFLAGS`.
57
58To run the unit tests on the host machine, run `make test` from the top-level directory. If you are cross-compiling, copy the test executable from the `tests` directory to the target machine.
59
60### Using the Mbed Crypto library
61
62To use the Mbed Crypto APIs, call `psa_crypto_init()` before calling any other API. This initializes the library.
63
64### Importing a key
65
66To use a key for cryptography operations in Mbed Crypto, you need to first import it into a key slot. Each slot can store only one key at a time. The slot where the key is stored must be unoccupied, and valid for a key of the chosen type.
67
68Prerequisites to importing keys:
69* Initialize the library with a successful call to `psa_crypto_init`.
70
71Importing a key and checking key information:
721. Import a key pair into key slot `1`.
731. Test the information stored in this slot:
74```C
75 int key_slot = 1;
Gilles Peskinec93b80c2019-05-16 19:39:54 +020076 uint8_t *data = "KEY_PAIR_KEY_DATA";
mohammad160387a7eeb2018-11-01 11:25:49 +020077 size_t data_size;
78 psa_key_type_t type = PSA_KEY_TYPE_RSA_PUBLIC_KEY;
79 size_t got_bits;
80 psa_key_type_t got_type;
81 size_t expected_bits = data_size;
82 psa_key_type_t type = PSA_KEY_TYPE_RAW_DATA;
83 size_t export_size = data_size;
84
85 psa_crypto_init();
86
87 /* Import the key */
88 status = psa_import_key(key_slot, type, data, data_size);
89
90 /* Test the key information */
91 status = psa_get_key_information(slot, &got_type, &got_bits);
92
93 /* Destroy the key */
94 psa_destroy_key(key_slot);
95 mbedtls_psa_crypto_free();
96```
97
98### Signing a message using RSA
99
100Mbed Crypto provides support for encrypting, decrypting, signing and verifying messages using public key signature algorithms (such as RSA or ECDSA).
101
102Prerequisites to working with the asymmetric cipher API:
103* Initialize the library with a successful call to `psa_crypto_init`.
104* Configure the key policy accordingly:
105 * `PSA_KEY_USAGE_SIGN` to allow signing.
106 * `PSA_KEY_USAGE_VERIFY` to allow signature verification.
107* Have a valid key in the key slot.
108
109To sign a given message `payload` using RSA:
1101. Set the key policy of the chosen key slot by calling `psa_key_policy_set_usage()` with the `PSA_KEY_USAGE_SIGN` parameter and the algorithm `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`.
111This allows the key in the key slot to be used for RSA signing.
1121. Import the key into the key slot by calling `psa_import_key()`. You can use an already imported key instead of importing a new one.
1131. Call `psa_asymmetric_sign()` and get the output buffer that contains the signature:
114```C
115 psa_status_t status;
116 int key_slot = 1;
117 unsigned char key[] = "RSA_KEY";
118 unsigned char payload[] = "ASYMMETRIC_INPUT_FOR_SIGN";
Jaeden Amero70261c52019-01-04 11:47:20 +0000119 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
mohammad160387a7eeb2018-11-01 11:25:49 +0200120 unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
121 size_t signature_length;
122
123 status = psa_crypto_init();
124
125 /* Import the key */
mohammad160387a7eeb2018-11-01 11:25:49 +0200126 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_SIGN,
127 PSA_ALG_RSA_PKCS1V15_SIGN_RAW);
128 status = psa_set_key_policy(key_slot, &policy);
129
Gilles Peskinec93b80c2019-05-16 19:39:54 +0200130 status = psa_import_key(key_slot, PSA_KEY_TYPE_RSA_KEY_PAIR,
mohammad160387a7eeb2018-11-01 11:25:49 +0200131 key, sizeof(key));
132
133 /* Sing message using the key */
134 status = psa_asymmetric_sign(key_slot, PSA_ALG_RSA_PKCS1V15_SIGN_RAW,
135 payload, sizeof(payload),
136 signature, sizeof(signature),
137 &signature_length);
138 /* Destroy the key */
139 psa_destroy_key(key_slot);
140 mbedtls_psa_crypto_free();
141```
142
143### Encrypting or decrypting using symmetric ciphers
144
145Mbed Crypto provides support for encrypting and decrypting messages using various symmetric cipher algorithms (both block and stream ciphers).
146
147Prerequisites to working with the symmetric cipher API:
148* Initialize the library with a successful call to `psa_crypto_init`.
149* Configure the key policy accordingly (`PSA_KEY_USAGE_ENCRYPT` to allow encryption or `PSA_KEY_USAGE_DECRYPT` to allow decryption).
150* Have a valid key in the key slot.
151
152Encrypting a message with a symmetric cipher:
1531. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the cipher functions.
1541. Call `psa_cipher_encrypt_setup` to initialize the operation structure and specify the algorithm and the key to be used.
1551. Call either `psa_cipher_generate_iv` or `psa_cipher_set_iv` to generate or set the initialization vector (IV). We recommended `psa_cipher_generate_iv`, unless you require a specific IV value.
1561. Call `psa_cipher_update` one or more times, passing either the whole or only a fragment of the message each time.
1571. Call `psa_cipher_finish` to end the operation and output the encrypted message.
158
159Encrypting random data using an AES key in cipher block chain (CBC) mode with no padding (assuming all prerequisites have been fulfilled):
160```c
161 psa_key_slot_t key_slot = 1;
162 psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
163 psa_cipher_operation_t operation;
164 size_t block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES);
165 unsigned char input[block_size];
166 unsigned char iv[block_size];
167 size_t iv_len;
168 unsigned char output[block_size];
169 size_t output_len;
170
171 /* generate some random data to be encrypted */
172 psa_generate_random(input, sizeof(input));
173
174 /* encrypt the key */
175 psa_cipher_encrypt_setup(&operation, key_slot, alg);
176 psa_cipher_generate_iv(&operation, iv, sizeof(iv), &iv_len);
177 psa_cipher_update(&operation, input, sizeof(input),
178 output, sizeof(output),
179 &output_len);
180 psa_cipher_finish(&operation,
181 output + output_len, sizeof(output) - output_len,
182 &output_len);
183 /* Clean up cipher operation context */
184 psa_cipher_abort(&operation);
185```
186
187Decrypting a message with a symmetric cipher:
1881. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the cipher functions.
1891. Call `psa_cipher_decrypt_setup` to initialize the operation structure and to specify the algorithm and the key to be used.
1901. Call `psa_cipher_set_iv` with the IV for the decryption.
1911. Call `psa_cipher_update` one or more times passing either the whole or only a fragment of the message each time.
1921. Call `psa_cipher_finish` to end the operation and output the decrypted message.
193
194Decrypting encrypted data using an AES key in CBC mode with no padding
195(assuming all prerequisites have been fulfilled):
196```c
197 psa_key_slot_t key_slot = 1;
198 psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
199 psa_cipher_operation_t operation;
200 size_t block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES);
201 unsigned char input[block_size];
202 unsigned char iv[block_size];
203 size_t iv_len;
204 unsigned char output[block_size];
205 size_t output_len;
206
207 /* setup input data */
208 fetch_iv(iv, sizeof(iv)); /* fetch the IV used when the data was encrypted */
209 fetch_input(input, sizeof(input)); /* fetch the data to be decrypted */
210
211 /* encrypt the encrypted data */
212 psa_cipher_decrypt_setup(&operation, key_slot, alg);
213 psa_cipher_set_iv(&operation, iv, sizeof(iv));
214 psa_cipher_update(&operation, input, sizeof(input),
215 output, sizeof(output),
216 &output_len);
217 psa_cipher_finish(&operation,
218 output + output_len, sizeof(output) - output_len,
219 &output_len);
220 /* Clean up cipher operation context */
221 psa_cipher_abort(&operation);
222```
223
224#### Handling cipher operation contexts
225
226Once you've initialized the operation structure with a successful call to `psa_cipher_encrypt_setup` or `psa_cipher_decrypt_setup`, you can terminate the operation at any time by calling `psa_cipher_abort`.
227
228The call to `psa_cipher_abort` frees any resources associated with the operation (except for the operation structure itself). An implicit call to `psa_cipher_abort` occurs when any of these conditions occur:
229* A call to `psa_cipher_generate_iv`, `psa_cipher_set_iv` or `psa_cipher_update` has failed (returning any status other than `PSA_SUCCESS`).
230* Either a successful or failed call to `psa_cipher_finish`.
231
232Once `psa_cipher_abort` has been called (either implicitly by the implementation or explicitly by the user), the operation structure is invalidated and may not be reused for the same operation. However, the operation structure may be reused for a different operation by calling either `psa_cipher_encrypt_setup` or `psa_cipher_decrypt_setup` again.
233
234For an operation that has been initialized successfully (by a successful call to `psa_cipher_encrypt_setup` or `psa_cipher_decrypt_setup`) it is imperative that at some time `psa_cipher_abort` is called.
235
236Multiple sequential calls to `psa_cipher_abort` on an operation that has already been terminated (either implicitly or explicitly) are safe and have no effect.
237
238### Hashing a message
239
240Mbed Crypto lets you compute and verify hashes using various hashing algorithms.
241
242The current implementation supports the following hash algorithms: `MD2`, `MD4`, `MD5`, `RIPEMD160`, `SHA-1`, `SHA-224`, `SHA-256`, `SHA-384`, and `SHA-512`.
243
244Prerequisites to working with the hash APIs:
245* Initialize the library with a successful call to `psa_crypto_init`.
246
247To calculate a hash:
2481. Allocate an operation structure (`psa_hash_operation_t`) to pass to the hash functions.
2491. Call `psa_hash_setup` to initialize the operation structure and specify the hash algorithm.
2501. Call `psa_hash_update` one or more times, passing either the whole or only a fragment of the message each time.
2511. Call `psa_hash_finish` to calculate the hash, or `psa_hash_verify` to compare the computed hash with an expected hash value.
252
253Calculate the `SHA-256` hash of a message:
254```c
255 psa_algorithm_t alg = PSA_ALG_SHA_256;
256 psa_hash_operation_t operation;
257 unsigned char input[] = { 'a', 'b', 'c' };
258 unsigned char actual_hash[PSA_HASH_MAX_SIZE];
259 size_t actual_hash_len;
260
261 /* Compute hash of message */
262 psa_hash_setup(&operation, alg);
263 psa_hash_update(&operation, input, sizeof(input));
264 psa_hash_finish(&operation, actual_hash, sizeof(actual_hash), &actual_hash_len);
265
266 /* Clean up hash operation context */
267 psa_hash_abort(&operation);
268```
269
270Verify the `SHA-256` hash of a message:
271```c
272 psa_algorithm_t alg = PSA_ALG_SHA_256;
273 psa_hash_operation_t operation;
274 unsigned char input[] = { 'a', 'b', 'c' };
275 unsigned char expected_hash[] = {
276 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
277 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
278 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
279 };
280 size_t expected_hash_len = PSA_HASH_SIZE(alg);
281
282 /* Verify message hash */
283 psa_hash_setup(&operation, alg);
284 psa_hash_update(&operation, input, sizeof(input));
285 psa_hash_verify(&operation, expected_hash, expected_hash_len);
286```
287
288The API provides the macro `PSA_HASH_SIZE`, which returns the expected hash length (in bytes) for the specified algorithm.
289
290#### Handling hash operation contexts
291
292Once the operation structure has been successfully initialized by a successful call to `psa_hash_setup`, it's possible to terminate the operation at any time by calling `psa_hash_abort`. The call to `psa_hash_abort` frees any resources associated with the operation (except for the operation structure itself).
293
294An implicit call to `psa_hash_abort` occurs when any of these conditions occur:
2951. A call to `psa_hash_update` has failed (returning any status other than `PSA_SUCCESS`).
2961. Either a successful or failed call to `psa_hash_finish`.
2971. Either a successful or failed call to `psa_hash_verify`.
298
299Once `psa_hash_abort` has been called (either implicitly by the implementation or explicitly by the user), the operation structure is invalidated and may not be reused for the same operation. However, the operation structure may be reused for a different operation by calling `psa_hash_setup` again.
300
301For an operation that has been initialized successfully (by a successful call to `psa_hash_setup`) it is imperative that at some time `psa_hash_abort` is called.
302
303Multiple sequential calls to `psa_hash_abort` on an operation that has already been terminated (either implicitly or explicitly) is safe and has no effect.
304
305### Generating a random value
306
307Mbed Crypto can generate random data.
308
309Prerequisites to random generation:
310* Initialize the library with a successful call to `psa_crypto_init`.
311
312Generate a random, ten-byte piece of data:
3131. Generate random bytes by calling `psa_generate_random()`:
314```C
315 psa_status_t status;
316 uint8_t random[10] = { 0 };
317 psa_crypto_init();
318 status = psa_generate_random(random, sizeof(random));
319
320 mbedtls_psa_crypto_free();
321```
322
323### Deriving a new key from an existing key
324
325Mbed Crypto provides a key derivation API that lets you derive new keys from existing ones. Key derivation is based upon the generator abstraction. A generator must first be initialized and set up (provided with a key and optionally other data) and then derived data can be read from it either to a buffer or directly imported into a key slot.
326
327Prerequisites to working with the key derivation APIs:
328* Initialize the library with a successful call to `psa_crypto_init`.
329* Configure the key policy for the key used for derivation (`PSA_KEY_USAGE_DERIVE`)
330* The key type must be `PSA_KEY_TYPE_DERIVE`.
331
332Deriving a new AES-CTR 128-bit encryption key into a given key slot using HKDF with a given key, salt and label:
3331. Set the key policy for key derivation by calling `psa_key_policy_set_usage()` with `PSA_KEY_USAGE_DERIVE` parameter, and the algorithm `PSA_ALG_HKDF(PSA_ALG_SHA_256)`.
3341. Import the key into the key slot by calling `psa_import_key()`. You can skip this step and the previous one if the key has already been imported into a known key slot.
3351. Set up the generator using the `psa_key_derivation` function providing a key slot containing a key that can be used for key derivation and a salt and label (Note: salt and label are optional).
3361. Initiate a key policy to for the derived key by calling `psa_key_policy_set_usage()` with `PSA_KEY_USAGE_ENCRYPT` parameter and the algorithm `PSA_ALG_CTR`.
3371. Set the key policy to the derived key slot.
Gilles Peskinea99d3fb2019-05-16 15:28:51 +02003381. Import a key from generator into the desired key slot using (`psa_key_derivation_output_key`).
mohammad160387a7eeb2018-11-01 11:25:49 +02003391. Clean up generator.
340
341At this point the derived key slot holds a new 128-bit AES-CTR encryption key derived from the key, salt and label provided:
342```C
343 psa_key_slot_t base_key = 1;
344 psa_key_slot_t derived_key = 2;
Jaeden Amero70261c52019-01-04 11:47:20 +0000345 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
mohammad160387a7eeb2018-11-01 11:25:49 +0200346
347 unsigned char key[] = {
348 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
349 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
350 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
351 0x0b };
352
353 unsigned char salt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
354 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c };
355
356 unsigned char label[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
357 0xf7, 0xf8, 0xf9 };
358
359 psa_algorithm_t alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
Jaeden Amero70261c52019-01-04 11:47:20 +0000360 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
Gilles Peskinea99d3fb2019-05-16 15:28:51 +0200361 psa_key_derivation_operation_t generator = PSA_KEY_DERIVATION_OPERATION_INIT;
mohammad160387a7eeb2018-11-01 11:25:49 +0200362 size_t derived_bits = 128;
363 size_t capacity = PSA_BITS_TO_BYTES(derived_bits);
364
365 status = psa_crypto_init();
366
367 /* Import a key for use in key derivation, if such a key has already been imported you can skip this part */
mohammad160387a7eeb2018-11-01 11:25:49 +0200368 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_DERIVE, alg);
369 status = psa_set_key_policy(base_key, &policy);
370
371 status = psa_import_key(base_key, PSA_KEY_TYPE_DERIVE, key, sizeof(key));
372
373 /* Derive a key into a key slot*/
374 status = psa_key_derivation(&generator, base_key, alg, salt, sizeof(salt),
375 label, sizeof(label), capacity);
376
377 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_ENCRYPT, PSA_ALG_CTR);
378
379 psa_set_key_policy(derived_key, &policy);
380
Gilles Peskinea99d3fb2019-05-16 15:28:51 +0200381 psa_key_derivation_output_key(derived_key, PSA_KEY_TYPE_AES, derived_bits, &generator);
mohammad160387a7eeb2018-11-01 11:25:49 +0200382
383 /* Clean up generator and key */
Gilles Peskinea99d3fb2019-05-16 15:28:51 +0200384 psa_key_derivation_abort(&generator);
mohammad160387a7eeb2018-11-01 11:25:49 +0200385 /* as part of clean up you may want to clean up the keys used by calling:
386 * psa_destroy_key( base_key ); or psa_destroy_key( derived_key ); */
387 mbedtls_psa_crypto_free();
388```
389
390### Authenticating and encrypting or decrypting a message
391
392Mbed Crypto provides a simple way for authenticate and encrypt with associated data (AEAD) supporting `PSA_ALG_CCM` algorithm.
393
394Prerequisites to working with the AEAD ciphers APIs:
395* Initialize the library with a successful call to `psa_crypto_init`.
396* The key policy for the key used for derivation must be configured accordingly (`PSA_KEY_USAGE_ENCRYPT` or `PSA_KEY_USAGE_DECRYPT`).
397
398To authenticate and encrypt a message:
399```C
400 int slot = 1;
401 psa_status_t status;
402 unsigned char key[] = { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
403 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF };
404
405 unsigned char nonce[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
406 0x08, 0x09, 0x0A, 0x0B };
407
408 unsigned char additional_data[] = { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20,
409 0xC3, 0x3C, 0x49, 0xFD, 0x70 };
410
411 unsigned char input_data[] = { 0xB9, 0x6B, 0x49, 0xE2, 0x1D, 0x62, 0x17, 0x41,
412 0x63, 0x28, 0x75, 0xDB, 0x7F, 0x6C, 0x92, 0x43,
413 0xD2, 0xD7, 0xC2 };
414 unsigned char *output_data = NULL;
415 size_t output_size = 0;
416 size_t output_length = 0;
417 size_t tag_length = 16;
Jaeden Amero70261c52019-01-04 11:47:20 +0000418 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
mohammad160387a7eeb2018-11-01 11:25:49 +0200419
420 output_size = sizeof(input_data) + tag_length;
421 output_data = malloc(output_size);
422 status = psa_crypto_init();
423
mohammad160387a7eeb2018-11-01 11:25:49 +0200424 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_ENCRYPT, PSA_ALG_CCM);
425 status = psa_set_key_policy(slot, &policy);
426
427 status = psa_import_key(slot, PSA_KEY_TYPE_AES, key, sizeof(key));
428
429 status = psa_aead_encrypt(slot, PSA_ALG_CCM,
430 nonce, sizeof(nonce),
431 additional_data, sizeof(additional_data),
432 input_data, sizeof(input_data),
433 output_data, output_size,
434 &output_length);
435
436 psa_destroy_key(slot);
437 mbedtls_free(output_data);
438 mbedtls_psa_crypto_free();
439```
440
441To authenticate and decrypt a message:
442
443```C
444 int slot = 1;
445 psa_status_t status;
446 unsigned char key[] = {
447 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
448 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF
449 };
450
451 unsigned char nonce[] = { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20, 0xC3,
452 0x3C, 0x49, 0xFD, 0x70
453 };
454
455 unsigned char additional_data[] = { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20,
456 0xC3, 0x3C, 0x49, 0xFD, 0x70
457 };
458 unsigned char input_data[] = { 0xB9, 0x6B, 0x49, 0xE2, 0x1D, 0x62, 0x17, 0x41,
459 0x63, 0x28, 0x75, 0xDB, 0x7F, 0x6C, 0x92, 0x43,
460 0xD2, 0xD7, 0xC2
461 };
462 unsigned char *output_data = NULL;
463 size_t output_size = 0;
464 size_t output_length = 0;
Jaeden Amero70261c52019-01-04 11:47:20 +0000465 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
mohammad160387a7eeb2018-11-01 11:25:49 +0200466
467 output_size = sizeof(input_data);
468 output_data = malloc(output_size);
469 status = psa_crypto_init();
470
mohammad160387a7eeb2018-11-01 11:25:49 +0200471 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_DECRYPT, PSA_ALG_CCM);
472 status = psa_set_key_policy(slot, &policy);
473
474 status = psa_import_key(slot, PSA_KEY_TYPE_AES, key, sizeof(key));
475
476 status = psa_aead_decrypt(slot, PSA_ALG_CCM,
477 nonce, sizeof(nonce),
478 additional_data, sizeof(additional_data),
479 input_data, sizeof(input_data),
480 output_data, output_size,
481 &output_length);
482
483 psa_destroy_key(slot);
484 mbedtls_free(output_data);
485 mbedtls_psa_crypto_free();
486```
487
488### Generating and exporting keys
489
490Mbed Crypto provides a simple way to generate a key or key pair.
491
492Prerequisites to using key generation and export APIs:
493* Initialize the library with a successful call to `psa_crypto_init`.
494
495Generate a piece of random 128-bit AES data:
4961. Set the key policy for key generation by calling `psa_key_policy_set_usage()` with the `PSA_KEY_USAGE_EXPORT` parameter and the algorithm `PSA_ALG_GCM`.
Gilles Peskine35ef36b2019-05-16 19:42:05 +02004971. Generate a random AES key by calling `psa_generate_key()`.
mohammad160387a7eeb2018-11-01 11:25:49 +02004981. Export the generated key by calling `psa_export_key()`:
499```C
500 int slot = 1;
501 size_t bits = 128;
502 size_t exported_size = bits;
503 size_t exported_length = 0;
504 uint8_t *exported = malloc(exported_size);
Jaeden Amero70261c52019-01-04 11:47:20 +0000505 psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
mohammad160387a7eeb2018-11-01 11:25:49 +0200506
507 psa_crypto_init();
508
mohammad160387a7eeb2018-11-01 11:25:49 +0200509 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_EXPORT, PSA_ALG_GCM);
510 psa_set_key_policy(slot, &policy);
511
512 /* Generate a key */
Gilles Peskine35ef36b2019-05-16 19:42:05 +0200513 psa_generate_key(slot, PSA_KEY_TYPE_AES, bits);
mohammad160387a7eeb2018-11-01 11:25:49 +0200514
515 psa_export_key(slot, exported, exported_size, &exported_length)
516
517 psa_destroy_key(slot);
518 mbedtls_psa_crypto_free();
519```
520
521### More about the Mbed Crypto library
522
523More information on [Mbed Crypto](https://github.com/ARMmbed/mbed-crypto/).
524
525More information on [PSA Crypto](https://github.com/ARMmbed/mbed-crypto/blob/development/docs/PSA_Crypto_API_Overview.pdf).