blob: 523db6bf810b1479f3e8f4948eb148c90419ed1f [file] [log] [blame]
// Copyright 2025 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include <string.h>
#include "../../../../crypto/fipsmodule/entropy/sha512.cc.inc"
#include "../modulewrapper/modulewrapper.h"
namespace bssl {
namespace acvp {
static bool GetConfig(const Span<const uint8_t> args[],
ReplyCallback write_reply) {
static constexpr char kConfig[] =
R"([
{
"algorithm": "acvptool",
"features": ["batch"]
},
{
"algorithm": "SHA2-384",
"revision": "1.0",
"messageLength": [{
"min": 0, "max": 65528, "increment": 8
}]
}
])";
return write_reply({bssl::StringAsBytes(kConfig)});
}
constexpr size_t DigestLength = 48;
static void HashSHA384(uint8_t *out_digest, Span<const uint8_t> input) {
bssl::entropy::SHA512_CTX ctx;
bssl::entropy::SHA384_Init(&ctx);
bssl::entropy::SHA384_Update(&ctx, input.data(), input.size());
bssl::entropy::SHA384_Final(out_digest, &ctx);
}
static bool SHA384(const Span<const uint8_t> args[],
ReplyCallback write_reply) {
uint8_t digest[DigestLength];
HashSHA384(digest, args[0]);
return write_reply({Span<const uint8_t>(digest)});
}
static bool SHA384MCT(const Span<const uint8_t> args[],
ReplyCallback write_reply) {
if (args[0].size() != DigestLength) {
return false;
}
uint8_t buf[DigestLength * 3];
memcpy(buf, args[0].data(), DigestLength);
memcpy(buf + DigestLength, args[0].data(), DigestLength);
memcpy(buf + 2 * DigestLength, args[0].data(), DigestLength);
for (size_t i = 0; i < 1000; i++) {
uint8_t digest[DigestLength];
HashSHA384(digest, buf);
memmove(buf, buf + DigestLength, DigestLength * 2);
memcpy(buf + DigestLength * 2, digest, DigestLength);
}
return write_reply({Span(buf).subspan(2 * DigestLength, DigestLength)});
}
static constexpr struct {
char name[kMaxNameLength + 1];
uint8_t num_expected_args;
bool (*handler)(const Span<const uint8_t> args[], ReplyCallback write_reply);
} kFunctions[] = {
{"getConfig", 0, GetConfig},
{"SHA2-384", 1, SHA384},
{"SHA2-384/MCT", 1, SHA384MCT},
};
Handler FindHandler(Span<const Span<const uint8_t>> args) {
auto algorithm = bssl::BytesAsStringView(args[0]);
for (const auto &func : kFunctions) {
if (algorithm == func.name) {
if (args.size() - 1 != func.num_expected_args) {
fprintf(stderr,
"\'%s\' operation received %zu arguments but expected %u.\n",
func.name, args.size() - 1, func.num_expected_args);
return nullptr;
}
return func.handler;
}
}
fprintf(stderr, "Unknown operation: %s\n", std::string(algorithm).c_str());
return nullptr;
}
} // namespace acvp
} // namespace bssl