13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/util/crypto_helpers.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/format_macros.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/base64.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/rand_util.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing std::string;
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing std::vector;
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMD5Calculator::MD5Calculator() {
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MD5Init(&context_);
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickMD5Calculator::~MD5Calculator() {}
26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MD5Calculator::AddData(const unsigned char* data, int length) {
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(bin_digest_.empty());
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MD5Update(&context_, data, length);
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MD5Calculator::CalcDigest() {
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (bin_digest_.empty()) {
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MD5Digest digest;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MD5Final(&digest, &context_);
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bin_digest_.assign(digest.a, digest.a + arraysize(digest.a));
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst vector<uint8>& MD5Calculator::GetDigest() {
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CalcDigest();
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return bin_digest_;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string MD5Calculator::GetHexDigest() {
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CalcDigest();
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  string hex = base::HexEncode(reinterpret_cast<char*>(&bin_digest_.front()),
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               bin_digest_.size());
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StringToLowerASCII(&hex);
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return hex;
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetRandomBytes(char* output, int output_length) {
54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  uint64 random_int;
55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const char* random_int_bytes = reinterpret_cast<const char*>(&random_int);
56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  int random_int_size = sizeof(random_int);
57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  for (int i = 0; i < output_length; i += random_int_size) {
58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    random_int = base::RandUint64();
59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int copy_count = std::min(output_length - i, random_int_size);
60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    memcpy(output + i, random_int_bytes, copy_count);
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstring Generate128BitRandomHexString() {
65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const int kNumberBytes = 128 / 8;
66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string random_bytes(kNumberBytes, ' ');
67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  GetRandomBytes(&random_bytes[0], kNumberBytes);
68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string base64_encoded_bytes;
69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  base::Base64Encode(random_bytes, &base64_encoded_bytes);
70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return base64_encoded_bytes;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
72