int ssl3_final_finish_mac(SSL *s, const char *sender, int len, unsigned char *p) { int ret; EVP_MD_CTX ctx; if (!ssl3_digest_cached_records(s, 0)) return 0; if (EVP_MD_CTX_type(s->s3->handshake_dgst) != NID_md5_sha1) { SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST); return 0; } EVP_MD_CTX_init(&ctx); EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst); ret = EVP_MD_CTX_size(&ctx); if (ret < 0) { EVP_MD_CTX_cleanup(&ctx); return 0; } if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0) || EVP_MD_CTX_ctrl(&ctx, EVP_CTRL_SSL3_MASTER_SECRET, s->session->master_key_length, s->session->master_key) <= 0 || EVP_DigestFinal_ex(&ctx, p, NULL) <= 0) { SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR); ret = 0; } EVP_MD_CTX_cleanup(&ctx); return ret; }
size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, unsigned char *p) { int ret; EVP_MD_CTX *ctx = NULL; if (!ssl3_digest_cached_records(s, 0)) { /* SSLfatal() already called */ return 0; } if (EVP_MD_CTX_type(s->s3->handshake_dgst) != NID_md5_sha1) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, SSL_R_NO_REQUIRED_DIGEST); return 0; } ctx = EVP_MD_CTX_new(); if (ctx == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_MALLOC_FAILURE); return 0; } if (!EVP_MD_CTX_copy_ex(ctx, s->s3->handshake_dgst)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR); return 0; } ret = EVP_MD_CTX_size(ctx); if (ret < 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR); EVP_MD_CTX_reset(ctx); return 0; } if ((sender != NULL && EVP_DigestUpdate(ctx, sender, len) <= 0) || EVP_MD_CTX_ctrl(ctx, EVP_CTRL_SSL3_MASTER_SECRET, (int)s->session->master_key_length, s->session->master_key) <= 0 || EVP_DigestFinal_ex(ctx, p, NULL) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR); ret = 0; } EVP_MD_CTX_free(ctx); return ret; }