acvp: add 3DES-CBC support

Change-Id: I2e6cc7367b5ca6631329be298fbed7424221a06b
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/43406
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
chromium-5359
Adam Langley 4 years ago committed by CQ bot account: commit-bot@chromium.org
parent e796cc6502
commit 9c12f01de7
  1. 59
      util/fipstools/acvp/acvptool/subprocess/block.go
  2. 1
      util/fipstools/acvp/acvptool/subprocess/subprocess.go
  3. 26
      util/fipstools/acvp/modulewrapper/modulewrapper.cc

@ -203,6 +203,65 @@ func iterate3DES(transact func(n int, args ...[]byte) ([][]byte, error), encrypt
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)
var result, prevResult, prevPrevResult []byte
for j := 0; j < 10000; j++ {
prevPrevResult = prevResult
prevResult = result
results, err := transact(1, key, input, iv)
if err != nil {
panic("block operation failed")
}
result = results[0]
if encrypt {
if j == 0 {
input = iv
} else {
input = prevResult
}
iv = result
} else {
iv = input
input = result
}
}
if encrypt {
iteration.CiphertextHex = hex.EncodeToString(result)
} else {
iteration.PlaintextHex = hex.EncodeToString(result)
}
keyShuffle3DES(key, result, prevResult, prevPrevResult)
if encrypt {
input = prevResult
iv = 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 {

@ -80,6 +80,7 @@ func NewWithIO(cmd *exec.Cmd, in io.WriteCloser, out io.ReadCloser) *Subprocess
"ACVP-AES-CBC": &blockCipher{"AES-CBC", 16, true, true, iterateAESCBC},
"ACVP-AES-CTR": &blockCipher{"AES-CTR", 16, false, true, nil},
"ACVP-TDES-ECB": &blockCipher{"3DES-ECB", 8, true, false, iterate3DES},
"ACVP-TDES-CBC": &blockCipher{"3DES-CBC", 8, true, true, iterate3DESCBC},
"ACVP-AES-GCM": &aead{"AES-GCM", false},
"ACVP-AES-CCM": &aead{"AES-CCM", true},
"ACVP-AES-KW": &aead{"AES-KW", false},

@ -258,6 +258,13 @@ static bool GetConfig(const Span<const uint8_t> args[]) {
"keyLen": [192],
"keyingOption": [1]
},
{
"algorithm": "ACVP-TDES-CBC",
"revision": "1.0",
"direction": ["encrypt", "decrypt"],
"keyLen": [192],
"keyingOption": [1]
},
{
"algorithm": "HMAC-SHA-1",
"revision": "1.0",
@ -728,9 +735,9 @@ static bool AESPaddedKeyWrapOpen(const Span<const uint8_t> args[]) {
Span<const uint8_t>(out));
}
template<bool Encrypt>
template<bool Encrypt, bool HasIV, const EVP_CIPHER* (*cipher_func)()>
static bool TDES(const Span<const uint8_t> args[]) {
const EVP_CIPHER *cipher = EVP_des_ede3();
const EVP_CIPHER *cipher = cipher_func();
if (args[0].size() != 24) {
fprintf(stderr, "Bad key length %u for 3DES.\n",
@ -742,14 +749,19 @@ static bool TDES(const Span<const uint8_t> args[]) {
static_cast<unsigned>(args[1].size()));
return false;
}
if (HasIV && args[2].size() != EVP_CIPHER_iv_length(cipher)) {
fprintf(stderr, "Bad IV length %u for 3DES.\n",
static_cast<unsigned>(args[2].size()));
return false;
}
std::vector<uint8_t> out;
out.resize(args[1].size());
bssl::ScopedEVP_CIPHER_CTX ctx;
int out_len, out_len2;
if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, args[0].data(), nullptr,
Encrypt ? 1 : 0) ||
if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, args[0].data(),
HasIV ? args[2].data() : nullptr, Encrypt ? 1 : 0) ||
!EVP_CIPHER_CTX_set_padding(ctx.get(), 0) ||
!EVP_CipherUpdate(ctx.get(), out.data(), &out_len, args[1].data(),
args[1].size()) ||
@ -1016,8 +1028,10 @@ static constexpr struct {
{"AES-KWP/open", 5, AESPaddedKeyWrapOpen},
{"AES-CCM/seal", 5, AEADSeal<AESCCMSetup>},
{"AES-CCM/open", 5, AEADOpen<AESCCMSetup>},
{"3DES-ECB/encrypt", 2, TDES<true>},
{"3DES-ECB/decrypt", 2, TDES<false>},
{"3DES-ECB/encrypt", 2, TDES<true, false, EVP_des_ede3>},
{"3DES-ECB/decrypt", 2, TDES<false, false, EVP_des_ede3>},
{"3DES-CBC/encrypt", 3, TDES<true, true, EVP_des_ede3_cbc>},
{"3DES-CBC/decrypt", 3, TDES<false, true, EVP_des_ede3_cbc>},
{"HMAC-SHA-1", 2, HMAC<EVP_sha1>},
{"HMAC-SHA2-224", 2, HMAC<EVP_sha224>},
{"HMAC-SHA2-256", 2, HMAC<EVP_sha256>},

Loading…
Cancel
Save