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