CRYPTOEMLIB

Detailed Description

Cryptography accelerator peripheral API.

For cryptographic support, users should consider the crypto APIs of the mbedTLS library provided by Silicon Labs instead of the interface provided in em_crypto.h. The mbedTLS library provides a much richer crypto API, including hardware acceleration of several functions.

The main purpose of em_crypto.h is to implement a thin software interface for the CRYPTO hardware functions especially for the accelerated APIs of the mbedTLS library. Additionally em_crypto.h implement the AES API of the em_aes.h (supported by classic EFM32) for backwards compatibility. The following list summarizes the em_crypto.h inteface:

AES

The AES APIs include support for AES-128 and AES-256 with block cipher modes:

CBC - Cipher Block Chaining mode

CFB - Cipher Feedback mode

CTR - Counter mode

ECB - Electronic Code Book mode

OFB - Output Feedback mode

For the AES APIs input/output data (plaintext, ciphertext, key, and so on) are treated as byte arrays, starting with most significant byte. In other words, 32 bytes of plaintext (B0...B31) is located in memory in the same order, with B0 at the lower address and B31 at the higher address.

Byte arrays must always be a multiple of AES block size, ie. a multiple of 16. Padding, if required, is done at the end of the byte array.

Byte arrays should be word (32 bit) aligned for performance considerations, since the array is accessed with 32 bit access type. The core MCUs supports unaligned accesses, but with a performance penalty.

It is possible to specify the same output buffer as input buffer as long as they point to the same address. In that case the provided input buffer is replaced with the encrypted/decrypted output. Notice that the buffers must be exactly overlapping. If partly overlapping, the behavior is undefined.

It is up to the user to use a cipher mode according to its requirements to avoid breaking security. See the specific cipher mode theory for details.

CRYPTO_Mul

CRYPTO_Mul is a function for multiplying big integers that are bigger than the operand size of the MUL instruction, which is 128 bits. CRYPTO_Mul multiplies all partial operands of the input operands using MUL to form a resulting number which may be twice the size of the operands.

CRPYTO_Mul is typically used by RSA implementations, which perform a huge amount of multiplication and square operations to implement modular exponentiation. Some RSA implementations use a number representation including arrays of 32bit words of variable size. Compile with -D USE_VARIABLE_SIZED_DATA_LOADS in order to load these numbers directly into CRYPTO without converting the number representation.

Load and Execute Instruction Sequences

The functions for loading data and executing instruction sequences can be used to implement complex algorithms like elliptic curve cryptography (ECC)) and authenticated encryption algorithms. There are two typical modes of operation:

Multi-sequence operation

Single static instruction sequence operation

In multi-sequence mode the software starts by loading input data, an instruction sequence, execute, and finally read the result. This process is repeated until the full crypto operation is complete.

When using a single static instruction sequence, only one instruction sequence is loaded initially. The sequence can be set up to run multiple times. Data can be loaded during the execution of the sequence by using DMA, BUFC and/or programmed I/O directly from the MCU core. For details about how to program the instruction sequences, see the reference manual of the particular Silicon Labs device.

To load input data to the CRYPTO module, use any of the following functions:

Default instruction sequence consisting of all ENDs. The user can initialize the instruction sequence with this default value set and fill in the desired operations from step 1. The first END instruction marks the end of the sequence.

Definition at line 556 of file em_crypto.h.

#define CRYPTO_MAX_SEQUENCE_INSTRUCTIONS (20)

The maximum number of crypto instructions in an instruction sequence.

Definition at line 541 of file em_crypto.h.

Typedef Documentation

typedef void(* CRYPTO_AES_CtrFuncPtr_TypeDef) (uint8_t *ctr)

AES counter modification function pointer.

Note

This is defined for backwards compatibility with EFM32 em_aes.h. The CRYPTO implementation of counter mode does not support counter update callbacks.

Instruction sequence type. Fill in the desired operations from step1, step2, and so on. The CRYPTO_CMD_INSTR_END marks the end of the sequence. Bit fields are used to format the memory layout of the struct equal to the sequence registers in the CRYPTO module.

A buffer to place encrypted/decrypted data. Must be at least len long. It may be set equal to in, in which case the input buffer is overwritten.

[in]

in

A buffer holding data to encrypt/decrypt. Must be at least len long.

[in]

len

A number of bytes to encrypt/decrypt. Must be a multiple of 16.

[in]

key

When encrypting, this is the 128 bit encryption key. When decrypting, this is the 128 bit decryption key. The decryption key may be generated from the encryption key with CRYPTO_AES_DecryptKey128(). If this argument is null, the key will not be loaded, as it is assumed the key has been loaded into KEYHA previously.

This function provides a low-level API for reading one of the multi-word registers in the crypto peripheral. Applications should use CRYPTO_DataRead, CRYPTO_DDataRead or CRYPTO_QDataRead for reading the value of DATA, DDATA, and QDATA registers.

Parameters

[in]

reg

A pointer to the crypto register.

[out]

val

This is a pointer to an array that is capable of holding 4 32 bit integers that will be filled with the 128 bit value from the crypto register.

This functions reads 260 bits from the DDATA0 register in the CRYPTO module. The data value is typically output from a big integer operation (see crypto instructions) when the result width is set to 260 bits by calling CRYPTO_ResultWidthSet(cryptoResult260Bits);

This functions writes 260 bits to the DDATA0 register in the CRYPTO module. The data value is typically input to a big integer operation (see crypto instructions) when the result width is set to 260 bits by calling CRYPTO_ResultWidthSet(cryptoResult260Bits);

This function reads the most significant bit (bit 255) of the DDATA1 register via the DDATA1MSB bit field in the DSTATUS register. This can be used to quickly check the signedness of a big integer resident in the CRYPTO module.

Load a sequence of instructions to be executed on the current values in the data registers.

This function loads a sequence of instructions to the crypto module. The instructions will be executed when the CRYPTO_InstructionSequenceExecute function is called. The first END marks the end of the sequence.

This function uses the CRYPTO unit to multiply two big integer operands. If USE_VARIABLE_SIZED_DATA_LOADS is defined, the sizes of the operands may be any multiple of 32 bits. If USE_VARIABLE_SIZED_DATA_LOADS is not defined, the sizes of the operands must be a multiple of 128 bits.