From b95124305ab15c7523d3e21437309fa5dd717ee8 Mon Sep 17 00:00:00 2001 From: Bob Beck Date: Tue, 19 Jul 2022 14:47:58 -0600 Subject: [PATCH] Mostly Revert 52426 - Drop AVCP support for 3DES Support is still needed for ACVP until 2023 Change-Id: Ia131a85bc06e7c61c823f1b3c021e2625a8769c4 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53465 Reviewed-by: Corie Pressley Reviewed-by: Adam Langley Commit-Queue: Bob Beck --- .../acvp/acvptool/subprocess/block.go | 128 ++++++++++++++++++ .../acvp/acvptool/subprocess/subprocess.go | 2 + .../acvptool/test/expected/ACVP-TDES-CBC.bz2 | Bin 0 -> 22159 bytes .../acvptool/test/expected/ACVP-TDES-ECB.bz2 | Bin 0 -> 18121 bytes util/fipstools/acvp/acvptool/test/tests.json | 2 + .../acvptool/test/vectors/ACVP-TDES-CBC.bz2 | Bin 0 -> 1009 bytes .../acvptool/test/vectors/ACVP-TDES-ECB.bz2 | Bin 0 -> 930 bytes 7 files changed, 132 insertions(+) create mode 100644 util/fipstools/acvp/acvptool/test/expected/ACVP-TDES-CBC.bz2 create mode 100644 util/fipstools/acvp/acvptool/test/expected/ACVP-TDES-ECB.bz2 create mode 100644 util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-CBC.bz2 create mode 100644 util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-ECB.bz2 diff --git a/util/fipstools/acvp/acvptool/subprocess/block.go b/util/fipstools/acvp/acvptool/subprocess/block.go index f979c8650..1b1e93b99 100644 --- a/util/fipstools/acvp/acvptool/subprocess/block.go +++ b/util/fipstools/acvp/acvptool/subprocess/block.go @@ -18,6 +18,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "math/bits" ) // aesKeyShuffle is the "AES Monte Carlo Key Shuffle" from the ACVP @@ -118,6 +119,113 @@ func iterateAESCBC(transact func(n int, args ...[]byte) ([][]byte, error), encry return mctResults } +// xorKeyWithOddParityLSB XORs value into key while setting the LSB of each bit +// to establish odd parity. This embedding of a parity check in a DES key is an +// old tradition and something that NIST's tests require (despite being +// undocumented). +func xorKeyWithOddParityLSB(key, value []byte) { + for i := range key { + v := key[i] ^ value[i] + // Use LSB to establish odd parity. + v ^= byte((bits.OnesCount8(v) & 1)) ^ 1 + key[i] = v + } +} + +// desKeyShuffle implements the manipulation of the Key arrays in the "TDES +// Monte Carlo Test - ECB mode" algorithm from the ACVP specification. +func keyShuffle3DES(key, result, prevResult, prevPrevResult []byte) { + xorKeyWithOddParityLSB(key[:8], result) + xorKeyWithOddParityLSB(key[8:16], prevResult) + xorKeyWithOddParityLSB(key[16:], prevPrevResult) +} + +// iterate3DES implements "TDES Monte Carlo Test - ECB mode" from the ACVP +// specification. +func iterate3DES(transact func(n int, args ...[]byte) ([][]byte, error), encrypt bool, key, input, iv []byte) (mctResults []blockCipherMCTResult) { + for i := 0; i < 400; i++ { + var iteration blockCipherMCTResult + keyHex := hex.EncodeToString(key) + iteration.Key1Hex = keyHex[:16] + iteration.Key2Hex = keyHex[16:32] + iteration.Key3Hex = keyHex[32:] + + if encrypt { + iteration.PlaintextHex = hex.EncodeToString(input) + } else { + iteration.CiphertextHex = hex.EncodeToString(input) + } + + results, err := transact(3, key, input, uint32le(10000)) + if err != nil { + panic("block operation failed") + } + result := results[0] + prevResult := results[1] + prevPrevResult := results[2] + + if encrypt { + iteration.CiphertextHex = hex.EncodeToString(result) + } else { + iteration.PlaintextHex = hex.EncodeToString(result) + } + + keyShuffle3DES(key, result, prevResult, prevPrevResult) + mctResults = append(mctResults, iteration) + input = result + } + + return mctResults +} + +// iterate3DESCBC implements "TDES Monte Carlo Test - CBC mode" from the ACVP +// specification. +func iterate3DESCBC(transact func(n int, args ...[]byte) ([][]byte, error), encrypt bool, key, input, iv []byte) (mctResults []blockCipherMCTResult) { + for i := 0; i < 400; i++ { + var iteration blockCipherMCTResult + keyHex := hex.EncodeToString(key) + iteration.Key1Hex = keyHex[:16] + iteration.Key2Hex = keyHex[16:32] + iteration.Key3Hex = keyHex[32:] + + if encrypt { + iteration.PlaintextHex = hex.EncodeToString(input) + } else { + iteration.CiphertextHex = hex.EncodeToString(input) + } + iteration.IVHex = hex.EncodeToString(iv) + + results, err := transact(3, key, input, iv, uint32le(10000)) + if err != nil { + panic("block operation failed") + } + + result := results[0] + prevResult := results[1] + prevPrevResult := results[2] + + if encrypt { + iteration.CiphertextHex = hex.EncodeToString(result) + } else { + iteration.PlaintextHex = hex.EncodeToString(result) + } + + keyShuffle3DES(key, result, prevResult, prevPrevResult) + + if encrypt { + input = prevResult + iv = result + } else { + iv = prevResult + input = result + } + + mctResults = append(mctResults, iteration) + } + + return mctResults +} + // blockCipher implements an ACVP algorithm by making requests to the subprocess // to encrypt and decrypt with a block cipher. type blockCipher struct { @@ -148,6 +256,11 @@ type blockCipherTestGroup struct { CiphertextHex string `json:"ct"` IVHex string `json:"iv"` KeyHex string `json:"key"` + + // 3DES tests serialise the key differently. + Key1Hex string `json:"key1"` + Key2Hex string `json:"key2"` + Key3Hex string `json:"key3"` } `json:"tests"` } @@ -168,6 +281,11 @@ type blockCipherMCTResult struct { PlaintextHex string `json:"pt"` CiphertextHex string `json:"ct"` IVHex string `json:"iv,omitempty"` + + // 3DES tests serialise the key differently. + Key1Hex string `json:"key1,omitempty"` + Key2Hex string `json:"key2,omitempty"` + Key3Hex string `json:"key3,omitempty"` } func (b *blockCipher) Process(vectorSet []byte, m Transactable) (interface{}, error) { @@ -213,6 +331,11 @@ func (b *blockCipher) Process(vectorSet []byte, m Transactable) (interface{}, er return nil, fmt.Errorf("test group %d has unknown type %q", group.ID, group.Type) } + if group.KeyBits == 0 { + // 3DES tests fail to set this parameter. + group.KeyBits = 192 + } + if group.KeyBits%8 != 0 { return nil, fmt.Errorf("test group %d contains non-byte-multiple key length %d", group.ID, group.KeyBits) } @@ -223,6 +346,11 @@ func (b *blockCipher) Process(vectorSet []byte, m Transactable) (interface{}, er } for _, test := range group.Tests { + if len(test.KeyHex) == 0 && len(test.Key1Hex) > 0 { + // 3DES encodes the key differently. + test.KeyHex = test.Key1Hex + test.Key2Hex + test.Key3Hex + } + if len(test.KeyHex) != keyBytes*2 { return nil, fmt.Errorf("test case %d/%d contains key %q of length %d, but expected %d-bit key", group.ID, test.ID, test.KeyHex, len(test.KeyHex), group.KeyBits) } diff --git a/util/fipstools/acvp/acvptool/subprocess/subprocess.go b/util/fipstools/acvp/acvptool/subprocess/subprocess.go index 5f7a273ec..158bae317 100644 --- a/util/fipstools/acvp/acvptool/subprocess/subprocess.go +++ b/util/fipstools/acvp/acvptool/subprocess/subprocess.go @@ -85,6 +85,8 @@ func NewWithIO(cmd *exec.Cmd, in io.WriteCloser, out io.ReadCloser) *Subprocess "ACVP-AES-CBC": &blockCipher{"AES-CBC", 16, 2, true, true, iterateAESCBC}, "ACVP-AES-CBC-CS3": &blockCipher{"AES-CBC-CS3", 16, 1, false, true, iterateAESCBC}, "ACVP-AES-CTR": &blockCipher{"AES-CTR", 16, 1, false, true, nil}, + "ACVP-TDES-ECB": &blockCipher{"3DES-ECB", 8, 3, true, false, iterate3DES}, + "ACVP-TDES-CBC": &blockCipher{"3DES-CBC", 8, 3, true, true, iterate3DESCBC}, "ACVP-AES-XTS": &xts{}, "ACVP-AES-GCM": &aead{"AES-GCM", false}, "ACVP-AES-GMAC": &aead{"AES-GCM", false}, diff --git a/util/fipstools/acvp/acvptool/test/expected/ACVP-TDES-CBC.bz2 b/util/fipstools/acvp/acvptool/test/expected/ACVP-TDES-CBC.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..4c2832c549bba24f87cccf009cfef1581049e18f GIT binary patch literal 22159 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 literal 0 HcmV?d00001 diff --git a/util/fipstools/acvp/acvptool/test/tests.json b/util/fipstools/acvp/acvptool/test/tests.json index 5765de179..f1cb04f93 100644 --- a/util/fipstools/acvp/acvptool/test/tests.json +++ b/util/fipstools/acvp/acvptool/test/tests.json @@ -9,6 +9,8 @@ {"Wrapper": "modulewrapper", "In": "vectors/ACVP-AES-KW.bz2", "Out": "expected/ACVP-AES-KW.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/ACVP-AES-KWP.bz2", "Out": "expected/ACVP-AES-KWP.bz2"}, {"Wrapper": "testmodulewrapper", "In": "vectors/ACVP-AES-XTS.bz2", "Out": "expected/ACVP-AES-XTS.bz2"}, +{"Wrapper": "modulewrapper", "In": "vectors/ACVP-TDES-CBC.bz2", "Out": "expected/ACVP-TDES-CBC.bz2"}, +{"Wrapper": "modulewrapper", "In": "vectors/ACVP-TDES-ECB.bz2", "Out": "expected/ACVP-TDES-ECB.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/CMAC-AES.bz2", "Out": "expected/CMAC-AES.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/ctrDRBG.bz2", "Out": "expected/ctrDRBG.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/ECDSA.bz2", "Out": "expected/ECDSA.bz2"}, diff --git a/util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-CBC.bz2 b/util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-CBC.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..33fdbf35ad4f6f3923654e50615fc5a259dc32c2 GIT binary patch literal 1009 zcmV}m zlN9nadXv!spa1{>0BTG$(-2Y`44MD{000Q5lO~xN2}A*)00000<^TWy0000007Vis z6A@F|22{!Fcp;Ne@{F6*ndM8=QPAU)5ar9xh(tX7TeolO-(B?Iq-c(yM>KOrw`6L| z3vtSGoR=sdh=?G7S5_Z0JOS8%f^{mR?o>iTy_T8&5%WfA`}XvoupKZ@b;o~9jnhg6 z_*vFA+Z}jy(@_`JYX$jXkGq*s*l`jJM-YQRk>PE&#LxE?Y%Ge!lRPR7C|Oanh3Neu z7!mxdW~CngfXMix3rYesMiyZhl|lo?*n4|HlygQAqA-9I*U#7O?S75&eh8@>q#sBr z7{I;~NVf~q;ZJ?Q`4$oi)L-Yi>pzTDso`78FSx+&x^?D!qd0No1At)TNPt|BJ6y8o zk}hnX@)5=%y^xVr1>}uU+2U52)C3~qnt`2@X{s=|CtlC!!uyPqolaxS+6e~J4Fa-2 zSq2pnsj(r6Dp4F!9dyjaC9}&R#V`mD4)9>p0R(IhOQ(4{WuX<+N?J)0Lp);1gRUfF z(@9Awt5s}$90w2w5}P|fI9#d9xE29=?~T=U^Atr;?KQHD;`l^qtr}|rSVf700$7||Uo7G|6%1t=SMU7MjM>`#F#%$c}G+e@p$ z(<{22=Xul69(Osu7$#s#N>dm>&JA{TfQ}?`2Xw%j*e%TKfU{W_HlS>3Nv-VoB%sE)3+cfu~{ysM?pL>kX#HFk`* z96Cy7s*FvL6X=G((?v|+DOI+dRO}WI;Z1kD|v2{w3ZwYNr* zF-l0TvH}9lVEni|2w;diCP*M5ipoE0?Wx4)2X4LAi%shK{GvRO)3QDnqvSq|V9LL9 z?4v~wUo?Grdk;cBh0B?mEEaJDXpV^CC!#x~MhsEI93=oFEpz$fPD(pgh{*`Lj?1w# zM{e0iHR6sYDAH}^%P#bJ`KXUU8frQYWm=&h(=@>|Ha&qP81{)G#-=yuM@{^ literal 0 HcmV?d00001 diff --git a/util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-ECB.bz2 b/util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-ECB.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..c8853ed2219388ed707949cbee9a3cec0864ffe7 GIT binary patch literal 930 zcmV;T16}+=T4*^jL0KkKS$D$JumA?OUw~C~PzV3;KcdeHF7MwePy`%$CBOiKLzn;n z0000000F6p#Apd7g&F_=9-|W=1DF5+00000009(81jRKTrkK=ekkG`?^nvJ^wLv0< zPt!;c^)`v7Kzbl(&OphqNfM$2zCV|{pI zIZi8#5JW@}LaD0{sg>rj5krtcA83dY7JI9Fk?lu{oiWF6psea*t)en9i%gxaS92M# zRXUk298%F>Bv=#_gM5YGLWM_tWko89n38wa4Jv}6ru$L-LNFubtym!ZK0_naj4ddr zQ5ac-VpRwZs^RJB22srzMu@;8O?y3iw_TfbpW1ocF&+7)V@bF$ueF3S)vfzcZg&q8mYRstAZexlP< zSFk<$3b$%kLbm#)j%a=FXkOyNz~yfSXzuGyptrlC1@9p#r=TIC0$t(8<8kDjsna}d zi*`PQw^E(S`>NJw*zV8d3~TUxb5AV%DpasvRHrV@0!gT?B5 zeAiROLB?B77Dhra(?%2D7YbPf!Gbs8e1b8L6#4L`iaQpF$q2fRi*PbWX30k-;Eo0e(reR9ekifo6e~xH`DtQF zO$v+~ZMH-LI7G7zC|MPwVlZ>sjk`75c@b5mBoX{0VmBTr=!`-$AjkY&$rRy2LEj5f Ez!l=2@Bjb+ literal 0 HcmV?d00001