blob: 0890296a2bc0fb8b69e84fa3ecb36f78aad0479f [file] [log] [blame]
// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "crypto/hmac.h"
#include <stddef.h>
#include <string.h>
#include <array>
#include <string>
#include <string_view>
#include "base/compiler_specific.h"
#include "base/strings/string_number_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(HMACTest, OneShotSha1) {
// RFC 2202 test case 3:
std::vector<uint8_t> key(20, 0xaa);
std::vector<uint8_t> data(50, 0xdd);
std::vector<uint8_t> expected;
CHECK(base::HexStringToBytes("125d7342b9ac11cd91a39af48aa17b4f63f175d3",
&expected));
// Old API signing:
{
crypto::HMAC hmac(crypto::HMAC::SHA1);
ASSERT_TRUE(hmac.Init(key));
std::array<uint8_t, crypto::hash::kSha1Size> result;
EXPECT_TRUE(hmac.Sign(data, result));
EXPECT_EQ(base::as_byte_span(expected), result);
}
// Old API verification:
{
crypto::HMAC hmac(crypto::HMAC::SHA1);
ASSERT_TRUE(hmac.Init(key));
EXPECT_TRUE(hmac.Verify(data, expected));
}
auto result = crypto::hmac::SignSha1(key, data);
EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
EXPECT_TRUE(crypto::hmac::VerifySha1(key, data, result));
result[0] ^= 0x01;
EXPECT_FALSE(crypto::hmac::VerifySha1(key, data, result));
}
TEST(HMACTest, OneShotSha256) {
// RFC 4231 test case 3:
std::vector<uint8_t> key(20, 0xaa);
std::vector<uint8_t> data(50, 0xdd);
std::vector<uint8_t> expected;
CHECK(base::HexStringToBytes(
"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
&expected));
// Old API signing:
{
crypto::HMAC hmac(crypto::HMAC::SHA256);
ASSERT_TRUE(hmac.Init(key));
std::array<uint8_t, crypto::hash::kSha256Size> result;
EXPECT_TRUE(hmac.Sign(data, result));
EXPECT_EQ(base::as_byte_span(expected), result);
}
// Old API verification:
{
crypto::HMAC hmac(crypto::HMAC::SHA256);
ASSERT_TRUE(hmac.Init(key));
EXPECT_TRUE(hmac.Verify(data, expected));
}
auto result = crypto::hmac::SignSha256(key, data);
EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
EXPECT_TRUE(crypto::hmac::VerifySha256(key, data, result));
result[0] ^= 0x01;
EXPECT_FALSE(crypto::hmac::VerifySha256(key, data, result));
}
TEST(HMACTest, OneShotSha384) {
// RFC 4231 test case 3:
std::vector<uint8_t> key(20, 0xaa);
std::vector<uint8_t> data(50, 0xdd);
std::vector<uint8_t> expected;
CHECK(
base::HexStringToBytes("88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe"
"83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27",
&expected));
std::array<uint8_t, crypto::hash::kSha384Size> result;
crypto::hmac::Sign(crypto::hash::kSha384, key, data, result);
EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
EXPECT_TRUE(crypto::hmac::Verify(crypto::hash::kSha384, key, data, result));
result[0] ^= 0x01;
EXPECT_FALSE(crypto::hmac::Verify(crypto::hash::kSha384, key, data, result));
}
TEST(HMACTest, OneShotSha512) {
// RFC 4231 test case 3:
std::vector<uint8_t> key(20, 0xaa);
std::vector<uint8_t> data(50, 0xdd);
std::vector<uint8_t> expected;
CHECK(base::HexStringToBytes(
"fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39"
"bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb",
&expected));
auto result = crypto::hmac::SignSha512(key, data);
EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
EXPECT_TRUE(crypto::hmac::VerifySha512(key, data, result));
result[0] ^= 0x01;
EXPECT_FALSE(crypto::hmac::VerifySha512(key, data, result));
}
TEST(HMACTest, OneShotWrongLengthDies) {
std::array<uint8_t, 32> key;
std::array<uint8_t, 32> data;
std::array<uint8_t, 16> small_hmac;
std::array<uint8_t, 128> big_hmac;
EXPECT_DEATH_IF_SUPPORTED(crypto::hmac::Sign(crypto::hash::HashKind::kSha256,
key, data, small_hmac),
"");
EXPECT_DEATH_IF_SUPPORTED(
crypto::hmac::Sign(crypto::hash::HashKind::kSha256, key, data, big_hmac),
"");
EXPECT_DEATH_IF_SUPPORTED(
(void)crypto::hmac::Verify(crypto::hash::HashKind::kSha256, key, data,
small_hmac),
"");
EXPECT_DEATH_IF_SUPPORTED(
(void)crypto::hmac::Verify(crypto::hash::HashKind::kSha256, key, data,
big_hmac),
"");
}
TEST(HMACTest, StreamingSha512) {
// RFC 4231 test case 3:
std::vector<uint8_t> key(20, 0xaa);
std::vector<uint8_t> data1(32, 0xdd);
std::vector<uint8_t> data2(18, 0xdd);
std::vector<uint8_t> expected;
CHECK(base::HexStringToBytes(
"fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39"
"bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb",
&expected));
crypto::hmac::HmacSigner signer(crypto::hash::kSha512, key);
signer.Update(data1);
signer.Update(data2);
auto result = signer.Finish();
EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
crypto::hmac::HmacVerifier verifier(crypto::hash::kSha512, key);
verifier.Update(data1);
verifier.Update(data2);
EXPECT_TRUE(verifier.Finish(result));
}