plan 9 kernel history: overview | file list | diff list

1995/1217/port/devssl.c (diff list | history)

1995/1215/sys/src/9/port/devssl.c:49,551995/1217/sys/src/9/port/devssl.c:49,55 (short | long | prev | next)
1995/1213    
	DigestState *(*hf)(uchar*, ulong, uchar*, DigestState*);	/* hash func */ 
 
	int	max;		/* maximum unpadded data per msg */ 
	int	maxpad;	/* maximum padded data per msg */ 
1995/1217    
	int	maxpad;		/* maximum padded data per msg */ 
1995/1213    
 
	/* input side */ 
	OneWay	in; 
1995/1215/sys/src/9/port/devssl.c:86,911995/1217/sys/src/9/port/devssl.c:86,102
1995/1213    
 
void producerand(void); 
 
1995/1217    
static void	ensure(Dstate*, Block**, int); 
static void	consume(Block**, uchar*, int); 
static void	setsecret(OneWay*, uchar*, int); 
static Block*	encryptb(Dstate*, Block*, int); 
static Block*	decryptb(Dstate*, Block*); 
static Block*	digestb(Dstate*, Block*, int); 
static void	checkdigestb(Dstate*, Block*); 
static Chan*	buftochan(char*, long); 
static void	dighangup(Dstate*); 
 
 
1995/1213    
void 
sslreset(void) 
{ 
1995/1215/sys/src/9/port/devssl.c:203,2261995/1217/sys/src/9/port/devssl.c:214,296
1995/1213    
	return n; 
} 
 
static void 
setsecret(OneWay *w, uchar *secret, int n) 
1995/1217    
Block* 
sslbread(Chan *c, long n, ulong offset) 
1995/1213    
{ 
	w->secret = smalloc(n); 
	memmove(w->secret, secret, n); 
	w->slen = n; 
	w->mid = 0; 
1995/1217    
	Block *bp, **l; 
	uchar count[2]; 
	int len; 
	int pad; 
1995/1213    
 
	switch(s->encryptalg){ 
	case DESCBC: 
		w->state = smalloc(sizeof(DESstate)); 
		setupDESstate(w->state, secret, 0); 
		break; 
	case DESCBC: 
		w->state = smalloc(sizeof(DESstate)); 
		setupDESstate(w->state, secret, secret+8); 
		break; 
1995/1217    
	USED(offset); 
 
	s = c->aux; 
	if(s == 0 || s->state != Established) 
		error(Ebadusefd); 
 
	if(waserror()){ 
		qunlock(&s->in); 
		dighangup(s); 
		nexterror(); 
1995/1213    
	} 
1995/1217    
	qlock(&s->in); 
 
	if(s->processed == 0){ 
	 
		/* read in the whole message */ 
		s->processed = s->unprocessed; 
		s->unprocessed =- 0; 
		ensure(s, &s->processed, 2); 
		consume(&s->processed, count, 2); 
		if(count[0] & 0x80){ 
			len = ((count[0] & 0x7f)<<8) | count[1]; 
			pad = 0; 
		} else { 
			len = ((count[0] & 0x3f)<<8) | count[1]; 
			ensure(s, &s->processed, 1); 
			consume(&s->processed, count, 1); 
			pad = count[0]; 
		} 
		ensure(s, &s->processed, len); 
 
		/* trade memory bandwidth for less processing complexity */ 
		b = s->processed = pullupblock(s->processed, len); 
 
		/* put remainder on unprocessed queue */ 
		i = BLEN(b); 
		if(i > len){ 
			i -= len; 
			s->unprocessed = allocb(i); 
			memmove(s->unprocessed->wp, b->rp+len, i); 
			s->unprocessed->wp += i; 
			b->wp -= i; 
		} 
 
		if(s->encrypalg) 
			b = decryptb(s, b); 
		else 
			checkdigestb(s, b); 
 
		/* remove pad */ 
		if(b->wp - b->rp > pad) 
			panic("sslbread"); 
		b->wp -= pad; 
		s->processed = b; 
	} 
 
	b = s->processed; 
	if(BLEN(b) > n){ 
		b = allocb(n); 
		memmove(b->wp, s->processed->rp, n); 
		b->wp += n; 
		s->processed->rp += n; 
	} else  
		s->processed = b->next; 
 
	qunlock(&s->in); 
	poperror(); 
 
	return b; 
1995/1213    
} 
 
long 
1995/1215/sys/src/9/port/devssl.c:326,3311995/1217/sys/src/9/port/devssl.c:396,402
1995/1215    
	Dstate *s; 
1995/1213    
	Block *nb; 
1995/1215    
	int h, n, m, pad, rv; 
1995/1217    
	uchar *p; 
1995/1215    
 
	s = c->aux; 
	if(s == 0 || s->state != Established) 
1995/1215/sys/src/9/port/devssl.c:379,3971995/1217/sys/src/9/port/devssl.c:450,475
1995/1215    
		m += s->diglen; 
 
		/* SSL style count */ 
1995/1217    
		p = np->rp; 
1995/1215    
		if(pad){ 
			memset(nb->wp, 0, pad); 
			m += pad; 
			nb->wp += pad; 
		} else 
1995/1217    
			p[0] = (m>>8); 
			p[1] = m; 
			p[2] = pad; 
			offset = 3; 
		} else { 
1995/1215    
			m |= 0x8000; 
		np->rp[0] = (m>>8); 
		np->rp[1] = m; 
1995/1217    
			p[0] = (m>>8); 
			p[1] = m; 
			offset = 2; 
		} 
1995/1213    
 
1995/1215    
		if(encryptalg) 
			encryptb(s, nb); 
1995/1217    
			nb = encryptb(s, nb, offset); 
1995/1215    
		else 
			digestb(s, nb); 
1995/1217    
			nb = digestb(s, nb, ofsetf); 
1995/1213    
 
1995/1215    
		(*devtab[s->c->type].bwrite)(s->c, nb, offset); 
1995/1213    
 
1995/1215/sys/src/9/port/devssl.c:402,5141995/1217/sys/src/9/port/devssl.c:480,485
1995/1215    
	return rv; 
1995/1213    
} 
 
1995/1215    
Block* 
sslbread(Chan *c, long n, ulong offset) 
1995/1213    
{ 
1995/1215    
	Block *bp, **l; 
	uchar count[2]; 
	int len; 
	int pad; 
1995/1213    
                 
1995/1215    
	USED(offset); 
1995/1213    
                 
1995/1215    
	s = c->aux; 
	if(s == 0 || s->state != Established) 
		error(Ebadusefd); 
                 
	if(waserror()){ 
		qunlock(&s->in); 
		dighangup(s); 
		nexterror(); 
1995/1213    
	} 
1995/1215    
	qlock(&s->in); 
                 
	if(s->processed == 0){ 
1995/1213    
	                 
1995/1215    
		/* read in the whole message */ 
		s->processed = s->unprocessed; 
		s->unprocessed =- 0; 
		ensure(s, &s->processed, 2); 
		consume(&s->processed, count, 2); 
		if(count[0] & 0x80){ 
			len = ((count[0] & 0x7f)<<8) | count[1]; 
			pad = 0; 
		} else { 
			len = ((count[0] & 0x3f)<<8) | count[1]; 
			ensure(s, &s->processed, 1); 
			consume(&s->processed, count, 1); 
			pad = count[0]; 
		} 
		ensure(s, &s->processed, len); 
                 
		/* put remainder on unprocessed */ 
		i = 0; 
		for(b = s->processed; b; b = b->next){ 
			i = BLEN(b); 
			if(i >= len) 
				break; 
			(*s->func)(b->rp, i, 0, &ss); 
			len -= i; 
		} 
		if(b == 0) 
			panic("digestbread"); 
		if(i > len){ 
			i -= len; 
			s->unprocessed = allocb(i); 
			memmove(s->unprocessed->wp, b->rp+len, i); 
			s->unprocessed->wp += i; 
			b->wp -= i; 
		} 
			                 
		if(s->encrypalg) 
			decryptb(s, len); 
		else 
			checkdigestb(s, len); 
                 
		if(pad){ 
			for(b = s->processed; b; b = b->next){ 
	} 
                 
	b = s->processed; 
	if(BLEN(b) > n){ 
		b = allocb(n); 
		memmove(b->wp, s->processed->rp, n); 
		b->wp += n; 
		s->processed->rp += n; 
	} else  
		s->processed = b->next; 
                 
	qunlock(&s->in); 
	poperror(); 
                 
	return b; 
1995/1213    
} 
                 
1995/1215    
Block* 
decryptb(Dstate *s, Block *b, int len) 
1995/1213    
{ 
	ulong n, h; 
	uchar *p, *ep; 
	DESstate *ds; 
                 
	h = s->diglen + 2; 
                 
	switch(s->encryptalg){ 
	case DESEBC: 
		ds = s->in.state; 
		ep = b->rp + BLEN(b); 
		for(p = b->rp + h; p < ep; p += 8) 
			block_cipher(ds->expanded, p, 1); 
		break; 
	case DESCBC: 
		ds = s->in.state; 
		ep = b->rp + BLEN(b); 
		for(p = b->rp + h; p < ep; p += 8) 
			bCBCDecrypt(p, ds->ivec, ds->expanded, 8); 
		break; 
	} 
} 
                 
/* 
 *  make sure we have at least 'n' bytes in list 'l' 
 */ 
1995/1215/sys/src/9/port/devssl.c:566,6511995/1217/sys/src/9/port/devssl.c:537,614
1995/1213    
	} 
} 
 
static Block* 
digestbread(Dstate *s, long n) 
1995/1217    
static void 
setsecret(OneWay *w, uchar *secret, int n) 
1995/1213    
{ 
	Block *b; 
	int i, m, len; 
	uchar *p; 
	uchar *dp; 
	uchar digestin[32]; 
	uchar digest[32]; 
	DigestState ss; 
1995/1217    
	w->secret = smalloc(n); 
	memmove(w->secret, secret, n); 
	w->slen = n; 
	w->mid = 0; 
1995/1213    
 
	memset(&ss, 0, sizeof(ss)); 
1995/1217    
	switch(s->encryptalg){ 
	case DESCBC: 
		w->state = smalloc(sizeof(DESstate)); 
		setupDESstate(w->state, secret, 0); 
		break; 
	case DESCBC: 
		w->state = smalloc(sizeof(DESstate)); 
		setupDESstate(w->state, secret, secret+8); 
		break; 
	} 
} 
1995/1213    
 
	ensure(s, &s->unprocessed, s->diglen); 
		len = 0; 
		for(i = 0; i < 4; i++){ 
			consume(&s->unprocessed, digestin+i, 1); 
			m = digestin[i]; 
			if((m & 0x80) == 0) 
				break; 
			len = (len<<7) | (m & 0x7f); 
		} 
	                 
		/* digest count */ 
		p = &digestin[s->diglen]; 
		(*s->func)(p, i, 0, &ss); 
		ensure(s, &s->unprocessed, s->diglen); 
1995/1217    
static Block* 
encryptb(Dstate *s, Block *b, int offset) 
{ 
	ulong n; 
	int j; 
	uchar *p, *ep; 
	DESstate *ds; 
1995/1213    
 
		/* get message */ 
		s->processed = s->unprocessed; 
		s->unprocessed = 0; 
		ensure(s, &s->processed, len); 
                 
		/* digest message */ 
		i = 0; 
		for(b = s->processed; b; b = b->next){ 
			i = BLEN(b); 
			if(i >= len) 
				break; 
			(*s->func)(b->rp, i, 0, &ss); 
			len -= i; 
		} 
		if(b == 0) 
			panic("digestbread"); 
		if(i > len){ 
			i -= len; 
			s->unprocessed = allocb(i); 
			memmove(s->unprocessed->wp, b->rp+len, i); 
			s->unprocessed->wp += i; 
			b->wp -= i; 
		} 
		(*s->func)(b->rp, len, 0, &ss); 
                 
		/* digest secret & message id */ 
		p = s->in.secret; 
		m = s->in.mid++; 
		*p++ = m>>24; 
		*p++ = m>>16; 
		*p++ = m>>8; 
		*p = m; 
		(*s->func)(s->in.secret, s->in.slen, digest, &ss); 
                 
		if(memcmp(digest, digestin, s->diglen) != 0) 
			error("bad digest"); 
1995/1217    
	switch(s->encryptalg){ 
	case DESEBC: 
		ds = s->out.state; 
		ep = b->rp + BLEN(b); 
		for(p = b->rp + offset; p < ep; p += 8) 
			block_cipher(ds->expanded, p, 0); 
		break; 
	case DESCBC: 
		ds = s->out.state; 
		ep = b->rp + BLEN(b); 
		for(p = b->rp + offset; p < ep; p += 8) 
			bCBCEncrypt(p, ds->ivec, ds->expanded, 8); 
		break; 
1995/1213    
	} 
1995/1217    
	return b; 
} 
1995/1213    
 
	b = s->processed; 
	if(BLEN(b) > n){ 
		b = allocb(n); 
		memmove(b->wp, s->processed->rp, n); 
		b->wp += n; 
		s->processed->rp += n; 
	} else  
		s->processed = b->next; 
1995/1217    
static Block* 
decryptb(Dstate *s, Block *b) 
{ 
	ulong n, h; 
	int j; 
	uchar *p, *ep; 
	DESstate *ds; 
1995/1213    
 
1995/1217    
	switch(s->encryptalg){ 
	case DESEBC: 
		ds = s->out.state; 
		ep = b->rp + BLEN(b); 
		for(p = b->rp + s->diglen; p < ep; p += 8) 
			block_cipher(ds->expanded, p, 1); 
		break; 
	case DESCBC: 
		ds = s->out.state; 
		ep = b->rp + BLEN(b); 
		for(p = b->rp + s->diglen; p < ep; p += 8) 
			bCBCDecrypt(p, ds->ivec, ds->expanded, 8); 
		break; 
	} 
1995/1213    
	return b; 
} 
 
1995/1215    
void 
digestb(Dstate *s, Block *b) 
1995/1217    
static Block* 
digestb(Dstate *s, Block *b, int offset) 
1995/1213    
{ 
1995/1215    
	Block *nb; 
	uchar *p; 
1995/1215/sys/src/9/port/devssl.c:657,6631995/1217/sys/src/9/port/devssl.c:620,626
1995/1215    
	w = &s->out; 
1995/1213    
 
1995/1215    
	memset(&ss, 0, sizeof(ss)); 
	h = s->diglen + 2; 
1995/1217    
	h = s->diglen + offset; 
1995/1215    
	n = BLEN(b) - h; 
1995/1213    
 
1995/1215    
	/* hash secret + message */ 
1995/1215/sys/src/9/port/devssl.c:671,7041995/1217/sys/src/9/port/devssl.c:634,676
1995/1215    
	*p++ = n>>16; 
	*p++ = n>>8; 
	*p = n; 
	(*s->func)(msgid, 4, nb->rp + 2, &ss); 
1995/1217    
	(*s->func)(msgid, 4, nb->rp+offset, &ss); 
 
	retrn b; 
1995/1215    
} 
1995/1213    
 
1995/1215    
long 
encryptb(Dstate *s, Block *b) 
1995/1217    
static void 
checkdigestb(Dstate *s, Block *b) 
1995/1215    
{ 
1995/1217    
	Block *nb; 
	uchar *p; 
	DigestState ss; 
	uchar msgid[4]; 
1995/1215    
	ulong n, h; 
	int j; 
	uchar *p, *ep, *ip; 
	DESstate *ds; 
1995/1217    
	OneWay *w; 
	uchar digest[128]; 
1995/1213    
 
1995/1215    
	h = s->diglen + 2; 
1995/1217    
	w = &s->in; 
1995/1213    
 
1995/1215    
	switch(s->encryptalg){ 
	case DESEBC: 
		ds = s->out.state; 
		ep = b->rp + BLEN(b); 
		for(p = b->rp + h; p < ep; p += 8) 
			block_cipher(ds->expanded, p, 0); 
		break; 
	case DESCBC: 
		ds = s->out.state; 
		ep = b->rp + BLEN(b); 
		for(p = b->rp + h; p < ep; p += 8) 
			bCBCEncrypt(p, ds->ivec, ds->expanded, 8); 
		break; 
	} 
	                 
1995/1217    
	memset(&ss, 0, sizeof(ss)); 
	h = s->diglen; 
	n = BLEN(b) - h; 
 
	/* hash secret + message */ 
	(*s->hf)(w->secret, w->slen, 0, &ss); 
	(*s->hf)(nb->rp + h, n, 0, &ss); 
 
	/* hash message id */ 
	p = msgid; 
	n = w->mid++; 
	*p++ = n>>24; 
	*p++ = n>>16; 
	*p++ = n>>8; 
	*p = n; 
	(*s->func)(msgid, 4, digest, &ss); 
 
	if(memcmp(digest, nb->rp, s->diglen) != 0) 
		error("bad digest"); 
1995/1213    
} 
 
1995/1215    
/* get channel associated with an fd */ 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)