@@ -487,6 +487,267 @@ bool wc_AesGcm_decrypt_sg_inplace(struct scatterlist *src, size_t src_len,
487487 ad , ad_len , nonce , key , key_len , 1 ));
488488}
489489
490+ #ifdef WOLFSSL_AESGCM_STREAM
491+
492+ static __always_inline bool wc_AesGcm_crypt_sg_inplace_prealloc (
493+ struct scatterlist * src , const size_t src_len ,
494+ const u8 * ad , const size_t ad_len ,
495+ u64 nonce ,
496+ Aes * aes ,
497+ int isDecrypt )
498+ {
499+ int ret = -1 ;
500+ struct sg_mapping_iter miter ;
501+ int miter_needs_stop = 0 ;
502+ unsigned int flags ;
503+ ssize_t sl ;
504+ byte full_nonce [AES_IV_SIZE ];
505+
506+ if (WARN_ON ((src_len > UINT_MAX ) ||
507+ (ad_len > UINT_MAX )))
508+ {
509+ ret = - EINVAL ;
510+ WC_DEBUG_PR_CODEPOINT ();
511+ goto out ;
512+ }
513+
514+ memset (full_nonce , 0 , sizeof (full_nonce ));
515+ #ifdef BIG_ENDIAN_ORDER
516+ nonce = cpu_to_le64 (nonce );
517+ #endif
518+ memcpy (full_nonce + 4 , (u8 * )& nonce , sizeof (nonce ));
519+
520+ /* Pass NULL key: wc_AesGcmInit skips wc_AesGcmSetKey when key is NULL,
521+ * reusing the key schedule already set at keypair creation time.
522+ */
523+ if (isDecrypt )
524+ ret = wc_AesGcmDecryptInit (aes , NULL , 0 ,
525+ full_nonce , (word32 )sizeof (full_nonce ));
526+ else
527+ ret = wc_AesGcmEncryptInit (aes , NULL , 0 ,
528+ full_nonce , (word32 )sizeof (full_nonce ));
529+ wc_ForceZero (full_nonce , sizeof full_nonce );
530+ if (ret != 0 ) {
531+ WC_DEBUG_PR_CODEPOINT ();
532+ goto out ;
533+ }
534+
535+ if (ad ) {
536+ if (isDecrypt )
537+ ret = wc_AesGcmDecryptUpdate (aes , NULL , NULL ,
538+ 0 , ad , ad_len );
539+ else
540+ ret = wc_AesGcmEncryptUpdate (aes , NULL , NULL ,
541+ 0 , ad , ad_len );
542+ if (ret != 0 ) {
543+ WC_DEBUG_PR_CODEPOINT ();
544+ goto out ;
545+ }
546+ }
547+
548+ flags = SG_MITER_TO_SG | SG_MITER_ATOMIC ;
549+
550+ sg_miter_start (& miter , src , sg_nents (src ), flags );
551+ miter_needs_stop = 1 ;
552+
553+ for (sl = (ssize_t )src_len ; sl > 0 && sg_miter_next (& miter ); sl -= miter .length ) {
554+ size_t length = min_t (size_t , sl , (ssize_t )miter .length );
555+
556+ if (isDecrypt )
557+ ret = wc_AesGcmDecryptUpdate (aes , miter .addr , miter .addr ,
558+ length , NULL , 0 );
559+ else
560+ ret = wc_AesGcmEncryptUpdate (aes , miter .addr , miter .addr ,
561+ length , NULL , 0 );
562+ if (ret != 0 ) {
563+ WC_DEBUG_PR_CODEPOINT ();
564+ goto out ;
565+ }
566+ }
567+
568+ if (sl <= - WC_AES_BLOCK_SIZE ) {
569+ if (isDecrypt )
570+ ret = wc_AesGcmDecryptFinal (aes , miter .addr + (ssize_t )miter .length + sl , WC_AES_BLOCK_SIZE );
571+ else
572+ ret = wc_AesGcmEncryptFinal (aes , miter .addr + (ssize_t )miter .length + sl , WC_AES_BLOCK_SIZE );
573+ if (ret < 0 ) {
574+ WC_DEBUG_PR_CODEPOINT ();
575+ goto out ;
576+ }
577+ }
578+
579+ sg_miter_stop (& miter );
580+ miter_needs_stop = 0 ;
581+
582+ if (sl > - WC_AES_BLOCK_SIZE ) {
583+ byte AuthTagBuf [WC_AES_BLOCK_SIZE ];
584+
585+ if (isDecrypt ) {
586+ scatterwalk_map_and_copy (AuthTagBuf , src , src_len ,
587+ sizeof AuthTagBuf , 0 /* isEncrypt */ );
588+ ret = wc_AesGcmDecryptFinal (aes , AuthTagBuf , WC_AES_BLOCK_SIZE );
589+ if (ret < 0 )
590+ goto out ;
591+ } else {
592+ ret = wc_AesGcmEncryptFinal (aes , AuthTagBuf , WC_AES_BLOCK_SIZE );
593+ if (ret < 0 )
594+ goto out ;
595+ scatterwalk_map_and_copy (AuthTagBuf , src , src_len ,
596+ sizeof AuthTagBuf , 1 /* isEncrypt */ );
597+ }
598+ }
599+
600+ ret = 0 ;
601+
602+ out :
603+
604+ if (miter_needs_stop )
605+ sg_miter_stop (& miter );
606+
607+ WC_DEBUG_PR_IF_NEG (ret );
608+
609+ return ret == 0 ;
610+ }
611+
612+ #else /* !WOLFSSL_AESGCM_STREAM */
613+
614+ static __always_inline bool wc_AesGcm_crypt_sg_inplace_prealloc (
615+ struct scatterlist * src , const size_t src_len ,
616+ const u8 * ad , const size_t ad_len ,
617+ u64 nonce ,
618+ Aes * aes ,
619+ int isDecrypt )
620+ {
621+ int ret = -1 ;
622+ struct sg_mapping_iter miter ;
623+ unsigned int flags ;
624+ byte full_nonce [AES_IV_SIZE ];
625+
626+ if (WARN_ON ((src_len > UINT_MAX ) ||
627+ (ad_len > UINT_MAX )))
628+ {
629+ ret = - EINVAL ;
630+ WC_DEBUG_PR_CODEPOINT ();
631+ goto out ;
632+ }
633+
634+ if (sg_nents (src ) < 1 ) {
635+ ret = - EINVAL ;
636+ WC_DEBUG_PR_CODEPOINT ();
637+ goto out ;
638+ }
639+
640+ memset (full_nonce , 0 , sizeof (full_nonce ));
641+ #ifdef BIG_ENDIAN_ORDER
642+ nonce = cpu_to_le64 (nonce );
643+ #endif
644+ memcpy (full_nonce + 4 , (u8 * )& nonce , sizeof (nonce ));
645+
646+ flags = SG_MITER_TO_SG | SG_MITER_ATOMIC ;
647+
648+ if (sg_nents (src ) == 1 ) {
649+ size_t length ;
650+
651+ sg_miter_start (& miter , src , sg_nents (src ), flags );
652+ if ((sg_nents (src ) == 1 ) && (! sg_miter_next (& miter ))) {
653+ sg_miter_stop (& miter );
654+ ret = - EINVAL ;
655+ WC_DEBUG_PR_CODEPOINT ();
656+ goto out ;
657+ }
658+
659+ if (miter .length < src_len + WC_AES_BLOCK_SIZE ) {
660+ sg_miter_stop (& miter );
661+ goto copy_after_all ;
662+ }
663+
664+ length = min_t (size_t , src_len , miter .length );
665+
666+ if (isDecrypt ) {
667+ ret = wc_AesGcmDecrypt (aes , miter .addr ,
668+ miter .addr , (word32 )length ,
669+ full_nonce , (word32 )sizeof (full_nonce ),
670+ miter .addr + length , WC_AES_BLOCK_SIZE ,
671+ ad , (word32 )ad_len );
672+ }
673+ else {
674+ ret = wc_AesGcmEncrypt (aes , miter .addr ,
675+ miter .addr , (word32 )length ,
676+ full_nonce , (word32 )sizeof (full_nonce ),
677+ miter .addr + length , WC_AES_BLOCK_SIZE ,
678+ ad , (word32 )ad_len );
679+ }
680+
681+ sg_miter_stop (& miter );
682+
683+ goto out ;
684+ }
685+
686+ copy_after_all :
687+ {
688+ byte * buf = (byte * )XMALLOC (src_len + WC_AES_BLOCK_SIZE , NULL , DYNAMIC_TYPE_TMP_BUFFER );
689+
690+ if (! buf ) {
691+ ret = - ENOMEM ;
692+ WC_DEBUG_PR_CODEPOINT ();
693+ goto out ;
694+ }
695+
696+ if (isDecrypt ) {
697+ scatterwalk_map_and_copy (buf , src , 0 , src_len + WC_AES_BLOCK_SIZE , 0 );
698+ ret = wc_AesGcmDecrypt (aes , buf ,
699+ buf , (word32 )src_len ,
700+ full_nonce , (word32 )sizeof (full_nonce ),
701+ buf + src_len , WC_AES_BLOCK_SIZE ,
702+ ad , (word32 )ad_len );
703+ if (ret == 0 )
704+ scatterwalk_map_and_copy (buf , src , 0 , src_len , 1 );
705+ wc_ForceZero (buf , src_len + WC_AES_BLOCK_SIZE );
706+ }
707+ else {
708+ scatterwalk_map_and_copy (buf , src , 0 , src_len , 0 );
709+ ret = wc_AesGcmEncrypt (aes , buf ,
710+ buf , (word32 )src_len ,
711+ full_nonce , (word32 )sizeof (full_nonce ),
712+ buf + src_len , WC_AES_BLOCK_SIZE ,
713+ ad , (word32 )ad_len );
714+ if (ret == 0 )
715+ scatterwalk_map_and_copy (buf , src , 0 , src_len + WC_AES_BLOCK_SIZE , 1 );
716+ else
717+ wc_ForceZero (buf , src_len + WC_AES_BLOCK_SIZE );
718+ }
719+ free (buf );
720+ }
721+
722+ out :
723+
724+ wc_ForceZero (full_nonce , sizeof full_nonce );
725+
726+ WC_DEBUG_PR_IF_NEG (ret );
727+
728+ return ret == 0 ;
729+ }
730+
731+ #endif /* !WOLFSSL_AESGCM_STREAM */
732+
733+ bool wc_AesGcm_encrypt_sg_inplace_prealloc (struct scatterlist * src , size_t src_len ,
734+ const u8 * ad , const size_t ad_len ,
735+ const u64 nonce ,
736+ Aes * aes )
737+ {
738+ WC_DEBUG_PR_FALSE_RET (wc_AesGcm_crypt_sg_inplace_prealloc (src , src_len , ad , ad_len ,
739+ nonce , aes , 0 ));
740+ }
741+
742+ bool wc_AesGcm_decrypt_sg_inplace_prealloc (struct scatterlist * src , size_t src_len ,
743+ const u8 * ad , const size_t ad_len ,
744+ const u64 nonce ,
745+ Aes * aes )
746+ {
747+ WC_DEBUG_PR_FALSE_RET (wc_AesGcm_crypt_sg_inplace_prealloc (src , src_len - WC_AES_BLOCK_SIZE ,
748+ ad , ad_len , nonce , aes , 1 ));
749+ }
750+
490751int wc_ecc_make_keypair_exim (u8 * private , const size_t private_len ,
491752 u8 * public , const size_t public_len ,
492753 const int curve_id , int compressed )
0 commit comments