int tls13_get_cert_verify_signature_input( SSL *ssl, uint8_t **out, size_t *out_len, enum ssl_cert_verify_context_t cert_verify_context) { CBB cbb; if (!CBB_init(&cbb, 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) { goto err; } for (size_t i = 0; i < 64; i++) { if (!CBB_add_u8(&cbb, 0x20)) { goto err; } } const uint8_t *context; size_t context_len; if (cert_verify_context == ssl_cert_verify_server) { /* Include the NUL byte. */ static const char kContext[] = "TLS 1.3, server CertificateVerify"; context = (const uint8_t *)kContext; context_len = sizeof(kContext); } else if (cert_verify_context == ssl_cert_verify_client) { static const char kContext[] = "TLS 1.3, client CertificateVerify"; context = (const uint8_t *)kContext; context_len = sizeof(kContext); } else if (cert_verify_context == ssl_cert_verify_channel_id) { static const char kContext[] = "TLS 1.3, Channel ID"; context = (const uint8_t *)kContext; context_len = sizeof(kContext); } else { goto err; } if (!CBB_add_bytes(&cbb, context, context_len)) { goto err; } uint8_t context_hashes[2 * EVP_MAX_MD_SIZE]; size_t context_hashes_len; if (!tls13_get_context_hashes(ssl, context_hashes, &context_hashes_len) || !CBB_add_bytes(&cbb, context_hashes, context_hashes_len) || !CBB_finish(&cbb, out, out_len)) { goto err; } return 1; err: OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); CBB_cleanup(&cbb); return 0; }
/* derive_secret derives a secret of length |len| and writes the result in |out| * with the given label and the current base secret and most recently-saved * handshake context. It returns one on success and zero on error. */ static int derive_secret(SSL *ssl, uint8_t *out, size_t len, const uint8_t *label, size_t label_len) { SSL_HANDSHAKE *hs = ssl->s3->hs; const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)); uint8_t context_hashes[2 * EVP_MAX_MD_SIZE]; size_t context_hashes_len; if (!tls13_get_context_hashes(ssl, context_hashes, &context_hashes_len)) { return 0; } return hkdf_expand_label(out, digest, hs->secret, hs->hash_len, label, label_len, context_hashes, context_hashes_len, len); }
int tls13_finished_mac(SSL *ssl, uint8_t *out, size_t *out_len, int is_server) { SSL_HANDSHAKE *hs = ssl->s3->hs; const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)); uint8_t key[EVP_MAX_MD_SIZE]; size_t key_len = EVP_MD_size(digest); uint8_t *traffic_secret; const char *label; if (is_server) { label = "server finished"; if (ssl->server) { traffic_secret = ssl->s3->write_traffic_secret; } else { traffic_secret = ssl->s3->read_traffic_secret; } } else { label = "client finished"; if (!ssl->server) { traffic_secret = ssl->s3->write_traffic_secret; } else { traffic_secret = ssl->s3->read_traffic_secret; } } uint8_t context_hashes[2 * EVP_MAX_MD_SIZE]; size_t context_hashes_len; unsigned len; if (!hkdf_expand_label(key, digest, traffic_secret, hs->hash_len, (const uint8_t *)label, strlen(label), NULL, 0, hs->hash_len) || !tls13_get_context_hashes(ssl, context_hashes, &context_hashes_len) || HMAC(digest, key, key_len, context_hashes, context_hashes_len, out, &len) == NULL) { return 0; } *out_len = len; return 1; }