1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 23:48:12 +00:00
This commit is contained in:
tychovrahe 2024-11-10 22:33:11 +01:00
parent 79cf4959d3
commit 7a0a69f97a
8 changed files with 291 additions and 3 deletions

View File

@ -26,7 +26,7 @@ if BENCHMARK and PYOPT != '0':
FEATURE_FLAGS = {
"RDI": True,
"SECP256K1_ZKP": True, # required for trezor.crypto.curve.bip340 (BIP340/Taproot)
"AES_GCM": BENCHMARK,
"AES_GCM": True,
}
FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga", "haptic"]

105
core/embed/trezorhal/aes.h Normal file
View File

@ -0,0 +1,105 @@
#ifndef TREZORHAL_AES_H
#define TREZORHAL_AES_H
#include <trezor_types.h>
/* The following calls handle mode initialisation, keying and completion */
int hwgcm_init_and_key(/* initialise mode and set key */
const unsigned char key[], /* the key value */
unsigned long key_len); /* the mode context */
int hwgcm_end(void); /* the mode context */
/* The following calls handle complete messages in memory as one operation */
//
// ret_type gcm_encrypt_message( /* encrypt an entire message */
// const unsigned char iv[], /* the initialisation vector */
// unsigned long iv_len, /* and its length in bytes */
// const unsigned char hdr[], /* the header buffer */
// unsigned long hdr_len, /* and its length in bytes */
// unsigned char msg[], /* the message buffer */
// unsigned long msg_len, /* and its length in bytes */
// unsigned char tag[], /* the buffer for the tag */
// unsigned long tag_len, /* and its length in bytes */
// gcm_ctx ctx[1]); /* the mode context */
//
// /* RETURN_GOOD is returned if the input tag */
// /* matches that for the decrypted message */
// ret_type gcm_decrypt_message( /* decrypt an entire message */
// const unsigned char iv[], /* the initialisation vector */
// unsigned long iv_len, /* and its length in bytes */
// const unsigned char hdr[], /* the header buffer */
// unsigned long hdr_len, /* and its length in bytes */
// unsigned char msg[], /* the message buffer */
// unsigned long msg_len, /* and its length in bytes */
// const unsigned char tag[], /* the buffer for the tag */
// unsigned long tag_len, /* and its length in bytes */
// gcm_ctx ctx[1]); /* the mode context */
/* The following calls handle messages in a sequence of operations followed */
/* by tag computation after the sequence has been completed. In these calls */
/* the user is responsible for verfiying the computed tag on decryption */
int hwgcm_init_message(/* initialise a new message */
const unsigned char iv[], /* the initialisation vector */
unsigned long iv_len); /* the mode context */
int hwgcm_auth_header(/* authenticate the header */
const unsigned char hdr[], /* the header buffer */
unsigned long hdr_len); /* the mode context */
int hwgcm_encrypt( /* encrypt & authenticate data */
unsigned char data[], /* the data buffer */
unsigned long data_len); /* the mode context */
int hwgcm_decrypt( /* authenticate & decrypt data */
unsigned char data[], /* the data buffer */
unsigned long data_len); /* the mode context */
int hwgcm_compute_tag( /* compute authentication tag */
unsigned char tag[], /* the buffer for the tag */
unsigned long tag_len); /* the mode context */
/* The use of the following calls should be avoided if possible because
their use requires a very good understanding of the way this encryption
mode works and the way in which this code implements it in order to use
them correctly.
The gcm_auth_data routine is used to authenticate encrypted message data.
In message encryption gcm_crypt_data must be called before gcm_auth_data
is called since it is encrypted data that is authenticated. In message
decryption authentication must occur before decryption and data can be
authenticated without being decrypted if necessary.
If these calls are used it is up to the user to ensure that these routines
are called in the correct order and that the correct data is passed to
them.
When gcm_compute_tag is called it is assumed that an error in use has
occurred if both encryption (or decryption) and authentication have taken
place but the total lengths of the message data respectively authenticated
and encrypted are not the same. If authentication has taken place but
there has been no corresponding encryption or decryption operations (none
at all) only a warning is issued. This should be treated as an error if it
occurs during encryption but it is only signalled as a warning as it might
be intentional when decryption operations are involved (this avoids having
different compute tag functions for encryption and decryption). Decryption
operations can be undertaken freely after authetication but if the tag is
computed after such operations an error will be signalled if the lengths
of the data authenticated and decrypted don't match.
*/
// int gcm_auth_data(/* authenticate ciphertext data */
// const unsigned char data[], /* the data buffer */
// unsigned long data_len, /* and its length in bytes */
// hw_aes_ctx ctx[1]); /* the mode context */
//
// int gcm_crypt_data( /* encrypt or decrypt data */
// unsigned char data[], /* the data buffer */ unsigned
// long data_len, /* and its length in bytes */
// hw_aes_ctx ctx[1]); /* the mode context */
#endif

View File

@ -21,6 +21,7 @@
#include "syscall.h"
#include "aes.h"
#include "bootutils.h"
#include "button.h"
#include "display.h"
@ -642,6 +643,39 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
challenge, challenge_len, hash, hash_len,
firmware_hash_callback_wrapper, callback_context);
} break;
case SYSCALL_AES_INIT: {
const uint8_t *key = (const uint8_t *)args[0];
size_t key_len = args[1];
args[0] = hwgcm_init_and_key(key, key_len);
} break;
case SYSCALL_AES_END: {
hwgcm_end();
} break;
case SYSCALL_AES_INIT_MESSAGE: {
const uint8_t *iv = (const uint8_t *)args[0];
size_t iv_len = args[1];
args[0] = hwgcm_init_message(iv, iv_len);
} break;
case SYSCALL_AES_DECRYPT: {
uint8_t *data = (uint8_t *)args[0];
size_t data_len = args[1];
args[0] = hwgcm_decrypt(data, data_len);
} break;
case SYSCALL_AES_ENCRYPT: {
uint8_t *data = (uint8_t *)args[0];
size_t data_len = args[1];
args[0] = hwgcm_encrypt(data, data_len);
} break;
case SYSCALL_AES_AUTH_HEADER: {
const uint8_t *hdr = (const uint8_t *)args[0];
size_t hdr_len = args[1];
args[0] = hwgcm_auth_header(hdr, hdr_len);
} break;
case SYSCALL_AES_COMPUTE_TAG: {
uint8_t *tag = (uint8_t *)args[0];
size_t tag_len = args[1];
args[0] = hwgcm_compute_tag(tag, tag_len);
} break;
default:
args[0] = 0xffffffff;

View File

@ -136,6 +136,14 @@ typedef enum {
SYSCALL_FIRMWARE_GET_VENDOR,
SYSCALL_FIRMWARE_CALC_HASH,
SYSCALL_AES_INIT,
SYSCALL_AES_END,
SYSCALL_AES_INIT_MESSAGE,
SYSCALL_AES_AUTH_HEADER,
SYSCALL_AES_ENCRYPT,
SYSCALL_AES_DECRYPT,
SYSCALL_AES_COMPUTE_TAG,
} syscall_number_t;
#endif // SYSCALL_NUMBERS_H

View File

@ -607,4 +607,43 @@ secbool firmware_calc_hash(const uint8_t *challenge, size_t challenge_len,
(uint32_t)callback_context,
SYSCALL_FIRMWARE_CALC_HASH);
}
#include "aes.h"
int hwgcm_init_and_key(/* initialise mode and set key */
const unsigned char key[], /* the key value */
unsigned long key_len) {
return syscall_invoke2((uint32_t)key, key_len, SYSCALL_AES_INIT);
}
int hwgcm_end(void) { return syscall_invoke0(SYSCALL_AES_END); }
int hwgcm_init_message(/* initialise a new message */
const unsigned char iv[], /* the initialisation vector */
unsigned long iv_len) {
return syscall_invoke2((uint32_t)iv, iv_len, SYSCALL_AES_INIT_MESSAGE);
}
int hwgcm_auth_header(/* authenticate the header */
const unsigned char hdr[], /* the header buffer */
unsigned long hdr_len) {
return syscall_invoke2((uint32_t)hdr, hdr_len, SYSCALL_AES_AUTH_HEADER);
}
int hwgcm_encrypt( /* encrypt & authenticate data */
unsigned char data[], /* the data buffer */
unsigned long data_len) {
return syscall_invoke2((uint32_t)data, data_len, SYSCALL_AES_ENCRYPT);
}
int hwgcm_decrypt( /* authenticate & decrypt data */
unsigned char data[], /* the data buffer */
unsigned long data_len) {
return syscall_invoke2((uint32_t)data, data_len, SYSCALL_AES_DECRYPT);
}
int hwgcm_compute_tag( /* compute authentication tag */
unsigned char tag[], /* the buffer for the tag */
unsigned long tag_len) {
return syscall_invoke2((uint32_t)tag, tag_len, SYSCALL_AES_COMPUTE_TAG);
}
#endif

View File

@ -0,0 +1,101 @@
#include <trezor_bsp.h>
#include <trezor_model.h>
#include <trezor_rtl.h>
#include "aes.h"
#include <stm32u5xx_hal_cryp.h>
#include <stm32u5xx_hal_cryp_ex.h>
#ifdef KERNEL_MODE
static CRYP_HandleTypeDef hcryp = {0};
uint32_t g_key[32 / 4] = {0};
int hwgcm_init_and_key(/* initialise mode and set key */
const unsigned char key[], unsigned long key_len) {
__HAL_RCC_AES_CLK_ENABLE();
hcryp.Instance = AES;
hcryp.Init.Algorithm = CRYP_AES_GCM_GMAC;
hcryp.Init.DataType = CRYP_DATATYPE_8B;
hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
hcryp.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
hcryp.Init.KeyMode = CRYP_KEYMODE_NORMAL;
hcryp.Init.KeySelect = CRYP_KEYSEL_SW;
hcryp.Init.pKey = g_key;
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
switch (key_len) {
case 16:
hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
memcpy(g_key, key, 16);
break;
case 32:
hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
memcpy(g_key, key, 32);
break;
default:
return -1;
}
HAL_CRYP_Init(&hcryp);
return 0;
}
int hwgcm_end(void) { return 0; }
int hwgcm_init_message(/* initialise a new message */
const unsigned char iv[], /* the initialisation vector */
unsigned long iv_len) {
hcryp.Init.pInitVect = (uint32_t*)iv;
return 0;
}
int hwgcm_auth_header(/* authenticate the header */
const unsigned char hdr[], /* the header buffer */
unsigned long hdr_len) {
hcryp.Init.Header = (uint32_t*)hdr;
hcryp.Init.HeaderSize = hdr_len;
return 0;
}
int hwgcm_encrypt( /* encrypt & authenticate data */
unsigned char data[], /* the data buffer */
unsigned long data_len) {
HAL_CRYP_Encrypt(&hcryp, (uint32_t*)data, data_len, (uint32_t*)data,
HAL_MAX_DELAY);
return 0;
}
int hwgcm_decrypt( /* authenticate & decrypt data */
unsigned char data[], /* the data buffer */
unsigned long data_len) {
HAL_CRYP_Decrypt(&hcryp, (uint32_t*)data, data_len, (uint32_t*)data,
HAL_MAX_DELAY);
return 0;
}
int hwgcm_compute_tag( /* compute authentication tag */
unsigned char tag[], /* the buffer for the tag */
unsigned long tag_len) {
HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag, HAL_MAX_DELAY);
return 0;
}
// ret_type gcm_auth_data(/* authenticate ciphertext data */
// const unsigned char data[], /* the data buffer */
// unsigned long data_len, /* and its length in bytes */
// hw_aes_ctx ctx[1]) {
// return 0;
// }
//
// ret_type gcm_crypt_data( /* encrypt or decrypt data */
// unsigned char data[], /* the data buffer */ unsigned
// long data_len, /* and its length in bytes */
// hw_aes_ctx ctx[1]) {
// return 0;
// }
#endif

View File

@ -48,7 +48,7 @@ extern "C" {
/*#define HAL_COMP_MODULE_ENABLED */
/*#define HAL_CORDIC_MODULE_ENABLED */
/*#define HAL_CRC_MODULE_ENABLED */
/*#define HAL_CRYP_MODULE_ENABLED */
#define HAL_CRYP_MODULE_ENABLED
/*#define HAL_DAC_MODULE_ENABLED */
#define HAL_DMA2D_MODULE_ENABLED
#define HAL_DSI_MODULE_ENABLED
@ -75,7 +75,6 @@ extern "C" {
/*#define HAL_RNG_MODULE_ENABLED */
#define HAL_RTC_MODULE_ENABLED
/*#define HAL_SAI_MODULE_ENABLED */
#define HAL_CRYP_MODULE_ENABLED
#define HAL_SD_MODULE_ENABLED
/*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */

View File

@ -20,6 +20,7 @@ def stm32u5_common_files(env, defines, sources, paths):
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_cortex.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_cryp.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_cryp_ex.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_dma2d.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_dma.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_dma_ex.c",
@ -51,6 +52,7 @@ def stm32u5_common_files(env, defines, sources, paths):
sources += [
"embed/trezorhal/stm32u5/applet.c",
"embed/trezorhal/stm32u5/aes.c",
"embed/trezorhal/stm32u5/board_capabilities.c",
"embed/trezorhal/stm32u5/bootutils.c",
"embed/trezorhal/stm32u5/entropy.c",