diff --git a/pkg/ipmi/aes_128_cbc.go b/pkg/ipmi/aes_128_cbc.go index a08fac9..0902703 100644 --- a/pkg/ipmi/aes_128_cbc.go +++ b/pkg/ipmi/aes_128_cbc.go @@ -66,7 +66,11 @@ func (a *AES128CBC) DecodeFromBytes(data []byte, _ gopacket.DecodeFeedback) erro mode.CryptBlocks(data[a.cipher.BlockSize():], data[a.cipher.BlockSize():]) padBytes := uint8(data[len(data)-1]) - if padBytes > uint8(a.cipher.BlockSize()-1) { + // table 13-20 of the spec says the confidentiality pad length ranges from + // 0 to 15 bytes if using AES, but we may receive 16 bytes if the BMC's + // implementation of AES in CBC mode requires a minimum of one pad byte + // (which is how OpenSSL works) and the message is already aligned. + if padBytes > uint8(a.cipher.BlockSize()) { return fmt.Errorf("invalid number of pad bytes: %v", padBytes) } padStart := len(data) - int(padBytes) - 1 diff --git a/pkg/ipmi/aes_128_cbc_test.go b/pkg/ipmi/aes_128_cbc_test.go index 2538147..c18ee65 100644 --- a/pkg/ipmi/aes_128_cbc_test.go +++ b/pkg/ipmi/aes_128_cbc_test.go @@ -29,8 +29,8 @@ func TestAES128CBCDecodeFromBytes(t *testing.T) { 0x7b, 0xec, 0x46, 0xd5, 0xbb, 0x90, 0xba, }, }, - // 15 bytes data (< block size, but 0 padding as 1 byte taken by padding - // length) + // 15 bytes of data encrypted with 0 bytes of padding (1 byte taken by + // padding length) { key: [16]byte{ 0x6f, 0x9c, 0xad, 0xa3, 0x92, 0xa3, 0xbb, 0x12, 0x8d, 0xdb, @@ -47,8 +47,30 @@ func TestAES128CBCDecodeFromBytes(t *testing.T) { 0x3a, 0x3c, 0x9b, 0x30, 0x81, }, }, - // 16 bytes data (must flow onto second block for padding length, max - // padding) + // 15 bytes of data encrypted with 16 bytes of padding. + // This is not how AES128CBC.SerializeTo would encrypt this message, but + // other implementations of AES in CBC mode may work this way (e.g. + // OpenSSL). + { + key: [16]byte{ + 0x12, 0xd4, 0x51, 0x8d, 0x94, 0x2e, 0x28, 0x78, 0x6a, 0x75, + 0x8b, 0xf5, 0xbe, 0x25, 0xaf, 0xf9, + }, + + data: []byte{ + 0xa2, 0x56, 0x33, 0xf7, 0xe2, 0xb4, 0x12, 0x33, 0xb8, 0xb, + 0xfb, 0xde, 0x47, 0x66, 0xa8, 0x9e, + 0x7a, 0xb7, 0xca, 0x4b, 0x3d, 0xb7, 0x8a, 0xf9, 0xc9, 0x5, + 0xaf, 0x3, 0xac, 0xb4, 0xae, 0xc8, 0xdb, 0x37, 0xb8, 0x42, + 0x2b, 0x62, 0x44, 0x3f, 0x33, 0x29, 0x52, 0x85, 0xd2, 0x11, + 0x73, 0xa, + }, + message: []byte{ + 0x66, 0x66, 0x68, 0x36, 0x53, 0x42, 0x34, 0x35, 0x6b, 0x6d, + 0x2c, 0x30, 0x39, 0x2d, 0x33, + }, + }, + // 16 bytes data (must flow onto second block for padding length) { key: [16]byte{ 0x02, 0x4a, 0x88, 0x40, 0xdd, 0x55, 0x04, 0xfb, 0xc9, 0x2e,