910e62b5创建于 1月15日历史提交
// 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));
}