mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #9638 from itayzafrir/crypto-access-control
Crypto Service - keys access controlpull/9878/head
commit
7656891179
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Arm Limited and affiliates
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "psa_crypto_access_control.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_slot_management.h"
|
||||
|
||||
#if defined(TARGET_TFM)
|
||||
#define SPM_PANIC(format, ...) \
|
||||
{ \
|
||||
while(1){}; \
|
||||
}
|
||||
#else
|
||||
#include "spm_panic.h"
|
||||
#endif
|
||||
|
||||
typedef struct psa_crypto_access_control_s {
|
||||
psa_key_handle_t key_handle;
|
||||
int32_t partition_id;
|
||||
} psa_crypto_access_control_t;
|
||||
|
||||
static psa_crypto_access_control_t crypto_access_control_arr[PSA_KEY_SLOT_COUNT];
|
||||
|
||||
static inline void psa_crypto_access_control_reset()
|
||||
{
|
||||
memset(crypto_access_control_arr, 0, sizeof(crypto_access_control_arr));
|
||||
}
|
||||
|
||||
void psa_crypto_access_control_init(void)
|
||||
{
|
||||
psa_crypto_access_control_reset();
|
||||
}
|
||||
|
||||
void psa_crypto_access_control_destroy(void)
|
||||
{
|
||||
psa_crypto_access_control_reset();
|
||||
}
|
||||
|
||||
void psa_crypto_access_control_register_handle(psa_key_handle_t key_handle, int32_t partition_id)
|
||||
{
|
||||
for (size_t i = 0; i < PSA_KEY_SLOT_COUNT; i++) {
|
||||
if (crypto_access_control_arr[i].key_handle == 0 &&
|
||||
crypto_access_control_arr[i].partition_id == 0) {
|
||||
crypto_access_control_arr[i].key_handle = key_handle;
|
||||
crypto_access_control_arr[i].partition_id = partition_id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SPM_PANIC("psa_crypto_access_control_register_handle failed");
|
||||
}
|
||||
|
||||
void psa_crypto_access_control_unregister_handle(psa_key_handle_t key_handle)
|
||||
{
|
||||
for (size_t i = 0; i < PSA_KEY_SLOT_COUNT; i++) {
|
||||
if (crypto_access_control_arr[i].key_handle == key_handle) {
|
||||
crypto_access_control_arr[i].key_handle = 0;
|
||||
crypto_access_control_arr[i].partition_id = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SPM_PANIC("psa_crypto_access_control_unregister_handle failed");
|
||||
}
|
||||
|
||||
uint8_t psa_crypto_access_control_is_handle_permitted(psa_key_handle_t key_handle, int32_t partition_id)
|
||||
{
|
||||
for (size_t i = 0; i < PSA_KEY_SLOT_COUNT; i++) {
|
||||
if (crypto_access_control_arr[i].key_handle == key_handle &&
|
||||
crypto_access_control_arr[i].partition_id == partition_id) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Arm Limited and affiliates
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_ACCESS_CONTROL_H
|
||||
#define PSA_CRYPTO_ACCESS_CONTROL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "crypto_platform.h"
|
||||
|
||||
/* initialize the module, resets all tracked information */
|
||||
void psa_crypto_access_control_init(void);
|
||||
|
||||
/* deinitialize the module, resets all tracked information */
|
||||
void psa_crypto_access_control_destroy(void);
|
||||
|
||||
/* tracks and associates the key_handle with partition_id */
|
||||
void psa_crypto_access_control_register_handle(psa_key_handle_t key_handle, int32_t partition_id);
|
||||
|
||||
/* removes tracking of the key_handle */
|
||||
void psa_crypto_access_control_unregister_handle(psa_key_handle_t key_handle);
|
||||
|
||||
/* checks if the key_handle is associated with the partition_id, returns 0 is false otherwise 1 */
|
||||
uint8_t psa_crypto_access_control_is_handle_permitted(psa_key_handle_t key_handle, int32_t partition_id);
|
||||
|
||||
#endif /* PSA_CRYPTO_ACCESS_CONTROL_H */
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
#include "crypto_platform_spe.h"
|
||||
#include "psa_crypto_srv_partition.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "psa_crypto_access_control.h"
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
|
|
@ -139,6 +140,7 @@ static void psa_crypto_init_operation(void)
|
|||
++psa_spm_init_refence_counter;
|
||||
if (psa_spm_init_refence_counter == 1) {
|
||||
memset(psa_spm_hash_clones, 0, sizeof(psa_spm_hash_clones));
|
||||
psa_crypto_access_control_init();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -176,6 +178,7 @@ static void psa_crypto_free_operation(void)
|
|||
|
||||
if (psa_spm_init_refence_counter == 0) {
|
||||
memset(psa_spm_hash_clones, 0, sizeof(psa_spm_hash_clones));
|
||||
psa_crypto_access_control_destroy();
|
||||
mbedtls_psa_crypto_free();
|
||||
}
|
||||
|
||||
|
|
@ -225,6 +228,12 @@ static void psa_mac_operation(void)
|
|||
|
||||
switch (psa_crypto.func) {
|
||||
case PSA_MAC_SIGN_SETUP: {
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_crypto.handle,
|
||||
psa_identity(msg.handle))) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
status = psa_mac_sign_setup(msg.rhandle,
|
||||
psa_crypto.handle,
|
||||
psa_crypto.alg);
|
||||
|
|
@ -232,6 +241,12 @@ static void psa_mac_operation(void)
|
|||
}
|
||||
|
||||
case PSA_MAC_VERIFY_SETUP: {
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_crypto.handle,
|
||||
psa_identity(msg.handle))) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
status = psa_mac_verify_setup(msg.rhandle,
|
||||
psa_crypto.handle,
|
||||
psa_crypto.alg);
|
||||
|
|
@ -587,6 +602,12 @@ static void psa_asymmetric_operation(void)
|
|||
SPM_PANIC("SPM read length mismatch");
|
||||
}
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_crypto.handle,
|
||||
psa_identity(msg.handle))) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (psa_crypto.func) {
|
||||
case PSA_ASYMMETRIC_SIGN: {
|
||||
uint8_t *signature;
|
||||
|
|
@ -773,6 +794,12 @@ static void psa_aead_operation()
|
|||
SPM_PANIC("SPM read length mismatch");
|
||||
}
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_crypto.handle,
|
||||
psa_identity(msg.handle))) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (psa_crypto.func) {
|
||||
case PSA_AEAD_ENCRYPT:
|
||||
case PSA_AEAD_DECRYPT: {
|
||||
|
|
@ -892,6 +919,12 @@ static void psa_symmetric_operation(void)
|
|||
|
||||
switch (psa_crypto_ipc.func) {
|
||||
case PSA_CIPHER_ENCRYPT_SETUP: {
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_crypto_ipc.handle,
|
||||
psa_identity(msg.handle))) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
status = psa_cipher_encrypt_setup(msg.rhandle,
|
||||
psa_crypto_ipc.handle,
|
||||
psa_crypto_ipc.alg);
|
||||
|
|
@ -899,6 +932,12 @@ static void psa_symmetric_operation(void)
|
|||
}
|
||||
|
||||
case PSA_CIPHER_DECRYPT_SETUP: {
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_crypto_ipc.handle,
|
||||
psa_identity(msg.handle))) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
status = psa_cipher_decrypt_setup(msg.rhandle,
|
||||
psa_crypto_ipc.handle,
|
||||
psa_crypto_ipc.alg);
|
||||
|
|
@ -1031,6 +1070,7 @@ static void psa_key_management_operation(void)
|
|||
{
|
||||
psa_msg_t msg = { 0 };
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
int32_t partition_id = 0;
|
||||
|
||||
psa_get(PSA_KEY_MNG, &msg);
|
||||
switch (msg.type) {
|
||||
|
|
@ -1055,11 +1095,19 @@ static void psa_key_management_operation(void)
|
|||
SPM_PANIC("SPM read length mismatch");
|
||||
}
|
||||
|
||||
partition_id = psa_identity(msg.handle);
|
||||
|
||||
switch (psa_key_mng.func) {
|
||||
case PSA_GET_KEY_LIFETIME: {
|
||||
size_t lifetime_length = msg.out_size[0];
|
||||
psa_key_lifetime_t lifetime;
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_key_mng.handle,
|
||||
partition_id)) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
status = psa_get_key_lifetime(psa_key_mng.handle,
|
||||
&lifetime);
|
||||
if (status == PSA_SUCCESS) {
|
||||
|
|
@ -1074,6 +1122,12 @@ static void psa_key_management_operation(void)
|
|||
size_t policy_length = msg.in_size[1];
|
||||
psa_key_policy_t policy;
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_key_mng.handle,
|
||||
partition_id)) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
bytes_read = psa_read(msg.handle, 1,
|
||||
&policy, policy_length);
|
||||
if (bytes_read != policy_length) {
|
||||
|
|
@ -1088,6 +1142,12 @@ static void psa_key_management_operation(void)
|
|||
size_t policy_size = msg.out_size[0];
|
||||
psa_key_policy_t policy;
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_key_mng.handle,
|
||||
partition_id)) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
status = psa_get_key_policy(psa_key_mng.handle, &policy);
|
||||
if (status == PSA_SUCCESS) {
|
||||
psa_write(msg.handle, 0, &policy, policy_size);
|
||||
|
|
@ -1098,7 +1158,15 @@ static void psa_key_management_operation(void)
|
|||
|
||||
case PSA_IMPORT_KEY: {
|
||||
size_t key_length = msg.in_size[1];
|
||||
uint8_t *key = mbedtls_calloc(1, key_length);
|
||||
uint8_t *key = NULL;
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_key_mng.handle,
|
||||
partition_id)) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
key = mbedtls_calloc(1, key_length);
|
||||
if (key == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
break;
|
||||
|
|
@ -1117,13 +1185,30 @@ static void psa_key_management_operation(void)
|
|||
}
|
||||
|
||||
case PSA_DESTROY_KEY: {
|
||||
status = psa_destroy_key(psa_key_mng.handle);
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_key_mng.handle,
|
||||
partition_id)) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
status = psa_destroy_key(psa_key_mng.handle);
|
||||
if (status == PSA_SUCCESS) {
|
||||
psa_crypto_access_control_unregister_handle(psa_key_mng.handle);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PSA_GET_KEY_INFORMATION: {
|
||||
psa_key_type_t type;
|
||||
size_t bits;
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_key_mng.handle,
|
||||
partition_id)) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
status = psa_get_key_information(psa_key_mng.handle,
|
||||
&type, &bits);
|
||||
if (msg.out_size[0] >= sizeof(psa_key_type_t))
|
||||
|
|
@ -1139,7 +1224,15 @@ static void psa_key_management_operation(void)
|
|||
case PSA_EXPORT_KEY: {
|
||||
size_t key_length = msg.out_size[0];
|
||||
size_t data_length;
|
||||
uint8_t *key = mbedtls_calloc(1, key_length);
|
||||
uint8_t *key = NULL;
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_key_mng.handle,
|
||||
partition_id)) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
key = mbedtls_calloc(1, key_length);
|
||||
if (key == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
break;
|
||||
|
|
@ -1160,7 +1253,15 @@ static void psa_key_management_operation(void)
|
|||
case PSA_EXPORT_PUBLIC_KEY: {
|
||||
size_t key_length = msg.out_size[0];
|
||||
size_t data_length;
|
||||
uint8_t *key = mbedtls_calloc(1, key_length);
|
||||
uint8_t *key = NULL;
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_key_mng.handle,
|
||||
partition_id)) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
key = mbedtls_calloc(1, key_length);
|
||||
if (key == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
break;
|
||||
|
|
@ -1184,6 +1285,12 @@ static void psa_key_management_operation(void)
|
|||
size_t parameter_size = msg.in_size[2];
|
||||
uint8_t *parameter = NULL;
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_key_mng.handle,
|
||||
partition_id)) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
bytes_read = psa_read(msg.handle, 1, &bits, bits_size);
|
||||
if (bytes_read != bits_size) {
|
||||
SPM_PANIC("SPM read length mismatch");
|
||||
|
|
@ -1214,6 +1321,7 @@ static void psa_key_management_operation(void)
|
|||
case PSA_ALLOCATE_KEY: {
|
||||
status = psa_allocate_key(&psa_key_mng.handle);
|
||||
if (status == PSA_SUCCESS) {
|
||||
psa_crypto_access_control_register_handle(psa_key_mng.handle, partition_id);
|
||||
psa_write(msg.handle, 0, &psa_key_mng.handle, sizeof(psa_key_mng.handle));
|
||||
}
|
||||
break;
|
||||
|
|
@ -1234,6 +1342,7 @@ static void psa_key_management_operation(void)
|
|||
|
||||
status = psa_create_key(psa_key_mng.lifetime, id, &psa_key_mng.handle);
|
||||
if (status == PSA_SUCCESS) {
|
||||
psa_crypto_access_control_register_handle(psa_key_mng.handle, partition_id);
|
||||
psa_write(msg.handle, 0, &psa_key_mng.handle, sizeof(psa_key_mng.handle));
|
||||
}
|
||||
break;
|
||||
|
|
@ -1254,13 +1363,24 @@ static void psa_key_management_operation(void)
|
|||
|
||||
status = psa_open_key(psa_key_mng.lifetime, id, &psa_key_mng.handle);
|
||||
if (status == PSA_SUCCESS) {
|
||||
psa_crypto_access_control_register_handle(psa_key_mng.handle, partition_id);
|
||||
psa_write(msg.handle, 0, &psa_key_mng.handle, sizeof(psa_key_mng.handle));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PSA_CLOSE_KEY: {
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_key_mng.handle,
|
||||
partition_id)) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
status = psa_close_key(psa_key_mng.handle);
|
||||
if (status == PSA_SUCCESS) {
|
||||
psa_crypto_access_control_unregister_handle(psa_key_mng.handle);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1443,6 +1563,12 @@ void psa_crypto_generator_operations(void)
|
|||
psa_key_type_t type;
|
||||
size_t bits;
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_crypto_ipc.handle,
|
||||
psa_identity(msg.handle))) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
bytes_read = psa_read(msg.handle, 1,
|
||||
&type, msg.in_size[1]);
|
||||
if (bytes_read != sizeof(type)) {
|
||||
|
|
@ -1466,7 +1592,15 @@ void psa_crypto_generator_operations(void)
|
|||
}
|
||||
|
||||
case PSA_KEY_DERIVATION: {
|
||||
uint8_t *salt = mbedtls_calloc(1, msg.in_size[1]);
|
||||
uint8_t *salt = NULL;
|
||||
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_crypto_ipc.handle,
|
||||
psa_identity(msg.handle))) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
salt = mbedtls_calloc(1, msg.in_size[1]);
|
||||
if (salt == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
break;
|
||||
|
|
@ -1503,8 +1637,15 @@ void psa_crypto_generator_operations(void)
|
|||
}
|
||||
|
||||
case PSA_KEY_AGREEMENT: {
|
||||
uint8_t *private_key = NULL;
|
||||
|
||||
uint8_t *private_key = mbedtls_calloc(1, msg.in_size[1]);
|
||||
if (!psa_crypto_access_control_is_handle_permitted(psa_crypto_ipc.handle,
|
||||
psa_identity(msg.handle))) {
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
private_key = mbedtls_calloc(1, msg.in_size[1]);
|
||||
if (private_key == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue