--- /dev/null
+#define _POSIX_C_SOURCE 200809L
+
+#include <arpa/inet.h>
+
+#include "tlse.h"
+
+#ifndef htonll
+#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
+#endif
+
+#ifndef ntohll
+#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
+#endif
+
+unsigned int tls_hmac_message(unsigned char local,
+ struct TLSContext *context,
+ const unsigned char *buf,
+ int buf_len,
+ const unsigned char *buf2,
+ int buf_len2, unsigned char *out,
+ unsigned int outlen
+ ) {
+ hmac_state hash;
+ int hash_idx;
+
+ int mac_size = outlen;
+
+ if (mac_size == TLS_SHA1_MAC_SIZE) {
+ hash_idx = find_hash("sha1");
+ } else if (mac_size == TLS_SHA384_MAC_SIZE) {
+ hash_idx = find_hash("sha384");
+ } else {
+ hash_idx = find_hash("sha256");
+ }
+
+ if (hmac_init(&hash, hash_idx,
+ local ? context->crypto.ctx_local_mac.local_mac : context->
+ crypto.ctx_remote_mac.remote_mac, mac_size)) {
+ return 0;
+ }
+
+ uint64_t sn;
+ if (local) {
+ sn = htonll(context->local_sequence_number);
+ } else {
+ sn = htonll(context->remote_sequence_number);
+ }
+
+ if (hmac_process(&hash, (unsigned char *)&sn, sizeof sn)) {
+ return 0;
+ }
+
+ if (hmac_process(&hash, buf, buf_len)) {
+ return 0;
+ }
+
+ if (buf2 && buf_len2) {
+ if (hmac_process(&hash, buf2, buf_len2)) {
+ return 0;
+ }
+ }
+ unsigned long ref_outlen = outlen;
+ if (hmac_done(&hash, out, &ref_outlen)) {
+ return 0;
+ }
+
+ return (unsigned int)ref_outlen;
+}
+