23
23
24
24
#include "cracen_psa_primitives.h"
25
25
26
+ #if defined(CONFIG_SOC_NRF54LV10A ) && defined(CONFIG_PSA_NEED_CRACEN_CTR_AES )
27
+ #include <cracen_sw_aes_ctr.h>
28
+ #endif
29
+
26
30
static bool is_alg_supported (psa_algorithm_t alg , const psa_key_attributes_t * attributes )
27
31
{
28
32
bool is_supported = false;
@@ -64,9 +68,8 @@ static bool is_alg_supported(psa_algorithm_t alg, const psa_key_attributes_t *at
64
68
}
65
69
66
70
static psa_status_t setup (enum cipher_operation dir , cracen_cipher_operation_t * operation ,
67
- const psa_key_attributes_t * attributes ,
68
- const uint8_t * key_buffer , size_t key_buffer_size ,
69
- psa_algorithm_t alg )
71
+ const psa_key_attributes_t * attributes , const uint8_t * key_buffer ,
72
+ size_t key_buffer_size , psa_algorithm_t alg )
70
73
{
71
74
if (!is_alg_supported (alg , attributes )) {
72
75
return PSA_ERROR_NOT_SUPPORTED ;
@@ -285,6 +288,29 @@ psa_status_t cracen_cipher_encrypt(const psa_key_attributes_t *attributes,
285
288
cracen_cipher_operation_t operation = {0 };
286
289
* output_length = 0 ;
287
290
291
+ #if defined(CONFIG_SOC_NRF54LV10A ) && defined(CONFIG_PSA_NEED_CRACEN_CTR_AES )
292
+ /* Route AES_CTR to software implementation due to 16-bit counter limitation */
293
+ if (alg == PSA_ALG_CTR ) {
294
+ if (output_size < input_length ) {
295
+ return PSA_ERROR_BUFFER_TOO_SMALL ;
296
+ }
297
+ /* Handle inplace encryption by moving plaintext to the right by iv_length
298
+ * bytes. This is done because in inplace encryption the input and output
299
+ * should point to the same data so that the output can overwrite its own
300
+ * input. If they are not in sync the output will overwrite the input of
301
+ * another operation which is of course wrong.
302
+ *
303
+ */
304
+ if (output == input + iv_length ) {
305
+ memmove (output , input , input_length );
306
+ input = output ;
307
+ }
308
+ return cracen_sw_aes_ctr_crypt (attributes , key_buffer , key_buffer_size , iv ,
309
+ iv_length , input , input_length , output , output_size ,
310
+ output_length );
311
+ }
312
+ #endif
313
+
288
314
/* If ECB is not enabled in the configuration the encrypt setup will return an not supported
289
315
* error and thus we don't need to write an else here.
290
316
*/
@@ -338,6 +364,15 @@ psa_status_t cracen_cipher_decrypt(const psa_key_attributes_t *attributes,
338
364
const size_t iv_size = (alg == PSA_ALG_STREAM_CIPHER ) ? 12 : SX_BLKCIPHER_IV_SZ ;
339
365
* output_length = 0 ;
340
366
367
+ #if defined(CONFIG_SOC_NRF54LV10A ) && defined(CONFIG_PSA_NEED_CRACEN_CTR_AES )
368
+ /* Route AES_CTR to software implementation due to 16-bit counter limitation */
369
+ if (alg == PSA_ALG_CTR ) {
370
+ return cracen_sw_aes_ctr_crypt (attributes , key_buffer , key_buffer_size , input ,
371
+ iv_size , input + iv_size , input_length - iv_size ,
372
+ output , output_size , output_length );
373
+ }
374
+ #endif
375
+
341
376
if (input_length == 0 ) {
342
377
return PSA_SUCCESS ;
343
378
}
@@ -462,6 +497,14 @@ psa_status_t cracen_cipher_encrypt_setup(cracen_cipher_operation_t *operation,
462
497
if (!is_multi_part_supported (alg )) {
463
498
return PSA_ERROR_NOT_SUPPORTED ;
464
499
}
500
+
501
+ #if defined(CONFIG_SOC_NRF54LV10A ) && defined(CONFIG_PSA_NEED_CRACEN_CTR_AES )
502
+ /* Route AES_CTR to software implementation due to 16-bit counter limitation */
503
+ if (alg == PSA_ALG_CTR ) {
504
+ return cracen_sw_aes_ctr_setup (operation , attributes , key_buffer , key_buffer_size );
505
+ }
506
+ #endif
507
+
465
508
return setup (CRACEN_ENCRYPT , operation , attributes , key_buffer , key_buffer_size , alg );
466
509
}
467
510
@@ -473,6 +516,14 @@ psa_status_t cracen_cipher_decrypt_setup(cracen_cipher_operation_t *operation,
473
516
if (!is_multi_part_supported (alg )) {
474
517
return PSA_ERROR_NOT_SUPPORTED ;
475
518
}
519
+
520
+ #if defined(CONFIG_SOC_NRF54LV10A ) && defined(CONFIG_PSA_NEED_CRACEN_CTR_AES )
521
+ /* Route AES_CTR to software implementation due to 16-bit counter limitation */
522
+ if (alg == PSA_ALG_CTR ) {
523
+ return cracen_sw_aes_ctr_setup (operation , attributes , key_buffer , key_buffer_size );
524
+ }
525
+ #endif
526
+
476
527
return setup (CRACEN_DECRYPT , operation , attributes , key_buffer , key_buffer_size , alg );
477
528
}
478
529
@@ -481,6 +532,13 @@ psa_status_t cracen_cipher_set_iv(cracen_cipher_operation_t *operation, const ui
481
532
{
482
533
__ASSERT_NO_MSG (iv != NULL );
483
534
535
+ #if defined(CONFIG_SOC_NRF54LV10A ) && defined(CONFIG_PSA_NEED_CRACEN_CTR_AES )
536
+ /* Route AES_CTR to software implementation due to 16-bit counter limitation */
537
+ if (operation -> alg == PSA_ALG_CTR ) {
538
+ return cracen_sw_aes_ctr_set_iv (operation , iv , iv_length );
539
+ }
540
+ #endif
541
+
484
542
/* Set IV is called after the encrypt/decrypt setup functions thus we
485
543
* know that we have CHACHA20 as the stream cipher here. Chacha20
486
544
* supports IV length of 12 bytes which uses a zero counter.
@@ -517,6 +575,14 @@ psa_status_t cracen_cipher_update(cracen_cipher_operation_t *operation, const ui
517
575
__ASSERT_NO_MSG (input != NULL || input_length == 0 );
518
576
__ASSERT_NO_MSG (output_length != NULL );
519
577
578
+ #if defined(CONFIG_SOC_NRF54LV10A ) && defined(CONFIG_PSA_NEED_CRACEN_CTR_AES )
579
+ /* Route AES_CTR to software implementation due to 16-bit counter limitation */
580
+ if (operation -> alg == PSA_ALG_CTR ) {
581
+ return cracen_sw_aes_ctr_update (operation , input , input_length , output , output_size ,
582
+ output_length );
583
+ }
584
+ #endif
585
+
520
586
int sx_status = SX_ERR_UNINITIALIZED_OBJ ;
521
587
psa_status_t psa_status = PSA_ERROR_CORRUPTION_DETECTED ;
522
588
* output_length = 0 ;
@@ -667,6 +733,13 @@ psa_status_t cracen_cipher_finish(cracen_cipher_operation_t *operation, uint8_t
667
733
{
668
734
__ASSERT_NO_MSG (output_length != NULL );
669
735
736
+ #if defined(CONFIG_SOC_NRF54LV10A ) && defined(CONFIG_PSA_NEED_CRACEN_CTR_AES )
737
+ /* Route AES_CTR to software implementation due to 16-bit counter limitation */
738
+ if (operation -> alg == PSA_ALG_CTR ) {
739
+ return cracen_sw_aes_ctr_finish (operation , output_length );
740
+ }
741
+ #endif
742
+
670
743
int sx_status ;
671
744
672
745
* output_length = 0 ;
@@ -807,6 +880,15 @@ psa_status_t cracen_cipher_finish(cracen_cipher_operation_t *operation, uint8_t
807
880
808
881
psa_status_t cracen_cipher_abort (cracen_cipher_operation_t * operation )
809
882
{
883
+ #if defined(CONFIG_SOC_NRF54LV10A ) && defined(CONFIG_PSA_NEED_CRACEN_CTR_AES )
884
+ /* Route AES_CTR to software implementation due to 16-bit counter limitation */
885
+ if (operation -> alg == PSA_ALG_CTR ) {
886
+ /* Software AES CTR implementation doesn't allocate hardware resources to free */
887
+ safe_memzero (operation , sizeof (cracen_cipher_operation_t ));
888
+ return PSA_SUCCESS ;
889
+ }
890
+ #endif
891
+
810
892
int sx_status ;
811
893
812
894
sx_status = sx_blkcipher_free (& operation -> cipher );
0 commit comments