Subversion Repositories planix.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 *  devtls - record layer for transport layer security 1.0 and secure sockets layer 3.0
3
 */
4
#include	"u.h"
5
#include	"../port/lib.h"
6
#include	"mem.h"
7
#include	"dat.h"
8
#include	"fns.h"
9
#include	"../port/error.h"
10
 
11
#include	<libsec.h>
12
 
13
typedef struct OneWay	OneWay;
14
typedef struct Secret		Secret;
15
typedef struct TlsRec	TlsRec;
16
typedef struct TlsErrs	TlsErrs;
17
 
18
enum {
19
	Statlen=	1024,		/* max. length of status or stats message */
20
	/* buffer limits */
21
	MaxRecLen		= 1<<14,	/* max payload length of a record layer message */
22
	MaxCipherRecLen	= MaxRecLen + 2048,
23
	RecHdrLen		= 5,
24
	MaxMacLen		= SHA1dlen,
25
 
26
	/* protocol versions we can accept */
27
	TLSVersion		= 0x0301,
28
	SSL3Version		= 0x0300,
29
	ProtocolVersion	= 0x0301,	/* maximum version we speak */
30
	MinProtoVersion	= 0x0300,	/* limits on version we accept */
31
	MaxProtoVersion	= 0x03ff,
32
 
33
	/* connection states */
34
	SHandshake	= 1 << 0,	/* doing handshake */
35
	SOpen		= 1 << 1,	/* application data can be sent */
36
	SRClose		= 1 << 2,	/* remote side has closed down */
37
	SLClose		= 1 << 3,	/* sent a close notify alert */
38
	SAlert		= 1 << 5,	/* sending or sent a fatal alert */
39
	SError		= 1 << 6,	/* some sort of error has occured */
40
	SClosed		= 1 << 7,	/* it is all over */
41
 
42
	/* record types */
43
	RChangeCipherSpec = 20,
44
	RAlert,
45
	RHandshake,
46
	RApplication,
47
 
48
	SSL2ClientHello = 1,
49
	HSSL2ClientHello = 9,  /* local convention;  see tlshand.c */
50
 
51
	/* alerts */
52
	ECloseNotify 			= 0,
53
	EUnexpectedMessage 	= 10,
54
	EBadRecordMac 		= 20,
55
	EDecryptionFailed 		= 21,
56
	ERecordOverflow 		= 22,
57
	EDecompressionFailure 	= 30,
58
	EHandshakeFailure 		= 40,
59
	ENoCertificate 			= 41,
60
	EBadCertificate 		= 42,
61
	EUnsupportedCertificate 	= 43,
62
	ECertificateRevoked 		= 44,
63
	ECertificateExpired 		= 45,
64
	ECertificateUnknown 	= 46,
65
	EIllegalParameter 		= 47,
66
	EUnknownCa 			= 48,
67
	EAccessDenied 		= 49,
68
	EDecodeError 			= 50,
69
	EDecryptError 			= 51,
70
	EExportRestriction 		= 60,
71
	EProtocolVersion 		= 70,
72
	EInsufficientSecurity 	= 71,
73
	EInternalError 			= 80,
74
	EUserCanceled 			= 90,
75
	ENoRenegotiation 		= 100,
76
 
77
	EMAX = 256
78
};
79
 
80
struct Secret
81
{
82
	char		*encalg;	/* name of encryption alg */
83
	char		*hashalg;	/* name of hash alg */
84
	int		(*enc)(Secret*, uchar*, int);
85
	int		(*dec)(Secret*, uchar*, int);
86
	int		(*unpad)(uchar*, int, int);
87
	DigestState	*(*mac)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
88
	int		block;		/* encryption block len, 0 if none */
89
	int		maclen;
90
	void		*enckey;
91
	uchar	mackey[MaxMacLen];
92
};
93
 
94
struct OneWay
95
{
96
	QLock		io;		/* locks io access */
97
	QLock		seclock;	/* locks secret paramaters */
98
	ulong		seq;
99
	Secret		*sec;		/* cipher in use */
100
	Secret		*new;		/* cipher waiting for enable */
101
};
102
 
103
struct TlsRec
104
{
105
	Chan	*c;				/* io channel */
106
	int		ref;				/* serialized by tdlock for atomic destroy */
107
	int		version;			/* version of the protocol we are speaking */
108
	char		verset;			/* version has been set */
109
	char		opened;			/* opened command every issued? */
110
	char		err[ERRMAX];		/* error message to return to handshake requests */
111
	vlong	handin;			/* bytes communicated by the record layer */
112
	vlong	handout;
113
	vlong	datain;
114
	vlong	dataout;
115
 
116
	Lock		statelk;
117
	int		state;
118
	int		debug;
119
 
120
	/* record layer mac functions for different protocol versions */
121
	void		(*packMac)(Secret*, uchar*, uchar*, uchar*, uchar*, int, uchar*);
122
 
123
	/* input side -- protected by in.io */
124
	OneWay		in;
125
	Block		*processed;	/* next bunch of application data */
126
	Block		*unprocessed;	/* data read from c but not parsed into records */
127
 
128
	/* handshake queue */
129
	Lock		hqlock;			/* protects hqref, alloc & free of handq, hprocessed */
130
	int		hqref;
131
	Queue		*handq;		/* queue of handshake messages */
132
	Block		*hprocessed;	/* remainder of last block read from handq */
133
	QLock		hqread;		/* protects reads for hprocessed, handq */
134
 
135
	/* output side */
136
	OneWay		out;
137
 
138
	/* protections */
139
	char		*user;
140
	int		perm;
141
};
142
 
143
struct TlsErrs{
144
	int	err;
145
	int	sslerr;
146
	int	tlserr;
147
	int	fatal;
148
	char	*msg;
149
};
150
 
151
static TlsErrs tlserrs[] = {
152
	{ECloseNotify,			ECloseNotify,			ECloseNotify,			0, 	"close notify"},
153
	{EUnexpectedMessage,	EUnexpectedMessage,	EUnexpectedMessage, 	1, "unexpected message"},
154
	{EBadRecordMac,		EBadRecordMac,		EBadRecordMac, 		1, "bad record mac"},
155
	{EDecryptionFailed,		EIllegalParameter,		EDecryptionFailed,		1, "decryption failed"},
156
	{ERecordOverflow,		EIllegalParameter,		ERecordOverflow,		1, "record too long"},
157
	{EDecompressionFailure,	EDecompressionFailure,	EDecompressionFailure,	1, "decompression failed"},
158
	{EHandshakeFailure,		EHandshakeFailure,		EHandshakeFailure,		1, "could not negotiate acceptable security parameters"},
159
	{ENoCertificate,		ENoCertificate,			ECertificateUnknown,	1, "no appropriate certificate available"},
160
	{EBadCertificate,		EBadCertificate,		EBadCertificate,		1, "corrupted or invalid certificate"},
161
	{EUnsupportedCertificate,	EUnsupportedCertificate,	EUnsupportedCertificate,	1, "unsupported certificate type"},
162
	{ECertificateRevoked,	ECertificateRevoked,		ECertificateRevoked,		1, "revoked certificate"},
163
	{ECertificateExpired,		ECertificateExpired,		ECertificateExpired,		1, "expired certificate"},
164
	{ECertificateUnknown,	ECertificateUnknown,	ECertificateUnknown,	1, "unacceptable certificate"},
165
	{EIllegalParameter,		EIllegalParameter,		EIllegalParameter,		1, "illegal parameter"},
166
	{EUnknownCa,			EHandshakeFailure,		EUnknownCa,			1, "unknown certificate authority"},
167
	{EAccessDenied,		EHandshakeFailure,		EAccessDenied,		1, "access denied"},
168
	{EDecodeError,			EIllegalParameter,		EDecodeError,			1, "error decoding message"},
169
	{EDecryptError,			EIllegalParameter,		EDecryptError,			1, "error decrypting message"},
170
	{EExportRestriction,		EHandshakeFailure,		EExportRestriction,		1, "export restriction violated"},
171
	{EProtocolVersion,		EIllegalParameter,		EProtocolVersion,		1, "protocol version not supported"},
172
	{EInsufficientSecurity,	EHandshakeFailure,		EInsufficientSecurity,	1, "stronger security routines required"},
173
	{EInternalError,			EHandshakeFailure,		EInternalError,			1, "internal error"},
174
	{EUserCanceled,		ECloseNotify,			EUserCanceled,			0, "handshake canceled by user"},
175
	{ENoRenegotiation,		EUnexpectedMessage,	ENoRenegotiation,		0, "no renegotiation"},
176
};
177
 
178
enum
179
{
180
	/* max. open tls connections */
181
	MaxTlsDevs	= 1024
182
};
183
 
184
static	Lock	tdlock;
185
static	int	tdhiwat;
186
static	int	maxtlsdevs = 128;
187
static	TlsRec	**tlsdevs;
188
static	char	**trnames;
189
static	char	*encalgs;
190
static	char	*hashalgs;
191
 
192
enum{
193
	Qtopdir		= 1,	/* top level directory */
194
	Qprotodir,
195
	Qclonus,
196
	Qencalgs,
197
	Qhashalgs,
198
	Qconvdir,		/* directory for a conversation */
199
	Qdata,
200
	Qctl,
201
	Qhand,
202
	Qstatus,
203
	Qstats,
204
};
205
 
206
#define TYPE(x) 	((x).path & 0xf)
207
#define CONV(x) 	(((x).path >> 5)&(MaxTlsDevs-1))
208
#define QID(c, y) 	(((c)<<5) | (y))
209
 
210
static void	checkstate(TlsRec *, int, int);
211
static void	ensure(TlsRec*, Block**, int);
212
static void	consume(Block**, uchar*, int);
213
static Chan*	buftochan(char*);
214
static void	tlshangup(TlsRec*);
215
static void	tlsError(TlsRec*, char *);
216
static void	alertHand(TlsRec*, char *);
217
static TlsRec	*newtls(Chan *c);
218
static TlsRec	*mktlsrec(void);
219
static DigestState*sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
220
static DigestState*sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
221
static DigestState*nomac(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
222
static void	sslPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac);
223
static void	tlsPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac);
224
static void	put64(uchar *p, vlong x);
225
static void	put32(uchar *p, u32int);
226
static void	put24(uchar *p, int);
227
static void	put16(uchar *p, int);
228
static u32int	get32(uchar *p);
229
static int	get16(uchar *p);
230
static void	tlsSetState(TlsRec *tr, int new, int old);
231
static void	rcvAlert(TlsRec *tr, int err);
232
static void	sendAlert(TlsRec *tr, int err);
233
static void	rcvError(TlsRec *tr, int err, char *msg, ...);
234
static int	rc4enc(Secret *sec, uchar *buf, int n);
235
static int	des3enc(Secret *sec, uchar *buf, int n);
236
static int	des3dec(Secret *sec, uchar *buf, int n);
237
static int	aesenc(Secret *sec, uchar *buf, int n);
238
static int	aesdec(Secret *sec, uchar *buf, int n);
239
static int	noenc(Secret *sec, uchar *buf, int n);
240
static int	sslunpad(uchar *buf, int n, int block);
241
static int	tlsunpad(uchar *buf, int n, int block);
242
static void	freeSec(Secret *sec);
243
static char	*tlsstate(int s);
244
static void	pdump(int, void*, char*);
245
 
246
#pragma	varargck	argpos	rcvError	3
247
 
248
static char *tlsnames[] = {
249
[Qclonus]		"clone",
250
[Qencalgs]	"encalgs",
251
[Qhashalgs]	"hashalgs",
252
[Qdata]		"data",
253
[Qctl]		"ctl",
254
[Qhand]		"hand",
255
[Qstatus]		"status",
256
[Qstats]		"stats",
257
};
258
 
259
static int convdir[] = { Qctl, Qdata, Qhand, Qstatus, Qstats };
260
 
261
static int
262
tlsgen(Chan *c, char*, Dirtab *, int, int s, Dir *dp)
263
{
264
	Qid q;
265
	TlsRec *tr;
266
	char *name, *nm;
267
	int perm, t;
268
 
269
	q.vers = 0;
270
	q.type = QTFILE;
271
 
272
	t = TYPE(c->qid);
273
	switch(t) {
274
	case Qtopdir:
275
		if(s == DEVDOTDOT){
276
			q.path = QID(0, Qtopdir);
277
			q.type = QTDIR;
278
			devdir(c, q, "#a", 0, eve, 0555, dp);
279
			return 1;
280
		}
281
		if(s > 0)
282
			return -1;
283
		q.path = QID(0, Qprotodir);
284
		q.type = QTDIR;
285
		devdir(c, q, "tls", 0, eve, 0555, dp);
286
		return 1;
287
	case Qprotodir:
288
		if(s == DEVDOTDOT){
289
			q.path = QID(0, Qtopdir);
290
			q.type = QTDIR;
291
			devdir(c, q, ".", 0, eve, 0555, dp);
292
			return 1;
293
		}
294
		if(s < 3){
295
			switch(s) {
296
			default:
297
				return -1;
298
			case 0:
299
				q.path = QID(0, Qclonus);
300
				break;
301
			case 1:
302
				q.path = QID(0, Qencalgs);
303
				break;
304
			case 2:
305
				q.path = QID(0, Qhashalgs);
306
				break;
307
			}
308
			perm = 0444;
309
			if(TYPE(q) == Qclonus)
310
				perm = 0555;
311
			devdir(c, q, tlsnames[TYPE(q)], 0, eve, perm, dp);
312
			return 1;
313
		}
314
		s -= 3;
315
		if(s >= tdhiwat)
316
			return -1;
317
		q.path = QID(s, Qconvdir);
318
		q.type = QTDIR;
319
		lock(&tdlock);
320
		tr = tlsdevs[s];
321
		if(tr != nil)
322
			nm = tr->user;
323
		else
324
			nm = eve;
325
		if((name = trnames[s]) == nil){
326
			name = trnames[s] = smalloc(16);
327
			snprint(name, 16, "%d", s);
328
		}
329
		devdir(c, q, name, 0, nm, 0555, dp);
330
		unlock(&tdlock);
331
		return 1;
332
	case Qconvdir:
333
		if(s == DEVDOTDOT){
334
			q.path = QID(0, Qprotodir);
335
			q.type = QTDIR;
336
			devdir(c, q, "tls", 0, eve, 0555, dp);
337
			return 1;
338
		}
339
		if(s < 0 || s >= nelem(convdir))
340
			return -1;
341
		lock(&tdlock);
342
		tr = tlsdevs[CONV(c->qid)];
343
		if(tr != nil){
344
			nm = tr->user;
345
			perm = tr->perm;
346
		}else{
347
			perm = 0;
348
			nm = eve;
349
		}
350
		t = convdir[s];
351
		if(t == Qstatus || t == Qstats)
352
			perm &= 0444;
353
		q.path = QID(CONV(c->qid), t);
354
		devdir(c, q, tlsnames[t], 0, nm, perm, dp);
355
		unlock(&tdlock);
356
		return 1;
357
	case Qclonus:
358
	case Qencalgs:
359
	case Qhashalgs:
360
		perm = 0444;
361
		if(t == Qclonus)
362
			perm = 0555;
363
		devdir(c, c->qid, tlsnames[t], 0, eve, perm, dp);
364
		return 1;
365
	default:
366
		lock(&tdlock);
367
		tr = tlsdevs[CONV(c->qid)];
368
		if(tr != nil){
369
			nm = tr->user;
370
			perm = tr->perm;
371
		}else{
372
			perm = 0;
373
			nm = eve;
374
		}
375
		if(t == Qstatus || t == Qstats)
376
			perm &= 0444;
377
		devdir(c, c->qid, tlsnames[t], 0, nm, perm, dp);
378
		unlock(&tdlock);
379
		return 1;
380
	}
381
}
382
 
383
static Chan*
384
tlsattach(char *spec)
385
{
386
	Chan *c;
387
 
388
	c = devattach('a', spec);
389
	c->qid.path = QID(0, Qtopdir);
390
	c->qid.type = QTDIR;
391
	c->qid.vers = 0;
392
	return c;
393
}
394
 
395
static Walkqid*
396
tlswalk(Chan *c, Chan *nc, char **name, int nname)
397
{
398
	return devwalk(c, nc, name, nname, nil, 0, tlsgen);
399
}
400
 
401
static int
402
tlsstat(Chan *c, uchar *db, int n)
403
{
404
	return devstat(c, db, n, nil, 0, tlsgen);
405
}
406
 
407
static Chan*
408
tlsopen(Chan *c, int omode)
409
{
410
	TlsRec *tr, **pp;
411
	int t, perm;
412
 
413
	perm = 0;
414
	omode &= 3;
415
	switch(omode) {
416
	case OREAD:
417
		perm = 4;
418
		break;
419
	case OWRITE:
420
		perm = 2;
421
		break;
422
	case ORDWR:
423
		perm = 6;
424
		break;
425
	}
426
 
427
	t = TYPE(c->qid);
428
	switch(t) {
429
	default:
430
		panic("tlsopen");
431
	case Qtopdir:
432
	case Qprotodir:
433
	case Qconvdir:
434
		if(omode != OREAD)
435
			error(Eperm);
436
		break;
437
	case Qclonus:
438
		tr = newtls(c);
439
		if(tr == nil)
440
			error(Enodev);
441
		break;
442
	case Qctl:
443
	case Qdata:
444
	case Qhand:
445
	case Qstatus:
446
	case Qstats:
447
		if((t == Qstatus || t == Qstats) && omode != OREAD)
448
			error(Eperm);
449
		if(waserror()) {
450
			unlock(&tdlock);
451
			nexterror();
452
		}
453
		lock(&tdlock);
454
		pp = &tlsdevs[CONV(c->qid)];
455
		tr = *pp;
456
		if(tr == nil)
457
			error("must open connection using clone");
458
		if((perm & (tr->perm>>6)) != perm
459
		&& (strcmp(up->user, tr->user) != 0
460
		    || (perm & tr->perm) != perm))
461
			error(Eperm);
462
		if(t == Qhand){
463
			if(waserror()){
464
				unlock(&tr->hqlock);
465
				nexterror();
466
			}
467
			lock(&tr->hqlock);
468
			if(tr->handq != nil)
469
				error(Einuse);
470
			tr->handq = qopen(2 * MaxCipherRecLen, 0, nil, nil);
471
			if(tr->handq == nil)
472
				error("cannot allocate handshake queue");
473
			tr->hqref = 1;
474
			unlock(&tr->hqlock);
475
			poperror();
476
		}
477
		tr->ref++;
478
		unlock(&tdlock);
479
		poperror();
480
		break;
481
	case Qencalgs:
482
	case Qhashalgs:
483
		if(omode != OREAD)
484
			error(Eperm);
485
		break;
486
	}
487
	c->mode = openmode(omode);
488
	c->flag |= COPEN;
489
	c->offset = 0;
490
	c->iounit = qiomaxatomic;
491
	return c;
492
}
493
 
494
static int
495
tlswstat(Chan *c, uchar *dp, int n)
496
{
497
	Dir *d;
498
	TlsRec *tr;
499
	int rv;
500
 
501
	d = nil;
502
	if(waserror()){
503
		free(d);
504
		unlock(&tdlock);
505
		nexterror();
506
	}
507
 
508
	lock(&tdlock);
509
	tr = tlsdevs[CONV(c->qid)];
510
	if(tr == nil)
511
		error(Ebadusefd);
512
	if(strcmp(tr->user, up->user) != 0)
513
		error(Eperm);
514
 
515
	d = smalloc(n + sizeof *d);
516
	rv = convM2D(dp, n, &d[0], (char*) &d[1]);
517
	if(rv == 0)
518
		error(Eshortstat);
519
	if(!emptystr(d->uid))
520
		kstrdup(&tr->user, d->uid);
521
	if(d->mode != ~0UL)
522
		tr->perm = d->mode;
523
 
524
	free(d);
525
	poperror();
526
	unlock(&tdlock);
527
 
528
	return rv;
529
}
530
 
531
static void
532
dechandq(TlsRec *tr)
533
{
534
	lock(&tr->hqlock);
535
	if(--tr->hqref == 0){
536
		if(tr->handq != nil){
537
			qfree(tr->handq);
538
			tr->handq = nil;
539
		}
540
		if(tr->hprocessed != nil){
541
			freeb(tr->hprocessed);
542
			tr->hprocessed = nil;
543
		}
544
	}
545
	unlock(&tr->hqlock);
546
}
547
 
548
static void
549
tlsclose(Chan *c)
550
{
551
	TlsRec *tr;
552
	int t;
553
 
554
	t = TYPE(c->qid);
555
	switch(t) {
556
	case Qctl:
557
	case Qdata:
558
	case Qhand:
559
	case Qstatus:
560
	case Qstats:
561
		if((c->flag & COPEN) == 0)
562
			break;
563
 
564
		tr = tlsdevs[CONV(c->qid)];
565
		if(tr == nil)
566
			break;
567
 
568
		if(t == Qhand)
569
			dechandq(tr);
570
 
571
		lock(&tdlock);
572
		if(--tr->ref > 0) {
573
			unlock(&tdlock);
574
			return;
575
		}
576
		tlsdevs[CONV(c->qid)] = nil;
577
		unlock(&tdlock);
578
 
579
		if(tr->c != nil && !waserror()){
580
			checkstate(tr, 0, SOpen|SHandshake|SRClose);
581
			sendAlert(tr, ECloseNotify);
582
			poperror();
583
		}
584
		tlshangup(tr);
585
		if(tr->c != nil)
586
			cclose(tr->c);
587
		freeSec(tr->in.sec);
588
		freeSec(tr->in.new);
589
		freeSec(tr->out.sec);
590
		freeSec(tr->out.new);
591
		free(tr->user);
592
		free(tr);
593
		break;
594
	}
595
}
596
 
597
/*
598
 *  make sure we have at least 'n' bytes in list 'l'
599
 */
600
static void
601
ensure(TlsRec *s, Block **l, int n)
602
{
603
	int sofar, i;
604
	Block *b, *bl;
605
 
606
	sofar = 0;
607
	for(b = *l; b; b = b->next){
608
		sofar += BLEN(b);
609
		if(sofar >= n)
610
			return;
611
		l = &b->next;
612
	}
613
 
614
	while(sofar < n){
615
		bl = devtab[s->c->type]->bread(s->c, MaxCipherRecLen + RecHdrLen, 0);
616
		if(bl == 0)
617
			error(Ehungup);
618
		*l = bl;
619
		i = 0;
620
		for(b = bl; b; b = b->next){
621
			i += BLEN(b);
622
			l = &b->next;
623
		}
624
		if(i == 0)
625
			error(Ehungup);
626
		sofar += i;
627
	}
628
if(s->debug) pprint("ensure read %d\n", sofar);
629
}
630
 
631
/*
632
 *  copy 'n' bytes from 'l' into 'p' and free
633
 *  the bytes in 'l'
634
 */
635
static void
636
consume(Block **l, uchar *p, int n)
637
{
638
	Block *b;
639
	int i;
640
 
641
	for(; *l && n > 0; n -= i){
642
		b = *l;
643
		i = BLEN(b);
644
		if(i > n)
645
			i = n;
646
		memmove(p, b->rp, i);
647
		b->rp += i;
648
		p += i;
649
		if(BLEN(b) < 0)
650
			panic("consume");
651
		if(BLEN(b))
652
			break;
653
		*l = b->next;
654
		freeb(b);
655
	}
656
}
657
 
658
/*
659
 *  give back n bytes
660
 */
661
static void
662
regurgitate(TlsRec *s, uchar *p, int n)
663
{
664
	Block *b;
665
 
666
	if(n <= 0)
667
		return;
668
	b = s->unprocessed;
669
	if(s->unprocessed == nil || b->rp - b->base < n) {
670
		b = allocb(n);
671
		memmove(b->wp, p, n);
672
		b->wp += n;
673
		b->next = s->unprocessed;
674
		s->unprocessed = b;
675
	} else {
676
		b->rp -= n;
677
		memmove(b->rp, p, n);
678
	}
679
}
680
 
681
/*
682
 *  remove at most n bytes from the queue
683
 */
684
static Block*
685
qgrab(Block **l, int n)
686
{
687
	Block *bb, *b;
688
	int i;
689
 
690
	b = *l;
691
	if(BLEN(b) == n){
692
		*l = b->next;
693
		b->next = nil;
694
		return b;
695
	}
696
 
697
	i = 0;
698
	for(bb = b; bb != nil && i < n; bb = bb->next)
699
		i += BLEN(bb);
700
	if(i > n)
701
		i = n;
702
 
703
	bb = allocb(i);
704
	consume(l, bb->wp, i);
705
	bb->wp += i;
706
	return bb;
707
}
708
 
709
static void
710
tlsclosed(TlsRec *tr, int new)
711
{
712
	lock(&tr->statelk);
713
	if(tr->state == SOpen || tr->state == SHandshake)
714
		tr->state = new;
715
	else if((new | tr->state) == (SRClose|SLClose))
716
		tr->state = SClosed;
717
	unlock(&tr->statelk);
718
	alertHand(tr, "close notify");
719
}
720
 
721
/*
722
 *  read and process one tls record layer message
723
 *  must be called with tr->in.io held
724
 *  We can't let Eintrs lose data, since doing so will get
725
 *  us out of sync with the sender and break the reliablity
726
 *  of the channel.  Eintr only happens during the reads in
727
 *  consume.  Therefore we put back any bytes consumed before
728
 *  the last call to ensure.
729
 */
730
static void
731
tlsrecread(TlsRec *tr)
732
{
733
	OneWay *volatile in;
734
	Block *volatile b;
735
	uchar *p, seq[8], header[RecHdrLen], hmac[MaxMacLen];
736
	int volatile nconsumed;
737
	int len, type, ver, unpad_len;
738
 
739
	nconsumed = 0;
740
	if(waserror()){
741
		if(strcmp(up->errstr, Eintr) == 0 && !waserror()){
742
			regurgitate(tr, header, nconsumed);
743
			poperror();
744
		}else
745
			tlsError(tr, "channel error");
746
		nexterror();
747
	}
748
	ensure(tr, &tr->unprocessed, RecHdrLen);
749
	consume(&tr->unprocessed, header, RecHdrLen);
750
if(tr->debug)pprint("consumed %d header\n", RecHdrLen);
751
	nconsumed = RecHdrLen;
752
 
753
	if((tr->handin == 0) && (header[0] & 0x80)){
754
		/* Cope with an SSL3 ClientHello expressed in SSL2 record format.
755
			This is sent by some clients that we must interoperate
756
			with, such as Java's JSSE and Microsoft's Internet Explorer. */
757
		len = (get16(header) & ~0x8000) - 3;
758
		type = header[2];
759
		ver = get16(header + 3);
760
		if(type != SSL2ClientHello || len < 22)
761
			rcvError(tr, EProtocolVersion, "invalid initial SSL2-like message");
762
	}else{  /* normal SSL3 record format */
763
		type = header[0];
764
		ver = get16(header+1);
765
		len = get16(header+3);
766
	}
767
	if(ver != tr->version && (tr->verset || ver < MinProtoVersion || ver > MaxProtoVersion))
768
		rcvError(tr, EProtocolVersion, "devtls expected ver=%x%s, saw (len=%d) type=%x ver=%x '%.12s'",
769
			tr->version, tr->verset?"/set":"", len, type, ver, (char*)header);
770
	if(len > MaxCipherRecLen || len < 0)
771
		rcvError(tr, ERecordOverflow, "record message too long %d", len);
772
	ensure(tr, &tr->unprocessed, len);
773
	nconsumed = 0;
774
	poperror();
775
 
776
	/*
777
	 * If an Eintr happens after this, we'll get out of sync.
778
	 * Make sure nothing we call can sleep.
779
	 * Errors are ok, as they kill the connection.
780
	 * Luckily, allocb won't sleep, it'll just error out.
781
	 */
782
	b = nil;
783
	if(waserror()){
784
		if(b != nil)
785
			freeb(b);
786
		tlsError(tr, "channel error");
787
		nexterror();
788
	}
789
	b = qgrab(&tr->unprocessed, len);
790
if(tr->debug) pprint("consumed unprocessed %d\n", len);
791
 
792
	in = &tr->in;
793
	if(waserror()){
794
		qunlock(&in->seclock);
795
		nexterror();
796
	}
797
	qlock(&in->seclock);
798
	p = b->rp;
799
	if(in->sec != nil) {
800
		/* to avoid Canvel-Hiltgen-Vaudenay-Vuagnoux attack, all errors here
801
		        should look alike, including timing of the response. */
802
		unpad_len = (*in->sec->dec)(in->sec, p, len);
803
		if(unpad_len >= in->sec->maclen)
804
			len = unpad_len - in->sec->maclen;
805
if(tr->debug) pprint("decrypted %d\n", unpad_len);
806
if(tr->debug) pdump(unpad_len, p, "decrypted:");
807
 
808
		/* update length */
809
		put16(header+3, len);
810
		put64(seq, in->seq);
811
		in->seq++;
812
		(*tr->packMac)(in->sec, in->sec->mackey, seq, header, p, len, hmac);
813
		if(unpad_len < in->sec->maclen)
814
			rcvError(tr, EBadRecordMac, "short record mac");
815
		if(memcmp(hmac, p+len, in->sec->maclen) != 0)
816
			rcvError(tr, EBadRecordMac, "record mac mismatch");
817
		b->wp = b->rp + len;
818
	}
819
	qunlock(&in->seclock);
820
	poperror();
821
	if(len < 0)
822
		rcvError(tr, EDecodeError, "runt record message");
823
 
824
	switch(type) {
825
	default:
826
		rcvError(tr, EIllegalParameter, "invalid record message %#x", type);
827
		break;
828
	case RChangeCipherSpec:
829
		if(len != 1 || p[0] != 1)
830
			rcvError(tr, EDecodeError, "invalid change cipher spec");
831
		qlock(&in->seclock);
832
		if(in->new == nil){
833
			qunlock(&in->seclock);
834
			rcvError(tr, EUnexpectedMessage, "unexpected change cipher spec");
835
		}
836
		freeSec(in->sec);
837
		in->sec = in->new;
838
		in->new = nil;
839
		in->seq = 0;
840
		qunlock(&in->seclock);
841
		break;
842
	case RAlert:
843
		if(len != 2)
844
			rcvError(tr, EDecodeError, "invalid alert");
845
		if(p[0] == 2)
846
			rcvAlert(tr, p[1]);
847
		if(p[0] != 1)
848
			rcvError(tr, EIllegalParameter, "invalid alert fatal code");
849
 
850
		/*
851
		 * propate non-fatal alerts to handshaker
852
		 */
853
		if(p[1] == ECloseNotify) {
854
			tlsclosed(tr, SRClose);
855
			if(tr->opened)
856
				error("tls hungup");
857
			error("close notify");
858
		}
859
		if(p[1] == ENoRenegotiation)
860
			alertHand(tr, "no renegotiation");
861
		else if(p[1] == EUserCanceled)
862
			alertHand(tr, "handshake canceled by user");
863
		else
864
			rcvError(tr, EIllegalParameter, "invalid alert code");
865
		break;
866
	case RHandshake:
867
		/*
868
		 * don't worry about dropping the block
869
		 * qbwrite always queues even if flow controlled and interrupted.
870
		 *
871
		 * if there isn't any handshaker, ignore the request,
872
		 * but notify the other side we are doing so.
873
		 */
874
		lock(&tr->hqlock);
875
		if(tr->handq != nil){
876
			tr->hqref++;
877
			unlock(&tr->hqlock);
878
			if(waserror()){
879
				dechandq(tr);
880
				nexterror();
881
			}
882
			b = padblock(b, 1);
883
			*b->rp = RHandshake;
884
			qbwrite(tr->handq, b);
885
			b = nil;
886
			poperror();
887
			dechandq(tr);
888
		}else{
889
			unlock(&tr->hqlock);
890
			if(tr->verset && tr->version != SSL3Version && !waserror()){
891
				sendAlert(tr, ENoRenegotiation);
892
				poperror();
893
			}
894
		}
895
		break;
896
	case SSL2ClientHello:
897
		lock(&tr->hqlock);
898
		if(tr->handq != nil){
899
			tr->hqref++;
900
			unlock(&tr->hqlock);
901
			if(waserror()){
902
				dechandq(tr);
903
				nexterror();
904
			}
905
			/* Pass the SSL2 format data, so that the handshake code can compute
906
				the correct checksums.  HSSL2ClientHello = HandshakeType 9 is
907
				unused in RFC2246. */
908
			b = padblock(b, 8);
909
			b->rp[0] = RHandshake;
910
			b->rp[1] = HSSL2ClientHello;
911
			put24(&b->rp[2], len+3);
912
			b->rp[5] = SSL2ClientHello;
913
			put16(&b->rp[6], ver);
914
			qbwrite(tr->handq, b);
915
			b = nil;
916
			poperror();
917
			dechandq(tr);
918
		}else{
919
			unlock(&tr->hqlock);
920
			if(tr->verset && tr->version != SSL3Version && !waserror()){
921
				sendAlert(tr, ENoRenegotiation);
922
				poperror();
923
			}
924
		}
925
		break;
926
	case RApplication:
927
		if(!tr->opened)
928
			rcvError(tr, EUnexpectedMessage, "application message received before handshake completed");
929
		if(BLEN(b) > 0){
930
			tr->processed = b;
931
			b = nil;
932
		}
933
		break;
934
	}
935
	if(b != nil)
936
		freeb(b);
937
	poperror();
938
}
939
 
940
/*
941
 * got a fatal alert message
942
 */
943
static void
944
rcvAlert(TlsRec *tr, int err)
945
{
946
	char *s;
947
	int i;
948
 
949
	s = "unknown error";
950
	for(i=0; i < nelem(tlserrs); i++){
951
		if(tlserrs[i].err == err){
952
			s = tlserrs[i].msg;
953
			break;
954
		}
955
	}
956
if(tr->debug) pprint("rcvAlert: %s\n", s);
957
 
958
	tlsError(tr, s);
959
	if(!tr->opened)
960
		error(s);
961
	error("tls error");
962
}
963
 
964
/*
965
 * found an error while decoding the input stream
966
 */
967
static void
968
rcvError(TlsRec *tr, int err, char *fmt, ...)
969
{
970
	char msg[ERRMAX];
971
	va_list arg;
972
 
973
	va_start(arg, fmt);
974
	vseprint(msg, msg+sizeof(msg), fmt, arg);
975
	va_end(arg);
976
if(tr->debug) pprint("rcvError: %s\n", msg);
977
 
978
	sendAlert(tr, err);
979
 
980
	if(!tr->opened)
981
		error(msg);
982
	error("tls error");
983
}
984
 
985
/*
986
 * make sure the next hand operation returns with a 'msg' error
987
 */
988
static void
989
alertHand(TlsRec *tr, char *msg)
990
{
991
	Block *b;
992
	int n;
993
 
994
	lock(&tr->hqlock);
995
	if(tr->handq == nil){
996
		unlock(&tr->hqlock);
997
		return;
998
	}
999
	tr->hqref++;
1000
	unlock(&tr->hqlock);
1001
 
1002
	n = strlen(msg);
1003
	if(waserror()){
1004
		dechandq(tr);
1005
		nexterror();
1006
	}
1007
	b = allocb(n + 2);
1008
	*b->wp++ = RAlert;
1009
	memmove(b->wp, msg, n + 1);
1010
	b->wp += n + 1;
1011
 
1012
	qbwrite(tr->handq, b);
1013
 
1014
	poperror();
1015
	dechandq(tr);
1016
}
1017
 
1018
static void
1019
checkstate(TlsRec *tr, int ishand, int ok)
1020
{
1021
	int state;
1022
 
1023
	lock(&tr->statelk);
1024
	state = tr->state;
1025
	unlock(&tr->statelk);
1026
	if(state & ok)
1027
		return;
1028
	switch(state){
1029
	case SHandshake:
1030
	case SOpen:
1031
		break;
1032
	case SError:
1033
	case SAlert:
1034
		if(ishand)
1035
			error(tr->err);
1036
		error("tls error");
1037
	case SRClose:
1038
	case SLClose:
1039
	case SClosed:
1040
		error("tls hungup");
1041
	}
1042
	error("tls improperly configured");
1043
}
1044
 
1045
static Block*
1046
tlsbread(Chan *c, long n, ulong offset)
1047
{
1048
	int ty;
1049
	Block *b;
1050
	TlsRec *volatile tr;
1051
 
1052
	ty = TYPE(c->qid);
1053
	switch(ty) {
1054
	default:
1055
		return devbread(c, n, offset);
1056
	case Qhand:
1057
	case Qdata:
1058
		break;
1059
	}
1060
 
1061
	tr = tlsdevs[CONV(c->qid)];
1062
	if(tr == nil)
1063
		panic("tlsbread");
1064
 
1065
	if(waserror()){
1066
		qunlock(&tr->in.io);
1067
		nexterror();
1068
	}
1069
	qlock(&tr->in.io);
1070
	if(ty == Qdata){
1071
		checkstate(tr, 0, SOpen);
1072
		while(tr->processed == nil)
1073
			tlsrecread(tr);
1074
 
1075
		/* return at most what was asked for */
1076
		b = qgrab(&tr->processed, n);
1077
if(tr->debug) pprint("consumed processed %ld\n", BLEN(b));
1078
if(tr->debug) pdump(BLEN(b), b->rp, "consumed:");
1079
		qunlock(&tr->in.io);
1080
		poperror();
1081
		tr->datain += BLEN(b);
1082
	}else{
1083
		checkstate(tr, 1, SOpen|SHandshake|SLClose);
1084
 
1085
		/*
1086
		 * it's ok to look at state without the lock
1087
		 * since it only protects reading records,
1088
		 * and we have that tr->in.io held.
1089
		 */
1090
		while(!tr->opened && tr->hprocessed == nil && !qcanread(tr->handq))
1091
			tlsrecread(tr);
1092
 
1093
		qunlock(&tr->in.io);
1094
		poperror();
1095
 
1096
		if(waserror()){
1097
			qunlock(&tr->hqread);
1098
			nexterror();
1099
		}
1100
		qlock(&tr->hqread);
1101
		if(tr->hprocessed == nil){
1102
			b = qbread(tr->handq, MaxRecLen + 1);
1103
			if(*b->rp++ == RAlert){
1104
				kstrcpy(up->errstr, (char*)b->rp, ERRMAX);
1105
				freeb(b);
1106
				nexterror();
1107
			}
1108
			tr->hprocessed = b;
1109
		}
1110
		b = qgrab(&tr->hprocessed, n);
1111
		poperror();
1112
		qunlock(&tr->hqread);
1113
		tr->handin += BLEN(b);
1114
	}
1115
 
1116
	return b;
1117
}
1118
 
1119
static long
1120
tlsread(Chan *c, void *a, long n, vlong off)
1121
{
1122
	Block *volatile b;
1123
	Block *nb;
1124
	uchar *va;
1125
	int i, ty;
1126
	char *buf, *s, *e;
1127
	ulong offset = off;
1128
	TlsRec * tr;
1129
 
1130
	if(c->qid.type & QTDIR)
1131
		return devdirread(c, a, n, 0, 0, tlsgen);
1132
 
1133
	tr = tlsdevs[CONV(c->qid)];
1134
	ty = TYPE(c->qid);
1135
	switch(ty) {
1136
	default:
1137
		error(Ebadusefd);
1138
	case Qstatus:
1139
		buf = smalloc(Statlen);
1140
		qlock(&tr->in.seclock);
1141
		qlock(&tr->out.seclock);
1142
		s = buf;
1143
		e = buf + Statlen;
1144
		s = seprint(s, e, "State: %s\n", tlsstate(tr->state));
1145
		s = seprint(s, e, "Version: %#x\n", tr->version);
1146
		if(tr->in.sec != nil)
1147
			s = seprint(s, e, "EncIn: %s\nHashIn: %s\n", tr->in.sec->encalg, tr->in.sec->hashalg);
1148
		if(tr->in.new != nil)
1149
			s = seprint(s, e, "NewEncIn: %s\nNewHashIn: %s\n", tr->in.new->encalg, tr->in.new->hashalg);
1150
		if(tr->out.sec != nil)
1151
			s = seprint(s, e, "EncOut: %s\nHashOut: %s\n", tr->out.sec->encalg, tr->out.sec->hashalg);
1152
		if(tr->out.new != nil)
1153
			seprint(s, e, "NewEncOut: %s\nNewHashOut: %s\n", tr->out.new->encalg, tr->out.new->hashalg);
1154
		qunlock(&tr->in.seclock);
1155
		qunlock(&tr->out.seclock);
1156
		n = readstr(offset, a, n, buf);
1157
		free(buf);
1158
		return n;
1159
	case Qstats:
1160
		buf = smalloc(Statlen);
1161
		s = buf;
1162
		e = buf + Statlen;
1163
		s = seprint(s, e, "DataIn: %lld\n", tr->datain);
1164
		s = seprint(s, e, "DataOut: %lld\n", tr->dataout);
1165
		s = seprint(s, e, "HandIn: %lld\n", tr->handin);
1166
		seprint(s, e, "HandOut: %lld\n", tr->handout);
1167
		n = readstr(offset, a, n, buf);
1168
		free(buf);
1169
		return n;
1170
	case Qctl:
1171
		buf = smalloc(Statlen);
1172
		snprint(buf, Statlen, "%llud", CONV(c->qid));
1173
		n = readstr(offset, a, n, buf);
1174
		free(buf);
1175
		return n;
1176
	case Qdata:
1177
	case Qhand:
1178
		b = tlsbread(c, n, offset);
1179
		break;
1180
	case Qencalgs:
1181
		return readstr(offset, a, n, encalgs);
1182
	case Qhashalgs:
1183
		return readstr(offset, a, n, hashalgs);
1184
	}
1185
 
1186
	if(waserror()){
1187
		freeblist(b);
1188
		nexterror();
1189
	}
1190
 
1191
	n = 0;
1192
	va = a;
1193
	for(nb = b; nb; nb = nb->next){
1194
		i = BLEN(nb);
1195
		memmove(va+n, nb->rp, i);
1196
		n += i;
1197
	}
1198
 
1199
	freeblist(b);
1200
	poperror();
1201
 
1202
	return n;
1203
}
1204
 
1205
/*
1206
 *  write a block in tls records
1207
 */
1208
static void
1209
tlsrecwrite(TlsRec *tr, int type, Block *b)
1210
{
1211
	Block *volatile bb;
1212
	Block *nb;
1213
	uchar *p, seq[8];
1214
	OneWay *volatile out;
1215
	int n, maclen, pad, ok;
1216
 
1217
	out = &tr->out;
1218
	bb = b;
1219
	if(waserror()){
1220
		qunlock(&out->io);
1221
		if(bb != nil)
1222
			freeb(bb);
1223
		nexterror();
1224
	}
1225
	qlock(&out->io);
1226
if(tr->debug)pprint("send %ld\n", BLEN(b));
1227
if(tr->debug)pdump(BLEN(b), b->rp, "sent:");
1228
 
1229
 
1230
	ok = SHandshake|SOpen|SRClose;
1231
	if(type == RAlert)
1232
		ok |= SAlert;
1233
	while(bb != nil){
1234
		checkstate(tr, type != RApplication, ok);
1235
 
1236
		/*
1237
		 * get at most one maximal record's input,
1238
		 * with padding on the front for header and
1239
		 * back for mac and maximal block padding.
1240
		 */
1241
		if(waserror()){
1242
			qunlock(&out->seclock);
1243
			nexterror();
1244
		}
1245
		qlock(&out->seclock);
1246
		maclen = 0;
1247
		pad = 0;
1248
		if(out->sec != nil){
1249
			maclen = out->sec->maclen;
1250
			pad = maclen + out->sec->block;
1251
		}
1252
		n = BLEN(bb);
1253
		if(n > MaxRecLen){
1254
			n = MaxRecLen;
1255
			nb = allocb(n + pad + RecHdrLen);
1256
			memmove(nb->wp + RecHdrLen, bb->rp, n);
1257
			bb->rp += n;
1258
		}else{
1259
			/*
1260
			 * carefully reuse bb so it will get freed if we're out of memory
1261
			 */
1262
			bb = padblock(bb, RecHdrLen);
1263
			if(pad)
1264
				nb = padblock(bb, -pad);
1265
			else
1266
				nb = bb;
1267
			bb = nil;
1268
		}
1269
 
1270
		p = nb->rp;
1271
		p[0] = type;
1272
		put16(p+1, tr->version);
1273
		put16(p+3, n);
1274
 
1275
		if(out->sec != nil){
1276
			put64(seq, out->seq);
1277
			out->seq++;
1278
			(*tr->packMac)(out->sec, out->sec->mackey, seq, p, p + RecHdrLen, n, p + RecHdrLen + n);
1279
			n += maclen;
1280
 
1281
			/* encrypt */
1282
			n = (*out->sec->enc)(out->sec, p + RecHdrLen, n);
1283
			nb->wp = p + RecHdrLen + n;
1284
 
1285
			/* update length */
1286
			put16(p+3, n);
1287
		}
1288
		if(type == RChangeCipherSpec){
1289
			if(out->new == nil)
1290
				error("change cipher without a new cipher");
1291
			freeSec(out->sec);
1292
			out->sec = out->new;
1293
			out->new = nil;
1294
			out->seq = 0;
1295
		}
1296
		qunlock(&out->seclock);
1297
		poperror();
1298
 
1299
		/*
1300
		 * if bwrite error's, we assume the block is queued.
1301
		 * if not, we're out of sync with the receiver and will not recover.
1302
		 */
1303
		if(waserror()){
1304
			if(strcmp(up->errstr, "interrupted") != 0)
1305
				tlsError(tr, "channel error");
1306
			nexterror();
1307
		}
1308
		devtab[tr->c->type]->bwrite(tr->c, nb, 0);
1309
		poperror();
1310
	}
1311
	qunlock(&out->io);
1312
	poperror();
1313
}
1314
 
1315
static long
1316
tlsbwrite(Chan *c, Block *b, ulong offset)
1317
{
1318
	int ty;
1319
	ulong n;
1320
	TlsRec *tr;
1321
 
1322
	n = BLEN(b);
1323
 
1324
	tr = tlsdevs[CONV(c->qid)];
1325
	if(tr == nil)
1326
		panic("tlsbwrite");
1327
 
1328
	ty = TYPE(c->qid);
1329
	switch(ty) {
1330
	default:
1331
		return devbwrite(c, b, offset);
1332
	case Qhand:
1333
		tlsrecwrite(tr, RHandshake, b);
1334
		tr->handout += n;
1335
		break;
1336
	case Qdata:
1337
		checkstate(tr, 0, SOpen);
1338
		tlsrecwrite(tr, RApplication, b);
1339
		tr->dataout += n;
1340
		break;
1341
	}
1342
 
1343
	return n;
1344
}
1345
 
1346
typedef struct Hashalg Hashalg;
1347
struct Hashalg
1348
{
1349
	char	*name;
1350
	int	maclen;
1351
	void	(*initkey)(Hashalg *, int, Secret *, uchar*);
1352
};
1353
 
1354
static void
1355
initmd5key(Hashalg *ha, int version, Secret *s, uchar *p)
1356
{
1357
	s->maclen = ha->maclen;
1358
	if(version == SSL3Version)
1359
		s->mac = sslmac_md5;
1360
	else
1361
		s->mac = hmac_md5;
1362
	memmove(s->mackey, p, ha->maclen);
1363
}
1364
 
1365
static void
1366
initclearmac(Hashalg *, int, Secret *s, uchar *)
1367
{
1368
	s->maclen = 0;
1369
	s->mac = nomac;
1370
}
1371
 
1372
static void
1373
initsha1key(Hashalg *ha, int version, Secret *s, uchar *p)
1374
{
1375
	s->maclen = ha->maclen;
1376
	if(version == SSL3Version)
1377
		s->mac = sslmac_sha1;
1378
	else
1379
		s->mac = hmac_sha1;
1380
	memmove(s->mackey, p, ha->maclen);
1381
}
1382
 
1383
static Hashalg hashtab[] =
1384
{
1385
	{ "clear", 0, initclearmac, },
1386
	{ "md5", MD5dlen, initmd5key, },
1387
	{ "sha1", SHA1dlen, initsha1key, },
1388
	{ 0 }
1389
};
1390
 
1391
static Hashalg*
1392
parsehashalg(char *p)
1393
{
1394
	Hashalg *ha;
1395
 
1396
	for(ha = hashtab; ha->name; ha++)
1397
		if(strcmp(p, ha->name) == 0)
1398
			return ha;
1399
	error("unsupported hash algorithm");
1400
	return nil;
1401
}
1402
 
1403
typedef struct Encalg Encalg;
1404
struct Encalg
1405
{
1406
	char	*name;
1407
	int	keylen;
1408
	int	ivlen;
1409
	void	(*initkey)(Encalg *ea, Secret *, uchar*, uchar*);
1410
};
1411
 
1412
static void
1413
initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *)
1414
{
1415
	s->enckey = smalloc(sizeof(RC4state));
1416
	s->enc = rc4enc;
1417
	s->dec = rc4enc;
1418
	s->block = 0;
1419
	setupRC4state(s->enckey, p, ea->keylen);
1420
}
1421
 
1422
static void
1423
initDES3key(Encalg *, Secret *s, uchar *p, uchar *iv)
1424
{
1425
	s->enckey = smalloc(sizeof(DES3state));
1426
	s->enc = des3enc;
1427
	s->dec = des3dec;
1428
	s->block = 8;
1429
	setupDES3state(s->enckey, (uchar(*)[8])p, iv);
1430
}
1431
 
1432
static void
1433
initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
1434
{
1435
	s->enckey = smalloc(sizeof(AESstate));
1436
	s->enc = aesenc;
1437
	s->dec = aesdec;
1438
	s->block = 16;
1439
	setupAESstate(s->enckey, p, ea->keylen, iv);
1440
}
1441
 
1442
static void
1443
initclearenc(Encalg *, Secret *s, uchar *, uchar *)
1444
{
1445
	s->enc = noenc;
1446
	s->dec = noenc;
1447
	s->block = 0;
1448
}
1449
 
1450
static Encalg encrypttab[] =
1451
{
1452
	{ "clear", 0, 0, initclearenc },
1453
	{ "rc4_128", 128/8, 0, initRC4key },
1454
	{ "3des_ede_cbc", 3 * 8, 8, initDES3key },
1455
	{ "aes_128_cbc", 128/8, 16, initAESkey },
1456
	{ "aes_256_cbc", 256/8, 16, initAESkey },
1457
	{ 0 }
1458
};
1459
 
1460
static Encalg*
1461
parseencalg(char *p)
1462
{
1463
	Encalg *ea;
1464
 
1465
	for(ea = encrypttab; ea->name; ea++)
1466
		if(strcmp(p, ea->name) == 0)
1467
			return ea;
1468
	error("unsupported encryption algorithm");
1469
	return nil;
1470
}
1471
 
1472
static long
1473
tlswrite(Chan *c, void *a, long n, vlong off)
1474
{
1475
	Encalg *ea;
1476
	Hashalg *ha;
1477
	TlsRec *volatile tr;
1478
	Secret *volatile tos, *volatile toc;
1479
	Block *volatile b;
1480
	Cmdbuf *volatile cb;
1481
	int m, ty;
1482
	char *p, *e;
1483
	uchar *volatile x;
1484
	ulong offset = off;
1485
 
1486
	tr = tlsdevs[CONV(c->qid)];
1487
	if(tr == nil)
1488
		panic("tlswrite");
1489
 
1490
	ty = TYPE(c->qid);
1491
	switch(ty){
1492
	case Qdata:
1493
	case Qhand:
1494
		p = a;
1495
		e = p + n;
1496
		do{
1497
			m = e - p;
1498
			if(m > MaxRecLen)
1499
				m = MaxRecLen;
1500
 
1501
			b = allocb(m);
1502
			if(waserror()){
1503
				freeb(b);
1504
				nexterror();
1505
			}
1506
			memmove(b->wp, p, m);
1507
			poperror();
1508
			b->wp += m;
1509
 
1510
			tlsbwrite(c, b, offset);
1511
 
1512
			p += m;
1513
		}while(p < e);
1514
		return n;
1515
	case Qctl:
1516
		break;
1517
	default:
1518
		error(Ebadusefd);
1519
		return -1;
1520
	}
1521
 
1522
	cb = parsecmd(a, n);
1523
	if(waserror()){
1524
		free(cb);
1525
		nexterror();
1526
	}
1527
	if(cb->nf < 1)
1528
		error("short control request");
1529
 
1530
	/* mutex with operations using what we're about to change */
1531
	if(waserror()){
1532
		qunlock(&tr->in.seclock);
1533
		qunlock(&tr->out.seclock);
1534
		nexterror();
1535
	}
1536
	qlock(&tr->in.seclock);
1537
	qlock(&tr->out.seclock);
1538
 
1539
	if(strcmp(cb->f[0], "fd") == 0){
1540
		if(cb->nf != 3)
1541
			error("usage: fd open-fd version");
1542
		if(tr->c != nil)
1543
			error(Einuse);
1544
		m = strtol(cb->f[2], nil, 0);
1545
		if(m < MinProtoVersion || m > MaxProtoVersion)
1546
			error("unsupported version");
1547
		tr->c = buftochan(cb->f[1]);
1548
		tr->version = m;
1549
		tlsSetState(tr, SHandshake, SClosed);
1550
	}else if(strcmp(cb->f[0], "version") == 0){
1551
		if(cb->nf != 2)
1552
			error("usage: version vers");
1553
		if(tr->c == nil)
1554
			error("must set fd before version");
1555
		if(tr->verset)
1556
			error("version already set");
1557
		m = strtol(cb->f[1], nil, 0);
1558
		if(m == SSL3Version)
1559
			tr->packMac = sslPackMac;
1560
		else if(m == TLSVersion)
1561
			tr->packMac = tlsPackMac;
1562
		else
1563
			error("unsupported version");
1564
		tr->verset = 1;
1565
		tr->version = m;
1566
	}else if(strcmp(cb->f[0], "secret") == 0){
1567
		if(cb->nf != 5)
1568
			error("usage: secret hashalg encalg isclient secretdata");
1569
		if(tr->c == nil || !tr->verset)
1570
			error("must set fd and version before secrets");
1571
 
1572
		if(tr->in.new != nil){
1573
			freeSec(tr->in.new);
1574
			tr->in.new = nil;
1575
		}
1576
		if(tr->out.new != nil){
1577
			freeSec(tr->out.new);
1578
			tr->out.new = nil;
1579
		}
1580
 
1581
		ha = parsehashalg(cb->f[1]);
1582
		ea = parseencalg(cb->f[2]);
1583
 
1584
		p = cb->f[4];
1585
		m = (strlen(p)*3)/2;
1586
		x = smalloc(m);
1587
		tos = nil;
1588
		toc = nil;
1589
		if(waserror()){
1590
			freeSec(tos);
1591
			freeSec(toc);
1592
			free(x);
1593
			nexterror();
1594
		}
1595
		m = dec64(x, m, p, strlen(p));
1596
		if(m < 2 * ha->maclen + 2 * ea->keylen + 2 * ea->ivlen)
1597
			error("not enough secret data provided");
1598
 
1599
		tos = smalloc(sizeof(Secret));
1600
		toc = smalloc(sizeof(Secret));
1601
		if(!ha->initkey || !ea->initkey)
1602
			error("misimplemented secret algorithm");
1603
		(*ha->initkey)(ha, tr->version, tos, &x[0]);
1604
		(*ha->initkey)(ha, tr->version, toc, &x[ha->maclen]);
1605
		(*ea->initkey)(ea, tos, &x[2 * ha->maclen], &x[2 * ha->maclen + 2 * ea->keylen]);
1606
		(*ea->initkey)(ea, toc, &x[2 * ha->maclen + ea->keylen], &x[2 * ha->maclen + 2 * ea->keylen + ea->ivlen]);
1607
 
1608
		if(!tos->mac || !tos->enc || !tos->dec
1609
		|| !toc->mac || !toc->enc || !toc->dec)
1610
			error("missing algorithm implementations");
1611
		if(strtol(cb->f[3], nil, 0) == 0){
1612
			tr->in.new = tos;
1613
			tr->out.new = toc;
1614
		}else{
1615
			tr->in.new = toc;
1616
			tr->out.new = tos;
1617
		}
1618
		if(tr->version == SSL3Version){
1619
			toc->unpad = sslunpad;
1620
			tos->unpad = sslunpad;
1621
		}else{
1622
			toc->unpad = tlsunpad;
1623
			tos->unpad = tlsunpad;
1624
		}
1625
		toc->encalg = ea->name;
1626
		toc->hashalg = ha->name;
1627
		tos->encalg = ea->name;
1628
		tos->hashalg = ha->name;
1629
 
1630
		free(x);
1631
		poperror();
1632
	}else if(strcmp(cb->f[0], "changecipher") == 0){
1633
		if(cb->nf != 1)
1634
			error("usage: changecipher");
1635
		if(tr->out.new == nil)
1636
			error("cannot change cipher spec without setting secret");
1637
 
1638
		qunlock(&tr->in.seclock);
1639
		qunlock(&tr->out.seclock);
1640
		poperror();
1641
		free(cb);
1642
		poperror();
1643
 
1644
		/*
1645
		 * the real work is done as the message is written
1646
		 * so the stream is encrypted in sync.
1647
		 */
1648
		b = allocb(1);
1649
		*b->wp++ = 1;
1650
		tlsrecwrite(tr, RChangeCipherSpec, b);
1651
		return n;
1652
	}else if(strcmp(cb->f[0], "opened") == 0){
1653
		if(cb->nf != 1)
1654
			error("usage: opened");
1655
		if(tr->in.sec == nil || tr->out.sec == nil)
1656
			error("cipher must be configured before enabling data messages");
1657
		lock(&tr->statelk);
1658
		if(tr->state != SHandshake && tr->state != SOpen){
1659
			unlock(&tr->statelk);
1660
			error("cannot enable data messages");
1661
		}
1662
		tr->state = SOpen;
1663
		unlock(&tr->statelk);
1664
		tr->opened = 1;
1665
	}else if(strcmp(cb->f[0], "alert") == 0){
1666
		if(cb->nf != 2)
1667
			error("usage: alert n");
1668
		if(tr->c == nil)
1669
			error("must set fd before sending alerts");
1670
		m = strtol(cb->f[1], nil, 0);
1671
 
1672
		qunlock(&tr->in.seclock);
1673
		qunlock(&tr->out.seclock);
1674
		poperror();
1675
		free(cb);
1676
		poperror();
1677
 
1678
		sendAlert(tr, m);
1679
 
1680
		if(m == ECloseNotify)
1681
			tlsclosed(tr, SLClose);
1682
 
1683
		return n;
1684
	} else if(strcmp(cb->f[0], "debug") == 0){
1685
		if(cb->nf == 2){
1686
			if(strcmp(cb->f[1], "on") == 0)
1687
				tr->debug = 1;
1688
			else
1689
				tr->debug = 0;
1690
		} else
1691
			tr->debug = 1;
1692
	} else
1693
		error(Ebadarg);
1694
 
1695
	qunlock(&tr->in.seclock);
1696
	qunlock(&tr->out.seclock);
1697
	poperror();
1698
	free(cb);
1699
	poperror();
1700
 
1701
	return n;
1702
}
1703
 
1704
static void
1705
tlsinit(void)
1706
{
1707
	struct Encalg *e;
1708
	struct Hashalg *h;
1709
	int n;
1710
	char *cp;
1711
	static int already;
1712
 
1713
	if(!already){
1714
		fmtinstall('H', encodefmt);
1715
		already = 1;
1716
	}
1717
 
1718
	tlsdevs = smalloc(sizeof(TlsRec*) * maxtlsdevs);
1719
	trnames = smalloc((sizeof *trnames) * maxtlsdevs);
1720
 
1721
	n = 1;
1722
	for(e = encrypttab; e->name != nil; e++)
1723
		n += strlen(e->name) + 1;
1724
	cp = encalgs = smalloc(n);
1725
	for(e = encrypttab;;){
1726
		strcpy(cp, e->name);
1727
		cp += strlen(e->name);
1728
		e++;
1729
		if(e->name == nil)
1730
			break;
1731
		*cp++ = ' ';
1732
	}
1733
	*cp = 0;
1734
 
1735
	n = 1;
1736
	for(h = hashtab; h->name != nil; h++)
1737
		n += strlen(h->name) + 1;
1738
	cp = hashalgs = smalloc(n);
1739
	for(h = hashtab;;){
1740
		strcpy(cp, h->name);
1741
		cp += strlen(h->name);
1742
		h++;
1743
		if(h->name == nil)
1744
			break;
1745
		*cp++ = ' ';
1746
	}
1747
	*cp = 0;
1748
}
1749
 
1750
Dev tlsdevtab = {
1751
	'a',
1752
	"tls",
1753
 
1754
	devreset,
1755
	tlsinit,
1756
	devshutdown,
1757
	tlsattach,
1758
	tlswalk,
1759
	tlsstat,
1760
	tlsopen,
1761
	devcreate,
1762
	tlsclose,
1763
	tlsread,
1764
	tlsbread,
1765
	tlswrite,
1766
	tlsbwrite,
1767
	devremove,
1768
	tlswstat,
1769
};
1770
 
1771
/* get channel associated with an fd */
1772
static Chan*
1773
buftochan(char *p)
1774
{
1775
	Chan *c;
1776
	int fd;
1777
 
1778
	if(p == 0)
1779
		error(Ebadarg);
1780
	fd = strtoul(p, 0, 0);
1781
	if(fd < 0)
1782
		error(Ebadarg);
1783
	c = fdtochan(fd, -1, 0, 1);	/* error check and inc ref */
1784
	return c;
1785
}
1786
 
1787
static void
1788
sendAlert(TlsRec *tr, int err)
1789
{
1790
	Block *b;
1791
	int i, fatal;
1792
	char *msg;
1793
 
1794
if(tr->debug)pprint("sendAlert %d\n", err);
1795
	fatal = 1;
1796
	msg = "tls unknown alert";
1797
	for(i=0; i < nelem(tlserrs); i++) {
1798
		if(tlserrs[i].err == err) {
1799
			msg = tlserrs[i].msg;
1800
			if(tr->version == SSL3Version)
1801
				err = tlserrs[i].sslerr;
1802
			else
1803
				err = tlserrs[i].tlserr;
1804
			fatal = tlserrs[i].fatal;
1805
			break;
1806
		}
1807
	}
1808
 
1809
	if(!waserror()){
1810
		b = allocb(2);
1811
		*b->wp++ = fatal + 1;
1812
		*b->wp++ = err;
1813
		if(fatal)
1814
			tlsSetState(tr, SAlert, SOpen|SHandshake|SRClose);
1815
		tlsrecwrite(tr, RAlert, b);
1816
		poperror();
1817
	}
1818
	if(fatal)
1819
		tlsError(tr, msg);
1820
}
1821
 
1822
static void
1823
tlsError(TlsRec *tr, char *msg)
1824
{
1825
	int s;
1826
 
1827
if(tr->debug)pprint("tleError %s\n", msg);
1828
	lock(&tr->statelk);
1829
	s = tr->state;
1830
	tr->state = SError;
1831
	if(s != SError){
1832
		strncpy(tr->err, msg, ERRMAX - 1);
1833
		tr->err[ERRMAX - 1] = '\0';
1834
	}
1835
	unlock(&tr->statelk);
1836
	if(s != SError)
1837
		alertHand(tr, msg);
1838
}
1839
 
1840
static void
1841
tlsSetState(TlsRec *tr, int new, int old)
1842
{
1843
	lock(&tr->statelk);
1844
	if(tr->state & old)
1845
		tr->state = new;
1846
	unlock(&tr->statelk);
1847
}
1848
 
1849
/* hand up a digest connection */
1850
static void
1851
tlshangup(TlsRec *tr)
1852
{
1853
	Block *b;
1854
 
1855
	qlock(&tr->in.io);
1856
	for(b = tr->processed; b; b = tr->processed){
1857
		tr->processed = b->next;
1858
		freeb(b);
1859
	}
1860
	if(tr->unprocessed != nil){
1861
		freeb(tr->unprocessed);
1862
		tr->unprocessed = nil;
1863
	}
1864
	qunlock(&tr->in.io);
1865
 
1866
	tlsSetState(tr, SClosed, ~0);
1867
}
1868
 
1869
static TlsRec*
1870
newtls(Chan *ch)
1871
{
1872
	TlsRec **pp, **ep, **np;
1873
	char **nmp;
1874
	int t, newmax;
1875
 
1876
	if(waserror()) {
1877
		unlock(&tdlock);
1878
		nexterror();
1879
	}
1880
	lock(&tdlock);
1881
	ep = &tlsdevs[maxtlsdevs];
1882
	for(pp = tlsdevs; pp < ep; pp++)
1883
		if(*pp == nil)
1884
			break;
1885
	if(pp >= ep) {
1886
		if(maxtlsdevs >= MaxTlsDevs) {
1887
			unlock(&tdlock);
1888
			poperror();
1889
			return nil;
1890
		}
1891
		newmax = 2 * maxtlsdevs;
1892
		if(newmax > MaxTlsDevs)
1893
			newmax = MaxTlsDevs;
1894
		np = smalloc(sizeof(TlsRec*) * newmax);
1895
		memmove(np, tlsdevs, sizeof(TlsRec*) * maxtlsdevs);
1896
		tlsdevs = np;
1897
		pp = &tlsdevs[maxtlsdevs];
1898
		memset(pp, 0, sizeof(TlsRec*)*(newmax - maxtlsdevs));
1899
 
1900
		nmp = smalloc(sizeof *nmp * newmax);
1901
		memmove(nmp, trnames, sizeof *nmp * maxtlsdevs);
1902
		trnames = nmp;
1903
 
1904
		maxtlsdevs = newmax;
1905
	}
1906
	*pp = mktlsrec();
1907
	if(pp - tlsdevs >= tdhiwat)
1908
		tdhiwat++;
1909
	t = TYPE(ch->qid);
1910
	if(t == Qclonus)
1911
		t = Qctl;
1912
	ch->qid.path = QID(pp - tlsdevs, t);
1913
	ch->qid.vers = 0;
1914
	unlock(&tdlock);
1915
	poperror();
1916
	return *pp;
1917
}
1918
 
1919
static TlsRec *
1920
mktlsrec(void)
1921
{
1922
	TlsRec *tr;
1923
 
1924
	tr = mallocz(sizeof(*tr), 1);
1925
	if(tr == nil)
1926
		error(Enomem);
1927
	tr->state = SClosed;
1928
	tr->ref = 1;
1929
	kstrdup(&tr->user, up->user);
1930
	tr->perm = 0660;
1931
	return tr;
1932
}
1933
 
1934
static char*
1935
tlsstate(int s)
1936
{
1937
	switch(s){
1938
	case SHandshake:
1939
		return "Handshaking";
1940
	case SOpen:
1941
		return "Established";
1942
	case SRClose:
1943
		return "RemoteClosed";
1944
	case SLClose:
1945
		return "LocalClosed";
1946
	case SAlert:
1947
		return "Alerting";
1948
	case SError:
1949
		return "Errored";
1950
	case SClosed:
1951
		return "Closed";
1952
	}
1953
	return "Unknown";
1954
}
1955
 
1956
static void
1957
freeSec(Secret *s)
1958
{
1959
	if(s != nil){
1960
		free(s->enckey);
1961
		free(s);
1962
	}
1963
}
1964
 
1965
static int
1966
noenc(Secret *, uchar *, int n)
1967
{
1968
	return n;
1969
}
1970
 
1971
static int
1972
rc4enc(Secret *sec, uchar *buf, int n)
1973
{
1974
	rc4(sec->enckey, buf, n);
1975
	return n;
1976
}
1977
 
1978
static int
1979
tlsunpad(uchar *buf, int n, int block)
1980
{
1981
	int pad, nn;
1982
 
1983
	pad = buf[n - 1];
1984
	nn = n - 1 - pad;
1985
	if(nn <= 0 || n % block)
1986
		return -1;
1987
	while(--n > nn)
1988
		if(pad != buf[n - 1])
1989
			return -1;
1990
	return nn;
1991
}
1992
 
1993
static int
1994
sslunpad(uchar *buf, int n, int block)
1995
{
1996
	int pad, nn;
1997
 
1998
	pad = buf[n - 1];
1999
	nn = n - 1 - pad;
2000
	if(nn <= 0 || n % block)
2001
		return -1;
2002
	return nn;
2003
}
2004
 
2005
static int
2006
blockpad(uchar *buf, int n, int block)
2007
{
2008
	int pad, nn;
2009
 
2010
	nn = n + block;
2011
	nn -= nn % block;
2012
	pad = nn - (n + 1);
2013
	while(n < nn)
2014
		buf[n++] = pad;
2015
	return nn;
2016
}
2017
 
2018
static int
2019
des3enc(Secret *sec, uchar *buf, int n)
2020
{
2021
	n = blockpad(buf, n, 8);
2022
	des3CBCencrypt(buf, n, sec->enckey);
2023
	return n;
2024
}
2025
 
2026
static int
2027
des3dec(Secret *sec, uchar *buf, int n)
2028
{
2029
	des3CBCdecrypt(buf, n, sec->enckey);
2030
	return (*sec->unpad)(buf, n, 8);
2031
}
2032
 
2033
static int
2034
aesenc(Secret *sec, uchar *buf, int n)
2035
{
2036
	n = blockpad(buf, n, 16);
2037
	aesCBCencrypt(buf, n, sec->enckey);
2038
	return n;
2039
}
2040
 
2041
static int
2042
aesdec(Secret *sec, uchar *buf, int n)
2043
{
2044
	aesCBCdecrypt(buf, n, sec->enckey);
2045
	return (*sec->unpad)(buf, n, 16);
2046
}
2047
 
2048
static DigestState*
2049
nomac(uchar *, ulong, uchar *, ulong, uchar *, DigestState *)
2050
{
2051
	return nil;
2052
}
2053
 
2054
/*
2055
 * sslmac: mac calculations for ssl 3.0 only; tls 1.0 uses the standard hmac.
2056
 */
2057
static DigestState*
2058
sslmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s,
2059
	DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen, int padlen)
2060
{
2061
	int i;
2062
	uchar pad[48], innerdigest[20];
2063
 
2064
	if(xlen > sizeof(innerdigest)
2065
	|| padlen > sizeof(pad))
2066
		return nil;
2067
 
2068
	if(klen>64)
2069
		return nil;
2070
 
2071
	/* first time through */
2072
	if(s == nil){
2073
		for(i=0; i<padlen; i++)
2074
			pad[i] = 0x36;
2075
		s = (*x)(key, klen, nil, nil);
2076
		s = (*x)(pad, padlen, nil, s);
2077
		if(s == nil)
2078
			return nil;
2079
	}
2080
 
2081
	s = (*x)(p, len, nil, s);
2082
	if(digest == nil)
2083
		return s;
2084
 
2085
	/* last time through */
2086
	for(i=0; i<padlen; i++)
2087
		pad[i] = 0x5c;
2088
	(*x)(nil, 0, innerdigest, s);
2089
	s = (*x)(key, klen, nil, nil);
2090
	s = (*x)(pad, padlen, nil, s);
2091
	(*x)(innerdigest, xlen, digest, s);
2092
	return nil;
2093
}
2094
 
2095
static DigestState*
2096
sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
2097
{
2098
	return sslmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen, 40);
2099
}
2100
 
2101
static DigestState*
2102
sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
2103
{
2104
	return sslmac_x(p, len, key, klen, digest, s, md5, MD5dlen, 48);
2105
}
2106
 
2107
static void
2108
sslPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac)
2109
{
2110
	DigestState *s;
2111
	uchar buf[11];
2112
 
2113
	memmove(buf, seq, 8);
2114
	buf[8] = header[0];
2115
	buf[9] = header[3];
2116
	buf[10] = header[4];
2117
 
2118
	s = (*sec->mac)(buf, 11, mackey, sec->maclen, 0, 0);
2119
	(*sec->mac)(body, len, mackey, sec->maclen, mac, s);
2120
}
2121
 
2122
static void
2123
tlsPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac)
2124
{
2125
	DigestState *s;
2126
	uchar buf[13];
2127
 
2128
	memmove(buf, seq, 8);
2129
	memmove(&buf[8], header, 5);
2130
 
2131
	s = (*sec->mac)(buf, 13, mackey, sec->maclen, 0, 0);
2132
	(*sec->mac)(body, len, mackey, sec->maclen, mac, s);
2133
}
2134
 
2135
static void
2136
put32(uchar *p, u32int x)
2137
{
2138
	p[0] = x>>24;
2139
	p[1] = x>>16;
2140
	p[2] = x>>8;
2141
	p[3] = x;
2142
}
2143
 
2144
static void
2145
put64(uchar *p, vlong x)
2146
{
2147
	put32(p, (u32int)(x >> 32));
2148
	put32(p+4, (u32int)x);
2149
}
2150
 
2151
static void
2152
put24(uchar *p, int x)
2153
{
2154
	p[0] = x>>16;
2155
	p[1] = x>>8;
2156
	p[2] = x;
2157
}
2158
 
2159
static void
2160
put16(uchar *p, int x)
2161
{
2162
	p[0] = x>>8;
2163
	p[1] = x;
2164
}
2165
 
2166
static u32int
2167
get32(uchar *p)
2168
{
2169
	return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
2170
}
2171
 
2172
static int
2173
get16(uchar *p)
2174
{
2175
	return (p[0]<<8)|p[1];
2176
}
2177
 
2178
static char *charmap = "0123456789abcdef";
2179
 
2180
static void
2181
pdump(int len, void *a, char *tag)
2182
{
2183
	uchar *p;
2184
	int i;
2185
	char buf[65+32];
2186
	char *q;
2187
 
2188
	p = a;
2189
	strcpy(buf, tag);
2190
	while(len > 0){
2191
		q = buf + strlen(tag);
2192
		for(i = 0; len > 0 && i < 32; i++){
2193
			if(*p >= ' ' && *p < 0x7f){
2194
				*q++ = ' ';
2195
				*q++ = *p;
2196
			} else {
2197
				*q++ = charmap[*p>>4];
2198
				*q++ = charmap[*p & 0xf];
2199
			}
2200
			len--;
2201
			p++;
2202
		}
2203
		*q = 0;
2204
 
2205
		if(len > 0)
2206
			pprint("%s...\n", buf);
2207
		else
2208
			pprint("%s\n", buf);
2209
	}
2210
}