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