1 /* cryptoCell.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <wolfssl/wolfcrypt/settings.h>
27
28 /* This source is included in wc_port.c */
29 /* WOLFSSL_CRYPTOCELL_C is defined by wc_port.c in case compile tries to
30 include this .c directly */
31 #ifdef WOLFSSL_CRYPTOCELL_C
32
33 #ifdef WOLFSSL_CRYPTOCELL
34
35 #include <wolfssl/wolfcrypt/error-crypt.h>
36 #include <wolfssl/wolfcrypt/logging.h>
37 #include <wolfssl/wolfcrypt/ecc.h>
38 #include <wolfssl/wolfcrypt/port/arm/cryptoCell.h>
39
40 #ifdef NO_INLINE
41 #include <wolfssl/wolfcrypt/misc.h>
42 #else
43 #define WOLFSSL_MISC_INCLUDED
44 #include <wolfcrypt/src/misc.c>
45 #endif
46
47 /* Global Variables (extern) */
48 CRYS_RND_State_t wc_rndState;
49 CRYS_RND_WorkBuff_t wc_rndWorkBuff;
50 SaSiRndGenerateVectWorkFunc_t wc_rndGenVectFunc = CRYS_RND_GenerateVector;
51
52 static word32 cc310_enableCount = 0;
53
cc310_enable(void)54 static void cc310_enable(void)
55 {
56 cc310_enableCount++;
57
58 /* Enable the CC310 HW/IQ once*/
59
60 NRF_CRYPTOCELL->ENABLE = 1;
61 NVIC_EnableIRQ(CRYPTOCELL_IRQn);
62 }
63
cc310_disable(void)64 static void cc310_disable(void)
65 {
66 cc310_enableCount--;
67
68 /* Disable HW/IRQ if no more users */
69 if (cc310_enableCount == 0) {
70 NRF_CRYPTOCELL->ENABLE = 0;
71 NVIC_DisableIRQ(CRYPTOCELL_IRQn);
72 }
73 }
74
cc310_Init(void)75 int cc310_Init(void)
76 {
77 int ret = 0;
78 static int initialized = 0;
79
80 if (!initialized) {
81 /* Enable the CC310 HW. */
82 cc310_enable();
83
84 /*Initialize the CC310 run-time library*/
85 ret = SaSi_LibInit();
86
87 if (ret != SA_SILIB_RET_OK) {
88 WOLFSSL_MSG("Error SaSi_LibInit");
89 return ret;
90 }
91
92 /* RNG CryptoCell CC310 */
93 ret = CRYS_RndInit(&wc_rndState, &wc_rndWorkBuff);
94 if (ret != CRYS_OK) {
95 WOLFSSL_MSG("Error CRYS_RndInit");
96 return ret;
97 }
98 initialized = 1;
99 }
100 return ret;
101 }
102
cc310_Free(void)103 void cc310_Free(void)
104 {
105 CRYSError_t crys_result;
106
107 SaSi_LibFini();
108
109 crys_result = CRYS_RND_UnInstantiation(&wc_rndState);
110
111 if (crys_result != CRYS_OK) {
112 WOLFSSL_MSG("Error RYS_RND_UnInstantiation");
113 }
114 cc310_disable();
115 }
116
cc310_random_generate(byte * output,word32 size)117 int cc310_random_generate(byte* output, word32 size)
118 {
119 CRYSError_t crys_result;
120
121 crys_result = CRYS_RND_GenerateVector(&wc_rndState, size, output);
122
123 return (crys_result == CRYS_OK) ? 0 : -1;
124 }
125 #ifdef HAVE_ECC
cc310_mapCurve(int curve_id)126 CRYS_ECPKI_DomainID_t cc310_mapCurve(int curve_id)
127 {
128 switch(curve_id)
129 {
130 case ECC_CURVE_DEF: return CRYS_ECPKI_DomainID_secp256r1; /* default */
131 case ECC_SECP160K1: return CRYS_ECPKI_DomainID_secp160k1;
132 case ECC_SECP160R1: return CRYS_ECPKI_DomainID_secp160r1;
133 case ECC_SECP160R2: return CRYS_ECPKI_DomainID_secp160r2;
134 case ECC_SECP192K1: return CRYS_ECPKI_DomainID_secp192k1;
135 case ECC_SECP192R1: return CRYS_ECPKI_DomainID_secp192r1;
136 case ECC_SECP224K1: return CRYS_ECPKI_DomainID_secp224k1;
137 case ECC_SECP224R1: return CRYS_ECPKI_DomainID_secp224r1;
138 case ECC_SECP256K1: return CRYS_ECPKI_DomainID_secp256k1;
139 case ECC_SECP256R1: return CRYS_ECPKI_DomainID_secp256r1;
140 case ECC_SECP384R1: return CRYS_ECPKI_DomainID_secp384r1;
141 case ECC_SECP521R1: return CRYS_ECPKI_DomainID_secp521r1;
142 default: WOLFSSL_MSG("Curve not identified");
143 return CRYS_ECPKI_DomainID_Builded;
144 }
145 }
146 #endif /* HAVE_ECC */
147
148 #ifndef NO_RSA
cc310_hashModeRSA(enum wc_HashType hash_type,int isHashed)149 CRYS_RSA_HASH_OpMode_t cc310_hashModeRSA(enum wc_HashType hash_type, int isHashed)
150 {
151 switch(hash_type)
152 {
153 case WC_HASH_TYPE_MD5:
154 #ifndef NO_MD5
155 return isHashed? CRYS_RSA_After_MD5_mode : CRYS_RSA_HASH_MD5_mode;
156 #endif
157 case WC_HASH_TYPE_SHA:
158 #ifndef NO_SHA
159 return isHashed? CRYS_RSA_After_SHA1_mode : CRYS_RSA_HASH_SHA1_mode;
160 #endif
161 case WC_HASH_TYPE_SHA224:
162 #ifdef WOLFSSL_SHA224
163 return isHashed? CRYS_RSA_After_SHA224_mode : CRYS_RSA_HASH_SHA224_mode;
164 #endif
165 case WC_HASH_TYPE_SHA256:
166 #ifndef NO_SHA256
167 return isHashed? CRYS_RSA_After_SHA256_mode : CRYS_RSA_HASH_SHA256_mode;
168 #endif
169 case WC_HASH_TYPE_SHA384:
170 #ifdef WOLFSSL_SHA384
171 return isHashed? CRYS_RSA_After_SHA384_mode : CRYS_RSA_HASH_SHA384_mode;
172 #endif
173 case WC_HASH_TYPE_SHA512:
174 #ifdef WOLFSSL_SHA512
175 return isHashed? CRYS_RSA_After_SHA512_mode : CRYS_RSA_HASH_SHA512_mode;
176 #endif
177 case WC_HASH_TYPE_NONE:
178 /* default to SHA256 */
179 return isHashed? CRYS_RSA_After_SHA256_mode : CRYS_RSA_HASH_SHA256_mode;
180 default:
181 return CRYS_RSA_After_HASH_NOT_KNOWN_mode;
182 }
183 }
184 #endif /* !NO_RSA */
185
186 #ifdef HAVE_ECC
cc310_hashModeECC(int hash_size)187 CRYS_ECPKI_HASH_OpMode_t cc310_hashModeECC(int hash_size)
188 {
189 CRYS_ECPKI_HASH_OpMode_t hash_mode;
190 switch (hash_size)
191 {
192 case 20:
193 hash_mode = CRYS_ECPKI_AFTER_HASH_SHA1_mode;
194 break;
195 case 28:
196 hash_mode = CRYS_ECPKI_AFTER_HASH_SHA224_mode;
197 break;
198 case 32:
199 hash_mode = CRYS_ECPKI_AFTER_HASH_SHA256_mode;
200 break;
201 case 48:
202 hash_mode = CRYS_ECPKI_AFTER_HASH_SHA384_mode;
203 break;
204 case 64:
205 hash_mode = CRYS_ECPKI_AFTER_HASH_SHA512_mode;
206 break;
207 default:
208 hash_mode = CRYS_ECPKI_HASH_OpModeLast;
209 break;
210 }
211 return hash_mode;
212 }
213 #endif /* HAVE_ECC */
214 #endif /* WOLFSSL_CRYPTOCELL*/
215
216 #if !defined(NO_CRYPT_BENCHMARK) && defined(WOLFSSL_nRF5x_SDK_15_2)
217
218 static int mRtcSec = 0;
219 static const nrfx_rtc_t rtc = NRFX_RTC_INSTANCE(0);
220
rtc_handler(nrfx_rtc_int_type_t int_type)221 static void rtc_handler(nrfx_rtc_int_type_t int_type)
222 {
223 if (int_type == NRFX_RTC_INT_COMPARE0) {
224 mRtcSec++;
225 nrfx_rtc_counter_clear(&rtc);
226 nrfx_rtc_int_enable(&rtc, RTC_CHANNEL_INT_MASK(0));
227 #ifdef BSP_LED_1
228 nrf_gpio_pin_toggle(BSP_LED_1);
229 #endif
230 }
231 else if (int_type == NRF_DRV_RTC_INT_TICK) {
232 #ifdef BSP_LED_0
233 nrf_gpio_pin_toggle(BSP_LED_0);
234 #endif
235 }
236 }
237
rtc_config(void)238 static void rtc_config(void)
239 {
240 uint32_t err_code;
241 nrfx_rtc_config_t config = NRFX_RTC_DEFAULT_CONFIG;
242
243 /* configure gpio for pin toggling. */
244 bsp_board_init(BSP_INIT_LEDS);
245
246 /* start the internal LFCLK XTAL oscillator.*/
247 err_code = nrf_drv_clock_init();
248 APP_ERROR_CHECK(err_code);
249 nrf_drv_clock_lfclk_request(NULL);
250
251 /* Initialize RTC instance */
252 err_code = nrfx_rtc_init(&rtc, &config, rtc_handler);
253 APP_ERROR_CHECK(err_code);
254
255 /* Enable tick event */
256 nrfx_rtc_tick_enable(&rtc, false);
257
258 /* Set compare channel to trigger interrupt after 1 seconds */
259 err_code = nrfx_rtc_cc_set(&rtc, 0, RTC_INPUT_FREQ, true);
260 APP_ERROR_CHECK(err_code);
261
262 /* Power on RTC instance */
263 nrfx_rtc_enable(&rtc);
264 }
265
rtc_get_ms(void)266 static int rtc_get_ms(void)
267 {
268 /* Prescaler is 12-bit for COUNTER: frequency = (32768/(PRESCALER+1)) */
269 int frequency = (RTC_INPUT_FREQ / (rtc_prescaler_get(rtc.p_reg) + 1));
270 uint32_t counter = nrfx_rtc_counter_get(&rtc);
271
272 /* Convert with rounding frequency to milliseconds */
273 return ((counter * 1000) + (frequency / 2) ) / frequency;
274 }
275
current_time(int reset)276 double current_time(int reset)
277 {
278 double time;
279 static int initialized = 0;
280
281 if (!initialized) {
282 rtc_config();
283 initialized = 1;
284 }
285 time = mRtcSec;
286 time += (double)rtc_get_ms() / 1000;
287
288 return time;
289 }
290
nrf_random_generate(byte * output,word32 size)291 int nrf_random_generate(byte* output, word32 size)
292 {
293 uint32_t err_code;
294 static int initialized = 0;
295
296 /* RNG must be initialized once */
297 if (!initialized) {
298 err_code = nrf_drv_rng_init(NULL);
299 if (err_code != NRF_SUCCESS) {
300 return -1;
301 }
302 initialized = 1;
303 }
304 nrf_drv_rng_block_rand(output, size);
305 return 0;
306 }
307 #endif /* !NO_CRYPT_BENCHMARK && WOLFSSL_nRF5x_SDK_15_2 */
308
309 #endif /* WOLFSSL_CRYPTOCELL_C */
310