@@ -3318,12 +3318,31 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
33183318 if (mechanism == CKM_AES_KEY_WRAP_PAD ) {
33193319 int i ;
33203320 byte padValue = pData [decDataLen - 1 ];
3321- if (padValue > KEYWRAP_BLOCK_SIZE || padValue > decDataLen )
3322- return CKR_ENCRYPTED_DATA_LEN_RANGE ;
3323- for (i = 0 ; i < padValue ; i ++ ) {
3324- if (pData [decDataLen - 1 - i ] != padValue )
3325- return CKR_ENCRYPTED_DATA_INVALID ;
3321+ unsigned int badPad = 0 ;
3322+ unsigned int inPad ;
3323+
3324+ /* Constant-time range check: padValue must be 1..KEYWRAP_BLOCK_SIZE
3325+ * and must not exceed decDataLen. */
3326+ badPad |= ((unsigned int )padValue - 1 ) >> 31 ;
3327+ badPad |= ((unsigned int )KEYWRAP_BLOCK_SIZE -
3328+ (unsigned int )padValue ) >> 31 ;
3329+ badPad |= ((unsigned int )decDataLen -
3330+ (unsigned int )padValue ) >> 31 ;
3331+
3332+ /* Constant-time padding byte verification.
3333+ * Always iterate KEYWRAP_BLOCK_SIZE times to avoid leaking
3334+ * padValue through iteration count. */
3335+ for (i = 0 ; i < KEYWRAP_BLOCK_SIZE ; i ++ ) {
3336+ /* Full mask: all-ones when i < padValue, else 0 */
3337+ inPad = 0 - (((unsigned int )i -
3338+ (unsigned int )padValue ) >> 31 );
3339+ badPad |= inPad &
3340+ ((unsigned int )pData [decDataLen - 1 - i ] ^
3341+ (unsigned int )padValue );
33263342 }
3343+
3344+ if (badPad != 0 )
3345+ return CKR_ENCRYPTED_DATA_INVALID ;
33273346 decDataLen -= padValue ;
33283347 }
33293348 * pulDataLen = decDataLen ;
0 commit comments