1// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#include <assert.h> 16 17#include <openssl/bytestring.h> 18#include <openssl/digest.h> 19#include <openssl/hkdf.h> 20#include <openssl/hmac.h> 21#include <openssl/mem.h> 22 23#include "internal.h" 24#include "../../internal.h" 25#include "../service_indicator/internal.h" 26 27 28// tls1_P_hash computes the TLS P_<hash> function as described in RFC 5246, 29// section 5. It XORs |out_len| bytes to |out|, using |md| as the hash and 30// |secret| as the secret. |label|, |seed1|, and |seed2| are concatenated to 31// form the seed parameter. It returns true on success and false on failure. 32static int tls1_P_hash(uint8_t *out, size_t out_len, 33 const EVP_MD *md, 34 const uint8_t *secret, size_t secret_len, 35 const char *label, size_t label_len, 36 const uint8_t *seed1, size_t seed1_len, 37 const uint8_t *seed2, size_t seed2_len) { 38 HMAC_CTX ctx, ctx_tmp, ctx_init; 39 uint8_t A1[EVP_MAX_MD_SIZE]; 40 unsigned A1_len; 41 int ret = 0; 42 43 const size_t chunk = EVP_MD_size(md); 44 HMAC_CTX_init(&ctx); 45 HMAC_CTX_init(&ctx_tmp); 46 HMAC_CTX_init(&ctx_init); 47 48 if (!HMAC_Init_ex(&ctx_init, secret, secret_len, md, NULL) || 49 !HMAC_CTX_copy_ex(&ctx, &ctx_init) || 50 !HMAC_Update(&ctx, (const uint8_t *) label, label_len) || 51 !HMAC_Update(&ctx, seed1, seed1_len) || 52 !HMAC_Update(&ctx, seed2, seed2_len) || 53 !HMAC_Final(&ctx, A1, &A1_len)) { 54 goto err; 55 } 56 57 for (;;) { 58 unsigned len_u; 59 uint8_t hmac[EVP_MAX_MD_SIZE]; 60 if (!HMAC_CTX_copy_ex(&ctx, &ctx_init) || 61 !HMAC_Update(&ctx, A1, A1_len) || 62 // Save a copy of |ctx| to compute the next A1 value below. 63 (out_len > chunk && !HMAC_CTX_copy_ex(&ctx_tmp, &ctx)) || 64 !HMAC_Update(&ctx, (const uint8_t *) label, label_len) || 65 !HMAC_Update(&ctx, seed1, seed1_len) || 66 !HMAC_Update(&ctx, seed2, seed2_len) || 67 !HMAC_Final(&ctx, hmac, &len_u)) { 68 goto err; 69 } 70 size_t len = len_u; 71 assert(len == chunk); 72 73 // XOR the result into |out|. 74 if (len > out_len) { 75 len = out_len; 76 } 77 for (size_t i = 0; i < len; i++) { 78 out[i] ^= hmac[i]; 79 } 80 out += len; 81 out_len -= len; 82 83 if (out_len == 0) { 84 break; 85 } 86 87 // Calculate the next A1 value. 88 if (!HMAC_Final(&ctx_tmp, A1, &A1_len)) { 89 goto err; 90 } 91 } 92 93 ret = 1; 94 95err: 96 OPENSSL_cleanse(A1, sizeof(A1)); 97 HMAC_CTX_cleanup(&ctx); 98 HMAC_CTX_cleanup(&ctx_tmp); 99 HMAC_CTX_cleanup(&ctx_init); 100 return ret; 101} 102 103int CRYPTO_tls1_prf(const EVP_MD *digest, 104 uint8_t *out, size_t out_len, 105 const uint8_t *secret, size_t secret_len, 106 const char *label, size_t label_len, 107 const uint8_t *seed1, size_t seed1_len, 108 const uint8_t *seed2, size_t seed2_len) { 109 if (out_len == 0) { 110 return 1; 111 } 112 113 OPENSSL_memset(out, 0, out_len); 114 115 const EVP_MD *const original_digest = digest; 116 FIPS_service_indicator_lock_state(); 117 int ret = 0; 118 119 if (digest == EVP_md5_sha1()) { 120 // If using the MD5/SHA1 PRF, |secret| is partitioned between MD5 and SHA-1. 121 size_t secret_half = secret_len - (secret_len / 2); 122 if (!tls1_P_hash(out, out_len, EVP_md5(), secret, secret_half, label, 123 label_len, seed1, seed1_len, seed2, seed2_len)) { 124 goto end; 125 } 126 127 // Note that, if |secret_len| is odd, the two halves share a byte. 128 secret += secret_len - secret_half; 129 secret_len = secret_half; 130 digest = EVP_sha1(); 131 } 132 133 ret = tls1_P_hash(out, out_len, digest, secret, secret_len, label, label_len, 134 seed1, seed1_len, seed2, seed2_len); 135 136end: 137 FIPS_service_indicator_unlock_state(); 138 if (ret) { 139 TLSKDF_verify_service_indicator(original_digest); 140 } 141 return ret; 142} 143 144int CRYPTO_tls13_hkdf_expand_label(uint8_t *out, size_t out_len, 145 const EVP_MD *digest, // 146 const uint8_t *secret, size_t secret_len, 147 const uint8_t *label, size_t label_len, 148 const uint8_t *hash, size_t hash_len) { 149 static const uint8_t kProtocolLabel[] = "tls13 "; 150 CBB cbb, child; 151 uint8_t *hkdf_label = NULL; 152 size_t hkdf_label_len; 153 154 FIPS_service_indicator_lock_state(); 155 CBB_zero(&cbb); 156 if (!CBB_init(&cbb, 2 + 1 + sizeof(kProtocolLabel) - 1 + label_len + 1 + 157 hash_len) || 158 !CBB_add_u16(&cbb, out_len) || 159 !CBB_add_u8_length_prefixed(&cbb, &child) || 160 !CBB_add_bytes(&child, kProtocolLabel, sizeof(kProtocolLabel) - 1) || 161 !CBB_add_bytes(&child, label, label_len) || 162 !CBB_add_u8_length_prefixed(&cbb, &child) || 163 !CBB_add_bytes(&child, hash, hash_len) || 164 !CBB_finish(&cbb, &hkdf_label, &hkdf_label_len)) { 165 CBB_cleanup(&cbb); 166 FIPS_service_indicator_unlock_state(); 167 return 0; 168 } 169 170 const int ret = HKDF_expand(out, out_len, digest, secret, secret_len, 171 hkdf_label, hkdf_label_len); 172 OPENSSL_free(hkdf_label); 173 174 FIPS_service_indicator_unlock_state(); 175 if (ret) { 176 TLSKDF_verify_service_indicator(digest); 177 } 178 return ret; 179} 180 181