int tls1_mac(SSL *ssl, unsigned char *md, int send)
{
    SSL3_RECORD *rec;
    unsigned char *seq;
    EVP_MD_CTX *hash;
    size_t md_size;
    int i;
    EVP_MD_CTX *hmac = NULL, *mac_ctx;
    unsigned char header[13];
    int stream_mac = (send ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM)
                      : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM));
    int t;
    if (send) {
        rec = RECORD_LAYER_get_wrec(&ssl->rlayer);
        seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
        hash = ssl->write_hash;
    } else {
        rec = RECORD_LAYER_get_rrec(&ssl->rlayer);
        seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer);
        hash = ssl->read_hash;
    }
    t = EVP_MD_CTX_size(hash);
    OPENSSL_assert(t >= 0);
    md_size = t;
    if (stream_mac) {
        mac_ctx = hash;
    } else {
        hmac = EVP_MD_CTX_new();
        if (hmac == NULL
                || !EVP_MD_CTX_copy(hmac, hash))
            return -1;
        mac_ctx = hmac;
    }
    if (SSL_IS_DTLS(ssl)) {
        unsigned char dtlsseq[8], *p = dtlsseq;
        s2n(send ? DTLS_RECORD_LAYER_get_w_epoch(&ssl->rlayer) :
            DTLS_RECORD_LAYER_get_r_epoch(&ssl->rlayer), p);
        memcpy(p, &seq[2], 6);
        memcpy(header, dtlsseq, 8);
    } else
        memcpy(header, seq, 8);
    header[8] = rec->type;
    header[9] = (unsigned char)(ssl->version >> 8);
    header[10] = (unsigned char)(ssl->version);
    header[11] = (rec->length) >> 8;
    header[12] = (rec->length) & 0xff;
    if (!send && !SSL_USE_ETM(ssl) &&
        EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
        ssl3_cbc_record_digest_supported(mac_ctx)) {
        if (ssl3_cbc_digest_record(mac_ctx,
                                   md, &md_size,
                                   header, rec->input,
                                   rec->length + md_size, rec->orig_len,
                                   ssl->s3->read_mac_secret,
                                   ssl->s3->read_mac_secret_size, 0) <= 0) {
            EVP_MD_CTX_free(hmac);
            return -1;
        }
    } else {
        if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0
                || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0
                || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) {
            EVP_MD_CTX_free(hmac);
            return -1;
        }
        if (!send && !SSL_USE_ETM(ssl) && FIPS_mode())
            tls_fips_digest_extra(ssl->enc_read_ctx,
                                  mac_ctx, rec->input,
                                  rec->length, rec->orig_len);
    }
    EVP_MD_CTX_free(hmac);
#ifdef TLS_DEBUG
    fprintf(stderr, "seq=");
    {
        int z;
        for (z = 0; z < 8; z++)
            fprintf(stderr, "%02X ", seq[z]);
        fprintf(stderr, "\n");
    }
    fprintf(stderr, "rec=");
    {
        unsigned int z;
        for (z = 0; z < rec->length; z++)
            fprintf(stderr, "%02X ", rec->data[z]);
        fprintf(stderr, "\n");
    }
#endif
    if (!SSL_IS_DTLS(ssl)) {
        for (i = 7; i >= 0; i--) {
            ++seq[i];
            if (seq[i] != 0)
                break;
        }
    }
#ifdef TLS_DEBUG
    {
        unsigned int z;
        for (z = 0; z < md_size; z++)
            fprintf(stderr, "%02X ", md[z]);
        fprintf(stderr, "\n");
    }
#endif
    return (md_size);
}
['int tls1_mac(SSL *ssl, unsigned char *md, int send)\n{\n    SSL3_RECORD *rec;\n    unsigned char *seq;\n    EVP_MD_CTX *hash;\n    size_t md_size;\n    int i;\n    EVP_MD_CTX *hmac = NULL, *mac_ctx;\n    unsigned char header[13];\n    int stream_mac = (send ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM)\n                      : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM));\n    int t;\n    if (send) {\n        rec = RECORD_LAYER_get_wrec(&ssl->rlayer);\n        seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);\n        hash = ssl->write_hash;\n    } else {\n        rec = RECORD_LAYER_get_rrec(&ssl->rlayer);\n        seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer);\n        hash = ssl->read_hash;\n    }\n    t = EVP_MD_CTX_size(hash);\n    OPENSSL_assert(t >= 0);\n    md_size = t;\n    if (stream_mac) {\n        mac_ctx = hash;\n    } else {\n        hmac = EVP_MD_CTX_new();\n        if (hmac == NULL\n                || !EVP_MD_CTX_copy(hmac, hash))\n            return -1;\n        mac_ctx = hmac;\n    }\n    if (SSL_IS_DTLS(ssl)) {\n        unsigned char dtlsseq[8], *p = dtlsseq;\n        s2n(send ? DTLS_RECORD_LAYER_get_w_epoch(&ssl->rlayer) :\n            DTLS_RECORD_LAYER_get_r_epoch(&ssl->rlayer), p);\n        memcpy(p, &seq[2], 6);\n        memcpy(header, dtlsseq, 8);\n    } else\n        memcpy(header, seq, 8);\n    header[8] = rec->type;\n    header[9] = (unsigned char)(ssl->version >> 8);\n    header[10] = (unsigned char)(ssl->version);\n    header[11] = (rec->length) >> 8;\n    header[12] = (rec->length) & 0xff;\n    if (!send && !SSL_USE_ETM(ssl) &&\n        EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&\n        ssl3_cbc_record_digest_supported(mac_ctx)) {\n        if (ssl3_cbc_digest_record(mac_ctx,\n                                   md, &md_size,\n                                   header, rec->input,\n                                   rec->length + md_size, rec->orig_len,\n                                   ssl->s3->read_mac_secret,\n                                   ssl->s3->read_mac_secret_size, 0) <= 0) {\n            EVP_MD_CTX_free(hmac);\n            return -1;\n        }\n    } else {\n        if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0\n                || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0\n                || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) {\n            EVP_MD_CTX_free(hmac);\n            return -1;\n        }\n        if (!send && !SSL_USE_ETM(ssl) && FIPS_mode())\n            tls_fips_digest_extra(ssl->enc_read_ctx,\n                                  mac_ctx, rec->input,\n                                  rec->length, rec->orig_len);\n    }\n    EVP_MD_CTX_free(hmac);\n#ifdef TLS_DEBUG\n    fprintf(stderr, "seq=");\n    {\n        int z;\n        for (z = 0; z < 8; z++)\n            fprintf(stderr, "%02X ", seq[z]);\n        fprintf(stderr, "\\n");\n    }\n    fprintf(stderr, "rec=");\n    {\n        unsigned int z;\n        for (z = 0; z < rec->length; z++)\n            fprintf(stderr, "%02X ", rec->data[z]);\n        fprintf(stderr, "\\n");\n    }\n#endif\n    if (!SSL_IS_DTLS(ssl)) {\n        for (i = 7; i >= 0; i--) {\n            ++seq[i];\n            if (seq[i] != 0)\n                break;\n        }\n    }\n#ifdef TLS_DEBUG\n    {\n        unsigned int z;\n        for (z = 0; z < md_size; z++)\n            fprintf(stderr, "%02X ", md[z]);\n        fprintf(stderr, "\\n");\n    }\n#endif\n    return (md_size);\n}', 'const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)\n{\n    if (!ctx)\n        return NULL;\n    return ctx->digest;\n}', 'int EVP_MD_size(const EVP_MD *md)\n{\n    if (!md) {\n        EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);\n        return -1;\n    }\n    return md->md_size;\n}', 'unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)\n{\n    return ctx->cipher->flags;\n}', 'char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)\n{\n    if (FIPS_mode())\n        return 0;\n    switch (EVP_MD_CTX_type(ctx)) {\n    case NID_md5:\n    case NID_sha1:\n    case NID_sha224:\n    case NID_sha256:\n    case NID_sha384:\n    case NID_sha512:\n        return 1;\n    default:\n        return 0;\n    }\n}', 'int FIPS_mode(void)\n{\n#ifdef OPENSSL_FIPS\n    return FIPS_module_mode();\n#else\n    return 0;\n#endif\n}', 'int EVP_MD_type(const EVP_MD *md)\n{\n    return md->type;\n}']