@@ -389,6 +389,113 @@ OT_TOOL_WEAK otError otPlatCryptoAesFree(otCryptoContext *aContext)
389389 return kErrorNone ;
390390}
391391
392+ #if OPENTHREAD_CONFIG_CRYPTO_PLATFORM_CCM_SINGLE_PART_ENABLE
393+
394+ OT_TOOL_WEAK otError otPlatCryptoAesCcmEncryptAndTag (const otCryptoKey *aKey,
395+ const uint8_t *aNonce,
396+ uint8_t aNonceLength,
397+ const void *aHeader,
398+ uint32_t aHeaderLength,
399+ uint8_t *aData,
400+ uint32_t aPayloadLength,
401+ uint8_t aTagLength)
402+ {
403+ Error error = kErrorNone ;
404+ psa_status_t status;
405+ psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT ;
406+ psa_algorithm_t algorithm = PSA_ALG_AEAD_WITH_SHORTENED_TAG (PSA_ALG_CCM , aTagLength);
407+ uint8_t trailing[AesCcm::kMaxTagLength ];
408+ size_t trailingLen = 0 ;
409+ size_t tagLen = 0 ;
410+ size_t outputLen = 0 ;
411+
412+ VerifyOrExit (aKey != nullptr && aNonce != nullptr && aData != nullptr , error = kErrorInvalidArgs );
413+
414+ status = psa_aead_encrypt_setup (&operation, aKey->mKeyRef , algorithm);
415+ SuccessOrExit (error = PsaToOtError (status));
416+
417+ status = psa_aead_set_lengths (&operation, aHeaderLength, aPayloadLength);
418+ SuccessOrExit (error = PsaToOtError (status));
419+
420+ status = psa_aead_set_nonce (&operation, aNonce, aNonceLength);
421+ SuccessOrExit (error = PsaToOtError (status));
422+
423+ if (aHeaderLength > 0 )
424+ {
425+ status = psa_aead_update_ad (&operation, static_cast <const uint8_t *>(aHeader), aHeaderLength);
426+ SuccessOrExit (error = PsaToOtError (status));
427+ }
428+
429+ // CCM may buffer the entire payload until Finish; pass in-place to avoid a copy.
430+ status = psa_aead_update (&operation, aData, aPayloadLength, aData, aPayloadLength, &outputLen);
431+ SuccessOrExit (error = PsaToOtError (status));
432+
433+ status = psa_aead_finish (&operation, trailing, sizeof (trailing), &trailingLen, aData + aPayloadLength, aTagLength,
434+ &tagLen);
435+ SuccessOrExit (error = PsaToOtError (status));
436+ VerifyOrExit (tagLen == aTagLength, error = kErrorFailed );
437+
438+ exit:
439+ if (error != kErrorNone )
440+ {
441+ psa_aead_abort (&operation);
442+ }
443+
444+ return error;
445+ }
446+
447+ OT_TOOL_WEAK otError otPlatCryptoAesCcmDecryptAndVerify (const otCryptoKey *aKey,
448+ const uint8_t *aNonce,
449+ uint8_t aNonceLength,
450+ const void *aHeader,
451+ uint32_t aHeaderLength,
452+ uint8_t *aData,
453+ uint32_t aPayloadLength,
454+ uint8_t aTagLength)
455+ {
456+ Error error = kErrorNone ;
457+ psa_status_t status;
458+ psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT ;
459+ psa_algorithm_t algorithm = PSA_ALG_AEAD_WITH_SHORTENED_TAG (PSA_ALG_CCM , aTagLength);
460+ uint8_t trailing[AesCcm::kMaxTagLength ];
461+ size_t trailingLen = 0 ;
462+ size_t outputLen = 0 ;
463+
464+ VerifyOrExit (aKey != nullptr && aNonce != nullptr && aData != nullptr , error = kErrorInvalidArgs );
465+
466+ status = psa_aead_decrypt_setup (&operation, aKey->mKeyRef , algorithm);
467+ SuccessOrExit (error = PsaToOtError (status));
468+
469+ status = psa_aead_set_lengths (&operation, aHeaderLength, aPayloadLength);
470+ SuccessOrExit (error = PsaToOtError (status));
471+
472+ status = psa_aead_set_nonce (&operation, aNonce, aNonceLength);
473+ SuccessOrExit (error = PsaToOtError (status));
474+
475+ if (aHeaderLength > 0 )
476+ {
477+ status = psa_aead_update_ad (&operation, static_cast <const uint8_t *>(aHeader), aHeaderLength);
478+ SuccessOrExit (error = PsaToOtError (status));
479+ }
480+
481+ // CCM may buffer the entire payload until Verify; pass in-place to avoid a copy.
482+ status = psa_aead_update (&operation, aData, aPayloadLength, aData, aPayloadLength, &outputLen);
483+ SuccessOrExit (error = PsaToOtError (status));
484+
485+ status = psa_aead_verify (&operation, trailing, sizeof (trailing), &trailingLen, aData + aPayloadLength, aTagLength);
486+ error = (status == PSA_ERROR_INVALID_SIGNATURE ) ? kErrorSecurity : PsaToOtError (status);
487+
488+ exit:
489+ if (error != kErrorNone )
490+ {
491+ psa_aead_abort (&operation);
492+ }
493+
494+ return error;
495+ }
496+
497+ #endif // OPENTHREAD_CONFIG_CRYPTO_PLATFORM_CCM_SINGLE_PART_ENABLE
498+
392499#if OPENTHREAD_FTD || OPENTHREAD_MTD
393500
394501OT_TOOL_WEAK otError otPlatCryptoHmacSha256Init (otCryptoContext *aContext)
0 commit comments