2 * Copyright (c) 2012 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.
8 * A NaClDesc subclass that exposes the platform secure RNG
14 #include "native_client/src/trusted/desc/nacl_desc_rng.h"
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"
20 #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
21 #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
23 static struct NaClDescVtbl const kNaClDescRngVtbl; /* fwd */
25 static int NaClDescRngSubclassCtor(struct NaClDescRng *self) {
26 if (!NaClSecureRngCtor(&self->rng)) {
29 NACL_VTBL(NaClRefCount, self) =
30 (struct NaClRefCountVtbl *) &kNaClDescRngVtbl;
35 (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
39 int NaClDescRngCtor(struct NaClDescRng *self) {
41 if (!NaClDescCtor((struct NaClDesc *) self)) {
44 rv = NaClDescRngSubclassCtor(self);
46 (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
51 static void NaClDescRngDtor(struct NaClRefCount *vself) {
52 struct NaClDescRng *self = (struct NaClDescRng *) vself;
54 (*NACL_VTBL(NaClSecureRngIf, &self->rng)->Dtor)(
55 (struct NaClSecureRngIf *) &self->rng);
56 NACL_VTBL(NaClDesc, self) = &kNaClDescVtbl;
57 (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
60 static ssize_t NaClDescRngRead(struct NaClDesc *vself,
63 struct NaClDescRng *self = (struct NaClDescRng *) vself;
65 (*NACL_VTBL(NaClSecureRngIf, &self->rng)->GenBytes)(
66 (struct NaClSecureRngIf *) &self->rng, buf, len);
70 static ssize_t NaClDescRngWrite(struct NaClDesc *vself,
73 UNREFERENCED_PARAMETER(vself);
74 UNREFERENCED_PARAMETER(buf);
77 * Eventually we may want to have secure pseudorandom number
78 * generators that permit mixing user-supplied data -- presumably
79 * low entropy, from timing of events or something like that -- into
80 * the generator state. This must be done carefully, of course,
81 * since we would not want the user-supplied data to destroy the
82 * internal generator's entropy.
87 static int NaClDescRngFstat(struct NaClDesc *vself,
88 struct nacl_abi_stat *statbuf) {
89 UNREFERENCED_PARAMETER(vself);
91 memset(statbuf, 0, sizeof *statbuf);
92 statbuf->nacl_abi_st_dev = 0;
93 #if defined(NACL_MASK_INODES)
94 statbuf->nacl_abi_st_ino = NACL_FAKE_INODE_NUM;
96 statbuf->nacl_abi_st_ino = 0;
98 statbuf->nacl_abi_st_mode = NACL_ABI_S_IRUSR | NACL_ABI_S_IFCHR;
99 statbuf->nacl_abi_st_nlink = 1;
100 statbuf->nacl_abi_st_uid = -1;
101 statbuf->nacl_abi_st_gid = -1;
102 statbuf->nacl_abi_st_rdev = 0;
103 statbuf->nacl_abi_st_size = 0;
104 statbuf->nacl_abi_st_blksize = 0;
105 statbuf->nacl_abi_st_blocks = 0;
106 statbuf->nacl_abi_st_atime = 0;
107 statbuf->nacl_abi_st_atimensec = 0;
108 statbuf->nacl_abi_st_mtime = 0;
109 statbuf->nacl_abi_st_mtimensec = 0;
110 statbuf->nacl_abi_st_ctime = 0;
111 statbuf->nacl_abi_st_ctimensec = 0;
117 * We allow descriptor "transfer", where in reality we create a
118 * separate rng locally at the recipient end. This is arguably
119 * semantically different since there is no shared access to the same
120 * generator; on the other hand, it should be polynomial-time
121 * indistinguishable since the output is supposed to be
122 * cryptographically secure.
124 static int NaClDescRngExternalizeSize(struct NaClDesc *vself,
127 return NaClDescExternalizeSize(vself, nbytes, nhandles);
130 static int NaClDescRngExternalize(struct NaClDesc *vself,
131 struct NaClDescXferState *xfer) {
132 return NaClDescExternalize(vself, xfer);
135 static struct NaClDescVtbl const kNaClDescRngVtbl = {
139 NaClDescMapNotImplemented,
140 NACL_DESC_UNMAP_NOT_IMPLEMENTED
143 NaClDescSeekNotImplemented,
144 NaClDescPReadNotImplemented,
145 NaClDescPWriteNotImplemented,
147 NaClDescGetdentsNotImplemented,
148 NaClDescRngExternalizeSize,
149 NaClDescRngExternalize,
150 NaClDescLockNotImplemented,
151 NaClDescTryLockNotImplemented,
152 NaClDescUnlockNotImplemented,
153 NaClDescWaitNotImplemented,
154 NaClDescTimedWaitAbsNotImplemented,
155 NaClDescSignalNotImplemented,
156 NaClDescBroadcastNotImplemented,
157 NaClDescSendMsgNotImplemented,
158 NaClDescRecvMsgNotImplemented,
159 NaClDescLowLevelSendMsgNotImplemented,
160 NaClDescLowLevelRecvMsgNotImplemented,
161 NaClDescConnectAddrNotImplemented,
162 NaClDescAcceptConnNotImplemented,
163 NaClDescPostNotImplemented,
164 NaClDescSemWaitNotImplemented,
165 NaClDescGetValueNotImplemented,
170 NaClDescIsattyNotImplemented,
171 NACL_DESC_DEVICE_RNG,
174 int NaClDescRngInternalize(struct NaClDesc **out_desc,
175 struct NaClDescXferState *xfer,
176 struct NaClDescQuotaInterface *quota_interface) {
178 struct NaClDescRng *rng = malloc(sizeof *rng);
180 UNREFERENCED_PARAMETER(xfer);
181 UNREFERENCED_PARAMETER(quota_interface);
183 rv = -NACL_ABI_ENOMEM;
186 if (!NaClDescInternalizeCtor((struct NaClDesc *) rng, xfer)) {
189 rv = -NACL_ABI_ENOMEM;
192 if (!NaClDescRngSubclassCtor(rng)) {
196 *out_desc = (struct NaClDesc *) rng;
200 NaClDescSafeUnref((struct NaClDesc *) rng);