mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
vfs/tresor_trust_anchor: fix alignment faults
Fixes alignment faults that occured in the AES256 implementations while wrapping or unwrapping keys on imx53_qsb, imx6q_sabrelite, and imx7d_sabre. The problem was that the unwrap_key/wrap_key functions did reinterpret casts from unsigned char pointers to uint64_t pointers and then directly used the 64 bit values of referenced by the latter. Most probably this caused the compiler to optimize operations in the assumption that the pointer is 8-byte aligned which then created alignment faults. As a solution, this commit changes the interface of the wrap_key/unwrap_key functions to take uint64 pointers as arguments instead of unsigned char pointers and then adapts the function users to ensure that they refer to appropriately aligned memory regions. Fixed #4932
This commit is contained in:
parent
6e7b66cb8a
commit
7b7851abfb
@ -97,12 +97,12 @@ void Aes_256::decrypt_with_zeroed_iv(unsigned char *plaintext_base,
|
||||
}
|
||||
|
||||
|
||||
void Aes_256_key_wrap::wrap_key(unsigned char *ciphertext_uint8,
|
||||
size_t ciphertext_size,
|
||||
unsigned char const *key_plaintext_uint8,
|
||||
size_t key_plaintext_size,
|
||||
unsigned char const *key_encryption_key_uint8,
|
||||
size_t key_encryption_key_size)
|
||||
void Aes_256_key_wrap::wrap_key(uint64_t *ciphertext_u64_ptr,
|
||||
size_t ciphertext_size,
|
||||
uint64_t const *key_plaintext_u64_ptr,
|
||||
size_t key_plaintext_size,
|
||||
uint64_t const *key_encryption_key_u64_ptr,
|
||||
size_t key_encryption_key_size)
|
||||
{
|
||||
if (ciphertext_size != CIPHERTEXT_SIZE) {
|
||||
class Bad_ciphertext_size { };
|
||||
@ -116,15 +116,10 @@ void Aes_256_key_wrap::wrap_key(unsigned char *ciphertext_uint8,
|
||||
class Bad_key_encryption_key_size { };
|
||||
throw Bad_key_encryption_key_size { };
|
||||
}
|
||||
uint64_t *ciphertext { (uint64_t *)ciphertext_uint8 };
|
||||
uint64_t const *key_plaintext { (uint64_t const *)key_plaintext_uint8 };
|
||||
uint64_t const *key_encryption_key {
|
||||
(uint64_t const *)key_encryption_key_uint8 };
|
||||
|
||||
ciphertext[0] = INTEGRITY_CHECK_VALUE;
|
||||
ciphertext_u64_ptr[0] = INTEGRITY_CHECK_VALUE;
|
||||
memcpy(
|
||||
&ciphertext[1], &key_plaintext[0],
|
||||
ciphertext_size - sizeof(ciphertext[0]));
|
||||
&ciphertext_u64_ptr[1], &key_plaintext_u64_ptr[0],
|
||||
ciphertext_size - sizeof(ciphertext_u64_ptr[0]));
|
||||
|
||||
for (unsigned step_idx = 0;
|
||||
step_idx < NR_OF_WRAPPING_STEPS;
|
||||
@ -135,8 +130,8 @@ void Aes_256_key_wrap::wrap_key(unsigned char *ciphertext_uint8,
|
||||
value_idx++) {
|
||||
|
||||
uint64_t encryption_input[2];
|
||||
encryption_input[0] = ciphertext[0];
|
||||
encryption_input[1] = ciphertext[value_idx];
|
||||
encryption_input[0] = ciphertext_u64_ptr[0];
|
||||
encryption_input[1] = ciphertext_u64_ptr[value_idx];
|
||||
|
||||
uint64_t encryption_output[2];
|
||||
|
||||
@ -144,7 +139,7 @@ void Aes_256_key_wrap::wrap_key(unsigned char *ciphertext_uint8,
|
||||
(unsigned char *)encryption_output,
|
||||
sizeof(encryption_output),
|
||||
(unsigned char *)encryption_input,
|
||||
(unsigned char *)key_encryption_key,
|
||||
(unsigned char *)key_encryption_key_u64_ptr,
|
||||
key_encryption_key_size);
|
||||
|
||||
uint64_t const xor_operand {
|
||||
@ -152,20 +147,20 @@ void Aes_256_key_wrap::wrap_key(unsigned char *ciphertext_uint8,
|
||||
((uint64_t)KEY_PLAINTEXT_NR_OF_64_BIT_VALUES * step_idx) +
|
||||
value_idx) };
|
||||
|
||||
ciphertext[0] = encryption_output[0] ^ xor_operand;
|
||||
ciphertext[value_idx] = encryption_output[1];
|
||||
ciphertext_u64_ptr[0] = encryption_output[0] ^ xor_operand;
|
||||
ciphertext_u64_ptr[value_idx] = encryption_output[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Aes_256_key_wrap::unwrap_key(unsigned char *key_plaintext_uint8,
|
||||
size_t key_plaintext_size,
|
||||
bool &key_plaintext_corrupt,
|
||||
unsigned char const *ciphertext_uint8,
|
||||
size_t ciphertext_size,
|
||||
unsigned char const *key_encryption_key_uint8,
|
||||
size_t key_encryption_key_size)
|
||||
void Aes_256_key_wrap::unwrap_key(uint64_t *key_plaintext_u64_ptr,
|
||||
size_t key_plaintext_size,
|
||||
bool &key_plaintext_corrupt,
|
||||
uint64_t const *ciphertext_u64_ptr,
|
||||
size_t ciphertext_size,
|
||||
uint64_t const *key_encryption_key_u64_ptr,
|
||||
size_t key_encryption_key_size)
|
||||
{
|
||||
if (key_plaintext_size != KEY_PLAINTEXT_SIZE) {
|
||||
class Bad_key_plaintext_size { };
|
||||
@ -179,13 +174,8 @@ void Aes_256_key_wrap::unwrap_key(unsigned char *key_plaintext_uint8,
|
||||
class Bad_key_encryption_key_size { };
|
||||
throw Bad_key_encryption_key_size { };
|
||||
}
|
||||
uint64_t *key_plaintext { (uint64_t *)key_plaintext_uint8 };
|
||||
uint64_t const *ciphertext { (uint64_t const *)ciphertext_uint8 };
|
||||
uint64_t const *key_encryption_key {
|
||||
(uint64_t const *)key_encryption_key_uint8 };
|
||||
|
||||
uint64_t integrity_check_value { ciphertext[0] };
|
||||
memcpy(&key_plaintext[0], &ciphertext[1], key_plaintext_size);
|
||||
uint64_t integrity_check_value { ciphertext_u64_ptr[0] };
|
||||
memcpy(&key_plaintext_u64_ptr[0], &ciphertext_u64_ptr[1], key_plaintext_size);
|
||||
|
||||
for (signed step_idx = NR_OF_WRAPPING_STEPS - 1;
|
||||
step_idx >= 0;
|
||||
@ -202,7 +192,7 @@ void Aes_256_key_wrap::unwrap_key(unsigned char *key_plaintext_uint8,
|
||||
|
||||
uint64_t encryption_input[2];
|
||||
encryption_input[0] = integrity_check_value ^ xor_operand;
|
||||
encryption_input[1] = key_plaintext[value_idx - 1];
|
||||
encryption_input[1] = key_plaintext_u64_ptr[value_idx - 1];
|
||||
|
||||
uint64_t encryption_output[2];
|
||||
|
||||
@ -210,11 +200,11 @@ void Aes_256_key_wrap::unwrap_key(unsigned char *key_plaintext_uint8,
|
||||
(unsigned char *)encryption_output,
|
||||
sizeof(encryption_output),
|
||||
(unsigned char *)encryption_input,
|
||||
(unsigned char *)key_encryption_key,
|
||||
(unsigned char *)key_encryption_key_u64_ptr,
|
||||
key_encryption_key_size);
|
||||
|
||||
integrity_check_value = encryption_output[0];
|
||||
key_plaintext[value_idx - 1] = encryption_output[1];
|
||||
key_plaintext_u64_ptr[value_idx - 1] = encryption_output[1];
|
||||
}
|
||||
}
|
||||
if (integrity_check_value == INTEGRITY_CHECK_VALUE) {
|
||||
|
@ -45,12 +45,12 @@ namespace Aes_256_key_wrap
|
||||
* key-encryption-key (KEK) size of 256 bits and a key (key data) size of
|
||||
* 256 bits.
|
||||
*/
|
||||
void wrap_key(unsigned char *ciphertext_uint8,
|
||||
Genode::size_t ciphertext_size,
|
||||
unsigned char const *key_plaintext_uint8,
|
||||
Genode::size_t key_plaintext_size,
|
||||
unsigned char const *key_encryption_key_uint8,
|
||||
Genode::size_t key_encryption_key_size);
|
||||
void wrap_key(Genode::uint64_t *ciphertext_u64_ptr,
|
||||
Genode::size_t ciphertext_size,
|
||||
Genode::uint64_t const *key_plaintext_u64_ptr,
|
||||
Genode::size_t key_plaintext_size,
|
||||
Genode::uint64_t const *key_encryption_key_u64_ptr,
|
||||
Genode::size_t key_encryption_key_size);
|
||||
|
||||
/**
|
||||
* Implementation of the "Key Unwrap" algorithm (alternative indexing-based
|
||||
@ -59,13 +59,13 @@ namespace Aes_256_key_wrap
|
||||
* key-encryption-key (KEK) size of 256 bits and a key (key data) size of
|
||||
* 256 bits.
|
||||
*/
|
||||
void unwrap_key(unsigned char *key_plaintext_uint8,
|
||||
Genode::size_t key_plaintext_size,
|
||||
bool &key_plaintext_corrupt,
|
||||
unsigned char const *ciphertext_uint8,
|
||||
Genode::size_t ciphertext_size,
|
||||
unsigned char const *key_encryption_key_uint8,
|
||||
Genode::size_t key_encryption_key_size);
|
||||
void unwrap_key(Genode::uint64_t *key_plaintext_u64_ptr,
|
||||
Genode::size_t key_plaintext_size,
|
||||
bool &key_plaintext_corrupt,
|
||||
Genode::uint64_t const *ciphertext_u64_ptr,
|
||||
Genode::size_t ciphertext_size,
|
||||
Genode::uint64_t const *key_encryption_key_u64_ptr,
|
||||
Genode::size_t key_encryption_key_size);
|
||||
}
|
||||
|
||||
#endif /* _AES_256_H_ */
|
||||
|
@ -68,6 +68,7 @@ class Trust_anchor
|
||||
Trust_anchor(Trust_anchor const &) = delete;
|
||||
Trust_anchor &operator=(Trust_anchor const&) = delete;
|
||||
|
||||
using uint64_t = Genode::uint64_t;
|
||||
using size_t = Genode::size_t;
|
||||
using Byte_range_ptr = Genode::Byte_range_ptr;
|
||||
using Const_byte_range_ptr = Genode::Const_byte_range_ptr;
|
||||
@ -113,8 +114,12 @@ class Trust_anchor
|
||||
|
||||
struct Private_key
|
||||
{
|
||||
unsigned char value[PRIVATE_KEY_SIZE] { };
|
||||
unsigned char value[PRIVATE_KEY_SIZE] __attribute__((aligned(sizeof(uint64_t)))) { };
|
||||
|
||||
uint64_t const *u64_ptr() const { return (uint64_t const *)value; }
|
||||
uint64_t *u64_ptr() { return (uint64_t *)value; }
|
||||
};
|
||||
|
||||
Private_key _private_key { };
|
||||
|
||||
struct Last_hash
|
||||
@ -128,9 +133,13 @@ class Trust_anchor
|
||||
struct Key
|
||||
{
|
||||
enum { KEY_LEN = 32 };
|
||||
unsigned char value[KEY_LEN] { };
|
||||
unsigned char value[KEY_LEN] __attribute__((aligned(sizeof(uint64_t)))) { };
|
||||
static constexpr size_t length = KEY_LEN;
|
||||
|
||||
uint64_t const *u64_ptr() const { return (uint64_t const *)value; }
|
||||
uint64_t *u64_ptr() { return (uint64_t *)value; }
|
||||
};
|
||||
|
||||
Key _decrypt_key { };
|
||||
Key _encrypt_key { };
|
||||
Key _generated_key { };
|
||||
@ -269,12 +278,12 @@ class Trust_anchor
|
||||
|
||||
bool private_key_corrupt;
|
||||
Aes_256_key_wrap::unwrap_key(
|
||||
_private_key.value,
|
||||
_private_key.u64_ptr(),
|
||||
sizeof(_private_key.value),
|
||||
private_key_corrupt,
|
||||
(unsigned char *)_key_io_job_buffer.base,
|
||||
_key_io_job_buffer.u64_ptr(),
|
||||
_key_io_job_buffer.size,
|
||||
(unsigned char *)_passphrase_hash_buffer.base,
|
||||
_passphrase_hash_buffer.u64_ptr(),
|
||||
_passphrase_hash_buffer.size);
|
||||
|
||||
if (private_key_corrupt) {
|
||||
@ -342,11 +351,11 @@ class Trust_anchor
|
||||
|
||||
_key_io_job_buffer.size = Aes_256_key_wrap::CIPHERTEXT_SIZE;
|
||||
Aes_256_key_wrap::wrap_key(
|
||||
(unsigned char *)_key_io_job_buffer.base,
|
||||
_key_io_job_buffer.u64_ptr(),
|
||||
_key_io_job_buffer.size,
|
||||
(unsigned char *)_private_key_io_job_buffer.base,
|
||||
_private_key_io_job_buffer.u64_ptr(),
|
||||
_private_key_io_job_buffer.size,
|
||||
(unsigned char *)_passphrase_hash_buffer.base,
|
||||
_passphrase_hash_buffer.u64_ptr(),
|
||||
_passphrase_hash_buffer.size);
|
||||
|
||||
_job_state = Job_state::PENDING;
|
||||
@ -543,13 +552,16 @@ class Trust_anchor
|
||||
|
||||
struct Private_key_io_job_buffer : Util::Io_job::Buffer
|
||||
{
|
||||
char buffer[PRIVATE_KEY_SIZE] { };
|
||||
char buffer[PRIVATE_KEY_SIZE] __attribute__((aligned(sizeof(uint64_t)))) { };
|
||||
|
||||
Private_key_io_job_buffer()
|
||||
{
|
||||
Buffer::base = buffer;
|
||||
Buffer::size = sizeof (buffer);
|
||||
}
|
||||
|
||||
uint64_t const *u64_ptr() const { return (uint64_t const *)buffer; }
|
||||
uint64_t *u64_ptr() { return (uint64_t *)buffer; }
|
||||
};
|
||||
|
||||
Vfs::Vfs_handle *_private_key_handle { nullptr };
|
||||
@ -563,24 +575,30 @@ class Trust_anchor
|
||||
|
||||
struct Key_io_job_buffer : Util::Io_job::Buffer
|
||||
{
|
||||
char buffer[Aes_256_key_wrap::CIPHERTEXT_SIZE] { };
|
||||
char buffer[Aes_256_key_wrap::CIPHERTEXT_SIZE] __attribute__((aligned(sizeof(uint64_t)))) { };
|
||||
|
||||
Key_io_job_buffer()
|
||||
{
|
||||
Buffer::base = buffer;
|
||||
Buffer::size = sizeof (buffer);
|
||||
}
|
||||
|
||||
uint64_t const *u64_ptr() const { return (uint64_t const *)buffer; }
|
||||
uint64_t *u64_ptr() { return (uint64_t *)buffer; }
|
||||
};
|
||||
|
||||
struct Passphrase_hash_buffer : Util::Io_job::Buffer
|
||||
{
|
||||
char buffer[PASSPHRASE_HASH_SIZE] { };
|
||||
char buffer[PASSPHRASE_HASH_SIZE] __attribute__((aligned(sizeof(uint64_t)))) { };
|
||||
|
||||
Passphrase_hash_buffer()
|
||||
{
|
||||
Buffer::base = buffer;
|
||||
Buffer::size = sizeof (buffer);
|
||||
}
|
||||
|
||||
uint64_t const *u64_ptr() const { return (uint64_t const *)buffer; }
|
||||
uint64_t *u64_ptr() { return (uint64_t *)buffer; }
|
||||
};
|
||||
|
||||
Key_io_job_buffer _key_io_job_buffer { };
|
||||
|
Loading…
x
Reference in New Issue
Block a user