1 : /*
2 : * Copyright (c) 2008 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * NaCl Service Runtime. Secure RNG implementation.
9 : */
10 : #include <windows.h>
11 :
12 : /*
13 : * #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036. See
14 : * the "Community Additions" comment on MSDN here:
15 : * http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx
16 : */
17 : #define SystemFunction036 NTAPI SystemFunction036
18 : #include <NTSecAPI.h>
19 : #undef SystemFunction036
20 :
21 : #include "native_client/src/shared/platform/nacl_log.h"
22 : #include "native_client/src/shared/platform/nacl_secure_random.h"
23 :
24 :
25 : static void NaClSecureRngDtor(struct NaClSecureRngIf *vself);
26 : static uint8_t NaClSecureRngGenByte(struct NaClSecureRngIf *vself);
27 :
28 : static struct NaClSecureRngIfVtbl const kNaClSecureRngVtbl = {
29 : NaClSecureRngDtor,
30 : NaClSecureRngGenByte,
31 : NaClSecureRngDefaultGenUint32,
32 : NaClSecureRngDefaultGenBytes,
33 : NaClSecureRngDefaultUniform,
34 : };
35 :
36 16 : void NaClSecureRngModuleInit(void) {
37 : return;
38 16 : }
39 :
40 11 : void NaClSecureRngModuleFini(void) {
41 : return;
42 11 : }
43 :
44 16 : int NaClSecureRngCtor(struct NaClSecureRng *self) {
45 16 : self->base.vtbl = &kNaClSecureRngVtbl;
46 16 : self->nvalid = 0;
47 16 : return 1;
48 16 : }
49 :
50 : int NaClSecureRngTestingCtor(struct NaClSecureRng *self,
51 : uint8_t *seed_material,
52 0 : size_t seed_bytes) {
53 : UNREFERENCED_PARAMETER(seed_material);
54 : UNREFERENCED_PARAMETER(seed_bytes);
55 0 : self->base.vtbl = NULL;
56 0 : self->nvalid = 0;
57 0 : return 0;
58 0 : }
59 :
60 11 : static void NaClSecureRngDtor(struct NaClSecureRngIf *vself) {
61 11 : struct NaClSecureRng *self = (struct NaClSecureRng *) vself;
62 11 : SecureZeroMemory(self->buf, sizeof self->buf);
63 11 : vself->vtbl = NULL;
64 : return;
65 11 : }
66 :
67 3 : static void NaClSecureRngFilbuf(struct NaClSecureRng *self) {
68 3 : if (!RtlGenRandom(self->buf, sizeof self->buf)) {
69 0 : NaClLog(LOG_FATAL, "RtlGenRandom failed: error 0x%x\n", GetLastError());
70 : }
71 3 : self->nvalid = sizeof self->buf;
72 3 : }
73 :
74 3 : static uint8_t NaClSecureRngGenByte(struct NaClSecureRngIf *vself) {
75 3 : struct NaClSecureRng *self = (struct NaClSecureRng *) vself;
76 3 : if (0 > self->nvalid) {
77 : NaClLog(LOG_FATAL,
78 : "NaClSecureRngGenByte: illegal buffer state, nvalid = %d\n",
79 0 : self->nvalid);
80 : }
81 3 : if (0 == self->nvalid) {
82 3 : NaClSecureRngFilbuf(self);
83 : }
84 3 : return self->buf[--self->nvalid];
85 3 : }
|