acvp: add AES-CTR support. Change-Id: I61ba8b0eb717d2e66f3e2b098819ce979b8aca88 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/43126 Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/util/fipstools/acvp/acvptool/acvp/acvp.go b/util/fipstools/acvp/acvptool/acvp/acvp.go index 52d7488..55d2f0b 100644 --- a/util/fipstools/acvp/acvptool/acvp/acvp.go +++ b/util/fipstools/acvp/acvptool/acvp/acvp.go
@@ -89,7 +89,7 @@ return conn, err }, }, - Timeout: 10 * time.Second, + Timeout: 30 * time.Second, } return &Server{client: client, prefix: prefix, totpFunc: totp, PrefixTokens: make(map[string]string)}
diff --git a/util/fipstools/acvp/acvptool/subprocess/block.go b/util/fipstools/acvp/acvptool/subprocess/block.go index 69a6517..9e51078 100644 --- a/util/fipstools/acvp/acvptool/subprocess/block.go +++ b/util/fipstools/acvp/acvptool/subprocess/block.go
@@ -23,9 +23,10 @@ // blockCipher implements an ACVP algorithm by making requests to the subprocess // to encrypt and decrypt with a block cipher. type blockCipher struct { - algo string - blockSize int - hasIV bool + algo string + blockSize int + inputsAreBlockMultiples bool + hasIV bool } type blockCipherVectorSet struct { @@ -97,7 +98,7 @@ var mct bool switch group.Type { - case "AFT": + case "AFT", "CTR": mct = false case "MCT": mct = true @@ -132,7 +133,7 @@ return nil, fmt.Errorf("failed to decode hex in test case %d/%d: %s", group.ID, test.ID, err) } - if len(input)%b.blockSize != 0 { + if b.inputsAreBlockMultiples && len(input)%b.blockSize != 0 { return nil, fmt.Errorf("test case %d/%d has input of length %d, but expected multiple of %d", group.ID, test.ID, len(input), b.blockSize) }
diff --git a/util/fipstools/acvp/acvptool/subprocess/subprocess.go b/util/fipstools/acvp/acvptool/subprocess/subprocess.go index 431c315..af757d5 100644 --- a/util/fipstools/acvp/acvptool/subprocess/subprocess.go +++ b/util/fipstools/acvp/acvptool/subprocess/subprocess.go
@@ -76,8 +76,9 @@ "SHA2-256": &hashPrimitive{"SHA2-256", 32}, "SHA2-384": &hashPrimitive{"SHA2-384", 48}, "SHA2-512": &hashPrimitive{"SHA2-512", 64}, - "ACVP-AES-ECB": &blockCipher{"AES", 16, false}, - "ACVP-AES-CBC": &blockCipher{"AES-CBC", 16, true}, + "ACVP-AES-ECB": &blockCipher{"AES", 16, true, false}, + "ACVP-AES-CBC": &blockCipher{"AES-CBC", 16, true, true}, + "ACVP-AES-CTR": &blockCipher{"AES-CTR", 16, false, true}, "HMAC-SHA-1": &hmacPrimitive{"HMAC-SHA-1", 20}, "HMAC-SHA2-224": &hmacPrimitive{"HMAC-SHA2-224", 28}, "HMAC-SHA2-256": &hmacPrimitive{"HMAC-SHA2-256", 32},
diff --git a/util/fipstools/acvp/modulewrapper/modulewrapper.cc b/util/fipstools/acvp/modulewrapper/modulewrapper.cc index 6ea5143..043d375 100644 --- a/util/fipstools/acvp/modulewrapper/modulewrapper.cc +++ b/util/fipstools/acvp/modulewrapper/modulewrapper.cc
@@ -171,6 +171,18 @@ "keyLen": [128, 192, 256] }, { + "algorithm": "ACVP-AES-CTR", + "revision": "1.0", + "direction": ["encrypt", "decrypt"], + "keyLen": [128, 192, 256], + "payloadLen": [{ + "min": 8, "max": 128, "increment": 8 + }], + "incrementalCounter": true, + "overflowCounter": true, + "performCounterTests": true + }, + { "algorithm": "ACVP-AES-CBC", "revision": "1.0", "direction": ["encrypt", "decrypt"], @@ -379,6 +391,26 @@ return WriteReply(STDOUT_FILENO, Span<const uint8_t>(out)); } +static bool AES_CTR(const Span<const uint8_t> args[]) { + AES_KEY key; + if (AES_set_encrypt_key(args[0].data(), args[0].size() * 8, &key) != 0) { + return false; + } + if (args[2].size() != AES_BLOCK_SIZE) { + return false; + } + uint8_t iv[AES_BLOCK_SIZE]; + memcpy(iv, args[2].data(), AES_BLOCK_SIZE); + + std::vector<uint8_t> out; + out.resize(args[1].size()); + unsigned num = 0; + uint8_t ecount_buf[AES_BLOCK_SIZE]; + AES_ctr128_encrypt(args[1].data(), out.data(), args[1].size(), &key, iv, + ecount_buf, &num); + return WriteReply(STDOUT_FILENO, Span<const uint8_t>(out)); +} + template <const EVP_MD *HashFunc()> static bool HMAC(const Span<const uint8_t> args[]) { const EVP_MD *const md = HashFunc(); @@ -624,6 +656,8 @@ {"AES/decrypt", 2, AES<AES_set_decrypt_key, AES_decrypt>}, {"AES-CBC/encrypt", 3, AES_CBC<AES_set_encrypt_key, AES_ENCRYPT>}, {"AES-CBC/decrypt", 3, AES_CBC<AES_set_decrypt_key, AES_DECRYPT>}, + {"AES-CTR/encrypt", 3, AES_CTR}, + {"AES-CTR/decrypt", 3, AES_CTR}, {"HMAC-SHA-1", 2, HMAC<EVP_sha1>}, {"HMAC-SHA2-224", 2, HMAC<EVP_sha224>}, {"HMAC-SHA2-256", 2, HMAC<EVP_sha256>},