Cryptography HAL API. More...
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
Go to the source code of this file.
Data Structures | |
struct | FuriHalCryptoKey |
FuriHalCryptoKey. More... | |
Macros | |
#define | FURI_HAL_CRYPTO_ENCLAVE_MASTER_KEY_SLOT (0u) |
Factory provisioned master key slot. | |
#define | FURI_HAL_CRYPTO_ENCLAVE_FACTORY_KEY_SLOT_START (1u) |
Factory provisioned keys slot range. | |
#define | FURI_HAL_CRYPTO_ENCLAVE_FACTORY_KEY_SLOT_END (10u) |
#define | FURI_HAL_CRYPTO_ENCLAVE_UNIQUE_KEY_SLOT (11u) |
Device unique key slot. | |
#define | FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_START (12u) |
User key slot range. | |
#define | FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_END (100u) |
#define | FURI_HAL_CRYPTO_ADVANCED_AVAIL 1 |
[Deprecated] Indicates availability of advanced crypto functions, will be dropped before v1.0 | |
Enumerations | |
enum | FuriHalCryptoKeyType { FuriHalCryptoKeyTypeMaster , FuriHalCryptoKeyTypeSimple , FuriHalCryptoKeyTypeEncrypted } |
FuriHalCryptoKey Type. More... | |
enum | FuriHalCryptoKeySize { FuriHalCryptoKeySize128 , FuriHalCryptoKeySize256 } |
FuriHalCryptoKey Size in bits. | |
enum | FuriHalCryptoGCMState { FuriHalCryptoGCMStateOk , FuriHalCryptoGCMStateError , FuriHalCryptoGCMStateAuthFailure } |
FuriHalCryptoGCMState Result of a GCM operation. More... | |
Functions | |
void | furi_hal_crypto_init (void) |
Initialize cryptography layer(includes AES engines, PKA and RNG) | |
bool | furi_hal_crypto_enclave_verify (uint8_t *keys_nb, uint8_t *valid_keys_nb) |
Verify factory provisioned keys. | |
bool | furi_hal_crypto_enclave_ensure_key (uint8_t key_slot) |
Ensure that requested slot and slots before this slot contains keys. | |
bool | furi_hal_crypto_enclave_store_key (FuriHalCryptoKey *key, uint8_t *slot) |
Store key in crypto enclave. | |
bool | furi_hal_crypto_enclave_load_key (uint8_t slot, const uint8_t *iv) |
Init AES engine and load key from crypto enclave. | |
bool | furi_hal_crypto_enclave_unload_key (uint8_t slot) |
Unload key and deinit AES engine. | |
bool | furi_hal_crypto_load_key (const uint8_t *key, const uint8_t *iv) |
Init AES engine and load supplied key. | |
bool | furi_hal_crypto_unload_key (void) |
Unload key and de-init AES engine. | |
bool | furi_hal_crypto_encrypt (const uint8_t *input, uint8_t *output, size_t size) |
Encrypt data. | |
bool | furi_hal_crypto_decrypt (const uint8_t *input, uint8_t *output, size_t size) |
Decrypt data. | |
bool | furi_hal_crypto_ctr (const uint8_t *key, const uint8_t *iv, const uint8_t *input, uint8_t *output, size_t length) |
Encrypt the input using AES-CTR. | |
bool | furi_hal_crypto_gcm (const uint8_t *key, const uint8_t *iv, const uint8_t *aad, size_t aad_length, const uint8_t *input, uint8_t *output, size_t length, uint8_t *tag, bool decrypt) |
Encrypt/decrypt the input using AES-GCM. | |
FuriHalCryptoGCMState | furi_hal_crypto_gcm_encrypt_and_tag (const uint8_t *key, const uint8_t *iv, const uint8_t *aad, size_t aad_length, const uint8_t *input, uint8_t *output, size_t length, uint8_t *tag) |
Encrypt the input using AES-GCM and generate a tag. | |
FuriHalCryptoGCMState | furi_hal_crypto_gcm_decrypt_and_verify (const uint8_t *key, const uint8_t *iv, const uint8_t *aad, size_t aad_length, const uint8_t *input, uint8_t *output, size_t length, const uint8_t *tag) |
Decrypt the input using AES-GCM and verify the provided tag. | |
Cryptography HAL API.
!!! READ THIS FIRST !!!
Flipper was never designed to be secure, nor it passed cryptography audit. Despite of the fact that keys are stored in secure enclave there are some types of attack that can be performed against AES engine to recover keys(theoretical). Also there is no way to securely deliver user keys to device and never will be. In addition device is fully open and there is no way to guarantee safety of your data, it can be easily dumped with debugger or modified code.
Secure enclave on WB series is implemented on core2 FUS side and can be used only if core2 alive. Enclave is responsible for storing, loading and unloading keys to and from enclave/AES in secure manner(AES engine key registers will be locked when key from enclave loaded)
There are 11 keys that we provision at factory:
Also there is a slot 11 that we use for device unique key. This slot is intentionally left blank till the moment of first use, so you can ensure that we don't know your unique key. Also you can provision this key by your self with crypto cli or API.
Other slots can be used for your needs. But since enclave is sequential append only, we can not guarantee you that slots you want are free. NEVER USE THEM FOR PUBLIC APPLICATIONS.
Also you can directly load raw keys into AES engine and use it for your needs.
#define FURI_HAL_CRYPTO_ENCLAVE_FACTORY_KEY_SLOT_START (1u) |
Factory provisioned keys slot range.
All of them are exactly same on all flippers.
#define FURI_HAL_CRYPTO_ENCLAVE_MASTER_KEY_SLOT (0u) |
Factory provisioned master key slot.
Should never be used.
#define FURI_HAL_CRYPTO_ENCLAVE_UNIQUE_KEY_SLOT (11u) |
Device unique key slot.
This key generated on first use or provisioned by user. Use furi_hal_crypto_enclave_ensure_key before using this slot.
#define FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_START (12u) |
User key slot range.
This slots can be used for your needs, but never use them in public apps.
enum FuriHalCryptoKeyType |
bool furi_hal_crypto_ctr | ( | const uint8_t * | key, |
const uint8_t * | iv, | ||
const uint8_t * | input, | ||
uint8_t * | output, | ||
size_t | length ) |
Encrypt the input using AES-CTR.
Decryption can be performed by supplying the ciphertext as input. Inits and deinits the AES engine internally.
[in] | key | pointer to 32 bytes key data |
[in] | iv | pointer to 12 bytes Initialization Vector data |
[in] | input | pointer to input data |
[out] | output | pointer to output data |
length | length of the input and output in bytes |
bool furi_hal_crypto_decrypt | ( | const uint8_t * | input, |
uint8_t * | output, | ||
size_t | size ) |
Decrypt data.
input | pointer to input data |
output | pointer to output data |
size | input/output buffer size in bytes |
bool furi_hal_crypto_enclave_ensure_key | ( | uint8_t | key_slot | ) |
Ensure that requested slot and slots before this slot contains keys.
This function is used to provision FURI_HAL_CRYPTO_ENCLAVE_UNIQUE_KEY_SLOT. Also you may want to use it to generate some unique keys in user key slot range.
[in] | key_slot | The key slot to enclave |
bool furi_hal_crypto_enclave_load_key | ( | uint8_t | slot, |
const uint8_t * | iv ) |
Init AES engine and load key from crypto enclave.
slot | enclave slot | |
[in] | iv | pointer to 16 bytes Initialization Vector data |
bool furi_hal_crypto_enclave_store_key | ( | FuriHalCryptoKey * | key, |
uint8_t * | slot ) |
Store key in crypto enclave.
key | FuriHalCryptoKey to be stored |
slot | pointer to int where enclave slot will be stored |
bool furi_hal_crypto_enclave_unload_key | ( | uint8_t | slot | ) |
Unload key and deinit AES engine.
slot | enclave slot |
bool furi_hal_crypto_enclave_verify | ( | uint8_t * | keys_nb, |
uint8_t * | valid_keys_nb ) |
Verify factory provisioned keys.
keys_nb | The keys number of |
valid_keys_nb | The valid keys number of |
bool furi_hal_crypto_encrypt | ( | const uint8_t * | input, |
uint8_t * | output, | ||
size_t | size ) |
Encrypt data.
input | pointer to input data |
output | pointer to output data |
size | input/output buffer size in bytes |
bool furi_hal_crypto_gcm | ( | const uint8_t * | key, |
const uint8_t * | iv, | ||
const uint8_t * | aad, | ||
size_t | aad_length, | ||
const uint8_t * | input, | ||
uint8_t * | output, | ||
size_t | length, | ||
uint8_t * | tag, | ||
bool | decrypt ) |
Encrypt/decrypt the input using AES-GCM.
When decrypting the tag generated needs to be compared to the tag attached to the ciphertext in a constant-time fashion. If the tags are not equal, the decryption failed and the plaintext returned needs to be discarded. Inits and deinits the AES engine internally.
[in] | key | pointer to 32 bytes key data |
[in] | iv | pointer to 12 bytes Initialization Vector data |
[in] | aad | pointer to additional authentication data |
aad_length | length of the additional authentication data in bytes | |
[in] | input | pointer to input data |
[out] | output | pointer to output data |
length | length of the input and output in bytes | |
[out] | tag | pointer to 16 bytes space for the tag |
decrypt | true for decryption, false otherwise |
FuriHalCryptoGCMState furi_hal_crypto_gcm_decrypt_and_verify | ( | const uint8_t * | key, |
const uint8_t * | iv, | ||
const uint8_t * | aad, | ||
size_t | aad_length, | ||
const uint8_t * | input, | ||
uint8_t * | output, | ||
size_t | length, | ||
const uint8_t * | tag ) |
Decrypt the input using AES-GCM and verify the provided tag.
Inits and deinits the AES engine internally.
[in] | key | pointer to 32 bytes key data |
[in] | iv | pointer to 12 bytes Initialization Vector data |
[in] | aad | pointer to additional authentication data |
aad_length | length of the additional authentication data in bytes | |
[in] | input | pointer to input data |
[out] | output | pointer to output data |
length | length of the input and output in bytes | |
[out] | tag | pointer to 16 bytes tag |
FuriHalCryptoGCMState furi_hal_crypto_gcm_encrypt_and_tag | ( | const uint8_t * | key, |
const uint8_t * | iv, | ||
const uint8_t * | aad, | ||
size_t | aad_length, | ||
const uint8_t * | input, | ||
uint8_t * | output, | ||
size_t | length, | ||
uint8_t * | tag ) |
Encrypt the input using AES-GCM and generate a tag.
Inits and deinits the AES engine internally.
[in] | key | pointer to 32 bytes key data |
[in] | iv | pointer to 12 bytes Initialization Vector data |
[in] | aad | pointer to additional authentication data |
aad_length | length of the additional authentication data in bytes | |
[in] | input | pointer to input data |
[out] | output | pointer to output data |
length | length of the input and output in bytes | |
[out] | tag | pointer to 16 bytes space for the tag |
bool furi_hal_crypto_load_key | ( | const uint8_t * | key, |
const uint8_t * | iv ) |
Init AES engine and load supplied key.
[in] | key | pointer to 32 bytes key data |
[in] | iv | pointer to 16 bytes Initialization Vector data |
bool furi_hal_crypto_unload_key | ( | void | ) |
Unload key and de-init AES engine.