blob: eac831546956e5800836e9c14b0922c1dd7b8d06 [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;
76 uint8_t *data = "KEYPAIR_KEY_DATA";
77 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";
119 psa_key_policy_t policy;
120 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 */
126 psa_key_policy_init(&policy);
127 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_SIGN,
128 PSA_ALG_RSA_PKCS1V15_SIGN_RAW);
129 status = psa_set_key_policy(key_slot, &policy);
130
131 status = psa_import_key(key_slot, PSA_KEY_TYPE_RSA_KEYPAIR,
132 key, sizeof(key));
133
134 /* Sing message using the key */
135 status = psa_asymmetric_sign(key_slot, PSA_ALG_RSA_PKCS1V15_SIGN_RAW,
136 payload, sizeof(payload),
137 signature, sizeof(signature),
138 &signature_length);
139 /* Destroy the key */
140 psa_destroy_key(key_slot);
141 mbedtls_psa_crypto_free();
142```
143
144### Encrypting or decrypting using symmetric ciphers
145
146Mbed Crypto provides support for encrypting and decrypting messages using various symmetric cipher algorithms (both block and stream ciphers).
147
148Prerequisites to working with the symmetric cipher API:
149* Initialize the library with a successful call to `psa_crypto_init`.
150* Configure the key policy accordingly (`PSA_KEY_USAGE_ENCRYPT` to allow encryption or `PSA_KEY_USAGE_DECRYPT` to allow decryption).
151* Have a valid key in the key slot.
152
153Encrypting a message with a symmetric cipher:
1541. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the cipher functions.
1551. Call `psa_cipher_encrypt_setup` to initialize the operation structure and specify the algorithm and the key to be used.
1561. 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.
1571. Call `psa_cipher_update` one or more times, passing either the whole or only a fragment of the message each time.
1581. Call `psa_cipher_finish` to end the operation and output the encrypted message.
159
160Encrypting random data using an AES key in cipher block chain (CBC) mode with no padding (assuming all prerequisites have been fulfilled):
161```c
162 psa_key_slot_t key_slot = 1;
163 psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
164 psa_cipher_operation_t operation;
165 size_t block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES);
166 unsigned char input[block_size];
167 unsigned char iv[block_size];
168 size_t iv_len;
169 unsigned char output[block_size];
170 size_t output_len;
171
172 /* generate some random data to be encrypted */
173 psa_generate_random(input, sizeof(input));
174
175 /* encrypt the key */
176 psa_cipher_encrypt_setup(&operation, key_slot, alg);
177 psa_cipher_generate_iv(&operation, iv, sizeof(iv), &iv_len);
178 psa_cipher_update(&operation, input, sizeof(input),
179 output, sizeof(output),
180 &output_len);
181 psa_cipher_finish(&operation,
182 output + output_len, sizeof(output) - output_len,
183 &output_len);
184 /* Clean up cipher operation context */
185 psa_cipher_abort(&operation);
186```
187
188Decrypting a message with a symmetric cipher:
1891. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the cipher functions.
1901. Call `psa_cipher_decrypt_setup` to initialize the operation structure and to specify the algorithm and the key to be used.
1911. Call `psa_cipher_set_iv` with the IV for the decryption.
1921. Call `psa_cipher_update` one or more times passing either the whole or only a fragment of the message each time.
1931. Call `psa_cipher_finish` to end the operation and output the decrypted message.
194
195Decrypting encrypted data using an AES key in CBC mode with no padding
196(assuming all prerequisites have been fulfilled):
197```c
198 psa_key_slot_t key_slot = 1;
199 psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
200 psa_cipher_operation_t operation;
201 size_t block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES);
202 unsigned char input[block_size];
203 unsigned char iv[block_size];
204 size_t iv_len;
205 unsigned char output[block_size];
206 size_t output_len;
207
208 /* setup input data */
209 fetch_iv(iv, sizeof(iv)); /* fetch the IV used when the data was encrypted */
210 fetch_input(input, sizeof(input)); /* fetch the data to be decrypted */
211
212 /* encrypt the encrypted data */
213 psa_cipher_decrypt_setup(&operation, key_slot, alg);
214 psa_cipher_set_iv(&operation, iv, sizeof(iv));
215 psa_cipher_update(&operation, input, sizeof(input),
216 output, sizeof(output),
217 &output_len);
218 psa_cipher_finish(&operation,
219 output + output_len, sizeof(output) - output_len,
220 &output_len);
221 /* Clean up cipher operation context */
222 psa_cipher_abort(&operation);
223```
224
225#### Handling cipher operation contexts
226
227Once 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`.
228
229The 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:
230* A call to `psa_cipher_generate_iv`, `psa_cipher_set_iv` or `psa_cipher_update` has failed (returning any status other than `PSA_SUCCESS`).
231* Either a successful or failed call to `psa_cipher_finish`.
232
233Once `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.
234
235For 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.
236
237Multiple sequential calls to `psa_cipher_abort` on an operation that has already been terminated (either implicitly or explicitly) are safe and have no effect.
238
239### Hashing a message
240
241Mbed Crypto lets you compute and verify hashes using various hashing algorithms.
242
243The current implementation supports the following hash algorithms: `MD2`, `MD4`, `MD5`, `RIPEMD160`, `SHA-1`, `SHA-224`, `SHA-256`, `SHA-384`, and `SHA-512`.
244
245Prerequisites to working with the hash APIs:
246* Initialize the library with a successful call to `psa_crypto_init`.
247
248To calculate a hash:
2491. Allocate an operation structure (`psa_hash_operation_t`) to pass to the hash functions.
2501. Call `psa_hash_setup` to initialize the operation structure and specify the hash algorithm.
2511. Call `psa_hash_update` one or more times, passing either the whole or only a fragment of the message each time.
2521. Call `psa_hash_finish` to calculate the hash, or `psa_hash_verify` to compare the computed hash with an expected hash value.
253
254Calculate the `SHA-256` hash of a message:
255```c
256 psa_algorithm_t alg = PSA_ALG_SHA_256;
257 psa_hash_operation_t operation;
258 unsigned char input[] = { 'a', 'b', 'c' };
259 unsigned char actual_hash[PSA_HASH_MAX_SIZE];
260 size_t actual_hash_len;
261
262 /* Compute hash of message */
263 psa_hash_setup(&operation, alg);
264 psa_hash_update(&operation, input, sizeof(input));
265 psa_hash_finish(&operation, actual_hash, sizeof(actual_hash), &actual_hash_len);
266
267 /* Clean up hash operation context */
268 psa_hash_abort(&operation);
269```
270
271Verify the `SHA-256` hash of a message:
272```c
273 psa_algorithm_t alg = PSA_ALG_SHA_256;
274 psa_hash_operation_t operation;
275 unsigned char input[] = { 'a', 'b', 'c' };
276 unsigned char expected_hash[] = {
277 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
278 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
279 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
280 };
281 size_t expected_hash_len = PSA_HASH_SIZE(alg);
282
283 /* Verify message hash */
284 psa_hash_setup(&operation, alg);
285 psa_hash_update(&operation, input, sizeof(input));
286 psa_hash_verify(&operation, expected_hash, expected_hash_len);
287```
288
289The API provides the macro `PSA_HASH_SIZE`, which returns the expected hash length (in bytes) for the specified algorithm.
290
291#### Handling hash operation contexts
292
293Once 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).
294
295An implicit call to `psa_hash_abort` occurs when any of these conditions occur:
2961. A call to `psa_hash_update` has failed (returning any status other than `PSA_SUCCESS`).
2971. Either a successful or failed call to `psa_hash_finish`.
2981. Either a successful or failed call to `psa_hash_verify`.
299
300Once `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.
301
302For 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.
303
304Multiple sequential calls to `psa_hash_abort` on an operation that has already been terminated (either implicitly or explicitly) is safe and has no effect.
305
306### Generating a random value
307
308Mbed Crypto can generate random data.
309
310Prerequisites to random generation:
311* Initialize the library with a successful call to `psa_crypto_init`.
312
313Generate a random, ten-byte piece of data:
3141. Generate random bytes by calling `psa_generate_random()`:
315```C
316 psa_status_t status;
317 uint8_t random[10] = { 0 };
318 psa_crypto_init();
319 status = psa_generate_random(random, sizeof(random));
320
321 mbedtls_psa_crypto_free();
322```
323
324### Deriving a new key from an existing key
325
326Mbed 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.
327
328Prerequisites to working with the key derivation APIs:
329* Initialize the library with a successful call to `psa_crypto_init`.
330* Configure the key policy for the key used for derivation (`PSA_KEY_USAGE_DERIVE`)
331* The key type must be `PSA_KEY_TYPE_DERIVE`.
332
333Deriving a new AES-CTR 128-bit encryption key into a given key slot using HKDF with a given key, salt and label:
3341. 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)`.
3351. 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.
3361. 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).
3371. 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`.
3381. Set the key policy to the derived key slot.
3391. Import a key from generator into the desired key slot using (`psa_generator_import_key`).
3401. Clean up generator.
341
342At this point the derived key slot holds a new 128-bit AES-CTR encryption key derived from the key, salt and label provided:
343```C
344 psa_key_slot_t base_key = 1;
345 psa_key_slot_t derived_key = 2;
346 psa_key_policy_t policy;
347
348 unsigned char key[] = {
349 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
350 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
351 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
352 0x0b };
353
354 unsigned char salt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
355 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c };
356
357 unsigned char label[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
358 0xf7, 0xf8, 0xf9 };
359
360 psa_algorithm_t alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
361 psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
362 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 */
368 psa_key_policy_init(&policy);
369 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_DERIVE, alg);
370 status = psa_set_key_policy(base_key, &policy);
371
372 status = psa_import_key(base_key, PSA_KEY_TYPE_DERIVE, key, sizeof(key));
373
374 /* Derive a key into a key slot*/
375 status = psa_key_derivation(&generator, base_key, alg, salt, sizeof(salt),
376 label, sizeof(label), capacity);
377
378 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_ENCRYPT, PSA_ALG_CTR);
379
380 psa_set_key_policy(derived_key, &policy);
381
382 psa_generator_import_key(derived_key, PSA_KEY_TYPE_AES, derived_bits, &generator);
383
384 /* Clean up generator and key */
385 psa_generator_abort(&generator);
386 /* as part of clean up you may want to clean up the keys used by calling:
387 * psa_destroy_key( base_key ); or psa_destroy_key( derived_key ); */
388 mbedtls_psa_crypto_free();
389```
390
391### Authenticating and encrypting or decrypting a message
392
393Mbed Crypto provides a simple way for authenticate and encrypt with associated data (AEAD) supporting `PSA_ALG_CCM` algorithm.
394
395Prerequisites to working with the AEAD ciphers APIs:
396* Initialize the library with a successful call to `psa_crypto_init`.
397* The key policy for the key used for derivation must be configured accordingly (`PSA_KEY_USAGE_ENCRYPT` or `PSA_KEY_USAGE_DECRYPT`).
398
399To authenticate and encrypt a message:
400```C
401 int slot = 1;
402 psa_status_t status;
403 unsigned char key[] = { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
404 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF };
405
406 unsigned char nonce[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
407 0x08, 0x09, 0x0A, 0x0B };
408
409 unsigned char additional_data[] = { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20,
410 0xC3, 0x3C, 0x49, 0xFD, 0x70 };
411
412 unsigned char input_data[] = { 0xB9, 0x6B, 0x49, 0xE2, 0x1D, 0x62, 0x17, 0x41,
413 0x63, 0x28, 0x75, 0xDB, 0x7F, 0x6C, 0x92, 0x43,
414 0xD2, 0xD7, 0xC2 };
415 unsigned char *output_data = NULL;
416 size_t output_size = 0;
417 size_t output_length = 0;
418 size_t tag_length = 16;
419
420 output_size = sizeof(input_data) + tag_length;
421 output_data = malloc(output_size);
422 status = psa_crypto_init();
423
424 psa_key_policy_init(&policy);
425 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_ENCRYPT, PSA_ALG_CCM);
426 status = psa_set_key_policy(slot, &policy);
427
428 status = psa_import_key(slot, PSA_KEY_TYPE_AES, key, sizeof(key));
429
430 status = psa_aead_encrypt(slot, PSA_ALG_CCM,
431 nonce, sizeof(nonce),
432 additional_data, sizeof(additional_data),
433 input_data, sizeof(input_data),
434 output_data, output_size,
435 &output_length);
436
437 psa_destroy_key(slot);
438 mbedtls_free(output_data);
439 mbedtls_psa_crypto_free();
440```
441
442To authenticate and decrypt a message:
443
444```C
445 int slot = 1;
446 psa_status_t status;
447 unsigned char key[] = {
448 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
449 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF
450 };
451
452 unsigned char nonce[] = { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20, 0xC3,
453 0x3C, 0x49, 0xFD, 0x70
454 };
455
456 unsigned char additional_data[] = { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20,
457 0xC3, 0x3C, 0x49, 0xFD, 0x70
458 };
459 unsigned char input_data[] = { 0xB9, 0x6B, 0x49, 0xE2, 0x1D, 0x62, 0x17, 0x41,
460 0x63, 0x28, 0x75, 0xDB, 0x7F, 0x6C, 0x92, 0x43,
461 0xD2, 0xD7, 0xC2
462 };
463 unsigned char *output_data = NULL;
464 size_t output_size = 0;
465 size_t output_length = 0;
466
467 output_size = sizeof(input_data);
468 output_data = malloc(output_size);
469 status = psa_crypto_init();
470
471 psa_key_policy_init(&policy);
472 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_DECRYPT, PSA_ALG_CCM);
473 status = psa_set_key_policy(slot, &policy);
474
475 status = psa_import_key(slot, PSA_KEY_TYPE_AES, key, sizeof(key));
476
477 status = psa_aead_decrypt(slot, PSA_ALG_CCM,
478 nonce, sizeof(nonce),
479 additional_data, sizeof(additional_data),
480 input_data, sizeof(input_data),
481 output_data, output_size,
482 &output_length);
483
484 psa_destroy_key(slot);
485 mbedtls_free(output_data);
486 mbedtls_psa_crypto_free();
487```
488
489### Generating and exporting keys
490
491Mbed Crypto provides a simple way to generate a key or key pair.
492
493Prerequisites to using key generation and export APIs:
494* Initialize the library with a successful call to `psa_crypto_init`.
495
496Generate a piece of random 128-bit AES data:
4971. 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`.
4981. Generate a random AES key by calling `psa_generate_key()`.
4991. Export the generated key by calling `psa_export_key()`:
500```C
501 int slot = 1;
502 size_t bits = 128;
503 size_t exported_size = bits;
504 size_t exported_length = 0;
505 uint8_t *exported = malloc(exported_size);
506
507 psa_crypto_init();
508
509 psa_key_policy_init(&policy);
510 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_EXPORT, PSA_ALG_GCM);
511 psa_set_key_policy(slot, &policy);
512
513 /* Generate a key */
514 psa_generate_key(slot, PSA_KEY_TYPE_AES, bits, NULL, 0);
515
516 psa_export_key(slot, exported, exported_size, &exported_length)
517
518 psa_destroy_key(slot);
519 mbedtls_psa_crypto_free();
520```
521
522### More about the Mbed Crypto library
523
524More information on [Mbed Crypto](https://github.com/ARMmbed/mbed-crypto/).
525
526More information on [PSA Crypto](https://github.com/ARMmbed/mbed-crypto/blob/development/docs/PSA_Crypto_API_Overview.pdf).