cbcmac,padding: supplement/update comments

This commit is contained in:
Sun Yimin 2025-03-20 16:34:19 +08:00 committed by GitHub
parent 3cc92436ee
commit a4affe6006
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 63 additions and 91 deletions

View File

@ -33,9 +33,8 @@ type cbcmac struct {
size int
}
// NewCBCMAC returns a CBC-MAC instance that implements the MAC with the given block cipher.
// The padding scheme is ISO/IEC 9797-1 method 2.
// GB/T 15821.1-2020 MAC scheme 1
// NewCBCMAC returns a CBC-MAC (GB/T 15821.1-2020 MAC scheme 1) instance that
// implements the MAC with the given block cipher. The padding scheme is ISO/IEC 9797-1 method 2.
func NewCBCMAC(b cipher.Block, size int) BockCipherMAC {
return NewCBCMACWithPadding(b, size, padding.NewISO9797M2Padding)
}
@ -45,19 +44,11 @@ func NewCBCMAC(b cipher.Block, size int) BockCipherMAC {
// with the specified block cipher, MAC size, and padding function. The MAC size must be greater
// than 0 and less than or equal to the block size of the cipher. If the size is invalid, the
// function will panic. The padding function is used to pad the input to the block size of the cipher.
//
// Parameters:
// - b: The block cipher to use for CBC-MAC.
// - size: The size of the MAC in bytes. Must be greater than 0 and less than or equal to the block size of the cipher.
// - paddingFunc: The padding function to use for padding the input to the block size of the cipher.
//
// Returns:
// - A BockCipherMAC instance that can be used to compute the CBC-MAC.
func NewCBCMACWithPadding(b cipher.Block, size int, paddingFunc padding.PaddingFunc) BockCipherMAC {
func NewCBCMACWithPadding(b cipher.Block, size int, newPaddingFunc padding.NewPaddingFunc) BockCipherMAC {
if size <= 0 || size > b.BlockSize() {
panic("cbcmac: invalid size")
}
return &cbcmac{b: b, pad: paddingFunc(uint(b.BlockSize())), size: size}
return &cbcmac{b: b, pad: newPaddingFunc(uint(b.BlockSize())), size: size}
}
func (c *cbcmac) Size() int {
@ -85,23 +76,14 @@ type emac struct {
size int
}
// NewEMAC returns an EMAC instance that implements MAC with the given block cipher.
// The padding scheme is ISO/IEC 9797-1 method 2.
// GB/T 15821.1-2020 MAC scheme 2
// NewEMAC returns an EMAC (GB/T 15821.1-2020 MAC scheme 2) instance that
// implements MAC with the given block cipher. The padding scheme is ISO/IEC 9797-1 method 2.
func NewEMAC(creator func(key []byte) (cipher.Block, error), key1, key2 []byte, size int) BockCipherMAC {
return NewEMACWithPadding(creator, key1, key2, size, padding.NewISO9797M2Padding)
}
// NewEMACWithPadding creates a new instance of EMAC (Encrypted Message Authentication Code) with padding.
// It takes the following parameters:
// - creator: a function that takes a key and returns a cipher.Block and an error.
// - key1: the first key used to create the first cipher.Block.
// - key2: the second key used to create the second cipher.Block.
// - size: the size of the MAC. It must be greater than 0 and less than or equal to the block size of the cipher.
// - paddingFunc: a function that returns the padding to be used.
//
// The function returns a BockCipherMAC instance. It panics if there is an error creating the cipher.Blocks or if the size is invalid.
func NewEMACWithPadding(creator func(key []byte) (cipher.Block, error), key1, key2 []byte, size int, paddingFunc padding.PaddingFunc) BockCipherMAC {
func NewEMACWithPadding(creator func(key []byte) (cipher.Block, error), key1, key2 []byte, size int, newPaddingFunc padding.NewPaddingFunc) BockCipherMAC {
var b1, b2 cipher.Block
var err error
if b1, err = creator(key1); err != nil {
@ -113,7 +95,7 @@ func NewEMACWithPadding(creator func(key []byte) (cipher.Block, error), key1, ke
if b2, err = creator(key2); err != nil {
panic(err)
}
return &emac{pad: paddingFunc(uint(b1.BlockSize())), b1: b1, b2: b2, size: size}
return &emac{pad: newPaddingFunc(uint(b1.BlockSize())), b1: b1, b2: b2, size: size}
}
func (e *emac) Size() int {
@ -135,24 +117,15 @@ func (e *emac) MAC(src []byte) []byte {
type ansiRetailMAC emac
// NewANSIRetailMAC returns an ANSI Retail MAC instance that implements MAC with the given block cipher.
// The padding scheme is ISO/IEC 9797-1 method 2.
// GB/T 15821.1-2020 MAC scheme 3
// NewANSIRetailMAC returns an ANSI Retail MAC (GB/T 15821.1-2020 MAC scheme 3) instance that
// implements MAC with the given block cipher. The padding scheme is ISO/IEC 9797-1 method 2.
func NewANSIRetailMAC(creator func(key []byte) (cipher.Block, error), key1, key2 []byte, size int) BockCipherMAC {
return NewANSIRetailMACWithPadding(creator, key1, key2, size, padding.NewISO9797M2Padding)
}
// NewANSIRetailMACWithPadding creates a new ANSI Retail MAC with padding.
// It takes the following parameters:
// - creator: a function that takes a key and returns a cipher.Block and an error.
// - key1: the first key used for the MAC.
// - key2: the second key used for the MAC.
// - size: the size of the MAC.
// - paddingFunc: a function used to pad the input data.
//
// It returns a BockCipherMAC which is an instance of ansiRetailMAC.
func NewANSIRetailMACWithPadding(creator func(key []byte) (cipher.Block, error), key1, key2 []byte, size int, paddingFunc padding.PaddingFunc) BockCipherMAC {
return (*ansiRetailMAC)(NewEMACWithPadding(creator, key1, key2, size, paddingFunc).(*emac))
func NewANSIRetailMACWithPadding(creator func(key []byte) (cipher.Block, error), key1, key2 []byte, size int, newPaddingFunc padding.NewPaddingFunc) BockCipherMAC {
return (*ansiRetailMAC)(NewEMACWithPadding(creator, key1, key2, size, newPaddingFunc).(*emac))
}
func (e *ansiRetailMAC) Size() int {
@ -179,14 +152,13 @@ type macDES struct {
size int
}
// NewMACDES returns a MAC-DES instance that implements MAC with the given block cipher.
// The padding scheme is ISO/IEC 9797-1 method 2.
// GB/T 15821.1-2020 MAC scheme 4
// NewMACDES returns a MAC-DES (GB/T 15821.1-2020 MAC scheme 4) instance that
// implements MAC with the given block cipher. The padding scheme is ISO/IEC 9797-1 method 2.
func NewMACDES(creator func(key []byte) (cipher.Block, error), key1, key2 []byte, size int) BockCipherMAC {
return NewMACDESWithPadding(creator, key1, key2, size, padding.NewISO9797M2Padding)
}
func NewMACDESWithPadding(creator func(key []byte) (cipher.Block, error), key1, key2 []byte, size int, paddingFunc padding.PaddingFunc) BockCipherMAC {
func NewMACDESWithPadding(creator func(key []byte) (cipher.Block, error), key1, key2 []byte, size int, newPaddingFunc padding.NewPaddingFunc) BockCipherMAC {
var b1, b2, b3 cipher.Block
var err error
if b1, err = creator(key1); err != nil {
@ -206,7 +178,7 @@ func NewMACDESWithPadding(creator func(key []byte) (cipher.Block, error), key1,
if b3, err = creator(key3); err != nil {
panic(err)
}
return &macDES{pad: paddingFunc(uint(b1.BlockSize())), b1: b1, b2: b2, b3: b3, size: size}
return &macDES{pad: newPaddingFunc(uint(b1.BlockSize())), b1: b1, b2: b2, b3: b3, size: size}
}
func (m *macDES) Size() int {
@ -241,8 +213,7 @@ type cmac struct {
len uint64
}
// NewCMAC returns a CMAC instance that implements MAC with the given block cipher.
// GB/T 15821.1-2020 MAC scheme 5
// NewCMAC returns a CMAC (GB/T 15821.1-2020 MAC scheme 5) instance that implements MAC with the given block cipher.
//
// Reference: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38B.pdf
func NewCMAC(b cipher.Block, size int) *cmac {
@ -381,22 +352,14 @@ type lmac struct {
size int
}
// NewLMAC returns an LMAC instance that implements MAC with the given block cipher.
// GB/T 15821.1-2020 MAC scheme 6
// NewLMAC returns an LMAC (GB/T 15821.1-2020 MAC scheme 6) instance that
// implements MAC with the given block cipher. The padding scheme is ISO/IEC 9797-1 method 2.
func NewLMAC(creator func(key []byte) (cipher.Block, error), key []byte, size int) BockCipherMAC {
return NewLMACWithPadding(creator, key, size, padding.NewISO9797M2Padding)
}
// NewLMACWithPadding creates a new LMAC (Length-based Message Authentication Code) with padding.
// It takes the following parameters:
// - creator: a function that takes a key and returns a cipher.Block and an error.
// - key: the key used for the MAC.
// - size: the size of the MAC output. It must be greater than 0 and less than or equal to the block size of the cipher.
// - paddingFunc: a function that returns a padding function for the given block size.
//
// The function initializes two cipher blocks using derived keys and returns an instance of BockCipherMAC.
// It panics if the key creation fails or if the size is invalid.
func NewLMACWithPadding(creator func(key []byte) (cipher.Block, error), key []byte, size int, paddingFunc padding.PaddingFunc) BockCipherMAC {
func NewLMACWithPadding(creator func(key []byte) (cipher.Block, error), key []byte, size int, newPaddingFunc padding.NewPaddingFunc) BockCipherMAC {
var b, b1, b2 cipher.Block
var err error
if b, err = creator(key); err != nil {
@ -419,7 +382,7 @@ func NewLMACWithPadding(creator func(key []byte) (cipher.Block, error), key []by
panic(err)
}
return &lmac{b1: b1, b2: b2, pad: paddingFunc(uint(blockSize)), size: size}
return &lmac{b1: b1, b2: b2, pad: newPaddingFunc(uint(blockSize)), size: size}
}
func (l *lmac) Size() int {
@ -445,8 +408,8 @@ type trCBCMAC struct {
size int
}
// NewTRCBCMAC returns a TR-CBC-MAC instance that implements MAC with the given block cipher.
// GB/T 15821.1-2020 MAC scheme 7
// NewTRCBCMAC returns a TR-CBC-MAC (GB/T 15821.1-2020 MAC scheme 7) instance that
// implements MAC with the given block cipher.
//
// Reference: TrCBC: Another look at CBC-MAC.
func NewTRCBCMAC(b cipher.Block, size int) BockCipherMAC {
@ -485,8 +448,7 @@ type cbcrMAC struct {
size int
}
// NewCBCRMAC returns a CBCRMAC instance that implements MAC with the given block cipher.
// GB/T 15821.1-2020 MAC scheme 8
// NewCBCRMAC returns a CBCRMAC (GB/T 15821.1-2020 MAC scheme 8) instance that implements MAC with the given block cipher.
//
// Reference: CBCR: CBC MAC with rotating transformations.
func NewCBCRMAC(b cipher.Block, size int) BockCipherMAC {

View File

@ -52,10 +52,10 @@ func TestCBCMAC(t *testing.T) {
func TestCBCMACWithPadding(t *testing.T) {
// Test vectors from GB/T 15821.1-2020 Appendix B.
cases := []struct {
key []byte
src []byte
tag []byte
paddingFunc padding.PaddingFunc
key []byte
src []byte
tag []byte
newPaddingFunc padding.NewPaddingFunc
}{
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
@ -94,7 +94,7 @@ func TestCBCMACWithPadding(t *testing.T) {
if err != nil {
t.Errorf("#%d: failed to create cipher: %v", i, err)
}
mac := NewCBCMACWithPadding(block, len(c.tag), c.paddingFunc)
mac := NewCBCMACWithPadding(block, len(c.tag), c.newPaddingFunc)
tag := mac.MAC(c.src)
if !bytes.Equal(tag, c.tag) {
t.Errorf("#%d: expect tag %x, got %x", i, c.tag, tag)
@ -105,11 +105,11 @@ func TestCBCMACWithPadding(t *testing.T) {
func TestEMACWithPadding(t *testing.T) {
// Test vectors from GB/T 15821.1-2020 Appendix B.
cases := []struct {
key1 []byte
key2 []byte
src []byte
tag []byte
paddingFunc padding.PaddingFunc
key1 []byte
key2 []byte
src []byte
tag []byte
newPaddingFunc padding.NewPaddingFunc
}{
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
@ -149,7 +149,7 @@ func TestEMACWithPadding(t *testing.T) {
}
for i, c := range cases {
mac := NewEMACWithPadding(sm4.NewCipher, c.key1, c.key2, len(c.tag), c.paddingFunc)
mac := NewEMACWithPadding(sm4.NewCipher, c.key1, c.key2, len(c.tag), c.newPaddingFunc)
tag := mac.MAC(c.src)
if !bytes.Equal(tag, c.tag) {
t.Errorf("#%d: expect tag %x, got %x", i, c.tag, tag)
@ -234,11 +234,11 @@ func TestANSIRetailMAC(t *testing.T) {
func TestANSIRetailMACWithPadding(t *testing.T) {
// Test vectors from GB/T 15821.1-2020 Appendix B.
cases := []struct {
key1 []byte
key2 []byte
src []byte
tag []byte
paddingFunc padding.PaddingFunc
key1 []byte
key2 []byte
src []byte
tag []byte
newPaddingFunc padding.NewPaddingFunc
}{
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
@ -278,7 +278,7 @@ func TestANSIRetailMACWithPadding(t *testing.T) {
}
for i, c := range cases {
mac := NewANSIRetailMACWithPadding(sm4.NewCipher, c.key1, c.key2, len(c.tag), c.paddingFunc)
mac := NewANSIRetailMACWithPadding(sm4.NewCipher, c.key1, c.key2, len(c.tag), c.newPaddingFunc)
tag := mac.MAC(c.src)
if !bytes.Equal(tag, c.tag) {
t.Errorf("#%d: expect tag %x, got %x", i, c.tag, tag)
@ -326,11 +326,11 @@ func TestMACDES(t *testing.T) {
func TestMACDESWithPadding(t *testing.T) {
// Test vectors from GB/T 15821.1-2020 Appendix B.
cases := []struct {
key1 []byte
key2 []byte
src []byte
tag []byte
paddingFunc padding.PaddingFunc
key1 []byte
key2 []byte
src []byte
tag []byte
newPaddingFunc padding.NewPaddingFunc
}{
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
@ -370,7 +370,7 @@ func TestMACDESWithPadding(t *testing.T) {
}
for i, c := range cases {
mac := NewMACDESWithPadding(sm4.NewCipher, c.key1, c.key2, 16, c.paddingFunc)
mac := NewMACDESWithPadding(sm4.NewCipher, c.key1, c.key2, 16, c.newPaddingFunc)
tag := mac.MAC(c.src)
if !bytes.Equal(tag, c.tag) {
t.Errorf("#%d: expect tag %x, got %x", i, c.tag, tag)
@ -451,10 +451,10 @@ func TestLMAC(t *testing.T) {
func TestLMACWithPadding(t *testing.T) {
// Test vectors from GB/T 15821.1-2020 Appendix B.
cases := []struct {
key []byte
src []byte
tag []byte
paddingFunc padding.PaddingFunc
key []byte
src []byte
tag []byte
newPaddingFunc padding.NewPaddingFunc
}{
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
@ -489,7 +489,7 @@ func TestLMACWithPadding(t *testing.T) {
}
for i, c := range cases {
mac := NewLMACWithPadding(sm4.NewCipher, c.key, 16, c.paddingFunc)
mac := NewLMACWithPadding(sm4.NewCipher, c.key, 16, c.newPaddingFunc)
tag := mac.MAC(c.src)
if !bytes.Equal(tag, c.tag) {
t.Errorf("#%d: expect tag %x, got %x", i, c.tag, tag)

View File

@ -8,8 +8,11 @@ type Padding interface {
Unpad(src []byte) ([]byte, error)
}
type PaddingFunc func(blockSize uint) Padding
type NewPaddingFunc func(blockSize uint) Padding
// NewPKCS7Padding creates a new PKCS7 padding scheme with the specified block size.
// The block size must be between 1 and 255, inclusive. If the block size is 0 or greater than 255,
// the function will panic with an "invalid block size" error.
func NewPKCS7Padding(blockSize uint) Padding {
if blockSize == 0 || blockSize > 255 {
panic("padding: invalid block size")
@ -17,6 +20,9 @@ func NewPKCS7Padding(blockSize uint) Padding {
return pkcs7Padding(blockSize)
}
// NewANSIX923Padding creates a new instance of ANSI X.923 padding with the specified block size.
// The block size must be between 1 and 255, inclusive. If the block size is 0 or greater than 255,
// the function will panic with an "invalid block size" message.
func NewANSIX923Padding(blockSize uint) Padding {
if blockSize == 0 || blockSize > 255 {
panic("padding: invalid block size")
@ -24,6 +30,8 @@ func NewANSIX923Padding(blockSize uint) Padding {
return ansiX923Padding(blockSize)
}
// NewISO9797M2Padding creates a new ISO/IEC 9797-1 Padding Method 2 (also known as ISO 10126) instance
// with the specified block size. The block size must be between 1 and 255 inclusive.
func NewISO9797M2Padding(blockSize uint) Padding {
if blockSize == 0 || blockSize > 255 {
panic("padding: invalid block size")
@ -31,6 +39,8 @@ func NewISO9797M2Padding(blockSize uint) Padding {
return iso9797M2Padding(blockSize)
}
// NewISO9797M3Padding creates a new ISO/IEC 9797-1 Padding Method 3 (also known as ISO 10126) padding scheme
// with the specified block size. The block size must be between 1 and 255 inclusive.
func NewISO9797M3Padding(blockSize uint) Padding {
if blockSize == 0 || blockSize > 255 {
panic("padding: invalid block size")