1 /*
2  * Copyright (c) 2020 Markus Fuchs <markus.fuchs@de.sauter-bc.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/init.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/device.h>
10 #include <zephyr/sys/__assert.h>
11 #include <zephyr/crypto/crypto.h>
12 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
13 #include <zephyr/drivers/clock_control.h>
14 #include <zephyr/drivers/reset.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <soc.h>
17 
18 #include "crypto_stm32_priv.h"
19 
20 #define LOG_LEVEL CONFIG_CRYPTO_LOG_LEVEL
21 #include <zephyr/logging/log.h>
22 LOG_MODULE_REGISTER(crypto_stm32);
23 
24 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_cryp)
25 #define DT_DRV_COMPAT st_stm32_cryp
26 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_aes)
27 #define DT_DRV_COMPAT st_stm32_aes
28 #else
29 #error No STM32 HW Crypto Accelerator in device tree
30 #endif
31 
32 #define CRYP_SUPPORT (CAP_RAW_KEY | CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | \
33 		      CAP_NO_IV_PREFIX)
34 #define BLOCK_LEN_BYTES 16
35 #define BLOCK_LEN_WORDS (BLOCK_LEN_BYTES / sizeof(uint32_t))
36 #define CRYPTO_MAX_SESSION CONFIG_CRYPTO_STM32_MAX_SESSION
37 
38 #if defined(CRYP_KEYSIZE_192B)
39 #define STM32_CRYPTO_KEYSIZE_192B_SUPPORT
40 #endif
41 
42 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_cryp)
43 #define STM32_CRYPTO_TYPEDEF            CRYP_TypeDef
44 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_aes)
45 #define STM32_CRYPTO_TYPEDEF            AES_TypeDef
46 #endif
47 
48 struct crypto_stm32_session crypto_stm32_sessions[CRYPTO_MAX_SESSION];
49 
50 typedef HAL_StatusTypeDef status_t;
51 
52 /**
53  * @brief Function pointer type for AES encryption/decryption operations.
54  *
55  * This type defines a function pointer for generic AES operations.
56  *
57  * @param hcryp       Pointer to a CRYP_HandleTypeDef structure that contains
58  *                    the configuration information for the CRYP module.
59  * @param in_data     Pointer to input data (plaintext for encryption or ciphertext for decryption).
60  * @param size        Length of the input data in bytes.
61  * @param out_data    Pointer to output data (ciphertext for encryption or plaintext for
62  * decryption).
63  * @param timeout     Timeout duration in milliseconds.
64  *
65  * @retval status_t  HAL status of the operation.
66  */
67 typedef status_t (*hal_cryp_aes_op_func_t)(CRYP_HandleTypeDef *hcryp, uint8_t *in_data,
68 					   uint16_t size, uint8_t *out_data, uint32_t timeout);
69 
70 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
71 #define hal_ecb_encrypt_op HAL_CRYP_AESECB_Encrypt
72 #define hal_ecb_decrypt_op HAL_CRYP_AESECB_Decrypt
73 #define hal_cbc_encrypt_op HAL_CRYP_AESCBC_Encrypt
74 #define hal_cbc_decrypt_op HAL_CRYP_AESCBC_Decrypt
75 #define hal_ctr_encrypt_op HAL_CRYP_AESCTR_Encrypt
76 #define hal_ctr_decrypt_op HAL_CRYP_AESCTR_Decrypt
77 #else
78 #define hal_ecb_encrypt_op hal_encrypt
79 #define hal_ecb_decrypt_op hal_decrypt
80 #define hal_cbc_encrypt_op hal_encrypt
81 #define hal_cbc_decrypt_op hal_decrypt
82 #define hal_ctr_encrypt_op hal_encrypt
83 #define hal_ctr_decrypt_op hal_decrypt
84 #endif
85 
86 /* L4 HAL driver uses uint8_t pointers for input/output data while the generic HAL driver uses
87  * uint32_t pointers.
88  */
89 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
90 #define CAST_VEC(x) (uint8_t *)(x)
91 #else
92 #define CAST_VEC(x) (uint32_t *)(x)
93 #endif
94 
copy_words_adjust_endianness(uint8_t * dst_buf,int dst_len,const uint8_t * src_buf,int src_len)95 static int copy_words_adjust_endianness(uint8_t *dst_buf, int dst_len, const uint8_t *src_buf,
96 					int src_len)
97 {
98 	if ((dst_len < src_len) || ((dst_len % 4) != 0)) {
99 		LOG_ERR("Buffer length error");
100 		return -EINVAL;
101 	}
102 
103 	memcpy(dst_buf, src_buf, src_len);
104 
105 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
106 	for (int i = 0; i < dst_len; i += sizeof(uint32_t)) {
107 		sys_mem_swap(&dst_buf[i], sizeof(uint32_t));
108 	}
109 #endif
110 
111 	return 0;
112 }
113 
do_aes(struct cipher_ctx * ctx,hal_cryp_aes_op_func_t fn,uint8_t * in_buf,int in_len,uint8_t * out_buf)114 static int do_aes(struct cipher_ctx *ctx, hal_cryp_aes_op_func_t fn, uint8_t *in_buf, int in_len,
115 		      uint8_t *out_buf)
116 {
117 	status_t status;
118 
119 	struct crypto_stm32_data *data = CRYPTO_STM32_DATA(ctx->device);
120 	struct crypto_stm32_session *session = CRYPTO_STM32_SESSN(ctx);
121 
122 	k_sem_take(&data->device_sem, K_FOREVER);
123 
124 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
125 	/* Device is initialized from the configuration in the encryption/decryption function
126 	 * called bellow.
127 	 */
128 	memcpy(&data->hcryp.Init, &session->config, sizeof(session->config));
129 #else
130 	status = HAL_CRYP_SetConfig(&data->hcryp, &session->config);
131 	if (status != HAL_OK) {
132 		LOG_ERR("Configuration error");
133 		k_sem_give(&data->device_sem);
134 		return -EIO;
135 	}
136 #endif
137 
138 	status = fn(&data->hcryp, in_buf, in_len, out_buf, HAL_MAX_DELAY);
139 	if (status != HAL_OK) {
140 		LOG_ERR("Encryption/decryption error");
141 		k_sem_give(&data->device_sem);
142 		return -EIO;
143 	}
144 
145 	k_sem_give(&data->device_sem);
146 
147 	return 0;
148 }
149 
150 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
hal_encrypt(CRYP_HandleTypeDef * hcryp,uint8_t * pPlainData,uint16_t Size,uint8_t * pCypherData,uint32_t Timeout)151 static status_t hal_encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size,
152 			    uint8_t *pCypherData, uint32_t Timeout)
153 {
154 	return HAL_CRYP_Encrypt(hcryp, (uint32_t *)pPlainData, Size, (uint32_t *)pCypherData,
155 				Timeout);
156 }
157 
hal_decrypt(CRYP_HandleTypeDef * hcryp,uint8_t * pCypherData,uint16_t Size,uint8_t * pPlainData,uint32_t Timeout)158 static status_t hal_decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size,
159 			    uint8_t *pPlainData, uint32_t Timeout)
160 {
161 	return HAL_CRYP_Decrypt(hcryp, (uint32_t *)pCypherData, Size, (uint32_t *)pPlainData,
162 				Timeout);
163 }
164 #endif
165 
crypto_stm32_ecb_encrypt(struct cipher_ctx * ctx,struct cipher_pkt * pkt)166 static int crypto_stm32_ecb_encrypt(struct cipher_ctx *ctx,
167 				    struct cipher_pkt *pkt)
168 {
169 	int ret;
170 
171 	/* For security reasons, ECB mode should not be used to encrypt
172 	 * more than one block. Use CBC mode instead.
173 	 */
174 	if (pkt->in_len > 16) {
175 		LOG_ERR("Cannot encrypt more than 1 block");
176 		return -EINVAL;
177 	}
178 
179 	ret = do_aes(ctx, hal_ecb_encrypt_op, pkt->in_buf, pkt->in_len, pkt->out_buf);
180 	if (ret == 0) {
181 		pkt->out_len = 16;
182 	}
183 
184 	return ret;
185 }
186 
crypto_stm32_ecb_decrypt(struct cipher_ctx * ctx,struct cipher_pkt * pkt)187 static int crypto_stm32_ecb_decrypt(struct cipher_ctx *ctx,
188 				    struct cipher_pkt *pkt)
189 {
190 	int ret;
191 
192 	/* For security reasons, ECB mode should not be used to encrypt
193 	 * more than one block. Use CBC mode instead.
194 	 */
195 	if (pkt->in_len > 16) {
196 		LOG_ERR("Cannot encrypt more than 1 block");
197 		return -EINVAL;
198 	}
199 
200 	ret = do_aes(ctx, hal_ecb_decrypt_op, pkt->in_buf, pkt->in_len, pkt->out_buf);
201 	if (ret == 0) {
202 		pkt->out_len = 16;
203 	}
204 
205 	return ret;
206 }
207 
crypto_stm32_cbc_encrypt(struct cipher_ctx * ctx,struct cipher_pkt * pkt,uint8_t * iv)208 static int crypto_stm32_cbc_encrypt(struct cipher_ctx *ctx,
209 				    struct cipher_pkt *pkt, uint8_t *iv)
210 {
211 	int ret;
212 	uint32_t vec[BLOCK_LEN_WORDS];
213 	int out_offset = 0;
214 
215 	struct crypto_stm32_session *session = CRYPTO_STM32_SESSN(ctx);
216 
217 	(void)copy_words_adjust_endianness((uint8_t *)vec, sizeof(vec), iv, BLOCK_LEN_BYTES);
218 
219 	session->config.pInitVect = CAST_VEC(vec);
220 
221 	if ((ctx->flags & CAP_NO_IV_PREFIX) == 0U) {
222 		/* Prefix IV to ciphertext unless CAP_NO_IV_PREFIX is set. */
223 		memcpy(pkt->out_buf, iv, 16);
224 		out_offset = 16;
225 	}
226 
227 	ret = do_aes(ctx, hal_cbc_encrypt_op, pkt->in_buf, pkt->in_len, pkt->out_buf + out_offset);
228 	if (ret == 0) {
229 		pkt->out_len = pkt->in_len + out_offset;
230 	}
231 
232 	return ret;
233 }
234 
crypto_stm32_cbc_decrypt(struct cipher_ctx * ctx,struct cipher_pkt * pkt,uint8_t * iv)235 static int crypto_stm32_cbc_decrypt(struct cipher_ctx *ctx,
236 				    struct cipher_pkt *pkt, uint8_t *iv)
237 {
238 	int ret;
239 	uint32_t vec[BLOCK_LEN_WORDS];
240 	int in_offset = 0;
241 
242 	struct crypto_stm32_session *session = CRYPTO_STM32_SESSN(ctx);
243 
244 	(void)copy_words_adjust_endianness((uint8_t *)vec, sizeof(vec), iv, BLOCK_LEN_BYTES);
245 
246 	session->config.pInitVect = CAST_VEC(vec);
247 
248 	if ((ctx->flags & CAP_NO_IV_PREFIX) == 0U) {
249 		in_offset = 16;
250 	}
251 
252 	ret = do_aes(ctx, hal_cbc_decrypt_op, pkt->in_buf + in_offset, pkt->in_len, pkt->out_buf);
253 	if (ret == 0) {
254 		pkt->out_len = pkt->in_len - in_offset;
255 	}
256 
257 	return ret;
258 }
259 
crypto_stm32_ctr_encrypt(struct cipher_ctx * ctx,struct cipher_pkt * pkt,uint8_t * iv)260 static int crypto_stm32_ctr_encrypt(struct cipher_ctx *ctx,
261 				    struct cipher_pkt *pkt, uint8_t *iv)
262 {
263 	int ret;
264 	uint32_t ctr[BLOCK_LEN_WORDS] = {0};
265 	int ivlen = BLOCK_LEN_BYTES - (ctx->mode_params.ctr_info.ctr_len >> 3);
266 
267 	struct crypto_stm32_session *session = CRYPTO_STM32_SESSN(ctx);
268 
269 	if (copy_words_adjust_endianness((uint8_t *)ctr, sizeof(ctr), iv, ivlen) != 0) {
270 		return -EIO;
271 	}
272 
273 	session->config.pInitVect = CAST_VEC(ctr);
274 
275 	ret = do_aes(ctx, hal_ctr_encrypt_op, pkt->in_buf, pkt->in_len, pkt->out_buf);
276 	if (ret == 0) {
277 		pkt->out_len = pkt->in_len;
278 	}
279 
280 	return ret;
281 }
282 
crypto_stm32_ctr_decrypt(struct cipher_ctx * ctx,struct cipher_pkt * pkt,uint8_t * iv)283 static int crypto_stm32_ctr_decrypt(struct cipher_ctx *ctx,
284 				    struct cipher_pkt *pkt, uint8_t *iv)
285 {
286 	int ret;
287 	uint32_t ctr[BLOCK_LEN_WORDS] = {0};
288 	int ivlen = BLOCK_LEN_BYTES - (ctx->mode_params.ctr_info.ctr_len >> 3);
289 
290 	struct crypto_stm32_session *session = CRYPTO_STM32_SESSN(ctx);
291 
292 	if (copy_words_adjust_endianness((uint8_t *)ctr, sizeof(ctr), iv, ivlen) != 0) {
293 		return -EIO;
294 	}
295 
296 	session->config.pInitVect = CAST_VEC(ctr);
297 
298 	ret = do_aes(ctx, hal_ctr_decrypt_op, pkt->in_buf, pkt->in_len, pkt->out_buf);
299 	if (ret == 0) {
300 		pkt->out_len = pkt->in_len;
301 	}
302 
303 	return ret;
304 }
305 
crypto_stm32_get_unused_session_index(const struct device * dev)306 static int crypto_stm32_get_unused_session_index(const struct device *dev)
307 {
308 	int i;
309 
310 	struct crypto_stm32_data *data = CRYPTO_STM32_DATA(dev);
311 
312 	k_sem_take(&data->session_sem, K_FOREVER);
313 
314 	for (i = 0; i < CRYPTO_MAX_SESSION; i++) {
315 		if (!crypto_stm32_sessions[i].in_use) {
316 			crypto_stm32_sessions[i].in_use = true;
317 			k_sem_give(&data->session_sem);
318 			return i;
319 		}
320 	}
321 
322 	k_sem_give(&data->session_sem);
323 
324 	return -1;
325 }
326 
crypto_stm32_session_setup(const struct device * dev,struct cipher_ctx * ctx,enum cipher_algo algo,enum cipher_mode mode,enum cipher_op op_type)327 static int crypto_stm32_session_setup(const struct device *dev,
328 				      struct cipher_ctx *ctx,
329 				      enum cipher_algo algo,
330 				      enum cipher_mode mode,
331 				      enum cipher_op op_type)
332 {
333 	int ctx_idx, ret;
334 	struct crypto_stm32_session *session;
335 
336 	if (ctx->flags & ~(CRYP_SUPPORT)) {
337 		LOG_ERR("Unsupported flag");
338 		return -EINVAL;
339 	}
340 
341 	if (algo != CRYPTO_CIPHER_ALGO_AES) {
342 		LOG_ERR("Unsupported algo");
343 		return -EINVAL;
344 	}
345 
346 	/* The CRYP peripheral supports the AES ECB, CBC, CTR, CCM and GCM
347 	 * modes of operation, of which ECB, CBC, CTR and CCM are supported
348 	 * through the crypto API. However, in CCM mode, although the STM32Cube
349 	 * HAL driver follows the documentation (cf. RM0090, par. 23.3) by
350 	 * padding incomplete input data blocks in software prior encryption,
351 	 * incorrect authentication tags are returned for input data which is
352 	 * not a multiple of 128 bits. Therefore, CCM mode is not supported by
353 	 * this driver.
354 	 */
355 	if ((mode != CRYPTO_CIPHER_MODE_ECB) &&
356 	    (mode != CRYPTO_CIPHER_MODE_CBC) &&
357 	    (mode != CRYPTO_CIPHER_MODE_CTR)) {
358 		LOG_ERR("Unsupported mode");
359 		return -EINVAL;
360 	}
361 
362 	/* The STM32F4 CRYP peripheral supports key sizes of 128, 192 and 256
363 	 * bits.
364 	 */
365 	if ((ctx->keylen != 16U) &&
366 #if defined(STM32_CRYPTO_KEYSIZE_192B_SUPPORT)
367 	    (ctx->keylen != 24U) &&
368 #endif
369 	    (ctx->keylen != 32U)) {
370 		LOG_ERR("%u key size is not supported", ctx->keylen);
371 		return -EINVAL;
372 	}
373 
374 	ctx_idx = crypto_stm32_get_unused_session_index(dev);
375 	if (ctx_idx < 0) {
376 		LOG_ERR("No free session for now");
377 		return -ENOSPC;
378 	}
379 	session = &crypto_stm32_sessions[ctx_idx];
380 	memset(&session->config, 0, sizeof(session->config));
381 
382 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
383 	struct crypto_stm32_data *data = CRYPTO_STM32_DATA(dev);
384 
385 	if (data->hcryp.State == HAL_CRYP_STATE_RESET) {
386 		if (HAL_CRYP_Init(&data->hcryp) != HAL_OK) {
387 			LOG_ERR("Initialization error");
388 			session->in_use = false;
389 			return -EIO;
390 		}
391 	}
392 #endif
393 
394 	switch (ctx->keylen) {
395 	case 16U:
396 		session->config.KeySize = CRYP_KEYSIZE_128B;
397 		break;
398 #if defined(STM32_CRYPTO_KEYSIZE_192B_SUPPORT)
399 	case 24U:
400 		session->config.KeySize = CRYP_KEYSIZE_192B;
401 		break;
402 #endif
403 	case 32U:
404 		session->config.KeySize = CRYP_KEYSIZE_256B;
405 		break;
406 	}
407 
408 	if (op_type == CRYPTO_CIPHER_OP_ENCRYPT) {
409 		switch (mode) {
410 		case CRYPTO_CIPHER_MODE_ECB:
411 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
412 			session->config.Algorithm = CRYP_AES_ECB;
413 #endif
414 			ctx->ops.block_crypt_hndlr = crypto_stm32_ecb_encrypt;
415 			break;
416 		case CRYPTO_CIPHER_MODE_CBC:
417 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
418 			session->config.Algorithm = CRYP_AES_CBC;
419 #endif
420 			ctx->ops.cbc_crypt_hndlr = crypto_stm32_cbc_encrypt;
421 			break;
422 		case CRYPTO_CIPHER_MODE_CTR:
423 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
424 			session->config.Algorithm = CRYP_AES_CTR;
425 #endif
426 			ctx->ops.ctr_crypt_hndlr = crypto_stm32_ctr_encrypt;
427 			break;
428 		default:
429 			break;
430 		}
431 	} else {
432 		switch (mode) {
433 		case CRYPTO_CIPHER_MODE_ECB:
434 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
435 			session->config.Algorithm = CRYP_AES_ECB;
436 #endif
437 			ctx->ops.block_crypt_hndlr = crypto_stm32_ecb_decrypt;
438 			break;
439 		case CRYPTO_CIPHER_MODE_CBC:
440 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
441 			session->config.Algorithm = CRYP_AES_CBC;
442 #endif
443 			ctx->ops.cbc_crypt_hndlr = crypto_stm32_cbc_decrypt;
444 			break;
445 		case CRYPTO_CIPHER_MODE_CTR:
446 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
447 			session->config.Algorithm = CRYP_AES_CTR;
448 #endif
449 			ctx->ops.ctr_crypt_hndlr = crypto_stm32_ctr_decrypt;
450 			break;
451 		default:
452 			break;
453 		}
454 	}
455 
456 	ret = copy_words_adjust_endianness((uint8_t *)session->key, CRYPTO_STM32_AES_MAX_KEY_LEN,
457 				 ctx->key.bit_stream, ctx->keylen);
458 	if (ret != 0) {
459 		return -EIO;
460 	}
461 
462 	session->config.pKey = CAST_VEC(session->key);
463 	session->config.DataType = CRYP_DATATYPE_8B;
464 
465 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
466 	session->config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
467 #endif
468 
469 	ctx->drv_sessn_state = session;
470 	ctx->device = dev;
471 
472 	return 0;
473 }
474 
crypto_stm32_session_free(const struct device * dev,struct cipher_ctx * ctx)475 static int crypto_stm32_session_free(const struct device *dev,
476 				     struct cipher_ctx *ctx)
477 {
478 	int i;
479 
480 	struct crypto_stm32_data *data = CRYPTO_STM32_DATA(dev);
481 	const struct crypto_stm32_config *cfg = CRYPTO_STM32_CFG(dev);
482 	struct crypto_stm32_session *session = CRYPTO_STM32_SESSN(ctx);
483 
484 	session->in_use = false;
485 
486 	k_sem_take(&data->session_sem, K_FOREVER);
487 
488 	/* Disable peripheral only if there are no more active sessions. */
489 	for (i = 0; i < CRYPTO_MAX_SESSION; i++) {
490 		if (crypto_stm32_sessions[i].in_use) {
491 			k_sem_give(&data->session_sem);
492 			return 0;
493 		}
494 	}
495 
496 #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
497 	/* Deinitialize and reset peripheral. */
498 	if (HAL_CRYP_DeInit(&data->hcryp) != HAL_OK) {
499 		LOG_ERR("Deinitialization error");
500 		k_sem_give(&data->session_sem);
501 		return -EIO;
502 	}
503 #endif
504 
505 	(void)reset_line_toggle_dt(&cfg->reset);
506 
507 	k_sem_give(&data->session_sem);
508 
509 	return 0;
510 }
511 
crypto_stm32_query_caps(const struct device * dev)512 static int crypto_stm32_query_caps(const struct device *dev)
513 {
514 	return CRYP_SUPPORT;
515 }
516 
crypto_stm32_init(const struct device * dev)517 static int crypto_stm32_init(const struct device *dev)
518 {
519 	const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
520 	struct crypto_stm32_data *data = CRYPTO_STM32_DATA(dev);
521 	const struct crypto_stm32_config *cfg = CRYPTO_STM32_CFG(dev);
522 
523 	if (!device_is_ready(clk)) {
524 		LOG_ERR("clock control device not ready");
525 		return -ENODEV;
526 	}
527 
528 	if (clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken) != 0) {
529 		LOG_ERR("clock op failed\n");
530 		return -EIO;
531 	}
532 
533 	k_sem_init(&data->device_sem, 1, 1);
534 	k_sem_init(&data->session_sem, 1, 1);
535 
536 	if (HAL_CRYP_DeInit(&data->hcryp) != HAL_OK) {
537 		LOG_ERR("Peripheral reset error");
538 		return -EIO;
539 	}
540 
541 	return 0;
542 }
543 
544 static DEVICE_API(crypto, crypto_enc_funcs) = {
545 	.cipher_begin_session = crypto_stm32_session_setup,
546 	.cipher_free_session = crypto_stm32_session_free,
547 	.cipher_async_callback_set = NULL,
548 	.query_hw_caps = crypto_stm32_query_caps,
549 };
550 
551 static struct crypto_stm32_data crypto_stm32_dev_data = {
552 	.hcryp = {
553 		.Instance = (STM32_CRYPTO_TYPEDEF *)DT_INST_REG_ADDR(0),
554 	}
555 };
556 
557 static const struct crypto_stm32_config crypto_stm32_dev_config = {
558 	.reset = RESET_DT_SPEC_INST_GET(0),
559 	.pclken = {
560 		.enr = DT_INST_CLOCKS_CELL(0, bits),
561 		.bus = DT_INST_CLOCKS_CELL(0, bus)
562 	}
563 };
564 
565 DEVICE_DT_INST_DEFINE(0, crypto_stm32_init, NULL,
566 		    &crypto_stm32_dev_data,
567 		    &crypto_stm32_dev_config, POST_KERNEL,
568 		    CONFIG_CRYPTO_INIT_PRIORITY, (void *)&crypto_enc_funcs);
569