/* compute TLSv1 PRF (pseudo random function using HMAC) */ static void doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen, const byte* label, word32 labLen, const byte* seed, word32 seedLen) { word32 half = (secLen + 1) / 2; byte md5_half[MAX_PRF_HALF]; /* half is real size */ byte sha_half[MAX_PRF_HALF]; /* half is real size */ byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ byte md5_result[MAX_PRF_DIG]; /* digLen is real size */ byte sha_result[MAX_PRF_DIG]; /* digLen is real size */ if (half > MAX_PRF_HALF) return; if (labLen + seedLen > MAX_PRF_LABSEED) return; if (digLen > MAX_PRF_DIG) return; XMEMSET(md5_result, 0, digLen); XMEMSET(sha_result, 0, digLen); XMEMCPY(md5_half, secret, half); XMEMCPY(sha_half, secret + half - secLen % 2, half); XMEMCPY(labelSeed, label, labLen); XMEMCPY(labelSeed + labLen, seed, seedLen); p_hash(md5_result, digLen, md5_half, half, labelSeed, labLen + seedLen, md5_mac); p_hash(sha_result, digLen, sha_half, half, labelSeed, labLen + seedLen, sha_mac); get_xor(digest, digLen, md5_result, sha_result); }
//get_remainder computes the remainder of a message unsigned int get_remainder(struct Message message){ //Set up the divisor polynomial struct Message divisor; divisor.quarter[4] = CRC_DIVISOR; int i; for(i = 0; i < 3; i++){ divisor.quarter[i] = 0; } divisor.quarter[3] = POWER_32; while(!is_quotient_zero(message)){ while(!is_divisor_smaller(message, divisor)){ //Keep right shifting divisor until it is legal to divide the quotient divisor = right_shift_message(divisor); } message = get_xor(message, divisor); } message = get_xor(message, divisor); //The non-quotient portion, namely the last 32 bits of the message is the remainder return message.quarter[0]; }
// compute TLSv1 PRF (pseudo random function using HMAC) void PRF(byte* digest, uint digLen, const byte* secret, uint secLen, const byte* label, uint labLen, const byte* seed, uint seedLen) { uint half = (secLen + 1) / 2; output_buffer md5_half(half); output_buffer sha_half(half); output_buffer labelSeed(labLen + seedLen); md5_half.write(secret, half); sha_half.write(secret + half - secLen % 2, half); labelSeed.write(label, labLen); labelSeed.write(seed, seedLen); output_buffer md5_result(digLen); output_buffer sha_result(digLen); p_hash(md5_result, md5_half, labelSeed, md5); p_hash(sha_result, sha_half, labelSeed, sha); md5_result.set_current(0); sha_result.set_current(0); get_xor(digest, digLen, md5_result, sha_result); }