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 */
| 619 | * verify means to check peers hmac |
| 620 | */ |
| 621 | void hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz, |
| 622 | ContentType content, bool verify) |
| 623 | { |
| 624 | Digest& mac = ssl.useCrypto().use_digest(); |
| 625 | opaque inner[SHA_LEN + PAD_MD5 + SEQ_SZ + SIZEOF_ENUM + LENGTH_SZ]; |
| 626 | opaque outer[SHA_LEN + PAD_MD5 + SHA_LEN]; |
| 627 | opaque result[SHA_LEN]; // max possible sizes |
| 628 | uint digestSz = mac.get_digestSize(); // actual sizes |
| 629 | uint padSz = mac.get_padSize(); |
| 630 | uint innerSz = digestSz + padSz + SEQ_SZ + SIZEOF_ENUM + LENGTH_SZ; |
| 631 | uint outerSz = digestSz + padSz + digestSz; |
| 632 | |
| 633 | // data |
| 634 | const opaque* mac_secret = ssl.get_macSecret(verify); |
| 635 | opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 }; |
| 636 | opaque length[LENGTH_SZ]; |
| 637 | c16toa(sz, length); |
| 638 | c32toa(ssl.get_SEQIncrement(verify), &seq[sizeof(uint32)]); |
| 639 | |
| 640 | // make inner |
| 641 | memcpy(inner, mac_secret, digestSz); |
| 642 | memcpy(&inner[digestSz], PAD1, padSz); |
| 643 | memcpy(&inner[digestSz + padSz], seq, SEQ_SZ); |
| 644 | inner[digestSz + padSz + SEQ_SZ] = content; |
| 645 | memcpy(&inner[digestSz + padSz + SEQ_SZ + SIZEOF_ENUM], length, LENGTH_SZ); |
| 646 | |
| 647 | mac.update(inner, innerSz); |
| 648 | mac.get_digest(result, buffer, sz); // append content buffer |
| 649 | |
| 650 | // make outer |
| 651 | memcpy(outer, mac_secret, digestSz); |
| 652 | memcpy(&outer[digestSz], PAD2, padSz); |
| 653 | memcpy(&outer[digestSz + padSz], result, digestSz); |
| 654 | |
| 655 | mac.get_digest(digest, outer, outerSz); |
| 656 | } |
| 657 | |
| 658 | |
| 659 | // TLS type HAMC |
no test coverage detected