1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2007-2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21%% 22%%---------------------------------------------------------------------- 23%% Purpose: Handles sslv3 encryption. 24%%---------------------------------------------------------------------- 25 26-module(ssl_v3). 27 28-include("ssl_cipher.hrl"). 29-include("ssl_internal.hrl"). 30-include("ssl_record.hrl"). % MD5 and SHA 31 32-export([master_secret/3, finished/3, certificate_verify/3, 33 mac_hash/6, setup_keys/7, 34 suites/0]). 35-compile(inline). 36 37%%==================================================================== 38%% Internal application API 39%%==================================================================== 40 41-spec master_secret(binary(), binary(), binary()) -> binary(). 42 43master_secret(PremasterSecret, ClientRandom, ServerRandom) -> 44 %% draft-ietf-tls-ssl-version3-00 - 6.2.2 45 %% key_block = 46 %% MD5(master_secret + SHA(`A' + master_secret + 47 %% ServerHello.random + 48 %% ClientHello.random)) + 49 %% MD5(master_secret + SHA(`BB' + master_secret + 50 %% ServerHello.random + 51 %% ClientHello.random)) + 52 %% MD5(master_secret + SHA(`CCC' + master_secret + 53 %% ServerHello.random + 54 %% ClientHello.random)) + [...]; 55 Block = generate_keyblock(PremasterSecret, ClientRandom, ServerRandom, 48), 56 Block. 57 58-spec finished(client | server, binary(), [binary()]) -> binary(). 59 60finished(Role, MasterSecret, Handshake) -> 61 %% draft-ietf-tls-ssl-version3-00 - 5.6.9 Finished 62 %% struct { 63 %% opaque md5_hash[16]; 64 %% opaque sha_hash[20]; 65 %% } Finished; 66 %% 67 %% md5_hash MD5(master_secret + pad2 + 68 %% MD5(handshake_messages + Sender + 69 %% master_secret + pad1)); 70 %% sha_hash SHA(master_secret + pad2 + 71 %% SHA(handshake_messages + Sender + 72 %% master_secret + pad1)); 73 Sender = get_sender(Role), 74 MD5 = handshake_hash(?MD5, MasterSecret, Sender, Handshake), 75 SHA = handshake_hash(?SHA, MasterSecret, Sender, Handshake), 76 <<MD5/binary, SHA/binary>>. 77 78-spec certificate_verify(md5sha | sha, binary(), [binary()]) -> binary(). 79 80certificate_verify(md5sha, MasterSecret, Handshake) -> 81 %% md5_hash 82 %% MD5(master_secret + pad_2 + 83 %% MD5(handshake_messages + master_secret + pad_1)); 84 %% sha_hash 85 %% SHA(master_secret + pad_2 + 86 %% SHA(handshake_messages + master_secret + pad_1)); 87 88 MD5 = handshake_hash(?MD5, MasterSecret, undefined, Handshake), 89 SHA = handshake_hash(?SHA, MasterSecret, undefined, Handshake), 90 <<MD5/binary, SHA/binary>>; 91 92certificate_verify(sha, MasterSecret, Handshake) -> 93 %% sha_hash 94 %% SHA(master_secret + pad_2 + 95 %% SHA(handshake_messages + master_secret + pad_1)); 96 97 handshake_hash(?SHA, MasterSecret, undefined, Handshake). 98 99-spec mac_hash(integer(), binary(), integer(), integer(), integer(), binary()) -> binary(). 100 101mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) -> 102 %% draft-ietf-tls-ssl-version3-00 - 5.2.3.1 103 %% hash(MAC_write_secret + pad_2 + 104 %% hash(MAC_write_secret + pad_1 + seq_num + 105 %% SSLCompressed.type + SSLCompressed.length + 106 %% SSLCompressed.fragment)); 107 Mac = mac_hash(Method, Mac_write_secret, 108 [<<?UINT64(Seq_num), ?BYTE(Type), 109 ?UINT16(Length)>>, Fragment]), 110 Mac. 111 112-spec setup_keys(binary(), binary(), binary(), 113 integer(), integer(), term(), integer()) -> 114 {binary(), binary(), binary(), 115 binary(), binary(), binary()}. 116 117setup_keys(MasterSecret, ServerRandom, ClientRandom, HS, KML, _EKML, IVS) -> 118 KeyBlock = generate_keyblock(MasterSecret, ServerRandom, ClientRandom, 119 2*(HS+KML+IVS)), 120 %% draft-ietf-tls-ssl-version3-00 - 6.2.2 121 %% The key_block is partitioned as follows. 122 %% client_write_MAC_secret[CipherSpec.hash_size] 123 %% server_write_MAC_secret[CipherSpec.hash_size] 124 %% client_write_key[CipherSpec.key_material] 125 %% server_write_key[CipherSpec.key_material] 126 %% client_write_IV[CipherSpec.IV_size] /* non-export ciphers */ 127 %% server_write_IV[CipherSpec.IV_size] /* non-export ciphers */ 128 <<ClientWriteMacSecret:HS/binary, ServerWriteMacSecret:HS/binary, 129 ClientWriteKey:KML/binary, ServerWriteKey:KML/binary, 130 ClientIV:IVS/binary, ServerIV:IVS/binary>> = KeyBlock, 131 {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey, 132 ServerWriteKey, ClientIV, ServerIV}. 133 134-spec suites() -> [ssl_cipher_format:cipher_suite()]. 135 136suites() -> 137 [ 138 ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 139 ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 140 ?TLS_RSA_WITH_AES_256_CBC_SHA, 141 ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 142 ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 143 ?TLS_RSA_WITH_3DES_EDE_CBC_SHA, 144 ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 145 ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 146 ?TLS_RSA_WITH_AES_128_CBC_SHA 147 ]. 148 149%%-------------------------------------------------------------------- 150%%% Internal functions 151%%-------------------------------------------------------------------- 152 153hash(?MD5, Data) -> 154 crypto:hash(md5, Data); 155hash(?SHA, Data) -> 156 crypto:hash(sha, Data). 157 158%%pad_1(?NULL) -> 159%% ""; 160pad_1(?MD5) -> 161 <<"666666666666666666666666666666666666666666666666">>; 162pad_1(?SHA) -> 163 <<"6666666666666666666666666666666666666666">>. 164%%pad_2(?NULL) -> 165%% ""; 166pad_2(?MD5) -> 167 <<"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" 168 "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\">>; 169pad_2(?SHA) -> 170 <<"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" 171 "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\">>. 172 173mac_hash(?NULL, _Secret, _Data) -> 174 <<>>; 175mac_hash(Method, Secret, Data) -> 176 InnerHash = hash(Method, [Secret, pad_1(Method), Data]), 177 hash(Method, [Secret, pad_2(Method), InnerHash]). 178 179handshake_hash(Method, MasterSecret, undefined, Handshake) -> 180 InnerHash = hash(Method, [Handshake, MasterSecret, pad_1(Method)]), 181 hash(Method, [MasterSecret, pad_2(Method), InnerHash]); 182handshake_hash(Method, MasterSecret, Sender, Handshake) -> 183 InnerHash = hash(Method, [Handshake, Sender, MasterSecret, pad_1(Method)]), 184 hash(Method, [MasterSecret, pad_2(Method), InnerHash]). 185 186get_sender(client) -> "CLNT"; 187get_sender(server) -> "SRVR". 188 189generate_keyblock(MasterSecret, ServerRandom, ClientRandom, WantedLength) -> 190 gen(MasterSecret, [MasterSecret, ServerRandom, ClientRandom], 191 WantedLength, 0, $A, 1, []). 192 193gen(_Secret, _All, Wanted, Len, _C, _N, Acc) when Wanted =< Len -> 194 <<Block:Wanted/binary, _/binary>> = list_to_binary(lists:reverse(Acc)), 195 Block; 196gen(Secret, All, Wanted, Len, C, N, Acc) -> 197 Prefix = lists:duplicate(N, C), 198 SHA = crypto:hash(sha, [Prefix, All]), 199 MD5 = crypto:hash(md5, [Secret, SHA]), 200 gen(Secret, All, Wanted, Len + 16, C+1, N+1, [MD5 | Acc]). 201