[crypto] Add missing padding length check in RSA decryption

RSA PKCS#1 requires a minimum of eight non-zero padding bytes for
encryption.  This limit is currently enforced when encrypting but not
validated when decrypting.

The only existing code path that can currently lead to RSA decryption
is CMS decryption, which can use RSA to decrypt the cipher key.  With
underlength PKCS#1 padding (and hence an overlength plaintext), the
decrypted cipher key would be rejected by the immediately following
call to cipher_setkey().

Add the missing padding length check as part of RSA decryption, and
add a test case (imported from Project Wycheproof) to ensure that this
check remains in place in future.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2026-09-02 16:36:41 +01:00
parent a2f979a300
commit 2b1eaff499
2 changed files with 164 additions and 2 deletions
+4 -2
View File
@@ -414,6 +414,7 @@ static int rsa_pkcs1_decrypt ( struct pubkey_algorithm *pubkey __unused,
void *temp;
uint8_t *encoded;
uint8_t *end;
uint8_t *pad;
uint8_t *zero;
uint8_t *start;
size_t len;
@@ -450,8 +451,9 @@ static int rsa_pkcs1_decrypt ( struct pubkey_algorithm *pubkey __unused,
rc = -EINVAL;
goto err_invalid;
}
zero = memchr ( &encoded[2], 0, ( end - &encoded[2] ) );
if ( ! zero ) {
pad = &encoded[2];
zero = memchr ( pad, 0, ( end - pad ) );
if ( ( ! zero ) || ( ( zero - pad ) < 8 /* minimum padding */ ) ) {
DBGC ( &context, "RSA %p invalid decrypted message:\n",
&context );
DBGC_HDA ( &context, 0, encoded, context.max_len );
+160
View File
@@ -685,6 +685,165 @@ PUBKEY_SIGNATURE_TEST ( pss_sha256_test, &pss_sha256_key,
0xab, 0x81, 0xb2, 0x93, 0x26, 0xfe, 0x44, 0xb4, 0xc5, 0x07,
0x83, 0x02, 0x6e, 0x56, 0x60, 0x47, 0x1d, 0xbc ) );
/** Invalid PKCS#1 padding key (from Project Wycheproof) */
PUBKEY_TEST ( wycheproof_key, &rsa_algorithm,
PRIVATE ( 0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x04, 0x82, 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3,
0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb3, 0x51,
0x0a, 0x2b, 0xcd, 0x4c, 0xe6, 0x44, 0xc5, 0xb5, 0x94, 0xae,
0x50, 0x59, 0xe1, 0x2b, 0x2f, 0x05, 0x4b, 0x65, 0x8d, 0x5d,
0xa5, 0x95, 0x9a, 0x2f, 0xdf, 0x18, 0x71, 0xb8, 0x08, 0xbc,
0x3d, 0xf3, 0xe6, 0x28, 0xd2, 0x79, 0x2e, 0x51, 0xaa, 0xd5,
0xc1, 0x24, 0xb4, 0x3b, 0xda, 0x45, 0x3d, 0xca, 0x5c, 0xde,
0x4b, 0xcf, 0x28, 0xe7, 0xbd, 0x4e, 0xff, 0xba, 0x0c, 0xb4,
0xb7, 0x42, 0xbb, 0xb6, 0xd5, 0xa0, 0x13, 0xcb, 0x63, 0xd1,
0xaa, 0x3a, 0x89, 0xe0, 0x26, 0x27, 0xef, 0x53, 0x98, 0xb5,
0x2c, 0x0c, 0xfd, 0x97, 0xd2, 0x08, 0xab, 0xeb, 0x8d, 0x7c,
0x9b, 0xce, 0x0b, 0xbe, 0xb0, 0x19, 0xa8, 0x6d, 0xdb, 0x58,
0x9b, 0xeb, 0x29, 0xa5, 0xb7, 0x4b, 0xf8, 0x61, 0x07, 0x5c,
0x67, 0x7c, 0x81, 0xd4, 0x30, 0xf0, 0x30, 0xc2, 0x65, 0x24,
0x7a, 0xf9, 0xd3, 0xc9, 0x14, 0x0c, 0xcb, 0x65, 0x30, 0x9d,
0x07, 0xe0, 0xad, 0xc1, 0xef, 0xd1, 0x5c, 0xf1, 0x7e, 0x7b,
0x05, 0x5d, 0x7d, 0xa3, 0x86, 0x8e, 0x46, 0x48, 0xcc, 0x3a,
0x18, 0x0f, 0x0e, 0xe7, 0xf8, 0xe1, 0xe7, 0xb1, 0x80, 0x98,
0xa3, 0x39, 0x1b, 0x4c, 0xe7, 0x16, 0x1e, 0x98, 0xd5, 0x7a,
0xf8, 0xa9, 0x47, 0xe2, 0x01, 0xa4, 0x63, 0xe2, 0xd6, 0xbb,
0xca, 0x80, 0x59, 0xe5, 0x70, 0x6e, 0x9d, 0xfe, 0xd8, 0xf4,
0x85, 0x64, 0x65, 0xff, 0xa7, 0x12, 0xed, 0x1a, 0xa1, 0x8e,
0x88, 0x8d, 0x12, 0xdc, 0x6a, 0xa0, 0x9c, 0xe9, 0x5e, 0xcf,
0xca, 0x83, 0xcc, 0x5b, 0x0b, 0x15, 0xdb, 0x09, 0xc8, 0x64,
0x7f, 0x5d, 0x52, 0x4c, 0x0f, 0x2e, 0x76, 0x20, 0xa3, 0x41,
0x6b, 0x96, 0x23, 0xca, 0xdc, 0x0f, 0x09, 0x7a, 0xf5, 0x73,
0x26, 0x1c, 0x98, 0xc8, 0x40, 0x0a, 0xa1, 0x2a, 0xf3, 0x8e,
0x43, 0xca, 0xd8, 0x4d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
0x82, 0x01, 0x00, 0x1a, 0x50, 0x2d, 0x0e, 0xea, 0x6c, 0x7b,
0x69, 0xe2, 0x1d, 0x58, 0x39, 0x10, 0x1f, 0x70, 0x54, 0x56,
0xed, 0x0e, 0xf8, 0x52, 0xfb, 0x47, 0xfe, 0x21, 0x07, 0x1f,
0x54, 0xc5, 0xf3, 0x3c, 0x8c, 0xeb, 0x06, 0x6c, 0x62, 0xd7,
0x27, 0xe3, 0x2d, 0x26, 0xc5, 0x81, 0x37, 0x32, 0x9f, 0x89,
0xd3, 0x19, 0x53, 0x25, 0xb7, 0x95, 0x26, 0x4c, 0x19, 0x5d,
0x85, 0x47, 0x2f, 0x75, 0x07, 0xdb, 0xd0, 0x96, 0x1d, 0x29,
0x51, 0xf9, 0x35, 0xa2, 0x6b, 0x34, 0xf0, 0xac, 0x24, 0xd1,
0x54, 0x90, 0xe1, 0x12, 0x8a, 0x9b, 0x71, 0x38, 0x91, 0x5b,
0xc7, 0xdb, 0xfa, 0x8f, 0xe3, 0x96, 0x35, 0x71, 0x31, 0xc5,
0x43, 0xae, 0x9c, 0x98, 0x50, 0x73, 0x68, 0xd9, 0xce, 0xb0,
0x8c, 0x1c, 0x61, 0x98, 0xa3, 0xed, 0xa7, 0xae, 0xa1, 0x85,
0xa0, 0xe9, 0x76, 0xcd, 0x42, 0xc2, 0x2d, 0x00, 0xf0, 0x03,
0xd9, 0xf1, 0x9d, 0x96, 0xea, 0x4c, 0x9a, 0xfc, 0xbf, 0xe1,
0x44, 0x1c, 0xcc, 0x80, 0x2c, 0xfb, 0x06, 0x89, 0xf5, 0x9d,
0x80, 0x4c, 0x6a, 0x4e, 0x4f, 0x40, 0x4c, 0x15, 0x17, 0x47,
0x45, 0xed, 0x6c, 0xb8, 0xbc, 0x88, 0xef, 0x0b, 0x33, 0xba,
0x0d, 0x2a, 0x80, 0xe3, 0x5e, 0x43, 0xbc, 0x90, 0xf3, 0x50,
0x05, 0x2e, 0x72, 0x01, 0x6e, 0x75, 0xb0, 0x0d, 0x35, 0x7a,
0x38, 0x1c, 0x9c, 0x0d, 0x46, 0x70, 0x69, 0xca, 0x66, 0x08,
0x87, 0xc9, 0x87, 0x76, 0x63, 0x49, 0xfc, 0xc4, 0x34, 0x60,
0xb4, 0xaa, 0x51, 0x6b, 0xce, 0x07, 0x9e, 0xdd, 0x87, 0xba,
0x16, 0x43, 0x07, 0xb7, 0x52, 0xc2, 0x77, 0xed, 0x95, 0x28,
0xad, 0x3b, 0xa0, 0xbf, 0x18, 0x77, 0x34, 0x9e, 0xd3, 0xb7,
0x96, 0x6a, 0x6c, 0x24, 0x01, 0x10, 0x40, 0x9b, 0xf4, 0xd0,
0xfa, 0xde, 0x0c, 0x68, 0xfd, 0xad, 0xd8, 0x47, 0xfd, 0x02,
0x81, 0x81, 0x00, 0xec, 0x12, 0x5c, 0xf3, 0x7e, 0x31, 0x0a,
0x2f, 0xf4, 0x62, 0x63, 0xb9, 0xb2, 0xe0, 0x62, 0x9d, 0x63,
0x90, 0x00, 0x5e, 0xc8, 0x89, 0x13, 0xd4, 0xfb, 0x71, 0xbd,
0x4d, 0xd8, 0x56, 0x12, 0x44, 0x98, 0xaa, 0xeb, 0xa9, 0x83,
0xd7, 0xba, 0x2b, 0xd9, 0x42, 0xe6, 0x4d, 0x22, 0x3f, 0xeb,
0x7a, 0x23, 0xaf, 0x4d, 0x60, 0x5e, 0xfe, 0xea, 0x6b, 0xd7,
0x0d, 0x39, 0xaf, 0xe9, 0x9d, 0x35, 0xa3, 0xaa, 0x15, 0xe7,
0x4a, 0x17, 0x68, 0x77, 0x80, 0x93, 0xbe, 0x0e, 0xdd, 0x4a,
0x8d, 0x09, 0xb2, 0xde, 0xf6, 0xdc, 0x9b, 0x67, 0xff, 0x85,
0x76, 0x46, 0x25, 0xc2, 0xe1, 0x92, 0x36, 0xdb, 0x4c, 0x40,
0x1c, 0xe3, 0x0a, 0x25, 0x72, 0xd3, 0xec, 0xb4, 0xf9, 0x69,
0xb7, 0xad, 0x19, 0xc5, 0x22, 0xc0, 0x2d, 0x77, 0x44, 0x65,
0x67, 0x6e, 0x1a, 0x37, 0x76, 0xc5, 0x4d, 0x62, 0x48, 0x34,
0x8b, 0x02, 0x81, 0x81, 0x00, 0xc2, 0x74, 0x2a, 0xbc, 0xd9,
0x89, 0x7b, 0xd4, 0xb0, 0xb6, 0x71, 0xf9, 0x73, 0xfc, 0x82,
0xa8, 0xf8, 0x4a, 0xbf, 0x57, 0x05, 0xff, 0x88, 0xdd, 0x41,
0x94, 0x86, 0x23, 0xaf, 0xe9, 0xdc, 0xa6, 0x0d, 0xc6, 0x54,
0x33, 0x90, 0x76, 0x7f, 0xea, 0xeb, 0xeb, 0x53, 0x95, 0x76,
0xee, 0x8b, 0xfa, 0x61, 0xb5, 0xfc, 0xbc, 0xa9, 0x4a, 0x7c,
0xef, 0x75, 0xa0, 0x91, 0x50, 0xc5, 0x40, 0xfa, 0x96, 0x94,
0xdd, 0x80, 0x04, 0xad, 0x23, 0x71, 0x8c, 0x88, 0x90, 0x49,
0x21, 0x93, 0x69, 0xc9, 0x9f, 0x44, 0x58, 0xd4, 0xaf, 0xc1,
0x48, 0xf6, 0xf0, 0x7d, 0xf8, 0x73, 0x24, 0xa9, 0x6d, 0x9c,
0xf7, 0xb3, 0x85, 0xdd, 0x86, 0x22, 0x41, 0x4a, 0x18, 0x32,
0xf9, 0xf2, 0x94, 0x46, 0xf0, 0x50, 0xc2, 0xd5, 0xa6, 0x40,
0x76, 0x49, 0xdc, 0x41, 0xab, 0x70, 0xe2, 0x3b, 0x3d, 0xcc,
0x22, 0xc9, 0x87, 0x02, 0x81, 0x81, 0x00, 0x96, 0xa9, 0x79,
0x8d, 0x25, 0x02, 0x63, 0x40, 0x0b, 0xb6, 0x27, 0x73, 0x42,
0x88, 0x16, 0x27, 0xe0, 0x7c, 0xec, 0xdf, 0x91, 0x18, 0x7b,
0x01, 0xb8, 0x9f, 0xf4, 0x73, 0x14, 0x18, 0x8a, 0x7c, 0x20,
0xfb, 0x24, 0x80, 0x01, 0x56, 0xd2, 0xc8, 0x5d, 0x56, 0x66,
0xe8, 0xdf, 0x6c, 0xef, 0xf9, 0xf9, 0x80, 0x4d, 0xdf, 0xad,
0x80, 0xff, 0x57, 0x67, 0xde, 0x56, 0xec, 0xc0, 0x29, 0xc7,
0x2b, 0xf6, 0xc7, 0x17, 0xdf, 0x9f, 0x64, 0xda, 0xaf, 0xc2,
0x9a, 0xcf, 0x9d, 0xc7, 0x90, 0x8f, 0x9a, 0x0a, 0xd6, 0x7e,
0x20, 0xe8, 0x94, 0x99, 0x36, 0xcc, 0xba, 0x18, 0xd0, 0x21,
0xa2, 0xc4, 0xfe, 0xbb, 0x04, 0x34, 0x9a, 0x2b, 0x20, 0x47,
0xc4, 0x90, 0x13, 0x85, 0xb6, 0xe5, 0xd0, 0xc6, 0x91, 0xd1,
0x18, 0xb3, 0x3f, 0x81, 0x80, 0x2b, 0x32, 0xac, 0x27, 0x2e,
0xf0, 0x9e, 0x42, 0xfa, 0xd5, 0x02, 0x81, 0x80, 0x05, 0x54,
0xf4, 0x1b, 0x0b, 0x87, 0xf6, 0x8a, 0x45, 0x72, 0x2b, 0x3b,
0xe0, 0xcf, 0x4a, 0xb1, 0xe1, 0x65, 0x03, 0x4c, 0x1a, 0x91,
0x00, 0x2a, 0xb8, 0xf2, 0x9e, 0x9e, 0xf9, 0xe2, 0xda, 0xb6,
0xfe, 0xe7, 0xb2, 0x45, 0x5b, 0xaf, 0xb4, 0x20, 0x37, 0xe9,
0xd2, 0xf7, 0xe5, 0x33, 0xf3, 0x48, 0xa1, 0x47, 0x41, 0x2f,
0xd7, 0x20, 0x80, 0xbe, 0x7c, 0x26, 0x33, 0xf5, 0xd8, 0x02,
0xc9, 0x1c, 0x39, 0xe6, 0xbc, 0xec, 0xe3, 0xe6, 0x75, 0xe5,
0x99, 0x95, 0x03, 0x3c, 0x55, 0x73, 0x70, 0x20, 0xda, 0xd9,
0xe8, 0xb3, 0x0d, 0x04, 0xb8, 0x28, 0xad, 0xfb, 0x93, 0x04,
0xad, 0x54, 0xa1, 0x1a, 0x35, 0xa4, 0xf5, 0x07, 0x09, 0x87,
0x6a, 0xc5, 0xb1, 0x18, 0x23, 0x6b, 0xa7, 0x6a, 0x4d, 0x7c,
0x9a, 0x29, 0x1d, 0xd9, 0x60, 0x7b, 0x16, 0x9d, 0xe1, 0xd1,
0x82, 0x38, 0x56, 0x91, 0x99, 0x9f, 0x02, 0x81, 0x80, 0x1c,
0x64, 0x01, 0x89, 0xd9, 0xbf, 0xe8, 0xc6, 0x23, 0x83, 0x32,
0x10, 0xa7, 0x6c, 0x42, 0x0c, 0x6f, 0x44, 0xe5, 0xd7, 0x60,
0xe2, 0x59, 0x91, 0x6c, 0xec, 0x2a, 0xe2, 0xb1, 0x56, 0x45,
0x69, 0x60, 0xfd, 0x95, 0xe2, 0x74, 0x76, 0x60, 0xc3, 0x89,
0x56, 0x22, 0x50, 0xf0, 0x55, 0x04, 0x9c, 0xfa, 0xb7, 0xe5,
0xc3, 0x03, 0x95, 0x49, 0x38, 0x4a, 0x7a, 0x2a, 0xae, 0xb1,
0xc8, 0x24, 0xd3, 0xaf, 0x70, 0x94, 0x82, 0xa8, 0xcf, 0x9b,
0x58, 0x70, 0x22, 0xa0, 0x0b, 0x1f, 0x07, 0x22, 0xdb, 0x50,
0xf3, 0x3c, 0xb2, 0x6d, 0xc2, 0x0d, 0xd2, 0x24, 0x5d, 0x52,
0x65, 0xdf, 0x61, 0xee, 0x29, 0x83, 0xc9, 0x38, 0xc2, 0x16,
0x7d, 0xce, 0xe1, 0x21, 0xfc, 0x4b, 0x44, 0x79, 0xc2, 0x37,
0xe7, 0x28, 0xcf, 0x63, 0x3a, 0xb6, 0x0a, 0x8c, 0x0e, 0xcd,
0x04, 0xfc, 0xe7, 0xe3, 0xba, 0xa5, 0x59 ),
PUBLIC() );
/** Invalid PKCS#1 padding test (from Project Wycheproof) */
PUBKEY_ENCRYPTION_TEST ( wycheproof_padding_test, &wycheproof_key, RANDOM(),
PLAINTEXT ( 0x54, 0x65, 0x73, 0x74 ),
CIPHERTEXT ( 0x6e, 0x0d, 0x50, 0x7f, 0x66, 0xe1, 0x6d, 0x4b, 0x73,
0x73, 0xa5, 0x04, 0xc6, 0xd4, 0x86, 0x92, 0xaa, 0xa5,
0x41, 0xfd, 0xd5, 0x9e, 0xeb, 0x5d, 0x4a, 0x2c, 0xd9,
0x1f, 0x60, 0x00, 0xce, 0x9b, 0x57, 0x34, 0xa2, 0x32,
0xd6, 0x54, 0x1a, 0x78, 0x72, 0x9a, 0xc8, 0x21, 0x52,
0xd3, 0xa3, 0x0b, 0x51, 0x95, 0x0a, 0x24, 0xae, 0x37,
0x9a, 0x10, 0x8e, 0xd2, 0x0f, 0xa4, 0xec, 0x75, 0x42,
0xfe, 0x22, 0x81, 0xc2, 0xdd, 0x5d, 0xe6, 0x85, 0x56,
0x4d, 0x15, 0x18, 0x2f, 0x3c, 0x73, 0xe9, 0xc0, 0x13,
0x5e, 0xbc, 0x99, 0x3f, 0x5a, 0xcd, 0x24, 0x0a, 0x34,
0x3d, 0x32, 0x57, 0x99, 0x75, 0x82, 0x32, 0x8c, 0x31,
0xbe, 0x21, 0x5c, 0x73, 0x49, 0x37, 0x54, 0x06, 0xaa,
0x78, 0xa3, 0xac, 0x35, 0x32, 0x72, 0x26, 0x83, 0x9b,
0xee, 0x2f, 0x1a, 0x4a, 0x0f, 0x8e, 0x6e, 0x06, 0x98,
0x6c, 0xb3, 0x38, 0x06, 0xc9, 0x3e, 0x0b, 0x0c, 0x1d,
0x6c, 0xfd, 0x23, 0xf4, 0xa6, 0x8c, 0x1f, 0x2a, 0x38,
0xc7, 0x4b, 0x8d, 0xf7, 0x0f, 0x28, 0x09, 0x84, 0xa8,
0x40, 0xc7, 0x10, 0xc5, 0x22, 0x79, 0x03, 0x4d, 0x04,
0xf6, 0x1e, 0x31, 0x3d, 0x4b, 0xcd, 0x8b, 0x3b, 0x5c,
0x58, 0x46, 0x8a, 0x44, 0x56, 0x5a, 0x1a, 0xcb, 0x2e,
0xef, 0xc6, 0xd4, 0x90, 0x44, 0xbe, 0x71, 0x63, 0xe6,
0x4e, 0xd8, 0x4b, 0x5e, 0x79, 0x91, 0xec, 0xba, 0x27,
0x4a, 0x3a, 0x7e, 0xe4, 0xde, 0xfb, 0x84, 0x2a, 0x86,
0xac, 0x4c, 0xbf, 0x2d, 0x3b, 0xfc, 0x9c, 0xf8, 0x70,
0xae, 0x02, 0x5a, 0x3e, 0x2f, 0xbc, 0x77, 0x59, 0x16,
0xa5, 0x95, 0x79, 0x76, 0x3c, 0x06, 0xeb, 0x84, 0xad,
0x8e, 0xdd, 0x1d, 0x03, 0x78, 0x7e, 0x60, 0x9a, 0xd4,
0x46, 0xde, 0x43, 0xeb, 0xed, 0x16, 0x33, 0x0a, 0xb0,
0x67, 0x16, 0xfa, 0x73 ) );
/**
* Perform RSA self-tests
*
@@ -705,6 +864,7 @@ static void rsa_test_exec ( void ) {
pubkey_sign_verify_ok ( &pss_md5_test );
pubkey_sign_verify_ok ( &pss_sha1_test );
pubkey_sign_verify_ok ( &pss_sha256_test );
pubkey_decrypt_fail_ok ( &wycheproof_padding_test );
/* Restore rsa_get_random() */
rsa_get_random = saved_get_random;