| #include "os.h" | 
 | #include <libsec.h> | 
 |  | 
 | /* rfc2104 */ | 
 | static DigestState* | 
 | hmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s, | 
 | 	DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen) | 
 | { | 
 | 	int i; | 
 | 	uchar pad[65], innerdigest[256]; | 
 |  | 
 | 	if(xlen > sizeof(innerdigest)) | 
 | 		return nil; | 
 |  | 
 | 	if(klen>64) | 
 | 		return nil; | 
 |  | 
 | 	/* first time through */ | 
 | 	if(s == nil){ | 
 | 		for(i=0; i<64; i++) | 
 | 			pad[i] = 0x36; | 
 | 		pad[64] = 0; | 
 | 		for(i=0; i<klen; i++) | 
 | 			pad[i] ^= key[i]; | 
 | 		s = (*x)(pad, 64, nil, nil); | 
 | 		if(s == nil) | 
 | 			return nil; | 
 | 	} | 
 |  | 
 | 	s = (*x)(p, len, nil, s); | 
 | 	if(digest == nil) | 
 | 		return s; | 
 |  | 
 | 	/* last time through */ | 
 | 	for(i=0; i<64; i++) | 
 | 		pad[i] = 0x5c; | 
 | 	pad[64] = 0; | 
 | 	for(i=0; i<klen; i++) | 
 | 		pad[i] ^= key[i]; | 
 | 	(*x)(nil, 0, innerdigest, s); | 
 | 	s = (*x)(pad, 64, nil, nil); | 
 | 	(*x)(innerdigest, xlen, digest, s); | 
 | 	return nil; | 
 | } | 
 |  | 
 | DigestState* | 
 | hmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s) | 
 | { | 
 | 	return hmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen); | 
 | } | 
 |  | 
 | DigestState* | 
 | hmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s) | 
 | { | 
 | 	return hmac_x(p, len, key, klen, digest, s, md5, MD5dlen); | 
 | } |