From 0e154ad9cbcda72c7b9982e8875d946cce10ac0a Mon Sep 17 00:00:00 2001 From: Sun Yimin Date: Tue, 3 Dec 2024 17:48:25 +0800 Subject: [PATCH] cbc-mac supplement test cases and document #281 --- README-EN.md | 1 + README.md | 1 + cbcmac/cbcmac.go | 15 +++++++-- cbcmac/cbcmac_test.go | 76 ++++++++++++++++++++++++++++++++++++++++++ cipher/gcm_sm4_test.go | 14 ++++++++ 5 files changed, 104 insertions(+), 3 deletions(-) diff --git a/README-EN.md b/README-EN.md index e980fb9..a1de3c3 100644 --- a/README-EN.md +++ b/README-EN.md @@ -25,6 +25,7 @@ ShangMi (SM) cipher suites for Golang, referred to as **GMSM**, is a secure, hig - **ZUC** - For ZUC implementation, SIMD, AES-NI and CLMUL are used under **amd64**, **arm64** and **ppc64x**, for detail please refer [Efficient Software Implementations of ZUC](https://github.com/emmansun/gmsm/wiki/Efficient-Software-Implementations-of-ZUC) +- **CBCMAC** - CBC-MAC and its variants (EMAC/ANSI retail MAC/MacDES/CMAC/LMAC/TrCBC/CBCR). - **CFCA** - some cfca specific implementations. - **CIPHER** - ECB/CCM/XTS/HCTR/BC/OFBNLF operation modes, XTS mode also supports **GB/T 17964-2021**. Current XTS mode implementation is **NOT** concurrent safe! **BC** and **OFBNLF** are legacy operation modes, **HCTR** is new operation mode in **GB/T 17964-2021**. **BC** operation mode is similar like **CBC**, there is no room for performance optimization in **OFBNLF** operation mode. diff --git a/README.md b/README.md index c213209..f3acf78 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Go语言商用密码软件,简称**GMSM**,一个安全、高性能、易于 - **ZUC** - 祖冲之序列密码算法实现。使用SIMD、AES指令以及无进位乘法指令,分别对**amd64**、**arm64**和**ppc64x**架构做了优化实现, 您也可以参考[ZUC实现及优化](https://github.com/emmansun/gmsm/wiki/Efficient-Software-Implementations-of-ZUC)和相关代码,以获得更多实现细节。ZUC包实现了基于祖冲之序列密码算法的机密性算法、128/256位完整性算法。 +- **CBCMAC** - 符合《GB/T 15852.1-2020 采用分组密码的机制》的消息鉴别码。 - **CFCA** - CFCA(中金)特定实现,目前实现的是SM2私钥、证书封装处理,对应SADK中的**PKCS12_SM2**。 - **CIPHER** - ECB/CCM/XTS/HCTR/BC/OFBNLF加密模式实现。XTS模式同时支持NIST规范和国标 **GB/T 17964-2021**。当前的XTS模式由于实现了BlockMode,其结构包含一个tweak数组,所以其**不支持并发使用**。**分组链接(BC)模式**和**带非线性函数的输出反馈(OFBNLF)模式**为分组密码算法的工作模式标准**GB/T 17964**的遗留模式,**带泛杂凑函数的计数器(HCTR)模式**是**GB/T 17964-2021**中的新增模式。分组链接(BC)模式和CBC模式类似;而带非线性函数的输出反馈(OFBNLF)模式的话,从软件实现的角度来看,基本没有性能优化的空间。 diff --git a/cbcmac/cbcmac.go b/cbcmac/cbcmac.go index 312595a..6dd7fa3 100644 --- a/cbcmac/cbcmac.go +++ b/cbcmac/cbcmac.go @@ -1,3 +1,7 @@ +// Copyright 2024 Sun Yimin. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + // Package cbcmac implements the Message Authentication Code with the block chipher mechanisms. package cbcmac @@ -8,7 +12,8 @@ import ( "github.com/emmansun/gmsm/padding" ) -// Reference: GB/T 15821.1-2020 Security techniques - Message authentication codes - Part 1: Mechanisms using block ciphers +// Reference: GB/T 15821.1-2020 Security techniques +// Message authentication codes - Part 1: Mechanisms using block ciphers // BockCipherMAC is the interface that wraps the basic MAC method. type BockCipherMAC interface { @@ -38,8 +43,6 @@ func NewCBCMAC(b cipher.Block, size int) BockCipherMAC { return &cbcmac{b: b, pad: padding.NewISO9797M2Padding(uint(b.BlockSize())), size: size} } -// Size returns the size of the MAC. -// The returned value is the same as the block size of the block cipher. func (c *cbcmac) Size() int { return c.size } @@ -188,6 +191,8 @@ type cmac struct { // NewCMAC returns a CMAC instance that implements MAC with the given block cipher. // GB/T 15821.1-2020 MAC scheme 5 +// +// Reference: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38B.pdf func NewCMAC(b cipher.Block, size int) BockCipherMAC { if size <= 0 || size > b.BlockSize() { panic("cbcmac: invalid size") @@ -307,6 +312,8 @@ type trCBCMAC struct { // NewTRCBCMAC returns a TR-CBC-MAC instance that implements MAC with the given block cipher. // GB/T 15821.1-2020 MAC scheme 7 +// +// Reference: TrCBC: Another look at CBC-MAC. func NewTRCBCMAC(b cipher.Block, size int) BockCipherMAC { if size <= 0 || size > b.BlockSize() { panic("cbcmac: invalid size") @@ -345,6 +352,8 @@ type cbcrMAC struct { // NewCBCRMAC returns a CBCRMAC instance that implements MAC with the given block cipher. // GB/T 15821.1-2020 MAC scheme 8 +// +// Reference: CBCR: CBC MAC with rotating transformations. func NewCBCRMAC(b cipher.Block, size int) BockCipherMAC { if size <= 0 || size > b.BlockSize() { panic("cbcmac: invalid size") diff --git a/cbcmac/cbcmac_test.go b/cbcmac/cbcmac_test.go index 29ab1d6..77b1fc7 100644 --- a/cbcmac/cbcmac_test.go +++ b/cbcmac/cbcmac_test.go @@ -17,6 +17,11 @@ func TestCBCMAC(t *testing.T) { src []byte tag []byte }{ + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + nil, + []byte{0x8c, 0x33, 0x8e, 0x5a, 0x27, 0xe3, 0x49, 0xbe, 0xae, 0x39, 0x21, 0x4f, 0xed, 0xa9, 0x70, 0x99}, + }, { []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, []byte("This is the test message for mac"), @@ -50,6 +55,12 @@ func TestEMAC(t *testing.T) { src []byte tag []byte }{ + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0x41, 0x49, 0xd2, 0xad, 0xed, 0x94, 0x56, 0x68, 0x1e, 0xc8, 0xb5, 0x11, 0xd9, 0xe7, 0xee, 0x04}, + nil, + []byte{0x2c, 0xf6, 0xed, 0xf6, 0x3c, 0xce, 0x14, 0x44, 0x89, 0xea, 0xdd, 0xf0, 0x7b, 0x49, 0x38, 0xdb}, + }, { []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, []byte{0x41, 0x49, 0xd2, 0xad, 0xed, 0x94, 0x56, 0x68, 0x1e, 0xc8, 0xb5, 0x11, 0xd9, 0xe7, 0xee, 0x04}, @@ -81,6 +92,12 @@ func TestANSIRetailMAC(t *testing.T) { src []byte tag []byte }{ + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0x41, 0x49, 0xd2, 0xad, 0xed, 0x94, 0x56, 0x68, 0x1e, 0xc8, 0xb5, 0x11, 0xd9, 0xe7, 0xee, 0x04}, + nil, + []byte{0xb4, 0x73, 0x6b, 0xe9, 0xa1, 0x74, 0xfa, 0xa3, 0x4d, 0xb1, 0xe9, 0xf1, 0xda, 0xcd, 0x5d, 0x62}, + }, { []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, []byte{0x41, 0x49, 0xd2, 0xad, 0xed, 0x94, 0x56, 0x68, 0x1e, 0xc8, 0xb5, 0x11, 0xd9, 0xe7, 0xee, 0x04}, @@ -112,6 +129,12 @@ func TestMACDES(t *testing.T) { src []byte tag []byte }{ + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + []byte{0x41, 0x49, 0xd2, 0xad, 0xed, 0x94, 0x56, 0x68, 0x1e, 0xc8, 0xb5, 0x11, 0xd9, 0xe7, 0xee, 0x04}, + nil, + []byte{0x0c, 0x56, 0x00, 0x96, 0xb6, 0x09, 0xed, 0x0e, 0xaa, 0x39, 0xaf, 0xd6, 0xe2, 0x66, 0x65, 0x11}, + }, { []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, []byte{0x41, 0x49, 0xd2, 0xad, 0xed, 0x94, 0x56, 0x68, 0x1e, 0xc8, 0xb5, 0x11, 0xd9, 0xe7, 0xee, 0x04}, @@ -142,6 +165,11 @@ func TestCMAC(t *testing.T) { src []byte tag []byte }{ + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + nil, + []byte{0x29, 0xe1, 0x54, 0x32, 0x2e, 0x5c, 0x7b, 0xd8, 0xee, 0x6a, 0x25, 0xba, 0x54, 0x9b, 0x24, 0xbc}, + }, { []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, []byte("This is the test message for mac"), @@ -173,6 +201,12 @@ func TestLMAC(t *testing.T) { src []byte tag []byte }{ + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + nil, + []byte{0xcd, 0x7e, 0xd2, 0x79, 0x64, 0xe2, 0x57, 0xc0, 0x77, 0xf0, 0x55, 0xf8, 0xee, 0x38, 0x3c, 0x3f}, + }, + { []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, []byte("This is the test message for mac"), @@ -201,6 +235,11 @@ func TestTRCBCMAC(t *testing.T) { src []byte tag []byte }{ + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + nil, + []byte{0xae, 0x39, 0x21, 0x4f, 0xed, 0xa9, 0x70, 0x99}, + }, { []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, []byte("This is the test message for mac"), @@ -233,6 +272,11 @@ func TestCBCRMAC(t *testing.T) { src []byte tag []byte }{ + { + []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + nil, + []byte{0x90, 0x9f, 0x5e, 0x6e, 0xd1, 0x55, 0x18, 0xc0, 0x12, 0x52, 0x30, 0x23, 0x83, 0xc6, 0x3e, 0x8c}, + }, { []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, []byte("This is the test message for mac"), @@ -324,6 +368,21 @@ var testVectors = []struct { hash: "070a16b46b4d4144f79bdd9dd04a287c", tagsize: 16, }, + { + key: "2b7e151628aed2a6abf7158809cf4f3c", + msg: "6bc1bee22e409f96e93d7e117393172aae2d8a57", + hash: "7d85449ea6ea19c823a7bf78837dfade", + tagsize: 16, + }, + { + key: "2b7e151628aed2a6abf7158809cf4f3c", + msg: "6bc1bee22e409f96e93d7e117393172a" + + "ae2d8a571e03ac9c9eb76fac45af8e51" + + "30c81c46a35ce411e5fbc1191a0a52ef" + + "f69f2445df4f9b17ad2b417be66c3710", + hash: "51f0bebf7e3b9d92fc49741779363cfe", + tagsize: 16, + }, { key: "2b7e151628aed2a6abf7158809cf4f3c", msg: "6bc1bee22e409f96e93d7e117393172a" + @@ -363,6 +422,23 @@ var testVectors = []struct { hash: "28a7023f452e8f82bd4bf28d8c37c35c", tagsize: 16, }, + { + key: "603deb1015ca71be2b73aef0857d7781" + + "1f352c073b6108d72d9810a30914dff4", + msg: "6bc1bee22e409f96e93d7e117393172aae2d8a57", + hash: "156727dc0878944a023c1fe03bad6d93", + tagsize: 16, + }, + { + key: "603deb1015ca71be2b73aef0857d7781" + + "1f352c073b6108d72d9810a30914dff4", + msg: "6bc1bee22e409f96e93d7e117393172a" + + "ae2d8a571e03ac9c9eb76fac45af8e51" + + "30c81c46a35ce411e5fbc1191a0a52ef" + + "f69f2445df4f9b17ad2b417be66c3710", + hash: "e1992190549f6ed5696a2c056c315410", + tagsize: 16, + }, { key: "603deb1015ca71be2b73aef0857d7781" + "1f352c073b6108d72d9810a30914dff4", diff --git a/cipher/gcm_sm4_test.go b/cipher/gcm_sm4_test.go index e3796e4..40d5463 100644 --- a/cipher/gcm_sm4_test.go +++ b/cipher/gcm_sm4_test.go @@ -23,6 +23,20 @@ var sm4GCMTests = []struct { "", "232f0cfe308b49ea6fc88229b5dc858d", }, + { // GB/T 15852.3-2019 A.4 GMAC + "feffe9928665731c6d6a8f9467308308", + "cafebabefacedbaddecaf888", + "", + "feedfacedeadbeeffeedfacedeadbeef", + "9d632570f93064264a20918e3081b4cd", + }, + { // GB/T 15852.3-2019 A.4 GMAC + "feffe9928665731c6d6a8f9467308308", + "cafebabefacedbaddecaf888", + "", + "feedfacedeadbeeffeedfacedeadbeefabaddad242831ec2217774244b7221b7", + "1eeaeb669e96bd059bd9929123030e78", + }, { // GB/T 36624-2018 C.5 2 "00000000000000000000000000000000", "000000000000000000000000",