Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / chromeos / login / hwid_checker.cc
blobf04337ca31bd6b35b45240a3d2a252bf7664f460
1 // Copyright (c) 2013 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.
5 #include "chrome/browser/chromeos/login/hwid_checker.h"
7 #include <cstdio>
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "base/strings/string_util.h"
12 #include "base/sys_info.h"
13 #include "chrome/common/chrome_switches.h"
14 #include "chromeos/chromeos_switches.h"
15 #include "chromeos/system/statistics_provider.h"
16 #include "third_party/re2/re2/re2.h"
17 #include "third_party/zlib/zlib.h"
19 namespace {
21 unsigned CalculateCRC32(const std::string& data) {
22 return static_cast<unsigned>(crc32(
24 reinterpret_cast<const Bytef*>(data.c_str()),
25 data.length()));
28 std::string CalculateHWIDv2Checksum(const std::string& data) {
29 unsigned crc32 = CalculateCRC32(data);
30 // We take four least significant decimal digits of CRC-32.
31 char checksum[5];
32 int snprintf_result =
33 snprintf(checksum, 5, "%04u", crc32 % 10000);
34 LOG_ASSERT(snprintf_result == 4);
35 return checksum;
38 bool IsCorrectHWIDv2(const std::string& hwid) {
39 std::string body;
40 std::string checksum;
41 if (!RE2::FullMatch(hwid, "([\\s\\S]*) (\\d{4})", &body, &checksum))
42 return false;
43 return CalculateHWIDv2Checksum(body) == checksum;
46 bool IsExceptionalHWID(const std::string& hwid) {
47 return RE2::PartialMatch(hwid, "^(SPRING [A-D])|(FALCO A)");
50 std::string CalculateExceptionalHWIDChecksum(const std::string& data) {
51 static const char base32_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
52 unsigned crc32 = CalculateCRC32(data);
53 // We take 10 least significant bits of CRC-32 and encode them in 2 characters
54 // using Base32 alphabet.
55 std::string checksum;
56 checksum += base32_alphabet[(crc32 >> 5) & 0x1f];
57 checksum += base32_alphabet[crc32 & 0x1f];
58 return checksum;
61 bool IsCorrectExceptionalHWID(const std::string& hwid) {
62 if (!IsExceptionalHWID(hwid))
63 return false;
64 std::string bom;
65 if (!RE2::FullMatch(hwid, "[A-Z0-9]+ ((?:[A-Z2-7]{4}-)*[A-Z2-7]{1,4})", &bom))
66 return false;
67 if (bom.length() < 2)
68 return false;
69 std::string hwid_without_dashes;
70 base::RemoveChars(hwid, "-", &hwid_without_dashes);
71 LOG_ASSERT(hwid_without_dashes.length() >= 2);
72 std::string not_checksum =
73 hwid_without_dashes.substr(0, hwid_without_dashes.length() - 2);
74 std::string checksum =
75 hwid_without_dashes.substr(hwid_without_dashes.length() - 2);
76 return CalculateExceptionalHWIDChecksum(not_checksum) == checksum;
79 std::string CalculateHWIDv3Checksum(const std::string& data) {
80 static const char base8_alphabet[] = "23456789";
81 static const char base32_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
82 unsigned crc32 = CalculateCRC32(data);
83 // We take 8 least significant bits of CRC-32 and encode them in 2 characters.
84 std::string checksum;
85 checksum += base8_alphabet[(crc32 >> 5) & 0x7];
86 checksum += base32_alphabet[crc32 & 0x1f];
87 return checksum;
90 bool IsCorrectHWIDv3(const std::string& hwid) {
91 if (IsExceptionalHWID(hwid))
92 return false;
93 std::string regex =
94 "([A-Z0-9]+ (?:[A-Z2-7][2-9][A-Z2-7]-)*[A-Z2-7])([2-9][A-Z2-7])";
95 std::string not_checksum, checksum;
96 if (!RE2::FullMatch(hwid, regex, &not_checksum, &checksum))
97 return false;
98 base::RemoveChars(not_checksum, "-", &not_checksum);
99 return CalculateHWIDv3Checksum(not_checksum) == checksum;
102 } // anonymous namespace
104 namespace chromeos {
106 bool IsHWIDCorrect(const std::string& hwid) {
107 return IsCorrectHWIDv2(hwid) || IsCorrectExceptionalHWID(hwid) ||
108 IsCorrectHWIDv3(hwid);
111 bool IsMachineHWIDCorrect() {
112 #if !defined(GOOGLE_CHROME_BUILD)
113 return true;
114 #endif
115 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
116 if (cmd_line->HasSwitch(::switches::kTestType))
117 return true;
118 if (!base::SysInfo::IsRunningOnChromeOS())
119 return true;
120 std::string hwid;
121 chromeos::system::StatisticsProvider* stats =
122 chromeos::system::StatisticsProvider::GetInstance();
123 if (!stats->GetMachineStatistic(chromeos::system::kHardwareClassKey, &hwid)) {
124 LOG(ERROR) << "Couldn't get machine statistic 'hardware_class'.";
125 return false;
127 if (!chromeos::IsHWIDCorrect(hwid)) {
128 LOG(ERROR) << "Machine has malformed HWID '" << hwid << "'.";
129 return false;
131 return true;
134 } // namespace chromeos