1 /*******************************************************************************
2 * File Name: cyhal_crypto_common.c
3 *
4 * Description:
5 * Provides a high level interface for interacting with the Infineon Crypto Accelerator.
6 * This is a wrapper around the lower level PDL API.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
11 * an affiliate of Cypress Semiconductor Corporation
12 *
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 *     http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27 
28 #include "cyhal_hwmgr.h"
29 #include "cyhal_crypto_common.h"
30 
31 #if (_CYHAL_DRIVER_AVAILABLE_CRYPTO)
32 
33 #if defined(__cplusplus)
34 extern "C"
35 {
36 #endif
37 
38 static CRYPTO_Type* const _CYHAL_CRYPTO_BASE_ADDRESSES[CYHAL_CRYPTO_INST_COUNT] =
39 {
40 #if defined (CRYPTO)
41     CRYPTO,
42 #endif
43 };
44 
45 // Number of Crypto features
46 #define _CYHAL_CRYPTO_FEATURES_NUM         ((uint32_t)CYHAL_CRYPTO_COMMON + 1u)
47 
48 // Defines for maximum available features in Crypto block
49 #define _CYHAL_CRYPTO_FEATURE_CRC_MAX_VAL         (1u)
50 #define _CYHAL_CRYPTO_FEATURE_TRNG_MAX_VAL        (1u)
51 #define _CYHAL_CRYPTO_FEATURE_VU_MAX_VAL          (256u)
52 #define _CYHAL_CRYPTO_FEATURE_COMMON_MAX_VAL      (256u)
53 
54 static uint16_t _cyhal_crypto_features[CYHAL_CRYPTO_INST_COUNT][_CYHAL_CRYPTO_FEATURES_NUM] = {{0}};
55 static uint16_t _cyhal_crypto_features_max_val[_CYHAL_CRYPTO_FEATURES_NUM] = {_CYHAL_CRYPTO_FEATURE_CRC_MAX_VAL,
56                                                                      _CYHAL_CRYPTO_FEATURE_TRNG_MAX_VAL,
57                                                                      _CYHAL_CRYPTO_FEATURE_VU_MAX_VAL,
58                                                                      _CYHAL_CRYPTO_FEATURE_COMMON_MAX_VAL};
59 
_cyhal_crypto_enabled(uint32_t instance_count)60 static bool _cyhal_crypto_enabled(uint32_t instance_count)
61 {
62     uint8_t reserved = (uint8_t)(_cyhal_crypto_features[instance_count][CYHAL_CRYPTO_CRC]  |
63                                  _cyhal_crypto_features[instance_count][CYHAL_CRYPTO_TRNG] |
64                                  _cyhal_crypto_features[instance_count][CYHAL_CRYPTO_VU]   |
65                                  _cyhal_crypto_features[instance_count][CYHAL_CRYPTO_COMMON]);
66 
67     return (reserved != 0);
68 }
69 
cyhal_crypto_reserve(CRYPTO_Type ** base,cyhal_resource_inst_t * resource,cyhal_crypto_feature_t feature)70 cy_rslt_t cyhal_crypto_reserve(CRYPTO_Type** base, cyhal_resource_inst_t *resource, cyhal_crypto_feature_t feature)
71 {
72     cy_rslt_t result = CYHAL_HWMGR_RSLT_ERR_INUSE;
73 
74     for (uint32_t i = 0u; i < CYHAL_CRYPTO_INST_COUNT; i++)
75     {
76         if (_cyhal_crypto_features[i][feature] < _cyhal_crypto_features_max_val[feature])
77         {
78             resource->type = CYHAL_RSC_CRYPTO;
79             resource->block_num = (uint8_t)i;
80             resource->channel_num = 0;
81             *base = _CYHAL_CRYPTO_BASE_ADDRESSES[i];
82 
83             result = CY_RSLT_SUCCESS;
84 
85             //Enable block if this as this first feature that is reserved in block
86             if (!_cyhal_crypto_enabled(i))
87             {
88                 result = cyhal_hwmgr_reserve(resource);
89                 if (result == CY_RSLT_SUCCESS)
90                 {
91 #if defined(CY_IP_MXCRYPTO)
92                     Cy_Crypto_Core_Enable(*base);
93 #elif defined(CY_IP_M0S8CRYPTO) || defined(CY_IP_M0S8CRYPTOLITE)
94                     Cy_Crypto_Enable(*base);
95 #endif
96                 }
97             }
98 
99             if(result == CY_RSLT_SUCCESS)
100             {
101                 ++_cyhal_crypto_features[i][feature];
102                 break;
103             }
104         }
105     }
106     return result;
107 }
108 
cyhal_crypto_free(CRYPTO_Type * base,cyhal_resource_inst_t * resource,cyhal_crypto_feature_t feature)109 void cyhal_crypto_free(CRYPTO_Type* base, cyhal_resource_inst_t *resource, cyhal_crypto_feature_t feature)
110 {
111     if (_cyhal_crypto_features[resource->block_num][feature] != 0)
112     {
113         --_cyhal_crypto_features[resource->block_num][feature];
114     }
115 
116     //If this was the last feature then free the underlying crypto block as well.
117     if (!_cyhal_crypto_enabled(resource->block_num))
118     {
119 #if defined(CY_IP_MXCRYPTO)
120         if (Cy_Crypto_Core_IsEnabled(base))
121         {
122             Cy_Crypto_Core_Disable(base);
123         }
124 #elif defined(CY_IP_M0S8CRYPTO) || defined(CY_IP_M0S8CRYPTOLITE)
125         if (Cy_Crypto_IsEnabled(base))
126         {
127             Cy_Crypto_Disable(base);
128         }
129 #else
130         CY_UNUSED_PARAMETER(base);
131 #endif
132         cyhal_hwmgr_free(resource);
133         resource->type = CYHAL_RSC_INVALID;
134     }
135 }
136 
137 #if defined(__cplusplus)
138 }
139 #endif
140 
141 #endif /* _CYHAL_DRIVER_AVAILABLE_CRYPTO */
142