- db[i] ^= maskeddb[i];
-
- SHA1(param, plen, phash);
-
- if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0)
- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
- else
- {
- for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
- if (db[i] != 0x00)
- break;
- if (db[i] != 0x01 || i++ >= dblen)
- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP,
- RSA_R_OAEP_DECODING_ERROR);
- else
- {
- mlen = dblen - i;
- if (tlen < mlen)
- {
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
- mlen = -1;
- }
- else
- memcpy(to, db + i, mlen);
- }
- }
- Free(db);
- return (mlen);
+ db[i] ^= maskeddb[i];
+
+ if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL))
+ goto cleanup;
+
+ good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));
+
+ found_one_byte = 0;
+ for (i = mdlen; i < dblen; i++) {
+ /*
+ * Padding consists of a number of 0-bytes, followed by a 1.
+ */
+ unsigned int equals1 = constant_time_eq(db[i], 1);
+ unsigned int equals0 = constant_time_is_zero(db[i]);
+ one_index = constant_time_select_int(~found_one_byte & equals1,
+ i, one_index);
+ found_one_byte |= equals1;
+ good &= (found_one_byte | equals0);
+ }
+
+ good &= found_one_byte;
+
+ /*
+ * At this point |good| is zero unless the plaintext was valid,
+ * so plaintext-awareness ensures timing side-channels are no longer a
+ * concern.
+ */
+ if (!good)
+ goto decoding_err;
+
+ msg_index = one_index + 1;
+ mlen = dblen - msg_index;
+
+ if (tlen < mlen) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE);
+ mlen = -1;
+ } else {
+ memcpy(to, db + msg_index, mlen);
+ goto cleanup;