1 /* 2 * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef CRYPTO_CONTEXT_POOL_H 8 #define CRYPTO_CONTEXT_POOL_H 9 10 #include <stdint.h> 11 #include <service/crypto/backend/crypto_backend.h> 12 13 /** 14 * Some crypto transactions require state to be held between separate 15 * service operations. A typical multi-call transaction such as a 16 * hash calculation comprises a setup, one or more updates and a finish 17 * operation. This pool is used for allocating state context for multi-call 18 * transactions. For a well behaved client, a fresh context is allocated 19 * on a setup and freed on the finish. To cope with badly behaved clients 20 * that may never finish a transaction, if no free contexts are available 21 * for a new transaction, the least recently used active context is 22 * recycled. 23 */ 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 /** 30 * Identifier for the operation type that a context is used for. 31 */ 32 enum crypto_context_op_id 33 { 34 CRYPTO_CONTEXT_OP_ID_NONE, 35 CRYPTO_CONTEXT_OP_ID_HASH, 36 CRYPTO_CONTEXT_OP_ID_MAC, 37 CRYPTO_CONTEXT_OP_ID_CIPHER, 38 CRYPTO_CONTEXT_OP_ID_AEAD, 39 CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION 40 }; 41 42 /** 43 * A crypto context, used to hold state for a multi-step transaction. 44 */ 45 struct crypto_context 46 { 47 enum crypto_context_op_id usage; 48 uint32_t client_id; 49 uint32_t op_handle; 50 struct crypto_context *next; 51 struct crypto_context *prev; 52 53 union context_variant 54 { 55 psa_hash_operation_t hash; 56 psa_mac_operation_t mac; 57 psa_cipher_operation_t cipher; 58 psa_aead_operation_t aead; 59 psa_key_derivation_operation_t key_derivation; 60 } op; 61 }; 62 63 /** 64 * The default pool size. This may be overridden to meet the needs 65 * of a particular deployment. 66 */ 67 #ifndef CRYPTO_CONTEXT_POOL_SIZE 68 #define CRYPTO_CONTEXT_POOL_SIZE (10) 69 #endif 70 71 /** 72 * The crypto context pool structure. 73 */ 74 struct crypto_context_pool 75 { 76 struct crypto_context contexts[CRYPTO_CONTEXT_POOL_SIZE]; 77 struct crypto_context *free; 78 struct crypto_context *active_head; 79 struct crypto_context *active_tail; 80 uint32_t most_recent_op_handle; 81 }; 82 83 /* 84 * Initializes a crypto_context_pool, called once during setup. 85 */ 86 void crypto_context_pool_init(struct crypto_context_pool *pool); 87 88 /* 89 * De-initializes a crypto_context_pool, called once during tear-down. 90 */ 91 void crypto_context_pool_deinit(struct crypto_context_pool *pool); 92 93 /* 94 * Allocate a fresh context. On success, a pointer to a crypto_context object 95 * is returned and an op handle is provided for reacqiring the context during 96 * sunsequent operations. 97 */ 98 struct crypto_context *crypto_context_pool_alloc(struct crypto_context_pool *pool, 99 enum crypto_context_op_id usage, 100 uint32_t client_id, 101 uint32_t *op_handle); 102 103 /* 104 * Frees a context after use. 105 */ 106 void crypto_context_pool_free(struct crypto_context_pool *pool, 107 struct crypto_context *context); 108 109 /* 110 * Find an allocated context. Returns NULL is no qualifying context is held. 111 */ 112 struct crypto_context *crypto_context_pool_find(struct crypto_context_pool *pool, 113 enum crypto_context_op_id usage, 114 uint32_t client_id, 115 uint32_t op_handle); 116 117 118 #ifdef __cplusplus 119 } /* extern "C" */ 120 #endif 121 122 #endif /* CRYPTO_CONTEXT_POOL_H */ 123