Flipper Zero Firmware
Loading...
Searching...
No Matches
furi_hal_crypto.h File Reference

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.
 

Detailed Description

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:

  • 0 - Master key for secure key delivery. Impossible to use for anything but key provisioning. We don't plan to use it too.
  • 1 - 10 - Keys used by firmware. All devices got the same set of keys. You also can use them in your applications.

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.

Macro Definition Documentation

◆ FURI_HAL_CRYPTO_ENCLAVE_FACTORY_KEY_SLOT_START

#define FURI_HAL_CRYPTO_ENCLAVE_FACTORY_KEY_SLOT_START   (1u)

Factory provisioned keys slot range.

All of them are exactly same on all flippers.

◆ FURI_HAL_CRYPTO_ENCLAVE_MASTER_KEY_SLOT

#define FURI_HAL_CRYPTO_ENCLAVE_MASTER_KEY_SLOT   (0u)

Factory provisioned master key slot.

Should never be used.

◆ FURI_HAL_CRYPTO_ENCLAVE_UNIQUE_KEY_SLOT

#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.

◆ FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_START

#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.

Enumeration Type Documentation

◆ FuriHalCryptoGCMState

FuriHalCryptoGCMState Result of a GCM operation.

Enumerator
FuriHalCryptoGCMStateOk 

operation successful

FuriHalCryptoGCMStateError 

error during encryption/decryption

FuriHalCryptoGCMStateAuthFailure 

tags do not match, auth failed

◆ FuriHalCryptoKeyType

FuriHalCryptoKey Type.

Enumerator
FuriHalCryptoKeyTypeMaster 

Master key.

FuriHalCryptoKeyTypeSimple 

Simple unencrypted key.

FuriHalCryptoKeyTypeEncrypted 

Encrypted with Master key.

Function Documentation

◆ furi_hal_crypto_ctr()

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.

Parameters
[in]keypointer to 32 bytes key data
[in]ivpointer to 12 bytes Initialization Vector data
[in]inputpointer to input data
[out]outputpointer to output data
lengthlength of the input and output in bytes
Returns
true on success

◆ furi_hal_crypto_decrypt()

bool furi_hal_crypto_decrypt ( const uint8_t * input,
uint8_t * output,
size_t size )

Decrypt data.

Parameters
inputpointer to input data
outputpointer to output data
sizeinput/output buffer size in bytes
Returns
true on success

◆ furi_hal_crypto_enclave_ensure_key()

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.

Warning
Because of the sequential nature of the secure enclave this method will generate key for all slots from FURI_HAL_CRYPTO_ENCLAVE_FACTORY_KEY_SLOT_END to the slot your requested. Keys are generated using on-chip RNG.
Parameters
[in]key_slotThe key slot to enclave
Returns
true if key exists or created, false if enclave corrupted

◆ furi_hal_crypto_enclave_load_key()

bool furi_hal_crypto_enclave_load_key ( uint8_t slot,
const uint8_t * iv )

Init AES engine and load key from crypto enclave.

Warning
Use only with furi_hal_crypto_enclave_unload_key()
Parameters
slotenclave slot
[in]ivpointer to 16 bytes Initialization Vector data
Returns
true on success

◆ furi_hal_crypto_enclave_store_key()

bool furi_hal_crypto_enclave_store_key ( FuriHalCryptoKey * key,
uint8_t * slot )

Store key in crypto enclave.

Parameters
keyFuriHalCryptoKey to be stored
slotpointer to int where enclave slot will be stored
Returns
true on success

◆ furi_hal_crypto_enclave_unload_key()

bool furi_hal_crypto_enclave_unload_key ( uint8_t slot)

Unload key and deinit AES engine.

Warning
Use only with furi_hal_crypto_enclave_load_key()
Parameters
slotenclave slot
Returns
true on success

◆ furi_hal_crypto_enclave_verify()

bool furi_hal_crypto_enclave_verify ( uint8_t * keys_nb,
uint8_t * valid_keys_nb )

Verify factory provisioned keys.

Parameters
keys_nbThe keys number of
valid_keys_nbThe valid keys number of
Returns
true if all enclave keys are intact, false otherwise

◆ furi_hal_crypto_encrypt()

bool furi_hal_crypto_encrypt ( const uint8_t * input,
uint8_t * output,
size_t size )

Encrypt data.

Parameters
inputpointer to input data
outputpointer to output data
sizeinput/output buffer size in bytes
Returns
true on success

◆ furi_hal_crypto_gcm()

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.

Parameters
[in]keypointer to 32 bytes key data
[in]ivpointer to 12 bytes Initialization Vector data
[in]aadpointer to additional authentication data
aad_lengthlength of the additional authentication data in bytes
[in]inputpointer to input data
[out]outputpointer to output data
lengthlength of the input and output in bytes
[out]tagpointer to 16 bytes space for the tag
decrypttrue for decryption, false otherwise
Returns
true on success

◆ furi_hal_crypto_gcm_decrypt_and_verify()

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.

Parameters
[in]keypointer to 32 bytes key data
[in]ivpointer to 12 bytes Initialization Vector data
[in]aadpointer to additional authentication data
aad_lengthlength of the additional authentication data in bytes
[in]inputpointer to input data
[out]outputpointer to output data
lengthlength of the input and output in bytes
[out]tagpointer to 16 bytes tag
Returns
FuriHalCryptoGCMStateOk on success, FuriHalCryptoGCMStateError on failure, FuriHalCryptoGCMStateAuthFailure if the tag does not match

◆ furi_hal_crypto_gcm_encrypt_and_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.

Parameters
[in]keypointer to 32 bytes key data
[in]ivpointer to 12 bytes Initialization Vector data
[in]aadpointer to additional authentication data
aad_lengthlength of the additional authentication data in bytes
[in]inputpointer to input data
[out]outputpointer to output data
lengthlength of the input and output in bytes
[out]tagpointer to 16 bytes space for the tag
Returns
FuriHalCryptoGCMStateOk on success, FuriHalCryptoGCMStateError on failure

◆ furi_hal_crypto_load_key()

bool furi_hal_crypto_load_key ( const uint8_t * key,
const uint8_t * iv )

Init AES engine and load supplied key.

Warning
Use only with furi_hal_crypto_unload_key()
Parameters
[in]keypointer to 32 bytes key data
[in]ivpointer to 16 bytes Initialization Vector data
Returns
true on success

◆ furi_hal_crypto_unload_key()

bool furi_hal_crypto_unload_key ( void )

Unload key and de-init AES engine.

Warning
Use this function only with furi_hal_crypto_load_key()
Returns
true on success