in tls/s2n_prf.c [672:728]
int s2n_prf_server_finished(struct s2n_connection *conn)
{
POSIX_ENSURE_REF(conn);
POSIX_ENSURE_REF(conn->secure);
POSIX_ENSURE_REF(conn->handshake.hashes);
struct s2n_blob master_secret, md5, sha;
uint8_t md5_digest[MD5_DIGEST_LENGTH];
uint8_t sha_digest[SHA384_DIGEST_LENGTH];
uint8_t server_finished_label[] = "server finished";
struct s2n_blob server_finished = { 0 };
struct s2n_blob label = { 0 };
if (conn->actual_protocol_version == S2N_SSLv3) {
return s2n_prf_sslv3_server_finished(conn);
}
server_finished.data = conn->handshake.server_finished;
server_finished.size = S2N_TLS_FINISHED_LEN;
POSIX_GUARD_RESULT(s2n_handshake_set_finished_len(conn, server_finished.size));
label.data = server_finished_label;
label.size = sizeof(server_finished_label) - 1;
master_secret.data = conn->secrets.version.tls12.master_secret;
master_secret.size = sizeof(conn->secrets.version.tls12.master_secret);
if (conn->actual_protocol_version == S2N_TLS12) {
switch (conn->secure->cipher_suite->prf_alg) {
case S2N_HMAC_SHA256:
POSIX_GUARD(s2n_hash_copy(&conn->handshake.hashes->hash_workspace, &conn->handshake.hashes->sha256));
POSIX_GUARD(s2n_hash_digest(&conn->handshake.hashes->hash_workspace, sha_digest, SHA256_DIGEST_LENGTH));
sha.size = SHA256_DIGEST_LENGTH;
break;
case S2N_HMAC_SHA384:
POSIX_GUARD(s2n_hash_copy(&conn->handshake.hashes->hash_workspace, &conn->handshake.hashes->sha384));
POSIX_GUARD(s2n_hash_digest(&conn->handshake.hashes->hash_workspace, sha_digest, SHA384_DIGEST_LENGTH));
sha.size = SHA384_DIGEST_LENGTH;
break;
default:
POSIX_BAIL(S2N_ERR_PRF_INVALID_ALGORITHM);
}
sha.data = sha_digest;
return s2n_prf(conn, &master_secret, &label, &sha, NULL, NULL, &server_finished);
}
POSIX_GUARD(s2n_hash_copy(&conn->handshake.hashes->hash_workspace, &conn->handshake.hashes->md5));
POSIX_GUARD(s2n_hash_digest(&conn->handshake.hashes->hash_workspace, md5_digest, MD5_DIGEST_LENGTH));
md5.data = md5_digest;
md5.size = MD5_DIGEST_LENGTH;
POSIX_GUARD(s2n_hash_copy(&conn->handshake.hashes->hash_workspace, &conn->handshake.hashes->sha1));
POSIX_GUARD(s2n_hash_digest(&conn->handshake.hashes->hash_workspace, sha_digest, SHA_DIGEST_LENGTH));
sha.data = sha_digest;
sha.size = SHA_DIGEST_LENGTH;
return s2n_prf(conn, &master_secret, &label, &md5, &sha, NULL, &server_finished);
}