2323use function openssl_verify ;
2424use function ord ;
2525use function str_repeat ;
26+ use function strlen ;
2627use function substr ;
2728
2829/**
@@ -176,6 +177,7 @@ public function decrypt(
176177 if ($ plaintext === false ) {
177178 throw new OpenSSLException ('Cannot decrypt data ' );
178179 }
180+
179181 return $ this ->useAuthTag ? $ plaintext : $ this ->unpad ($ plaintext );
180182 }
181183
@@ -299,11 +301,16 @@ public function setDigestAlg(string $digest): void
299301 * Pad a plaintext using ISO 10126 padding.
300302 *
301303 * @param string $plaintext The plaintext to pad.
302- *
303304 * @return string The padded plaintext.
305+ *
306+ * @throws \OpenSSLException in case padding failed
304307 */
305308 public function pad (string $ plaintext ): string
306309 {
310+ if ($ this ->blocksize > 256 ) {
311+ throw new OpenSSLException ('Block size higher than 256 not allowed ' );
312+ }
313+
307314 $ padchr = $ this ->blocksize - (mb_strlen ($ plaintext ) % $ this ->blocksize );
308315 $ pattern = chr ($ padchr );
309316 return $ plaintext . str_repeat ($ pattern , $ padchr );
@@ -314,11 +321,29 @@ public function pad(string $plaintext): string
314321 * Remove an existing ISO 10126 padding from a given plaintext.
315322 *
316323 * @param string $plaintext The padded plaintext.
317- *
318324 * @return string The plaintext without the padding.
325+ *
326+ * @throws \OpenSSLException in case unpadding failed
319327 */
320328 public function unpad (string $ plaintext ): string
321329 {
322- return substr ($ plaintext , 0 , -ord (substr ($ plaintext , -1 )));
330+ $ len = mb_strlen ($ plaintext );
331+ if ($ len === 0 ) {
332+ /*
333+ * Use a single, generic error for every decryption failure. Do not
334+ * reveal whether the padding (as opposed to the ciphertext) was the
335+ * cause: distinguishable padding errors turn unauthenticated CBC
336+ * decryption into a padding oracle (plaintext recovery).
337+ */
338+ throw new OpenSSLException ('Cannot decrypt data ' );
339+ }
340+
341+ $ padLen = ord ($ plaintext [$ len - 1 ]);
342+ $ blocksize = $ this ->blocksize ?? 16 ;
343+ if ($ padLen < 1 || $ padLen > $ blocksize || $ padLen > $ len ) {
344+ throw new OpenSSLException ('Cannot decrypt data ' );
345+ }
346+
347+ return substr ($ plaintext , 0 , -$ padLen );
323348 }
324349}
0 commit comments