p256_key_util_unittest.cc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/gcm_driver/crypto/p256_key_util.h"
  5. #include <stddef.h>
  6. #include <set>
  7. #include "base/base64.h"
  8. #include "crypto/ec_private_key.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. namespace gcm {
  11. namespace {
  12. // A P-256 point in uncompressed form consists of 0x04 (to denote that the point
  13. // is uncompressed per SEC1 2.3.3) followed by two, 32-byte field elements.
  14. const size_t kUncompressedPointBytes = 1 + 2 * 32;
  15. // Precomputed private/public key-pair. Keys are stored on disk, so previously
  16. // created values must continue to be usable for computing shared secrets.
  17. const char kBobPrivateKey[] =
  18. "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgS8wRbDOWz0lKExvIVQiRKtPAP8"
  19. "dgHUHAw5gyOd5d4jKhRANCAARZb49Va5MD/KcWtc0oiWc2e8njBDtQzj0mzcOl1fDSt16Pvu6p"
  20. "fTU3MTWnImDNnkPxtXm58K7Uax8jFxA4TeXJ";
  21. const char kBobPublicKey[] =
  22. "BFlvj1VrkwP8pxa1zSiJZzZ7yeMEO1DOPSbNw6XV8NK3Xo++7ql9NTcxNaciYM2eQ/G1ebnwrt"
  23. "RrHyMXEDhN5ck=";
  24. const char kCarolPrivateKey[] =
  25. "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgmqy/ighwCm+RBP4Kct3rzaFEJ"
  26. "CZhokknro3KYsriurChRANCAAScr5sTsqmlP8SqiI+8fzxVLr1pby2HyG5mC5J0WSpYVIpMNS"
  27. "C16k1qcxqOJ4fiv8Ya47FYw/MIS7X1kobK27mP";
  28. const char kCarolPublicKey[] =
  29. "BJyvmxOyqaU/xKqIj7x/PFUuvWlvLYfIbmYLknRZKlhUikw1ILXqTWpzGo4nh+K/xhrjsVjD8"
  30. "whLtfWShsrbuY8=";
  31. // The shared secret between Bob and Carol.
  32. const char kBobCarolSharedSecret[] =
  33. "AUNmKkgLLVLf6j/VnA9Eg1CiPSPfQHGirQj79n4vOyw=";
  34. TEST(P256KeyUtilTest, UniqueKeyPairGeneration) {
  35. // Canary for determining that no key repetitions are found in few iterations.
  36. std::set<std::string> seen_private_keys;
  37. std::set<std::string> seen_public_keys;
  38. for (int iteration = 0; iteration < 10; ++iteration) {
  39. SCOPED_TRACE(iteration);
  40. std::string private_key, public_key;
  41. std::unique_ptr<crypto::ECPrivateKey> key(crypto::ECPrivateKey::Create());
  42. ASSERT_TRUE(key);
  43. ASSERT_TRUE(GetRawPublicKey(*key, &public_key));
  44. ASSERT_TRUE(GetRawPrivateKey(*key, &private_key));
  45. EXPECT_NE(private_key, public_key);
  46. EXPECT_GT(private_key.size(), 0u);
  47. EXPECT_EQ(public_key.size(), kUncompressedPointBytes);
  48. EXPECT_EQ(0u, seen_private_keys.count(private_key));
  49. EXPECT_EQ(0u, seen_public_keys.count(public_key));
  50. seen_private_keys.insert(private_key);
  51. seen_public_keys.insert(public_key);
  52. }
  53. }
  54. TEST(P256KeyUtilTest, SharedSecretCalculation) {
  55. std::unique_ptr<crypto::ECPrivateKey> bob_key =
  56. crypto::ECPrivateKey::Create();
  57. std::unique_ptr<crypto::ECPrivateKey> alice_key =
  58. crypto::ECPrivateKey::Create();
  59. std::string alice_public_key, bob_public_key, alice_private_key,
  60. bob_private_key;
  61. ASSERT_TRUE(GetRawPublicKey(*bob_key, &bob_public_key));
  62. ASSERT_TRUE(GetRawPublicKey(*alice_key, &alice_public_key));
  63. ASSERT_TRUE(GetRawPrivateKey(*bob_key, &bob_private_key));
  64. ASSERT_TRUE(GetRawPrivateKey(*alice_key, &alice_private_key));
  65. ASSERT_NE(bob_public_key, alice_public_key);
  66. ASSERT_NE(bob_private_key, alice_private_key);
  67. std::string bob_shared_secret, alice_shared_secret;
  68. ASSERT_TRUE(
  69. ComputeSharedP256Secret(*bob_key, alice_public_key, &bob_shared_secret));
  70. ASSERT_TRUE(ComputeSharedP256Secret(*alice_key, bob_public_key,
  71. &alice_shared_secret));
  72. EXPECT_GT(bob_shared_secret.size(), 0u);
  73. EXPECT_EQ(bob_shared_secret, alice_shared_secret);
  74. std::string unused_shared_secret;
  75. // Empty and too short peer public values should be considered invalid.
  76. ASSERT_FALSE(ComputeSharedP256Secret(*bob_key, "", &unused_shared_secret));
  77. ASSERT_FALSE(ComputeSharedP256Secret(*bob_key, bob_public_key.substr(1),
  78. &unused_shared_secret));
  79. }
  80. TEST(P256KeyUtilTest, SharedSecretWithPreExistingKey) {
  81. std::string bob_private_key, bob_public_key;
  82. ASSERT_TRUE(base::Base64Decode(kBobPrivateKey, &bob_private_key));
  83. ASSERT_TRUE(base::Base64Decode(kBobPublicKey, &bob_public_key));
  84. std::vector<uint8_t> bob_private_key_vec(
  85. bob_private_key.begin(), bob_private_key.end());
  86. std::unique_ptr<crypto::ECPrivateKey> bob_key =
  87. crypto::ECPrivateKey::CreateFromPrivateKeyInfo(bob_private_key_vec);
  88. ASSERT_TRUE(bob_key);
  89. // First verify against a newly created, ephemeral key-pair.
  90. std::unique_ptr<crypto::ECPrivateKey> alice_key(
  91. crypto::ECPrivateKey::Create());
  92. std::string alice_public_key;
  93. ASSERT_TRUE(GetRawPublicKey(*alice_key, &alice_public_key));
  94. std::string bob_shared_secret, alice_shared_secret;
  95. ASSERT_TRUE(ComputeSharedP256Secret(*bob_key, alice_public_key,
  96. &bob_shared_secret));
  97. ASSERT_TRUE(ComputeSharedP256Secret(*alice_key, bob_public_key,
  98. &alice_shared_secret));
  99. EXPECT_GT(bob_shared_secret.size(), 0u);
  100. EXPECT_EQ(bob_shared_secret, alice_shared_secret);
  101. std::string carol_private_key, carol_public_key;
  102. ASSERT_TRUE(base::Base64Decode(kCarolPrivateKey, &carol_private_key));
  103. ASSERT_TRUE(base::Base64Decode(kCarolPublicKey, &carol_public_key));
  104. std::vector<uint8_t> carol_private_key_vec(
  105. carol_private_key.begin(), carol_private_key.end());
  106. std::unique_ptr<crypto::ECPrivateKey> carol_key =
  107. crypto::ECPrivateKey::CreateFromPrivateKeyInfo(carol_private_key_vec);
  108. ASSERT_TRUE(carol_key);
  109. bob_shared_secret.clear();
  110. std::string carol_shared_secret;
  111. // Then verify against another stored key-pair and shared secret.
  112. ASSERT_TRUE(ComputeSharedP256Secret(*bob_key, carol_public_key,
  113. &bob_shared_secret));
  114. ASSERT_TRUE(ComputeSharedP256Secret(*carol_key, bob_public_key,
  115. &carol_shared_secret));
  116. EXPECT_GT(carol_shared_secret.size(), 0u);
  117. EXPECT_EQ(carol_shared_secret, bob_shared_secret);
  118. std::string bob_carol_shared_secret;
  119. ASSERT_TRUE(base::Base64Decode(
  120. kBobCarolSharedSecret, &bob_carol_shared_secret));
  121. EXPECT_EQ(carol_shared_secret, bob_carol_shared_secret);
  122. }
  123. } // namespace
  124. } // namespace gcm