1 : /*
2 : * Copyright 2011 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can
4 : * be found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * A NaClDesc subclass that exposes the platform secure RNG
9 : * implementation.
10 : */
11 :
12 : #include <string.h>
13 :
14 : #include "native_client/src/trusted/desc/nacl_desc_rng.h"
15 :
16 : #include "native_client/src/shared/platform/nacl_secure_random.h"
17 : #include "native_client/src/shared/platform/nacl_secure_random_base.h"
18 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
19 :
20 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
21 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
22 :
23 : static struct NaClDescVtbl const kNaClDescRngVtbl; /* fwd */
24 :
25 19 : int NaClDescRngCtor(struct NaClDescRng *self) {
26 19 : if (!NaClDescCtor((struct NaClDesc *) self)) {
27 0 : goto base_ctor_fail;
28 : }
29 19 : if (!NaClSecureRngCtor(&self->rng)) {
30 0 : goto rng_ctor_fail;
31 : }
32 19 : NACL_VTBL(NaClRefCount, self) =
33 : (struct NaClRefCountVtbl *) &kNaClDescRngVtbl;
34 19 : return 1;
35 :
36 : /* failure cleanup */
37 0 : rng_ctor_fail:
38 0 : (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
39 0 : base_ctor_fail:
40 0 : return 0;
41 : }
42 :
43 0 : static void NaClDescRngDtor(struct NaClRefCount *vself) {
44 0 : struct NaClDescRng *self = (struct NaClDescRng *) vself;
45 :
46 0 : (*NACL_VTBL(NaClSecureRngIf, &self->rng)->Dtor)(
47 : (struct NaClSecureRngIf *) &self->rng);
48 0 : NACL_VTBL(NaClDesc, self) = &kNaClDescVtbl;
49 0 : (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
50 0 : }
51 :
52 : static ssize_t NaClDescRngRead(struct NaClDesc *vself,
53 : void *buf,
54 0 : size_t len) {
55 0 : struct NaClDescRng *self = (struct NaClDescRng *) vself;
56 :
57 0 : (*NACL_VTBL(NaClSecureRngIf, &self->rng)->GenBytes)(
58 : (struct NaClSecureRngIf *) &self->rng, buf, len);
59 0 : return len;
60 : }
61 :
62 : static ssize_t NaClDescRngWrite(struct NaClDesc *vself,
63 : void const *buf,
64 0 : size_t len) {
65 : UNREFERENCED_PARAMETER(vself);
66 : UNREFERENCED_PARAMETER(buf);
67 :
68 : /*
69 : * Eventually we may want to have secure pseudorandom number
70 : * generators that permit mixing user-supplied data -- presumably
71 : * low entropy, from timing of events or something like that -- into
72 : * the generator state. This must be done carefully, of course,
73 : * since we would not want the user-supplied data to destroy the
74 : * internal generator's entropy.
75 : */
76 0 : return len;
77 : }
78 :
79 : static int NaClDescRngFstat(struct NaClDesc *vself,
80 0 : struct nacl_abi_stat *statbuf) {
81 : UNREFERENCED_PARAMETER(vself);
82 :
83 0 : memset(statbuf, 0, sizeof *statbuf);
84 0 : statbuf->nacl_abi_st_dev = 0;
85 : #if defined(NACL_MASK_INODES)
86 : statbuf->nacl_abi_st_ino = NACL_FAKE_INODE_NUM;
87 : #else
88 0 : statbuf->nacl_abi_st_ino = 0;
89 : #endif
90 0 : statbuf->nacl_abi_st_mode = NACL_ABI_S_IRUSR | NACL_ABI_S_IFCHR;
91 0 : statbuf->nacl_abi_st_nlink = 1;
92 0 : statbuf->nacl_abi_st_uid = -1;
93 0 : statbuf->nacl_abi_st_gid = -1;
94 0 : statbuf->nacl_abi_st_rdev = 0;
95 0 : statbuf->nacl_abi_st_size = 0;
96 0 : statbuf->nacl_abi_st_blksize = 0;
97 0 : statbuf->nacl_abi_st_blocks = 0;
98 0 : statbuf->nacl_abi_st_atime = 0;
99 0 : statbuf->nacl_abi_st_atimensec = 0;
100 0 : statbuf->nacl_abi_st_mtime = 0;
101 0 : statbuf->nacl_abi_st_mtimensec = 0;
102 0 : statbuf->nacl_abi_st_ctime = 0;
103 0 : statbuf->nacl_abi_st_ctimensec = 0;
104 :
105 0 : return 0;
106 : }
107 :
108 : /*
109 : * We allow descriptor "transfer", where in reality we create a
110 : * separate rng locally at the recipient end. This is arguably
111 : * semantically different since there is no shared access to the same
112 : * generator; on the other hand, it should be polynomial-time
113 : * indistinguishable since the output is supposed to be
114 : * cryptographically secure.
115 : */
116 : static int NaClDescRngExternalizeSize(struct NaClDesc *vself,
117 : size_t *nbytes,
118 0 : size_t *nhandles) {
119 : UNREFERENCED_PARAMETER(vself);
120 :
121 0 : *nbytes = 0;
122 0 : *nhandles = 0;
123 0 : return 0;
124 : }
125 :
126 : static int NaClDescRngExternalize(struct NaClDesc *vself,
127 0 : struct NaClDescXferState *xfer) {
128 : UNREFERENCED_PARAMETER(vself);
129 : UNREFERENCED_PARAMETER(xfer);
130 :
131 0 : return 0;
132 : }
133 :
134 : static struct NaClDescVtbl const kNaClDescRngVtbl = {
135 : {
136 : NaClDescRngDtor,
137 : },
138 : NaClDescMapNotImplemented,
139 : NaClDescUnmapUnsafeNotImplemented,
140 : NaClDescUnmapNotImplemented,
141 : NaClDescRngRead,
142 : NaClDescRngWrite,
143 : NaClDescSeekNotImplemented,
144 : NaClDescIoctlNotImplemented,
145 : NaClDescRngFstat,
146 : NaClDescGetdentsNotImplemented,
147 : NACL_DESC_DEVICE_RNG,
148 : NaClDescRngExternalizeSize,
149 : NaClDescRngExternalize,
150 : NaClDescLockNotImplemented,
151 : NaClDescTryLockNotImplemented,
152 : NaClDescUnlockNotImplemented,
153 : NaClDescWaitNotImplemented,
154 : NaClDescTimedWaitAbsNotImplemented,
155 : NaClDescSignalNotImplemented,
156 : NaClDescBroadcastNotImplemented,
157 : NaClDescSendMsgNotImplemented,
158 : NaClDescRecvMsgNotImplemented,
159 : NaClDescConnectAddrNotImplemented,
160 : NaClDescAcceptConnNotImplemented,
161 : NaClDescPostNotImplemented,
162 : NaClDescSemWaitNotImplemented,
163 : NaClDescGetValueNotImplemented,
164 : };
165 :
166 : int NaClDescRngInternalize(struct NaClDesc **out_desc,
167 : struct NaClDescXferState *xfer,
168 0 : struct NaClDescQuotaInterface *quota_interface) {
169 : int rv;
170 0 : struct NaClDescRng *rng = malloc(sizeof *rng);
171 :
172 : UNREFERENCED_PARAMETER(xfer);
173 : UNREFERENCED_PARAMETER(quota_interface);
174 0 : if (NULL == rng) {
175 0 : rv = -NACL_ABI_ENOMEM;
176 0 : goto cleanup;
177 : }
178 0 : if (!NaClDescRngCtor(rng)) {
179 0 : rv = -NACL_ABI_EIO;
180 0 : goto cleanup;
181 : }
182 0 : *out_desc = (struct NaClDesc *) rng;
183 0 : rv = 0; /* yay! */
184 0 : cleanup:
185 0 : return rv;
186 : }
|