Skip to content

Commit c23c4c3

Browse files
committed
disco: allow asynchronous signing requests
1 parent 536fcc9 commit c23c4c3

File tree

10 files changed

+116
-64
lines changed

10 files changed

+116
-64
lines changed

src/disco/bundle/fd_bundle_tile.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,8 @@ unprivileged_init( fd_topo_t * topo,
523523
sign_out->mcache,
524524
sign_out->dcache,
525525
sign_in->mcache,
526-
sign_in->dcache
526+
sign_in->dcache,
527+
sign_out->mtu
527528
) ) ) ) {
528529
FD_LOG_ERR(( "fd_keyguard_client_join failed" )); /* unreachable */
529530
}

src/disco/keyguard/fd_keyguard_client.c

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,33 @@
11
#include "fd_keyguard_client.h"
22

3+
#include "../../tango/mcache/fd_mcache.h"
4+
#include "../../tango/dcache/fd_dcache.h"
5+
36
void *
4-
fd_keyguard_client_new( void * shmem,
7+
fd_keyguard_client_new( void * shmem,
58
fd_frag_meta_t * request_mcache,
6-
uchar * request_data,
9+
uchar * request_dcache,
710
fd_frag_meta_t * response_mcache,
8-
uchar * response_data ) {
11+
uchar * response_dcache,
12+
ulong request_mtu ) {
913
fd_keyguard_client_t * client = (fd_keyguard_client_t*)shmem;
10-
client->request = request_mcache;
11-
client->request_depth = fd_mcache_depth( request_mcache );
12-
client->request_seq = 0UL;
13-
client->request_data = request_data;
14-
15-
client->response = response_mcache;
16-
client->response_depth = fd_mcache_depth( response_mcache );
17-
client->response_seq = 0UL;
18-
client->response_data = response_data;
14+
15+
client->request = request_mcache;
16+
client->request_depth = fd_mcache_depth( request_mcache );
17+
client->request_seq = 0UL;
18+
client->request_mem = fd_wksp_containing( request_dcache );
19+
client->request_chunk0 = fd_dcache_compact_chunk0( client->request_mem, request_dcache );
20+
client->request_wmark = fd_dcache_compact_wmark( client->request_mem, request_dcache, request_mtu );
21+
client->request_chunk = client->request_chunk0;
22+
client->request_mtu = request_mtu;
23+
24+
client->response = response_mcache;
25+
client->response_depth = fd_mcache_depth( response_mcache );
26+
client->response_seq = 0UL;
27+
client->response_mem = fd_wksp_containing( response_dcache );
28+
client->response_chunk0 = fd_dcache_compact_chunk0( client->response_mem, response_dcache );
29+
client->response_wmark = fd_dcache_compact_wmark( client->response_mem, response_dcache, 64UL );
30+
1931
return shmem;
2032
}
2133

@@ -25,12 +37,15 @@ fd_keyguard_client_sign( fd_keyguard_client_t * client,
2537
uchar const * sign_data,
2638
ulong sign_data_len,
2739
int sign_type ) {
40+
FD_TEST( sign_data_len<=client->request_mtu );
2841

29-
fd_memcpy( client->request_data, sign_data, sign_data_len );
42+
uchar * dst = fd_chunk_to_laddr( client->request_mem, client->request_chunk );
43+
fd_memcpy( dst, sign_data, sign_data_len );
3044

3145
ulong sig = (ulong)(uint)sign_type;
32-
fd_mcache_publish( client->request, client->request_depth, client->request_seq, sig, 0UL, sign_data_len, 0UL, 0UL, 0UL );
33-
client->request_seq = fd_seq_inc( client->request_seq, 1UL );
46+
fd_mcache_publish( client->request, client->request_depth, client->request_seq, sig, client->request_chunk, sign_data_len, 0UL, 0UL, 0UL );
47+
client->request_seq = fd_seq_inc( client->request_seq, 1UL );
48+
client->request_chunk = fd_dcache_compact_next( client->request_chunk, sign_data_len, client->request_chunk0, client->request_wmark );
3449

3550
fd_frag_meta_t meta;
3651
fd_frag_meta_t const * mline;
@@ -41,7 +56,13 @@ fd_keyguard_client_sign( fd_keyguard_client_t * client,
4156
if( FD_UNLIKELY( !poll_max ) ) FD_LOG_ERR(( "sign request timed out while polling" ));
4257
if( FD_UNLIKELY( seq_diff ) ) FD_LOG_ERR(( "sign request was overrun while polling" ));
4358

44-
fd_memcpy( signature, client->response_data, 64UL );
59+
/* Chunk is in shared memory and might be be written to by an
60+
attacking tile after we validate it, so load once. */
61+
ulong chunk = FD_VOLATILE_CONST( mline->chunk );
62+
FD_TEST( chunk>=client->response_chunk0 && chunk<=client->response_wmark );
63+
64+
uchar * src = fd_chunk_to_laddr( client->response_mem, chunk );
65+
fd_memcpy( signature, src, 64UL );
4566

4667
seq_found = fd_frag_meta_seq_query( mline );
4768
if( FD_UNLIKELY( fd_seq_ne( seq_found, client->response_seq ) ) ) FD_LOG_ERR(( "sign request was overrun while reading" ));

src/disco/keyguard/fd_keyguard_client.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
keyguard tile verifies that all incoming requests are
2525
specifically formatted for that role. */
2626

27-
#include "fd_keyguard.h"
27+
#include "../../tango/fd_tango_base.h"
2828

2929
#define FD_KEYGUARD_CLIENT_ALIGN (128UL)
3030
#define FD_KEYGUARD_CLIENT_FOOTPRINT (128UL)
@@ -33,12 +33,18 @@ struct __attribute__((aligned(FD_KEYGUARD_CLIENT_ALIGN))) fd_keyguard_client {
3333
fd_frag_meta_t * request;
3434
ulong request_seq;
3535
ulong request_depth;
36-
uchar * request_data;
36+
fd_wksp_t * request_mem;
37+
ulong request_chunk;
38+
ulong request_chunk0;
39+
ulong request_wmark;
40+
ulong request_mtu;
3741

3842
fd_frag_meta_t * response;
3943
ulong response_seq;
4044
ulong response_depth;
41-
uchar * response_data;
45+
fd_wksp_t * response_mem;
46+
ulong response_chunk0;
47+
ulong response_wmark;
4248
};
4349
typedef struct fd_keyguard_client fd_keyguard_client_t;
4450

@@ -47,9 +53,10 @@ FD_PROTOTYPES_BEGIN
4753
void *
4854
fd_keyguard_client_new( void * shmem,
4955
fd_frag_meta_t * request_mcache,
50-
uchar * request_data,
56+
uchar * request_dcache,
5157
fd_frag_meta_t * response_mcache,
52-
uchar * response_data );
58+
uchar * response_dcache,
59+
ulong request_mtu );
5360

5461
static inline fd_keyguard_client_t *
5562
fd_keyguard_client_join( void * shclient ) { return (fd_keyguard_client_t*)shclient; }

src/disco/pack/fd_pack_tile.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1182,7 +1182,8 @@ unprivileged_init( fd_topo_t * topo,
11821182
sign_out->mcache,
11831183
sign_out->dcache,
11841184
sign_in->mcache,
1185-
sign_in->dcache ) ) ) ) {
1185+
sign_in->dcache,
1186+
sign_out->mtu ) ) ) ) {
11861187
FD_LOG_ERR(( "failed to construct keyguard" ));
11871188
}
11881189
/* Initialize enough of the prev config that it produces a

src/disco/shred/fd_shred_tile.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1176,7 +1176,8 @@ unprivileged_init( fd_topo_t * topo,
11761176
sign_out->mcache,
11771177
sign_out->dcache,
11781178
sign_in->mcache,
1179-
sign_in->dcache ) ) );
1179+
sign_in->dcache,
1180+
sign_out->mtu ) ) );
11801181

11811182
ulong shred_limit = fd_ulong_if( tile->shred.larger_shred_limits_per_block, 32UL*32UL*1024UL, 32UL*1024UL );
11821183
fd_fec_set_t * resolver_sets = fec_sets + (shred_store_mcache_depth+1UL)/2UL + 1UL;

src/disco/shred/fd_shredder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "../../ballet/reedsol/fd_reedsol.h"
1111
#include "../../ballet/bmtree/fd_bmtree.h"
1212
#include "../../ballet/shred/fd_fec_set.h"
13+
#include "../../ballet/shred/fd_shred.h"
1314

1415
#define FD_SHREDDER_MAX_STAKE_WEIGHTS (1UL<<20)
1516

src/disco/sign/fd_sign_tile.c

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,22 @@
1616
/* fd_sign_in_ctx_t is a context object for each in (producer) mcache
1717
connected to the sign tile. */
1818

19-
typedef struct {
20-
ulong seq;
21-
fd_frag_meta_t * mcache;
22-
uchar * data;
23-
} fd_sign_out_ctx_t;
19+
struct fd_sign_out_ctx {
20+
fd_wksp_t * out_mem;
21+
ulong out_chunk0;
22+
ulong out_wmark;
23+
ulong out_chunk;
24+
};
25+
typedef struct fd_sign_out_ctx fd_sign_out_ctx_t;
26+
27+
struct fd_sign_in_ctx {
28+
int role;
29+
fd_wksp_t * mem;
30+
ulong chunk0;
31+
ulong wmark;
32+
ulong mtu;
33+
};
34+
typedef struct fd_sign_in_ctx fd_sign_in_ctx_t;
2435

2536
typedef struct {
2637
uchar _data[ FD_KEYGUARD_SIGN_REQ_MTU ];
@@ -31,10 +42,7 @@ typedef struct {
3142

3243
uchar event_concat[ 18UL+32UL ];
3344

34-
int in_role[ MAX_IN ];
35-
uchar * in_data[ MAX_IN ];
36-
ushort in_mtu [ MAX_IN ];
37-
45+
fd_sign_in_ctx_t in[ MAX_IN ];
3846
fd_sign_out_ctx_t out[ MAX_IN ];
3947

4048
fd_sha512_t sha512 [ 1 ];
@@ -103,18 +111,19 @@ during_frag_sensitive( void * _ctx,
103111
ulong sz ) {
104112
(void)seq;
105113
(void)sig;
106-
(void)chunk;
107114

108115
fd_sign_ctx_t * ctx = (fd_sign_ctx_t *)_ctx;
109116
FD_TEST( in_idx<MAX_IN );
110117

111-
int role = ctx->in_role[ in_idx ];
112-
uint mtu = ctx->in_mtu [ in_idx ];
118+
int role = ctx->in[ in_idx ].role;
119+
ulong mtu = ctx->in[ in_idx ].mtu;
113120

114-
if( sz>mtu ) {
115-
FD_LOG_EMERG(( "oversz signing request (role=%d sz=%lu mtu=%u)", role, sz, mtu ));
121+
if( chunk<ctx->in[ in_idx ].chunk0 || chunk>ctx->in[ in_idx ].wmark || sz>mtu ) {
122+
FD_LOG_EMERG(( "oversz or out of bounds signing request (role=%d chunk=%lu sz=%lu mtu=%lu, chunk0=%lu, wmark=%lu)", role, chunk, sz, mtu, ctx->in[ in_idx ].chunk0, ctx->in[ in_idx ].wmark ));
116123
}
117-
fd_memcpy( ctx->_data, ctx->in_data[ in_idx ], sz );
124+
125+
void * src = fd_chunk_to_laddr( ctx->in[ in_idx ].mem, chunk );
126+
fd_memcpy( ctx->_data, src, sz );
118127
}
119128

120129

@@ -139,17 +148,15 @@ after_frag_sensitive( void * _ctx,
139148
ulong tspub,
140149
fd_stem_context_t * stem ) {
141150
(void)seq;
142-
(void)tsorig;
143151
(void)tspub;
144-
(void)stem;
145152

146153
fd_sign_ctx_t * ctx = (fd_sign_ctx_t *)_ctx;
147154

148155
int sign_type = (int)(uint)sig;
149156

150157
FD_TEST( in_idx<MAX_IN );
151158

152-
int role = ctx->in_role[ in_idx ];
159+
int role = ctx->in[ in_idx ].role;
153160

154161
fd_keyguard_authority_t authority = {0};
155162
memcpy( authority.identity_pubkey, ctx->public_key, 32 );
@@ -158,33 +165,40 @@ after_frag_sensitive( void * _ctx,
158165
FD_LOG_EMERG(( "fd_keyguard_payload_authorize failed (role=%d sign_type=%d)", role, sign_type ));
159166
}
160167

168+
long sign_duration = -fd_tickcount();
169+
170+
uchar * dst = fd_chunk_to_laddr( ctx->out[ in_idx ].out_mem, ctx->out[ in_idx ].out_chunk );
171+
161172
switch( sign_type ) {
162173
case FD_KEYGUARD_SIGN_TYPE_ED25519: {
163-
fd_ed25519_sign( ctx->out[ in_idx ].data, ctx->_data, sz, ctx->public_key, ctx->private_key, ctx->sha512 );
174+
fd_ed25519_sign( dst, ctx->_data, sz, ctx->public_key, ctx->private_key, ctx->sha512 );
164175
break;
165176
}
166177
case FD_KEYGUARD_SIGN_TYPE_SHA256_ED25519: {
167178
uchar hash[ 32 ];
168179
fd_sha256_hash( ctx->_data, sz, hash );
169-
fd_ed25519_sign( ctx->out[ in_idx ].data, hash, 32UL, ctx->public_key, ctx->private_key, ctx->sha512 );
180+
fd_ed25519_sign( dst, hash, 32UL, ctx->public_key, ctx->private_key, ctx->sha512 );
170181
break;
171182
}
172183
case FD_KEYGUARD_SIGN_TYPE_PUBKEY_CONCAT_ED25519: {
173184
memcpy( ctx->concat+ctx->public_key_base58_sz+1UL, ctx->_data, 9UL );
174-
fd_ed25519_sign( ctx->out[ in_idx ].data, ctx->concat, ctx->public_key_base58_sz+1UL+9UL, ctx->public_key, ctx->private_key, ctx->sha512 );
185+
fd_ed25519_sign( dst, ctx->concat, ctx->public_key_base58_sz+1UL+9UL, ctx->public_key, ctx->private_key, ctx->sha512 );
175186
break;
176187
}
177188
case FD_KEYGUARD_SIGN_TYPE_FD_METRICS_REPORT_CONCAT_ED25519: {
178189
memcpy( ctx->event_concat+18UL, ctx->_data, 32UL );
179-
fd_ed25519_sign( ctx->out[ in_idx ].data, ctx->event_concat, 18UL+32UL, ctx->public_key, ctx->private_key, ctx->sha512 );
190+
fd_ed25519_sign( dst, ctx->event_concat, 18UL+32UL, ctx->public_key, ctx->private_key, ctx->sha512 );
180191
break;
181192
}
182193
default:
183194
FD_LOG_EMERG(( "invalid sign type: %d", sign_type ));
184195
}
185196

186-
fd_mcache_publish( ctx->out[ in_idx ].mcache, 128UL, ctx->out[ in_idx ].seq, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL );
187-
ctx->out[ in_idx ].seq = fd_seq_inc( ctx->out[ in_idx ].seq, 1UL );
197+
sign_duration += fd_tickcount();
198+
fd_histf_sample( ctx->sign_duration, (ulong)sign_duration );
199+
200+
fd_stem_publish( stem, in_idx, 0UL, ctx->out[ in_idx ].out_chunk, 64UL, 0UL, tsorig, 0UL );
201+
ctx->out[ in_idx ].out_chunk = fd_dcache_compact_next( ctx->out[ in_idx ].out_chunk, 64UL, ctx->out[ in_idx ].out_chunk0, ctx->out[ in_idx ].out_wmark );
188202
}
189203

190204
static void
@@ -250,52 +264,55 @@ unprivileged_init_sensitive( fd_topo_t * topo,
250264
ctx->keyswitch = fd_keyswitch_join( fd_topo_obj_laddr( topo, tile->keyswitch_obj_id ) );
251265
derive_fields( ctx );
252266

253-
for( ulong i=0UL; i<MAX_IN; i++ ) ctx->in_role[ i ] = -1;
267+
for( ulong i=0UL; i<MAX_IN; i++ ) ctx->in[ i ].role = -1;
254268

255269
for( ulong i=0UL; i<tile->in_cnt; i++ ) {
256270
fd_topo_link_t * in_link = &topo->links[ tile->in_link_id[ i ] ];
257271
fd_topo_link_t * out_link = &topo->links[ tile->out_link_id[ i ] ];
258272

259273
if( in_link->mtu > FD_KEYGUARD_SIGN_REQ_MTU ) FD_LOG_CRIT(( "oversz link[%lu].mtu=%lu", i, in_link->mtu ));
260-
ctx->in_data[ i ] = in_link->dcache;
261-
ctx->in_mtu [ i ] = (ushort)in_link->mtu;
274+
ctx->in[ i ].mem = fd_wksp_containing( in_link->dcache );
275+
ctx->in[ i ].mtu = in_link->mtu;
276+
ctx->in[ i ].chunk0 = fd_dcache_compact_chunk0( ctx->in[ i ].mem, in_link->dcache );
277+
ctx->in[ i ].wmark = fd_dcache_compact_wmark( ctx->in[ i ].mem, in_link->dcache, in_link->mtu );
262278

263-
ctx->out[ i ].mcache = out_link->mcache;
264-
ctx->out[ i ].data = out_link->dcache;
265-
ctx->out[ i ].seq = 0UL;
279+
ctx->out[ i ].out_mem = fd_wksp_containing( out_link->dcache );
280+
ctx->out[ i ].out_chunk0 = fd_dcache_compact_chunk0( ctx->out[ i ].out_mem, out_link->dcache );
281+
ctx->out[ i ].out_wmark = fd_dcache_compact_wmark( ctx->out[ i ].out_mem, out_link->dcache, 64UL );
282+
ctx->out[ i ].out_chunk = ctx->out[ i ].out_chunk0;
266283

267284
if( !strcmp( in_link->name, "shred_sign" ) ) {
268-
ctx->in_role[ i ] = FD_KEYGUARD_ROLE_LEADER;
285+
ctx->in[ i ].role = FD_KEYGUARD_ROLE_LEADER;
269286
FD_TEST( !strcmp( out_link->name, "sign_shred" ) );
270287
FD_TEST( in_link->mtu==32UL );
271288
FD_TEST( out_link->mtu==64UL );
272289
} else if ( !strcmp( in_link->name, "gossip_sign" ) ) {
273-
ctx->in_role[ i ] = FD_KEYGUARD_ROLE_GOSSIP;
290+
ctx->in[ i ].role = FD_KEYGUARD_ROLE_GOSSIP;
274291
FD_TEST( !strcmp( out_link->name, "sign_gossip" ) );
275292
FD_TEST( in_link->mtu==2048UL );
276293
FD_TEST( out_link->mtu==64UL );
277294
} else if ( !strcmp( in_link->name, "repair_sign")) {
278-
ctx->in_role[ i ] = FD_KEYGUARD_ROLE_REPAIR;
295+
ctx->in[ i ].role = FD_KEYGUARD_ROLE_REPAIR;
279296
FD_TEST( !strcmp( out_link->name, "sign_repair" ) );
280297
FD_TEST( in_link->mtu==2048UL );
281298
FD_TEST( out_link->mtu==64UL );
282299
} else if ( !strcmp(in_link->name, "send_sign" ) ) {
283-
ctx->in_role[ i ] = FD_KEYGUARD_ROLE_SEND;
300+
ctx->in[ i ].role = FD_KEYGUARD_ROLE_SEND;
284301
FD_TEST( !strcmp( out_link->name, "sign_send" ) );
285302
FD_TEST( in_link->mtu==FD_TXN_MTU );
286303
FD_TEST( out_link->mtu==64UL );
287304
} else if( !strcmp(in_link->name, "bundle_sign" ) ) {
288-
ctx->in_role[ i ] = FD_KEYGUARD_ROLE_BUNDLE;
305+
ctx->in[ i ].role = FD_KEYGUARD_ROLE_BUNDLE;
289306
FD_TEST( !strcmp( out_link->name, "sign_bundle" ) );
290307
FD_TEST( in_link->mtu==9UL );
291308
FD_TEST( out_link->mtu==64UL );
292309
} else if( !strcmp(in_link->name, "event_sign" ) ) {
293-
ctx->in_role[ i ] = FD_KEYGUARD_ROLE_EVENT;
310+
ctx->in[ i ].role = FD_KEYGUARD_ROLE_EVENT;
294311
FD_TEST( !strcmp( out_link->name, "sign_event" ) );
295312
FD_TEST( in_link->mtu==32UL );
296313
FD_TEST( out_link->mtu==64UL );
297314
} else if( !strcmp(in_link->name, "pack_sign" ) ) {
298-
ctx->in_role[ i ] = FD_KEYGUARD_ROLE_BUNDLE_CRANK;
315+
ctx->in[ i ].role = FD_KEYGUARD_ROLE_BUNDLE_CRANK;
299316
FD_TEST( !strcmp( out_link->name, "sign_pack" ) );
300317
FD_TEST( in_link->mtu==1232UL );
301318
FD_TEST( out_link->mtu==64UL );

src/discof/gossip/fd_gossip_tile.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,8 @@ unprivileged_init( fd_topo_t * topo,
742742
sign_out->mcache,
743743
sign_out->dcache,
744744
sign_in->mcache,
745-
sign_in->dcache ) )==NULL ) {
745+
sign_in->dcache,
746+
sign_out->mtu ) )==NULL ) {
746747
FD_LOG_ERR(( "Keyguard join failed" ));
747748
}
748749

src/discof/repair/fd_repair_tile.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,8 @@ unprivileged_init( fd_topo_t * topo,
968968
sign_out->mcache,
969969
sign_out->dcache,
970970
sign_in->mcache,
971-
sign_in->dcache ) ) == NULL ) {
971+
sign_in->dcache,
972+
sign_out->mtu ) ) == NULL ) {
972973
FD_LOG_ERR(( "Keyguard join failed" ));
973974
}
974975

src/discof/send/fd_send_tile.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,8 @@ unprivileged_init( fd_topo_t * topo,
551551
sign_out->mcache,
552552
sign_out->dcache,
553553
sign_in->mcache,
554-
sign_in->dcache ) )==NULL ) {
554+
sign_in->dcache,
555+
sign_out->mtu ) )==NULL ) {
555556
FD_LOG_ERR(( "Keyguard join failed" ));
556557
}
557558

0 commit comments

Comments
 (0)