15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <windows.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036.  See the
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// "Community Additions" comment on MSDN here:
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define SystemFunction036 NTAPI SystemFunction036
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <NTSecAPI.h>
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#undef SystemFunction036
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <algorithm>
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <limits>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: This function must be cryptographically secure. http://crbug.com/140076
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint64 RandUint64() {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint64 number;
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RandBytes(&number, sizeof(number));
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return number;
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RandBytes(void* output, size_t output_length) {
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  char* output_ptr = static_cast<char*>(output);
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (output_length > 0) {
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ULONG output_bytes_this_pass = static_cast<ULONG>(std::min(
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        output_length, static_cast<size_t>(std::numeric_limits<ULONG>::max())));
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const bool success =
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RtlGenRandom(output_ptr, output_bytes_this_pass) != FALSE;
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CHECK(success);
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    output_length -= output_bytes_this_pass;
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    output_ptr += output_bytes_this_pass;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
44