// TLS type HAMC void TLS_hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz, ContentType content, bool verify) { mySTL::auto_ptr<Digest> hmac; opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 }; opaque length[LENGTH_SZ]; opaque inner[SIZEOF_ENUM + VERSION_SZ + LENGTH_SZ]; // type + version + len c16toa(sz, length); c32toa(ssl.get_SEQIncrement(verify), &seq[sizeof(uint32)]); MACAlgorithm algo = ssl.getSecurity().get_parms().mac_algorithm_; if (algo == sha) hmac.reset(NEW_YS HMAC_SHA(ssl.get_macSecret(verify), SHA_LEN)); else if (algo == rmd) hmac.reset(NEW_YS HMAC_RMD(ssl.get_macSecret(verify), RMD_LEN)); else hmac.reset(NEW_YS HMAC_MD5(ssl.get_macSecret(verify), MD5_LEN)); hmac->update(seq, SEQ_SZ); // seq_num inner[0] = content; // type inner[SIZEOF_ENUM] = ssl.getSecurity().get_connection().version_.major_; inner[SIZEOF_ENUM + SIZEOF_ENUM] = ssl.getSecurity().get_connection().version_.minor_; // version memcpy(&inner[SIZEOF_ENUM + VERSION_SZ], length, LENGTH_SZ); // length hmac->update(inner, sizeof(inner)); hmac->get_digest(digest, buffer, sz); // content }
/* compute SSLv3 HMAC into digest see * buffer is of sz size and includes HandShake Header but not a Record Header * verify means to check peers hmac */ void hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz, ContentType content, bool verify) { Digest& mac = ssl.useCrypto().use_digest(); opaque inner[SHA_LEN + PAD_MD5 + SEQ_SZ + SIZEOF_ENUM + LENGTH_SZ]; opaque outer[SHA_LEN + PAD_MD5 + SHA_LEN]; opaque result[SHA_LEN]; // max possible sizes uint digestSz = mac.get_digestSize(); // actual sizes uint padSz = mac.get_padSize(); uint innerSz = digestSz + padSz + SEQ_SZ + SIZEOF_ENUM + LENGTH_SZ; uint outerSz = digestSz + padSz + digestSz; // data const opaque* mac_secret = ssl.get_macSecret(verify); opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 }; opaque length[LENGTH_SZ]; c16toa(sz, length); c32toa(ssl.get_SEQIncrement(verify), &seq[sizeof(uint32)]); // make inner memcpy(inner, mac_secret, digestSz); memcpy(&inner[digestSz], PAD1, padSz); memcpy(&inner[digestSz + padSz], seq, SEQ_SZ); inner[digestSz + padSz + SEQ_SZ] = content; memcpy(&inner[digestSz + padSz + SEQ_SZ + SIZEOF_ENUM], length, LENGTH_SZ); mac.update(inner, innerSz); mac.get_digest(result, buffer, sz); // append content buffer // make outer memcpy(outer, mac_secret, digestSz); memcpy(&outer[digestSz], PAD2, padSz); memcpy(&outer[digestSz + padSz], result, digestSz); mac.get_digest(digest, outer, outerSz); }