예제 #1
0
파일: prf.c 프로젝트: Deadolus/ecc
/*
	MD5 portions of the prf
*/
__inline static int32_t pMd5(const unsigned char *key, uint16_t keyLen,
				const unsigned char *text, uint16_t textLen,
				unsigned char *out, uint16_t outLen)
{
	psHmacMd5_t		ctx;
	unsigned char	a[MD5_HASH_SIZE];
	unsigned char	mac[MD5_HASH_SIZE];
	unsigned char	hmacKey[MD5_HASH_SIZE];
	int32_t			rc = PS_FAIL;
	uint16_t		hmacKeyLen, i, keyIter;

	for (keyIter = 1; (uint16_t)(MD5_HASH_SIZE * keyIter) < outLen;) {
		keyIter++;
	}
	if ((rc = psHmacMd5(key, keyLen, text, textLen, a,
			hmacKey, &hmacKeyLen)) < 0) {
		goto L_RETURN;
	}
	if (hmacKeyLen != keyLen) {
/*
		Support for keys larger than 64 bytes.  Must take the hash of
		the original key in these cases which is indicated by different
		outgoing values from the passed in key and keyLen values
*/
		psAssert(keyLen > 64);
		/* Typecast is OK, we don't update key below */
		key = (const unsigned char *)hmacKey;
		keyLen = hmacKeyLen;
	}
	for (i = 0; i < keyIter; i++) {
		if ((rc = psHmacMd5Init(&ctx, key, keyLen)) < 0) {
			goto L_RETURN;
		}
		psHmacMd5Update(&ctx, a, MD5_HASH_SIZE);
		psHmacMd5Update(&ctx, text, textLen);
		psHmacMd5Final(&ctx, mac);
		if (i == keyIter - 1) {
			memcpy(out + (MD5_HASH_SIZE*i), mac, outLen - (MD5_HASH_SIZE*i));
		} else {
			memcpy(out + (MD5_HASH_SIZE * i), mac, MD5_HASH_SIZE);
			if ((rc = psHmacMd5(key, keyLen, a, MD5_HASH_SIZE, a,
					hmacKey, &hmacKeyLen)) < 0) {
				goto L_RETURN;
			}
		}
	}
	rc = PS_SUCCESS;
L_RETURN:
	memzero_s(a, MD5_HASH_SIZE);
	memzero_s(mac, MD5_HASH_SIZE);
	memzero_s(hmacKey, MD5_HASH_SIZE);
	if (rc < 0) {
		memzero_s(out, outLen);	/* zero any partial result on error */
	}
	return rc;
}
예제 #2
0
파일: hmac.c 프로젝트: Deadolus/ecc
void psHmacUpdate(psHmac_t *ctx, const unsigned char *buf, uint32_t len)
{
	switch((psCipherType_e)ctx->type) {
#ifdef USE_HMAC_MD5
	case HMAC_MD5:
		psHmacMd5Update(&ctx->u.md5, buf, len);
		break;
#endif
#ifdef USE_HMAC_SHA1
	case HMAC_SHA1:
		psHmacSha1Update(&ctx->u.sha1, buf, len);
		break;
#endif
#ifdef USE_HMAC_SHA256
	case HMAC_SHA256:
		psHmacSha256Update(&ctx->u.sha256, buf, len);
		break;
#endif
#ifdef USE_HMAC_SHA384
	case HMAC_SHA384:
		psHmacSha384Update(&ctx->u.sha384, buf, len);
		break;
#endif
	default:
		break;
	}
}
예제 #3
0
/*
	HMAC-MD5
	http://www.faqs.org/rfcs/rfc2104.html

	the HMAC_MD5 transform looks like:

		MD5(K XOR opad, MD5(K XOR ipad, text))
       
		where K is an n byte key
		ipad is the byte 0x36 repeated 64 times

		opad is the byte 0x5c repeated 64 times
		and text is the data being protected

	If the keyLen is > 64 bytes, we hash the key and use it instead
*/
int32 psHmacMd5(unsigned char *key, uint32 keyLen, 
				const unsigned char *buf, uint32 len, unsigned char *hash,
				unsigned char *hmacKey, uint32 *hmacKeyLen)
{
	psHmacContext_t		ctx;
	psDigestContext_t	md;
/*
	Support for keys larger than 64 bytes.  In this case, we take the
	hash of the key itself and use that instead.  Inform the caller by
	updating the hmacKey and hmacKeyLen outputs
*/
	if (keyLen > 64) {
		psMd5Init(&md);
		psMd5Update(&md, key, keyLen);
		*hmacKeyLen = psMd5Final(&md, hash);
		memcpy(hmacKey, hash, *hmacKeyLen);
	} else {
		hmacKey = key;
		*hmacKeyLen = keyLen;
	}

	psHmacMd5Init(&ctx, hmacKey, *hmacKeyLen);
	psHmacMd5Update(&ctx, buf, len);
	return psHmacMd5Final(&ctx, hash);
}
예제 #4
0
파일: tls.c 프로젝트: Deadolus/ecc
/*
	TLS MD5 HMAC generate/verify
*/
int32_t tlsHMACMd5(ssl_t *ssl, int32 mode, unsigned char type,
				 unsigned char *data, uint32 len, unsigned char *mac)
{
	psHmacMd5_t			ctx;
	unsigned char		*key, *seq;
	unsigned char		majVer, minVer, tmp[5];
	int32				i;

	majVer = ssl->majVer;
	minVer = ssl->minVer;

	if (mode == HMAC_CREATE) {
		key = ssl->sec.writeMAC;
		seq = ssl->sec.seq;
	} else { /* HMAC_VERIFY */
		key = ssl->sec.readMAC;
		seq = ssl->sec.remSeq;
	}
	/* Sanity */
	if (key == NULL) {
		return PS_FAILURE;
	}

	if (psHmacMd5Init(&ctx, key, MD5_HASH_SIZE) < 0) {
		return PS_FAIL;
	}
#ifdef USE_DTLS
	if (ssl->flags & SSL_FLAGS_DTLS) {
		if (mode == HMAC_CREATE) {
			psHmacMd5Update(&ctx, ssl->epoch, 2);
			psHmacMd5Update(&ctx, ssl->rsn, 6);
		} else { /* HMAC_VERIFY */
			psHmacMd5Update(&ctx, ssl->rec.epoch, 2);
			psHmacMd5Update(&ctx, ssl->rec.rsn, 6);
		}
	} else {
#endif /* USE_DTLS */
		psHmacMd5Update(&ctx, seq, 8);
		for (i = 7; i >= 0; i--) {
			seq[i]++;
			if (seq[i] != 0) {
				break;
			}
		}
#ifdef USE_DTLS
	}
#endif /* USE_DTLS */

	tmp[0] = type;
	tmp[1] = majVer;
	tmp[2] = minVer;
	tmp[3] = (len & 0xFF00) >> 8;
	tmp[4] = len & 0xFF;
	psHmacMd5Update(&ctx, tmp, 5);
	psHmacMd5Update(&ctx, data, len);
	psHmacMd5Final(&ctx, mac);

	return PS_SUCCESS;
}
예제 #5
0
파일: tls.c 프로젝트: B-Rich/NUL
/*
	MD5 portions of the prf
*/
static int32 pMd5(unsigned char *key, uint32 keyLen, 
				unsigned char *text, uint32 textLen,
				unsigned char *out, uint32 outLen)
{
	psHmacContext_t	ctx;
	unsigned char	a[MD5_HASH_SIZE];
	unsigned char	mac[MD5_HASH_SIZE];
	unsigned char	hmacKey[MD5_HASH_SIZE];
	int32			i, keyIter = 1;
	uint32			hmacKeyLen;

	while ((uint32)(MD5_HASH_SIZE * keyIter) < outLen) {
		keyIter++;
	}
	psHmacMd5(key, keyLen, text, textLen, a, hmacKey, &hmacKeyLen);
	if (hmacKeyLen != keyLen) {
/*
		Support for keys larger than 64 bytes.  Must take the hash of
		the original key in these cases which is indicated by different
		outgoing values from the passed in key and keyLen values
*/
		psAssert(keyLen > 64);
		key = hmacKey;
		keyLen = hmacKeyLen;
	}
	for (i = 0; i < keyIter; i++) {
		psHmacMd5Init(&ctx, key, keyLen);
		psHmacMd5Update(&ctx, a, MD5_HASH_SIZE);
		psHmacMd5Update(&ctx, text, textLen);
		psHmacMd5Final(&ctx, mac);
		if (i == keyIter - 1) {
			memcpy(out + (MD5_HASH_SIZE*i), mac, outLen - (MD5_HASH_SIZE*i));
		} else {
			memcpy(out + (MD5_HASH_SIZE * i), mac, MD5_HASH_SIZE);
			psHmacMd5(key, keyLen, a, MD5_HASH_SIZE, a, hmacKey, &hmacKeyLen);
		}
	}
	return 0;
}
예제 #6
0
파일: tls.c 프로젝트: B-Rich/NUL
/*
	TLS MD5 HMAC generate/verify
*/
int32 tlsHMACMd5(ssl_t *ssl, int32 mode, unsigned char type,	
				 unsigned char *data, uint32 len, unsigned char *mac)
{
	psHmacContext_t		ctx;
	unsigned char		*key, *seq;
	unsigned char		majVer, minVer, tmp[5];
	int32				i;

	majVer = ssl->majVer;
	minVer = ssl->minVer;
	
	if (mode == HMAC_CREATE) {
		key = ssl->sec.writeMAC;
		seq = ssl->sec.seq;
	} else { /* HMAC_VERIFY */
		key = ssl->sec.readMAC;
		seq = ssl->sec.remSeq;
	}
	
	psHmacMd5Init(&ctx, key, MD5_HASH_SIZE);
		psHmacMd5Update(&ctx, seq, 8);
		for (i = 7; i >= 0; i--) {
			seq[i]++;
			if (seq[i] != 0) {
				break; 
			}
		}

	tmp[0] = type;
	tmp[1] = majVer;
	tmp[2] = minVer;
	tmp[3] = (len & 0xFF00) >> 8;
	tmp[4] = len & 0xFF;
	psHmacMd5Update(&ctx, tmp, 5);
	psHmacMd5Update(&ctx, data, len);
	return psHmacMd5Final(&ctx, mac);
}
예제 #7
0
파일: hmac.c 프로젝트: Deadolus/ecc
int32_t psHmacMd5(const unsigned char *key, uint16_t keyLen,
				const unsigned char *buf, uint32_t len,
				unsigned char hash[MD5_HASHLEN],
				unsigned char *hmacKey, uint16_t *hmacKeyLen)
{
	int32_t				rc;
	union {
		psHmacMd5_t		mac;
		psMd5_t			md;
	} u;
	psHmacMd5_t			*mac = &u.mac;
	psMd5_t				*md = &u.md;
/*
	Support for keys larger than 64 bytes.  In this case, we take the
	hash of the key itself and use that instead.  Inform the caller by
	updating the hmacKey and hmacKeyLen outputs
*/
	if (keyLen > 64) {
		if ((rc = psMd5Init(md)) < 0) {
			return rc;
		}
		psMd5Update(md, key, keyLen);
		psMd5Final(md, hash);
		*hmacKeyLen = MD5_HASHLEN;
		memcpy(hmacKey, hash, *hmacKeyLen);
	} else {
		hmacKey = (unsigned char *)key; /* @note typecasting from const */
		*hmacKeyLen = keyLen;
	}
	if ((rc = psHmacMd5Init(mac, hmacKey, *hmacKeyLen)) < 0) {
		return rc;
	}
	psHmacMd5Update(mac, buf, len);
	psHmacMd5Final(mac, hash);
	return PS_SUCCESS;
}