/* $OpenBSD: tls12_lib.c,v 1.3 2021/05/02 15:57:29 jsing Exp $ */ /* * Copyright (c) 2021 Joel Sing * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "ssl_locl.h" static int tls12_finished_verify_data(SSL *s, const char *finished_label, size_t finished_label_len, uint8_t *verify_data, size_t verify_data_len, size_t *out_len) { uint8_t transcript_hash[EVP_MAX_MD_SIZE]; size_t transcript_hash_len; *out_len = 0; if (s->session->master_key_length <= 0) return 0; if (verify_data_len < TLS1_FINISH_MAC_LENGTH) return 0; if (!tls1_transcript_hash_value(s, transcript_hash, sizeof(transcript_hash), &transcript_hash_len)) return 0; if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length, finished_label, finished_label_len, transcript_hash, transcript_hash_len, NULL, 0, NULL, 0, NULL, 0, verify_data, TLS1_FINISH_MAC_LENGTH)) return 0; *out_len = TLS1_FINISH_MAC_LENGTH; return 1; } static int tls12_client_finished_verify_data(SSL *s, uint8_t *verify_data, size_t verify_data_len, size_t *out_len) { return tls12_finished_verify_data(s, TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, verify_data, verify_data_len, out_len); } static int tls12_server_finished_verify_data(SSL *s, uint8_t *verify_data, size_t verify_data_len, size_t *out_len) { return tls12_finished_verify_data(s, TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, verify_data, verify_data_len, out_len); } int tls12_derive_finished(SSL *s) { if (!s->server) { return tls12_client_finished_verify_data(s, S3I(s)->hs.finished, sizeof(S3I(s)->hs.finished), &S3I(s)->hs.finished_len); } else { return tls12_server_finished_verify_data(s, S3I(s)->hs.finished, sizeof(S3I(s)->hs.finished), &S3I(s)->hs.finished_len); } } int tls12_derive_peer_finished(SSL *s) { if (s->server) { return tls12_client_finished_verify_data(s, S3I(s)->hs.peer_finished, sizeof(S3I(s)->hs.peer_finished), &S3I(s)->hs.peer_finished_len); } else { return tls12_server_finished_verify_data(s, S3I(s)->hs.peer_finished, sizeof(S3I(s)->hs.peer_finished), &S3I(s)->hs.peer_finished_len); } } int tls12_derive_master_secret(SSL *s, uint8_t *premaster_secret, size_t premaster_secret_len) { s->session->master_key_length = 0; if (premaster_secret_len == 0) return 0; CTASSERT(sizeof(s->session->master_key) == SSL_MAX_MASTER_KEY_LENGTH); if (!tls1_PRF(s, premaster_secret, premaster_secret_len, TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0, s->s3->server_random, SSL3_RANDOM_SIZE, NULL, 0, s->session->master_key, sizeof(s->session->master_key))) return 0; s->session->master_key_length = SSL_MAX_MASTER_KEY_LENGTH; return 1; }